Skip to content

Commit 1f6428f

Browse files
akinomyogascop
andcommitted
docs(styleguide): add section for quoting
- docs(styleguide): fix example for case patterns - docs(styleguide): rephrase note on quoting of here strings - docs(styleguide): fix explanation of _comp_split - docs(styleguide): elaborate description of quoting - docs(styleguide): update examples of quoting Co-authored-by: Ville Skyttä <ville.skytta@iki.fi>
1 parent aebb073 commit 1f6428f

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

doc/styleguide.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,62 @@ it.
122122
## Function and variable names
123123

124124
See [API and naming](api-and-naming.md).
125+
126+
## Quoting of words
127+
128+
To avoid unexpected word splitting and pathname expansions, an argument of
129+
commands needs to be properly quoted when it contains shell expansions such as
130+
`$var`, `$(cmd)`, and `$((expr))`.
131+
132+
When one intentionally wants word splitting and pathname expansions, one should
133+
consider using the utility functions provided by bash-completion. To safely
134+
split a string without being affected by non-standard `IFS` and pathname
135+
expansions, use the shell function `_comp_split`. To safely obtain filenames
136+
by pathname expansions without being affected by `failglob`, etc., use the
137+
shell function `_comp_expand_glob`. Note that `_comp_expand_glob` should be
138+
always used for the pathname patterns even if the pattern does not contain
139+
shell expansions.
140+
141+
In the following contexts, the quoting to suppress word splitting and pathname
142+
expansions are not needed.
143+
144+
- The right-hand sides of variable assignments ... `v=WORD` (e.g. `v=$var`)
145+
- The arguments of conditional commands ... `[[ WORD ]]` (e.g. `[[ $var ]]`)
146+
- The argument specified to `case` statement ... `case WORD in foo) ;; esac`
147+
(e.g. `case $var in foo) ;; esac`)
148+
149+
In bash-completion, we do not quote them by default. However, there are
150+
exceptions where the quoting is still needed for other reasons.
151+
152+
- When the word *directly* contains shell special characters (space, tab,
153+
newline, or a character from ``;|&()<>\\$`'"#!~{``), these characters need to
154+
be quoted. The "*directly*" means that the special characters produced by
155+
shell expansions are excluded here. For example, when one wants to include a
156+
whitespace as a part of the value of the word, the right-hand side can be
157+
quoted as `v="a b"`.
158+
- An empty word (i.e., the word whose value is an empty string) is specified by
159+
`""`. The right-hand side of an assignment technically can be an empty
160+
string as `var=`, but we still use `var=""` there because `shellcheck`
161+
suggests that e.g. `var= cmd` is confusing with `var=cmd`.
162+
- `$*` and `${array[*]}` need to be always quoted because they can be affected
163+
by the word splitting in bash <= 4.2 even in the above contexts.
164+
- In the following contexts, double-quoting of shell expansions is needed
165+
unless the result of expansions is intentionally treated as glob patterns or
166+
regular expressions.
167+
- The right-hand sides of `==`, `!=`, and `=~` in the conditional commands
168+
... `[[ word == "$var" ]]`
169+
- The case patterns ... `case word in "$var") ;; esac`
170+
171+
Note: Here strings `cat <<<$var` are also supposed to be safe against word
172+
splitting and pathname expansions without quoting, but bash <= 4.3 has a bug
173+
[1], so they need to be quoted for as long as we support bash 4.3.
174+
175+
- [koalaman/shellcheck#1009 (comment)](https://github.com/koalaman/shellcheck/issues/1009#issuecomment-488395630)
176+
177+
There are also preferences on the type of quoting, which are though not too
178+
strict. We prefer to use double quotes over single quotes by default. When
179+
the value contains `$`, `` ` ``, `\`, and `"`, we can use single quotes to
180+
avoid backslash escaping or use the one that minimizes the use of backslash
181+
escaping. When the value contains control characters such as a tab and a
182+
newline, we do not directly include them but we use backslash escape sequences
183+
such as `\t` and `\n` in the escape string `$'...'`.

0 commit comments

Comments
 (0)