format(docs): remove escaped t's

This commit is contained in:
Vera De Kalb 2024-03-30 14:09:26 -05:00
parent a0a82533bc
commit 4166a76a00
70 changed files with 283 additions and 283 deletions

View File

@ -90,7 +90,7 @@ See [read](commands/builtin/read.md)
### Changes to the "help" builtin ### Changes to the "help" builtin
The builtin itself didn\'t change much, but the data displayed is more The builtin itself didn't change much, but the data displayed is more
structured now. The help texts are in a better format, much easier to structured now. The help texts are in a better format, much easier to
read. read.

View File

@ -60,7 +60,7 @@ f3
## Notes ## Notes
- `caller` produces no output unless used within a script that's run - `caller` produces no output unless used within a script that's run
from a real file. It isn\'t particularly useful for interactive use, from a real file. It isn't particularly useful for interactive use,
but can be used to create a decent `die` function to track down but can be used to create a decent `die` function to track down
errors in moderately complex scripts. errors in moderately complex scripts.
`{ bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'` `{ bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'`

View File

@ -22,7 +22,7 @@ variable.
When used in a function, `declare` makes `NAMEs` local variables, unless When used in a function, `declare` makes `NAMEs` local variables, unless
used with the `-g` option. used with the `-g` option.
Don\'t use it's synonym `typeset` when coding for Bash, since it's Don't use it's synonym `typeset` when coding for Bash, since it's
tagged as obsolete. tagged as obsolete.
### Options ### Options
@ -167,7 +167,7 @@ for details. ksh93 namerefs are much more powerful than Bash's.
possible exception of Zsh in Bash compatibility mode. Bash marks the possible exception of Zsh in Bash compatibility mode. Bash marks the
synonym `typeset` as obsolete, which in Bash behaves identically to synonym `typeset` as obsolete, which in Bash behaves identically to
`declare`. All other Korn-like shells use `typeset`, so it probably `declare`. All other Korn-like shells use `typeset`, so it probably
isn\'t going away any time soon. Unfortunately, being a non-standard isn't going away any time soon. Unfortunately, being a non-standard
builtin, `typeset` differs significantly between shells. ksh93 also builtin, `typeset` differs significantly between shells. ksh93 also
considers `typeset` a special builtin, while Bash does not - even in considers `typeset` a special builtin, while Bash does not - even in
POSIX mode. If you use `typeset`, you should attempt to only use it POSIX mode. If you use `typeset`, you should attempt to only use it

View File

@ -10,7 +10,7 @@
newline. The return status is always `0`. If the newline. The return status is always `0`. If the
[shopt](../../commands/builtin/shopt.md) option `xpg_echo` is set, Bash [shopt](../../commands/builtin/shopt.md) option `xpg_echo` is set, Bash
dynamically determines whether echo should expand escape characters dynamically determines whether echo should expand escape characters
(listed below) by default based on the current platform. `echo` doesn\'t (listed below) by default based on the current platform. `echo` doesn't
interpret `--` as the end of options, and will simply print this string interpret `--` as the end of options, and will simply print this string
if given. if given.

View File

@ -33,7 +33,7 @@ the `eval` command below it.
Frequently, `eval` is used to cause side-effects by performing a pass of Frequently, `eval` is used to cause side-effects by performing a pass of
expansion on the code before executing the resulting string. This allows expansion on the code before executing the resulting string. This allows
for things that otherwise wouldn\'t be possible with ordinary Bash for things that otherwise wouldn't be possible with ordinary Bash
syntax. This also, of course, makes `eval` the most powerful command in syntax. This also, of course, makes `eval` the most powerful command in
all of shell programming (and in most other languages for that matter). all of shell programming (and in most other languages for that matter).
@ -106,7 +106,7 @@ controlled carefully by the caller is a good way to use it.
of eval will leak out into the surrounding environment. It is of eval will leak out into the surrounding environment. It is
possible to work around this limitation by prefixing special possible to work around this limitation by prefixing special
builtins with the `command` regular builtin, but current versions of builtins with the `command` regular builtin, but current versions of
~~ksh93~~ and zsh don\'t do this properly ~~ksh93~~ and zsh don't do this properly
([fixed](http://article.gmane.org/gmane.comp.programming.tools.ast.devel/686) ([fixed](http://article.gmane.org/gmane.comp.programming.tools.ast.devel/686)
in ksh 93v- 2012-10-24 alpha). Earlier versions of zsh work (with in ksh 93v- 2012-10-24 alpha). Earlier versions of zsh work (with
`setopt POSIX_BUILTINS` \-- looks like a regression). This works `setopt POSIX_BUILTINS` \-- looks like a regression). This works
@ -129,12 +129,12 @@ controlled carefully by the caller is a good way to use it.
$ ( x=a; eval "$x"'=( a b\ c d )'; printf '<%s> ' "${a[@]}"; echo ) # Proper quoting then gives us the expected results. $ ( x=a; eval "$x"'=( a b\ c d )'; printf '<%s> ' "${a[@]}"; echo ) # Proper quoting then gives us the expected results.
<a> <b c> <d> <a> <b c> <d>
We don\'t know why Bash does this. Since parentheses are metacharacters, We don't know why Bash does this. Since parentheses are metacharacters,
they must ordinary be quoted or escaped when used as arguments. The they must ordinary be quoted or escaped when used as arguments. The
first example above is the same error as the second in all non-Bash first example above is the same error as the second in all non-Bash
shells, even those with compound assignment. shells, even those with compound assignment.
In the case of `eval` it isn\'t recommended to use this behavior, In the case of `eval` it isn't recommended to use this behavior,
because unlike e.g. [declare](../../commands/builtin/declare.md), the initial because unlike e.g. [declare](../../commands/builtin/declare.md), the initial
expansion is still subject to all expansions including expansion is still subject to all expansions including
[word-splitting](../../syntax/expansion/wordsplit.md) and [pathname [word-splitting](../../syntax/expansion/wordsplit.md) and [pathname

View File

@ -22,7 +22,7 @@ There are no options.
### Exit status ### Exit status
Naturally, you can\'t ask for the exit status from within the shell that Naturally, you can't ask for the exit status from within the shell that
executed the `exit` command, because the shell exits. executed the `exit` command, because the shell exits.
Status Reason Status Reason

View File

@ -24,7 +24,7 @@ difference being `let` is a builtin (simple command), and `((` is a
compound command. The arguments to `let` are therefore subject to all compound command. The arguments to `let` are therefore subject to all
the same expansions and substitutions as any other simple command - the same expansions and substitutions as any other simple command -
requiring proper quoting and escaping - whereas the contents of `((` requiring proper quoting and escaping - whereas the contents of `((`
aren\'t subject to [word-splitting](../../syntax/expansion/wordsplit.md) or aren't subject to [word-splitting](../../syntax/expansion/wordsplit.md) or
[pathname expansion](../../syntax/expansion/globs.md) (almost never desirable [pathname expansion](../../syntax/expansion/globs.md) (almost never desirable
for arithmetic). For this reason, **the [arithmetic compound for arithmetic). For this reason, **the [arithmetic compound
command](../../syntax/ccmd/arithmetic_eval.md) should generally be preferred command](../../syntax/ccmd/arithmetic_eval.md) should generally be preferred
@ -80,7 +80,7 @@ needed.
- It seems to be a common misunderstanding that `let` has some legacy - It seems to be a common misunderstanding that `let` has some legacy
purpose. Both `let` and [[^1]](../../syntax/ccmd/arithmetic_eval.md) were purpose. Both `let` and [[^1]](../../syntax/ccmd/arithmetic_eval.md) were
ksh88 features and almost identical in terms of portability as ksh88 features and almost identical in terms of portability as
everything that inherited one also tended to get the other. Don\'t everything that inherited one also tended to get the other. Don't
choose `let` over `((` expecting it to work in more places. choose `let` over `((` expecting it to work in more places.
- [expr(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html#tag_20_42) - [expr(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html#tag_20_42)
is a command one is likely to come across sooner or later. While it is a command one is likely to come across sooner or later. While it

View File

@ -26,7 +26,7 @@ way, and takes all the same options, with 3 exceptions:
## Portability considerations ## Portability considerations
- `local` is not specified by POSIX. Most bourne-like shells don\'t - `local` is not specified by POSIX. Most bourne-like shells don't
have a builtin called `local`, but some such as `dash` and the have a builtin called `local`, but some such as `dash` and the
busybox shell do. busybox shell do.
@ -41,15 +41,15 @@ way, and takes all the same options, with 3 exceptions:
```{=html} ```{=html}
<!-- --> <!-- -->
``` ```
- In ksh93, using POSIX-style function definitions, `typeset` doesn\'t - In ksh93, using POSIX-style function definitions, `typeset` doesn't
set `local` variables, but rather acts upon variables of the set `local` variables, but rather acts upon variables of the
next-outermost scope (e.g. setting attributes). Using `typeset` next-outermost scope (e.g. setting attributes). Using `typeset`
within functions defined using ksh `function name {` syntax, within functions defined using ksh `function name {` syntax,
variables follow roughly variables follow roughly
[lexical-scoping](http://community.schemewiki.org/?lexical-scope), [lexical-scoping](http://community.schemewiki.org/?lexical-scope),
except that functions themselves don\'t have scope, just like Bash. except that functions themselves don't have scope, just like Bash.
This means that even functions defined within a \"function's This means that even functions defined within a \"function's
scope\" don\'t have access to non-local variables except through scope\" don't have access to non-local variables except through
`namerefs`. `namerefs`.
## See also ## See also

View File

@ -29,13 +29,13 @@ given array `ARRAY` is set readonly.
`-t` Remove any trailing newline from a line read, before it is assigned to an array element. `-t` Remove any trailing newline from a line read, before it is assigned to an array element.
`-u FD` Read from filedescriptor `FD` rather than standard input. `-u FD` Read from filedescriptor `FD` rather than standard input.
While `mapfile` isn\'t a common or portable shell feature, it's While `mapfile` isn't a common or portable shell feature, it's
functionality will be familiar to many programmers. Almost all functionality will be familiar to many programmers. Almost all
programming languages (aside from shells) with support for compound programming languages (aside from shells) with support for compound
datatypes like arrays, and which handle open file objects in the datatypes like arrays, and which handle open file objects in the
traditional way, have some analogous shortcut for easily reading all traditional way, have some analogous shortcut for easily reading all
lines of some input as a standard feature. In Bash, `mapfile` in itself lines of some input as a standard feature. In Bash, `mapfile` in itself
can\'t do anything that couldn\'t already be done using read and a loop, can't do anything that couldn't already be done using read and a loop,
and if portability is even a slight concern, should never be used. and if portability is even a slight concern, should never be used.
However, it does *significantly* outperform a read loop, and can make However, it does *significantly* outperform a read loop, and can make
for shorter and cleaner code - especially convenient for interactive for shorter and cleaner code - especially convenient for interactive
@ -62,7 +62,7 @@ Note the use of command grouping to keep the emerge command inside the
pipe's subshell and within the scope of \"args\". Also note the unusual pipe's subshell and within the scope of \"args\". Also note the unusual
redirection. This is because the -a flag makes emerge interactive, redirection. This is because the -a flag makes emerge interactive,
asking the user for confirmation before continuing, and checking with asking the user for confirmation before continuing, and checking with
isatty(3) to abort if stdin isn\'t pointed at a terminal. Since stdin of isatty(3) to abort if stdin isn't pointed at a terminal. Since stdin of
the entire command group is still coming from the pipe even though the entire command group is still coming from the pipe even though
mapfile has read all available input, we just borrow FD 1 as it just so mapfile has read all available input, we just borrow FD 1 as it just so
happens to be pointing where we want it. More on this over at greycat's happens to be pointing where we want it. More on this over at greycat's
@ -216,6 +216,6 @@ each subsequent 2 iterations. The RETURN trap is unimportant.
## See also ## See also
- [arrays](../../syntax/arrays.md) - [arrays](../../syntax/arrays.md)
- [read](../../commands/builtin/read.md) - If you don\'t know about this yet, - [read](../../commands/builtin/read.md) - If you don't know about this yet,
why are you reading this page? why are you reading this page?
- <http://mywiki.wooledge.org/BashFAQ/001> - It's FAQ 1 for a reason. - <http://mywiki.wooledge.org/BashFAQ/001> - It's FAQ 1 for a reason.

View File

@ -12,7 +12,7 @@ expects a comma after the format string and between each of the
arguments of a **printf** command. For examples, see: [code arguments of a **printf** command. For examples, see: [code
snippet](../../printf?&.md#using_printf_inside_of_awk). \</div\> snippet](../../printf?&.md#using_printf_inside_of_awk). \</div\>
Unlike other documentations, I don\'t want to redirect you to the manual Unlike other documentations, I don't want to redirect you to the manual
page for the `printf()` C function family. However, if you\'re more page for the `printf()` C function family. However, if you\'re more
experienced, that should be the most detailed description for the format experienced, that should be the most detailed description for the format
strings and modifiers. strings and modifiers.
@ -54,7 +54,7 @@ argument!).
`-v VAR` If given, the output is assigned to the variable `VAR` instead of printed to `stdout` (comparable to `sprintf()` in some way) `-v VAR` If given, the output is assigned to the variable `VAR` instead of printed to `stdout` (comparable to `sprintf()` in some way)
---------- ------------------------------------------------------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------------------------------------------------------
The `-v` Option can\'t assign directly to array indexes in Bash versions The `-v` Option can't assign directly to array indexes in Bash versions
older than Bash 4.1. older than Bash 4.1.
\<note warning\> In versions newer than 4.1, one must be careful when \<note warning\> In versions newer than 4.1, one must be careful when
@ -84,8 +84,8 @@ recognized to give a number-argument to `printf`:
`0N` An octal number `0N` An octal number
`0xN` A hexadecimal number `0xN` A hexadecimal number
`0XN` A hexadecimal number `0XN` A hexadecimal number
`"X` (a literal double-quote infront of a character): interpreted as number (underlying codeset) **don\'t forget escaping** `"X` (a literal double-quote infront of a character): interpreted as number (underlying codeset) **don't forget escaping**
`'X` (a literal single-quote infront of a character): interpreted as number (underlying codeset) **don\'t forget escaping** `'X` (a literal single-quote infront of a character): interpreted as number (underlying codeset) **don't forget escaping**
[**If more arguments than format specifiers**]{.underline} are present, [**If more arguments than format specifiers**]{.underline} are present,
then the format string is re-used until the last argument is then the format string is re-used until the last argument is
@ -143,7 +143,7 @@ all mean the same: A placeholder for data with a specified format:
`%G` Same as `%g`, but print it like `%E` `%G` Same as `%g`, but print it like `%E`
`%c` Interprets the associated argument as **char**: only the first character of a given argument is printed `%c` Interprets the associated argument as **char**: only the first character of a given argument is printed
`%s` Interprets the associated argument literally as string `%s` Interprets the associated argument literally as string
`%n` Assigns the number of characters printed so far to the variable named in the corresponding argument. Can\'t specify an array index. If the given name is already an array, the value is assigned to the zeroth element. `%n` Assigns the number of characters printed so far to the variable named in the corresponding argument. Can't specify an array index. If the given name is already an array, the value is assigned to the zeroth element.
`%a` Interprets the associated argument as **double**, and prints it in the form of a C99 [hexadecimal floating-point literal](http://www.exploringbinary.com/hexadecimal-floating-point-constants/). `%a` Interprets the associated argument as **double**, and prints it in the form of a C99 [hexadecimal floating-point literal](http://www.exploringbinary.com/hexadecimal-floating-point-constants/).
`%A` Same as `%a`, but print it like `%E` `%A` Same as `%a`, but print it like `%E`
`%(FORMAT)T` output the date-time string resulting from using `FORMAT` as a format string for `strftime(3)`. The associated argument is the number of seconds since Epoch, or `-1` (current time) or `-2` (shell startup time). If no corresponding argument is supplies, the current time is used as default `%(FORMAT)T` output the date-time string resulting from using `FORMAT` as a format string for `strftime(3)`. The associated argument is the number of seconds since Epoch, or `-1` (current time) or `-2` (shell startup time). If no corresponding argument is supplies, the current time is used as default
@ -192,7 +192,7 @@ that precedes the number to print, like (prints 4,3000000000):
printf "%.*f\n" 10 4,3 printf "%.*f\n" 10 4,3
The format `.*N` to specify the N\'th argument for precision does not The format `.*N` to specify the N'th argument for precision does not
work in Bash. work in Bash.
For strings, the precision specifies the maximum number of characters to For strings, the precision specifies the maximum number of characters to
@ -364,7 +364,7 @@ correct awk syntax.
With appropriate metacharacter escaping the bash printf can be called With appropriate metacharacter escaping the bash printf can be called
from inside awk (as from perl and other languages that support shell from inside awk (as from perl and other languages that support shell
callout) as long as you don\'t care about program efficiency or callout) as long as you don't care about program efficiency or
readability. readability.
echo "Foo" | awk '{ system( "printf \"%s\\n \" \"" $1 "\"" ) }' echo "Foo" | awk '{ system( "printf \"%s\\n \" \"" $1 "\"" ) }'
@ -453,7 +453,7 @@ fmt++;
synopsis as: synopsis as:
`print: print [-Rnprs] [-u unit] [-f format] [arguments]`. However, `print: print [-Rnprs] [-u unit] [-f format] [arguments]`. However,
only `-Rrnfu` are actually functional. Internally, `-p` is a noop only `-Rrnfu` are actually functional. Internally, `-p` is a noop
(it doesn\'t tie in with Bash coprocs at all), and `-s` only sets a (it doesn't tie in with Bash coprocs at all), and `-s` only sets a
flag but has no effect. `-Cev` are unimplemented. flag but has no effect. `-Cev` are unimplemented.
```{=html} ```{=html}

View File

@ -49,7 +49,7 @@ line is read). That means the timeout can occur during input, too.
`-N <NCHARS>` reads `<NCHARS>` characters of input, *ignoring any delimiter*, then quits `-N <NCHARS>` reads `<NCHARS>` characters of input, *ignoring any delimiter*, then quits
`-p <PROMPT>` the prompt string `<PROMPT>` is output (without a trailing automatic newline) before the read is performed `-p <PROMPT>` the prompt string `<PROMPT>` is output (without a trailing automatic newline) before the read is performed
`-r` raw input - **disables** interpretion of **backslash escapes** and **line-continuation** in the read data `-r` raw input - **disables** interpretion of **backslash escapes** and **line-continuation** in the read data
`-s` secure input - don\'t echo input if on a terminal (passwords!) `-s` secure input - don't echo input if on a terminal (passwords!)
`-t <TIMEOUT>` wait for data `<TIMEOUT>` seconds, then quit (exit code 1). Fractional seconds (\"5.33\") are allowed since Bash 4. A value of 0 immediately returns and indicates if data is waiting in the exit code. Timeout is indicated by an exit code greater than 128. If timeout arrives before data is read completely (before end-of-line), the partial data is saved. `-t <TIMEOUT>` wait for data `<TIMEOUT>` seconds, then quit (exit code 1). Fractional seconds (\"5.33\") are allowed since Bash 4. A value of 0 immediately returns and indicates if data is waiting in the exit code. Timeout is indicated by an exit code greater than 128. If timeout arrives before data is read completely (before end-of-line), the partial data is saved.
`-u <FD>` use the filedescriptor number `<FD>` rather than `stdin` (0) `-u <FD>` use the filedescriptor number `<FD>` rather than `stdin` (0)
@ -254,9 +254,9 @@ date/time string are recognized correctly.
- POSIX(r) only specified the `-r` option (raw read); `-r` is not only - POSIX(r) only specified the `-r` option (raw read); `-r` is not only
POSIX, you can find it in earlier Bourne source code POSIX, you can find it in earlier Bourne source code
- POSIX(r) doesn\'t support arrays - POSIX(r) doesn't support arrays
- `REPLY` is not POSIX(r), you need to set `IFS` to the empty string - `REPLY` is not POSIX(r), you need to set `IFS` to the empty string
to get the whole line for shells that don\'t know `REPLY`. to get the whole line for shells that don't know `REPLY`.
`while IFS= read -r line; do `while IFS= read -r line; do
... ...
done < text.txt done < text.txt

View File

@ -7,7 +7,7 @@
## Description ## Description
The `readonly` builtin command is used to mark variables or functions as The `readonly` builtin command is used to mark variables or functions as
read-only, which means unchangeable. This implies that it can\'t be read-only, which means unchangeable. This implies that it can't be
unset anymore. A `readonly` variable may not be redefined in child unset anymore. A `readonly` variable may not be redefined in child
scopes. A readonly global may not be redefined as a function local scopes. A readonly global may not be redefined as a function local
variable. Simple command environment assignments may not reference variable. Simple command environment assignments may not reference

View File

@ -18,7 +18,7 @@ There are no options.
### Exit status ### Exit status
If everything is okay, the `return` command doesn\'t come back. If it If everything is okay, the `return` command doesn't come back. If it
comes back, there was a problem in doing the return. comes back, there was a problem in doing the return.
Status Reason Status Reason

View File

@ -27,7 +27,7 @@ set flags (true for most commands on UNIX(r)).
Flag Optionname Description Flag Optionname Description
------ ---------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------ ---------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`-a` `allexport` Automatically mark new and altered variables to be exported to subsequent environments. `-a` `allexport` Automatically mark new and altered variables to be exported to subsequent environments.
`-b` `notify` Don\'t wait for the next prompt to print when showing the reports for a terminated background job (only with job control) `-b` `notify` Don't wait for the next prompt to print when showing the reports for a terminated background job (only with job control)
`-e` `errexit` When set, the shell exits when a simple command in a command list exits non-zero (`FALSE`). This is not done in situations, where the exit code is already checked (`if`, `while`, `until`, `||`, `&&`) `-e` `errexit` When set, the shell exits when a simple command in a command list exits non-zero (`FALSE`). This is not done in situations, where the exit code is already checked (`if`, `while`, `until`, `||`, `&&`)
`-f` `noglob` Disable [pathname expansion](../../syntax/expansion/globs.md) (globbing) `-f` `noglob` Disable [pathname expansion](../../syntax/expansion/globs.md) (globbing)
`-h` `hashall` Remembers the location of commands when they\'re called (hashing). Enabled by default. `-h` `hashall` Remembers the location of commands when they\'re called (hashing). Enabled by default.
@ -41,10 +41,10 @@ set flags (true for most commands on UNIX(r)).
`-v` `verbose` Print shell input lines as they are read - useful for debugging. `-v` `verbose` Print shell input lines as they are read - useful for debugging.
`-x` `xtrace` Print commands just before execution - with all expansions and substitutions done, and words marked - useful for debugging. `-x` `xtrace` Print commands just before execution - with all expansions and substitutions done, and words marked - useful for debugging.
`-B` `braceexpand` The shell performs [brace expansion](../../syntax/expansion/brace.md) This is on by default. `-B` `braceexpand` The shell performs [brace expansion](../../syntax/expansion/brace.md) This is on by default.
`-C` \<BOOKMARK:tag_noclobber\>`noclobber` Don\'t overwrite files on redirection operations. You can override that by specifying the `>|` redirection operator when needed. See [redirection](../../syntax/redirection.md) `-C` \<BOOKMARK:tag_noclobber\>`noclobber` Don't overwrite files on redirection operations. You can override that by specifying the `>|` redirection operator when needed. See [redirection](../../syntax/redirection.md)
`-E` `errtrace` `ERR`-traps are inherited by by shell functions, command substitutions, and commands executed in a subshell environment. `-E` `errtrace` `ERR`-traps are inherited by by shell functions, command substitutions, and commands executed in a subshell environment.
`-H` `histexpand` Enable `!`-style history expansion. Defaults to `on` for interactive shells. `-H` `histexpand` Enable `!`-style history expansion. Defaults to `on` for interactive shells.
`-P` `physical` Don\'t follow symlinks when changing directories - use the physical filesystem structure. `-P` `physical` Don't follow symlinks when changing directories - use the physical filesystem structure.
`-T` `functrace` `DEBUG`- and `RETURN`-traps are inherited by subsequent environments, like `-E` for `ERR` trap. `-T` `functrace` `DEBUG`- and `RETURN`-traps are inherited by subsequent environments, like `-E` for `ERR` trap.
`-` \"End of options\" - all following arguments are assigned to the positional parameters, even when they begin with a dash. `-x` and `-v` options are turned off. Positional parameters are unchanged (unlike using `--`!) when no further arguments are given. `-` \"End of options\" - all following arguments are assigned to the positional parameters, even when they begin with a dash. `-x` and `-v` options are turned off. Positional parameters are unchanged (unlike using `--`!) when no further arguments are given.
`--` If no arguments follow, the positional parameters are unset. With arguments, the positional parameters are set, even if the strings begin with a `-` (dash) like an option. `--` If no arguments follow, the positional parameters are unset. With arguments, the positional parameters are set, even if the strings begin with a `-` (dash) like an option.

View File

@ -67,8 +67,8 @@ There are no options.
command shift 2\>/dev/null; then echo \"\$1\"; else echo \"no command shift 2\>/dev/null; then echo \"\$1\"; else echo \"no
args\"; fi; }; f\' args\"; fi; }; f\'
no args \</code\> While, POSIX requires this behavior, it isn\'t very no args \</code\> While, POSIX requires this behavior, it isn't very
obvious and some shells don\'t do it correctly. To work around this, you obvious and some shells don't do it correctly. To work around this, you
can use something like: can use something like:
\<code\> \$ mksh -c \'f() { if ! \${1+false} && shift; then echo \<code\> \$ mksh -c \'f() { if ! \${1+false} && shift; then echo

View File

@ -33,7 +33,7 @@ When listing options, the exit code is `TRUE` (0), if all options are
enabled, `FALSE` otherwise. enabled, `FALSE` otherwise.
When setting/unsetting an option, the exit code is `TRUE` unless the When setting/unsetting an option, the exit code is `TRUE` unless the
named option doesn\'t exitst. named option doesn't exitst.
## Examples ## Examples

View File

@ -51,7 +51,7 @@ variable has been set, then the variable of the same name in the
next-outermost scope becomes visible to its scope and all children - as next-outermost scope becomes visible to its scope and all children - as
if the variable that was unset was never set to begin with. This if the variable that was unset was never set to begin with. This
property allows looking upwards through the stack as variable names are property allows looking upwards through the stack as variable names are
unset, so long as unset and the local it unsets aren\'t together in the unset, so long as unset and the local it unsets aren't together in the
same scope level. same scope level.
Here's a demonstration of this behavior. Here's a demonstration of this behavior.
@ -130,7 +130,7 @@ Some things to observe:
- Declaring a global with declare -g bypasses all locals and sets or - Declaring a global with declare -g bypasses all locals and sets or
modifies the variable of the global scope (outside of all modifies the variable of the global scope (outside of all
functions). It has no affect on the visibility of the global. functions). It has no affect on the visibility of the global.
- This doesn\'t apply to individual array elements. If two local - This doesn't apply to individual array elements. If two local
arrays of the same name appear in different scopes, the entire array arrays of the same name appear in different scopes, the entire array
of the inner scope needs to be unset before any elements of the of the inner scope needs to be unset before any elements of the
outer array become visible. This makes \"unset\" and \"unset2\" outer array become visible. This makes \"unset\" and \"unset2\"

View File

@ -36,9 +36,9 @@ purposes, like reporting a termination by a signal:
--------- ------------------------------------------------------------------------------------------------------------------------------------------------------------ --------- ------------------------------------------------------------------------------------------------------------------------------------------------------------
0 success 0 success
1-255 failure (in general) 1-255 failure (in general)
126 the requested command (file) can\'t be executed (but was found) 126 the requested command (file) can't be executed (but was found)
127 command (file) not found 127 command (file) not found
128 according to ABS it's used to report an invalid argument to the exit builtin, but I wasn\'t able to verify that in the source code of Bash (see code 255) 128 according to ABS it's used to report an invalid argument to the exit builtin, but I wasn't able to verify that in the source code of Bash (see code 255)
128 + N the shell was terminated by the signal N (also used like this by various other programs) 128 + N the shell was terminated by the signal N (also used like this by various other programs)
255 wrong argument to the exit builtin (see code 128) 255 wrong argument to the exit builtin (see code 128)
@ -51,7 +51,7 @@ control statements like `if` or `while`.
## Portability ## Portability
Tables of shell behavior involving non-portable side-effects or common Tables of shell behavior involving non-portable side-effects or common
bugs with exit statuses. Note heirloom doesn\'t support pipeline bugs with exit statuses. Note heirloom doesn't support pipeline
negation (`! pipeline`). negation (`! pipeline`).
### Misc ### Misc

View File

@ -26,7 +26,7 @@ file and a hard link, let's take a look at the example:
$ ln a b $ ln a b
$ ln -s a c $ ln -s a c
as you can see file(1) can\'t differentiate between a real file \'a\' as you can see file(1) can't differentiate between a real file \'a\'
and a hard link \'b\', but it can tell \'c\' is a sym link and a hard link \'b\', but it can tell \'c\' is a sym link
$ file * $ file *
@ -41,7 +41,7 @@ same inode number AND are on the same file system it means they are
$ ls -i * $ ls -i *
5262 a 5262 b 5263 c 5262 a 5262 b 5263 c
hard links don\'t consume additional space on the filesystem, the space hard links don't consume additional space on the filesystem, the space
is freed when the last hard link pointing to it is deleted. is freed when the last hard link pointing to it is deleted.
## See also ## See also

View File

@ -26,7 +26,7 @@ systems, including:
- may be able to take arguments for the interpreter - may be able to take arguments for the interpreter
- \... - \...
POSIX(r) doesn\'t specify the shebang, though in general it's commonly POSIX(r) doesn't specify the shebang, though in general it's commonly
supported by operating systems. supported by operating systems.
## See also ## See also

View File

@ -39,7 +39,7 @@ A positional parameter is denoted by a number other than `0` (zero).
Positional parameters reflect the shell's arguments that are not given Positional parameters reflect the shell's arguments that are not given
to the shell itself (in practise, the script arguments, also the to the shell itself (in practise, the script arguments, also the
function arguments). You can\'t directly assign to the positional function arguments). You can't directly assign to the positional
parameters, however, [the set builtin command](../commands/builtin/set.md) parameters, however, [the set builtin command](../commands/builtin/set.md)
can be used to indirectly set them. can be used to indirectly set them.

View File

@ -1,12 +1,12 @@
# Shell # Shell
On UNIX(r), the shell is the main interaction tool between the On UNIX(r), the shell is the main interaction tool between the
user-level and the system. That doesn\'t necessarily mean the user user-level and the system. That doesn't necessarily mean the user
always sits infront of a shell, but it's integral part of the system, always sits infront of a shell, but it's integral part of the system,
not only an \"optional commandline interpreter\". not only an \"optional commandline interpreter\".
The main job of a shell is to execute commands as a user requests them. The main job of a shell is to execute commands as a user requests them.
This behaviour alone doesn\'t help much. A shell knits some intelligence This behaviour alone doesn't help much. A shell knits some intelligence
and flow control around the possibility to execute commands - it's a and flow control around the possibility to execute commands - it's a
complete commandline-oriented user-interface (UI). complete commandline-oriented user-interface (UI).

View File

@ -5,7 +5,7 @@ to another filename. Since it really only points to another **filename**
it can it can
- reference filenames on other filesystems - reference filenames on other filesystems
- reference filenames that don\'t actually exist - reference filenames that don't actually exist
- save a reference to the name of a directory - save a reference to the name of a directory
## See also ## See also

View File

@ -18,7 +18,7 @@ In brief, the *reverse polish notation* means the numbers are put on the
stack first, then an operation is applied to them. Instead of writing stack first, then an operation is applied to them. Instead of writing
`1+1`, you write `1 1+`. `1+1`, you write `1 1+`.
By default `dc`, unlike `bc`, doesn\'t print anything, the result is By default `dc`, unlike `bc`, doesn't print anything, the result is
pushed on the stack. You have to use the \"p\" command to print the pushed on the stack. You have to use the \"p\" command to print the
element at the top of the stack. Thus a simple operation looks like: element at the top of the stack. Thus a simple operation looks like:
@ -26,7 +26,7 @@ element at the top of the stack. Thus a simple operation looks like:
2 2
I used a \"here string\" present in bash 3.x, ksh93 and zsh. if your I used a \"here string\" present in bash 3.x, ksh93 and zsh. if your
shell doesn\'t support this, you can use `echo '1 1+p' | dc` or if you shell doesn't support this, you can use `echo '1 1+p' | dc` or if you
have GNU `dc`, you can use `dc -e '1 1 +p`\'. have GNU `dc`, you can use `dc -e '1 1 +p`\'.
Of course, you can also just run `dc` and enter the commands. Of course, you can also just run `dc` and enter the commands.
@ -142,7 +142,7 @@ command `f`. The stack remains unchanged:
Note how the first element that will be popped from the stack is printed Note how the first element that will be popped from the stack is printed
first, if you are used to an HP calculator, it's the reverse. first, if you are used to an HP calculator, it's the reverse.
Don\'t hesitate to put `f` in the examples of this tutorial, it doesn\'t Don't hesitate to put `f` in the examples of this tutorial, it doesn't
change the result, and it's a good way to see what's going on. change the result, and it's a good way to see what's going on.
## Registers ## Registers
@ -159,7 +159,7 @@ supposed to use the NUL byte. Using a register is easy:
+p # add the 2 values and print +p # add the 2 values and print
EOF EOF
The above snippet uses newlines to embed comments, but it doesn\'t The above snippet uses newlines to embed comments, but it doesn't
really matter, you can use `echo '12sa10la+p'| dc`, with the same really matter, you can use `echo '12sa10la+p'| dc`, with the same
results. results.
@ -184,7 +184,7 @@ enclosed in `[]`. You can print it with `p`: `dc <<< '[Hello World!]p'`
and you can evalute it with x: `dc <<< '[1 2+]xp'`. and you can evalute it with x: `dc <<< '[1 2+]xp'`.
This is not that interesting until combined with registers. First, This is not that interesting until combined with registers. First,
let's say we want to calculate the square of a number (don\'t forget to let's say we want to calculate the square of a number (don't forget to
include `f` if you get lost!): include `f` if you get lost!):
dc << EOF dc << EOF
@ -223,7 +223,7 @@ we are used to reading:
Some `dc` have `>R <R =R`, GNU `dc` had some more, check your manual. Some `dc` have `>R <R =R`, GNU `dc` had some more, check your manual.
Note that the test \"consumes\" its operands: the 2 first elements are Note that the test \"consumes\" its operands: the 2 first elements are
popped off the stack (you can verify that popped off the stack (you can verify that
`dc <<< "[f]sR 2 1 >R 1 2 >R f"` doesn\'t print anything) `dc <<< "[f]sR 2 1 >R 1 2 >R f"` doesn't print anything)
Have you noticed how we can *include* a macro (string) in a macro? and Have you noticed how we can *include* a macro (string) in a macro? and
as `dc` relies on a stack we can, in fact, use the macro recursively as `dc` relies on a stack we can, in fact, use the macro recursively
@ -261,7 +261,7 @@ stack instead of a register for the index.
## Next ## Next
Check your dc manual, i haven\'t decribed everything, like arrays (only Check your dc manual, i haven't decribed everything, like arrays (only
documented with \"; : are used by bc(1) for array operations\" on documented with \"; : are used by bc(1) for array operations\" on
solaris, probably because *echo \'1 0:a 0Sa 2 0:a La 0;ap\' \| dc* solaris, probably because *echo \'1 0:a 0Sa 2 0:a La 0;ap\' \| dc*
results in //Segmentation Fault (core dump) //, the latest solaris uses results in //Segmentation Fault (core dump) //, the latest solaris uses

View File

@ -41,7 +41,7 @@ common example is a script that gives the user the option of having
## How does it work? ## How does it work?
The first time you run chatter(), the function redefines itself based on The first time you run chatter(), the function redefines itself based on
the value of verbose. Thereafter, chatter doesn\'t check \$verbose, it the value of verbose. Thereafter, chatter doesn't check \$verbose, it
simply is. Further calls to the function reflect its collapsed nature. simply is. Further calls to the function reflect its collapsed nature.
If verbose is unset, chatter will echo nothing, with no extra effort If verbose is unset, chatter will echo nothing, with no extra effort
from the developer. from the developer.

View File

@ -4,7 +4,7 @@
## General ## General
For this task, you don\'t have to write large parser routines (unless For this task, you don't have to write large parser routines (unless
you want it 100% secure or you want a special file syntax) - you can use you want it 100% secure or you want a special file syntax) - you can use
the Bash source command. The file to be sourced should be formated in the Bash source command. The file to be sourced should be formated in
key=\"value\" format, otherwise bash will try to interpret commands: key=\"value\" format, otherwise bash will try to interpret commands:
@ -74,10 +74,10 @@ malicious code:
echo rm -fr ~/* echo rm -fr ~/*
mailto=netadmin@example.com mailto=netadmin@example.com
You don\'t want these `echo`-commands (which could be any other You don't want these `echo`-commands (which could be any other
commands!) to be executed. One way to be a bit safer is to filter only commands!) to be executed. One way to be a bit safer is to filter only
the constructs you want, write the filtered results to a new file and the constructs you want, write the filtered results to a new file and
source the new file. We also need to be sure something nefarious hasn\'t source the new file. We also need to be sure something nefarious hasn't
been added to the end of one of our name=value parameters, perhaps using been added to the end of one of our name=value parameters, perhaps using
; or && command separators. In those cases, perhaps it is simplest to ; or && command separators. In those cases, perhaps it is simplest to
just ignore the line entirely. Egrep (`grep -E`) will help us here, it just ignore the line entirely. Egrep (`grep -E`) will help us here, it
@ -99,11 +99,11 @@ filters by description:
source "$configfile" source "$configfile"
**[To make clear what it does:]{.underline}** egrep checks if the file **[To make clear what it does:]{.underline}** egrep checks if the file
contains something we don\'t want, if yes, egrep filters the file and contains something we don't want, if yes, egrep filters the file and
writes the filtered contents to a new file. If done, the original file writes the filtered contents to a new file. If done, the original file
name is changed to the name stored in the variable `configfile`. The name is changed to the name stored in the variable `configfile`. The
file named by that variable is sourced, as if it were the original file. file named by that variable is sourced, as if it were the original file.
This filter allows only `NAME=VALUE` and comments in the file, but it This filter allows only `NAME=VALUE` and comments in the file, but it
doesn\'t prevent all methods of code execution. I will address that doesn't prevent all methods of code execution. I will address that
later. later.

View File

@ -45,7 +45,7 @@ of the old style backticks:
sh $ for i in *.zip; do j=$(basename "$i" ".zip"); mkdir $j; cd $j; unzip ../$i; cd ..; done sh $ for i in *.zip; do j=$(basename "$i" ".zip"); mkdir $j; cd $j; unzip ../$i; cd ..; done
``` ```
In Bash we don\'t need the subshell or the external basename command. In Bash we don't need the subshell or the external basename command.
See [Substring removal with parameter See [Substring removal with parameter
expansion](../syntax/pe.md#substring_removal): expansion](../syntax/pe.md#substring_removal):
@ -66,7 +66,7 @@ command(s), check for success! You can do this with the \"`&&`\"
conjunction, that way, if the previous command fails, bash will not try conjunction, that way, if the previous command fails, bash will not try
to execute the following command(s). It's fully POSIX(r). Oh, and to execute the following command(s). It's fully POSIX(r). Oh, and
remember what I said about [wordsplitting](../syntax/expansion/wordsplit.md) remember what I said about [wordsplitting](../syntax/expansion/wordsplit.md)
in the previous step? Well, if you don\'t quote `$j`, wordsplitting can in the previous step? Well, if you don't quote `$j`, wordsplitting can
happen again. happen again.
``` bash ``` bash
@ -106,7 +106,7 @@ mkdir "$j" && cd "$j" && unzip ../$i && cd -
Well, besides word splitting, there's nothing terribly wrong with this. Well, besides word splitting, there's nothing terribly wrong with this.
Still, did it occur to you that unzip might already be able to target a Still, did it occur to you that unzip might already be able to target a
directory? There isn\'t a standard for the `unzip` command, but all the directory? There isn't a standard for the `unzip` command, but all the
implementations I\'ve seen can do it with the -d flag. So we can drop implementations I\'ve seen can do it with the -d flag. So we can drop
the cd commands entirely: the cd commands entirely:

View File

@ -13,14 +13,14 @@ that, e.g. editing active and open files, the lack of GNU, or other
Why `ed`? Why `ed`?
- maybe your `sed` doesn\'t support in-place edit - maybe your `sed` doesn't support in-place edit
- maybe you need to be as portable as possible - maybe you need to be as portable as possible
- maybe you need to really edit in-file (and not create a new file - maybe you need to really edit in-file (and not create a new file
like GNU `sed`) like GNU `sed`)
- last but not least: standard `ed` has very good editing and - last but not least: standard `ed` has very good editing and
addressing possibilities, compared to standard `sed` addressing possibilities, compared to standard `sed`
Don\'t get me wrong, this is **not** meant as anti-`sed` article! It's Don't get me wrong, this is **not** meant as anti-`sed` article! It's
just meant to show you another way to do the job. just meant to show you another way to do the job.
## Commanding ed ## Commanding ed
@ -133,7 +133,7 @@ always a good idea to have a backup copy!**
## Editing your files ## Editing your files
Most of these things can be done with `sed`. But there are also things Most of these things can be done with `sed`. But there are also things
that can\'t be done in `sed` or can only be done with very complex code. that can't be done in `sed` or can only be done with very complex code.
### Simple word substitutions ### Simple word substitutions
@ -179,7 +179,7 @@ regexp
\...using the `m` command: `<ADDRESS> m <TARGET-ADDRESS>` \...using the `m` command: `<ADDRESS> m <TARGET-ADDRESS>`
This is definitely something that can\'t be done easily with sed. This is definitely something that can't be done easily with sed.
# moving lines 5-9 to the end of the file # moving lines 5-9 to the end of the file
ed -s test.txt <<< $'5,9m$\nw' ed -s test.txt <<< $'5,9m$\nw'
@ -206,7 +206,7 @@ command: `j` (join).
ed -s file <<< $'1,$j\nw' ed -s file <<< $'1,$j\nw'
Compared with two other methods (using `tr` or `sed`), you don\'t have Compared with two other methods (using `tr` or `sed`), you don't have
to delete all newlines and manually add one at the end. to delete all newlines and manually add one at the end.
### File operations ### File operations
@ -288,7 +288,7 @@ attempt the substitution on all non blank lines
**\_\_ shell parameters are expanded \_\_** **\_\_ shell parameters are expanded \_\_**
If you don\'t quote the delimiter, \$ has a special meaning. This sounds If you don't quote the delimiter, \$ has a special meaning. This sounds
obvious but it's easy to forget this fact when you use addresses like obvious but it's easy to forget this fact when you use addresses like
\$-1 or commands like \$a. Either quote the \$ or the delimiter: \$-1 or commands like \$a. Either quote the \$ or the delimiter:

View File

@ -40,14 +40,14 @@ several logical groups:
- `-f` is also an option, but this option has an associated **option - `-f` is also an option, but this option has an associated **option
argument** (an argument to the option `-f`): `/etc/mybackup.conf`. argument** (an argument to the option `-f`): `/etc/mybackup.conf`.
The option argument is usually the argument following the option The option argument is usually the argument following the option
itself, but that isn\'t mandatory. Joining the option and option itself, but that isn't mandatory. Joining the option and option
argument into a single argument `-f/etc/mybackup.conf` is valid. argument into a single argument `-f/etc/mybackup.conf` is valid.
- `-r` depends on the configuration. In this example, `-r` doesn\'t - `-r` depends on the configuration. In this example, `-r` doesn't
take arguments so it's a standalone option like `-x`. take arguments so it's a standalone option like `-x`.
- `./foo.txt` and `./bar.txt` are remaining arguments without any - `./foo.txt` and `./bar.txt` are remaining arguments without any
associated options. These are often used as **mass-arguments**. For associated options. These are often used as **mass-arguments**. For
example, the filenames specified for `cp(1)`, or arguments that example, the filenames specified for `cp(1)`, or arguments that
don\'t need an option to be recognized because of the intended don't need an option to be recognized because of the intended
behavior of the program. POSIX(r) calls them **operands**. behavior of the program. POSIX(r) calls them **operands**.
To give you an idea about why `getopts` is useful, The above command To give you an idea about why `getopts` is useful, The above command
@ -79,8 +79,8 @@ left to parse, it's easy to use in a while-loop:
done done
`getopts` will parse options and their possible arguments. It will stop `getopts` will parse options and their possible arguments. It will stop
parsing on the first non-option argument (a string that doesn\'t begin parsing on the first non-option argument (a string that doesn't begin
with a hyphen (`-`) that isn\'t an argument for any option in front of with a hyphen (`-`) that isn't an argument for any option in front of
it). It will also stop parsing when it sees the `--` (double-hyphen), it). It will also stop parsing when it sees the `--` (double-hyphen),
which means [end of options](../dict/terms/end_of_options.md). which means [end of options](../dict/terms/end_of_options.md).
@ -90,7 +90,7 @@ which means [end of options](../dict/terms/end_of_options.md).
------------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[OPTIND](../syntax/shellvars.md#OPTIND) Holds the index to the next argument to be processed. This is how `getopts` \"remembers\" its own status between invocations. Also useful to shift the positional parameters after processing with `getopts`. `OPTIND` is initially set to 1, and **needs to be re-set to 1 if you want to parse anything again with getopts** [OPTIND](../syntax/shellvars.md#OPTIND) Holds the index to the next argument to be processed. This is how `getopts` \"remembers\" its own status between invocations. Also useful to shift the positional parameters after processing with `getopts`. `OPTIND` is initially set to 1, and **needs to be re-set to 1 if you want to parse anything again with getopts**
[OPTARG](../syntax/shellvars.md#OPTARG) This variable is set to any argument for an option found by `getopts`. It also contains the option flag of an unknown option. [OPTARG](../syntax/shellvars.md#OPTARG) This variable is set to any argument for an option found by `getopts`. It also contains the option flag of an unknown option.
[OPTERR](../syntax/shellvars.md#OPTERR) (Values 0 or 1) Indicates if Bash should display error messages generated by the `getopts` builtin. The value is initialized to **1** on every shell startup - so be sure to always set it to **0** if you don\'t want to see annoying messages! **`OPTERR` is not specified by POSIX for the `getopts` builtin utility \-\-- only for the C `getopt()` function in `unistd.h` (`opterr`).** `OPTERR` is bash-specific and not supported by shells such as ksh93, mksh, zsh, or dash. [OPTERR](../syntax/shellvars.md#OPTERR) (Values 0 or 1) Indicates if Bash should display error messages generated by the `getopts` builtin. The value is initialized to **1** on every shell startup - so be sure to always set it to **0** if you don't want to see annoying messages! **`OPTERR` is not specified by POSIX for the `getopts` builtin utility \-\-- only for the C `getopt()` function in `unistd.h` (`opterr`).** `OPTERR` is bash-specific and not supported by shells such as ksh93, mksh, zsh, or dash.
`getopts` also uses these variables for error reporting (they\'re set to `getopts` also uses these variables for error reporting (they\'re set to
value-combinations which arent possible in normal operation). value-combinations which arent possible in normal operation).
@ -138,7 +138,7 @@ default (which means it parses `"$@"`).
You can give your own set of arguments to the utility to parse. Whenever You can give your own set of arguments to the utility to parse. Whenever
additional arguments are given after the `VARNAME` parameter, `getopts` additional arguments are given after the `VARNAME` parameter, `getopts`
doesn\'t try to parse the positional parameters, but these given words. doesn't try to parse the positional parameters, but these given words.
This way, you are able to parse any option set you like, here for This way, you are able to parse any option set you like, here for
example from an array: example from an array:
@ -160,7 +160,7 @@ Regarding error-reporting, there are two modes `getopts` can run in:
- silent mode - silent mode
For productive scripts I recommend to use the silent mode, since For productive scripts I recommend to use the silent mode, since
everything looks more professional, when you don\'t see annoying everything looks more professional, when you don't see annoying
standard messages. Also it's easier to handle, since the failure cases standard messages. Also it's easier to handle, since the failure cases
are indicated in an easier way. are indicated in an easier way.
@ -211,17 +211,17 @@ Let's do some tests:
$ ./go_test.sh $ ./go_test.sh
$ $
Nothing happened? Right. `getopts` didn\'t see any valid or invalid Nothing happened? Right. `getopts` didn't see any valid or invalid
options (letters preceded by a dash), so it wasn\'t triggered. options (letters preceded by a dash), so it wasn't triggered.
#### Calling it with non-option arguments #### Calling it with non-option arguments
$ ./go_test.sh /etc/passwd $ ./go_test.sh /etc/passwd
$ $
Again \-\-- nothing happened. The **very same** case: `getopts` didn\'t Again \-\-- nothing happened. The **very same** case: `getopts` didn't
see any valid or invalid options (letters preceded by a dash), so it see any valid or invalid options (letters preceded by a dash), so it
wasn\'t triggered. wasn't triggered.
The arguments given to your script are of course accessible as `$1` - The arguments given to your script are of course accessible as `$1` -
`${N}`. `${N}`.
@ -236,7 +236,7 @@ First, an **invalid** one:
Invalid option: -b Invalid option: -b
$ $
As expected, `getopts` didn\'t accept this option and acted like told As expected, `getopts` didn't accept this option and acted like told
above: It placed `?` into `$opt` and the invalid option character (`b`) above: It placed `?` into `$opt` and the invalid option character (`b`)
into `$OPTARG`. With our `case` statement, we were able to detect this. into `$OPTARG`. With our `case` statement, we were able to detect this.
@ -271,7 +271,7 @@ times**:
The last examples lead us to some points you may consider: The last examples lead us to some points you may consider:
- **invalid options don\'t stop the processing**: If you want to stop - **invalid options don't stop the processing**: If you want to stop
the script, you have to do it yourself (`exit` in the right place) the script, you have to do it yourself (`exit` in the right place)
- **multiple identical options are possible**: If you want to disallow - **multiple identical options are possible**: If you want to disallow
these, you have to check manually (e.g. by setting a variable or so) these, you have to check manually (e.g. by setting a variable or so)
@ -310,14 +310,14 @@ Let's do the very same tests we did in the last example:
$ ./go_test.sh $ ./go_test.sh
$ $
As above, nothing happened. It wasn\'t triggered. As above, nothing happened. It wasn't triggered.
#### Calling it with non-option arguments #### Calling it with non-option arguments
$ ./go_test.sh /etc/passwd $ ./go_test.sh /etc/passwd
$ $
The **very same** case: It wasn\'t triggered. The **very same** case: It wasn't triggered.
#### Calling it with option-arguments #### Calling it with option-arguments
@ -327,7 +327,7 @@ The **very same** case: It wasn\'t triggered.
Invalid option: -b Invalid option: -b
$ $
As expected, as above, `getopts` didn\'t accept this option and acted As expected, as above, `getopts` didn't accept this option and acted
like programmed. like programmed.
**Valid** option, but without the mandatory **argument**: **Valid** option, but without the mandatory **argument**:

View File

@ -12,11 +12,11 @@ prevent this, a form of `MUTEX` (**mutual exclusion**) lock is needed.
The basic procedure is simple: The script checks if a specific condition The basic procedure is simple: The script checks if a specific condition
(locking) is present at startup, if yes, it's locked - the scipt (locking) is present at startup, if yes, it's locked - the scipt
doesn\'t start. doesn't start.
This article describes locking with common UNIX(r) tools. There are This article describes locking with common UNIX(r) tools. There are
other special locking tools available, But they\'re not standardized, or other special locking tools available, But they\'re not standardized, or
worse yet, you can\'t be sure they\'re present when you want to run your worse yet, you can't be sure they\'re present when you want to run your
scripts. **A tool designed for specifically for this purpose does the scripts. **A tool designed for specifically for this purpose does the
job much better than general purpose code.** job much better than general purpose code.**
@ -32,7 +32,7 @@ limits.
## Choose the locking method ## Choose the locking method
The best way to set a global lock condition is the UNIX(r) filesystem. The best way to set a global lock condition is the UNIX(r) filesystem.
Variables aren\'t enough, as each process has its own private variable Variables aren't enough, as each process has its own private variable
space, but the filesystem is global to all processes (yes, I know about space, but the filesystem is global to all processes (yes, I know about
chroots, namespaces, \... special case). You can \"set\" several things chroots, namespaces, \... special case). You can \"set\" several things
in the filesystem that can be used as locking indicator: in the filesystem that can be used as locking indicator:
@ -47,7 +47,7 @@ the existance of the lockfile, if no lockfile exists, it creates one and
continues. Those are **two separate steps**! That means it's **not an continues. Those are **two separate steps**! That means it's **not an
atomic operation**. There's a small amount of time between checking and atomic operation**. There's a small amount of time between checking and
creating, where another instance of the same script could perform creating, where another instance of the same script could perform
locking (because when it checked, the lockfile wasn\'t there)! In that locking (because when it checked, the lockfile wasn't there)! In that
case you would have 2 instances of the script running, both thinking case you would have 2 instances of the script running, both thinking
they are succesfully locked, and can operate without colliding. Setting they are succesfully locked, and can operate without colliding. Setting
the timestamp is similar: One step to check the timespamp, a second step the timestamp is similar: One step to check the timespamp, a second step
@ -129,7 +129,7 @@ differences compared to the very simple example above:
- traps are created to automatically remove the lock when the script - traps are created to automatically remove the lock when the script
terminates, or is killed terminates, or is killed
Details on how the script is killed aren\'t given, only code relevant to Details on how the script is killed aren't given, only code relevant to
the locking process is shown: the locking process is shown:
``` bash ``` bash

View File

@ -17,7 +17,7 @@ only an introduction.
This article is based on the debianized Berkeley implementation of This article is based on the debianized Berkeley implementation of
`pax`, but implementation-specific things should be tagged as such. `pax`, but implementation-specific things should be tagged as such.
Unfortunately, the Debian package doesn\'t seem to be maintained Unfortunately, the Debian package doesn't seem to be maintained
anymore. anymore.
## Overview ## Overview
@ -71,7 +71,7 @@ options, e.g. rewriting groups) to another location.
### Archive data ### Archive data
When you don\'t specify anything special, `pax` will attempt to read When you don't specify anything special, `pax` will attempt to read
archive data from standard input (read/list modes) and write archive archive data from standard input (read/list modes) and write archive
data to standard output (write mode). This ensures `pax` can be easily data to standard output (write mode). This ensures `pax` can be easily
used as part of a shell pipe construct, e.g. to read a compressed used as part of a shell pipe construct, e.g. to read a compressed
@ -170,7 +170,7 @@ customized to include permissions, timestamps, etc. with the
specification is strongly derived from the `printf(3)` format specification is strongly derived from the `printf(3)` format
specification. specification.
**Unfortunately** the `pax` utility delivered with Debian doesn\'t seem **Unfortunately** the `pax` utility delivered with Debian doesn't seem
to support these extended listing formats. to support these extended listing formats.
However, `pax` lists archive members in a `ls -l`-like format, when you However, `pax` lists archive members in a `ls -l`-like format, when you
@ -238,7 +238,7 @@ The same, but with an archive, can be accomplished by:
pax -w -T 0000 -f /n/mybackups/$(date +%A) pax -w -T 0000 -f /n/mybackups/$(date +%A)
In this case, the day-name is an archive-file (you don\'t need a In this case, the day-name is an archive-file (you don't need a
filename extension like `.tar` but you can add one, if desired). filename extension like `.tar` but you can add one, if desired).
### Changing filenames while archiving ### Changing filenames while archiving
@ -292,7 +292,7 @@ that you want to extract only the \"usr\" directory:
Like `cpio`, pax can read filenames from standard input (`stdin`). This Like `cpio`, pax can read filenames from standard input (`stdin`). This
provides great flexibility - for example, a `find(1)` command may select provides great flexibility - for example, a `find(1)` command may select
files/directories in ways pax can\'t do itself. In **write** mode files/directories in ways pax can't do itself. In **write** mode
(creating an archive) or **copy** mode, when no filenames are given, pax (creating an archive) or **copy** mode, when no filenames are given, pax
expects to read filenames from standard input. For example: expects to read filenames from standard input. For example:

View File

@ -227,7 +227,7 @@ So, as a simple example (albeit slightly contrived), is the following:
## Order Of Redirection, i.e., \"\> file 2\>&1\" vs. \"2\>&1 \>file\" ## Order Of Redirection, i.e., \"\> file 2\>&1\" vs. \"2\>&1 \>file\"
While it doesn\'t matter where the redirections appears on the command While it doesn't matter where the redirections appears on the command
line, their order does matter. They are set up from left to right. line, their order does matter. They are set up from left to right.
- `2>&1 >file` - `2>&1 >file`
@ -313,7 +313,7 @@ Then it sees our duplication `2>&1`:
And voila, both `1` and `2` are redirected to file. And voila, both `1` and `2` are redirected to file.
## Why sed 's/foo/bar/\' file \>file Doesn\'t Work ## Why sed 's/foo/bar/\' file \>file Doesn't Work
This is a common error, we want to modify a file using something that This is a common error, we want to modify a file using something that
reads from a file and writes the result to `stdout`. To do this, we reads from a file and writes the result to `stdout`. To do this, we
@ -329,7 +329,7 @@ truncated. When `sed` starts to read the file, it contains nothing.
In Bash the `exec` built-in replaces the shell with the specified In Bash the `exec` built-in replaces the shell with the specified
program. So what does this have to do with redirection? `exec` also program. So what does this have to do with redirection? `exec` also
allow us to manipulate the file descriptors. If you don\'t specify a allow us to manipulate the file descriptors. If you don't specify a
program, the redirection after `exec` modifies the file descriptors of program, the redirection after `exec` modifies the file descriptors of
the current shell. the current shell.
@ -366,7 +366,7 @@ user to press a key:
while read -r line;do echo "$line"; read -p "Press any key" -n 1;done < file while read -r line;do echo "$line"; read -p "Press any key" -n 1;done < file
And, surprise this doesn\'t work. Why? because the shell descriptor of And, surprise this doesn't work. Why? because the shell descriptor of
the while loop looks like: the while loop looks like:
--- +-----------------------+ --- +-----------------------+

View File

@ -3,7 +3,7 @@
![](keywords>bash shell scripting options runtime variable behaviour) ![](keywords>bash shell scripting options runtime variable behaviour)
This information was taken from a Bash version \"`4.1`\", every now and This information was taken from a Bash version \"`4.1`\", every now and
then new options are added, so likely, this list isn\'t complete. then new options are added, so likely, this list isn't complete.
The shell-options can be set with the [shopt builtin The shell-options can be set with the [shopt builtin
command](../commands/builtin/shopt.md). command](../commands/builtin/shopt.md).
@ -490,7 +490,7 @@ There are two options that influence the parsing this way:
- `extglob` - `extglob`
- `extquote` - `extquote`
Consequence: You **can\'t** use the new syntax (e.g. the extended Consequence: You **can't** use the new syntax (e.g. the extended
globbing syntax) and the command to enable it **in the same line**. globbing syntax) and the command to enable it **in the same line**.
$ shopt -s extglob; echo !(*.txt) # this is the WRONG way! $ shopt -s extglob; echo !(*.txt) # this is the WRONG way!

View File

@ -21,14 +21,14 @@ And yes, these bashphorisms reflect the daily reality in `#bash`.
4 The questioner will not read and apply the answers he is given but will instead continue to practice bashphorism #1 and bashphorism #2. 4 The questioner will not read and apply the answers he is given but will instead continue to practice bashphorism #1 and bashphorism #2.
5 The ignorant will continually mis-educate the other noobies. 5 The ignorant will continually mis-educate the other noobies.
6 When given a choice of solutions, the newbie will always choose the wrong one. 6 When given a choice of solutions, the newbie will always choose the wrong one.
7 The newbie will always find a reason to say, \"It doesn\'t work.\" 7 The newbie will always find a reason to say, \"It doesn't work.\"
8 If you don\'t know to whom the bashphorism's referring, it's you. 8 If you don't know to whom the bashphorism's referring, it's you.
9 All examples given by the questioner will be broken, misleading, wrong, and not representative of the actual question. 9 All examples given by the questioner will be broken, misleading, wrong, and not representative of the actual question.
10 See B1 10 See B1
11 Please apply `(( % 10 ))` to the bashphorism value. 11 Please apply `(( % 10 ))` to the bashphorism value.
12 All logic is deniable; however, some logic will \*plonk\* you if you deny it. 12 All logic is deniable; however, some logic will \*plonk\* you if you deny it.
13 Everyone ignores greycat when he is right. When he is wrong, it is !b1 13 Everyone ignores greycat when he is right. When he is wrong, it is !b1
14 The newbie doesn\'t actually know what he's asking. If he did, he wouldn\'t need to ask. 14 The newbie doesn't actually know what he's asking. If he did, he wouldn't need to ask.
15 The more advanced you are, the more likely you are to be overcomplicating it. 15 The more advanced you are, the more likely you are to be overcomplicating it.
16 The more beginner you are, the more likely you are to be overcomplicating it. 16 The more beginner you are, the more likely you are to be overcomplicating it.
17 A newbie comes to #bash to get his script confirmed. He leaves disappointed. 17 A newbie comes to #bash to get his script confirmed. He leaves disappointed.
@ -39,14 +39,14 @@ And yes, these bashphorisms reflect the daily reality in `#bash`.
22 The newcomer will abuse the bot's factoid triggers for their own entertainment until someone gets annoyed enough to ask them to message it privately instead. 22 The newcomer will abuse the bot's factoid triggers for their own entertainment until someone gets annoyed enough to ask them to message it privately instead.
23 Everyone is a newcomer. 23 Everyone is a newcomer.
24 The newcomer will address greybot as if it were human. 24 The newcomer will address greybot as if it were human.
25 The newbie won\'t accept any answer that uses practical or standard tools. 25 The newbie won't accept any answer that uses practical or standard tools.
26 The newbie will not TELL you about this restriction until you have wasted half an hour. 26 The newbie will not TELL you about this restriction until you have wasted half an hour.
27 The newbie will lie. 27 The newbie will lie.
28 When the full horror of the newbie's true goal is revealed, the newbie will try to restate the goal to trick you into answering. Newbies are stupid. 28 When the full horror of the newbie's true goal is revealed, the newbie will try to restate the goal to trick you into answering. Newbies are stupid.
29 It's always git. Or python virtualenv. Or docker. One of those pieces of shit. ALWAYS. 29 It's always git. Or python virtualenv. Or docker. One of those pieces of shit. ALWAYS.
30 They won\'t show you the homework assignment. That would make it too easy. 30 They won't show you the homework assignment. That would make it too easy.
31 Your teacher is a f\*\*king idiot. 31 Your teacher is a f\*\*king idiot.
32 The more horrifyingly wrong a proposed solution is, the more likely it will be used. 32 The more horrifyingly wrong a proposed solution is, the more likely it will be used.
33 The newbie cannot explain what he is doing, or why. He will show you incomprehensible, nonworking code instead. What? You can\'t read his mind?! 33 The newbie cannot explain what he is doing, or why. He will show you incomprehensible, nonworking code instead. What? You can't read his mind?!
Please feel free to correct or extend this page whenever needed. Please feel free to correct or extend this page whenever needed.

View File

@ -76,7 +76,7 @@ mode (for running, not for starting!)](#posix_run_mode).
[**Bash starts in `sh` compatiblity mode when:**]{.underline} [**Bash starts in `sh` compatiblity mode when:**]{.underline}
- the base filename in `argv[0]` is `sh` (:!: NB: `/bin/sh` may be - the base filename in `argv[0]` is `sh` (:!: NB: `/bin/sh` may be
linked to `/bin/bash`, but that doesn\'t mean it acts like linked to `/bin/bash`, but that doesn't mean it acts like
`/bin/bash` :!:) `/bin/bash` :!:)
### POSIX mode ### POSIX mode
@ -85,7 +85,7 @@ When Bash is started in POSIX(r) mode, it follows the POSIX(r) standard
for startup files. In this mode, **interactive shells** expand the for startup files. In this mode, **interactive shells** expand the
[ENV](../syntax/shellvars.md#ENV) variable and commands are read and executed [ENV](../syntax/shellvars.md#ENV) variable and commands are read and executed
from the file whose name is the expanded value.\ from the file whose name is the expanded value.\
No other startup files are read. Hence, a non-interactive shell doesn\'t No other startup files are read. Hence, a non-interactive shell doesn't
read any startup files in POSIX(r) mode. read any startup files in POSIX(r) mode.
[**Bash starts in POSIX(r) mode when:**]{.underline} [**Bash starts in POSIX(r) mode when:**]{.underline}
@ -315,29 +315,29 @@ In restricted mode, Bash sets up (and runs) a shell environment that's
far more controlled and limited than the standard shell mode. It acts far more controlled and limited than the standard shell mode. It acts
like normal Bash with the following restrictions: like normal Bash with the following restrictions:
- the `cd` command can\'t be used to change directories - the `cd` command can't be used to change directories
- the variables [SHELL](../syntax/shellvars.md#SHELL), - the variables [SHELL](../syntax/shellvars.md#SHELL),
[PATH](../syntax/shellvars.md#PATH), [ENV](../syntax/shellvars.md#ENV) and [PATH](../syntax/shellvars.md#PATH), [ENV](../syntax/shellvars.md#ENV) and
[BASH_ENV](../syntax/shellvars.md#BASH_ENV) can\'t be set or unset [BASH_ENV](../syntax/shellvars.md#BASH_ENV) can't be set or unset
- command names that contain a `/` (slash) can\'t be called (hence - command names that contain a `/` (slash) can't be called (hence
you\'re limited to `PATH`) you\'re limited to `PATH`)
- filenames containing a `/` (slash) can\'t be specified as argument - filenames containing a `/` (slash) can't be specified as argument
to the `source` or `.` builtin command to the `source` or `.` builtin command
- filenames containing a `/` (slash) can\'t be specified as argument - filenames containing a `/` (slash) can't be specified as argument
to the `-p` option of the `hash` builtin command to the `-p` option of the `hash` builtin command
- function definitions are not inherited from the environment at shell - function definitions are not inherited from the environment at shell
startup startup
- the environment variable [SHELLOPTS](../syntax/shellvars.md#SHELLOPTS) is - the environment variable [SHELLOPTS](../syntax/shellvars.md#SHELLOPTS) is
ignored at startup ignored at startup
- redirecting output using the `>`, `>|`, `<>`, `>&`, `&>`, and `>>` - redirecting output using the `>`, `>|`, `<>`, `>&`, `&>`, and `>>`
redirection operators isn\'t allowed redirection operators isn't allowed
- the `exec` builtin command can\'t replace the shell with another - the `exec` builtin command can't replace the shell with another
process process
- adding or deleting builtin commands with the `-f` and `-d` options - adding or deleting builtin commands with the `-f` and `-d` options
to the enable builtin command is forbidden to the enable builtin command is forbidden
- using the `enable` builtin command to enable disabled shell builtins - using the `enable` builtin command to enable disabled shell builtins
doesn\'t work doesn't work
- the `-p` option to the `command` builtin command doesn\'t work - the `-p` option to the `command` builtin command doesn't work
- turning off restricted mode with `set +r` or `set +o restricted` is - turning off restricted mode with `set +r` or `set +o restricted` is
(of course) forbidden (of course) forbidden

View File

@ -154,7 +154,7 @@ For this topic, see also
`echo` `\uNNNN` and `\UNNNNNNNN` escape sequences 4.2-alpha for: `printf`, `echo -e`, `$'...'` `echo` `\uNNNN` and `\UNNNNNNNN` escape sequences 4.2-alpha for: `printf`, `echo -e`, `$'...'`
`exec` option `-a` to give a `argv[0]` string 4.2-alpha `exec` option `-a` to give a `argv[0]` string 4.2-alpha
`time` allowed as a command by itself to display timing values of the shell and its children 4.2-alpha POSIX change `time` allowed as a command by itself to display timing values of the shell and its children 4.2-alpha POSIX change
`help` `help` now searches exact topic-strings (i.e. `help read` won\'t find `readonly` anymore) 4.3-alpha `help` `help` now searches exact topic-strings (i.e. `help read` won't find `readonly` anymore) 4.3-alpha
`return` accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller) 4.3-alpha `return` accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller) 4.3-alpha
`exit` accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller) 4.3-alpha `exit` accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller) 4.3-alpha
`read` `read` skips `NUL` (ASCII Code 0) in input 4.3-alpha `read` `read` skips `NUL` (ASCII Code 0) in input 4.3-alpha

View File

@ -40,7 +40,7 @@ You can follow the process by using `echo` as a fake interpreter:
#!/bin/echo #!/bin/echo
We don\'t need a script body here, as the file will never be interpreted We don't need a script body here, as the file will never be interpreted
and executed by \"`echo`\". You can see what the Operating System does, and executed by \"`echo`\". You can see what the Operating System does,
it calls \"`/bin/echo`\" with the name of the executable file and it calls \"`/bin/echo`\" with the name of the executable file and
following arguments. following arguments.
@ -58,7 +58,7 @@ be is system-specific (see
executes a file with a #!/bin/bash shebang, the shebang itself is executes a file with a #!/bin/bash shebang, the shebang itself is
ignored, since the first character is a hashmark \"#\", which indicates ignored, since the first character is a hashmark \"#\", which indicates
a comment. The shebang is for the operating system, not for the shell. a comment. The shebang is for the operating system, not for the shell.
Programs that don\'t ignore such lines, may not work as shebang driven Programs that don't ignore such lines, may not work as shebang driven
interpreters. interpreters.
\<WRAP center round important 60%\> [**Attention:**]{.underline}When the \<WRAP center round important 60%\> [**Attention:**]{.underline}When the
@ -145,11 +145,11 @@ code is a number between 0 and 255. Values from 126 to 255 are reserved
for use by the shell directly, or for special purposes, like reporting a for use by the shell directly, or for special purposes, like reporting a
termination by a signal: termination by a signal:
- **126**: the requested command (file) was found, but can\'t be - **126**: the requested command (file) was found, but can't be
executed executed
- **127**: command (file) not found - **127**: command (file) not found
- **128**: according to ABS it's used to report an invalid argument - **128**: according to ABS it's used to report an invalid argument
to the exit builtin, but I wasn\'t able to verify that in the source to the exit builtin, but I wasn't able to verify that in the source
code of Bash (see code 255) code of Bash (see code 255)
- **128 + N**: the shell was terminated by the signal N - **128 + N**: the shell was terminated by the signal N
- **255**: wrong argument to the exit builtin (see code 128) - **255**: wrong argument to the exit builtin (see code 128)
@ -242,7 +242,7 @@ SOMEWORD
``` ```
What happened? The `:` pseudo command was given some input by What happened? The `:` pseudo command was given some input by
redirection (a here-document) - the pseudo command didn\'t care about redirection (a here-document) - the pseudo command didn't care about
it, effectively, the entire block was ignored. it, effectively, the entire block was ignored.
The here-document-tag was quoted here **to avoid substitutions** in the The here-document-tag was quoted here **to avoid substitutions** in the

View File

@ -9,16 +9,16 @@ but as hints and comments about debugging a Bash script.
Do **not** name your script `test`, for example! *Why?* `test` is the Do **not** name your script `test`, for example! *Why?* `test` is the
name of a UNIX(r)-command, and [most likely built into your name of a UNIX(r)-command, and [most likely built into your
shell]{.underline} (it's a built-in in Bash) - so you won\'t be able to shell]{.underline} (it's a built-in in Bash) - so you won't be able to
run a script with the name `test` in a normal way. run a script with the name `test` in a normal way.
**Don\'t laugh!** This is a classic mistake :-) **Don't laugh!** This is a classic mistake :-)
## Read the error messages ## Read the error messages
Many people come into IRC and ask something like *\"Why does my script Many people come into IRC and ask something like *\"Why does my script
fail? I get an error!\"*. And when you ask them what the error message fail? I get an error!\"*. And when you ask them what the error message
is, they don\'t even know. Beautiful. is, they don't even know. Beautiful.
Reading and interpreting error messages is 50% of your job as debugger! Reading and interpreting error messages is 50% of your job as debugger!
Error messages actually **mean** something. At the very least, they can Error messages actually **mean** something. At the very least, they can
@ -329,11 +329,11 @@ carriage return character!):
Here's what happens because of the `#!/bin/bash^M` in our shebang: Here's what happens because of the `#!/bin/bash^M` in our shebang:
- the file `/bin/bash^M` doesn\'t exist (hopefully) - the file `/bin/bash^M` doesn't exist (hopefully)
- So Bash prints an error message which (depending on the terminal, - So Bash prints an error message which (depending on the terminal,
the Bash version, or custom patches!) may or may not expose the the Bash version, or custom patches!) may or may not expose the
problem. problem.
- the script can\'t be executed - the script can't be executed
The error message can vary. If you\'re lucky, you\'ll get: The error message can vary. If you\'re lucky, you\'ll get:

View File

@ -28,7 +28,7 @@ See also:
- [Bash startup mode: SH mode](../scripting/bashbehaviour.md#sh_mode) - [Bash startup mode: SH mode](../scripting/bashbehaviour.md#sh_mode)
- [Bash run mode: POSIX mode](../scripting/bashbehaviour.md#posix_run_mode) - [Bash run mode: POSIX mode](../scripting/bashbehaviour.md#posix_run_mode)
### Your script named \"test\" doesn\'t execute ### Your script named \"test\" doesn't execute
Give it another name. The executable `test` already exists. Give it another name. The executable `test` already exists.
@ -59,7 +59,7 @@ text formed by the prefix, the postfix and the braces themselves are
generated. In the example, these are only two: `-i*.vob` and `-i`. The generated. In the example, these are only two: `-i*.vob` and `-i`. The
filename expansion happens **after** that, so there is a chance that filename expansion happens **after** that, so there is a chance that
`-i*.vob` is expanded to a filename - if you have files like `-i*.vob` is expanded to a filename - if you have files like
`-ihello.vob`. But it definitely doesn\'t do what you expected. `-ihello.vob`. But it definitely doesn't do what you expected.
Please see: Please see:
@ -90,7 +90,7 @@ variable! Bash is not PHP!
A variable name preceeded with a dollar-sign always means that the A variable name preceeded with a dollar-sign always means that the
variable gets **expanded**. In the example above, it might expand to variable gets **expanded**. In the example above, it might expand to
nothing (because it wasn\'t set), effectively resulting in\... nothing (because it wasn't set), effectively resulting in\...
="Hello world!" ="Hello world!"
@ -140,7 +140,7 @@ A typical beginner's trap is quoting.
As noted above, when you want to **expand** a variable i.e. \"get the As noted above, when you want to **expand** a variable i.e. \"get the
content\", the variable name needs to be prefixed with a dollar-sign. content\", the variable name needs to be prefixed with a dollar-sign.
But, since Bash knows various ways to quote and does word-splitting, the But, since Bash knows various ways to quote and does word-splitting, the
result isn\'t always the same. result isn't always the same.
Let's define an example variable containing text with spaces: Let's define an example variable containing text with spaces:
@ -195,7 +195,7 @@ process you execute to start that script `./script.sh`):
Exporting is one-way. The direction is from parent process to child Exporting is one-way. The direction is from parent process to child
process, not the reverse. The above example **will** work, when you process, not the reverse. The above example **will** work, when you
don\'t execute the script, but include (\"source\") it: don't execute the script, but include (\"source\") it:
$ source ./script.sh $ source ./script.sh
$ echo $hello $ echo $hello
@ -213,7 +213,7 @@ Please see:
### Reacting to exit codes ### Reacting to exit codes
If you just want to react to an exit code, regardless of its specific If you just want to react to an exit code, regardless of its specific
value, you **don\'t need** to use `$?` in a test command like this: value, you **don't need** to use `$?` in a test command like this:
``` bash ``` bash
grep ^root: /etc/passwd >/dev/null 2>&1 grep ^root: /etc/passwd >/dev/null 2>&1

View File

@ -22,9 +22,9 @@ In these cases the portable syntax should be preferred.
`command\ <<<\ WORD` `command <<MARKER WORD MARKER` a here-string, a special form of the here-document, avoid it in portable scripts! POSIX(r) `command\ <<<\ WORD` `command <<MARKER WORD MARKER` a here-string, a special form of the here-document, avoid it in portable scripts! POSIX(r)
`export VAR=VALUE` `VAR=VALUE export VAR` Though POSIX(r) allows it, some shells don\'t want the assignment and the exporting in one command POSIX(r), zsh, ksh, \... `export VAR=VALUE` `VAR=VALUE export VAR` Though POSIX(r) allows it, some shells don't want the assignment and the exporting in one command POSIX(r), zsh, ksh, \...
`(( MATH ))` `: $(( MATH ))` POSIX(r) does\'t define an arithmetic compund command, many shells don\'t know it. Using the pseudo-command `:` and the arithmetic expansion `$(( ))` is a kind of workaround here. **Attention:** Not all shell support assignment like `$(( a = 1 + 1 ))`! Also see below for a probably more portable solution. all POSIX(r) compatible shells `(( MATH ))` `: $(( MATH ))` POSIX(r) does't define an arithmetic compund command, many shells don't know it. Using the pseudo-command `:` and the arithmetic expansion `$(( ))` is a kind of workaround here. **Attention:** Not all shell support assignment like `$(( a = 1 + 1 ))`! Also see below for a probably more portable solution. all POSIX(r) compatible shells
`[[\ EXPRESSION\ ]]` `[ EXPRESSION ]`\ The Bashish test keyword is reserved by POSIX(r), but not defined. Use the old fashioned way with the `test` command. See [the classic test command](../commands/classictest.md) POSIX(r) and others `[[\ EXPRESSION\ ]]` `[ EXPRESSION ]`\ The Bashish test keyword is reserved by POSIX(r), but not defined. Use the old fashioned way with the `test` command. See [the classic test command](../commands/classictest.md) POSIX(r) and others
or\ or\
@ -39,7 +39,7 @@ In these cases the portable syntax should be preferred.
Here is some assorted portability information. Take it as a small guide Here is some assorted portability information. Take it as a small guide
to make your scripts a bit more portable. It's not complete (it never to make your scripts a bit more portable. It's not complete (it never
will be!) and it's not very detailed (e.g. you won\'t find information will be!) and it's not very detailed (e.g. you won't find information
about how which shell technically forks off which subshell). It's just about how which shell technically forks off which subshell). It's just
an assorted small set of portability guidelines. *-Thebonsai* an assorted small set of portability guidelines. *-Thebonsai*
@ -57,7 +57,7 @@ The *new value* is seen by subsequent programs
- only after an explicit export with `export VARIABLE` (e.g. Sun's - only after an explicit export with `export VARIABLE` (e.g. Sun's
`/bin/sh`) `/bin/sh`)
Since an extra `export` doesn\'t hurt, the safest and most portable way Since an extra `export` doesn't hurt, the safest and most portable way
is to always (re-)export a changed variable if you want it to be seen by is to always (re-)export a changed variable if you want it to be seen by
subsequent processes. subsequent processes.
@ -84,8 +84,8 @@ aritrhmetic expansions, so the most portable is *with quotes*.
The overall problem with `echo` is, that there are 2 (maybe more) The overall problem with `echo` is, that there are 2 (maybe more)
mainstream flavours around. The only case where you may safely use an mainstream flavours around. The only case where you may safely use an
`echo` on all systems is: Echoing non-variable arguments that don\'t `echo` on all systems is: Echoing non-variable arguments that don't
start with a `-` (dash) and don\'t contain a `\` (backslash). start with a `-` (dash) and don't contain a `\` (backslash).
Why? (list of known behaviours) Why? (list of known behaviours)
@ -113,7 +113,7 @@ existance of [the `printf` command](../commands/builtin/printf.md).
#### PWD #### PWD
[PWD](../syntax/shellvars.md#PWD) is POSIX but not Bourne. Most shells are [PWD](../syntax/shellvars.md#PWD) is POSIX but not Bourne. Most shells are
*not POSIX* in that they don\'t ignore the value of the `PWD` *not POSIX* in that they don't ignore the value of the `PWD`
environment variable. Workaround to fix the value of `PWD` at the start environment variable. Workaround to fix the value of `PWD` at the start
of your script: of your script:
@ -157,7 +157,7 @@ directory names, so it's basically possible to run a loop and check
every `PATH` component for the command you\'re looking for and for every `PATH` component for the command you\'re looking for and for
executability. executability.
However, this method doesn\'t look nice. There are other ways of doing However, this method doesn't look nice. There are other ways of doing
this, using commands that are *not directly* related to this task. this, using commands that are *not directly* related to this task.
#### hash #### hash
@ -183,7 +183,7 @@ Somewhat of a mass-check:
fi fi
done done
Here (bash 3), `hash` also respects builtin commands. I don\'t know if Here (bash 3), `hash` also respects builtin commands. I don't know if
this works everywhere, but it seems logical. this works everywhere, but it seems logical.
#### command #### command
@ -199,6 +199,6 @@ accessible by `PATH`:
echo "sed is available" echo "sed is available"
fi fi
[^1]: \"portable\" doesn\'t necessarily mean it's POSIX, it can also [^1]: \"portable\" doesn't necessarily mean it's POSIX, it can also
mean it's \"widely used and accepted\", and thus maybe more mean it's \"widely used and accepted\", and thus maybe more
portable than POSIX(r portable than POSIX(r

View File

@ -21,8 +21,8 @@ of POSIX, and some may be incompatible with POSIX.
`&>FILE` and `>&FILE` `>FILE 2>&1` This redirection syntax is short for `>FILE 2>&1` and originates in the C Shell. The latter form is especially uncommon and should never be used, and the explicit form using separate redirections is preferred over both. These shortcuts contribute to confusion about the copy descriptor because the syntax is unclear. They also introduce parsing ambiguity, and conflict with POSIX. Shells without this feature treat `cmd1 &>file cmd2` as: \"background `cmd1` and then execute `cmd2` with its stdout redirected to `file`\", which is the correct interpretation of this expression. See: [redirection](../syntax/redirection.md) \`\$ { bash; dash \</dev/fd/0; } \<\<\<\'echo foo\>/dev/null&\>/dev/fd/2 echo bar\' foo echo bar bar\` `&>FILE` and `>&FILE` `>FILE 2>&1` This redirection syntax is short for `>FILE 2>&1` and originates in the C Shell. The latter form is especially uncommon and should never be used, and the explicit form using separate redirections is preferred over both. These shortcuts contribute to confusion about the copy descriptor because the syntax is unclear. They also introduce parsing ambiguity, and conflict with POSIX. Shells without this feature treat `cmd1 &>file cmd2` as: \"background `cmd1` and then execute `cmd2` with its stdout redirected to `file`\", which is the correct interpretation of this expression. See: [redirection](../syntax/redirection.md) \`\$ { bash; dash \</dev/fd/0; } \<\<\<\'echo foo\>/dev/null&\>/dev/fd/2 echo bar\' foo echo bar bar\`
`$[EXPRESSION]` `$((EXPRESSION))` This undocumented syntax is completely replaced by the POSIX-conforming arithmetic expansion `$((EXPRESSION))`. It is unimplemented almost everywhere except Bash and Zsh. See [arithmetic expansion](../syntax/expansion/arith.md). [Some discussion](http://lists.gnu.org/archive/html/bug-bash/2012-04/msg00034.html). `$[EXPRESSION]` `$((EXPRESSION))` This undocumented syntax is completely replaced by the POSIX-conforming arithmetic expansion `$((EXPRESSION))`. It is unimplemented almost everywhere except Bash and Zsh. See [arithmetic expansion](../syntax/expansion/arith.md). [Some discussion](http://lists.gnu.org/archive/html/bug-bash/2012-04/msg00034.html).
`COMMAND\ |&\ COMMAND` `COMMAND 2>&1 | COMMAND` This is an alternate pipeline operator derived from Zsh. Officially, it is not considered deprecated by Bash, but I highly discourage it. It conflicts with the list operator used for [coprocess](../syntax/keywords/coproc.md) creation in most Korn shells. It also has confusing behavior. The stdout is redirected first like an ordinary pipe, while the stderr is actually redirected last \-- after other redirects preceding the pipe operator. Overall, it's pointless syntax bloat. Use an explicit redirect instead. `COMMAND\ |&\ COMMAND` `COMMAND 2>&1 | COMMAND` This is an alternate pipeline operator derived from Zsh. Officially, it is not considered deprecated by Bash, but I highly discourage it. It conflicts with the list operator used for [coprocess](../syntax/keywords/coproc.md) creation in most Korn shells. It also has confusing behavior. The stdout is redirected first like an ordinary pipe, while the stderr is actually redirected last \-- after other redirects preceding the pipe operator. Overall, it's pointless syntax bloat. Use an explicit redirect instead.
`function\ NAME()\ COMPOUND-CMD` `NAME()\ COMPOUND-CMD` or `function\ NAME\ {\ CMDS;\ }` This is an amalgamation between the Korn and POSIX style function definitions - using both the `function` keyword and parentheses. It has no useful purpose and no historical basis or reason to exist. It is not specified by POSIX. It is accepted by Bash, mksh, zsh, and perhaps some other Korn shells, where it is treated as identical to the POSIX-style function. It is not accepted by AT&T ksh. It should never be used. See the next table for the `function` keyword. Bash doesn\'t have this feature documented as expressly deprecated. `function\ NAME()\ COMPOUND-CMD` `NAME()\ COMPOUND-CMD` or `function\ NAME\ {\ CMDS;\ }` This is an amalgamation between the Korn and POSIX style function definitions - using both the `function` keyword and parentheses. It has no useful purpose and no historical basis or reason to exist. It is not specified by POSIX. It is accepted by Bash, mksh, zsh, and perhaps some other Korn shells, where it is treated as identical to the POSIX-style function. It is not accepted by AT&T ksh. It should never be used. See the next table for the `function` keyword. Bash doesn't have this feature documented as expressly deprecated.
`for x; { ...;}` `do`, `done`, `in`, `esac`, etc. This undocumented syntax replaces the `do` and `done` reserved words with braces. Many Korn shells support various permutations on this syntax for certain compound commands like `for`, `case`, and `while`. Which ones and certain details like whether a newline or semicolon are required vary. Only `for` works in Bash. Needless to say, don\'t use it. `for x; { ...;}` `do`, `done`, `in`, `esac`, etc. This undocumented syntax replaces the `do` and `done` reserved words with braces. Many Korn shells support various permutations on this syntax for certain compound commands like `for`, `case`, and `while`. Which ones and certain details like whether a newline or semicolon are required vary. Only `for` works in Bash. Needless to say, don't use it.
This table lists syntax that is specified by POSIX (unless otherwise This table lists syntax that is specified by POSIX (unless otherwise
specified below), but has been superseded by superior alternatives specified below), but has been superseded by superior alternatives
@ -34,19 +34,19 @@ historical reasons.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Syntax Replacement Description Syntax Replacement Description
----------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Unquoted expansions, [wordsplit](../syntax/expansion/wordsplit.md), and [globs](../syntax/expansion/globs.md) [Proper quoting](http://mywiki.wooledge.org/Quotes), Ksh/Bash-style [arrays](../syntax/arrays.md), The \"\$@\" expansion, [read](../commands/builtin/read.md) *Quoting errors* are a broad category of common mistakes brought about by a few unintuitive features carried over from the Bourne shell due to complaints of broken scripts and changes in previously documented behavior. Most of the important expansions are performed at the same time from left to right. However, a few expansions, most notably word-splitting and globbing, and in shells other than Bash, [brace expansion](../syntax/expansion/brace.md), are performed **on the results of previous expansions, by default, unless they are quoted.** This means that the act of expanding an unquoted variable in an ordinary argument context, depending on the value of the variable, can yield different results depending on possibly uncontrolled side-effects like the value of `IFS`, and the names of files in the current working directory. You can\'t get globbing without word-splitting, or vice versa (without `set -f`). [You can\'t store a command or character-delimited list in a variable and safely evaluate it with unquoted expansion](http://mywiki.wooledge.org/BashFAQ/050). If possible, always choose a shell that supports Korn shell arrays such as Bash. They are a vital but non-standard feature for writing clean, safe scripts. Well-written scripts don\'t use word-splitting. A few exceptions are listed on the [word splitting page](../syntax/expansion/wordsplit.md). A significant proportion of the issues on the famous [Pitfalls list](http://mywiki.wooledge.org/BashPitfalls) fall under this category. See also: *[Don\'t read lines with for!](http://mywiki.wooledge.org/DontReadLinesWithFor)* Unquoted expansions, [wordsplit](../syntax/expansion/wordsplit.md), and [globs](../syntax/expansion/globs.md) [Proper quoting](http://mywiki.wooledge.org/Quotes), Ksh/Bash-style [arrays](../syntax/arrays.md), The \"\$@\" expansion, [read](../commands/builtin/read.md) *Quoting errors* are a broad category of common mistakes brought about by a few unintuitive features carried over from the Bourne shell due to complaints of broken scripts and changes in previously documented behavior. Most of the important expansions are performed at the same time from left to right. However, a few expansions, most notably word-splitting and globbing, and in shells other than Bash, [brace expansion](../syntax/expansion/brace.md), are performed **on the results of previous expansions, by default, unless they are quoted.** This means that the act of expanding an unquoted variable in an ordinary argument context, depending on the value of the variable, can yield different results depending on possibly uncontrolled side-effects like the value of `IFS`, and the names of files in the current working directory. You can't get globbing without word-splitting, or vice versa (without `set -f`). [You can't store a command or character-delimited list in a variable and safely evaluate it with unquoted expansion](http://mywiki.wooledge.org/BashFAQ/050). If possible, always choose a shell that supports Korn shell arrays such as Bash. They are a vital but non-standard feature for writing clean, safe scripts. Well-written scripts don't use word-splitting. A few exceptions are listed on the [word splitting page](../syntax/expansion/wordsplit.md). A significant proportion of the issues on the famous [Pitfalls list](http://mywiki.wooledge.org/BashPitfalls) fall under this category. See also: *[Don't read lines with for!](http://mywiki.wooledge.org/DontReadLinesWithFor)*
`` `COMMANDS` `` `$(COMMANDS)` This is the older Bourne-compatible form of the [command substitution](../syntax/expansion/cmdsubst.md). Both the `` `COMMANDS` `` and `$(COMMANDS)` syntaxes are specified by POSIX, but the latter is [greatly]{.underline} preferred, though the former is unfortunately still very prevalent in scripts. New-style command substitutions are widely implemented by every modern shell (and then some). The only reason for using backticks is for compatibility with a real Bourne shell (like Heirloom). Backtick command substitutions require special escaping when nested, and examples found in the wild are improperly quoted more often than not. See: *[Why is \$(\...) preferred over \`\...\` (backticks)?](http://mywiki.wooledge.org/BashFAQ/082)*. `` `COMMANDS` `` `$(COMMANDS)` This is the older Bourne-compatible form of the [command substitution](../syntax/expansion/cmdsubst.md). Both the `` `COMMANDS` `` and `$(COMMANDS)` syntaxes are specified by POSIX, but the latter is [greatly]{.underline} preferred, though the former is unfortunately still very prevalent in scripts. New-style command substitutions are widely implemented by every modern shell (and then some). The only reason for using backticks is for compatibility with a real Bourne shell (like Heirloom). Backtick command substitutions require special escaping when nested, and examples found in the wild are improperly quoted more often than not. See: *[Why is \$(\...) preferred over \`\...\` (backticks)?](http://mywiki.wooledge.org/BashFAQ/082)*.
`[\ EXPRESSION\ ]`\\ and\\ `test\ EXPRESSION` `[[\ EXPRESSION\ ]]` `test` and `[` are the Bourne/POSIX commands for evaluating test expressions (they are almost identical, and `[` is somewhat more common). The expressions consist of regular arguments, unlike the Ksh/Bash `[[` command. While the issue is analogous to `let` vs `((`, the advantages of `[[` vs `[` are even more important because the arguments/expansions aren\'t just concatenated into one expression. With the classic `[` command, the number of arguments is significant. If at all possible, use the [conditional expression](../syntax/ccmd/conditional_expression.md) (\"new test command\") `[[ EXPRESSION ]]`. Unless there is a need for POSIX compatibility, there are only a few reasons to use `[`. `[[` is one of the most portable and consistent non-POSIX ksh extensions available. See: [conditional_expression](../syntax/ccmd/conditional_expression.md) and *[What is the difference between test, \[ and \[\[ ?](http://mywiki.wooledge.org/BashFAQ/031)* `[\ EXPRESSION\ ]`\\ and\\ `test\ EXPRESSION` `[[\ EXPRESSION\ ]]` `test` and `[` are the Bourne/POSIX commands for evaluating test expressions (they are almost identical, and `[` is somewhat more common). The expressions consist of regular arguments, unlike the Ksh/Bash `[[` command. While the issue is analogous to `let` vs `((`, the advantages of `[[` vs `[` are even more important because the arguments/expansions aren't just concatenated into one expression. With the classic `[` command, the number of arguments is significant. If at all possible, use the [conditional expression](../syntax/ccmd/conditional_expression.md) (\"new test command\") `[[ EXPRESSION ]]`. Unless there is a need for POSIX compatibility, there are only a few reasons to use `[`. `[[` is one of the most portable and consistent non-POSIX ksh extensions available. See: [conditional_expression](../syntax/ccmd/conditional_expression.md) and *[What is the difference between test, \[ and \[\[ ?](http://mywiki.wooledge.org/BashFAQ/031)*
`set -e`, `set -o errexit`\ proper control flow and error handling `set -e` causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as \"error handling\"; it's not, it's just a way to find the place you\'ve *forgotten* to put error handling.\ `set -e`, `set -o errexit`\ proper control flow and error handling `set -e` causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as \"error handling\"; it's not, it's just a way to find the place you\'ve *forgotten* to put error handling.\
and the `ERR` trap Think of it as akin to `use strict` in Perl or `throws` in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use.\ and the `ERR` trap Think of it as akin to `use strict` in Perl or `throws` in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use.\
Because it provides no notification of the location of the error, it's more useful combined with `set -x` or the `DEBUG` trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself.\ Because it provides no notification of the location of the error, it's more useful combined with `set -x` or the `DEBUG` trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself.\
Most of this also applies to the `ERR` trap, though I\'ve seen it used in a few places in shells that lack `pipefail` or `PIPESTATUS`. The `ERR` trap is not POSIX, but `set -e` is. `failglob` is another Bash feature that falls into this category (mainly useful for debugging).\ Most of this also applies to the `ERR` trap, though I\'ve seen it used in a few places in shells that lack `pipefail` or `PIPESTATUS`. The `ERR` trap is not POSIX, but `set -e` is. `failglob` is another Bash feature that falls into this category (mainly useful for debugging).\
**The `set -e` feature generates more questions and false bug reports on the Bash mailing list than all other features combined!** Please do not rely on `set -e` for logic in scripts. If you still refuse to take this advice, make sure you understand **exactly** how it works. See: *[Why doesn\'t set -e (or set -o errexit, or trap ERR) do what I expected?](http://mywiki.wooledge.org/BashFAQ/105)* and <http://www.fvue.nl/wiki/Bash:_Error_handling> **The `set -e` feature generates more questions and false bug reports on the Bash mailing list than all other features combined!** Please do not rely on `set -e` for logic in scripts. If you still refuse to take this advice, make sure you understand **exactly** how it works. See: *[Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected?](http://mywiki.wooledge.org/BashFAQ/105)* and <http://www.fvue.nl/wiki/Bash:_Error_handling>
`set -u` or `set -o nounset` Proper control flow and error handling `set -u` causes attempts to expand unset variables or parameters as fatal errors. Like `set -e`, it bypasses control flow and exits immediately from the current shell environment. Like non-zero statuses, unset variables are a normal part of most non-trivial shell scripts. Living with `set -u` requires hacks like `${1+"$1"}` for each expansion that might possibly be unset. Only very current shells guarantee that expanding `@` or `*` won\'t trigger an error when no parameters are set (<http://austingroupbugs.net/view.php?id=155>, <http://www.in-ulm.de/~mascheck/various/bourne_args/>). Apparently some find it useful for debugging. See *[How do I determine whether a variable is already defined? Or a function?](http://mywiki.wooledge.org/BashFAQ/083)* for how to properly test for defined variables. Don\'t use `set -u`. `set -u` or `set -o nounset` Proper control flow and error handling `set -u` causes attempts to expand unset variables or parameters as fatal errors. Like `set -e`, it bypasses control flow and exits immediately from the current shell environment. Like non-zero statuses, unset variables are a normal part of most non-trivial shell scripts. Living with `set -u` requires hacks like `${1+"$1"}` for each expansion that might possibly be unset. Only very current shells guarantee that expanding `@` or `*` won't trigger an error when no parameters are set (<http://austingroupbugs.net/view.php?id=155>, <http://www.in-ulm.de/~mascheck/various/bourne_args/>). Apparently some find it useful for debugging. See *[How do I determine whether a variable is already defined? Or a function?](http://mywiki.wooledge.org/BashFAQ/083)* for how to properly test for defined variables. Don't use `set -u`.
`${var?msg}` or `${var:?msg}` Proper control flow and error handling Like `set -u`, this expansion causes a fatal error which immediately exits the current shell environment if the given parameter is unset or is null. It prints the error message given, to the right of the operator. If a value is expected and you\'d like to create an assertion or cause errors, it's better to test for undefined variables using one of [these techniques](http://mywiki.wooledge.org/BashFAQ/083) and handle the error manually, or call a `die` function. This expansion is defined by POSIX. It's better than `set -u`, because it's explicit, but not by much. It also allows you to accidentally construct hilariously deceptive error messages: `bash -c 'f() { definitely_not_printf "${printf:?"$1" - No such option}"; }; f -v' `${var?msg}` or `${var:?msg}` Proper control flow and error handling Like `set -u`, this expansion causes a fatal error which immediately exits the current shell environment if the given parameter is unset or is null. It prints the error message given, to the right of the operator. If a value is expected and you\'d like to create an assertion or cause errors, it's better to test for undefined variables using one of [these techniques](http://mywiki.wooledge.org/BashFAQ/083) and handle the error manually, or call a `die` function. This expansion is defined by POSIX. It's better than `set -u`, because it's explicit, but not by much. It also allows you to accidentally construct hilariously deceptive error messages: `bash -c 'f() { definitely_not_printf "${printf:?"$1" - No such option}"; }; f -v'
bash: printf: -v - No such option` bash: printf: -v - No such option`
@ -59,15 +59,15 @@ portability requirements, or in order to make use of some subtle
behavioral differences. These are frequently (mis)used for no reason. behavioral differences. These are frequently (mis)used for no reason.
Writing portable scripts that go outside of POSIX features requires Writing portable scripts that go outside of POSIX features requires
knowing how to account for many (often undocumented) differences across knowing how to account for many (often undocumented) differences across
many shells. If you do happen to know what you\'re doing, don\'t be too many shells. If you do happen to know what you\'re doing, don't be too
surprised if you run across someone telling you not to use these. surprised if you run across someone telling you not to use these.
Syntax Replacement Description Syntax Replacement Description
------------------------------- --------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------- --------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`function\ NAME\ {\ CMDS;\ }` `NAME()\ COMPOUND-CMD` This is the ksh form of function definition created to extend the Bourne and POSIX form with modified behaviors and additional features like local variables. The idea was for new-style functions to be analogous to regular builtins with their own environment and scope, while POSIX-style functions are more like special builtins. `function` is supported by almost every ksh-derived shell including Bash and Zsh, but isn\'t specified by POSIX. Bash treats all function styles the same, but this is unusual. `function` has some preferable characteristics in many ksh variants, making it more portable for scripts that use non-POSIX extensions by some measures. If you\'re going to use the `function` keyword, it implies that you\'re either targeting Ksh specifically, or that you have detailed knowledge of how to compensate for differences across shells. It should always be used consistently with `typeset`, but never used with `declare` or `local`. Also in ksh93, the braces are not a [command group](../syntax/ccmd/grouping_plain.md), but a required part of the syntax (unlike Bash and others). See [shell function definitions](../syntax/basicgrammar.md#shell_function_definitions) `function\ NAME\ {\ CMDS;\ }` `NAME()\ COMPOUND-CMD` This is the ksh form of function definition created to extend the Bourne and POSIX form with modified behaviors and additional features like local variables. The idea was for new-style functions to be analogous to regular builtins with their own environment and scope, while POSIX-style functions are more like special builtins. `function` is supported by almost every ksh-derived shell including Bash and Zsh, but isn't specified by POSIX. Bash treats all function styles the same, but this is unusual. `function` has some preferable characteristics in many ksh variants, making it more portable for scripts that use non-POSIX extensions by some measures. If you\'re going to use the `function` keyword, it implies that you\'re either targeting Ksh specifically, or that you have detailed knowledge of how to compensate for differences across shells. It should always be used consistently with `typeset`, but never used with `declare` or `local`. Also in ksh93, the braces are not a [command group](../syntax/ccmd/grouping_plain.md), but a required part of the syntax (unlike Bash and others). See [shell function definitions](../syntax/basicgrammar.md#shell_function_definitions)
`typeset` `declare`, `local`, `export`, `readonly` This is closely related to the above, and should often be used together. `typeset` exists primarily for `ksh` compatibility, but is marked as \"deprecated\" in Bash (though I don\'t entirely agree with this). This makes some sense, because future compatibility can\'t be guaranteed, and any compatibility at all, requires understanding the non-POSIX features of other shells and their differences. Using `declare` instead of `typeset` emphasizes your intention to be \"Bash-only\", and definitely breaks everywhere else (except possibly zsh if you\'re lucky). The issue is further complicated by Dash and the [Debian policy](http://www.debian.org/doc/debian-policy/ch-files.html#s-scripts) requirement for a `local` builtin, which is itself not entirely compatible with Bash and other shells. `typeset` `declare`, `local`, `export`, `readonly` This is closely related to the above, and should often be used together. `typeset` exists primarily for `ksh` compatibility, but is marked as \"deprecated\" in Bash (though I don't entirely agree with this). This makes some sense, because future compatibility can't be guaranteed, and any compatibility at all, requires understanding the non-POSIX features of other shells and their differences. Using `declare` instead of `typeset` emphasizes your intention to be \"Bash-only\", and definitely breaks everywhere else (except possibly zsh if you\'re lucky). The issue is further complicated by Dash and the [Debian policy](http://www.debian.org/doc/debian-policy/ch-files.html#s-scripts) requirement for a `local` builtin, which is itself not entirely compatible with Bash and other shells.
\'\'let \'EXPR\' \'\' `((EXPR))` or `[\ $((EXPR))\ -ne\ 0 ]` `let` is the \"simple command\" variant of arithmetic evaluation command, which takes regular arguments. Both `let` and `((expr))` were present in ksh88, and everything that supports one should support the other. Neither are POSIX. The compound variant is preferable because it doesn\'t take regular arguments for [wordsplitting](../syntax/expansion/wordsplit.md) and [globbing](../syntax/expansion/globs.md), which makes it safer and clearer. It is also usually faster, especially in Bash, where compound commands are typically significantly faster. Some of the (few) reasons for using `let` are detailed on the [let](../commands/builtin/let.md) page. See [arithmetic evaluation compound command](../syntax/ccmd/arithmetic_eval.md) \'\'let \'EXPR\' \'\' `((EXPR))` or `[\ $((EXPR))\ -ne\ 0 ]` `let` is the \"simple command\" variant of arithmetic evaluation command, which takes regular arguments. Both `let` and `((expr))` were present in ksh88, and everything that supports one should support the other. Neither are POSIX. The compound variant is preferable because it doesn't take regular arguments for [wordsplitting](../syntax/expansion/wordsplit.md) and [globbing](../syntax/expansion/globs.md), which makes it safer and clearer. It is also usually faster, especially in Bash, where compound commands are typically significantly faster. Some of the (few) reasons for using `let` are detailed on the [let](../commands/builtin/let.md) page. See [arithmetic evaluation compound command](../syntax/ccmd/arithmetic_eval.md)
`eval` Depends. Often code can be restructured to use better alternatives. `eval` is thrown in here for good measure, as sadly it is so often misused that any use of `eval` (even the rare clever one) is immediately dismissed as wrong by experts, and among the most immediate solutions abused by beginners. In reality, there are correct ways to use `eval`, and even cases in which it's necessary, even in sophisticated shells like Bash and Ksh. `eval` is unusual in that it is less frequently appropriate in more feature-rich shells than in more minimal shells like Dash, where it is used to compensate for more limitations. If you find yourself needing `eval` too frequently, it might be a sign that you\'re either better off using a different language entirely, or trying to borrow an idiom from some other paradigm that isn\'t well suited to the shell language. By the same token, there are some cases in which working too hard to avoid `eval` ends up adding a lot of complexity and sacrificing all portability. Don\'t substitute a clever `eval` for something that's a bit \"too clever\", just to avoid the `eval`, yet, take reasonable measures to avoid it where it is sensible to do so. See: [eval](../commands/builtin/eval.md) and [Eval command and security issues](http://mywiki.wooledge.org/BashFAQ/048). `eval` Depends. Often code can be restructured to use better alternatives. `eval` is thrown in here for good measure, as sadly it is so often misused that any use of `eval` (even the rare clever one) is immediately dismissed as wrong by experts, and among the most immediate solutions abused by beginners. In reality, there are correct ways to use `eval`, and even cases in which it's necessary, even in sophisticated shells like Bash and Ksh. `eval` is unusual in that it is less frequently appropriate in more feature-rich shells than in more minimal shells like Dash, where it is used to compensate for more limitations. If you find yourself needing `eval` too frequently, it might be a sign that you\'re either better off using a different language entirely, or trying to borrow an idiom from some other paradigm that isn't well suited to the shell language. By the same token, there are some cases in which working too hard to avoid `eval` ends up adding a lot of complexity and sacrificing all portability. Don't substitute a clever `eval` for something that's a bit \"too clever\", just to avoid the `eval`, yet, take reasonable measures to avoid it where it is sensible to do so. See: [eval](../commands/builtin/eval.md) and [Eval command and security issues](http://mywiki.wooledge.org/BashFAQ/048).
## See also ## See also

View File

@ -47,7 +47,7 @@ is the prompt\...):
> /usr/bin/testscript > /usr/bin/testscript
/usr/bin/testscript /usr/bin/testscript
However, this isn\'t true for login shells: However, this isn't true for login shells:
> echo "$0" > echo "$0"
-bash -bash
@ -135,7 +135,7 @@ a given wordlist. The loop uses the positional parameters as a wordlist:
------------------------------------------------------------------------ ------------------------------------------------------------------------
The next method is similar to the first example (the `for` loop), but it The next method is similar to the first example (the `for` loop), but it
doesn\'t test for reaching `$#`. It shifts and checks if `$1` still doesn't test for reaching `$#`. It shifts and checks if `$1` still
expands to something, using the [test command](../commands/classictest.md): expands to something, using the [test command](../commands/classictest.md):
while [ "$1" ] while [ "$1" ]
@ -275,7 +275,7 @@ To make your program accept options as standard command syntax:
`COMMAND [options] <params>` \# Like \'cat -A file.txt\' `COMMAND [options] <params>` \# Like \'cat -A file.txt\'
See simple option parsing code below. It's not that flexible. It See simple option parsing code below. It's not that flexible. It
doesn\'t auto-interpret combined options (-fu USER) but it works and is doesn't auto-interpret combined options (-fu USER) but it works and is
a good rudimentary way to parse your arguments. a good rudimentary way to parse your arguments.
#!/bin/sh #!/bin/sh
@ -335,7 +335,7 @@ This simple wrapper enables filtering unwanted options (here: `-a` and
`--all` for `ls`) out of the command line. It reads the positional `--all` for `ls`) out of the command line. It reads the positional
parameters and builds a filtered array consisting of them, then calls parameters and builds a filtered array consisting of them, then calls
`ls` with the new option set. It also respects the `--` as \"end of `ls` with the new option set. It also respects the `--` as \"end of
options\" for `ls` and doesn\'t change anything after it: options\" for `ls` and doesn't change anything after it:
#!/bin/bash #!/bin/bash

View File

@ -8,7 +8,7 @@ The processes in UNIX(r) are - unlike other systems - **organized as a
tree**. Every process has a parent process that started, or is tree**. Every process has a parent process that started, or is
responsible, for it. Every process has its own **context memory** (Not responsible, for it. Every process has its own **context memory** (Not
the memory where the process stores its data, rather, the memory where the memory where the process stores its data, rather, the memory where
data is stored that doesn\'t directly belong to the process, but is data is stored that doesn't directly belong to the process, but is
needed to run the process) i.e. [**The environment**]{.underline}. needed to run the process) i.e. [**The environment**]{.underline}.
Every process has its **own** environment space. Every process has its **own** environment space.
@ -34,7 +34,7 @@ set by login scripts or programs).
All the diagrams of the process tree use names like \"`xterm`\" or All the diagrams of the process tree use names like \"`xterm`\" or
\"`bash`\", but that's just to make it easier to understand what's \"`bash`\", but that's just to make it easier to understand what's
going on, it doesn\'t mean those processes are actually executed. going on, it doesn't mean those processes are actually executed.
Let's take a short look at what happens when you \"execute a program\" Let's take a short look at what happens when you \"execute a program\"
from the Bash prompt, a program like \"ls\": from the Bash prompt, a program like \"ls\":
@ -65,7 +65,7 @@ The copy of the environment from the first step (forking) becomes the
environment for the final running program (in this case, `ls`). environment for the final running program (in this case, `ls`).
[**What is so important about it?**]{.underline} In our example, what [**What is so important about it?**]{.underline} In our example, what
the program `ls` does inside its own environment, it can\'t affect the the program `ls` does inside its own environment, it can't affect the
environment of its parent process (in this case, `bash`). The environment of its parent process (in this case, `bash`). The
environment was copied when ls was executed. Nothing is \"copied back\" environment was copied when ls was executed. Nothing is \"copied back\"
to the parent environment when `ls` terminates. to the parent environment when `ls` terminates.
@ -73,7 +73,7 @@ to the parent environment when `ls` terminates.
## Bash playing with pipes ## Bash playing with pipes
Pipes are a very powerful tool. You can connect the output of one Pipes are a very powerful tool. You can connect the output of one
process to the input of another process. We won\'t delve into piping at process to the input of another process. We won't delve into piping at
this point, we just want to see how it looks in the process tree. Again, this point, we just want to see how it looks in the process tree. Again,
we execute some commands, this time, we\'ll run `ls` and `grep`: we execute some commands, this time, we\'ll run `ls` and `grep`:
@ -85,8 +85,8 @@ It results in a tree like this:
xterm ----- bash --| xterm ----- bash --|
+-- grep +-- grep
Note once again, `ls` can\'t influence the `grep` environment, `grep` Note once again, `ls` can't influence the `grep` environment, `grep`
can\'t influence the `ls` environment, and neither `grep` nor `ls` can can't influence the `ls` environment, and neither `grep` nor `ls` can
influence the `bash` environment. influence the `bash` environment.
[**How is that related to shell programming?!?**]{.underline} [**How is that related to shell programming?!?**]{.underline}
@ -112,10 +112,10 @@ See the relationship? The forked Bash process will count the lines like
a charm. It will also set the variable `counter` as directed. But if a charm. It will also set the variable `counter` as directed. But if
everything ends, this extra process will be terminated - **your everything ends, this extra process will be terminated - **your
\"counter\" variable is gone.** You see a 0 because in the main shell it \"counter\" variable is gone.** You see a 0 because in the main shell it
was 0, and wasn\'t changed by the child process! was 0, and wasn't changed by the child process!
[**So, how do we count the lines?**]{.underline} Easy: **Avoid the [**So, how do we count the lines?**]{.underline} Easy: **Avoid the
subshell.** The details don\'t matter, the important thing is the shell subshell.** The details don't matter, the important thing is the shell
that sets the counter must be the \"main shell\". For example: that sets the counter must be the \"main shell\". For example:
counter=0 counter=0
@ -126,7 +126,7 @@ that sets the counter must be the \"main shell\". For example:
It's nearly self-explanatory. The `while` loop runs in the **current It's nearly self-explanatory. The `while` loop runs in the **current
shell**, the counter is incremented in the **current shell**, everything shell**, the counter is incremented in the **current shell**, everything
vital happens in the **current shell**, also the `read` command sets the vital happens in the **current shell**, also the `read` command sets the
variable `REPLY` (the default if nothing is given), though we don\'t use variable `REPLY` (the default if nothing is given), though we don't use
it here. it here.
## Actions that create a subshell ## Actions that create a subshell
@ -140,10 +140,10 @@ As shown above, Bash will create subprocesses everytime it executes
commands. That's nothing new. commands. That's nothing new.
But if your command is a subprocess that sets variables you want to use But if your command is a subprocess that sets variables you want to use
in your main script, that won\'t work. in your main script, that won't work.
For exactly this purpose, there's the `source` command (also: the *dot* For exactly this purpose, there's the `source` command (also: the *dot*
`.` command). Source doesn\'t execute the script, it imports the other `.` command). Source doesn't execute the script, it imports the other
script's code into the current shell: script's code into the current shell:
source ./myvariables.sh source ./myvariables.sh

View File

@ -10,8 +10,8 @@ it\".
This is not a bible, of course. But I have seen so much ugly and This is not a bible, of course. But I have seen so much ugly and
terrible code (not only in shell) during all the years, that I\'m 100% terrible code (not only in shell) during all the years, that I\'m 100%
convinced there needs to be *some* code layout and style. No matter convinced there needs to be *some* code layout and style. No matter
which one you use, use it throughout your code (at least don\'t change which one you use, use it throughout your code (at least don't change
it within the same shellscript file); don\'t change your code layout it within the same shellscript file); don't change your code layout
with your mood. with your mood.
Some good code layout helps you to read your own code after a while. And Some good code layout helps you to read your own code after a while. And
@ -203,7 +203,7 @@ in-code documentation for them.
Unless you are really sure what you\'re doing, **quote every parameter Unless you are really sure what you\'re doing, **quote every parameter
expansion**. expansion**.
There are some cases where this isn\'t needed from a technical point of There are some cases where this isn't needed from a technical point of
view, e.g. view, e.g.
- inside `[[ ... ]]` (other than the RHS of the `==`, `!=`, and `=~` - inside `[[ ... ]]` (other than the RHS of the `==`, `!=`, and `=~`
@ -214,7 +214,7 @@ view, e.g.
But quoting these is never a mistake. If you quote every parameter But quoting these is never a mistake. If you quote every parameter
expansion, you\'ll be safe. expansion, you\'ll be safe.
If you need to parse a parameter as a list of words, you can\'t quote, If you need to parse a parameter as a list of words, you can't quote,
of course, e.g. of course, e.g.
list="one two three" list="one two three"
@ -260,7 +260,7 @@ Avoid it, unless absolutely neccesary:
- `eval` can be your neckshot - `eval` can be your neckshot
- there are most likely other ways to achieve what you want - there are most likely other ways to achieve what you want
- if possible, re-think the way your script works, if it seems you - if possible, re-think the way your script works, if it seems you
can\'t avoid `eval` with your current method can't avoid `eval` with your current method
- if you really, really, have to use it, then take care, and be sure - if you really, really, have to use it, then take care, and be sure
about what you\'re doing about what you\'re doing
@ -309,7 +309,7 @@ declared before the main script code runs. This gives a far better
overview and ensures that all function names are known before they are overview and ensures that all function names are known before they are
used. used.
Since a function isn\'t parsed before it is executed, you usually don\'t Since a function isn't parsed before it is executed, you usually don't
have to ensure they\'re in a specific order. have to ensure they\'re in a specific order.
The portable form of the function definition should be used, without the The portable form of the function definition should be used, without the
@ -321,7 +321,7 @@ command](../syntax/ccmd/grouping_plain.md)):
} }
Speaking about the command grouping in function definitions using Speaking about the command grouping in function definitions using
`{ ...; }`: If you don\'t have a good reason to use another compound `{ ...; }`: If you don't have a good reason to use another compound
command directly, you should always use this one. command directly, you should always use this one.
## Behaviour and robustness ## Behaviour and robustness

View File

@ -4,13 +4,13 @@
Terminal (control) codes are used to issue specific commands to your Terminal (control) codes are used to issue specific commands to your
terminal. This can be related to switching colors or positioning the terminal. This can be related to switching colors or positioning the
cursor, i.e. anything that can\'t be done by the application itself. cursor, i.e. anything that can't be done by the application itself.
## How it technically works ## How it technically works
A terminal control code is a special sequence of characters that is A terminal control code is a special sequence of characters that is
printed (like any other text). If the terminal understands the code, it printed (like any other text). If the terminal understands the code, it
won\'t display the character-sequence, but will perform some action. You won't display the character-sequence, but will perform some action. You
can print the codes with a simple `echo` command. can print the codes with a simple `echo` command.
[**Note:**]{.underline} I see codes referenced as \"Bash colors\" [**Note:**]{.underline} I see codes referenced as \"Bash colors\"
@ -43,11 +43,11 @@ I listed only the most relevant codes, of course, any ANSI terminal
understands many more! But let's keep the discussion centered on common understands many more! But let's keep the discussion centered on common
shell scripting ;-) shell scripting ;-)
If I couldn\'t find a matching ANSI escape, you\'ll see a :?: as the If I couldn't find a matching ANSI escape, you\'ll see a :?: as the
code. Feel free to mail me or fix it. code. Feel free to mail me or fix it.
The ANSI codes always start with the ESC character. (ASCII 0x1B or octal The ANSI codes always start with the ESC character. (ASCII 0x1B or octal
033) This isn\'t part of the list, but **you should avoid using the ANSI 033) This isn't part of the list, but **you should avoid using the ANSI
codes directly - use the `tput` command!** codes directly - use the `tput` command!**
All codes that can be used with `tput` can be found in terminfo(5). (on All codes that can be used with `tput` can be found in terminfo(5). (on
@ -178,7 +178,7 @@ termcap/terminfo. While `xterm` and most of its clones (`rxvt`, `urxvt`,
etc) will support the instructions, your operating system may not etc) will support the instructions, your operating system may not
include references to them in its default xterm profile. (FreeBSD, in include references to them in its default xterm profile. (FreeBSD, in
particular, falls into this category.) If \`tput smcup\` appears to do particular, falls into this category.) If \`tput smcup\` appears to do
nothing for you, and you don\'t want to modify your system nothing for you, and you don't want to modify your system
termcap/terminfo data, and you KNOW that you are using a compatible termcap/terminfo data, and you KNOW that you are using a compatible
xterm application, the following may work for you: xterm application, the following may work for you:
@ -210,7 +210,7 @@ terminals](https://gist.github.com/XVilka/8346728#now-supporting-truecolour)
also support full 24-bit colors, and any X11 color code can be written also support full 24-bit colors, and any X11 color code can be written
directly into a special escape sequence. ([More directly into a special escape sequence. ([More
infos](https://gist.github.com/XVilka/8346728)) Only a few programs make infos](https://gist.github.com/XVilka/8346728)) Only a few programs make
use of anything beyond 256 colors, and tput doesn\'t know about them. use of anything beyond 256 colors, and tput doesn't know about them.
Colors beyond 16 usually only apply to modern terminal emulators running Colors beyond 16 usually only apply to modern terminal emulators running
in graphical environments. in graphical environments.
@ -304,7 +304,7 @@ at most 16, and reduces raw output by more than half. The `doBash`
function uses integer arithmetic, but is still ksh93-compatible (run as function uses integer arithmetic, but is still ksh93-compatible (run as
e.g. `bash ./mandelbrot` to use it). The ksh93-only floating-point e.g. `bash ./mandelbrot` to use it). The ksh93-only floating-point
`doKsh` is almost 10x faster than `doBash` (thus the ksh shebang by `doKsh` is almost 10x faster than `doBash` (thus the ksh shebang by
default), but uses only features that don\'t make the Bash parser crash. default), but uses only features that don't make the Bash parser crash.
#!/usr/bin/env ksh #!/usr/bin/env ksh

View File

@ -8,7 +8,7 @@ type : snipplet
Make your scripts output more readable using bash colors. Simply add Make your scripts output more readable using bash colors. Simply add
these variables to your script, and you will be able to echo in color. these variables to your script, and you will be able to echo in color.
(I haven\'t added all the colors available, just some basics) (I haven't added all the colors available, just some basics)
# Colors # Colors
ESC_SEQ="\x1b[" ESC_SEQ="\x1b["

View File

@ -14,7 +14,7 @@ data fields that can contain the delimiter.
"fir,st", "second", "last" "fir,st", "second", "last"
"firtst one", "sec,ond field", "final,ly" "firtst one", "sec,ond field", "final,ly"
Simply using the comma as separator for `awk` won\'t work here, of Simply using the comma as separator for `awk` won't work here, of
course. course.
Solution: Use the field separator `", "|^"|"$` for `awk`. Solution: Use the field separator `", "|^"|"$` for `awk`.
@ -28,7 +28,7 @@ This is an OR-ed list of 3 possible separators:
-------- ----------------------------------------------- -------- -----------------------------------------------
You can tune these delimiters if you have other needs (for example if You can tune these delimiters if you have other needs (for example if
you don\'t have a space after the commas). you don't have a space after the commas).
Test: Test:

View File

@ -31,7 +31,7 @@ You will get something like this:
./bg_kill1.sh: line 11: 3413 Killed sleep 300 ./bg_kill1.sh: line 11: 3413 Killed sleep 300
Yes, we killed it Yes, we killed it
This is more or less a normal message. And it can\'t be easily This is more or less a normal message. And it can't be easily
redirected since it's the shell itself that yells this message, not the redirected since it's the shell itself that yells this message, not the
command `kill` or something else. You would have to redirect the whole command `kill` or something else. You would have to redirect the whole
script's output. script's output.

View File

@ -98,7 +98,7 @@ principle as this [string reverse
example](../commands/builtin/eval.md#expansion_side-effects). It completely example](../commands/builtin/eval.md#expansion_side-effects). It completely
depends on Bash due to its brace expansion evaluation order and array depends on Bash due to its brace expansion evaluation order and array
parameter parsing details. As above, the eval only inserts the COLUMNS parameter parsing details. As above, the eval only inserts the COLUMNS
expansion into the expression and isn\'t involved in the rest, other expansion into the expression and isn't involved in the rest, other
than to put the `_` value into the environment of the `_[0]` expansion. than to put the `_` value into the environment of the `_[0]` expansion.
This works well since we\'re not creating one set of arguments and then This works well since we\'re not creating one set of arguments and then
editing or deleting them to create another as in the previous examples. editing or deleting them to create another as in the previous examples.

View File

@ -65,7 +65,7 @@ rndstr()
\</div\> \</div\>
The remaining examples don\'t use quite the same tricks, which will The remaining examples don't use quite the same tricks, which will
hopefully be explained elsewhere eventually. See hopefully be explained elsewhere eventually. See
[unset](../commands/builtin/unset.md#scope) for why doing assignments in this [unset](../commands/builtin/unset.md#scope) for why doing assignments in this
way works well. way works well.
@ -108,10 +108,10 @@ modifier instructs printf to use the value preceding each parameter as
the field width. Note the space between the parameters. This example the field width. Note the space between the parameters. This example
unfortunately relies upon the unquoted command substitution to perform unfortunately relies upon the unquoted command substitution to perform
unsafe wordsplitting so that the outer printf gets each argument. Values unsafe wordsplitting so that the outer printf gets each argument. Values
in the array can\'t contain characters in IFS, or anything that might be in the array can't contain characters in IFS, or anything that might be
interpreted as a pattern without using `set -f`. interpreted as a pattern without using `set -f`.
Lastly, empty brace expansions can be used which don\'t generate any Lastly, empty brace expansions can be used which don't generate any
output that would need to be filtered. The disadvantage of course is output that would need to be filtered. The disadvantage of course is
that you must construct the brace expansion syntax to add up to the that you must construct the brace expansion syntax to add up to the
number of arguments to be generated, where the most optimal solution is number of arguments to be generated, where the most optimal solution is

View File

@ -8,7 +8,7 @@ LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
Applies at least to `openssh`. Applies at least to `openssh`.
To get the hostkeys for a server, and write them to `known_hosts`-file To get the hostkeys for a server, and write them to `known_hosts`-file
(to avoid that yes/no query when the key isn\'t known), you can do: (to avoid that yes/no query when the key isn't known), you can do:
ssh-keyscan -t rsa foo foo.example.com 1.2.3.4 >> ~/.ssh/known_host ssh-keyscan -t rsa foo foo.example.com 1.2.3.4 >> ~/.ssh/known_host

View File

@ -91,7 +91,7 @@ mean:
bash: 43#H: value too great for base (error token is "43#H") bash: 43#H: value too great for base (error token is "43#H")
If you have no clue what a base is and why there might be other bases, If you have no clue what a base is and why there might be other bases,
and what numbers are and how they are built, then you don\'t need and what numbers are and how they are built, then you don't need
different bases. different bases.
If you want to convert between the usual bases (octal, decimal, hex), If you want to convert between the usual bases (octal, decimal, hex),
@ -103,7 +103,7 @@ strings.
Shell variables can of course be used as operands, even when the integer Shell variables can of course be used as operands, even when the integer
attribute is not turned on (by `declare -i <NAME>`). If the variable is attribute is not turned on (by `declare -i <NAME>`). If the variable is
empty (null) or unset, its reference evaluates to 0. If the variable empty (null) or unset, its reference evaluates to 0. If the variable
doesn\'t hold a value that looks like a valid expression (numbers or doesn't hold a value that looks like a valid expression (numbers or
operations), the expression is re-used to reference, for example, the operations), the expression is re-used to reference, for example, the
named parameters, e.g.: named parameters, e.g.:
@ -265,7 +265,7 @@ codes of commands or functions to be executed. `if` statements, `while`
loops, etc., they all take the return codes of commands as conditions. loops, etc., they all take the return codes of commands as conditions.
Now the problem is: The return codes (0 means \"TRUE\" or \"SUCCESS\", Now the problem is: The return codes (0 means \"TRUE\" or \"SUCCESS\",
not 0 means \"FALSE\" or \"FAILURE\") don\'t correspond to the meaning not 0 means \"FALSE\" or \"FAILURE\") don't correspond to the meaning
of the result of an arithmetic expression (0 means \"FALSE\", not 0 of the result of an arithmetic expression (0 means \"FALSE\", not 0
means \"TRUE\"). means \"TRUE\").

View File

@ -43,7 +43,7 @@ Bash supports two different types of ksh-like one-dimensional arrays.
arrays allow you to look up a value from a table based upon its arrays allow you to look up a value from a table based upon its
corresponding string label. **Associative arrays are always corresponding string label. **Associative arrays are always
unordered**, they merely *associate* key-value pairs. If you unordered**, they merely *associate* key-value pairs. If you
retrieve multiple values from the array at once, you can\'t count on retrieve multiple values from the array at once, you can't count on
them coming out in the same order you put them in. Associative them coming out in the same order you put them in. Associative
arrays always carry the `-A` attribute, and unlike indexed arrays, arrays always carry the `-A` attribute, and unlike indexed arrays,
Bash requires that they always be declared explicitly (as indexed Bash requires that they always be declared explicitly (as indexed
@ -127,7 +127,7 @@ variables.
`ARRAY+=(E1\ E2\ ...)` Append to ARRAY. `ARRAY+=(E1\ E2\ ...)` Append to ARRAY.
`ARRAY=("${ANOTHER_ARRAY[@]}")` Copy ANOTHER_ARRAY to ARRAY, copying each element. `ARRAY=("${ANOTHER_ARRAY[@]}")` Copy ANOTHER_ARRAY to ARRAY, copying each element.
As of now, arrays can\'t be exported. As of now, arrays can't be exported.
### Getting values ### Getting values
@ -137,7 +137,7 @@ check the notes about arrays. \</note\>
Syntax Description Syntax Description
----------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`${ARRAY[N]}` Expands to the value of the index `N` in the **indexed** array `ARRAY`. If `N` is a negative number, it's treated as the offset from the maximum assigned index (can\'t be used for assignment) - 1 `${ARRAY[N]}` Expands to the value of the index `N` in the **indexed** array `ARRAY`. If `N` is a negative number, it's treated as the offset from the maximum assigned index (can't be used for assignment) - 1
`${ARRAY[S]}` Expands to the value of the index `S` in the **associative** array `ARRAY`. `${ARRAY[S]}` Expands to the value of the index `S` in the **associative** array `ARRAY`.
`"${ARRAY[@]}" ${ARRAY[@]} "${ARRAY[*]}" ${ARRAY[*]}` Similar to [mass-expanding positional parameters](../scripting/posparams.md#mass_usage), this expands to all elements. If unquoted, both subscripts `*` and `@` expand to the same result, if quoted, `@` expands to all elements individually quoted, `*` expands to all elements quoted as a whole. `"${ARRAY[@]}" ${ARRAY[@]} "${ARRAY[*]}" ${ARRAY[*]}` Similar to [mass-expanding positional parameters](../scripting/posparams.md#mass_usage), this expands to all elements. If unquoted, both subscripts `*` and `@` expand to the same result, if quoted, `@` expands to all elements individually quoted, `*` expands to all elements quoted as a whole.
`"${ARRAY[@]:N:M}" ${ARRAY[@]:N:M} "${ARRAY[*]:N:M}" ${ARRAY[*]:N:M}` Similar to what this syntax does for the characters of a single string when doing [substring expansion](../syntax/pe.md#substring_expansion), this expands to `M` elements starting with element `N`. This way you can mass-expand individual indexes. The rules for quoting and the subscripts `*` and `@` are the same as above for the other mass-expansions. `"${ARRAY[@]:N:M}" ${ARRAY[@]:N:M} "${ARRAY[*]:N:M}" ${ARRAY[*]:N:M}` Similar to what this syntax does for the characters of a single string when doing [substring expansion](../syntax/pe.md#substring_expansion), this expands to `M` elements starting with element `N`. This way you can mass-expand individual indexes. The rules for quoting and the subscripts `*` and `@` are the same as above for the other mass-expansions.
@ -246,7 +246,7 @@ sometimes. Please understand that **numerical array indexing begins at 0
The method above, walking through an array by just knowing its number of The method above, walking through an array by just knowing its number of
elements, only works for arrays where all elements are set, of course. elements, only works for arrays where all elements are set, of course.
If one element in the middle is removed, then the calculation is If one element in the middle is removed, then the calculation is
nonsense, because the number of elements doesn\'t correspond to the nonsense, because the number of elements doesn't correspond to the
highest used index anymore (we call them \"*sparse arrays*\"). highest used index anymore (we call them \"*sparse arrays*\").
Now, suppose that you want to replace your array `sentence` with the Now, suppose that you want to replace your array `sentence` with the
@ -297,7 +297,7 @@ starting at zero) just is replaced with an arbitrary string:
sentence[End]='in what you send' sentence[End]='in what you send'
sentence['Very end']=... sentence['Very end']=...
[**Beware:**]{.underline} don\'t rely on the fact that the elements are [**Beware:**]{.underline} don't rely on the fact that the elements are
ordered in memory like they were declared, it could look like this: ordered in memory like they were declared, it could look like this:
# output from 'set' command # output from 'set' command
@ -305,7 +305,7 @@ ordered in memory like they were declared, it could look like this:
This effectively means, you can get the data back with This effectively means, you can get the data back with
`"${sentence[@]}"`, of course (just like with numerical indexing), but `"${sentence[@]}"`, of course (just like with numerical indexing), but
you can\'t rely on a specific order. If you want to store ordered data, you can't rely on a specific order. If you want to store ordered data,
or re-order data, go with numerical indexes. For associative arrays, you or re-order data, go with numerical indexes. For associative arrays, you
usually query known index values: usually query known index values:
@ -479,7 +479,7 @@ dynamically calls a function whose name is resolved from the array.
prior to assignment. In order to preserve attributes, you must use prior to assignment. In order to preserve attributes, you must use
the `+=` operator. However, declaring an associative array, then the `+=` operator. However, declaring an associative array, then
attempting an `a=(...)` style compound assignment without specifying attempting an `a=(...)` style compound assignment without specifying
indexes is an error. I can\'t explain this indexes is an error. I can't explain this
inconsistency.` $ ksh -c 'function f { typeset -a a; a=([0]=foo [1]=bar); typeset -p a; }; f' # Attribute is lost, and since subscripts are given, we default to associative. inconsistency.` $ ksh -c 'function f { typeset -a a; a=([0]=foo [1]=bar); typeset -p a; }; f' # Attribute is lost, and since subscripts are given, we default to associative.
typeset -A a=([0]=foo [1]=bar) typeset -A a=([0]=foo [1]=bar)
$ ksh -c 'function f { typeset -a a; a+=([0]=foo [1]=bar); typeset -p a; }; f' # Now using += gives us the expected results. $ ksh -c 'function f { typeset -a a; a+=([0]=foo [1]=bar); typeset -p a; }; f' # Now using += gives us the expected results.
@ -490,7 +490,7 @@ dynamically calls a function whose name is resolved from the array.
- Only Bash and mksh support compound assignment with mixed explicit - Only Bash and mksh support compound assignment with mixed explicit
subscripts and automatically incrementing subscripts. In ksh93, in subscripts and automatically incrementing subscripts. In ksh93, in
order to specify individual subscripts within a compound assignment, order to specify individual subscripts within a compound assignment,
all subscripts must be given (or none). Zsh doesn\'t support all subscripts must be given (or none). Zsh doesn't support
specifying individual subscripts at all. specifying individual subscripts at all.
- Appending to a compound assignment is a fairly portable way to - Appending to a compound assignment is a fairly portable way to
append elements after the last index of an array. In Bash, this also append elements after the last index of an array. In Bash, this also
@ -526,7 +526,7 @@ dynamically calls a function whose name is resolved from the array.
portability. portability.
- Zsh and mksh do not support compound assignment arguments to - Zsh and mksh do not support compound assignment arguments to
`typeset`. `typeset`.
- Ksh88 didn\'t support modern compound array assignment syntax. The - Ksh88 didn't support modern compound array assignment syntax. The
original (and most portable) way to assign multiple elements is to original (and most portable) way to assign multiple elements is to
use the `set -A name arg1 arg2 ...` syntax. This is supported by use the `set -A name arg1 arg2 ...` syntax. This is supported by
almost all shells that support ksh-like arrays except for Bash. almost all shells that support ksh-like arrays except for Bash.
@ -563,9 +563,9 @@ dynamically calls a function whose name is resolved from the array.
- Assigning or referencing negative indexes in mksh causes - Assigning or referencing negative indexes in mksh causes
wrap-around. The max index appears to be `UINT_MAX`, which would be wrap-around. The max index appears to be `UINT_MAX`, which would be
addressed by `arr[-1]`. addressed by `arr[-1]`.
- So far, Bash's `-v var` test doesn\'t support individual array - So far, Bash's `-v var` test doesn't support individual array
subscripts. You may supply an array name to test whether an array is subscripts. You may supply an array name to test whether an array is
defined, but can\'t check an element. ksh93's `-v` supports both. defined, but can't check an element. ksh93's `-v` supports both.
Other shells lack a `-v` test. Other shells lack a `-v` test.
### Bugs ### Bugs
@ -608,7 +608,7 @@ dynamically calls a function whose name is resolved from the array.
<a b cfoo> <a b cfoo>
` `
- **Fixed in 4.3** Process substitutions are evaluated within array - **Fixed in 4.3** Process substitutions are evaluated within array
indexes. Zsh and ksh don\'t do this in any arithmetic context. indexes. Zsh and ksh don't do this in any arithmetic context.
`# print "moo" `# print "moo"
dev=fd=1 _[1<(echo moo >&2)]= dev=fd=1 _[1<(echo moo >&2)]=

View File

@ -7,7 +7,7 @@ code you see everywhere, the code you use, is based on those rules.
However, **this is a very theoretical view**, but if you\'re interested, However, **this is a very theoretical view**, but if you\'re interested,
it may help you understand why things look the way they look. it may help you understand why things look the way they look.
If you don\'t know the commands used in the following examples, just If you don't know the commands used in the following examples, just
trust the explanation. trust the explanation.
## Simple Commands ## Simple Commands
@ -29,7 +29,7 @@ Every complex Bash operation can be split into simple commands:
LC_ALL=C ls LC_ALL=C ls
The last one might not be familiar. That one simply adds \"`LC_ALL=C`\" The last one might not be familiar. That one simply adds \"`LC_ALL=C`\"
to the environment of the `ls` program. It doesn\'t affect your current to the environment of the `ls` program. It doesn't affect your current
shell. This also works while calling functions, unless Bash runs in shell. This also works while calling functions, unless Bash runs in
POSIX(r) mode (in which case it affects your current shell). POSIX(r) mode (in which case it affects your current shell).
@ -50,8 +50,8 @@ FIXME Missing an additional article about pipelines and pipelining
`[time [-p]] [ ! ] command [ | command2 ... ]` `[time [-p]] [ ! ] command [ | command2 ... ]`
**Don\'t get confused** about the name \"pipeline.\" It's a grammatic **Don't get confused** about the name \"pipeline.\" It's a grammatic
name for a construct. Such a pipeline isn\'t necessarily a pair of name for a construct. Such a pipeline isn't necessarily a pair of
commands where stdout/stdin is connected via a real pipe. commands where stdout/stdin is connected via a real pipe.
Pipelines are one or more [simple Pipelines are one or more [simple
@ -254,14 +254,14 @@ It is possible to create function names containing slashes:
echo LS FAKE echo LS FAKE
} }
The elements of this name aren\'t subject to a path search. The elements of this name aren't subject to a path search.
Weird function names should not be used. Quote from the maintainer: Weird function names should not be used. Quote from the maintainer:
- * It was a mistake to allow such characters in function names - * It was a mistake to allow such characters in function names
(\`unset\' doesn\'t work to unset them without forcing -f, for (\`unset\' doesn't work to unset them without forcing -f, for
instance). We\'re stuck with them for backwards compatibility, but I instance). We\'re stuck with them for backwards compatibility, but I
don\'t have to encourage their use. * don't have to encourage their use. *
## Grammar summary ## Grammar summary

View File

@ -68,7 +68,7 @@ command](../../syntax/ccmd/arithmetic_eval.md) would be structured as:
(( <EXPR3> )) (( <EXPR3> ))
done done
The equivalent `while` construct isn\'t exactly the same, because both, The equivalent `while` construct isn't exactly the same, because both,
the `for` and the `while` loop behave differently in case you use the the `for` and the `while` loop behave differently in case you use the
[continue](../../commands/builtin/continuebreak.md) command. [continue](../../commands/builtin/continuebreak.md) command.
@ -83,7 +83,7 @@ Bash, Ksh93, Mksh, and Zsh also provide an alternate syntax for the
echo $x echo $x
} }
This syntax is **not documented** and shouldn\'t be used. I found the This syntax is **not documented** and shouldn't be used. I found the
parser definitions for it in 1.x code, and in modern 4.x code. My guess parser definitions for it in 1.x code, and in modern 4.x code. My guess
is that it's there for compatibility reasons. Unlike the other is that it's there for compatibility reasons. Unlike the other
aforementioned shells, Bash does not support the analogous syntax for aforementioned shells, Bash does not support the analogous syntax for
@ -220,16 +220,16 @@ variables.
## Portability considerations ## Portability considerations
- C-style for loops aren\'t POSIX. They are available in Bash, ksh93, - C-style for loops aren't POSIX. They are available in Bash, ksh93,
and zsh. All 3 have essentially the same syntax and behavior. and zsh. All 3 have essentially the same syntax and behavior.
- C-style for loops aren\'t available in mksh. - C-style for loops aren't available in mksh.
## Bugs ## Bugs
- *Fixed in 4.3*. ~~There appears to be a bug as of Bash 4.2p10 in - *Fixed in 4.3*. ~~There appears to be a bug as of Bash 4.2p10 in
which command lists can\'t be distinguished from the for loop's which command lists can't be distinguished from the for loop's
arithmetic argument delimiter (both semicolons), so command arithmetic argument delimiter (both semicolons), so command
substitutions within the C-style for loop expression can\'t contain substitutions within the C-style for loop expression can't contain
more than one command.~~ more than one command.~~
## See also ## See also

View File

@ -25,9 +25,9 @@ Bash 4 introduces two new action terminators. The classic behavior using
`;;` is to execute only the list associated with the first matching `;;` is to execute only the list associated with the first matching
pattern, then break out of the `case` block. The `;&` terminator causes pattern, then break out of the `case` block. The `;&` terminator causes
`case` to also execute the next block without testing its pattern. The `case` to also execute the next block without testing its pattern. The
`;;&` operator is like `;;`, except the case statement doesn\'t `;;&` operator is like `;;`, except the case statement doesn't
terminate after executing the associated list - Bash just continues terminate after executing the associated list - Bash just continues
testing the next pattern as though the previous pattern didn\'t match. testing the next pattern as though the previous pattern didn't match.
Using these terminators, a `case` statement can be configured to test Using these terminators, a `case` statement can be configured to test
against all patterns, or to share code between blocks, for example. against all patterns, or to share code between blocks, for example.
@ -74,7 +74,7 @@ Another one of my stupid examples\...
echo 'Hm, a bit awry, no?' echo 'Hm, a bit awry, no?'
;; ;;
orange|tangerine) orange|tangerine)
echo $'Eeeks! I don\'t like those!\nGo away!' echo $'Eeeks! I don't like those!\nGo away!'
exit 1 exit 1
;; ;;
*) *)
@ -153,7 +153,7 @@ f a b c
and close braces may be used in place of `in` and `esac`: and close braces may be used in place of `in` and `esac`:
`case word { x) ...; };`. This is similar to the alternate form Bash `case word { x) ...; };`. This is similar to the alternate form Bash
supports for its [for loops](../../syntax/ccmd/classic_for.md), but Bash supports for its [for loops](../../syntax/ccmd/classic_for.md), but Bash
doesn\'t support this syntax for `case..esac`. doesn't support this syntax for `case..esac`.
## See also ## See also

View File

@ -8,7 +8,7 @@
The conditional expression is meant as the modern variant of the The conditional expression is meant as the modern variant of the
[classic test command](../../commands/classictest.md). Since it is **not** a [classic test command](../../commands/classictest.md). Since it is **not** a
normal command, Bash doesn\'t need to apply the normal commandline normal command, Bash doesn't need to apply the normal commandline
parsing rules like recognizing `&&` as [command parsing rules like recognizing `&&` as [command
list](../../syntax/basicgrammar.md#lists) operator. list](../../syntax/basicgrammar.md#lists) operator.
@ -153,7 +153,7 @@ Example:
As of Bash 4.1 alpha, the test primaries \'\<\' and \'\>\' (compare As of Bash 4.1 alpha, the test primaries \'\<\' and \'\>\' (compare
strings lexicographically) use the current locale settings, while the strings lexicographically) use the current locale settings, while the
same primitives for the builtin test command don\'t. This leads to the same primitives for the builtin test command don't. This leads to the
following situation where they behave differently: following situation where they behave differently:
$ ./cond.sh $ ./cond.sh
@ -162,7 +162,7 @@ following situation where they behave differently:
[ ' 4' \< '1' ] --> exit 0 [ ' 4' \< '1' ] --> exit 0
[ 'step+' \< 'step-' ] --> exit 0 [ 'step+' \< 'step-' ] --> exit 0
It won\'t be aligned. The conditional expression continues to respect It won't be aligned. The conditional expression continues to respect
the locate, as introduced with 4.1-alpha, the builtin `test`/`[` command the locate, as introduced with 4.1-alpha, the builtin `test`/`[` command
continues to behave differently. continues to behave differently.
@ -178,7 +178,7 @@ both contains whitespace and is not the result of an expansion.
## Portability considerations ## Portability considerations
- `[[ ... ]]` functionality isn\'t specified by POSIX(R), though it's - `[[ ... ]]` functionality isn't specified by POSIX(R), though it's
a reserved word a reserved word
- Amongst the major \"POSIX-shell superset languages\" (for lack of a - Amongst the major \"POSIX-shell superset languages\" (for lack of a
better term) which do have `[[`, the test expression compound better term) which do have `[[`, the test expression compound
@ -192,7 +192,7 @@ both contains whitespace and is not the result of an expansion.
- As an extension to POSIX ERE, most GNU software supports - As an extension to POSIX ERE, most GNU software supports
backreferences in ERE, including Bash. According to POSIX, only BRE backreferences in ERE, including Bash. According to POSIX, only BRE
is supposed to support them. This requires Bash to be linked against is supposed to support them. This requires Bash to be linked against
glibc, so it won\'t necessarily work on all platforms. For example, glibc, so it won't necessarily work on all platforms. For example,
`$(m='(abc(def))(\1)(\2)'; [[ abcdefabcdefdef =~ $m ]]; printf '<%s> ' $? "${BASH_REMATCH[@]}" )` `$(m='(abc(def))(\1)(\2)'; [[ abcdefabcdefdef =~ $m ]]; printf '<%s> ' $? "${BASH_REMATCH[@]}" )`
will give `<0> <abcdefabcdefdef> <abcdef> <def> <abcdef> <def>`. will give `<0> <abcdefabcdefdef> <abcdef> <def> <abcdef> <def>`.
- the `=~` (regex) operator was introduced in Bash 3.0, and its - the `=~` (regex) operator was introduced in Bash 3.0, and its

View File

@ -26,7 +26,7 @@ function printSum {
} }
``` ```
**Note** that in Bash you don\'t need the arithmetic expansion to check **Note** that in Bash you don't need the arithmetic expansion to check
for the boolean value of an arithmetic expression. This can be done for the boolean value of an arithmetic expression. This can be done
using the [arithmetic evaluation compound using the [arithmetic evaluation compound
command](../../syntax/ccmd/arithmetic_eval.md): command](../../syntax/ccmd/arithmetic_eval.md):
@ -58,7 +58,7 @@ echo $(($x[0])) # Error. This expands to $((1[0])), an invalid expression.
## Bugs and Portability considerations ## Bugs and Portability considerations
- The original Bourne shell doesn\'t have arithmetic expansions. You - The original Bourne shell doesn't have arithmetic expansions. You
have to use something like `expr(1)` within backticks instead. Since have to use something like `expr(1)` within backticks instead. Since
`expr` is horrible (as are backticks), and arithmetic expansion is `expr` is horrible (as are backticks), and arithmetic expansion is
required by POSIX, you should not worry about this, and preferably required by POSIX, you should not worry about this, and preferably

View File

@ -34,7 +34,7 @@ Another common pitfall is to assume that a range like `{1..200}` can be
expressed with variables using `{$a..$b}`. Due to what I described expressed with variables using `{$a..$b}`. Due to what I described
above, it **simply is not possible**, because it's the very first step above, it **simply is not possible**, because it's the very first step
in doing expansions. A possible way to achieve this, if you really in doing expansions. A possible way to achieve this, if you really
can\'t handle this in another way, is using the `eval` command, which can't handle this in another way, is using the `eval` command, which
basically evaluates a commandline twice: `eval echo {$a..$b}` For basically evaluates a commandline twice: `eval echo {$a..$b}` For
instance, when embedded inside a for loop : instance, when embedded inside a for loop :
`for i in $(eval echo {$a..$b})` This requires that the entire command `for i in $(eval echo {$a..$b})` This requires that the entire command
@ -78,7 +78,7 @@ With prefix or suffix strings, the result is a space-separated list of
The brace expansion is only performed, if the given string list is The brace expansion is only performed, if the given string list is
really a **list of strings**, i.e., if there is a minimum of one \"`,`\" really a **list of strings**, i.e., if there is a minimum of one \"`,`\"
(comma)! Something like `{money}` doesn\'t expand to something special, (comma)! Something like `{money}` doesn't expand to something special,
it's really only the text \"`{money}`\". it's really only the text \"`{money}`\".
## Ranges ## Ranges
@ -160,7 +160,7 @@ then the lowercase ones:
In this example, `wget` is used to download documentation that is split In this example, `wget` is used to download documentation that is split
over several numbered webpages. over several numbered webpages.
`wget` won\'t see your braces. It will see **6 different URLs** to `wget` won't see your braces. It will see **6 different URLs** to
download. download.
wget http://docs.example.com/documentation/slides_part{1,2,3,4,5,6}.html wget http://docs.example.com/documentation/slides_part{1,2,3,4,5,6}.html

View File

@ -26,7 +26,7 @@ other `IFS`-characters they contain.
be matched explicitly be matched explicitly
- the dot at the beginning of a filename must be matched explicitly - the dot at the beginning of a filename must be matched explicitly
(also one following a `/` in the glob) (also one following a `/` in the glob)
- a glob that doesn\'t match a filename is unchanged and remains what - a glob that doesn't match a filename is unchanged and remains what
it is it is
## Customization ## Customization
@ -42,8 +42,8 @@ other `IFS`-characters they contain.
- when the shell option `dirspell` is set, Bash performs spelling - when the shell option `dirspell` is set, Bash performs spelling
corrections when matching directory names corrections when matching directory names
- when the shell option `globstar` is set, the glob `**` will - when the shell option `globstar` is set, the glob `**` will
recursively match all files and directories. This glob isn\'t recursively match all files and directories. This glob isn't
\"configurable\", i.e. you **can\'t** do something like `**.c` to \"configurable\", i.e. you **can't** do something like `**.c` to
recursively get all `*.c` filenames. recursively get all `*.c` filenames.
- when the shell option `globasciiranges` is set, the bracket-range - when the shell option `globasciiranges` is set, the bracket-range
globs (e.g. `[A-Z]`) use C locale order rather than the configured globs (e.g. `[A-Z]`) use C locale order rather than the configured
@ -80,7 +80,7 @@ with an error, since no file named `*.txt` exists.
Now, when the shell option `nullglob` is set, Bash will remove the Now, when the shell option `nullglob` is set, Bash will remove the
entire glob from the command line. In case of the for-loop here, not entire glob from the command line. In case of the for-loop here, not
even one iteration will be done. It just won\'t run. even one iteration will be done. It just won't run.
So in our first example: So in our first example:

View File

@ -14,7 +14,7 @@ The most simple example of this behaviour is a referenced variable:
mystring="Hello world" mystring="Hello world"
echo "$mystring" echo "$mystring"
The `echo` program definitely doesn\'t care about what a shell variable The `echo` program definitely doesn't care about what a shell variable
is. It is Bash's job to deal with the variable. Bash **expands** the is. It is Bash's job to deal with the variable. Bash **expands** the
string \"`$mystring`\" to \"`Hello world`\", so that `echo` will only string \"`$mystring`\" to \"`Hello world`\", so that `echo` will only
see `Hello world`, not the variable or anything else! see `Hello world`, not the variable or anything else!
@ -22,12 +22,12 @@ see `Hello world`, not the variable or anything else!
After all these expansions and substitutions are done, all quotes that After all these expansions and substitutions are done, all quotes that
are not meant literally (i.e., [the quotes that marked contiguous are not meant literally (i.e., [the quotes that marked contiguous
words](../../syntax/quoting.md), as part of the shell syntax) are removed from words](../../syntax/quoting.md), as part of the shell syntax) are removed from
the commandline text, so the called program won\'t see them. This step the commandline text, so the called program won't see them. This step
is called **quote-removal**. is called **quote-removal**.
## Overview ## Overview
Saw a possible expansion syntax but don\'t know what it is? Here's a Saw a possible expansion syntax but don't know what it is? Here's a
small list. small list.
- [Parameter expansion](../../syntax/pe.md) (it has its own [overview - [Parameter expansion](../../syntax/pe.md) (it has its own [overview

View File

@ -24,8 +24,8 @@ is connected to a FIFO or a file in `/dev/fd/`. The filename (where the
filedescriptor is connected) is then used as a substitution for the filedescriptor is connected) is then used as a substitution for the
`<(...)`-construct. `<(...)`-construct.
That, for example, allows to give data to a command that can\'t be That, for example, allows to give data to a command that can't be
reached by pipelining (that doesn\'t expect its data from `stdin` but reached by pipelining (that doesn't expect its data from `stdin` but
from a file). from a file).
### Scope ### Scope
@ -53,7 +53,7 @@ the caller when the callee returns.
In essence, process substitutions expanded to variables within functions In essence, process substitutions expanded to variables within functions
remain open until the function in which the process substitution occured remain open until the function in which the process substitution occured
returns - even when assigned to locals that were set by a function's returns - even when assigned to locals that were set by a function's
caller. Dynamic scope doesn\'t protect them from closing. caller. Dynamic scope doesn't protect them from closing.
## Examples ## Examples
@ -74,7 +74,7 @@ diff <(ls "$first_directory") <(ls "$second_directory")
``` ```
This will compare the contents of each directory. In this command, each This will compare the contents of each directory. In this command, each
*process* is *substituted* for a *file*, and diff doesn\'t see \<(bla), *process* is *substituted* for a *file*, and diff doesn't see \<(bla),
it sees two files, so the effective command is something like it sees two files, so the effective command is something like
``` bash ``` bash
@ -88,7 +88,7 @@ where those files are written to and destroyed automatically.
\<WRAP center round info 60%\> See Also: \<WRAP center round info 60%\> See Also:
[BashFAQ/024](http://mywiki.wooledge.org/BashFAQ/024) \-- *I set [BashFAQ/024](http://mywiki.wooledge.org/BashFAQ/024) \-- *I set
variables in a loop that's in a pipeline. Why do they disappear after variables in a loop that's in a pipeline. Why do they disappear after
the loop terminates? Or, why can\'t I pipe data to read?* \</WRAP\> the loop terminates? Or, why can't I pipe data to read?* \</WRAP\>
One of the most common uses for process substitutions is to avoid the One of the most common uses for process substitutions is to avoid the
final subshell that results from executing a pipeline. The following is final subshell that results from executing a pipeline. The following is
@ -159,7 +159,7 @@ See the above section on [#scope](#scope)
- Process substitution is supported only on systems that support - Process substitution is supported only on systems that support
either named pipes (FIFO - a [special either named pipes (FIFO - a [special
file](../../dict/terms/special_file.md)) or the `/dev/fd/*` method for file](../../dict/terms/special_file.md)) or the `/dev/fd/*` method for
accessing open files. If the system doesn\'t support `/dev/fd/*`, accessing open files. If the system doesn't support `/dev/fd/*`,
Bash falls back to creating named pipes. Note that not all shells Bash falls back to creating named pipes. Note that not all shells
that support process substitution have that fallback. that support process substitution have that fallback.
- Bash evaluates process substitutions within array indices, but not - Bash evaluates process substitutions within array indices, but not

View File

@ -39,7 +39,7 @@ Tilde expansion is also performed everytime a variable is assigned:
echo foo=~ echo foo=~
echo foo=:~ echo foo=:~
I don\'t know yet, if this is a bug or intended. \</note\> I don't know yet, if this is a bug or intended. \</note\>
This way you can correctly use the tilde expansion in your This way you can correctly use the tilde expansion in your
[PATH](../../syntax/shellvars.md#PATH): [PATH](../../syntax/shellvars.md#PATH):
@ -60,8 +60,8 @@ This way you can correctly use the tilde expansion in your
This form expands to the home-directory of the current user (`~`) or the This form expands to the home-directory of the current user (`~`) or the
home directory of the given user (`~<NAME>`). home directory of the given user (`~<NAME>`).
If the given user doesn\'t exist (or if his home directory isn\'t If the given user doesn't exist (or if his home directory isn't
determinable, for some reason), it doesn\'t expand to something else, it determinable, for some reason), it doesn't expand to something else, it
stays what it is. The requested home directory is found by asking the stays what it is. The requested home directory is found by asking the
operating system for the associated home directory for `<NAME>`. operating system for the associated home directory for `<NAME>`.

View File

@ -31,14 +31,14 @@ The results of the expansions mentioned above are scanned for
`IFS`-characters. If **one or more** (in a sequence) of them is found, `IFS`-characters. If **one or more** (in a sequence) of them is found,
the expansion result is split at these positions into multiple words. the expansion result is split at these positions into multiple words.
This doesn\'t happen when the expansion results were **double-quoted**. This doesn't happen when the expansion results were **double-quoted**.
When a null-string (e.g., something that before expanded to When a null-string (e.g., something that before expanded to
\>\>nothing\<\<) is found, it is removed, unless it is quoted (`''` or \>\>nothing\<\<) is found, it is removed, unless it is quoted (`''` or
`""`). `""`).
[**Again note:**]{.underline} Without any expansion beforehand, Bash [**Again note:**]{.underline} Without any expansion beforehand, Bash
won\'t perform word splitting! In this case, the initial token parsing won't perform word splitting! In this case, the initial token parsing
is solely responsible. is solely responsible.
## See also ## See also

View File

@ -113,7 +113,7 @@ As of Bash Version 4, when a command search fails, the shell executes a
shell function named `command_not_found_handle()` using the failed shell function named `command_not_found_handle()` using the failed
command as arguments. This can be used to provide user friendly messages command as arguments. This can be used to provide user friendly messages
or install software packages etc. Since this function runs in a separate or install software packages etc. Since this function runs in a separate
execution environment, you can\'t really influence the main shell with execution environment, you can't really influence the main shell with
it (changing directory, setting variables). it (changing directory, setting variables).
FIXME to be continued FIXME to be continued

View File

@ -100,7 +100,7 @@ nothing read
``` ```
Even though this example is the same as the first `awk` example, the Even though this example is the same as the first `awk` example, the
`read` doesn\'t return because the output is waiting in a buffer. `read` doesn't return because the output is waiting in a buffer.
See [this faq entry on Greg's See [this faq entry on Greg's
wiki](http://mywiki.wooledge.org/BashFAQ/009) for some workarounds and wiki](http://mywiki.wooledge.org/BashFAQ/009) for some workarounds and
@ -147,7 +147,7 @@ Here, fd 3 is inherited.
### Anonymous Coprocess ### Anonymous Coprocess
Unlike ksh, Bash doesn\'t have true anonymous coprocesses. Instead, Bash Unlike ksh, Bash doesn't have true anonymous coprocesses. Instead, Bash
assigns FDs to a default array named `COPROC` if no `NAME` is supplied. assigns FDs to a default array named `COPROC` if no `NAME` is supplied.
Here's an example: Here's an example:
@ -171,7 +171,7 @@ $ IFS= read -ru ${COPROC[0]} x; printf '%s\n' "$x"
foobar foobar
``` ```
When we don\'t need our command anymore, we can kill it via its pid: When we don't need our command anymore, we can kill it via its pid:
$ kill $COPROC_PID $ kill $COPROC_PID
$ $
@ -229,7 +229,7 @@ added to the language which runs the preceding *pipeline* as a coprocess
(This is another reason not to use the special `|&` pipe operator in (This is another reason not to use the special `|&` pipe operator in
Bash \-- its syntax is conflicting). The `-p` option to the `read` and Bash \-- its syntax is conflicting). The `-p` option to the `read` and
`print` builtins can then be used to read and write to the pipe of the `print` builtins can then be used to read and write to the pipe of the
coprocess (whose FD isn\'t yet known). Special redirects are added to coprocess (whose FD isn't yet known). Special redirects are added to
move the last spawned coprocess to a different FD: `<&p` and `>&p`, at move the last spawned coprocess to a different FD: `<&p` and `>&p`, at
which point it can be accessed at the new FD using ordinary redirection, which point it can be accessed at the new FD using ordinary redirection,
and another coprocess may then be started, again using `|&`. and another coprocess may then be started, again using `|&`.

View File

@ -168,9 +168,9 @@ It was an unfortunate design decision to use the `!` prefix for
indirection, as it introduces parsing ambiguity with other parameter indirection, as it introduces parsing ambiguity with other parameter
expansions that begin with `!`. Indirection is not possible in expansions that begin with `!`. Indirection is not possible in
combination with any parameter expansion whose modifier requires a combination with any parameter expansion whose modifier requires a
prefix to the parameter name. Specifically, indirection isn\'t possible prefix to the parameter name. Specifically, indirection isn't possible
on the `${!var@}`, `${!var*}`, `${!var[@]}`, `${!var[*]}`, and `${#var}` on the `${!var@}`, `${!var*}`, `${!var[@]}`, `${!var[*]}`, and `${#var}`
forms. This means the `!` prefix can\'t be used to retrieve the indices forms. This means the `!` prefix can't be used to retrieve the indices
of an array, the length of a string, or number of elements in an array of an array, the length of a string, or number of elements in an array
indirectly (see [syntax/arrays#indirection](../syntax/arrays.md#indirection) indirectly (see [syntax/arrays#indirection](../syntax/arrays.md#indirection)
for workarounds). Additionally, the `!`-prefixed parameter expansion for workarounds). Additionally, the `!`-prefixed parameter expansion
@ -401,9 +401,9 @@ example string:
`Be liberal in what you accept, and conservativehappy in what you send` `Be liberal in what you accept, and conservativehappy in what you send`
Since there is only one \"conservative\" in that example, it really Since there is only one \"conservative\" in that example, it really
doesn\'t matter which of the two forms we use. doesn't matter which of the two forms we use.
Let's play with the word \"in\", I don\'t know if it makes any sense, Let's play with the word \"in\", I don't know if it makes any sense,
but let's substitute it with \"by\". but let's substitute it with \"by\".
[**First form: Substitute first occurrence**]{.underline} [**First form: Substitute first occurrence**]{.underline}
@ -491,7 +491,7 @@ Assume: `array=(This is a text)`
[**Attention:**]{.underline} The number of used elements does not need [**Attention:**]{.underline} The number of used elements does not need
to conform to the highest index. Sparse arrays are possible in Bash, to conform to the highest index. Sparse arrays are possible in Bash,
that means you can have 4 elements, but with indexes 1, 7, 20, 31. **You that means you can have 4 elements, but with indexes 1, 7, 20, 31. **You
can\'t loop through such an array with a counter loop based on the can't loop through such an array with a counter loop based on the
number of elements!** number of elements!**
## Substring expansion ## Substring expansion
@ -603,7 +603,7 @@ useful, you need to put that parameter syntax in.
read -p "Enter your gender (just press ENTER to not tell us): " GENDER read -p "Enter your gender (just press ENTER to not tell us): " GENDER
echo "Your gender is ${GENDER:-a secret}." echo "Your gender is ${GENDER:-a secret}."
It will print \"Your gender is a secret.\" when you don\'t enter the It will print \"Your gender is a secret.\" when you don't enter the
gender. Note that the default value is **used on expansion time**, it is gender. Note that the default value is **used on expansion time**, it is
**not assigned to the parameter**. **not assigned to the parameter**.
@ -802,7 +802,7 @@ Removing the first 6 characters from a text string:
- **Fixed in 4.2.36** - **Fixed in 4.2.36**
([patch](ftp://ftp.cwru.edu/pub/bash/bash-4.2-patches/bash42-036)). ([patch](ftp://ftp.cwru.edu/pub/bash/bash-4.2-patches/bash42-036)).
Bash doesn\'t follow either POSIX or its own documentation when Bash doesn't follow either POSIX or its own documentation when
expanding either a quoted `"$@"` or `"${arr[@]}"` with an adjacent expanding either a quoted `"$@"` or `"${arr[@]}"` with an adjacent
expansion. `"$@$x"` expands in the same way as `"$*$x"` - i.e. all expansion. `"$@$x"` expands in the same way as `"$*$x"` - i.e. all
parameters plus the adjacent expansion are concatenated into a parameters plus the adjacent expansion are concatenated into a
@ -857,7 +857,7 @@ Removing the first 6 characters from a text string:
`When `IFS` is set to a non-null value, or unset, all shells behave `When `IFS` is set to a non-null value, or unset, all shells behave
the same - first expanding into separate args, then applying the same - first expanding into separate args, then applying
pathname expansion and word-splitting to the results, except for pathname expansion and word-splitting to the results, except for
zsh, which doesn\'t do pathname expansion in its default mode. zsh, which doesn't do pathname expansion in its default mode.
```{=html} ```{=html}
<!-- --> <!-- -->
@ -884,7 +884,7 @@ Removing the first 6 characters from a text string:
ksh : <a> <b> <ca> <b> <c> <a b c> ksh : <a> <b> <ca> <b> <c> <a b c>
zsh : <a> <b> <ca> <b> <c> <a-b-c> zsh : <a> <b> <ca> <b> <c> <a-b-c>
`ksh93 and mksh can additionally achieve this side effect (and `ksh93 and mksh can additionally achieve this side effect (and
others) via the `${ cmds;}` expansion. I haven\'t yet tested every others) via the `${ cmds;}` expansion. I haven't yet tested every
possible side-effect that can affect expansion halfway through possible side-effect that can affect expansion halfway through
expansion that way. expansion that way.
@ -900,7 +900,7 @@ Removing the first 6 characters from a text string:
```{=html} ```{=html}
<!-- --> <!-- -->
``` ```
- Bash (and most other shells) don\'t allow .'s in identifiers. In - Bash (and most other shells) don't allow .'s in identifiers. In
ksh93, dots in variable names are used to reference methods (i.e. ksh93, dots in variable names are used to reference methods (i.e.
\"Discipline Functions\"), attributes, special shell variables, and \"Discipline Functions\"), attributes, special shell variables, and
to define the \"real value\" of an instance of a class. to define the \"real value\" of an instance of a class.
@ -920,7 +920,7 @@ Removing the first 6 characters from a text string:
- Bash only evaluates the subscripts of the slice expansion - Bash only evaluates the subscripts of the slice expansion
(`${x:y:z}`) if the parameter is set (for both nested expansions and (`${x:y:z}`) if the parameter is set (for both nested expansions and
arithmetic). For ranges, Bash evaluates as little as possible, i.e., arithmetic). For ranges, Bash evaluates as little as possible, i.e.,
if the first part is out of range, the second won\'t be evaluated. if the first part is out of range, the second won't be evaluated.
ksh93 and mksh always evaluate the subscript parts even if the ksh93 and mksh always evaluate the subscript parts even if the
parameter is unset. parameter is unset.
` $ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=(); echo "${x[@]:n,6:m}"' # No output ` $ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=(); echo "${x[@]:n,6:m}"' # No output

View File

@ -43,7 +43,7 @@ backslash:
echo \$HOME is set to \"$HOME\" echo \$HOME is set to \"$HOME\"
- `\$HOME` won\'t expand because it's not in variable-expansion - `\$HOME` won't expand because it's not in variable-expansion
syntax anymore syntax anymore
- The backslash changes the quotes into literals - otherwise Bash - The backslash changes the quotes into literals - otherwise Bash
would interpret them would interpret them
@ -112,7 +112,7 @@ single-quote that closes the string.
echo 'Your PATH is: $PATH' echo 'Your PATH is: $PATH'
`$PATH` won\'t be expanded, it's interpreted as ordinary text because `$PATH` won't be expanded, it's interpreted as ordinary text because
it's surrounded by strong quotes. it's surrounded by strong quotes.
In practise that means, to produce a text like `Here's my test...` as a In practise that means, to produce a text like `Here's my test...` as a
@ -259,8 +259,8 @@ Now the command has three parameters, which makes sense for a binary
(two argument) operator. (two argument) operator.
**[Hint:]{.underline}** Inside the [conditional **[Hint:]{.underline}** Inside the [conditional
expression](../syntax/ccmd/conditional_expression.md) (`[[ ]]`) Bash doesn\'t expression](../syntax/ccmd/conditional_expression.md) (`[[ ]]`) Bash doesn't
perform word splitting, and thus you don\'t need to quote your variable perform word splitting, and thus you don't need to quote your variable
references - they are always seen as \"one word\". references - they are always seen as \"one word\".
## See also ## See also

View File

@ -883,7 +883,7 @@ the history list:
--------------- ------------------------------------------------------------------------------------------------------------ --------------- ------------------------------------------------------------------------------------------------------------
`ignorespace` lines which begin with a space character are not saved in the history list `ignorespace` lines which begin with a space character are not saved in the history list
`ignoredups` don\'t save lines matching the previous history entry `ignoredups` don't save lines matching the previous history entry
`ignoreboth` short for `ignorespace:ignoredups` `ignoreboth` short for `ignorespace:ignoredups`
`erasedups` remove all previous lines matching the current line from the history list before the current line is saved `erasedups` remove all previous lines matching the current line from the history list before the current line is saved
--------------- ------------------------------------------------------------------------------------------------------------ --------------- ------------------------------------------------------------------------------------------------------------

View File

@ -22,7 +22,7 @@ by a space. When you enter an echo command at the Bash prompt, Bash will
look for those special characters, and use them to separate the look for those special characters, and use them to separate the
parameters. parameters.
You don\'t know what I\'m talking about? I\'m talking about this: You don't know what I\'m talking about? I\'m talking about this:
$ echo Hello little world $ echo Hello little world
Hello little world Hello little world
@ -40,7 +40,7 @@ Bash splits the command line at the blanks into words, then it calls
echo with **each word as an argument**. In this example, echo is called echo with **each word as an argument**. In this example, echo is called
with three arguments: \"`Hello`\", \"`little`\" and \"`world`\"! with three arguments: \"`Hello`\", \"`little`\" and \"`world`\"!
[Does that mean we can\'t echo more than one Space?]{.underline} Of [Does that mean we can't echo more than one Space?]{.underline} Of
course not! Bash treats blanks as special characters, but there are two course not! Bash treats blanks as special characters, but there are two
ways to tell Bash not to treat them special: **Escaping** and ways to tell Bash not to treat them special: **Escaping** and
**quoting**. **quoting**.
@ -56,7 +56,7 @@ None of the escaped spaces will be used to perform word splitting. Thus,
echo is called with one argument: \"`Hello little world`\". echo is called with one argument: \"`Hello little world`\".
Bash has a mechanism to \"escape\" an entire string: **Quoting**. In the Bash has a mechanism to \"escape\" an entire string: **Quoting**. In the
context of command-splitting, which this section is about, it doesn\'t context of command-splitting, which this section is about, it doesn't
matter which kind of quoting you use: weak quoting or strong quoting, matter which kind of quoting you use: weak quoting or strong quoting,
both cause Bash to not treat spaces as special characters: both cause Bash to not treat spaces as special characters: