Search code examples
bashprocesssignals

How can kill all the processes triggered by hotkey with some smart way?


I want to kill a process and its son process with trap command:

vim   waiting.sh 
trap "kill $$" EXIT
sleep 10000

Now run it in background:

debian@debian:~$  bash   waiting.sh  &
[1] 29590

Have a look at all processes

debian@debian:~$  ps aux | grep '[w]aiting.sh'
debian     29590  0.0  0.0  14556  3164 pts/1    S    16:16   0:00 bash waiting.sh
debian@debian:~$  ps aux | grep '[s]leep'
debian     29591  0.0  0.0  13104   508 pts/1    S    16:16   0:00 sleep 10000

Press ctrl+c to trigger the trap:

debian@debian:~$  ^C
debian@debian:~$  ps aux | grep '[w]aiting.sh'
debian     29590  0.0  0.0  14556  3164 pts/1    S    16:16   0:00 bash waiting.sh
debian@debian:~$  ps aux | grep '[s]leep'
debian     29591  0.0  0.0  13104   508 pts/1    S    16:16   0:00 sleep 10000   

How can kill all the processes with trap?
To make my request more concrete,show my os and desktop environment.

debian@debian:~$  uname -a
Linux debian 5.10.0-11-amd64 #1 SMP Debian 5.10.92-2 (2022-02-28) x86_64 GNU/Linux
debian@debian:~$  dpkg -l lxde
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=================================
ii  lxde           11           all          metapackage for LXDE
debian@debian:~$  dpkg -l openbox
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version         Architecture Description
+++-==============-===============-============-===============================>
ii  openbox        3.6.1-9+deb11u1 amd64        standards-compliant, fast, ligh

I bind hotkey with voice capture,whenever listen to the music playing on my favorite website,click ctrl+shift+r,the bash script /usr/hotkey/ch.sh called ,ffmpeg running on the background,music captured,i want to finish the music capture when to click ctrl+c,my script failed.

  vim  $HOME/.config/openbox/lxde-rc.xml
  <!-- Keybindings for recording voice playing on sound card-->
    <keybind key="C-S-r">
      <action name="Execute">
      <command>bash /usr/hotkey/cr.sh</command>
      </action>
    </keybind>

  cat  /usr/hotkey/cr.sh
  pid=$$
  trap  " pkill -P $pid;kill $pid " SIGINT
  if [[ -f "/tmp/out.mkv" ]];then  rm -f "/tmp/out.mkv";fi
  voice='alsa_output.pci-0000_09_00.6.analog-stereo.monitor'
  ffmpeg -f pulse -i $voice /tmp/out.mkv

I have tried many kinds of trap format, never done.In order to kill ffmpeg,open a terminal and issue commands:

ps aux |grep [f]fmpeg #get ffmpeg's pid
kill pid_number       #close the process

So i want to improve the code,to kill the process triggered by ctrl+shift+r with more samrt way.


Solution

  • From the extended context you provided the first thing that comes to my mind is using a PID-file and a companion command.

    Something like this:

    # cr.sh
    ffmpeg ... &
    # note down pid
    echo $! >/tmp/cr.pid
    
    # cr-stop.sh
    kill $(cat /tmp/cr.pid)
    

    then you should be able to use cr-stop.sh to stop ffmpeg.