views:

63

answers:

7

Suppose I have variable "x" in bash. How can I test if it's some number?

I tried if x=5; then echo "it is 5"; fi but that doesn't work,

then I tried if x==5; then echo "it is 5"; fi but that also doesn't work,

then I tried if [x==5]; then echo "it is 5"; fi but that also doesn't work,

then I tried if [[x==5]]; then echo "it is 5"; fi but that also doesn't work,

then I tried if [[x=5]]; then echo "it is 5"; fi but that also doesn't work,

then I tried if [x=5]; then echo "it is 5"; fi but that also doesn't work,

then I tried if [x -eq 5]; then echo "it is 5"; fi but that also doesn't work,

then I tried if [[x -eq 5]]; then echo "it is 5"; fi and it finally worked.

I am lost. Bash seems to be hell. Why so many ways didn't work? And only the last one did?

Can't bash adopt if x==5; then ...; fi syntax?

Thanks, Boda Cydo

A: 

Variables in bash should have a $ before them - if [${x} -eq 5] should have worked too.

smichak
No, that won't work. There has to be a space after `[` and one before `]`: `if [ ${x} -eq 5 ]` or `if [ $x -eq 5 ]`
Dennis Williamson
+3  A: 

Try:

if [ "$x" = 5 ]; then echo "it is 5"; fi

Note that [ is a command in itself; you may find that it's symlinked to test on your system. So, man test tells you how to use it. In particular, it is important to put a space after it.

ggg
In bash, however, `[` and `test` are built-ins. The `/usr/bin/test` command is **almost** identical, but there happen to be some discrepancies. Therefore, consult `help [` and `help test` rather than `man test`.
Bolo
Thanks. But what is quoting for? Why did you quote `"$x"`?
bodacydo
@bodacydo: Quoting `"$x"` prevents a syntax error if `$x` is empty.
ggg
A: 

You might find chapter 7.1. Test Constructs in the Advanced Bash-Scripting Guide helpful.

stacker
+2  A: 

Bash cannot adopt the "if x==5" syntax to have the semantics that you want because it is already valid syntax with a different meaning. 'if x==5; then ...; fi' currently sets x to the value '=5' and then executes the commands following then.

In terms of your first question, I advise avoiding the bracket notation completely. Just do

if test "$x" = 5; then
...
fi

Also note that 'if test x = 5' will always be false, since this is a comparison of the literal string 'x' and the literal string '5'. You need to use $x to get the value of the variable.

William Pursell
Thanks, I did not know this before!
bodacydo
A: 

Can't bash adopt if x==5; then ...; fi syntax?

In Bash, you can use this syntax which allows you to omit the dollar sign and avoid using -eq, so it comes closest to what you'd like to use:

if (( x == 5 ))

You can even leave out the spaces if you prefer:

if ((x==5))
Dennis Williamson
A: 

you can use case/esac

case "$x" in
 5) echo "x is 5";;
esac
ghostdog74
+1  A: 

sh syntax is actually amazingly flexible, and it is quite possible to get the syntax that you want. For example, if you want to be able to write "if x == 5", you just need to realize that sh will evaluate that string by invoking a command named 'x' with arguments '==' and '5', and react to the value returned by that function. The following is probably not a good idea for any sort of production setting, but it may be instructive to understand how this works:

#!/bin/sh

declare() {
    eval $1'() {
    case $# in
        0) test $'$1';;
        1) false;;
        *) case $1 in
            =) shift; 
            '$1'=$(expr $*);;
            ==) test "$'$1'" = $2;;
            .=) '$1'="$'$1'$2";;
            +=) '$1'=$(expr $'$1' + $2);;
            -=) '$1'=$(expr $'$1' - $2);;
            *) false;;
        esac
    esac
    }'
}

declare x
x = 5
if x == 4; then echo not printed; fi  
if x == 5; then echo x = $x; fi  # "x = 5"
x += 2;
if x == 5; then echo not printed; fi  
if x == 7; then echo x = $x; fi  # "x = 7"
x = foo
x .= bar
echo x = $x                      # "x = foobar"
x = 4 + 5
echo x = $x                      # "x = 9"

The output of the above script is:

x = 5
x = 7
x = foobar
x = 9

William Pursell
This is pure genius! Wow. Just wow!
bodacydo