Wait command doesn't work as expected with init script and pidfile

I'm trying to create an init script that can shut down a VM and waits for the shutdown to complete, before shutting down OpenWrt. I found out that the wait command doesn't work as expected when using it in an init script.

This script works as expected:



sleep 5s &
echo $! > $sleep_pidfile

echo "PID is: $(cat $sleep_pidfile)"
wait $(cat $sleep_pidfile)

echo "wait exited with code: $?"
rm $sleep_pidfile

It waits 5 seconds and the exit code is 0:

# ./pidfiletest.sh 
PID is: 5942
wait exited with code: 0

With an init script the same thing doesn't work, the script exits immediately and wait exits with 127:

#!/bin/sh /etc/rc.common



start() {
sleep 300 &

echo $! > $sleep_pidfile
echo "sleep PID is: $(cat $sleep_pidfile)"

stop() {
echo "Executing insomnia.sh in background"
/root/insomnia.sh &

echo "waiting for process with PID: $(cat $sleep_pidfile)"
wait $(cat $sleep_pidfile)
echo "wait exit code: $?"
rm $sleep_pidfile
# /etc/init.d/rc_pidtest start
sleep PID is: 6018
# /etc/init.d/rc_pidtest stop
waiting for process with PID: 6018
wait exit code: 127

Also running wait manually with the PID doesn't work:

# wait 6018
# echo $?

Does anybody know what's causing this?

Just ran a quick check, as wait is a shell built-in and who knows just what busybox implements. It seems to be working on a recent openwrt-18.06 build (I don't recall any changes to busybox config related to wait)

jeff@office:~$ sh -c 'sleep 20' & 
jeff@office:~$ ps
  PID TTY          TIME CMD
 5566 pts/0    00:00:00 ash
 5583 pts/0    00:00:00 sleep
 5584 pts/0    00:00:00 ps
jeff@office:~$ wait 5583 && echo $?
[1]+  Done                       sh -c "sleep 20"

Maybe try running your script with -x to get some insight?

I forgot to mention, I'm on branch openwrt-18.06 as well, busybox is v1.28.3.
On my machine, your test works as expected, too. My first thought was, that the pidfile handling in my init script was wrong, so I wrote the simpler script (the first example). The weird thing is that they do more or less the same. The simple script works, the init script doesn't.

# ps
 7127 root      3084 S    sleep 300
# sh -x /etc/rc.common /etc/init.d/rc_pidtest stop
+ . /lib/functions.sh
+ N='
+ _C=0
+ LIST_SEP=' '
+ reset_cb
+ '[' -z  -a -f /lib/config/uci.sh ]
+ . /lib/config/uci.sh
+ . /lib/functions/service.sh
+ initscript=/etc/init.d/rc_pidtest
+ action=stop
+ shift 2
+ . /etc/init.d/rc_pidtest
+ START=99
+ STOP=1
+ sleep_pidfile=/var/run/sleep.pid
+ '[' -n  ]
+ ALL_COMMANDS='start stop reload restart boot shutdown enable disable enabled depends '
+ list_contains ALL_COMMANDS stop
+ local 'var=ALL_COMMANDS'
+ local 'str=stop'
+ local val
+ eval 'val=" ${ALL_COMMANDS} "'
+ val=' start stop reload restart boot shutdown enable disable enabled depends  '
+ '[' ' start' '!=' ' start stop reload restart boot shutdown enable disable enabled depends  ' ]
+ stop
+ cat /var/run/sleep.pid
+ echo 'waiting for process with PID: 7127'
waiting for process with PID: 7127
+ cat /var/run/sleep.pid
+ wait 7127
+ echo 'wait exit code: 127'
wait exit code: 127
+ rm /var/run/sleep.pid

So the script correctly executes wait 7127. As I wrote before: running wait 7127 manually doesn't work either.

Maybe I'll try to install bash and see if the same happens there.

Behavior on bash stays the same, but the error message is more helpful:

# wait 8202
bash: wait: pid 8202 is not a child of this shell

So I found the cause of this error - I guess I have to find another solution instead of wait
But thanks for your response!

This stackoverflow has some solutions for this problem. I went with

while [ -e /proc/$(cat $sleep_pidfile) ]; do sleep 1s; done

which works

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.