Bash if statement produces different result with exclamation mark in different positions - bash

My first question is why putting ! in the front of if statement fails to produce syntax error when status is not double quoted. That is how is [ ! $x = "string" ] different from
[ $x != "string" ]?
My script is as follows.
#!/bin/bash
status=" "
# Comparison 1: without error
echo "-----Comparison 1-----"
if [ ! $status = "success" ]
then echo 'Error: status was not success but: ' $status
else
echo "The status is success."
fi
echo "-----Comparison 2-----"
# Comparison 2: with error message but still shows success
if [ $status != "success" ]
then echo 'Error: status was not success but: ' $status
else
echo "The status is success."
fi
echo "-----Comparison 3-----"
# Comparison 3: Correct result after quoting status
if [ ! "$status" == "success" ]
then echo 'Error: status was not success but: ' $status
else
echo "The status is success."
fi
echo "-----Comparison 4-----"
# Comparison 4: Correct result after quoting status
if [ "$status" != "success" ]
then echo 'Error: status was not success but: ' $status
else
echo "The status is success."
fi
The output is
-----Comparison 1-----
The status is success.
-----Comparison 2-----
./test2.sh: line 14: [: !=: unary operator expected
The status is success.
-----Comparison 3-----
Error: status was not success but:
-----Comparison 4-----
Error: status was not success but:
Additional questions
Why does it produce "The status is success." in Comparison 2 after a syntax error? How would a syntax error in an if statement affects the evaluated result of such if statement?
p.s. I know we need "" around $status to make output right.

You need to quote $status. Without the quotes, your first comparison is
if [ ! = "success" ]
which will fail because ! and success are not equal strings.
Your second one results in a syntactically invalid expression for [:
if [ != "success" ]
The syntax error you see in condition 2 isn't a shell syntax error, but a condition syntax error raised by the [ command. The command itself runs fine, but exits with a non-zero exit status.

Related

shell script if condition giving error message in openshift platform . if[ == ] : not found [No such file or directory ]

I've implemented script like below:
podName=someValue ; // Here value is dynamic (empty or non empty)
if[ $podName == " "] then
echo "Empty"
Even though I got empty an output but still could see:
if[ == ] : not found [No such file or directory ]
error message while running the script.
Seems like there is a small formatting issue which is causing this error. This should be the correct code.
podName=someValue
if [ "$podName" == " " ]; then
echo "Empty"
fi
You can check if the string is empty in bash / sh like this (some containers don't have bash shell):
podName="someValue"
if [ -z "$podName" ]; then
echo "Empty"
fi
or:
podName="someValue"
if [ "$podName" = "" ]; then
echo "Empty"
fi
The following syntax works only in bash [ "$podName" == "" ]

Check return value of command in if bash statement

I have a simple script that tries to curl and URL and echo a string if it failed or succeeded. But I get the following warnings, depending on how I form this if statement.
Depending on the quotes I use in the statement below I get the following warnings:
: -ne: unary operator expected
: integer expression expected
With the alternative check (as comment), I get the following error
((: != 0 : syntax error: operand expected (error token is "!= 0 ")
The script:
c=`curl -s -m 10 https://example.com` || ce=$?
#if (( ${je} != 0 )); then
if [ ${ce} -ne 0 ]; then
echo "Failed"
else
echo "Succeeded"
fi
How do I correctly check the return value of the curl command in a bash if-statement?
The problem is that you only set the exit status when the curl command fails.
If the command succeeds, then variable ce is not set (and also not quoted) and the test executes if [ -ne 0 ]; then and prints the error message.
Quoting the variable alone wouldn't help in this case, you would just get a different error message.
To fix this, set variable ce after the curl command no matter what the exit status of the curl command is:
c=$(curl -s -m 10 https://example.com)
ce=$?
if [ "$ce" -ne 0 ]; then
echo "Failed"
else
echo "Succeeded"
fi
Or shorter without exit status variable:
c=$(curl -s -m 10 https://example.com)
if [ $? -ne 0 ]; then
echo "Failed"
else
echo "Succeeded"
fi

Shell Script won't fail in Jenkins

I have a simple shell script which I want to set up as a periodic Jenkins job rather than a cronjob for visibility and usability for less experienced users.
Here is the script:
#!/bin/bash
outputfile=/opt/jhc/streaming/check_error_output.txt
if [ "grep -sq 'Unable' $outputfile" == "0" ]; then
echo -e "ERROR MESSAGE FOUND\n"
exit 1
else
echo -e "NO ERROR MESSAGES HAVE BEEN FOUND\n"
exit 0
fi
My script will always return "NO ERROR MESSAGES HAVE BEEN FOUND" regardless of whether or not 'Unable' is in $outputfile, what am I doing wrong?
I also need my Jenkins job to class this as a success if 'Unable' isn't found (e.g. If script returns "0" then pass, everything else is fail)
Execute the grep command and check the exit status instead:
#!/bin/bash
outputfile=/opt/jhc/streaming/check_error_output.txt
grep -sq 'Unable' $outputfile
if [ "$?" == "0" ]; then
echo -e "ERROR MESSAGE FOUND\n"
exit 1
else
echo -e "NO ERROR MESSAGES HAVE BEEN FOUND\n"
exit 0
fi
You are comparing two different strings. The outcome will always be false, i.e. the else part is taken.
Also, no need to explicitly query the status code. Do it like this:
if grep -sq 'Unable' $outputfile
then
....
else
....
fi

Bash, issue with if

I'm parsing the result of a curl call into a variable this way:
result=$(curl some curl parameters)
I'm then making a check:
if [ $result != "job completed" ];
then printf "ok"
fi
but I'm getting the following error:
[: too many arguments
any idea why?
It's almost certainly because you haven't stringified the result, meaning that the [ command is being given more than three arguments.
If it contains the string job completed, you will end up with:
if [ job completed != "job completed" ] ...
I suggest you try:
if [ "$result" != "job completed" ] ...

Bash ignore error and get return code

I am using set -e to abort on errors.
But for particular one function I want to ignore error and on error I want return code of the function.
Example:
do_work || true
if [ $? -ne 0 ]
then
echo "Error"
fi
But it is not work return code is always true due || true
How to get return code on do_work on error ?
do_work || {
status=$?
echo "Error"
}
Several of the answers given here are not correct, because they result in a test against a variable that will be un-defined if do_work succeeds.
We need to cover the successful case as well, so the answer is:
set -eu
do_work && status=0 || status=1
The poster's question is a little ambiguous because it says in the text "on error I want return code" but then the code implies "I always want the return code"
To illustrate, here is problematic code:
set -e
do_work() {
return 0
}
status=123
do_work || status=$?
echo $status
In this code the value printed is 123, and not 0 as we might hope for.
You could use a subshell shortcut:
( set +e; do_work )
if [ $? -ne 0 ]
then
echo "Error"
fi
Hope this helps =)
One way is to use a pipe, -e only looks at the right-most result of a pipe:
set -e
do_work | true
retn=${PIPESTATUS[0]}
if (( $retn != 0 ))
then
echo "Error $retn"
fi
echo Ending
I wrote a simple do_work which just did exit 42 and got the following output:
Error 42
Ending
The PIPESTATUS array is maintained by Bash, with each element giving the return code of each part of the pipeline. We need to capture it at once (hence $retn) since it is overwritten at each command.
Of course this might be problematic if your do_work includes a pipe itself.
do_work || status=$?
if [ $status -ne 0 ]
then
echo "Oh no - Fail whale $status has arrived"
fi

Resources