Check that a variable is a number in UNIX shell [duplicate] - unix

This question already has answers here:
How do I test if a variable is a number in Bash?
(40 answers)
Closed 1 year ago.
How do I check to see if a variable is a number, or contains a number, in UNIX shell?

if echo $var | egrep -q '^[0-9]+$'; then
# $var is a number
else
# $var is not a number
fi

Shell variables have no type, so the simplest way is to use the return type test command:
if [ $var -eq $var 2> /dev/null ]; then ...
(Or else parse it with a regexp)

No forks, no pipes. Pure POSIX shell:
case $var in
(*[!0-9]*|'') echo not a number;;
(*) echo a number;;
esac
(Assumes number := a string of digits). If you want to allow signed numbers with a single leading - or + as well, strip the optional sign like this:
case ${var#[-+]} in
(*[!0-9]*|'') echo not a number;;
(*) echo a number;;
esac

In either ksh93 or bash with the extglob option enabled:
if [[ $var == +([0-9]) ]]; then ...

Here's a version using only the features available in a bare-bones shell (ie it'd work in sh), and with one less process than using grep:
if expr "$var" : '[0-9][0-9]*$'>/dev/null; then
echo yes
else
echo no
fi
This checks that the $var represents only an integer; adjust the regexp to taste, and note that the expr regexp argument is implicitly anchored at the beginning.

This can be checked using regular expression.
###
echo $var|egrep '^[0-9]+$'
if [ $? -eq 0 ]; then
echo "$var is a number"
else
echo "$var is not a number"
fi

I'm kind of newbee on shell programming so I try to find out most easy and readable
It will just check the var is greater or same as 0
I think it's nice way to choose parameters... may be not what ever... :
if [ $var -ge 0 2>/dev/null ] ; then ...

INTEGER
if echo "$var" | egrep -q '^\-?[0-9]+$'; then
echo "$var is an integer"
else
echo "$var is not an integer"
fi
tests (with var=2 etc.):
2 is an integer
-2 is an integer
2.5 is not an integer
2b is not an integer
NUMBER
if echo "$var" | egrep -q '^\-?[0-9]*\.?[0-9]+$'; then
echo "$var is a number"
else
echo "$var is not a number"
fi
tests (with var=2 etc.):
2 is a number
-2 is a number
-2.6 is a number
-2.c6 is not a number
2. is not a number
2.0 is a number

if echo $var | egrep -q '^[0-9]+$'
Actually this does not work if var is multiline.
ie
var="123
qwer"
Especially if var comes from a file :
var=`cat var.txt`
This is the simplest :
if [ "$var" -eq "$var" ] 2> /dev/null
then echo yes
else echo no
fi

Here is the test without any regular expressions (tcsh code):
Create a file checknumber:
#! /usr/bin/env tcsh
if ( "$*" == "0" ) then
exit 0 # number
else
((echo "$*" | bc) > /tmp/tmp.txt) >& /dev/null
set tmp = `cat /tmp/tmp.txt`
rm -f /tmp/tmp/txt
if ( "$tmp" == "" || $tmp == 0 ) then
exit 1 # not a number
else
exit 0 # number
endif
endif
and run
chmod +x checknumber
Use
checknumber -3.45
and you'll got the result as errorlevel ($?).
You can optimise it easily.

( test ! -z "$num" && test "$num" -eq "$num" 2> /dev/null ) && {
# $num is a number
}

You can do that with simple test command.
$ test ab -eq 1 >/dev/null 2>&1
$ echo $?
2
$ test 21 -eq 1 >/dev/null 2>&1
$ echo $?
1
$ test 1 -eq 1 >/dev/null 2>&1
$ echo $?
0
So if the exit status is either 0 or 1 then it is a integer , but if the exis status is 2 then it is not a number.

a=123
if [ `echo $a | tr -d [:digit:] | wc -w` -eq 0 ]
then
echo numeric
else
echo ng
fi
numeric
a=12s3
if [ `echo $a | tr -d [:digit:] | wc -w` -eq 0 ]
then
echo numeric
else
echo ng
fi
ng

Taking the value from Command line and showing THE INPUT IS DECIMAL/NON-DECIMAL and NUMBER or not:
NUMBER=$1
IsDecimal=`echo "$NUMBER" | grep "\."`
if [ -n "$IsDecimal" ]
then
echo "$NUMBER is Decimal"
var1=`echo "$NUMBER" | cut -d"." -f1`
var2=`echo "$NUMBER" | cut -d"." -f2`
Digit1=`echo "$var1" | egrep '^-[0-9]+$'`
Digit2=`echo "$var1" | egrep '^[0-9]+$'`
Digit3=`echo "$var2" | egrep '^[0-9]+$'`
if [ -n "$Digit1" ] && [ -n "$Digit3" ]
then
echo "$NUMBER is a number"
elif [ -n "$Digit2" ] && [ -n "$Digit3" ]
then
echo "$NUMBER is a number"
else
echo "$NUMBER is not a number"
fi
else
echo "$NUMBER is not Decimal"
Digit1=`echo "$NUMBER" | egrep '^-[0-9]+$'`
Digit2=`echo "$NUMBER" | egrep '^[0-9]+$'`
if [ -n "$Digit1" ] || [ -n "$Digit2" ]; then
echo "$NUMBER is a number"
else
echo "$NUMBER is not a number"
fi
fi

Related

How to test empty input?

The following command finishes silently when the input is empty. How to test for empty input and do something different depending on whether the input is empty or not?
$ jq -e -r .data < /dev/null
$ echo $?
0
One way would be to use the -s option and test for the empty array:
jq -s 'if . == [] then "empty" else .[0].data end' </dev/null
empty
But what else should be considered an empty input? As JSON ignores newlines etc., there could be an actual input which is considered an empty JSON:
echo | jq -s 'if . == [] then "empty" else .[0].data end'
empty
While the expected case will pass...
echo '{"data":1}' | jq -s 'if . == [] then "empty" else .[0].data end'
1
...other non-empty cases may not be caught as with the empty case
echo '{"other":1}' | jq -s 'if . == [] then "empty" else .[0].data end'
null
However, to elaborate more, you'd need to specify what "do something different" means. If you wanted to fail, like with the -e option but with a custom error message, you could read in the whole input as raw text using the -Rs option, then try to convert it to JSON using the fromjson builtin, and react upon that if it failed using the ? and // operators:
jq -Rs 'fromjson? // error("Bad input") | .data' </dev/null
jq: error (at <stdin>:1): Bad input
echo | jq -Rs 'fromjson? // error("Bad input") | .data'
jq: error (at <stdin>:1): Bad input
echo '{"data":1}' | jq -Rs 'fromjson? // error("Bad input") | .data'
1
You can use
jq -ne 'input? // null'
$ echo {} | jq -ne 'input? // null' >/dev/null; echo $?
0
$ echo '' | jq -ne 'input? // null' >/dev/null; echo $?
1
$ </dev/null jq -ne 'input? // null' >/dev/null; echo $?
1
If you also want to check that .data isn't missing and isn't null (or false), you can use
jq -ne 'input? // null | .data'
$ echo '{"data":123}' | jq -ne 'input? // null | .data' >/dev/null; echo $?
0
$ echo '{"data":null}' | jq -ne 'input? // null | .data' >/dev/null; echo $?
1
$ echo {} | jq -ne 'input? // null | .data' >/dev/null; echo $?
1
$ echo '' | jq -ne 'input? // null | .data' >/dev/null; echo $?
1
$ </dev/null jq -ne 'input? // null | .data' >/dev/null; echo $?
1

test ./script.sh doit test dont show true output

#!/usr/bin/env zsh
doit() {
if [[ "$1" = "start" ]]; then
for loc in $(cat all-doc); do
if ! screen -list | grep -q My-$loc; then
screen -dmS My-$loc /home/Server -f /home/$loc.cfg
fi
done
elif [[ "$1" = "stop" ]]; then
for loc in $(cat all-doc); do
if screen -list | grep -q My-$loc; then
pkill -f My-$loc;
fi
done
else
echo "Option: ERROR..."
fi
}
nothing() {
if [[ "$1" = "start" ]]; then
echo "Option: 1"
elif [[ "$1" = "stop" ]]; then
echo "Option: 2"
else
echo "Option: 3"
fi
}
case "$2" in
start)
"$1" "$2";
;;
stop)
"$1" "$2";
;;
restart)
restart;
;;
*)
echo "Usage: $0 {doit|nothing} {start|stop|restart}"
exit 1
;;
esac
exit 0
Output:
./script.sh:34> case test (start)
./script.sh:34> case test (stop)
./script.sh:34> case test (restart)
./script.sh:34> case test (*)
./script.sh:45> echo 'Usage: ./script.sh {start|stop|restart}'
sage: ./script.sh {start|stop|restart}
./script.sh:46> exit 1
this script for start and stop and restart my servers.
If $2 not match with "start" "stop" "restart" in both function must call else but not work.
Ok question is why ./script.sh doit test did not call
else
echo "Option: ERROR..."
whats the sulotion ? Is there better way to do somthing for ./script.sh $1 $2 i mean $1 get function and $2 get start|stop|restart ?

recovering deleted script running in background

I have script which is running in bg(nohup) but it was accidently deleted,but that is continue running now I need to edit the code which is already deleted.
How can I now get that code.I assume somewhere it should be as it is running.
Try this :
#!/bin/bash
if [[ ! $1 || $1 == -h || $1 == --help ]]; then
echo -e "Usage:\n\n\t$0 '[path/]<file name>'"
exit 1
fi
files=(
$(file 2>/dev/null /proc/*/fd/* |
grep "(deleted)'$" |
sed -r 's#(:.*broken\s+symbolic\s+link\s+to\s+.|\(deleted\).$)# #g' |
grep "$1" |
cut -d' ' -f1
)
)
if [[ ${files[#]} ]]; then
for f in ${files[#]}; do
echo "fd $f match... Try to copy this fd to another place quickly!"
done
else
echo >&2 "No matching fd found..."
exit 2
fi
Not tested on non GNU-Linux

How to capture result from cat in unix, for server monitoring

Hi I need to create a server monitoring, where I need to store the memory in use, cpu utilization by processes and overall cpu utilization.
I wrote the below script using top command
#!/bin/ksh
echo " " > top.txt
top -b -d 1 > top.txt
var =20
MEM = "$(cat top.txt |grep Memory | cut -c 8-12)"
JAV = $(cat top.txt |grep java | cut -c 55-60)
SSH = $(cat top.txt |grep ssh | cut -c 55-60)
mailing_list="xxxxxx#yyyy.co.in"
subject_line="monitring"
if [ $mem -gt $var || $ jav -gt "10" || $ssh -gt "10"] ;then
echo $mem
echo $jav
echo $ssh
echo "there is some problem"| mailx -b "${mailing_list}" -s "${subject_line}" " "
fi
exit 0
When i execute thisa script I recieve a waring that mem jav not found.
Please help me with this
My task is to create a monitoring script.
Thanks in advance
You have spaces around = in your variable assignments. Remove those. That is what causes those MEM: command not found errors.
You say:
if [ $mem -gt $var || $ jav -gt "10" || $ssh -gt "10"] ;then
There are multiple problems with this. Say:
if [[ $mem -gt $var || $jav -gt "10" || $ssh -gt "10" ]]; then
You also seem to be mixing cases. Variable names are case-sensitive.

zsh: parse error: condition expected: "$1"

I tried to write a script to compile java files with gentoos java-config but i ended up getting an error
zsh: parse error: condition expected: "$1" Can anyone tell me what this means and why it gets reported at line 16 in the function.
function jComp() {
local java_mods = ""
if (( $# == 0)); then
echo "using javac on .java in folder"
`javac *.java`
return 0
elif [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
echo "Usage: jComp [java modules] [file]"
echo
echo "Options:"
echo " -h, This help message."
echo "modules has to be in the (java-config -l) list"
echo
echo "Report bugs to <tellone.diloom#gmail.com>."
return 0
fi
if [[ "$(java-config -v)" == "" ]]; then
echo "This script depends on java-config"
return 1
elif [[ "$1" =="-d" ]] || [[ "$1" == "--default"]]; then
`javac -cp .:$(java-config -p junit-4) *.java`
if [[ $# == 2 ]]; then
`javac -c .:$(java-config -p junit-4) "$2"`
return 0
fi
fi
while (( $# > 1 )); do
if [[ ! -f "$1" ]]; then
java_mods="$java_mods $1"
shift
continue
fi
done
`javac -cp .:$(java-config $java_mods)`
return 0
}
Links and comment are welcome. Thanks in advance
It looks like your code is trying to compare a string stored in argument $1 to the string -d but the comparison is missing a space after the double equal sign:
elif [[ "$1" =="-d" ]] || [[ "$1" == "--default"]]; then
^
elif [[ "$1" == "-d" ]] || [[ "$1" == "--default"]]; then
I haven't tried the code but, do try and let me know if it solved it !
Btw, it also looks like the second comparison will also fail because of a lack of space before the double square closing brackets:
elif [[ "$1" == "-d" ]] || [[ "$1" == "--default"]]; then
^
elif [[ "$1" == "-d" ]] || [[ "$1" == "--default" ]]; then
All your backticked commands look wrong. You want to run the commands, not interpret their output as a command to run, right? If so, remove all the backticks from the javac invocations.
Then there is a missing space in [[ "$1" =="-d" ]] to make the == a separate token (and another as pointed out by leroyse).

Resources