Compare commits

..

8 Commits

Author SHA1 Message Date
Florian Köhler
6cfac9a69c
Merge pull request #20 from sahal/main
Some checks failed
Build and deploy to GitHub Pages / deploy (push) Has been cancelled
More table formatting fixes along with some extra formatting fixes for free
2024-11-13 13:03:00 +01:00
Sahal Ansari
2849f0ac0e added script to generate diff table for PRs. 2024-11-13 13:01:26 +01:00
Sahal Ansari
cea8224acf fix improper escape. 2024-11-13 13:01:26 +01:00
Sahal Ansari
130cf66693 updated remaining WRAP blocks with Mkdocs Admonitions 2024-11-13 13:01:26 +01:00
Sahal Ansari
738b13c314 formatting fixes for parameter expansion - my favorite article. 2024-11-13 13:01:26 +01:00
Sahal Ansari
991569619d missed some table formatting in last commit. 2024-11-13 13:01:26 +01:00
Florian Köhler
5fdf713d7a
Merge pull request #21 from sseering/main
Switch to using the standards format (requirements.txt) for Python deps.
2024-11-13 12:56:39 +01:00
Stefan Seering
113cbf9225
Switch to using the standards format (requirements.txt) for Python dependencies. 2024-11-05 12:02:29 +01:00
23 changed files with 398 additions and 420 deletions

View File

@ -11,7 +11,7 @@ To edit and develop locally install the following packages and run the built in
```bash ```bash
python3 -m venv env python3 -m venv env
source env/bin/activate source env/bin/activate
pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-awesome-pages-plugin mkdocs-minify-plugin pip install -r requirements.txt
mkdocs serve mkdocs serve
``` ```

View File

@ -26,11 +26,11 @@ is given or the shell is configured to do so (see the `-P` option of
### Options ### Options
Option Description |Option|Description|
-------- ---------------------------------------------------- |------|-----------|
`-L` Follow symbolic links (default) |`-L`|Follow symbolic links (default)|
`-P` Do not follow symbolic links |`-P`|Do not follow symbolic links|
`-@` Browse a file's extended attributed, if supported |`-@`|Browse a file's extended attributed, if supported|
### Exit status ### Exit status

View File

@ -30,54 +30,36 @@ tagged as obsolete.
Below, `[-+]X` indicates an attribute, use `-X` to set the attribute, Below, `[-+]X` indicates an attribute, use `-X` to set the attribute,
`+X` to remove it. `+X` to remove it.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |Option|Description|
Option Description |------|-----------|
--------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |`[-+]a`|make NAMEs indexed arrays (removing with `+a` is valid syntax, but leads to an error message)|
`[-+]a` make NAMEs indexed arrays (removing with `+a` is valid syntax, but leads to an error message) |`[-+]A`|make NAMEs associative arrays|
|`[-+]c`|**Undocumented** convert NAMEs to "capcase" on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with `-DCASEMOD_CAPCASE`|
`[-+]A` make NAMEs associative arrays |`-f`|restrict action or display to function names and definitions (removing with `+f` is valid syntax, but leads to an error message)|
|`-F`|restrict display to function names only (plus line number and source file when debugging)|
`[-+]c` **Undocumented** convert NAMEs to "capcase" on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with `-DCASEMOD_CAPCASE` |`-g`|create global variables when used in a shell function; otherwise ignored (by default, `declare` declares local scope variables when used in shell functions)|
|`[-+]i`|make NAMEs have the "integer" attribute|
`-f` restrict action or display to function names and definitions (removing with `+f` is valid syntax, but leads to an error message) |`[-+]l`|convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters)|
|`[-+]n`|make NAME a reference to the variable named by its value. Introduced in Bash 4.3-alpha. ''`${!NAME}`'' reveals the reference variable name, VALUE. Use `unset -n NAME` to unset the variable. (`unset -v NAME` unsets the VALUE variable.) Use `[[ -R NAME ]]` to test if NAME has been set to a VALUE, another variable's name.|
`-F` restrict display to function names only (plus line number and source file when debugging) |`-p`|display the attributes and value of each NAME|
|`[-+]r`|make NAMEs readonly (removing with `+r` is valid syntax, but not possible)|
`-g` create global variables when used in a shell function; otherwise ignored (by default, `declare` declares local scope variables when used in shell functions) |`[-+]t`|make NAMEs have the "trace" attribute (effective only for functions)|
|`[-+]u`|convert NAMEs to upper case on assignment (makes sure the variable contains only upper case letters)|
`[-+]i` make NAMEs have the "integer" attribute |`[-+]x`|make NAMEs exported|
`[-+]l` convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters)
`[-+]n` make NAME a reference to the variable named by its value. Introduced in Bash 4.3-alpha.
''`${!NAME}`'' reveals the reference variable name, VALUE.
Use `unset -n NAME` to unset the variable. (`unset -v NAME` unsets the VALUE variable.)
Use `[[ -R NAME ]]` to test if NAME has been set to a VALUE, another variable's name.
`-p` display the attributes and value of each NAME
`[-+]r` make NAMEs readonly (removing with `+r` is valid syntax, but not possible)
`[-+]t` make NAMEs have the "trace" attribute (effective only for functions)
`[-+]u` convert NAMEs to upper case on assignment (makes sure the variable contains only upper case letters)
`[-+]x` make NAMEs exported
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Return status ### Return status
Status Reason |Status|Reason|
-------- ---------------------------------------------------------------------------------------- |------|------|
0 no error |0|no error|
!= 0 invalid option |!= 0|invalid option|
!= 0 invalid variable name given |!= 0|invalid variable name given|
!= 0 attempt to **define** a function using `-f` |!= 0|attempt to **define** a function using `-f`|
!= 0 assignment to a readonly variable |!= 0|assignment to a readonly variable|
!= 0 removing the readonly-attribute from a readonly variable |!= 0|removing the readonly-attribute from a readonly variable|
!= 0 assignment to an array variable without the compound assignment syntax (`array=(...)`) |!= 0|assignment to an array variable without the compound assignment syntax (`array=(...)`)|
!= 0 attempt to use `+a` to "destroy" an array |!= 0|attempt to use `+a` to "destroy" an array|
!= 0 attemt to display a non-existent function with `-f` |!= 0|attemt to display a non-existent function with `-f`|
## Notes ## Notes

View File

@ -16,31 +16,31 @@ if given.
### Options ### Options
Option Description Option|Description|
-------- ---------------------------------------------------------------------------------------------------------------- ------|-----------|
`-n` The trailing newline is suppressed. |`-n`|The trailing newline is suppressed.|
`-e` Interpretation of the following backslash-escaped characters (below) is enabled. |`-e`|Interpretation of the following backslash-escaped characters (below) is enabled.|
`-E` Disables the interpretation of these escape characters, even on systems where they are interpreted by default. |`-E`|Disables the interpretation of these escape characters, even on systems where they are interpreted by default.|
### Escape sequences ### Escape sequences
Escape Description |Escape|Description|
-------------- --------------------------------------------------------------------------------------------------------------- |------|-----------|
`\a` alert (bell) |`\a`|alert (bell)|
`\b` backspace |`\b`|backspace|
`\c` suppress further output |`\c`|suppress further output|
`\e` |`\e`|
`\E` an escape character |`\E`|an escape character|
`\f` form feed |`\f`|form feed|
`\n` new line |`\n`|new line|
`\r` carriage return |`\r`|carriage return|
`\t` horizontal tab |`\t`|horizontal tab|
`\v` vertical tab |`\v`|vertical tab|
`\\` backslash |`\\`|backslash|
`\0nnn` the eight-bit character whose value is the octal value nnn (zero to three octal digits) |`\0nnn`|the eight-bit character whose value is the octal value nnn (zero to three octal digits)|
`\xHH` the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) |`\xHH`|the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)|
`\uHHHH` the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits) |`\uHHHH`|the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)|
`\UHHHHHHHH` the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits) |`\UHHHHHHHH`|the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)|
## Examples ## Examples

View File

@ -17,11 +17,11 @@ shell without executing any program.
### Options ### Options
Option Description |Option|Description|
----------- ---------------------------------------------------------------------------------------------------------------------- |------|-----------|
`-a NAME` Passes `NAME` as zeroth argument for the program to be executed |`-a NAME`|Passes `NAME` as zeroth argument for the program to be executed|
`-c` Execute the program with an empty (cleared) environment |`-c`|Execute the program with an empty (cleared) environment|
`-l` Prepends a dash (`-`) to the zeroth argument of the program to be executed, similar to what the `login` program does |`-l`|Prepends a dash (`-`) to the zeroth argument of the program to be executed, similar to what the `login` program does|
### Exit status ### Exit status

View File

@ -25,9 +25,9 @@ There are no options.
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|
-------- ---------------------------------------------------------------------------- |------|------|
255 invalid (e.g. non-numeric) argument - this staus is returned to the parent |255|invalid (e.g. non-numeric) argument - this staus is returned to the parent|
## Examples ## Examples

View File

@ -14,21 +14,21 @@ it.
### Options ### Options
Option Description |Option|Description|
-------- ------------------------------------------------------------------------------------------------------------ |------|-----------|
`-f` refer to shell functions |`-f`|refer to shell functions|
`-n` remove the export property from any referenced `NAME` |`-n`|remove the export property from any referenced `NAME`|
`-p` print all exported variables, with `-f`, print all exported functions - all in a format re-usable as input |`-p`|print all exported variables, with `-f`, print all exported functions - all in a format re-usable as input|
An argument of `--` disables further option processing. An argument of `--` disables further option processing.
### Return status ### Return status
Status Reason |Status|Reason|
-------- --------------------------- |------|------|
0 no error |0|no error|
!=0 invalid option |!=0|invalid option|
!=0 a given `NAME` is invalid |!=0|a given `NAME` is invalid|
## Examples ## Examples

View File

@ -32,22 +32,22 @@ external `kill` command of the operating system to
### Options ### Options
Option Description |Option|Description|
------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |------|-----------|
`-s SIGNAL` specifies the signal to send |`-s SIGNAL`|specifies the signal to send|
`-n SIGNALNUMBER` specifies the signal to send |`-n SIGNALNUMBER`|specifies the signal to send|
`-SIGNAL` specifies the signal to send |`-SIGNAL`|specifies the signal to send|
`-l [SIGNAL...]` Lists supported/known signal numbers and their symbolic name. If `SIGNAL` is given, only list this signal, translated (if a number is given the symbolic name is printed, and vice versa) |`-l [SIGNAL...]`|Lists supported/known signal numbers and their symbolic name. If `SIGNAL` is given, only list this signal, translated (if a number is given the symbolic name is printed, and vice versa)|
`-L [SIGNAL...]` Same as `-l [SIGNAL]` (compatiblity option) |`-L [SIGNAL...]`|Same as `-l [SIGNAL]` (compatiblity option)|
### Return status ### Return status
Status Reason |Status|Reason|
-------- ----------------------------------------------------------------------------------------------------- |------|------|
0 no error/success |0|no error/success|
!=0 invalid option |!=0|invalid option|
!=0 invalid signal specification |!=0|invalid signal specification|
!=0 error returned by the system function (e.g. insufficient permissions to send to a specific process) |!=0|error returned by the system function (e.g. insufficient permissions to send to a specific process)|
## Examples ## Examples

View File

@ -41,12 +41,13 @@ command](../../syntax/ccmd/arithmetic_eval.md):
$ echo "$a - $b - $?" $ echo "$a - $b - $?"
4 - 2 - 0 4 - 2 - 0
<WRAP info> Remember that inside arithmetic evaluation contexts, all !!! INFO ""
other expansions are processed as usual (from left-to-right), and the Remember that inside arithmetic evaluation contexts, all
resulting text is evaluated as an arithmetic expression. Arithmetic other expansions are processed as usual (from left-to-right), and the
already has a way to control precedence using parentheses, so it's very resulting text is evaluated as an arithmetic expression. Arithmetic
rare to need to nest arithmetic expansions within one another. It's already has a way to control precedence using parentheses, so it's very
used above only to illustrate how this precedence works. </WRAP> rare to need to nest arithmetic expansions within one another. It's
used above only to illustrate how this precedence works.
Unlike `((`, being a simple command `let` has its own environment. In Unlike `((`, being a simple command `let` has its own environment. In
Bash, built-ins that can set variables process any arithmetic under Bash, built-ins that can set variables process any arithmetic under

View File

@ -19,15 +19,15 @@ target array must be a "normal" integer indexed array.
`mapfile` returns success (0) unless an invalid option is given or the `mapfile` returns success (0) unless an invalid option is given or the
given array `ARRAY` is set readonly. given array `ARRAY` is set readonly.
Option Description |Option|Description|
--------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------- |------|-----------|
`-c QUANTUM` Specifies the number of lines that have to be read between every call to the callback specified with `-C`. The default QUANTUM is 5000 |`-c QUANTUM`|Specifies the number of lines that have to be read between every call to the callback specified with `-C`. The default QUANTUM is 5000|
`-C CALLBACK` Specifies a callback. The string `CALLBACK` can be any shell code, the index of the array that will be assigned, and the line is appended at evaluation time. |`-C CALLBACK`|Specifies a callback. The string `CALLBACK` can be any shell code, the index of the array that will be assigned, and the line is appended at evaluation time.|
`-n COUNT` Reads at most `COUNT` lines, then terminates. If `COUNT` is 0, then all lines are read (default). |`-n COUNT`|Reads at most `COUNT` lines, then terminates. If `COUNT` is 0, then all lines are read (default).|
`-O ORIGIN` Starts populating the given array `ARRAY` at the index `ORIGIN` rather than clearing it and starting at index 0. |`-O ORIGIN`|Starts populating the given array `ARRAY` at the index `ORIGIN` rather than clearing it and starting at index 0.|
`-s COUNT` Discards the first `COUNT` lines read. |`-s COUNT`|Discards the first `COUNT` lines read.|
`-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

View File

@ -20,17 +20,16 @@ If `<NAME...>` is given, the line is word-split using
`<NAME>`. The remaining words are all assigned to the last `<NAME>` if `<NAME>`. The remaining words are all assigned to the last `<NAME>` if
more words than variable names are present. more words than variable names are present.
<WRAP center round info 90%> If no `<NAME>` is given, the whole line !!! INFO
read (without performing word-splitting!) is assigned to the shell If no `<NAME>` is given, the whole line
variable [REPLY](../../syntax/shellvars.md#REPLY). Then, `REPLY` really contains read (without performing word-splitting!) is assigned to the shell
the line as it was read, without stripping pre- and postfix spaces and variable [REPLY](../../syntax/shellvars.md#REPLY). Then, `REPLY` really contains
other things! the line as it was read, without stripping pre- and postfix spaces and
other things!
while read -r; do while read -r; do
printf '"%s"\n' "$REPLY" printf '"%s"\n' "$REPLY"
done <<<" a line with prefix and postfix space " done <<<" a line with prefix and postfix space "
</WRAP>
If a timeout is given, or if the shell variable If a timeout is given, or if the shell variable
[TMOUT](../../syntax/shellvars.md#TMOUT) is set, it is counted from initially [TMOUT](../../syntax/shellvars.md#TMOUT) is set, it is counted from initially
@ -39,19 +38,19 @@ line is read). That means the timeout can occur during input, too.
### Options ### Options
Option Description |Option|Description|
---------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |------|-----------|
`-a <ARRAY>` read the data word-wise into the specified array `<ARRAY>` instead of normal variables |`-a <ARRAY>`|read the data word-wise into the specified array `<ARRAY>` instead of normal variables|
`-d <DELIM>` recognize `<DELIM>` as data-end, rather than `<newline>` |`-d <DELIM>`|recognize `<DELIM>` as data-end, rather than `<newline>`|
`-e` on interactive shells: use Bash's readline interface to read the data. Since version 5.1-alpha, this can also be used on specified file descriptors using `-u` |`-e`|on interactive shells: use Bash's readline interface to read the data. Since version 5.1-alpha, this can also be used on specified file descriptors using `-u`|
`-i <STRING>` preloads the input buffer with text from `<STRING>`, only works when Readline (`-e`) is used |`-i <STRING>`|preloads the input buffer with text from `<STRING>`, only works when Readline (`-e`) is used|
`-n <NCHARS>` reads `<NCHARS>` characters of input, then quits |`-n <NCHARS>`|reads `<NCHARS>` characters of input, then quits|
`-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)|
When both, `-a <ARRAY>` and a variable name `<NAME>` is given, then the When both, `-a <ARRAY>` and a variable name `<NAME>` is given, then the
array is set, but not the variable. array is set, but not the variable.
@ -61,38 +60,35 @@ Of course it's valid to set individual array elements without using
read MYARRAY[5] read MYARRAY[5]
<WRAP center round important 90%> !!! WARNING
Reading into array elements using the syntax above **may cause [pathname
expansion](../../syntax/expansion/globs.md) to occur**.
Reading into array elements using the syntax above **may cause [pathname Example: You are in a directory with a file named `x1`, and you want to
expansion](../../syntax/expansion/globs.md) to occur**. read into an array `x`, index `1` with
Example: You are in a directory with a file named `x1`, and you want to read x[1]
read into an array `x`, index `1` with
read x[1] then pathname expansion will expand to the filename `x1` and break your
processing!
then pathname expansion will expand to the filename `x1` and break your Even worse, if `nullglob` is set, your array/index will disappear.
processing!
Even worse, if `nullglob` is set, your array/index will disappear. To avoid this, either **disable pathname expansion** or **quote** the
array name and index:
To avoid this, either **disable pathname expansion** or **quote** the read 'x[1]'
array name and index:
read 'x[1]'
</WRAP>
### Return status ### Return status
Status Reason |Status|Reason|
-------- --------------------------------------------------- |------|------|
0 no error |0|no error|
0 error when assigning to a read-only variable [^1] |0|error when assigning to a read-only variable [^1]|
2 invalid option |2|invalid option|
>128 timeout (see `-t`) |>128|timeout (see `-t`)|
!=0 invalid filedescriptor supplied to `-u` |!=0|invalid filedescriptor supplied to `-u`|
!=0 end-of-file reached |!=0|end-of-file reached|
### read without -r ### read without -r

View File

@ -32,15 +32,15 @@ The code is a number between 0 and 255, where the part from 126 to 255
is reserved to be used by the Bash shell directly or for special is reserved to be used by the Bash shell directly or for special
purposes, like reporting a termination by a signal: purposes, like reporting a termination by a signal:
Code Description |Code|Description|
--------- ------------------------------------------------------------------------------------------------------------------------------------------------------------ |----|-----------|
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)|
The lower codes 0 to 125 are not reserved and may be used for whatever The lower codes 0 to 125 are not reserved and may be used for whatever
the program likes to report. A value of **0 means successful** the program likes to report. A value of **0 means successful**
@ -56,85 +56,51 @@ negation (`! pipeline`).
### Misc ### Misc
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |test|bash 4.2.45|bash (POSIX)|zsh 5.0.2 (emulate ksh)|ksh93 93v- 2013-03-18|mksh R44 2013/02/24|posh 0.11|dash 0.5.7.3|busybox 1.2.1|heirloom 050706|
test bash\ bash\ zsh 5.0.2\ ksh93\ mksh\ posh\ dash\ busybox\ heirloom\ |--|--|--|--|--|--|--|--|--|--|
4.2.45 (POSIX) (emulate ksh) 93v- 2013-03-18 R44 2013/02/24 0.11 0.5.7.3 1.2.1 050706 |<pre>:; : \`false\` \`echo $? >&2\`</pre>|1|1|1|1|0|0|0|0|1|
----------------------------------------------------------------------------------------------------- -------- --------- --------------- ----------------- ---------------- ------- --------- ---------- ----------- |<pre>false; eval; echo $?</pre>|0|0|0|0|0|1|0|1|0|
`` :; : `false` `echo $? >&2` `` 1 1 1 1 0 0 0 0 1 |<pre>x=\`false\` eval echo $?</pre>|1|1|1|1|0|0|0|0|1|
|<pre>eval echo \$? <&0\`false\`</pre>|1|1|1|1|0|0|0|0|1|
|<pre>while :; do ! break; done; echo $?</pre>|1|1|1|1|0|0|1|1|-|
|<pre>false; :| echo $?</pre><br>[discussion](https://lists.gnu.org/archive/html/bug-bash/2010-09/msg00009.html)|1|1|1|0|1|1|1|1|0|
|<pre>(exit 2); for x in "\`exit 3\`"; do echo $?; done</pre>|3|3|3|3|2|2|0|0|3|
`false; eval; echo $?` 0 0 0 0 0 1 0 1 0
`` x=`false` eval echo \$? `` 1 1 1 1 0 0 0 0 1
`` eval echo \$? <&0`false` `` 1 1 1 1 0 0 0 0 1
`while :; do ! break; done; echo $?` 1 1 1 1 0 0 1 1 -
[discussion](https://lists.gnu.org/archive/html/bug-bash/2010-09/msg00009.html)`false; : | echo $?` 1 1 1 0 1 1 1 1 0
`` (exit 2); for x in "`exit 3`"; do echo $?; done `` 3 3 3 3 2 2 0 0 3
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### functions ### functions
Measuring side-effects during the function call, during return, and Measuring side-effects during the function call, during return, and
transparency of the return builtin. transparency of the return builtin.
------------------------------------------------------------------------------------------------------------------------------------------- |test|bash|bash<br>(POSIX)|zsh<br>(emulate ksh)|ksh93|mksh|posh|dash|busybox|heirloom
test bash bash\ zsh\ ksh93 mksh posh dash busybox heirloom |--|--|--|--|--|--|--|--|--|--|
(POSIX) (emulate ksh) |<pre>f() { echo $?; }; :; f \`false\`</pre>|1|1|1|1|0|0|0|0|1|
-------------------------------------------------------- ------ --------- --------------- ------- ------ ------ ------ --------- ---------- |<pre>f() { return; }; false; f; echo $?</pre>|1|1|1|0|1|1|1|1|1|
`` f() { echo $?; }; :; f `false` `` 1 1 1 1 0 0 0 0 1 |<pre>f() { return $?; }; false; f; echo $?</pre>|1|1|1|1|1|1|1|1|1|
|<pre>f() { ! return; }; f; echo $?</pre>|0|0|1|0|0|0|1|1|-|
`f() { return; }; false; f; echo $?` 1 1 1 0 1 1 1 1 1 |<pre>f() { ! return; }; false; f; echo $?</pre>|1|1|0|0|1|1|0|0|-|
|<pre>f() { return; }; x=\`false\` f; echo $?</pre>|1|1|1|1|0|0|0|0|0|
`f() { return $?; }; false; f; echo $?` 1 1 1 1 1 1 1 1 1 |<pre>f() { return; }; f <&0\`false\`; echo $?</pre>|1|1|1|1|0|0|0|0|1|
|<pre>f() { x=\`false\` return; }; f; echo $?</pre>|1|1|1|0|0|0|0|0|1|
`f() { ! return; }; f; echo $?` 0 0 1 0 0 0 1 1 - |<pre>f() { return <&0\`false\`; }; f; echo $?</pre>|1|1|1|0|0|0|0|0|1|
|<pre>f() { x=\`false\` return <&0\`false\`; }; f; echo $?</pre>|1|1|1|1|0|0|0|0|1|
`f() { ! return; }; false; f; echo $?` 1 1 0 0 1 1 0 0 -
`` f() { return; }; x=`false` f; echo $? `` 1 1 1 1 0 0 0 0 0
`` f() { return; }; f <&0`false`; echo $? `` 1 1 1 1 0 0 0 0 1
`` f() { x=`false` return; }; f; echo $? `` 1 1 1 0 0 0 0 0 1
`` f() { return <&0`false`; }; f; echo $? `` 1 1 1 0 0 0 0 0 1
`` f() { x=`false` return <&0`false`; }; f; echo $? `` 1 1 1 1 0 0 0 0 1
-------------------------------------------------------------------------------------------------------------------------------------------
### case..esac ### case..esac
Statuses measured within the command and after, with matching and Statuses measured within the command and after, with matching and
non-matching patterns. non-matching patterns.
------------------------------------------------------------------------------------------------------------------------------------------------- |test|bash|bash<br>(POSIX)|zsh<br>(emulate ksh)|ksh93|mksh|posh|dash|busybox|heirloom|
test bash bash\ zsh\ ksh93 mksh posh dash busybox heirloom |--|--|--|--|--|--|--|--|--|--|
(POSIX) (emulate ksh) |<pre>(exit 2); case x in x) echo $?;; esac</pre>|2|2|0|2|2|2|0|0|2|
-------------------------------------------------------------- ------ --------- --------------- ------- ------ ------ ------ --------- ---------- |<pre> (exit 2); case \`exit 3\`x in x) echo $?;; esac</pre>|3|3|0|3|2|2|0|0|3|
`(exit 2); case x in x) echo $?;; esac` 2 2 0 2 2 2 0 0 2 |<pre> (exit 2); case x in \`exit 4\`x) echo $?;; esac</pre>|4|4|4|4|2|2|0|0|4|
|<pre> (exit 2); case \`exit 3\`x in \`exit 4\`x) echo $?;; esac</pre>|4|4|4|4|2|2|0|0|4|
`` (exit 2); case `exit 3`x in x) echo $?;; esac `` 3 3 0 3 2 2 0 0 3 |<pre>(exit 2); case x in x);; esac; echo $?</pre>|0|0|0|0|0|0|0|0|2|
|<pre>(exit 2); case x in "");; esac; echo $?</pre>|0|0|0|0|0|0|0|0|2|
`` (exit 2); case x in `exit 4`x) echo $?;; esac `` 4 4 4 4 2 2 0 0 4 |<pre>(exit 2); case \`exit 3\`x in x);; esac; echo $?</pre>|0|0|0|3|0|0|0|0|3|
|<pre>(exit 2); case \`exit 3\`x in "");; esac; echo $?</pre>|0|0|0|3|0|0|0|0|3|
`` (exit 2); case `exit 3`x in `exit 4`x) echo $?;; esac `` 4 4 4 4 2 2 0 0 4 |<pre>(exit 2); case x in \`exit 4\`x);; esac; echo $?</pre>|0|0|0|4|0|0|0|0|4|
|<pre>(exit 2); case x in \`exit 4\`);; esac; echo $?</pre>|0|0|4|4|0|0|0|0|4|
`(exit 2); case x in x);; esac; echo $?` 0 0 0 0 0 0 0 0 2 |<pre>(exit 2); case \`exit 3\`x in \`exit 4\`);; esac; echo $?</pre>|0|0|4|4|0|0|0|0|4|
|<pre> (exit 2); case \`exit 3\`x in \`exit 4\`x);; esac; echo $?</pre>|0|0|0|4|0|0|0|0|4|
`(exit 2); case x in "");; esac; echo $?` 0 0 0 0 0 0 0 0 2
`` (exit 2); case `exit 3`x in x);; esac; echo $? `` 0 0 0 3 0 0 0 0 3
`` (exit 2); case `exit 3`x in "");; esac; echo $? `` 0 0 0 3 0 0 0 0 3
`` (exit 2); case x in `exit 4`x);; esac; echo $? `` 0 0 0 4 0 0 0 0 4
`` (exit 2); case x in `exit 4`);; esac; echo $? `` 0 0 4 4 0 0 0 0 4
`` (exit 2); case `exit 3`x in `exit 4`);; esac; echo $? `` 0 0 4 4 0 0 0 0 4
`` (exit 2); case `exit 3`x in `exit 4`x);; esac; echo $? `` 0 0 0 4 0 0 0 0 4
-------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -61,8 +61,9 @@ 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
to set the timestamp. to set the timestamp.
<WRAP center round tip 60%> <u>**Conclusion:**</u> We need an !!! NOTE ""
operation that does the check and the locking in one step. </WRAP> <u>**Conclusion:**</u> We need an
operation that does the check and the locking in one step.
A simple way to get that is to create a **lock directory** - with the A simple way to get that is to create a **lock directory** - with the
mkdir command. It will: mkdir command. It will:

View File

@ -38,12 +38,12 @@ There are four basic operation modes to *list*, *read*, *write* and
*copy* archives. They're switched with combinations of `-r` and `-w` *copy* archives. They're switched with combinations of `-r` and `-w`
command line options: command line options:
Mode RW-Options |Mode|RW-Options|
------- ----------------- |----|----------|
List *no RW-options* |List|*no RW-options*|
Read `-r` |Read|`-r`|
Write `-w` |Write|`-w`|
Copy `-r -w` |Copy|`-r -w`|
#### List #### List
@ -99,14 +99,14 @@ creates `ustar` if no options are specified).
The following archive formats are supported (Berkeley implementation): The following archive formats are supported (Berkeley implementation):
--------- ---------------------------- | | |
ustar POSIX TAR format (default) |--|--|
cpio POSIX CPIO format |ustar|POSIX TAR format (default)|
tar classic BSD TAR format |cpio|POSIX CPIO format|
bcpio old binary CPIO format |tar|classic BSD TAR format|
sv4cpio SVR4 CPIO format |bcpio|old binary CPIO format|
sv4crc SVR4 CPIO format with CRC |sv4cpio|SVR4 CPIO format|
--------- ---------------------------- |sv4crc|SVR4 CPIO format with CRC|
Berkeley `pax` supports options `-z` and `-j`, similar to GNU `tar`, to Berkeley `pax` supports options `-z` and `-j`, similar to GNU `tar`, to
filter archive files through GZIP/BZIP2. filter archive files through GZIP/BZIP2.
@ -337,13 +337,13 @@ in your `~/.bashrc` can be useful :-D.
Here is a quick table comparing (GNU) `tar` and `pax` to help you to Here is a quick table comparing (GNU) `tar` and `pax` to help you to
make the switch: make the switch:
TAR PAX Notes |TAR|PAX|Notes|
------------------------------------- ------------------------------------------ ----------------------------------------------------------------------- |---|---|-----|
`tar xzvf file.tar.gz` `pax -rvz -f file.tar.gz` `-z` is an extension, POSIXly: `gunzip <file.tar.gz | pax -rv` |`tar xzvf file.tar.gz`|`pax -rvz -f file.tar.gz`|`-z` is an extension, POSIXly: `gunzip <file.tar.gz | pax -rv`|
`tar czvf archive.tar.gz path ...` `pax -wvz -f archive.tar.gz path ...` `-z` is an extension, POSIXly: `pax -wv path | gzip > archive.tar.gz` |`tar czvf archive.tar.gz path ...`|`pax -wvz -f archive.tar.gz path ...`|`-z` is an extension, POSIXly: `pax -wv path | gzip > archive.tar.gz`|
`tar xjvf file.tar.bz2` `bunzip2 <file.tar.bz2 | pax -rv` |`tar xjvf file.tar.bz2`|`bunzip2 <file.tar.bz2 | pax -rv`|
`tar cjvf archive.tar.bz2 path ...` `pax -wv path | bzip2 > archive.tar.bz2` |`tar cjvf archive.tar.bz2 path ...`|`pax -wv path | bzip2 > archive.tar.bz2`|
`tar tzvf file.tar.gz` `pax -vz -f file.tar.gz` `-z` is an extension, POSIXly: `gunzip <file.tar.gz | pax -v` |`tar tzvf file.tar.gz`|`pax -vz -f file.tar.gz`|`-z` is an extension, POSIXly: `gunzip <file.tar.gz | pax -v`|
`pax` might not create ustar (`tar`) archives by default but its own pax `pax` might not create ustar (`tar`) archives by default but its own pax
format, add `-x ustar` if you want to ensure pax creates tar archives! format, add `-x ustar` if you want to ensure pax creates tar archives!

View File

@ -69,12 +69,13 @@ 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%> <u>**Attention:**</u>When the !!! WARNING
specified interpreter is unavailable or not executable (permissions), <u>**Attention:**</u>When the
you usually get a "`bad interpreter`" error message., If you get specified interpreter is unavailable or not executable (permissions),
nothing and it fails, check the shebang. Older Bash versions will you usually get a "`bad interpreter`" error message., If you get
respond with a "`no such file or directory`" error for a nonexistant nothing and it fails, check the shebang. Older Bash versions will
interpreter specified by the shebang. </WRAP> respond with a "`no such file or directory`" error for a nonexistant
interpreter specified by the shebang.
**Additional note:** When you specify `#!/bin/sh` as shebang and that's **Additional note:** When you specify `#!/bin/sh` as shebang and that's
a link to a Bash, then Bash will run in POSIX(r) mode! See: a link to a Bash, then Bash will run in POSIX(r) mode! See:
@ -130,16 +131,16 @@ and system-variable names are usually all in UPPERCASE. However, you
should avoid naming your variables any of the following (incomplete should avoid naming your variables any of the following (incomplete
list!): list!):
---------------- ------------- ---------------- --------------- ------------------ ----------------- | | | | | | |
`BASH` `BASH_ARGC` `BASH_ARGV` `BASH_LINENO` `BASH_SOURCE` `BASH_VERSINFO` |--|--|--|--|--|--|
`BASH_VERSION` `COLUMNS` `DIRSTACK` `DISPLAY` `EDITOR` `EUID` |`BASH`|`BASH_ARGC`|`BASH_ARGV`|`BASH_LINENO`|`BASH_SOURCE`|`BASH_VERSINFO`|
`GROUPS` `HISTFILE` `HISTFILESIZE` `HISTSIZE` `HOME` `HOSTNAME` |`BASH_VERSION`|`COLUMNS`|`DIRSTACK`|`DISPLAY`|`EDITOR`|`EUID`|
`IFS` `LANG` `LANGUAGE` `LC_ALL` `LINES` `LOGNAME` |`GROUPS`|`HISTFILE`|`HISTFILESIZE`|`HISTSIZE`|`HOME`|`HOSTNAME`|
`LS_COLORS` `MACHTYPE` `MAILCHECK` `OLDPWD` `OPTERR` `OPTIND` |`IFS`|`LANG`|`LANGUAGE`|`LC_ALL`|`LINES`|`LOGNAME`|
`OSTYPE` `PATH` `PIPESTATUS` `PPID` `PROMPT_COMMAND` `PS1` |`LS_COLORS`|`MACHTYPE`|`MAILCHECK`|`OLDPWD`|`OPTERR`|`OPTIND`|
`PS2` `PS4` `PS3` `PWD` `SHELL` `SHELLOPTS` |`OSTYPE`|`PATH`|`PIPESTATUS`|`PPID`|`PROMPT_COMMAND`|`PS1`|
`SHLVL` `TERM` `UID` `USER` `USERNAME` `XAUTHORITY` |`PS2`|`PS4`|`PS3`|`PWD`|`SHELL`|`SHELLOPTS`|
---------------- ------------- ---------------- --------------- ------------------ ----------------- |`SHLVL`|`TERM`|`UID`|`USER`|`USERNAME`|`XAUTHORITY`|
This list is incomplete. **The safest way is to use all-lowercase This list is incomplete. **The safest way is to use all-lowercase
variable names.** variable names.**

View File

@ -116,7 +116,7 @@ for example
When you need the **content** of a variable, you prefix its name with When you need the **content** of a variable, you prefix its name with
**a dollar-sign**, like **a dollar-sign**, like
- echo \"The used picture is: \$picture\" echo "The used picture is: $picture"
#### Whitespace #### Whitespace
@ -154,12 +154,12 @@ Let's define an example variable containing text with spaces:
example="Hello world" example="Hello world"
Used form result number of words |Used form|result|number of words|
-------------- --------------- ----------------- |---------|------|---------------|
`$example` `Hello world` 2 |`$example`|`Hello world`|2|
`"$example"` `Hello world` 1 |`"$example"`|`Hello world`|1|
`\$example` `$example` 1 |`\$example`|`$example`|1|
`'$example'` `$example` 1 |`'$example'`|`$example`|1|
If you use parameter expansion, you **must** use the **name** (`PATH`) If you use parameter expansion, you **must** use the **name** (`PATH`)
of the referenced variables/parameters. i.e. **not** (`$PATH`): of the referenced variables/parameters. i.e. **not** (`$PATH`):

View File

@ -89,37 +89,23 @@ terminals.
### Cursor handling ### Cursor handling
------------------------------------------------------------------------------------------------------------------------------- |ANSI | terminfo equivalent | Description |
ANSI terminfo equivalent Description |----------------------------------------|---------------------|-------------|
----------------------------------------- --------------------- --------------------------------------------------------------- |`[ <X> ; <Y> H`<br>`[ <X> ; <Y> f`|`cup <X> <Y>`|Home-positioning to `X` and `Y` coordinates<br>:!: it seems that ANSI uses 1-1 as home while `tput` uses 0-0|
`[ <X> ; <Y> H`\ `cup <X> <Y>` Home-positioning to `X` and `Y` coordinates\ |`[ H`|`home`|Move cursor to home position (0-0)|
`[ <X> ; <Y> f` :!: it seems that ANSI uses 1-1 as home while `tput` uses 0-0 |`7`|`sc`|Save current cursor position|
|`8`|`rc`|Restore saved cursor position|
`[ H` `home` Move cursor to home position (0-0) |:?: most likely a normal code like `\b`|`cub1`|move left one space (backspace)|
|VT100 `[ ? 25 l`|`civis`|make cursor invisible|
`7` `sc` Save current cursor position |VT100 `[ ? 25 h`|`cvvis`|make cursor visible|
`8` `rc` Restore saved cursor position
:?: most likely a normal code like `\b` `cub1` move left one space (backspace)
VT100 `[ ? 25 l` `civis` make cursor invisible
VT100 `[ ? 25 h` `cvvis` make cursor visible
-------------------------------------------------------------------------------------------------------------------------------
### Erasing text ### Erasing text
------------------------------------------------------------------------------------------------ |ANSI |terminfo equivalent |Description|
ANSI terminfo equivalent Description |---------|---------------------|-----------|
--------- --------------------- ---------------------------------------------------------------- |`[ K`<br>`[ 0 K`|`el`|**Clear line** from current cursor position **to end** of line|
`[ K`\ `el` **Clear line** from current cursor position **to end** of line |`[ 1 K`|`el1`|**Clear line from beginning** to current cursor position|
`[ 0 K` |`[ 2 K`|`el2` :?:|**Clear whole line** (cursor position unchanged)|
`[ 1 K` `el1` **Clear line from beginning** to current cursor position
`[ 2 K` `el2`:?: **Clear whole line** (cursor position unchanged)
------------------------------------------------------------------------------------------------
### General text attributes ### General text attributes
@ -133,6 +119,7 @@ terminals.
|`[ 5 m`|`blink`|Set "blink" attribute| |`[ 5 m`|`blink`|Set "blink" attribute|
|`[ 7 m`|`rev`|Set "reverse" attribute| |`[ 7 m`|`rev`|Set "reverse" attribute|
|`[ 8 m`|`invis`|Set "hidden" attribute| |`[ 8 m`|`invis`|Set "hidden" attribute|
### Foreground coloring ### Foreground coloring
|ANSI|terminfo equivalent|Description| |ANSI|terminfo equivalent|Description|

View File

@ -1,10 +1,11 @@
---
tags:
- awk
- csv
---
# Using `awk` to deal with CSV that uses quoted/unquoted delimiters # Using `awk` to deal with CSV that uses quoted/unquoted delimiters
---- dataentry snipplet ---- snipplet_tags : awk, csv
LastUpdate_dt : 2010-07-31 Contributors : SiegX (IRC) type : snipplet
------------------------------------------------------------------------
CSV files are a mess, yes. CSV files are a mess, yes.
Assume you have CSV files that use the comma as delimiter and quoted Assume you have CSV files that use the comma as delimiter and quoted
@ -21,11 +22,11 @@ Solution: Use the field separator `", "|^"|"$` for `awk`.
This is an OR-ed list of 3 possible separators: This is an OR-ed list of 3 possible separators:
-------- ----------------------------------------------- | | |
`", "` matches the area between the datafields |--------|----------------------------------------------|
`^"` matches the area left of the first datafield |`", "` | matches the area between the datafields|
`"$` matches the area right of the last data field |`^"` | matches the area left of the first datafield|
-------- ----------------------------------------------- |`"$` | matches the area right of the last data field|
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).

View File

@ -1,15 +1,15 @@
---
tags:
- arguments
- quoting
- escape
- quote
- wrapper
- generate
---
# Generate code with own arguments properly quoted # Generate code with own arguments properly quoted
---- dataentry snipplet ---- snipplet_tags: arguments, quoting,
escaping, wrapper LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
type: snipplet
------------------------------------------------------------------------
Keywords: arguments,escape,quote,wrapper,generate
-------------- -----------------------------------------
Contributor: self
There are situations where Bash code needs to generate Bash code. A There are situations where Bash code needs to generate Bash code. A
script that writes out another script the user or cron may start, for script that writes out another script the user or cron may start, for
example. example.

View File

@ -52,47 +52,47 @@ For a more technical view what a parameter is and which types exist,
Looking for a specific syntax you saw, without knowing the name? Looking for a specific syntax you saw, without knowing the name?
- [Simple usage](#simple_usage) - [Simple usage](#simple-usage)
- `$PARAMETER` - `$PARAMETER`
- `${PARAMETER}` - `${PARAMETER}`
- [Indirection](#indirection) - [Indirection](#indirection)
- `${!PARAMETER}` - `${!PARAMETER}`
- [Case modification](#case_modification) - [Case modification](#case-modification)
- `${PARAMETER^}` - `${PARAMETER^}`
- `${PARAMETER^^}` - `${PARAMETER^^}`
- `${PARAMETER,}` - `${PARAMETER,}`
- `${PARAMETER,,}` - `${PARAMETER,,}`
- `${PARAMETER~}` - `${PARAMETER~}`
- `${PARAMETER~~}` - `${PARAMETER~~}`
- [Variable name expansion](#variable_name_expansion) - [Variable name expansion](#variable-name-expansion)
- `${!PREFIX*}` - `${!PREFIX*}`
- `${!PREFIX@}` - `${!PREFIX@}`
- [Substring removal](#substring_removal) (also for **filename - [Substring removal](#substring-removal) (also for **filename
manipulation**!) manipulation**!)
- `${PARAMETER#PATTERN}` - `${PARAMETER#PATTERN}`
- `${PARAMETER##PATTERN}` - `${PARAMETER##PATTERN}`
- `${PARAMETER%PATTERN}` - `${PARAMETER%PATTERN}`
- `${PARAMETER%%PATTERN}` - `${PARAMETER%%PATTERN}`
- [Search and replace](#search_and_replace) - [Search and replace](#search-and-replace)
- `${PARAMETER/PATTERN/STRING}` - `${PARAMETER/PATTERN/STRING}`
- `${PARAMETER//PATTERN/STRING}` - `${PARAMETER//PATTERN/STRING}`
- `${PARAMETER/PATTERN}` - `${PARAMETER/PATTERN}`
- `${PARAMETER//PATTERN}` - `${PARAMETER//PATTERN}`
- [String length](#string_length) - [String length](#string-length)
- `${#PARAMETER}` - `${#PARAMETER}`
- [Substring expansion](#substring_expansion) - [Substring expansion](#substring-expansion)
- `${PARAMETER:OFFSET}` - `${PARAMETER:OFFSET}`
- `${PARAMETER:OFFSET:LENGTH}` - `${PARAMETER:OFFSET:LENGTH}`
- [Use a default value](#use_a_default_value) - [Use a default value](#use-a-default-value)
- `${PARAMETER:-WORD}` - `${PARAMETER:-WORD}`
- `${PARAMETER-WORD}` - `${PARAMETER-WORD}`
- [Assign a default value](#assign_a_default_value) - [Assign a default value](#assign-a-default-value)
- `${PARAMETER:=WORD}` - `${PARAMETER:=WORD}`
- `${PARAMETER=WORD}` - `${PARAMETER=WORD}`
- [Use an alternate value](#use_an_alternate_value) - [Use an alternate value](#use-an-alternate-value)
- `${PARAMETER:+WORD}` - `${PARAMETER:+WORD}`
- `${PARAMETER+WORD}` - `${PARAMETER+WORD}`
- [Display error if null or unset](#display_error_if_null_or_unset) - [Display error if null or unset](#display-error-if-null-or-unset)
- `${PARAMETER:?WORD}` - `${PARAMETER:?WORD}`
- `${PARAMETER?WORD}` - `${PARAMETER?WORD}`
@ -226,14 +226,11 @@ The `^` operator modifies the first character to uppercase, the `,`
operator to lowercase. When using the double-form (`^^` and `,,`), all operator to lowercase. When using the double-form (`^^` and `,,`), all
characters are converted. characters are converted.
<wrap center round info 60%> !!! INFO
The (**currently undocumented**) operators `~` and `~~` reverse the case
The (**currently undocumented**) operators `~` and `~~` reverse the case of the given text (in `PARAMETER`).`~` reverses the case of first letter
of the given text (in `PARAMETER`).`~` reverses the case of first letter of words in the variable while `~~` reverses case for all. Thanks to
of words in the variable while `~~` reverses case for all. Thanks to `Bushmills` and `geirha` on the Freenode IRC channel for this finding.
`Bushmills` and `geirha` on the Freenode IRC channel for this finding.
</wrap>
<u>**Example: Rename all `*.txt` filenames to lowercase**</u> <u>**Example: Rename all `*.txt` filenames to lowercase**</u>
@ -270,9 +267,8 @@ Assume: `array=(This is some Text)`
- => `This Is Some Text` - => `This Is Some Text`
- `echo "${array[@]^^}"` - `echo "${array[@]^^}"`
- => `THIS IS SOME TEXT` - => `THIS IS SOME TEXT`
- `echo "${array[2]^^}"`
* ''echo "${array[2]^^}"'' - => `SOME`
* => ''SOME''
## Variable name expansion ## Variable name expansion
@ -322,10 +318,10 @@ will try to remove the shortest text matching the pattern, while
following examples to get the idea (matched text ~~marked striked~~, following examples to get the idea (matched text ~~marked striked~~,
remember it will be removed!): remember it will be removed!):
Syntax Result |Syntax|Result|
-------------------- ---------------------------------------------------------------------- |------|------|
`${MYSTRING#*in}` ~~Be liberal in~~ what you accept, and conservative in what you send |`${MYSTRING#*in}`|~~Be liberal in~~ what you accept, and conservative in what you send|
`${MYSTRING##*in}` ~~Be liberal in what you accept, and conservative in~~ what you send |`${MYSTRING##*in}`|~~Be liberal in what you accept, and conservative in~~ what you send|
### From the end ### From the end
@ -334,10 +330,10 @@ remember it will be removed!):
In the second form everything will be the same, except that Bash now In the second form everything will be the same, except that Bash now
tries to match the pattern from the end of the string: tries to match the pattern from the end of the string:
Syntax Result |Syntax|Result|
-------------------- ---------------------------------------------------------------------- |------|------|
`${MYSTRING%in*}` Be liberal in what you accept, and conservative ~~in what you send~~ |`${MYSTRING%in*}`|Be liberal in what you accept, and conservative ~~in what you send~~|
`${MYSTRING%%in*}` Be liberal ~~in what you accept, and conservative in what you send~~ |`${MYSTRING%%in*}`|Be liberal ~~in what you accept, and conservative in what you send~~|
The second form nullifies variables that begin with `in`, by working The second form nullifies variables that begin with `in`, by working
from the end. from the end.
@ -351,16 +347,16 @@ filename**. Just look at the following list with examples:
- **Get name without extension** - **Get name without extension**
- `${FILENAME%.*}` - `${FILENAME%.*}`
- => `bash_hackers.txt` - => <code>bash_hackers<del>.txt</del></code>
- **Get extension** - **Get extension**
- `${FILENAME##*.}` - `${FILENAME##*.}`
- => `bash_hackers.txt` - => <code><del>bash_hackers.</del>txt</code>
- **Get directory name** - **Get directory name**
- `${PATHNAME%/*}` - `${PATHNAME%/*}`
- => `/home/bash/bash_hackers.txt` - => <code>/home/bash<del>/bash_hackers.txt</del></code>
- **Get filename** - **Get filename**
- `${PATHNAME##*/}` - `${PATHNAME##*/}`
- => `/home/bash/bash_hackers.txt` - => <code><del>/home/bash/</del>bash_hackers.txt</code>
These are the syntaxes for filenames with a single extension. Depending These are the syntaxes for filenames with a single extension. Depending
on your needs, you might need to adjust shortest/longest match. on your needs, you might need to adjust shortest/longest match.
@ -413,7 +409,7 @@ example string:
${MYSTRING//conservative/happy} ${MYSTRING//conservative/happy}
=> =>
`Be liberal in what you accept, and conservativehappy in what you send` <code>Be liberal in what you accept, and <del>conservative</del>happy in what you send</code>
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.
@ -425,14 +421,14 @@ but let's substitute it with "by".
${MYSTRING/in/by} ${MYSTRING/in/by}
=> `Be liberal inby what you accept, and conservative in what you send` <code>Be liberal <del>in</del>by what you accept, and conservative by what you send</code>
<u>**Second form: Substitute all occurrences**</u> <u>**Second form: Substitute all occurrences**</u>
${MYSTRING//in/by} ${MYSTRING//in/by}
=> =>
`Be liberal inby what you accept, and conservative inby what you send` <code>Be liberal <del>in</del>by what you accept, and conservative <del>in</del>by what you send</code>
<u>**Anchoring**</u> Additionally you can "anchor" an <u>**Anchoring**</u> Additionally you can "anchor" an
expression: A `#` (hashmark) will indicate that your expression is expression: A `#` (hashmark) will indicate that your expression is
@ -536,7 +532,7 @@ that the offset 0 is the first character:
echo ${MYSTRING:35} echo ${MYSTRING:35}
=> =>
`<del>Be liberal in what you accept, and </del>conservative in what you send` <code><del>Be liberal in what you accept, and </del>conservative in what you send</code>
### Using Offset and Length ### Using Offset and Length
@ -545,7 +541,7 @@ In the second form we also give a length value:
echo ${MYSTRING:35:12} echo ${MYSTRING:35:12}
=> =>
`<del>Be liberal in what you accept, and </del>conservative<del> in what you send</del>` <code><del>Be liberal in what you accept, and </del>conservative<del> in what you send</del></code>
### Negative Offset Value ### Negative Offset Value
@ -570,7 +566,7 @@ then:
echo "${MYSTRING:11:-17}" echo "${MYSTRING:11:-17}"
=> =>
`<del>Be liberal </del>in what you accept, and conservative<del> in what you send</del>` <code><del>Be liberal </del>in what you accept, and conservative<del> in what you send</del></code>
This works since Bash 4.2-alpha, see also This works since Bash 4.2-alpha, see also
[bashchanges](../scripting/bashchanges.md). [bashchanges](../scripting/bashchanges.md).
@ -823,9 +819,11 @@ Removing the first 6 characters from a text string:
parameters plus the adjacent expansion are concatenated into a parameters plus the adjacent expansion are concatenated into a
single argument. As a workaround, each expansion needs to be quoted single argument. As a workaround, each expansion needs to be quoted
separately. Unfortunately, this bug took a very long time to separately. Unfortunately, this bug took a very long time to
notice.`~ $ set -- a b c; x=foo; printf '<%s> ' "$@$x" "$*""$x" "$@""$x" notice.
```
~ $ set -- a b c; x=foo; printf '<%s> ' "$@$x" "$*""$x" "$@""$x"
<a b cfoo> <a b cfoo> <a> <b> <cfoo> <a b cfoo> <a b cfoo> <a> <b> <cfoo>
` ```
- Almost all shells disagree about the treatment of an unquoted `$@`, - Almost all shells disagree about the treatment of an unquoted `$@`,
`${arr[@]}`, `$*`, and `${arr[*]}` when `${arr[@]}`, `$*`, and `${arr[*]}` when
@ -836,7 +834,9 @@ Removing the first 6 characters from a text string:
are few good reasons to leave `IFS` set to null for more than the are few good reasons to leave `IFS` set to null for more than the
duration of a command or two, and even fewer to expand `$@` and `$*` duration of a command or two, and even fewer to expand `$@` and `$*`
unquoted, this should be a rare issue. **Always quote unquoted, this should be a rare issue. **Always quote
them**!`touch x 'y z' them**!
```
touch x 'y z'
for sh in bb {{d,b}a,{m,}k,z}sh; do for sh in bb {{d,b}a,{m,}k,z}sh; do
echo "$sh" echo "$sh"
"$sh" -s a 'b c' d \* </dev/fd/0 "$sh" -s a 'b c' d \* </dev/fd/0
@ -848,7 +848,9 @@ Removing the first 6 characters from a text string:
printf "<%s> " $@ printf "<%s> " $@
echo echo
EOF EOF
``bb ```
```
bb
<ab cd*> <ab cd*>
<ab cd*> <ab cd*>
dash dash
@ -866,7 +868,8 @@ Removing the first 6 characters from a text string:
zsh zsh
<a> <b c> <d> <x> <y z> <a> <b c> <d> <x> <y z>
<a> <b c> <d> <x> <y z> <a> <b c> <d> <x> <y z>
`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.
@ -875,7 +878,9 @@ Removing the first 6 characters from a text string:
the behavior of inserting delimiter characters from IFS in `$*`, and the behavior of inserting delimiter characters from IFS in `$*`, and
the way adjacent arguments are concatenated, when IFS is modified in the way adjacent arguments are concatenated, when IFS is modified in
the middle of expansion through the middle of expansion through
side-effects.`for sh in bb {{d,b}a,po,{m,}k,z}sh; do side-effects.
```
for sh in bb {{d,b}a,po,{m,}k,z}sh; do
printf '%-4s: ' "$sh" printf '%-4s: ' "$sh"
"$sh" </dev/fd/0 "$sh" </dev/fd/0
done <<\EOF done <<\EOF
@ -885,14 +890,17 @@ Removing the first 6 characters from a text string:
printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}" printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}"
echo echo
EOF EOF
``bb : <a b cabc> <a-b-c> ```
```
bb : <a b cabc> <a-b-c>
dash: <a b cabc> <a-b-c> dash: <a b cabc> <a-b-c>
bash: <a> <b> <ca> <b> <c-a b c> bash: <a> <b> <ca> <b> <c-a b c>
posh: <a> <b> <ca b c> <a-b-c> posh: <a> <b> <ca b c> <a-b-c>
mksh: <a> <b> <ca b c> <a-b-c> mksh: <a> <b> <ca b c> <a-b-c>
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.
@ -920,7 +928,8 @@ Removing the first 6 characters from a text string:
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
$ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=([5]=hi); echo "${x[@]:n,6:m}"' $ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=([5]=hi); echo "${x[@]:n,6:m}"'
yo yo
$ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=([6]=hi); echo "${x[@]:n,6:m}"' $ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=([6]=hi); echo "${x[@]:n,6:m}"'
@ -929,7 +938,7 @@ Removing the first 6 characters from a text string:
yojo yojo
$ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=12345; echo "${x:n,6:m}"' $ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=12345; echo "${x:n,6:m}"'
yo yo
` ```
### Quote Nesting ### Quote Nesting
@ -937,26 +946,30 @@ Removing the first 6 characters from a text string:
expansion that expands to multiple words, and nesting such expansion that expands to multiple words, and nesting such
expansions, not all combinations of nested quoting are possible. expansions, not all combinations of nested quoting are possible.
# Bash ```
$ typeset -a a=(meh bleh blerg) b # Bash
$ IFS=e $ typeset -a a=(meh bleh blerg) b
$ printf "<%s> " "${b[@]-"${a[@]}" "${a[@]}"}"; echo # The entire PE is quoted so Bash considers the inner quotes redundant. $ IFS=e
<meh> <bleh> <blerg meh> <bleh> <blerg> $ printf "<%s> " "${b[@]-"${a[@]}" "${a[@]}"}"; echo # The entire PE is quoted so Bash considers the inner quotes redundant.
$ printf "<%s> " "${b[@]-${a[@]} ${a[@]}}"; echo # The outer quotes cause the inner expansions to be considered quoted. <meh> <bleh> <blerg meh> <bleh> <blerg>
<meh> <bleh> <blerg meh> <bleh> <blerg> $ printf "<%s> " "${b[@]-${a[@]} ${a[@]}}"; echo # The outer quotes cause the inner expansions to be considered quoted.
$ b=(meep beep) <meh> <bleh> <blerg meh> <bleh> <blerg>
$ printf "<%s> " "${b[@]-"${a[@]}" "${a[@]}"}" "${b[@]-${a[@]} ${a[@]}}"; echo # Again no surprises. Outer quotes quote everything recursively. $ b=(meep beep)
<meep> <beep> <meep> <beep> $ printf "<%s> " "${b[@]-"${a[@]}" "${a[@]}"}" "${b[@]-${a[@]} ${a[@]}}"; echo # Again no surprises. Outer quotes quote everything recursively.
<meep> <beep> <meep> <beep>
```
Now lets see what can happen if we leave the outside unquoted. Now lets see what can happen if we leave the outside unquoted.
# Bash ```
$ typeset -a a=(meh bleh blerg) b # Bash
$ IFS=e $ typeset -a a=(meh bleh blerg) b
$ printf "<%s> " ${b[@]-"${a[@]}" "${a[@]}"}; echo # Inner quotes make inner expansions quoted. $ IFS=e
<meh> <bleh> <blerg meh> <bleh> <blerg> $ printf "<%s> " ${b[@]-"${a[@]}" "${a[@]}"}; echo # Inner quotes make inner expansions quoted.
$ printf "<%s> " ${b[@]-${a[@]} ${a[@]}}; echo' # No quotes at all wordsplits / globs, like you'd expect. <meh> <bleh> <blerg meh> <bleh> <blerg>
<m> <h> <bl> <h> <bl> <rg m> <h> <bl> <h> <bl> <rg> $ printf "<%s> " ${b[@]-${a[@]} ${a[@]}}; echo' # No quotes at all wordsplits / globs, like you'd expect.
<m> <h> <bl> <h> <bl> <rg m> <h> <bl> <h> <bl> <rg>
```
This all might be intuitive, and is the most common implementation, but This all might be intuitive, and is the most common implementation, but
this design sucks for a number of reasons. For one, it means Bash makes this design sucks for a number of reasons. For one, it means Bash makes

View File

@ -233,14 +233,14 @@ A readonly array variable whose members hold version information for
this instance of Bash. The values assigned to the array members are as this instance of Bash. The values assigned to the array members are as
follows: follows:
-------------------- ---------------------------------------- |--|--|
BASH_VERSINFO\[0\] The major version number (the release) |--|--|
BASH_VERSINFO\[1\] The minor version number (the version) |BASH_VERSINFO\[0\]|The major version number (the release)|
BASH_VERSINFO\[2\] The patch level |BASH_VERSINFO\[1\]|The minor version number (the version)|
BASH_VERSINFO\[3\] The build version |BASH_VERSINFO\[2\]|The patch level|
BASH_VERSINFO\[4\] The release status (e.g., beta1) |BASH_VERSINFO\[3\]|The build version|
BASH_VERSINFO\[5\] The value of `MACHTYPE` |BASH_VERSINFO\[4\]|The release status (e.g., beta1)|
-------------------- ---------------------------------------- |BASH_VERSINFO\[5\]|The value of `MACHTYPE`|
### BASH_VERSION ### BASH_VERSION
@ -316,13 +316,13 @@ current command, the value of this variable is equal to `${#COMP_LINE}`.
Set to an integer value corresponding to the type of completion Set to an integer value corresponding to the type of completion
attempted that caused a completion function to be called: attempted that caused a completion function to be called:
------- --------------------------------------------------- |--|--|
`TAB` normal completion |--|--|
`?` listing completions after successive tabs |`TAB`|normal completion|
`!` listing alternatives on partial word completion |`?`|listing completions after successive tabs|
`@` to list completions if the word is not unmodified |`!`|listing alternatives on partial word completion|
`%` for menu completion |`@`|to list completions if the word is not unmodified|
------- --------------------------------------------------- |`%`|for menu completion|
!!! warning "FIXME" !!! warning "FIXME"
where are the integer values? where are the integer values?
@ -1047,7 +1047,7 @@ selected with a variable starting with `LC_`.
### LC_ALL ### LC_ALL
| Variable: |`LC_ALL` |Since: |unknown| | Variable: |`LC_ALL` |Since: |unknown|
-------------- ----------------- ------------ --------- | -------------- |----------------- |------------ |---------|
| Type: |normal variable |Read-only: |no| | Type: |normal variable |Read-only: |no|
| Set by Bash: |no |Default: |n/a| | Set by Bash: |no |Default: |n/a|

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
mkdocs-material
mkdocs-git-revision-date-localized-plugin
mkdocs-awesome-pages-plugin
mkdocs-minify-plugin

26
scripts/generate-diff-links.sh Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
GIT_HASH="${1:-50aeb31ff80e7bdde9b8edd50ab924e3791fe606}"
BASE_LOCAL_URL="http://127.0.0.1:8000/bash-hackers-wiki/"
BASE_DEPLOY_URL="https://flokoe.github.io/bash-hackers-wiki/"
BASE_ARCHIVE_URL="https://web.archive.org/web/20230127020427/https://wiki.bash-hackers.org/"
# Table Headers
cat << EOF
|Filename|Local Version|Deployed Version|Archive Version|
|--|--|--|--|
EOF
for file in $(git show --name-only "${GIT_HASH}" | grep md$); do
filename_no_docs_prefix="${file#*docs/}"
filename_no_ext="${filename_no_docs_prefix%.*}"
echo "|"${filename_no_docs_prefix} \
"|[${filename_no_ext}](${BASE_LOCAL_URL}${filename_no_ext})" \
"|[${filename_no_ext}](${BASE_DEPLOY_URL}${filename_no_ext})" \
"|[${filename_no_ext}](${BASE_ARCHIVE_URL}${filename_no_ext})|"
done