I am executing a ksh
script from another ksh
script. The called script ends by executing ksh
which simply stops the caller script from continuing.
MRE
#!/bin/ksh
# Caller Script
. ~/called
# Does not continue to next echo.
echo "DONE!"
#!/bin/ksh
#Called script
# Some exports..
ENV=calledcalled ksh
Output with set -x
++ ksh
++ ENV=calledcalled
.kshrc executed
If I run calledcalled
directly in my caller it works fine (i.e. continues with next commands. Why does this happen? I checked $?
and it is 0
. I tried ./called || true
. Please let me know if more information is needed.
Note: Called script is outside my control.
This is completely normal and expected. Remember, when you run cmd1; cmd2
, cmd2
doesn't run until cmd1
exits.
When your script runs ksh
(and is invoked from a terminal or other context where reading from stdin doesn't cause an immediate EOF), nothing is making that new copy of ksh exit -- it waits for code to run to be given to it on stdin as normal -- so that script is just sitting around waiting for the copy of ksh
to exit before it does anything else.
There are plenty of ways you can work around this. A few easy ones:
Ensure that stdin is empty so the child interpreter can't wait for input
. ~/called </dev/null
Define a function named ksh that doesn't do anything at all.
ksh() { echo "Not actually running ksh" >&2; }
. ~/called
Set ENV
(a variable which, when defined, tells any shell to run the code in that file before doing anything else) to the filename of a script that, when run, causes any interactive shell to exit immediately.
exit_script=$(mktemp -t exit_script.XXXXXX)
printf '%s\n' 'case $- in *i*) exit 0;; esac' >"$exit_script"
ENV=$exit_script . ~/called
rm -f -- "$exit_script"
The above are just a few approaches; you can surely imagine many more with just a little thought and experimentation.