Programs don't show up in jobs if I start them in the background with a shell script

I want to launch a three programs (2x streamlit, 1x python) in the background with a shell script:

#!/bin/sh
cd /Users/mc/src/crypto/ || exit
streamlit run dashboard.py &
streamlit run dashboard_basis_viewer.py &
/Users/mc/.virtualenvs/crypto/bin/python basis_calculator.py &

This script works (i.e. the programs start fine) but there are two problems:

  1. None of the processes show up under the jobs command
  2. If I close the terminal (iTerm), all those processes are still running

If I launch the last 3 lines manually from the command line, I don't get either of those problems. What's going on here? How can I fix it?


What's going on here?

You have a process running a shell. Based on information given in the posted question, the assumption is made this is a zsh, but others may be possible. When the posted script is executed, a new process is created to run the script in a /bin/sh. This new process starts three new background jobs associated with the /bin/sh. The /bin/sh then terminates, leaving the three jobs as orphan processes. So when the jobs command is entered, the three jobs do not appear, because three now orphaned processes were never jobs of the original zsh. Furthermore, when the zsh terminates, no termination type signals are sent to the three jobs because the processes are orphans.

How can I fix it?

If there is a need for the three jobs to appear when the jobs command is entered, then a . or source command can precede the scripts path and name. The script will be executed in the current zsh and therefore the first line in the posted script will be ignored. For example, if the name of the script is myscript and is in the current working directory, then either of the following could be entered.

. ./myscript
source ./myscript 

If need there is no need for the three jobs to appear when the jobs command is entered, then a line containing the wait command could be appended to the posted script. This will prevent the orphans from being created, when the following is used to execute the script in the background.

./myscript &

Finally, the idea of a script could be abandoned in favor of a function instead. Below is an example.

myfunction()
{
    local "cwd=$(pwd)"
    cd /Users/mc/src/crypto/
    local "n=$?"
    if [[ n -eq 0 ]]; then 
        streamlit run dashboard.py &
        streamlit run dashboard_basis_viewer.py &
        /Users/mc/.virtualenvs/crypto/bin/python basis_calculator.py &
        n="$?"
    fi
    cd "$cwd"
    return "$n"
}