8

Effectively what I'm trying to accomplish is the following, where cmd1 takes a while to run (~1 minute) and cmd2 returns almost instantly whenever run:

  1. cmd1 starts
  2. wait a little while (~10 seconds)
  3. cmd2 runs
  4. wait a little while again
  5. cmd2 runs again
  6. some time passes
  7. cmd1 finishes

It is essential this be scripted since it has got to go inside a rather large loop, which runs cmd1 with many different parameters, and then does the same all over again for several other longish-running commands.

How can I accomplish this?

Mala
  • 7,288
  • 11
  • 35
  • 38

1 Answers1

14
cmd1 &
cmd1_pid=$!
sleep 10
cmd2
sleep 10
cmd2
wait $cmd1_pid

explanation: cmd1 & launches a process in the background of the shell. the $! variable contains the pid of that background process. the shell keeps processing the other cmds. sleep 10 means 'wait a little while'. OP just wants to fire cmd2 in linear order so that part is trivial. at the end of the script snippet we just wait for cmd1 to finish (it might be even finished earlier) with wait $cmd1_pid.

akira
  • 61,009
  • 17
  • 135
  • 165
  • thanks! I don't think this exactly solves the use case i have above, but I expect I can modify it slightly so as to do what i need :) – Mala Aug 03 '11 at 06:00
  • oh sorry I didn't mean to imply that any part of it was still opaque to me, just that this doesn't (unless I misunderstand your answer?) exactly follow the steps I posted above - i'm marking this accepted as soon as SU lets me – Mala Aug 03 '11 at 06:06
  • i changed the solution to mimic directly your 7 steps – akira Aug 03 '11 at 06:06
  • awesome - i thought that was what was different :) Thanks for teaching me about the pid/wait stuff! I'm sure that'll come in handy a lot in the future as well – Mala Aug 03 '11 at 06:09
  • it was different a little bit :) in the first draft i ran `cmd1` and `cmd2` both in background. but your first statement already showed that you grabbed the concept the first time already, nevertheless i wanted to answer the original problem as good as possible. so .. :) – akira Aug 03 '11 at 06:12
  • @akira You wrote 'wait' in the code snippet, and then 'waitpid' in the text - I'm assuming it should be the same (which one?) in both places? – David Doria Dec 18 '13 at 18:46
  • @DavidDoria: fixed. – akira Dec 19 '13 at 09:21
  • You don't need to store the PID. Just use `wait` to wait for all background jobs to finish or in the rare case you need to wait for just one specific background job, use `wait %1` (1 being the job id in this example). For more advanced scripts, use `coproc MYCMD { cmd1; }`, then `wait $MYCMD_PID`. – Stefan Seidel Dec 19 '13 at 10:01
  • @StefanSeidel: "7. cmd1 finishes.", that's why i `wait` for it. `coproc` is a 4er-bashism, might not be available in other shells. using `%1` instead of storing the pid sucks in terms of "start a new command here and there and start counting started processes". – akira Dec 19 '13 at 16:22