Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I have a function which returns 1 if the number is a valid ten digit number:

valNum()
{
    flag=1
    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=0
    fi
    return $flag
}

It is getting called by:

if [[ $(valNum $num) -eq 1 ]]; then
      #do something
fi

The function is working fine if the number is valid but is showing syntax error if input a invalid number.

share|improve this question

3 Answers 3

up vote 5 down vote accepted

@choroba's answer is correct, however this example might be clearer:

valNum $num
valNumResult=$? # '$?' is the return value of the previous command
if [[ $valNumResult -eq 1 ]]
then
  : # do something
fi

This example is a little longer (setting $valNumResult then querying that value), but more-explicitly describes what happens: that valNum() returns a value, and that value can be queried and tested.

P.S. Please do yourself a favor and return 0 for true and non-zero for false. That way you can use the return value to indicate "why we failed" in the failure case.

share|improve this answer

Functions in bash can only return exit codes. The command substitution, conversely, is used to get the standard output of a command or function. Therefore, to check the returned flag, you do not need the substitution:

if valNum "$num" ; then
    # ...
fi

But, for it to work, you should return 0 if the number is valid, and 1 if it is not (exit code 0 means no error).

share|improve this answer
    
I dont get it. In the example 24.7 in tldp.org/LDP/abs/html/complexfunct.html the function is returning the max value and not the exit code. Though your suggestion is working but I am not able to understand why it is working –  user2179293 Sep 15 '13 at 7:44
1  
since your test is to find out if the input is a valid 10-digit integer or not, i.e. true or false, the function returns either 0 or 1. choroba's example works because if valnum "$num" is equivalent to if valnum "$num" = 0 i.e. "if it is true". basic rule of thumb in sh scripting is that 0 = true/success, non-zero = false/error. –  cas Sep 15 '13 at 8:10
1  
BTW, that "Advanced Bash-Scripting Guide" isn't a very good guide - it's wrong about a lot of things and encourages some poor scripting practices. the Bash FAQ at mywiki.wooledge.org/BashFAQ is much better resource. –  cas Sep 15 '13 at 8:12
    
see unix.stackexchange.com/questions/12236/… –  cas Sep 15 '13 at 8:14
    
your function is failing because it is echo-ing the string "Invalid Number", and you then doing a numeric comparison between that string and the number 1 with if [[ $(valNum $num) -eq 1 ]] –  cas Sep 15 '13 at 8:19

You cannot return an arbitrary result from a shell function. You can only return a status code which is an integer between 0 and 255. (While you can pass a larger value to return, it is truncated modulo 256.) The value must be 0 to indicate success and a different value to indicate failure; by convention you should stick to error codes between 1 and 125, as higher values have a special meaning (bad external command for 126 and 127, killed by a signal for higher values).

Since you are returning a yes-or-no result here, a status code is appropriate. Since flag seems to indicate a success or failure, you should use the conventional values of 0 for success and 1 for failure (the opposite of what you wrote). You can then use your function directly in an if statement.

valNum ()
{
  local flag=0
  if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
    echo 1>&2 "Invalid Number"
    flag=1
  fi
  return $flag
}
if valNum "$num"; then
  #do something
fi

If you need to discriminate between failure codes, call the function directly. Immediately after it returns, the failure code is available in $?. You can then check it with a case statement:

valNum "$num"
case $? in …

If you need to use the status code later, save it into another variable before $? is overwritten by the next command.

valNum "$num"
valNum_status=$?

What you wrote didn't work because the command substitution $(…) expands to the output of the function, which in your code is either the error message or empty, never 1.

If you need to pass more information than a status code allows out of a shell functions, you have two possibilities:

  • Print some text on standard output, and call the function in a command substitution: $(valNum "$num")
  • Assign to one or more variable inside the function and read those variables later.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.