This is a card in Dave's Virtual Box of Cards.

Common Bash with examples

Created: 2022-09-02

Okay, I’m finally starting this cheatsheet because I keep looking up the same stuff over and over.

Make a script exit on errors

set -e

Brace expansion

Comma-separated series:

$ echo x{A,B,C}x
xAx xBx xCx

$ echo foo{bar,baz,qux}
foobar foobaz fooqux

$ echo foo{.txt,.jpg,.c}
foo.txt foo.jpg foo.c

$ echo {foo,bar,baz}{.txt,.jpg,.c}
foo.txt foo.jpg foo.c bar.txt bar.jpg bar.c baz.txt baz.jpg baz.c

Ranges {start..end} with optional {s..e..increment}:

$ echo x{A..D}x
xAx xBx xCx xDx

$ echo {1..4}
1 2 3 4

$ echo {4..1}
4 3 2 1

$ echo {00..16}
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16

$ echo {Z..A}
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

$ echo {z..a}
z y x w v u t s r q p o n m l k j i h g f e d c b a

$ echo {2..16..2}
2 4 6 8 10 12 14 16

$ echo {000..100..10}
000 010 020 030 040 050 060 070 080 090 100

Series and range combo examples (this is so powerful):

$ echo foo{01..04}{.txt,.log}
foo01.txt foo01.log foo02.txt foo02.log foo03.txt foo03.log foo04.txt foo04.log

$ echo foo{01..03}{A..C}{.txt,.log}
foo01A.txt foo01A.log foo01B.txt foo01B.log foo01C.txt foo01C.log
foo02A.txt foo02A.log foo02B.txt foo02B.log foo02C.txt foo02C.log
foo03A.txt foo03A.log foo03B.txt foo03B.log foo03C.txt foo03C.log

Loops

For in a script:

for i in 1 2 3 4
do
    echo "$1 is a number."
done

1 is a number.
2 is a number.
3 is a number.
4 is a number.

For at the command line:

$ for i in 1 2 3 4; do echo "$i is a number."; done
1 is a number.
2 is a number.
3 is a number.
4 is a number.

Redirection

  • 0 - STDIN

  • 1 - STDOUT

  • 2 - STDERR

> and >> Redirect STDIN to file:

$ echo "foo" 1> foo.txt    redirects explicit STDOUT to foo.txt (overwrite)
$ echo "foo" > foo.txt     redirects default STDOUT to foo.txt  (overwrite)
$ echo "foo" 1>> foo.txt   redirects explicit STDOUT to foo.txt (append)
$ echo "foo" >> foo.txt    redirects default STDOUT to foo.txt  (append)
$ cat foo.txt
foo
foo

2> (and 2>>) Redirect only STDERR to file:

$ touch foo.txt
$ ls foo.txt noexist.txt 2> foo.txt
foo.txt
$ cat foo.txt
ls: cannot access 'noexist.txt': No such file or directory

&> (and &>>) Redirect STDIN and STDERR to file

$ ls foo.txt noexist.txt &> foo.txt
$ cat foo.txt
ls: cannot access 'noexist.txt': No such file or directory
foo.txt

>&2 to write to STDERR

if [[ bad thing happened ]]
then
    echo "Sorry about the bad thing!" >&2
    exit 1
fi

2>&1 Duplicate

Redirect command to STDIN (!)


Parameter expansion

Command substitution - use command output as if it were a variable:

$ file $(which bash)
/usr/bin/bash: symbolic link to /bin/bash

Variable expansion (substrings, removing prefixes and suffixes):

$ myfoo="foo foo bar bar"
$ echo $myfoo          foo foo bar bar
$ echo ${myfoo}        foo foo bar bar
$ echo ${myfoo:5}      oo bar bar         (substring)
$ echo ${myfoo:5:5}    oo ba              (substring:len)
$ echo ${myfoo#foo}    foo bar bar        (prefix)
$ echo ${myfoo#*foo}   foo bar bar        (wild prefix)
$ echo ${myfoo##*foo}  bar bar            (greedy wild prefix)
$ echo ${myfoo%bar}    foo foo bar        (suffix)
$ echo ${myfoo%bar*}   foo foo bar        (wild suffix)
$ echo ${myfoo%%bar*}  foo foo            (greedy wild suffix)

Handling unset variables

$ echo $nofoo                            ($nofoo is not set to anything)
$ echo ${nofoo:-hello}        hello      ($nofoo remains unset)
$ echo ${nofoo:=hello}        hello      ($nofoo set to 'hello')
$ echo ${nofoo2:?Required.}   bash: nofoo2: Required. (And exits script!)