Stopping a script process with a Control + C or something
Solution 1
Your pipeline
ps -aux | grep sox | kill 0
will not do what you want to do. This is because kill
won't ever read the input from grep
(the result from grep
will also contain a lot of other things than just the PID of the sox
process).
If you have pkill
, just do
pkill sox
instead (use pkill -INT sox
to send the same signal as Ctrl+C does).
If you change your startup script to
#!/bin/bash
NOW=$( date '+%F_%H:%M:%S' )
filename="/home/pi/gets/$NOW.wav"
sox -t alsa plughw:1 "$NOW.wav" & sox_pid="$!"
printf 'sox pid is %d\n' "$sox_pid"
wait
# Alternatively (instead of "wait", if you want to kill sox after six seconds):
# sleep 6 && kill "$sox_pid"
echo "$filename"
You will get the PID of the sox
process printed to the terminal and you could use that to do kill pid
(with pid
replaced by that number).
Using &
ofte the sox
invocation places it in the background. The PID of that background task is automatically stored in $!
and the code above assigns it to sox_pid
which is later printed.
The wait
command waits for the sox
command (running in the background) to finish.
As we discussed in a previous session: Double-quote all variable expansions.
Solution 2
use trapping:
#!/bin/bash
# this is a trap for ctrl + c
trap ctrl_c INT
function ctrl_c()
{
echo "Trap: CTRL+C received, exit"
exit
}
Related videos on Youtube
Reckless Liberty
Updated on September 18, 2022Comments
-
Reckless Liberty over 1 year
I am trying to make an AV bug raspberry pi for a class.
I am using sox to record sound. Which is working fine.
the issue is sox needs to be stopped by a control+C to stop and create the new file. If killall is sent from a different ssh session it will drop the other session and sox will not create the file.
listen.sh
#! /bin/bash NOW=$( date '+%F_%H:%M:%S' ) filename="/home/pi/gets/$NOW.wav" sox -t alsa plughw:1 $NOW.wav; sleep 6; echo $filename
I have tried making a separate script for stopping it; pretty much
killlisten.sh
#! /bin/bash sleep 5; ps | grep sox | kill 0;
Then run a
superscript.sh
#! /bin/bash ./listen.sh; ./killlisten.sh;
Any advice on how to stop sox in a way that would still produce an output file would be great. This will ideally be set to run at set times so avoiding human interaction is essential.
-
Reckless Liberty over 6 yearsAwesome, thank you for the great explanation as well as the solution!
-
Reckless Liberty over 6 yearsfor: printf 'sox pid is %d\n' "$sox_pid" Did you %d to ensure that the PID was inputted as an integer? Why not use %s? Just trying to learn, thank you.
-
Reckless Liberty over 6 yearsError IDing, nice. The & after the sox is so BASH will create the $sox_pid? and printf? so sox needs to be in the bg for the rest of the script to work?
-
Kusalananda over 6 years@RecklessLiberty The
&
starts the given command as a background task, which gives control back to the script immediately. The PID of the command is then available in$!
. Theprintf
is solely for the user, in case they would want to kill the job manually withkill
so that they know what PID to kill (it's not strictly needed). -
Reckless Liberty over 4 yearsI didn't even know i could nest commands in a variable's parameters. Very cool.