@ Anatomy of the Command Line SCaLE 14x der.hans Canonical 2016Jan23 16:30 Room 101 @ Caveats . Skipping some pedantic details for sake of time . Presume you're already familiar with shell features such as pipes, redirection, variable expansion. . Going for the clearer examples rather than better code @ ordering . redirection . pre-command variable assignment . expansion . pipes . commands @ redirection . ripped from last week's headlines echo "UseRoaming no" >> /etc/ssh/ssh_config echo "UseRoaming no" | sudo tee -a /etc/ssh/ssh_config echo anke >file.txt; grep anke file.txt echo anke >file.txt; grep anke file.txt | grep anke >file.txt echo anke >file.txt; ls -l file.txt; grep anke file.txt | grep anke | tee file.txt echo -n $( echo foo >>file.txt ) >file.txt echo $( echo foo >>file.txt; ls -l file.txt ) >file.txt @ pre-command variable assignments LANG=C LANG=de_DE.UTF-8 find /ttmp | LANG=en_US sed -re 's/' unset fred; fred=file.txt echo fred >$fred @ expansion . the 7 layer burrito of the command line . 7 forms of expansion: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion @ expansion order . brace expansion . tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion) . word splitting . pathname expansion @ bonus layer . process substitution .. evaluated at the same time as tilde, parameter, variable, and arithmetic expansion and command substitution @ tokenizing From the bash man page: Only brace expansion, word splitting, and pathname expansion can change the number of words of the expansion; other expansions expand a single word to a single word. The only exceptions to this are the expansions of "$@" and "${name[@]}" as explained above (see PARAMETERS). @ brace expansion . bashism, not in sh . left to right order is preserved echo {,/usr,${HOME}/local,/usr/local}/{,s}bin echo {,/usr}/{,s}bin echo {1..10} ten=10; echo {1..$ten} echo {1{0..9},20} echo {a..e} echo 1{0..9..2} @ tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution . the squishy things, e.g. beans, cheese, salsa, guacamole, sriracha . appear in the order encountered, might be intermixed @ tilde expansion . ls -ld ~/../../var/{lib,log,cache} . ~+ . ~- . dirs . beware use in scripts @ parameter expansion . e.g. variables . lots of fun string manipulation that can be done during parameter expansion .. search the bash manpage for :- @ command substitution and subshell . copy of current env, not a brand new shell . the turducken of burritos . command substitution .. replaces the command with the results of the command .. $(command) .. NOTE: do not use backticks ... backticks are not readable ... nesting with backticks is a quoting nightmare . subshell .. create a new env that doesn't change parent environment .. ( cmd1; cmd2; cmd3 ) .. $( < $file ) is faster than $( cat $file ) . "If the substitution appears within double quotes, word splitting and pathname expansion are not performed on the results." @ arithmetic expansion echo $(( 3 + 1 )) . integer only echo $(( 3 + 1.5 )) echo $(( 4 / 3 )) . the expression is double quoted . $[expression] syntax is deprecated . nesting echo $(( 3 + $(( 1 + 2 )) )) . a double quote inside expression remains a double quote . parameter and variable expansion, command substitution, and quote removal happen ( rush=2112; echo $(( 2 * $rush )) ) # ( orwell=$(( 1900 + 48 )); echo $orwell ) ( cent=19; year=48; orwell=$(( $cent * 100 + $year )); echo $orwell ) @ process substitution . system must support named pipes (FIFOs) or /dev/fd ls -l <( echo anke ) # show /dev/fd grep sources.list <(find /etc/ 2>/dev/null) . useful for place where you need a file, but have stdout ls -lR * >ls-lR.out diff ls-lR.out <(ls -lR *) ( i=1984; while read i; do j=$(( ++i )); done < <( echo 2112 ); echo $j ) @ word splitting . splits on text not in double quotes . IFS ls $( echo /etc/resolv.conf /etc/issue ) @ pathname expansion . globbing @ quote removal @ pipes . all commands fire up at the same time find /ttmp | sed -re 's/' sleep 2 | find /ttmp | sed -re 's/' sleep 2 | find /ttmp | sed -re 's/' | ls -l /etc/issue @ command . the command or equivalent @ functions, aliases . e.g. commands @ regex . passed from shell to comand, but beware interpretation as globs touch f.{1,2,3}.txt echo fff >file.txt grep f.* file.txt echo f.* file.txt grep f file.txt @ further examples (n05.txt; while read name; do count=$( grep -c "$name" $file ); echo $count $name; done < <(grep -E '^ [A-Z]* [A-Z]*$' $file | sort -u ) | sort -nr ) | less file=file.2016Jan05.txt; while read name; do count=$( grep -c "$name" $file ); echo $count $name; done < <(grep -E '^ [A-Z]* [A-Z]*$' $file | sort -u ) | sort -nr ) | less @ resources . bash man page . Advanced Bash-Scripting Guide @ 2016 der.hans CC BY-SA 4.0 Unported