4

I have created a bash script to record sound input via the line in/mic port of the sound card and when sound is detected via breaking silence it records to a temp file, then date-stamps it in a new file and adds it to a database.

What i need to achieve is a good way of making the script start at boot, keep running the script over and over, and restart if it failed to restart itself. Below is the code i have currently put together from various sources and it works well so far. But i need it to be able to run 24/7 without any user interaction.

This is my first real bash script that i have created so would like a more experienced input to the method i have used and if it is wrong or right.

I did try to daemonize via the start-stop-daemon but ended up with multiple running scripts and sox commands. Currently i have it to execute at boot in rc.local, personally i don't think it is the correct way to restart the script by adding the command for it again at the bottom of the script... but i don't know of any other way.

Any sort of help is greatly appreciated.

#!/bin/bash

#Remove temp file just incase
rm -rf temp.mp3

#Listen for audio and record
sox -d /home/user/temp.mp3 silence 1 5 8% 1 0:00:01 8%

#Check if temp.mp3 is greater than 800 bytes so we don't get blank recordings added to the
#database, if the file is below 800 bytes remove the file and restart.
for i in /home/user/temp.mp3 ; do
   b=`stat -c %s "$i"`
if [ $b -ge 800 ] ; then

NAME=`date +%Y-%m-%d_%H-%M-%S`
TIME=`date +%H:%M:%S`
FILENAME=/var/www/Recordings/$NAME.mp3
FILEWWW=Recordings/$NAME.mp3
mv /home/user/temp.mp3 $FILENAME
rm -rf temp.mp3

mysql --host=localhost --user=root --password=pass database << EOF
insert into recordings (id,time,filename,active,status) values('NULL','$TIME','$FILEWWW','1','1');
EOF


else
rm -rf /home/user/temp.mp3
echo 'No sound detected, Restarting...'
fi
done

/home/user/vox
exit 0
user3323052
  • 90
  • 1
  • 6

3 Answers3

1

To restart script you can call it by crontab Crontab Howto

Mr.Sem
  • 30
  • 4
  • Yeah, i already knew about crontab, i've used that quite a lot before. But you can only check every minute right? I'm thinking that with bash theres surely a way to keep the script going on it's own without re calling itself every time it finishes. – user3323052 Feb 19 '14 at 09:05
  • yes, you can shedule with crontab when you want start (minutes, hours, days, weeks, etc etc). if you want to restart your script when the script have finished you can create a function in script and then call this function when the execution are finished like a loop. – Mr.Sem Feb 19 '14 at 14:16
  • The function method and calling itself has worked to create the loop. Now when it's daemonized it only has once instance of the script running. I've also tested killing sox whilst it's listening and it re loops and starts it again. Which is perfect. I will use cron to check if the script is running and set the cron to log if it was running or not to see how it performs. Hopefully the way that the script is wrote is correct. Thanks for the help! – user3323052 Feb 19 '14 at 17:16
1

Did you try Daemonizing your script? Different Operating System have their own documentation of how to daemonize a script and add it to the system startup. Looking at your question, I believe this is what you have to do. But be careful of using system resources and include proper sleep times as to minimize the use of system resources.

Else Also adding a cron job is suggested as that would not be running all the time in the background.

Gurubaran
  • 718
  • 8
  • 13
  • Yes, i did daemonize the script but end up with many processes of the same script running ie 'root 2693 0.0 0.2 2740 1160 ? S 08:53 0:00 /bin/bash /home/user/vox root 2913 0.2 0.2 2732 1112 ? S 08:57 0:00 /bin/bash /home/user/vox' – user3323052 Feb 19 '14 at 08:58
  • Does your script fork off a new process? Also, your script must end with a proper return value ( i.e echo $? should give you a 0 for successful completion) when run as a normal shell script. – Gurubaran Feb 19 '14 at 19:08
  • your code looks fine to me though it is hard to read without proper indentation :p... – Gurubaran Feb 27 '14 at 03:11
0

@Gurubaran Here is the new code, it used to fork off a new process but now i use the loop via a function calling itself so it doesn't fork, although the sox command is a separate fork, it's necessary and i make sure i kill sox just incase. Does this all look ok? it seems to work very well. I need to test it properly when i receive the cable to test with what it's used for instead of my phone. The script is also daemonized via start-stop-daemon

#!/bin/bash

pkill sox
function vox() {
rm -rf /home/user/temp.mp3
sox -d /home/user/temp.mp3 silence 1 5 4% 1 0:00:01 4%
wait

for i in /home/user/temp.mp3 ; do
   b=`stat -c %s "$i"`
if [ $b -ge 800 ] ; then

NAME=`date +%Y-%m-%d_%H-%M-%S`
TIME=`date +%H:%M:%S`
FILENAME=/var/www/Recordings/$NAME.mp3
FILEWWW=Recordings/$NAME.mp3
mv /home/user/temp.mp3 $FILENAME
rm -rf /home/user/temp.mp3

mysql --host=localhost --user=root --password=pass database << EOF
insert into recordings (id,time,filename,active,status) values('NULL','$TIME','$FILEWWW','1','1');
EOF

else
rm -rf /home/user/temp.mp3
fi
done
vox 
}
vox 
user3323052
  • 90
  • 1
  • 6