Note:
wait $subshell
won't work as $subshell
is not a child of the process you're running wait
in. Anyway, you'd not waiting for the process doing the wait
so it doesn't matter much.
kill $subshell
is going to kill the subshell but not sleep
if the subshell had managed to start it by the time kill
was run. You could however run sleep
in the same process with exec
- you can use SIGPIPE instead of SIGTERM to avoid the message
- leaving a variable unquoted in list contexts has a very special meaning in
bash
.
So having said all that, you can do:
(
subshell=$BASHPID
kill -s PIPE "$subshell" &
sleep 600
)
echo subshell done
(replace sleep 60
with exec sleep 60
if you want the kill
to kill sleep
and not just the subshell, which in this case might not even have time to run sleep
by the time you kill it).
In any case, I'm not sure what you want to achieve with that.
sleep 600 &
would be a more reliable way to start sleep
in background if that's what you wanted to do (or (sleep 600 &)
if you wanted to hide that sleep
process from the main shell)
Now with your actual
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
command, note that sudo
does spawn a child process to run the command (if only because it may need to log its status or perform some PAM session tasks afterwards). stdbuf
will however execute wpa_supplicant
in the same process, so in the end you'll have three processes (in addition to the rest of the script) in wpa_supplicant
's ancestry:
- the subshell
- sudo as a child of 1
- wpa_supplicant (which was earlier running stdbuf) as a child of 2
If you kill 1, that doesn't automatically kills 2. If you kill 2 however, unless it's with a signal like SIGKILL that can't be intercepted, that will kill 3 as sudo
happens to forward the signals it receives to the command it runs.
In any case, that's not the subshell you'd want to kill here, it's 3 or at least 2.
Now, if it's running as root
and the rest of the script is not, you won't be able to kill it so easily.
You'd need the kill
to be done as root
, so you'd need:
sudo WIFI="$wifi" bash -c '
(echo "$BASHPID" &&
exec stdbuf -o0 wpa_supplicant -Dwext -i"$WIFI" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1
) | {
read pid &&
grep -m1 "pre-shared key may be incorrect" &&
kill -s PIPE "$pid"
}'
That way, wpa_supplicant
will be running in the same $BASHPID
process as the subshell as we're making of that with exec
.
We get the pid through the pipe and run kill
as root.
Note that if you're ready to wait a little longer,
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 |
grep -m1 "pre-shared key may be incorrect"
Would have wpa_supplicant
killed automatically with a SIGPIPE (by the system, so no permission issue) the next time it writes something to that pipe after grep
is gone.
Some shell implementations would not wait for sudo
after grep
has returned (leaving it running in background until it gets SIGPIPEd), and with bash
, you can also do that using the grep ... <(sudo ...)
syntax, where bash
doesn't wait for sudo
either after grep
has returned.
More at Grep slow to exit after finding match?
echo
still run if the parent script is killed? – Philip Kirkbride Nov 24 '17 at 01:02echo
is – Nov 24 '17 at 02:54