diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-02-22 11:23:54 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-02-22 11:23:54 +0200 |
commit | 55ff42d0144cb303d8a1b5c02e630c72e19ec517 (patch) | |
tree | 17dec1d12c32f58c273cf52df69096254cb9e4f9 /doc | |
parent | 79a23985860126f59cf0c26f9d8ee98001c9f95c (diff) |
Update bash guide to always use [[ ]]
Diffstat (limited to 'doc')
-rw-r--r-- | doc/bash-style.cli | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/doc/bash-style.cli b/doc/bash-style.cli index 8de01da..3f620f4 100644 --- a/doc/bash-style.cli +++ b/doc/bash-style.cli @@ -48,7 +48,7 @@ For \c{if}/\c{while} and \c{for}/\c{do} the corresponding \c{then} or \c{do} is written on the same line after a semicolon, for example: \ -if [ ... ]; then +if [[ ... ]]; then ... fi @@ -60,9 +60,8 @@ done Do use \c{elif} instead of nested \c{else} and \c{if} (and consider if \c{case} can be used instead). -For \c{if} use \c{[ ]} for basic tests and \c{[[ ]]} if the previous form is -not sufficient or hairy. In particular, \c{[[ ]]} results in cleaner code -for complex expressions, for example: +For \c{if}/\c{while} use \c{[[ ]]} since it results in cleaner code for +complex expressions, for example: \ if [[ \"$foo\" && (\"$bar\" || \"$baz\") ]]; then @@ -70,6 +69,9 @@ if [[ \"$foo\" && (\"$bar\" || \"$baz\") ]]; then fi \ +\N|If for some reason you need the semantics of \c{[}, use \c{test} instead to +make it clear this is intentional.| + \h1#struct|Structure| The overall structure of the script should be as follows: @@ -148,7 +150,7 @@ file= Parse the command line options/arguments. For example: \ -while [ \"$#\" -gt 0 ]; do +while [[ \"$#\" -gt 0 ]]; do case \"$1\" in -q) quiet=\"y\" @@ -160,7 +162,7 @@ while [ \"$#\" -gt 0 ]; do shift ;; *) - if [ -n \"$file\" ]; then + if [[ -n \"$file\" ]]; then error \"$usage\" fi @@ -179,11 +181,11 @@ then always strip the trailing slash (as shown above for the \c{-t} option). Validate option/argument values. For example: \ -if [ -z \"$file\" ]; then +if [[ -z \"$file\" ]]; then error \"$usage\" fi -if [ ! -d \"$file\" ]; then +if [[ ! -d \"$file\" ]]; then error \"'$file' does not exist or is not a directory\" fi \ @@ -199,11 +201,14 @@ functions, then define them just before use. We quote every variable expansion, no exceptions. For example: \ -if [ -n \"$foo\" ]; then +if [[ -n \"$foo\" ]]; then ... fi \ +\N|While there is no word splitting in the \c{[[ ]]} context, we still quote +variable expansions for consistency.| + This also applies to command substitution (which we always write as \c{$(foo arg)} rather than \c{`foo arg`}), for example: @@ -232,13 +237,27 @@ option=--quiet # Option name. seds='s%^./%%' # sed script. \ -Take care to quote globs that are not meant to be expanded. And since quoting -will inhibit globbing, you may end up with expansions along these lines: +Take care to quote globs that are not meant to be expanded, for example: + +\ +unset \"array[0]\" +\ + +And since quoting will inhibit globbing, you may end up with expansions along +these lines: \ rm -f \"$dir/$name\".* \ +Note also that globbing is not performed in the \c{[[ ]]} context so this is +ok: + +if [[ -v array[0] ]]; then + ... +fi + + \N|One exception to this quoting rule is arithmetic expansion (\c{$((\ ))}): Bash treats it as if it was double-quoted and, as a result, any inner quoting is treated literally. For example: @@ -259,7 +278,7 @@ typical example of a space-aware argument handling: \ files=() -while [ \"$#\" -gt 0 ]; do +while [[ \"$#\" -gt 0 ]]; do case \"$1\" in ... @@ -304,11 +323,11 @@ can have terse and natural looking conditions, for example: first=true while ...; do - if [ ! \"$first\" ]; then + if [[ ! \"$first\" ]]; then ... fi - if [ \"$first\" ]; then + if [[ \"$first\" ]]; then first= fi @@ -601,7 +620,7 @@ cleanup /no/such/dir | cat r=\"${PIPESTATUS[0]}\" set -o pipefail -if [ \"$r\" -ne 0 ]; then +if [[ \"$r\" -ne 0 ]]; then ... fi \ |