Reputation: 13
I am a pipefitter working in a weld shop and need music as commercial radio is very repetitive. I went and bought a RPI3 and put Raspian Stretch Lite on it with the fm_transmitter program. I got the shell script far along enough that the radio works fine but sometimes I'll get a song to play again within a short time. This is just by chance as the RANDOM_FILE variable chooses from an entire directory. I have also gotten the script to log each song that is played in a text file. I would like to use tail and grep to search the text file for the current selected RANDOM_FILE and check if it is present within the last X number of songs in the log. I want the script to restart back at the top defining a new RANDOM_FILE if the RANDOM_FILE is present in the grep command. If it isn't present, I want the script to continue, allowing the RANDOM_FILE to play through the fm_transmitter program.
I would also like for someone to check that the string defining RANDOM_FILE is in fact, truly random and correct.
Below is the script in it's current form. I believe I am close, but am going wrong somewhere as I still am getting repeats. I need help with the "if" "then" "else" and "return" commands. I am hoping this is a quick and easy solution.
Thank you in advance to anyone that takes the time to help me out.
#!/bin/bash
while :
do
files=(/home/pi/music/*.wav)
RANDOM_FILE="${files[RANDOM % ${#files[@]}]}"
if tail -n 25 /home/pi/transmit_log.txt | grep "$RANDOM_FILE" = true ; then
echo -e "---SONG_SKIPPED---" >> /home/pi/transmit_log.txt ; return 7
else
# [ tail -n 25 /home/pi/transmit_log.txt | grep "$RANDOM_FILE" = false ] ; then
return 22
fi
echo -e "$RANDOM_FILE" >> /home/pi/transmit_log.txt
sox -v 3 "$RANDOM_FILE" -r 44100 -c 1 -b 16 -t wav - | sudo ./fm_transmitter -f 91.7 -
sleep .5
done
Upvotes: 0
Views: 93
Reputation: 84
I don't believe you can return in the if/else statement like so. Return is used in a function to return a value. Instead, you can use continue, that will skip until the next iteration of the loop (and fix the test like suggested by codeforester):
#!/bin/bash
while :
do
files=(/home/pi/music/*.wav)
RANDOM_FILE="${files[RANDOM % ${#files[@]}]}"
if tail -n 25 /home/pi/transmit_log.txt | grep -q "$RANDOM_FILE" ; then
echo "---SONG_SKIPPED---" >> /home/pi/transmit_log.txt
continue
fi
echo "$RANDOM_FILE" >> /home/pi/transmit_log.txt
sox -v 3 "$RANDOM_FILE" -r 44100 -c 1 -b 16 -t wav - | sudo ./fm_transmitter -f 91.7 -
sleep .5
done
Alternatively, it can be better to split your tests like shown below to make the if condition smaller and more readable:
already_played=$( tail -n 25 /home/pi/transmit_log.txt | grep "$RANDOM_FILE" )
if [ ! -z "$aldeady_played" ]; then
...
fi
Upvotes: 1
Reputation: 42999
The issue is in this statement:
if tail -n 25 /home/pi/transmit_log.txt | grep "$RANDOM_FILE" = true; then ...
The right way to it is:
if tail -n 25 /home/pi/transmit_log.txt | grep -q "$RANDOM_FILE"; then ...
In your construct, = true
would be passed as arguments to grep
. That's not what you want, right? grep -q
will return 0 (or true) if the pattern was found and I believe that is what you want.
Upvotes: 0