beer9
asked on
How following if statement works in bash script?
bash-4.1$ if grep -q sh 1.txt; then echo found; else echo not found; fi
found
bash-4.1$ if grep -q she 1.txt; then echo found; else echo not found; fi
not found
bash-4.1$ cat 1.txt
bash
grep would return 0 if there is match and 1 if there is no match. I assume 0 is false but I getting 'found' output. What is happening here. Please help me to understand it. Thanks!
ASKER
"if" is using the exit status.. so if grep return 1 ( not found) then that is "true" and it should print "found" but it is printing "not found".
How is it working here?
How is it working here?
Why don't you try something like
if (( grep -c sh 1.txt > 0 )); then echo found; else echo not found; fi
if (( grep -c sh 1.txt > 0 )); then echo found; else echo not found; fi
"if" is using the exit status.. so if grep return 1 ( not found) then that is "true"
No. A non zero status is false if you are using an if test.
I'm a little confused as to what the issue is.
Your code is correct and your results are correct.
Your code is correct and your results are correct.
Well if you use the operators right, you get what you want
if [[ $(grep sh 1.txt) ]]; then echo found; else echo not found; fi
Within [[ ]], exit status of 0 is true and yes you don't need -q.
if [[ $(grep sh 1.txt) ]]; then echo found; else echo not found; fi
Within [[ ]], exit status of 0 is true and yes you don't need -q.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi farzanj, here are four different ways which is creating more confusion to me.
above one if there is match then "if" gets 0 and I am using negate to make it correct. which is fine with me
same as above example
above one is mathematical evaluation and 0 means false and 1 is ture. that is also ok
if this one I am failed to understand, if is evaluating 0 as true and 1 as false (grep return 0 if there is match, and return 1 if there is no match)
bash-3.2$ if [[ $(grep -q sh 1.sh) ]] ; then echo good; else echo bad; fi
bad
bash-3.2$ if [[ ! $(grep -q sh 1.sh) ]] ; then echo good; else echo bad; fi
good
bash-3.2$ cat 1.sh
bash
above one if there is match then "if" gets 0 and I am using negate to make it correct. which is fine with me
bash-3.2$ if (( $(grep -q sh 1.sh) )) ; then echo good; else echo bad; fi
bad
bash-3.2$ if ! (( $(grep -q sh 1.sh) )) ; then echo good; else echo bad; fi
good
same as above example
bash-3.2$ if (( 0 )) ; then echo good; else echo bad; fi
bad
bash-3.2$ if (( 1 )) ; then echo good; else echo bad; fi
good
above one is mathematical evaluation and 0 means false and 1 is ture. that is also ok
bash-3.2$ if grep -q sh 1.sh; then echo good; else echo bad; fi
good
bash-3.2$ if ! grep -q sh 1.sh; then echo good; else echo bad; fi
bad
if this one I am failed to understand, if is evaluating 0 as true and 1 as false (grep return 0 if there is match, and return 1 if there is no match)
ASKER
Again, there is one more confusion over using -q of grep. Both are totally opposite
bash-3.2$ if [[ $(grep -q sh 1.sh) ]] ; then echo good; else echo bad; fi
bad
bash-3.2$ if [[ ! $(grep -q sh 1.sh) ]] ; then echo good; else echo bad; fi
good
bash-3.2$ cat 1.sh
bash
bash-3.2$ if [[ $(grep sh 1.sh) ]] ; then echo good; else echo bad; fi
good
bash-3.2$ if ! [[ $(grep sh 1.sh) ]] ; then echo good; else echo bad; fi
bad
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Well, it appears to me that it is not going by exit status at all. Please disregard my earlier comment.
If it sees any output, anything not zero then it is true. If there is no output, or output is zero, it will be false.
if [[ $(grep -q sh 1.sh) ]] ; then echo good; else echo bad; fi
bad
if [[ $(grep sh 1.sh) ]] ; then echo good; else echo bad; fi
good
grep -q sh 1.sh ---- No output
grep sh 1.sh
sh
If it sees any output, anything not zero then it is true. If there is no output, or output is zero, it will be false.
if [[ $(grep -q sh 1.sh) ]] ; then echo good; else echo bad; fi
bad
if [[ $(grep sh 1.sh) ]] ; then echo good; else echo bad; fi
good
grep -q sh 1.sh ---- No output
grep sh 1.sh
sh
ASKER
Thanks Tintin for the clarification.
for below
the exit status is 0 so "if" should fail and print bad. how we are getting "good" instead?
for below
if $(grep -q sh 1.sh) ; then echo good; else echo bad; fi
the exit status is 0 so "if" should fail and print bad. how we are getting "good" instead?
Accept my apology for earlier comment as I think it was not correct.
It is not going by exit status but the output. Zero or no output means false otherwise true.
Reason I am saying this is the exit status of both the statements is 0.
> grep -q sh 1.sh
>echo $?
0
>grep sh 1.sh
sh
>echo $?
0
It is not going by exit status but the output. Zero or no output means false otherwise true.
Reason I am saying this is the exit status of both the statements is 0.
> grep -q sh 1.sh
>echo $?
0
>grep sh 1.sh
sh
>echo $?
0
Let me be even more specific. If there is any output for standard output (No standard error), it is true.
No output means false
No output means false
Another thing: Even output of zero is true. So, it sees output vs. no output.
Just remember in *nix, 0 means success and >0 means not success.
Ultimately all the variations of the if tests will evaluate to a status of 0 (true) or 1 (false).
Ultimately all the variations of the if tests will evaluate to a status of 0 (true) or 1 (false).
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
So when grep successfully matches something, it has an exit status of 0 and when grep doesn't match anything, it has an exit status of 1