Bash Q: how to keep a script from failing when a var is undef or empty
Hello, One thing I run into all the time with bash script is: I get a script that works perfectly when every thing is right, and is supposted to aleart me when something is wrong - often bashed on whether or not a particular var says something. But often the script fails because bash trips out over trying to test an empty var. For example: #!/bin/sh TAPESTATE=`mt -f /dev/st0 status | head -2 |tail -1 | cut -d " " -f4` if [ ${TAPESTATE} == "512" ]; then READY="yes" else READY="no" && echo "No tape in oe1 tape drive" | mail -s "Oe1 tape error" jw@mailsw.com fi if [ ${READY} == "yes" ]; then tar cplvf /dev/st0 -T /etc/mcmurray_backup.lst || echo "Tar failed during oe1 tape backup job" | mail -s "Oe1 backup job tar error" jw@mailsw.com else echo "Script failure in oe1 tar backup job" | mail -s "Oe1 backup job - error in script" jw@mailsw.com exit 1 fi As long as there's a tape in the tape drive it works out fine, but when there's not a tape, "mt -f /dev/st0 status" give the response: mt: /dev/st0: No medium found And apparently sends it to sterr so that $TAPESTATE remains empty (null). Now instead of just calmly passing on to the next section: else READY="no" && echo "No tape in oe1 tape drive" Bash give a response like this: usr/local/sbin/tape_bakup.sh: line 5: [: ==: unary operator expected And I've tried eq also. What's the proper way to do something like this? Thanks. -- ---------------------------------------------------- Jonathan Wilson Cedar Creek Software http://www.cedarcreeksoftware.com
if [ ${TAPESTATE}_x == "512_x" ]; then or the more modern if [ "$TAPESTATE" == "512" ]; then HTH, Jeffrey Quoting JW <jw@mailsw.com>:
Hello,
One thing I run into all the time with bash script is:
I get a script that works perfectly when every thing is right, and is supposted to aleart me when something is wrong - often bashed on whether or not a particular var says something.
But often the script fails because bash trips out over trying to test an empty var. For example:
#!/bin/sh
TAPESTATE=`mt -f /dev/st0 status | head -2 |tail -1 | cut -d " " -f4`
if [ ${TAPESTATE} == "512" ]; then [snip]
What's the proper way to do something like this?
JW writes:
TAPESTATE=`mt -f /dev/st0 status | head -2 |tail -1 | cut -d " " -f4`
if [ ${TAPESTATE} == "512" ]; then READY="yes" else READY="no" && echo "No tape in oe1 tape drive" | mail -s "Oe1 tape error" jw@mailsw.com fi
A general way to test for a non-empty string is: if [ -n "${TAPESTATE}" ]; then ... fi Or its converse, to test for an empty string: if [ -z "${TAPESTATE}" ]; then ... fi See "man test". The left bracket [ is the same thing as the "test" command. -Ti
Ti, JW, On Friday 01 October 2004 00:49, Ti Kan wrote:
JW writes:
TAPESTATE=`mt -f /dev/st0 status | head -2 |tail -1 | cut -d " " -f4`
if [ ${TAPESTATE} == "512" ]; then READY="yes" else READY="no" && echo "No tape in oe1 tape drive" | mail -s "Oe1 tape error" jw@mailsw.com fi
A general way to test for a non-empty string is:
if [ -n "${TAPESTATE}" ]; then ... fi
In a simple case like this, the {curly braces} are not necessary. They're needed when using the special variable dereferencing syntaxes or when it necessary to delimit the variable name from following interpolated text. BASH has loads of fancy variable manipulating features. For example, the ability to substitute a default value if the variable is unset and / or set to an empty value. You can get it to generate an error message or assign a default value, too. The ability to manipulate the value before inserting it is very, very handy. BASH is utterly feature-laden (for better or worse--I happen to like it). I recommend that you assimilate knowledge about it capabilities on a demand basis. So now, while you're dealing with variable dereferencing and testing issues, read up on variables and the "test" built-in and expand your repertoire of BASH scripting capabilities. I find the book "Linux Shell scripting with Bash" (by Ken. O. Burtch and publisehd by Developer's Library, ISBN 0-672-32642-6) very helpful.
Or its converse, to test for an empty string:
if [ -z "${TAPESTATE}" ]; then ... fi
See "man test". The left bracket [ is the same thing as the "test" command.
Test is a BASH built-in, so use "help test" or read the BASH manual page to make sure you're getting any details specific to BASH. Also, be sure to check out the '[[' counterpart to '['. '[[' evaluates expressions and can do glob pattern matching in addition to literal equality testing.
-Ti
Randall Schulz
participants (4)
-
Jeffrey L. Taylor
-
JW
-
Randall R Schulz
-
ti@amb.org