Why use double quotes in a [[ ]] test?
Let's say we have 2 integers in a bash script:
value1=5
value2=3
Then why do we need to use double quotes in case of a test ? For example:
if [[ "$value1" -eq "$value2" ]]
Why not just use the following ?
if [[ $value1 -eq $value2 ]]
To me, the double quotes don't make any sense.
bash shell quoting variable test
|
show 4 more comments
Let's say we have 2 integers in a bash script:
value1=5
value2=3
Then why do we need to use double quotes in case of a test ? For example:
if [[ "$value1" -eq "$value2" ]]
Why not just use the following ?
if [[ $value1 -eq $value2 ]]
To me, the double quotes don't make any sense.
bash shell quoting variable test
5
Quoting in the shell has little to do with strings (as in data types.) It's really about preventing the shell from performing word splitting (and other kinds of expansions.)
– filbranden
Feb 15 at 12:27
12
While, as terdon pointed out, it is not necessary too quote variables in this specific construct (and, of course, with one-word-values anywhere), I'd like to give the advice to always quote your vars. Do you really know in wich contexts you can leave variables unquoted? The reason to quote at all, even if it's not necessary with5
and3
, is maintainability. The values may change later, and the resulting errors may not be obvious.
– Peter A. Schneider
Feb 15 at 13:15
2
@sudodus I don't think that's true for[[ ]]
, only for[ ]
.
– Benjamin W.
Feb 15 at 20:25
1
You are right, @BenjaminW. Word splitting is not the only case why it is a good idea to use double quotes for variables. There is also the case when a variable is blank. That will make the statement in [ ] fail (for example [ 2 -eq ] with an error, but [[ ]] is not vulnerable (like the case with word splitting).
– sudodus
Feb 15 at 20:32
2
@marcelm, Bash, ksh and Zsh have integer variables, and within[[ ]]
they also coerce the operands of-eq
to integers.
– ilkkachu
Feb 15 at 23:01
|
show 4 more comments
Let's say we have 2 integers in a bash script:
value1=5
value2=3
Then why do we need to use double quotes in case of a test ? For example:
if [[ "$value1" -eq "$value2" ]]
Why not just use the following ?
if [[ $value1 -eq $value2 ]]
To me, the double quotes don't make any sense.
bash shell quoting variable test
Let's say we have 2 integers in a bash script:
value1=5
value2=3
Then why do we need to use double quotes in case of a test ? For example:
if [[ "$value1" -eq "$value2" ]]
Why not just use the following ?
if [[ $value1 -eq $value2 ]]
To me, the double quotes don't make any sense.
bash shell quoting variable test
bash shell quoting variable test
edited Feb 17 at 0:15
Jeff Schaller
43.4k1160140
43.4k1160140
asked Feb 15 at 10:14
MeerkatMeerkat
1185
1185
5
Quoting in the shell has little to do with strings (as in data types.) It's really about preventing the shell from performing word splitting (and other kinds of expansions.)
– filbranden
Feb 15 at 12:27
12
While, as terdon pointed out, it is not necessary too quote variables in this specific construct (and, of course, with one-word-values anywhere), I'd like to give the advice to always quote your vars. Do you really know in wich contexts you can leave variables unquoted? The reason to quote at all, even if it's not necessary with5
and3
, is maintainability. The values may change later, and the resulting errors may not be obvious.
– Peter A. Schneider
Feb 15 at 13:15
2
@sudodus I don't think that's true for[[ ]]
, only for[ ]
.
– Benjamin W.
Feb 15 at 20:25
1
You are right, @BenjaminW. Word splitting is not the only case why it is a good idea to use double quotes for variables. There is also the case when a variable is blank. That will make the statement in [ ] fail (for example [ 2 -eq ] with an error, but [[ ]] is not vulnerable (like the case with word splitting).
– sudodus
Feb 15 at 20:32
2
@marcelm, Bash, ksh and Zsh have integer variables, and within[[ ]]
they also coerce the operands of-eq
to integers.
– ilkkachu
Feb 15 at 23:01
|
show 4 more comments
5
Quoting in the shell has little to do with strings (as in data types.) It's really about preventing the shell from performing word splitting (and other kinds of expansions.)
– filbranden
Feb 15 at 12:27
12
While, as terdon pointed out, it is not necessary too quote variables in this specific construct (and, of course, with one-word-values anywhere), I'd like to give the advice to always quote your vars. Do you really know in wich contexts you can leave variables unquoted? The reason to quote at all, even if it's not necessary with5
and3
, is maintainability. The values may change later, and the resulting errors may not be obvious.
– Peter A. Schneider
Feb 15 at 13:15
2
@sudodus I don't think that's true for[[ ]]
, only for[ ]
.
– Benjamin W.
Feb 15 at 20:25
1
You are right, @BenjaminW. Word splitting is not the only case why it is a good idea to use double quotes for variables. There is also the case when a variable is blank. That will make the statement in [ ] fail (for example [ 2 -eq ] with an error, but [[ ]] is not vulnerable (like the case with word splitting).
– sudodus
Feb 15 at 20:32
2
@marcelm, Bash, ksh and Zsh have integer variables, and within[[ ]]
they also coerce the operands of-eq
to integers.
– ilkkachu
Feb 15 at 23:01
5
5
Quoting in the shell has little to do with strings (as in data types.) It's really about preventing the shell from performing word splitting (and other kinds of expansions.)
– filbranden
Feb 15 at 12:27
Quoting in the shell has little to do with strings (as in data types.) It's really about preventing the shell from performing word splitting (and other kinds of expansions.)
– filbranden
Feb 15 at 12:27
12
12
While, as terdon pointed out, it is not necessary too quote variables in this specific construct (and, of course, with one-word-values anywhere), I'd like to give the advice to always quote your vars. Do you really know in wich contexts you can leave variables unquoted? The reason to quote at all, even if it's not necessary with
5
and 3
, is maintainability. The values may change later, and the resulting errors may not be obvious.– Peter A. Schneider
Feb 15 at 13:15
While, as terdon pointed out, it is not necessary too quote variables in this specific construct (and, of course, with one-word-values anywhere), I'd like to give the advice to always quote your vars. Do you really know in wich contexts you can leave variables unquoted? The reason to quote at all, even if it's not necessary with
5
and 3
, is maintainability. The values may change later, and the resulting errors may not be obvious.– Peter A. Schneider
Feb 15 at 13:15
2
2
@sudodus I don't think that's true for
[[ ]]
, only for [ ]
.– Benjamin W.
Feb 15 at 20:25
@sudodus I don't think that's true for
[[ ]]
, only for [ ]
.– Benjamin W.
Feb 15 at 20:25
1
1
You are right, @BenjaminW. Word splitting is not the only case why it is a good idea to use double quotes for variables. There is also the case when a variable is blank. That will make the statement in [ ] fail (for example [ 2 -eq ] with an error, but [[ ]] is not vulnerable (like the case with word splitting).
– sudodus
Feb 15 at 20:32
You are right, @BenjaminW. Word splitting is not the only case why it is a good idea to use double quotes for variables. There is also the case when a variable is blank. That will make the statement in [ ] fail (for example [ 2 -eq ] with an error, but [[ ]] is not vulnerable (like the case with word splitting).
– sudodus
Feb 15 at 20:32
2
2
@marcelm, Bash, ksh and Zsh have integer variables, and within
[[ ]]
they also coerce the operands of -eq
to integers.– ilkkachu
Feb 15 at 23:01
@marcelm, Bash, ksh and Zsh have integer variables, and within
[[ ]]
they also coerce the operands of -eq
to integers.– ilkkachu
Feb 15 at 23:01
|
show 4 more comments
5 Answers
5
active
oldest
votes
Word splitting.
This example is very improbable, but possible, so if you want to code defensively, cover your tracks with quotes:
$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'
OK, all good so far. Let's throw the wrench into the gears:
$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected
Oops.
$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'
Ahh.
2
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
5
Yes, this isn't really relevant to bash's[[ ]]
construct.
– terdon♦
Feb 15 at 16:34
1
Eh?[ $value1 -eq $value2 ]
with an emptyvalue1
would be'[' -eq 3 ']'
with no''
on the left-hand side.
– Charles Duffy
Feb 16 at 19:19
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
1
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
add a comment |
You don't actually need the quotes here. This is one of the very few cases where it is safe to use a variable unquoted. You can confirm this with set -x
:
$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
As you can see above, the quoted and unquoted versions of the test are resolved to the exact same thing by bash. The same should be true for zsh
and, I think, any other shell that supports the [[ ]]
operator.
Note that this is not the case with the more portable [ ]
:
$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!
The [ ]
construct, unlike the [[ ]]
one, does require quoting.
Some useful links to learn more about when and why quoting is required:
- Why does my shell script choke on whitespace or other special characters?
- Security implications of forgetting to quote a variable in bash/POSIX shells
- When is double-quoting necessary?
In this case with integer variables it would be better to declare them as such.declare -i var1=
is0
when evaluated.
– Freddy
Feb 15 at 10:52
4
Note that-eq
is arithmetic comparison, so you can even leave the$
out (in[[ .. ]]
), and write[[ a -eq b ]]
. With string comparison, you need the$
, of course, so[[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
2
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the[[ ]]
) then you need to quote, yes.
– terdon♦
Feb 15 at 14:51
3
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or((...))
or$((...)
. It appears to work, but (old grumpy man, enable) I don't like it.
– glenn jackman
Feb 15 at 16:11
1
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to-eq
and friends inside[[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)
– ilkkachu
Feb 15 at 16:32
|
show 3 more comments
Even though the double quotes aren't necessary, reasons to use them are:
- Good practice/habit: In this case they aren't necessary, but in general double quotes are to avoid unintended word splitting.
- Because
value1
andvalue2
are variable, and you might not know what they contain. Otherwise you might as well ask, "Why bother with variables instead of checkingif [[ 5 -eq 3 ]]
? Or taking it further, why bother with theif
at all when you already know that 5 isn't equal to 3? It's often better to be defensive. (It's true that word-splitting won't happen in[[
, but cases where word-splitting does not happen are rare. Again, see the first point.)
add a comment |
Not directly related to your question, but I use
if (( $value1 == $value2 )); then
when I compare numbers but there you also don't have to use quotes.
2
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the$
. This question, however, seems to focus on variables used within[[ ... ]]
tests.
– Kusalananda
Feb 16 at 21:47
1
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
add a comment |
You are absolutely right!
The quoting within double square brackets makes no sense at all.
But since I use double quotes daily -- especially for single square bracket expressions, passing arguments to functions and scripts, as well as variable assignment sometimes (which is completely useless for simple delcarations) -- I guess some people, at least I do, write double quotes around variable expansions instinctively.
Double quoting can give you a sense of savety. It is like coming home
where double quotes are. - D. Kummer
A benefit of doing double quotes consequently and comprehensibly -- but only as it makes sense -- is that coworkers who are new to bash can learn how to write more stable scripts.
It also accentuates the fact that the art of data processing with bash is more about separating data streams (including variables) by field separators and pipe them through filters. As soon as you got your data chunks separated from the stream, hold them together with double quotes!
Another benefit could be the better readability of bash scripts with double quoted strings within a code highlighting editor.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f500828%2fwhy-use-double-quotes-in-a-test%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Word splitting.
This example is very improbable, but possible, so if you want to code defensively, cover your tracks with quotes:
$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'
OK, all good so far. Let's throw the wrench into the gears:
$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected
Oops.
$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'
Ahh.
2
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
5
Yes, this isn't really relevant to bash's[[ ]]
construct.
– terdon♦
Feb 15 at 16:34
1
Eh?[ $value1 -eq $value2 ]
with an emptyvalue1
would be'[' -eq 3 ']'
with no''
on the left-hand side.
– Charles Duffy
Feb 16 at 19:19
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
1
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
add a comment |
Word splitting.
This example is very improbable, but possible, so if you want to code defensively, cover your tracks with quotes:
$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'
OK, all good so far. Let's throw the wrench into the gears:
$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected
Oops.
$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'
Ahh.
2
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
5
Yes, this isn't really relevant to bash's[[ ]]
construct.
– terdon♦
Feb 15 at 16:34
1
Eh?[ $value1 -eq $value2 ]
with an emptyvalue1
would be'[' -eq 3 ']'
with no''
on the left-hand side.
– Charles Duffy
Feb 16 at 19:19
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
1
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
add a comment |
Word splitting.
This example is very improbable, but possible, so if you want to code defensively, cover your tracks with quotes:
$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'
OK, all good so far. Let's throw the wrench into the gears:
$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected
Oops.
$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'
Ahh.
Word splitting.
This example is very improbable, but possible, so if you want to code defensively, cover your tracks with quotes:
$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'
OK, all good so far. Let's throw the wrench into the gears:
$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected
Oops.
$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'
Ahh.
answered Feb 15 at 16:07
community wiki
glenn jackman
2
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
5
Yes, this isn't really relevant to bash's[[ ]]
construct.
– terdon♦
Feb 15 at 16:34
1
Eh?[ $value1 -eq $value2 ]
with an emptyvalue1
would be'[' -eq 3 ']'
with no''
on the left-hand side.
– Charles Duffy
Feb 16 at 19:19
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
1
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
add a comment |
2
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
5
Yes, this isn't really relevant to bash's[[ ]]
construct.
– terdon♦
Feb 15 at 16:34
1
Eh?[ $value1 -eq $value2 ]
with an emptyvalue1
would be'[' -eq 3 ']'
with no''
on the left-hand side.
– Charles Duffy
Feb 16 at 19:19
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
1
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
2
2
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
But OP uses double brackets, so no word splitting takes place.
– user000001
Feb 15 at 16:22
5
5
Yes, this isn't really relevant to bash's
[[ ]]
construct.– terdon♦
Feb 15 at 16:34
Yes, this isn't really relevant to bash's
[[ ]]
construct.– terdon♦
Feb 15 at 16:34
1
1
Eh?
[ $value1 -eq $value2 ]
with an empty value1
would be '[' -eq 3 ']'
with no ''
on the left-hand side.– Charles Duffy
Feb 16 at 19:19
Eh?
[ $value1 -eq $value2 ]
with an empty value1
would be '[' -eq 3 ']'
with no ''
on the left-hand side.– Charles Duffy
Feb 16 at 19:19
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
I was surprised too, but there's the evidence.
– glenn jackman
Feb 16 at 20:59
1
1
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
This answer does not directly relate to the question. I'm surprised it was accepted. Setting as community wiki.
– glenn jackman
Feb 20 at 20:23
add a comment |
You don't actually need the quotes here. This is one of the very few cases where it is safe to use a variable unquoted. You can confirm this with set -x
:
$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
As you can see above, the quoted and unquoted versions of the test are resolved to the exact same thing by bash. The same should be true for zsh
and, I think, any other shell that supports the [[ ]]
operator.
Note that this is not the case with the more portable [ ]
:
$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!
The [ ]
construct, unlike the [[ ]]
one, does require quoting.
Some useful links to learn more about when and why quoting is required:
- Why does my shell script choke on whitespace or other special characters?
- Security implications of forgetting to quote a variable in bash/POSIX shells
- When is double-quoting necessary?
In this case with integer variables it would be better to declare them as such.declare -i var1=
is0
when evaluated.
– Freddy
Feb 15 at 10:52
4
Note that-eq
is arithmetic comparison, so you can even leave the$
out (in[[ .. ]]
), and write[[ a -eq b ]]
. With string comparison, you need the$
, of course, so[[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
2
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the[[ ]]
) then you need to quote, yes.
– terdon♦
Feb 15 at 14:51
3
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or((...))
or$((...)
. It appears to work, but (old grumpy man, enable) I don't like it.
– glenn jackman
Feb 15 at 16:11
1
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to-eq
and friends inside[[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)
– ilkkachu
Feb 15 at 16:32
|
show 3 more comments
You don't actually need the quotes here. This is one of the very few cases where it is safe to use a variable unquoted. You can confirm this with set -x
:
$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
As you can see above, the quoted and unquoted versions of the test are resolved to the exact same thing by bash. The same should be true for zsh
and, I think, any other shell that supports the [[ ]]
operator.
Note that this is not the case with the more portable [ ]
:
$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!
The [ ]
construct, unlike the [[ ]]
one, does require quoting.
Some useful links to learn more about when and why quoting is required:
- Why does my shell script choke on whitespace or other special characters?
- Security implications of forgetting to quote a variable in bash/POSIX shells
- When is double-quoting necessary?
In this case with integer variables it would be better to declare them as such.declare -i var1=
is0
when evaluated.
– Freddy
Feb 15 at 10:52
4
Note that-eq
is arithmetic comparison, so you can even leave the$
out (in[[ .. ]]
), and write[[ a -eq b ]]
. With string comparison, you need the$
, of course, so[[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
2
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the[[ ]]
) then you need to quote, yes.
– terdon♦
Feb 15 at 14:51
3
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or((...))
or$((...)
. It appears to work, but (old grumpy man, enable) I don't like it.
– glenn jackman
Feb 15 at 16:11
1
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to-eq
and friends inside[[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)
– ilkkachu
Feb 15 at 16:32
|
show 3 more comments
You don't actually need the quotes here. This is one of the very few cases where it is safe to use a variable unquoted. You can confirm this with set -x
:
$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
As you can see above, the quoted and unquoted versions of the test are resolved to the exact same thing by bash. The same should be true for zsh
and, I think, any other shell that supports the [[ ]]
operator.
Note that this is not the case with the more portable [ ]
:
$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!
The [ ]
construct, unlike the [[ ]]
one, does require quoting.
Some useful links to learn more about when and why quoting is required:
- Why does my shell script choke on whitespace or other special characters?
- Security implications of forgetting to quote a variable in bash/POSIX shells
- When is double-quoting necessary?
You don't actually need the quotes here. This is one of the very few cases where it is safe to use a variable unquoted. You can confirm this with set -x
:
$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
As you can see above, the quoted and unquoted versions of the test are resolved to the exact same thing by bash. The same should be true for zsh
and, I think, any other shell that supports the [[ ]]
operator.
Note that this is not the case with the more portable [ ]
:
$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!
The [ ]
construct, unlike the [[ ]]
one, does require quoting.
Some useful links to learn more about when and why quoting is required:
- Why does my shell script choke on whitespace or other special characters?
- Security implications of forgetting to quote a variable in bash/POSIX shells
- When is double-quoting necessary?
edited Feb 16 at 14:29
ilkkachu
61.6k10100177
61.6k10100177
answered Feb 15 at 10:42
terdon♦terdon
132k32261441
132k32261441
In this case with integer variables it would be better to declare them as such.declare -i var1=
is0
when evaluated.
– Freddy
Feb 15 at 10:52
4
Note that-eq
is arithmetic comparison, so you can even leave the$
out (in[[ .. ]]
), and write[[ a -eq b ]]
. With string comparison, you need the$
, of course, so[[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
2
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the[[ ]]
) then you need to quote, yes.
– terdon♦
Feb 15 at 14:51
3
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or((...))
or$((...)
. It appears to work, but (old grumpy man, enable) I don't like it.
– glenn jackman
Feb 15 at 16:11
1
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to-eq
and friends inside[[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)
– ilkkachu
Feb 15 at 16:32
|
show 3 more comments
In this case with integer variables it would be better to declare them as such.declare -i var1=
is0
when evaluated.
– Freddy
Feb 15 at 10:52
4
Note that-eq
is arithmetic comparison, so you can even leave the$
out (in[[ .. ]]
), and write[[ a -eq b ]]
. With string comparison, you need the$
, of course, so[[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
2
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the[[ ]]
) then you need to quote, yes.
– terdon♦
Feb 15 at 14:51
3
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or((...))
or$((...)
. It appears to work, but (old grumpy man, enable) I don't like it.
– glenn jackman
Feb 15 at 16:11
1
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to-eq
and friends inside[[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)
– ilkkachu
Feb 15 at 16:32
In this case with integer variables it would be better to declare them as such.
declare -i var1=
is 0
when evaluated.– Freddy
Feb 15 at 10:52
In this case with integer variables it would be better to declare them as such.
declare -i var1=
is 0
when evaluated.– Freddy
Feb 15 at 10:52
4
4
Note that
-eq
is arithmetic comparison, so you can even leave the $
out (in [[ .. ]]
), and write [[ a -eq b ]]
. With string comparison, you need the $
, of course, so [[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
Note that
-eq
is arithmetic comparison, so you can even leave the $
out (in [[ .. ]]
), and write [[ a -eq b ]]
. With string comparison, you need the $
, of course, so [[ $a = $b ]]
– ilkkachu
Feb 15 at 13:05
2
2
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:
var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the [[ ]]
) then you need to quote, yes.– terdon♦
Feb 15 at 14:51
@user000001 good point. Although, of course, it's very possible that you want those expanded. For example, I would expect this to be a match:
var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. If you want to use the glob characters without their acting as a glob in a globbing context (such as the [[ ]]
) then you need to quote, yes.– terdon♦
Feb 15 at 14:51
3
3
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or
((...))
or $((...)
. It appears to work, but (old grumpy man, enable) I don't like it.– glenn jackman
Feb 15 at 16:11
@ilkkachu, that surprises me. I thought that "bare" variables would only be considered within an array subscript or
((...))
or $((...)
. It appears to work, but (old grumpy man, enable) I don't like it.– glenn jackman
Feb 15 at 16:11
1
1
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to
-eq
and friends inside [[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)– ilkkachu
Feb 15 at 16:32
@glennjackman, well, sorry to be the one to tell you that, but yeah, the operands to
-eq
and friends inside [[ ]]
are arithmetic contexts, too. :) (Related: Automatic variable expansion inside bash [[ ]] command)– ilkkachu
Feb 15 at 16:32
|
show 3 more comments
Even though the double quotes aren't necessary, reasons to use them are:
- Good practice/habit: In this case they aren't necessary, but in general double quotes are to avoid unintended word splitting.
- Because
value1
andvalue2
are variable, and you might not know what they contain. Otherwise you might as well ask, "Why bother with variables instead of checkingif [[ 5 -eq 3 ]]
? Or taking it further, why bother with theif
at all when you already know that 5 isn't equal to 3? It's often better to be defensive. (It's true that word-splitting won't happen in[[
, but cases where word-splitting does not happen are rare. Again, see the first point.)
add a comment |
Even though the double quotes aren't necessary, reasons to use them are:
- Good practice/habit: In this case they aren't necessary, but in general double quotes are to avoid unintended word splitting.
- Because
value1
andvalue2
are variable, and you might not know what they contain. Otherwise you might as well ask, "Why bother with variables instead of checkingif [[ 5 -eq 3 ]]
? Or taking it further, why bother with theif
at all when you already know that 5 isn't equal to 3? It's often better to be defensive. (It's true that word-splitting won't happen in[[
, but cases where word-splitting does not happen are rare. Again, see the first point.)
add a comment |
Even though the double quotes aren't necessary, reasons to use them are:
- Good practice/habit: In this case they aren't necessary, but in general double quotes are to avoid unintended word splitting.
- Because
value1
andvalue2
are variable, and you might not know what they contain. Otherwise you might as well ask, "Why bother with variables instead of checkingif [[ 5 -eq 3 ]]
? Or taking it further, why bother with theif
at all when you already know that 5 isn't equal to 3? It's often better to be defensive. (It's true that word-splitting won't happen in[[
, but cases where word-splitting does not happen are rare. Again, see the first point.)
Even though the double quotes aren't necessary, reasons to use them are:
- Good practice/habit: In this case they aren't necessary, but in general double quotes are to avoid unintended word splitting.
- Because
value1
andvalue2
are variable, and you might not know what they contain. Otherwise you might as well ask, "Why bother with variables instead of checkingif [[ 5 -eq 3 ]]
? Or taking it further, why bother with theif
at all when you already know that 5 isn't equal to 3? It's often better to be defensive. (It's true that word-splitting won't happen in[[
, but cases where word-splitting does not happen are rare. Again, see the first point.)
edited Feb 15 at 18:54
answered Feb 15 at 13:18
jamesdlinjamesdlin
554413
554413
add a comment |
add a comment |
Not directly related to your question, but I use
if (( $value1 == $value2 )); then
when I compare numbers but there you also don't have to use quotes.
2
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the$
. This question, however, seems to focus on variables used within[[ ... ]]
tests.
– Kusalananda
Feb 16 at 21:47
1
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
add a comment |
Not directly related to your question, but I use
if (( $value1 == $value2 )); then
when I compare numbers but there you also don't have to use quotes.
2
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the$
. This question, however, seems to focus on variables used within[[ ... ]]
tests.
– Kusalananda
Feb 16 at 21:47
1
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
add a comment |
Not directly related to your question, but I use
if (( $value1 == $value2 )); then
when I compare numbers but there you also don't have to use quotes.
Not directly related to your question, but I use
if (( $value1 == $value2 )); then
when I compare numbers but there you also don't have to use quotes.
answered Feb 16 at 21:44
frampframp
1113
1113
2
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the$
. This question, however, seems to focus on variables used within[[ ... ]]
tests.
– Kusalananda
Feb 16 at 21:47
1
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
add a comment |
2
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the$
. This question, however, seems to focus on variables used within[[ ... ]]
tests.
– Kusalananda
Feb 16 at 21:47
1
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
2
2
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the $
. This question, however, seems to focus on variables used within [[ ... ]]
tests.– Kusalananda
Feb 16 at 21:47
if (( value1 == value2 )); then
. In arithmetic contexts, you don't even need the $
. This question, however, seems to focus on variables used within [[ ... ]]
tests.– Kusalananda
Feb 16 at 21:47
1
1
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
I know. But I frankly don't use this feature because I want to have my variable names be consistent and thus use $ as a prefix all the time.
– framp
Feb 18 at 19:31
add a comment |
You are absolutely right!
The quoting within double square brackets makes no sense at all.
But since I use double quotes daily -- especially for single square bracket expressions, passing arguments to functions and scripts, as well as variable assignment sometimes (which is completely useless for simple delcarations) -- I guess some people, at least I do, write double quotes around variable expansions instinctively.
Double quoting can give you a sense of savety. It is like coming home
where double quotes are. - D. Kummer
A benefit of doing double quotes consequently and comprehensibly -- but only as it makes sense -- is that coworkers who are new to bash can learn how to write more stable scripts.
It also accentuates the fact that the art of data processing with bash is more about separating data streams (including variables) by field separators and pipe them through filters. As soon as you got your data chunks separated from the stream, hold them together with double quotes!
Another benefit could be the better readability of bash scripts with double quoted strings within a code highlighting editor.
add a comment |
You are absolutely right!
The quoting within double square brackets makes no sense at all.
But since I use double quotes daily -- especially for single square bracket expressions, passing arguments to functions and scripts, as well as variable assignment sometimes (which is completely useless for simple delcarations) -- I guess some people, at least I do, write double quotes around variable expansions instinctively.
Double quoting can give you a sense of savety. It is like coming home
where double quotes are. - D. Kummer
A benefit of doing double quotes consequently and comprehensibly -- but only as it makes sense -- is that coworkers who are new to bash can learn how to write more stable scripts.
It also accentuates the fact that the art of data processing with bash is more about separating data streams (including variables) by field separators and pipe them through filters. As soon as you got your data chunks separated from the stream, hold them together with double quotes!
Another benefit could be the better readability of bash scripts with double quoted strings within a code highlighting editor.
add a comment |
You are absolutely right!
The quoting within double square brackets makes no sense at all.
But since I use double quotes daily -- especially for single square bracket expressions, passing arguments to functions and scripts, as well as variable assignment sometimes (which is completely useless for simple delcarations) -- I guess some people, at least I do, write double quotes around variable expansions instinctively.
Double quoting can give you a sense of savety. It is like coming home
where double quotes are. - D. Kummer
A benefit of doing double quotes consequently and comprehensibly -- but only as it makes sense -- is that coworkers who are new to bash can learn how to write more stable scripts.
It also accentuates the fact that the art of data processing with bash is more about separating data streams (including variables) by field separators and pipe them through filters. As soon as you got your data chunks separated from the stream, hold them together with double quotes!
Another benefit could be the better readability of bash scripts with double quoted strings within a code highlighting editor.
You are absolutely right!
The quoting within double square brackets makes no sense at all.
But since I use double quotes daily -- especially for single square bracket expressions, passing arguments to functions and scripts, as well as variable assignment sometimes (which is completely useless for simple delcarations) -- I guess some people, at least I do, write double quotes around variable expansions instinctively.
Double quoting can give you a sense of savety. It is like coming home
where double quotes are. - D. Kummer
A benefit of doing double quotes consequently and comprehensibly -- but only as it makes sense -- is that coworkers who are new to bash can learn how to write more stable scripts.
It also accentuates the fact that the art of data processing with bash is more about separating data streams (including variables) by field separators and pipe them through filters. As soon as you got your data chunks separated from the stream, hold them together with double quotes!
Another benefit could be the better readability of bash scripts with double quoted strings within a code highlighting editor.
answered Feb 20 at 12:06
Dominik KummerDominik Kummer
788
788
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f500828%2fwhy-use-double-quotes-in-a-test%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
Quoting in the shell has little to do with strings (as in data types.) It's really about preventing the shell from performing word splitting (and other kinds of expansions.)
– filbranden
Feb 15 at 12:27
12
While, as terdon pointed out, it is not necessary too quote variables in this specific construct (and, of course, with one-word-values anywhere), I'd like to give the advice to always quote your vars. Do you really know in wich contexts you can leave variables unquoted? The reason to quote at all, even if it's not necessary with
5
and3
, is maintainability. The values may change later, and the resulting errors may not be obvious.– Peter A. Schneider
Feb 15 at 13:15
2
@sudodus I don't think that's true for
[[ ]]
, only for[ ]
.– Benjamin W.
Feb 15 at 20:25
1
You are right, @BenjaminW. Word splitting is not the only case why it is a good idea to use double quotes for variables. There is also the case when a variable is blank. That will make the statement in [ ] fail (for example [ 2 -eq ] with an error, but [[ ]] is not vulnerable (like the case with word splitting).
– sudodus
Feb 15 at 20:32
2
@marcelm, Bash, ksh and Zsh have integer variables, and within
[[ ]]
they also coerce the operands of-eq
to integers.– ilkkachu
Feb 15 at 23:01