Bash reference
Contents
Bash reference¶
Reference notes for all things related to the Bourne Again Shell, and derivatives.
Table of Contents¶
Redirections¶
I/O redirection¶
The following are commonly used redirection operators. These operations work on file descriptors:
0 - stdin
1 - stdout
2 - stderr
Output operators¶
Example use:
# write "Some Text" to the file `output.txt`
echo "Some text" > output.txt
> FILENAME
pipe to file, will overwrite if present>> FILENAME
pipe to file, appends if present
Specific output operators; note, for each there exists the >>
variant:
1> FILENAME
pipe onlystdout
2> FILENAME
pipe onlystderr
&> FILENAME
pipe bothstdout
andstderr
J> FILENAME
pipe file descriptorJ
(default 1 if not present) to fileJ>&K
pipe file descriptorJ
to file descriptorK
Input operators¶
Example use:
# same as `cat logfile | grep Error`
grep Error < logfile.txt
< FILENAME
accept input as coming from file, sometimes also0<
<&J
accept input as coming from file descriptorJ
Opening and closing file descriptors¶
Example use:
echo "Hello World" > file.txt
exec 3<> file.txt # open `file.txt` and assign file descriptor 3 to it
read -n 5 <&3 # read 4 characters of the file
echo -n , >&3 # write a ,
exec 3>&- # close file descriptor
cat file.txt
# Hello, World
J<> FILENAME
open file for reading and writing assigned to file descriptorJ
.J
defaults to0
if not present. IfFILENAME
does not exist, then it will be createdJ<&-
close input file descriptorJ
.J
defaults to 0 if not givenJ>&-
close output file descriptorJ
Operation ordering¶
The order in which I/O operations are used can affect their behaviour. Consider the following examples
exec 3>&1 # open fd 3 to `stdout`
ls -l >&3 3>&- | grep bad >&3 # close fd 3 for `grep` but not for `ls`
exec 3>&-
Here documents¶
Full examples and documentation is available here. The basic use replaces stdin
in the preceding command:
cat <<EOF
...
EOF
Note: the symbol need not be EOF
, but any unique character string, and the terminating symbol must exist on a new line with no preceding characters (whitespace, or otherwise).
Supressing tabs (output will be flush left)
cat <<-EOF
...
EOF
By default, here documents support parameter substitution. To disable it
cat <<'EOF' # alternatively \EOF or "EOF"
...
EOF
Here documents create temporary files that are deleted after opening, and not available to other processes: this can be demonstrated
bash -c 'lsof -a -p $$ -d0' << EOF
EOF
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# lsof 4375 aelfric 0r REG 8,18 0 9962257 /tmp/zshc3dfTh (deleted)
Operators¶
The following operators use single square bracket notation (unless otherwise indicated), as in the example:
if [ $a -eq $b ]; then
echo "a and b are numerically equal!"
fi
As they are presented, these operators are true when the accompanying statement is true. In general, any given operator may be reversed with the !
(not) operator:
if ! [ $a -eq $b ]; then
echo "a and b are *not* numerically equal!"
fi
Numerical comparison operators¶
-eq
is equal to-ne
is not equal to-gt
is greater than, alternatively>
in double parentheses-ge
is greater than or equal to, alternatively>=
in double parentheses-lt
is less than, alternatively<
in double parentheses-le
is less than or equal to, alternatively<=
in double parentheses
String comparison operators¶
It is a good practice to always quote a tested string, unless the pattern matching behaviours are desired.
=
is equal to==
is equal to, with different behaviour when framed in double brackets
[[ $a == b* ]] # pattern matching, with wildcard
[[ $a == "b*" ]] # literal matching, i.e. `$a` equal to exactly z*
!=
is not equal to<
is less than in ASCII alphabetical ordering>
is greater than in ASCII alphabetical ordering=~
regex match, requires double brackets. Uses POSIX character classes.
The following are unary operators:
-z
string is null (zero length)-n
string is not null
File test operators¶
These operators act on file paths, either as strings or on expanded variables. They are all unary operators, unless otherwise stated.
-e
exists-f
is regular (not a directory or device file)-s
is non-zero size-d
is a directory-h
is a symbolic link, alternatively-L
-S
is a socket-g
sgid (set-group-id) flag is set – file belongs to the group that owns the directory-u
suid (set-user-id) flag is set – file will execute as root (provided owned by root); shows ans
in permissions.
The following are evaluated in the context of the script’s executing user
-r
has read permissions-w
has write permissions-x
has execute permissions-O
user owns this file-G
GID of file is the same as user’s
The following are binary operators
-nt
left file is newer than right file-ot
left file is older than right file-ef
left file and right file are hard links to the same file
Special variables¶
Most of these are taken from an advanced scripting guide.
$$
: process ID, often the same as$BASHPID
, contextually of the executing script.$MACHTYPE
: machine hardware type (i386, x86_64, …).$_
: set to the final argument of the previously executed command.
For $_
, consider
du > /dev/null
echo $_
# du
ls -l > /dev/null
echo $_
# -l
Positional parameters¶
Only avaible in function calls
$#
: the number of arguments passed.$*
: all positional parameters as a single word.$@
:$*
but with each parameter being seen as a seperate word.
The $@
variable responds to shift
calls, which removes $1
and decrements the positional index of every remaining variable by one.
For example, a script which is passed 1 2 3 4 5
as input:
echo "$@" # 1 2 3 4 5
shift
echo "$@" # 2 3 4 5
shift
echo "$@" # 3 4 5
POSIX character classes¶
POSIX character classes are groups of similar characters used in POSIX regex expressions, amongst other places. They may be typed in either completely lower or uppercase; that is, [:alpha:]
and [:ALPHA:]
are equivalent.
POSIX Class |
Meaning |
---|---|
|
lowercase letters |
|
uppercase letters |
|
alphabetic characters |
|
alphanumeric characters |
|
digits |
|
hex digits |
|
spaces and tabs |
|
all white space characters, incl. |
|
control characters |
|
punctuation symbols |
|
visible characters and spaces |
|
visible characters |
|
ASCII characters |
|
alphanumeric and underscore (i.e. regex |
There are two special classes for denoting the beginning [:<:]
and end [:>:]
of a word.
Link: for more information, see regular expressions info.
IFS¶
The internal field seperator is used by many shell commands to work out how to do word splitting in the input.
A useful case to remember is that new-line characters are escaped
IFS=$'\n'
The first character in the IFS definition also marks how common shell commands will bind words together. For example
IFS=":;-"
and
IFS="-:;"
will both split words on any of :
, ;
, or -
characters – but when used with the $*
special variable have a different effect:
bash -c 'set a b c d; IFS=":;-"; echo "$*" '
# a:b:c:d
bash -c 'set a b c d; IFS="-:;"; echo "$*" '
# a-b-c-d
Environment contexts¶
Environment variables set during the context of a command may be passed with
SOME_VAR=some_val ./script.sh
or using exec
and env
to run the program in a modified environment
exec env SOME_VAR=some_val ./script.sh
Parameter manipulation¶
Reference for manipulating parameters/variables with bash; for more, see parameter substitution.
Default¶
When accessing a variable $var
, which may or may not be set.
Note, in all of these, the modification :
in the syntax will also use apply the default value if $var
is declared, but set to null
.
Use default¶
For default values, there are two syntax options
${var-$var2}
${var:-$var2}
which can also be used with command substitutions
${var-`pwd`}
Set to default¶
${var=default_value}
${var:=default_value}
Error¶
To print an error message if a variable is not set, use
${var?err_message}
${var:?err_message}
Trimming¶
Example for trimming known characters from the end of a string
${var%.mp4} # removes .mp4
${var%.*} # removes any filename suffix
The %
operator removes a suffix, and the #
operator removes a prefix.
Substring extraction¶
For all but the last 4 characters:
${var:0:${#var}-4}
# note the 0 is implicit; the above is equivalent to
${var::${#var}-4}
# and on many bash derivatives, the string length is also implicit
${var::-4}
find
¶
The find
command has numerous very useful features.
not
conditional¶
To find files not matching a certain predicate, find
supports the -not
argument: for example,
find . -name "*.md" -not -name "index.md"
to find files ending in .md
but not files called index.md
.
-exec
options¶
The -exec
flag supports two terminations:
serial
find . -exec echo {} \;
to execute, in this case, echo
on each file, calling the command once per file.
group
find . -exec echo {} +
to execute echo on all of the output combined together as words, calling the command once per file.
Piping¶
If -exec
needs to pipe the output of a command to another, there are two useful ways of achieving this.
The first is by (ab)using sh
find . -exec sh -c "cat {} | grep Example" \;
Or otherwise by piping the output through xargs
seperated by new lines:
find . | xargs -d\\n cat | grep Example