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
Related
I am trying to check if the the variable $userSelection is not having value 1, 2 or 3, then I display error message. Tried the following and other combinations, but no luck.
if [ $userSelection -ne 1 || $userSelection -ne 2 ] || [ $userSelection -ne 2 || $userSelection -ne 3 ]
then
echo "Option selected not valid...please try again."
fi
Am getting error [: missing]'`.
For your actual needs the right code should be the following:
if [ "$userSelection" -ne 1 ] && [ "$userSelection" -ne 2 ] && [ "$userSelection" -ne 3 ]
then
echo "Option selected not valid...please try again."
fi
From what you are saying the only right choices should be 1,2 or 3.
Missing brackets aside, the simplest way to make such a check is with a case statement instead:
case $userSelection in
1|2|3) ;;
*) echo "Option selected not valid...please try again." ;;
esac
I'm nearly done writing a script for an assignment, but am having some trouble thinking of how to do this final part.
My problem is within a while loop; it prints out the number based on the IF statements, the number entered will always be an even number.
The IFs aren't connected by else/elif because the number should be able to printed out if it applies to more than 1 of the statements.
I want to print $starting on every loop if it doesn't meet any of the IF conditions, but if it does I don't want to print it. Can anyone see how to do that?
while [[ $starting -lt $ending ]]; do
if [ $((starting %7)) -eq 0 ]
then
echo "$starting red"
fi
if [ $((starting % 11)) -eq 0 ]
then
echo "$starting green"
fi
if [ $((starting % 13)) -eq 0 ]
then
echo "$starting blue"
fi
starting=$((starting + 2))
done
Keep track of whether you've done what you want to do in a variable:
while [[ $starting -lt $ending ]]; do
handled=0
if [ $((starting %7)) -eq 0 ]
then
echo "$starting red"
handled=1
fi
if [ $((starting % 11)) -eq 0 ]
then
echo "$starting green"
handled=1
fi
if [ $((starting % 13)) -eq 0 ]
then
echo "$starting blue"
handled=1
fi
if ! (( handled ))
then
echo "$starting didn't match anything"
fi
starting=$((starting + 2))
done
Add another if at the end that checks if none of the previous if statements are true. if !(starting%7==0 or starting%11==0 or starting%13==0) => echo starting
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.
I was modifying an script didn't know how to write more than one condition in an if statement. I want to connect the two condition with an AND.
if [ envoi1 -eq 2 ];then
if [ envoi2 -eq 0 ];then
echo 'Ahora mismo.'
envoi = 1
fi
else
if [ envoi2 -eq 1 ];then
if [ envoi1 -eq 1 ];then
echo 'Situacion Normal.'
envoi = 1
fi
else
echo 'Raruno'
envoi=`expr $envoi1 + envoi2`
fi
fi
Now i use nested if to do the same but the code it's not so clear for me.
try this:
if [ $envoi1 -eq 2 ] && [ $envoi2 -eq 0 ] ; then
envoi = 1
fi
In bash, you can use [[ as follows:
if [[ $envoi2 -eq 1 && $envoi1 -eq 1 ]]; then
echo "Situacion Normal."
envoi=1
fi
However, [[ is not POSIX and will not work if you are using the /bin/sh shell. So if portability is desired use:
if [ $envoi2 -eq 1 -a $envoi1 -eq 1 ]; then
echo "Situacion Normal."
envoi=1
fi
Also note that when assigning variables you should not have any spaces on either side of the =.
My current script does the following;
It takes integer as a command line argument and starts from 1 to N , it checks whether the numbers are divisible by 3, 5 or both of them. It simply prints out Uc for 3, Bes for 5 and UcBes for 3,5. If the command line argument is empty, it does the same operation but the loop goes to 1 to 20.
I am having this error "Too many arguments at line 11,15 and 19".
Here is the code:
#!/bin/bash
if [ ! -z $1 ]; then
for i in `seq 1 $1`
do
if [ [$i % 3] -eq 0 ]; then
echo "Uc"
elif [ i % 5 -eq 0 ]; then
echo "Bes"
elif [ i % 3 -eq 0 ] && [ i % 5 -eq 0 ]
then
echo "UcBes"
else
echo "$i"
fi
done
elif [ -z $1 ]
then
for i in {1..20}
do
if [ i % 3 -eq 0 ]
then
echo "Uc"
elif [ i % 5 -eq 0 ]
then
echo "Bes"
elif [ i % 3 -eq 0 ] && [ i % 5 -eq 0 ]
then
echo "UcBes"
else
echo "$i"
fi
done
else
echo "heheheh"
fi
Note that [ is actually synonym for the test builtin in shell (try which [ in your terminal), and not a conditional syntax like other languages, so you cannot do:
if [ [$i % 3] -eq 0 ]; then
Moreover, always make sure that there is at least one space between [, ], and the variables that comprise the logical condition check in between them.
The syntax for evaluating an expression such as modulo is enclosure by $((...)), and the variable names inside need not be prefixed by $:
remainder=$((i % 3))
if [ $remainder -eq 0 ]; then
You should probably use something like :
if [ $(($i % 3)) -eq 0 ]
instead of
if [ $i % 3 -eq 0 ]
if [ [$i % 3] -eq 0 ]
Your script could be greatly simplified. For example:
#!/bin/sh
n=0
while test $(( ++n )) -le ${1:-20}; do
t=$n
expr $n % 3 > /dev/null || { printf Uc; t=; }
expr $n % 5 > /dev/null || { printf Bes; t=; }
echo $t
done
gives slightly different error messages if the argument is not an integer, but otherwise behaves the same.