I use shell scripts to react to system events and update status displays in my window manager. For example, one script determines the current wifi status by listenining to multiple sources:
- associate/dissociate events from wpa_supplicant
- address changes from ip (so i know when dhcpcd has assigned an address)
- a timer process (so the signal strength updates from time to time)
To achieve the multiplexing, I end up spawning background processes:
{ wpa_cli -p /var/run/wpa_supplicant -i wlan0 -a echo &
ip monitor address &
while sleep 30; do echo; done } |
while read line; do update_wifi_status; done &
ie, the setup is that whenever any of the event sources output a line, my wifi status updates. The entire pipeline is run in the background (the final '&') because I also watch another event source that causes my script to terminate:
wait_for_termination
kill $!
The kill is supposed to clean up the background processes, but in this form it doesn't quite do the job. The 'wpa_cli' and 'ip' processes always survive, at least, and nor do they die on their next event (in theory they should get a SIGPIPE; I guess the reading process must still be alive too).
The question is, how to reliably [and elegantly!] clean up all the background processes spawned?