27

I'm looking for something like command1 ; command2 i.e. how to run command2 after command1 but I'd like to plan execution of command2 when command1 is already running.

It can be solved by just typing the command2 and confirming by Enter supposed that the command1 is not consuming standard input and that the command1 doesn't produce to much text on output making it impractical to type (typed characters are blended with the command1 output).

0

5 Answers 5

35

Generally what I do is: Ctrl+Z fg && command2

  1. Ctrl+Z to pause it and let you type more in the shell.
  2. Optionally bg, to resume command1 in the background while you type out command2.
  3. fg && command2 to resume command1 in the foreground and queue up command2 afterwards if command1 succeeds. You can of course substitute ; or || for the && if you so desire.
0
24
  1. start a command

    command1
    
  2. pause the execution by pressing Ctrl+Z

  3. find the job number of the paused command (it's usually already printed to console when to console when to command is paused) by executing

    jobs
    
  4. let command1 continue in background

    bg
    
  5. plan execution of command2 to await finish of command1

    wait -n <command1 job number> ; command2
    

Documentation Job Control Builtins

6
  • You can 'accept' your own answer (click the tick icon) into order to show other users that there is a good answer to your question.
    – sudodus
    Dec 14, 2018 at 11:52
  • 1
    @sudodus Own answer can be accepted at earliest 2 days after the question was asked. stackoverflow.blog/2009/01/06/accept-your-own-answers
    – czerny
    Dec 14, 2018 at 11:59
  • 7
    In simple cases I sometimes control-z then use fg ; command. Or even fg && command to only run the 2nd command / pipeline if the first one was successful. (You can still use bg while thinking / typing, if it doesn't spew text on the terminal.) Dec 14, 2018 at 13:32
  • 2
    I'm a bit confused as to what this approach offers beyond the typical command1; command2 syntax. Could you please clarify this for me?
    – Haxiel
    Dec 14, 2018 at 17:32
  • 1
    command1 & proceed_after=$! then when you've got the next command figured out wait -n $proceed_after; command 2
    – studog
    Dec 14, 2018 at 18:27
8

There are several alternatives.

  • With one ampersand, 'push to background', the second program starts after the first one starts, but they will probably run alongside each other.

    command1 & command2
    
  • With two ampersands, 'logical and', the second program will start only if the first program finished successfully.

    command1 && command2
    
  • With a semicolon separating the commands in the command line, the the second program will start, when the first program finished, even if it failed or was interrupted.

    command1 ; command2
    
  • You can use wait <PID> to wait for the first command to finish, if it is already running from the same shell (in the same terminal window).

  • Otherwise if the first command is already running from another shell (in another window), you can use a small while loop using ps to check if the PID is still found by ps. When it is no longer found, the second command will be started.

    This demo example for bash checks if top is running via the PID, and runs the command

    echo "*** $USER, I am ready now ***"
    

    if/when top is no longer running.

    pid=$(ps -A|grep top|cut -d ' ' -f 1); \
    while [ "$pid" != "" ]; do ps -A|grep "$pid" > /dev/null; \
    if [ $? -eq 0 ]; then sleep 5;else pid=""; fi; done; \
    echo "*** $USER, I am ready now ***"
    
0
0

The standard way is just to let command 1 start in the background and then have command 2 start either in the background or in the foreground. The full command is this:

command1 & command2

& is not a connector between these two commands. It can be used with command1 alone to have it started in the background:

command1 &

And this is right syntax for starting both commands in the background:

command1 & command2 &
4
  • Thank you for your answer. I don't mind if commands are running in background or foreground. I'd like to run them serially (one starts when the previous one ends) and I'd like to plan the execution of the second one when the first one is already running.
    – czerny
    Dec 14, 2018 at 11:22
  • @czerny So you want the second one to start while the first one is still running, when it's already finished, or?
    – user147505
    Dec 14, 2018 at 11:25
  • I'd like the second command to be started when the first command finishes
    – czerny
    Dec 14, 2018 at 11:53
  • 1
    @czerny Then just use ;. Or do you want to do something while the first one is still running?
    – user147505
    Dec 14, 2018 at 12:54
-3

If you have a choice to use two terminals, here's what you can do:

  • Assuming you are already running command1 in a terminal (let's call it terminal1)
  • Start a new terminal (let's call it terminal2)
  • Find process ID of command1 (let's call it command1_pid). In terminal2, run command ps -ef | grep <command1> (you might want to properly form the filter string in grep command so that you do not accidently find another process having as a substring).
  • Run command wait <command1_pid> ; command2

Basically, wait is a bash built-in command that waits until the provided PIDs exit and then return. You are simply delegating your waiting for command1 to finish, on to bash's wait command.

2
  • 2
    It doesn't seem to work for me. Running wait in different terminal outputs following error message: bash: wait: pid 19531 is not a child of this shell.
    – czerny
    Dec 14, 2018 at 11:48
  • 1
    @czerny That's normal, I don't think this answer was tested. POSIX wait system calls only work on child processes, so one bash process can't wait for the children of a different instance of bash. man7.org/linux/man-pages/man2/wait.2.html#ERRORS says wait and waitpid return with ECHILD error status in this case. Dec 14, 2018 at 13:38

Not the answer you're looking for? Browse other questions tagged .