====== Bash Cheatsheet ======
===== Special parameters =====
[[https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#Special-Parameters|Source]]
* ''$*'' : Positional parameters. Separated by IFS. | $1c$2c$3
* ''$@'' : Positional parameters. Separated by space. | $1 $2 $3
* ''"$@"'' : Positional parameters. Separated by space. Separated words. | "$1" "$2" "$3"
* ''$#'' : Number of positional parameters.
* ''$?'' : Exit status of the most recently executed foreground pipeline.
* ''$-'' : Current option flags as specified upon invocation, by the set builtin command, or those set by the shell itself (such as the -i option).
* ''$$'' : Process ID of the shell. In a () subshell, it expands to the process ID of the invoking shell, not the subshell.
* ''$!'' : Process ID of the most recently executed background (asynchronous) command.
* ''$0'' : Name of the shell or shell script.
* ''$_'' : Last argument to the previous command, after expansion. (Or absolute shell pathname if first command).
===== Parameters expansion =====
[[http://wiki.bash-hackers.org/syntax/pe|Source]]
* Simple usage
* ''$PARAMETER''
* ''${PARAMETER}''
* Indirection
* ''${!PARAMETER}'' : Value of the variable whose name is ''PARAMETER''.
* Case modification
* ''${PARAMETER^}'' : First upper.
* ''${PARAMETER^^}'' : Whole upper.
* ''${PARAMETER,}'' : First lower.
* ''${PARAMETER,,}'' : Whole lower.
* ''${PARAMETER~}'' : Switch first.
* ''${PARAMETER~~}'' : Switch all.
* Variable name expansion
* ''${!PREFIX*}'' : List of all variables and arrays names beginning with ''PREFIX''.
* ''${!PREFIX@}'' : Idem.
* Substring removal (also for **filename manipulation**!)
* ''${PARAMETER#PATTERN}'' : Strip left (short match).
* ''${PARAMETER##PATTERN}'' : Strip left (long match).
* ''${PARAMETER%PATTERN}'' : Strip right (short match).
* ''${PARAMETER%%PATTERN}'' : Strip right (long match).
* Search and replace
* ''${PARAMETER/PATTERN/STRING}'' : Replace (fisrt occurence).
* ''${PARAMETER//PATTERN/STRING}'' : Replace (all occurences).
* ''${PARAMETER/PATTERN}'' : Search (first occurence).
* ''${PARAMETER//PATTERN}'' Search (all occurrences).
* String length
* ''${#PARAMETER}''
* Substring expansion
* ''${PARAMETER:OFFSET}''
* ''${PARAMETER:OFFSET:LENGTH}''
* Use a default value
* ''${PARAMETER:-WORD}'' : ''WORD'' when ''PARAMETER'' is unset or empty.
* ''${PARAMETER-WORD}'' : ''WORD'' when ''PARAMETER'' is unset.
* Assign a default value
* ''${PARAMETER:=WORD}'' : Expand AND assign ''WORD'' when ''PARAMETER'' is unset or empty.
* ''${PARAMETER=WORD}'' : Expand AND assign ''WORD'' when ''PARAMETER'' is unset.
* Use an alternate value
* ''${PARAMETER:+WORD}'' : Nothing if ''PARAMETER'' is unset or empty, ''WORD'' else.
* ''${PARAMETER+WORD}'' : Nothing if ''PARAMETER'' is unset, ''WORD'' else.
* Display error if null or unset
* ''${PARAMETER:?WORD}'' : Like '':-'' AND sets non-null exit code and ''$?''.
* ''${PARAMETER?WORD}'' : Like ''-'' AND sets non-null exit code and ''$?''.
==== Work with file paths ====
* ''dirname=${fullpath%/*}''
* ''filename=${fullpath##*/}''
* ''extension=${filename##*.}''
* ~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz
==== Output of a shell command ====
* ''$(mycmd params)''mydate=$(date +%Y-%m-%d)
mytimestamp=$(date '+%Y-%m-%d %H:%M:%S')
===== Mastering history =====
[[http://www.eriwen.com/bash/effective-shorthand/|Source]]
* ''!!'' : expands to the last command and all arguments
* ''!-3'' : 3rd-to-last command and all arguments
* ''!^'' : first argument of the last command in history
* ''!:2'' : 2nd argument of the last command
* ''!$'' : last argument of the last command
* ''!*'' : all arguments of the last command, but not the command itself
* ''!42'' : expands to the 42nd command in the history list
* ''!foo'' : last command beginning with "foo"
* ''!?baz'' : last command containing "baz"
* ''^foo^bar'' : last command with the first occurrence of "foo" replaced with "bar"
* ''!:gs/foo/bar'' : last command with all occurrences of "foo" replaced with "bar"
* '':p'' : prints command without executing
===== Redirection =====
[[http://www.losurs.org/docs/redirection|Deux trois trucs intéressants sur les redirections]]
* Diriger plusieurs lignes vers un fichier :/bin/cat <$FILE
text1
text2
text3
text4
EOM
* Normal:
* ''binary > file'' (send stdout to file)
* ''binary 2> file'' (send stderr to file)
* ''binary > file 2>&1'' (send stdout and stderr to file)
* ''binary < file'' (take stdin from file)
* Append:
* ''binary %%>>%% file'' (send stdout to end of file)
* ''binary 2%%>>%% file'' (send stderr to end of file)
* ''binary %%>>%% file 2>&1'' (send stdout and stderr to end of file)
* ''binary %%<<%%x'' (take stdin until "x" occurs)
* Pipes:
* ''binary1 | binary2'' (pipe stdout of binary1 to stdin of binary2)
* ''binary1 2>&1 | binary2'' (pipe stdout and stderr of binary1 to binary2)
==== The problem with cats ... ====
Take a simple redirection example such as this:
''cat file1 | tr -d '\015' > file2''
You've wasted a process on cat, since you could accomplish the same thing (and have it execute faster!) by doing this:
''tr -d '\015' < file1 > file2''
==== Sending stderr through a pipe ====
Sending only stderr down a pipe, while having stdout still go to the screen, is an interesting trick. It can be done by passing the stdout and stderr file descriptors to temporary file descriptors, and basically playing a game of 3 card monte with the values:
''(binary 3>&1 1>&2 2>&3 3>&-) | mail me@somewhere.org &''
===== Fonctions =====
''func_name () { cmd1; cmd2 }''
On retrouve cette syntax au coeur de la fameuse fork bomb bash '':(){ :|:& };:'' où '':'' est le nom de la fonction. L'utilisation du pipe et des '':'' est a priori seulement là pour obfusquer un peu plus la syntaxe ('':'') et la raccourcir (''|''). ''f(){f&;f&;};f'' fait quaisment la même chose.