1

I want to launch 2 processes in the background, but I need the 2nd one to wait for the 1st to finish. Both are going to be very lengthy, so I also need to be able to log out from the terminal.

At the moment I have this:

 nohup ./script1.sh $arg1 &    
 wait
 nohup ./script1.sh $arg2 &

The problem here is that I cannot use my terminal or log out while waiting. I also tried to capture command' 1 PID and feed it to wait but the problem persists.

In summary, I want to launch the main script calling script1 and script2, close my terminal and open it 5 days later. In this time I need script1 to run first, and only after it finishes script2 can start running.

  • Site node: If you want to run programs and then close your terminal and log out but you later want to see (and possibly control with Ctrl-C or Ctrl-Z) the running program in a terminal again you can have a look at screen and tmux. – Lucas Apr 17 '16 at 9:43
  • Any reason not to start screen or tmux and run the scripts from there as script1.sh $arg1; script1.sh $args2 ? – Anthon Apr 17 '16 at 10:55
4

Basic concepts ...

To run two scripts after each other you place a semi colon between them: script1 args ...; script2 args ... or in a script you can also put them on two lines like this:

#!/bin/sh
script1 args ...
script2 args ...

This also works if you want to run them in the background. You just put them in a subshell and put the subshell in the background: (script1 args ...; script2 args ...) & or:

#!/bin/sh
(
  script1 args ...
  script2 args ...
) &

If you want to run the second script only if the first script did exit successful (with code 0) you can replace the semi colon with &&: script1 args ... && script2 args ...

... with nohup

But nohup wants to run one command and a subshell is not a single command, it is a shell construct that only works in the shell. But we can start a new shell that executes the two scripts, pass that as one command to nohup and put all this together in the background:

#!/bin/sh
nohup sh -c 'script1 args ...; script2 args ...' &

If you have variables in args ... you will have to use double quotes and you have to take special care to escape them correctly so here is another way:

... with double fork

The shell only knows and cares about it's direct children. You are warned if there are still processes running in the background when you try to exit, and these direct children are killed if you really exit the shell. The solution is to put a subshell in the background that itself puts your command in the background. Your shell will only know about the subshell and not about the command. But you can not rely on the redirection magic of nohub like this and have to set up your own redirection:

#!/bin/sh
(
  # outer subshell, will be known to your shell
  (
    # inner subshell, "hidden" from your interactive shell
    script1 "$args" ... > ~/script1.stdout.log 2> ~/script1.stderr.log
    script2 "$args" ... > ~/script2.stdout.log 2> ~/script2.stderr.log
    # note that you can do normal quoting here
  ) &
) &
  • Should i make any modifications to run it in a bash script? I know sh is kind of a superset for bash but just to be sure... – pilu Apr 17 '16 at 9:32
  • It's the other way round: bash is a superset of sh or sh is the subset of bash. So no modifications needed. – Lucas Apr 17 '16 at 9:33
  • 1
    Unfortunately argument passing is problematic. Both commands are failing to read their arguments. My final syntax is this: nohup sh -c './submitAll.sh args $NEW_DB $OLD_FASTA_DIR $NEW_ORGS $VO $isBBH "expandedTimestamp.out"; ./submitAll.sh args $FULL_DB $NEW_FASTA_DIR $FULL_ORGS $VO $isBBH "expandedTimestamp.out"' & – pilu Apr 17 '16 at 9:46
  • If you have variables you need to expand in the arguments you need to use double quotes instead of single quotes. But is these variables can contain special characters (space, quotes, semicolon, and, pipe, ...) you have to take special care and you are heading for quoteing and escaping hell ... :(. By the way is args a neccessary argument for you script or did you copy it from me? I just put args there as an example. – Lucas Apr 17 '16 at 9:50
  • oh yea i forgot about expansion. I tried both with and without args just to be sure. The whole thing seems to be working with the double quotes, thanks a ton and sorry for my newbie questions :) – pilu Apr 17 '16 at 9:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.