10

I'm trying do to a script to check the CA power status

this is my code:

#!/bin/bash

a=$(acpitool -a)

echo "$a"

if $a -eq "AC adapter : online"
then
echo "ONLINE"
else
echo "OFFLINE"
fi

It's not working; the variable $a ia not compare with the the string "AC adapter : online". How to convert the output of command acpitool -a to a string?

This is what happens:

AC adapter     : online 
./acpower.sh: linha 7: AC: comando não encontrado
OFFLINE

Problem solved!

This is the new code, whith the help of all of you, thanks.

#!/bin/bash

# set the variable
a=$(acpitool -a)

# remove white spaces
a=${a// /}

# echo for test
echo $a

# compare the result
if [[ "$a" == 'ACadapter:online' ]]
then
# then that the imagination is the limit
echo "ONLINE"
else
# else if you have no imagination you're lost
echo "OFFLINE"
fi

This code may be use on a server, to alert if the power fails!

2
  • How about putting $a in quotes when comparing? like: if "$a" -eq "AC adapter : online"? Commented Jul 27, 2013 at 17:43
  • 1
    Welcome to Stack Overflow. Please read the About page soon. You did a nice job on your question; you showed the code, you explained what you wanted and what you got as an error — all good technique. Commented Jul 27, 2013 at 17:57

4 Answers 4

9

How to fix the problem

The shell (or the test command) uses = for string equality and -eq for numeric equality. Some versions of the shell support == as a synonym for = (but = is defined by the POSIX test command). By contrast, Perl uses == for numeric equality and eq for string equality.

You also need to use one of the test commands:

if [ "$a" = "AC adapter : online" ]
then echo "ONLINE"
else echo "OFFLINE"
fi

Or:

if [[ "$a" = "AC adapter : online" ]]
then echo "ONLINE"
else echo "OFFLINE"
fi

With the [[ operator, you could drop the quotes around "$a".

Why you got the error message

When you wrote:

if $a -eq "AC adapter : online"

the shell expanded it to:

if AC adapter : online -eq "AC adapter : online"

which is a request to execute the command AC with the 5 arguments shown, and compare the exit status of the command with 0 (considering 0 — success — as true and anything non-zero as false). Clearly, you don't have a command called AC on your system (which is not very surprising).

This means you can write:

if grep -q -e 'some.complex*pattern' $files
then echo The pattern was found in some of the files
else echo The pattern was not found in any of the files
fi

If you want to test strings, you have to use the test command or the [[ ... ]] operator. The test command is the same as the [ command except that when the command name is [, the last argument must be ].

Sign up to request clarification or add additional context in comments.

Comments

3

Put the comparision in square brackets and add double quotes around the $a:

if [ "$a" == "AC adapter : online" ]; then
  ...

Without the square brackets bash tries to execute the expression and evaluate the return value.

It may also be a good idea to put the command substitution in double quotes:

a="$(acpitool -a)"

3 Comments

The double quotes around a="$(acpitool -a)" are not necessary, though they do no harm — unless the command needs double-quoted arguments, in which case the outer double quotes complicate things to the extent that it is much better to drop them.
@JonathanLeffler No, they don't. Command substitution with $() differs from command substitution with `` in this respect. Something like a="$(echo "foo bar")" will work just fine.
Ugh...ISTR coming across this recently, and you're right about a="$(echo "a ")" working OK. It confuses the hell out of me so I'd not do it, but I learned shell coding in shells where it really did matter (ones which didn't have $(...) at all — it hadn't been invented yet), so I tend to be old-fashioned.
3

Please try this -

    #!/bin/bash
    a="$(acpitool -a)"

    echo "$a"

    if [ "$a" == 'AC adapter : online' ]
    then
    echo "ONLINE"
    else
    echo "OFFLINE"
    fi

Explanation: -eq is mainly used for equivalence for integer expressions. So, == is the way to go! And, use double quotes across $a or $(acpitool -a) to prevent word splitting. An argument enclosed within double quotes presents itself as a single word, even if it contains whitespace separators.

4 Comments

That will solve the problem(s), but your answer would be improved if you explained why.
@JonathanLeffler: I hope it's better now. Many thanks for your suggestion.
Yes, it is better. You didn't (yet) note that you added the test command to the if statement. :) Just picking nits.
He can figure that out, I guess :) And you answer sufficiently answers that I suppose. So, I won't worry much :)
1

Problem solved!

This is the new code, whith the help of all of you, thanks.

#!/bin/bash

# set the variable
a=$(acpitool -a)

# remove white spaces
a=${a// /}

# echo for test
echo $a

# compare the result
if [[ "$a" == 'ACadapter:online' ]]
then
# then that the imagination is the limit
echo "ONLINE"
else
# else if you have no imagination you're lost
echo "OFFLINE"
fi

This code may be use on a server, to alert if the power fails!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.