Jamie
Jamie

Reputation: 7431

How to get the PID of a piped command in a BASH 2.05 script?

I'm trying to get the PID of a piped data collection command in a BASH script so that I can kill the process once another (foreground) process has completed. I've got a timeout on the data collection command, but I don't know beforehand how long it should be; anywhere from a few minutes to several hours.

This question How to get the PID of a process in a pipeline was informative, but it didn't pan out. Probably because I'm using BASH 2.05 (on an embedded system).

Initial testing on the command line for the jobs -p command looked promising. In practice, I replace ksmon command below with a piped command (ksmon | {various filters} | gzip -c > file) so the "$!" BASH variable gives the last process in the pipe, not the ksmon program I'm trying to kill:

Test:/ $  ksmon > /dev/null & jobs -p
[1] 2016
2016
Test:/ $  ps | grep ksmon
 2016 root        660 S   ksmon
 2018 root        580 S   grep ksmon
Test:/ $  kill $(jobs -p)
[1]+  Terminated              ksmon >/dev/null
Test:/ $  ps | grep ksmon
 2021 root        580 S   grep ksmon
Test:/ $

Whoohoo! So I tried to put that in a script:

Test:/ $  cat > test.sh << EOF
> #!/bin/bash
> # That's bash 2.05
> ksmon > /dev/null & jobs -p
> EOF
Test:/ $  chmod 755 test.sh
Test:/ $  ./test.sh
Test:/ $
Test:/ $  # Nothing ...
Test:/ $  ps | grep ksmon
 2025 root        660 S   ksmon
 2027 root        580 S   grep ksmon
Test:/ $  jobs -p
Test:/ $

This is the version I'm trying to get it working with:

Test:/ $  bash --version
GNU bash, version 2.05.0(2)-release (arm-Artila-linux-gnu)
Copyright 2000 Free Software Foundation, Inc.

Oddly enough, the above script does works on an Ubuntu host.

What do I have to do to make jobs -p work in a BASH 2.05 script, or is there an alternative?

One thought was to just subtract a fixed number from the $! variable, but I'm not sure if that a good idea ...

EDIT: The reason I'd like to kill the first program in the pipe, is that all the programs that follow in the pipe, particularly gzip will do a nice job of closing their output streams.

Upvotes: 3

Views: 1088

Answers (1)

user1643723
user1643723

Reputation: 4222

I suggest you to use $! to get PID of the last process in the pipe; then use lsof to sequentially determine previous processes in chain by open file descriptors from /proc.

Upvotes: 2

Related Questions