csh
is an utterly horrible shell. (Making that statement up front to avoid the inevitable comments of "don't use csh", or perhaps I should just state that for the sake of any readers: please, if you value your sanity, do not use csh
.) I have a rather large collection of csh
scripts that I'm trying to make useful, and I just discovered that exit
does not exit the script when called from a sourced file. In other words:
#!/bin/csh
source [file with content "exit"]
echo No reasonable script should print this
Produces output.
Is there any way to modify that behavior? As far as I can tell, the original authors of the scripts I am modifying intended the main script to terminate, and that certainly would be desirable behavior, and simply invoking the example above via sh
produces that result, but what gives? Is there any reasonable purpose for this behavior? (That's just me ranting, the real question is: is there an option to csh to change the behavior?)
The manual of (t)csh say: exit [expr] The shell exits either with the value of the specified expr (an expression, as described under Expressions) or, without expr, with the value 0.
man tcsh: $_ Substitutes the command line of the last command executed.
To exit out of both the sourced script and the parent interpreter in csh/tcsh, I use exec /bin/false
or exec /bin/true
, depending on the success condition I want passed back to the parent process. The sourcing shell exits with the appropriate return value.
I don't think this pertains to the original context of the question, but if exit
is being used to close a login script, and hence logout the user, you can just use logout
instead of exit
.
Apropos the popular community sport I call 'csh bashing':
"csh is an utterly horrible shell."
Perhaps, but tcsh is a very easy to use, easy to code, lightweight and stable shell, available just about everywhere with fairly uniform features. Albeit, it does have some quirks which are frustrating until you learn to navigate around them. It helps to have a pretty-printer for long scripts.
The "source file [argv]" feature is the closest thing to a subroutine in tcsh, and since it shares the same namespace with the caller, it's perfectly reasonable that the exit command work more like a 'return' statement in that context. Note that an exit statement does suspend processing in the sourced file, and returns a value via $status.
Sourced tcsh files also allow the caller to post a separate $argv without losing the original, or not, in which case the caller's $argv is visible to the sourced file. If the sourced file writes to $argv, it's modified for the caller as well.
If you define an alias that sources a file, you can put together some fairly versatile multi-function scripts:
alias func 'set srcf="test.tcsf" ; set args=(!*) ; source $srcf $args'
However, if you have multiple source files in play, you need to adopt some namespace management conventions in order to insure they don't step on each other. Bottom-line, there are reasons tcsh is still in use after all these years, primarily that it's quick and easy to use, once you understand the quirks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With