Why is this bash IF statement not working? - bash

if [[ $DATA == *?xml* ]]
then
if [[ $DATA == *misuse* ]]
then echo "Misuse" >> $OUTPUTPAST2
else echo "All Good" >> $OUTPUTPAST2
fi
else echo "Not xml" >> $OUTPUTPAST2
fi
Where $DATA does not contain the string ?xmlI am expecting an output of Not xml, but I am getting output of All Good.
What am I doing wrong?

? is special character in glob which means match any single character.
Use it like this:
if [[ "$DATA" == *'?xml'* ]]
then
if [[ "$DATA" == *misuse* ]]
then echo "Misuse" >> $OUTPUTPAST2
else echo "All Good" >> $OUTPUTPAST2
fi
else
echo "Not xml" >> $OUTPUTPAST2
fi

While quoting the question mark will suffice to solve your immediate problem, this looks like code which really really wants to be a case statement instead.
case $DATA in
*'?xml'*misuse* | *misuse*'?xml'*)
echo Misuse ;;
*'?xml'*) echo All Good ;;
*) echo Not xml;;
esac >>$OUTPUTPAST2
Notice also how the redirection can go after the entire block, to avoid a lot of repetition.
(If "misuse" can only go after the "?xml" marker, you can simplify.)

Related

`line 1: syntax error near unexpected token `newline'` when run bash `case` function

#!/bin/bash
set -e
deb_folder='/home'
myinstall(){
deb=$1
temp="${1%.*}"
num="${temp##*.}"
temp2="${temp%.*}"
method="${temp2##*.}"
case "$method" in
md5)
md5=md5sum $deb
echo 'here'
if [[ "${md5:0:3}${md5: -3}" == "$num" ]]; then echo 'correct' else echo $deb'md5 error';false;fi
;;
256)
sha256=sha256sum $deb
if [[ "${sha256:0:3}${sha256: -3}" == "$num" ]]; then apt-get install $deb; else echo $deb'sha256 error';false;fi
;;
*) echo $deb'sum type wrong'
;;
esac
}
myinstall "${deb_folder}/rstudio-1.4.1106-amd64.md5.e596d3.deb"
Expect result of above bash script is correct or /home/rstudio-1.4.1106-amd64.md5.e596d3.debmd5 error,but I got here after change md5=md5sum $deb to md5=$(md5sum $deb).
Where is the problem?
Problem 1
Instead of md5=md5sum $deb you probably meant md5=$(md5sum $deb) or even better md5=$(md5sum "$deb"). The same goes for sha256=sha256sum $deb.
md5=$(md5sum $deb) runs the command md5sum $deb and stores its output in the variable md5.
md5=md5sum $deb runs the "command" $deb while setting the environment variable md5=md5sum for this command. You may have seen this construct in idioms like IFS= read -r line or LC_ALL=C sort before.
Problem 2
The following if has only one branch. That else is very misleading.
if [[ "${md5:0:3}${md5: -3}" == "$num" ]]; then echo 'correct' else echo $deb'md5 error';false;fi
If written properly formatted, the problem becomes clear:
if [[ "${md5:0:3}${md5: -3}" == "$num" ]]; then
echo 'correct' else echo $deb'md5 error'
false
fi
Here the else is not a keyword, but a simple argument to echo. If you enter the if you would get the output correct else echo /home/rstudio-1.4.1106-amd64.md5.e596d3.debmd5 error.
To fix this, add a ; or linebreak before else.
You may as well fix the check "${md5:0:3}${md5: -3}" == "$num". I don't think these things will ever be equal. Execute your script with set -x to print the values of your variables, then you see the problems.

Bash if statement gives opposite response than expected

I think i'm missing something very obvious. But shouldn't the following code produce the opposite response? I thought if the statement "if s == d" is used and s is not equal to d then the if statement should return false and not run the following code. This is not what appears to happen. Can anyone explain what i've missed. I think it's something very obvious.
Thanks
s=2
d=3
if ! [ "$s == $d" ]; then echo "hello"; fi
if [ "$s == $d" ]; then echo "hello"; fi
hello
You are quoting the entire string "$s == $d" when you should be quoting the two arguments "$s" and "$d".
This means that instead of comparing $s to $d, you are checking whether "2 == 3" is a non-empty string (which it is).
This will correctly print "not equal":
s=2
d=3
if ! [ "$s" == "$d" ]; then echo "not equal"; fi
if [ "$s" == "$d" ]; then echo "equal"; fi

compare three or more variables are not equal in bash

I can't figure how to detect equality and return equal vars, tried many way with this thread
tag="AA"
prst_tag[1]="BB"
prst_tag[2]="CC"
prst_tag[3]="AA"
prst_tag[4]="EE"
What i exactly want to do:
if $tag or ${prst_tag[1]} or ${prst_tag[2]} or ${prst_tag[3]} or ${prst_tag[4]} have equal value; then
echo "equal TAG found"
echo "tag: $tag"
echo "prst_tag[1]: ${prst_tag[1]}"
echo "prst_tag[2]: ${prst_tag[2]}"
echo "prst_tag[3]: ${prst_tag[3]}"
echo "prst_tag[4]: ${prst_tag[4]}"
fi
Help appreciated
I really didn't understand your question, but i assume you want to compare strings. Here is example how to compare string with array of strings:
tag="AA"
prst_tag[1]="BB"
prst_tag[2]="CC"
prst_tag[3]="AA"
prst_tag[4]="EE"
found=false
for i in "${prst_tag[#]}"
do
if [ "$tag" = "$i" ]; then
found=true
fi
done
if [ "$found" = "true" ];then
echo "equal TAG found"
else
echo "equal TAG not found"
fi

Bash: If line begins with >

I want an if/then statement in Bash and I can't seem to get it to work. I would like to say "If the line begins with > character, then do this, else do something else".
I have:
while IFS= read -r line
do
if [[$line == ">"*]]
then
echo $line'first'
else
echo $line'second'
fi
done
But it isn't working.
I also tried to escape the ">" by saying:
if [[$line == ^\>*]]
Which didn't work either.
Both ways I am getting this error:
line 27: [[>blah: command not found
Suggestions?
Spaces are needed inside [[ and ]] as follows:
if [[ "$line" == ">"* ]]; then
echo "found"
else
echo "not found"
fi
This attempt attempt uses a regex:
line="> line"
if [[ $line =~ ^\> ]] ; then
echo "found"
else
echo "not found"
fi
This one uses a glob pattern:
line="> line"
if [[ $line == \>* ]] ; then
echo "found"
else
echo "not found"
fi
Spacing is important.
$ [[ ">test" == ">"* ]]; echo $?
0
$ [[ "test" == ">"* ]]; echo $?
1
if grep -q '>' <<<$line; then
..
else
..
fi
using grep is much better :)

Shell script check if variable contains spaces

I am new to shell scripting. I have a variable containing path to specific file. I want to check if this variable has any spaces in it.
I tried with
if [[ ${VAR} = "${VAR% *}" ]] ; then
echo "contains spaces"
else
echo "doesnot contain spaces"
fi
But it doesn't work. Any help will be really appreciable.
or
case ${VAR} in
*\ * ) echo "VAR=$VAR has at least one space char" ;;
* ) echo "VAR=$VAR has no space chars" ;;
esac
IHTH
Good solution but you need to reverse the conditions. ${VAR% *} strips up to the last space, so if it is equal to ${VAR} then there weren't any spaces.
You should escape the first ${VAR} in "" as well in case it is empty.
if [[ "${VAR}" == "${VAR% *}" ]] ; then
echo "doesn't contains spaces"
else
echo "contains spaces"
fi
Another solution:
echo $VAR | grep ".*\s.*" && echo "Space exists" || echo "No space exists"

Resources