editing mode in default editor to enter commands like you would in a script, executed upon save+close. Also great when pasting (longer) scripts into your terminal
Customise in config:: ~/.inputrc
enable Pg up/down to search command history, based on characters typed so far
bracketed paste: encapsulate pasted content in special control characters to avoid command execution upon newline characters - this greatly enhances pasting commands into your commandline, especially if you’re clumsy or don’t trust your various copy buffers.
local-a# local array
global-A# global associative array# declare and typeset create local var.s unless -g is specifieddeclare-r# read-onlydeclare-x# mark for exportdeclare-g# global variable in functiontypeset-ii# integer, faster arithmetic and operations such as let y=x**2
s='abcABC123ABCabc'echo${s:3}${s:6:3}${s:(-3)}${s: -6}# negative indices (position from end of string) need parentheses or space to be escaped# extract a maximum of $length positional parameters, starting at $positionfunctionf(){start=2number=4echo${*:$start}echo${@:$start:$number}}
f{1..10}# 2 3 4 5 6 7 8 9 10# 2 3 4 5
Deleting substrings
12345
s='abcABC123xyzABC456'echo${s#a*C}# delete shortest match from beginningecho${s##a*C}# delete longest match from beginningecho${s%A*[0-9]}# delete shortest match from endecho${s%%A*[0-9]}# delete longest match from end
Substring substitution
12345678
stringZ=abcABC123ABCabc
echo$stringZecho${stringZ/abc}# delete from startecho${stringZ/%abc}# delete from endecho${stringZ/#abc/XYZ}# replace from startecho${stringZ/%abc/XYZ}# replace from endecho${stringZ//abc/XYZ}# replace all occurancesecho${stringZ//abc}# delete all occurances
String concatenation
123456
a='bla'b='blubb'c=${a}${b}echo$cb+=$aecho$b
To lower or upper case
1234567
s='bla blubb'echo${s^}# first upper caseecho${s^^}# all upper caseecho${s^^[l]}# only certain characterss='BLA BLUBB'echo${s,}# first lower caseecho${s,,}# all lower case
Sanitise a string
12
s='abc123XYZ@troll_ol-!"ยง$%&/()=?'echo${s//[^a-zA-Z0-9_@\\\-.]}# delete all characters not matching
fname=john
john=thomas
echo${!fname}# returns thomas# use default value if parameter is unset or nullmyvar=${1:-Default}# assign default to parameter if unset or null[[-f"${myfile:=/tmp/myfile}"]]||touch"$myfile"
## explicit declaration (can also be done implicitely, on-the-fly)declare-aarr1# indexed arraydeclare-Aarr2# associative arrayarr3=("derp""schlerp"123)## access elementsecho${arr3[0]}# first, starting at 0echo${arr3[-2]}# 2nd from back (since bash 4.2 - 4.3)## access entire arrayecho${arr[@]}## orecho${arr[*]}## access slice/rangeecho${arr[@]:2}# from element 2echo${arr[@]::2}# up to, excluding element 2## add elementarr1+=("new""elements")## number of elements${#arr[@]}
The only difference between @ and * is when the form ${my_array[x]} is surrounded with double-quotes. In this case, * expands to a single word where array elements are separated with space. @ expands each array element to a separate word. This is especially important when using the form to iterate through array elements. https://linuxize.com/post/bash-arrays/
$0# shell or script name$@# arguments$*# arguments$## number of arguments$$# current shell pid$!# last pid$?# return value of last process${-}# current shell options${_}# argument to previous command
# overwrite original positional parametersset--"${newparams[@]}"# drop current first argument, can be used to iteratively reduce number of argumentsshift
read arguments from STDIN/STDERR
1234
functionmyfunc(){declareargs=${*:-$(</dev/stderr)}# use command arguments OR stderr# ...}
refer to previous command’s arguments
12345
echo123echo!:2# previous 2nd argumentecho!:*# previous all argumentsecho!:^# previous first argumentecho!:$# previous last argument
manshoptcompgen-b# list builtin bash commands from possible auto-completionscompgen-c# list commands from possible auto-completionsenable# List bash builtins and whether they're enabled(IFS=': ';ls-1$PATH)# list available commands from PATH environment variable
command grouping
12
(list)# create subshell with subshell environment{list;}# executed in current shell context. semicolons required.
Here Documents: inline files with optional variable substitution TLDP #dev/shell/heredoc
1 2 3 4 5 6 7 8 9101112
# variable expansion
sed's/\/.*\///'<< EOF Found your home directory, $HOME!EOF# literal, no variable expansion
sed's/\/.*\///'<< 'EOF' I just checked $HOME.EOF# trim leading whitespace
sed's/\/.*\///'<<- EOF And this will remove leading whitespace, $HOME.EOF
cut
1
cut-d" "-f2,3# Cut fields from file/standard input if omitted. Delimiter " ", fields 2+3
getoptions: shell script, versatile and portable, less overhead
> An elegant option/argument parser for shell scripts (full support for bash and all POSIX shells)