How to make exit behave when "sourced" in csh
Asked Answered
T

6

6

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?)

Tarrant answered 26/11, 2012 at 18:22 Comment(0)
S
7

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.

Shocking answered 6/5, 2014 at 17:42 Comment(0)
A
2

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.

Aubergine answered 12/4, 2013 at 16:34 Comment(0)
M
1

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.

Moolah answered 19/1, 2016 at 18:0 Comment(1)
I work in an environment where tcsh is used often with the "idiom" shown in this answer. I can absolutely deny that the reason it is still used is its versatility and ease of use. It is easy to misuse, has a terrible lack of common shell features and it is probably the most inconsistent language ever invented in the world. The reason it is still used is because it was the default shell in one of the world's most successful proprietary unices, Sun OS, and C Shell makes it really hard to refactor any environment built on it. Also because corporations don't like to spend money on refactoring.Behan
P
0

I don't claim to know much about csh, I mostly use "bash", and I think a long time ago in a land far away I might have used "ksh: on Sun "pizza" boxen. After poking around a bit, I noticed a few csh behvior change switches, but what if you tried something like this:

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 of the status variable.

I got this from here

Paymaster answered 26/11, 2012 at 18:41 Comment(0)
B
0

You can alias exit to setup some value and then check for it:

$ cat a.csh
#!/bin/csh
alias exit 'set abort=1; ""exit'
...
exit

And when sourcing the file:

$ cat b.csh
#!/bin/csh
source a.csh
if ( $?abort ) exit

Addendum:

I forgot to say you might change the source code on the fly:

$ cat b.csh
#!/bin/csh
source `sed '2 i alias exit '"'set abort=1; "'""exit'"'" a.csh`
if ( $?abort ) exit

This will have some penalty when compared as altering the script directly, but you don't need to bother about the original script anymore.

Bolding answered 18/2, 2013 at 13:27 Comment(0)
P
0

unset TERMINATE

unsetenv TERMINATE

echo "$TERMINATE"

Panda answered 3/11, 2021 at 9:54 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Pierro

© 2022 - 2024 — McMap. All rights reserved.