The Art of Command Line (2021)

Believe it or not, the shell script is getting more impactful in the DevOps era!

marp theme paginate
true
gaia
true

The Art of Command Line

2021-02-22

Kenta Yamamoto (@i05) This work is licensed under a Creative Commons Attribution 4.0 International License


Unix Philosophy – “The Art of UNIX Programming” (2003)

raymond-2003


Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new features.

$ history | awk '{ print $2 }' | sort | uniq -c | awk '$1>1' | sort -r | head
    791 g
    172 cat
    115 git
     83 echo
     71 brew
     70 yarn
     68 ll
     50 dig
     49 gcloud
     43 jj

For example, you have to sort the output before uniq because they only do one thing:

$ history | awk '{ print $2 }' | sort | uniq -c | awk '$1>1' | sort -r | head

Execute a shell script:

#!/usr/bin/env bash
# command-ranking.sh
set -euo pipefail
history | awk '{ print $2 }' | sort | uniq -c | awk '$1>1' | sort -r
$ chmod u+x ./command-ranking.sh
$ bash ./command-ranking.sh | head

Interface – standard streams:

  • STDIN
  • STDOUT
  • STDERR
$ time curl -IL https://example.com/ 2>&1 > file.txt
$ time curl -IL https://example.com/
...
curl -IL https://example.com/  0.02s user 0.01s system 5% cpu 0.467 total

Parameters – $0, $1, $#, $@

#!/usr/bin/env bash
# sample.sh
cat -
echo "file=$0, 1st-arg=$1, 2nd-arg=$2, arg-num=$# args=$@"
$ echo "Hello" | bash $(pwd)/sample.sh foo bar baz
Hello
file=/Users/kyamamoto/src/bitbucket.org/i05/support/sample.sh, 1st-arg=foo, 2nd-arg=bar, arg-num=3 args=foo bar baz

Sounds of Silence – $?

$ touch ~/tmp/sample.txt
$ echo $?
0
$ mv no-such-file.txt /tmp/
mv: cannot stat 'no-such-file.txt': No such file or directory
$ echo $?
1

Subroutine – $(command)

$ curl "https://jpnic.rdap.apnic.net/ip/$(dig +short myip.opendns.com @resolver1.opendns.com)" \
| jq .

Construct argument list – xargs:

$ find . -type f -name "*" ! -path '*/.svn/*' ! -path '*/.git/*' -print0 \
| xargs -0 grep --ignore-case --line-number 'foo'

Parallel execution – xargs:

$ find . -type f -not -name '*.bz2' -print0 \
| xargs -0 -L 1 -P $(sysctl -n hw.ncpu) bzip2

Multibyte encoding – nkf:

$ find . -type f -name "*.txt" | xargs nkf --guess
$ find . -type f -print0 | xargs -0 nkf --overwrite -w

Multiline:

TEXT_LIST=$(cat << EOF
__HERE_DOCUMENT__
__HERE_DOCUMENT__
EOF
)

Runs everywhere:

case "${OSTYPE}" in
# Mac
darwin*)
    [ -f ~/.zshrc.osx ] && . ~/.zshrc.osx
    ;;
# Linux
linux*)
    [ -f ~/.zshrc.linux ] && . ~/.zshrc.linux
    ;;
esac

Pitfall

  • Mac – BSD
    • or consider installing brew install gnu-sed instead
$ LANG=C find . -type f -name "*" ! -path '*/.svn/*' ! -path '*/.git/*' -print0 \
| xargs -0 sed -i '~' -e 's///gi'
  • Linux – GNU
$ find . -type f -name "*" ! -path '*/.svn/*' ! -path '*/.git/*' -print0 \
| xargs -0 sed -i -e 's///gi'

Pitfall

  • Mac – BSD
$ LANG=C git ls-files -z | xargs -0 sed -i '' -e 's///gi'`
  • Linux – GNU
$ git ls-files -z | xargs -0 sed -i -e 's///gi'

Git subcommands:

$ git grep 'Could not find the specified attachment on the server'

Release your brain resource:

  • Easily navigate directories – go with fewer cds!
  • Remote repository management – let the tool decide where to locate the cloning repositories

Recommended commands:

  • jq
  • awk
  • rsync
  • time
  • watch

Linter:


$ echo "Thank you!"


view raw deck.md hosted with ❤ by GitHub

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中