I am trying to set up a cron job to run regression tests for software that usually runs in an interactive environment (CASA, for the morbidly curious: http://casa.nrao.edu/). I have a shell script, which, in MWE form (mwe.sh), does:

casapy -c mwe.py

where it is supposed to execute that script. casapy is a fairly complicated bit of business that does a lot of things internally, including importing and setting up an ipython client for multiprocessing.

Here is my problem: If I run the code interactively, i.e. type casapy -c mwe.py on the bash shell command line, it works. If I run:

source mwe.sh

the code still runs exactly as expected and performs the tests. Great!

If instead, I run

bash mwe.sh

the startup script hangs permanently. I've tracked this down to a few different locations in the startup script that all are capable of independently failing.

So, my question: What are the differences between starting commands in the interactive shell environment and from within a script? Especially, what are the differences that can be narrowed down to differences between source file.sh and sh file.sh?

In particular, in the context of the cron job I'm trying to run, is there any way to do the equivalent of sourceing a file on the interactive command line?

EDIT: one last piece of information - I think this failure only happens on mac, not on linux, but I don't know if that provides any useful information at all because the underlying code is somewhat different for the two platforms.


source foo.sh runs the script in the current Bash shell, very similar to simply replacing the source foo.sh command by the contents of the foo.sh file. sh foo.sh runs the script within the context of a new sh shell, which on many OSes is not even Bash (which may be one reason the script doesn't work).

  • Thanks. In the context of the question, though, I'm still trying to understand what difference could cause my code to crash. Are there any differences besides the environment variables? (as I've now indicated, the shell is the same, bash, in both cases) – keflavich Feb 24 '15 at 16:37

The differences between starting commands in the interactive shell environment or from within a script is the environment.

To see the differences between source foo.sh and sh foo.sh you have to know what happens in either way:

  1. source foo.sh:

source is a bash-only built-in command. That means when you call source, there is no executable like /bin/source or so. bash itself parses the command-line interface for so called shell builtin commands. The source command is a builtin function of bash to ...

read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename.

So, it's like when you just copy and paste line by line of your foo.sh file and press Enter after every line. When no bash is running, then there is also no source command.

  1. sh foo.sh:

This call the default shell /bin/sh with an argument, a command_file. That is a pathname of a file containing commands. That file need not be executable. And there is also no necessarity of a hashbang line in it. So, a new shell is started (/bin/sh) and in that new shell, the command in the file are executed line by line. But, now the environment is not the current shell environment. It's the environment generated by the shell.

  • Thanks. Are there any differences besides the generated environment? The only different environment variables I can see are SHLVL and TMPDIR. I can't figure out any reason these variables would affect the script I'm running. – keflavich Feb 24 '15 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.