How to use the exit status from a function within my script - bash

I have a script and within it I call a function. How can I use the exit status from the function to print a message, without incorporating the message inside the function?
I am supposed to write a script which has:
Your script should contain a function increasingNos that uses three parameters. All three parameters should be integers. The function is a "success" (with exit status 0) if there are exactly three parameters and they are numbers in increasing order. The function should have an exit status of 1 if there are three parameters but they are not in increasing order. The function should should have an exit status of 2 if there are fewer or more than 3 parameters.
and...
you should print an appropriate message to the standard output after calling increasingNos with parameters 17 5 23 to say whether or not there were three parameters and whether or not they were numbers in increasing order. Use an if conditional and the exit status on your function call to do this. This if conditional may not be in the function increasingNos.
This is what I have come up; whenever I run the script, it exits when the function call hits an exit status. How can I execute the rest of the script?
increasingNos(){
if [ $# -ne 3 ];then
exit 2
fi
if [ $1 -ge $2 ] || [ $2 -ge $3 ];then
exit 1
else
exit 0
fi
}
increasingNos 17 5 23
if [ $? -eq 2 ];then
echo "You did not supply exactly 3 integer parameters!"
fi
if [ $? -eq 1 ];then
echo "Your parameters were not input in increasing order!"
fi
if [ $? -eq 0 ];then
echo "Congrats, you supplied 3 integers in increasing order!"
fi

Use return instead of exit and save the value of $? in a variable, because it will change after the first test.
This works:
increasingNos(){
if [ $# -ne 3 ];then
return 2
fi
if [ $1 -ge $2 ] || [ $2 -ge $3 ];then
return 1
else
return 0
fi
}
increasingNos 17 5 23
stat=$?
if [ $stat -eq 2 ];then
echo "You did not supply exactly 3 integer parameters!"
fi
if [ $stat -eq 1 ];then
echo "Your parameters were not input in increasing order!"
fi
if [ $stat -eq 0 ];then
echo "Congrats, you supplied 3 integers in increasing order!"
fi

You need to use return rather than exit in your functions.

Related

If statement not evaluated correctly

I have a simple bash function that returns 3 numerical values: 0, 1, 2
When testing for the return value I get the correct value depending on the one returned from the function. # echo $? -> 0, 1, 2
However, when using an if-else statement the return value is not evaluate as I expected. For example when the function returns value = 2 in the if-else statement the elif [ $? -eq 1 ]; then is choosen
if [ "$?" -eq "0" ]; then
echo "0"
elif [ "$?" -eq "1" ]; then
echo "1"
elif [ "$?" -eq "2" ]; then
echo "2"
else
echo "Incorrect"
fi
Result:
output is: 1
I expect:
output is: 2
Any thoughts.
Cheers,
Roland
By running [ "$?" -eq "0" ] you are changing the value of $?. If you want to compare it several times, store its value into a non-magical variable and compare it instead.
Other option is to use case:
case $? in
(0) echo 0 ;;
(1) echo 1 ;;
(2) echo 2 ;;
(*) echo Incorrect
esac

How do a test if a parameter is a number in a script using expr?

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
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.
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

How to check length of an argument in bash script

how can I check the length of an argument in bash script?
Let's say that the length of an argument should not exceed 1.
args=("$#")
if [ ${args[0] -gt 1]; then
echo "Length of arg. 1 must be 1"
fi
This however doesn't work properly, since it will check if args[0] > 1 and not len(args[0] > 1):
./sth.sh 2 1 1
"Length of arg. 1 must be 1"
LENGTH is 1, but it still echoes.
I also tried this:
args=("$#")
if [ ${#args[0] -gt 1]; then
echo "Length of arg. 1 must be 1"
fi
However, it doesn't echo anything.
You can use this:
if [ "$#" -ne 1 ]; then
echo "Illegal number of parameters"
fi
Or
if test "$#" -ne 1; then
echo "Illegal number of parameters"
fi
Later check the length of each argument like this:
for var in "$#"
do
check=${#var}
if [ $check -ne 1 ]; then echo "error" ; exit
fi
done

check if the argument is a number inside the shell script [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I test if a variable is a number in bash?
I try writing the fibonacci sequence by shell scripting for example if user entered 5 after the script name in the command line the script needs to print out the 5 fibonacci numbers from the beginning which are:
0 1 1 2 3
I have completed the script but I need to check the user input if it is positive number that I have a problem in this part.
in the command line the user should call the script and then enter a positive number
./script number
and this is my code:
#!/bin/sh
[ $# -ne 1 ] && { echo "enter a number please" ; exit 1 ; }
[ ! echo $1 | egrep -q '^[0-9]+$' && $1 -lt 0 ] && { echo "negative" ; exit 1 ; }
f0=0
f1=1
counter=2
if [ $1 -eq 0 ] ; then
echo -n "0"
elif [ $1 -ge 1 ] ; then
echo -n "0 1"
fi
while [ $counter -le $1 ] && [ $1 -gt 1 ] ; do
echo -n "$fn "
fn=`expr $f0 + $f1`
f0=$f1
f1=$fn
counter=`expr $counter + 1`
done
echo ""
if [ $1 -ge 0 2>/dev/null ] ; then
it works for positive numbers equal or greater than 0
Take a look at this:
http://www.bashguru.com/2010/12/how-to-validate-integer-input-using.html
Apparently someone wrote multiple shell scripts to do exactly that.

How to count and check passed arguments?

How can I translate the following Ruby code to Bash?
if ARGV.length == 0
abort "\nError: The project name is required. Aborting...\n\n"
elsif ARGV.length > 2
abort "\nError: The program takes two arguments maximum. Aborting...\n\n"
end
#!/bin/bash
USAGE="$0: <project name> [subproject attribute]"
if [ $# -lt 1 ]; then echo -e "Error: The project name is required.\n$USAGE" >&2; exit 1; fi
if [ $# -gt 2 ]; then echo -e "Error: Two arguments maximum.\n$USAGE" >&2; exit 1; fi
The following should be what you need:
#!/bin/bash
if [ $# -eq 0 ]; then
echo -e "\nError: The project name is required. Aborting...\n\n"
exit 1
elif [ $# -gt 2 ]; then
echo -e "\nError: The program takes two arguments maximum. Aborting...\n\n"
exit 1
fi
The TLDP bash guide is very good if you are looking to learn bash, see TDLP Bash guide.
Maybe:
#!/bin/bash
function functionName {
if [ $# = 0 ]
then echo "\nError: The project name is required. Aborting...\n\n"; exit 1
fi
if [ $# \> 2 ]
then echo "\nError: The program takes two arguments maximum. Aborting...\n\n"; exit 1
fi
}
functionName a

Resources