Search code examples
bashsshbackground-processnohupsequential

Bash script to run a detached loop that sequentially starts backgound processes


I am trying to run a series of tests on a remote Linux server to which I am connecting via ssh.

  • I don't want to have to stay logged in the ssh session during the runs -> nohup(?)
  • I don't want to have to keep checking if one run is done -> for loop(?)
  • Because of licensing issues, I can only run a single testing process at a time -> sequential
  • I want to keep working while the test set is being processed -> background

Here's what I tried:

#!/usr/bin/env bash
# Assembling a list of commands to be executed sequentially
TESTRUNS="";
for i in `ls ../testSet/*`;
do 
  MSG="running test problem ${i##*/}";
  RUN="mySequentialCommand $i > results/${i##*/} 2> /dev/null;";
  TESTRUNS=$TESTRUNS"echo $MSG; $RUN"; 
done
#run commands with nohup to be able to log out of ssh session
nohup eval $TESTRUNS &

But it looks like nohup doesn't fare too well with eval. Any thoughts?


Solution

  • You could take a look at screen, an alternative for nohup with additional features. I will replace your testscript with while [ 1 ]; do printf "."; sleep 5; done for testing the screen solution.
    The commands screen -ls are optional, just showing what is going on.

    prompt> screen -ls
    No Sockets found in /var/run/uscreens/S-notroot.
    prompt> screen
    prompt> screen -ls
    prompt> while [ 1 ]; do printf "."; sleep 5; done
    # You don't get a prompt. Use "CTRL-a d" to detach from your current screen
    prompt> screen -ls
    # do some work
    # connect to screen with batch running
    prompt> screen -r
    # Press ^C to terminate the batch (script printing dots)
    prompt> screen -ls
    prompt> exit
    prompt> screen -ls
    

    Google for screenrc to see how you can customize the interface.

    You can change your script into something like

    #!/usr/bin/env bash
    # Assembling a list of commands to be executed sequentially
    for i in ../testSet/*; do
    do 
      echo "Running test problem ${i##*/}"
      mySequentialCommand $i > results/${i##*/} 2> /dev/null 
    done
    

    Above script can be started with nohup scriptname & when you do not use screen or simple scriptname inside the screen.