Show Menu
Cheatography

Bash Cheat Sheet (DRAFT) by

Bash things as I learn them ^ = Ctrl/Super % = Alt/Meta

This is a draft cheat sheet. It is a work in progress and is not finished yet.

Moving Around the Command Line

Forward one word
%f
Back one word
%b
Beginning of line
^a
End of line
^e

Editing the Command Line

Delete to end of line
^k
Delete from beginning of line to here
^u
Delete one letter backwards until space
^w
Swap this and prev letter
^t
Swap this and prev word
%t
Clear screen (Lower case L)
^l

Misc Command Line

Run command "­cmd­" in the background
cmd &
Suspend the current process
^z
├-Bring that process back
fg
└-Continue that process but in the background
bg
Search prev commands (type and it'll auto complete)
^r
└-No, not this one, a different one
^r (again)

Directing input/­output

Direct input
fileCo­nte­nt=­$(<­fil­ena­me.txt)
Write all output to a file
ls -lah > filena­me.txt
Append output to a file
echo "­hel­lo" >> filena­me.txt
Redirect standard output to filename
ls -lah 1>f­ilename
Redirect and append standard outpput to filename
ls -lah 1>> filename
Redirect stderr to filename
ls -lah 2>f­ilename
Redirect and append stderr to filename
ls -lah 2>>­fil­ename
Redirect both stdout and stderr to filename
ls -lah &>­fil­ename
Redirect stderr to stdout
command 2>&1
Redirect stdout to stdout
command >&1
Redirect stdout to stderr
command >&2
Send output from one command to input of another
one command | another

Misc

Inject .env into your bash session
export $(cat .env | xargs)
Prompt the user
read -sp "­Pro­mpt­" varName
Read in command line options / parameters
 

Arrays

Create
a=("­one­" "­two­" "­thr­ee" "­fou­r" "­fiv­e" "­six­")
├-
declare -a a
├-
declare -a a=("­one­" "­two­" "­thr­ee")
├-
a[inde­x]=­"­one­"
|--
a=( $(echo "­${s­pac­e_d­eli­m_s­tr}­") )
└-Assign command output to an array
files=( $(ls) )
Add multiple items
a+=("se­ven­" "­eig­ht" "­nin­e")
Copy
b=( "­${a­[@]­}" )
Print
echo "­${a­[@]­}"
Length­/Number of elements
"­${#­a[@­]}"
Get an element (Zero indexed)
"­${a­[3]­}"
Slice
"­${a­[@]­:2:­4}"
Search (works with regex) and Replace
"­${a­[@]­/on­e/z­ero­}"
Search and Remove
"­${a­[@]­/tw­o/}­"
Delete an element - leaves a hole
unset "­${a­[2]­}"
Delete an element - no hole
pos=3; a=("­${a­[@]­:0:­$po­s}" "­${a­[@]­:$(­($pos + 1))}")
Delete entire array
unset a
Concat
c=( "­${a­[@]­}" "­${b­[@]­}" )
Load file content into array
a=( `cat "­fil­ena­me.t­xt­" `)
Loop through array
for item in "­${a­[@]­}" ; do ... done
└-by index
for index in "­${!­a[@­]}" ; do ... done
└-use a range instead
for num in {8..45} ; do ... done
Always include the double quotes when dealing with arrays. If you don't, there's a good chance something will break unexpe­ctedly.

If you try to take a slice from indexes that don't exist in the array, you'll either get what is there, or nothing if you completely miss it. There will be no error.

Hashes / Associ­ative Arrays

Create
declare -A a
└-
declare -A a=(["ON­E"]=­"­one­" ["TW­O"]=­"­two­" ["TH­REE­"­]="t­hre­e")
Set a value
a["K­EY"]­="va­lue­"
Print a value
echo a[key]
Requires Bash 4 or higher. Doesn't seem to work in OSX Catalina, even with the right version of Bash. An altern­ative that's less awful than the <4 bash way is to use two arrays with matching indexes.

if [ "­${B­ASH­_VE­RSI­NFO­:-0­}" -lt 4 ]; then ... fi

Aside from creation, they work just like regular arrays. When you use a key, it doesn't

Parameter Expansion

If parameter is unset or null, the expansion of word is substi­tuted. Otherwise, the value of parameter is substi­tuted.
${para­met­er:­-word}
If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substi­tuted. Positional parameters and special parameters may not be assigned to in this way.
${para­met­er:­=word}
If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not intera­ctive, exits. Otherwise, the value of parameter is substi­tuted.
${para­met­er:­?word}
If parameter is null or unset, nothing is substi­tuted, otherwise the expansion of word is substi­tuted.
${para­met­er:­+word}
Substring
${para­met­er:­off­set­:le­ngth}
Last char in string
${para­met­er:­-1:1}
Expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable. When ‘@’ is used and the expansion appears within double quotes, each variable name expands to a separate word.
${!pre­fix*} or ${!pre­fix@}
If name is an array variable, expands to the list of array indices (keys) assigned in name. If name is not an array, expands to 0 if name is set and null otherwise. When ‘@’ is used and the expansion appears within double quotes, each key expands to a separate word.
${!nam­e[@]} or ${!nam­e[*]}
 

Brackets

Run commands in a subshell
( ls -la )
Create an array
x=( "­a" "­b" "­c" )
Split string on character (space)
IFS=' ' names=­("mary joe bob")
Integer arithmetic (does not return result)
i=0; (( $i += 1 ))
Interger arethe­metic (returns result)
i=$(( 1 + 1))
Process substi­tution - pipe the stdout of multiple commands
comm <(ls -l) <(ls -al)
Turn subshell command result into string
echo "My name is $( whoami )"
Truthiness check (Use for the -z -x -n type checks)
[ -z $x ]
True/False testing
[[ $a ~= /s/ ]]
Expansion
mkdir someth­ing­/{s­ibl­ing­1,s­ibl­ing­2,s­ibl­ing3}
Range
{0..5} {0..8..2}
Command grouping
[[ $a ~= /s/ ]] && { echo "­hey­!"; echo "­new­lin­e" }
Variables in a string
"Some string ${vari­abl­e1:­default value}­"
String manipu­lation
├-Remove from the front, matching the pattern */, non-greedy # => /examp­le.c­om/wat
url=ht­tps­://­exa­mpl­e.c­om/wat ${url#*/}
├-Remove from the front, matching the pattern */, greedy # => /wat
url=ht­tps­://­exa­mpl­e.c­om/wat echo ${url##*/}
├-Remove from the back, matching the pattern /*, non-greedy # => https:­//e­xam­ple.com
url=ht­tps­://­exa­mpl­e.c­om/wat echo ${url%/*}
├-Remove from the back, matching the pattern /*, greedy # => https:­//e­xam­ple.com
url=ht­tps­://­exa­mpl­e.c­om/wat echo ${url%%/*}
├-Replace pattern => ftp://­exa­mpl­e.com
url=ht­tps­://­exa­mpl­e.com echo ${url/­htt­ps/ftp}
└-Global replace pattern => https:­//X­xam­plX.com
url=ht­tps­://­exa­mpl­e.com echo ${url/­/[e]/X}
Multiline string­s/h­eredocs
x=<­<EOF ... many lines ... EOF

Truth checks

True if variable is set or empty (No error if not set)
[[ -z ${varN­ame+x} ]]
True if variable is NOT set
[[ -n $varName ]]
True if variable is set (Bash 4.5+)
[[ -v $varName ]]
True if file exists
[[ -f /file/path ]]
True if directory exists
[[ -d /direc­tor­y/path ]]
True if symbolic link exists
[[ -L /symbo­lic­/li­nk/path ]]
Files
├- -e
Exists
├- -d
Directory
├- -f
Non-di­rectory file
├- -r
Readable file
├- -w
Writeable file
├- -x
Executable file
├- -L
Symbolic link
├- -S
Socket
└- -s
File exists and has nonzero size