Convert all builtin commands to Markdown

This commit is contained in:
flokoe 2023-07-05 10:53:12 +02:00
parent f79b5314b2
commit 1406408dff
22 changed files with 2576 additions and 0 deletions

View File

@ -0,0 +1,82 @@
# The caller builtin command
## Synopsis
caller [FRAMENUMBER]
## Description
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
filename.
When an execution frame number is given (0 - topmost), the linenumber,
the subroutine (function) and the filename is printed. When an invalid
execution frame number is given, it exists `FALSE`. This way it can be
used in a loop (see the examples section below).
## Examples
### Simple stack trace
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\".
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.
``` bash
#!/bin/bash
die() {
local frame=0
while caller $frame; do
((++frame));
done
echo "$*"
exit 1
}
f1() { die "*** an error occured ***"; }
f2() { f1; }
f3() { f2; }
f3
```
**Output**
12 f1 ./callertest.sh
13 f2 ./callertest.sh
14 f3 ./callertest.sh
16 main ./callertest.sh
*** an error occured ***
## Notes
- `caller` produces no output unless used within a script that\'s run
from a real file. It isn\'t particularly useful for interactive use,
but can be used to create a decent `die` function to track down
errors in moderately complex scripts.
`{ bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'`
- For more sophisticated debugging, Bash extended debugging features
are available and a number of special parameters that give more
detail than caller (e.g. BASH_ARG{C,V}). Tools such as
[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
actually allowed, with no special interpretation of an
\"expression\" as far as we can tell.
## Portability considerations
- `caller` is not specified by POSIX(R)
- the `caller` builtin command appeared in Bash version 3.0
## See also

View File

@ -0,0 +1,59 @@
# The cd builtin command
## Synopsis
cd [-L|-P] [DIRECTORY]
cd -
## Description
The `cd` builtin command is used to change the current working directory
- to the given directory (`cd DIRECTORY`)
- to the previous working directory (`cd -`) as saved in the
[OLDPWD](/syntax/shellvars#OLDPWD) shell variable
- to the user\'s home directory as specified in the
[HOME](/syntax/shellvars#HOME) environment variable (when used
without a `DIRECTORY` argument)
The `cd` builtin command searches the directories listed in
[CDPATH](/syntax/shellvars#CDPATH) for a matching directory.
The default behaviour is to follow symbolic links unless the `-P` option
is given or the shell is configured to do so (see the `-P` option of
[the set builtin command](/commands/builtin/set)).
### Options
Option Description
-------- ----------------------------------------------------
`-L` Follow symbolic links (default)
`-P` Do not follow symbolic links
`-@` Browse a file\'s extended attributed, if supported
### Exit status
- true if the directory was changed successfully
- false if a change to the home directory was requested, but
[HOME](/syntax/shellvars#HOME) is unset
- false if anything else goes wrong
## Examples
### Change the working directory to the user\'s home directory
cd
### Change the working directory to the previous directory
cd -
## Portability considerations
## See also
- variable [CDPATH](/syntax/shellvars#CDPATH)
- variable [HOME](/syntax/shellvars#HOME)
- variable [OLDPWD](/syntax/shellvars#OLDPWD)
- the `-P` option of [the set builtin command](/commands/builtin/set)

View File

@ -0,0 +1,184 @@
# The declare builtin command
## Synopsis
declare [-aAfFgilnrtux] [-p] [NAME[=VALUE] ...]
# obsolete typeset synonym
typeset [-aAfFgilnrtux] [-p] [NAME[=VALUE] ...]
## Description
`declare` is used to display or set variables along with variable
attributes. When used to display variables/functions and their value,
the output is re-usable as input for the shell.
If no `NAME` is given, it displays the values of all variables or
functions when restricted by the `-f` option.
If `NAME` is followed by `=VALUE`, `declare` also sets the value for a
variable.
When used in a function, `declare` makes `NAMEs` local variables, unless
used with the `-g` option.
Don\'t use it\'s synonym `typeset` when coding for Bash, since it\'s
tagged as obsolete.
### Options
Below, `[-+]X` indicates an attribute, use `-X` to set the attribute,
`+X` to remove it.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Option Description
--------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------
`[-+]a` make NAMEs indexed arrays (removing with `+a` is valid syntax, but leads to an error message)
`[-+]A` make NAMEs associative arrays
`[-+]c` **Undocumented** convert NAMEs to \"capcase\" on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with `-DCASEMOD_CAPCASE`
`-f` restrict action or display to function names and definitions (removing with `+f` is valid syntax, but leads to an error message)
`-F` restrict display to function names only (plus line number and source file when debugging)
`-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
`[-+]l` convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters)
`[-+]n` make NAME a reference to the variable named by its value. Introduced in Bash 4.3-alpha.\
\'\' \${!NAME}\'\' reveals the reference variable name, VALUE.\
Use `unset -n NAME` to unset the variable. (`unset -v NAME` unsets the VALUE variable.)\
Use `[[ -R NAME ]]` to test if NAME has been set to a VALUE, another variable\'s name.
`-p` display the attributes and value of each NAME
`[-+]r` make NAMEs readonly (removing with `+r` is valid syntax, but not possible)
`[-+]t` make NAMEs have the \"trace\" attribute (effective only for functions)
`[-+]u` convert NAMEs to upper case on assignment (makes sure the variable contains only upper case letters)
`[-+]x` make NAMEs exported
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Return status
Status Reason
-------- ----------------------------------------------------------------------------------------
0 no error
!= 0 invalid option
!= 0 invalid variable name given
!= 0 attempt to **define** a function using `-f`
!= 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 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
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
assignment.
## Examples
### Display defined functions
`declare -f` can be used to display all defined functions\...
$ declare -f
foo ()
{
echo "FOO is BAR"
}
world ()
{
echo "Hello World!"
}
\...or just a specific defined function.
$ declare -f foo
foo ()
{
echo "FOO is BAR"
}
### Nameref
Bash 4.3 adds a new way to indirectly reference variables. `typeset -n`
or `declare -n` can be used to make a variable indirectly refer to
another. In Bash, the lvalue of the assignment given to `typeset -n` or
`declare -n` will refer to the variable whose name is expanded on the
RHS.
`typeset -n` is used in the example below. See notes below.
# Sum a set of arrays and assign the result indirectly, also printing each intermediary result (without portability workarounds)
# sum name arrname [ arrname ... ]
function sum {
typeset -n _result=$1 _arr
typeset IFS=+
_result=0
for _arr in "${@:2}"; do # Demonstrate the special property of "for" on a nameref.
(( _result += ${_arr[*]} ))
printf '%s = %d\n' "${!_result}" "$_result" # Demonstrate the special property of ${!ref} on a nameref.
done
}
a=(1 2 3) b=(6 5 4) c=(2 4 6)
sum total a b c
printf 'Final value of "total" is: %d\n' "$total"
\<div hide\> function sum {
typeset -n _result=$1
shift
typeset IFS=+ _arrx
_result=0
for _arrx in "$@"; do # Demonstrate the special property of "for" on a nameref.
typeset -n _arr=$_arrx
(( _result += ${_arr[*]} ))
printf '%s = %d\n' "${!_result}" "$_result" # Demonstrate the special property of ${!ref} on a nameref.
done
}
a=(1 2 3); b=(6 5 4); c=(2 4 6) sum total a b c printf \'Final value of
\"total\" is: %d\\n\' \"\$total\" \</div\>
`typeset -n` is currently implemented in ksh93, mksh, and Bash 4.3. Bash
and mksh\'s implementations are quite similar, but much different from
ksh93\'s. See [Portability considerations](#portability_considerations)
for details. ksh93 namerefs are much more powerful than Bash\'s.
## Portability considerations
- `declare` is not specified by POSIX(r)
- `declare` is unique to Bash and totally non-portable with the
possible exception of Zsh in Bash compatibility mode. Bash marks the
synonym `typeset` as obsolete, which in Bash behaves identically to
`declare`. All other Korn-like shells use `typeset`, so it probably
isn\'t going away any time soon. Unfortunately, being a non-standard
builtin, `typeset` differs significantly between shells. ksh93 also
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\...
## See also
- [arrays](/syntax/arrays)
- [readonly](/commands/builtin/readonly)
- [unset](/commands/builtin/unset)
- [declaration commands](http://austingroupbugs.net/view.php?id=351)
will change the behavior of certain builtins such as `export` in the
next version of POSIX.

View File

@ -0,0 +1,92 @@
# The echo builtin command
## Synopsis
echo [-neE] [arg ...]
## Description
`echo` outputs it\'s args to stdout, separated by spaces, followed by a
newline. The return status is always `0`. If the
[shopt](/commands/builtin/shopt) option `xpg_echo` is set, Bash
dynamically determines whether echo should expand escape characters
(listed below) by default based on the current platform. `echo` doesn\'t
interpret `--` as the end of options, and will simply print this string
if given.
### Options
Option Description
-------- ----------------------------------------------------------------------------------------------------------------
`-n` The trailing newline is suppressed.
`-e` Interpretation of the following backslash-escaped characters (below) is enabled.
`-E` Disables the interpretation of these escape characters, even on systems where they are interpreted by default.
### Escape sequences
Escape Description
-------------- ---------------------------------------------------------------------------------------------------------------
`\a` alert (bell)
`\b` backspace
`\c` suppress further output
`\e`
`\E` an escape character
`\f` form feed
`\n` new line
`\r` carriage return
`\t` horizontal tab
`\v` vertical tab
`\\` backslash
`\0nnn` the eight-bit character whose value is the octal value nnn (zero to three octal digits)
`\xHH` the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
`\uHHHH` the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
`\UHHHHHHHH` the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)
## Examples
## Portability considerations
- `echo` is a portability train wreck. No major shell follows POSIX
completely, and any shell that attempts to do so should be
considered horribly broken.
[SUSv4](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37)
specifies that `echo` **shall not** include any options. Further, it
specifies that the behavior of `-n` as a first argument shall be
determined by the implementation, unless XSI is followed, in which
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
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) instead!** If portability is a
requirement, you should consider using `printf` *exclusively* and
just ignore that `echo` even exists. If you must use `echo -e` and
refuse to use `printf`, it is usually acceptable to use \'\'echo
\$\'\...\' \'\'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) still includes most of the
functionality of both, and should usually be the most preferred
option.
## See also
- [printf](/commands/builtin/printf)
- <http://cfajohnson.com/shell/cus-faq.html#Q0b>
- <http://www.in-ulm.de/~mascheck/various/echo+printf/>

View File

@ -0,0 +1,174 @@
# The eval builtin command
## Synopsis
eval: eval [arg ...]
## Description
`eval` takes its arguments, concatenates them separated by spaces, and
executes the resulting string as Bash code in the current execution
environment. `eval` in Bash works in essentially the same way as most
other languages that have an `eval` function. Perhaps the easiest way to
think about `eval` is that it works in the same way as running \'\'bash
-c \"bash code\...\" \'\'from a script, except in the case of `eval`,
the given code is executed in the current shell environment rather than
a child process.
## Examples
In this example, the literal text within the
[here-document](/syntax/redirection#here_documents) is executed as Bash
code exactly as though it were to appear within the script in place of
the `eval` command below it.
#!/usr/bin/env bash
{ myCode=$(</dev/stdin); } <<\EOF
... arbitrary bash code here ...
EOF
eval "$myCode"
### Expansion side-effects
Frequently, `eval` is used to cause side-effects by performing a pass of
expansion on the code before executing the resulting string. This allows
for things that otherwise wouldn\'t be possible with ordinary Bash
syntax. This also, of course, makes `eval` the most powerful command in
all of shell programming (and in most other languages for that matter).
This code defines a set of identical functions using the supplied names.
`eval` is the only way to achieve this effect.
main() {
local fun='() { echo "$FUNCNAME"; }' x
for x in {f..n}; do
eval "${x}${fun}"
done
"$@"
}
main "$@"
### 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
through printf requiring another `eval` to peel off the escaping again.
while (( ++n <= 5 )) || ! evalBall="eval $evalBall"; do
printf -v evalBall 'eval %q' "printf $n;${evalBall-printf '0\n'}"
done
$evalBall
The above example is mostly fun and games but illustrates the
`printf %q` property.
### Higher-order functions
Since all current POSIX-compatible shells lack support for [first-class
functions](http://en.wikipedia.org/wiki/First-class_function), it can be
tempting and sometimes useful to simulate some of their effect using
`eval` to evaluate a string containing code.
This example shows [partial
application](http://en.wikipedia.org/wiki/Partial_application) using
`eval`.
function partial {
eval shift 2 \; function "$1" \{ "$2" "$(printf '%q ' "${@:3}")" '"$@"; }'
}
function repeat {
[[ $1 == +([0-9]) ]] || return
typeset n
while ((n++ < $1)); do
"${@:2}"
done
}
partial print3 repeat 3 printf '%s ' # Create a new function named print3
print3 hi # Print "hi" 3 times
echo
This is very easy to do incorrectly and not usually considered idiomatic
of Bash if used extensively. However abstracting eval behind functions
that validate their input and/or make clear which input must be
controlled carefully by the caller is a good way to use it.
## Portability considerations
- Unfortunately, because eval is a **special builtin**, it only gets
its own environment in Bash, and only when Bash is not in POSIX
mode. In all other shells plus Bash in POSIX mode, the environment
of eval will leak out into the surrounding environment. It is
possible to work around this limitation by prefixing special
builtins with the `command` regular builtin, but current versions of
~~ksh93~~ and zsh don\'t do this properly
([fixed](http://article.gmane.org/gmane.comp.programming.tools.ast.devel/686)
in ksh 93v- 2012-10-24 alpha). Earlier versions of zsh work (with
`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.
<a> <b c> <d>
$ ( 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.
-bash: syntax error near unexpected token `('
$ ( x=a; eval "$x"'=( a b\ c d )'; printf '<%s> ' "${a[@]}"; echo ) # Proper quoting then gives us the expected results.
<a> <b c> <d>
We don\'t know why Bash does this. Since parentheses are metacharacters,
they must ordinary be quoted or escaped when used as arguments. The
first example above is the same error as the second in all non-Bash
shells, even those with compound assignment.
In the case of `eval` it isn\'t recommended to use this behavior,
because unlike e.g. [declare](commands/builtin/declare), the initial
expansion is still subject to all expansions including
[word-splitting](syntax/expansion/wordsplit) and [pathname
expansion](syntax/expansion/glob).
$ ( set -x; touch 'x+=(\[[123]\]=*)' 'x+=([3]=yo)'; eval x+=(*); echo "${x[@]}" )
+ touch 'x+=(\[[123]\]=*)' 'x+=([3]=yo)'
+ eval 'x+=(\[[123]\]=*)' 'x+=([3]=yo)'
++ x+=(\[[123]\]=*)
++ x+=([3]=yo)
+ echo '[[123]]=*' yo
[[123]]=* yo
Other commands known to be affected by compound assignment arguments
include: [let](commands/builtin/let),
[declare](commands/builtin/declare),
[typeset](commands/builtin/typeset), [local](commands/builtin/local),
[export](commands/builtin/export), and
[readonly](commands/builtin/readonly). More oddities below show both
similarities and differences to commands like
[declare](commands/builtin/declare). The rules for `eval` appear
identical to those of [let](commands/builtin/let).
## See also
- [BashFAQ 48 - eval and security
issues](http://mywiki.wooledge.org/BashFAQ/048) \-- **IMPORTANT**
- [Another eval
article](http://fvue.nl/wiki/Bash:_Why_use_eval_with_variable_expansion%3F)
- [Indirection via
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) \--
`printf %q` work-alike for POSIX.
- [The \"magic alias\"
hack](http://www.chiark.greenend.org.uk/~sgtatham/aliases.html)

View File

@ -0,0 +1,85 @@
# The exec builtin command
## Synopsis
exec [-a NAME] [-cl] [COMMAND] [ARG...] [REDIRECTION...]
## Description
The `exec` builtin command is used to
- **replace** the shell with a given program (executing it, **not as
new process**)
- set redirections for the program to execute or for the current shell
If only redirections are given, the redirections affect the current
shell without executing any program.
### Options
Option Description
----------- ----------------------------------------------------------------------------------------------------------------------
`-a NAME` Passes `NAME` as zeroth argument for the program to be executed
`-c` Execute the program with an empty (cleared) environment
`-l` Prepends a dash (`-`) to the zeroth argument of the program to be executed, similar to what the `login` program does
### Exit status
- on redirection errors it returns 1, otherwise 0
- on exec failures:
- a non-interactive shell terminates; if the [shell option
execfail](/internals/shell_options#execfail) is set `exec`
returns failure
- in an interactive shell, `exec` returns failure
## Examples
### Wrapper around a program
``` bash
myprog=/bin/ls
echo "This is the wrapper script, it will exec $myprog"
# do some vodoo here, probably change the arguments etc.
# well, stuff a wrapper is there for
exec "$myprog" "$@"
```
### Open a file as input for the script
``` bash
# open it
exec 3< input.txt
# for example: read one line from the file(-descriptor)
read -u 3 LINE
# or
read LINE <&3
# finally, close it
exec 3<&-
```
### Overall script logfile
To redirect the whole `stdout` and `stderr` of the shell or shellscript
to a file, you can use the `exec` builtin command:
``` bash
exec >/var/adm/my.log 2>&1
# script continues here...
```
## Portability considerations
*POSIX(r) specifies error code ranges:
* if ''exec'' can't find the program to execute, the error code shall be 126
* on a redirection error, the error code shall be between 1 and 125
* the ''-a NAME'' option appeared in Bash 4.2-alpha
* POSIX(r) does **not** specify any options for ''exec'' (like ''-c'', ''-l'', ''-a NAME'').
## See also
- [redirection](/syntax/redirection)

View File

@ -0,0 +1,46 @@
# The exit builtin command
## Synopsis
exit [N]
## Description
The `exit` command terminates the current shell (or script).
If `N` is given, the return code to the parent process is set to `N`. If
not, the returned status the the status of the most recently executed
command (i.e. `$?`).
A [trap](/commands/builtin/trap) on `EXIT` is executed before the shell
exits, except the executed `exit` command is part of an already running
trap.
### Options
There are no options.
### Exit status
Naturally, you can\'t ask for the exit status from within the shell that
executed the `exit` command, because the shell exits.
Status Reason
-------- ----------------------------------------------------------------------------
255 invalid (e.g. non-numeric) argument - this staus is returned to the parent
## Examples
### Exit the shell and explicitely set its exit status
exit 3
## Portability considerations
- if `N` is specified, but its value is not between 0 and 255
inclusively, the exit status is undefined.
## See also
- [The trap builtin command](/commands/builtin/trap)
- [The exit status](/dict/terms/exit_status)

View File

@ -0,0 +1,52 @@
# The export builtin command
## Synopsis
export [-fn] [NAME[=VALUE] ...]
export -p
## Description
The `export` builtin command is used to mark variables or functions
referenced by `NAME` for automatic export to the environment. If `NAME`
is a shell variable, a value `VALUE` can be assigned before exporting
it.
### Options
Option Description
-------- ------------------------------------------------------------------------------------------------------------
`-f` refer to shell functions
`-n` remove the export property from any referenced `NAME`
`-p` print all exported variables, with `-f`, print all exported functions - all in a format re-usable as input
An argument of `--` disables further option processing.
### Return status
Status Reason
-------- ---------------------------
0 no error
!=0 invalid option
!=0 a given `NAME` is invalid
## Examples
Set the display to use when launching a GUI application (useful during
SSH sessions):
export DISPLAY=":0"
Set your default text editor (e.g. SublimeText):
export EDITOR=subl
## Portability considerations
- in POSIX(r), only the `-p` option is specified
- in POSIX(r), only variables (with value assignment) are to be
exported, not shell functions
## See also
- [declare](/commands/builtin/declare)

View File

@ -0,0 +1,71 @@
# The kill builtin command
## Synopsis
kill [-s SIGNAL | -n SIGNALNUMBER | -SIGNAL] PID|JOB
kill -l|-L [SIGNAL...]
## Description
The `kill` command is used to send signals to processes specified by
their `PID` or their `JOB`-specification.
The signal(s) to be specified can have the following formats:
- Numerical: The signal is specified using its constant numeric value.
Be aware that not all systems have identical numbers for the
signals.
- Symbolic (long): The signal is specified using the same name that is
used for the constant/macro in the C API (`SIG<name>`)
- Symbolic (short): The signal is specified using the name from the C
API without the `SIG`-prefix (`<name>`)
Without any specified signal, the command sends the `SIGTERM`-signal.
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
limit is reached
### Options
Option Description
------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`-s SIGNAL` specifies the signal to send
`-n SIGNALNUMBER` specifies the signal to send
`-SIGNAL` specifies the signal to send
`-l [SIGNAL...]` Lists supported/known signal numbers and their symbolic name. If `SIGNAL` is given, only list this signal, translated (if a number is given the symbolic name is printed, and vice versa)
`-L [SIGNAL...]` Same as `-l [SIGNAL]` (compatiblity option)
### Return status
Status Reason
-------- -----------------------------------------------------------------------------------------------------
0 no error/success
!=0 invalid option
!=0 invalid signal specification
!=0 error returned by the system function (e.g. insufficient permissions to send to a specific process)
## Examples
### List supported signals
kill -l
### Send KILL to a process ID
kill -9 12345
kill -KILL 12345
kill -SIGKILL 12345
## Portability considerations
- POSIX(R) and ISO C only standardize symbolic signal names (no
numbers) and a default action
## See also

View File

@ -0,0 +1,111 @@
# The let builtin command
## Synopsis
let arg [arg ...]
## Description
The `let` builtin command evaluates each supplied word from left to
right as an [arithmetic expression](/syntax/arith_expr) 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\")
For this return code mapping, please see [this
section](/syntax/arith_expr#arithmetic_expressions_and_return_codes).
They work in the same way as `((`.
## Examples
`let` is very similar to [((](/syntax/ccmd/arithmetic_eval) - the only
difference being `let` is a builtin (simple command), and `((` is a
compound command. The arguments to `let` are therefore subject to all
the same expansions and substitutions as any other simple command -
requiring proper quoting and escaping - whereas the contents of `((`
aren\'t subject to [word-splitting](/syntax/expansion/wordsplit) or
[pathname expansion](/syntax/expansion/globs) (almost never desirable
for arithmetic). For this reason, **the [arithmetic compound
command](/syntax/ccmd/arithmetic_eval) should generally be preferred
over `let`**.
$ let 'b = a' "(a += 3) + $((a = 1)), b++"
$ echo "$a - $b - $?"
4 - 2 - 0
Is equivalent to the [arithmetic evaluation compound
command](/syntax/ccmd/arithmetic_eval):
$ (( b = a, (a += 3) + $((a = 1)), b++ ))
$ echo "$a - $b - $?"
4 - 2 - 0
\<WRAP info\> Remember that inside arithmetic evaluation contexts, all
other expansions are processed as usual (from left-to-right), and the
resulting text is evaluated as an arithmetic expression. Arithmetic
already has a way to control precedence using parentheses, so it\'s very
rare to need to nest arithmetic expansions within one another. It\'s
used above only to illustrate how this precedence works. \</WRAP\>
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
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
modified by the builtin.
~ $ ( y=1+1 let x=y; declare -p x y )
declare -- x="2"
bash: declare: y: not found
~ $ ( y=1+1 let x=y++; declare -p x y )
declare -- x="2"
declare -- y="3"
This can be useful in certain situations where a temporary variable is
needed.
## Portability considerations
- the `let` command is not specified by POSIX(r). The portable
alternative is: `[ "$(( <EXPRESSION> ))" -ne 0 ]`. To make portable
scripts simpler and cleaner, `let` can be defined as: `# POSIX
let() {
IFS=, command eval test '$(($*))' -ne 0
}
` Aside from differences in supported arithmetic features, this
should be identical to the Bash/Ksh `let`.
- It seems to be a common misunderstanding that `let` has some legacy
purpose. Both `let` and [[^1]](syntax/ccmd/arithmetic_eval) were
ksh88 features and almost identical in terms of portability as
everything that inherited one also tended to get the other. Don\'t
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
preferred. Both [arithmetic expansion](/syntax/arith_expr)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
bash variables but instead returns a result on stdout. `expr` takes
each operator it recognizes as a separate word and then concatenates
them into a single expression that\'s evaluated according to it\'s
own rules (which differ from shell arithmetic). `let` parses each
word it recieves on its own and evaluates it as an expression
without generating any output other than a return code.
- For unknown reasons, `let` is one of the Bash commands with special
parsing for arguments formatted like compound array assignments.
See: [eval](commands/builtin/eval#portability_considerations) for
details. There are no known practical uses for this. Parentheses are
treated as grouping operators and compound assignment is not
possible by arithmetic expressions.
## See also
- Internal: [arithmetic expansion](/syntax/expansion/arith)
- Internal: [arithmetic expressions](/syntax/arith_expr)
- Internal: [arithmetic evaluation compound
command](/syntax/ccmd/arithmetic_eval)
[^1]: \...

View File

@ -0,0 +1,57 @@
# The local builtin command
## Synopsis
local [option] name[=value] ...
## Description
`local` is identical to [declare](/commands/builtin/declare) in every
way, and takes all the same options, with 3 exceptions:
- Usage outside of a function is an error. Both `declare` and `local`
within a function have the same effect on variable scope, including
the -g option.
- `local` with no options prints variable names and values in the same
format as `declare` with no options, except the variables are
filtered to print only locals that were set in the same scope from
which `local` was called. Variables in parent scopes are not
printed.
- If name is '-', the set of shell options is made local to the
function in which local is invoked: shell options changed using the
set builtin inside the function are restored to their original
values when the function returns. The restore is effected as if a
series of set commands were executed to restore the values that were
in place before the function.
## Portability considerations
- `local` is not specified by POSIX. Most bourne-like shells don\'t
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`
within functions defined using ksh `function name {` syntax,
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
`namerefs`.
## See also
- <http://wiki.bash-hackers.org/scripting/basics#variable_scope>

View File

@ -0,0 +1,221 @@
# The mapfile builtin command
## Synopsis
mapfile [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-C CALLBACK] [-c QUANTUM] [ARRAY]
readarray [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-C CALLBACK] [-c QUANTUM] [ARRAY]
## Description
This builtin is also accessible using the command name `readarray`.
`mapfile` is one of the two builtin commands primarily intended for
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.
`mapfile` returns success (0) unless an invalid option is given or the
given array `ARRAY` is set readonly.
Option Description
--------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------
`-c QUANTUM` Specifies the number of lines that have to be read between every call to the callback specified with `-C`. The default QUANTUM is 5000
`-C CALLBACK` Specifies a callback. The string `CALLBACK` can be any shell code, the index of the array that will be assigned, and the line is appended at evaluation time.
`-n COUNT` Reads at most `COUNT` lines, then terminates. If `COUNT` is 0, then all lines are read (default).
`-O ORIGIN` Starts populating the given array `ARRAY` at the index `ORIGIN` rather than clearing it and starting at index 0.
`-s COUNT` Discards the first `COUNT` lines read.
`-t` Remove any trailing newline from a line read, before it is assigned to an array element.
`-u FD` Read from filedescriptor `FD` rather than standard input.
While `mapfile` isn\'t a common or portable shell feature, it\'s
functionality will be familiar to many programmers. Almost all
programming languages (aside from shells) with support for compound
datatypes like arrays, and which handle open file objects in the
traditional way, have some analogous shortcut for easily reading all
lines of some input as a standard feature. In Bash, `mapfile` in itself
can\'t do anything that couldn\'t already be done using read and a loop,
and if portability is even a slight concern, should never be used.
However, it does *significantly* outperform a read loop, and can make
for shorter and cleaner code - especially convenient for interactive
use.
## Examples
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
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
command with no wordsplitting, pathname expansion, or other monkey
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
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
the entire command group is still coming from the pipe even though
mapfile has read all available input, we just borrow FD 1 as it just so
happens to be pointing where we want it. More on this over at greycat\'s
wiki: <http://mywiki.wooledge.org/BashFAQ/024>
### 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
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
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
element to be assigned, though it can read and modify any array elements
already assigned.
A very simple example might be to use it as a kind of progress bar. This
will print a dot for each line read. Note the escaped comment to hide
the appended words from printf.
$ printf '%s\n' {1..5} | mapfile -c 1 -C '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\".
$ foo() { echo "|$1|"; }; mapfile -n 11 -c 2 -C 'foo' <file
|2|
|4|
etc..
For the sake of completeness, here are some more complicated examples
inspired by a question asked in #bash - how to prepend something to
every line of some input, and then output even and odd lines to separate
files. This is far from the best possible answer, but hopefully
illustrates the callback behavior:
$ { printf 'input%s\n' {1..10} | mapfile -c 1 -C '>&$(( (${#x[@]} % 2) + 3 )) printf -- "%.sprefix %s"' x; } 3>outfile0 4>outfile1
$ cat outfile{0,1}
prefix input1
prefix input3
prefix input5
prefix input7
prefix input9
prefix input2
prefix input4
prefix input6
prefix input8
prefix input10
Since redirects are syntactically allowed anywhere in a command, we put
it before the printf to stay out of the way of additional arguments.
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
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).
$ y=( 'odd[j]' 'even[j++]' ); printf 'input%s\n' {1..10} | { mapfile -tc 1 -C 'printf -v "${y[${#x[@]} % 2]}" -- "%.sprefix %s"' x; printf '%s\n' "${odd[@]}" '' "${even[@]}"; }
prefix input1
prefix input3
prefix input5
prefix input7
prefix input9
prefix input2
prefix input4
prefix input6
prefix input8
prefix input10
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
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.
#!/usr/bin/env bash
showRecord() {
printf 'key[%d] = %d, %d\n' "$1" "${vals[@]:keys[$1]*2:2}"
}
parseRecords() {
trap 'unset -f _f' RETURN
_f() {
local x
IFS=: read -r _ x
((keys[x]=n++))
}
local n
_f
mapfile -tc2 -C _f "$1"
eval "$1"'=("${'"$1"'[@]##*:}")' # Return the array with some modification
}
main() {
local -a keys vals
parseRecords vals
showRecord "$1"
}
main "$1" <<-"EOF"
fabric.domain:123
routex:1
routey:2
fabric.domain:321
routex:6
routey:4
EOF
For example, running `scriptname 321` would output `key[321] = 6, 4`.
Every 2 lines read by `mapfile`, the function `_f` is called, which
reads one additional line. Since the first line in the file is a key,
and `_f` is responsible for the keys, it gets called first so that
`mapfile` starts by reading the second line of input, calling `_f` with
each subsequent 2 iterations. The RETURN trap is unimportant.
## Bugs
- Early implementations were buggy. For example, `mapfile` filling the
readline history buffer with calls to the `CALLBACK`. This was fixed
in 4.1 beta.
- `mapfile -n` reads an extra line beyond the last line assigned to
the array, through Bash. [Fixed in
4.2.35](ftp://ftp.gnu.org/gnu/bash/bash-4.2-patches/bash42-035).
- `mapfile` callbacks could cause a crash if the variable being
assigned is manipulated in certain ways.
<https://lists.gnu.org/archive/html/bug-bash/2013-01/msg00039.html>.
Fixed in 4.3.
## To Do
- Create an implementation as a shell function that\'s portable
between Ksh, Zsh, and Bash (and possibly other bourne-like shells
with array support).
## See also
- [arrays](/syntax/arrays)
- [read](/commands/builtin/read) - If you don\'t know about this yet,
why are you reading this page?
- <http://mywiki.wooledge.org/BashFAQ/001> - It\'s FAQ 1 for a reason.

View File

@ -0,0 +1,476 @@
# The printf command
\<div center round todo box 70%\> 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! \</div\> \<div
center round tip 70%\> [**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).
[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?&#using_printf_inside_of_awk). \</div\>
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
experienced, that should be the most detailed description for the format
strings and modifiers.
Due to conflicting historical implementations of the `echo` command,
POSIX(r) recommends that `printf` is preferred over `echo`.
## General
The `printf` command provides a method to print preformatted text
similar to the `printf()` system interface (C function). It\'s meant as
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
the issue.
## Syntax
printf <FORMAT> <ARGUMENTS...>
The text format is given in `<FORMAT>`, while all arguments the
formatstring may point to are given after that, here, indicated by
`<ARGUMENTS...>`.
Thus, a typical `printf`-call looks like:
printf "Surname: %s\nName: %s\n" "$SURNAME" "$FIRSTNAME"
where `"Surname: %s\nName: %s\n"` is the format specification, and the
two variables are passed as arguments, the `%s` in the formatstring
points to (for every format specifier you give, `printf` awaits one
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)
---------- -------------------------------------------------------------------------------------------------------------------------------
The `-v` Option can\'t assign directly to array indexes in Bash versions
older than Bash 4.1.
\<note warning\> 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")'
\...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), and a similar one to
[mapfile](commands/builtin/mapfile), though performing expansions into
their arguments is less common. \</note\>
### Arguments
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**
[**If more arguments than format specifiers**]{.underline} 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
(empty).
Take care to avoid [word splitting](/syntax/expansion/wordsplit), as
accidentally passing the wrong number of arguments can produce wildly
different and unexpected results. See [this article](/syntax/words).
\<note warning\> [**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`!):
printf '%d\n' 08
\</note\>
### Format strings
The format string interpretion is derived from the C `printf()` function
family. Only format specifiers that end in one of the letters
`diouxXfeEgGaAcs` are recognized.
To print a literal `%` (percent-sign), use `%%` in the format string.
[**Again:**]{.underline} Every format specifier expects an associated
argument provided!
These specifiers have different names, depending who you ask. But they
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 `<N>±e<N>` 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:
### Modifiers
To be more flexible in the output of numbers and strings, the `printf`
command allows format modifiers. These are specified **between** the
introductory `%` and the character that specifies the format:
printf "%50s\n" "This field is 50 characters wide..."
#### Field and printing modifiers
Field output format
--------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`<N>` **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
`<space>` 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}
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
The precision for a floating- or double-number can be specified by using
`.<DIGITS>`, where `<DIGITS>` is the number of digits for precision. If
`<DIGITS>` is an asterisk (`*`), the precision is read from the argument
that precedes the number to print, like (prints 4,3000000000):
printf "%.*f\n" 10 4,3
The format `.*N` to specify the N\'th argument for precision does not
work in Bash.
For strings, the precision specifies the maximum number of characters to
print (i.e., the maximum field width). For integers, it specifies the
number of digits to print (zero-padding!).
### Escape codes
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 `?`
`\<NNN>` Interprets `<NNN>` as **octal** number and prints the corresponding character from the character set
`\0<NNN>` same as `\<NNN>`
`\x<NNN>` Interprets `<NNN>` as **hexadecimal** number and prints the corresponding character from the character set (**3 digits**)
`\u<NNNN>` same as `\x<NNN>`, but **4 digits**
`\U<NNNNNNNN>` same as `\x<NNN>`, 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.
------ -------------------------------------------------------------------------------------------------------------------------------------------------------------
- Backslashes in the escapes: `\'`, `\"`, and `\?` are not removed.
- Octal escapes beginning with `\0` may contain up to four digits.
(POSIX specifies up to three).
These are also respects in which `%b` differs from the escapes used by
[\$\'\...\'](syntax/quoting#ansi_c_like_strings) style quoting.
## Examples
### Snipplets
- print the decimal representation of a hexadecimal number (preserve
the sign)
- `printf "%d\n" 0x41`
- `printf "%d\n" -0x41`
- `printf "%+d\n" 0x41`
- print the octal representation of a decimal number
- `printf "%o\n" 65`
- `printf "%05o\n" 65` (5 characters width, padded with zeros)
- this prints a 0, since no argument is specified
- `printf "%d\n"`
- print the code number of the character `A`
- `printf "%d\n" \'A`
- `printf "%d\n" "'A"`
- Generate a greeting banner and assign it to the variable `GREETER`
- `printf -v GREETER "Hello %s" "$LOGNAME"`
- Print a text at the end of the line, using `tput` to get the current
line width
- `printf "%*s\n" $(tput cols) "Hello world!"`
### Small code table
This small loop prints all numbers from 0 to 127 in
- decimal
- octal
- hex
```{=html}
<!-- -->
```
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, \...):
the_mac="0:13:ce:7:7a:ad"
# lowercase hex digits
the_mac="$(printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${the_mac//:/ 0x})"
# or the uppercase-digits variant
the_mac="$(printf "%02X:%02X:%02X:%02X:%02X:%02X" 0x${the_mac//:/ 0x})"
### Replacement echo
This code was found in Solaris manpage for echo(1).
Solaris version of `/usr/bin/echo` is equivalent to:
printf "%b\n" "$*"
Solaris `/usr/ucb/echo` is equivalent to:
if [ "X$1" = "X-n" ]
then
shift
printf "%s" "$*"
else
printf "%s\n" "$*"
fi
### prargs Implementation
Working off the replacement echo, here is a terse implementation of
prargs:
printf '"%b"\n' "$0" "$@" | nl -v0 -s": "
### repeating a character (for example to print a line)
A small trick: Combining printf and parameter expansion to draw a line
length=40
printf -v line '%*s' "$length"
echo ${line// /-}
or:
length=40
eval printf -v line '%.0s-' {1..$length}
### Replacement for some calls to date(1)
The `%(...)T` format string is a direct interface to `strftime(3)`.
$ printf 'This is week %(%U/%Y)T.\n' -1
This is week 52/2010.
Please read the manpage of `strftime(3)` to get more information about
the supported formats.
## differences from awk printf
Awk also derives its *printf()* function from C, and therefore has
similar format specifiers. However, in all versions of awk the space
character is used as a string concatenation operator, so it cannot be
used as an argument separator. **Arguments to awk printf must be
separated by commas.** Some versions of awk do not require printf
arguments to be surrounded by parentheses, but you should use them
anyway to provide portability.
In the following example, the two strings are concatenated by the
intervening space so that no argument remains to fill the format.
$ echo "Foo" | awk '{ printf "%s\n" $1 }'
awk: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
`%s
Foo'
^ ran out for this one
Simply replacing the space with a comma and adding parentheses yields
correct awk syntax.
$ echo "Foo" | awk '{ printf( "%s\n", $1 ) }'
Foo
With appropriate metacharacter escaping the bash printf can be called
from inside awk (as from perl and other languages that support shell
callout) as long as you don\'t care about program efficiency or
readability.
echo "Foo" | awk '{ system( "printf \"%s\\n \" \"" $1 "\"" ) }'
Foo
## Differences from C, and portability considerations
- 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
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
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
#define LENMODS "hjlLtz"
...
/* skip possible format modifiers */
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
system\'s `/usr/bin/printf` or equivalent. The mksh maintainer
recommends using `print`. The development version (post- R40f) adds
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}
<!-- -->
```
# 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
[echo](commands/builtin/echo)\'s portability pitfalls. Bash, ksh93,
and zsh\'s `print` have an `-f` option which takes a `printf` format
string and applies it to the remaining arguments. Bash lists the
synopsis as:
`print: print [-Rnprs] [-u unit] [-f format] [arguments]`. However,
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) removes trailing newlines
before substituting the text, `printf -v` preserves all output.
## See also
- SUS: [printf
utility](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html)
and [printf()
function](http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html)
- [Code snip: Print a horizontal
line](/snipplets/print_horizontal_line) uses some `printf` examples
- [Greg\'s BashFAQ 18: How can I use numbers with leading zeros in a
loop, e.g., 01, 02?](BashFAQ>018)

View File

@ -0,0 +1,269 @@
# The read builtin command
*read something about read here!*
## Synopsis
read [-ers] [-u <FD>] [-t <TIMEOUT>] [-p <PROMPT>] [-a <ARRAY>] [-n <NCHARS>] [-N <NCHARS>] [-d <DELIM>] [-i <TEXT>] [<NAME...>]
## Description
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 `<NAME...>`.
Since Bash 4.3-alpha, `read` skips any `NUL` (ASCII code 0) characters
in input.
If `<NAME...>` is given, the line is word-split using
[IFS](/syntax/shellvars#IFS) variable, and every word is assigned to one
`<NAME>`. The remaining words are all assigned to the last `<NAME>` if
more words than variable names are present.
\<WRAP center round info 90%\> If no `<NAME>` is given, the whole line
read (without performing word-splitting!) is assigned to the shell
variable [REPLY](/syntax/shellvars#REPLY). Then, `REPLY` really contains
the line as it was read, without stripping pre- and postfix spaces and
other things!
while read -r; do
printf '"%s"\n' "$REPLY"
done <<<" a line with prefix and postfix space "
\</WRAP\>
If a timeout is given, or if the shell variable
[TMOUT](/syntax/shellvars#TMOUT) is set, it is counted from initially
waiting for input until the completion of input (i.e. until the complete
line is read). That means the timeout can occur during input, too.
### Options
Option Description
---------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`-a <ARRAY>` read the data word-wise into the specified array `<ARRAY>` instead of normal variables
`-d <DELIM>` recognize `<DELIM>` as data-end, rather than `<newline>`
`-e` on interactive shells: use Bash\'s readline interface to read the data. Since version 5.1-alpha, this can also be used on specified file descriptors using `-u`
`-i <STRING>` preloads the input buffer with text from `<STRING>`, only works when Readline (`-e`) is used
`-n <NCHARS>` reads `<NCHARS>` characters of input, then quits
`-N <NCHARS>` reads `<NCHARS>` characters of input, *ignoring any delimiter*, then quits
`-p <PROMPT>` the prompt string `<PROMPT>` is output (without a trailing automatic newline) before the read is performed
`-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 <TIMEOUT>` wait for data `<TIMEOUT>` seconds, then quit (exit code 1). Fractional seconds (\"5.33\") are allowed since Bash 4. A value of 0 immediately returns and indicates if data is waiting in the exit code. Timeout is indicated by an exit code greater than 128. If timeout arrives before data is read completely (before end-of-line), the partial data is saved.
`-u <FD>` use the filedescriptor number `<FD>` rather than `stdin` (0)
When both, `-a <ARRAY>` and a variable name `<NAME>` is given, then the
array is set, but not the variable.
Of course it\'s valid to set individual array elements without using
`-a`:
read MYARRAY[5]
\<WRAP center round important 90%\>
Reading into array elements using the syntax above **may cause [pathname
expansion](/syntax/expansion/globs) to occur**.
Example: You are in a directory with a file named `x1`, and you want to
read into an array `x`, index `1` with
read x[1]
then pathname expansion will expand to the filename `x1` and break your
processing!
Even worse, if `nullglob` is set, your array/index will disappear.
To avoid this, either **disable pathname expansion** or **quote** the
array name and index:
read 'x[1]'
\</WRAP\>
### Return status
Status Reason
-------- ---------------------------------------------------
0 no error
0 error when assigning to a read-only variable [^1]
2 invalid option
\>128 timeout (see `-t`)
!=0 invalid filedescriptor supplied to `-u`
!=0 end-of-file reached
### read without -r
Essentially all you need to know about `-r` is to **ALWAYS** use it. The
exact behavior you get without `-r` is completely useless even for weird
purposes. It basically allows the escaping of input which matches
something in IFS, and also escapes line continuations. It\'s explained
pretty well in the [POSIX
read](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html#tag_20_109)
spec.
2012-05-23 13:48:31 geirha it should only remove the backslashes, not change \n and \t and such into newlines and tabs
2012-05-23 13:49:00 ormaaj so that's what read without -r does?
2012-05-23 13:49:16 geirha no, -r doesn't remove the backslashes
2012-05-23 13:49:34 ormaaj I thought read <<<'str' was equivalent to read -r <<<$'str'
2012-05-23 13:49:38 geirha # read x y <<< 'foo\ bar baz'; echo "<$x><$y>"
2012-05-23 13:49:40 shbot geirha: <foo bar><baz>
2012-05-23 13:50:32 geirha no, read without -r is mostly pointless. Damn bourne
2012-05-23 13:51:08 ormaaj So it's mostly (entirely) used to escape spaces
2012-05-23 13:51:24 ormaaj and insert newlines
2012-05-23 13:51:47 geirha ormaaj: you mostly get the same effect as using \ at the prompt
2012-05-23 13:52:04 geirha echo \" outputs a " , read x <<< '\"' reads a "
2012-05-23 13:52:32 ormaaj oh weird
2012-05-23 13:52:46 * ormaaj struggles to think of a point to that...
2012-05-23 13:53:01 geirha ormaaj: ask Bourne :P
2012-05-23 13:53:20 geirha (not Jason)
2012-05-23 13:53:56 ormaaj hm thanks anyway :)
## Examples
### Rudimentary cat replacement
A rudimentary replacement for the `cat` command: read lines of input
from a file and print them on the terminal.
opossum() {
while read -r; do
printf "%s\n" "$REPLY"
done <"$1"
}
[**Note:**]{.underline} 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\...
Remember the MSDOS `pause` command? Here\'s something similar:
pause() {
local dummy
read -s -r -p "Press any key to continue..." -n 1 dummy
}
Notes:
- `-s` to suppress terminal echo (printing)
- `-r` to not interpret special characters (like waiting for a second
character if somebody presses the backslash)
### Reading Columns
#### Simple Split
Read can be used to split a string:
var="one two three"
read -r col1 col2 col3 <<< "$var"
printf "col1: %s col2: %s col3 %s\n" "$col1" "$col2" "$col3"
Take care that you cannot use a pipe:
echo "$var" | read col1 col2 col3 # does not work!
printf "col1: %s col2: %s col3 %s\n" "$col1" "$col2" "$col3"
Why? because the commands of the pipe run in subshells that cannot
modify the parent shell. As a result, the variables `col1`, `col2` and
`col3` of the parent shell are not modified (see article:
[processtree](/scripting/processtree)).
If the variable has more fields than there are variables, the last
variable get the remaining of the line:
read col1 col2 col3 <<< "one two three four"
printf "%s\n" "$col3" #prints three four
#### Changing The Separator
By default reads separates the line in fields using spaces or tabs. You
can modify this using the *special variable*
[IFS](/syntax/shellvars#IFS), the Internal Field Separator.
IFS=":" read -r col1 col2 <<< "hello:world"
printf "col1: %s col2: %s\n" "$col1" "$col2"
Here we use the `var=value command` syntax to set the environment of
`read` temporarily. We could have set `IFS` normally, but then we would
have to take care to save its value and restore it afterward
(`OLD=$IFS IFS=":"; read ....;IFS=$OLD`).
The default `IFS` is special in that 2 fields can be separated by one or
more space or tab. When you set `IFS` to something besides whitespace
(space or tab), the fields are separated by **exactly** one character:
IFS=":" read -r col1 col2 col3 <<< "hello::world"
printf "col1: %s col2: %s col3 %s\n" "$col1" "$col2" "$col3"
See how the `::` in the middle infact defines an additional *empty
field*.
The fields are separated by exactly one character, but the character can
be different between each field:
IFS=":|@" read -r col1 col2 col3 col4 <<< "hello:world|in@bash"
printf "col1: %s col2: %s col3 %s col4 %s\n" "$col1" "$col2" "$col3" "$col4"
### Are you sure?
asksure() {
echo -n "Are you sure (Y/N)? "
while read -r -n 1 -s answer; do
if [[ $answer = [YyNn] ]]; then
[[ $answer = [Yy] ]] && retval=0
[[ $answer = [Nn] ]] && retval=1
break
fi
done
echo # just a final linefeed, optics...
return $retval
}
### using it
if asksure; then
echo "Okay, performing rm -rf / then, master...."
else
echo "Pfff..."
fi
### Ask for a path with a default value
[**Note:**]{.underline} The `-i` option was introduced with Bash 4
read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
The user will be prompted, he can just accept the default, or edit it.
### Multichar-IFS: Parsing a simple date/time string
Here, `IFS` contains both, a colon and a space. The fields of the
date/time string are recognized correctly.
datetime="2008:07:04 00:34:45"
IFS=": " read -r year month day hour minute second <<< "$datetime"
## Portability considerations
- POSIX(r) only specified the `-r` option (raw read); `-r` is not only
POSIX, you can find it in earlier Bourne source code
- POSIX(r) doesn\'t support arrays
- `REPLY` is not POSIX(r), you need to set `IFS` to the empty string
to get the whole line for shells that don\'t know `REPLY`.
`while IFS= read -r line; do
...
done < text.txt
`
## See also
- Internal: [The printf builtin command](/commands/builtin/printf)
[^1]: fixed in 4.2-rc1

View File

@ -0,0 +1,45 @@
# The readonly builtin command
## Synopsis
readonly [-p] [-a] [-A] [-f] [NAME[=VALUE] ...]
## Description
The `readonly` builtin command is used to mark variables or functions as
read-only, which means unchangeable. This implies that it can\'t be
unset anymore. A `readonly` variable may not be redefined in child
scopes. A readonly global may not be redefined as a function local
variable. Simple command environment assignments may not reference
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
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
## Examples
## Portability considerations
- in POSIX(r), only the `-p` option is specified
## See also
- [declare](/commands/builtin/declare)
- [unset](/commands/builtin/unset)

View File

@ -0,0 +1,35 @@
# The return builtin command
## Synopsis
return [N]
## Description
The `return` command returns from a shell function.
If `N` is given, the return code to the caller is set to `N`. If not,
the returned status the the status of the most recently executed command
(i.e. `$?`).
### Options
There are no options.
### Exit status
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
## Examples
## Portability considerations
## See also
- [The exit builtin command](/commands/builtin/exit)
- [The exit status](/dict/terms/exit_status)

View File

@ -0,0 +1,81 @@
# The set builtin command
FIXME incomplete - text, examples, maybe extended description
## Synopsis
set [--abefhkmnptuvxBCHP] <-o OPTIONNAME> [-][--] <POSPARAMS>
## Description
`set` is primarily made to
- set the positional parameters (see [handling positional
parameters](/scripting/posparams)) to `<POSPARAMS>`
- set shell attributes with short options (see below)
- set shell attributes with long option names (see below)
Without any options, `set` displays all shell- and environment-variables
(only is POSIX-mode) in a re-usable format `NAME=VALUE`.
### Attributes
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) (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) This is on by default.
`-C` \<BOOKMARK:tag_noclobber\>`noclobber` Don\'t overwrite files on redirection operations. You can override that by specifying the `>|` redirection operator when needed. See [redirection](/syntax/redirection)
`-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).
`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
Tag a part of a shell script to output debugging information (`-x`):
``` bash
#!/bin/bash
...
set -x # on
...
set +x # off
...
```
## Portability considerations
`set` and its basic behaviour and options are specified by POSIX(r).
However, options that influence Bash-specific things are not portable,
naturally.
## See also
- Internal: [The shopt builtin command](/commands/builtin/shopt)

View File

@ -0,0 +1,88 @@
# The shift builtin command
## Synopsis
shift [n]
## Description
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
changed. The very first positional parameter is discarded, the second
becomes the first one, etc.
Imagine the following set of positional parameters (`$1` to `$4`):
1 This
--- ------
2 is
3 a
4 test
When you use `shift 1`, they will be changed to:
1 is
--- ------
2 a
3 test
The [special parameter](/syntax/shellvars#special_parameters) `$#` will
reflect the final number of positional parameters.
If the number given is 0, no changes are made to the positional
parameters.
### Options
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
## Examples
## Portability considerations
- The `shift` builtin command is specified by POSIX(r).
- Many shells will throw a fatal error when attempting to `shift` more
than the number of positional parameters. **POSIX does not require
that behavior**. Bash (even in POSIX mode) and Zsh return 1 when
there are no args, and no error output is produced unless the
[shift_verbose](internals/shell_options#shift_verbose)
[shopt](commands/builtin/shopt) 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'
dash: 1: shift: can't shift that many
` In most shells, you can work around this problem using the
[command](/commands/builtin/command) builtin to suppress fatal
errors caused by *special builtins*. \<code\> \$ dash -c \'f() { if
command shift 2\>/dev/null; then echo \"\$1\"; else echo \"no
args\"; fi; }; f\'
no args \</code\> While, POSIX requires this behavior, it isn\'t very
obvious and some shells don\'t do it correctly. To work around this, you
can use something like:
\<code\> \$ mksh -c \'f() { if ! \${1+false} && shift; then echo
\"\$1\"; else echo \"no args\"; fi; }; f\' no args \</code\> ~~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. \<code\> \$ bb -c \'f() { if shift; then echo \"\$1\";
else echo \"no args\"; fi; }; f\'
(no output) \</code\> The above mksh workaround will work in this case
too.
## See also

View File

@ -0,0 +1,51 @@
# The shopt builtin command
The `shopt` builtin manages [shell options](/internals/shell_options), a
set of boolean (`on`/`off`) configuration variables that control the
behaviour of the shell.
## Synopsis
shopt [-pqsu] [-o] <OPTNAME...>
## Description
Note: Some of these options and other shell options can also be set with
[the set builtin](/commands/builtin/set).
### Options
Option Description
-------- -----------------------------------------------------------------------------------------------------------------------------
`-o` Restrict the values of `<OPTNAME...>` to only those also known by [the set builtin](/commands/builtin/set)
`-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 `<OPTNAME...>` or list all *enabled* options if no names are given
`-u` Disabe ([u]{.underline}nset) the shell options named by `<OPTNAME...>` 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
printed.
### Exit code
When listing options, the exit code is `TRUE` (0), if all options are
enabled, `FALSE` otherwise.
When setting/unsetting an option, the exit code is `TRUE` unless the
named option doesn\'t exitst.
## Examples
Enable the `nullglob` option:
shopt -s nullglob
## Portability considerations
The `shopt` command is not portable accross different shells.
## See also
- Internal: [The set builtin command](/commands/builtin/set)
- Internal: [List of shell options](/internals/shell_options)

View File

@ -0,0 +1,72 @@
# The trap builtin command
## Synopsis
trap [-lp] [[ARGUMENT] SIGNAL]
## Description
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`
specification can be
- the name of a signal with the SIG prefix, e.g. `SIGTERM`
- the name of a signal without the SIG prefix, e.g. `TERM`
- the number of a signal (see `trap -l`), e.g. `15`
- the name or number of a special event (see table below), e.g. `EXIT`
Without any options or operands, `trap` prints a list of installed traps
in a reusable format (equivalent to the `-p` option).
Special `ARGUMENT`s
- if `ARGUMENT` is absent or `-` (dash), the signal/event handler is
reset to its original value
- if `ARGUMENT` is the null string, the signal/event is ignored
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) 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
### Return status
Status Reason
-------- ------------------------------
0 no error/success
!=0 invalid option
!=0 invalid signal specification
## Examples
### List installed traps
trap
### Ignore terminal interrupt (Ctrl-C, SIGINT)
trap '' INT
## Portability considerations
- `trap` is specified by POSIX(R) without the `-l` and `-p` options
- in POSIX(R), beside signals, only `EXIT` (0) is valid as an event
## See also
- [the set command](/commands/builtin/set) for the `-e` (`errexit`)
option

View File

@ -0,0 +1,181 @@
# The unset builtin command
## Synopsis
unset [-f|v] [-n] [NAME ...]
## Description
The `unset` builtin command is used to unset values and attributes of
shell variables and functions. Without any option, `unset` tries to
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
### 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
## Examples
unset -v EDITOR
unset -f myfunc1 myfunc2
### Scope
In bash, unset has some interesting properties due to its unique dynamic
scope. If a local variable is both declared and unset (by calling unset
on the local) from within the same function scope, then the variable
appears unset to that scope and all child scopes until either returning
from the function, or another local variable of the same name is
declared underneath where the original variable was unset. In other
words, the variable looks unset to everything until returning from the
function in which the variable was set (and unset), at which point
variables of the same name from higher scopes are uncovered and
accessible once again.
If however unset is called from a child scope relative to where a local
variable has been set, then the variable of the same name in the
next-outermost scope becomes visible to its scope and all children - as
if the variable that was unset was never set to begin with. This
property allows looking upwards through the stack as variable names are
unset, so long as unset and the local it unsets aren\'t together in the
same scope level.
Here\'s a demonstration of this behavior.
#!/usr/bin/env bash
FUNCNEST=10
# Direct recursion depth.
# Search up the stack for the first non-FUNCNAME[1] and count how deep we are.
callDepth() {
# Strip "main" off the end of FUNCNAME[@] if current function is named "main" and
# Bash added an extra "main" for non-interactive scripts.
if [[ main == !(!("${FUNCNAME[1]}")|!("${FUNCNAME[-1]}")) && $- != *i* ]]; then
local -a 'fnames=("${FUNCNAME[@]:1:${#FUNCNAME[@]}-2}")'
else
local -a 'fnames=("${FUNCNAME[@]:1}")'
fi
if (( ! ${#fnames[@]} )); then
printf 0
return
fi
local n
while [[ $fnames == ${fnames[++n]} ]]; do
:
done
printf -- $n
}
# This function is the magic stack walker.
unset2() {
unset -v -- "$@"
}
f() {
local a
if (( (a=$(callDepth)) <= 4 )); then
(( a == 1 )) && unset a
(( a == 2 )) && declare -g a='global scope yo'
f
else
trap 'declare -p a' DEBUG
unset2 a # declare -- a="5"
unset a a # declare -- a="4"
unset a # declare -- a="2"
unset a # ./unset-tests: line 44: declare: a: not found
: # declare -- a="global scope yo"
fi
}
a='global scope'
f
# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:
output:
declare -- a="5"
declare -- a="4"
declare -- a="2"
./unset-tests: line 44: declare: a: not found
declare -- a="global scope yo"
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
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.
- Declaring a global with declare -g bypasses all locals and sets or
modifies the variable of the global scope (outside of all
functions). It has no affect on the visibility of the global.
- 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\"
identical for individual array elements, and for arrays as a whole,
unset and unset2 behave as they do for scalar variables.
### Args
Like several other Bash builtins that take parameter names, unset
expands its arguments.
~ $ ( a=({a..d}); unset 'a[2]'; declare -p a )
declare -a a='([0]="a" [1]="b" [3]="d")'
As usual in such cases, it\'s important to quote the args to avoid
accidental results such as globbing.
~ $ ( a=({a..d}) b=a c=d d=1; set -x; unset "${b}["{2..3}-c\]; declare -p a )
+ unset 'a[2-1]' 'a[3-1]'
+ declare -p a
declare -a a='([0]="a" [3]="d")'
Of course hard to follow indirection is still possible whenever
arithmetic is involved, also as shown above, even without extra
expansions.
In Bash, the `unset` builtin only evaluates array subscripts if the
array itself is set.
~ $ ( unset -v 'a[$(echo a was set >&2)0]' )
~ $ ( a=(); unset -v 'a[$(echo a was set >&2)0]' )
a was set
## Portability considerations
Quoting POSIX:
If neither -f nor -v is specified, name refers to a variable; if a variable by that name does not exist, it is unspecified whether a function by that name, if any, shall be unset.
Therefore, it is recommended to explicitly specify `-f` or `-v` when
using `unset`. Also, I prefer it as a matter of style.
## See also
- [declare](/commands/builtin/declare)
- [unset](/commands/builtin/unset)
- [POSIX `unset`
utility](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_29)

View File

@ -0,0 +1,44 @@
# The wait builtin command
## Synopsis
wait [-f] [-n] [-p VARNAME] [ID...]
## Description
The `wait` builtin command is used to wait for job completion and return
exit status.
- if `ID` is a job specification, it waits for all processes in the
pipeline of this job
- 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 termination instead of status change (`-f` option)
`ID` may be an operating system process identifier or a shell job
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`
### 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
## Examples
## Portability considerations
## See also