Does not work to execute command in double brackets in bash
The short answer is:
[
and[[
expect an expression.if
expects a command.
Saying:
[[ $(command) ]]
would essentially execute:
[[ -n <command_output> ]]
which may or may not be what you want. On the other hand, saying:
$command && echo something || echo other
would echo something
or other
based on the return code of the command (0
and non-zero respectively).
bash double bracket issue
The problem lies in your script invocation. You're issuing:
$ sudo sh if_test.sh
On Ubuntu systems, /bin/sh
is dash
, not bash
, and dash
does not support the double bracket keyword (or didn't at the time of this posting, I haven't double-checked). You can solve your problem by explicitly invoking bash
instead:
$ sudo bash if_test.sh
Alternatively, you can make your script executable and rely on the shebang line:
$ chmod +x if_test.sh
$ sudo ./if_test.sh
Also note that, when used between double square brackets, ==
is a pattern matching operator, not the equality operator. If you want to test for equality, you can either use -eq
:
if [[ "14" -eq "14" ]]; then
echo "FOO"
fi
Or double parentheses:
if (( 14 == 14 )); then
echo "FOO"
fi
Double-bracket if-statement not working
They both "work" for me, however you are using the wrong type of test. The >
inside [[
is doing a textual comparison. For an arithmetic comparison either use the old -gt
or (better) the correct brackets - double parentheses:
if (( nb_dd > 0 )); then
INPUT_TYPE="txt"
fi
Note that the $
is not used, since only numerics can be compared inside ((...))
(using a $
inside might work but can give strange side-effects because of expansion order).
An issue with double brackets in shell scripting
It sounds like your shell is POSIX sh
, which does not have the [[
builtin. Possible solutions include translating it to an expression that works for sh
or changing the shebang line to be #!/bin/bash
. Changing the shebang is generally the best solution.
You may have a POSIX sh
if you're on Ubuntu, they use dash.
Are double square brackets [[ ]] preferable over single square brackets [ ] in Bash?
[[
has fewer surprises and is generally safer to use. But it is not portable - POSIX doesn't specify what it does and only some shells support it (beside bash, I heard ksh supports it too). For example, you can do
[[ -e $b ]]
to test whether a file exists. But with [
, you have to quote $b
, because it splits the argument and expands things like "a*"
(where [[
takes it literally). That has also to do with how [
can be an external program and receives its argument just normally like every other program (although it can also be a builtin, but then it still has not this special handling).
[[
also has some other nice features, like regular expression matching with =~
along with operators like they are known in C-like languages. Here is a good page about it: What is the difference between test, [
and [[
? and Bash Tests
How to use double or single brackets, parentheses, curly braces
In Bash, test
and [
are shell builtins.
The double bracket, which is a shell keyword, enables additional functionality. For example, you can use &&
and ||
instead of -a
and -o
and there's a regular expression matching operator =~
.
Also, in a simple test, double square brackets seem to evaluate quite a lot quicker than single ones.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
The braces, in addition to delimiting a variable name are used for parameter expansion so you can do things like:
Truncate the contents of a variable
$ var="abcde"; echo ${var%d*}
abcMake substitutions similar to
sed
$ var="abcde"; echo ${var/de/12}
abc12Use a default value
$ default="hello"; unset var; echo ${var:-$default}
helloand several more
Also, brace expansions create lists of strings which are typically iterated over in loops:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Note that the leading zero and increment features weren't available before Bash 4.
Thanks to gboffi for reminding me about brace expansions.
Double parentheses are used for arithmetic operations:
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
and they enable you to omit the dollar signs on integer and array variables and include spaces around operators for readability.
Single brackets are also used for array indices:
array[4]="hello"
element=${array[index]}
Curly brace are required for (most/all?) array references on the right hand side.
ephemient's comment reminded me that parentheses are also used for subshells. And that they are used to create arrays.
array=(1 2 3)
echo ${array[1]}
2
run command inside of ${ curly braces
You can't run a command inside ${}
, except in the fallback clause for when a value is not set (in POSIX sh or bash; might be feasible in zsh, which allows all manner of oddball syntax).
Regardless, far fewer contortions are needed if using a function:
# yes, you can call this cd, if you *really* want to.
cdr() {
if (( $# )); then
command cd "$@"
else
local home
home=$(git rev-parse --show-toplevel 2>/dev/null) || home=$HOME
command cd "$home"
fi
}
Note:
- Using a function lets us test our argument list, use branching logic, have local variables, &c.
command cd
is used to call through to the realcd
implementation rather than recursing.
Double parenthesis with and without dollar
In the following, I use "returns" to indicate return values and "produces" to indicate "substitutes the resulting text."
$(...)
means execute the command in the parens in a subshell and produces its stdout. Example:$ echo "The current date is $(date)"
The current date is Mon Jul 6 14:27:59 PDT 2015(...)
means run the commands listed in the parens in a subshell. Example:$ a=1; (a=2; echo "inside: a=$a"); echo "outside: a=$a"
inside: a=2
outside: a=1$((...))
means perform arithmetic and produce the result of the calculation. Example:$ a=$((2+3)); echo "a=$a"
a=5((...))
means perform arithmetic, possibly changing the values of shell variables, but don't produce its result. Example:$ ((a=2+3)); echo "a=$a"
a=5Note that the return value of the calculation is returned, so it can be used in
while
orif
.${...}
means produce the value of the shell variable named in the braces. Example:$ echo ${SHELL}
/bin/bash{...}
means execute the commands in the braces as a group. Example:$ false || { echo "We failed"; exit 1; }
We failed
More generally what does the dollar sign stand for?
It means whatever it means in the given context.
What is the function of * between double brackets?
I'm going to assume you had backticks instead of single quotes for the command, and no space in !=
:
[[ `/bin/somecommand 2>dev/null` != *'1'* ]]
In a double bracket [[ .. ]]
expression, the right-hand side of =
/==
and !=
is interpreted as a glob pattern, so *
means "any string".
Essentially, *'1'*
will match all string that contains a 1
anywhere (such as foo1bar
and 3210
), while '1'
will only match exactly the string 1
.
Related Topics
Docker Oci Runtime Create Failed: Container_Linux.Go:349: Starting Container Process Caused
Dbus_Bus_Request_Name (): Connections Are Not Allowed to Own the Service
How to Make Static Linked Elf File to Load Ld_Preload .So
Catching a Direct Redirect to /Dev/Tty
Automake Subdir-Objects Is Disabled
The New Line Characted in the String Constant Isn't Being Recognized by Nasm
How to Pass Command Line Parameters with Quotes Stored in Single Variable
Docker Container Accessible Only via Cloudflare Cdn (Selected Ip Ranges)
How to Retrieve Advertising Payload from Ibeacon/Ble
Best Text Search Engine for Integrating with Custom Web App
Replace Text Based on a Dictionary
Running Multiple Compass-Sass Watch Operations Automatically
Remove a Specific Line from a File Without Using Sed or Awk
How to Use a Seq_File in Linux Kernel Modules
Changing Pecl Installation Directory
What Does the "Mov Rax, Qword Ptr Fs:0X28" Assembly Instruction Do