The most straightforward way would be to explicitly have the first script
exit if the other script failed. Put the script execution in a conditional, like
otherscript.sh || exit 1
if ! otherscript.sh ; then
echo "otherscript failed with exit code $ret. exit." >&2
This would allow the main script to do any cleanup it wants, or just try some other solution, possibly depending on what the child's exit code was. In the first one, we could use just
|| exit, to pass the child's exit code along.
If you want to have the main script exit when any command it starts fails, then
echo "this will not run if otherscript fails"
set -e doesn't apply to programs that run inside conditional constructs so we can still test for particular codes or tail them with
|| true to ignore the failure. But with exit points everywhere now, we could use
trap somecmd EXIT to do any cleanup before the shell exits, regardless of where it happens.
Having the inner script force the main script to exit is also possible, but a bit unfriendly, you wouldn't expect a usual application to do it. But, if you want to, just having the inner script plain old shoot its parent process is one way:
$ cat mainscript.sh
echo "$0 exiting normally"
$ cat otherscript.sh
echo "$0 kill $PPID"
$ bash mainscript.sh
./otherscript.sh kill 11825
Here, if you run
otherscript.sh from an interactive shell, it will try to shoot the interactive session. All shells I tested seem to ignore the
SIGTERM in this case when running interactively, though. In any case, the main shell could again
Instead of shooting just the parent process, you could use
kill 0 to kill all processes in the process group
otherscript.sh runs in. If started from a noninteractive shell, that would usually include the parent.