bodacydo
bodacydo

Reputation: 79369

What are the ways to do numeric testing in bash?

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

Upvotes: 3

Views: 3737

Answers (7)

William Pursell
William Pursell

Reputation: 212268

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

Upvotes: 1

ghostdog74
ghostdog74

Reputation: 342443

you can use case/esac

case "$x" in
 5) echo "x is 5";;
esac

Upvotes: 0

William Pursell
William Pursell

Reputation: 212268

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.

Upvotes: 2

Dennis Williamson
Dennis Williamson

Reputation: 360143

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))

Upvotes: 0

stacker
stacker

Reputation: 68962

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

Upvotes: 0

ggg
ggg

Reputation: 1723

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.

Upvotes: 2

smichak
smichak

Reputation: 4958

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

Upvotes: 1

Related Questions