Check if variable is numeric or string

I have a problem in a shell program where I do errorchecking.

I ask a returnvalue from the database, which usually is a number, and this goes to a variable.
Now, I want to know if the returnvalue is a number or a string (the erromessage)

A sample of what I have:

tail -2 $log > $templog
head -1 $templog | read returnstatus

if [ $returnstatus > 0 ]
then
   errorfunction $returnstatus
fi

This goes well when $returnstatus is 0 or 20000 but, of course, not when $returnstatus is for example 'Arithemic overflow'

I also tried

if [ "$returnstatus" > "0" ]

but still no succes.

what I want is something like:

if $returnvalue between 0 and 999999
then
   returnfunction $returnvalue
else
   set returnstatus=123456
   returnfunction  $returnvalue
fi

Or a check if $returnstatus is a number or not, if that is possible.

So, how do I do this in ksh script?
I work om HP-UX.

LVL 3
ahoorAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

liddlerCommented:
How about?
if [ "$returnstatus" -gt "0" ] && [ "$returnstatus" -lt "999999" ]
yuzhCommented:
if [ ${returnstatus} -gt 0 -a ${returnstatus} -lt "999999" ]  ; then
yuzhCommented:
if [ ${returnstatus} -gt 0 -a ${returnstatus} -lt 999999 ]  ; then
OWASP: Forgery and Phishing

Learn the techniques to avoid forgery and phishing attacks and the types of attacks an application or network may face.

ahoorAuthor Commented:
Ok, as a workaround this works.

I still get an error executing the script but it does continue with a good errormessage.

Sample from my script:

tail -2 $log > $templog
head -1 $templog | read returnstatus

echo $returnstatus

if [ "$returnstatus" -gt "0" ] && [ "$returnstatus" -lt "999999" ]
then
   [some script]
else
   returnstatus="160032"
  [some script]
fi

output on screen:
Arithmetic overflow occurred.
./script.ksh[343]: Arithmetic overflow occurred.: syntax error

output in log (nevermind the dutch language):

Er is een fout opgetreden bij het uitvoeren van de interface.
Melding:

Msg 160032, Level 16, State 1:

You can see it does continue with the correct errorvalue, so it does go into the 'else' part of the statement.
If I could get rid if the syntax error it would be great, if not I'll just have to work with this. I'll leave this question open til tomorrow to see if someone has a great idea...

thanx so far.
ahoorAuthor Commented:
Yuzh your statement does give another syntaxerror:

./import_jaarplan_test2.ksh[343]: overflow: unknown test operator

Otherwise I get the same result as Liddler's solution.
yuzhCommented:
which version of HP-UX are you using.

if [ ${returnstatus} -gt 0 -a ${returnstatus} -lt 999999 ]  ; then

should not cause overflow.

Please post your whole script

yuzhCommented:
Here's some of the sample code from one of my script. it is runing
everyday under HP-UX:

        CTIME=`date +%Y%m%d%H%M`
        if [ $CTIME -ge $STIME -a $CTIME -lt $ETIME ] ; then
            trap "endlog" 0 1 2 15
        ........
        else
           # do soemthing
        fi

PS: CTIME is a lot bigger than 999999

mbekkerCommented:
Hello,

I've put an 'expr' in the following script to determine if the variable is a string or an integer. In this case you can perform other actions whenever an invalid string is returned:

tail -2 $log | head -1 | read returnstatus

expr $returnstatus + 0 >/dev/null 2>&1
if [ $? -ne 0 ]
then
  echo "Invalid returncode: $returnstatus"
  # [some script]
else
  if [ $returnstatus -gt 0 -a $returnstatus -lt 999999 ]
  then
    echo "Valid returncode: $returnstatus"
    # [some script]
  else
    echo "Other returncode: $returnstatus"
    returnstatus="160032"
    # [some script]
  fi
fi

Good luck!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ahoorAuthor Commented:
Yes! Thanks, I was looking for a function like this...
It works perfect now.

CuthbertDibbleGrubCommented:
If you're using the Korn shell, you can define a variable as an integer thus:

typeset -i my_number

and then assign it using:

my_number=`a UNIX command` or my_number=7

If you assign a non-numeric value to the variable, it will assign zero to it instead.  Therefore, you can then test for a numeric value like this:

if [ my_number -gt 0 ]
then
  echo "It's a number!"
else
  echo "It's not a number!"
fi

Note that variables typeset in this way can be used without the need for teh '$' or expr syntax e.g. a=a+1; if [ a -eq 10 ]; then echo "It equals ten."; fi

Shaun.

JJSmithCommented:
Adding 0 to a variable is the recognised way of achiving a numeric test. However just for fun, why not delete all digits from the string and test if there is anything left.

eg
if [ -n "`echo "$returnstatus" | tr -d [0-9]`]; then
   echo "Invalid returncode: $returnstatus"
else
   carry on .....
fi

It all depends on how 'perfectionist' or 'anally retentive' we want to be ;-) - this option will return invalid if the returnstatus contains leading or trailing spaces, as a space is not numeric - some of the other options above will not.

Cheers
JJ
vocogovCommented:
I figured it out.
expr $userinput + 0 > /dev/null 2>&1
if [ $? -eq 0 ] ; then
  go on with my script stuff
else
  display error message
fi

Am attaching working code.  Still more to be done but this gets me through the error checking.
#! /bin/ksh
# set -x
# This menu reads a control file to gather the latest list of agents
#  then checks to see if the agent is running as a process.
# When displaying the agent list on the screen, it's status is included
#  (running or stopped).
# Until the user exits the program, each time they press the enter key
#  (whether they entered a reply or not) the program loops and provides
#  a current status of the agent processes.
# They choose which agent they'd like to start from the menu.
# Only agents that are not running will be started regardless of what
#  the user selects.
#

while true
do
clear
  echo "Below are agents and their current statuses."
  echo
  echo
  echo "Press ENTER to refresh screen or choose an agent below to stop it. "
  echo "Note: Logging will stay enabled for the tables in the agent. "
  echo
  AGENTCTL=/iway/cdcagent/config/agent.ctl
  proc_count=0
  cat $AGENTCTL |  while read LINE
  do
  case $LINE in
    \#* )   ;;  #comment line-Ignore
       *) PROCESS=`ps -ef | grep iwaycdcagent | grep $LINE | awk '{print $2}'`
          proc_count=`expr $proc_count + 1`
          item_list=`echo $item_list $LINE`
          if [ "$PROCESS" = "" ] ; then
            echo "$proc_count. $LINE - stopped"
          else
            echo "$proc_count. $LINE - Running"
          fi
  esac

  done

  proc_count=`expr $proc_count + 1`  # this sets the next menu item for ALL
  echo "$proc_count. ALL running agents"

  echo "x. Exit"
  echo
  echo Select an item to stop an agent or $proc_count for ALL Agents.
  echo
  echo $MSG
  echo


  read answer1 answer2

lanswer1=`echo $answer1 | tr '[A-Z]' '[a-z]'`
lanswer2=`echo $answer2 | tr '[A-Z]' '[a-z]'`

if [ "$lanswer1" = "x" ] ; then
  break
fi

if [ "$lanswer2" = "" ] || [ "$lanswer2" = "reset" ] ; then

expr $lanswer1 + 0 > /dev/null 2>&1
if [ $? -eq 0 ] && [ "$lanswer1" != "" ] ; then
   lanswer1=`expr $lanswer1 + 0`
    if [ $lanswer1 -lt $proc_count ] ; then
     startitem=`echo "$item_list" | cut -f"$lanswer1"-"$lanswer1" -d" "`
     PROCESS=`ps -ef | grep iwaycdcagent | grep $startitem | awk '{print $2}'`
     if [ "$PROCESS" = "" ] ; then
#      start command here.
      MSG="$startitem starting...press ENTER to refresh status."
     else
      MSG="$startitem already running."
     fi
    elif [ "$lanswer1" -eq "$proc_count" ] ; then # this to start all loop
      proc_loop=1
      while [ $proc_loop -lt $proc_count ]
      do
       startitem=`echo "$item_list" | cut -f"$proc_loop"-"$proc_loop" -d" "`
       PROCESS=`ps -ef | grep iwaycdcagent | grep $startitem | awk '{print $2}'`
        if [ "$PROCESS" = "" ] ; then
          # start command issued here
     echo "this msg to suppress error since command isnt used yet" > /dev/null
        fi
        proc_loop=`expr $proc_loop + 1`
      done
      MSG="starting all agents...press ENTER to refresh status."
    else
      MSG="...Invalid option. Try again."
    fi
  else
    MSG="...Invalid option. Try again."
  fi

else # answer2 not valid
  MSG="...Invalid option $answer2.  Try again."
fi
done

Open in new window

vocogovCommented:
oops.. posted to wrong place.  Ugh.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.