diff --git a/docs/commands/builtin/caller.md b/docs/commands/builtin/caller.md index 2cca00a..844f0d1 100644 --- a/docs/commands/builtin/caller.md +++ b/docs/commands/builtin/caller.md @@ -8,7 +8,7 @@ The `caller` builtin command is used to print execution frames of subroutine calls. Without giving a framenumber, the topmost execution -frame information is printed (\"who called me\") wile linenumber and +frame information is printed ("who called me") wile linenumber and filename. When an execution frame number is given (0 - topmost), the linenumber, @@ -22,10 +22,10 @@ used in a loop (see the examples section below). The code below defines a function `die` that is used to exit the program. It prints a list of execution frames, starting with the topmost -frame (0). The topmost frame is the \"caller of the die function\", in -this case function \"f1\". +frame (0). The topmost frame is the "caller of the die function", in +this case function "f1". -This way, you can print a \"stack trace\" for debugging or logging +This way, you can print a "stack trace" for debugging or logging purposes. The code is made very simple, just to show the basic purposes. @@ -70,9 +70,9 @@ f3 [Bashdb](http://bashdb.sourceforge.net/) can assist in using some of Bash's more advanced debug features. - The Bash manpage and help text specifies that the argument to - `caller` is an \"expr\" (whatever that means). Only an integer is + `caller` is an "expr" (whatever that means). Only an integer is actually allowed, with no special interpretation of an - \"expression\" as far as we can tell. + "expression" as far as we can tell. ## Portability considerations diff --git a/docs/commands/builtin/declare.md b/docs/commands/builtin/declare.md index 440f181..e38b6c4 100644 --- a/docs/commands/builtin/declare.md +++ b/docs/commands/builtin/declare.md @@ -37,7 +37,7 @@ Below, `[-+]X` indicates an attribute, use `-X` to set the attribute, `[-+]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` + `[-+]c` **Undocumented** convert NAMEs to "capcase" on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with `-DCASEMOD_CAPCASE` `-f` restrict action or display to function names and definitions (removing with `+f` is valid syntax, but leads to an error message) @@ -45,20 +45,20 @@ Below, `[-+]X` indicates an attribute, use `-X` to set the attribute, `-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 + `[-+]i` make NAMEs have the "integer" attribute `[-+]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.)\ + `[-+]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) + `[-+]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) @@ -76,13 +76,13 @@ Below, `[-+]X` indicates an attribute, use `-X` to set the attribute, != 0 assignment to 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 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` ## Notes Unix shells offer very few datatypes. Bash and some other shells extend -this by allowing \"attributes\" to be set on variable names. The only +this by allowing "attributes" to be set on variable names. The only attributes specified by POSIX are `export` and `readonly`, which are set by their own dedicated builtins. Datatypes in bash have a few other interesting capabilities such as the ability to modify data on @@ -92,23 +92,23 @@ assignment. ### Display defined functions -`declare -f` can be used to display all defined functions\... +`declare -f` can be used to display all defined functions... $ declare -f - foo () - { + foo () + { echo "FOO is BAR" } - world () - { + world () + { echo "Hello World!" } -\...or just a specific defined function. +...or just a specific defined function. $ declare -f foo - foo () - { + foo () + { echo "FOO is BAR" } @@ -172,7 +172,7 @@ for details. ksh93 namerefs are much more powerful than Bash's. considers `typeset` a special builtin, while Bash does not - even in POSIX mode. If you use `typeset`, you should attempt to only use it in portable ways. -- **todo** nameref portability\... +- **todo** nameref portability... ## See also diff --git a/docs/commands/builtin/echo.md b/docs/commands/builtin/echo.md index e99d9a1..047bb0d 100644 --- a/docs/commands/builtin/echo.md +++ b/docs/commands/builtin/echo.md @@ -29,7 +29,7 @@ if given. `\a` alert (bell) `\b` backspace `\c` suppress further output - `\e` + `\e` `\E` an escape character `\f` form feed `\n` new line @@ -56,17 +56,14 @@ if given. case `-n` is always treated as a string, and backslash escapes are interpreted by default. `dash` has the misfeature of following this and interpreting escapes by default, but includes a `-n` feature for - suppressing newlines nevertheless.\ - \ - In practice, if you\'re able to assume a korn-like shell including + suppressing newlines nevertheless. + + In practice, if you're able to assume a korn-like shell including bash, mksh, or zsh, `echo` when used in simple cases is generally reliable. For example, in the very common situation in which echo is supplied with a single argument and whose output is to have a newline appended, using `echo` is considered common practice. -```{=html} - -``` - **Never use options to `echo`! *Ever*!** Any time you feel tempted to use `echo -e`, `-n`, or any other special feature of echo, **use [printf](../../commands/builtin/printf.md) instead!** If portability is a @@ -76,9 +73,6 @@ if given. \$\'\...\' \'\'if targeting only shells that support this special quoting style. -```{=html} - -``` - `ksh93` has a `print` command, which if coding specifically for `ksh93` should be preferred over `echo`. [printf](../../commands/builtin/printf.md) still includes most of the diff --git a/docs/commands/builtin/eval.md b/docs/commands/builtin/eval.md index ed97c0f..930b69e 100644 --- a/docs/commands/builtin/eval.md +++ b/docs/commands/builtin/eval.md @@ -55,7 +55,7 @@ This code defines a set of identical functions using the supplied names. ### Using printf %q The `printf %q` format string performs shell escaping on its arguments. -This makes `printf %q` the \"anti-eval\" - with each pass of a string +This makes `printf %q` the "anti-eval" - with each pass of a string through printf requiring another `eval` to peel off the escaping again. while (( ++n <= 5 )) || ! evalBall="eval $evalBall"; do @@ -112,16 +112,11 @@ controlled carefully by the caller is a good way to use it. `setopt POSIX_BUILTINS` -- looks like a regression). This works correctly in Bash POSIX mode, Dash, and mksh. -```{=html} - -``` - `eval` is another one of the few Bash builtins with keyword-like conditional parsing of arguments that are in the form of compound assignments. -```{=html} - -``` + $ ( eval a=( a b\\ c d ); printf '<%s> ' "${a[@]}"; echo ) # Only works in Bash. $ ( x=a; eval "$x"=( a b\\ c d ); printf '<%s> ' "${a[@]}"; echo ) # Argument is no longer in the form of a valid assignment, therefore ordinary parsing rules apply. @@ -168,7 +163,7 @@ identical to those of [let](../../commands/builtin/let.md). eval](http://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.2BAC8-reference_variables) - [More indirection via eval](http://fvue.nl/wiki/Bash:_Passing_variables_by_reference) -- [Martin Väth's \"push\"](https://github.com/vaeth/push) -- +- [Martin Väth's "push"](https://github.com/vaeth/push) -- `printf %q` work-alike for POSIX. -- [The \"magic alias\" +- [The "magic alias" hack](http://www.chiark.greenend.org.uk/~sgtatham/aliases.html) diff --git a/docs/commands/builtin/kill.md b/docs/commands/builtin/kill.md index da12b52..a534e1f 100644 --- a/docs/commands/builtin/kill.md +++ b/docs/commands/builtin/kill.md @@ -27,7 +27,7 @@ The `kill` command is a Bash builtin command instead of relying on the external `kill` command of the operating system to - be able to use shell job specifications instead of Unix process IDs -- be able to send signals (\"kill something\") also, when your process +- be able to send signals ("kill something") also, when your process limit is reached ### Options diff --git a/docs/commands/builtin/let.md b/docs/commands/builtin/let.md index 91db394..1d4f1ca 100644 --- a/docs/commands/builtin/let.md +++ b/docs/commands/builtin/let.md @@ -10,8 +10,8 @@ The `let` builtin command evaluates each supplied word from left to right as an [arithmetic expression](../../syntax/arith_expr.md) and returns an exit code according to the truth value of the rightmost expression. -- 0 (TRUE) when `arg` evaluated to not 0 (arithmetic \"true\") -- 1 (FALSE) when `arg` evaluated to 0 (arithmetic \"false\") +- 0 (TRUE) when `arg` evaluated to not 0 (arithmetic "true") +- 1 (FALSE) when `arg` evaluated to 0 (arithmetic "false") For this return code mapping, please see [this section](../../syntax/arith_expr.md#arithmetic_expressions_and_return_codes). @@ -50,7 +50,7 @@ used above only to illustrate how this precedence works. Unlike `((`, being a simple command `let` has its own environment. In Bash, built-ins that can set variables process any arithmetic under -their own environment, which makes the variable effectively \"local\" to +their own environment, which makes the variable effectively "local" to the builtin unless the variable is also set or modified by the builtin. This differs in other shells, such as ksh93, where environment assignments to regular builtins are always local even if the variable is @@ -84,7 +84,7 @@ needed. choose `let` over `((` expecting it to work in more places. - [expr(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html#tag_20_42) is a command one is likely to come across sooner or later. While it - is more \"standard\" than `let`, the above should always be + is more "standard" than `let`, the above should always be preferred. Both [arithmetic expansion](../../syntax/arith_expr.md)s and the `[` test operator are specified by POSIX(r) and satisfy almost all of expr's use-cases. Unlike `let`, `expr` cannot assign directly to @@ -108,4 +108,4 @@ needed. - Internal: [arithmetic evaluation compound command](../../syntax/ccmd/arithmetic_eval.md) -[^1]: \... +[^1]: ... diff --git a/docs/commands/builtin/local.md b/docs/commands/builtin/local.md index 0a15a30..bd63a4a 100644 --- a/docs/commands/builtin/local.md +++ b/docs/commands/builtin/local.md @@ -30,17 +30,11 @@ way, and takes all the same options, with 3 exceptions: have a builtin called `local`, but some such as `dash` and the busybox shell do. -```{=html} - -``` - The behavior of function scope is not defined by POSIX, however local variables are implemented widely by bourne-like shells, and behavior differs substantially. Even the`dash` shell has local variables. -```{=html} - -``` - In ksh93, using POSIX-style function definitions, `typeset` doesn't set `local` variables, but rather acts upon variables of the next-outermost scope (e.g. setting attributes). Using `typeset` @@ -48,8 +42,8 @@ way, and takes all the same options, with 3 exceptions: variables follow roughly [lexical-scoping](http://community.schemewiki.org/?lexical-scope), except that functions themselves don't have scope, just like Bash. - This means that even functions defined within a \"function's - scope\" don't have access to non-local variables except through + This means that even functions defined within a "function's + scope" don't have access to non-local variables except through `namerefs`. ## See also diff --git a/docs/commands/builtin/mapfile.md b/docs/commands/builtin/mapfile.md index fcad769..8f5108a 100644 --- a/docs/commands/builtin/mapfile.md +++ b/docs/commands/builtin/mapfile.md @@ -14,7 +14,7 @@ This builtin is also accessible using the command name `readarray`. handling standard input (the other being `read`). `mapfile` reads lines of standard input and assigns each to the elements of an indexed array. If no array name is given, the default array name is `MAPFILE`. The -target array must be a \"normal\" integer indexed array. +target array must be a "normal" integer indexed array. `mapfile` returns success (0) unless an invalid option is given or the given array `ARRAY` is set readonly. @@ -47,9 +47,9 @@ Here's a real-world example of interactive use borrowed from Gentoo workflow. Xorg updates require rebuilding drivers, and the Gentoo-suggested command is less than ideal, so let's Bashify it. The first command produces a list of packages, one per line. We can read -those into the array named \"args\" using `mapfile`, stripping trailing -newlines with the \'-t\' option. The resulting array is then expanded -into the arguments of the \"emerge\" command - an interface to Gentoo's +those into the array named "args" using `mapfile`, stripping trailing +newlines with the '`-t`' option. The resulting array is then expanded +into the arguments of the `emerge` command - an interface to Gentoo's package manager. This type of usage can make for a safe and effective replacement for xargs(1) in certain situations. Unlike xargs, all arguments are guaranteed to be passed to a single invocation of the @@ -59,7 +59,7 @@ business. # eix --only-names -IC x11-drivers | { mapfile -t args; emerge -av1 "${args[@]}" <&1; } Note the use of command grouping to keep the emerge command inside the -pipe's subshell and within the scope of \"args\". Also note the unusual +pipe's subshell and within the scope of "args". Also note the unusual redirection. This is because the -a flag makes emerge interactive, asking the user for confirmation before continuing, and checking with isatty(3) to abort if stdin isn't pointed at a terminal. Since stdin of @@ -71,11 +71,11 @@ wiki: ### The callback This is one of the more unusual features of a Bash builtin. As far as -I\'m able to tell, the exact behavior is as follows: If defined, as each +I'm able to tell, the exact behavior is as follows: If defined, as each line is read, the code contained within the string argument to the -C flag is evaluated and executed *before* the assignment of each array element. There are no restrictions to this string, which can be any -arbitrary code, however, two additional \"words\" are automatically +arbitrary code, however, two additional "words" are automatically appended to the end before evaluation: the index, and corresponding line of data to be assigned to the next array element. Since all this happens before assignment, the callback feature cannot be used to modify the @@ -91,9 +91,9 @@ the appended words from printf. Really, the intended usage is for the callback to just contain the name of a function, with the extra words passed to it as arguments. If -you\'re going to use callbacks at all, this is probably the best way -because it allows for easy access to the arguments with no ugly \"code -in a string\". +you're going to use callbacks at all, this is probably the best way +because it allows for easy access to the arguments with no ugly "code +in a string". $ foo() { echo "|$1|"; }; mapfile -n 11 -c 2 -C 'foo' \" for appending on each call by +Rather than opening "outfile<n>" for appending on each call by calculating the filename, open an FD for each first and calculate which FD to send output to by measuring the size of x mod 2. The zero-width format specification is used to absorb the index number argument. Another variation might be to add each of these lines to the elements of -separate arrays. I\'ll leave dissecting this one as an exercise for the +separate arrays. I'll leave dissecting this one as an exercise for the reader. This is quite the hack but illustrates some interesting properties of printf -v and mapfile -C (which you should probably never use in real code). @@ -147,7 +147,7 @@ use in real code). This example based on yet another #bash question illustrates mapfile in combination with read. The sample input is the heredoc to `main`. The -goal is to build a \"struct\" based upon records in the input file made +goal is to build a "struct" based upon records in the input file made up of the numbers following the colon on each line. Every 3rd line is a key followed by 2 corresponding fields. The showRecord function takes a key and returns the record. diff --git a/docs/commands/builtin/printf.md b/docs/commands/builtin/printf.md index 4292cb2..1007a19 100644 --- a/docs/commands/builtin/printf.md +++ b/docs/commands/builtin/printf.md @@ -1,19 +1,22 @@ # The printf command -
FIXME Stranger, this is a very big -topic that needs experience - please fill in missing information, extend -the descriptions, and correct the details if you can!
[**Attention:**]{.underline} This is about the -Bash-builtin command `printf` - however, the description should be -nearly identical for an external command that follows POSIX(r). +!!! warning "FIXME" + This is a very big topic that needs experience - please fill in + missing information, extend the descriptions, and correct the details + if you can! -[GNU Awk](http://www.gnu.org/software/gawk/manual/gawk.html#Printf) -expects a comma after the format string and between each of the -arguments of a **printf** command. For examples, see: [code -snippet](../../printf?&.md#using_printf_inside_of_awk).
+!!! info "Bash-Builtin" + This is about the Bash-builtin command `printf` - however, the + description should be nearly identical for an external command that + follows POSIX(r). + + [GNU Awk](http://www.gnu.org/software/gawk/manual/gawk.html#Printf) + expects a comma after the format string and between each of + the arguments of a **printf** command. For examples, see: [code + snippet](#differences-from-awk-printf). Unlike other documentations, I don't want to redirect you to the manual -page for the `printf()` C function family. However, if you\'re more +page for the `printf()` C function family. However, if you're more experienced, that should be the most detailed description for the format strings and modifiers. @@ -28,7 +31,7 @@ successor for `echo` and has far more features and possibilities. Beside other reasons, POSIX(r) has a very good argument to recommend it: Both historical main flavours of the `echo` command are mutual -exclusive, they collide. A \"new\" command had to be invented to solve +exclusive, they collide. A "new" command had to be invented to solve the issue. ## Syntax @@ -50,27 +53,28 @@ argument!). ### Options - ---------- ------------------------------------------------------------------------------------------------------------------------------- - `-v VAR` If given, the output is assigned to the variable `VAR` instead of printed to `stdout` (comparable to `sprintf()` in some way) - ---------- ------------------------------------------------------------------------------------------------------------------------------- +| Option | Description | +|--------|-------------| +|`-v VAR`|If given, the output is assigned to the variable `VAR` instead of printed to `stdout` (comparable to `sprintf()` in some way)| The `-v` Option can't assign directly to array indexes in Bash versions older than Bash 4.1. - In versions newer than 4.1, one must be careful when -performing expansions into the first non-option argument of printf as -this opens up the possibility of an easy code injection vulnerability. +!!! danger "Danger" + In versions newer than 4.1, one must be careful when + performing expansions into the first non-option argument of printf as + this opens up the possibility of an easy code injection vulnerability. - $ var='-vx[$(echo hi >&2)]'; printf "$var" hi; declare -p x - hi - declare -a x='([0]="hi")' + $ var='-vx[$(echo hi >&2)]'; printf "$var" hi; declare -p x + hi + declare -a x='([0]="hi")' -\...where the echo can of course be replaced with any arbitrary command. -If you must, either specify a hard-coded format string or use -- to -signal the end of options. The exact same issue also applies to -[read](../../commands/builtin/read.md), and a similar one to -[mapfile](../../commands/builtin/mapfile.md), though performing expansions into -their arguments is less common. + ...where the echo can of course be replaced with any arbitrary command. + If you must, either specify a hard-coded format string or use -- to + signal the end of options. The exact same issue also applies to + [read](../../commands/builtin/read.md), and a similar one to + [mapfile](../../commands/builtin/mapfile.md), though performing expansions into + their arguments is less common. ### Arguments @@ -78,16 +82,16 @@ Of course in shell-meaning the arguments are just strings, however, the common C-notations plus some additions for number-constants are recognized to give a number-argument to `printf`: - Number-Format Description - --------------- ------------------------------------------------------------------------------------------------------------------------ - `N` A normal decimal number - `0N` An octal number - `0xN` A hexadecimal number - `0XN` A hexadecimal number - `"X` (a literal double-quote infront of a character): interpreted as number (underlying codeset) **don't forget escaping** - `'X` (a literal single-quote infront of a character): interpreted as number (underlying codeset) **don't forget escaping** +| Number-Format | Description | +|----------------|--------------| +|`N`|A normal decimal number| +|`0N`|An octal number| +|`0xN`|A hexadecimal number| +|`0XN`|A hexadecimal number| +|`"X`|(a literal double-quote infront of a character): interpreted as number (underlying codeset) **don't forget escaping**| +|`'X`|(a literal single-quote infront of a character): interpreted as number (underlying codeset) **don't forget escaping**| -[**If more arguments than format specifiers**]{.underline} are present, +**If more arguments than format specifiers** are present, then the format string is re-used until the last argument is interpreted. If fewer format specifiers than arguments are present, then number-formats are set to zero, while string-formats are set to null @@ -97,15 +101,15 @@ Take care to avoid [word splitting](../../syntax/expansion/wordsplit.md), as accidentally passing the wrong number of arguments can produce wildly different and unexpected results. See [this article](../../syntax/words.md). - [**Again, attention:**]{.underline} When a numerical -format expects a number, the internal `printf`-command will use the -common Bash arithmetic rules regarding the base. A command like the -following example **will** throw an error, since `08` is not a valid -octal number (`00` to `07`!): +!!! danger "Attention" + When a numerical + format expects a number, the internal `printf`-command will use the + common Bash arithmetic rules regarding the base. A command like the + following example **will** throw an error, since `08` is not a valid + octal number (`00` to `07`!): - printf '%d\n' 08 + printf '%d\n' 08 - ### Format strings @@ -115,7 +119,7 @@ family. Only format specifiers that end in one of the letters To print a literal `%` (percent-sign), use `%%` in the format string. -[**Again:**]{.underline} Every format specifier expects an associated +**Again:** Every format specifier expects an associated argument provided! These specifiers have different names, depending who you ask. But they @@ -124,30 +128,30 @@ all mean the same: A placeholder for data with a specified format: - format placeholder - conversion specification - formatting token -- \... +- ... - Format Description - -------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `%b` Print the associated argument while interpreting backslash escapes in there - `%q` Print the associated argument **shell-quoted**, reusable as input - `%d` Print the associated argument as **signed decimal** number - `%i` Same as `%d` - `%o` Print the associated argument as **unsigned octal** number - `%u` Print the associated argument as **unsigned decimal** number - `%x` Print the associated argument as **unsigned hexadecimal** number with lower-case hex-digits (a-f) - `%X` Same as `%x`, but with upper-case hex-digits (A-F) - `%f` Interpret and print the associated argument as **floating point** number - `%e` Interpret the associated argument as **double**, and print it in `±e` format - `%E` Same as `%e`, but with an upper-case `E` in the printed format - `%g` Interprets the associated argument as **double**, but prints it like `%f` or `%e` - `%G` Same as `%g`, but print it like `%E` - `%c` Interprets the associated argument as **char**: only the first character of a given argument is printed - `%s` Interprets the associated argument literally as string - `%n` Assigns the number of characters printed so far to the variable named in the corresponding argument. Can't specify an array index. If the given name is already an array, the value is assigned to the zeroth element. - `%a` Interprets the associated argument as **double**, and prints it in the form of a C99 [hexadecimal floating-point literal](http://www.exploringbinary.com/hexadecimal-floating-point-constants/). - `%A` Same as `%a`, but print it like `%E` - `%(FORMAT)T` output the date-time string resulting from using `FORMAT` as a format string for `strftime(3)`. The associated argument is the number of seconds since Epoch, or `-1` (current time) or `-2` (shell startup time). If no corresponding argument is supplies, the current time is used as default - `%%` No conversion is done. Produces a `%` (percent sign) +| Format | Description | +|-------------|----------------| +|`%b`|Print the associated argument while interpreting backslash escapes in there| +|`%q`|Print the associated argument **shell-quoted**, reusable as input| +|`%d`|Print the associated argument as **signed decimal** number| +|`%i`|Same as `%d`| +|`%o`|Print the associated argument as **unsigned octal** number| +|`%u`|Print the associated argument as **unsigned decimal** number| +|`%x`|Print the associated argument as **unsigned hexadecimal** number with lower-case hex-digits (a-f)| +|`%X`|Same as `%x`, but with upper-case hex-digits (A-F)| +|`%f`|Interpret and print the associated argument as **floating point** number| +|`%e`|Interpret the associated argument as **double**, and print it in `±e` format +|`%E`|Same as `%e`, but with an upper-case `E` in the printed format| +|`%g`|Interprets the associated argument as **double**, but prints it like `%f` or `%e` +|`%G`|Same as `%g`, but print it like `%E`| +|`%c`|Interprets the associated argument as **char**: only the first character of a given argument is printed| +|`%s`|Interprets the associated argument literally as string| +|`%n`|Assigns the number of characters printed so far to the variable named in the corresponding argument. Can't specify an array index. If the given name is already an array, the value is assigned to the zeroth element.| +|`%a`|Interprets the associated argument as **double**, and prints it in the form of a C99 [hexadecimal floating-point literal](http://www.exploringbinary.com/hexadecimal-floating-point-constants/).| +|`%A`|Same as `%a`, but print it like `%E`| +|`%(FORMAT)T`|output the date-time string resulting from using `FORMAT` as a format string for `strftime(3)`. The associated argument is the number of seconds since Epoch, or `-1` (current time) or `-2` (shell startup time). If no corresponding argument is supplies, the current time is used as default| +|`%%`|No conversion is done. Produces a `%` (percent sign)| Some of the mentioned format specifiers can modify their behaviour by getting a format modifier: @@ -162,26 +166,26 @@ introductory `%` and the character that specifies the format: #### Field and printing modifiers - Field output format - --------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `` **Any number**: Specifies a **minimum field width**, if the text to print is shorter, it's padded with spaces, if the text is longer, the field is expanded - `.` **The dot**: Together with a field width, the field is **not** expanded when the text is longer, the text is truncated instead. \"`%.s`\" is an undocumented equivalent for \"`%.0s`\", which will force a field width of zero, effectively hiding the field from output - `*` **The asterisk**: the width is given as argument before the string or number. Usage (the \"`*`\" corresponds to the \"`20`\"): `printf "%*s\n" 20 "test string"` - `#` \"Alternative format\" for numbers: see table below - `-` **Left-bound** text printing in the field (standard is **right-bound**) - `0` Pads numbers with zeros, not spaces - `` Pad a positive number with a space, where a minus (`-`) is for negative numbers - `+` Prints all numbers **signed** (`+` for positive, `-` for negative) - `'` For decimal conversions, the thousands grouping separator is applied to the integer portion of the output according to the current LC_NUMERIC +|Field | output format| +|-------|-------------| +|``|**Any number**: Specifies a **minimum field width**, if the text to print is shorter, it's padded with spaces, if the text is longer, the field is expanded| +|`.`|**The dot**: Together with a field width, the field is **not** expanded when the text is longer, the text is truncated instead. "`%.s`" is an undocumented equivalent for "`%.0s`", which will force a field width of zero, effectively hiding the field from output| +|`*`|**The asterisk**: the width is given as argument before the string or number. Usage (the "`*`" corresponds to the "`20`"): `printf "%*s\n" 20 "test string"`| +|`#`|"Alternative format" for numbers: see table below| +|`-`|**Left-bound** text printing in the field (standard is **right-bound**)| +|`0`|Pads numbers with zeros, not spaces| +|``|Pad a positive number with a space, where a minus (`-`) is for negative numbers| +|`+`|Prints all numbers **signed** (`+` for positive, `-` for negative)| +|`'`|For decimal conversions, the thousands grouping separator is applied to the integer portion of the output according to the current LC_NUMERIC| -[**The \"alternative format\" modifier `#`:**]{.underline} +**The "alternative format" modifier `#`:** - Alternative Format - -------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------- - `%#o` The octal number is printed with a leading zero, unless it's zero itself - `%#x`, `%#X` The hex number is printed with a leading \"`0x`\"/\"`0X`\", unless it's zero - `%#g`, `%#G` The float number is printed with **trailing zeros** until the number of digits for the current precision is reached (usually trailing zeros are not printed) - all number formats except `%d`, `%o`, `%x`, `%X` Always print a decimal point in the output, even if no digits follow it +|Alternative|Format| +|-----------|------| +|`%#o`|The octal number is printed with a leading zero, unless it's zero itself| +|`%#x`, `%#X`|The hex number is printed with a leading "`0x`"/"`0X`", unless it's zero| +|`%#g`, `%#G`|The float number is printed with **trailing zeros** until the number of digits for the current precision is reached (usually trailing zeros are not printed)| +|all number formats except `%d`, `%o`, `%x`, `%X`|Always print a decimal point in the output, even if no digits follow it| #### Precision @@ -204,30 +208,30 @@ number of digits to print (zero-padding!). These are interpreted if used anywhere in the format string, or in an argument corresponding to a `%b` format. - Code Description - ---------------- --------------------------------------------------------------------------------------------------------------------------- - `\\` Prints the character `\` (backslash) - `\a` Prints the alert character (ASCII code 7 decimal) - `\b` Prints a backspace - `\f` Prints a form-feed - `\n` Prints a newline - `\r` Prints a carriage-return - `\t` Prints a horizontal tabulator - `\v` Prints a vertical tabulator - `\"` Prints a `'` - `\?` Prints a `?` - `` Interprets `` as **octal** number and prints the corresponding character from the character set - `\0` same as `` - `\x` Interprets `` as **hexadecimal** number and prints the corresponding character from the character set (**3 digits**) - `\u` same as `\x`, but **4 digits** - `\U` same as `\x`, but **8 digits** +|Code|Description| +|----|-----------| +|`\\`|Prints the character `\` (backslash)| +|`\a`|Prints the alert character (ASCII code 7 decimal)| +|`\b`|Prints a backspace| +|`\f`|Prints a form-feed| +|`\n`|Prints a newline| +|`\r`|Prints a carriage-return| +|`\t`|Prints a horizontal tabulator| +|`\v`|Prints a vertical tabulator| +|`\"`|Prints a `'`| +|`\?`|Prints a `?`| +|``|Interprets `` as **octal** number and prints the corresponding character from the character set| +|`\0`|same as ``| +|`\x`|Interprets `` as **hexadecimal** number and prints the corresponding character from the character set (**3 digits**)| +|`\u`|same as `\x`, but **4 digits**| +|`\U`|same as `\x`, but **8 digits**| The following additional escape and extra rules apply only to arguments associated with a `%b` format: - ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------- - `\c` Terminate output similarly to the `\c` escape used by `echo -e`. printf produces no additional output after coming across a `\c` escape in a `%b` argument. - ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------- +|Escape Rule|Description| +|-----------|-----------| +|`\c`|Terminate output similarly to the `\c` escape used by `echo -e`. printf produces no additional output after coming across a `\c` escape in a `%b` argument.| - Backslashes in the escapes: `\'`, `\"`, and `\?` are not removed. - Octal escapes beginning with `\0` may contain up to four digits. @@ -267,18 +271,17 @@ This small loop prints all numbers from 0 to 127 in - octal - hex -```{=html} - +```bash +for ((x=0; x <= 127; x++)); do + printf '%3d | %04o | 0x%02x\n' "$x" "$x" "$x" +done ``` - for ((x=0; x <= 127; x++)); do - printf '%3d | %04o | 0x%02x\n' "$x" "$x" "$x" - done ### Ensure well-formatted MAC address This code here will take a common MAC address and rewrite it into a well-known format (regarding leading zeros or upper/lowercase of the hex -digits, \...): +digits, ...): the_mac="0:13:ce:7:7a:ad" @@ -375,29 +378,23 @@ readability. - The a, A, e, E, f, F, g, and G conversions are supported by Bash, but not required by POSIX. -```{=html} - -``` - There is no wide-character support (wprintf). For instance, if you - use `%c`, you\'re actually asking for the first byte of the + use `%c`, you're actually asking for the first byte of the argument. Likewise, the maximum field width modifier (dot) in combination with `%s` goes by bytes, not characters. This limits some of printf's functionality to working with ascii only. ksh93's `printf` supports the `L` modifier with `%s` and `%c` (but so far not `%S` or `%C`) in order to treat precision as character width, not byte count. zsh appears to adjust itself dynamically based upon - `LANG` and `LC_CTYPE`. If `LC_CTYPE=C`, zsh will throw \"character - not in range\" errors, and otherwise supports wide characters + `LANG` and `LC_CTYPE`. If `LC_CTYPE=C`, zsh will throw "character + not in range" errors, and otherwise supports wide characters automatically if a variable-width encoding is set for the current locale. -```{=html} - -``` - Bash recognizes and skips over any characters present in the length modifiers specified by POSIX during format string parsing. -``` c|builtins/printf.def +``` c title="builtins/printf.def" #define LENMODS "hjlLtz" ... /* skip possible format modifiers */ @@ -405,7 +402,6 @@ modstart = fmt; while (*fmt && strchr (LENMODS, *fmt)) fmt++; ``` - - mksh has no built-in printf by default (usually). There is an unsupported compile-time option to include a very poor, basically unusable implementation. For the most part you must rely upon the @@ -414,36 +410,32 @@ fmt++; a new parameter expansion in the form of `${name@Q}` which fills the role of `printf %q` -- expanding in a shell-escaped format. -```{=html} - -``` - ksh93 optimizes builtins run from within a command substitution and which have no redirections to run in the shell's process. Therefore the `printf -v` functionality can be closely matched by `var=$(printf ...)` without a big performance hit. -```{=html} - +```bash +# Illustrates Bash-like behavior. Redefining printf is usually unnecessary / not recommended. +function printf { + case $1 in + -v) + shift + nameref x=$1 + shift + x=$(command printf "$@") + ;; + *) + command printf "$@" + esac +} +builtin cut +print $$ +printf -v 'foo[2]' '%d\n' "$(cut -d ' ' -f 1 /proc/self/stat)" +typeset -p foo +# 22461 +# typeset -a foo=([2]=22461) ``` - # Illustrates Bash-like behavior. Redefining printf is usually unnecessary / not recommended. - function printf { - case $1 in - -v) - shift - nameref x=$1 - shift - x=$(command printf "$@") - ;; - *) - command printf "$@" - esac - } - builtin cut - print $$ - printf -v 'foo[2]' '%d\n' "$(cut -d ' ' -f 1 /proc/self/stat)" - typeset -p foo - # 22461 - # typeset -a foo=([2]=22461) - The optional Bash loadable `print` may be useful for ksh compatibility and to overcome some of @@ -455,10 +447,6 @@ fmt++; only `-Rrnfu` are actually functional. Internally, `-p` is a noop (it doesn't tie in with Bash coprocs at all), and `-s` only sets a flag but has no effect. `-Cev` are unimplemented. - -```{=html} - -``` - Assigning to variables: The `printf -v` way is slightly different to the way using command-substitution. [Command substitution](../../syntax/expansion/cmdsubst.md) removes trailing newlines diff --git a/docs/commands/builtin/read.md b/docs/commands/builtin/read.md index ddb6971..42e8d03 100644 --- a/docs/commands/builtin/read.md +++ b/docs/commands/builtin/read.md @@ -8,7 +8,7 @@ ## Description -The `read` builtin reads **one line** of data (text, user input, \...) +The `read` builtin reads **one line** of data (text, user input, ...) from standard input or a supplied filedescriptor number into one or more variables named by ``. @@ -50,7 +50,7 @@ line is read). That means the timeout can occur during input, too. `-p ` the prompt string `` 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 `-s` secure input - don't echo input if on a terminal (passwords!) - `-t ` wait for data `` 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 ` wait for data `` 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 ` use the filedescriptor number `` rather than `stdin` (0) When both, `-a ` and a variable name `` is given, then the @@ -134,12 +134,12 @@ from a file and print them on the terminal. done <"$1" } -[**Note:**]{.underline} Here, `read -r` and the default `REPLY` is used, +**Note:** Here, `read -r` and the default `REPLY` is used, because we want to have the real literal line, without any mangeling. `printf` is used, because (depending on settings), `echo` may interpret some baskslash-escapes or switches (like `-n`). -### Press any key\... +### Press any key... Remember the MSDOS `pause` command? Here's something similar: @@ -236,7 +236,7 @@ be different between each field: ### Ask for a path with a default value -[**Note:**]{.underline} The `-i` option was introduced with Bash 4 +**Note:** The `-i` option was introduced with Bash 4 read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH diff --git a/docs/commands/builtin/readonly.md b/docs/commands/builtin/readonly.md index e0e4a55..a96c3a1 100644 --- a/docs/commands/builtin/readonly.md +++ b/docs/commands/builtin/readonly.md @@ -15,23 +15,23 @@ readonly variables. ### Options - Option Description - -------- ------------------------------------------------------------------------------------------------------------------------ - `-a` refer to normal arrays - `-A` refer to associative arrays - `-f` refer to functions - `-p` print all read-only variables or functions, `-a`, `-A` and `-f` can be used to filter. The output is reusable as input +|Option|Description| +|-|-| +|`-a`|refer to normal arrays| +|`-A`|refer to associative arrays| +|`-f`|refer to functions| +|`-p`|print all read-only variables or functions, `-a`, `-A` and `-f` can be used to filter. The output is reusable as input| An argument of `--` disables further option processing. ### Return status - Status Reason - -------- -------------------------------- - 0 no error - !=0 invalid option - !=0 invalid combination of options - !=0 a given `NAME` is invalid +|Status|Reason| +|-|-| +|0|no error| +|!=0|invalid option| +|!=0|invalid combination of options| +|!=0|a given `NAME` is invalid| ## Examples diff --git a/docs/commands/builtin/return.md b/docs/commands/builtin/return.md index c3ebecc..08733b2 100644 --- a/docs/commands/builtin/return.md +++ b/docs/commands/builtin/return.md @@ -21,9 +21,9 @@ There are no options. If everything is okay, the `return` command doesn't come back. If it comes back, there was a problem in doing the return. - Status Reason - -------- ------------------------------------------------------------------------- - 1 `return` was called while not being in a shell function or sourced file +|Status|Reason| +|-|-| +|1|`return` was called while not being in a shell function or sourced file| ## Examples diff --git a/docs/commands/builtin/set.md b/docs/commands/builtin/set.md index 7f29036..ae437ce 100644 --- a/docs/commands/builtin/set.md +++ b/docs/commands/builtin/set.md @@ -1,6 +1,7 @@ # The set builtin command -FIXME incomplete - text, examples, maybe extended description +!!! warning "FIXME" + incomplete text, examples, maybe extended description ## Synopsis @@ -24,38 +25,38 @@ All attributes below can be switched on using `-X` and switched off using `+X`. This is done because of the historical meaning of the `-` to set flags (true for most commands on UNIX(r)). - Flag Optionname Description - ------ ---------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `-a` `allexport` Automatically mark new and altered variables to be exported to subsequent environments. - `-b` `notify` Don't wait for the next prompt to print when showing the reports for a terminated background job (only with job control) - `-e` `errexit` When set, the shell exits when a simple command in a command list exits non-zero (`FALSE`). This is not done in situations, where the exit code is already checked (`if`, `while`, `until`, `||`, `&&`) - `-f` `noglob` Disable [pathname expansion](../../syntax/expansion/globs.md) (globbing) - `-h` `hashall` Remembers the location of commands when they\'re called (hashing). Enabled by default. - `-k` `keyword` Allows to place environment-assignments everywhere in the commandline, not only infront of the called command. - `-m` `monitor` **Monitor mode**. With job control, a short descriptive line is printed when a backgroud job ends. Default is \"on\" for interactive shells (with job control). - `-n` `noexec` Read and parse but **do not execute commands** - useful for checking scripts for syntax errors. Ignored by interactive shells. - `-o` Set/unset attributes with long option names, e.g. `set -o noglob`. The long option names are in the second column of this table. If no option name is given, all options are printed with their current status. - `-p` `privileged` Turn on privileged mode. - `-t` `onecmd` Exit after reading and executing **one** command. - `-u` `nounset` Treat unset variables as an error when performing parameter expansion. Non-interactive shells exit on this error. - `-v` `verbose` Print shell input lines as they are read - useful for debugging. - `-x` `xtrace` Print commands just before execution - with all expansions and substitutions done, and words marked - useful for debugging. - `-B` `braceexpand` The shell performs [brace expansion](../../syntax/expansion/brace.md) This is on by default. - `-C` `noclobber` Don't overwrite files on redirection operations. You can override that by specifying the `>|` redirection operator when needed. See [redirection](../../syntax/redirection.md) - `-E` `errtrace` `ERR`-traps are inherited by by shell functions, command substitutions, and commands executed in a subshell environment. - `-H` `histexpand` Enable `!`-style history expansion. Defaults to `on` for interactive shells. - `-P` `physical` Don't follow symlinks when changing directories - use the physical filesystem structure. - `-T` `functrace` `DEBUG`- and `RETURN`-traps are inherited by subsequent environments, like `-E` for `ERR` trap. - `-` \"End of options\" - all following arguments are assigned to the positional parameters, even when they begin with a dash. `-x` and `-v` options are turned off. Positional parameters are unchanged (unlike using `--`!) when no further arguments are given. - `--` If no arguments follow, the positional parameters are unset. With arguments, the positional parameters are set, even if the strings begin with a `-` (dash) like an option. - Long options usable with `-o` without a short equivalent - `emacs` Use an emacs-style command line editing interface. This is enabled by default when the shell is interactive, unless the shell is started with `--noediting` option. - `history` If set, command historization is done (enabled by default on interactive shells) - `ignoreeof` The effect is as if the shell command `IGNOREEOF=10` had been executed. See [shell variables](../../syntax/shellvars.md). - `nolog` **(currently ignored)** - `pipefail` If set, the exit code from a pipeline is different from the normal (\"last command in pipeline\") behaviour: `TRUE` when no command failed, `FALSE` when something failed (code of the rightmost command that failed) - `posix` When set, Bash runs in POSIX mode. - `vi` Enables a `vi`-style command line editing interface. +|Flag|Optionname|Description| +|----|----------|-----------| +|`-a`|`allexport`|Automatically mark new and altered variables to be exported to subsequent environments.| +|`-b`|`notify`|Don't wait for the next prompt to print when showing the reports for a terminated background job (only with job control)| +|`-e`|`errexit`|When set, the shell exits when a simple command in a command list exits non-zero (`FALSE`). This is not done in situations, where the exit code is already checked (`if`, `while`, `until`, `||`, `&&`)| +|`-f`|`noglob`|Disable [pathname expansion](../../syntax/expansion/globs.md) (globbing)| +|`-h`|`hashall`|Remembers the location of commands when they're called (hashing). Enabled by default.| +|`-k`|`keyword`|Allows to place environment-assignments everywhere in the commandline, not only infront of the called command.| +|`-m`|`monitor`|**Monitor mode**. With job control, a short descriptive line is printed when a backgroud job ends. Default is "on" for interactive shells (with job control).| +|`-n`|`noexec`|Read and parse but **do not execute commands** - useful for checking scripts for syntax errors. Ignored by interactive shells.| +|`-o`||Set/unset attributes with long option names, e.g. `set -o noglob`. The long option names are in the second column of this table. If no option name is given, all options are printed with their current status.| +|`-p`|`privileged`|Turn on privileged mode.| +|`-t`|`onecmd`|Exit after reading and executing **one** command.| +|`-u`|`nounset`|Treat unset variables as an error when performing parameter expansion. Non-interactive shells exit on this error.| +|`-v`|`verbose`|Print shell input lines as they are read - useful for debugging.| +|`-x`|`xtrace`|Print commands just before execution - with all expansions and substitutions done, and words marked - useful for debugging.| +|`-B`|`braceexpand`|The shell performs [brace expansion](../../syntax/expansion/brace.md) This is on by default.| +|`-C`|`noclobber`|Don't overwrite files on redirection operations. You can override that by specifying the `>|` redirection operator when needed. See [redirection](../../syntax/redirection.md)| +|`-E`|`errtrace`|`ERR`-traps are inherited by by shell functions, command substitutions, and commands executed in a subshell environment.| +|`-H`|`histexpand`|Enable `!`-style history expansion. Defaults to `on` for interactive shells.| +|`-P`|`physical`|Don't follow symlinks when changing directories - use the physical filesystem structure.| +|`-T`|`functrace`|`DEBUG`- and `RETURN`-traps are inherited by subsequent environments, like `-E` for `ERR` trap.| +|`-`||"End of options" - all following arguments are assigned to the positional parameters, even when they begin with a dash. `-x` and `-v` options are turned off. Positional parameters are unchanged (unlike using `--`!) when no further arguments are given.| +|`--`||If no arguments follow, the positional parameters are unset. With arguments, the positional parameters are set, even if the strings begin with a `-` (dash) like an option.| +|**Long options usable with `-o` without a short equivalent**||| +||`emacs`|Use an emacs-style command line editing interface. This is enabled by default when the shell is interactive, unless the shell is started with `--noediting` option.| +||`history`|If set, command historization is done (enabled by default on interactive shells)| +||`ignoreeof`|The effect is as if the shell command `IGNOREEOF=10` had been executed. See [shell variables](../../syntax/shellvars.md).| +||`nolog`|**(currently ignored)**| +||`pipefail`|If set, the exit code from a pipeline is different from the normal ("last command in pipeline") behaviour: `TRUE` when no command failed, `FALSE` when something failed (code of the rightmost command that failed)| +||`posix`|When set, Bash runs in POSIX mode.| +||`vi`|Enables a `vi`-style command line editing interface.| ## Examples diff --git a/docs/commands/builtin/shift.md b/docs/commands/builtin/shift.md index e8a45d6..f4d4b20 100644 --- a/docs/commands/builtin/shift.md +++ b/docs/commands/builtin/shift.md @@ -6,7 +6,7 @@ ## Description -The `shift` builtin command is used to \"shift\" the positional +The `shift` builtin command is used to "shift" the positional parameters by the given number `n` or by 1, if no number is given. This means, the number and the position of the positional parameters are @@ -15,18 +15,20 @@ becomes the first one, etc. Imagine the following set of positional parameters (`$1` to `$4`): - 1 This - --- ------ - 2 is - 3 a - 4 test +|Positional Parameter|Value| +|-|-| +|1|This +|2|is| +|3|a| +|4|test| When you use `shift 1`, they will be changed to: - 1 is - --- ------ - 2 a - 3 test +|Positional Parameter|Value| +|-|-| +|1|is| +|2|a| +|3|test| The [special parameter](../../syntax/shellvars.md#special_parameters) `$#` will reflect the final number of positional parameters. @@ -40,12 +42,12 @@ There are no options. ### Return status - Status Reason - -------- ----------------------------------------------------------------------------------------------------- - 0 no error - 1 non-numeric argument - 1 given number (or the default 1) is bigger than the number of actually present positional parameters - 1 given number is negative +|Status|Reason| +|------|------| +|0|no error| +|1|non-numeric argument| +|1|given number (or the default 1) is bigger than the number of actually present positional parameters| +|1|given number is negative| ## Examples @@ -59,30 +61,37 @@ There are no options. [shift_verbose](../../internals/shell_options.md#shift_verbose) [shopt](../../commands/builtin/shopt.md) option is enabled. Ksh93, pdksh, posh, mksh, and dash, all throw useless fatal shell - errors.`$ dash -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f' + errors. +``` +$ dash -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f' dash: 1: shift: can't shift that many - ` In most shells, you can work around this problem using the +``` + In most shells, you can work around this problem using the `command` builtin to suppress fatal - errors caused by *special builtins*. \$ dash -c \'f() { if - command shift 2>/dev/null; then echo \"\$1\"; else echo \"no - args\"; fi; }; f\' - -no args While, POSIX requires this behavior, it isn't very + errors caused by *special builtins*. +``` +$ dash -c 'f() { if command shift 2>/dev/null; then echo "$1"; else echo "no args"; fi; }; f' +no args +``` +While, POSIX requires this behavior, it isn't very obvious and some shells don't do it correctly. To work around this, you can use something like: - - \$ mksh -c \'f() { if ! \${1+false} && shift; then echo -\"\$1\"; else echo \"no args\"; fi; }; f\' no args ~~The mksh -maintainer refuses to change either the `shift` or `command` builtins.~~ +``` +$ mksh -c 'f() { if ! ${1+false} && shift; then echo "$1"; else echo "no args"; fi; }; f' +no args +``` +The mksh maintainer refuses to change either the `shift` or `command` builtins. [Fixed](https://github.com/MirBSD/mksh/commit/996e05548ab82f7ef2dea61f109cc7b6d13837fa). (Thanks!) - Perhaps almost as bad as the above, busybox sh's `shift` always returns success, even when attempting to shift beyond the final - argument. \$ bb -c \'f() { if shift; then echo \"\$1\"; - else echo \"no args\"; fi; }; f\' - -(no output) The above mksh workaround will work in this case + argument. +``` +$ bb -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f' +(no output) +``` +The above mksh workaround will work in this case too. ## See also diff --git a/docs/commands/builtin/shopt.md b/docs/commands/builtin/shopt.md index f3f135e..1b1385b 100644 --- a/docs/commands/builtin/shopt.md +++ b/docs/commands/builtin/shopt.md @@ -15,13 +15,13 @@ Note: Some of these options and other shell options can also be set with ### Options - Option Description - -------- ----------------------------------------------------------------------------------------------------------------------------- - `-o` Restrict the values of `` to only those also known by [the set builtin](../../commands/builtin/set.md) - `-p` Print all shell options and their current value. **Default**. - `-q` Quiet mode. Set exit code if named option is set. For multiple options: `TRUE` if all options are set, `FALSE` otherwise - `-s` Enable ([s]{.underline}et) the shell options named by `` or list all *enabled* options if no names are given - `-u` Disabe ([u]{.underline}nset) the shell options named by `` or list all *disabled* options if no names are given +|Option|Description| +|------|-----------| +|`-o`|Restrict the values of `` to only those also known by [the set builtin](../../commands/builtin/set.md)| +|`-p`|Print all shell options and their current value. **Default**.| +|`-q`|Quiet mode. Set exit code if named option is set. For multiple options: `TRUE` if all options are set, `FALSE` otherwise| +|`-s`|Enable (set) the shell options named by `` or list all *enabled* options if no names are given| +|`-u`|Disabe (unset) the shell options named by `` or list all *disabled* options if no names are given| As noted above, if only `-s` or `-u` are given without any option names, only the currently enabled (`-s`) or disabled (`-u`) options are diff --git a/docs/commands/builtin/trap.md b/docs/commands/builtin/trap.md index ee299df..29e6a8a 100644 --- a/docs/commands/builtin/trap.md +++ b/docs/commands/builtin/trap.md @@ -6,8 +6,8 @@ ## Description -The `trap` command is used to \"trap\" signals and other events. In this -context, \"trapping\" means to install handler code. +The `trap` command is used to "trap" signals and other events. In this +context, "trapping" means to install handler code. The shell code `ARGUMENT` is to be read and executed whenever the shell receives a signal or another event `SIGNAL`. The given `SIGNAL` @@ -29,27 +29,27 @@ Special `ARGUMENT`s Special events - Name Code Description - ---------- ------ -------------------------------------------------------------------------------------------------------------------------------------------- - `EXIT` 0 executed on shell exit - `DEBUG` executed before every simple command - `RETURN` executed when a shell function or a sourced code finishes executing - `ERR` executed each time a command's failure would cause the shell to exit when the [`-e` option (`errexit`)](../../commands/builtin/set.md) is enabled +|Name|Code|Description| +|----|----|-----------| +|`EXIT`|0|executed on shell exit| +|`DEBUG`||executed before every simple command| +|`RETURN`||executed when a shell function or a sourced code finishes executing| +|`ERR`||executed each time a command's failure would cause the shell to exit when the [`-e` option (`errexit`)](../../commands/builtin/set.md) is enabled| ### Options - Option Description - -------- ------------------------------------------------------------------------------------------ - `-l` print a list of signal names and their corresponding numbers - `-p` display the trap commands associated with each signal specification in a reusable format +|Option|Description| +|------|-----------| +|`-l`|print a list of signal names and their corresponding numbers| +|`-p`|display the trap commands associated with each signal specification in a reusable format| ### Return status - Status Reason - -------- ------------------------------ - 0 no error/success - !=0 invalid option - !=0 invalid signal specification +|Status|Reason| +|------|------| +|0|no error/success| +|!=0|invalid option| +|!=0|invalid signal specification| ## Examples diff --git a/docs/commands/builtin/unset.md b/docs/commands/builtin/unset.md index f8f4328..586825a 100644 --- a/docs/commands/builtin/unset.md +++ b/docs/commands/builtin/unset.md @@ -12,20 +12,20 @@ unset a variable first, then a function. ### Options - Option Description - -------- -------------------------------------------------------------------------------------------------------------- - `-f` treats each `NAME` as a function name - `-v` treats each `NAME` as a variable name - `-n` treats each `NAME` as a name reference and unsets the variable itself rather than the variable it references +|Option|Description| +|------|-----------| +|`-f`|treats each `NAME` as a function name| +|`-v`|treats each `NAME` as a variable name| +|`-n`|treats each `NAME` as a name reference and unsets the variable itself rather than the variable it references| ### Exit status - Status Reason - -------- ---------------------------------------------------- - 0 no error - !=0 invalid option - !=0 invalid combination of options (`-v` **and** `-f`) - !=0 a given `NAME` is read-only +|Status|Reason| +|------|------| +|0|no error| +|!=0|invalid option| +|!=0|invalid combination of options (`-v` **and** `-f`)| +|!=0|a given `NAME` is read-only| ## Examples @@ -71,8 +71,8 @@ Here's a demonstration of this behavior. local -a 'fnames=("${FUNCNAME[@]:1}")' fi - if (( ! ${#fnames[@]} )); then - printf 0 + if (( ! ${#fnames[@]} )); then + printf 0 return fi @@ -123,7 +123,7 @@ Some things to observe: - `unset2` is only really needed once. We remain 5 levels deep in `f`'s for the remaining `unset` calls, which peel away the outer layers of `a`'s. -- Notice that the \"a\" is unset using an ordinary unset command at +- Notice that the "a" is unset using an ordinary unset command at recursion depth 1, and subsequently calling unset reveals a again in the global scope, which has since been modified in a lower scope using declare -g. @@ -133,7 +133,7 @@ Some things to observe: - This doesn't apply to individual array elements. If two local arrays of the same name appear in different scopes, the entire array of the inner scope needs to be unset before any elements of the - outer array become visible. This makes \"unset\" and \"unset2\" + outer array become visible. This makes "unset" and "unset2" identical for individual array elements, and for arrays as a whole, unset and unset2 behave as they do for scalar variables. diff --git a/docs/commands/builtin/wait.md b/docs/commands/builtin/wait.md index 3777f74..06644c3 100644 --- a/docs/commands/builtin/wait.md +++ b/docs/commands/builtin/wait.md @@ -14,7 +14,7 @@ exit status. - waits for a specific job (asynchronous command) and report its exit status if one or more `ID` is given - waits for all running jobs (asynchronous commands) -- waits for \"the next\" job (`-n` option) +- waits for "the next" job (`-n` option) - waits for termination instead of status change (`-f` option) `ID` may be an operating system process identifier or a shell job @@ -22,20 +22,20 @@ specification. ### Options - Option Description - -------------- --------------------------------------------------------------------------------------------------------------------------------- - `-n` Waits for \"the next\" child to exit (as opposed to \"all children\" without this option). Accepts a list of IDs (jobs) - `-f` Waits for the termination of the given `ID` (instead of waiting for a status change only) - `-p VARNAME` When waiting for a list (-n) or all jobs, writes the job ID to the job that was actually terminated into the variable `VARNAME` +|Option|Description| +|------|-----------| +|`-n`|Waits for "the next" child to exit (as opposed to "all children" without this option). Accepts a list of IDs (jobs)| +|`-f`|Waits for the termination of the given `ID` (instead of waiting for a status change only)| +|`-p VARNAME`|When waiting for a list (-n) or all jobs, writes the job ID to the job that was actually terminated into the variable `VARNAME`| ### Return status The return status is the return status of the job waited for, or - Status Reason - -------- ------------------------------------------------- - 0 waited for all jobs in shell's job list - 1 the given `ID` is not a valid job or process ID +|Status|Reason| +|------|------| +|0|waited for all jobs in shell's job list| +|1|the given `ID` is not a valid job or process ID| ## Examples diff --git a/docs/dict/parameter.md b/docs/dict/parameter.md index 9f9a6cd..fb4e799 100644 --- a/docs/dict/parameter.md +++ b/docs/dict/parameter.md @@ -1,7 +1,7 @@ # Parameter -Also the article for: [variable]{.underline}, [positional -parameter]{.underline}, [special parameter]{.underline} +Also the article for: variable, positional +parameter, special parameter In Bash, a parameter is simply an entity that stores values and can be referenced. Depending on the type, the parameters can be set directly, diff --git a/docs/dict/shell.md b/docs/dict/shell.md index 4d6bc7f..6aa198f 100644 --- a/docs/dict/shell.md +++ b/docs/dict/shell.md @@ -10,7 +10,8 @@ This behaviour alone doesn't help much. A shell knits some intelligence and flow control around the possibility to execute commands - it's a complete commandline-oriented user-interface (UI). -FIXME +!!! warning "FIXME" + tbd. ## See also diff --git a/docs/howto/calculate-dc.md b/docs/howto/calculate-dc.md index c5605bc..3ed9f88 100644 --- a/docs/howto/calculate-dc.md +++ b/docs/howto/calculate-dc.md @@ -12,9 +12,9 @@ tags: ## Introduction dc(1) is a non standard, but commonly found, reverse-polish Desk -Calculator. According to Ken Thompson, \"dc is the oldest language on +Calculator. According to Ken Thompson, "dc is the oldest language on Unix; it was written on the PDP-7 and ported to the PDP-11 before Unix -\[itself\] was ported\". +\[itself\] was ported". Historically the standard bc(1) has been implemented as a *front-end to dc*. @@ -26,15 +26,15 @@ stack first, then an operation is applied to them. Instead of writing `1+1`, you write `1 1+`. By default `dc`, unlike `bc`, doesn't print anything, the result is -pushed on the stack. You have to use the \"p\" command to print the +pushed on the stack. You have to use the "p" command to print the element at the top of the stack. Thus a simple operation looks like: $ dc <<< '1 1+pq' 2 -I used a \"here string\" present in bash 3.x, ksh93 and zsh. if your +I used a "here string" present in bash 3.x, ksh93 and zsh. if your shell doesn't support this, you can use `echo '1 1+p' | dc` or if you -have GNU `dc`, you can use `dc -e '1 1 +p`\'. +have GNU `dc`, you can use `dc -e '1 1 +p'`. Of course, you can also just run `dc` and enter the commands. @@ -53,7 +53,7 @@ GNU `dc` adds a couple more. To input a negative number you need to use the `_` (underscore) character: - $ dc <<< '1_1-p' + $ dc <<< '1_1-p' 2 You can use the *digits* `0` to `9` and the *letters* `A` to `F` as @@ -63,21 +63,21 @@ with lower case characters. A number with a letter is considered hexadecimal: dc <<< 'Ap' - 10 + 10 The **output** is converted to **base 10** by default ## Scale And Base `dc` is a calulator with abitrary precision, by default this precision -is 0. thus `dc <<< "5 4/p"` prints \"1\". +is 0. thus `dc <<< "5 4/p"` prints "1". We can increase the precision using the `k` command. It pops the value at the top of the stack and uses it as the precision argument: dc <<< '2k5 4/p' # prints 1.25 dc <<< '4k5 4/p' # prints 1.2500 - dc <<< '100k 2vp' + dc <<< '100k 2vp' 1.4142135623730950488016887242096980785696718753769480731766797379907\ 324784621070388503875343276415727 @@ -102,7 +102,7 @@ commands, including `i`: 16i 16o # base is 16 for input and output 10p # prints 10 10i # ! set the base to 10 i.e. to 16 decimal - 17p # prints 17 + 17p # prints 17 EOF This code prints 17 while we might think that `10i` reverts the base @@ -123,9 +123,6 @@ There are two basic commands to manipulate the stack: - `d` duplicates the top of the stack - `c` clears the stack -```{=html} - -``` $ dc << EOF 2 # put 2 on the stack d # duplicate i.e. put another 2 on the stack @@ -228,7 +225,7 @@ we are used to reading: EOF Some `dc` have `>R R 1 2 >R f"` doesn't print anything) @@ -246,13 +243,13 @@ as `dc` relies on a stack we can, in fact, use the macro recursively We have recursivity, we have test, we have loops: dc << EOF - [ li # put our index i on the stack + [ li # put our index i on the stack p # print it, to see what's going on 1 - # we decrement the index by one si # store decremented index (i=i-1) 0 li >L # if i > 0 then execute L ] sL # store our macro with the name L - + 10 si # let's give to our index the value 10 lLx # and start our loop EOF @@ -260,16 +257,16 @@ We have recursivity, we have test, we have loops: Of course code written this way is far too easy to read! Make sure to remove all those extra spaces newlines and comments: - dc <<< '[lip1-si0li>L]sL10silLx' + dc <<< '[lip1-si0li>L]sL10silLx' dc <<< '[p1-d0 /dev/null) ]]; then + unset -f find # We can just use the command find + elif [[ $(command find "$0" -perm /u+x 2> /dev/null) ]]; then find() { - hash find || { echo 'find not found!'; exit 1; } - # We can be pretty sure "$0" should be executable. - if [[ $(command find "$0" -executable 2> /dev/null) ]]; then - unset -f find # We can just use the command find - elif [[ $(command find "$0" -perm /u+x 2> /dev/null) ]]; then - find() { - typeset arg args - for arg do - [[ $arg = -executable ]] && args+=(-perm /u+x) || args+=("$arg") - done - command find "${args[@]}" - } - elif [[ $(command find "$0" -perm +u+x 2> /dev/null) ]]; then - find() { - typeset arg args - for arg do - [[ $arg = -executable ]] && args+=(-perm +u+x) || args+=("$arg") - done - command find "${args[@]}" - } - else # Last resort - find() { - typeset arg args - for arg do - [[ $arg = -executable ]] && args+=(-exec test -x {} \; -print) || args+=("$arg") - done - command find "${args[@]}" - } - fi - find "$@" + typeset arg args + for arg do + [[ $arg = -executable ]] && args+=(-perm /u+x) || args+=("$arg") + done + command find "${args[@]}" } + elif [[ $(command find "$0" -perm +u+x 2> /dev/null) ]]; then + find() { + typeset arg args + for arg do + [[ $arg = -executable ]] && args+=(-perm +u+x) || args+=("$arg") + done + command find "${args[@]}" + } + else # Last resort + find() { + typeset arg args + for arg do + [[ $arg = -executable ]] && args+=(-exec test -x {} \; -print) || args+=("$arg") + done + command find "${args[@]}" + } + fi + find "$@" +} +``` - #!/bin/bash - # Using collapsing functions to turn debug messages on/off +```bash +#!/bin/bash +# Using collapsing functions to turn debug messages on/off - [ "--debug" = "$1" ] && dbg=echo || dbg=: +[ "--debug" = "$1" ] && dbg=echo || dbg=: - # From now on if you use $dbg instead of echo, you can select if messages will be shown +# From now on if you use $dbg instead of echo, you can select if messages will be shown - $dbg "This message will only be displayed if --debug is specified at the command line +$dbg "This message will only be displayed if --debug is specified at the command line +``` diff --git a/docs/howto/conffile.md b/docs/howto/conffile.md index 5360986..fd96fd0 100644 --- a/docs/howto/conffile.md +++ b/docs/howto/conffile.md @@ -16,7 +16,7 @@ tags: For this task, you don't have to write large parser routines (unless you want it 100% secure or you want a special file syntax) - you can use the Bash source command. The file to be sourced should be formated in -key=\"value\" format, otherwise bash will try to interpret commands: +key="value" format, otherwise bash will try to interpret commands: #!/bin/bash echo "Reading config...." >&2 @@ -50,7 +50,7 @@ usage of the dot is identical: ## Per-user configs There's also a way to provide a system-wide config file in /etc and a -custom config in \~/(user's home) to override system-wide defaults. In +custom config in ~/(user's home) to override system-wide defaults. In the following example, the if/then construct is used to check for the existance of a user-specific config: @@ -66,11 +66,11 @@ existance of a user-specific config: As mentioned earlier, the sourced file can contain anything a Bash script can. Essentially, it **is** an included Bash script. That creates -security issues. A malicicios person can \"execute\" arbitrary code when +security issues. A malicicios person can "execute" arbitrary code when your script is sourcing its config file. You might want to allow only constructs in the form `NAME=VALUE` in that file (variable assignment syntax) and maybe comments (though technically, comments are -unimportant). Imagine the following \"config file\", containing some +unimportant). Imagine the following "config file", containing some malicious code: # cool config file for my even cooler script @@ -107,7 +107,7 @@ filters by description: # now source it, either the original or the filtered variant source "$configfile" -**[To make clear what it does:]{.underline}** egrep checks if the file +**To make clear what it does:** egrep checks if the file contains something we don't want, if yes, egrep filters the file and writes the filtered contents to a new file. If done, the original file name is changed to the name stored in the variable `configfile`. The diff --git a/docs/howto/dissectabadoneliner.md b/docs/howto/dissectabadoneliner.md index 0a73a83..81d47b3 100644 --- a/docs/howto/dissectabadoneliner.md +++ b/docs/howto/dissectabadoneliner.md @@ -1,36 +1,36 @@ # Dissect a bad oneliner -``` bash +```bash $ ls *.zip | while read i; do j=`echo $i | sed 's/.zip//g'`; mkdir $j; cd $j; unzip ../$i; cd ..; done ``` This is an actual one-liner someone asked about in `#bash`. **There are several things wrong with it. Let's break it down!** -``` bash +```bash $ ls *.zip | while read i; do ...; done ``` (Please read .) This command executes `ls` on the expansion of `*.zip`. Assuming there are filenames -in the current directory that end in \'.zip\', ls will give a +in the current directory that end in '.zip', ls will give a human-readable list of those names. The output of ls is not for parsing. But in sh and bash alike, we can loop safely over the glob itself: -``` bash +```bash $ for i in *.zip; do j=`echo $i | sed 's/.zip//g'`; mkdir $j; cd $j; unzip ../$i; cd ..; done ``` Let's break it down some more! -``` bash +```bash j=`echo $i | sed 's/.zip//g'` # where $i is some name ending in '.zip' ``` The goal here seems to be get the filename without its `.zip` extension. In fact, there is a POSIX(r)-compliant command to do this: `basename` The implementation here is suboptimal in several ways, but the only -thing that's genuinely error-prone with this is \"`echo $i`\". Echoing +thing that's genuinely error-prone with this is "`echo $i`". Echoing an *unquoted* variable means [wordsplitting](../syntax/expansion/wordsplit.md) will take place, so any whitespace in `$i` will essentially be normalized. In `sh` it is @@ -41,7 +41,7 @@ performance in a loop). Just for good measure, let's use the more readable, [modern](../syntax/expansion/cmdsubst.md) `$()` construct instead of the old style backticks: -``` bash +```bash sh $ for i in *.zip; do j=$(basename "$i" ".zip"); mkdir $j; cd $j; unzip ../$i; cd ..; done ``` @@ -49,27 +49,27 @@ In Bash we don't need the subshell or the external basename command. See [Substring removal with parameter expansion](../syntax/pe.md#substring_removal): -``` bash +```bash bash $ for i in *.zip; do j="${i%.zip}"; mkdir $j; cd $j; unzip ../$i; cd ..; done ``` Let's keep going: -``` bash +```bash $ mkdir $j; cd $j; ...; cd .. ``` As a programmer, you **never** know the situation under which your program will run. Even if you do, the following best practice will never hurt: When a following command depends on the success of a previous -command(s), check for success! You can do this with the \"`&&`\" +command(s), check for success! You can do this with the "`&&`" conjunction, that way, if the previous command fails, bash will not try to execute the following command(s). It's fully POSIX(r). Oh, and remember what I said about [wordsplitting](../syntax/expansion/wordsplit.md) in the previous step? Well, if you don't quote `$j`, wordsplitting can happen again. -``` bash +```bash $ mkdir "$j" && cd "$j" && ... && cd .. ``` @@ -78,47 +78,47 @@ contains a slash? Then `cd ..` will not return to the original directory. That's wrong! `cd -` causes cd to return to the previous working directory, so it's a much better choice: -``` bash +```bash $ mkdir "$j" && cd "$j" && ... && cd - ``` (If it occurred to you that I forgot to check for success after cd -, -good job! You could do this with `{ cd - || break; }`, but I\'m going to +good job! You could do this with `{ cd - || break; }`, but I'm going to leave that out because it's verbose and I think it's likely that we will be able to get back to our original working directory without a problem.) So now we have: -``` bash +```bash sh $ for i in *.zip; do j=$(basename "$i" ".zip"); mkdir "$j" && cd "$j" && unzip ../$i && cd -; done ``` -``` bash +```bash bash $ for i in *.zip; do j="${i%.zip}"; mkdir "$j" && cd "$j" && unzip ../$i && cd -; done ``` Let's throw the `unzip` command back in the mix: -``` bash +```bash mkdir "$j" && cd "$j" && unzip ../$i && cd - ``` Well, besides word splitting, there's nothing terribly wrong with this. Still, did it occur to you that unzip might already be able to target a directory? There isn't a standard for the `unzip` command, but all the -implementations I\'ve seen can do it with the -d flag. So we can drop +implementations I've seen can do it with the -d flag. So we can drop the cd commands entirely: -``` bash +```bash $ mkdir "$j" && unzip -d "$j" "$i" ``` -``` bash +```bash sh $ for i in *.zip; do j=$(basename "$i" ".zip"); mkdir "$j" && unzip -d "$j" "$i"; done ``` -``` bash +```bash bash $ for i in *.zip; do j="${i%.zip}"; mkdir "$j" && unzip -d "$j" "$i"; done ``` diff --git a/docs/howto/edit-ed.md b/docs/howto/edit-ed.md index 283aca6..1a03485 100644 --- a/docs/howto/edit-ed.md +++ b/docs/howto/edit-ed.md @@ -20,7 +20,7 @@ contents with `sed`, and the file is open elsewhere and read by some process, you will find out that GNU `sed` and its `-i` option will not allow you to edit the file. There are circumstances where you may need that, e.g. editing active and open files, the lack of GNU, or other -`sed`, with \"in-place\" option available. +`sed`, with "in-place" option available. Why `ed`? @@ -40,12 +40,12 @@ Since `ed` is an interactive text editor, it reads and executes commands that come from `stdin`. There are several ways to feed our commands to ed: -**[Pipelines]{.underline}** +**Pipelines** echo '' | ed To inject the needed newlines, etc. it may be easier to use the builtin -command, `printf` (\"help printf\"). Shown here as an example Bash +command, `printf` ("help printf"). Shown here as an example Bash function to prefix text to file content: @@ -55,11 +55,11 @@ function to prefix text to file content: printf '%s\n' H 1i "$1" . w | ed -s "$2" } -**[Here-strings]{.underline}** +**Here-strings** ed <<< '' -**[Here-documents]{.underline}** +**Here-documents** ed < @@ -71,17 +71,17 @@ it looks best here IMHO. There are other ways to provide input to `ed`. For example, process substitution. But these should be enough for daily needs. -Since `ed` wants commands separated by newlines, I\'ll use a special +Since `ed` wants commands separated by newlines, I'll use a special Bash quoting method, the C-like strings `$'TEXT'`, as it can interpret a -set of various escape sequences and special characters. I\'ll use the +set of various escape sequences and special characters. I'll use the `-s` option to make it less verbose. ## The basic interface Check the `ed` manpage for details -Similar to `vi` or `vim`, `ed` has a \"command mode\" and an -\"interactive mode\". For non-interactive use, the command mode is the +Similar to `vi` or `vim`, `ed` has a "command mode" and an +"interactive mode". For non-interactive use, the command mode is the usual choice. Commands to `ed` have a simple and regular structure: zero, one, or two @@ -103,7 +103,7 @@ no RE can ever match a newline. ## Debugging your ed scripts -By default, `ed` is not very talkative and will simply print a \"?\" +By default, `ed` is not very talkative and will simply print a "?" when an error occurs. Interactively you can use the `h` command to get a short message explaining the last error. You can also turn on a mode that makes `ed` automatically print this message with the `H` command. @@ -156,8 +156,8 @@ lines, it's considered an error.** ed -s test.txt <<< $',s/Windows(R)-compatible/POSIX-conform/g\nw' -[Note:]{.underline} The comma as single address operator is an alias for -`1,$` (\"all lines\"). +Note: The comma as single address operator is an alias for +`1,$` ("all lines"). #### Substitutions in specific lines @@ -188,7 +188,7 @@ regexp #### Move a block of text -\...using the `m` command: `
m ` +...using the `m` command: `
m ` This is definitely something that can't be done easily with sed. @@ -200,7 +200,7 @@ This is definitely something that can't be done easily with sed. #### Copy a block of text -\...using the `t` command: `
t ` +...using the `t` command: `
t ` You use the `t` command just like you use the `m` (move) command. @@ -212,7 +212,7 @@ You use the `t` command just like you use the `m` (move) command. #### Join all lines -\...but leave the final newline intact. This is done by an extra +...but leave the final newline intact. This is done by an extra command: `j` (join). ed -s file <<< $'1,$j\nw' @@ -263,7 +263,7 @@ about it with the g (global) command: echo $'1\n1\n3' > file #replace all lines matching 1 by "replacement" - ed -s file <<< $'g/1/s/1/replacement/\n,p' + ed -s file <<< $'g/1/s/1/replacement/\n,p' #replace the first line matching 1 by "replacement" #(because it starts searching from the last line) @@ -272,7 +272,7 @@ about it with the g (global) command: **\_\_ an error stops the script \_\_** You might think that it's not a problem and that the same thing happens -with sed and you\'re right, with the exception that if ed does not find +with sed and you're right, with the exception that if ed does not find a pattern it's an error, while sed just continues with the next line. For instance, let's say that you want to change foo to bar on the first line of the file and add something after the next line, ed will stop if @@ -299,9 +299,9 @@ attempt the substitution on all non blank lines **\_\_ shell parameters are expanded \_\_** -If you don't quote the delimiter, \$ has a special meaning. This sounds +If you don't quote the delimiter, `$` has a special meaning. This sounds obvious but it's easy to forget this fact when you use addresses like -\$-1 or commands like \$a. Either quote the \$ or the delimiter: +`$-1` or commands like `$a`. Either quote the `$` or the delimiter: #fails ed -s file << EOF @@ -309,15 +309,15 @@ obvious but it's easy to forget this fact when you use addresses like last line . w - EOF + EOF #ok ed -s file << EOF - \$a + $a last line . w - EOF + EOF #ok again ed -s file << 'EOF' @@ -325,11 +325,11 @@ obvious but it's easy to forget this fact when you use addresses like last line . w - EOF + EOF -**\_\_ \".\" is not a command \_\_** +**\_\_ "." is not a command \_\_** -The . used to terminate the command \"a\" must be the only thing on the +The . used to terminate the command "a" must be the only thing on the line. take care if you indent the commands: #ed doesn't care about the spaces before the commands, but the . must be the only thing on the line: @@ -358,7 +358,7 @@ expression => print). ref ### wc -l -Since the default for the `ed` \"print line number\" command is the last +Since the default for the `ed` "print line number" command is the last line, a simple `=` (equal sign) will print this line number and thus the number of lines of the file: @@ -366,23 +366,24 @@ number of lines of the file: ### cat -Yea, it's a joke\... +Yea, it's a joke... ed -s file <<< $',p' -\...but a similar thing to `cat` showing line-endings and escapes can be +...but a similar thing to `cat` showing line-endings and escapes can be done with the `list` command (l): ed -s file <<< $',l' -FIXME to be continued +!!! warning "FIXME" + to be continued ## Links Reference: - [Gnu ed](http://www.gnu.org/software/ed/manual/ed_manual.html) - if - we had to guess, you\'re probably using this one. + we had to guess, you're probably using this one. - POSIX [ed](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ed.html#tag_20_38), [ex](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html#tag_20_40), diff --git a/docs/howto/getopts_tutorial.md b/docs/howto/getopts_tutorial.md index 5fcc941..24f16cb 100644 --- a/docs/howto/getopts_tutorial.md +++ b/docs/howto/getopts_tutorial.md @@ -27,7 +27,7 @@ are: - Being a builtin, `getopts` can set shell variables to use for parsing (impossible for an *external* process!) - There's no need to argue with several `getopt` implementations - which had buggy concepts in the past (whitespace, \...) + which had buggy concepts in the past (whitespace, ...) - `getopts` is defined in POSIX(r). ------------------------------------------------------------------------ @@ -38,7 +38,7 @@ parameters](../scripting/posparams.md). ### Terminology -It's useful to know what we\'re talking about here, so let's see\... +It's useful to know what we're talking about here, so let's see... Consider the following command line: mybackup -x -f /etc/mybackup.conf -r ./foo.txt ./bar.txt @@ -97,13 +97,13 @@ which means [end of options](../dict/end_of_options.md). ### Used variables - variable description - ------------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [OPTIND](../syntax/shellvars.md#OPTIND) Holds the index to the next argument to be processed. This is how `getopts` \"remembers\" its own status between invocations. Also useful to shift the positional parameters after processing with `getopts`. `OPTIND` is initially set to 1, and **needs to be re-set to 1 if you want to parse anything again with getopts** - [OPTARG](../syntax/shellvars.md#OPTARG) This variable is set to any argument for an option found by `getopts`. It also contains the option flag of an unknown option. - [OPTERR](../syntax/shellvars.md#OPTERR) (Values 0 or 1) Indicates if Bash should display error messages generated by the `getopts` builtin. The value is initialized to **1** on every shell startup - so be sure to always set it to **0** if you don't want to see annoying messages! **`OPTERR` is not specified by POSIX for the `getopts` builtin utility --- only for the C `getopt()` function in `unistd.h` (`opterr`).** `OPTERR` is bash-specific and not supported by shells such as ksh93, mksh, zsh, or dash. +|variable|description| +|--------|-----------| +|[OPTIND](../syntax/shellvars.md#OPTIND)|Holds the index to the next argument to be processed. This is how `getopts` "remembers" its own status between invocations. Also useful to shift the positional parameters after processing with `getopts`. `OPTIND` is initially set to 1, and **needs to be re-set to 1 if you want to parse anything again with getopts** +|[OPTARG](../syntax/shellvars.md#OPTARG)|This variable is set to any argument for an option found by `getopts`. It also contains the option flag of an unknown option.| +|[OPTERR](../syntax/shellvars.md#OPTERR)|(Values 0 or 1) Indicates if Bash should display error messages generated by the `getopts` builtin. The value is initialized to **1** on every shell startup - so be sure to always set it to **0** if you don't want to see annoying messages! **`OPTERR` is not specified by POSIX for the `getopts` builtin utility --- only for the C `getopt()` function in `unistd.h` (`opterr`).** `OPTERR` is bash-specific and not supported by shells such as ksh93, mksh, zsh, or dash.| -`getopts` also uses these variables for error reporting (they\'re set to +`getopts` also uses these variables for error reporting (they're set to value-combinations which arent possible in normal operation). ### Specify what you want @@ -114,10 +114,11 @@ The base-syntax for `getopts` is: where: - `OPTSTRING` tells `getopts` which options to expect and where to expect arguments (see below) - ------------- ------------------------------------------------------------------------------------ - `VARNAME` tells `getopts` which shell-variable to use for option reporting - `ARGS` tells `getopts` to parse these optional words instead of the positional parameters +|Option|Description| +|------|-----------| +|`OPTSTRING`|tells `getopts` which options to expect and where to expect arguments (see below)| +|`VARNAME`|tells `getopts` which shell-variable to use for option reporting| +|`ARGS`|tells `getopts` to parse these optional words instead of the positional parameters| #### The option-string @@ -136,7 +137,7 @@ an argument (i.e. to become `-A SOMETHING`) just do: If the **very first character** of the option-string is a `:` (colon), which would normally be nonsense because there's no option letter -preceding it, `getopts` switches to \"**silent error reporting mode**\". +preceding it, `getopts` switches to "**silent error reporting mode**". In productive scripts, this is usually what you want because it allows you to handle errors yourself without being disturbed by annoying messages. @@ -177,15 +178,17 @@ are indicated in an easier way. #### Verbose Mode - invalid option `VARNAME` is set to `?` (question-mark) and `OPTARG` is unset - ----------------------------- ---------------------------------------------------------------------------------------------- - required argument not found `VARNAME` is set to `?` (question-mark), `OPTARG` is unset and an *error message is printed* +|failure|message| +|-------|-------| +|invalid option|`VARNAME` is set to `?` (question-mark) and `OPTARG` is unset| +|required argument not found|`VARNAME` is set to `?` (question-mark), `OPTARG` is unset and an *error message is printed*| #### Silent Mode - invalid option `VARNAME` is set to `?` (question-mark) and `OPTARG` is set to the (invalid) option character - ----------------------------- ----------------------------------------------------------------------------------------------- - required argument not found `VARNAME` is set to `:` (colon) and `OPTARG` contains the option-character in question +|failure|message| +|-------|-------| +|invalid option|`VARNAME` is set to `?` (question-mark) and `OPTARG` is set to the (invalid) option character| +|required argument not found|`VARNAME` is set to `:` (colon) and `OPTARG` contains the option-character in question| ## Using it @@ -212,7 +215,7 @@ while getopts ":a" opt; do done ``` -I put that into a file named `go_test.sh`, which is the name you\'ll see +I put that into a file named `go_test.sh`, which is the name you'll see below in the examples. Let's do some tests: @@ -220,7 +223,7 @@ Let's do some tests: #### Calling it without any arguments $ ./go_test.sh - $ + $ Nothing happened? Right. `getopts` didn't see any valid or invalid options (letters preceded by a dash), so it wasn't triggered. @@ -228,7 +231,7 @@ options (letters preceded by a dash), so it wasn't triggered. #### Calling it with non-option arguments $ ./go_test.sh /etc/passwd - $ + $ Again --- nothing happened. The **very same** case: `getopts` didn't see any valid or invalid options (letters preceded by a dash), so it @@ -245,7 +248,7 @@ First, an **invalid** one: $ ./go_test.sh -b Invalid option: -b - $ + $ As expected, `getopts` didn't accept this option and acted like told above: It placed `?` into `$opt` and the invalid option character (`b`) @@ -255,7 +258,7 @@ Now, a **valid** one (`-a`): $ ./go_test.sh -a -a was triggered! - $ + $ You see, the detection works perfectly. The `a` was put into the variable `$opt` for our case statement. @@ -268,7 +271,7 @@ calling: Invalid option: -x Invalid option: -b Invalid option: -c - $ + $ Finally, it's of course possible, to give our option **multiple times**: @@ -278,7 +281,7 @@ times**: -a was triggered! -a was triggered! -a was triggered! - $ + $ The last examples lead us to some points you may consider: @@ -319,14 +322,14 @@ Let's do the very same tests we did in the last example: #### Calling it without any arguments $ ./go_test.sh - $ + $ As above, nothing happened. It wasn't triggered. #### Calling it with non-option arguments $ ./go_test.sh /etc/passwd - $ + $ The **very same** case: It wasn't triggered. @@ -336,7 +339,7 @@ The **very same** case: It wasn't triggered. $ ./go_test.sh -b Invalid option: -b - $ + $ As expected, as above, `getopts` didn't accept this option and acted like programmed. @@ -345,7 +348,7 @@ like programmed. $ ./go_test.sh -a Option -a requires an argument. - $ + $ The option was okay, but there is an argument missing. diff --git a/docs/howto/mutex.md b/docs/howto/mutex.md index e098ac2..a765882 100644 --- a/docs/howto/mutex.md +++ b/docs/howto/mutex.md @@ -23,8 +23,8 @@ The basic procedure is simple: The script checks if a specific condition doesn't start. This article describes locking with common UNIX(r) tools. There are -other special locking tools available, But they\'re not standardized, or -worse yet, you can't be sure they\'re present when you want to run your +other special locking tools available, But they're not standardized, or +worse yet, you can't be sure they're present when you want to run your scripts. **A tool designed for specifically for this purpose does the job much better than general purpose code.** @@ -42,7 +42,7 @@ limits. The best way to set a global lock condition is the UNIX(r) filesystem. Variables aren't enough, as each process has its own private variable space, but the filesystem is global to all processes (yes, I know about -chroots, namespaces, \... special case). You can \"set\" several things +chroots, namespaces, ... special case). You can "set" several things in the filesystem that can be used as locking indicator: - create files @@ -61,7 +61,7 @@ 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:**]{.underline} We need an + **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 @@ -95,14 +95,14 @@ trapped. I am sure there there is a better solution than this suggestion* --- **sn18** 2009/12/19 08:24* **Note:** While perusing the Internet, I found some people asking if the -`mkdir` method works \"on all filesystems\". Well, let's say it should. +`mkdir` method works "on all filesystems". Well, let's say it should. The syscall under `mkdir` is guarenteed to work atomicly in all cases, at least on Unices. Two examples of problems are NFS filesystems and filesystems on cluster servers. With those two scenarios, dependencies exist related to the mount options and implementation. However, I successfully use this simple method on an Oracle OCFS2 filesystem in a -4-node cluster environment. So let's just say \"it should work under -normal conditions\". +4-node cluster environment. So let's just say "it should work under +normal conditions". Another atomic method is setting the `noclobber` shell option (`set -C`). That will cause redirection to fail, if the file the @@ -162,12 +162,12 @@ echo -n "[statsgen] Locking: " >&2 if mkdir "${LOCKDIR}" &>/dev/null; then - # lock succeeded, install signal handlers before storing the PID just in case + # lock succeeded, install signal handlers before storing the PID just in case # storing the PID fails trap 'ECODE=$?; echo "[statsgen] Removing lock. Exit: ${ETXT[ECODE]}($ECODE)" >&2 rm -rf "${LOCKDIR}"' 0 - echo "$$" >"${PIDFILE}" + echo "$$" >"${PIDFILE}" # the following handler will exit the script upon receiving these signals # the trap on "0" (EXIT) from above will be triggered by this trap's "exit" command! trap 'echo "[statsgen] Killed by a signal." >&2 diff --git a/docs/howto/pax.md b/docs/howto/pax.md index 507cbaa..af15f57 100644 --- a/docs/howto/pax.md +++ b/docs/howto/pax.md @@ -35,7 +35,7 @@ anymore. ### Operation modes 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: Mode RW-Options @@ -123,7 +123,7 @@ files to list or extract. - if you specify the `-c` option, `pax` will invert the matches, i.e. it matches all filenames **except** those matching the specified patterns -- if no patterns are given, `pax` will \"match\" (list or extract) all +- if no patterns are given, `pax` will "match" (list or extract) all files from the archive - **To avoid conflicts with shell pathname expansion, it's wise to quote patterns!** @@ -207,7 +207,7 @@ To copy directory contents to another directory, similar to a `cp -a` command, use: mkdir destdir - pax -rw dir destdir #creates a copy of dir in destdir/, i.e. destdir/dir + pax -rw dir destdir #creates a copy of dir in destdir/, i.e. destdir/dir ### Copying files via ssh @@ -223,7 +223,7 @@ on the remote machine. ### Backup your daily work -[**Note:**]{.underline} `-T` is an extension and is not defined by +**Note:** `-T` is an extension and is not defined by POSIX. Say you have write-access to a fileserver mounted on your filesystem @@ -234,14 +234,14 @@ modified today: pax -rw -T 0000 data/ /n/mybackups/$(date +%A)/ This is done using the `-T` switch, which normally allows you to specify -a time window, but in this case, only the start time which means \"today -at midnight\". +a time window, but in this case, only the start time which means "today +at midnight". -When you execute this \"very simple backup\" after your daily work, you +When you execute this "very simple backup" after your daily work, you will have a copy of the modified files. -[**Note:**]{.underline} The `%A` format from `date` expands to the name -of the current day, localized, e.g. \"Friday\" (en) or \"Mittwoch\" +**Note:** The `%A` format from `date` expands to the name +of the current day, localized, e.g. "Friday" (en) or "Mittwoch" (de). The same, but with an archive, can be accomplished by: @@ -282,19 +282,19 @@ The -s command seen above can be used to exclude a file. The substitution must result in a null string: For example, let's say that you want to exclude all the CVS directories to create a source code archive. We are going to replace the names containing /CVS/ with -nothing, note the .\* they are needed because we need to match the +nothing, note the `.*` they are needed because we need to match the entire pathname. - pax -w -x ustar -f release.tar -s',.*/CVS/.*,,' myapplication + pax -w -x ustar -f release.tar -s',.*/CVS/.*,,' myapplication You can use several -s options, for instance, let's say you also want -to remove files ending in \~: +to remove files ending in `~`: - pax -w -x ustar -f release.tar -'s,.*/CVS/.*,,' -'s/.*~//' myapplication + pax -w -x ustar -f release.tar -'s,.*/CVS/.*,,' -'s/.*~//' myapplication This can also be done while reading an archive, for instance, suppose -you have an archive containing a \"usr\" and a \"etc\" directory but -that you want to extract only the \"usr\" directory: +you have an archive containing a "usr" and a "etc" directory but +that you want to extract only the "usr" directory: pax -r -f archive.tar -s',^etc/.*,,' #the etc/ dir is not extracted @@ -341,8 +341,8 @@ make the switch: ------------------------------------- ------------------------------------------ ----------------------------------------------------------------------- `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 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 &2`, `2>&1` or `1>&3-` do. # stdin, stdout, stderr @@ -22,7 +22,7 @@ When Bash starts, normally, 3 file descriptors are opened, `0`, `1` and `2` also known as standard input (`stdin`), standard output (`stdout`) and standard error (`stderr`). -For example, with Bash running in a Linux terminal emulator, you\'ll +For example, with Bash running in a Linux terminal emulator, you'll see: # lsof +f g -ap $BASHPID -d 0,1,2 @@ -54,7 +54,7 @@ connected to `/dev/pts/5`. # Simple Redirections -## Output Redirection \"n> file\" +## Output Redirection "n> file" `>` is probably the simplest redirection. @@ -107,7 +107,7 @@ pointing to `file`. The command will then start with: What will the command do with this descriptor? It depends. Often nothing. We will see later why we might want other file descriptors. -## Input Redirection \"n< file\" +## Input Redirection "n< file" When you run a commandusing `command < file`, it changes the file descriptor `0` so that it looks like: @@ -130,7 +130,7 @@ from the console. As with `>`, `<` can be used to open a new file descriptor for reading, `command 3&1 | less` --- +--------------+ --- +--------------+ Why is it called *duplicating*? Because after `2>&1`, we have 2 file -descriptors pointing to the same file. Take care not to call this \"File -Descriptor Aliasing\"; if we redirect `stdout` after `2>&1` to a file +descriptors pointing to the same file. Take care not to call this "File +Descriptor Aliasing"; if we redirect `stdout` after `2>&1` to a file `B`, file descriptor `2` will still be opened on the file `A` where it was. This is often misunderstood by people wanting to redirect both standard input and standard output to the file. Continue reading for @@ -223,9 +223,10 @@ Similarly for output file descriptors, writing a line to file descriptor `s` will append a line to a file as will writing a line to file descriptor `t`. -The syntax is somewhat confusing in that you would think -that the arrow would point in the direction of the copy, but it's -reversed. So it's `target>&source` effectively. +!!! info "Tip" + The syntax is somewhat confusing in that you would think + that the arrow would point in the direction of the copy, but it's + reversed. So it's `target>&source` effectively. So, as a simple example (albeit slightly contrived), is the following: @@ -235,7 +236,7 @@ So, as a simple example (albeit slightly contrived), is the following: exec 1>&3 # Copy 3 back into 1 echo Done # Output to original stdout -## Order Of Redirection, i.e., \"> file 2>&1\" vs. \"2>&1 >file\" +## Order Of Redirection, i.e., "`> file 2>&1`" vs. "`2>&1 >file`" While it doesn't matter where the redirections appears on the command line, their order does matter. They are set up from left to right. @@ -323,7 +324,7 @@ Then it sees our duplication `2>&1`: And voila, both `1` and `2` are redirected to file. -## Why sed 's/foo/bar/\' file >file Doesn't Work +## Why sed 's/foo/bar/' file >file Doesn't Work This is a common error, we want to modify a file using something that reads from a file and writes the result to `stdout`. To do this, we @@ -332,7 +333,7 @@ as we have seen, the redirections are setup before the command is actually executed. So **BEFORE** sed starts, standard output has already been redirected, -with the additional side effect that, because we used >, \"file\" gets +with the additional side effect that, because we used >, "file" gets truncated. When `sed` starts to read the file, it contains nothing. ## exec @@ -447,8 +448,8 @@ it. It's probably better to do something like: #we don't need 3 any more -I\'ve seen some people using this as a way to discard, say stderr, using -something like: command 2>&-. Though it might work, I\'m not sure if +I've seen some people using this as a way to discard, say stderr, using +something like: command 2>&-. Though it might work, I'm not sure if you can expect all applications to behave correctly with a closed stderr. @@ -598,11 +599,11 @@ original `stderr`. # Syntax I used to have trouble choosing between `0&<3` `3&>1` `3>&1` `->2` -`-<&0` `&-<0` `0<&-` etc\... (I think probably because the syntax is +`-<&0` `&-<0` `0<&-` etc... (I think probably because the syntax is more representative of the result, i.e., the redirection, than what is done, i.e., opening, closing, or duplicating file descriptors). -If this fits your situation, then maybe the following \"rules\" will +If this fits your situation, then maybe the following "rules" will help you, a redirection is always like the following: lhs op rhs @@ -612,18 +613,12 @@ help you, a redirection is always like the following: the op is `<` then there is an implicit 0, if it's `>` or `>>`, there is an implicit 1. -```{=html} - -``` - `op` is `<`, `>`, `>>`, `>|`, or `<>`: - `<` if the file decriptor in `lhs` will be read, `>` if it will be written, `>>` if data is to be appended to the file, `>|` to overwrite an existing file or `<>` if it will be both read and written. -```{=html} - -``` - `rhs` is the thing that the file descriptor will describe: - It can be the name of a file, the place where another descriptor goes (`&1`), or, `&-`, which will close the file descriptor. @@ -638,49 +633,34 @@ The shell is pretty loose about what it considers a valid redirect. While opinions probably differ, this author has some (strong) recommendations: -- **Always** keep redirections \"tightly grouped\" -- that is, **do +- **Always** keep redirections "tightly grouped" -- that is, **do not** include whitespace anywhere within the redirection syntax except within quotes if required on the RHS (e.g. a filename that contains a space). Since shells fundamentally use whitespace to delimit fields in general, it is visually much clearer for each redirection to be separated by whitespace, but grouped in chunks that contain no unnecessary whitespace. - -```{=html} - -``` - **Do** always put a space between each redirection, and between the - argument list and the first redirect. - -```{=html} - -``` - **Always** place redirections together at the very end of a command after all arguments. Never precede a command with a redirect. Never - put a redirect in the middle of the arguments. - -```{=html} - -``` - **Never** use the Csh `&>foo` and `>&foo` shorthand redirects. Use the long form `>foo 2>&1`. (see: [obsolete](../scripting/obsolete.md)) -```{=html} - +```bash +# Good! This is clearly a simple commmand with two arguments and 4 redirections +cmd arg1 arg2 /dev/null >&2 + +# Good! +{ cmd1 <<<'my input'; cmd2; } >someFile + +# Bad. Is the "1" a file descriptor or an argument to cmd? (answer: it's the FD). Is the space after the herestring part of the input data? (answer: No). +# The redirects are also not delimited in any obvious way. +cmd 2>& 1 <<< stuff + +# Hideously Bad. It's difficult to tell where the redirects are and whether they're even valid redirects. +# This is in fact one command with one argument, an assignment, and three redirects. +foo=barbleh ``` - # Good! This is clearly a simple commmand with two arguments and 4 redirections - cmd arg1 arg2 /dev/null >&2 - - # Good! - { cmd1 <<<'my input'; cmd2; } >someFile - - # Bad. Is the "1" a file descriptor or an argument to cmd? (answer: it's the FD). Is the space after the herestring part of the input data? (answer: No). - # The redirects are also not delimited in any obvious way. - cmd 2>& 1 <<< stuff - - # Hideously Bad. It's difficult to tell where the redirects are and whether they're even valid redirects. - # This is in fact one command with one argument, an assignment, and three redirects. - foo=barbleh # Conclusion @@ -689,9 +669,9 @@ I hope this tutorial worked for you. I lied, I did not explain `1>&3-`, go check the manual ;-) Thanks to Stéphane Chazelas from whom I stole both the intro and the -example\.... +example.... -The intro is inspired by this introduction, you\'ll find a nice exercise +The intro is inspired by this introduction, you'll find a nice exercise there too: - [A Detailed Introduction to I/O and I/O diff --git a/docs/howto/testing-your-scripts.md b/docs/howto/testing-your-scripts.md index e5feadc..fb9265f 100644 --- a/docs/howto/testing-your-scripts.md +++ b/docs/howto/testing-your-scripts.md @@ -23,7 +23,7 @@ We have a simple **stat.sh** script: echo "PYTHON LINES: $LINES" This script evaluate the number of python files and the number of python -code lines in the files. We can use it like **./stat.sh ** +code lines in the files. We can use it like **`./stat.sh `** ### Create testsuit diff --git a/docs/internals/shell_options.md b/docs/internals/shell_options.md index 50fd0d5..b114bc1 100644 --- a/docs/internals/shell_options.md +++ b/docs/internals/shell_options.md @@ -11,7 +11,7 @@ tags: # List of shell options -This information was taken from a Bash version \"`4.1`\", every now and +This information was taken from a Bash version "`4.1`", every now and then new options are added, so likely, this list isn't complete. The shell-options can be set with the [shopt builtin @@ -21,35 +21,35 @@ command](../commands/builtin/shopt.md). ### autocd - Option: `autocd` Since: 4.0-alpha - ------------- ------------------ ---------- ----------- - Shell mode: interactive only Default: off +| Option: | `autocd` | Since: | 4.0-alpha | +|:------------|:-----------------|:---------|:----------| +| Shell mode: | interactive only | Default: | off | If set, a command name that is the name of a directory is executed as if it were the argument to the cd command. ### assoc_expand_once - Option: `assoc_expand_once` Since: 5.0-alpha - ------------- --------------------- ---------- ----------- - Shell mode: all Default: off +| Option: | `assoc_expand_once` | Since: | 5.0-alpha | +|:------------|:--------------------|:---------|:----------| +| Shell mode: | all | Default: | off | If set, Bash attempts to expand associative array options only once. ### cdable_vars - Option: `cdable_vars` Since: unknown - ------------- --------------- ---------- --------- - Shell mode: all Default: off +| Option: | `cdable_vars` | Since: | unknown | +|:------------|:--------------|:---------|:--------| +| Shell mode: | all | Default: | off | Treat every **non-directory argument** to the `cd`-command as variable name containing a directory to `cd` into. ### cdspell - Option: `cdspell` Since: unknown - ------------- ------------------ ---------- --------- - Shell mode: interactive only Default: off +| Option: | `cdspell` | Since: | unknown | +|:------------|:-----------------|:---------|:--------| +| Shell mode: | interactive only | Default: | off | If set, minor errors in the spelling of a directory component in a cd command will be corrected. The errors checked for are transposed @@ -59,9 +59,9 @@ proceeds. ### checkhash - Option: `checkhash` Since: unknown - ------------- ------------- ---------- --------- - Shell mode: all Default: off +| Option: | `checkhash` | Since: | unknown | +|:------------|:------------|:---------|:--------| +| Shell mode: | all | Default: | off | If set, Bash checks that a command found in the hash table exists before trying to execute it. If a hashed command no longer exists, a normal @@ -69,9 +69,9 @@ path search is performed. ### checkjobs - Option: `checkjobs` Since: 4.0-alpha - ------------- ------------------ ---------- ----------- - Shell mode: interactive only Default: off +| Option: | `checkjobs` | Since: | 4.0-alpha | +|:------------|:-----------------|:---------|:----------| +| Shell mode: | interactive only | Default: | off | If set, Bash lists the status of any stopped and running jobs before exiting an interactive shell. If any jobs are running, this causes the @@ -81,9 +81,9 @@ stopped. ### checkwinsize - Option: `checkwinsize` Since: unknown - ------------- ---------------- ---------- --------- - Shell mode: all Default: on +| Option: | `checkwinsize` | Since: | unknown | +|:------------|:---------------|:---------|:--------| +| Shell mode: | all | Default: | on | If set, Bash checks the window size after each command and, if necessary, updates the values of the variables @@ -92,9 +92,9 @@ necessary, updates the values of the variables ### cmdhist - Option: `cmdhist` Since: unknown - ------------- ----------- ---------- --------- - Shell mode: all Default: off +| Option: | `cmdhist` | Since: | unknown | +|:------------|:----------|:---------|:--------| +| Shell mode: | all | Default: | off | If set, Bash attempts to save all lines of a multiple-line command in the same history entry. This allows easy re-editing of multi-line @@ -102,65 +102,64 @@ commands. ### compat31 - Option: `compat31` Since: 3.2 - ------------- ------------ ---------- ----- - Shell mode: all Default: off +| Option: | `compat31` | Since: | 3.2 | +|:------------|:-----------|:---------|:----| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 3.1 ### compat32 - Option: `compat32` Since: 4.0 - ------------- ------------ ---------- ----- - Shell mode: all Default: off +| Option: | `compat32` | Since: | 4.0 | +|:------------|:-----------|:---------|:----| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 3.2 ### compat40 - Option: `compat40` Since: 4.1-beta - ------------- ------------ ---------- ---------- - Shell mode: all Default: off +| Option: | `compat40` | Since: | 4.1-beta | +|:------------|:-----------|:---------|:---------| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 4.0 ### compat41 - Option: `compat41` Since: 4.2-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `compat41` | Since: | 4.2-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 4.1 ### compat42 - Option: `compat42` Since: 4.3-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `compat42` | Since: | 4.3-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 4.2 - ### compat43 - Option: `compat43` Since: 4.4-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `compat43` | Since: | 4.4-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 4.3 ### compat44 - Option: `compat44` Since: 5.0-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `compat44` | Since: | 5.0-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | Compatiblity mode for Bash 4.4 ### direxpand - Option: `direxpand` Since: 4.3-alpha - ------------- ------------- ---------- ------------------------------------------------------------------------ - Shell mode: all Default: off (unless changed on compile-time with `--enable-direxpand-default`) +| Option: | `direxpand` | Since: | 4.3-alpha | +|:------------|:------------|:---------|:-----------------------------------------------------------------------| +| Shell mode: | all | Default: | off (unless changed on compile-time with `--enable-direxpand-default`) | If set, bash replaces directory names with the results of word expansion when performing filename completion. This changes the contents of the @@ -169,27 +168,27 @@ user typed. ### dirspell - Option: `dirspell` Since: 4.0-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `dirspell` | Since: | 4.0-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | If set, Bash will perform spelling corrections on directory names to match a glob. ### dotglob - Option: `dotglob` Since: unknown - ------------- ----------- ---------- --------- - Shell mode: all Default: off +| Option: | `dotglob` | Since: | unknown | +|:------------|:----------|:---------|:--------| +| Shell mode: | all | Default: | off | If set, Bash includes filenames beginning with a `.` (dot) in the results of [pathname expansion](../syntax/expansion/globs.md). ### execfail - Option: `execfail` Since: unknown - ------------- ----------------- ---------- --------- - Shell mode: non-interactive Default: off +| Option: | `execfail` | Since: | unknown | +|:------------|:----------------|:---------|:--------| +| Shell mode: | non-interactive | Default: | off | If set, a non-interactive shell will not exit if it cannot execute the file specified as an argument to the `exec`-builtin command. An @@ -197,26 +196,26 @@ interactive shell does not exit if `exec` fails. ### expand_aliases - Option: `expand_aliases` Since: unknown - ------------- ------------------ ---------- ----------------------------------------- - Shell mode: all Default: on (interactive), off (non-interactive) +| Option: | `expand_aliases` | Since: | unknown | +|:------------|:-----------------|:---------|:----------------------------------------| +| Shell mode: | all | Default: | on (interactive), off (non-interactive) | If set, aliases are expanded. This option is enabled by default for interactive shells. ### extdebug - Option: `extdebug` Since: 3.0-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `extdebug` | Since: | 3.0-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | If set, behavior intended for use by debuggers is enabled. ### extglob - Option: `extglob` Since: 2.02-alpha1 - ------------- ----------- ---------- ------------- - Shell mode: all Default: off +| Option: | `extglob` | Since: | 2.02-alpha1 | +|:------------|:----------|:---------|:------------| +| Shell mode: | all | Default: | off | If set, the extended [pattern matching](../syntax/pattern.md) features are enabled. See the important note below under [Parser @@ -224,9 +223,9 @@ configurations](#parser_configurations). ### extquote - Option: `extquote` Since: 3.0-alpha (?) - ------------- ------------ ---------- --------------- - Shell mode: all Default: on +| Option: | `extquote` | Since: | 3.0-alpha (?) | +|:------------|:-----------|:---------|:--------------| +| Shell mode: | all | Default: | on | If set, `$'string'` and `$"string"` quoting is performed within [parameter expansions](../syntax/pe.md) enclosed in double quotes. See the @@ -235,18 +234,18 @@ configurations](#parser_configurations). ### failglob - Option: `failglob` Since: 3.0-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `failglob` | Since: | 3.0-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | If set, patterns which fail to match filenames during pathname expansion result in an error message. ### force_fignore - Option: `force_fignore` Since: 3.0-alpha - ------------- ----------------- ---------- ----------- - Shell mode: interactive Default: on +| Option: | `force_fignore` | Since: | 3.0-alpha | +|:------------|:----------------|:---------|:----------| +| Shell mode: | interactive | Default: | on | If set, the suffixes specified by the [FIGNORE](../syntax/shellvars.md#FIGNORE) shell variable cause words to be @@ -255,9 +254,9 @@ the only possible completions. This option is enabled by default. ### globasciiranges - Option: `globasciiranges` Since: 4.3-alpha - ------------- ------------------- ---------- ----------------------------------- - Shell mode: all Default: on (configurable at compile time) +| Option: | `globasciiranges` | Since: | 4.3-alpha | +|:------------|:------------------|:---------|:----------------------------------| +| Shell mode: | all | Default: | on (configurable at compile time) | If set, range expressions used in pattern matching behave as if in the traditional C locale when performing comparisons. That is, the current @@ -267,26 +266,26 @@ will collate together. ### globstar - Option: `globstar` Since: 4.0-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `globstar` | Since: | 4.0-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | If set, recursive globbing with `**` is enabled. ### gnu_errfmt - Option: `gnu_errfmt` Since: 3.0-alpha - ------------- -------------- ---------- ----------- - Shell mode: all Default: off +| Option: | `gnu_errfmt` | Since: | 3.0-alpha | +|:------------|:-------------|:---------|:----------| +| Shell mode: | all | Default: | off | -If set, shell error messages are written in the \"standard GNU error -message format\". +If set, shell error messages are written in the "standard GNU error +message format". ### histappend - Option: `histappend` Since: unknown - ------------- ----------------- ---------- --------- - Shell mode: interactive (?) Default: off +| Option: | `histappend` | Since: | unknown | +|:------------|:----------------|:---------|:--------| +| Shell mode: | interactive (?) | Default: | off | If set, the history list is appended to the file named by the value of the [HISTFILE](../syntax/shellvars.md#HISTFILE) variable when the shell @@ -294,53 +293,53 @@ exits, rather than overwriting the file. ### histreedit - Option: `histreedit` Since: unknown - ------------- ----------------- ---------- --------- - Shell mode: interactive (?) Default: off +| Option: | `histreedit` | Since: | unknown | +|:------------|:----------------|:---------|:--------| +| Shell mode: | interactive (?) | Default: | off | If set, and readline is being used, a user is given the opportunity to re-edit a failed history substitution. ### histverify - Option: `histverify` Since: unknown - ------------- ----------------- ---------- --------- - Shell mode: interactive (?) Default: off +| Option: | `histverify` | Since: | unknown | +|:------------|:----------------|:---------|:--------| +| Shell mode: | interactive (?) | Default: | off | Allow to review a history substitution result by loading the resulting line into the editing buffer, rather than directly executing it. ### hostcomplete - Option: `hostcomplete` Since: 2.0-alpha3 - ------------- ----------------- ---------- ------------ - Shell mode: interactive (?) Default: on +| Option: | `hostcomplete` | Since: | 2.0-alpha3 | +|:------------|:----------------|:---------|:-----------| +| Shell mode: | interactive (?) | Default: | on | If set, Bash completion also completes hostnames. On by default. ### huponexit - Option: `huponexit` Since: 2.02-alpha1 - ------------- ------------------- ---------- ------------- - Shell mode: interactive login Default: off +| Option: | `huponexit` | Since: | 2.02-alpha1 | +|:------------|:------------------|:---------|:------------| +| Shell mode: | interactive login | Default: | off | If set, Bash will send the `SIGHUP` signal to all jobs when an interactive login shell exits. ### interactive_comments - Option: `interactive_comments` Since: unknown - ------------- ------------------------ ---------- --------- - Shell mode: interactive Default: on +| Option: | `interactive_comments` | Since: | unknown | +|:------------|:-----------------------|:---------|:--------| +| Shell mode: | interactive | Default: | on | Allow [commenting](../scripting/basics.md#comments) in interactive shells, on by default. ### lastpipe - Option: `lastpipe` Since: 4.2-alpha - ------------- ------------ ---------- ----------- - Shell mode: all Default: off +| Option: | `lastpipe` | Since: | 4.2-alpha | +|:------------|:-----------|:---------|:----------| +| Shell mode: | all | Default: | off | If set, **and job control is not active**, the shell runs the last command of a pipeline not executed in the background in the current @@ -348,9 +347,9 @@ shell environment. ### lithist - Option: `lithist` Since: unknown - ------------- ------------- ---------- --------- - Shell mode: interactive Default: off +| Option: | `lithist` | Since: | unknown | +|:------------|:------------|:---------|:--------| +| Shell mode: | interactive | Default: | off | If set, and the [#cmdhist](#cmdhist) option is enabled, multi-line commands are saved to the history with embedded newlines rather than @@ -358,36 +357,36 @@ using semicolon separators where possible. ### localvar_inherit - Option: `localvar_inherit` Since: 5.0-alpha - ------------- -------------------- ---------- ----------- - Shell mode: all Default: off +| Option: | `localvar_inherit` | Since: | 5.0-alpha | +|:------------|:-------------------|:---------|:----------| +| Shell mode: | all | Default: | off | If this option is set, a local variable inherits the value of a variable with the same name at the nearest preceding scope. ### login_shell - Option: `login_shell` Since: 2.05a-alpha1 - ------------- --------------- ---------- -------------- - Shell mode: all Default: n/a +| Option: | `login_shell` | Since: | 2.05a-alpha1 | +|:------------|:--------------|:---------|:-------------| +| Shell mode: | all | Default: | n/a | The option is set when Bash is a login shell. This is a readonly option. ### mailwarn - Option: `mailwarn` Since: unknown - ------------- ----------------- ---------- --------- - Shell mode: interactive (?) Default: off +| Option: | `mailwarn` | Since: | unknown | +|:------------|:----------------|:---------|:--------| +| Shell mode: | interactive (?) | Default: | off | If set, and a file that Bash is checking for mail has been accessed -since the last time it was checked, the message \"The mail in mailfile -has been read\" is displayed. +since the last time it was checked, the message "The mail in mailfile +has been read" is displayed. ### no_empty_cmd_completion - Option: `mailwarn` Since: unknown - ------------- ----------------- ---------- --------- - Shell mode: interactive (?) Default: off +| Option: | `mailwarn` | Since: | unknown | +|:------------|:----------------|:---------|:--------| +| Shell mode: | interactive (?) | Default: | off | If set, and readline is being used, Bash will not attempt to search the PATH for possible completions when completion is attempted on an empty @@ -395,45 +394,45 @@ line. ### nocaseglob - Option: `nocaseglob` Since: 2.02-alpha1 - ------------- -------------- ---------- ------------- - Shell mode: all Default: off +| Option: | `nocaseglob` | Since: | 2.02-alpha1 | +|:------------|:-------------|:---------|:------------| +| Shell mode: | all | Default: | off | If set, Bash matches filenames in a case-insensitive fashion when performing pathname expansion. ### nocasematch - Option: `nocasematch` Since: 3.1-alpha1 - ------------- --------------- ---------- ------------ - Shell mode: all Default: off +| Option: | `nocasematch` | Since: | 3.1-alpha1 | +|:------------|:--------------|:---------|:-----------| +| Shell mode: | all | Default: | off | If set, Bash matches patterns in a case-insensitive fashion when performing matching while executing `case` or `[[` conditional commands. ### nullglob - Option: `nullglob` Since: unknown - ------------- ------------ ---------- --------- - Shell mode: all Default: off +| Option: | `nullglob` | Since: | unknown | +|:------------|:-----------|:---------|:--------| +| Shell mode: | all | Default: | off | If set, Bash allows patterns which match no files to expand to a null string, rather than themselves. ### progcomp - Option: `progcomp` Since: 2.04-alpha1 - ------------- ----------------- ---------- ------------- - Shell mode: interactive (?) Default: on +|Option:|`progcomp`|Since:|2.04-alpha1| +|-------|----------|------|----------| +|Shell mode:|interactive (?)|Default:|on| If set, the programmable completion facilities are enabled. This option is enabled by default. ### promptvars - Option: `promptvars` Since: unknown - ------------- -------------- ---------- --------- - Shell mode: interactive Default: on +|Option:|`promptvars`|Since:|unknown| +|-------|------------|------|-------| +|Shell mode:|interactive|Default:|on| If set, prompt strings undergo parameter expansion, command substitution, arithmetic expansion, and quote removal after being @@ -442,27 +441,27 @@ default. ### restricted_shell - Option: `restricted_shell` Since: 2.03-alpha - ------------- -------------------- ---------- ------------ - Shell mode: interactive (?) Default: off +|Option:|`restricted_shell`|Since:|2.03-alpha| +|-------|------------------|------|-------| +|Shell mode:|interactive (?)|Default:|off| The option is set when Bash is a restricted shell. This is a readonly option. ### shift_verbose - Option: `shift_verbose` Since: unknown - ------------- ----------------- ---------- ----------------------- - Shell mode: all Default: off, on in POSIX mode +|Option:|`shift_verbose`|Since:|unknown| +|-------|---------------|------|-------| +|Shell mode:|all|Default:|off, on in POSIX mode| If set, the shift builtin prints an error message when the shift count exceeds the number of positional parameters. ### sourcepath - Option: `sourcepath` Since: unknown - ------------- -------------- ---------- --------- - Shell mode: all Default: on +|Option:|`sourcepath`|Since:|unknown| +|-------|------------|------|-------| +|Shell mode:|all|Default:|on| If set, the source builtin command uses the value of PATH to find the directory containing the file supplied as an argument. This option is @@ -470,9 +469,9 @@ enabled by default. ### syslog_history - Option: `syslog_history` Since: 5.0-alpha - ------------- ------------------ ---------- ----------- - Shell mode: unknown Default: off +|Option:|`syslog_history`|Since:|5.0-alpha| +|-------|----------------|------|--------| +|Shell mode:|unknown|Default:|off| If set, the shell history is sent to syslog. @@ -481,9 +480,9 @@ syslog. ### xpg_echo - Option: `xpg_echo` Since: 2.04-beta1 - ------------- ------------ ---------- ------------ - Shell mode: all Default: off +|Option:|`xpg_echo`|Since:|2.04-beta1| +|-------|----------|------|----------| +|Shell mode:|all|Default:|off| If set, the `echo`-builtin command expands backslash-escape sequences by default (POSIX, SUS, XPG). diff --git a/docs/misc/bashphorisms.md b/docs/misc/bashphorisms.md index adb2f44..70463c4 100644 --- a/docs/misc/bashphorisms.md +++ b/docs/misc/bashphorisms.md @@ -5,48 +5,48 @@ in mind that this version is a snapshot, the bashphorisms are changed here and there. Also, [another snapshot](http://mywiki.wooledge.org/BashFAQ/064). -I think `greycat` was the first one who had the idea, but I\'m not sure. +I think `greycat` was the first one who had the idea, but I'm not sure. Our bashphorisms can be queried from `greybot` using `!bN`, where `N` is the bashphorism number. And yes, these bashphorisms reflect the daily reality in `#bash`. - Number Bashphorism - -------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------- - 0 The questioner will never tell you what they are really doing the first time they ask. - 1 The questioner's first description of the problem/question will be misleading. - 2 The questioner will keep changing the question until it drives the helpers in the channel insane. - 3 Offtopicness will continue until someone asks a bash question that falls under bashphorisms 1 and/or 2, and `greycat` gets pissed off. - 4 The questioner will not read and apply the answers he is given but will instead continue to practice bashphorism #1 and bashphorism #2. - 5 The ignorant will continually mis-educate the other noobies. - 6 When given a choice of solutions, the newbie will always choose the wrong one. - 7 The newbie will always find a reason to say, \"It doesn't work.\" - 8 If you don't know to whom the bashphorism's referring, it's you. - 9 All examples given by the questioner will be broken, misleading, wrong, and not representative of the actual question. - 10 See B1 - 11 Please apply `(( % 10 ))` to the bashphorism value. - 12 All logic is deniable; however, some logic will \*plonk\* you if you deny it. - 13 Everyone ignores greycat when he is right. When he is wrong, it is !b1 - 14 The newbie doesn't actually know what he's asking. If he did, he wouldn't need to ask. - 15 The more advanced you are, the more likely you are to be overcomplicating it. - 16 The more beginner you are, the more likely you are to be overcomplicating it. - 17 A newbie comes to #bash to get his script confirmed. He leaves disappointed. - 18 The newbie will not accept the answer you give, no matter how right it is. - 19 The newbie is a bloody loon. - 20 The newbie will always have some excuse for doing it wrong. - 21 When the newbie's question is ambiguous, the proper interpretation will be whichever one makes the problem the hardest to solve. - 22 The newcomer will abuse the bot's factoid triggers for their own entertainment until someone gets annoyed enough to ask them to message it privately instead. - 23 Everyone is a newcomer. - 24 The newcomer will address greybot as if it were human. - 25 The newbie won't accept any answer that uses practical or standard tools. - 26 The newbie will not TELL you about this restriction until you have wasted half an hour. - 27 The newbie will lie. - 28 When the full horror of the newbie's true goal is revealed, the newbie will try to restate the goal to trick you into answering. Newbies are stupid. - 29 It's always git. Or python virtualenv. Or docker. One of those pieces of shit. ALWAYS. - 30 They won't show you the homework assignment. That would make it too easy. - 31 Your teacher is a f\*\*king idiot. - 32 The more horrifyingly wrong a proposed solution is, the more likely it will be used. - 33 The newbie cannot explain what he is doing, or why. He will show you incomprehensible, nonworking code instead. What? You can't read his mind?! +|Number|Bashphorism| +|------|-----------| +|0|The questioner will never tell you what they are really doing the first time they ask.| +|1|The questioner's first description of the problem/question will be misleading.| +|2|The questioner will keep changing the question until it drives the helpers in the channel insane.| +|3|Offtopicness will continue until someone asks a bash question that falls under bashphorisms 1 and/or 2, and `greycat` gets pissed off.| +|4|The questioner will not read and apply the answers he is given but will instead continue to practice bashphorism #1 and bashphorism #2.| +|5|The ignorant will continually mis-educate the other noobies.| +|6|When given a choice of solutions, the newbie will always choose the wrong one.| +|7|The newbie will always find a reason to say, "It doesn't work."| +|8|If you don't know to whom the bashphorism's referring, it's you.| +|9|All examples given by the questioner will be broken, misleading, wrong, and not representative of the actual question.| +|10|See B1| +|11|Please apply `(( % 10 ))` to the bashphorism value.| +|12|All logic is deniable; however, some logic will *plonk* you if you deny it.| +|13|Everyone ignores greycat when he is right. When he is wrong, it is !b1| +|14|The newbie doesn't actually know what he's asking. If he did, he wouldn't need to ask.| +|15|The more advanced you are, the more likely you are to be overcomplicating it.| +|16|The more beginner you are, the more likely you are to be overcomplicating it.| +|17|A newbie comes to #bash to get his script confirmed. He leaves disappointed.| +|18|The newbie will not accept the answer you give, no matter how right it is.| +|19|The newbie is a bloody loon.| +|20|The newbie will always have some excuse for doing it wrong.| +|21|When the newbie's question is ambiguous, the proper interpretation will be whichever one makes the problem the hardest to solve.| +|22|The newcomer will abuse the bot's factoid triggers for their own entertainment until someone gets annoyed enough to ask them to message it privately instead.| +|23|Everyone is a newcomer.| +|24|The newcomer will address greybot as if it were human.| +|25|The newbie won't accept any answer that uses practical or standard tools.| +|26|The newbie will not TELL you about this restriction until you have wasted half an hour.| +|27|The newbie will lie.| +|28|When the full horror of the newbie's true goal is revealed, the newbie will try to restate the goal to trick you into answering. Newbies are stupid.| +|29|It's always git. Or python virtualenv. Or docker. One of those pieces of shit. ALWAYS.| +|30|They won't show you the homework assignment. That would make it too easy.| +|31|Your teacher is a f**king idiot.| +|32|The more horrifyingly wrong a proposed solution is, the more likely it will be used.| +|33|The newbie cannot explain what he is doing, or why. He will show you incomprehensible, nonworking code instead. What? You can't read his mind?!| Please feel free to correct or extend this page whenever needed. diff --git a/docs/scripting/bashbehaviour.md b/docs/scripting/bashbehaviour.md index 974274a..e243c3f 100644 --- a/docs/scripting/bashbehaviour.md +++ b/docs/scripting/bashbehaviour.md @@ -12,13 +12,14 @@ tags: # Bash's behaviour -FIXME incomplete +!!! warning "FIXME" + incomplete ## Bash startup modes ### Login shell -As a \"login shell\", Bash reads and sets (executes) the user's profile +As a "login shell", Bash reads and sets (executes) the user's profile from `/etc/profile` and one of `~/.bash_profile`, `~/.bash_login`, or `~/.profile` (in that order, using the first one that's readable!). @@ -27,20 +28,20 @@ When a login shell exits, Bash reads and executes commands from the file Why an extra login shell mode? There are many actions and variable sets that only make sense for the initial user login. That's why all UNIX(r) -shells have (should have) a \"login\" mode. +shells have (should have) a "login" mode. -[**Methods to start Bash as a login shell:**]{.underline} +**Methods to start Bash as a login shell:** - the first character of `argv[0]` is `-` (a hyphen): traditional UNIX(r) shells start from the `login` binary - Bash is started with the `-l` option - Bash is started with the `--login` option -[**Methods to test for login shell mode:**]{.underline} +**Methods to test for login shell mode:** - the shell option `login_shell` is set -[**Related switches:**]{.underline} +**Related switches:** - `--noprofile` disables reading of all profile files @@ -49,7 +50,7 @@ shells have (should have) a \"login\" mode. When Bash starts as an interactive non-login shell, it reads and executes commands from `~/.bashrc`. This file should contain, for example, aliases, since they need to be defined in every shell as -they\'re not inherited from the parent shell. +they're not inherited from the parent shell. The feature to have a system-wide `/etc/bash.bashrc` or a similar system-wide rc-file is specific to vendors and distributors that ship @@ -57,11 +58,11 @@ system-wide rc-file is specific to vendors and distributors that ship system-wide rc file is to `source /etc/bashrc` from every user's `~/.bashrc`. -[**Methods to test for interactive-shell mode:**]{.underline} +**Methods to test for interactive-shell mode:** - the special parameter `$-` contains the letter `i` (lowercase I) -[**Related switches:**]{.underline} +**Related switches:** - `-i` forces the interactive mode - `--norc` disables reading of the startup files (e.g. @@ -83,7 +84,7 @@ used as the name of the startup file. After the startup files are read, Bash enters the [POSIX(r) compatiblity mode (for running, not for starting!)](#posix_run_mode). -[**Bash starts in `sh` compatiblity mode when:**]{.underline} +**Bash starts in `sh` compatiblity mode when:** - the base filename in `argv[0]` is `sh` (:!: NB: `/bin/sh` may be linked to `/bin/bash`, but that doesn't mean it acts like @@ -94,11 +95,11 @@ mode (for running, not for starting!)](#posix_run_mode). When Bash is started in POSIX(r) mode, it follows the POSIX(r) standard for startup files. In this mode, **interactive shells** expand the [ENV](../syntax/shellvars.md#ENV) variable and commands are read and executed -from the file whose name is the expanded value.\ +from the file whose name is the expanded value. No other startup files are read. Hence, a non-interactive shell doesn't read any startup files in POSIX(r) mode. -[**Bash starts in POSIX(r) mode when:**]{.underline} +**Bash starts in POSIX(r) mode when:** - the commandline option `--posix` is specified - the environment variable @@ -112,13 +113,13 @@ read any startup files in POSIX(r) mode. Bash usually reads the first file found, when multiple choices are given (for user files in `~/`) - Mode `/etc/profile` `~/.bash_profile` `~/.bash_login` `~/.profile` `~/.bashrc` `${ENV}` - ----------------------- ---------------- ------------------- ----------------- -------------- ------------- ---------- - Login shell X X X X - - - Interactive shell - - - - X - - SH compatible login X - - X - - - SH compatible - - - - - X - POSIX(r) compatiblity - - - - - X +|Mode|`/etc/profile`|`~/.bash_profile`|`~/.bash_login`|`~/.profile`|`~/.bashrc`|`${ENV}`| +|--|--|--|--|--|--|--| +|Login shell|✅|✅|✅|✅|🚫|🚫| +|Interactive shell|🚫|🚫|🚫|🚫|✅|🚫| +|SH compatible login|✅|🚫|🚫|✅|🚫|🚫| +|SH compatible|🚫|🚫|🚫|🚫|🚫|✅| +|POSIX(r) compatiblity|🚫|🚫|🚫|🚫|🚫|✅| ## Bash run modes @@ -304,9 +305,10 @@ and parsing (excerpt from a Bash maintainer's document): Bash can be configured to be POSIX-conformant by default, by specifying the `--enable-strict-posix-default' to `configure' when building. -FIXME help me to find out what breaks in POSIX(r) mode! +!!! warning "FIXME" + help me to find out what breaks in POSIX(r) mode! -[**The POSIX(r) mode can be switched on by:**]{.underline} +**The POSIX(r) mode can be switched on by:** - Bash starting as `sh` (the basename of `argv[0]` is `sh`) - starting Bash with the commandline option `--posix` @@ -314,7 +316,7 @@ FIXME help me to find out what breaks in POSIX(r) mode! [POSIXLY_CORRECT](../syntax/shellvars.md#POSIXLY_CORRECT) is set - the command `set -o posix` -[**Tests for the POSIX(r) mode:**]{.underline} +**Tests for the POSIX(r) mode:** - the variable [SHELLOPTS](../syntax/shellvars.md#SHELLOPTS) contains `posix` in its list @@ -330,7 +332,7 @@ like normal Bash with the following restrictions: [PATH](../syntax/shellvars.md#PATH), [ENV](../syntax/shellvars.md#ENV) and [BASH_ENV](../syntax/shellvars.md#BASH_ENV) can't be set or unset - command names that contain a `/` (slash) can't be called (hence - you\'re limited to `PATH`) + you're limited to `PATH`) - filenames containing a `/` (slash) can't be specified as argument to the `source` or `.` builtin command - filenames containing a `/` (slash) can't be specified as argument @@ -351,19 +353,19 @@ like normal Bash with the following restrictions: - turning off restricted mode with `set +r` or `set +o restricted` is (of course) forbidden -The \"-r\" restrictions are turned on **after** Bash has read its +The "-r" restrictions are turned on **after** Bash has read its startup files. When the command that is run is a shell script, then the restrictions are **turned off** for the (sub-)shell that runs that shell script. -[**The restricted shell can be switched on by:**]{.underline} +**The restricted shell can be switched on by:** - calling Bash as `rbash` (the basename of `argv[0]` is `rbash`) - calling Bash with the `-r` option - calling Bash with the `--restricted` option -[**Tests for restricted mode:**]{.underline} +**Tests for restricted mode:** - the special parameter `$-` contains the letter `r` (lowercase R) - the shell option `restricted_shell` is set and can be checked by the diff --git a/docs/scripting/bashchanges.md b/docs/scripting/bashchanges.md index b513955..4fb3cee 100644 --- a/docs/scripting/bashchanges.md +++ b/docs/scripting/bashchanges.md @@ -22,56 +22,56 @@ For this topic, see also - [shell_options](../internals/shell_options.md) - [set](../commands/builtin/set.md) - Feature or change description Appeared in Bash version See also/remarks - --------------------------------- -------------------------- --------------------------------------------------------------------------------- - `posix` (for `set -o`) 1.14.0 - `hostcomplete` 2.0-alpha3 - `expand_aliases` 2.0 - `huponexit` 2.02-alpha1 - `nocaseglob` 2.02-alpha1 - `extglob` 2.02-alpha1 together with extended globbing, KSH88 - `restricted_shell` 2.03-alpha - `xpg_echo` 2.04-beta1 - `progcomp` 2.04-alpha1 - `no_empty_command_completion` 2.04 - `login_shell` 2.05a-alpha1 - `nolog` (for `set -o`) 2.05a - `gnu_errfmt` 3.0-alpha - `force_fignore` 3.0-alpha - `failglob` 3.0-alpha - `extquote` 3.0-alpha unsure -- verify! - `extdebug` 3.0-alpha - `pipefail` (for `set -o`) 3.0 - `functrace` (for `set -o`) 3.0 - `errtrace` (for `set -o`) 3.0 - `nocasematch` 3.1-alpha1 - `dirspell` 4.0-alpha - `globstar` 4.0-alpha - `checkjobs` 4.0-alpha - `autocd` 4.0-alpha - `set -e` effects more intuitive 4.0 not directly specified by POSIX, but in consensus with POSIX WG - `compat40` 4.1-beta - `lastpipe` 4.2-alpha only works with job control disabled - `compat41` 4.2-alpha - `globasciiranges` 4.3-alpha enable \"character range globbing\" to always act as if in `C` locale - `compat42` 4.3-alpha - `compat43` 4.4-alpha - `compat44` 5.0-alpha - `localvar_inherit` 5.0-alpha local variables inherit preceeding scope values if they have the same name - `syslog_history` 5.0-alpha send history lines to syslog (undocumented, default off) if syslog is supported - `assoc_expand_once` 5.0-alpha expand associative array subscripts only one - `globasciiranges` 5.0-beta New default: on (default may be configured at compile time) - `localvar_inherit` 5.0-beta guard code against inheriting from an incompatible data type - `checkwinsize` 5.0-beta2 New default: on - `shift_verbose` 5.0-beta2 Default on when in POSIX mode +|Feature or change description|Appeared in Bash version|See also/remarks| +|--|--|--| +|`posix` (for `set -o`)|1.14.0|| +|`hostcomplete`|2.0-alpha3|| +|`expand_aliases`|2.0|| +|`huponexit`|2.02-alpha1|| +|`nocaseglob`|2.02-alpha1|| +|`extglob`|2.02-alpha1|together with extended globbing, KSH88| +|`restricted_shell`|2.03-alpha|| +|`xpg_echo`|2.04-beta1|| +|`progcomp`|2.04-alpha1|| +|`no_empty_command_completion`|2.04|| +|`login_shell`|2.05a-alpha1|| +|`nolog` (for `set -o`)|2.05a|| +|`gnu_errfmt`|3.0-alpha|| +|`force_fignore`|3.0-alpha|| +|`failglob`|3.0-alpha|| +|`extquote`|3.0-alpha|unsure -- verify!| +|`extdebug`|3.0-alpha|| +|`pipefail` (for `set -o`)|3.0|| +|`functrace` (for `set -o`)|3.0|| +|`errtrace` (for `set -o`)|3.0|| +|`nocasematch`|3.1-alpha1|| +|`dirspell`|4.0-alpha|| +|`globstar`|4.0-alpha|| +|`checkjobs`|4.0-alpha|| +|`autocd`|4.0-alpha|| +|`set -e` effects more intuitive|4.0|not directly specified by POSIX, but in consensus with POSIX WG| +|`compat40`|4.1-beta|| +|`lastpipe`|4.2-alpha|only works with job control disabled| +|`compat41`|4.2-alpha|| +|`globasciiranges`|4.3-alpha|enable "character range globbing" to always act as if in `C` locale| +|`compat42`|4.3-alpha|| +|`compat43`|4.4-alpha|| +|`compat44`|5.0-alpha|| +|`localvar_inherit`|5.0-alpha|local variables inherit preceeding scope values if they have the same name| +|`syslog_history`|5.0-alpha|send history lines to syslog (undocumented, default off) if syslog is supported| +|`assoc_expand_once`|5.0-alpha|expand associative array subscripts only one| +|`globasciiranges`|5.0-beta|New default: on (default may be configured at compile time)| +|`localvar_inherit`|5.0-beta|guard code against inheriting from an incompatible data type| +|`checkwinsize`|5.0-beta2|New default: on| +|`shift_verbose`|5.0-beta2|Default on when in POSIX mode| ### General (all/many builtins) - Feature or change description Appeared in Bash version See also/remarks - ----------------------------------------------------------------------- -------------------------- ----------------------------------------------------------------- - generally return 2 on usage error 2.0 - generally accept `--` (end of options) 2.0 - (where applicable) implement a `-p` option to produce reusable output 2.0 `shopt` and `umask` builtins were fixed to support that in 2.02 +|Feature or change description|Appeared in Bash version|See also/remarks| +|--|--|--| +|generally return 2 on usage error|2.0|| +|generally accept `--` (end of options)|2.0|| +|(where applicable) implement a `-p` option to produce reusable output|2.0|`shopt` and `umask` builtins were fixed to support that in 2.02| ### printf @@ -79,20 +79,20 @@ For this topic, see also - [printf](../commands/builtin/printf.md) - Feature or change description Appeared in Bash version See also/remarks - ------------------------------------------------------------- -------------------------- -------------------------------------------------------- - new `printf` command 2.02-alpha1 - respects `0..` and `0x..` prefixed numbers 2.04-beta1 consistency with arithmetic - POSIX(r) length specifiers `j`, `t` and `z` 2.05a-alpha1 ISO C99 - POSIX(r) flag `'` 2.05a-alpha1 - conversion `a` and `A` 2.05a-rc1 if provided by the underlying printf(3) - conversion `F` 2.05a-rc1 - conversion `n` 2.05a-rc1 - new option `-v` 3.1-alpha1 - escape sequences `\"` and `\?` 3.0-beta1 - modified option `-v` to assign to individual array elements 4.1-alpha - conversion `(...)T` 4.2-alpha support stftime(3) date/time format; uses current time - `\uNNNN` and `\UNNNNNNNN` escape sequences 4.2-alpha for: `printf`, `echo -e`, `$'...'` +|Feature or change description|Appeared in Bash version|See also/remarks| +|--|--|--| +|new `printf` command|2.02-alpha1|| +|respects `0..` and `0x..` prefixed numbers|2.04-beta1|consistency with arithmetic| +|POSIX(r) length specifiers `j`, `t` and `z`|2.05a-alpha1|ISO C99| +|POSIX(r) flag `'`|2.05a-alpha1|| +|conversion `a` and `A`|2.05a-rc1|if provided by the underlying printf(3)| +|conversion `F`|2.05a-rc1|| +|conversion `n`|2.05a-rc1|| +|new option `-v`|3.1-alpha1|| +|escape sequences `\"` and `\?`|3.0-beta1|| +|modified option `-v` to assign to individual array elements|4.1-alpha|| +|conversion `(...)T`|4.2-alpha|support stftime(3) date/time format; uses current time| +|`\uNNNN` and `\UNNNNNNNN` escape sequences|4.2-alpha|for: `printf`, `echo -e`, `$'...'`| ### Conditional expressions and test command @@ -101,141 +101,141 @@ For this topic, see also - [conditional_expression](../syntax/ccmd/conditional_expression.md) - [classictest](../commands/classictest.md) - Feature or change description Appeared in Bash version See also/remarks - -------------------------------------------------------------------- -------------------------- -------------------------------------------------------------------------------------- - `test`: `-o`, `==`, `<` and `>` 2.0 - `test`: `-N` 2.02 - `[[...]]`: new 2.02-alpha1 KSH93 - `[[...]]`: regex support (`=~`) 3.0-alpha - `[[...]]`: quotable right-hand-side of `=~` forces string matching 3.2-alpha for consistency with pattern matching - `[[...]]`: `<` and `>` operators respect locale 4.1-alpha for consistency, since 4.1-beta: ensure you have set compatiblity to >4.0 (default) - `test`/`[`/`[[`: `-v` 4.2-alpha check if a variable is set - `test`/`[`/`[[`: `-v` 4.2-alpha support array syntax to check for elements - `test`/`[`/`[[`: `-N` accepts nanoseconds 5.1-alpha - `test`/`[`/`[[`: `-v` accepts positional parameters 5.1-alpha +|Feature or change description|Appeared in Bash version|See also/remarks| +|--|--|--| +|`test`: `-o`, `==`, `<` and `>`|2.0|| +|`test`: `-N`|2.02|| +|`[[...]]`: new|2.02-alpha1|KSH93| +|`[[...]]`: regex support (`=~`)|3.0-alpha|| +|`[[...]]`: quotable right-hand-side of `=~` forces string matching|3.2-alpha|for consistency with pattern matching| +|`[[...]]`: `<` and `>` operators respect locale|4.1-alpha|for consistency, since 4.1-beta: ensure you have set compatiblity to \>4.0 (default)| +|`test`/`[`/`[[`: `-v`|4.2-alpha|check if a variable is set| +|`test`/`[`/`[[`: `-v`|4.2-alpha|support array syntax to check for elements| +|`test`/`[`/`[[`: `-N` accepts nanoseconds|5.1-alpha|| +|`test`/`[`/`[[`: `-v` accepts positional parameters|5.1-alpha|| ### Other builtins and keywords - Builtin Feature or change description Appeared in Bash version See also/remarks - ----------------------- -------------------------------------------------------------------------------------------------------------------------------------------- -------------------------- ----------------------------------------------------------------------------------------------- - `bashbug` new 1.14.0 - `select` new 1.14.0 - `disown` new 2.0 - `shopt` new 2.0 [shopt](../commands/builtin/shopt.md) - `declare` new options `-a` and `-F` 2.0 - `enable` builtin has basic plugin support (dlopen) 2.0 - `exec` options `-l`, `-c` and `-a` 2.0 - `read` options `-p`, `-e` and `-a` 2.0 [read](../commands/builtin/read.md) - `readonly` option `-a` 2.0 [arrays](../syntax/arrays.md) - `time` new keyword 2.0 - `shopt` `-p` (reusable output) 2.02 - `umask` `-p` (reusable output) 2.02 - `complete` new 2.04-devel for and together with support for programmable completion - `compgen` new 2.04-devel for and together with support for programmable completion - `read` options `-t`, `-n`, `-d`, `-s` 2.04-devel [read](../commands/builtin/read.md) - `for ((...;...;...))` new 2.04-devel KSH93 - `set` print shell functions in a format reusable as input 2.05-beta1 - `for` allow an empty word list 2.05a-alpha1 - `read` new option `-u` 2.05b-alpha1 [read](../commands/builtin/read.md) - `caller` new 3.0 [caller](../commands/builtin/caller.md) - `coproc` new 4.0-alpha - `declare` new options `-l` and `-u` 4.0-alpha together with case-changing expansion forms - `case` new action list terminators \'\';;& and \'\';& 4.0-alpha ksh93: only `;&`. zsh and mksh: `;|`. mksh: all 4, (`;;&` is undocumented Bash compatibility) - `read` changed `-t` (fractional seconds) 4.0-alpha - `mapfile` new 4.0-alpha - `read` new option `-i` 4.0-alpha - `compopt` new 4.0-alpha - `read` modified option `-t` to test for data 4.0-beta - `read` new option `-N` 4.1-alpha - `mapfile` changed behaviour regarding history spamming 4.1-alpha - `declare` new option `-g` 4.2-alpha - `mapfile` calls the callback with an additional argument: The line (data) 4.2-alpha - `cd` new option `-e` 4.2-alpha - `echo` `\uNNNN` and `\UNNNNNNNN` escape sequences 4.2-alpha for: `printf`, `echo -e`, `$'...'` - `exec` option `-a` to give a `argv[0]` string 4.2-alpha - `time` allowed as a command by itself to display timing values of the shell and its children 4.2-alpha POSIX change - `help` `help` now searches exact topic-strings (i.e. `help read` won't find `readonly` anymore) 4.3-alpha - `return` accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller) 4.3-alpha - `exit` accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller) 4.3-alpha - `read` `read` skips `NUL` (ASCII Code 0) in input 4.3-alpha - `declare` new option `-n`/`+n` to support nameref variable type 4.3-alpha - `wait` new option `-n` to wait for the next background job to finish, returning its exit status. 4.3-alpha - `read` `read` checks first variable argument for validity before trying to read inout 4.3-beta - `help` attempts substring matching (as it did through bash-4.2) if exact string matching fails 4.3-beta2 - `fc` interprets option `-0` (zero) as the current command line 4.3-beta2 - `cd` new option `-@` to browse a file's extended attributes (on systems that support `O_XATTR`) 4.3-rc1 - `kill` new option `-L` (upper case ell) to list signals like the normal lowercase option `-l` (compatiblity with some standalone `kill` commands) 4.4-beta - `mapfile` new option `-d` 4.4-alpha - `wait` new option `-f` 5.0-alpha - `history` option `-d` allows negative numbers to index from the end of the history list 5.0-alpha - `umask` allows modes greater than octal 777 5.0-alpha - `times` honors current locale settings when printing decimal points 5.0-alpha - `kill` New options `-n SIGNUMBER` and `-s SIGNAME` 5.0-beta2 [kill](../commands/builtin/kill.md) - `select` Support for an empty wordlist following `in` 5.0-beta2 - `read` Option `-e` (use ReadLine to obtain input) now works with arbitrary file descriptors (given by `-u` option) 5.1-alpha - `trap` `-p` option prints signals with SIG_DFL/SIG_IGN on shell start (POSIX mode) 5.1-alpha - `unset` automatically tries to unset a function if the given name is an invalid variable name 5.1-aplha - `wait` option `-n` now accepts a list of jobs 5.1-alpha - `wait` new option `-p NAME` to store PID/JobID (useful when waiting for a list of jobs) 5.1-alpha - `local` new option `-p` to print local variables in the current scope 5.1-alpha - `ulimit` new option `-R` to get/set `RLIMIT_RTTIME` resource 5.1-alpha +|Builtin|Feature or change description|Appeared in Bash version|See also/remarks| +|--|--|--|--| +|`bashbug`|new|1.14.0|| +|`select`|new|1.14.0|| +|`disown`|new|2.0|| +|`shopt`|new|2.0|[shopt](../commands/builtin/shopt.md)| +|`declare`|new options `-a` and `-F`|2.0|| +|`enable`|builtin has basic plugin support (dlopen)|2.0|| +|`exec`|options `-l`, `-c` and `-a`|2.0|| +|`read`|options `-p`, `-e` and `-a`|2.0|[read](../commands/builtin/read.md)| +|`readonly`|option `-a`|2.0|[arrays](../syntax/arrays.md)| +|`time`|new keyword|2.0|| +|`shopt`|`-p` (reusable output)|2.02|| +|`umask`|`-p` (reusable output)|2.02|| +|`complete`|new|2.04-devel|for and together with support for programmable completion| +|`compgen`|new|2.04-devel|for and together with support for programmable completion| +|`read`|options `-t`, `-n`, `-d`, `-s`|2.04-devel|[read](../commands/builtin/read.md)| +|`for ((...;...;...))`|new|2.04-devel|KSH93| +|`set`|print shell functions in a format reusable as input|2.05-beta1|| +|`for`|allow an empty word list|2.05a-alpha1|| +|`read`|new option `-u`|2.05b-alpha1|[read](../commands/builtin/read.md)| +|`caller`|new|3.0|[caller](../commands/builtin/caller.md)| +|`coproc`|new|4.0-alpha|| +|`declare`|new options `-l` and `-u`|4.0-alpha|together with case-changing expansion forms| +|`case`|new action list terminators '';;& and '';&|4.0-alpha|ksh93: only `;&`. zsh and mksh: `;|`. mksh: all 4, (`;;&` is undocumented Bash compatibility)| +|`read`|changed `-t` (fractional seconds)|4.0-alpha|| +|`mapfile`|new|4.0-alpha|| +|`read`|new option `-i`|4.0-alpha|| +|`compopt`|new|4.0-alpha|| +|`read`|modified option `-t` to test for data|4.0-beta|| +|`read`|new option `-N`|4.1-alpha|| +|`mapfile`|changed behaviour regarding history spamming|4.1-alpha|| +|`declare`|new option `-g`|4.2-alpha|| +|`mapfile`|calls the callback with an additional argument: The line (data)|4.2-alpha|| +|`cd`|new option `-e`|4.2-alpha|| +|`echo`|`\uNNNN` and `\UNNNNNNNN` escape sequences|4.2-alpha|for: `printf`, `echo -e`, `$'...'`| +|`exec`|option `-a` to give a `argv[0]` string|4.2-alpha|| +|`time`|allowed as a command by itself to display timing values of the shell and its children|4.2-alpha|POSIX change| +|`help`|`help` now searches exact topic-strings (i.e. `help read` won't find `readonly` anymore)|4.3-alpha|| +|`return`|accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller)|4.3-alpha|| +|`exit`|accept negative values as return value (e.g. `return -1` will show as (8 bit) 255 in the caller)|4.3-alpha|| +|`read`|`read` skips `NUL` (ASCII Code 0) in input|4.3-alpha|| +|`declare`|new option `-n`/`+n` to support nameref variable type|4.3-alpha|| +|`wait`|new option `-n` to wait for the next background job to finish, returning its exit status.|4.3-alpha|| +|`read`|`read` checks first variable argument for validity before trying to read inout|4.3-beta|| +|`help`|attempts substring matching (as it did through bash-4.2) if exact string matching fails|4.3-beta2|| +|`fc`|interprets option `-0` (zero) as the current command line|4.3-beta2|| +|`cd`|new option `-@` to browse a file's extended attributes (on systems that support `O_XATTR`)|4.3-rc1|| +|`kill`|new option `-L` (upper case ell) to list signals like the normal lowercase option `-l` (compatiblity with some standalone `kill` commands)|4.4-beta|| +|`mapfile`|new option `-d`|4.4-alpha|| +|`wait`|new option `-f`|5.0-alpha|| +|`history`|option `-d` allows negative numbers to index from the end of the history list|5.0-alpha|| +|`umask`|allows modes greater than octal 777|5.0-alpha|| +|`times`|honors current locale settings when printing decimal points|5.0-alpha|| +|`kill`|New options `-n SIGNUMBER` and `-s SIGNAME`|5.0-beta2|[kill](/commands/builtin/kill)| +|`select`|Support for an empty wordlist following `in`|5.0-beta2|| +|`read`|Option `-e` (use ReadLine to obtain input) now works with arbitrary file descriptors (given by `-u` option)|5.1-alpha|| +|`trap`|`-p` option prints signals with SIG_DFL/SIG_IGN on shell start (POSIX mode)|5.1-alpha|| +|`unset`|automatically tries to unset a function if the given name is an invalid variable name|5.1-aplha|| +|`wait`|option `-n` now accepts a list of jobs|5.1-alpha|| +|`wait`|new option `-p NAME` to store PID/JobID (useful when waiting for a list of jobs)|5.1-alpha|| +|`local`|new option `-p` to print local variables in the current scope|5.1-alpha|| +|`ulimit`|new option `-R` to get/set `RLIMIT_RTTIME` resource|5.1-alpha|| ## Builtin variables - Feature or change description Appeared in Bash version See also - --------------------------------------------------- -------------------------- ---------------------------------------------------------------------------------- - `HISTCMD` 1.14.0 interactive usage - `PS1`, `PS2`, `PATH`, and `IFS` are unsettable 2.0 - `DIRSTACK` array variable 2.0 - `PIPESTATUS` array variable 2.0 - `BASH_VERSINFO` array variable 2.0 - `HOSTNAME` 2.0 - `SHELLOPTS` 2.0 - `MACHTYPE` 2.0 - `GLOBIGNORE` 2.0 - `HISTIGNORE` 2.0 - respect `LC_ALL` 2.0 - respect `LC_MESSAGES` 2.0 - respect `LC_CTYPE` 2.0 - respect `LC_COLLATE` 2.0 - respect `LANG` 2.0 - `GROUPS` array variable 2.01 - `GROUPS` unsettable/takes (discarded) assignments 2.04 - `FUNCNAME` 2.04 - respect `LC_NUMERIC` 2.04 - `TMOUT` 2.05b - `BASH_REMATCH` 3.0 together with regex support in `[[...]]` - `BASH_ARGC` 3.0 debugger support - `BASH_ARGV` 3.0 debugger support - `BASH_SOURCE` 3.0 debugger support - `BASH_LINENO` 3.0 debugger support - `BASH_SUBSHELL` 3.0 debugger support - `BASH_EXECUTION_STRING` 3.0 debugger support - `BASH_COMMAND` 3.0 debugger support - `HISTTIMEFORMAT` 3.0 - `COMP_WORDBREAKS` 3.0 - respect `LC_TIME` 3.1 - `BASHPID` 4.0-alpha Added to mksh R41. - `PROMPT_DIRTRIM` 4.0 - `BASH_XTRACEFD` 4.1-alpha - `BASHOPTS` 4.1-alpha - `FUNCNEST` 4.2-alpha - `HISTSIZE` 4.3-alpha can be set to negative values for unlimited history length - `HISTFILESIZE` 4.3-alpha can be set to negative values for unlimit history file size - `CHILD_MAX` 4.3-alpha max. number of exit status of children the shell remembers - `BASH_COMPAT` 4.3-alpha set shell compatiblity levels - `EPOCHSECONDS` 5.0-alpha expands to the time in seconds since Unix epoch - `EPOCHREALTIME` 5.0-alpha expands to the time in seconds since Unix epoch with microsecond granularity - `BASH_ARGV0` 5.0-alpha get/set `$0` - `PATH` 5.0-alpha Possibility to set a static path for use in a restricted shell (at compile time) - `HISTSIZE` 5.0-beta Default can now be set at runtime - `SRANDOM` 5.1-alpha New random generator for 32bit numbers (using various methods in the backend) - `ARGV0` 5.1-alpha Respected when set in initial shell environment, then initially used to set `$0` - `BASH_REMATCH` 5.1-alpha Not readonly anymore - `PROMPT_COMMANDS` 5.1-alpha New array variable. List of commands to be executed like `PROMPT_COMMAND` - `SECONDS` 5.1-alpha Assignment using arithmetic expressions (is nominally an integer variabnle) - `RANDOM` 5.1-alpha Assignment using arithmetic expressions (is nominally an integer variabnle) - `LINENO` 5.1-alpha Not an integer variabe +|Feature or change description|Appeared in Bash version|See also| +|--|--|--| +|`HISTCMD`|1.14.0|interactive usage| +|`PS1`, `PS2`, `PATH`, and `IFS` are unsettable|2.0|| +|`DIRSTACK` array variable|2.0|| +|`PIPESTATUS` array variable|2.0|| +|`BASH_VERSINFO` array variable|2.0|| +|`HOSTNAME`|2.0|| +|`SHELLOPTS`|2.0|| +|`MACHTYPE`|2.0|| +|`GLOBIGNORE`|2.0|| +|`HISTIGNORE`|2.0|| +|respect `LC_ALL`|2.0|| +|respect `LC_MESSAGES`|2.0|| +|respect `LC_CTYPE`|2.0|| +|respect `LC_COLLATE`|2.0|| +|respect `LANG`|2.0|| +|`GROUPS` array variable|2.01|| +|`GROUPS` unsettable/takes (discarded) assignments|2.04|| +|`FUNCNAME`|2.04|| +|respect `LC_NUMERIC`|2.04|| +|`TMOUT`|2.05b|| +|`BASH_REMATCH`|3.0|together with regex support in `[[...]]`| +|`BASH_ARGC`|3.0|debugger support| +|`BASH_ARGV`|3.0|debugger support| +|`BASH_SOURCE`|3.0|debugger support| +|`BASH_LINENO`|3.0|debugger support| +|`BASH_SUBSHELL`|3.0|debugger support| +|`BASH_EXECUTION_STRING`|3.0|debugger support| +|`BASH_COMMAND`|3.0|debugger support| +|`HISTTIMEFORMAT`|3.0|| +|`COMP_WORDBREAKS`|3.0|| +|respect `LC_TIME`|3.1|| +|`BASHPID`|4.0-alpha|Added to mksh R41.| +|`PROMPT_DIRTRIM`|4.0|| +|`BASH_XTRACEFD`|4.1-alpha|| +|`BASHOPTS`|4.1-alpha|| +|`FUNCNEST`|4.2-alpha|| +|`HISTSIZE`|4.3-alpha|can be set to negative values for unlimited history length| +|`HISTFILESIZE`|4.3-alpha|can be set to negative values for unlimit history file size| +|`CHILD_MAX`|4.3-alpha|max. number of exit status of children the shell remembers| +|`BASH_COMPAT`|4.3-alpha|set shell compatiblity levels| +|`EPOCHSECONDS`|5.0-alpha|expands to the time in seconds since Unix epoch| +|`EPOCHREALTIME`|5.0-alpha|expands to the time in seconds since Unix epoch with microsecond granularity| +|`BASH_ARGV0`|5.0-alpha|get/set `$0`| +|`PATH`|5.0-alpha|Possibility to set a static path for use in a restricted shell (at compile time)| +|`HISTSIZE`|5.0-beta|Default can now be set at runtime| +|`SRANDOM`|5.1-alpha|New random generator for 32bit numbers (using various methods in the backend)| +|`ARGV0`|5.1-alpha|Respected when set in initial shell environment, then initially used to set `$0`| +|`BASH_REMATCH`|5.1-alpha|Not readonly anymore| +|`PROMPT_COMMANDS`|5.1-alpha|New array variable. List of commands to be executed like `PROMPT_COMMAND`| +|`SECONDS`|5.1-alpha|Assignment using arithmetic expressions (is nominally an integer variabnle)| +|`RANDOM`|5.1-alpha|Assignment using arithmetic expressions (is nominally an integer variabnle)| +|`LINENO`|5.1-alpha|Not an integer variabe| ## Quoting, expansions, substitutions and related @@ -243,40 +243,40 @@ For this topic, see also - [pe](../syntax/pe.md). - Feature or change description Appeared in Bash version Remarks - ------------------------------------------------------------------------------------------------------ -------------------------- --------------------------------------------------------------------------------------------------------------- - Support for integer-indexed arrays 2.0 relevant builtins also got array support - `${PARAMETER//PATTERN/REPLACEMENT}` 2.0 - `${PARAMETER:OFFSET:LENGTH}` 2.0 - `${!PARAMETER}` (indirection) 2.0 - `$"..."` (localized strings) 2.0 - `$'...'` (ANSI-C-like strings) 2.0 - `\xNNN` in `$'...'` (and `echo -e`) 2.02-alpha1 - `$(< FILENAME)` (file content) 2.02-alpha1 - globbing (`fnmatch()`) capable of POSIX(r) character classes etc. 2.02-alpha1 - extended globbing 2.02-alpha1 KSH88 - globbing inside array mass-assignment: `ARRAY=(*.txt)` 2.03-alpha - `$'...\'...'` escaped single quote inside ANSI-C-like strings 2.04-devel KSH93 - `${!PREFIX*}` (parameter name expansion) 2.04 KSH93 - `$'...'` expands `\cx` (Control-x) 2.05b - `[:class:]` syntax for pattern matching 2.05b KSH93 - `${!ARRAY[@]}` (array index expansion) 3.0-alpha KSH93 - `{x..y}` (range brace expansion) 3.0-alpha - `$'...'` expands `\xNNN` (Hexdigits) 3.0 - `+=` operator for arrays and strings 3.1-alpha1 - `${PARAMETER//PATTERN/REPLACEMENT}` behaviour changed 3.2-alpha anchoring for global substitution is no longer allowed, changes the way old syntax may work - `${@:0:x}` includes `$0` 4.0-alpha - Support for associative arrays 4.0-alpha relevant builtins also got associative array support - case modification operators for expansions 4.0-alpha - `{0x..0y}` (zeropadding brace expansion) 4.0-alpha - numerically indexed arrays can be accessed (on expansion time) from the end using negative indexes 4.1-alpha - `\uNNNN` and `\uNNNNNNNN` in `$'...'` 4.2-alpha for: `printf`, `echo -e`, `$'...'` - `${PARAMETER:OFFSET:LENGTH}`: Negative `LENGTH` values are used as offset from the end of the string 4.2-alpha Substrings only for Bash and ksh93. Works also for argument expansions in zsh. ksh93 can use `${arr[n..-m]}`. - Word expansions like `${foo##bar}` understand indirect variable references 4.3-beta - Transformations 4.4 - Process substitution now works in POSIX mode 5.1-alpha - New transformations: `U`, `u`, `L` 5.1-alpha Case-transformation - New transformation: `K` 5.1-alpha Display associative arrays as key/value pairs +|Feature or change description|Appeared in Bash version|Remarks| +|--|--|--| +|Support for integer-indexed arrays|2.0|relevant builtins also got array support| +|`${PARAMETER//PATTERN/REPLACEMENT}`|2.0|| +|`${PARAMETER:OFFSET:LENGTH}`|2.0|| +|`${!PARAMETER}` (indirection)|2.0|| +|`$"..."` (localized strings)|2.0|| +|`$'...'` (ANSI-C-like strings)|2.0|| +|`\xNNN` in `$'...'` (and `echo -e`)|2.02-alpha1|| +|`$(< FILENAME)` (file content)|2.02-alpha1|| +|globbing (`fnmatch()`) capable of POSIX(r) character classes etc.|2.02-alpha1|| +|extended globbing|2.02-alpha1|KSH88| +|globbing inside array mass-assignment: `ARRAY=(*.txt)`|2.03-alpha|| +|`$'...\'...'` escaped single quote inside ANSI-C-like strings|2.04-devel|KSH93| +|`${!PREFIX*}` (parameter name expansion)|2.04|KSH93| +|`$'...'` expands `\cx` (Control-x)|2.05b|| +|`[:class:]` syntax for pattern matching|2.05b|KSH93| +|`${!ARRAY[@]}` (array index expansion)|3.0-alpha|KSH93| +|`{x..y}` (range brace expansion)|3.0-alpha|| +|`$'...'` expands `\xNNN` (Hexdigits)|3.0|| +|`+=` operator for arrays and strings|3.1-alpha1|| +|`${PARAMETER//PATTERN/REPLACEMENT}` behaviour changed|3.2-alpha|anchoring for global substitution is no longer allowed, changes the way old syntax may work| +|`${@:0:x}` includes `$0`|4.0-alpha|| +|Support for associative arrays|4.0-alpha|relevant builtins also got associative array support| +|case modification operators for expansions|4.0-alpha|| +|`{0x..0y}` (zeropadding brace expansion)|4.0-alpha|| +|numerically indexed arrays can be accessed (on expansion time) from the end using negative indexes|4.1-alpha|| +|`\uNNNN` and `\uNNNNNNNN` in `$'...'`|4.2-alpha|for: `printf`, `echo -e`, `$'...'`| +|`${PARAMETER:OFFSET:LENGTH}`: Negative `LENGTH` values are used as offset from the end of the string|4.2-alpha|Substrings only for Bash and ksh93. Works also for argument expansions in zsh. ksh93 can use `${arr[n..-m]}`.| +|Word expansions like `${foo##bar}` understand indirect variable references|4.3-beta|| +|Transformations|4.4|| +|Process substitution now works in POSIX mode|5.1-alpha|| +|New transformations: `U`, `u`, `L`|5.1-alpha|Case-transformation| +|New transformation: `K`|5.1-alpha|Display associative arrays as key/value pairs| ## Arithmetic @@ -285,15 +285,15 @@ For this topic, see also - [arith_expr](../syntax/arith_expr.md) - [arith](../syntax/expansion/arith.md) - Feature or change description Appeared in Bash version Remarks - -------------------------------------------- -------------------------- ------------------------------------------- - `((...))` 2.0-beta2 KSH93 - ternary operator 2.0 - base 64 integer constants 2.0 the max. base before is unknown. Anybody? - deprecated `$[...]` in favor of `$((...))` 2.0 - exponentiaition operator (`**`) 2.02-alpha1 - comma operator `EXPR,EXPR` 2.04-devel - pre- and postfix operators 2.04-devel +|Feature or change description|Appeared in Bash version|Remarks| +|--|--|--| +|`((...))`|2.0-beta2|KSH93| +|ternary operator|2.0|| +|base 64 integer constants|2.0|the max. base before is unknown. Anybody?| +|deprecated `$[...]` in favor of `$((...))`|2.0|| +|exponentiaition operator (`**`)|2.02-alpha1|| +|comma operator `EXPR,EXPR`|2.04-devel|| +|pre- and postfix operators|2.04-devel|| ## Redirection and related @@ -301,33 +301,33 @@ For this topic, see also - [redirection](../syntax/redirection.md) - Feature or change description Appeared in Bash version Remarks - --------------------------------------------------------------------------------------- -------------------------- --------- - socket redirection (`/dev/tcp/`, `/dev/udp/`) 2.04-devel - OS/filesystem-independent support for `/dev/std(in|out|err)` and `/dev/fd/*` 2.04 - socket redirection accepts service names 2.05 - `[n]<&word-` and `[n]>&word-` FD-duplicate/closing 2.05b-alpha1 KSH93 - Here strings: `<<< WORD` 2.05b-alpha1 - `|&` (synonym for `2>&1 |`) 4.0-alpha - `&>>` (equiv. to `>>FILE 2>&1`) 4.0-alpha - `{varname}` style automatic file descriptor allocation 4.1-alpha ksh93 - `{varname[idx]}` fd allocation accepts array subscripts and special-meaning variables 4.3-alpha ksh93 +|Feature or change description|Appeared in Bash version|Remarks| +|--|--|--| +|socket redirection (`/dev/tcp/`, `/dev/udp/`)|2.04-devel|| +|OS/filesystem-independent support for `/dev/std(in|out|err)` and `/dev/fd/*`|2.04|| +|socket redirection accepts service names|2.05|| +|`[n]<&word-` and `[n]>&word-` FD-duplicate/closing|2.05b-alpha1|KSH93| +|Here strings: `<<< WORD`|2.05b-alpha1|| +|`|&` (synonym for `2>&1|`)|4.0-alpha|| +|`&>>` (equiv. to `>>FILE 2>&1`)|4.0-alpha|| +|`{varname}` style automatic file descriptor allocation|4.1-alpha|ksh93| +|`{varname[idx]}` fd allocation accepts array subscripts and special-meaning variables|4.3-alpha|ksh93| ## Misc - Feature or change description Appeared in Bash version See also/remarks - ------------------------------------------------------------------------------------------------- -------------------------- ------------------------------------------------------------------------------------------------------------------------------------------ - `DEBUG` trap 2.0 - `ERR` trap 2.05a KSH93 - Support for multibyte characters: Unicode / UTF8 2.05b - `RETURN` trap 3.0 ksh93 `EXIT` trap evaluates in caller scope (for `function name {`). Bash `RETURN` in same scope. - `command_not_found_handle` handler function 4.0-alpha - official introduction of switchable \"compatiblity levels\" 4.0-alpha `compat31` was introduced in a 3.2 version, mainly because of the incompatibilities that were introduced by the changed `=~` operator - `[[...]]` and `((...))` conditional commands are subject to the `ERR` trap and `set -e` feature 4.1-alpha - ACL support for file status checks 4.1-alpha - Assignment to negative array indices 4.3-alpha ksh93, zsh - `declare`/`typeset -n` 4.3-alpha Support for nameref variable type, a variable referencing another one by name - shells started to run process substitutions now run any trap set on `EXIT` 4.3-beta - process substitution does not inherit the `v` flag 5.0-alpha - `ERR` trap 5.0-alpha Reports more reliable line numbers - Variable assignment 5.0-beta Assignments preceeding a special builtin that chages variable attributes are not propagated back unless compatiblity mode is 44 or lower +|Feature or change description|Appeared in Bash version|See also/remarks| +|--|--|--| +|`DEBUG` trap|2.0|| +|`ERR` trap|2.05a|KSH93| +|Support for multibyte characters: Unicode / UTF8|2.05b|| +|`RETURN` trap|3.0|ksh93 `EXIT` trap evaluates in caller scope (for `function name {`). Bash `RETURN` in same scope.| +|`command_not_found_handle` handler function|4.0-alpha|| +|official introduction of switchable "compatiblity levels"|4.0-alpha|`compat31` was introduced in a 3.2 version, mainly because of the incompatibilities that were introduced by the changed `=~` operator| +|`[[...]]` and `((...))` conditional commands are subject to the `ERR` trap and `set -e` feature|4.1-alpha|| +|ACL support for file status checks|4.1-alpha|| +|Assignment to negative array indices|4.3-alpha|ksh93, zsh| +|`declare`/`typeset -n`|4.3-alpha|Support for nameref variable type, a variable referencing another one by name| +|shells started to run process substitutions now run any trap set on `EXIT`|4.3-beta|| +|process substitution does not inherit the `v` flag|5.0-alpha|| +|`ERR` trap|5.0-alpha|Reports more reliable line numbers| +|Variable assignment|5.0-beta|Assignments preceeding a special builtin that chages variable attributes are not propagated back unless compatiblity mode is 44 or lower| diff --git a/docs/scripting/basics.md b/docs/scripting/basics.md index f1f2778..07621a5 100644 --- a/docs/scripting/basics.md +++ b/docs/scripting/basics.md @@ -49,31 +49,31 @@ You can follow the process by using `echo` as a fake interpreter: #!/bin/echo We don't need a script body here, as the file will never be interpreted -and executed by \"`echo`\". You can see what the Operating System does, -it calls \"`/bin/echo`\" with the name of the executable file and +and executed by "`echo`". You can see what the Operating System does, +it calls "`/bin/echo`" with the name of the executable file and following arguments. $ /home/bash/bin/test testword hello /home/bash/bin/test testword hello -The same way, with `#!/bin/bash` the shell \"`/bin/bash`\" is called +The same way, with `#!/bin/bash` the shell "`/bin/bash`" is called with the script filename as an argument. It's the same as executing -\"`/bin/bash /home/bash/bin/test testword hello`\" +"`/bin/bash /home/bash/bin/test testword hello`" If the interpreter can be specified with arguments and how long it can be is system-specific (see [#!-magic](http://www.in-ulm.de/~mascheck/various/shebang/)). When Bash executes a file with a #!/bin/bash shebang, the shebang itself is -ignored, since the first character is a hashmark \"#\", which indicates +ignored, since the first character is a hashmark "`#`", which indicates a comment. The shebang is for the operating system, not for the shell. Programs that don't ignore such lines, may not work as shebang driven interpreters. - [**Attention:**]{.underline}When the + **Attention:**When the specified interpreter is unavailable or not executable (permissions), -you usually get a \"`bad interpreter`\" error message., If you get +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 +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 @@ -85,7 +85,7 @@ A common method is to specify a shebang like #!/usr/bin/env bash -\...which just moves the location of the potential problem to +...which just moves the location of the potential problem to - the `env` utility must be located in /usr/bin/ - the needed `bash` binary must be located in `PATH` @@ -104,7 +104,7 @@ files*: - **stdout**: standard output - **stderr**: standard error output -Usually, they\'re all connected to your terminal, stdin as input file +Usually, they're all connected to your terminal, stdin as input file (keyboard), stdout and stderr as output files (screen). When calling such a program, the invoking shell can change these filedescriptor connections away from the terminal to any other file (see redirection). @@ -179,8 +179,8 @@ else fi ``` -A common decision making command is \"`test`\" or its equivalent -\"`[`\". But note that, when calling test with the name \"`[`\", the +A common decision making command is "`test`" or its equivalent +"`[`". But note that, when calling test with the name "`[`", the square brackets are not part of the shell syntax, the left bracket **is** the test command! @@ -194,7 +194,7 @@ fi Read more about [the test command](../commands/classictest.md) -A common exit code check method uses the \"`||`\" or \"`&&`\" operators. +A common exit code check method uses the "`||`" or "`&&`" operators. This lets you execute a command based on whether or not the previous command completed successfully: @@ -203,13 +203,13 @@ grep ^root: /etc/passwd >/dev/null || echo "root was not found - check the pub a which vi && echo "Your favourite editor is installed." ``` -Please, when your script exits on errors, provide a \"FALSE\" exit code, +Please, when your script exits on errors, provide a "`FALSE`" exit code, so others can check the script execution. ## Comments In a larger, or complex script, it's wise to comment the code. Comments -can help with debugging or tests. Comments start with the \# character +can help with debugging or tests. Comments start with the `#` character (hashmark) and continue to the end of the line: ``` bash @@ -226,7 +226,7 @@ All three syntactically correct. ### Block commenting To temporarily disable complete blocks of code you would normally have -to prefix every line of that block with a \# (hashmark) to make it a +to prefix every line of that block with a `#` (hashmark) to make it a comment. There's a little trick, using the pseudo command `:` (colon) and input redirection. The `:` does nothing, it's a pseudo command, so it does not care about standard input. In the following code example, @@ -254,14 +254,14 @@ redirection (a here-document) - the pseudo command didn't care about it, effectively, the entire block was ignored. The here-document-tag was quoted here **to avoid substitutions** in the -\"commented\" text! Check [redirection with +"commented" text! Check [redirection with here-documents](../syntax/redirection.md#tag_heredoc) for more ## Variable scope In Bash, the scope of user variables is generally *global*. That means, -it does **not** matter whether a variable is set in the \"main program\" -or in a \"function\", the variable is defined everywhere. +it does **not** matter whether a variable is set in the "main program" +or in a "function", the variable is defined everywhere. Compare the following *equivalent* code snippets: @@ -280,10 +280,10 @@ echo $myvariable ``` In both cases, the variable `myvariable` is set and accessible from -everywhere in that script, both in functions and in the \"main -program\". +everywhere in that script, both in functions and in the "main +program". -**[Attention:]{.underline}** When you set variables in a child process, +**Attention:** When you set variables in a child process, for example a *subshell*, they will be set there, but you will **never** have access to them outside of that subshell. One way to create a subshell is the pipe. It's all mentioned in a small article about [Bash @@ -359,7 +359,7 @@ export myvariable ``` Remember that the *exported* variable is a **copy**. There is no -provision to \"copy it back to the parent.\" See the article about [Bash +provision to "copy it back to the parent." See the article about [Bash in the process tree](../scripting/processtree.md)! [^1]: under specific circumstances, also by the shell itself diff --git a/docs/scripting/debuggingtips.md b/docs/scripting/debuggingtips.md index fe25aff..e1d97f7 100644 --- a/docs/scripting/debuggingtips.md +++ b/docs/scripting/debuggingtips.md @@ -16,16 +16,16 @@ but as hints and comments about debugging a Bash script. ## Use a unique name for your script Do **not** name your script `test`, for example! *Why?* `test` is the -name of a UNIX(r)-command, and [most likely built into your -shell]{.underline} (it's a built-in in Bash) - so you won't be able to +name of a UNIX(r)-command, and most likely built into your +shell (it's a built-in in Bash) - so you won't be able to run a script with the name `test` in a normal way. **Don't laugh!** This is a classic mistake :-) ## Read the error messages -Many people come into IRC and ask something like *\"Why does my script -fail? I get an error!\"*. And when you ask them what the error message +Many people come into IRC and ask something like *"Why does my script +fail? I get an error!"*. And when you ask them what the error message is, they don't even know. Beautiful. Reading and interpreting error messages is 50% of your job as debugger! @@ -33,9 +33,9 @@ Error messages actually **mean** something. At the very least, they can give you hints as to where to start debugging. **READ YOUR ERROR MESSAGES!** -You may ask yourself why is this mentioned as debugging tip? Well, [you +You may ask yourself why is this mentioned as debugging tip? Well, you would be surprised how many shell users ignore the text of error -messages!]{.underline} When I find some time, I\'ll paste 2 or 3 IRC +messages! When I find some time, I'll paste 2 or 3 IRC log-snips here, just to show you that annoying fact. ## Use a good editor @@ -85,7 +85,7 @@ There are two useful debug outputs for that task (both are written to - print commands to be executed to `stderr` as if they were read from input (script file or keyboard) - print everything **before** any ([substitution and - expansion](../syntax/expansion/intro.md), \...) is applied + expansion](../syntax/expansion/intro.md), ...) is applied - `set -x` mode (`set -o xtrace`) - print everything as if it were executed, after [substitution and expansion](../syntax/expansion/intro.md) is applied @@ -98,7 +98,7 @@ There are two useful debug outputs for that task (both are written to configurable file descriptor, rather than sdtout by setting the [BASH_XTRACEFD](../syntax/shellvars.md#BASH_XTRACEFD) variable. -**[Hint:]{.underline}** These modes can be entered when calling Bash: +**Hint:** These modes can be entered when calling Bash: - from commandline: `bash -vx ./myscript` - from shebang (OS dependant): `#!/bin/bash -vx` @@ -116,9 +116,9 @@ That fails. Why? Let's see the `xtrace` output: + '[' bar baz = test ']' -And now you see that it's (\"bar\" and \"baz\") recognized as two +And now you see that it's ("bar" and "baz") recognized as two separate words (which you would have realized if you READ THE ERROR -MESSAGES ;) ). Let's check it\... +MESSAGES ;) ). Let's check it... # next try [ "$foo" = test ] @@ -146,7 +146,7 @@ function*: +(somefile.bash:412): echo 'Hello world' -\...and like this when you trace code *inside a function*: +...and like this when you trace code *inside a function*: +(somefile.bash:412): myfunc(): echo 'Hello world' @@ -236,14 +236,14 @@ command](../syntax/ccmd/intro.md): - did you close your `{` with a `}`? - did you close your `(` with a `)`? -**[Note:]{.underline}** It seems that here-documents (tested on versions +**Note:** It seems that here-documents (tested on versions `1.14.7`, `2.05b`, `3.1.17` and `4.0`) are correctly terminated when there is an EOF before the end-of-here-document tag (see [redirection](../syntax/redirection.md)). The reason is unknown, but it seems to be deliberate. Bash 4.0 added an extra message for this: `` warning: here-document at line delimited by end-of-file (wanted `') `` -### Unexpected end of file while looking for matching \... +### Unexpected end of file while looking for matching ... script.sh: line 50: unexpected EOF while looking for matching `"' script.sh: line 100: syntax error: unexpected end of file @@ -266,13 +266,13 @@ example for `xtrace` output from above. External commands may display such an error message though in our example, it was the **internal** test-command that yielded the error. -### !\": event not found +### !": event not found $ echo "Hello world!" bash: !": event not found This is not an error per se. It happens in interactive shells, when the -C-Shell-styled history expansion (\"`!searchword`\") is enabled. This is +C-Shell-styled history expansion ("`!searchword`") is enabled. This is the default. Disable it like this: set +H @@ -317,8 +317,8 @@ CRs are a pain. Some possible sources of CRs: - a DOS/Windows text editor -- a UNIX(r) text editor that is \"too smart\" when determining the - file content type (and thinks \"*it's a DOS text file*\") +- a UNIX(r) text editor that is "too smart" when determining the + file content type (and thinks "*it's a DOS text file*") - a direct copy and paste from certain webpages (some pastebins are known for this) @@ -343,7 +343,7 @@ Here's what happens because of the `#!/bin/bash^M` in our shebang: problem. - the script can't be executed -The error message can vary. If you\'re lucky, you\'ll get: +The error message can vary. If you're lucky, you'll get: bash: ./testing.sh: /bin/bash^M: bad interpreter: No such file or directory @@ -355,9 +355,10 @@ Why? Because when printed literally, the `^M` makes the cursor go back to the beginning of the line. The whole error message is *printed*, but you *see* only part of it! - It's easy to imagine the `^M` is bad in other places -too. If you get weird and illogical messages from your script, rule out -the possibility that`^M` is involved. Find and eliminate it! +!!! warning "warning" + It's easy to imagine the `^M` is bad in other places + too. If you get weird and illogical messages from your script, rule out + the possibility that`^M` is involved. Find and eliminate it! ### How can I find and eliminate them? @@ -376,7 +377,8 @@ the possibility that`^M` is involved. Find and eliminate it! - [the set builtin command](../commands/builtin/set.md) (for `-v` and `-x`) -FIXME +!!! warning "FIXME" + tbd. - DEBUG trap - BASH Debugger diff --git a/docs/scripting/newbie_traps.md b/docs/scripting/newbie_traps.md index 472c664..3705471 100644 --- a/docs/scripting/newbie_traps.md +++ b/docs/scripting/newbie_traps.md @@ -17,8 +17,8 @@ Here are some typical traps: ### Your perfect Bash script executes with syntax errors If you write Bash scripts with Bash specific syntax and features, run -them with [Bash]{.underline}, and run them with Bash in [native -mode]{.underline}. +them with Bash, and run them with Bash in native +mode. **Wrong**: @@ -36,7 +36,7 @@ See also: - [Bash startup mode: SH mode](../scripting/bashbehaviour.md#sh_mode) - [Bash run mode: POSIX mode](../scripting/bashbehaviour.md#posix_run_mode) -### Your script named \"test\" doesn't execute +### Your script named "test" doesn't execute Give it another name. The executable `test` already exists. diff --git a/docs/scripting/nonportable.md b/docs/scripting/nonportable.md index 0b1e592..637206e 100644 --- a/docs/scripting/nonportable.md +++ b/docs/scripting/nonportable.md @@ -21,27 +21,16 @@ e.g. if there is a corresponding POSIX(r)-compatible syntax (see Some syntax elements have a BASH-specific, and a portable[^1]) pendant. In these cases the portable syntax should be preferred. - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - construct portable equivalent Description Portability - ------------------------------------------ --------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------- - `source\ FILE` `. FILE` include a script file Bourne shell (bash, ksh, POSIX(r), zsh, \...) - - `declare`\\ keyword `typeset` keyword define local variables (or variables with special attributes) ksh, zsh, \..., **not POSIX!** - - `command\ <<<\ WORD` `command <\ TEMPFILE COMMAND\ <\ TEMPFILE` Process substitution (here used with redirection); use the old fashioned way (tempfiles) POSIX(r) and others - - `((echo X);(echo Y))` `( (echo X); (echo Y) )` Nested subshells (separate the inner `()` from the outer `()` by spaces, to not confuse the shell regarding arithmetic control operators) POSIX(r) and others - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +|construct|portable equivalent|Description|Portability| +|---------|-------------------|-----------|-----------| +|`source FILE`|`. FILE`|include a script file|Bourne shell (bash, ksh, POSIX(r), zsh, …)| +|`declare` keyword|`typeset` keyword|define local variables (or variables with special attributes)|ksh, zsh, …, **not POSIX!**| +|`command <<< WORD`|`command < TEMPFILE`\n`COMMAND < TEMPFILE`|Process substitution (here used with redirection); use the old fashioned way (tempfiles)|POSIX(r) and others| +|`((echo X);(echo Y))`|`( (echo X); (echo Y) )`|Nested subshells (separate the inner `()` from the outer `()` by spaces, to not confuse the shell regarding arithmetic control operators)|POSIX(r) and others| ## Portability rationale @@ -51,8 +40,9 @@ will be!) and it's not very detailed (e.g. you won't find information about how which shell technically forks off which subshell). It's just an assorted small set of portability guidelines. *-Thebonsai* -FIXME UNIX shell gurus out there, please be patient with a newbie like -me and give comments and hints instead of flames. +!!! warning "FIXME" + UNIX shell gurus out there, please be patient with a newbie like me + and give comments and hints instead of flames. ### Environment (exported) variables @@ -100,7 +90,7 @@ Why? (list of known behaviours) - may or may not automatically interpret backslash escpape codes in the strings - may or may not automatically interpret switches (like `-n`) -- may or may not ignore \"end of options\" tag (`--`) +- may or may not ignore "end of options" tag (`--`) - `echo -n` and `echo -e` are neither portable nor standard (**even within the same shell**, depending on the version or environment variables or the build options, especially KSH93 and Bash) @@ -113,7 +103,7 @@ existance of [the `printf` command](../commands/builtin/printf.md). - `${var:x:x}` is KSH93/Bash specific - `${var/../..}` and `${var//../..}` are KSH93/Bash specific - `var=$*` and `var=$@` are not handled the same in all shells if the - first char of IFS is not \" \" (space). `var="$*"` should work + first char of IFS is not " " (space). `var="$*"` should work (except the Bourne shell always joins the expansions with space) ### Special variables @@ -130,11 +120,11 @@ of your script: #### RANDOM [RANDOM](../syntax/shellvars.md#RANDOM) is Bash/KSH/ZSH specific variable -that will give you a random number up to 32767 (2\^15-1). Among many +that will give you a random number up to 32767 (2^15-1). Among many other available external options, you can use awk to generate a random number. There are multiple implementations of awk and which version your -system uses will depend. Most modern systems will call \'gawk\' (i.e. -GNU awk) or \'nawk\'. \'oawk\' (i.e. Original/Old awk) does not have the +system uses will depend. Most modern systems will call 'gawk' (i.e. +GNU awk) or 'nawk'. 'oawk' (i.e. Original/Old awk) does not have the rand() or srand() functions, so is best avoided. # 'gawk' can produce random numbers using srand(). In this example, 10 integers between 1 and 500: @@ -143,10 +133,10 @@ rand() or srand() functions, so is best avoided. # 'nawk' and 'mawk' does the same, but needs a seed to be provided for its rand() function. In this example we use $(date) randpm=$(mawk -v min=1 -v max=500 -v nNum=10 -v seed="$(date +%Y%M%d%H%M%S)" 'BEGIN { srand(seed); for (i = 0; i < nNum; ++i) {print int(min + rand() * (max - min)} }') -*Yes, I\'m not an `awk` expert, so please correct it, rather than +*Yes, I'm not an `awk` expert, so please correct it, rather than complaining about possible stupid code!* - # Well, seeing how this //is// BASH-hackers.org I kinda missed the bash way of doing the above ;-) + # Well, seeing how this //is// BASH-hackers.org I kinda missed the bash way of doing the above ;-) # print a number between 0 and 500 :-) printf $(( 500 * RANDOM / 32767 )) @@ -162,7 +152,7 @@ Find another method. The [PATH](../syntax/shellvars.md#PATH) variable is a colon-delimited list of directory names, so it's basically possible to run a loop and check -every `PATH` component for the command you\'re looking for and for +every `PATH` component for the command you're looking for and for executability. However, this method doesn't look nice. There are other ways of doing @@ -207,6 +197,6 @@ accessible by `PATH`: echo "sed is available" fi -[^1]: \"portable\" doesn't necessarily mean it's POSIX, it can also - mean it's \"widely used and accepted\", and thus maybe more +[^1]: "portable" doesn't necessarily mean it's POSIX, it can also + mean it's "widely used and accepted", and thus maybe more portable than POSIX(r diff --git a/docs/scripting/obsolete.md b/docs/scripting/obsolete.md index 11219bd..7344c27 100644 --- a/docs/scripting/obsolete.md +++ b/docs/scripting/obsolete.md @@ -15,6 +15,8 @@ obsolete by some measure. A thorough discussion of the rationale is beyond the scope of this page. See the [portability page](../scripting/nonportable.md) for a discussion on portability issues. +## Tolerated but few ligitimate uses + This first table lists syntax that is tolerated by Bash but has few if any legitimate uses. These features exist mostly for Bourne, csh, or some other backward compatibility with obsolete shells, or were @@ -24,13 +26,16 @@ everyone except maybe code golfers. New scripts should never use them. None of the items on this list are specified by the most current version of POSIX, and some may be incompatible with POSIX. - Syntax Replacement Description - ---------------------------------- --------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `&>FILE` and `>&FILE` `>FILE 2>&1` This redirection syntax is short for `>FILE 2>&1` and originates in the C Shell. The latter form is especially uncommon and should never be used, and the explicit form using separate redirections is preferred over both. These shortcuts contribute to confusion about the copy descriptor because the syntax is unclear. They also introduce parsing ambiguity, and conflict with POSIX. Shells without this feature treat `cmd1 &>file cmd2` as: \"background `cmd1` and then execute `cmd2` with its stdout redirected to `file`\", which is the correct interpretation of this expression. See: [redirection](../syntax/redirection.md) \`\$ { bash; dash /dev/null&>/dev/fd/2 echo bar\' foo echo bar bar\` - `$[EXPRESSION]` `$((EXPRESSION))` This undocumented syntax is completely replaced by the POSIX-conforming arithmetic expansion `$((EXPRESSION))`. It is unimplemented almost everywhere except Bash and Zsh. See [arithmetic expansion](../syntax/expansion/arith.md). [Some discussion](http://lists.gnu.org/archive/html/bug-bash/2012-04/msg00034.html). - `COMMAND\ |&\ COMMAND` `COMMAND 2>&1 | COMMAND` This is an alternate pipeline operator derived from Zsh. Officially, it is not considered deprecated by Bash, but I highly discourage it. It conflicts with the list operator used for [coprocess](../syntax/keywords/coproc.md) creation in most Korn shells. It also has confusing behavior. The stdout is redirected first like an ordinary pipe, while the stderr is actually redirected last -- after other redirects preceding the pipe operator. Overall, it's pointless syntax bloat. Use an explicit redirect instead. - `function\ NAME()\ COMPOUND-CMD` `NAME()\ COMPOUND-CMD` or `function\ NAME\ {\ CMDS;\ }` This is an amalgamation between the Korn and POSIX style function definitions - using both the `function` keyword and parentheses. It has no useful purpose and no historical basis or reason to exist. It is not specified by POSIX. It is accepted by Bash, mksh, zsh, and perhaps some other Korn shells, where it is treated as identical to the POSIX-style function. It is not accepted by AT&T ksh. It should never be used. See the next table for the `function` keyword. Bash doesn't have this feature documented as expressly deprecated. - `for x; { ...;}` `do`, `done`, `in`, `esac`, etc. This undocumented syntax replaces the `do` and `done` reserved words with braces. Many Korn shells support various permutations on this syntax for certain compound commands like `for`, `case`, and `while`. Which ones and certain details like whether a newline or semicolon are required vary. Only `for` works in Bash. Needless to say, don't use it. +|Syntax|Replacement|Description| +|--|--|--| +|`&>FILE` and `>&FILE`|`>FILE 2>&1`|This redirection syntax is short for `>FILE 2>&1` and originates in the C Shell. The latter form is especially uncommon and should never be used, and the explicit form using separate redirections is preferred over both. These shortcuts contribute to confusion about the copy descriptor because the syntax is unclear. They also introduce parsing ambiguity, and conflict with POSIX. Shells without this feature treat `cmd1 &>file cmd2` as: "background `cmd1` and then execute `cmd2` with its stdout redirected to `file`", which is the correct interpretation of this expression. See: [redirection](../syntax/redirection.md)
$ { bash; dash /dev/null&>/dev/fd/2 echo bar'
foo echo bar
bar
| +|`$[EXPRESSION]`|`$((EXPRESSION))`|This undocumented syntax is completely replaced by the POSIX-conforming arithmetic expansion `$((EXPRESSION))`. It is unimplemented almost everywhere except Bash and Zsh. See [arithmetic expansion](../syntax/expansion/arith.md). [Some discussion](http://lists.gnu.org/archive/html/bug-bash/2012-04/msg00034.html).| +|`COMMAND|& COMMAND`|`COMMAND 2>&1| COMMAND`|This is an alternate pipeline operator derived from Zsh. Officially, it is not considered deprecated by Bash, but I highly discourage it. It conflicts with the list operator used for [coprocess](../syntax/keywords/coproc.md) creation in most Korn shells. It also has confusing behavior. The stdout is redirected first like an ordinary pipe, while the stderr is actually redirected last – after other redirects preceding the pipe operator. Overall, it's pointless syntax bloat. Use an explicit redirect instead.| +|`function NAME() COMPOUND-CMD`|`NAME() COMPOUND-CMD` or `function NAME { CMDS; }`|This is an amalgamation between the Korn and POSIX style function definitions - using both the `function` keyword and parentheses. It has no useful purpose and no historical basis or reason to exist. It is not specified by POSIX. It is accepted by Bash, mksh, zsh, and perhaps some other Korn shells, where it is treated as identical to the POSIX-style function. It is not accepted by AT&T ksh. It should never be used. See the next table for the `function` keyword. Bash doesn't have this feature documented as expressly deprecated.| +|`for x; { ...;}`|`do`, `done`, `in`, `esac`, etc.|This undocumented syntax replaces the `do` and `done` reserved words with braces. Many Korn shells support various permutations on this syntax for certain compound commands like `for`, `case`, and `while`. Which ones and certain details like whether a newline or semicolon are required vary. Only `for` works in Bash. Needless to say, don't use it.| + + +## Syntax superseded by superior alternatives This table lists syntax that is specified by POSIX (unless otherwise specified below), but has been superseded by superior alternatives @@ -39,43 +44,33 @@ reasons such as encouraging bad practices or dangerous code. Those that are specified by POSIX may be badly designed and unchangeable for historical reasons. - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Syntax Replacement Description - ----------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Unquoted expansions, [wordsplit](../syntax/expansion/wordsplit.md), and [globs](../syntax/expansion/globs.md) [Proper quoting](http://mywiki.wooledge.org/Quotes), Ksh/Bash-style [arrays](../syntax/arrays.md), The \"\$@\" expansion, [read](../commands/builtin/read.md) *Quoting errors* are a broad category of common mistakes brought about by a few unintuitive features carried over from the Bourne shell due to complaints of broken scripts and changes in previously documented behavior. Most of the important expansions are performed at the same time from left to right. However, a few expansions, most notably word-splitting and globbing, and in shells other than Bash, [brace expansion](../syntax/expansion/brace.md), are performed **on the results of previous expansions, by default, unless they are quoted.** This means that the act of expanding an unquoted variable in an ordinary argument context, depending on the value of the variable, can yield different results depending on possibly uncontrolled side-effects like the value of `IFS`, and the names of files in the current working directory. You can't get globbing without word-splitting, or vice versa (without `set -f`). [You can't store a command or character-delimited list in a variable and safely evaluate it with unquoted expansion](http://mywiki.wooledge.org/BashFAQ/050). If possible, always choose a shell that supports Korn shell arrays such as Bash. They are a vital but non-standard feature for writing clean, safe scripts. Well-written scripts don't use word-splitting. A few exceptions are listed on the [word splitting page](../syntax/expansion/wordsplit.md). A significant proportion of the issues on the famous [Pitfalls list](http://mywiki.wooledge.org/BashPitfalls) fall under this category. See also: *[Don't read lines with for!](http://mywiki.wooledge.org/DontReadLinesWithFor)* +|Syntax|Replacement|Description| +|------|-----------|-----------| +|Unquoted expansions, [wordsplitting](../syntax/expansion/wordsplit.md), and [Pathname expansion (globbing)](../syntax/expansion/globs.md)|[Proper quoting](http://mywiki.wooledge.org/Quotes), Ksh/Bash-style [arrays](../syntax/arrays.md), The "$@" expansion, [the read builtin command](../commands/builtin/read.md)|*Quoting errors* are a broad category of common mistakes brought about by a few unintuitive features carried over from the Bourne shell due to complaints of broken scripts and changes in previously documented behavior. Most of the important expansions are performed at the same time from left to right. However, a few expansions, most notably word-splitting and globbing, and in shells other than Bash, [brace expansion](../syntax/expansion/brace.md), are performed **on the results of previous expansions, by default, unless they are quoted.** This means that the act of expanding an unquoted variable in an ordinary argument context, depending on the value of the variable, can yield different results depending on possibly uncontrolled side-effects like the value of `IFS`, and the names of files in the current working directory. You can't get globbing without word-splitting, or vice versa (without `set -f`). [You can't store a command or character-delimited list in a variable and safely evaluate it with unquoted expansion](http://mywiki.wooledge.org/BashFAQ/050). If possible, always choose a shell that supports Korn shell arrays such as Bash. They are a vital but non-standard feature for writing clean, safe scripts. Well-written scripts don't use word-splitting. A few exceptions are listed on the [word splitting page](../syntax/expansion/wordsplit.md). A significant proportion of the issues on the famous [Pitfalls list](http://mywiki.wooledge.org/BashPitfalls) fall under this category. See also: *[Don't read lines with for!](http://mywiki.wooledge.org/DontReadLinesWithFor)*| +|``COMMANDS``|`$(COMMANDS)`|his is the older Bourne-compatible form of the [command substitution](../syntax/expansion/cmdsubst.md). Both the `` `COMMANDS` `` and `$(COMMANDS)` syntaxes are specified by POSIX, but the latter is [greatly]{.underline} preferred, though the former is unfortunately still very prevalent in scripts. New-style command substitutions are widely implemented by every modern shell (and then some). The only reason for using backticks is for compatibility with a real Bourne shell (like Heirloom). Backtick command substitutions require special escaping when nested, and examples found in the wild are improperly quoted more often than not. See: *[Why is $(...) preferred over `...` (backticks)?](http://mywiki.wooledge.org/BashFAQ/082)*.| +|`[ EXPRESSION ]` and `test EXPRESSION`|`[[ EXPRESSION ]]`|`test` and `[` are the Bourne/POSIX commands for evaluating test expressions (they are almost identical, and `[` is somewhat more common). The expressions consist of regular arguments, unlike the Ksh/Bash `[[` command. While the issue is analogous to `let` vs `((`, the advantages of `[[` vs `[` are even more important because the arguments/expansions aren't just concatenated into one expression. With the classic `[` command, the number of arguments is significant. If at all possible, use the [conditional expression](../syntax/ccmd/conditional_expression.md) ("new test command") `[[ EXPRESSION ]]`. Unless there is a need for POSIX compatibility, there are only a few reasons to use `[`. `[[` is one of the most portable and consistent non-POSIX ksh extensions available. See: [conditional_expression](../syntax/ccmd/conditional_expression.md) and *[What is the difference between test, \[ and \[\[ ?](http://mywiki.wooledge.org/BashFAQ/031)*| +|`set -e`, `set -o errexit` and the `ERR` trap|proper control flow and error handling|`set -e` causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as "error handling"; it's not, it's just a way to find the place you've *forgotten* to put error handling.
Think of it as akin to `use strict` in Perl or `throws` in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use.
Because it provides no notification of the location of the error, it's more useful combined with `set -x` or the `DEBUG` trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself.
Most of this also applies to the `ERR` trap, though I've seen it used in a few places in shells that lack `pipefail` or `PIPESTATUS`. The `ERR` trap is not POSIX, but `set -e` is. `failglob` is another Bash feature that falls into this category (mainly useful for debugging).
**The `set -e` feature generates more questions and false bug reports on the Bash mailing list than all other features combined!** Please do not rely on `set -e` for logic in scripts. If you still refuse to take this advice, make sure you understand **exactly** how it works. See: *[Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected?](http://mywiki.wooledge.org/BashFAQ/105)* and | +|`set -u` or `set -o nounset`|Proper control flow and error handling|`set -u` causes attempts to expand unset variables or parameters as fatal errors. Like `set -e`, it bypasses control flow and exits immediately from the current shell environment. Like non-zero statuses, unset variables are a normal part of most non-trivial shell scripts. Living with `set -u` requires hacks like `${1+"$1"}` for each expansion that might possibly be unset. Only very current shells guarantee that expanding `@` or `*` won't trigger an error when no parameters are set (, ). Apparently some find it useful for debugging. See [How do I determine whether a variable is already defined? Or a function?](http://mywiki.wooledge.org/BashFAQ/083) for how to properly test for defined variables. Don't use `set -u`.| +|`${var?msg}` or `${var:?msg}`|Proper control flow and error handling|Like `set -u`, this expansion causes a fatal error which immediately exits the current shell environment if the given parameter is unset or is null. It prints the error message given, to the right of the operator. If a value is expected and you'd like to create an assertion or cause errors, it's better to test for undefined variables using one of [these techniques](http://mywiki.wooledge.org/BashFAQ/083) and handle the error manually, or call a `die` function. This expansion is defined by POSIX. It's better than `set -u`, because it's explicit, but not by much. It also allows you to accidentally construct hilariously deceptive error messages:
bash -c 'f() { definitely_not_printf "${printf:?"$1" - No such option}"; }; f -v'
bash: printf: -v - No such option
| - `` `COMMANDS` `` `$(COMMANDS)` This is the older Bourne-compatible form of the [command substitution](../syntax/expansion/cmdsubst.md). Both the `` `COMMANDS` `` and `$(COMMANDS)` syntaxes are specified by POSIX, but the latter is [greatly]{.underline} preferred, though the former is unfortunately still very prevalent in scripts. New-style command substitutions are widely implemented by every modern shell (and then some). The only reason for using backticks is for compatibility with a real Bourne shell (like Heirloom). Backtick command substitutions require special escaping when nested, and examples found in the wild are improperly quoted more often than not. See: *[Why is \$(\...) preferred over \`\...\` (backticks)?](http://mywiki.wooledge.org/BashFAQ/082)*. - - `[\ EXPRESSION\ ]`\\ and\\ `test\ EXPRESSION` `[[\ EXPRESSION\ ]]` `test` and `[` are the Bourne/POSIX commands for evaluating test expressions (they are almost identical, and `[` is somewhat more common). The expressions consist of regular arguments, unlike the Ksh/Bash `[[` command. While the issue is analogous to `let` vs `((`, the advantages of `[[` vs `[` are even more important because the arguments/expansions aren't just concatenated into one expression. With the classic `[` command, the number of arguments is significant. If at all possible, use the [conditional expression](../syntax/ccmd/conditional_expression.md) (\"new test command\") `[[ EXPRESSION ]]`. Unless there is a need for POSIX compatibility, there are only a few reasons to use `[`. `[[` is one of the most portable and consistent non-POSIX ksh extensions available. See: [conditional_expression](../syntax/ccmd/conditional_expression.md) and *[What is the difference between test, \[ and \[\[ ?](http://mywiki.wooledge.org/BashFAQ/031)* - - `set -e`, `set -o errexit`\ proper control flow and error handling `set -e` causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as \"error handling\"; it's not, it's just a way to find the place you\'ve *forgotten* to put error handling.\ - and the `ERR` trap Think of it as akin to `use strict` in Perl or `throws` in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use.\ - Because it provides no notification of the location of the error, it's more useful combined with `set -x` or the `DEBUG` trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself.\ - Most of this also applies to the `ERR` trap, though I\'ve seen it used in a few places in shells that lack `pipefail` or `PIPESTATUS`. The `ERR` trap is not POSIX, but `set -e` is. `failglob` is another Bash feature that falls into this category (mainly useful for debugging).\ - **The `set -e` feature generates more questions and false bug reports on the Bash mailing list than all other features combined!** Please do not rely on `set -e` for logic in scripts. If you still refuse to take this advice, make sure you understand **exactly** how it works. See: *[Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected?](http://mywiki.wooledge.org/BashFAQ/105)* and - - `set -u` or `set -o nounset` Proper control flow and error handling `set -u` causes attempts to expand unset variables or parameters as fatal errors. Like `set -e`, it bypasses control flow and exits immediately from the current shell environment. Like non-zero statuses, unset variables are a normal part of most non-trivial shell scripts. Living with `set -u` requires hacks like `${1+"$1"}` for each expansion that might possibly be unset. Only very current shells guarantee that expanding `@` or `*` won't trigger an error when no parameters are set (, ). Apparently some find it useful for debugging. See *[How do I determine whether a variable is already defined? Or a function?](http://mywiki.wooledge.org/BashFAQ/083)* for how to properly test for defined variables. Don't use `set -u`. - - `${var?msg}` or `${var:?msg}` Proper control flow and error handling Like `set -u`, this expansion causes a fatal error which immediately exits the current shell environment if the given parameter is unset or is null. It prints the error message given, to the right of the operator. If a value is expected and you\'d like to create an assertion or cause errors, it's better to test for undefined variables using one of [these techniques](http://mywiki.wooledge.org/BashFAQ/083) and handle the error manually, or call a `die` function. This expansion is defined by POSIX. It's better than `set -u`, because it's explicit, but not by much. It also allows you to accidentally construct hilariously deceptive error messages: `bash -c 'f() { definitely_not_printf "${printf:?"$1" - No such option}"; }; f -v' - bash: printf: -v - No such option` - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +# Frequently misued This table lists features that are used only if you have a specific reason to prefer it over another alternative. These have some legitimate -uses if you know what you\'re doing, such as for those with specific +uses if you know what you're doing, such as for those with specific portability requirements, or in order to make use of some subtle behavioral differences. These are frequently (mis)used for no reason. Writing portable scripts that go outside of POSIX features requires knowing how to account for many (often undocumented) differences across -many shells. If you do happen to know what you\'re doing, don't be too +many shells. If you do happen to know what you're doing, don't be too surprised if you run across someone telling you not to use these. - Syntax Replacement Description - ------------------------------- --------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `function\ NAME\ {\ CMDS;\ }` `NAME()\ COMPOUND-CMD` This is the ksh form of function definition created to extend the Bourne and POSIX form with modified behaviors and additional features like local variables. The idea was for new-style functions to be analogous to regular builtins with their own environment and scope, while POSIX-style functions are more like special builtins. `function` is supported by almost every ksh-derived shell including Bash and Zsh, but isn't specified by POSIX. Bash treats all function styles the same, but this is unusual. `function` has some preferable characteristics in many ksh variants, making it more portable for scripts that use non-POSIX extensions by some measures. If you\'re going to use the `function` keyword, it implies that you\'re either targeting Ksh specifically, or that you have detailed knowledge of how to compensate for differences across shells. It should always be used consistently with `typeset`, but never used with `declare` or `local`. Also in ksh93, the braces are not a [command group](../syntax/ccmd/grouping_plain.md), but a required part of the syntax (unlike Bash and others). See [shell function definitions](../syntax/basicgrammar.md#shell_function_definitions) - `typeset` `declare`, `local`, `export`, `readonly` This is closely related to the above, and should often be used together. `typeset` exists primarily for `ksh` compatibility, but is marked as \"deprecated\" in Bash (though I don't entirely agree with this). This makes some sense, because future compatibility can't be guaranteed, and any compatibility at all, requires understanding the non-POSIX features of other shells and their differences. Using `declare` instead of `typeset` emphasizes your intention to be \"Bash-only\", and definitely breaks everywhere else (except possibly zsh if you\'re lucky). The issue is further complicated by Dash and the [Debian policy](http://www.debian.org/doc/debian-policy/ch-files.html#s-scripts) requirement for a `local` builtin, which is itself not entirely compatible with Bash and other shells. - \'\'let \'EXPR\' \'\' `((EXPR))` or `[\ $((EXPR))\ -ne\ 0 ]` `let` is the \"simple command\" variant of arithmetic evaluation command, which takes regular arguments. Both `let` and `((expr))` were present in ksh88, and everything that supports one should support the other. Neither are POSIX. The compound variant is preferable because it doesn't take regular arguments for [wordsplitting](../syntax/expansion/wordsplit.md) and [globbing](../syntax/expansion/globs.md), which makes it safer and clearer. It is also usually faster, especially in Bash, where compound commands are typically significantly faster. Some of the (few) reasons for using `let` are detailed on the [let](../commands/builtin/let.md) page. See [arithmetic evaluation compound command](../syntax/ccmd/arithmetic_eval.md) - `eval` Depends. Often code can be restructured to use better alternatives. `eval` is thrown in here for good measure, as sadly it is so often misused that any use of `eval` (even the rare clever one) is immediately dismissed as wrong by experts, and among the most immediate solutions abused by beginners. In reality, there are correct ways to use `eval`, and even cases in which it's necessary, even in sophisticated shells like Bash and Ksh. `eval` is unusual in that it is less frequently appropriate in more feature-rich shells than in more minimal shells like Dash, where it is used to compensate for more limitations. If you find yourself needing `eval` too frequently, it might be a sign that you\'re either better off using a different language entirely, or trying to borrow an idiom from some other paradigm that isn't well suited to the shell language. By the same token, there are some cases in which working too hard to avoid `eval` ends up adding a lot of complexity and sacrificing all portability. Don't substitute a clever `eval` for something that's a bit \"too clever\", just to avoid the `eval`, yet, take reasonable measures to avoid it where it is sensible to do so. See: [eval](../commands/builtin/eval.md) and [Eval command and security issues](http://mywiki.wooledge.org/BashFAQ/048). +|Syntax|Replacement|Description| +|--|--|--| +|`function NAME { CMDS; }`|`NAME() COMPOUND-CMD`|This is the ksh form of function definition created to extend the Bourne and POSIX form with modified behaviors and additional features like local variables. The idea was for new-style functions to be analogous to regular builtins with their own environment and scope, while POSIX-style functions are more like special builtins. `function` is supported by almost every ksh-derived shell including Bash and Zsh, but isn't specified by POSIX. Bash treats all function styles the same, but this is unusual. `function` has some preferable characteristics in many ksh variants, making it more portable for scripts that use non-POSIX extensions by some measures. If you're going to use the `function` keyword, it implies that you're either targeting Ksh specifically, or that you have detailed knowledge of how to compensate for differences across shells. It should always be used consistently with `typeset`, but never used with `declare` or `local`. Also in ksh93, the braces are not a [command group](../syntax/ccmd/grouping_plain), but a required part of the syntax (unlike Bash and others). See [shell function definitions](../syntax/basicgrammar#shell_function_definitions)| +|`typeset`|`declare`, `local`, `export`, `readonly`|This is closely related to the above, and should often be used together. `typeset` exists primarily for `ksh` compatibility, but is marked as "deprecated" in Bash (though I don't entirely agree with this). This makes some sense, because future compatibility can't be guaranteed, and any compatibility at all, requires understanding the non-POSIX features of other shells and their differences. Using `declare` instead of `typeset` emphasizes your intention to be "Bash-only", and definitely breaks everywhere else (except possibly zsh if you're lucky). The issue is further complicated by Dash and the [Debian policy](http://www.debian.org/doc/debian-policy/ch-files.html#s-scripts) requirement for a `local` builtin, which is itself not entirely compatible with Bash and other shells.| +|`let 'EXPR' `|`((EXPR))` or `[ $((EXPR)) -ne 0 ]`|`let` is the "simple command" variant of arithmetic evaluation command, which takes regular arguments. Both `let` and `((expr))` were present in ksh88, and everything that supports one should support the other. Neither are POSIX. The compound variant is preferable because it doesn't take regular arguments for [wordsplitting](../syntax/expansion/wordsplit) and [globbing](../syntax/expansion/globs), which makes it safer and clearer. It is also usually faster, especially in Bash, where compound commands are typically significantly faster. Some of the (few) reasons for using `let` are detailed on the [let](../commands/builtin/let) page. See [arithmetic evaluation compound command](../syntax/ccmd/arithmetic_eval)| +|`eval`|Depends. Often code can be restructured to use better alternatives.|`eval` is thrown in here for good measure, as sadly it is so often misused that any use of `eval` (even the rare clever one) is immediately dismissed as wrong by experts, and among the most immediate solutions abused by beginners. In reality, there are correct ways to use `eval`, and even cases in which it's necessary, even in sophisticated shells like Bash and Ksh. `eval` is unusual in that it is less frequently appropriate in more feature-rich shells than in more minimal shells like Dash, where it is used to compensate for more limitations. If you find yourself needing `eval` too frequently, it might be a sign that you're either better off using a different language entirely, or trying to borrow an idiom from some other paradigm that isn't well suited to the shell language. By the same token, there are some cases in which working too hard to avoid `eval` ends up adding a lot of complexity and sacrificing all portability. Don't substitute a clever `eval` for something that's a bit "too clever", just to avoid the `eval`, yet, take reasonable measures to avoid it where it is sensible to do so. See: [The eval builtin command](../commands/builtin/eval) and [Eval command and security issues](http://mywiki.wooledge.org/BashFAQ/048 "http://mywiki.wooledge.org/BashFAQ/048").| ## See also diff --git a/docs/scripting/posparams.md b/docs/scripting/posparams.md index af495ae..9474ece 100644 --- a/docs/scripting/posparams.md +++ b/docs/scripting/posparams.md @@ -17,15 +17,15 @@ The day will come when you want to give arguments to your scripts. These arguments are known as **positional parameters**. Some relevant special parameters are described below: - Parameter(s) Description - ------------------ ------------------------------------------------------------------------------------------------------------------------------------ - `$0` the first positional parameter, equivalent to `argv[0]` in C, see [the first argument](../scripting/posparams.md#the_first_argument) - `$FUNCNAME` the function name ([**attention**]{.underline}: inside a function, `$0` is still the `$0` of the shell, **not** the function name) - `$1 ... $9` the argument list elements from 1 to 9 - `${10} ... ${N}` the argument list elements beyond 9 (note the [parameter expansion](../syntax/pe.md) syntax!) - `$*` all positional parameters except `$0`, see [mass usage](../scripting/posparams.md#mass_usage) - `$@` all positional parameters except `$0`, see [mass usage](../scripting/posparams.md#mass_usage) - `$#` the number of arguments, not counting `$0` +|Parameter(s)|Description| +|------------|-----------| +|`$0`|the first positional parameter, equivalent to `argv[0]` in C, see [the first argument](../scripting/posparams.md#the_first_argument)| +|`$FUNCNAME`|the function name (**attention**: inside a function, `$0` is still the `$0` of the shell, **not** the function name)| +|`$1 ... $9`|the argument list elements from 1 to 9| +|`${10} ... ${N}`|the argument list elements beyond 9 (note the [parameter expansion](../syntax/pe.md) syntax!)| +|`$*`|all positional parameters except `$0`, see [mass usage](../scripting/posparams.md#mass_usage)| +|`$@`|all positional parameters except `$0`, see [mass usage](../scripting/posparams.md#mass_usage)| +|`$#`|the number of arguments, not counting `$0`| These positional parameters reflect exactly what was given to the script when it was called. @@ -33,8 +33,7 @@ when it was called. Option-switch parsing (e.g. `-h` for displaying help) is not performed at this point. -See also [the dictionary entry for -\"parameter\"](../dict/parameter.md). +See also [the dictionary entry for "parameter"](../dict/parameter.md). ## The first argument @@ -42,15 +41,15 @@ The very first argument you can access is referenced as `$0`. It is usually set to the script's name exactly as called, and it's set on shell initialization: -[Testscript]{.underline} - it just echos `$0`: +Testscript - it just echos `$0`: #!/bin/bash echo "$0" You see, `$0` is always set to the name the script is called with (`>` -is the prompt\...): +is the prompt...): - > ./testscript + > ./testscript ./testscript > /usr/bin/testscript @@ -79,7 +78,7 @@ values: - `$1` will be discarded - `$2` will become `$1` - `$3` will become `$2` -- \... +- ... - in general: `$N` will become `$N-1` The command can take a number as argument: Number of positions to shift. @@ -139,7 +138,7 @@ a given wordlist. The loop uses the positional parameters as a wordlist: echo "$arg" done -[Advantage:]{.underline} The positional parameters will be preserved +Advantage: The positional parameters will be preserved ------------------------------------------------------------------------ @@ -172,7 +171,7 @@ There is a [small tutorial dedicated to ### All Positional Parameters -Sometimes it's necessary to just \"relay\" or \"pass\" given arguments +Sometimes it's necessary to just "relay" or "pass" given arguments to another program. It's very inefficient to do that in one of these loops, as you will destroy integrity, most likely (spaces!). @@ -180,27 +179,27 @@ The shell developers created `$*` and `$@` for this purpose. As overview: - Syntax Effective result - -------- ----------------------------- - `$*` `$1 $2 $3 ... ${N}` - `$@` `$1 $2 $3 ... ${N}` - `"$*"` `"$1c$2c$3c...c${N}"` - `"$@"` `"$1" "$2" "$3" ... "${N}"` +|Syntax|Effective result| +|-------|----------------------------| +|`$*`|`$1 $2 $3 ... ${N}`| +|`$@`|`$1 $2 $3 ... ${N}`| +|`"$*"`|`"$1c$2c$3c...c${N}"`| +|`"$@"`|`"$1" "$2" "$3" ... "${N}"`| Without being quoted (double quotes), both have the same effect: All positional parameters from `$1` to the last one used are expanded without any special handling. When the `$*` special parameter is double quoted, it expands to the -equivalent of: `"$1c$2c$3c$4c........$N"`, where \'c\' is the first +equivalent of: `"$1c$2c$3c$4c........$N"`, where 'c' is the first character of `IFS`. But when the `$@` special parameter is used inside double quotes, it -expands to the equivanent of\... +expands to the equivanent of... `"$1" "$2" "$3" "$4" ..... "$N"` -\...which **reflects all positional parameters as they were set +...which **reflects all positional parameters as they were set initially** and passed to the script or function. If you want to re-use your positional parameters to **call another program** (for example in a wrapper-script), then this is the choice for you, use double quoted @@ -234,12 +233,12 @@ reverse starting with the last one. `COUNT` may not be negative, i.e. the element count may not be decremented. -[**Example:**]{.underline} START at the last positional parameter: +**Example:** START at the last positional parameter: echo "${@: -1}" -[**Attention**]{.underline}: As of Bash 4, a `START` of `0` includes the -special parameter `$0`, i.e. the shell name or whatever \$0 is set to, +**Attention**: As of Bash 4, a `START` of `0` includes the +special parameter `$0`, i.e. the shell name or whatever `$0` is set to, when the positional parameters are in use. A `START` of `1` begins at `$1`. In Bash 3 and older, both `0` and `1` began at `$1`. @@ -247,7 +246,7 @@ when the positional parameters are in use. A `START` of `1` begins at Setting positional parameters with command line arguments, is not the only way to set them. The [builtin command, set](../commands/builtin/set.md) -may be used to \"artificially\" change the positional parameters from +may be used to "artificially" change the positional parameters from inside the script or function: set "This is" my new "set of" positional parameters @@ -260,7 +259,7 @@ inside the script or function: # $5: positional # $6: parameters -It's wise to signal \"end of options\" when setting positional +It's wise to signal "end of options" when setting positional parameters this way. If not, the dashes might be interpreted as an option switch by `set` itself: @@ -273,7 +272,8 @@ flags, which may otherwise be reset by `set` set -$- ... -FIXME continue +!!! warning "FIXME" + continue ## Production examples @@ -281,7 +281,7 @@ FIXME continue To make your program accept options as standard command syntax: -`COMMAND [options] ` \# Like \'cat -A file.txt\' +`COMMAND [options] # Like 'cat -A file.txt'` See simple option parsing code below. It's not that flexible. It doesn't auto-interpret combined options (-fu USER) but it works and is @@ -343,8 +343,8 @@ a good rudimentary way to parse your arguments. This simple wrapper enables filtering unwanted options (here: `-a` and `--all` for `ls`) out of the command line. It reads the positional parameters and builds a filtered array consisting of them, then calls -`ls` with the new option set. It also respects the `--` as \"end of -options\" for `ls` and doesn't change anything after it: +`ls` with the new option set. It also respects the `--` as "end of +options" for `ls` and doesn't change anything after it: #!/bin/bash diff --git a/docs/scripting/processtree.md b/docs/scripting/processtree.md index cf0d262..8d1a0ef 100644 --- a/docs/scripting/processtree.md +++ b/docs/scripting/processtree.md @@ -18,7 +18,7 @@ tree**. Every process has a parent process that started, or is responsible, for it. Every process has its own **context memory** (Not the memory where the process stores its data, rather, the memory where data is stored that doesn't directly belong to the process, but is -needed to run the process) i.e. [**The environment**]{.underline}. +needed to run the process) i.e. **The environment**. Every process has its **own** environment space. @@ -28,7 +28,7 @@ form, but they are not related to shell variables. A variable named `LANG`, for example, is used by every program that looks it up in its environment to determinate the current locale. -**[Attention:]{.underline}** A variable that is set, like with +**Attention:** A variable that is set, like with `MYVAR=Hello`, is **not** automatically part of the environment. You need to put it into the environment with the bash builtin command `export`: @@ -41,30 +41,30 @@ set by login scripts or programs). ## Executing programs -All the diagrams of the process tree use names like \"`xterm`\" or -\"`bash`\", but that's just to make it easier to understand what's +All the diagrams of the process tree use names like "`xterm`" or +"`bash`", but that's just to make it easier to understand what's going on, it doesn't mean those processes are actually executed. -Let's take a short look at what happens when you \"execute a program\" -from the Bash prompt, a program like \"ls\": +Let's take a short look at what happens when you "execute a program" +from the Bash prompt, a program like "ls": $ ls Bash will now perform **two steps**: - It will make a copy of itself -- The copy will replace itself with the \"ls\" program +- The copy will replace itself with the "ls" program -The copy of Bash will inherit the environment from the \"main Bash\" +The copy of Bash will inherit the environment from the "main Bash" process: All environment variables will also be copied to the new process. This step is called **forking**. For a short moment, you have a process tree that might look like -this\... +this... xterm ----- bash ----- bash(copy) -\...and after the \"second Bash\" (the copy) replaces itself with the +...and after the "second Bash" (the copy) replaces itself with the `ls` program (the copy execs it), it might look like xterm ----- bash ----- ls @@ -73,10 +73,10 @@ If everything was okay, the two steps resulted in one program being run. The copy of the environment from the first step (forking) becomes the environment for the final running program (in this case, `ls`). -[**What is so important about it?**]{.underline} In our example, what +**What is so important about it?** In our example, what the program `ls` does inside its own environment, it can't affect the environment of its parent process (in this case, `bash`). The -environment was copied when ls was executed. Nothing is \"copied back\" +environment was copied when ls was executed. Nothing is "copied back" to the parent environment when `ls` terminates. ## Bash playing with pipes @@ -84,7 +84,7 @@ to the parent environment when `ls` terminates. Pipes are a very powerful tool. You can connect the output of one process to the input of another process. We won't delve into piping at this point, we just want to see how it looks in the process tree. Again, -we execute some commands, this time, we\'ll run `ls` and `grep`: +we execute some commands, this time, we'll run `ls` and `grep`: $ ls | grep myfile @@ -98,7 +98,7 @@ Note once again, `ls` can't influence the `grep` environment, `grep` can't influence the `ls` environment, and neither `grep` nor `ls` can influence the `bash` environment. -[**How is that related to shell programming?!?**]{.underline} +**How is that related to shell programming?!?** Well, imagine some Bash code that reads data from a pipe. For example, the internal command `read`, which reads data from *stdin* and puts it @@ -120,12 +120,12 @@ it a bit, we have: See the relationship? The forked Bash process will count the lines like a charm. It will also set the variable `counter` as directed. But if everything ends, this extra process will be terminated - **your -\"counter\" variable is gone.** You see a 0 because in the main shell it +"counter" variable is gone.** You see a 0 because in the main shell it was 0, and wasn't changed by the child process! -[**So, how do we count the lines?**]{.underline} Easy: **Avoid the +**So, how do we count the lines?** Easy: **Avoid the subshell.** The details don't matter, the important thing is the shell -that sets the counter must be the \"main shell\". For example: +that sets the counter must be the "main shell". For example: counter=0 @@ -185,4 +185,5 @@ pipe in the command substitution: xterm ----- bash ----- bash (cmd. subst.) --| +-- wc -l -FIXME to be continued +!!! warning "FIXME" + to be continued diff --git a/docs/scripting/style.md b/docs/scripting/style.md index 79b2d38..57bc038 100644 --- a/docs/scripting/style.md +++ b/docs/scripting/style.md @@ -1,14 +1,15 @@ # Scripting with style -FIXME continue +!!! warning "FIXME" + continue These are some coding guidelines that helped me to read and understand my own code over the years. They also will help to produce code that -will be a bit more robust than \"if something breaks, I know how to fix -it\". +will be a bit more robust than "if something breaks, I know how to fix +it". This is not a bible, of course. But I have seen so much ugly and -terrible code (not only in shell) during all the years, that I\'m 100% +terrible code (not only in shell) during all the years, that I'm 100% convinced there needs to be *some* code layout and style. No matter which one you use, use it throughout your code (at least don't change it within the same shellscript file); don't change your code layout @@ -22,7 +23,7 @@ of course it helps others to read the code. Indentation is nothing that technically influences a script, it's only for us humans. -I\'m used to seeing/using indentation of *two space characters* (though +I'm used to seeing/using indentation of *two space characters* (though many may prefer 4 spaces, see below in the discussion section): - it's easy and fast to type @@ -32,7 +33,7 @@ many may prefer 4 spaces, see below in the discussion section): waste too much space on the line Speaking of hard-tabs: Avoid them if possible. They only make trouble. I -can imagine one case where they\'re useful: Indenting +can imagine one case where they're useful: Indenting [here-documents](../syntax/redirection.md#here_documents). ### Breaking up lines @@ -40,33 +41,33 @@ can imagine one case where they\'re useful: Indenting Whenever you need to break lines of long code, you should follow one of these two rules: -[**Indention using command width:**]{.underline} +**Indention using command width:** activate some_very_long_option \ some_other_option -[**Indention using two spaces:**]{.underline} +**Indention using two spaces:** activate some_very_long_option \ some_other_option Personally, with some exceptions, I prefer the first form because it -supports the visual impression of \"these belong together\". +supports the visual impression of "these belong together". ### Breaking compound commands [Compound commands](../syntax/ccmd/intro.md) form the structures that make a shell script different from a stupid enumeration of commands. Usually -they contain a kind of \"head\" and a \"body\" that contains command +they contain a kind of "head" and a "body" that contains command lists. This type of compound command is relatively easy to indent. -I\'m used to (not all points apply to all compound commands, just pick +I'm used to (not all points apply to all compound commands, just pick the basic idea): - put the introducing keyword and the initial command list or - parameters on one line (\"head\") -- put the \"body-introducing\" keyword on the same line -- the command list of the \"body\" on separate lines, indented by two + parameters on one line ("head") +- put the "body-introducing" keyword on the same line +- the command list of the "body" on separate lines, indented by two spaces - put the closing keyword on a separated line, indented like the initial introducing keyword @@ -82,7 +83,7 @@ What?! Well, here again: ##### if/then/elif/else This construct is a bit special, because it has keywords (`elif`, -`else`) \"in the middle\". The visually appealing way is to indent them +`else`) "in the middle". The visually appealing way is to indent them like this: if ...; then @@ -110,7 +111,7 @@ like this: The `case` construct might need a bit more discussion here, since its structure is a bit more complex. -In general, every new \"layer\" gets a new indentation level: +In general, every new "layer" gets a new indentation level: case $input in hello) @@ -149,13 +150,13 @@ It's - just like in C - the middle ground between smart, efficient and readable. If you need to use a cryptic construct, include a comment that explains -what your \"monster\" does. +what your "monster" does. ### Variable names Since all reserved variables are `UPPERCASE`, the safest way is to only use `lowercase` variable names. This is true for reading user input, -loop counting variables, etc., \... (in the example: `file`) +loop counting variables, etc., ... (in the example: `file`) - prefer `lowercase` variables - if you use `UPPERCASE` names, **do not use reserved variable names** @@ -165,9 +166,6 @@ loop counting variables, etc., \... (in the example: `file`) - if you use `UPPERCASE` names, prepend the name with a unique prefix (`MY_` in the example below) -```{=html} - -``` #!/bin/bash # the prefix 'MY_' @@ -200,7 +198,7 @@ in-code documentation for them. ### Parameter expansion -Unless you are really sure what you\'re doing, **quote every parameter +Unless you are really sure what you're doing, **quote every parameter expansion**. There are some cases where this isn't needed from a technical point of @@ -212,7 +210,7 @@ view, e.g. - variable assignment: `VAR=$WORD` But quoting these is never a mistake. If you quote every parameter -expansion, you\'ll be safe. +expansion, you'll be safe. If you need to parse a parameter as a list of words, you can't quote, of course, e.g. @@ -252,8 +250,8 @@ should quote the command substitution! ### Eval -Well, like Greg says: **\"If eval is the answer, surely you are asking -the wrong question.\"** +Well, like Greg says: **"If eval is the answer, surely you are asking +the wrong question."** Avoid it, unless absolutely neccesary: @@ -262,7 +260,7 @@ Avoid it, unless absolutely neccesary: - if possible, re-think the way your script works, if it seems you can't avoid `eval` with your current method - if you really, really, have to use it, then take care, and be sure - about what you\'re doing + about what you're doing ## Basic structure @@ -281,8 +279,8 @@ The basic structure of a script simply reads: If possible (I know it's not always possible!), use a [shebang](../dict/interpreter_directive.md). -Be careful with `/bin/sh`: The argument that \"on Linux `/bin/sh` is -Bash\" **is a lie** (and technically irrelevant) +Be careful with `/bin/sh`: The argument that "on Linux `/bin/sh` is +Bash" **is a lie** (and technically irrelevant) The shebang serves two purposes for me: @@ -290,16 +288,16 @@ The shebang serves two purposes for me: called directly: If you code for Bash, specify `bash`! - it documents the desired interpreter (so: use `bash` when you write a Bash-script, use `sh` when you write a general Bourne/POSIX - script, \...) + script, ...) ### Configuration variables I call variables that are meant to be changed by the user -\"configuration variables\" here. +"configuration variables" here. Make them easy to find (directly at the top of the script), give them meaningful names and maybe a short comment. As noted above, use -`UPPERCASE` for them only when you\'re sure about what you\'re doing. +`UPPERCASE` for them only when you're sure about what you're doing. `lowercase` will be the safest. ### Function definitions @@ -310,7 +308,7 @@ overview and ensures that all function names are known before they are used. Since a function isn't parsed before it is executed, you usually don't -have to ensure they\'re in a specific order. +have to ensure they're in a specific order. The portable form of the function definition should be used, without the `function` keyword (here using the [grouping compound @@ -336,7 +334,7 @@ begins its work in a potentially broken state. ### Availability of commands If you use external commands that may not be present on the path, or not -installed, check for their availability, then tell the user they\'re +installed, check for their availability, then tell the user they're missing. Example: @@ -370,9 +368,9 @@ means: This, **and only this**, will enable the calling component to check the operation status of your script. -You know: **\"One of the main causes of the fall of the Roman Empire was +You know: **"One of the main causes of the fall of the Roman Empire was that, lacking zero, they had no way to indicate successful termination -of their C programs.\"** *-- Robert Firth* +of their C programs."** *-- Robert Firth* ## Misc @@ -405,5 +403,5 @@ of their C programs.\"** *-- Robert Firth* ### Tooling - some of these guidelines, such as indentation, positioning of - \"body-introducing\" keywords, and portable function declarations, + "body-introducing" keywords, and portable function declarations, can be enforced by [shfmt](https://github.com/mvdan/sh) diff --git a/docs/scripting/terminalcodes.md b/docs/scripting/terminalcodes.md index 7eded0d..96c1996 100644 --- a/docs/scripting/terminalcodes.md +++ b/docs/scripting/terminalcodes.md @@ -23,8 +23,8 @@ printed (like any other text). If the terminal understands the code, it won't display the character-sequence, but will perform some action. You can print the codes with a simple `echo` command. -[**Note:**]{.underline} I see codes referenced as \"Bash colors\" -sometimes (several \"Bash tutorials\" etc\...): That's a completely +**Note:** I see codes referenced as "Bash colors" +sometimes (several "Bash tutorials" etc...): That's a completely incorrect definition. ## The tput command @@ -43,7 +43,7 @@ understands). ## The codes -In this list I\'ll focus on ANSI/VT100 control codes for the most common +In this list I'll focus on ANSI/VT100 control codes for the most common actions - take it as quick reference. The documentation of your terminal or the `terminfo` database is always the preferred source when something is unclear! Also the `tput` acronyms are usually the ones dedicated for @@ -53,7 +53,7 @@ I listed only the most relevant codes, of course, any ANSI terminal understands many more! But let's keep the discussion centered on common shell scripting ;-) -If I couldn't find a matching ANSI escape, you\'ll see a :?: as the +If I couldn't find a matching ANSI escape, you'll see a :?: as the code. Feel free to mail me or fix it. The ANSI codes always start with the ESC character. (ASCII 0x1B or octal @@ -63,29 +63,29 @@ codes directly - use the `tput` command!** All codes that can be used with `tput` can be found in terminfo(5). (on OpenBSD at least) See [OpenBSD's terminfo(5)](http://www.openbsd.org/cgi-bin/man.cgi?query=terminfo&apropos=0&sektion=5&manpath=OpenBSD+Current&arch=i386&format=html) -under the [Capabilities]{.underline} section. The *cap-name* is the code +under the Capabilities section. The *cap-name* is the code to use with tput. A description of each code is also provided. ### General useful ASCII codes The **Ctrl-Key** representation is simply associating the non-printable characters from ASCII code 1 with the printable (letter) characters from -ASCII code 65 (\"A\"). ASCII code 1 would be `^A` (Ctrl-A), while ASCII +ASCII code 65 ("A"). ASCII code 1 would be `^A` (Ctrl-A), while ASCII code 7 (BEL) would be `^G` (Ctrl-G). This is a common representation (and input method) and historically comes from one of the VT series of terminals. - Name decimal octal hex C-escape Ctrl-Key Description - ------- --------- ------- ------ ---------- ---------- -------------------------------- - `BEL` 7 007 0x07 `\a` `^G` Terminal bell - `BS` 8 010 0x08 `\b` `^H` Backspace - `HT` 9 011 0x09 `\t` `^I` Horizontal TAB - `LF` 10 012 0x0A `\n` `^J` Linefeed (newline) - `VT` 11 013 0x0B `\v` `^K` Vertical TAB - `FF` 12 014 0x0C `\f` `^L` Formfeed (also: New page `NP`) - `CR` 13 015 0x0D `\r` `^M` Carriage return - `ESC` 27 033 0x1B `` `^[` Escape character - `DEL` 127 177 0x7F `` `` Delete character +|Name|decimal|octal|hex|C-escape|Ctrl-Key|Description| +|-------|---------|-------|------|----------|----------|--------------------------------| +|`BEL`|7|007|0x07|`\a`|`^G`|Terminal bell| +|`BS`|8|010|0x08|`\b`|`^H`|Backspace| +|`HT`|9|011|0x09|`\t`|`^I`|Horizontal TAB| +|`LF`|10|012|0x0A|`\n`|`^J`|Linefeed (newline)| +|`VT`|11|013|0x0B|`\v`|`^K`|Vertical TAB| +|`FF`|12|014|0x0C|`\f`|`^L`|Formfeed (also: New page `NP`)| +|`CR`|13|015|0x0D|`\r`|`^M`|Carriage return| +|`ESC`|27|033|0x1B|``|`^[`|Escape character| +|`DEL`|127|177|0x7F|``|``|Delete character| ### Cursor handling @@ -114,7 +114,7 @@ terminals. ANSI terminfo equivalent Description --------- --------------------- ---------------------------------------------------------------- `[ K`\ `el` **Clear line** from current cursor position **to end** of line - `[ 0 K` + `[ 0 K` `[ 1 K` `el1` **Clear line from beginning** to current cursor position @@ -123,44 +123,43 @@ terminals. ### General text attributes - ANSI terminfo equivalent Description - --------- ----------------------------- ------------------------------------------------ - `[ 0 m` `sgr0` Reset all attributes - `[ 1 m` `bold` Set \"bright\" attribute - `[ 2 m` `dim` Set \"dim\" attribute - `[ 3 m` `smso` Set \"standout\" attribute - `[ 4 m` set `smul` unset `rmul` :?: Set \"underscore\" (underlined text) attribute - `[ 5 m` `blink` Set \"blink\" attribute - `[ 7 m` `rev` Set \"reverse\" attribute - `[ 8 m` `invis` Set \"hidden\" attribute - +|ANSI|terminfo equivalent|Description| +|----|-------------------|-----------| +|`[ 0 m`|`sgr0`|Reset all attributes| +|`[ 1 m`|`bold`|Set "bright" attribute| +|`[ 2 m`|`dim`|Set "dim" attribute| +|`[ 3 m`|`smso`|Set "standout" attribute| +|`[ 4 m`|set `smul` unset `rmul` :?:|Set "underscore" (underlined text) attribute| +|`[ 5 m`|`blink`|Set "blink" attribute| +|`[ 7 m`|`rev`|Set "reverse" attribute| +|`[ 8 m`|`invis`|Set "hidden" attribute| ### Foreground coloring - ANSI terminfo equivalent Description - ----------- --------------------- ---------------------------------------------- - `[ 3 0 m` `setaf 0` Set **foreground** to color #0 - **black** - `[ 3 1 m` `setaf 1` Set **foreground** to color #1 - **red** - `[ 3 2 m` `setaf 2` Set **foreground** to color #2 - **green** - `[ 3 3 m` `setaf 3` Set **foreground** to color #3 - **yellow** - `[ 3 4 m` `setaf 4` Set **foreground** to color #4 - **blue** - `[ 3 5 m` `setaf 5` Set **foreground** to color #5 - **magenta** - `[ 3 6 m` `setaf 6` Set **foreground** to color #6 - **cyan** - `[ 3 7 m` `setaf 7` Set **foreground** to color #7 - **white** - `[ 3 9 m` `setaf 9` Set **default** color as foreground color +|ANSI|terminfo equivalent|Description| +|----|-------------------|-----------| +|`[ 3 0 m`|`setaf 0`|Set **foreground** to color \#0 - **black**| +|`[ 3 1 m`|`setaf 1`|Set **foreground** to color \#1 - **red**| +|`[ 3 2 m`|`setaf 2`|Set **foreground** to color \#2 - **green**| +|`[ 3 3 m`|`setaf 3`|Set **foreground** to color \#3 - **yellow**| +|`[ 3 4 m`|`setaf 4`|Set **foreground** to color \#4 - **blue**| +|`[ 3 5 m`|`setaf 5`|Set **foreground** to color \#5 - **magenta**| +|`[ 3 6 m`|`setaf 6`|Set **foreground** to color \#6 - **cyan**| +|`[ 3 7 m`|`setaf 7`|Set **foreground** to color \#7 - **white**| +|`[ 3 9 m`|`setaf 9`|Set **default** color as foreground color| ### Background coloring - ANSI terminfo equivalent Description - ----------- --------------------- ---------------------------------------------- - `[ 4 0 m` `setab 0` Set **background** to color #0 - **black** - `[ 4 1 m` `setab 1` Set **background** to color #1 - **red** - `[ 4 2 m` `setab 2` Set **background** to color #2 - **green** - `[ 4 3 m` `setab 3` Set **background** to color #3 - **yellow** - `[ 4 4 m` `setab 4` Set **background** to color #4 - **blue** - `[ 4 5 m` `setab 5` Set **background** to color #5 - **magenta** - `[ 4 6 m` `setab 6` Set **background** to color #6 - **cyan** - `[ 4 7 m` `setab 7` Set **background** to color #7 - **white** - `[ 4 9 m` `setab 9` Set **default** color as background color +|ANSI|terminfo equivalent|Description| +|----|-------------------|-----------| +|`[ 4 0 m`|`setab 0`|Set **background** to color \#0 - **black**| +|`[ 4 1 m`|`setab 1`|Set **background** to color \#1 - **red**| +|`[ 4 2 m`|`setab 2`|Set **background** to color \#2 - **green**| +|`[ 4 3 m`|`setab 3`|Set **background** to color \#3 - **yellow**| +|`[ 4 4 m`|`setab 4`|Set **background** to color \#4 - **blue**| +|`[ 4 5 m`|`setab 5`|Set **background** to color \#5 - **magenta**| +|`[ 4 6 m`|`setab 6`|Set **background** to color \#6 - **cyan**| +|`[ 4 7 m`|`setab 7`|Set **background** to color \#7 - **white**| +|`[ 4 9 m`|`setab 9`|Set **default** color as background color| ### Misc codes @@ -168,7 +167,7 @@ terminals. Used capabilities: `smcup`, `rmcup` -You\'ve undoubtedly already encountered programs that restore the +You've undoubtedly already encountered programs that restore the terminal contents after they do their work (like `vim`). This can be done by the following commands: @@ -187,7 +186,7 @@ These features require that certain capabilities exist in your termcap/terminfo. While `xterm` and most of its clones (`rxvt`, `urxvt`, etc) will support the instructions, your operating system may not include references to them in its default xterm profile. (FreeBSD, in -particular, falls into this category.) If \`tput smcup\` appears to do +particular, falls into this category.) If `tput smcup` appears to do nothing for you, and you don't want to modify your system termcap/terminfo data, and you KNOW that you are using a compatible xterm application, the following may work for you: @@ -198,14 +197,14 @@ xterm application, the following may work for you: Certain software uses these codes (via their termcap capabilities) as well. You may have seen the screen save/restore in `less`, `vim`, `top`, `screen` and others. Some of these applications may also provide -configuration options to \*disable\* this behaviour. For example, `less` +configuration options to *disable* this behaviour. For example, `less` has a `-X` option for this, which can also be set in an environment variable: export LESS=X less /path/to/file -Similarly, `vim` can be configured not to \"restore\" the screen by +Similarly, `vim` can be configured not to "restore" the screen by adding the following to your `~/.vimrc`: set t_ti= t_te= @@ -226,7 +225,7 @@ in graphical environments. The Virtual Terminal implemented in the Linux kernel supports only 16 colors, and the usual default terminfo entry for `TERM=linux` defines -only 8. There is sometimes an alternate \"linux-16color\" that you can +only 8. There is sometimes an alternate "linux-16color" that you can switch to, to get the other 8 colors. ## Bash examples @@ -237,11 +236,11 @@ switch to, to get the other 8 colors. ### Colors using tput -[Directly inside the echo:]{.underline} +Directly inside the echo: echo "TPUT is a $(tput setaf 2)nice$(tput setaf 9) and $(tput setaf 5)user friendly$(tput setaf 9) terminal capability database." -[With preset variables:]{.underline} +With preset variables: COL_NORM="$(tput setaf 9)" COL_RED="$(tput setaf 1)" @@ -250,7 +249,7 @@ switch to, to get the other 8 colors. ### Misc -[HOME function]{.underline} +HOME function home() { # yes, actually not much shorter ;-) @@ -323,7 +322,7 @@ default), but uses only features that don't make the Bash parser crash. # Combined Bash/ksh93 flavors by Dan Douglas (ormaaj) function doBash { - typeset P Q X Y a b c i v x y + typeset P Q X Y a b c i v x y for ((P=10**8,Q=P/100,X=320*Q/cols,Y=210*Q/lines,y=-105*Q,v=-220*Q,x=v;y<105*Q;x=v,y+=Y)); do for ((;x**Notes:** - if done blindly, the `known_host`-file may grow very large. It might be wise to check for key existance first diff --git a/docs/snipplets/wrapperargs.md b/docs/snipplets/wrapperargs.md index 0b41326..9078a70 100644 --- a/docs/snipplets/wrapperargs.md +++ b/docs/snipplets/wrapperargs.md @@ -31,7 +31,7 @@ then this script should generate code that looks like you need correct escapes or quotes to not generate shell special characters out of normal text (like embedded dollar signs `$`). -**[Solution:]{.underline}** +**Solution:** A loop over the own arguments that writes out properly quoted/escaped code to the generated script file @@ -67,7 +67,7 @@ The generated script will look like: #!/bin/bash - echo 'fir$t' 'seco "ond"' 'thir'\''d' + echo 'fir$t' 'seco "ond"' 'thir'\''d' ## Using printf @@ -90,4 +90,4 @@ The generated script will look like: #!/bin/bash - echo fir\$t seco\ \"ond\" thir\'d + echo fir\$t seco\ \"ond\" thir\'d diff --git a/docs/syntax/arith_expr.md b/docs/syntax/arith_expr.md index f703835..332f2de 100644 --- a/docs/syntax/arith_expr.md +++ b/docs/syntax/arith_expr.md @@ -74,7 +74,7 @@ When no base is specified, the base 10 (decimal) is assumed, except when the prefixes as mentioned above (octals, hexadecimals) are present. The specified base can range from 2 to 64. To represent digits in a specified base greater than 10, characters other than 0 to 9 are needed -(in this order, low => high): +(in this order, low => high): - `0 ... 9` - `a ... z` @@ -124,8 +124,8 @@ named parameters, e.g.: # will output "3"! Of course, in the end, when it finally evaluates to something that is -**not** a valid arithmetic expression (newlines, ordinary text, \...) -then you\'ll get an error. +**not** a valid arithmetic expression (newlines, ordinary text, ...) +then you'll get an error. When variables are referenced, the notation `1 + $X` is equivalent to the notation `1 + X`, both are allowed. @@ -138,10 +138,10 @@ an arithmetic expression. ## Truth Unlike command exit and return codes, arithmetic expressions evaluate to -logical \"true\" when they are not 0. When they are 0, they evaluate to -\"false\". The [arithmetic evaluation compound -command](../syntax/ccmd/arithmetic_eval.md) reverses the \"truth\" of an -arithmetic expression to match the \"truth\" of command exit codes: +logical "true" when they are not 0. When they are 0, they evaluate to +"false". The [arithmetic evaluation compound +command](../syntax/ccmd/arithmetic_eval.md) reverses the "truth" of an +arithmetic expression to match the "truth" of command exit codes: - if the arithmetic expression brings up a value not 0 (arithmetic true), it returns 0 (shell true) @@ -160,89 +160,79 @@ That means, the following `if`-clause will execute the `else`-thread: ### Assignment - Operator Description - --------------------- ---------------------------------------------------------------------------------------------------- - ` = ` normal assignment - ` *= ` equivalent to ` = * `, see [calculation operators](../syntax/arith_expr.md#calculations) - ` /= ` equivalent to ` = / `, see [calculation operators](../syntax/arith_expr.md#calculations) - ` %= ` equivalent to ` = % `, see [calculation operators](../syntax/arith_expr.md#calculations) - ` += ` equivalent to ` = + `, see [calculation operators](../syntax/arith_expr.md#calculations) - ` -= ` equivalent to ` = - `, see [calculation operators](../syntax/arith_expr.md#calculations) - ` <<= ` equivalent to ` = << `, see [bit operations](../syntax/arith_expr.md#bit_operations) - ` >>= ` equivalent to ` = >> `, see [bit operations](../syntax/arith_expr.md#bit_operations) - ` &= ` equivalent to ` = & `, see [bit operations](../syntax/arith_expr.md#bit_operations) - ` ^= ` equivalent to ` = ^ `, see [bit operations](../syntax/arith_expr.md#bit_operations) - ` |= ` equivalent to ` = | `, see [bit operations](../syntax/arith_expr.md#bit_operations) +|Operator|Description| +|--------|-----------| +|` = `|normal assignment| +|` *= `|equivalent to ` = * `, see [calculation operators](../syntax/arith_expr.md#calculations)| +|` /= `|equivalent to ` = / `, see [calculation operators](../syntax/arith_expr.md#calculations)| +|` %= `|equivalent to ` = % `, see [calculation operators](../syntax/arith_expr.md#calculations)| +|` += `|equivalent to ` = + `, see [calculation operators](../syntax/arith_expr.md#calculations)| +|` -= `|equivalent to ` = - `, see [calculation operators](../syntax/arith_expr.md#calculations)| +|` <<= `|equivalent to ` = << `, see [bit operations](../syntax/arith_expr.md#bit_operations)| +|` >>= `|equivalent to ` = >> `, see [bit operations](../syntax/arith_expr.md#bit_operations)| +|` &= `|equivalent to ` = & `, see [bit operations](../syntax/arith_expr.md#bit_operations)| +|` ^= `|equivalent to ` = ^ `, see [bit operations](../syntax/arith_expr.md#bit_operations)| +|`|= `|equivalent to ` = |`, see [bit operations](../syntax/arith_expr.md#bit_operations)| ### Calculations - Operator Description - ---------- -------------------- - `*` multiplication - `/` division - `%` remainder (modulo) - `+` addition - `-` subtraction - `**` exponentiation +|Operator|Description| +|--------|-----------| +|`*`|multiplication| +|`/`|division| +|`%`|remainder (modulo)| +|`+`|addition| +|`-`|subtraction| +|`**`|exponentiation| ### Comparisons - Operator Description - ---------- ----------------------------------- - `<` comparison: less than - `>` comparison: greater than - `<=` comparison: less than or equal - `>=` comparison: greater than or equal - `==` equality - `!=` inequality +|Operator|Description| +|--------|-----------| +|`<`|comparison: less than| +|`>`|comparison: greater than| +|`<=`|comparison: less than or equal| +|`>=`|comparison: greater than or equal| +|`==`|equality| +|`!=`|inequality| ### Bit operations - Operator Description - ---------- ---------------------------- - `~` bitwise negation - `<<` bitwise shifting (left) - `>>` bitwise shifting (right) - `&` bitwise AND - `^` bitwise exclusive OR (XOR) - `|` bitwise OR +|Operator|Description| +|--------|-----------| +|`~`|bitwise negation| +|`<<`|bitwise shifting (left)| +|`>>`|bitwise shifting (right)| +|`&`|bitwise AND| +|`^`|bitwise exclusive OR (XOR)| +|`|`|bitwise OR| ### Logical - Operator Description - ---------- ------------------ - `!` logical negation - `&&` logical AND - `||` logical OR +|Operator|Description| +|--------|-----------| +|`!`|logical negation| +|`&&`|logical AND| +|`||`|logical OR| + ### Misc - ------------------------------------------------------------------------------------------------- - Operator Description - ---------------------------- -------------------------------------------------------------------- - `id++` **post-increment** of the variable `id` (not required by POSIX(r)) - - `id--` **post-decrement** of the variable `id` (not required by POSIX(r)) - - `++id` **pre-increment** of the variable `id` (not required by POSIX(r)) - - `--id` **pre-decrement** of the variable `id` (not required by POSIX(r)) - - `+` unary plus - - `-` unary minus - - ` ? : ` conditional (ternary) operator\ - ? : - - ` , ` expression list - - `( )` subexpression (to force precedence) - ------------------------------------------------------------------------------------------------- +|Operator|Description| +|--------|-----------| +|`id++`|**post-increment** of the variable `id` (not required by POSIX(r))| +|`id--`|**post-decrement** of the variable `id` (not required by POSIX(r))| +|`++id`|**pre-increment** of the variable `id` (not required by POSIX(r))| +|`--id`|**pre-decrement** of the variable `id` (not required by POSIX(r))| +|`+`|unary plus| +|`-`|unary minus| +|` ? : `|conditional (ternary) operator <condition> ? <result-if-true> : <result-if-false>| +|` , `|expression list| +|`( )`|subexpression (to force precedence)| ## Precedence -The operator precedence is as follows (highest -> lowest): +The operator precedence is as follows (highest -> lowest): - Postfix (`id++`, `id--`) - Prefix (`++id`, `--id`) @@ -274,19 +264,19 @@ Bash's overall language construct is based on exit codes or return codes of commands or functions to be executed. `if` statements, `while` loops, etc., they all take the return codes of commands as conditions. -Now the problem is: The return codes (0 means \"TRUE\" or \"SUCCESS\", -not 0 means \"FALSE\" or \"FAILURE\") don't correspond to the meaning -of the result of an arithmetic expression (0 means \"FALSE\", not 0 -means \"TRUE\"). +Now the problem is: The return codes (0 means "TRUE" or "SUCCESS", +not 0 means "FALSE" or "FAILURE") don't correspond to the meaning +of the result of an arithmetic expression (0 means "FALSE", not 0 +means "TRUE"). That's why all commands and keywords that do arithmetic operations attempt to **translate** the arithmetical meaning into an equivalent return code. This simply means: -- if the arithmetic operation evaluates to 0 (\"FALSE\"), the return - code is not 0 (\"FAILURE\") -- if the arithmetic operation evaluates to 1 (\"TRUE\"), the return - code is 0 (\"SUCCESS\") +- if the arithmetic operation evaluates to 0 ("FALSE"), the return + code is not 0 ("FAILURE") +- if the arithmetic operation evaluates to 1 ("TRUE"), the return + code is 0 ("SUCCESS") This way, you can easily use arithmetic expressions (along with the commands or keywords that operate them) as conditions for `if`, `while` @@ -302,47 +292,48 @@ else fi ``` - Beware that `set -e` can change the -runtime behavior of scripts. For example, +!!! warning "Beware that `set -e` can change the runtime behavior of scripts." -This non-equivalence of code behavior deserves some attention. Consider -what happens if v happens to be zero in the expression below: + For example, -``` bash -((v += 0)) -echo $? -``` + This non-equivalence of code behavior deserves some attention. Consider + what happens if v happens to be zero in the expression below: -1 + ``` bash + ((v += 0)) + echo $? + ``` -(\"FAILURE\") + 1 -``` bash -v=$((v + 0)) -echo $? -``` + ("FAILURE") -0 + ``` bash + v=$((v + 0)) + echo $? + ``` -(\"SUCCESS\") + 0 -The return code behavior is not equivalent to the arithmetic behavior, -as has been noted. + ("SUCCESS") -A workaround is to use a list operation that returns True, or use the -second assignment style. + The return code behavior is not equivalent to the arithmetic behavior, + as has been noted. -``` bash -((v += 0)) || : -echo $? -``` + A workaround is to use a list operation that returns True, or use the + second assignment style. -0 + ``` bash + ((v += 0)) || : + echo $? + ``` -(\"SUCCESS\") + 0 -This change in code behavior was discovered once the script was run -under set -e. + ("SUCCESS") + + This change in code behavior was discovered once the script was run + under set -e. ## Arithmetic expressions in Bash @@ -350,4 +341,4 @@ under set -e.
- [Arithmetic expansion](../syntax/expansion/arith.md) - [Arithmetic evaluation compound command](../syntax/ccmd/arithmetic_eval.md) -- [The \"let\" builtin command](../commands/builtin/let.md) +- [The "let" builtin command](../commands/builtin/let.md) diff --git a/docs/syntax/arrays.md b/docs/syntax/arrays.md index 3f574dd..d286de2 100644 --- a/docs/syntax/arrays.md +++ b/docs/syntax/arrays.md @@ -38,7 +38,7 @@ Bash supports two different types of ksh-like one-dimensional arrays. ksh88. Similar, partially compatible syntax was inherited by many derivatives including Bash. Indexed arrays always carry the `-a` attribute. -- *Associative arrays* (sometimes known as a \"hash\" or \"dict\") use +- *Associative arrays* (sometimes known as a "hash" or "dict") use arbitrary nonempty strings as keys. In other words, associative arrays allow you to look up a value from a table based upon its corresponding string label. **Associative arrays are always @@ -99,12 +99,12 @@ an array without assigning any values (see [declaration](#Declaration)). The following explicitly give variables array attributes, making them arrays: - Syntax Description - -------------------- ------------------------------------------------------------------------------------------------------------------------- - `ARRAY=()` Declares an **indexed** array `ARRAY` and initializes it to be empty. This can also be used to empty an existing array. - `ARRAY[0]=` Generally sets the first element of an **indexed** array. If no array `ARRAY` existed before, it is created. - `declare -a ARRAY` Declares an **indexed** array `ARRAY`. An existing array is not initialized. - `declare -A ARRAY` Declares an **associative** array `ARRAY`. This is the one and only way to create associative arrays. +|Syntax|Description| +|------|-----------| +|`ARRAY=()`|Declares an **indexed** array `ARRAY` and initializes it to be empty. This can also be used to empty an existing array.| +|`ARRAY[0]=`|Generally sets the first element of an **indexed** array. If no array `ARRAY` existed before, it is created.| +|`declare -a ARRAY`|Declares an **indexed** array `ARRAY`. An existing array is not initialized.| +|`declare -A ARRAY`|Declares an **associative** array `ARRAY`. This is the one and only way to create associative arrays.| As an example, and for use below, let's declare our `NAMES` array as described [above](#purpose): @@ -116,31 +116,32 @@ described [above](#purpose): Storing values in arrays is quite as simple as storing values in normal variables. - Syntax Description - --------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `ARRAY[N]=VALUE` Sets the element `N` of the **indexed** array `ARRAY` to `VALUE`. **`N` can be any valid [arithmetic expression](../syntax/arith_expr.md)**. - `ARRAY[STRING]=VALUE` Sets the element indexed by `STRING` of the **associative array** `ARRAY`. - `ARRAY=VALUE` As above. If no index is given, as a default the zeroth element is set to `VALUE`. Careful, this is even true of associative arrays - there is no error if no key is specified, and the value is assigned to string index \"0\". - `ARRAY=(E1\ E2\ ...)` Compound array assignment - sets the whole array `ARRAY` to the given list of elements indexed sequentially starting at zero. The array is unset before assignment unless the += operator is used. When the list is empty (`ARRAY=()`), the array will be set to an empty array. This method obviously does not use explicit indexes. An **associative array** can **not** be set like that! Clearing an associative array using `ARRAY=()` works. - `ARRAY=([X]=E1\ [Y]=E2\ ...)` Compound assignment for indexed arrays with index-value pairs declared individually (here for example `X` and `Y`). X and Y are arithmetic expressions. This syntax can be combined with the above - elements declared without an explicitly specified index are assigned sequentially starting at either the last element with an explicit index, or zero. - `ARRAY=([S1]=E1\ [S2]=E2\ ...)` Individual mass-setting for **associative arrays**. The named indexes (here: `S1` and `S2`) are strings. - `ARRAY+=(E1\ E2\ ...)` Append to ARRAY. - `ARRAY=("${ANOTHER_ARRAY[@]}")` Copy ANOTHER_ARRAY to ARRAY, copying each element. +|Syntax|Description| +|------|-----------| +|`ARRAY[N]=VALUE`|Sets the element `N` of the **indexed** array `ARRAY` to `VALUE`. **`N` can be any valid [arithmetic expression](../syntax/arith_expr.md)**.| +|`ARRAY[STRING]=VALUE`|Sets the element indexed by `STRING` of the **associative array** `ARRAY`.| +|`ARRAY=VALUE`|As above. If no index is given, as a default the zeroth element is set to `VALUE`. Careful, this is even true of associative arrays - there is no error if no key is specified, and the value is assigned to string index "0".| +|`ARRAY=(E1\ E2\ ...)`|Compound array assignment - sets the whole array `ARRAY` to the given list of elements indexed sequentially starting at zero. The array is unset before assignment unless the += operator is used. When the list is empty (`ARRAY=()`), the array will be set to an empty array. This method obviously does not use explicit indexes. An **associative array** can **not** be set like that! Clearing an associative array using `ARRAY=()` works.| +|`ARRAY=([X]=E1\ [Y]=E2\ ...)`|Compound assignment for indexed arrays with index-value pairs declared individually (here for example `X` and `Y`). X and Y are arithmetic expressions. This syntax can be combined with the above - elements declared without an explicitly specified index are assigned sequentially starting at either the last element with an explicit index, or zero.| +|`ARRAY=([S1]=E1\ [S2]=E2\ ...)`|Individual mass-setting for **associative arrays**. The named indexes (here: `S1` and `S2`) are strings.| +|`ARRAY+=(E1\ E2\ ...)`|Append to ARRAY.| +|`ARRAY=("${ANOTHER_ARRAY[@]}")`|Copy ANOTHER_ARRAY to ARRAY, copying each element.| As of now, arrays can't be exported. ### Getting values - For completeness and details on several parameter expansion -variants, see the [article about parameter expansion](../syntax/pe.md) and -check the notes about arrays. +!!! info "" + For completeness and details on several parameter expansion + variants, see the [article about parameter expansion](../syntax/pe.md) and + check the notes about arrays. - Syntax Description - ----------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `${ARRAY[N]}` Expands to the value of the index `N` in the **indexed** array `ARRAY`. If `N` is a negative number, it's treated as the offset from the maximum assigned index (can't be used for assignment) - 1 - `${ARRAY[S]}` Expands to the value of the index `S` in the **associative** array `ARRAY`. - `"${ARRAY[@]}" ${ARRAY[@]} "${ARRAY[*]}" ${ARRAY[*]}` Similar to [mass-expanding positional parameters](../scripting/posparams.md#mass_usage), this expands to all elements. If unquoted, both subscripts `*` and `@` expand to the same result, if quoted, `@` expands to all elements individually quoted, `*` expands to all elements quoted as a whole. - `"${ARRAY[@]:N:M}" ${ARRAY[@]:N:M} "${ARRAY[*]:N:M}" ${ARRAY[*]:N:M}` Similar to what this syntax does for the characters of a single string when doing [substring expansion](../syntax/pe.md#substring_expansion), this expands to `M` elements starting with element `N`. This way you can mass-expand individual indexes. The rules for quoting and the subscripts `*` and `@` are the same as above for the other mass-expansions. +|Syntax|Description| +|------|-----------| +|`${ARRAY[N]}`|Expands to the value of the index `N` in the **indexed** array `ARRAY`. If `N` is a negative number, it's treated as the offset from the maximum assigned index (can't be used for assignment) - 1| +|`${ARRAY[S]}`|Expands to the value of the index `S` in the **associative** array `ARRAY`.| +|`"${ARRAY[@]}" ${ARRAY[@]} "${ARRAY[*]}" ${ARRAY[*]}`|Similar to [mass-expanding positional parameters](../scripting/posparams.md#mass_usage), this expands to all elements. If unquoted, both subscripts `*` and `@` expand to the same result, if quoted, `@` expands to all elements individually quoted, `*` expands to all elements quoted as a whole.| +|`"${ARRAY[@]:N:M}" ${ARRAY[@]:N:M} "${ARRAY[*]:N:M}" ${ARRAY[*]:N:M}`|Similar to what this syntax does for the characters of a single string when doing [substring expansion](../syntax/pe.md#substring_expansion), this expands to `M` elements starting with element `N`. This way you can mass-expand individual indexes. The rules for quoting and the subscripts `*` and `@` are the same as above for the other mass-expansions.| For clarification: When you use the subscripts `@` or `*` for mass-expanding, then the behaviour is exactly what it is for `$@` and @@ -150,62 +151,50 @@ article to understand what's going on. ### Metadata - -------------------------------------------------------------------------------------------------------------------------------- - Syntax Description - --------------------- ---------------------------------------------------------------------------------------------------------- - `${#ARRAY[N]}` Expands to the **length** of an individual array member at index `N` (**stringlength**) - - `${#ARRAY[STRING]}` Expands to the **length** of an individual associative array member at index `STRING` (**stringlength**) - - `${#ARRAY[@]}`\ Expands to the **number of elements** in `ARRAY` - `${#ARRAY[*]}` - - `${!ARRAY[@]}`\ Expands to the **indexes** in `ARRAY` since BASH 3.0 - `${!ARRAY[*]}` - -------------------------------------------------------------------------------------------------------------------------------- +|Syntax|Description| +|------|-----------| +|`${#ARRAY[N]}`|Expands to the **length** of an individual array member at index `N` (**stringlength**)| +|`${#ARRAY[STRING]}`|Expands to the **length** of an individual associative array member at index `STRING` (**stringlength**)| +|`${#ARRAY[@]}` \ `${#ARRAY[*]}`|Expands to the **number of elements** in `ARRAY`| +|`${!ARRAY[@]}` \ `${!ARRAY[*]}`|Expands to the **indexes** in `ARRAY` since BASH 3.0| ### Destruction The [unset](../commands/builtin/unset.md) builtin command is used to destroy (unset) arrays or individual elements of arrays. - -------------------------------------------------------------------------------------------------- - Syntax Description - -------------------------- ----------------------------------------------------------------------- - `unset -v ARRAY`\ Destroys a complete array - `unset -v ARRAY[@]`\ - `unset -v ARRAY[*]` - - `unset -v ARRAY[N]` Destroys the array element at index `N` - - `unset -v ARRAY[STRING]` Destroys the array element of the associative array at index `STRING` - -------------------------------------------------------------------------------------------------- +|Syntax|Description| +|------|-----------| +|`unset -v ARRAY` \ `unset -v ARRAY[@]` \ `unset -v ARRAY[*]`|Destroys a complete array| +|`unset -v ARRAY[N]`|Destroys the array element at index `N`| +|`unset -v ARRAY[STRING]`|Destroys the array element of the associative array at index `STRING`| It is best to [explicitly specify -v](../commands/builtin/unset.md#portability_considerations) when unsetting variables with unset. - Specifying unquoted array elements as arguments to any -command, such as with the syntax above **may cause [pathname -expansion](../syntax/expansion/globs.md) to occur** due to the presence of -glob characters. +!!! warning "warning" + Specifying unquoted array elements as arguments to any + command, such as with the syntax above **may cause [pathname + expansion](../syntax/expansion/globs.md) to occur** due to the presence of + glob characters. -Example: You are in a directory with a file named `x1`, and you want to -destroy an array element `x[1]`, with + Example: You are in a directory with a file named `x1`, and you want to + destroy an array element `x[1]`, with - unset x[1] + unset 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, **always quote** the array name and index: + To avoid this, **always quote** the array name and index: - unset -v 'x[1]' + unset -v 'x[1]' -This applies generally to all commands which take variable names as -arguments. Single quotes preferred. + This applies generally to all commands which take variable names as + arguments. Single quotes preferred. ## Usage @@ -247,7 +236,7 @@ The method above, walking through an array by just knowing its number of elements, only works for arrays where all elements are set, of course. If one element in the middle is removed, then the calculation is nonsense, because the number of elements doesn't correspond to the -highest used index anymore (we call them \"*sparse arrays*\"). +highest used index anymore (we call them "*sparse arrays*"). Now, suppose that you want to replace your array `sentence` with the values in the [previously-declared array](#purpose) `NAMES` . You might @@ -297,7 +286,7 @@ starting at zero) just is replaced with an arbitrary string: sentence[End]='in what you send' sentence['Very end']=... -[**Beware:**]{.underline} don't rely on the fact that the elements are +**Beware:** don't rely on the fact that the elements are ordered in memory like they were declared, it could look like this: # output from 'set' command @@ -320,9 +309,9 @@ associative array indexed with the SHA sum of the files: # Thanks to Tramp in #bash for the idea and the code unset flist; declare -A flist; - while read -r sum fname; do + while read -r sum fname; do if [[ ${flist[$sum]} ]]; then - printf 'rm -- "%s" # Same as >%s<\n' "$fname" "${flist[$sum]}" + printf 'rm -- "%s" # Same as >%s<\n' "$fname" "${flist[$sum]}" else flist[$sum]="$fname" fi @@ -369,13 +358,13 @@ strings would have been inserted into the integer array without evaluating the arithmetic. A special-case of this is shown in the next section. - Bash declaration commands are really keywords in disguise. They -magically parse arguments to determine whether they are in the form of a -valid assignment. If so, they are evaluated as assignments. If not, they -are undergo normal argument expansion before being passed to the builtin -which evaluates the resulting string as an assignment (somewhat like -`eval`, but there are differences.) `'Todo:`\' Discuss this in detail. - +!!! info "info" + Bash declaration commands are really keywords in disguise. They + magically parse arguments to determine whether they are in the form of a + valid assignment. If so, they are evaluated as assignments. If not, they + are undergo normal argument expansion before being passed to the builtin + which evaluates the resulting string as an assignment (somewhat like + `eval`, but there are differences.) `'Todo:`\' Discuss this in detail. ### Indirection @@ -385,7 +374,7 @@ syntax. Parameters whose values are of the form: `name[index]`, results. This is mainly useful for passing arrays (especially multiple arrays) by name to a function. -This example is an \"isSubset\"-like predicate which returns true if all +This example is an "isSubset"-like predicate which returns true if all key-value pairs of the array given as the first argument to isSubset correspond to a key-value of the array given as the second argument. It demonstrates both indirect array expansion and indirect key-passing @@ -550,7 +539,7 @@ dynamically calls a function whose name is resolved from the array. the subscript or the value first can change in almost every shell for both expansions and arithmetic variables. See [evaluation order](#evaluation_order) for details. -- Bash 4.1.\* and below cannot use negative subscripts to address +- Bash 4.1.* and below cannot use negative subscripts to address array indexes relative to the highest-numbered index. You must use the subscript expansion, i.e. `"${arr[@]:(-n):1}"`, to expand the nth-last element (or the next-highest indexed after `n` if `arr[n]` @@ -570,7 +559,7 @@ dynamically calls a function whose name is resolved from the array. ### Bugs -- **Fixed in 4.3** Bash 4.2.\* and earlier considers each chunk of a +- **Fixed in 4.3** Bash 4.2.* and earlier considers each chunk of a compound assignment, including the subscript for globbing. The subscript part is considered quoted, but any unquoted glob characters on the right-hand side of the `[...]=` will be clumped @@ -586,7 +575,7 @@ dynamically calls a function whose name is resolved from the array. 1=a ` - **Fixed in 4.3** In addition to the above globbing issue, - assignments preceding \"declare\" have an additional effect on brace + assignments preceding "declare" have an additional effect on brace and pathname expansion. `$ set -x; foo=bar declare arr=( {1..10} ) + foo=bar + declare 'arr=(1)' 'arr=(2)' 'arr=(3)' 'arr=(4)' 'arr=(5)' 'arr=(6)' 'arr=(7)' 'arr=(8)' 'arr=(9)' 'arr=(10)' @@ -687,6 +676,3 @@ to generate these results. detailed discussion on arrays with many examples. - [BashSheet - Arrays](http://mywiki.wooledge.org/BashSheet#Arrays) - Bashsheet quick-reference on Greycat's wiki. - -
vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=dokuwiki et -wrap lbr:
diff --git a/docs/syntax/basicgrammar.md b/docs/syntax/basicgrammar.md index 3cc550a..cbce76c 100644 --- a/docs/syntax/basicgrammar.md +++ b/docs/syntax/basicgrammar.md @@ -12,7 +12,7 @@ tags: Bash builds its features on top of a few basic **grammar rules**. The code you see everywhere, the code you use, is based on those rules. -However, **this is a very theoretical view**, but if you\'re interested, +However, **this is a very theoretical view**, but if you're interested, it may help you understand why things look the way they look. If you don't know the commands used in the following examples, just @@ -36,7 +36,7 @@ Every complex Bash operation can be split into simple commands: ls -l LC_ALL=C ls -The last one might not be familiar. That one simply adds \"`LC_ALL=C`\" +The last one might not be familiar. That one simply adds "`LC_ALL=C`" to the environment of the `ls` program. It doesn't affect your current shell. This also works while calling functions, unless Bash runs in POSIX(r) mode (in which case it affects your current shell). @@ -46,19 +46,21 @@ can catch it and act on it. Exit code range is from 0 to 255, where 0 means success, and the rest mean either something failed, or there is an issue to report back to the calling program. - The simple command construct is the -**base** for all higher constructs. Everything you execute, from -pipelines to functions, finally ends up in (many) simple commands. -That's why Bash only has one method to [expand and execute a simple -command](../syntax/grammar/parser_exec.md). +!!! info "info" + The simple command construct is the + **base** for all higher constructs. Everything you execute, from + pipelines to functions, finally ends up in (many) simple commands. + That's why Bash only has one method to [expand and execute a simple + command](../syntax/grammar/parser_exec.md). ## Pipelines -FIXME Missing an additional article about pipelines and pipelining +!!! warning "FIXME" + Missing an additional article about pipelines and pipelining `[time [-p]] [ ! ] command [ | command2 ... ]` -**Don't get confused** about the name \"pipeline.\" It's a grammatic +**Don't get confused** about the name "pipeline." It's a grammatic name for a construct. Such a pipeline isn't necessarily a pair of commands where stdout/stdin is connected via a real pipe. @@ -73,10 +75,10 @@ count the lines generated by the ls command. The result is the number of directory entries in /etc. The last command in the pipeline will set the exit code for the -pipeline. This exit code can be \"inverted\" by prefixing an exclamation -mark to the pipeline: An unsuccessful pipeline will exit \"successful\" +pipeline. This exit code can be "inverted" by prefixing an exclamation +mark to the pipeline: An unsuccessful pipeline will exit "successful" and vice versa. In this example, the commands in the if stanza will be -executed if the pattern \"\^root:\" is **not** found in `/etc/passwd`: +executed if the pattern "^root:" is **not** found in `/etc/passwd`: if ! grep '^root:' /etc/passwd; then echo "No root user defined... eh?" @@ -85,10 +87,10 @@ executed if the pattern \"\^root:\" is **not** found in `/etc/passwd`: Yes, this is also a pipeline (although there is no pipe!), because the **exclamation mark to invert the exit code** can only be used in a pipeline. If `grep`'s exit code is 1 (FALSE) (the text was not found), -the leading `!` will \"invert\" the exit code, and the shell sees (and +the leading `!` will "invert" the exit code, and the shell sees (and acts on) exit code 0 (TRUE) and the `then` part of the `if` stanza is executed. One could say we checked for -\"`not grep "^root" /etc/passwd`\". +"`not grep "^root" /etc/passwd`". The [set option pipefail](../commands/builtin/set.md#attributes) determines the behavior of how bash reports the exit code of a pipeline. If it's @@ -117,7 +119,8 @@ syntax: ## Lists -FIXME Missing an additional article about list operators +!!! warning "FIXME" + Missing an additional article about list operators A list is a sequence of one or more [pipelines](#pipelines) separated by one of the operators `;`, `&`, `&&`, or `││`, and @@ -128,15 +131,15 @@ that all have **different meanings** for Bash. Your whole Bash script technically is one big single list! - Operator Description - ------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ` ` Newlines completely separate pipelines. The next pipeline is executed without any checks. (You enter a command and press ``!) - ` ; ` The semicolon does what `` does: It separates the pipelines - ` & ` The pipeline in front of the `&` is executed **asynchronously** (\"in the background\"). If a pipeline follows this, it is executed immediately after the async pipeline starts - ` && ` `` is executed and **only** if its exit code was 0 (TRUE), then `` is executed (AND-List) - ` || ` `` is executed and **only** if its exit code was **not** 0 (FALSE), then `` is executed (OR-List) +|Operator|Description| +|--------|-----------| +|` `|Newlines completely separate pipelines. The next pipeline is executed without any checks. (You enter a command and press ``!)| +|` ; `|The semicolon does what `` does: It separates the pipelines| +|` & `|The pipeline in front of the `&` is executed **asynchronously** ("in the background"). If a pipeline follows this, it is executed immediately after the async pipeline starts| +|` && `|`` is executed and **only** if its exit code was 0 (TRUE), then `` is executed (AND-List)| +|`||`|`` is executed and **only** if its exit code was **not** 0 (FALSE), then `` is executed (OR-List)| -**Note:** POSIX calls this construct a \"compound lists\". +**Note:** POSIX calls this construct a "compound lists". ## Compound Commands @@ -144,7 +147,7 @@ See also the [list of compound commands](../syntax/ccmd/intro.md). There are two forms of compound commands: -- form a new syntax element using a list as a \"body\" +- form a new syntax element using a list as a "body" - completly independant syntax elements Essentially, everything else that's not described in this article. @@ -157,29 +160,30 @@ Compound commands have the following characteristics: See the following table for a short overview (no details - just an overview): - Compound command syntax Description - ------------------------------------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------- - `( )` Execute `` in an extra subshell => [article](../syntax/ccmd/grouping_subshell.md) - `{ ; }` Execute `` as separate group (but not in a subshell) => [article](../syntax/ccmd/grouping_plain.md) - `(( ))` Evaluate the arithmetic expression `` => [article](../syntax/ccmd/arithmetic_eval.md) - `[[ ]]` Evaluate the conditional expression `` (aka \"the new test command\") => [article](../syntax/ccmd/conditional_expression.md) - `for in ; do ; done` Executes `` while setting the variable `` to one of `` on every iteration (classic for-loop) => [article](../syntax/ccmd/classic_for.md) - `for (( ; ; )) ; do ; done` C-style for-loop (driven by arithmetic expressions) => [article](../syntax/ccmd/c_for.md) - `select in ; do ; done` Provides simple menus => [article](../syntax/ccmd/user_select.md) - `case in ) ;; ... esac` Decisions based on pattern matching - executing `` on match => [article](../syntax/ccmd/case.md) - `if ; then ; else ; fi` The if clause: makes decisions based on exit codes => [article](../syntax/ccmd/if_clause.md) - `while ; do ; done` Execute `` while `` returns TRUE (exit code) => [article](../syntax/ccmd/while_loop.md) - `until ; do ; done` Execute `` until `` returns TRUE (exit code) => [article](../syntax/ccmd/until_loop.md) +|Compound command syntax|Description| +|-----------------------|-----------| +|`( )`|Execute `` in an extra subshell =\> [article](../syntax/ccmd/grouping_subshell.md)| +|`{ ; }`|Execute `` as separate group (but not in a subshell) =\> [article](../syntax/ccmd/grouping_plain.md)| +|`(( ))`|Evaluate the arithmetic expression `` =\> [article](../syntax/ccmd/arithmetic_eval.md)| +|`[[ ]]`|Evaluate the conditional expression `` (aka "the new test command") =\> [article](../syntax/ccmd/conditional_expression.md)| +|`for in ; do ; done`|Executes `` while setting the variable `` to one of `` on every iteration (classic for-loop) =\> [article](../syntax/ccmd/classic_for.md)| +|`for (( ; ; )) ; do ; done`|C-style for-loop (driven by arithmetic expressions) =\> [article](../syntax/ccmd/c_for.md)| +|`select in ; do ; done`|Provides simple menus =\> [article](../syntax/ccmd/user_select.md)| +|`case in ) ;; ... esac`|Decisions based on pattern matching - executing `` on match =\> [article](../syntax/ccmd/case.md)| +|`if ; then ; else ; fi`|The if clause: makes decisions based on exit codes =\> [article](../syntax/ccmd/if_clause.md)| +|`while ; do ; done`|Execute `` while `` returns TRUE (exit code) =\> [article](../syntax/ccmd/while_loop.md)| +|`until ; do ; done`|Execute `` until `` returns TRUE (exit code) =\> [article](../syntax/ccmd/until_loop.md)| ## Shell Function Definitions -FIXME Missing an additional article about shell functions +!!! warning "FIXME" + Missing an additional article about shell functions A shell function definition makes a [compound command](#compound_commands) available via a new name. When -the function runs, it has its own \"private\" set of positional +the function runs, it has its own "private" set of positional parameters and I/O descriptors. It acts like a script-within-the-script. -Simply stated: **You\'ve created a new command.** +Simply stated: **You've created a new command.** The definition is easy (one of many possibilities): @@ -219,7 +223,7 @@ without the space. I suggest using the first form. It's specified in POSIX and all Bourne-like shells seem to support it. -[**Note:**]{.underline} Before version `2.05-alpha1`, Bash only +**Note:** Before version `2.05-alpha1`, Bash only recognized the definition using curly braces (`name() { ... }`), other shells allow the definition using **any** command (not just the compound command set). @@ -237,16 +241,16 @@ like this: } # this $1 belongs the script itself! - mycmd "$1" # Execute command immediately after defining function + mycmd "$1" # Execute command immediately after defining function exit 0 **Just informational(1):** Internally, for forking, Bash stores function definitions in environment -variables. Variables with the content \"*() \....*\". +variables. Variables with the content "*() ....*". -Something similar to the following works without \"officially\" +Something similar to the following works without "officially" declaring a function: $ export testfn="() { echo test; }" @@ -267,8 +271,8 @@ The elements of this name aren't subject to a path search. Weird function names should not be used. Quote from the maintainer: - * It was a mistake to allow such characters in function names - (\`unset\' doesn't work to unset them without forcing -f, for - instance). We\'re stuck with them for backwards compatibility, but I + (`unset` doesn't work to unset them without forcing `-f`, for + instance). We're stuck with them for backwards compatibility, but I don't have to encourage their use. * ## Grammar summary @@ -288,15 +292,16 @@ Weird function names should not be used. Quote from the maintainer: ## Examples for classification -FIXME more\... +!!! warning "FIXME" + more... ------------------------------------------------------------------------ -[A (very) simple command]{.underline} +A (very) simple command echo "Hello world..." -[All of the following are simple commands]{.underline} +All of the following are simple commands x=5 @@ -306,7 +311,7 @@ FIXME more\... ------------------------------------------------------------------------ -[A common compound command]{.underline} +A common compound command if [ -d /data/mp3 ]; then cp mymusic.mp3 /data/mp3 diff --git a/docs/syntax/ccmd/c_for.md b/docs/syntax/ccmd/c_for.md index 5f2e600..4ad1f37 100644 --- a/docs/syntax/ccmd/c_for.md +++ b/docs/syntax/ccmd/c_for.md @@ -20,10 +20,10 @@ The C-style for-loop is a [compound command](../../syntax/basicgrammar.md#compound_commands) derived from the -equivalent ksh88 feature, which is in turn derived from the C \"for\" +equivalent ksh88 feature, which is in turn derived from the C "for" keyword. Its purpose is to provide a convenient way to evaluate arithmetic expressions in a loop, plus initialize any required -arithmetic variables. It is one of the main \"loop with a counter\" +arithmetic variables. It is one of the main "loop with a counter" mechanisms available in the language. The `((;;))` syntax at the top of the loop is not an ordinary @@ -103,7 +103,7 @@ functions and local variables for initialization. ### Simple counter -A simple counter, the loop iterates 101 times (\"0\" to \"100\" are 101 +A simple counter, the loop iterates 101 times ("0" to "100" are 101 numbers -> 101 runs!), and everytime the variable `x` is set to the current value. @@ -111,9 +111,6 @@ current value. - Before every iteration it **checks** if `x ≤ 100` - After every iteration it **changes** `x++` -```{=html} - -``` for ((x = 0 ; x <= 100 ; x++)); do echo "Counter: $x" done @@ -131,8 +128,8 @@ will count from 0 to 100, but with a **step of 10**. ### Bits analyzer This example loops through the bit-values of a Byte, beginning from 128, -ending at 1. If that bit is set in the `testbyte`, it prints \"`1`\", -else \"`0`\" => it prints the binary representation of the `testbyte` +ending at 1. If that bit is set in the `testbyte`, it prints "`1`", +else "`0`" => it prints the binary representation of the `testbyte` value (8 bits). #!/usr/bin/env bash @@ -161,7 +158,7 @@ value (8 bits). # vim: set fenc=utf-8 ff=unix ft=sh : -
+
testbyte=123 for (( n = 128 ; n >= 1 ; n /= 2 )); do @@ -173,11 +170,11 @@ value (8 bits). done echo -
+
Why that one begins at 128 (highest value, on the left) and not 1 (lowest value, on the right)? It's easier to print from left to -right\... +right... We arrive at 128 for `n` through the recursive arithmetic expression stored in `x`, which calculates the next-greatest power of 2 after `m`. @@ -186,7 +183,7 @@ it has a built-in feature for `printf` to print a representation of any number in an arbitrary base (up to 64). Very few languages have that ability built-in, even things like Python. -### Up, down, up, down\... +### Up, down, up, down... This counts up and down from `0` to `${1:-5}`, `${2:-4}` times, demonstrating more complicated arithmetic expressions with multiple @@ -196,7 +193,8 @@ variables. printf '%*s\n' "$((n+1))" "$n" done - \~ \$ bash <(xclip -o) 1 +``` bash +~ \$ bash <(xclip -o) 1 2 3 @@ -216,7 +214,8 @@ variables. 3 2 -1 +1 +``` ## Portability considerations diff --git a/docs/syntax/ccmd/case.md b/docs/syntax/ccmd/case.md index e273a80..8e18517 100644 --- a/docs/syntax/ccmd/case.md +++ b/docs/syntax/ccmd/case.md @@ -43,7 +43,7 @@ done**, which means you can leave expansions unquoted without problems: esac This is similar to the behavior of the [conditional expression command -(\"new test command\")](../../syntax/ccmd/conditional_expression.md) (also no +("new test command")](../../syntax/ccmd/conditional_expression.md) (also no word splitting for expansions). Unlike the C-case-statement, only the matching list and nothing else is @@ -55,13 +55,13 @@ This is a POSIX-compatable equivalent to the `@(pattern-list)` extglob construct. The `case` statement is one of the most difficult commands to indent -clearly, and people frequently ask about the most \"correct\" style. +clearly, and people frequently ask about the most "correct" style. Just do your best - there are many variations of indenting style for `case` and no real agreed-upon best practice. ## Examples -Another one of my stupid examples\... +Another one of my stupid examples... printf '%s ' 'Which fruit do you like most?' read -${BASH_VERSION+e}r fruit diff --git a/docs/syntax/ccmd/classic_for.md b/docs/syntax/ccmd/classic_for.md index e40020b..dc8dc06 100644 --- a/docs/syntax/ccmd/classic_for.md +++ b/docs/syntax/ccmd/classic_for.md @@ -23,7 +23,7 @@ alternative, historical and undocumented syntax [^1] ## Description For every word in ``, one iteration of the loop is performed and -the variable `` is set to the current word. If no \"`in `\" +the variable `` is set to the current word. If no "`in `" is present to give an own word-list, then the positional parameters (`"$@"`) are used (the arguments to the script or function). In this case (and only in this case), the semicolon between the variable name @@ -60,14 +60,14 @@ specified by POSIX(r). The return status is the one of the last command executed in `` or `0` (`TRUE`), if the item list `` evaluates to nothing (i.e.: -\"is empty\"!). +"is empty"!). ## Examples ### Iterate over array elements With some array syntax (see [arrays](../../syntax/arrays.md)) you can easily -\"feed\" the for-loop to iterate over all elements in an array (by +"feed" the for-loop to iterate over all elements in an array (by mass-expanding all elements): ``` bash @@ -156,7 +156,7 @@ done ### Loop over a number range -Beginning in Bash 4, you can also use \"sequence expression\" form of +Beginning in Bash 4, you can also use "sequence expression" form of [brace expansion](../../syntax/expansion/brace.md) syntax when looping over numbers, and this form does not create leading zeroes unless you ask for them: diff --git a/docs/syntax/ccmd/conditional_expression.md b/docs/syntax/ccmd/conditional_expression.md index 6b517ec..154a77a 100644 --- a/docs/syntax/ccmd/conditional_expression.md +++ b/docs/syntax/ccmd/conditional_expression.md @@ -16,28 +16,17 @@ The testing features basically are the same (see the lists for [classic test command](../../commands/classictest.md)), with some additions and extensions. - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Operator Description - -------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------- - `( )` Used to group expressions, to influence precedence of operators - - ` && ` `TRUE` if ``**and**`` are `TRUE` (do **not** use `-a`!) - - ` || ` `TRUE` if ``**or**`` is `TRUE` (do **not** use `-o`!) - - ` == ` `` is checked against the pattern `` - `TRUE` on a match\ - *But note¹, quoting the pattern forces a literal comparison.* - - ` = ` equivalent to the `==` operator - - ` != ` `` is checked against the pattern `` - `TRUE` on **no match** - - ` =~ ` `` is checked against the [extended regular expression](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended) `` - `TRUE` on a match - - See the [classic test operators](../../commands/classictest.md#file_tests) Do **not** use the `test`-typical operators `-a` and `-o` for AND and OR. - - See also [arithmetic comparisons](../../syntax/arith_expr.md#comparisons) Using `(( ))`, the [arithmetic expression compound command](../../syntax/ccmd/arithmetic_eval.md) - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +|Operator|Description| +|--|--| +|`( )`|Used to group expressions, to influence precedence of operators| +|` && `|`TRUE` if ``**and**`` are `TRUE` (do **not** use `-a`!)| +|`||`|`TRUE` if ``**or**`` is `TRUE` (do **not** use `-o`!)| +|` == `|`` is checked against the pattern `` - `TRUE` on a match
*But note¹, quoting the pattern forces a literal comparison.*| +|` = `|equivalent to the `==` operator| +|` != `|`` is checked against the pattern `` - `TRUE` on **no match**| +|` =~ `|`` is checked against the [extended regular expression](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended) `` - `TRUE` on a match| +|See the [classic test operators](../../commands/classictest.md#file_tests)|Do **not** use the `test`-typical operators `-a` and `-o` for AND and OR.| +|See also [arithmetic comparisons](../../syntax/arith_expr.md#comparisons)|Using `(( ))`, the [arithmetic expression compound command](../../syntax/ccmd/arithmetic_eval.md)| When the `==` and `!=` operators are used, the string to the right of the operator is considered a pattern and matched according to the rules @@ -50,7 +39,7 @@ literal string. When the operators `<` and `>` are used (string collation order), the test happens using the current locale when the `compat` level is greater -than \"40\". +than "40". Operator precedence (highest => lowest): @@ -151,7 +140,7 @@ Example: ### Behaviour differences compared to the builtin test command -As of Bash 4.1 alpha, the test primaries \'<\' and \'>\' (compare +As of Bash 4.1 alpha, the test primaries '<' and '>' (compare strings lexicographically) use the current locale settings, while the same primitives for the builtin test command don't. This leads to the following situation where they behave differently: @@ -180,7 +169,7 @@ both contains whitespace and is not the result of an expansion. - `[[ ... ]]` functionality isn't specified by POSIX(R), though it's a reserved word -- Amongst the major \"POSIX-shell superset languages\" (for lack of a +- Amongst the major "POSIX-shell superset languages" (for lack of a better term) which do have `[[`, the test expression compound command is one of the very most portable non-POSIX features. Aside from the `=~` operator, almost every major feature is consistent diff --git a/docs/syntax/ccmd/grouping_plain.md b/docs/syntax/ccmd/grouping_plain.md index 7dec041..8d4fc0c 100644 --- a/docs/syntax/ccmd/grouping_plain.md +++ b/docs/syntax/ccmd/grouping_plain.md @@ -13,7 +13,7 @@ The [list](../../syntax/basicgrammar.md#lists) `` is simply executed in the **current** shell environment. The list must be terminated with a **newline** or **semicolon**. For parsing reasons, the curly braces must -be separated from `` by a **semicolon** and **blanks** if they\'re +be separated from `` by a **semicolon** and **blanks** if they're in the same line! [^1][^2] This is known as a **group command**. The return status is the [exit diff --git a/docs/syntax/ccmd/grouping_subshell.md b/docs/syntax/ccmd/grouping_subshell.md index 169ecd2..13ee17f 100644 --- a/docs/syntax/ccmd/grouping_subshell.md +++ b/docs/syntax/ccmd/grouping_subshell.md @@ -8,7 +8,7 @@ The [list](../../syntax/basicgrammar.md#lists) `` is executed in a separate shell - a subprocess. No changes to the environment (variables -etc\...) are reflected in the \"main shell\". +etc...) are reflected in the "main shell". ## Examples diff --git a/docs/syntax/ccmd/intro.md b/docs/syntax/ccmd/intro.md index 6573c32..e5b3fa9 100644 --- a/docs/syntax/ccmd/intro.md +++ b/docs/syntax/ccmd/intro.md @@ -1,10 +1,10 @@ # Bash compound commands The main part of Bash's syntax are the so-called **compound commands**. -They\'re called like that because they use \"real\" commands ([simple +They're called like that because they use "real" commands ([simple commands](../../syntax/basicgrammar.md#simple_commands) or [lists](../../syntax/basicgrammar.md#lists)) and knit some intelligence around -them. That is what the essential \"Bash language\" is made of. +them. That is what the essential "Bash language" is made of. ## Command grouping @@ -17,7 +17,7 @@ Note that conditionals can also be scripted using [list](../../syntax/basicgrammar.md#lists), which are syntax elements, not commands. -- the \"new\" test command: [conditional +- the "new" test command: [conditional expression](conditional_expression.md) - if-clause: [conditional branching](if_clause.md) - case statement: [pattern-based branching](case.md) diff --git a/docs/syntax/expansion/brace.md b/docs/syntax/expansion/brace.md index a4ab5cf..b0c3269 100644 --- a/docs/syntax/expansion/brace.md +++ b/docs/syntax/expansion/brace.md @@ -53,8 +53,8 @@ expansion is to be assigned to an array, another method is possible using [declaration commands](../../commands/builtin/declare.md): `declare -a 'pics=(img{'"$a..$b"'}.png)'; mv "${pics[@]}" ../imgs` This is significantly safer, but one must still be careful to control the -values of \$a and \$b. Both the exact quoting, and explicitly including -\"-a\" are important. +values of `$a` and `$b`. Both the exact quoting, and explicitly including +"`-a`" are important. The brace expansion is present in two basic forms, **string lists** and **ranges**. @@ -87,24 +87,21 @@ With prefix or suffix strings, the result is a space-separated list of _I- _want- _my- _money- _back- The brace expansion is only performed, if the given string list is -really a **list of strings**, i.e., if there is a minimum of one \"`,`\" +really a **list of strings**, i.e., if there is a minimum of one "`,`" (comma)! Something like `{money}` doesn't expand to something special, -it's really only the text \"`{money}`\". +it's really only the text "`{money}`". ## Ranges {..} Brace expansion using ranges is written giving the startpoint and the -endpoint of the range. This is a \"sequence expression\". The sequences +endpoint of the range. This is a "sequence expression". The sequences can be of two types - integers (optionally zero padded, optionally with a given increment) - characters -```{=html} - -``` $ echo {5..12} 5 6 7 8 9 10 11 12 @@ -186,13 +183,10 @@ for. mkdir /home/bash/test/{foo,bar,baz,cat,dog} -### Generate numbers with a prefix 001 002 \... +### Generate numbers with a prefix 001 002 ... - Using a prefix: -```{=html} - -``` for i in 0{1..9} 10; do printf "%s\n" "$i";done If you need to create words with the number embedded, you can use nested @@ -202,9 +196,6 @@ brace: - Formatting the numbers with printf: -```{=html} - -``` echo $(printf "img%02d.png " {1..99}) See the [text below](#news_in_bash_4.0) for a new Bash 4 method. @@ -217,34 +208,33 @@ Can be written as somecommand -v{,,,,} -\...which is a kind of a hack, but hey, it works. +...which is a kind of a hack, but hey, it works. -
-#### More fun -The most optimal possible brace expansion to expand n arguments of -course consists of n's prime factors. We can use the \"factor\" program -bundled with GNU coreutils to emit a brace expansion that will expand -any number of arguments. +!!! info "More fun" - function braceify { - [[ $1 == +([[:digit:]]) ]] || return - typeset -a a - read -ra a < <(factor "$1") - eval "echo $(printf '{$(printf ,%%.s {1..%s})}' "${a[@]:1}")" - } + The most optimal possible brace expansion to expand n arguments of + course consists of n's prime factors. We can use the "factor" program + bundled with GNU coreutils to emit a brace expansion that will expand + any number of arguments. - printf 'eval printf "$arg"%s' "$(braceify 1000000)" + function braceify { + [[ $1 == +([[:digit:]]) ]] || return + typeset -a a + read -ra a < <(factor "$1") + eval "echo $(printf '{$(printf ,%%.s {1..%s})}' "${a[@]:1}")" + } -\"Braceify\" generates the expansion code itself. In this example we -inject that output into a template which displays the most terse brace -expansion code that would expand `"$arg"` 1,000,000 times if evaluated. -In this case, the output is: + printf 'eval printf "$arg"%s' "$(braceify 1000000)" - eval printf "$arg"{,,}{,,}{,,}{,,}{,,}{,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,} + "Braceify" generates the expansion code itself. In this example we + inject that output into a template which displays the most terse brace + expansion code that would expand `"$arg"` 1,000,000 times if evaluated. + In this case, the output is: + + eval printf "$arg"{,,}{,,}{,,}{,,}{,,}{,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,} -
## New in Bash 4.0 diff --git a/docs/syntax/expansion/cmdsubst.md b/docs/syntax/expansion/cmdsubst.md index c5334dd..40935c0 100644 --- a/docs/syntax/expansion/cmdsubst.md +++ b/docs/syntax/expansion/cmdsubst.md @@ -33,12 +33,12 @@ In later steps, **if not quoted**, the results undergo [word splitting](../../syntax/expansion/wordsplit.md) and [pathname expansion](../../syntax/expansion/globs.md). You have to remember that, because the word splitting will also remove embedded newlines and other `IFS` -characters and break the results up into several words. Also you\'ll +characters and break the results up into several words. Also you'll probably get unexpected pathname matches. **If you need the literal results, quote the command substitution!** The second form `` `COMMAND` `` is more or less obsolete for Bash, since -it has some trouble with nesting (\"inner\" backticks need to be +it has some trouble with nesting ("inner" backticks need to be escaped) and escaping characters. Use `$(COMMAND)`, it's also POSIX! When you [call an explicit subshell](../../syntax/ccmd/grouping_subshell.md) @@ -72,17 +72,17 @@ escaping-neutral, it's nestable, it's also POSIX. But take a look at the following code snips to decide yourself which form you need under specific circumstances: -**[Nesting]{.underline}** +**Nesting** Backtick form `` `...` `` is not directly nestable. You will have to -escape the \"inner\" backticks. Also, the deeper you go, the more escape +escape the "inner" backticks. Also, the deeper you go, the more escape characters you need. Ugly. echo `echo `ls`` # INCORRECT echo `echo \`ls\`` # CORRECT echo $(echo $(ls)) # CORRECT -**[Parsing]{.underline}** +**Parsing** All is based on the fact that the backquote-form is simple character substitution, while every `$()`-construct opens an own, subsequent @@ -91,21 +91,21 @@ normal on a commandline. No special escaping of **nothing** is needed: echo "$(echo "$(ls)")" # nested double-quotes - no problem -**[Constructs you should avoid]{.underline}** +**Constructs you should avoid** It's not all shiny with `$()`, at least for my current Bash -(`3.1.17(1)-release`. :!: [**Update:** Fixed since `3.2-beta` together -with a misinterpretion of \'))\' being recognized as arithmetic -expansion \[by redduck666\]]{.underline}). This command seems to -incorrectly close the substitution step and echo prints \"ls\" and -\")\": +(`3.1.17(1)-release`. :!: **Update:** Fixed since `3.2-beta` together +with a misinterpretion of '))' being recognized as arithmetic +expansion by redduck666). This command seems to +incorrectly close the substitution step and echo prints "ls" and +")": echo $( # some comment ending with a ) ls ) -It seems that every closing \")\" confuses this construct. Also a (very +It seems that every closing ")" confuses this construct. Also a (very uncommon ;-)) construct like: echo $(read VAR; case "$var" in foo) blah ;; esac) # spits out some error, when it sees the ";;" @@ -113,7 +113,7 @@ uncommon ;-)) construct like: # fixes it: echo $(read VAR; case "$var" in (foo) blah ;; esac) # will work, but just let it be, please ;-) -**[Conclusion:]{.underline}** +**Conclusion:** In general, the `$()` should be the preferred method: @@ -141,11 +141,11 @@ target, because command substitution only catches `STDOUT`! var=$(echo -n $'\n'); echo -n "$var"; # $var == "" var=$(echo -n $'\n'; echo -n x); var="${var%x}"; echo -n "$var" # $var == "\n" -This adds \"x\" to the output, which prevents the trailing newlines of -the previous commands\' output from being deleted by \$(). +This adds "x" to the output, which prevents the trailing newlines of +the previous commands' output from being deleted by `$()`. -By removing this \"x\" later on, we are left with the previous -commands\' output with its trailing newlines. +By removing this "x" later on, we are left with the previous +commands' output with its trailing newlines. ## See also diff --git a/docs/syntax/expansion/globs.md b/docs/syntax/expansion/globs.md index b84bdde..7815df9 100644 --- a/docs/syntax/expansion/globs.md +++ b/docs/syntax/expansion/globs.md @@ -3,8 +3,8 @@ ## General Unlike on other platforms you may have seen, on UNIX(r), the shell is -responsible for interpreting and expanding globs (\"filename -wildcards\"). A called program will never see the glob itself; it will +responsible for interpreting and expanding globs ("filename +wildcards"). A called program will never see the glob itself; it will only see the expanded filenames as its arguments (here, all filenames matching `*.log`): @@ -43,7 +43,7 @@ other `IFS`-characters they contain. corrections when matching directory names - when the shell option `globstar` is set, the glob `**` will recursively match all files and directories. This glob isn't - \"configurable\", i.e. you **can't** do something like `**.c` to + "configurable", i.e. you **can't** do something like `**.c` to recursively get all `*.c` filenames. - when the shell option `globasciiranges` is set, the bracket-range globs (e.g. `[A-Z]`) use C locale order rather than the configured @@ -56,7 +56,7 @@ other `IFS`-characters they contain. ### nullglob Normally, when no glob specified matches an existing filename, no -pathname expansion is performed, and the globs are [**not**]{.underline} +pathname expansion is performed, and the globs are **not** removed: $ echo "Textfiles here:" *.txt @@ -75,7 +75,7 @@ This can be very annoying, for example when you drive a done When no file name matches the glob, the loop will not only output stupid -text (\"`BEGIN: *.txt`\"), but also will make the `cat`-command fail +text ("`BEGIN: *.txt`"), but also will make the `cat`-command fail with an error, since no file named `*.txt` exists. Now, when the shell option `nullglob` is set, Bash will remove the @@ -92,11 +92,11 @@ and the glob is gone. ### Glob characters -- \* - means \'match any number of characters\'. \'/\' is not matched +- `*` - means \'match any number of characters\'. \'/\' is not matched (and depending on your settings, things like \'.\' may or may not be matched, see above) -- ? - means \'match any single character\' -- \[abc\] - match any of the characters listed. This syntax also +- `?` - means \'match any single character\' +- `[abc]` - match any of the characters listed. This syntax also supports ranges, like \[0-9\] For example, to match something beginning with either \'S\' or \'K\' diff --git a/docs/syntax/expansion/intro.md b/docs/syntax/expansion/intro.md index 2e5b2c5..367ad75 100644 --- a/docs/syntax/expansion/intro.md +++ b/docs/syntax/expansion/intro.md @@ -28,7 +28,7 @@ The most simple example of this behaviour is a referenced variable: The `echo` program definitely doesn't care about what a shell variable is. It is Bash's job to deal with the variable. Bash **expands** the -string \"`$mystring`\" to \"`Hello world`\", so that `echo` will only +string "`$mystring`" to "`Hello world`", so that `echo` will only see `Hello world`, not the variable or anything else! After all these expansions and substitutions are done, all quotes that diff --git a/docs/syntax/expansion/proc_subst.md b/docs/syntax/expansion/proc_subst.md index 0675522..ee26231 100644 --- a/docs/syntax/expansion/proc_subst.md +++ b/docs/syntax/expansion/proc_subst.md @@ -42,21 +42,22 @@ from a file). ### Scope - Note: According to multiple comments and sources, the -scope of process substitution file descriptors is **not** stable, -guaranteed, or specified by bash. Newer versions of bash (5.0+) seem to -have shorter scope, and substitutions scope seems to be shorter than -function scope. See -[stackexchange](https://unix.stackexchange.com/questions/425456/conditional-process-substitution) -and -[stackoverflow](https://stackoverflow.com/questions/46660020/bash-what-is-the-scope-of-the-process-substitution); -the latter discussion contains a script that can test the scoping -behavior case-by-case +!!! note "Note" + According to multiple comments and sources, the + scope of process substitution file descriptors is **not** stable, + guaranteed, or specified by bash. Newer versions of bash (5.0+) seem to + have shorter scope, and substitutions scope seems to be shorter than + function scope. See + [stackexchange](https://unix.stackexchange.com/questions/425456/conditional-process-substitution) + and + [stackoverflow](https://stackoverflow.com/questions/46660020/bash-what-is-the-scope-of-the-process-substitution); + the latter discussion contains a script that can test the scoping + behavior case-by-case If a process substitution is expanded as an argument to a function, expanded to an environment variable during calling of a function, or expanded to any assignment within a function, the process substitution -will be \"held open\" for use by any command within the function or its +will be "held open" for use by any command within the function or its callees, until the function in which it was set returns. If the same variable is set again within a callee, unless the new variable is local, the previous process substitution is closed and will be unavailable to @@ -97,10 +98,11 @@ where those files are written to and destroyed automatically. ### Avoiding subshells - See Also: -[BashFAQ/024](http://mywiki.wooledge.org/BashFAQ/024) -- *I set -variables in a loop that's in a pipeline. Why do they disappear after -the loop terminates? Or, why can't I pipe data to read?* +!!! info "See Also" + See Also: + [BashFAQ/024](http://mywiki.wooledge.org/BashFAQ/024) -- *I set + variables in a loop that's in a pipeline. Why do they disappear after + the loop terminates? Or, why can't I pipe data to read?* One of the most common uses for process substitutions is to avoid the final subshell that results from executing a pipeline. The following is @@ -120,7 +122,7 @@ Due to the pipe, the `while read; do ... done` part is executed in a subshell (in Bash, by default), which means `counter` is only incremented within the subshell. When the pipeline finishes, the subshell is terminated, and the `counter` visible to `echo` is still at -\"0\"! +"0"! Process substitution helps us avoid the pipe operator (the reason for the subshell): @@ -149,7 +151,7 @@ note that the space is required in order to disambiguate the syntax from ### Process substitution assigned to a parameter This example demonstrates how process substitutions can be made to -resemble \"passable\" objects. This results in converting the output of +resemble "passable" objects. This results in converting the output of `f`'s argument to uppercase. ``` bash diff --git a/docs/syntax/expansion/tilde.md b/docs/syntax/expansion/tilde.md index 0d4e5eb..d586be7 100644 --- a/docs/syntax/expansion/tilde.md +++ b/docs/syntax/expansion/tilde.md @@ -44,24 +44,25 @@ Tilde expansion is also performed everytime a variable is assigned: - after **every** `:` (colon) in the assigned value: `TARGET=file:~moonman/share` - As of now (Bash 4.3-alpha) the following constructs -**also** works, though it's not a variable assignment: +!!! info "Note" + As of now (Bash 4.3-alpha) the following constructs + **also** works, though it's not a variable assignment: - echo foo=~ - echo foo=:~ + echo foo=~ + echo foo=:~ -I don't know yet, if this is a bug or intended. + I don't know yet, if this is a bug or intended. This way you can correctly use the tilde expansion in your [PATH](../../syntax/shellvars.md#PATH): PATH=~/mybins:~peter/mybins:$PATH -**Spaces in the referenced pathes?** A construct like\... +**Spaces in the referenced pathes?** A construct like... ~/"my directory" -\...is perfectly valid and works! +...is perfectly valid and works! ## Home directory @@ -84,7 +85,7 @@ precedence: - expand to the home directory of the user executing the shell (operating system) -That means, the variable `HOME` can override the \"real\" home +That means, the variable `HOME` can override the "real" home directory, at least regarding tilde expansion. ## Current working directory diff --git a/docs/syntax/expansion/wordsplit.md b/docs/syntax/expansion/wordsplit.md index f7e3e01..41e2a28 100644 --- a/docs/syntax/expansion/wordsplit.md +++ b/docs/syntax/expansion/wordsplit.md @@ -1,6 +1,7 @@ # Word splitting -FIXME to be continued! +!!! warning "FIXME" + to be continued! Word splitting occurs once any of the following expansions are done (and only then!) @@ -18,9 +19,9 @@ are **not double-quoted**! The `IFS` variable holds the characters that Bash sees as word boundaries in this step. The default contains the characters -- -- -- +- <space> +- <tab> +- <newline> These characters are also assumed when IFS is **unset**. When `IFS` is **empty** (nullstring), no word splitting is performed at all. @@ -34,10 +35,10 @@ the expansion result is split at these positions into multiple words. This doesn't happen when the expansion results were **double-quoted**. When a null-string (e.g., something that before expanded to ->>nothing<<) is found, it is removed, unless it is quoted (`''` or +>>nothing<<) is found, it is removed, unless it is quoted (`''` or `""`). -[**Again note:**]{.underline} Without any expansion beforehand, Bash +**Again note:** Without any expansion beforehand, Bash won't perform word splitting! In this case, the initial token parsing is solely responsible. diff --git a/docs/syntax/grammar/parser_exec.md b/docs/syntax/grammar/parser_exec.md index 72275fb..0bd0874 100644 --- a/docs/syntax/grammar/parser_exec.md +++ b/docs/syntax/grammar/parser_exec.md @@ -10,22 +10,22 @@ tags: - execution --- -FIXME work in progress\... +!!! warning "FIXME" + work in progress... # Parsing and execution Nearly everything in [Bash grammar](../../syntax/basicgrammar.md) can be broken -down to a \"simple command\". The only thing Bash has to expand, +down to a "simple command". The only thing Bash has to expand, evaluate and execute is the simple command. ## Simple command expansion -
+!!! info "info" -- -- + - + - -
This step happens after the initial command line splitting. @@ -82,7 +82,7 @@ The behavior regarding the variable assignment errors can be tested:
-**[This one exits the script completely]{.underline}** +**This one exits the script completely** #!/bin/sh # This shell runs in POSIX mode! @@ -95,8 +95,8 @@ The behavior regarding the variable assignment errors can be tested: echo POST -**[This one terminates only the enclosing compound command (the -`{ ...; }`):]{.underline}** +**This one terminates only the enclosing compound command (the +`{ ...; }`):** #!/bin/bash # This shell runs in native Bash-mode! @@ -126,7 +126,8 @@ or install software packages etc. Since this function runs in a separate execution environment, you can't really influence the main shell with it (changing directory, setting variables). -FIXME to be continued +!!! warning "FIXME" + to be continued ## See also diff --git a/docs/syntax/keywords/coproc.md b/docs/syntax/keywords/coproc.md index 4b84057..ba838c5 100644 --- a/docs/syntax/keywords/coproc.md +++ b/docs/syntax/keywords/coproc.md @@ -108,7 +108,7 @@ more information on buffering issues. #### background processes -A coprocess\' file descriptors are accessible only to the process from +A coprocess' file descriptors are accessible only to the process from which the `coproc` was started. They are not inherited by subshells. Here is a not-so-meaningful illustration. Suppose we want to @@ -200,7 +200,7 @@ $ #!/bin/bash # we start tee in the background # redirecting its output to the stdout of the script -{ coproc tee { tee logfile ;} >&3 ;} 3>&1 +{ coproc tee { tee logfile ;} >&3 ;} 3>&1 # we redirect stding and stdout of the script to our coprocess exec >&${tee[1]} 2>&1 ``` @@ -222,7 +222,7 @@ exec >&${tee[1]} 2>&1 ### Other shells -ksh93, mksh, zsh, and Bash all support something called \"coprocesses\" +ksh93, mksh, zsh, and Bash all support something called "coprocesses" which all do approximately the same thing. ksh93 and mksh have virtually identical syntax and semantics for coprocs. A *list* operator: `|&` is added to the language which runs the preceding *pipeline* as a coprocess @@ -258,7 +258,7 @@ more. See more details The ability to use multiple coprocesses in Bash is considered -\"experimental\". Bash will throw an error if you attempt to start more +"experimental". Bash will throw an error if you attempt to start more than one. This may be overridden at compile-time with the `MULTIPLE_COPROCS` option. However, at this time there are still issues -- see the above mailing list discussion. diff --git a/docs/syntax/pattern.md b/docs/syntax/pattern.md index 274d8ea..a129364 100644 --- a/docs/syntax/pattern.md +++ b/docs/syntax/pattern.md @@ -26,7 +26,7 @@ A pattern is a **string description**. Bash uses them in various ways: The pattern description language is relatively easy. Any character that's not mentioned below matches itself. The `NUL` character may not -occur in a pattern. If special characters are quoted, they\'re matched +occur in a pattern. If special characters are quoted, they're matched literally, i.e., without their special meaning. Do **not** confuse patterns with ***regular expressions***, because they @@ -34,30 +34,30 @@ share some symbols and do similar matching work. ## Normal pattern language - Sequence Description - ---------- ---------------------------------------------------------------------------------------------------------------- - `*` Matches **any string**, including the null string (empty string) - `?` Matches any **single character** - `X` Matches the character `X` which can be any character that has no special meaning - `\X` Matches the character `X`, where the character's special meaning is stripped by the backslash - `\\` Matches a backslash - `[...]` Defines a pattern **bracket expression** (see below). Matches any of the enclosed characters at this position. +|Sequence|Description| +|--------|-----------| +|`*`|Matches **any string**, including the null string (empty string)| +|`?`|Matches any **single character**| +|`X`|Matches the character `X` which can be any character that has no special meaning| +|`\X`|Matches the character `X`, where the character's special meaning is stripped by the backslash| +|`\\`|Matches a backslash| +|`[...]`|Defines a pattern **bracket expression** (see below). Matches any of the enclosed characters at this position.| ### Bracket expressions The bracket expression `[...]` mentioned above has some useful applications: - Bracket expression Description - ---------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `[XYZ]` The \"normal\" bracket expression, matching either `X`, `Y` or `Z` - `[X-Z]` A range expression: Matching all the characters from `X` to `Y` (your current **locale**, defines how the characters are **sorted**!) - `[[:class:]]` Matches all the characters defined by a [POSIX(r) character class](https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap07.html#tag_07_03_01): `alnum`, `alpha`, `ascii`, `blank`, `cntrl`, `digit`, `graph`, `lower`, `print`, `punct`, `space`, `upper`, `word` and `xdigit` - `[^...]` A negating expression: It matches all the characters that are **not** in the bracket expression - `[!...]` Equivalent to `[^...]` - `[]...]` or `[-...]` Used to include the characters `]` and `-` into the set, they need to be the first characters after the opening bracket - `[=C=]` Matches any character that is eqivalent to the collation weight of `C` (current locale!) - `[[.SYMBOL.]]` Matches the collating symbol `SYMBOL` +|Bracket expression|Description| +|------------------|-----------| +|`[XYZ]`|The "normal" bracket expression, matching either `X`, `Y` or `Z`| +|`[X-Z]`|A range expression: Matching all the characters from `X` to `Y` (your current **locale**, defines how the characters are **sorted**!)| +|`[[:class:]]`|Matches all the characters defined by a [POSIX(r) character class](https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap07.html#tag_07_03_01): `alnum`, `alpha`, `ascii`, `blank`, `cntrl`, `digit`, `graph`, `lower`, `print`, `punct`, `space`, `upper`, `word` and `xdigit`| +|`[^...]`|A negating expression: It matches all the characters that are **not** in the bracket expression| +|`[!...]`|Equivalent to `[^...]`| +|`[]...]` or `[-...]`|Used to include the characters `]` and `-` into the set, they need to be the first characters after the opening bracket| +|`[=C=]`|Matches any character that is eqivalent to the collation weight of `C` (current locale!)| +|`[[.SYMBOL.]]`|Matches the collating symbol `SYMBOL`| ### Examples @@ -66,23 +66,23 @@ Some simple examples using normal pattern matching: - Pattern `"Hello world"` matches - `Hello world` - Pattern `[Hh]"ello world"` matches - - => `Hello world` - - => `hello world` + - => `Hello world` + - => `hello world` - Pattern `Hello*` matches (for example) - - => `Hello world` - - => `Helloworld` - - => `HelloWoRlD` - - => `Hello` + - => `Hello world` + - => `Helloworld` + - => `HelloWoRlD` + - => `Hello` - Pattern `Hello world[[:punct:]]` matches (for example) - - => `Hello world!` - - => `Hello world.` - - => `Hello world+` - - => `Hello world?` + - => `Hello world!` + - => `Hello world.` + - => `Hello world+` + - => `Hello world?` - Pattern `[[.backslash.]]Hello[[.vertical-line.]]world[[.exclamation-mark.]]` matches (using [collation symbols](https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap07.html#tag_07_03_02_04)) - - => `\Hello|world!` + - => `\Hello|world!` ## Extended pattern language @@ -90,17 +90,17 @@ If you set the [shell option](../internals/shell_options.md) `extglob`, Bash understands some powerful patterns. A `` is one or more patterns, separated by the pipe-symbol (`PATTERN|PATTERN`). - --------------------- ------------------------------------------------------------ - `?()` Matches **zero or one** occurrence of the given patterns - `*()` Matches **zero or more** occurrences of the given patterns - `+()` Matches **one or more** occurrences of the given patterns - `@()` Matches **one** of the given patterns - `!()` Matches anything **except** one of the given patterns - --------------------- ------------------------------------------------------------ +|Extended pattern|Matches| +|----------------|-------| +|`?()`|Matches **zero or one** occurrence of the given patterns| +|`*()`|Matches **zero or more** occurrences of the given patterns| +|`+()`|Matches **one or more** occurrences of the given patterns| +|`@()`|Matches **one** of the given patterns| +|`!()`|Matches anything **except** one of the given patterns| ### Examples -**[Delete all but one specific file]{.underline}** +**Delete all but one specific file** rm -f !(survivior.txt) @@ -108,15 +108,15 @@ patterns, separated by the pipe-symbol (`PATTERN|PATTERN`). ### Related shell options - option classification description - ------------------- ------------------------------------- ------------------------------------------------------------------------------- - `dotglob` [globbing](../syntax/expansion/globs.md) see [Pathname expansion customization](../syntax/expansion/globs.md#Customization) - `extglob` global enable/disable extended pattern matching language, as described above - `failglob` [globbing](../syntax/expansion/globs.md) see [Pathname expansion customization](../syntax/expansion/globs.md#Customization) - `nocaseglob` [globbing](../syntax/expansion/globs.md) see [Pathname expansion customization](../syntax/expansion/globs.md#Customization) - `nocasematch` pattern/string matching perform pattern matching without regarding the case of individual letters - `nullglob` [globbing](../syntax/expansion/globs.md) see [Pathname expansion customization](../syntax/expansion/globs.md#Customization) - `globasciiranges` [globbing](../syntax/expansion/globs.md) see [Pathname expansion customization](../syntax/expansion/globs.md#Customization) +|option|classification|description| +|------|--------------|-----------| +|`dotglob`|[globbing](../syntax/expansion/globs.md)|see [Pathname expansion customization](/syntax/expansion/globs.md#Customization)| +|`extglob`|global|enable/disable extended pattern matching language, as described above| +|`failglob`|[globbing](../syntax/expansion/globs.md)|see [Pathname expansion customization](/syntax/expansion/globs.md#Customization)| +|`nocaseglob`|[globbing](../syntax/expansion/globs.md)|see [Pathname expansion customization](/syntax/expansion/globs.md#Customization)| +|`nocasematch`|pattern/string matching|perform pattern matching without regarding the case of individual letters| +|`nullglob`|[globbing](../syntax/expansion/globs.md)|see [Pathname expansion customization](/syntax/expansion/globs.md#Customization)| +|`globasciiranges`|[globbing](../syntax/expansion/globs.md)|see [Pathname expansion customization](/syntax/expansion/globs.md#Customization)| ## Bugs and Portability considerations @@ -152,12 +152,12 @@ to those described above. \* ksh93 supports arbitrary quantifiers just like ERE using the `{from,to}(pattern-list)` syntax. `{2,4}(foo)bar` matches between 2-4 -\"foo\"'s followed by \"bar\". `{2,}(foo)bar` matches 2 or more -\"foo\"'s followed by \"bar\". You can probably figure out the rest. So +"foo"'s followed by "bar". `{2,}(foo)bar` matches 2 or more +"foo"'s followed by "bar". You can probably figure out the rest. So far, none of the other shells support this syntax. \* In ksh93, a `pattern-list` may be delimited by either `&` or `|`. `&` -means \"all patterns must be matched\" instead of \"any pattern\". For +means "all patterns must be matched" instead of "any pattern". For example, `[[ fo0bar == @(fo[0-9]&+([[:alnum:]]))bar ]]` would be true while `[[ f00bar == @(fo[0-9]&+([[:alnum:]]))bar ]]` is false, because all members of the and-list must be satisfied. No other shell supports diff --git a/docs/syntax/pe.md b/docs/syntax/pe.md index 70d0a32..9d90e47 100644 --- a/docs/syntax/pe.md +++ b/docs/syntax/pe.md @@ -46,7 +46,7 @@ applicable description mentions arrays below. Please also see the [article about arrays](../syntax/arrays.md). For a more technical view what a parameter is and which types exist, -[see the dictionary entry for \"parameter\"](../dict/parameter.md). +[see the dictionary entry for "parameter"](../dict/parameter.md). ## Overview @@ -107,16 +107,16 @@ is identical to using `$FOO` like you see it everywhere, but has the advantage that it can be immediately followed by characters that would be interpreted as part of the parameter name otherwise. Compare these two expressions (`WORD="car"` for example), where we want to print a -word with a trailing \"s\": +word with a trailing "s": echo "The plural of $WORD is most likely $WORDs" echo "The plural of $WORD is most likely ${WORD}s" -[Why does the first one fail?]{.underline} It prints nothing, because a -parameter (variable) named \"`WORDs`\" is undefined and thus printed as -\"\" (*nothing*). Without using braces for parameter expansion, Bash +Why does the first one fail? It prints nothing, because a +parameter (variable) named "`WORDs`" is undefined and thus printed as +"" (*nothing*). Without using braces for parameter expansion, Bash will interpret the sequence of all valid characters from the introducing -\"`$`\" up to the last valid character as name of the parameter. When +"`$`" up to the last valid character as name of the parameter. When using braces you just force Bash to **only interpret the name inside your braces**. @@ -138,9 +138,9 @@ individual indexes or mass arguments. An individual index behaves like a normal parameter, for the mass expansion, please read the article about arrays linked above. -- \${array\[5\]} -- \${array\[\*\]} -- \${array\[@\]} +- `${array[5]}` +- `${array[*]}` +- `${array[@]}` ## Indirection @@ -158,13 +158,13 @@ you can instead use the form to enter a level of indirection. The referenced parameter is not `PARAMETER` itself, but the parameter whose name is stored as the value -of `PARAMETER`. If the parameter `PARAMETER` has the value \"`TEMP`\", +of `PARAMETER`. If the parameter `PARAMETER` has the value "`TEMP`", then `${!PARAMETER}` will expand to the value of the parameter named `TEMP`: read -rep 'Which variable do you want to inspect? ' look_var - printf 'The value of "%s" is: "%s"\n' "$look_var" "${!look_var}" + printf 'The value of "%s" is: "%s"\n' "$look_var" "${!look_var}" Of course the indirection also works with special variables: @@ -193,7 +193,7 @@ of an array, the length of a string, or number of elements in an array indirectly (see [syntax/arrays#indirection](../syntax/arrays.md#indirection) for workarounds). Additionally, the `!`-prefixed parameter expansion conflicts with ksh-like shells which have the more powerful -\"name-reference\" form of indirection, where the exact same syntax is +"name-reference" form of indirection, where the exact same syntax is used to expand to the name of the variable being referenced. Indirect references to [array names](../syntax/arrays.md) are also possible @@ -235,13 +235,13 @@ of words in the variable while `~~` reverses case for all. Thanks to -[**Example: Rename all `*.txt` filenames to lowercase**]{.underline} +**Example: Rename all `*.txt` filenames to lowercase** for file in *.txt; do mv "$file" "${file,,}" done -[**Note:**]{.underline} Case modification is a handy feature you can +**Note:** Case modification is a handy feature you can apply to a name or a title. Or is it? Case modification was an important aspect of the Bash 4 release. Bash version 4, RC1 would perform word splitting, and then case modification, resulting in title case (where @@ -271,9 +271,6 @@ Assume: `array=(This is some Text)` - `echo "${array[@]^^}"` - => `THIS IS SOME TEXT` -```{=html} - -``` * ''echo "${array[2]^^}"'' * => ''SOME'' @@ -288,7 +285,7 @@ string `PREFIX`. The elements of the list are separated by the first character in the `IFS`-variable ( by default). This will show all defined variable names (not values!) beginning with -\"BASH\": +"BASH": $ echo ${!BASH*} BASH BASH_ARGC BASH_ARGV BASH_COMMAND BASH_LINENO BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION @@ -319,9 +316,9 @@ Example string (*just a quote from a big man*): `${PARAMETER#PATTERN}` and `${PARAMETER##PATTERN}` This form is to remove the described [pattern](../syntax/pattern.md) trying -to **match it from the beginning of the string**. The operator \"`#`\" +to **match it from the beginning of the string**. The operator "`#`" will try to remove the shortest text matching the pattern, while -\"`##`\" tries to do it with the longest text matching. Look at the +"`##`" tries to do it with the longest text matching. Look at the following examples to get the idea (matched text ~~marked striked~~, remember it will be removed!): @@ -347,7 +344,7 @@ from the end. ### Common use -[**How the heck does that help to make my life easier?**]{.underline} +**How the heck does that help to make my life easier?** Well, maybe the most common use for it is to **extract parts of a filename**. Just look at the following list with examples: @@ -410,7 +407,7 @@ The first one (*one slash*) is to only substitute **the first occurrence** of the given pattern, the second one (*two slashes*) is to substitute **all occurrences** of the pattern. -First, let's try to say \"happy\" instead of \"conservative\" in our +First, let's try to say "happy" instead of "conservative" in our example string: ${MYSTRING//conservative/happy} @@ -418,26 +415,26 @@ example string: => `Be liberal in what you accept, and conservativehappy in what you send` -Since there is only one \"conservative\" in that example, it really +Since there is only one "conservative" in that example, it really doesn't matter which of the two forms we use. -Let's play with the word \"in\", I don't know if it makes any sense, -but let's substitute it with \"by\". +Let's play with the word "in", I don't know if it makes any sense, +but let's substitute it with "by". -[**First form: Substitute first occurrence**]{.underline} +**First form: Substitute first occurrence** ${MYSTRING/in/by} => `Be liberal inby what you accept, and conservative in what you send` -[**Second form: Substitute all occurrences**]{.underline} +**Second form: Substitute all occurrences** ${MYSTRING//in/by} => `Be liberal inby what you accept, and conservative inby what you send` -[**Anchoring**]{.underline} Additionally you can \"anchor\" an +**Anchoring** Additionally you can "anchor" an expression: A `#` (hashmark) will indicate that your expression is matched against the beginning portion of the string, a `%` (percent-sign) will do it for the end portion. @@ -478,7 +475,7 @@ expanded. Again, a quote from a big man, to have a test text: MYSTRING="Be liberal in what you accept, and conservative in what you send" -Using echo `${#MYSTRING}`\... +Using echo `${#MYSTRING}`... => `64` @@ -493,7 +490,7 @@ There's not much to say about it, mh? For [arrays](../syntax/arrays.md), this expansion type has two meanings: - For **individual** elements, it reports the string length of the - element (as for every \"normal\" parameter) + element (as for every "normal" parameter) - For the **mass subscripts** `@` and `*` it reports the number of set elements in the array @@ -502,11 +499,11 @@ Example: Assume: `array=(This is a text)` - `echo ${#array[1]}` - - => 2 (the word \"is\" has a length of 2) + - => 2 (the word "is" has a length of 2) - `echo ${#array[@]}` - => 4 (the array contains 4 elements) -[**Attention:**]{.underline} The number of used elements does not need +**Attention:** The number of used elements does not need to conform to the highest index. Sparse arrays are possible in Bash, that means you can have 4 elements, but with indexes 1, 7, 20, 31. **You can't loop through such an array with a counter loop based on the @@ -593,7 +590,7 @@ Example: Assume: `array=(This is a text)` - `echo ${array[0]:2:2}` - - => `is` (the \"is\" in \"This\", array element 0) + - => `is` (the "is" in "This", array element 0) - `echo ${array[@]:1:2}` - => `is a` (from element 1 inclusive, 2 elements are expanded, i.e. element 1 and 2) @@ -621,7 +618,7 @@ useful, you need to put that parameter syntax in. read -p "Enter your gender (just press ENTER to not tell us): " GENDER echo "Your gender is ${GENDER:-a secret}." -It will print \"Your gender is a secret.\" when you don't enter the +It will print "Your gender is a secret." when you don't enter the gender. Note that the default value is **used on expansion time**, it is **not assigned to the parameter**. @@ -712,7 +709,7 @@ Let's change our code example from above: ### Assign a default value: Arrays For [arrays](../syntax/arrays.md) this expansion type is limited. For an -individual index, it behaves like for a \"normal\" parameter, the +individual index, it behaves like for a "normal" parameter, the default value is assigned to this one element. The mass-expansion subscripts `@` and `*` **can not be used here** because it's not possible to assign to them! @@ -732,7 +729,7 @@ you can specify**: The above code will simply add a warning if `JAVAPATH` is set (because it could influence the startup behaviour of that imaginary application). -Some more unrealistic example\... Ask for some flags (for whatever +Some more unrealistic example... Ask for some flags (for whatever reason), and then, if they were set, print a warning and also print the flags: @@ -761,7 +758,7 @@ if variables you need (and that can be empty) are undefined: ### Use an alternate value: Arrays Similar to the cases for [arrays](../syntax/arrays.md) to expand to a default -value, this expansion behaves like for a \"normal\" parameter when using +value, this expansion behaves like for a "normal" parameter when using individual array elements by index, but reacts differently when using the mass-expansion subscripts `@` and `*`: @@ -830,9 +827,6 @@ Removing the first 6 characters from a text string:
` -```{=html} - -``` - Almost all shells disagree about the treatment of an unquoted `$@`, `${arr[@]}`, `$*`, and `${arr[*]}` when [IFS](http://mywiki.wooledge.org/IFS) is set to null. POSIX is @@ -877,9 +871,6 @@ Removing the first 6 characters from a text string: pathname expansion and word-splitting to the results, except for zsh, which doesn't do pathname expansion in its default mode. -```{=html} - -``` - Additionally, shells disagree about various wordsplitting behaviors, the behavior of inserting delimiter characters from IFS in `$*`, and the way adjacent arguments are concatenated, when IFS is modified in @@ -906,35 +897,23 @@ Removing the first 6 characters from a text string: possible side-effect that can affect expansion halfway through expansion that way. -```{=html} - -``` - As previously mentioned, the Bash form of indirection by prefixing a parameter expansion with a `!` conflicts with the same syntax used by mksh, zsh, and ksh93 for a different purpose. Bash will - \"slightly\" modify this expansion in the next version with the + "slightly" modify this expansion in the next version with the addition of namerefs. -```{=html} - -``` - Bash (and most other shells) don't allow .'s in identifiers. In ksh93, dots in variable names are used to reference methods (i.e. - \"Discipline Functions\"), attributes, special shell variables, and - to define the \"real value\" of an instance of a class. + "Discipline Functions"), attributes, special shell variables, and + to define the "real value" of an instance of a class. -```{=html} - -``` - In ksh93, the `_` parameter has even more uses. It is used in the same way as `self` in some object-oriented languages; as a placeholder for some data local to a class; and also as the mechanism for class inheritance. In most other contexts, `_` is compatible with Bash. -```{=html} - -``` - Bash only evaluates the subscripts of the slice expansion (`${x:y:z}`) if the parameter is set (for both nested expansions and arithmetic). For ranges, Bash evaluates as little as possible, i.e., @@ -954,13 +933,10 @@ Removing the first 6 characters from a text string: ### Quote Nesting -- In most shells, when dealing with an \"alternate\" parameter +- In most shells, when dealing with an "alternate" parameter expansion that expands to multiple words, and nesting such expansions, not all combinations of nested quoting are possible. -```{=html} - -``` # Bash $ typeset -a a=(meh bleh blerg) b $ IFS=e @@ -1007,7 +983,7 @@ Consider the following (only slightly far-fetched) code: "${someCmd[@]-"$someOtherCmd" arg2 "${otherArgs[@]}"}" arg5 -This final line is perhaps not the most obvious, but I\'ve run into +This final line is perhaps not the most obvious, but I've run into cases were this type of logic can be desirable and realistic. We can deduce what was intended: diff --git a/docs/syntax/quoting.md b/docs/syntax/quoting.md index c3955c0..a5e3108 100644 --- a/docs/syntax/quoting.md +++ b/docs/syntax/quoting.md @@ -27,7 +27,7 @@ All three forms have the very same purpose: **They give you general control over parsing, expansion and expansion results.** Besides these basic variants, there are some special quoting methods -(like interpreting ANSI-C escapes in a string) you\'ll meet below. +(like interpreting ANSI-C escapes in a string) you'll meet below. :!: **ATTENTION** :!: The quote characters (`"`, double quote and `'`, single quote) are a syntax element that influence parsing. It is not @@ -77,7 +77,7 @@ beautify your code: } The backslash can be used to mask every character that has a special -meaning to bash. [Exception:]{.underline} Inside a single-quoted string +meaning to bash. Exception: Inside a single-quoted string (see below). ## Weak quoting @@ -105,7 +105,7 @@ unless you have a file named `*`, spit out an error. Will work as expected. `$PATH` is expanded, because it's double (weak) quoted. -If a backslash in double quotes (\"weak quoting\") occurs, there are 2 +If a backslash in double quotes ("weak quoting") occurs, there are 2 ways to deal with it - if the baskslash is followed by a character that would have a @@ -131,7 +131,7 @@ it's surrounded by strong quotes. In practise that means, to produce a text like `Here's my test...` as a single-quoted string, you have to leave and re-enter the single quoting -to get the character \"`'`\" as literal text: +to get the character "`'`" as literal text: # WRONG echo 'Here's my test...' @@ -151,25 +151,25 @@ C-like escape sequences. The Syntax is: where the following escape sequences are decoded in `string`: - Code Meaning - -------------- ------------------------------------------------------------------------------------------------------------------------------------- - `\"` double-quote - `\'` single-quote - `\\` backslash - `\a` terminal alert character (bell) - `\b` backspace - `\e` escape (ASCII 033) - `\E` escape (ASCII 033) **\\E is non-standard** - `\f` form feed - `\n` newline - `\r` carriage return - `\t` horizontal tab - `\v` vertical tab - `\cx` a control-x character, for example, `$'\cZ'` to print the control sequence composed of Ctrl-Z (`^Z`) - `\uXXXX` Interprets `XXXX` as a hexadecimal number and prints the corresponding character from the character set (4 digits) (Bash 4.2-alpha) - `\UXXXXXXXX` Interprets `XXXX` as a hexadecimal number and prints the corresponding character from the character set (8 digits) (Bash 4.2-alpha) - `\nnn` the eight-bit character whose value is the octal value nnn (one to three digits) - `\xHH` the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) +|Code|Meaning| +|----|-------| +|`\"`|double-quote| +|`\'`|single-quote| +|`\\`|backslash| +|`\a`|terminal alert character (bell)| +|`\b`|backspace| +|`\e`|escape (ASCII 033)| +|`\E`|escape (ASCII 033) **\E is non-standard**| +|`\f`|form feed| +|`\n`|newline| +|`\r`|carriage return| +|`\t`|horizontal tab| +|`\v`|vertical tab| +|`\cx`|a control-x character, for example, `$'\cZ'` to print the control sequence composed of Ctrl-Z (`^Z`)| +|`\uXXXX`|Interprets `XXXX` as a hexadecimal number and prints the corresponding character from the character set (4 digits) (Bash 4.2-alpha)| +|`\UXXXXXXXX`|Interprets `XXXX` as a hexadecimal number and prints the corresponding character from the character set (8 digits) (Bash 4.2-alpha)| +|`\nnn`|the eight-bit character whose value is the octal value nnn (one to three digits)| +|`\xHH`|the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)| This is especially useful when you want to pass special characters as arguments to some programs, like passing a newline to sed. @@ -181,8 +181,8 @@ The `$'...'` syntax comes from ksh93, but is portable to most modern shells including pdksh. A [specification](http://austingroupbugs.net/view.php?id=249#c590) for it was accepted for SUS issue 7. There are still some stragglers, such as -most ash variants including dash, (except busybox built with \"bash -compatibility\" features). +most ash variants including dash, (except busybox built with "bash +compatibility" features). ## I18N/L10N @@ -197,7 +197,7 @@ quoted string. If the string was replaced (translated), the result is double quoted. -In case you\'re a C programmer: The purpose of `$"..."` is the same as +In case you're a C programmer: The purpose of `$"..."` is the same as for `gettext()` or `_()`. For useful examples to localize your scripts, please see [Appendix I of @@ -216,7 +216,7 @@ iterate through. The list can also be in a variable: mylist="DOG CAT BIRD HORSE" -**[WRONG]{.underline}** way to iterate through this list: +**WRONG** way to iterate through this list: for animal in "$mylist"; do echo $animal @@ -226,7 +226,7 @@ Why? Due to the double-quotes, technically, the expansion of `$mylist` is seen as **one word**. The for loop iterates exactly one time, with `animal` set to the whole list. -**[RIGHT]{.underline}** way to iterate through this list: +**RIGHT** way to iterate through this list: for animal in $mylist; do echo $animal @@ -251,7 +251,7 @@ test string with spaces: mystring="my string" -And now check that string against the word \"testword\": +And now check that string against the word "testword": [ $mystring = testword ] # WRONG! @@ -272,20 +272,16 @@ So what you really want to do is: Now the command has three parameters, which makes sense for a binary (two argument) operator. -**[Hint:]{.underline}** Inside the [conditional +**Hint:** Inside the [conditional expression](../syntax/ccmd/conditional_expression.md) (`[[ ]]`) Bash doesn't perform word splitting, and thus you don't need to quote your variable -references - they are always seen as \"one word\". +references - they are always seen as "one word". ## See also -- Internal: [Some words about words\...](../syntax/words.md) +- Internal: [Some words about words...](../syntax/words.md) - Internal: [Word splitting](../syntax/expansion/wordsplit.md) - Internal: [Introduction to expansions and substitutions](../syntax/expansion/intro.md) - -```{=html} - -``` - External: [Grymore: Shellquoting](http://www.grymoire.com/Unix/Quote.html) diff --git a/docs/syntax/redirection.md b/docs/syntax/redirection.md index 0efd471..b36e491 100644 --- a/docs/syntax/redirection.md +++ b/docs/syntax/redirection.md @@ -1,6 +1,8 @@ # Redirection -Fix me: To be continued\ +!!! warning "FIXME" + To be continued + Redirection makes it possible to control where the output of a command goes to, and where the input of a command comes from. It's a mighty tool that, together with pipelines, makes the shell powerful. The @@ -10,15 +12,18 @@ be executed](../syntax/grammar/parser_exec.md). Under normal circumstances, there are 3 files open, accessible by the file descriptors 0, 1 and 2, all connected to your terminal: - Name FD Description - ---------- ---- -------------------------------------------------------- - `stdin` 0 standard input stream (e.g. keyboard) - `stdout` 1 standard output stream (e.g. monitor) - `stderr` 2 standard error output stream (usually also on monitor) +|Name|FD|Description| +|----|--|-----------| +|`stdin`|0|standard input stream (e.g. keyboard)| +|`stdout`|1|standard output stream (e.g. monitor)| +|`stderr`|2|standard error output stream (usually also on monitor)| -The terms \"monitor\" and \"keyboard\" refer to the -same device, the **terminal** here. Check your preferred UNIX(r)-FAQ for -details, I\'m too lazy to explain what a terminal is ;-) + + +!!! info "INFO" + The terms "monitor" and "keyboard" refer to the + same device, the **terminal** here. Check your preferred UNIX(r)-FAQ for + details, I'm too lazy to explain what a terminal is ;-) Both, `stdout` and `stderr` are output file descriptors. Their difference is the **convention** that a program outputs payload on @@ -33,7 +38,7 @@ this descriptor, you just use the number: cat some_file.txt 2>/dev/null Whenever you **reference** a descriptor, to point to its current target -file, then you use a \"`&`\" followed by a the descriptor number: +file, then you use a "`&`" followed by a the descriptor number: # this executes the echo-command and redirects its normal output (stdout) to the standard error target echo "There was an error" 1>&2 @@ -45,26 +50,27 @@ these examples are equivalent: cat >new.txt foo.txt bar.txt >new.txt cat foo.txt bar.txt -Every redirection operator takes one or two -words as operands. If you have to use operands (e.g. filenames to -redirect to) that contain spaces you **must** quote them! +!!! info "important" + Every redirection operator takes one or two + words as operands. If you have to use operands (e.g. filenames to + redirect to) that contain spaces you **must** quote them! ## Valid redirection targets and sources This syntax is recognized whenever a `TARGET` or a `SOURCE` specification (like below in the details descriptions) is used. - Syntax Description - ---------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------- - `FILENAME` references a normal, ordinary filename from the filesystem (which can of course be a FIFO, too. Simply everything you can reference in the filesystem) - `&N` references the current target/source of the filedescriptor `N` (\"duplicates\" the filedescriptor) - `&-` closes the redirected filedescriptor, useful instead of `> /dev/null` constructs (`> &-`) - `/dev/fd/N` duplicates the filedescriptor `N`, if `N` is a valid integer - `/dev/stdin` duplicates filedescriptor 0 (`stdin`) - `/dev/stdout` duplicates filedescriptor 1 (`stdout`) - `/dev/stderr` duplicates filedescriptor 2 (`stderr`) - `/dev/tcp/HOST/PORT` assuming `HOST` is a valid hostname or IP address, and `PORT` is a valid port number or service name: redirect from/to the corresponding TCP socket - `/dev/udp/HOST/PORT` assuming `HOST` is a valid hostname or IP address, and `PORT` is a valid port number or service name: redirect from/to the corresponding UDP socket +|Syntax|Description| +|------|-----------| +|`FILENAME`|references a normal, ordinary filename from the filesystem (which can of course be a FIFO, too. Simply everything you can reference in the filesystem)| +|`&N`|references the current target/source of the filedescriptor `N` ("duplicates" the filedescriptor)| +|`&-`|closes the redirected filedescriptor, useful instead of `> /dev/null` constructs (`> &-`)| +|`/dev/fd/N`|duplicates the filedescriptor `N`, if `N` is a valid integer| +|`/dev/stdin`|duplicates filedescriptor 0 (`stdin`)| +|`/dev/stdout`|duplicates filedescriptor 1 (`stdout`)| +|`/dev/stderr`|duplicates filedescriptor 2 (`stderr`)| +|`/dev/tcp/HOST/PORT`|assuming `HOST` is a valid hostname or IP address, and `PORT` is a valid port number or service name: redirect from/to the corresponding TCP socket| +|`/dev/udp/HOST/PORT`|assuming `HOST` is a valid hostname or IP address, and `PORT` is a valid port number or service name: redirect from/to the corresponding UDP socket| If a target/source specification fails to open, the whole redirection operation fails. Avoid referencing file descriptors above 9, since you @@ -106,9 +112,10 @@ specified target. It's **equivalent** to Since Bash4, there's `&>>TARGET`, which is equivalent to `>> TARGET 2>&1`. -This syntax is deprecated and should not be -used. See the page about [obsolete and deprecated -syntax](../scripting/obsolete.md). +!!! info "important" + This syntax is deprecated and should not be + used. See the page about [obsolete and deprecated + syntax](../scripting/obsolete.md). ## Appending redirected output and error output @@ -145,7 +152,7 @@ omitted, filedescriptor 0 (`stdin`) is assumed. TAG A here-document is an input redirection using source data specified -directly at the command line (or in the script), no \"external\" source. +directly at the command line (or in the script), no "external" source. The redirection-operator `<<` is used together with a tag `TAG` that's used to mark the end of input later: @@ -178,11 +185,12 @@ here-documents. The tag you use **must** be the only word in the line, to be recognized as end-of-here-document marker. -It seems that here-documents (tested on versions -`1.14.7`, `2.05b` and `3.1.17`) are correctly terminated when there is -an EOF before the end-of-here-document tag. The reason is unknown, but -it seems to be done on purpose. Bash 4 introduced a warning message when -end-of-file is seen before the tag is reached. +!!! info "info" + It seems that here-documents (tested on versions + `1.14.7`, `2.05b` and `3.1.17`) are correctly terminated when there is + an EOF before the end-of-here-document tag. The reason is unknown, but + it seems to be done on purpose. Bash 4 introduced a warning message when + end-of-file is seen before the tag is reached. ## Here strings @@ -201,7 +209,7 @@ The here-string will append a newline (`\n`) to the data. ## Multiple redirections More redirection operations can occur in a line of course. The order is -**important**! They\'re evaluated from **left to right**. If you want to +**important**! They're evaluated from **left to right**. If you want to redirect both, `stderr` and `stdout` to the same file (like `/dev/null`, to hide it), this is **the wrong way**: @@ -216,12 +224,12 @@ Why? Relatively easy: - initially, `stdout` points to your terminal (you read it) - same applies to `stderr`, it's connected to your terminal - `2>&1` redirects `stderr` away from the terminal to the target for - `stdout`: **the terminal** (again\...) + `stdout`: **the terminal** (again...) - `1>/dev/null` redirects `stdout` away from your terminal to the file `/dev/null` What remains? `stdout` goes to `/dev/null`, `stderr` still (or better: -\"again\") goes to the terminal. You have to swap the order to make it +"again") goes to the terminal. You have to swap the order to make it do what you want: ``` bash diff --git a/docs/syntax/shellvars.md b/docs/syntax/shellvars.md index 4b2cdcf..030bfcc 100644 --- a/docs/syntax/shellvars.md +++ b/docs/syntax/shellvars.md @@ -2,54 +2,36 @@ ## Special Parameters - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - parameter character expansion description - ----------- ------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `*` asterisk The positional parameters starting from the first. When used inside doublequotes (see [quoting](../syntax/quoting.md)), like `"$*"`, it expands to all positional parameters *as one word*, delimited by the first character of the `IFS` variable (a space in this example): `"$1 $2 $3 $4"`.\ - If `IFS` is unset, the delimiter used will be always a space, if `IFS` is NULL, the delimiter will be nothing, which effectively concatenates all the positional parameters without any delimiter.\ - When used unquoted, it will just expand to the strings, one by one, not preserving the word boundaries (i.e. word splitting will split the text again, if it contains `IFS` characters.\ - See also the [scripting article about handling positional parameters](../scripting/posparams.md). - - `@` at-sign The positional parameters starting from the first. When used inside doublequotes (see [quoting](../syntax/quoting.md)), like `"$@"`, it expands all positional parameters *as separate words*: `"$1" "$2" "$3" "$4"`\ - Without doublequotes, the behaviour is like the one of `*` without doublequotes.\ - See also the [scripting article about handling positional parameters](../scripting/posparams.md). - - `#` hash mark Number of positional parameters (decimal)\ - See also the [scripting article about handling positional parameters](../scripting/posparams.md). - - `?` question mark Status of the most recently executed foreground-pipeline (exit/return code) - - `-` dash Current option flags set by the shell itself, on invocation, or using the [set builtin command](../commands/builtin/set.md). It's just a set of characters, like `himB` for `h`, `i`, `m` and `B`. - - `$` dollar-sign The process ID (PID) of the shell. In an [explicit subshell](../syntax/ccmd/grouping_subshell.md) it expands to the PID of the current \"main shell\", not the subshell. This is different from `$BASHPID`! - - `!` exclamation mark The process ID (PID) of the most recently executed background pipeline (like started with `command &`) - - `0` zero The name of the shell or the shell script (filename). Set by the shell itself.\ - If Bash is started with a filename to execute (script), it's set to this filename. If started with the `-c ` option (commandline given as argument), then `$0` will be the first argument after the given ``. Otherwise, it is set to the string given on invocation for `argv[0]`.\ - Unlike popular belief, `$0` is *not a positional parameter*. - - `_` underscore A kind of catch-all parameter. Directly after shell invocation, it's set to the filename used to invoke Bash, or the absolute or relative path to the script, just like `$0` would show it. Subsequently, expands to the last argument to the previous command. Placed into the environment when executing commands, and set to the full pathname of these commands. When checking mail, this parameter holds the name of the mail file currently being checked. - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +|parameter|character|expansion description| +|---------|---------|---------------------| +|`*`|asterisk|The positional parameters starting from the first. When used inside doublequotes (see [quoting](../syntax/quoting)), like `"$*"`, it expands to all positional parameters *as one word*, delimited by the first character of the `IFS` variable (a space in this example): `"$1 $2 $3 $4"`.
If `IFS` is unset, the delimiter used will be always a space, if `IFS` is NULL, the delimiter will be nothing, which effectively concatenates all the positional parameters without any delimiter.
When used unquoted, it will just expand to the strings, one by one, not preserving the word boundaries (i.e. word splitting will split the text again, if it contains `IFS` characters.
See also the [scripting article about handling positional parameters](../scripting/posparams).| +|`@`|at-sign|The positional parameters starting from the first. When used inside doublequotes (see [quoting](../syntax/quoting)), like `"$@"`, it expands all positional parameters *as separate words*: `"$1" "$2" "$3" "$4"`
Without doublequotes, the behaviour is like the one of `*` without doublequotes.
See also the [scripting article about handling positional parameters](../scripting/posparams).| +|`#`|hash mark|Number of positional parameters (decimal)
See also the [scripting article about handling positional parameters](../scripting/posparams).| +|`?`|question mark|Status of the most recently executed foreground-pipeline (exit/return code)| +|`-`|dash|Current option flags set by the shell itself, on invocation, or using the [set builtin command](../commands/builtin/set). It\'s just a set of characters, like `himB` for `h`, `i`, `m` and `B`.| +|`$`|dollar-sign|The process ID (PID) of the shell. In an [explicit subshell](../syntax/ccmd/grouping_subshell) it expands to the PID of the current \"main shell\", not the subshell. This is different from `$BASHPID`!| +|`!`|exclamation mark|The process ID (PID) of the most recently executed background pipeline (like started with `command &`)| +|`0`|zero|The name of the shell or the shell script (filename). Set by the shell itself.
If Bash is started with a filename to execute (script), it\'s set to this filename. If started with the `-c ` option (commandline given as argument), then `$0` will be the first argument after the given ``. Otherwise, it is set to the string given on invocation for `argv[0]`.
Unlike popular belief, `$0` is *not a positional parameter*.| +|`_`|underscore|A kind of catch-all parameter. Directly after shell invocation, it\'s set to the filename used to invoke Bash, or the absolute or relative path to the script, just like `$0` would show it. Subsequently, expands to the last argument to the previous command. Placed into the environment when executing commands, and set to the full pathname of these commands. When checking mail, this parameter holds the name of the mail file currently being checked.| ## Shell Variables ### BASH - Variable: `BASH` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Expands to the full file name used to invoke the current instance of Bash. ### BASHOPTS - Variable: `BASHOPTS` Since: 4.1-alpha - -------------- ----------------- ------------ ----------- - Type: normal variable Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`BASHOPTS` |Since: |4.1-alpha| +| -------------- |----------------- |------------ |-----------| +| Type: |normal variable |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| A colon-separated list of enabled shell options. @@ -67,10 +49,10 @@ This variable is read-only. ### BASHPID - Variable: `BASHPID` Since: 4.0-alpha - -------------- ------------------ ------------ ----------- - Type: integer variable Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`BASHPID` |Since: |4.0-alpha| +| -------------- |------------------ |------------ |-----------| +| Type: |integer variable |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| Always expands to the process ID of the current Bash process. This differs from the special parameter `$` under certain circumstances, such @@ -78,10 +60,10 @@ as subshells that do not require Bash to be re-initialized. ### BASH_ALIASES - Variable: `BASH_ALIASES` Since: unknown - -------------- ------------------- ------------ --------- - Type: associative array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_ALIASES` |Since: |unknown| +| -------------- |------------------- |------------ |---------| +| Type: |associative array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An associative array variable whose members correspond to the internal list of aliases as maintained by the alias builtin. Elements added to @@ -93,10 +75,10 @@ builtin command. ### BASH_ARGC - Variable: `BASH_ARGC` Since: 3.0 - -------------- --------------------------------- ------------ ----- - Type: integer indexed array Read-only: no - Set by Bash: only in extended debugging mode Default: n/a +| Variable: |`BASH_ARGC` |Since: |3.0| +| -------------- |--------------------------------- |------------ |-----| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |only in extended debugging mode |Default: |n/a| An array variable whose values are the number of parameters in each frame of the current Bash execution call stack. @@ -109,10 +91,10 @@ subroutine is executed, the number of parameters passed is pushed onto ### BASH_ARGV - Variable: `BASH_ARGV` Since: 3.0 - -------------- --------------------------------- ------------ ----- - Type: integer indexed array Read-only: no - Set by Bash: only in extended debugging mode Default: n/a +| Variable: |`BASH_ARGV` |Since: |3.0| +| -------------- |--------------------------------- |------------ |-----| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |only in extended debugging mode |Default: |n/a| An array variable containing all of the parameters in the current Bash execution call stack. @@ -124,10 +106,10 @@ subroutine is executed, the parameters supplied are pushed onto ### BASH_ARGV0 - Variable: `BASH_ARGV0` Since: 5.0-alpha - -------------- -------------- ------------ -------------- - Type: string Read-only: no - Set by Bash: yes Default: same as `$0` +| Variable: |`BASH_ARGV0` |Since: |5.0-alpha| +| -------------- |-------------- |------------ |--------------| +| Type: |string |Read-only: |no| +| Set by Bash: |yes |Default: |same as `$0`| Expands to the name of the shell or shell script - as the special parameter `$0` does. Assignments to `BASH_ARGV0` causes the value to be @@ -138,10 +120,10 @@ subsequently reset. ### BASH_CMDS - Variable: `BASH_CMDS` Since: unknown - -------------- ------------------- ------------ --------- - Type: associative array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_CMDS` |Since: |unknown| +| -------------- |------------------- |------------ |---------| +| Type: |associative array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An associative array variable whose members correspond to the internal hash table of commands as maintained by the `hash` builtin @@ -154,10 +136,10 @@ builtin command. ### BASH_COMMAND - Variable: `BASH_COMMAND` Since: 3.0 - -------------- ----------------- ------------ ----- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_COMMAND` |Since: |3.0| +| -------------- |----------------- |------------ |-----| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The command currently being executed or about to be executed, unless the shell is executing a command as the result of a trap, in which case it @@ -165,10 +147,10 @@ is the command executing at the time of the trap. ### BASH_COMPAT - Variable: `BASH_COMPAT` Since: 4.3-alpha - -------------- ----------------- ------------ ----------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`BASH_COMPAT` |Since: |4.3-alpha| +| -------------- |----------------- |------------ |-----------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The value is used to set the shell's compatibility level. The value may be a decimal number (e.g., `4.2`) or an integer (e.g., `42`) @@ -183,19 +165,19 @@ valid value. ### BASH_EXECUTION_STRING - Variable: `BASH_EXECUTION_STRING` Since: 3.0 - -------------- ------------------------- ------------ ----- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_EXECUTION_STRING` |Since: |3.0| +| -------------- |------------------------- |------------ |-----| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The command argument to the `-c` invocation option. ### BASH_LINENO - Variable: `BASH_LINENO` Since: 3.0 - -------------- ----------------------- ------------ ----- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_LINENO` |Since: |3.0| +| -------------- |----------------------- |------------ |-----| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable whose members are the line numbers in source files corresponding to each member of `FUNCNAME`. @@ -206,10 +188,10 @@ corresponding to each member of `FUNCNAME`. ### BASH_REMATCH - Variable: `BASH_REMATCH` Since: 3.0 - -------------- ----------------------- ------------ ----- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_REMATCH` |Since: |3.0| +| -------------- |----------------------- |------------ |-----| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable whose members are assigned by the `=~` binary operator to the `[[` conditional command. @@ -222,30 +204,30 @@ Before Bash version 5.1-alpha this variable was readonly. ### BASH_SOURCE - Variable: `BASH_SOURCE` Since: 3.0 - -------------- ----------------------- ------------ ----- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_SOURCE` |Since: |3.0| +| -------------- |----------------------- |------------ |-----| +| Type: |integer |indexed |array Read-only: no| +| Set by Bash: |yes |Default: |n/a| An array variable whose members are the source filenames corresponding to the elements in the `FUNCNAME` array variable. ### BASH_SUBSHELL - Variable: `BASH_SUBSHELL` Since: 3.0 - -------------- ----------------- ------------ ----- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_SUBSHELL` |Since: |3.0| +| -------------- |----------------- |------------ |-----| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Incremented by one each time a subshell or subshell environment is spawned. The initial value is 0. ### BASH_VERSINFO - Variable: `BASH_VERSINFO` Since: 2.0 - -------------- ----------------------- ------------ ----- - Type: integer indexed array Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`BASH_VERSINFO` |Since: |2.0| +| -------------- |----------------------- |------------ |-----| +| Type: |integer indexed array |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| A readonly array variable whose members hold version information for this instance of Bash. The values assigned to the array members are as @@ -262,22 +244,22 @@ follows: ### BASH_VERSION - Variable: `BASH_VERSION` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`BASH_VERSION` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Expands to a string describing the version of this instance of Bash. -Since Bash 2.0 it includes the shell's \"release status\" (alpha\[N\], +Since Bash 2.0 it includes the shell's "release status" (alpha\[N\], beta\[N\], release). ### CHILD_MAX - Variable: `CHILD_MAX` Since: 4.3-alpha - -------------- ----------------- ------------ ----------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`CHILD_MAX` |Since: |4.3-alpha| +| -------------- |----------------- |------------ |-----------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| Set the number of exited child status values for the shell to remember. Bash will not allow this value to be decreased below a POSIX-mandated @@ -286,39 +268,39 @@ exceed. The minimum value is system-dependent. ### COMP_CWORD - Variable: `COMP_CWORD` Since: unknown - -------------- --------------------------------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: only for programmable completion facilities Default: n/a +| Variable: |`COMP_CWORD` |Since: |unknown| +| -------------- |--------------------------------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |only for programmable completion facilities |Default: |n/a| An index into `COMP_WORDS` of the word containing the current cursor position. ### COMP_KEY - Variable: `COMP_KEY` Since: unknown - -------------- --------------------------------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: only for programmable completion facilities Default: n/a +| Variable: |`COMP_KEY` |Since: |unknown| +| -------------- |--------------------------------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |only for programmable completion facilities |Default: |n/a| The key (or final key of a key sequence) used to invoke the current completion function. ### COMP_LINE - Variable: `COMP_LINE` Since: unknown - -------------- --------------------------------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: only for programmable completion facilities Default: n/a +| Variable: |`COMP_LINE` |Since: |unknown| +| -------------- |--------------------------------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |only for programmable completion facilities |Default: |n/a| The current command line. ### COMP_POINT - Variable: `COMP_POINT` Since: unknown - -------------- --------------------------------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: only for programmable completion facilities Default: n/a +| Variable: |`COMP_POINT` |Since: |unknown| +| -------------- |--------------------------------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |only for programmable completion facilities |Default: |n/a| The index of the current cursor position relative to the beginning of the current command. If the current cursor position is at the end of the @@ -326,10 +308,10 @@ current command, the value of this variable is equal to `${#COMP_LINE}`. ### COMP_TYPE - Variable: `COMP_TYPET` Since: unknown - -------------- --------------------------------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: only for programmable completion facilities Default: n/a +| Variable: |`COMP_TYPET` |Since: |unknown| +| -------------- |--------------------------------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |only for programmable completion facilities |Default: |n/a| Set to an integer value corresponding to the type of completion attempted that caused a completion function to be called: @@ -342,14 +324,15 @@ attempted that caused a completion function to be called: `%` for menu completion ------- --------------------------------------------------- -FIXME where are the integer values? +!!! warning "FIXME" + where are the integer values? ### COMP_WORDBREAKS - Variable: `COMP_WORDBREAKS` Since: unknown - -------------- ------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`COMP_WORDBREAKS` |Since: |unknown| +| -------------- |------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Reports the set of characters that the readline library treats as word separators when performing word completion. @@ -359,10 +342,10 @@ is subsequently reset. ### COMP_WORDS - Variable: `COMP_WORDS` Since: unknown - -------------- --------------------------------------------- ------------ --------- - Type: integer indexed array Read-only: no - Set by Bash: only for programmable completion facilities Default: n/a +| Variable: |`COMP_WORDS` |Since: |unknown| +| -------------- |--------------------------------------------- |------------ |---------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |only for programmable completion facilities |Default: |n/a| An array variable consisting of the individual words in the current command line. The line is split into words as readline would split it, @@ -370,20 +353,20 @@ using `COMP_WORDBREAKS` as described above. ### COPROC - Variable: `COPROC` Since: unknown - -------------- ----------------------- ------------ --------- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`COPROC` |Since: |unknown| +| -------------- |----------------------- |------------ |---------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable created to hold the file descriptors for output from and input to an unnamed coprocess. ### DIRSTACK - Variable: `DIRSTACK` Since: unknown - -------------- ----------------------- ------------ --------- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`DIRSTACK` |Since: |unknown| +| -------------- |----------------------- |------------ |---------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable containing the current contents of the directory stack. @@ -400,10 +383,10 @@ is subsequently reset. ### EPOCHREALTIME - Variable: `EPOCHREALTIME` Since: 5.0-alpha - -------------- ------------------ ------------ ----------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`EPOCHREALTIME` |Since: |5.0-alpha| +| -------------- |------------------ |------------ |-----------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Expands to the number of seconds since Unix expoch as a floating point value with micro-second granularity. @@ -413,10 +396,10 @@ it loses its special properties, even if it is subsequently reset. ### EPOCHSECONDS - Variable: `EPOCHSECONDS` Since: 5.0-alpha - -------------- ------------------ ------------ ----------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`EPOCHSECONDS` |Since: |5.0-alpha| +| -------------- |------------------ |------------ |-----------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Expands to the number of seconds since Unix expoch. @@ -425,29 +408,30 @@ it loses its special properties, even if it is subsequently reset. ### EUID - Variable: `EUID` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`EUID` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| Expands to the effective user ID of the current user, initialized at shell startup. -:!: Do not rely on this variable when security is a concern. +!!! Danger "!" + Do not rely on this variable when security is a concern. ### FUNCNAME - Variable: `FUNCNAME` Since: 2.04 - -------------- ----------------------------- ------------ ------ - Type: integer indexed array Read-only: no - Set by Bash: only inside shell functions Default: n/a +| Variable: |`FUNCNAME` |Since: |2.04| +| -------------- |----------------------------- |------------ |------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |only inside shell functions |Default: |n/a| An array variable containing the names of all shell functions currently in the execution call stack. The element with index 0 is the name of any currently-executing shell function. The bottom-most element (the one with the highest index) is -\"main\". +"main". This variable can be used with `BASH_LINENO` and `BASH_SOURCE`: Each element of `FUNCNAME` has corresponding elements in `BASH_LINENO` and @@ -466,10 +450,10 @@ is subsequently reset. ### GROUPS - Variable: `GROUPS` Since: 2.01 - -------------- ----------------------- ------------ ------ - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`GROUPS` |Since: |2.01| +| -------------- |----------------------- |------------ |------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable containing the list of groups of which the current user is a member. @@ -481,10 +465,10 @@ is subsequently reset. ### HISTCMD - Variable: `HISTCMD` Since: 1.14.0 - -------------- ------------------ ------------ -------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`HISTCMD` |Since: |1.14.0| +| -------------- |------------------ |------------ |--------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Expands to the history number (index in the history list) of the current command. @@ -494,19 +478,19 @@ is subsequently reset. ### HOSTNAME - Variable: `HOSTNAME` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`HOSTNAME` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Automatically set to the name of the current host. ### HOSTTYPE - Variable: `HOSTTYPE` Since: unknown - -------------- ----------------- ------------ ------------------ - Type: normal variable Read-only: no - Set by Bash: yes Default: system-dependent +| Variable: |`HOSTTYPE` |Since: |unknown| +| -------------- |----------------- |------------ |------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |system-dependent| Automatically set to a string that uniquely describes the type of machine on which Bash is executing. @@ -517,10 +501,10 @@ Example content: ### LINENO - Variable: `LINENO` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`LINENO` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Each time this parameter is referenced, the shell substitutes a decimal number representing the current sequential line number (starting with 1) @@ -534,13 +518,13 @@ is subsequently reset. ### MACHTYPE - Variable: `MACHTYPE` Since: unknown - -------------- ----------------- ------------ ------------------ - Type: normal variable Read-only: no - Set by Bash: yes Default: system-dependent +| Variable: |`MACHTYPE` |Since: |unknown| +| -------------- |----------------- |------------ |------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |system-dependent| Automatically set to a string that fully describes the system type on -which Bash is executing, in the standard GNU \"cpu-company-system\" +which Bash is executing, in the standard GNU "cpu-company-system" format. Example content: @@ -549,49 +533,49 @@ Example content: ### MAPFILE - Variable: `MAPFILE` Since: unknown - -------------- ----------------------- ------------ --------- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`MAPFILE` |Since: |unknown| +| -------------- |----------------------- |------------ |---------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable created to hold the text read by the [mapfile builtin command](../commands/builtin/mapfile.md) when no variable name is supplied. ### OLDPWD - Variable: `OLDPWD` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`OLDPWD` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The previous working directory as set by the cd command. ### OPTARG - Variable: `OPTARG` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`OPTARG` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The value of the last option argument processed by the `getopts` builtin command. ### OPTIND - Variable: `OPTIND` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`OPTIND` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The index of the next argument to be processed by the `getopts` builtin command. ### OSTYPE - Variable: `OSTYPE` Since: unknown - -------------- ----------------- ------------ ------------------ - Type: normal variable Read-only: no - Set by Bash: yes Default: system-dependent +| Variable: |`OSTYPE` |Since: |unknown| +| -------------- |----------------- |------------ |------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |system-dependent| Automatically set to a string that describes the operating system on which Bash is executing. @@ -602,10 +586,10 @@ Example content: ### PIPESTATUS - Variable: `PIPESTATUS` Since: 2.0 - -------------- ----------------------- ------------ ----- - Type: integer indexed array Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`PIPESTATUS` |Since: |2.0| +| -------------- |----------------------- |------------ |-----| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| An array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may @@ -613,29 +597,29 @@ contain only a single command). ### PPID - Variable: `PPID` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`PPID` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| The process ID of the shell's parent process. ### PWD - Variable: `PWD` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`PWD` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The current working directory as set by the [cd builtin command](../commands/builtin/cd.md). ### RANDOM - Variable: `RANDOM` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`RANDOM` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Each time this parameter is referenced, a random integer between 0 and 32767 is generated. The sequence of random numbers may be initialized by @@ -646,29 +630,29 @@ is subsequently reset. ### READLINE_LINE - Variable: `READLINE_LINE` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`READLINE_LINE` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The contents of the readline line buffer, for use with `bind -x`. ### READLINE_POINT - Variable: `READLINE_POINT` Since: unknown - -------------- ------------------ ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`READLINE_POINT` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| The position of the insertion point in the readline line buffer, for use with `bind -x`. ### REPLY - Variable: `REPLY` Since: unknown - -------------- ------------------------------------------------------------ ------------ --------- - Type: normal variable Read-only: no - Set by Bash: only by the [read builtin command](../commands/builtin/read.md) Default: n/a +| Variable: |`REPLY` |Since: |unknown| +| -------------- |------------------------------------------------------------ |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |only by the [read builtin command](../commands/builtin/read.md) |Default: |n/a| Set to the line of input read by the [read builtin command](../commands/builtin/read.md) when no arguments are supplied that @@ -676,10 +660,10 @@ name target variables. ### SECONDS - Variable: `SECONDS` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`SECONDS` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Each time this parameter is referenced, the number of seconds since shell invocation is returned. If a value is assigned to SECONDS, the @@ -691,10 +675,10 @@ is subsequently reset. ### SHELLOPTS - Variable: `SHELLOPTS` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`SHELLOPTS` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| A colon-separated list of enabled shell options. Each word in the list is a valid argument for the `-o` option to the [set builtin @@ -706,19 +690,19 @@ option in the list will be enabled before reading any startup files. ### SHLVL - Variable: `SHLVL` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`SHLVL` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| Incremented by one each time an instance of Bash is started. ### UID - Variable: `UID` Since: unknown - -------------- ------------------ ------------ --------- - Type: integer variable Read-only: yes - Set by Bash: yes Default: n/a +| Variable: |`UID` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |integer variable |Read-only: |yes| +| Set by Bash: |yes |Default: |n/a| Expands to the user ID of the current user, initialized at shell startup. @@ -727,10 +711,10 @@ startup. ### BASH_ENV - Variable: `BASH_ENV` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`BASH_ENV` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If this parameter is set when Bash is executing a shell script, its value is interpreted as a filename containing commands to initialize the @@ -746,10 +730,10 @@ before being interpreted as a file name. ### BASH_XTRACEFD - Variable: `BASH_XTRACEFD` Since: 4.1-alpha - -------------- ----------------- ------------ ----------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`BASH_XTRACEFD` |Since: |4.1-alpha| +| -------------- |----------------- |------------ |-----------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set to an integer corresponding to a valid file descriptor, Bash will write the trace output generated when `set -x` is enabled to that file @@ -765,10 +749,10 @@ unsetting it will result in the standard error being closed. ### CDPATH - Variable: `CDPATH` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`CDPATH` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The search path for the [cd builtin command](../commands/builtin/cd.md). @@ -781,10 +765,10 @@ Example content: ### COLUMNS - Variable: `COLUMNS` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: on `SIGWINCH` Default: n/a +| Variable: |`COLUMNS` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |on `|SIGWINCH` Default: |n/a| Used by the select compound command to determine the terminal width when printing selection lists. Automatically set upon receipt of a @@ -792,10 +776,10 @@ printing selection lists. Automatically set upon receipt of a ### COMPREPLY - Variable: `COMPREPLY` Since: unknown - -------------- ----------------------- ------------ --------- - Type: integer indexed array Read-only: no - Set by Bash: no Default: n/a +| Variable: |`COMPREPLY` |Since: |unknown| +| -------------- |----------------------- |------------ |---------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |no |Default: |n/a| An array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion @@ -803,39 +787,39 @@ facility. ### EMACS - Variable: `EMACS` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`EMACS` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If Bash finds this variable in the environment when the shell starts -with value \"t\", it assumes that the shell is running in an Emacs shell +with value "t", it assumes that the shell is running in an Emacs shell buffer and disables line editing. ### ENV - Variable: `ENV` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`ENV` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| Similar to `BASH_ENV`: Used when the shell is invoked in POSIX(r) mode. ### FCEDIT - Variable: `FCEDIT` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`FCEDIT` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The default editor for the `fc` builtin command. ### FIGNORE - Variable: `FIGNORE` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`FIGNORE` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| A colon-separated list of suffixes to ignore when performing filename completion. A filename whose suffix matches one of the entries in @@ -847,10 +831,10 @@ Example content: ### FUNCNEST - Variable: `FUNCNEST` Since: 4.2-alpha - -------------- ----------------- ------------ ----------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`FUNCNEST` |Since: |4.2-alpha| +| -------------- |----------------- |------------ |-----------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set to a numeric value greater than 0, defines a maximum function nesting level. Function invocations that exceed this nesting level will @@ -861,10 +845,10 @@ Negative values, 0 or non-numeric assignments have the effect as if ### GLOBIGNORE - Variable: `GLOBIGNORE` Since: 2.0 - -------------- ----------------- ------------ ----- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`GLOBIGNORE` |Since: |2.0| +| -------------- |----------------- |------------ |-----| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| A colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname @@ -873,20 +857,20 @@ is removed from the list of matches. ### HISTCONTROL - Variable: `HISTCONTROL` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`HISTCONTROL` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| A colon-separated list of values controlling how commands are saved on the history list: - --------------- ------------------------------------------------------------------------------------------------------------ - `ignorespace` lines which begin with a space character are not saved in the history list - `ignoredups` don't save lines matching the previous history entry - `ignoreboth` short for `ignorespace:ignoredups` - `erasedups` remove all previous lines matching the current line from the history list before the current line is saved - --------------- ------------------------------------------------------------------------------------------------------------ +| | | +| ---------------|-------------------------------------------------------------------------| +| `ignorespace` | lines which begin with a space character are not saved in the history list| +| `ignoredups` | don't save lines matching the previous history entry| +| `ignoreboth` | short for `ignorespace:ignoredups`| +| `erasedups` | remove all previous lines matching the current line from the history list before the current line is saved| Any value not in the above list is ignored. @@ -898,24 +882,24 @@ of the value of `HISTCONTROL`. ### HISTFILE - Variable: `HISTFILE` Since: unknown - -------------- ----------------- ------------ --------------------------- - Type: normal variable Read-only: no - Set by Bash: if unset Default: \'\' \~/.bash_history\'\' +| Variable: |`HISTFILE` |Since: |unknown| +| -------------- |----------------- |------------ |---------------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: \'\' \~/.bash_history\'\' -The name of the file in which command history is saved. +The |name of the file in which command history is saved.| If unset, the command history is not saved when an interactive shell exits. ### HISTFILESIZE - Variable: `HISTFILESIZE` Since: unknown - -------------- ----------------- ------------ ------------ - Type: normal variable Read-only: no - Set by Bash: if unset Default: `HISTSIZE` +| Variable: |`HISTFILESIZE` |Since: |unknown| +| -------------- |----------------- |------------ |------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: `HISTSIZE` -The maximum number of lines contained in the history file. +The |maximum number of lines contained in the history file.| When this variable is assigned a value, the history file is truncated, if necessary, by removing the oldest entries, to contain no more than @@ -928,21 +912,21 @@ interactive shell exits. ### HISTIGNORE - Variable: `HISTIGNORE` Since: 2.0 - -------------- ----------------- ------------ ----- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`HISTIGNORE` |Since: |2.0| +| -------------- |----------------- |------------ |-----| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| A colon-separated list of patterns used to decide which command lines should be saved on the history list. Each pattern is anchored at the beginning of the line and must match the complete line (no implicit -\'\*\' is appended). +'`*`' is appended). Each pattern is tested against the line after the checks specified by `HISTCONTROL` are applied. -In addition to the normal shell pattern matching characters, \"&\" -matches the previous history line. \"&\" may be escaped using a +In addition to the normal shell pattern matching characters, "&" +matches the previous history line. "&" may be escaped using a backslash; the backslash is removed before attempting a match. The second and subsequent lines of a multi-line compound command are not @@ -951,10 +935,10 @@ tested, and are added to the history regardless of the value of ### HISTSIZE - Variable: `HISTSIZE` Since: unknown - -------------- ----------------- ------------ ----------------------------------- - Type: normal variable Read-only: no - Set by Bash: if unset Default: set at compile time (default 500) +| Variable: |`HISTSIZE` |Since: |unknown| +| -------------- |----------------- |------------ |-----------------------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: |set at compile time (default 500)| The number of commands to remember in the command history. @@ -964,10 +948,10 @@ unlimited. ### HISTTIMEFORMAT - Variable: `HISTTIMEFORMAT` Since: unknown - -------------- ------------------ ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`HISTTIMEFORMAT` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If this variable is set and not null, its value is used as a format string for `strftime(3)` to print the time stamp associated with each @@ -979,10 +963,10 @@ comment character to distinguish timestamps from other history lines. ### HOME - Variable: `HOME` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`HOME` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The home directory of the current user. @@ -993,10 +977,10 @@ expansion](../syntax/expansion/tilde.md). ### HOSTFILE - Variable: `HOSTFILE` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`HOSTFILE` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| Contains the name of a file in the same format as `/etc/hosts` that should be read when the shell needs to complete a hostname. @@ -1014,20 +998,20 @@ When `HOSTFILE` is unset, the hostname list is cleared. ### IFS - Variable: `IFS` Since: unknown - -------------- ----------------- ------------ ------------------------- - Type: normal variable Read-only: no - Set by Bash: no Default: `` +| Variable: |`IFS` |Since: |unknown| +| -------------- |----------------- |------------ |-------------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |``| -The Internal Field Separator that is used for word splitting after +The Internal Field Separator |that is used for word splitting after| expansion and to split lines into words with the read builtin command. ### IGNOREEOF - Variable: `IGNOREEOF` Since: unknown - -------------- ----------------- ------------ ------------------- - Type: normal variable Read-only: no - Set by Bash: no Default: 10 (when invalid) +| Variable: |`IGNOREEOF` |Since: |unknown| +| -------------- |----------------- |------------ |-------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |10 (when invalid)| Controls the action of an interactive shell on receipt of an `EOF` character (e.g. by Ctrl-D) as the sole input. @@ -1042,40 +1026,40 @@ If it does not exist, `EOF` signifies the end of input to the shell. ### INPUTRC - Variable: `INPUTRC` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`INPUTRC` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The filename for the readline startup file, overriding the default of `~/.inputrc`. ### LANG - Variable: `LANG` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`LANG` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| Used to determine the locale category for any category not specifically selected with a variable starting with `LC_`. ### LC_ALL - Variable: `LC_ALL` Since: unknown +| Variable: |`LC_ALL` |Since: |unknown| -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| This variable overrides the value of `LANG` and any other `LC_` variable specifying a locale category. ### LC_COLLATE - Variable: `LC_COLLATE` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`LC_COLLATE` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| This variable determines the collation order used when sorting the results of pathname expansion, and determines the behavior of range @@ -1084,10 +1068,10 @@ pathname expansion and pattern matching. ### LC_CTYPE - Variable: `LC_CTYPE` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`LC_CTYPE` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| This variable determines the interpretation of characters and the behavior of character classes within pathname expansion and pattern @@ -1095,29 +1079,29 @@ matching. ### LC_MESSAGES - Variable: `LC_MESSAGES` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`LC_MESSAGES` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| This variable determines the locale used to translate double- quoted strings preceded by a `$`. ### LC_NUMERIC - Variable: `LC_NUMERIC` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`LC_NUMERIC` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| This variable determines the locale category used for number formatting. ### LINES - Variable: `LINES` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: on `SIGWINCH` Default: n/a +| Variable: |`LINES` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |on `|SIGWINCH` Default: |n/a| Used by the select compound command to determine the column length for printing selection lists. Automatically set upon receipt of a @@ -1125,10 +1109,10 @@ printing selection lists. Automatically set upon receipt of a ### MAIL - Variable: `MAIL` Since: unknown - -------------- ----------------- ------------ ------------------ - Type: normal variable Read-only: no - Set by Bash: no Default: system-dependent +| Variable: |`MAIL` |Since: |unknown| +| -------------- |----------------- |------------ |------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |system-dependent| If this parameter is set to a file or directory name and the `MAILPATH` variable is not set, Bash informs the user of the arrival of mail in the @@ -1136,12 +1120,12 @@ specified file or Maildir-format direc‐ tory. ### MAILCHECK - Variable: `MAILCHECK` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: 60 +| Variable: |`MAILCHECK` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |60| -Specifies how often (in seconds) Bash checks for mail. +Specifies |how often (in seconds) Bash checks for mail.| When it is time to check for mail, the shell does so before displaying the primary prompt. @@ -1151,15 +1135,15 @@ greater than or equal to zero, the shell disables mail checking. ### MAILPATH - Variable: `MAILPATH` Since: unknown - -------------- ----------------- ------------ ------------------ - Type: normal variable Read-only: no - Set by Bash: no Default: system-dependent +| Variable: |`MAILPATH` |Since: |unknown| +| -------------- |----------------- |------------ |------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |system-dependent| A colon-separated list of file names to be checked for mail. The message to be printed when mail arrives in a particular file may be -specified by separating the file name from the message with a \'?\' +specified by separating the file name from the message with a '?' (question mark). When used in the text of the message, `$_` expands to the name of the @@ -1171,10 +1155,10 @@ Example content: ### OPTERR - Variable: `OPTERR` Since: unknown - -------------- ----------------- ------------ -------------------- - Type: normal variable Read-only: no - Set by Bash: yes Default: 1 (set on startup) +| Variable: |`OPTERR` |Since: |unknown| +| -------------- |----------------- |------------ |--------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |1 (set on startup)| If set to the value 1, Bash displays error messages generated by the `getopts` builtin command. @@ -1184,10 +1168,10 @@ script is executed. ### PATH - Variable: `PATH` Since: unknown - -------------- ----------------- ------------ ---------------------------------------- - Type: normal variable Read-only: no - Set by Bash: no Default: system-dependent (set on compile time) +| Variable: |`PATH` |Since: |unknown| +| -------------- |----------------- |------------ |----------------------------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |system-dependent (set on compile time)| The search path for commands. This is a colon-separated list of directories in which the shell looks for commands. @@ -1202,10 +1186,10 @@ There can be a static path compiled in for use in a restricted shell. ### POSIXLY_CORRECT - Variable: `POSIXLY_CORRECT` Since: unknown - -------------- ------------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`POSIXLY_CORRECT` |Since: |unknown| +| -------------- |------------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If this variable is in the environment when Bash starts, the shell enters posix mode before reading the startup files, as if the `--posix` @@ -1216,30 +1200,30 @@ the command `set -o posix` had been executed. ### PROMPT_COMMAND - Variable: `PROMPT_COMMAND` Since: unknown - -------------- ------------------ ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`PROMPT_COMMAND` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set, the value is executed as a command prior to issuing each primary prompt. ### PROMPT_COMMANDS - Variable: `PROMPT_COMMANDS` Since: 5.1-alpha - -------------- ----------------------- ------------ ----------- - Type: integer indexed array Read-only: no - Set by Bash: no Default: n/a +| Variable: |`PROMPT_COMMANDS` |Since: |5.1-alpha| +| -------------- |----------------------- |------------ |-----------| +| Type: |integer indexed array |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set, each element is executed as a command prior to issuing each primary prompt (like `PROMPT_COMMAND`, just as array). ### PROMPT_DIRTRIM - Variable: `PROMPT_DIRTRIM` Since: unknown - -------------- ------------------ ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`PROMPT_DIRTRIM` |Since: |unknown| +| -------------- |------------------ |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set to a number greater than zero, the value is used as the number of trailing directory components to retain when expanding the `\w` and `\W` @@ -1249,63 +1233,63 @@ Characters removed are replaced with an ellipsis. ### PS0 - Variable: `PS0` Since: 4.4.0 - -------------- ----------------- ------------ -------------- - Type: normal variable Read-only: no - Set by Bash: if unset Default: \"\'\'\'\'\" +| Variable: |`PS0` |Since: |4.4.0| +| -------------- |----------------- |------------ |--------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: |\"\'\'\'\'\"| -Expanded and displayed by interactive shells after reading a complete +Expanded |and displayed by interactive shells after reading a complete| command but before executing it. ### PS1 - Variable: `PS1` Since: unknown - -------------- ----------------- ------------ -------------------------- - Type: normal variable Read-only: no - Set by Bash: if unset Default: \"\'\'\\s-\\v\\\$ \'\'\" +| Variable: |`PS1` |Since: |unknown| +| -------------- |----------------- |------------ |--------------------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: |\"\'\'\\s-\\v\\\$ \'\'\"| -The value of this parameter is expanded and used as the primary prompt +The |value of this parameter is expanded and used as the primary prompt| string. See [Controlling the Prompt](https://www.gnu.org/software/bash/manual/bash.html#Controlling-the-Prompt). ### PS2 - Variable: `PS2` Since: unknown - -------------- ----------------- ------------ ----------------- - Type: normal variable Read-only: no - Set by Bash: if unset Default: \"\'\'> \'\'\" +| Variable: |`PS2` |Since: |unknown| +| -------------- |----------------- |------------ |-----------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: |\"\'\'> \'\'\"| -The value of this parameter is expanded as with PS1 and used as the +The |value of this parameter is expanded as with PS1 and used as the| secondary prompt string. ### PS3 - Variable: `PS3` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`PS3` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The value of this parameter is used as the prompt for the select command. ### PS4 - Variable: `PS4` Since: unknown - -------------- ----------------- ------------ ---------------- - Type: normal variable Read-only: no - Set by Bash: if unset Default: \"\'\'+ \'\'\" +| Variable: |`PS4` |Since: |unknown| +| -------------- |----------------- |------------ |----------------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |if unset |Default: \"\'\'+ \'\'\" -The value of this parameter is expanded as with `PS1` and the value is +The |value of this parameter is expanded as with `PS1` and the value is| printed before each command Bash displays during an execution trace. The first character of `PS4` is replicated multiple times, as necessary, to indicate multiple levels of indirection. ### SHELL - Variable: `SHELL` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`SHELL` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The full pathname to the shell is kept in this environment variable. If it is not set when the shell starts, Bash assigns the full pathname of @@ -1313,10 +1297,10 @@ the current user's login shell. ### SRANDOM - Variable: `SRANDOM` Since: 5.1-alpha - -------------- ----------------- ------------ ----------- - Type: normal variable Read-only: no - Set by Bash: yes Default: n/a +| Variable: |`SRANDOM` |Since: |5.1-alpha| +| -------------- |----------------- |------------ |-----------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |yes |Default: |n/a| A variable that delivers a 32bit random number. The random number generation uses platform specific generators in the background and a @@ -1324,10 +1308,10 @@ builtin fallback generator. ### TIMEFORMAT - Variable: `TIMEFORMAT` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`TIMEFORMAT` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The value of this parameter is used as a format string specifying how the timing information for pipelines prefixed with the time reserved @@ -1337,20 +1321,20 @@ The % character introduces an escape sequence that is expanded to a time value or other information. The escape sequences and their meanings are as follows, the braces denote optional portions: - ------------ ---------------------------------------------- - `%%` a literal `%` (percent sign) - `%[p][l]R` elapsed time in seconds - `%[p][l]U` number of CPU seconds spent in user mode - `%[p][l]S` number of CPU seconds spent in system mode - `%P` CPU percentage, computed as `(%U + %S) / %R` - ------------ ---------------------------------------------- +| | | +|:-----------|:---------------------------------------------| +| `%%` | a literal `%` (percent sign) | +| `%[p][l]R` | elapsed time in seconds | +| `%[p][l]U` | number of CPU seconds spent in user mode | +| `%[p][l]S` | number of CPU seconds spent in system mode | +| `%P` | CPU percentage, computed as `(%U + %S) / %R` | The optional modifiers (p and l) are: - ----- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - `p` A digit specifying the precision. A value of 0 causes no decimal point or fraction to be output. At most three digits after the decimal point are shown. If not specified, the value 3 is used. - `l` A longer format, including minutes, of the form MMmSS.FFs. The value of p determines whether or not the fraction is included. - ----- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| | | +|--|--| +| `p` | A digit specifying the precision. A value of 0 causes no decimal point or fraction to be output. At most three digits after the decimal point are shown. If not specified, the value 3 is used. | +| `l` | A longer format, including minutes, of the form MMmSS.FFs. The value of p determines whether or not the fraction is included. | If this variable is not set, Bash acts as if it had the value @@ -1362,10 +1346,10 @@ A trailing newline is added when the format string is displayed. ### TMOUT - Variable: `TMOUT` Since: 2.05b - -------------- ----------------- ------------ ------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`TMOUT` |Since: |2.05b| +| -------------- |----------------- |------------ |-------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set to a value greater than zero, `TMOUT` is treated as the default timeout for the [read builtin command](../commands/builtin/read.md). @@ -1380,20 +1364,20 @@ arrive. ### TMPDIR - Variable: `TMPDIR` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`TMPDIR` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| If set, Bash uses its value as the name of a directory in which Bash creates temporary files for the shell's use. ### auto_resume - Variable: `auto_resume` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`auto_resume` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| This variable controls how the shell interacts with the user and job control. If this variable is set, single word simple commands without @@ -1413,25 +1397,25 @@ stopped job's name; this provides functionality analogous to the ### histchars - Variable: `histchars` Since: unknown - -------------- ----------------- ------------ --------- - Type: normal variable Read-only: no - Set by Bash: no Default: n/a +| Variable: |`histchars` |Since: |unknown| +| -------------- |----------------- |------------ |---------| +| Type: |normal variable |Read-only: |no| +| Set by Bash: |no |Default: |n/a| The two or three characters which control history expansion and tokenization. The first character is the history expansion character, the character -which signals the start of a history expansion, normally \'!\' +which signals the start of a history expansion, normally '!' (exlamation mark). The second character is the quick substitution character, which is used as shorthand for re-running the previous command entered, substi tuting -one string for another in the command. The default is \'\^\' (carret). +one string for another in the command. The default is '^' (carret). The optional third character is the character which indicates that the remainder of the line is a comment when found as the first character of -a word, normally \'#\' (hash mark). The history comment character causes +a word, normally '#' (hash mark). The history comment character causes history substitution to be skipped for the remaining words on the line. It does not necessarily cause the shell parser to treat the rest of the line as a comment. diff --git a/docs/syntax/words.md b/docs/syntax/words.md index 1cbde31..c9ff16a 100644 --- a/docs/syntax/words.md +++ b/docs/syntax/words.md @@ -10,12 +10,13 @@ tags: - recognition --- -# Words\... +# Words... -FIXME This article needs a review, it covers two topics (command line -splitting and word splitting) and mixes both a bit too much. But in -general, it's still usable to help understand this behaviour, it's -\"wrong but not wrong\". +!!! warning "FIXME" + This article needs a review, it covers two topics (command line + splitting and word splitting) and mixes both a bit too much. But in + general, it's still usable to help understand this behaviour, it's + "wrong but not wrong". One fundamental principle of Bash is to recognize words entered at the command prompt, or under other circumstances like variable-expansion. @@ -32,7 +33,7 @@ by a space. When you enter an echo command at the Bash prompt, Bash will look for those special characters, and use them to separate the parameters. -You don't know what I\'m talking about? I\'m talking about this: +You don't know what I'm talking about? I'm talking about this: $ echo Hello little world Hello little world @@ -48,9 +49,9 @@ blank characters is treated as a single blank.** Here's an example: Bash splits the command line at the blanks into words, then it calls echo with **each word as an argument**. In this example, echo is called -with three arguments: \"`Hello`\", \"`little`\" and \"`world`\"! +with three arguments: "`Hello`", "`little`" and "`world`"! -[Does that mean we can't echo more than one Space?]{.underline} Of +Does that mean we can't echo more than one Space? Of course not! Bash treats blanks as special characters, but there are two ways to tell Bash not to treat them special: **Escaping** and **quoting**. @@ -63,9 +64,9 @@ Escaping is done by preceeding the character with a backslash: Hello little world None of the escaped spaces will be used to perform word splitting. Thus, -echo is called with one argument: \"`Hello little world`\". +echo is called with one argument: "`Hello little world`". -Bash has a mechanism to \"escape\" an entire string: **Quoting**. In the +Bash has a mechanism to "escape" an entire string: **Quoting**. In the context of command-splitting, which this section is about, it doesn't matter which kind of quoting you use: weak quoting or strong quoting, both cause Bash to not treat spaces as special characters: @@ -76,7 +77,7 @@ both cause Bash to not treat spaces as special characters: $ echo 'Hello little world' Hello little world -[What is it all about now?]{.underline} Well, for example imagine a +What is it all about now? Well, for example imagine a program that expects a filename as an argument, like cat. Filenames can have spaces in them: @@ -141,41 +142,37 @@ and the first review is: echo The file is named $MYFILE -The parser will scan for blanks and mark the relevant words (\"splitting -the command line\"): +The parser will scan for blanks and mark the relevant words ("splitting +the command line"): - Initial command line splitting: - --------------------------------- -------- -------- -------- --------- ----------- - Word 1 Word 2 Word 3 Word 4 Word 5 Word 6 - `echo` `The` `file` `is` `named` `$MYFILE` +| Initial command line splitting: | | | | | | +|---------------------------------|--------|--------|--------|---------|-----------| +| Word 1 | Word 2 | Word 3 | Word 4 | Word 5 | Word 6 | +| `echo` | `The` | `file` | `is` | `named` | `$MYFILE` | A [parameter/variable expansion](../syntax/pe.md) is part of that command line, Bash will perform the substitution, and the [word splitting](../syntax/expansion/wordsplit.md) on the results: - Word splitting after substitution: - ------------------------------------ -------- -------- -------- --------- -------- ------------ - Word 1 Word 2 Word 3 Word 4 Word 5 Word 6 Word 7 - `echo` `The` `file` `is` `named` `THE` `FILE.TXT` +| Word splitting after substitution: | | | | | | | +|------------------------------------|--------|--------|--------|---------|--------|------------| +| Word 1 | Word 2 | Word 3 | Word 4 | Word 5 | Word 6 | Word 7 | +| `echo` | `The` | `file` | `is` | `named` | `THE` | `FILE.TXT` | Now let's imagine we quoted `$MYFILE`, the command line now looks like: echo The file is named "$MYFILE" - Word splitting after substitution (quoted!): - ---------------------------------------------- -------- -------- -------- --------- ---------------- - Word 1 Word 2 Word 3 Word 4 Word 5 Word 6 - `echo` `The` `file` `is` `named` `THE FILE.TXT` +| Word splitting after substitution (quoted!): | | | | | | +|----------------------------------------------|--------|--------|--------|---------|----------------| +| Word 1 | Word 2 | Word 3 | Word 4 | Word 5 | Word 6 | +| `echo` | `The` | `file` | `is` | `named` | `THE FILE.TXT` | -***Bold Text*72i love this world**===== See also ===== +# See also - Internal: [Quoting and character escaping](../syntax/quoting.md) - Internal: [Word splitting](../syntax/expansion/wordsplit.md) - Internal: [Introduction to expansions and substitutions](../syntax/expansion/intro.md) - -```{=html} - -``` - External: [Grymore: Shellquoting](http://www.grymoire.com/Unix/Quote.html)