note/sh-builtin

Shell (Bash) Cheatsheet

Structures

a; brun a, then run b
a && brun a, if succeeded, then run b
a || brun b, if failed, then run b

if [[ ! -f .bashrc ]]; then
    echo "conf is not found"
    touch .bashrc
fi

is equivalent to:

[[ -f .bashrc]] || {
    echo "conf is not found"
    touch .bashrc
}

function

function f() {
    echo $1
    return 1
}
# Or:
f() {
    echo $1
    return 1
}
  • $1, $2 etc is the 1st, 2nd etc argument
  • $# is the amount of arguments
  • $* / $@ is an array of all arguments
  • return: built-in command for exiting function (with an exit code)

case

case $var in
    1)
        echo one;;
    2)
        echo two;;
    *)
        echo other;;
esac

for

for var in one two three
do
    echo $var
done
for (( i=0; i<10; i++ ))
do
    echo $i
done

if

if <list0>; then
    <list1>
else
    <list2>
fi

Run <list1> when <list0> exit with code 0, elsewhere run <list2>.

Brackets

[ ] / [[ ]]

(Built-in command) Conditional brackets, you can think the left bracket as a program. The “program” returns an error code depending on the <expression>. [[ is an enhanced version of [ which may not be available in lower versions of bash.

if [[ <expression> ]]; then
    <list>
fi

Here's an incomplete list of <expression>:

  • -a <file>: true when file exist
  • -v <var>: true when variable is set
  • str1 <|>|==|=|!= str2: compare strings lexicographically
  • str1 <OP> str2: compare numerically, where <OP> is:
    • -eq, -ne: equal to, not equal to
    • -lt, -le: less than, less than or equal to
    • -gt, -ge: greater than, greater than or equal to

(( ))

(Built-in command) Exit with code 0 when it's a non-zero number.

(( 1 )) # code 0
(( 0 )) # code 1
(( nan )) # code 1

$[ ]

(Keyword) Math brackets.

echo $[ 9 * 9 ] # 81

$( )

(Keyword) Equivalent to `` .

Variable

There are two types of variables, string and array.

# Create a string variable $var with value '233', note that there should be no space surrounding '='
var=233
# Get the value of $var
echo $var
# Create an array variable
arr=(first second third)

Tip: var=string with-space is invalid, it will execute command with-space with $var set to string, use quotes in these cases.

Built-in variables

$1, $2, etc.arguments pass to shell or functions
$#count of the arguments
$@the arguments array
$?exit code of the last process or function

String clipping

${<variable>:<start>:<length>}
str="Bourne-Again Shell's great"
echo ${str:7:5} # Again

String splitting

var="123/456/789"
echo ${var#*/}    # 456/489
echo ${var##*/}   # 789
echo ${var%/*}    # 123/456
echo ${var%%/*}   # 123
|->|
123/456/789
|----->|

       |<-|
123/456/789
   |<-----|

String substitution

${var:-word}if var is empty, return word. If not, return var
${var:+word}if var is not empty, return word. If empty, return var (which is nothing)
${var/pattern/word}substitude the first occurrence of pattern with word in var
${var//pattern/word}substitude all occurrences of pattern with word in var

Array

ExpressionReturn valueDescription
arr=(first second third)assign $arr with an array
echo $arrbash: first, zsh: first second third
arr[1]=2ndarray item assignment, the suffix counts from 0, negative: reverse counting
echo ${arr[1]}2ndget an item
${arr[@]}first 2nd thirdget all items
${!arr[@]}0 1 2
${#arr[@]}3len of array

Quotes

  • "": parse variables and escape characters in it
  • '': what you see is what you get
echo ~    # /home/genel
echo "~"  # ~
echo *    # documents downloads pictures music
echo "*"  # *

Pipes

a > file.txtstdout -> file
a 2> file2.txtstderr -> file
a 2>&1stderr -> stdout
a >> file.txtappend stdout to a file
a | bstdout of a -> stdin of b
a < file.txtfile -> stdin
a `b`stdout -> args
a << "some string""some string" -> stdin
a <& <number>duplicate file descriptor <number> of current bash session to stdin of a
a >& <number>duplicate file descriptor <number> of current bash session to stdout of a
a << delimiter
    This is here-doc.
    You can write anything here
    as the stdin of 'a',
    until your 'delimiter' appears.
delimiter

In some cases (e.g. in scripts), you don't want program to print anything to the session. Redirect the stdout and stderr of the program to /dev/null.

a <&0  # duplicate stdin of the bash session to a
a >&1  # duplicate stdout of the bash session to a

Built-in command

echo <args>args -> stdout
pwdshow current working directory
source <file>run a shell script in current shell process (preserve states after the script exit)
eval <command>run a command in current shell process
exec <program>run a program to replace current shell process

Variable

export <var>[=<value>]make a variable environ, vars are not accessible by other programs by default
set -- "qwe" "rty"let $1: "qwe", $2: "rty"
read [-p "Your name? "] varread some val to a variable
<var>=<value> <program>run a program under an environ var
getopts <optstr> <var>see Getopts

Variables are global by default, use a local keyword to limit their scopes.

f() { a=2333; }
f
echo $a    # 2333
g() { local b=2333; }
g
echo $b    # ''

Process

fg <process>put a background process foreground, or continue a suspended process foreground
bg <process>continue a suspended process background
kill [-SIG<signal>] <process>terminate, or send signals to processes
disown <process>detach children processes from current shell. i.e. Exiting the shell doesn't end the process.
coproc <program>create an asynchronous process, and connect its stdin and stdout to file descriptors (${COPROC[0]} & ${COPROC[1]}) of current shell session

In REPL, press Ctrl-Z to suspend a process.

kill is also an external program, but the built-in one has more capabilities. e.g. You can specify <process> not only with PID, but also with "%<process_name>".

Other commands

trueexit with code 0
falseexit with code 1

Others

<(a)execute a program, and expose the process' stdout as a file
>(a)...expose the process' stdin as a file
a &run a in the background

About Me