Reputation: 7431
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
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