1

I've been trying to figure out a way to test if a parameter is a number using the command expr.

In my script so far I've written:

expr $1 + 1 2>/dev/null
if [ $? -eq 2 -o $1 -lt 0 ]
then
    echo "$1 is not a positive integer" >&2
    exit 1
fi

What I'm trying to do here is to add 1 to the variable. If this provokes an error (which means that the variable isn't a number), the result will be sent to /dev/null. After, I test if the return code is 2 or if the variable is less than 0. However this doesn't seem to work... any ideas?

P.S. Please keep in mind that I must use expr

AlexT
  • 589
  • 2
  • 9
  • 23
  • did you try it without the `2>/dev/null`. Also, do you know about `set -x` for debugging (and `set +x` to turn off). What are your sample inputs? (please edit Q). finally, what does `man expr` say? Good luck. – shellter Oct 10 '16 at 13:39
  • 1
    `-o` does not short-circuit in bash. Both sides of the operator are evaluated. – Phylogenesis Oct 10 '16 at 13:45

2 Answers2

0

Your condition is evaluated whatever the value of $1, it means that if $1 is not a number, the shell will throw a syntax error.

I first check if expr fails (don't pre-suppose about the error code, just test for non-zero). If it does, I set the error flag. Then if the error flag is not set, I know that this is a number, then I check for positive (the error flag protects from evaluating $1 with a non-integer.

Not sure this is the best way but works:

error=0

expr $1 + 1 2>/dev/null >/dev/null 

if [ $? -ne 0 ] ; then
  error=1
fi
if [ $error -eq 0 ] ; then
  if [ $1 -lt 0 ] ; then
     error=1
  fi
fi

if [ $error -eq 1 ] ; then
    echo "$1 is not a positive integer" >&2
    exit 1
fi

test:

$ exprtest.sh foo
foo is not a positive integer

$ exprtest.sh 4

$ exprtest.sh -5
-5 is not a positive integer

Note: 0 passes the test, although some may object that it's not strictly a positive integer.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

you can also try this;

#!/bin/bash
expr $1 + 1 2>/dev/null >/dev/null 
if [ $? -eq 2 ] || [ $1 -lt 0 ]
then
    echo "$1 is not a positive integer" >&2
    exit 1
fi

Eg:

user@host:/tmp/test$ ./test.sh foo
foo is not a positive integer

user@host:/tmp/test$ ./test.sh 4

user@host:/tmp/test$ ./test.sh -5
-5 is not a positive integer
Mustafa DOGRU
  • 3,994
  • 1
  • 16
  • 24