class: center, middle, inverse # 像黑客一样使用 ``` _ _ | | (_) | | _ _ __ _ ___ __ | | | | '_ \| | | \ \/ / | |____| | | | | |_| |> < |______|_|_| |_|\__,_/_/\_\ ``` ## 命令行 ``` toy 2014.3.30 ``` --- class: inverse ## 我喜欢使用命令行的原因 ### - 功能强大 ``` % history | > awk '{CMD[$2]++;count++;}END \ > { for (a in CMD)print CMD[a] " " \ > CMD[a]/count*100 "% " a;}' | > grep -v "./" | > column -c3 -s " " -t | > sort -nr | > nl | > head -n10 ``` --- class: inverse ## 我喜欢使用命令行的原因 ### ``` 1 181 8.0516% ls 2 174 7.74021% git 3 167 7.42883% cd 4 163 7.25089% jq 5 154 6.85053% l 6 137 6.09431% vim 7 102 4.53737% rm 8 59 2.62456% ll 9 52 2.31317% echo 10 49 2.17972% ssh ``` ([source](http://linux.byexamples.com/archives/332/what-is-your-10-common-linux-commands/)) --- class: inverse ## 我喜欢使用命令行的原因 ### - 灵活高效 ``` % cd photos % ls -l | grep Mar ``` --- class: inverse ## 我喜欢使用命令行的原因 ### - 能自动化 ``` % ./script.sh ``` --- class: center, middle, inverse ## 魔法即将启幕...... --- class: center, middle, inverse ![Magic](img/unix-magic.jpg) --- class: inverse ## 人非圣贤,孰能无过? ### - 重新输入,然后执行 - 稍加编辑,再来执行 - ? --- class: inverse ## 人非圣贤,孰能无过? ### - 使用 ^ 删掉多余部分 ``` % grep fooo /var/log/auth.log % ^o % grep foo /var/log/auth.log ``` --- class: inverse ## 人非圣贤,孰能无过? ### - 使用 ^old^new 换掉输错或输少的部分 ``` % cat myflie % ^li^il % cat myfile % ansible vod -m command -a 'uptim' % ^im^ime % ansible vod -m command -a 'uptime' ``` --- class: inverse ## 人非圣贤,孰能无过? ### - 使用 !:gs/old/new 将 old 全部换成 new ``` % ansible nginx -m command -a 'which nginx' % !:gs/nginx/squid % ansible squid -m command -a 'which squid' % ^nginx^squid^:G # zsh ``` --- class: inverse ## 人非圣贤,孰能无过? ### #### 要记住的是: - 一删 - 二换 - 三全变 --- class: inverse ## 忘记历史,就是背叛。 ### - 了解历史记录的大小 ``` % echo $HISTSIZE 1000 ``` - 历史记录的保存位置 ``` % echo $HISTFILE /home/xiaodong/.zhistory ``` - 历史记录的保存大小 ``` % echo $HISTFILESIZE # bash 1000 % echo $SAVEHIST # zsh 1000 ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 查看历史 ``` % history % history | less 1 hist 2 ./code/gs/update_system.pl -n 3 emerge -C chromium 4 emerge @preserved-rebuild 5* df -h ...... % history 5 % history | grep string ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 Ctrl + r 逆向搜索历史命令 ``` % (reverse-i-search)`h': history 5 ``` - 使用 Ctrl + p 访问上一条命令 ``` % history 5 [Ctrl + p] ``` - 使用 Ctrl + n 访问下一条命令 ``` % [Ctrl + n] ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 !! 执行上一条命令 ``` % !! % sudo !! % apt-get install figlet E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root? % sudo !! sudo apt-get install figlet ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 !foo 执行以 foo 开头的命令 ``` % !his history ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 !?foo 执行包含 foo 的命令 ``` % !?is echo $histchars ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 !n 执行第 n 个命令 ``` % !10 vim lib/TunePage.pm ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 !-n 执行倒数第 n 个命令 ``` % !-2 htop % !-1 == !! ``` - Tip: 给命令提示符中增加历史命令编号 ``` % export PS1='!\! \u@\h:\w\$ ' !998 xiaodong@codetoy:~$ ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 使用 !# 引用当前行 ``` % cp filename filename.old % cp filename !#:1.old ``` --- class: inverse ## 忘记历史,就是背叛。 ### #### 关于历史引用,要记住的是: - !! - ![?]字符串 - ![-]数字 - !# --- class: inverse ## 忘记历史,就是背叛。 ### - 历史命令 Word 选取图 ![history words](img/hist-word.png) --- class: inverse ## 忘记历史,就是背叛。 ### - 通过 !$ 得到上一条命令的最后一位参数 ``` % mkdir videos % cd !$ % [Alt + .] ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 通过 !^ 得到上一条命令的第一个参数 ``` % ls /usr/share/doc /usr/share/man % cd !^ % [Ctrl + Alt + y] ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 通过 !:n 得到上一条命令第 n 个参数 ``` % touch foo.txt bar.txt baz.txt % vim !:2 vim bar.txt ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 通过 !:x-y 得到上一条命令从 x 到 y 的参数 ``` % touch foo.txt bar.txt baz.txt % vim !:1-2 vim foo.txt bar.txt ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 通过 !:n* 得到上一条命令从 n 开始到最后的参数 ``` % cat /etc/resolv.conf /etc/hosts /etc/hostname % vim !:2* vim /etc/hosts /etc/hostname ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 通过 !* 得到上一条命令的所有参数 ``` % ls code src % cp -r !* ``` --- class: inverse ## 忘记历史,就是背叛。 ### #### 关于 Word 选取,要记住的是: - n - ^|$ - [n]* - x-y ``` % !an:$ % !10:2-4 % !{an}2 ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :h 选取路径开头 ``` % ls /usr/share/fonts/truetype % cd !$:h cd /usr/share/fonts ``` - 相当于 dirname --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :t 选取路径结尾 ``` % wget http://nginx.org/download/nginx-1.4.7.tar.gz % tar zxvf !$:t tar zxvf nginx-1.4.7.tar.gz ``` - 相当于 basename --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :r 选取文件名 ``` % unzip filename.zip % cd !$:r cd filename ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :e 选取扩展名 ``` % echo abc.jpg % echo !$:e echo .jpg # bash .jpg echo jpg # zsh jpg ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :p 打印命令行 ``` % echo * README.md css img index.html js % !:p echo * ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :s 做替换 ``` % echo this that % !:s/is/e echo the that ``` - 惯用法: ^is^e --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :g 做全局操作 ``` % echo abcd abef % !:gs/ab/cd echo cdcd cdef cdcd cdef ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :u 将其更改为大写 (zsh) ``` % echo $histchars % echo !$:u echo $HISTCHARS ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 利用 :l 将其更改为小写 (zsh) ``` % echo !$:l echo $histchars ``` --- class: inverse ## 忘记历史,就是背叛。 ### #### 关于修饰符,要记住的是: - h|t - r|e - p - s - g - u|l ``` % ls /usr/share/fonts/opentype % echo !$:t:u echo OPENTYPE ``` --- class: inverse ## 忘记历史,就是背叛。 ### - 历史展开模式 ![History](img/hist.png) --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 alias -s 定义后缀别名 (zsh) ``` % alias -s pl=perl % script.pl perl script.pl % alias -s pdf=zathura % vimbook.pdf zathura vimbook.pdf ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 {} 构造字符串 ``` % cp file.c file.c.bak % cp file.c{,.bak} % echo cp file.c{,.bak} % vim {a,b,c}file.c vim afile.c bfile.c cfile.c % vim [abc]file.c # ? % vim {a..c}file.c # bash % setopt braceccl # zsh % vim {a-c}file.c # zsh ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 {} 构造字符串 (续) ``` % wget http://linuxtoy.org/img/{1..5}.jpg 1.jpg 2.jpg 3.jpg 4.jpg 5.jpg % touch {01..5}.txt 01.txt 02.txt 03.txt 04.txt 05.txt % touch {1..10..2}.txt 1.txt 3.txt 5.txt 7.txt 9.txt % echo {1..10..-2} # zsh 9 7 5 3 1 % echo {9..1..2} # bash 9 7 5 3 1 ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 {} 构造字符串 (续) ``` % mkdir -p 2014/{01..12}/{baby,photo} % echo {{A..Z},{a..z},{0..9}} ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 \`` 或 $() 做命令替换 ``` % grep -l error *.pm # (1) TunePage.pm % vim TunePage.pm # (2) % vim `grep -l error *.pm` % vim $(grep -l error *.pm) ``` - 嵌套时,$() 可读性更清晰,而 \`` 则较差 ``` % vim $(grep -l failed $(date +'%Y%m%d').log) % vim `grep -l failed \`date +'%Y%m%d'\`.log` ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用变量保存信息 ``` % LOG=/var/log/emerge.log % head $LOG % grep -i compiling $LOG ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 for ... in 重复执行命令 ``` % figlet -f font-type-1 Linux # (1) % figlet -f font-type-2 Linux # (2) % figlet -f font-type-3 Linux # (3) % ... % cd /usr/share/figlet % for font in *.flf > do > echo $font > figlet -f $font Linux > done % for font in *.flf; do echo $font; figlet -f $font Linux; done ``` --- class: inverse ## 常备锦囊,内藏妙计。 ### - 使用 for ... in 重复执行命令 (续) ``` % for dev in /dev/sd{a..d} > do > hdparm -t $dev > done ``` --- class: inverse ## 重要原则 ### - Type less, accomplish more (少打多做) - DRY, don't repeat yourself (不要重复你自己) - Care about your tool (关心你的工具) --- class: inverse ## 本讲之外 ### - Tab 补全 - 使用通配符 (* ? [a-z] [0-9]) - 用快捷键编辑命令行 - 字符串处理 - 复合命令 (; && ||) --- class: inverse ## 扩展阅读 ### ``` - bash: man history - zsh: man zshexpn - Bash Reference Manual: https://www.gnu.org/software/bash/manual/html_node/index.html - A User's Guide to ZSH: http://zsh.sourceforge.net/Guide/zshguide.html - Book: Unix Power Tools ``` --- class: center, middle, inverse ## Q & A --- class: inverse ## 联系方式 ### ``` - Website: http://linuxtoy.org - Twitter: http://twitter.com/linuxtoy - GitHub: http://github.com/xuxiaodong - Gmail: xxdlhy@gmail.com ``` --- class: center, middle, inverse ## 谢谢大家! --- class: center, middle, inverse Made in [Remark](http://remarkjs.com)