0

Intention


I am in the middle of writing a little shell script (POSIX, except for the system_beep()).

The script, which runs in Cygwin, should find out, if my mother's laptop is closed or not and give me clear result and if open also a 5x a beep.

Code


#!/bin/bash

set -o nounset

blink=$(tput blink)
bold=$(tput bold)
reverse=$(tput rev)
no_color=$(tput sgr0)

red=$(tput setaf 1)
#blue=$(tput setaf 4)
#cyan=$(tput setaf 6)
green=$(tput setaf 2)
#white=$(tput setaf 7)
#yellow=$(tput setaf 3)
#magenta=$(tput setaf 5)

lid_open_color="${blink}${bold}${reverse}${red}"
lid_closed_color="${blink}${bold}${reverse}${green}"

system_beep()
{
    echo -ne '\007'
}

beep_x_times()
{
    i=1; while [ "$i" -le "$1" ]; do

        i=$((i + 1))
        system_beep
        sleep 1s

    done
}

get_lid_state_mom()
{
    if ! ssh heruser@laptop_ip -p port_number -o ConnectTimeout=3 -i /home/myuser/.ssh/id_rsa 2> /dev/null \
        cat /proc/acpi/button/lid/LID0/state | awk '{print $2}'; then

#    if [ "$?" -ne 0 ]; then

        echo "Error connecting to Mom via SSH"
        exit 1

    fi

}

state=$(get_lid_state_mom)



if [ "$state" = "closed" ]; then

    echo "${lid_closed_color}closed${no_color}"

elif [ "$state" = "open" ]; then

    echo "${lid_open_color}open${no_color}"
    beep_x_times 5

else

    echo "Some error occurred!"

fi

Problem

In spite of my efforts, I seem to be unable to understand why I get:

$ ./lid-status-mama-beep
Some error occurred!

While it behaves correctly, when the laptop is SSH connectable:

If the lid is closed:

$ ./lid-status-mama-beep
closed

If the lid is open:

$ ./lid-status-mama-beep
open

I obviously do something wrong in this error handling case.


Question

How do I make this script output:

Error connecting to Mom via SSH

when the connection is down for whatever reason?

1

Solution

See comments for explanation on each line.

get_lid_state_mom()
{
    # I have omitted awk completely here, getting raw value instead
    ssh -p port_number -o ConnectTimeout=3 -i /home/myuser/.ssh/id_rsa heruser@laptop_ip cat /proc/acpi/button/lid/LID0/state 2> /dev/null
}

# this had to be renamed in order for me to know it is a raw value
lid_state_raw=$(get_lid_state_mom)

# indirect test for successful execution seems to be the best method
if [ "$?" -ne 0 ]; then

    echo "Error connecting to Mom via SSH"
    exit 1

fi

# after the success extract the state from the raw value
lid_state=$(echo "$lid_state_raw" | awk '{print $2}')
0

Reason

Your if statement in get_lid_state_mom is wrong.

In the following code snippet, you can see that only the exit value of second_command is taken in account.

if ! first_command | second_command ; then 
    echo "second_command exited false"
fi

The ! inverts the result of all first_command | second_command, so it is equivalent to ! second_command

In your code second_command is the call to awk, so your if is true only when awk fails.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.