TheChopsChronicles
TheChopsChronicles

Reputation: 13

"If" "then" "else" and "return" command syntax

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

Answers (2)

Asct20
Asct20

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

codeforester
codeforester

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

Related Questions