Why is it an error if string starts with a slash?
[[ "/a" -eq "a" ]]
-bash: [[: /a: syntax error: operand expected (error token is "/a")
Seems a bit unexpected.
Problem is not / but use of -eq operator, which is used for integer equality in shell.
If you change -eq with = then error will not be there:
[[ "/a" = "a" ]] && date || pwd
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.
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.
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 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>" ]]