` and a variable name `` is given, then the
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]
-
+!!! 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
-expansion](../../syntax/expansion/globs.md) to occur**.
+ Example: You are in a directory with a file named `x1`, and you want to
+ read into an array `x`, index `1` with
-Example: You are in a directory with a file named `x1`, and you want to
-read into an array `x`, index `1` with
+ read x[1]
- 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
-processing!
+ Even worse, if `nullglob` is set, your array/index will disappear.
-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
-array name and index:
-
- read 'x[1]'
-
-
+ read 'x[1]'
### Return status
- Status Reason
- -------- ---------------------------------------------------
- 0 no error
- 0 error when assigning to a read-only variable [^1]
- 2 invalid option
- >128 timeout (see `-t`)
- !=0 invalid filedescriptor supplied to `-u`
- !=0 end-of-file reached
+|Status|Reason|
+|------|------|
+|0|no error|
+|0|error when assigning to a read-only variable [^1]|
+|2|invalid option|
+|>128|timeout (see `-t`)|
+|!=0|invalid filedescriptor supplied to `-u`|
+|!=0|end-of-file reached|
### read without -r
diff --git a/docs/dict/exit_status.md b/docs/dict/exit_status.md
index fdc3390..9d041fc 100644
--- a/docs/dict/exit_status.md
+++ b/docs/dict/exit_status.md
@@ -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
purposes, like reporting a termination by a signal:
- Code Description
- --------- ------------------------------------------------------------------------------------------------------------------------------------------------------------
- 0 success
- 1-255 failure (in general)
- 126 the requested command (file) can't be executed (but was 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 + 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)
+|Code|Description|
+|----|-----------|
+|0|success|
+|1-255|failure (in general)|
+|126|the requested command (file) can't be executed (but was 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+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)|
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**
@@ -56,85 +56,51 @@ negation (`! pipeline`).
### Misc
- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 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
- ----------------------------------------------------------------------------------------------------- -------- --------- --------------- ----------------- ---------------- ------- --------- ---------- -----------
- `` :; : `false` `echo $? >&2` `` 1 1 1 1 0 0 0 0 1
+|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|
+|--|--|--|--|--|--|--|--|--|--|
+|:; : \`false\` \`echo $? >&2\`
|1|1|1|1|0|0|0|0|1|
+|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|-|
+|false; :| echo $?
[discussion](https://lists.gnu.org/archive/html/bug-bash/2010-09/msg00009.html)|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|
- `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
Measuring side-effects during the function call, during return, and
transparency of the return builtin.
- -------------------------------------------------------------------------------------------------------------------------------------------
- test bash bash\ zsh\ ksh93 mksh posh dash busybox heirloom
- (POSIX) (emulate ksh)
- -------------------------------------------------------- ------ --------- --------------- ------- ------ ------ ------ --------- ----------
- `` f() { echo $?; }; :; f `false` `` 1 1 1 1 0 0 0 0 1
-
- `f() { return; }; false; f; echo $?` 1 1 1 0 1 1 1 1 1
-
- `f() { return $?; }; false; f; echo $?` 1 1 1 1 1 1 1 1 1
-
- `f() { ! return; }; f; echo $?` 0 0 1 0 0 0 1 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
- -------------------------------------------------------------------------------------------------------------------------------------------
+|test|bash|bash
(POSIX)|zsh
(emulate ksh)|ksh93|mksh|posh|dash|busybox|heirloom
+|--|--|--|--|--|--|--|--|--|--|
+|f() { echo $?; }; :; f \`false\`
|1|1|1|1|0|0|0|0|1|
+|f() { return; }; false; f; echo $?
|1|1|1|0|1|1|1|1|1|
+|f() { return $?; }; false; f; echo $?
|1|1|1|1|1|1|1|1|1|
+|f() { ! return; }; f; echo $?
|0|0|1|0|0|0|1|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
Statuses measured within the command and after, with matching and
non-matching patterns.
- -------------------------------------------------------------------------------------------------------------------------------------------------
- test bash bash\ zsh\ ksh93 mksh posh dash busybox heirloom
- (POSIX) (emulate ksh)
- -------------------------------------------------------------- ------ --------- --------------- ------- ------ ------ ------ --------- ----------
- `(exit 2); case x in x) echo $?;; esac` 2 2 0 2 2 2 0 0 2
-
- `` (exit 2); case `exit 3`x in x) echo $?;; esac `` 3 3 0 3 2 2 0 0 3
-
- `` (exit 2); case x in `exit 4`x) echo $?;; esac `` 4 4 4 4 2 2 0 0 4
-
- `` (exit 2); case `exit 3`x in `exit 4`x) echo $?;; esac `` 4 4 4 4 2 2 0 0 4
-
- `(exit 2); case x in x);; esac; echo $?` 0 0 0 0 0 0 0 0 2
-
- `(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
- -------------------------------------------------------------------------------------------------------------------------------------------------
+|test|bash|bash
(POSIX)|zsh
(emulate ksh)|ksh93|mksh|posh|dash|busybox|heirloom|
+|--|--|--|--|--|--|--|--|--|--|
+|(exit 2); case x in x) echo $?;; esac
|2|2|0|2|2|2|0|0|2|
+| (exit 2); case \`exit 3\`x in x) echo $?;; esac
|3|3|0|3|2|2|0|0|3|
+| (exit 2); case x in \`exit 4\`x) echo $?;; esac
|4|4|4|4|2|2|0|0|4|
+| (exit 2); case \`exit 3\`x in \`exit 4\`x) echo $?;; esac
|4|4|4|4|2|2|0|0|4|
+|(exit 2); case x in x);; esac; echo $?
|0|0|0|0|0|0|0|0|2|
+|(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|
diff --git a/docs/howto/mutex.md b/docs/howto/mutex.md
index a765882..211356b 100644
--- a/docs/howto/mutex.md
+++ b/docs/howto/mutex.md
@@ -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
to set the timestamp.
- **Conclusion:** We need an
-operation that does the check and the locking in one step.
+!!! NOTE ""
+ **Conclusion:** 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
mkdir command. It will:
diff --git a/docs/howto/pax.md b/docs/howto/pax.md
index af15f57..4b52c37 100644
--- a/docs/howto/pax.md
+++ b/docs/howto/pax.md
@@ -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`
command line options:
- Mode RW-Options
- ------- -----------------
- List *no RW-options*
- Read `-r`
- Write `-w`
- Copy `-r -w`
+|Mode|RW-Options|
+|----|----------|
+|List|*no RW-options*|
+|Read|`-r`|
+|Write|`-w`|
+|Copy|`-r -w`|
#### List
@@ -99,14 +99,14 @@ creates `ustar` if no options are specified).
The following archive formats are supported (Berkeley implementation):
- --------- ----------------------------
- ustar POSIX TAR format (default)
- cpio POSIX CPIO format
- tar classic BSD TAR format
- bcpio old binary CPIO format
- sv4cpio SVR4 CPIO format
- sv4crc SVR4 CPIO format with CRC
- --------- ----------------------------
+| | |
+|--|--|
+|ustar|POSIX TAR format (default)|
+|cpio|POSIX CPIO format|
+|tar|classic BSD TAR format|
+|bcpio|old binary CPIO format|
+|sv4cpio|SVR4 CPIO format|
+|sv4crc|SVR4 CPIO format with CRC|
Berkeley `pax` supports options `-z` and `-j`, similar to GNU `tar`, to
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
make the switch:
- TAR PAX Notes
- ------------------------------------- ------------------------------------------ -----------------------------------------------------------------------
- `tar xzvf file.tar.gz` `pax -rvz -f file.tar.gz` `-z` is an extension, POSIXly: `gunzip archive.tar.gz`
- `tar xjvf file.tar.bz2` `bunzip2 archive.tar.bz2`
- `tar tzvf file.tar.gz` `pax -vz -f file.tar.gz` `-z` is an extension, POSIXly: `gunzip archive.tar.gz`|
+|`tar xjvf file.tar.bz2`|`bunzip2 archive.tar.bz2`|
+|`tar tzvf file.tar.gz`|`pax -vz -f file.tar.gz`|`-z` is an extension, POSIXly: `gunzip **Attention:**When the
-specified interpreter is unavailable or not executable (permissions),
-you usually get a "`bad interpreter`" error message., If you get
-nothing and it fails, check the shebang. Older Bash versions will
-respond with a "`no such file or directory`" error for a nonexistant
-interpreter specified by the shebang.
+!!! WARNING
+ **Attention:**When the
+ specified interpreter is unavailable or not executable (permissions),
+ you usually get a "`bad interpreter`" error message., If you get
+ nothing and it fails, check the shebang. Older Bash versions will
+ 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
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
list!):
- ---------------- ------------- ---------------- --------------- ------------------ -----------------
- `BASH` `BASH_ARGC` `BASH_ARGV` `BASH_LINENO` `BASH_SOURCE` `BASH_VERSINFO`
- `BASH_VERSION` `COLUMNS` `DIRSTACK` `DISPLAY` `EDITOR` `EUID`
- `GROUPS` `HISTFILE` `HISTFILESIZE` `HISTSIZE` `HOME` `HOSTNAME`
- `IFS` `LANG` `LANGUAGE` `LC_ALL` `LINES` `LOGNAME`
- `LS_COLORS` `MACHTYPE` `MAILCHECK` `OLDPWD` `OPTERR` `OPTIND`
- `OSTYPE` `PATH` `PIPESTATUS` `PPID` `PROMPT_COMMAND` `PS1`
- `PS2` `PS4` `PS3` `PWD` `SHELL` `SHELLOPTS`
- `SHLVL` `TERM` `UID` `USER` `USERNAME` `XAUTHORITY`
- ---------------- ------------- ---------------- --------------- ------------------ -----------------
+| | | | | | |
+|--|--|--|--|--|--|
+|`BASH`|`BASH_ARGC`|`BASH_ARGV`|`BASH_LINENO`|`BASH_SOURCE`|`BASH_VERSINFO`|
+|`BASH_VERSION`|`COLUMNS`|`DIRSTACK`|`DISPLAY`|`EDITOR`|`EUID`|
+|`GROUPS`|`HISTFILE`|`HISTFILESIZE`|`HISTSIZE`|`HOME`|`HOSTNAME`|
+|`IFS`|`LANG`|`LANGUAGE`|`LC_ALL`|`LINES`|`LOGNAME`|
+|`LS_COLORS`|`MACHTYPE`|`MAILCHECK`|`OLDPWD`|`OPTERR`|`OPTIND`|
+|`OSTYPE`|`PATH`|`PIPESTATUS`|`PPID`|`PROMPT_COMMAND`|`PS1`|
+|`PS2`|`PS4`|`PS3`|`PWD`|`SHELL`|`SHELLOPTS`|
+|`SHLVL`|`TERM`|`UID`|`USER`|`USERNAME`|`XAUTHORITY`|
This list is incomplete. **The safest way is to use all-lowercase
variable names.**
diff --git a/docs/scripting/newbie_traps.md b/docs/scripting/newbie_traps.md
index 3705471..ea80acc 100644
--- a/docs/scripting/newbie_traps.md
+++ b/docs/scripting/newbie_traps.md
@@ -116,7 +116,7 @@ for example
When you need the **content** of a variable, you prefix its name with
**a dollar-sign**, like
-- echo \"The used picture is: \$picture\"
+ echo "The used picture is: $picture"
#### Whitespace
@@ -154,12 +154,12 @@ Let's define an example variable containing text with spaces:
example="Hello world"
- Used form result number of words
- -------------- --------------- -----------------
- `$example` `Hello world` 2
- `"$example"` `Hello world` 1
- `\$example` `$example` 1
- `'$example'` `$example` 1
+|Used form|result|number of words|
+|---------|------|---------------|
+|`$example`|`Hello world`|2|
+|`"$example"`|`Hello world`|1|
+|`\$example`|`$example`|1|
+|`'$example'`|`$example`|1|
If you use parameter expansion, you **must** use the **name** (`PATH`)
of the referenced variables/parameters. i.e. **not** (`$PATH`):
diff --git a/docs/scripting/terminalcodes.md b/docs/scripting/terminalcodes.md
index 96c1996..bf73621 100644
--- a/docs/scripting/terminalcodes.md
+++ b/docs/scripting/terminalcodes.md
@@ -89,37 +89,23 @@ terminals.
### Cursor handling
- -------------------------------------------------------------------------------------------------------------------------------
- ANSI terminfo equivalent Description
- ----------------------------------------- --------------------- ---------------------------------------------------------------
- `[ ; H`\ `cup ` Home-positioning to `X` and `Y` coordinates\
- `[ ; f` :!: it seems that ANSI uses 1-1 as home while `tput` uses 0-0
-
- `[ H` `home` Move cursor to home position (0-0)
-
- `7` `sc` Save current cursor position
-
- `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
- -------------------------------------------------------------------------------------------------------------------------------
+|ANSI | terminfo equivalent | Description |
+|----------------------------------------|---------------------|-------------|
+|`[ ; H`
`[ ; f`|`cup `|Home-positioning to `X` and `Y` coordinates
:!: it seems that ANSI uses 1-1 as home while `tput` uses 0-0|
+|`[ H`|`home`|Move cursor to home position (0-0)|
+|`7`|`sc`|Save current cursor position|
+|`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
- ------------------------------------------------------------------------------------------------
- ANSI terminfo equivalent Description
- --------- --------------------- ----------------------------------------------------------------
- `[ K`\ `el` **Clear line** from current cursor position **to end** of line
- `[ 0 K`
-
- `[ 1 K` `el1` **Clear line from beginning** to current cursor position
-
- `[ 2 K` `el2`:?: **Clear whole line** (cursor position unchanged)
- ------------------------------------------------------------------------------------------------
+|ANSI |terminfo equivalent |Description|
+|---------|---------------------|-----------|
+|`[ K`
`[ 0 K`|`el`|**Clear line** from current cursor position **to end** of line|
+|`[ 1 K`|`el1`|**Clear line from beginning** to current cursor position|
+|`[ 2 K`|`el2` :?:|**Clear whole line** (cursor position unchanged)|
### General text attributes
@@ -133,6 +119,7 @@ terminals.
|`[ 5 m`|`blink`|Set "blink" attribute|
|`[ 7 m`|`rev`|Set "reverse" attribute|
|`[ 8 m`|`invis`|Set "hidden" attribute|
+
### Foreground coloring
|ANSI|terminfo equivalent|Description|
diff --git a/docs/snipplets/awkcsv.md b/docs/snipplets/awkcsv.md
index bd1b9e9..b484c5d 100644
--- a/docs/snipplets/awkcsv.md
+++ b/docs/snipplets/awkcsv.md
@@ -1,10 +1,11 @@
+---
+tags:
+ - awk
+ - csv
+---
+
# 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.
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:
- -------- -----------------------------------------------
- `", "` matches the area between the datafields
- `^"` matches the area left of the first datafield
- `"$` matches the area right of the last data field
- -------- -----------------------------------------------
+| | |
+|--------|----------------------------------------------|
+|`", "` | matches the area between the datafields|
+|`^"` | 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 don't have a space after the commas).
diff --git a/docs/snipplets/wrapperargs.md b/docs/snipplets/wrapperargs.md
index 9078a70..3947ce3 100644
--- a/docs/snipplets/wrapperargs.md
+++ b/docs/snipplets/wrapperargs.md
@@ -1,15 +1,15 @@
+---
+tags:
+ - arguments
+ - quoting
+ - escape
+ - quote
+ - wrapper
+ - generate
+---
+
# 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
script that writes out another script the user or cron may start, for
example.
diff --git a/docs/syntax/pe.md b/docs/syntax/pe.md
index 9d90e47..803108f 100644
--- a/docs/syntax/pe.md
+++ b/docs/syntax/pe.md
@@ -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?
-- [Simple usage](#simple_usage)
+- [Simple usage](#simple-usage)
- `$PARAMETER`
- `${PARAMETER}`
- [Indirection](#indirection)
- `${!PARAMETER}`
-- [Case modification](#case_modification)
+- [Case modification](#case-modification)
- `${PARAMETER^}`
- `${PARAMETER^^}`
- `${PARAMETER,}`
- `${PARAMETER,,}`
- `${PARAMETER~}`
- `${PARAMETER~~}`
-- [Variable name expansion](#variable_name_expansion)
+- [Variable name expansion](#variable-name-expansion)
- `${!PREFIX*}`
- `${!PREFIX@}`
-- [Substring removal](#substring_removal) (also for **filename
+- [Substring removal](#substring-removal) (also for **filename
manipulation**!)
- `${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}`
- `${PARAMETER//PATTERN}`
-- [String length](#string_length)
+- [String length](#string-length)
- `${#PARAMETER}`
-- [Substring expansion](#substring_expansion)
+- [Substring expansion](#substring-expansion)
- `${PARAMETER:OFFSET}`
- `${PARAMETER:OFFSET:LENGTH}`
-- [Use a default value](#use_a_default_value)
+- [Use a default value](#use-a-default-value)
- `${PARAMETER:-WORD}`
- `${PARAMETER-WORD}`
-- [Assign a default value](#assign_a_default_value)
+- [Assign a default value](#assign-a-default-value)
- `${PARAMETER:=WORD}`
- `${PARAMETER=WORD}`
-- [Use an alternate value](#use_an_alternate_value)
+- [Use an alternate value](#use-an-alternate-value)
- `${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}`
@@ -226,14 +226,11 @@ The `^` operator modifies the first character to uppercase, the `,`
operator to lowercase. When using the double-form (`^^` and `,,`), all
characters are converted.
-
-
-The (**currently undocumented**) operators `~` and `~~` reverse the case
-of the given text (in `PARAMETER`).`~` reverses the case of first letter
-of words in the variable while `~~` reverses case for all. Thanks to
-`Bushmills` and `geirha` on the Freenode IRC channel for this finding.
-
-
+!!! INFO
+ The (**currently undocumented**) operators `~` and `~~` reverse the case
+ of the given text (in `PARAMETER`).`~` reverses the case of first letter
+ of words in the variable while `~~` reverses case for all. Thanks to
+ `Bushmills` and `geirha` on the Freenode IRC channel for this finding.
**Example: Rename all `*.txt` filenames to lowercase**
@@ -270,9 +267,8 @@ Assume: `array=(This is some Text)`
- => `This Is Some Text`
- `echo "${array[@]^^}"`
- => `THIS IS SOME TEXT`
-
- * ''echo "${array[2]^^}"''
- * => ''SOME''
+- `echo "${array[2]^^}"`
+ - => `SOME`
## 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~~,
remember it will be removed!):
- 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
+|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|
### 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
tries to match the pattern from the end of the string:
- 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~~
+|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~~|
The second form nullifies variables that begin with `in`, by working
from the end.
@@ -351,16 +347,16 @@ filename**. Just look at the following list with examples:
- **Get name without extension**
- `${FILENAME%.*}`
- - => `bash_hackers.txt`
+ - => bash_hackers.txt
- **Get extension**
- `${FILENAME##*.}`
- - => `bash_hackers.txt`
+ - => bash_hackers.txt
- **Get directory name**
- `${PATHNAME%/*}`
- - => `/home/bash/bash_hackers.txt`
+ - => /home/bash/bash_hackers.txt
- **Get filename**
- `${PATHNAME##*/}`
- - => `/home/bash/bash_hackers.txt`
+ - => /home/bash/bash_hackers.txt
These are the syntaxes for filenames with a single extension. Depending
on your needs, you might need to adjust shortest/longest match.
@@ -413,7 +409,7 @@ example string:
${MYSTRING//conservative/happy}
=>
-`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
doesn't matter which of the two forms we use.
@@ -425,14 +421,14 @@ but let's substitute it with "by".
${MYSTRING/in/by}
-=> `Be liberal inby what you accept, and conservative in what you send`
+Be liberal inby what you accept, and conservative by what you send
**Second form: Substitute all occurrences**
${MYSTRING//in/by}
=>
-`Be liberal inby what you accept, and conservative inby what you send`
+Be liberal inby what you accept, and conservative inby what you send
**Anchoring** Additionally you can "anchor" an
expression: A `#` (hashmark) will indicate that your expression is
@@ -536,7 +532,7 @@ that the offset 0 is the first character:
echo ${MYSTRING:35}
=>
-`Be liberal in what you accept, and conservative in what you send`
+Be liberal in what you accept, and conservative in what you send
### Using Offset and Length
@@ -545,7 +541,7 @@ In the second form we also give a length value:
echo ${MYSTRING:35:12}
=>
-`Be liberal in what you accept, and conservative in what you send`
+Be liberal in what you accept, and conservative in what you send
### Negative Offset Value
@@ -570,7 +566,7 @@ then:
echo "${MYSTRING:11:-17}"
=>
-`Be liberal in what you accept, and conservative in what you send`
+Be liberal in what you accept, and conservative in what you send
This works since Bash 4.2-alpha, see also
[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
single argument. As a workaround, each expansion needs to be quoted
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"
- `
+ ```
- Almost all shells disagree about the treatment of an unquoted `$@`,
`${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
duration of a command or two, and even fewer to expand `$@` and `$*`
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
echo "$sh"
"$sh" -s a 'b c' d \* " $@
echo
EOF
- ``bb
+ ```
+ ```
+ bb
dash
@@ -866,7 +868,8 @@ Removing the first 6 characters from a text string:
zsh
- `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
pathname expansion and word-splitting to the results, except for
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 way adjacent arguments are concatenated, when IFS is modified in
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"
"$sh" ' ${*}${IFS=}${*}${IFS:=-}"${*}"
echo
EOF
- ``bb :
+ ```
+ ```
+ bb :
dash:
bash:
posh:
mksh:
ksh :
zsh :
- `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
possible side-effect that can affect expansion halfway through
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.
ksh93 and mksh always evaluate the subscript parts even if the
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}"'
yo
$ 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
$ bash -c 'n="y[\$(printf yo >&2)1]" m="y[\$(printf jo >&2)1]"; x=12345; echo "${x:n,6:m}"'
yo
- `
+ ```
### Quote Nesting
@@ -937,26 +946,30 @@ Removing the first 6 characters from a text string:
expansion that expands to multiple words, and nesting such
expansions, not all combinations of nested quoting are possible.
- # Bash
- $ typeset -a a=(meh bleh blerg) b
- $ IFS=e
- $ 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.
-
- $ b=(meep beep)
- $ printf "<%s> " "${b[@]-"${a[@]}" "${a[@]}"}" "${b[@]-${a[@]} ${a[@]}}"; echo # Again no surprises. Outer quotes quote everything recursively.
-
+```
+# Bash
+ $ typeset -a a=(meh bleh blerg) b
+ $ IFS=e
+ $ 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.
+
+ $ b=(meep beep)
+ $ printf "<%s> " "${b[@]-"${a[@]}" "${a[@]}"}" "${b[@]-${a[@]} ${a[@]}}"; echo # Again no surprises. Outer quotes quote everything recursively.
+
+```
Now lets see what can happen if we leave the outside unquoted.
- # Bash
- $ typeset -a a=(meh bleh blerg) b
- $ IFS=e
- $ 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.
-
+```
+# Bash
+ $ typeset -a a=(meh bleh blerg) b
+ $ IFS=e
+ $ 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.
+
+```
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
diff --git a/docs/syntax/shellvars.md b/docs/syntax/shellvars.md
index 030bfcc..a21678f 100644
--- a/docs/syntax/shellvars.md
+++ b/docs/syntax/shellvars.md
@@ -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
follows:
- -------------------- ----------------------------------------
- BASH_VERSINFO\[0\] The major version number (the release)
- BASH_VERSINFO\[1\] The minor version number (the version)
- BASH_VERSINFO\[2\] The patch level
- BASH_VERSINFO\[3\] The build version
- BASH_VERSINFO\[4\] The release status (e.g., beta1)
- BASH_VERSINFO\[5\] The value of `MACHTYPE`
- -------------------- ----------------------------------------
+|--|--|
+|--|--|
+|BASH_VERSINFO\[0\]|The major version number (the release)|
+|BASH_VERSINFO\[1\]|The minor version number (the version)|
+|BASH_VERSINFO\[2\]|The patch level|
+|BASH_VERSINFO\[3\]|The build version|
+|BASH_VERSINFO\[4\]|The release status (e.g., beta1)|
+|BASH_VERSINFO\[5\]|The value of `MACHTYPE`|
### 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
attempted that caused a completion function to be called:
- ------- ---------------------------------------------------
- `TAB` normal completion
- `?` listing completions after successive tabs
- `!` listing alternatives on partial word completion
- `@` to list completions if the word is not unmodified
- `%` for menu completion
- ------- ---------------------------------------------------
+|--|--|
+|--|--|
+|`TAB`|normal completion|
+|`?`|listing completions after successive tabs|
+|`!`|listing alternatives on partial word completion|
+|`@`|to list completions if the word is not unmodified|
+|`%`|for menu completion|
!!! warning "FIXME"
where are the integer values?
@@ -1047,7 +1047,7 @@ selected with a variable starting with `LC_`.
### LC_ALL
| Variable: |`LC_ALL` |Since: |unknown|
- -------------- ----------------- ------------ ---------
+| -------------- |----------------- |------------ |---------|
| Type: |normal variable |Read-only: |no|
| Set by Bash: |no |Default: |n/a|
diff --git a/scripts/generate-diff-links.sh b/scripts/generate-diff-links.sh
new file mode 100755
index 0000000..f538fd6
--- /dev/null
+++ b/scripts/generate-diff-links.sh
@@ -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
+