I'm trying to write a bash script to perform basic arithmetic operations but I want to run a comparison on the arguments first to check that they're a number greater than zero.
I want an error to pop up if the arguments args aren't >= 0 so I have:
if ! [[ $1 -ge 0 ]]; then
echo "bad number: $1"
fi
But whenever I type in something like "blah + 9" it should tell me "bad number: blah", instead it treats "blah" as a zero and it gives the output as 9. If I use -gt 0 it eliminates the "blah" but also doesn't let me use zeros.
Perhaps it will work with these small adjustments:
#! /bin/sh
if [ -n "$(echo "$1" | egrep "^[0-9]+$")" ]; then
echo "good number: $1"
else
echo "bad number: $1"
fi
Be sure to copy it exactly. egrep "^[0-9]+$" is only allowing integers - no spaces and no ",", ".", "+" or "-", you have to adjust that if you want to allow more.
$ sh test.sh 5
good number: 5 #$1 is 5
$ sh test.sh fg
bad number: fg #$1 is fg
$ sh test.sh 3 gfg 5
good number: 3 #$1 is 3
$ sh test.sh "3 gfg 5"
bad number: 3 gfg 5 #$1 is "3 gfg 5"
$ cat test.sh
#! /bin/bash
if [[ `echo $1 | egrep "^[0-9]*$"` ]]
then
echo "good number: $1"
else
echo "bad number: $1"
fi
#!/bin/bash
a='blah'
[ "$a" -eq 0 ] 2>/dev/null ; x="$?" # Get error status to x variable
# As per man bash, if x greater than 1, $a is not an integer
if [ "$x" -gt 1 ]; then
echo 'Bad integer'
fi
exit 0
This worked (though I'm sure egrep would've been fine too):
if ! [[ `echo $1 | grep "^[0-9]*$"` ]]
Also, decided to put a counter in each of the improper argument tests so that I could stop the script only after each test finished. Is there a more efficient way of doing this?
let probs=0
#each test if then
let probs++
#after all tests finish
if [[ probs -ne 0 ]]
then
exit
fi
eeek! and a new question... how do I make it so my script doesn't try to use any of bash's special characters in the arguments?
blah:~$ ./math *& p 2
[1] 9028
-bash: p: command not found
blah:~$ usage: ./math <number> <operation> <number>
./math 3 p 2
Result is 5
[1]+ Done ./math *
ctrl+c kills the goofy stuff after it but I don't want to do that whenever some weird crap pops up, want it totally idiot proof.
What you describe is a feature of the shell, giving 'idiots' access to a shell is the problem here. Perhaps you should consider some sort of menu-driven utility rather than shell access.
Yes, but it's better when things can be done with built-in functions.
You may not remark any speed in your example, but it can save you some time when you use these external programs within loops.
Like this?
#!/bin/bash
testInt() {
[ "$1" -eq 0 ] 2>/dev/null
[ "$?" -gt 1 ] && { testResult=$((testResult+1)); return 1;}
return 0
}
a='blah'
testInt "$a" && {
echo "Do whatever you want with $a, but you won't see this first message, because $a is not an integer"
}
b='1234'
testInt "$b" && {
echo "Do whatever you want with $b, you see this message, because $b is an integer"
}
[ "$testResult" -gt 0 ] && {
echo "$testResult test(s) failed. Exiting the script now"
exit 1
}
echo 'None of the tests failed, we continue up to the next exit 0'
exit 0