This question already has answers here:
Shell equality operators (=, ==, -eq)
(4 answers)
Closed 4 years ago.
i am studying shell script right now. I started to learn how to work with more complex if statements. What's wrong with this code bellow? I read other similar questions here in stackoverflow, but i couldnt resolve my problem. Now im verifying if the first, second or third argument is null. In the future i pretend to verify based in some regex or something like that.
Thanks!!
The code (line 9):
if [ "$1" -eq "" ] || [ "$2" -eq "" ] || [ "$3" -eq "" ] then ...
line 9: [: : integer expression expected line 9: [: : integer
expression expected line 9: [: : integer expression expected
-eq performs an arithmetic comparison between two numbers. Use = for string comparisons. Or better yet, use [[ and ==.
[[ $1 == "" ]]
[ "$1" = "" ]
You can also use -z and -n to directly test whether a value is empty/non-empty.
[[ -n $value ]] # [[ $value != "" ]]
[[ -z $value ]] # [[ $value == "" ]]
use [[ and ]] for the more modern / complex operators. This is a bashism, so beware.
Related
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 have seen similar situations but couldn't really figure out how to correctly apply the suggested solutions to my situation.
I have a bash script with the following lines:
LAST=$(ssh root#host ls /backup3/mycomp/partition1/ | tail -1)
#get last backup dir (formatted YYYY-MM-DD/). If none exist then get yesterdays Date
if [[ -z "$LAST" || "$LAST" -eq "$TODAY" ]]
then
log "/backup3/$HOST/$NAME/ does not exist, probably first backup or second backup done today."
LAST="$YESTERDAY"
fi
When I run this, I get the following error:
[[: 2014-11-08: value too great for base (error token is "08")
because I am actually searching for physical directory names, I cant just remove the zero. How would I go about making this work?
Replace:
if [[ -z "$LAST" || "$LAST" -eq "$TODAY" ]]
With:
if [[ -z "$LAST" || "$LAST" == "$TODAY" ]]
Since dates are not valid numbers, you want to do string comparison (==) not numeric comparison (-eq).
Discussion
Observe:
$ [[ "10-1" -eq "9" ]] && echo True
True
$ [[ "6+3" -eq "9" ]] && echo True
True
In the numeric context, signaled -eq, the shell is doing arithmetic on the arguments. This means that, for your date 2014-11-08, the shell was taking 2014, subtracting 11, and then trying to subtract 08. The shell treats any number that begins with a 0 as octal. Since 08 is not a valid octal number, you received an error message.
Comparison of [ and [[
As Jonathan Leffler points out, the implied arithmetic feature of [[ is another subtle difference between the old [ and the newer [[. Observe:
$ [[ "6+3" -eq "9" ]] && echo True
True
$ [ "6+3" -eq "9" ] && echo True
bash: [: 6+3: integer expression expected
The implied arithmetic feature of [[ is not present in [.
I'm trying to write a shell script, but it's giving me a syntax error at the following command:
if [[ -n ${array[$x1]} -a [ expr length "$x1" -gt 2 ] ]]
This is the error message:
./project: line 45: syntax error in conditional expression
./project: line 45: syntax error near `-a'
./project: line 45: ` if [[ -n ${array[$x1]} -a [ expr length "$x1" -gt 2 ] ]]'
What am I doing wrong?
Use && not -a in [[ ]]
Also, expr length won't do what you expect here. The better approach, since you're already using bash extensions, is to use the ${#param} expansion to get the length of $param, and evaluate that within a math context, like so:
if [[ -n ${array[$x1]} ]] && (( ${#x1} > 2 )); then
...
fi
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>" ]]