1

Okay, so this might be a very silly question and I don't write shell scripts too often. I'm trying to start 3 processes in the background, one after the another within a shell script, for example:

#!/bin/sh
PROCESS1 &
PROCESS2 &
PROCESS3 &

Here is the problem. I need to start these processes in the same order as shown. Also, the PID of the PROCESS2 needs to be passed as the command line argument to the PROCESS3. All of these processes run in the infinite loop and they do work smoothly when ran in 3 separate terminals.

I tried:

#!/bin/sh
PROCESS1 &
PROCESS2 &
PID_PROCESS2=$!
PROCESS3 ${PID_PROCESS2} &

This starts the PROCESS1 and PROCESS3 but the PROCESS2 exits immediately without printing any error. It just vanishes. The ps command it shows no traces of PROCESS2. Printing the PID_PROCESS2 gives some value 'p' and the PROCESS3 runs just fine with the value 'p' as its argument. What's the problem and where am I lacking?

PROBABLY IMPORTANT DETAILS

1) In the above example, I'm using the qualified paths to invoke the respective processes and all of them are native binaries and are in the same directory. For example,

#!/bin/sh
/usr/bin/PROCESS1 &

The output of ps is as described above,

$ps | grep "/path/to/PROCESS"
10064 root 16536 S /path/to/PROCESS1
10066 root 11084 S /path/to/PROCESS3 10065

which clearly tells the PROCESS2 started but exited for some unknown reason.

2) PROCESS2 communicates with PROCESS1 via a FIFO(named pipe) and it's a one-way communication.

WORKAROUND

#/bin/sh
/path/to/PROCESS1 &
/path/to/PROCESS2 & PROCESS2_PID=$!
export P2PID=${PROCESS2_PID}
sh -c "/path/to/PROCESS3 ${P2PID}"

This seems to do the job with one extra process for sh.

$ps | grep "/path/to/PROCESS"
10174 root 16536 R /path/to/PROCESS1
10175 root 71720 S /path/to/PROCESS2
10177 root 27772 S sh -c /path/to/PROCESS3 10175
10076 root 11084 S /path/to/PROCESS3 100175

But I still don't have any idea why this works. Can someone suggest what sort of "magic" happened in this case?

  • You say that all three run smoothly if run in different terminals. Do any of them do console I/O? – Andy Dalton Aug 12 '18 at 22:59
  • No console IO except for the command line arguments for the PROCESS3 i.e. the PID of PROCESS2. I find it first using ps | grep PROCESS2 and then pass it over to PROCESS2. – Prateek Gupta Aug 13 '18 at 4:42
1

Based on what you're describing it sounds like there's something fundamentally wrong with PROCESS2 that's causing it to exit. If I model what you're describing with 3 processes, it mostly works as one would expect when you background the 3 processes and then capture and pass the 2nd process's PID to process 3.

Example

example script
$ cat runny.bash
#!/bin/bash

proc3func() {
  echo $1
  sleep 7 &
}

sleep 9 &
sleep 8 &
PID2=$!
proc3func ${PID2} &
example run
$ ./runny.bash ; sleep 2; ps -eaf
4279
UID        PID  PPID  C STIME TTY          TIME CMD
...
vagrant   4278     1  0 20:21 pts/1    00:00:00 sleep 9
vagrant   4279     1  0 20:21 pts/1    00:00:00 sleep 8
vagrant   4282     1  0 20:21 pts/1    00:00:00 sleep 7

In the above output we can see the PID, 4279 being echoed to the screen followed by the output of ps -eaf which shows our 3 processes.

Debugging

I'd suggest enabling set -x so that you can follow what commands are executing as you run your script or running it like this:

$ bash -x ./runny.bash
+ PID2=4612
+ sleep 9
+ sleep 8
+ proc3func 4612
+ echo 4612
4612
+ sleep 7
  • I'm still unable to figure out what's wrong with the PROCESS2. I gave up and am now using fork() and execvp() to invoke all these processes in a chain. But I surely did not know about the above debugging technique. Thanks for sharing that. – Prateek Gupta Aug 19 '18 at 21:44

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.