In my script, I have the following:
cat list | xargs -P6 -n2 ./first_queue &
where list
is just a file with pairs of words that I want to process:
word1 word2
word3 word4
etc...
first_queue
is just another script. I am trying to get the pid of all 6 processes that are spawned by this xargs right after I call it so that I can later terminate them. I read that $!
gives the pid of the last process that ran in the background. However, I want all 6 of them. How can I get them?
More details:
I wrote the following small script to test what @xenoid suggested:
cat list | xargs -P6 -n2 ./first_queue &
id=$(echo $!)
echo $id
ids=$(pgrep -P $id)
echo $ids
ps aux | grep $id
for x in $ids; do
echo $x
ps aux | grep $x
kill $x
done
kill $id
ps aux | grep $id
for x in $ids; do
ps aux | grep $x
done
Here is first_queue
extremely simplified (to the command that is giving me the trouble, and that keeps running despite running kill
on the parent process i.e xargs as well as the child processes):
srr=$1
bioproject=$2
prefetch $srr -O download_dir/$bioproject
prefetch
just downloads data from an online database.
The PID you get with
$!
isxargs
's own PID (because this isxargs
that you are sending to the background...), not the one of your processes. If you terminate it it will terminate all its children (i.e., any of your processes still running).If you want the pids of the child processes you can use
pgrep -P {parent}
where{parent}
isxargs
PID.Edit:
When you run a command (pid=Y) in a script (pid=X), and send a signal to the script (to pid=X), the signal is not forwarded to the command (so pid=Y doesn't see it).
You can write a contrived script that starts the command in the background, grabs its pid (Y), traps signals send to pid=X and forwards them to pid=Y.
But in many cases, the command is the last significant bit of code to run (the script exits with the command's return code). When this is so instead of using:
you write your script as:
In the first case the script is the process with pid=X and the command is the process with pid=Y. With
exec
, process with pid=X becomes the command, and everything happens as if you calledthe_command
directly: there is no pid=Y, and signals sent to process X (the script) are received by thethe_command
when it runs.