PDA

View Full Version : Variables in Bash Scripts


Unch
2006-03-19, 12:25
Hello,

I'm dabbling with shell scripts for the first time, and I've hit a bit of a barrier.

I'm trying to make a script that will run a couple of programs, capture the output ( just a short string from each one) and then append some info to a log file depending upon the output. My problem is that I can't get my script to compare the string from the output to the string I'm looking for.


$MYOUTPUT=$(program < data)
echo $MYOUTPUT
if [ "$MYOUTPUT" = "foo" ]
then
echo output was foo
fi


There seems to be so many conflicting bits of info about using if and strings on the net. All the ways I've tried so far either give me a ./test.sh: line 10: foo: command not found or does not compare properly.

Wickers
2006-03-19, 13:27
And you are just working with strings?

(what? like md5 sums?)

Anyhow, I like bash, but it was easier for me to think of a solution in Python:


#this is python code
import sys

if sys.argv[1] == sys.argv[2]:
print "output was foo"
else:
print "output was not foo"


Copy that to a text file, and name it compare.py (or whatever name you'd like).

Use it in your bash script like this:


#this is bash code
test="string"
test2="string" #maybe this is your constant, in which case you could sub $test2 with a "string" directly.
python compare.py $test $test2



Anyhow, there's much better ways of getting this job done... but then I'd have to look stuff up. :p

euain
2006-03-19, 13:30
Hello,

I'm dabbling with shell scripts for the first time, and I've hit a bit of a barrier.


$MYOUTPUT=$(program < data)
echo $MYOUTPUT
if [ "$MYOUTPUT" = "foo" ]
then
echo output was foo
fi



Hmm.. try

MYOUTPUT=$(program < data)
echo $MYOUYPUT
if [ ${MYOUTPUT} = foo ]; then
echo output was foo
fi


The initial assignment should not have the leading $.
Other than that, it looks pretty much OK.

I normally avoid the line like if [ ${MYOUTPUT} = foo ]; then in preference to if [ $(echo $MYOUTPUT | grep -c foo) -ge 1]; then or something similar because it is less likely to trip you up (certainly if the program is something like a ftp client and its return will vary but should always contain a particular numerical value/string to dignify success etc).

The grep command also allows you to specify any regular expressions you want..

Wickers
2006-03-19, 13:38
hmm... I did not even catch the extra $. hehe.

Majost
2006-03-19, 14:36
It works now, right? Regardless, if you haven't found this guide yet, you definitely should take a look at it: The Advanced Bash-Scripting Guide (http://www.tldp.org/LDP/abs/html/).

It's quite marvelous... I learned everything I know about Bash through it.

From there, you will find:
Using the [[ ... ]] test construct, rather than [ ... ] can prevent many logic errors in scripts. For example, the &&, ||, <, and > operators work within a [[ ]] test, despite giving an error within a [ ] construct.

Unch
2006-03-19, 14:48
Thanks, for the quick replies, but it still isn't working!

Using if [ ${MYOUTPUT} = foo ] gives me the error:-
./test.sh: line 9: [: too many arguments

And using if [ $(echo $MYOUTPUT | grep -c foo) -ge 1] gets me a:-

./test.sh: line 9: [: missing `]'

Majost
2006-03-19, 14:52
Thanks, for the quick replies, but it still isn't working!

Using if [ ${MYOUTPUT} = foo ] gives me the error:-
./test.sh: line 9: [: too many arguments

And using if [ $(echo $MYOUTPUT | grep -c foo) -ge 1] gets me a:-

./test.sh: line 9: [: missing `]'
For the first case, try putting them in quotes again. The {} just makes sure that the shell knows where the variable ends. It's good for times when you have stuff running right up to variables... ie ${number1}-${number2}.
if [ "${MYOUTPUT}" = "foo" ]

And for the second, make sure that there's a space between your bracket and the one. And, again quote your variable.
if [ $(echo "$MYOUTPUT" | grep -c foo) -ge 1 ]

For the record, I just tried essentially the same thing.
MYOUTPUT="foo"
if [ "$MYOUTPUT" = "foo" ]
then echo 'YES'
fi
And that worked

Unch
2006-03-19, 15:13
Thanks!

I just sussed the [ ] problem myself. Glad you confirmed it. I hadn't read anywhere that the scripts were picky about spacing.

I've learnt a few extra hints in here too.

Thanks once again for all your help guys!

euain
2006-03-19, 15:20
I think I know what the problem is.. as Majost says - you do need the quotes. Probably, the output (MYOUTPUT) has spaces in it?

It is good practice to put the variable name in {}s as it means that you can butt stuff against it. So something like:

aVar="filename"
cat > ${aVar}log.txt

will work (without the {}s, there would be no variable "aVarlog" - and the file would just be ".txt")

thuh Freak
2006-03-20, 11:59
Thanks!

I just sussed the [ ] problem myself. Glad you confirmed it. I hadn't read anywhere that the scripts were picky about spacing.

I've learnt a few extra hints in here too.

Thanks once again for all your help guys!
fyi: the reason shells are picky about spacing, around the [ & ], is becase [ is literally the name of a program (it also doubles as a shell builtin). if you think of it as a program, its a little easier to understand why the shell cares about spacing (otherise, it'd think whatever you were suffixing was part of the exe name).

Wickers
2006-03-20, 14:20
fyi: the reason shells are picky about spacing, around the [ & ], is becase [ is literally the name of a program ...


man test


Correct! :)