On Github pbrisbin / talk-effective-shell
% whoami Pat Brisbin - Developer at thoughtbot http://pbrisbin.com @patbrisbin me@pbrisbin.com
% head -n 1 /var/log/pacman.log | sed 's/^\[\(.*\)\].*/\1/' 2007-04-25 00:04
Category of close-source operating systems
"The Unix Philosophy"
Re-implemented as open-source many times
Anything that can be "invoked"
A command for running other commands
Idealized shell with all (and only) the functionality outlined in the specification
Does not exist
BSD
Very close to POSIX
OSX, Arch Linux
Arrays, regular expressions
When invoked as sh, tries to be POSIX
Personal favorite for non-interactive use
Debian (Ubuntu et al)
Similar to Bash with subtle differences
Also tries to be POSIX if invoked as sh
Newest / widely adopted shell
Suffix and global aliases, better tab-completion, fancy globs
Personal favorite for interactive use
Google: switch to zsh on OSX
Do not install Oh-my-zsh (yet)
Consider grml-zsh-config
% alias v='vim' % v --version # shows vim --version...
% alias -s txt="less" % ./something.txt # opens the file in less...
% alias -g L='| less' % grep pattern file.text L # same as grep ... | less
% ls *.mp4 foo.mp4 bar.mp4
% for file in *.mp4; do > echo "A file! $file" > done A file! foo.mp4 A file! bar.mp4
% ls *(.) # * but files only foo.txt bar.txt
% ls *(/) # * but directories only baz/ bat/
And about a 1,000 more...
% command 2>/dev/null
% command &>/dev/null
% command >/dev/null 2>&1
% echo "I'll go to stdout" >&2
% cat file.txt | grep 'some-pattern'
% grep 'some-pattern' < file.txt
% grep 'some-pattern' file.txt
% for x in {1..3}; do > echo "$x" > done 1 2 3
% ls file % cp file{,.bak} % ls file file.bak
% mkdir -p test/{models,views}/{lib,ext} % tree test test ├── models │ ├── ext │ └── lib └── views ├── ext └── lib 6 directories, 0 files
% cat file.txt one line two line three line four
% cat other-file.txt five and six seven
% cat file.txt other-file.txt one line two line three line four five and six seven
% grep line file.txt one line two line three line
% cat file.txt other-file.txt | grep five five and six
% grep -q line file.txt; echo $? 0
% grep -q "something else" file.txt; echo $? 1
% cut -d ' ' -f 2 file.txt line line line
% cut -d e -f 1 file.txt on two lin three lin four
% sed 's/line/word/' file.txt one word two word three word four
% sed '/\(.*\) \(.*\)/!d; s//\1-"\2"/' one-"line" two-"line" three-"line"
% grep -F 'error' log.txt | cut -d ' ' -f 3 | sort | uniq -c | sort -rn 12 2013-03-05 7 2013-03-08 6 2013-03-04 4 2013-03-06 3 2013-03-02 1 2013-03-09
Build these up incrementally
% grep -Fq ':./bin:' <<<":$PATH:" || PATH="./bin:$PATH"
% printf "%s\n" "foo" "bar" |\ > grep "o" | sed 's/f/m/' moo
% for file in *; do > # ... > done
% if thing; then > # ... > fi
% fix_file() { > local file="$1" fixed_file > > # lower case letters, remove spaces etc > fixed_file="$( ... )" > > echo "$fixed_file" > }
% for file in *; do > fixed="$(fix_file "$file") > > mv "$file" "$fixed" > done
% ls -1 hot.rod.mp4 The Big Lebowski.m4v in-Bruges.iso bRick.mp4
% for file in *; do > echo "$file" > done hot.rod.mp4 The Big Lebowski.m4v in-Bruges.iso bRick.mp4
% var="hot.rod.mp4" % echo "${var%.*}" hot.rod % echo "%{var##*.}" mp4
% for file in *; do > title="${file%.*}" > ext="${file##*.}" > echo "$title ($ext)" > done hot.rod (mp4) The Big Lebowski (m4v) in-Bruges (iso) bRick (mp4)
% echo "A-really bad.title" | sed 's/[ -.]\+/_/g; s/.*/\L&/' "a_really_bad_title"
% for file in *; do > fixed="$(echo "${file%.*}" | sed 's/[ -.]\+/_/g; s/.*/\L&/')" > ext="${file##*.}" > echo "$fixed ($ext)" > done hot_rod (mp4) the_big_lebowski (m4v) in_bruges (iso) brick (mp4)
% for file in *; do > fixed="$(echo "${file%.*}" | sed 's/[ -.]\+/_/g; s/.*/\L&/')" > ext="${file##*.}" > mv -v "$file" "$fixed.$ext" > done ’hot.rod.mp4’ -> ’hot_rod.mp4’ ’The Big Lebowski.m4v’ -> ’the_big_lebowski.m4v’ ’in-Bruges.iso’ -> ’in_bruges.iso’ ’bRick.mp4’ -> ’brick.mp4’
% curl -s -L "https://github.com/hakimel/reveal.js/archive/2.6.1.tar.gz" | tar xvf - % mv reveal.js-2.6.1 my_talk % cd my_talk % vim index.html
#!/bin/sh talks="$HOME/Code/talks" reveal_version='2.6.1' reveal_src_url="https://github.com/hakimel/reveal.js/archive/${reveal_version}.tar.gz" title="$*" directory="$talks/$(printf "$title" | sed 's/.*/\L&/; s/ \+/_/g')" curl -L -# "$reveal_src_url" | tar fxz - mv "reveal.js-$reveal_version" "$directory" cat > "$directory/index.html" << EOF <!doctype html> <html lang="en"> <!-- ... --> </html> EOF
% ./new-talk Effective Shell % vim effective_shell/slides/title.md