Search code examples
linuxshellksh

Calling `ksh` from `ksh` script stops execution


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.


Solution

  • 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.