[comp.unix.shell] csh exit

dfoster@jarthur.Claremont.EDU (Derek R. Foster) (03/05/91)

Can anyone explain the following output? I looked at the csh man page under
"exit" and it said that exit(stat) would terminate a shell and return
exit status 'stat', where stat was an expression. However, I tried it, and
received the following results ( the '%' is my prompt):  

% if { exit( 1 == 1 ) } echo "y"
% if { exit( 1 == 0 ) } echo "y"
y
% if { exit( 1 != 1 ) } echo "y"
y
% if { exit( 0 == 0 ) } echo "y"

As you can see, it appears that the opposite truth value is being returned.
When the expression ( 1 == 1, etc. ) is true, the value given to the 'if'
statement is false, and vice versa. This seems to be quite consistent.
(It makes no difference if I run the 'exit' command in a subshell by enclosing
the { } in ( ), just in case you were wondering.)

Why is this happening? Is this a bug or a feature? Can anyone else reproduce
these results?

The reason I am trying to do this is so that I can write, in effect,
user-defined functions along the lines of:

alias isxxxfile 'exit ( "\!*" =~ xxx* )'

if { isxxxfile $somefile } dosomething;

If there is an easier way to do this, I would appreciate information on it.
Mostly, however, I would like to understand why exit( ) seems to be logically
inverting its operands.

Any help would be greatly appreciated.

Thanks!

Derek Riippa Foster

jik@athena.mit.edu (Jonathan I. Kamens) (03/05/91)

In article <11074@jarthur.Claremont.EDU>, dfoster@jarthur.Claremont.EDU (Derek R. Foster) writes:
|> % if { exit( 1 == 1 ) } echo "y"
|> % if { exit( 1 == 0 ) } echo "y"
|> y
|> % if { exit( 1 != 1 ) } echo "y"
|> y
|> % if { exit( 0 == 0 ) } echo "y"

  The problem is that you are confusing exit statuses and with csh boolean
expressions.

  When it comes to exit statuses, a 0 exit status is considered "true", and a
non-zero exit status is considered "false".  This is because a zero exit
status indicates that a program executed successfully, which is what should be
treated as "true", while a non-zero exit status usually indicates that a
program was unsuccessful in some way.

  However, csh uses 1 to indicate true in boolean expressions, and 0 to
indicate false.  So, let's analyze what I've quoted above.  The first one
reads:

	if { exit( 1 == 1 ) } echo "y"

The expression "1 == 1" is true.  Since it is a boolean expression, that means
it takes on the value 1.  That means that the subshell exits with exit status
1.

  Now comes the reversal.  You're checking that exit status using `{' and `}',
rather than the the more common `(' and `)'.  The only documentation about `{'
and `}' in my csh man page says, "Also available in expressions as primitive
operands are command executions enclosed in `{' and `}'..."  What that doesn't
tell you is that since what you're evaluating is the exit status of a command,
rather than a boolean expression, the whole "{...}" expression is going to
be true only if the command run inside inside it exits with a zero exit status.

  But in the case I mentioned, it *didn't*, it exited with a non-zero exit
status, which means to the shell that it "failed," which means that the
"{...}" expression is going to evaluate into a false boolean expression.

  You said that the point of all this is to do something like this:

	alias isxxxfile 'exit ( "\!*" =~ xxx* )'
	
	if { isxxxfile $somefile } dosomething;

You can probably achieve that by just redefining the alias so that it uses
"!~" instead of "=~"; in other words, reverse the boolean value of your check,
so that the subshell exits with an *exit value* opposite the *boolean value*
you are trying to test for.  Observe:

	% alias isxxxfile 'exit ( "\!*" !~ xxx* )'
	% if { isxxxfile xxxfrep } echo "It is."
	It is.
	% if { isxxxfile yyyfrep } echo "It is."
	% if (! { isxxxfile yyyfrep } ) echo "It isn't."
	It isn't.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710