Reputation: 71
Is there a way to wait until a process finishes if I'm not the one who started it?
e.g. if I ran "ps -ef" and pick any PID (assuming I have rights to access process information) - is there a way I can wait until the PID completes and get its exit code?
Upvotes: 7
Views: 2716
Reputation: 41
If you can live without the exit code:
tail --pid=$pid -f /dev/null
Upvotes: 4
Reputation: 732
You could use strace
, which tracks signals and system calls. The following command waits until a program is done, then prints its exit code:
$ strace -e none -e exit_group -p $PID # process calls exit(1)
Process 23541 attached - interrupt to quit
exit_group(1) = ?
Process 23541 detached
$ strace -e none -e exit_group -p $PID # ^C at the keyboard
Process 22979 attached - interrupt to quit
--- SIGINT (Interrupt) @ 0 (0) ---
Process 22979 detached
$ strace -e none -e exit_group -p $PID # kill -9 $PID
Process 22983 attached - interrupt to quit
+++ killed by SIGKILL +++
Signals from ^Z
, fg
and kill -USR1
get printed too. Either way, you'll need to use sed
if you want to use the exit code in a shell script.
If that's too much shell code, you can use a program I hacked together in C a while back. It uses ptrace()
to catch signals and exit codes of pids. (It has rough edges and may not work in all situations.)
I hope that helps!
Upvotes: 8
Reputation: 213386
is there a way I can wait until the PID completes and get its exit code
Yes, if the process is not being ptrace
d by somebody else, you can PTRACE_ATTACH
to it, and get notified about various events (e.g. signals received), and about its exit.
Beware, this is quite complicated to handle properly.
Upvotes: 4
Reputation: 22482
If you know the process ID you can make use of the wait
command which is a bash builtin:
wait PID
You can get the PID of the last command run in bash using $!
. Or, you can grep for it with from the output of ps
.
In fact, the wait command is a useful way to run parralel command in bash. Here's an example:
# Start the processes in parallel...
./script1.sh 1>/dev/null 2>&1 &
pid1=$!
./script2.sh 1>/dev/null 2>&1 &
pid2=$!
./script3.sh 1>/dev/null 2>&1 &
pid3=$!
./script4.sh 1>/dev/null 2>&1 &
pid4=$!
# Wait for processes to finish...
echo -ne "Commands sent... "
wait $pid1
err1=$?
wait $pid2
err2=$?
wait $pid3
err3=$?
wait $pid4
err4=$?
# Do something useful with the return codes...
if [ $err1 -eq 0 -a $err2 -eq 0 -a $err3 -eq 0 -a $err4 -eq 0 ]
then
echo "pass"
else
echo "fail"
fi
Upvotes: -1