Timeline for When is double-quoting necessary?
Current License: CC BY-SA 4.0
50 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Nov 28, 2023 at 11:13 | history | edited | Gilles 'SO- stop being evil' | CC BY-SA 4.0 | add a note about pattern/regex position in [[ … ]] in zsh |
| Nov 28, 2023 at 9:49 | comment | added | Gilles 'SO- stop being evil' | @Carl Re. scalar variable: good point, thanks. Re. what is desired: well, sure, there's no law of physics that requires double quotes. The point of this question is when you need double quotes to ensure that $var (or variant) is the value of var rather than doing some extra processing. | |
| Nov 28, 2023 at 9:48 | history | edited | Gilles 'SO- stop being evil' | CC BY-SA 4.0 | clarify a passage that didn't make it explicit that it was only about scalar variables |
| Nov 27, 2023 at 13:33 | comment | added | Carl | @Gilles'SO-stopbeingevil' (cont'd) Also wording choice about "when double-quoting is required", "you can omit..." etc. might be a bit misleading for arrays, since it is more about choosing the desired behaviour. E.g. we commonly do arr=(a b ..); for e in $arr; do ..; where only unqoted $arr (or "${(@)arr}"/"$arr[@]") does what we want. Similarly "_The @ [...] sometimes requires double quotes..._" could be slightly misleading since (@)` is typ. used in order to be able to double-quote the expression. * * * It's obvious you know all this; these clarifications could help readers. | |
| Nov 27, 2023 at 13:13 | comment | added | Carl | @Gilles'SO-stopbeingevil' on section "Zsh": It could be worth clarifying that this part of the answer focuses on/mostly assumes we are dealing with scalar variables, as opposed to arrays; e.g. when you say "you can omit the double quotes most of the time", "$var never expands to multiple words". If $var is an array, the unquoted form typically expands to a separate word for each non-empty element, if a list of words is possible in that context. | |
| Nov 18, 2022 at 9:55 | review | Suggested edits | |||
| Nov 18, 2022 at 11:00 | |||||
| Aug 27, 2022 at 9:22 | comment | added | Gilles 'SO- stop being evil' | @G-ManSays'ReinstateMonica' (6) The rest of the answer is an expansion of that sentence. It shows contexts where a string is expected, vs a list or a pattern. | |
| Aug 27, 2022 at 9:21 | comment | added | Gilles 'SO- stop being evil' | @G-ManSays'ReinstateMonica' (2) Again, long answer, plus not really related to the question. (3) IIRC ksh, zsh and bash all behave slightly differently with =~ and quoting, it could be a thread on its own. (4) My answer already states that double quotes inside arithmetic expressions are problematic in “some shells”, I don't see the need to get into details. I could link to a post (not a comment thread). (5) I could link to that thread for the dangers of doing it wrong (but that's kind of the question's purview anyway). Why your answer specifically? | |
| Aug 27, 2022 at 9:13 | comment | added | Gilles 'SO- stop being evil' | @G-ManSays'ReinstateMonica' (Wow, that's a lot for comments, some of it would be more suitable as questions on the specific aspect.) (1) Your example shows scalar assignments (which happen to be assigning to array elements). There's also the bash (and zsh) syntax array=([INDEX]=ELEMENT), that one is actually assigning ELEMENT as a scalar despite being inside an array element, but I'm not sure about adding it to this answer which is already long. No idea what you're on about, “left/right-hand side” (commonly abbreviated LHS/RHS) is common terminology. | |
| Aug 27, 2022 at 8:55 | comment | added | G-Man Says 'Reinstate Monica' | (Cont’d) … (6) I’m completely mystified by this “when a raw string is expected” / “when a raw string is expected by the parser” dichotomy. I don’t have a question about it; I literally do not understand what’s being said, and, especially, the distinction between the two variants. Can you expand on that enough to facilitate comprehension by people who aren’t smarter than I? | |
| Aug 27, 2022 at 8:55 | comment | added | G-Man Says 'Reinstate Monica' | (Cont’d) … (5) You say “An unquoted variable … can be useful … when you know that the value doesn't contain any wildcard character … and you want to split it at whitespace ….” You might want to link to my answer to Security implications of forgetting to quote a variable in bash/POSIX shells — But what if …? … (Cont’d) | |
| Aug 27, 2022 at 8:54 | comment | added | G-Man Says 'Reinstate Monica' | (Cont’d) … (4) You mention arithmetic expressions. You might want to note that the rules for that vary between Bash versions, and are (arguably) inconsistent within some versions. See the comments here. … (Cont’d) | |
| Aug 27, 2022 at 8:54 | comment | added | G-Man Says 'Reinstate Monica' | (Cont’d) … (2) You might want to link to How can I use a variable as a case condition? and point out that, while a *, ? or […] in an unquoted variable in a case pattern is interpreted as a glob-style pattern, a | (being shell syntax rather than glob syntax) does not delimit multiple glob-style patterns. (3) You might want to add example(s) for =~ to your discussion of [[…]]. c.t and c.*t are pedagogically useful, with test strings like “cat”, “city”, “coat” and “cot”. … (Cont’d) | |
| Aug 27, 2022 at 8:54 | comment | added | G-Man Says 'Reinstate Monica' | (1) I just stumbled across this (again) and I was struck / puzzled by your statement “On the right-hand side of a scalar (not array) variable assignment.” (emphasis added) Perhaps you should clarify that colors[1]=$ruby_color / colors[2]=$pumpkin_color / colors[3]=$schoolbus_color / colors[4]=$grass_color, etc., are fine, and maybe give a suitable caveated example of what doesn’t work. P.S. I’m on a personal crusade to stamp out the phrases “left-hand” and “right-hand” except when talking about gloves or silverware etiquette. Why not just say “right side”? … (Cont’d) | |
| Aug 12, 2022 at 8:25 | history | edited | Stéphane Chazelas | CC BY-SA 4.0 | added 433 characters in body |
| Aug 12, 2022 at 5:21 | history | edited | Gilles 'SO- stop being evil' | CC BY-SA 4.0 | "left-hand side" and "right-hand side" are technical terms |
| Aug 12, 2022 at 4:48 | history | edited | G-Man Says 'Reinstate Monica' | CC BY-SA 4.0 | What do hands have to do with it? I type with my paws! :-) Also, fixed dubious grammar and added some clarification. |
| S Aug 11, 2022 at 17:44 | history | suggested | Ezra Citron | CC BY-SA 4.0 | fixed a few grammatical/punctuation errors |
| Aug 11, 2022 at 17:24 | review | Suggested edits | |||
| S Aug 11, 2022 at 17:44 | |||||
| Feb 19, 2021 at 7:32 | comment | added | RichieHH | Super answer. Just reinforcing what a mess it as and to... Quote unless you have a specific reason not to | |
| Nov 9, 2020 at 17:44 | comment | added | Gilles 'SO- stop being evil' | @user7392 I don't know. You should ask a new question. | |
| Nov 9, 2020 at 17:42 | comment | added | All The Rage | I really want to be able to put backslashes before the spaces when defining the variable and have them be respected after expanding it. Is there any way I can do that? It would solve this problem so nicely. | |
| Nov 9, 2020 at 17:40 | comment | added | All The Rage | I set a variable like: o='OneDrive - MyCompany'. Then I use it: cd "$o"/Docu. Then I press TAB to do word completion on the folder name. The result is cd $o/Documents. I hit enter and it fails because it stole my double quotes. I want to use "$o" as a very fast shortcut for that directory name. I don't want to type "$o/Docu and then press TAB and then ", which works. When I start typing I don't want to think about whether I might press TAB to expand something later in the path. I just want to follow the rule to double quote variables. That doesn't work here. Any suggestions? | |
| Sep 8, 2020 at 17:55 | comment | added | Jani Uusitalo | @Gilles'SO-stopbeingevil' Ok, it was just my misunderstanding then; I interpreted the quote as meaning "you should quote RHS regular expressions". | |
| Sep 8, 2020 at 13:10 | comment | added | Gilles 'SO- stop being evil' | @JaniUusitalo That's the point: if you leave the variable unquoted, it's interpreted as a regular expression. If you quote it, it's interpreted as a substring. So for example [[ $x =~ ^$a ]] checks whether the value of x starts with a string that matches the regular expression contained in a, whereas [[ $x =~ ^"$a" ]] checks whether the value of x starts with the string which is the value of a. | |
| Sep 8, 2020 at 12:38 | comment | added | Jani Uusitalo | "Except that you do need double quotes where a pattern or regular expression is expected: on the right-hand side of = or == or != or =~." Perhaps I'm misunderstanding this, but AFAIK, a RHS regular expression (i.e. after =~) should always be unquoted (since Bash 3.2 at least). | |
| Dec 15, 2017 at 15:12 | comment | added | Friartek | @Gilles Being ill and on antibiotics is no excuse for dumb mistakes on my part. Let myself get bit by the evil quote gods while working with arrays, then applied those results back to your original code. ${…%?} does work as you said and is a simple way around $(...) stripping trailing "empty lines". Still having a problem with the term "line break", took it to mean some quite different. My use case now is array=(${(@f)"${$(somecommand; echo _)%?}"}). I apologize to you and all here for the noise. I will delete some of my previous comments so others wont make my mistake. | |
| Dec 15, 2017 at 10:54 | comment | added | Gilles 'SO- stop being evil' | @Friartek You keep mentioning an “empty line which wasn't there before”, but I don't understand why you think there is such a thing. Adding ;echo _ adds an underscore and a line break. The command substitution removes this line break. ${…%?} removes the underscore. You're left with exactly the output of the command, including its trailing line breaks if any. | |
| Dec 15, 2017 at 1:40 | comment | added | Friartek | @Gilles Hi. Sorry, not what I'm seeing. This is how I understand what is going on. $() will strip all trailing blank lines from a command within the parentheses. By adding ;echo _ to the end of the output of "somecommand", this tacks on an additional line with an underscore so any trailing blank lines from "somecommand" will be protected from $(). %? then deletes the underscore, leaving an empty line which wasn't there before. This is especially noticeable when there are no trailing blank lines from "somecommand". Am I missing or misinterpreting something here? | |
| Dec 14, 2017 at 18:22 | comment | added | Gilles 'SO- stop being evil' | @Friartek No: "${$(somecommand; echo _)%?}" is the exact output of the command, including a final newline if there is one (and there usually is). If you want the output of the command without trailing newlines, it's just "$(somecommand; echo _)". | |
| Dec 14, 2017 at 16:33 | comment | added | Friartek | Sorry, ignore my previous comment, it was added before complete and edited within time limit. 1) "${$(somecommand; echo _)%?}" technically outputs the exact output of the command, but it also adds an additional newline to the end. "${"${$(somecommand; echo _)%?}"%$'\n'}" appears to correct this. 2) It isn't stated what the expected output of "${(@f)$(somecommand)}", to get an array, should be. The result is, all trailing newlines are remove. If you require an array with trailing newlines, "${(@f)"${$(somecommand; echo _)%?}"%$'\n'}" should give you the desired result. | |
| Dec 14, 2017 at 16:12 | comment | added | Friartek | 1) "${$(somecommand; echo _)%?}" technically outputs the exact output of the command, but it also adds an additional newline to the end. "${"${$(df|dfalign; echo _)%?}"%$'\n'}" appears to correct this.2) It isn't stated what the expected output of "${(@f)$(somecommand)}", to get an array, should be. The result is, all trailing newlines are remove. If you require an array with trailing newlines, "${(@f)"${$(somecommand; echo _)%?}"}" comes close, but you will have to deal with the additional newline. | |
| Nov 29, 2017 at 23:04 | comment | added | Alex Dupuy | Great answer. There's one other place you don't need quotes, which is when using + in variable substitution, e.g. ${VARNAME+replacement}, although you do need to quote the replacement if it has whitespace or contains any variables, e.g. ${VARNAME:+--opt="$VARNAME"}. | |
| Jun 22, 2017 at 11:16 | history | edited | Stéphane Chazelas | CC BY-SA 3.0 | added 105 characters in body |
| Jun 22, 2017 at 10:11 | history | edited | Stéphane Chazelas | CC BY-SA 3.0 | added 105 characters in body |
| Apr 13, 2017 at 12:37 | history | edited | CommunityBot | replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/ | |
| Mar 17, 2017 at 12:04 | history | edited | Stéphane Chazelas | CC BY-SA 3.0 | added 182 characters in body |
| Mar 10, 2017 at 11:43 | history | edited | Stéphane Chazelas | CC BY-SA 3.0 | added 2 characters in body |
| Mar 10, 2017 at 11:04 | comment | added | Gilles 'SO- stop being evil' | @CharlesDuffy Ugh, I hadn't thought of this misreading. I've changed “where” to “when” and reinforced the sentence as you suggested. | |
| Mar 10, 2017 at 11:02 | history | edited | Gilles 'SO- stop being evil' | CC BY-SA 3.0 | reinforce a sentence that got misinterpreted |
| Mar 10, 2017 at 4:01 | comment | added | Charles Duffy | FYI -- over on StackOverflow, I've had someone pull the "optional when a raw string is expected" language in this answer out to defend not quoting an argument to echo. It might be worth trying to make the language even more explicit ("when a raw string is expected by the parser", perhaps?) | |
| Nov 29, 2016 at 4:21 | comment | added | Cyker | Also, for anyone who is interested, the formal names of split+glob are word splitting and pathname expansion. | |
| Nov 29, 2016 at 4:20 | comment | added | Cyker | This is what man bash says: The expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. | |
| Nov 29, 2016 at 4:05 | comment | added | Cyker | In fact, you need to leave the quotes out in order for a variable to be parsed as an arithmetic expression. Why am I able to make your example work with quotes: echo "$(("$expr"))" | |
| Jun 13, 2016 at 0:03 | history | edited | Gilles 'SO- stop being evil' | CC BY-SA 3.0 | mention that ksh88 does globbing on >$foo in scripts (thanks Stéphane Chazelas) |
| Jan 6, 2015 at 4:49 | history | edited | muru | CC BY-SA 3.0 | Presumably accidental quote misplacement? |
| Dec 6, 2014 at 16:48 | vote | accept | kjo | ||
| Jun 6, 2014 at 10:00 | history | edited | Gilles 'SO- stop being evil' | CC BY-SA 3.0 | zsh: discuss command substitution; discuss cases where unquoted expansion is useful |
| Jun 11, 2013 at 6:53 | history | edited | Stéphane Chazelas | CC BY-SA 3.0 | a few corrections |
| Mar 22, 2013 at 0:28 | history | answered | Gilles 'SO- stop being evil' | CC BY-SA 3.0 |