The following bash script is giving me problems:
#!/bin/bash
if [[ $VAR -eq "<EMPTY>" ]]; then echo "Hello World!"; fi
Bash fails, complaining:
line 3: [[: <EMPTY>: syntax error: operand expected (error token is "<EMPTY>")
How can I test if the string contained in VAR is equivalent to the string "<EMPTY>"?
You are using the wrong operator. == is for strings, -eq is for numbers.
#!/bin/bash
if [[ $VAR == "<EMPTY>" ]]; then echo "Hello World!"; fi
Inside [[ ... ]], -eq has a different meaning: it is used to compare integers. You can use (( ... )) to compare integeres with normal operators, though. Use the following for strings:
[[ $VAR == "<EMPTY>" ]]
Related
I am trying to understand the logic of Bash algorithm.
When I tried this, it printed "a":
a=a;[ $a == "a" ] && echo $a
So far so good. Then I tried the following and it printed "a" again:
a=a;[[ $a == "a" ]] && echo $a
Now I introduced an error by using arithmetic comparison:
a=abc;[ $a -eq "abc" ] && echo $a
I got an error message that makes sense:
-bash: [: abc: integer expression expected
Then I tried to do this with double bracket and got no error, but "abc":
a=abc;[[ $a -eq "abc" ]] && echo $a
I can sort of explain it (bash is trying to be accomodating), but then I got something that puzzles me. If I do that, I get an error message about recursion:
a=a;[[ $a -eq "a" ]] && echo $a
-bash: [[: a: expression recursion level exceeded (error token is "a")
If I use single brackets, there is no recursion but a reasonable error "integer expression expected":
a=a;[ $a -eq "a" ] && echo $a
-bash: [: abc: integer expression expected
This is weird. What Bash is trying to do in that "recursion" case with double brackets? I am talking about:
a=a;[[ $a -eq "a" ]] && echo $a
-bash: [[: a: expression recursion level exceeded (error token is "a")
It's trying to coerce a into a numeric form. It does this by treating its contents as a variable name to dereference; when the result of this is a loop, you get a "recursion level exceeded" error.
Thus:
a=b
b=10
[[ $a -eq 10 ]]
...is true.
In Xcode 8 I have a Run Script that is comparing a string to a regex:
if [ "$MOBILE_BUNDLE_IDENTIFIER" =~ ".+(Debug)" ]
then
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Debug
elif [ "$MOBILE_BUNDLE_IDENTIFIER" =~ ".+(Test)" ]
then
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Production
elif [ "$MOBILE_BUNDLE_IDENTIFIER" =~ ".+(ProductionTest)" ]
then
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Test
else
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Store
fi
The variable $MOBILE_BUNDLE_IDENTIFIER will be one of the following:
com.cnt.Filer
com.cnt.Filer.ProductionTest
com.cnt.Filer.Debug
com.cnt.Filer.Test
When I run this I get the following error:
line 4: [: =~: binary operator expected
line 7: [: =~: binary operator expected
line 10: [: =~: binary operator expected
In the full script lines 4, 7 and 10 are the then statements.
Does anyone know how I can successfully compare my variable to the regex?
You should be using [[ string =~ regex ]] for regex in BASH
Don't quote regex
Looks like you don't even need regex, you can just do string comparison using ==
Your script can be this:
if [[ $MOBILE_BUNDLE_IDENTIFIER == *Debug* ]]; then
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Debug
elif [[ $MOBILE_BUNDLE_IDENTIFIER == *Test* ]]; then
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Production
elif [[ $MOBILE_BUNDLE_IDENTIFIER == *ProductionTest* ]]; then
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Test
else
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Store
fi
PS: You may also consider using case
case "$MOBILE_BUNDLE_IDENTIFIER" in
*Debug*)
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Debug
;;
*Test*)
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Production
;;
*ProductionTest*)
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Test
;;
*)
RESOURCE_PATH=${SRCROOT}/Resources/Clients/Cnt/Files/Store
;;
esac
I found this question for how to do conditional assignment in bash, but what I'm trying to do is a little more complex, and I can't seem to get the syntax right. The condition in my case is to test a variable to see if it exists, and the output is concatenated to a string.
Here's what I have so far:
fwversion="${BASH_REMATCH[1]}.$(( [[ BASH_REMATCH[2] ]] ? BASH_REMATCH[2] : 0 ))"
Which produces this error message:
bash: line 41: [[ BASH_REMATCH[2] ]] ? BASH_REMATCH[2] : 0 : syntax error:
operand expected (error token is "[[ BASH_REMATCH[2] ]] ? BASH_REMATCH[2] : 0 ")
Here's what I'm trying to achieve as C++ code:
std::string fwversion = BASH_REMATCH[1] + "." + ((BASH_REMATCH[2]) ? : BASH_REMATCH[2] : 0);
What's the correct syntax to do this in bash? Thanks.
Looks like [[ ... ]] are not understood in an arithmetic expression.
I'd do this:
fwversion=${BASH_REMATCH[1]}
[[ ${BASH_REMATCH[2]} ]] && fwversion+=${BASH_REMATCH[2]} || fwversion+=0
or
[[ ${BASH_REMATCH[2]} ]] && ext=${BASH_REMATCH[2]} || ext=0
fwversion="${BASH_REMATCH[1]}.$ext"
On second thought, I wouldn't do that at all, I'd use the power of the shell's parameter expansion
str="foo:bar"
if [[ $str =~ ^([a-z]+):([a-z]*)$ ]]; then
echo "${BASH_REMATCH[1]}.${BASH_REMATCH[2]:-0}"
fi
foo.bar
str="foo:"
if [[ $str =~ ^([a-z]+):([a-z]*)$ ]]; then
echo "${BASH_REMATCH[1]}.${BASH_REMATCH[2]:-0}"
fi
foo.0
I'm trying to check if string contains any wildcards.
Here is my failing attempt:
#!/bin/bash
WILDCARDS='* . ? ! ] ['
a="foo*bar"
for x in $REJECTED_WILDCARDS
do
if [[ "$a" == *"$x"* ]]
then
echo "It's there!";
fi
done
Any suggestions?
Slightly shorter and without a loop:
if [ "$a" != "${a//[\[\]|.? +*]/}" ] ; then
echo "wildcard found"
fi
The parameter substitution deletes all wildcards.
The strings are than no longer equal.
Set wildcards into a bash array, like so
wildcards=( '*' '.' '?' '|' ']' '[' )
Then
a="foo*bar"
for wildcard in "${wildcards[#]}";
do
if [[ $a == *"${wildcard}"* ]];
then
echo 'yes';
fi;
done
if [[ $line == *"option 1"* ]]
then
CURRENT_OPTION=1
fi
if [[ $line == *"option 2"* ]]
then
CURRENT_OPTION=2
fi
if [[ $line =~ "What i want" ]]
then
if [[ $CURRENT_OPTION -eq 1 ]]
then
MEM1=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }')
elif [[ $CURRENT_OPTION -eq 2 ]]
then
MEM2=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }')
fi
fi
Because CURRENT_OPTION is defined within an if, its value is not correct when checked in the third if. How do I pass it out so that it is?
Just declare CURRENT_OPTION at the top, something like:
declare -i CURRENT_OPTION=0
i to declare it as an int.
In all of your if statements you should enclose the variables in double quotes. If the variable is an empty string (or if the variable doesn't exist) then the if statement will not contain enough arguments and will throw an error.
Here is an example:
if [[ $var -eq 1 ]]
then
echo yes
else
echo no
fi
If var is uninitialised, bash will expand the statement to look like this:
if [[ -eq 1 ]]
then
echo yes
else
echo no
fi
There are not enough arguments to make the if statement valid here, and bash will throw an error:
bash: conditional binary operator expected
bash: syntax error near `1'
By wrapping the variable in quotes, this situation is avoided. This statement:
if [[ "$var" -eq 1 ]]
...
is expanded to:
if [[ "" -eq 1 ]]
...
and now the if statement has enough arguments (the first one being an empty string) to parse.