5

I have two programs in Linux (shell scripts, for example):

NeverEnding.sh
AllwaysEnds.sh

The first one does never stop, so I wanna run it in background.
The second one does stop with no problem.

I would like to make a Linux shell script that calls them both, but automatically stops (kill, for example) the first when the second will have finished.

Specific command-line tools allowed, if needed.

Sopalajo de Arrierez
  • 3,543
  • 4
  • 34
  • 52

1 Answers1

5

You can send the first into the background with & and get the PID of it by $!. Then after the second finishes in the foreground you can kill the first:

#!/bin/bash

NeverEnding.sh &
pid=$!

AllwaysEnds.sh

kill $pid

You don't actually need to save the pid in a variable, since $! only gets updated when you start a background process, it's just make it more easy to read.

fejese
  • 4,601
  • 4
  • 29
  • 36
  • It works fine, @fejese, thanks you. Should it be possible to pass a parameter to `AllwaysEnds.sh`? – Sopalajo de Arrierez Mar 31 '14 at 00:30
  • Sure, just add the parameter as you'd call it from the command line: `AllwaysEnds.sh --answer 42` – fejese Mar 31 '14 at 08:44
  • Sorry, @fejese, I was talking about adding parameters when calling the main scripts, the shell script that start both programs and close the first after finishing the second. `AllwaysEnd.sh` should receive this `--answer 42` parameter. – Sopalajo de Arrierez Mar 31 '14 at 14:24
  • 3
    @SopalajodeArrierez You can change this script with `AllwaysEnds.sh "$@"`. It will pass all the arguments of the main script to `AllwaysEnds.sh`. For details see [this guide](http://www.tldp.org/LDP/abs/html/internalvariables.html). BTW, it also explains `$!` and contains a couple of examples on job control. – Andrey Mar 31 '14 at 15:20
  • 1
    I almost second @Andrey's comment, except for the quotes around `$@`. But that depends on what you want to achieve. If you want all separate parameters passed as they are to `AllwaysEnds.sh` (btw it's always) then you don't need the quotes. You only need them if you want to pass all parameters that you gave to the wrapper script to `AllwaysEnds.sh` as the first and only parameter. – fejese Mar 31 '14 at 15:38
  • `$ ./test.sh --answer 42 : ($@ arg #1) --answer ($@ arg #2) 42 ("$@" arg #1) --answer ("$@" arg #2) 42`; `$ ./test.sh '--answer 42' : ($@ arg #1) --answer ($@ arg #2) 42 ("$@" arg #1) --answer 42 ("$@" arg #2)` – Andrey Mar 31 '14 at 16:02
  • 2
    @fejese: [`"$@"` has special meaning inside double-quotes](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02). It doesn't work as you think it does. See [Propagate all arguments in a bash shell script](http://stackoverflow.com/q/4824590/4279) – jfs Mar 31 '14 at 23:24
  • Thanks @J.F.Sebastian, that was useful and new. – fejese Apr 01 '14 at 08:43