3

I have to source a tcsh script to modify environment variables.

Some tests are to be done and if any fails the sourcing shall stop without exiting the shell. I do not want to run the script as a subprocess because I would need to modify env variables in the parent process which a subprocess cannot do. This is similar but different to this question where the author actually can run the script as a subprocess.

The usual workaround is to create an alias which runs a script (csh/bash/perl/python/...) which writes a tempfile with all the env var settings and at the end sources & deletes that tempfile. Here's more info for those interested (demoing a solution for bash). For my very simple and short stuff I'm doing that additional alias is not wanted.

So my workaround is to provoke a syntax error which stops any source execution. Here's an example:

test $ADMIN_USER = `filetest -U: $SOME_FILE` || "Error: Admin user must own admin file"

The shortcircuit || causes the error text to be ignored in case of goodness. On a test failure the error text is interpreted as a command, not found, the source stops and produces a reasonable error message:

Error: Admin user must own admin file: Command not found.

Is there any nicer way in doing this? Some csh/tcsh built-in that I've overlooked?

Community
  • 1
  • 1
cfi
  • 10,915
  • 8
  • 57
  • 103
  • why not just a conditional block around the conditional variables, i.e. `if ( \`filetest -U: $SOMEFILE\` ) ; then set vars ; else set ohter vars endif`. Sorry my (t)csh syntax is rather rusty, so I'm not certain about the need for `( parens )`. Good luck. – shellter May 09 '12 at 11:27
  • The problem is not with the control flow inside the `source`. The problem is with stopping sourc'ing the script without exiting the shell it was sourced from. If I would create an `if` conditional for a test, the `else` would span to the end of the file. That's unwieldy for ten or so tests (nesting!). - Unless I can combine all tests to one (or few) locations, which I am not sure that I want to do. – cfi May 09 '12 at 11:35
  • Come to think about it, this problem exist in the same way in a bash script, doesn't it? – cfi May 09 '12 at 11:38
  • yes, would be same problem in most shells. I'm surprised that your `...|| "Error: Admin..."` thingy stops the sourcing of a file while letting the surrounding script continue. I would have expected it to report the error and continue with the next line of the sourced file. This may be one in the feature column for (t)csh! Good luck. – shellter May 09 '12 at 12:10
  • "the surrounding script" is just the interactive shell. That is why I cannot use a simple `exit` command. If a sourc'ed script does an `exit` that would exit the interactive shell – cfi May 09 '12 at 13:02
  • Oh. Wait. That was my assumption. Just tested and it does not exit! – cfi May 09 '12 at 13:03

1 Answers1

3

Thanks to a discussion with the user shellter I just verified my assumption that

test $ADMIN_USER = `filetest -U: $SOME_FILE` || \
  echo "Error: Admin user must own admin file" && \
    exit

would actually quit the enclosing interactive shell. But it does not.

So the answer to my above question actually is:

Just use a normal exit and the source will stop sourcing the script while keeping the calling interactive shell running.

Community
  • 1
  • 1
cfi
  • 10,915
  • 8
  • 57
  • 103
  • So (t)csh is different? My experience (in ksh and bash) is that any `exit` that is not in a sub-process will close the current interactive shell. (I don't have any access to a (t)csh environment). Good luck. – shellter May 09 '12 at 14:19