po主Linux/Unix奇菜无比,看到Toy大神的PPT《像黑客一样使用 Linux 命令行》 画面太美,就必须学习一下。
依然是用OSX冒充Linux…
Talk is cheap…
1. 有趣的历史命令统计脚本 用简单的几行命令找出shell执行过的历史命令中出镜率最高的10个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ➜ ~ 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 1 265 10.3962% git 2 258 10.1216% ls 3 205 8.04237% sudo 4 166 6.51236% man 5 164 6.4339% awk 6 118 4.62927% vi 7 92 3.60926% cd 8 80 3.13849% port 9 76 2.98156% cat 10 73 2.86387% ps
history
其实是fc -l 1
的别名,而fc
命令可以用来列出 、编辑 、重新执行 用户过去向Shell中输入的内容;
再用awk
过滤并统计history
的结果:取history返回值的第二列(命令名称),存入名为CMD 的映射并累加重复的命令,count 负责统计总命令数,统计结束后按行输出<命令执行的次数、占总命令数的百分比、该命令的名称>;
再用grep -v
去除那些带有'/'
的目录跳转(使用grep -vE "./| \."
对po主有奇效,因为po主有时会使用类似.ssh
的不规范写法进入一个目录);
再用column
命令造一个漂亮的表格;
再用sort
命令排序取逆;
再用nl
命令给结果加上序号;
再用head
命令取TOP10;
于是就漂亮的统计出了我的历史记录使用结果(看到man
和sudo
的排名就知道应该是个noob)。
2. 有用的执行的命令的修改 po主因为noob,不熟悉系统,经常在输入命令的时候出现typo…这也是没办法的事,如果重新键入,或是把历史记录掉出来再移动光标至输入错误处修改,就太麻烦了,还好shell可以帮我:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ➜ ~ finder ~ -iname "using-cli-like-a-hacker.md" zsh: command not found: finder ➜ ~ ^er ➜ ~ find ~ -iname "using-cli-like-a-hacker.md" /Users/zealot/blog/source /_posts/using-cli-like-a-hacker.md ➜ ~ echo "the ordre is incorrect" the ordre is incorrect ➜ ~ ^re^er ➜ ~ echo "the order is incorrect" the order is incorrect ➜ ~ echo "there is a typo" there is a typo ➜ ~ ^a^no ➜ ~ echo "there is no typo" there is no typo ➜ ~ ln /opt/local /bin/hub /usr/bin/hub ln: /opt/local /bin/hub: No such file or directory ➜ ~ ^hub^git^:G ➜ ~ ln /opt/local /bin/git /usr/bin/git
Toy神的口诀是:
一删(^er
)
二改(^a^no
)
三全换(^hub^git^:G
或!:gs/hub/git
)
3. 深入了解命令历史 3.1 历史记录属性: 1 2 3 4 5 6 7 8 9 10 11 12 ➜ ~ echo $HISTSIZE 10000 ➜ ~ echo $HISTFILE /Users/zealot/.zsh_history ➜ ~ echo $HISTFILESIZE 10000 ➜ ~ echo $SAVEHIST 10000
3.2 查看历史记录: 1 2 3 4 5 ➜ ~ history | less ➜ ~ history 5 history | grep string
1 2 ➜ ~ history | less bck-i-search: history |
按下[ctrl+P]访问前一条命令
按下[ctrl+N]访问下一条命令
3.3 关于!
的历史引用
这个很常用,特别是在没有权限的时候配合sudo
使用:
1 2 3 4 5 6 7 8 ➜ ~ port -v selfupdate ... failed: Permission denied ... ➜ ~ sudo !! ➜ ~ sudo port -v selfupdate Password: ...
1 2 ➜ ~ !port ➜ ~ port outdated
1 2 ➜ ~ !?out ➜ ~ port outdated
1 2 ➜ ~ !-9 ➜ ~ echo $HISTSIZE
注:!-1
== !!
。
1 2 ➜ ~ echo ! ➜ ~ echo echo
3.4 历史命令的Word选取
1 2 3 4 ➜ ~ mkdir videos ➜ ~ cd !$ ➜ ~ cd videos ➜ videos
也可以通过快捷键[alt+.]获得。
注:OSX上需要设置在Terminal->Terminal->Preferences->Settings->Keyboard中设置“Use option as meta key”,在iTerm上通常设置“left option key as +Esc”。
1 2 3 4 5 6 7 8 9 ➜ ~ ls /usr/share/doc /usr/share/man /usr/share/doc: ... /usr/share/man: ... ➜ ~ cd !^ ➜ ~ cd /usr/share/doc ➜ doc
也可以通过快捷键[Ctrl+Alt+Y]获得。(OSX上似乎不行…求指点)
* 使用!:n
得到上一条命令第n个参数:
1 2 3 ➜ ~ touch foo.txt bar.txt baz.txt ➜ ~ vim !:2 ➜ ~ vim bar.txt
1 2 3 ➜ ~ touch foo.txt bar.txt baz.txt ➜ ~ rm !:1-3 ➜ ~ rm foo.txt bar.txt baz.txt
使用!:n*
得到上一条命令中从第n个参数开始到最后的参数:
1 2 3 ➜ ~ cat /etc/resolv.conf /etc/hosts /etc/hostname ➜ ~ vim !:2* ➜ ~ vim /etc/hosts /etc/hostname
1 2 3 ➜ ~ ls src dst ➜ ~ cp -r !* ➜ ~ cp -r src dst
关于Word选取,需要记住的是:
n
:第n个参数;
^|$
:第一个参数|最后一个参数;
n*
:从第n个参数开始取到最后的参数;
x-y
:从第x个参数开始取到第y个参数;
3.5 历史命令的修饰符
1 2 3 4 ➜ ~ ls /usr/share/doc/bash/bash.html /usr/share/doc/bash/bash.html ➜ ~ ls !$:h ➜ ~ ls /usr/share/doc/bash
相当于使用dirname
命令。
1 2 3 4 ➜ ~ wget http://nginx.org/download/nginx-1.7.2.tar.gz ... ➜ ~ tar zxvf !$:t ➜ ~ tar zxvf nginx-1.7.2.tar.gz
相当于使用basename
命令。
1 2 3 4 5 6 ➜ ~ wget http://nginx.org/download/nginx-1.7.2.zip ... ➜ ~ unzip nginx-1.7.2.zip ... ➜ ~ cd !$:r ➜ ~ cd nginx-1.7.2
1 2 3 4 5 6 7 8 ➜ ~ echo filname.extension filname.extension ➜ ~ echo !$:e ➜ ~ echo extension .extension extension
1 2 3 4 ➜ ~ echo * ... ➜ ~ !:p ➜ ~ echo *
1 2 3 4 ➜ ~ echo this that this that ➜ ~ !:s/is/e ➜ ~ echo the that
也就是前面提到的“二改”:
1 2 3 4 ➜ ~ echo this that this that ➜ ~ ^is^e ➜ ~ echo the that
1 2 3 4 ➜ ~ echo abcd abef abcd abef ➜ ~ !:gs/ab/cd ➜ ~ echo cdcd cdef
也就是前面提到的“三全换”:
1 2 3 4 ➜ ~ echo abcd abef abcd abef ➜ ~ ^ab^cd ^:G ➜ ~ echo cdcd cdef
1 2 3 4 5 ➜ ~ echo $histfile ➜ ~ echo !$:u ➜ ~ echo $HISTFILE /Users/zealot/.zsh_history
1 2 3 4 5 ➜ ~ echo $HISTORY ➜ ~ echo !$:l ➜ ~ echo $history ...
关于修饰符,要记住的是:
h|t
:选取路径的开头|结尾;
r|e
:选取文件名|扩展名;
p
:打印命令;
s
:替换操作;
g
:全局操作;
u|l
:将参数改为大写|小写;
综上:
4. 常备锦囊,内藏妙计
1 2 3 ➜ ~ alias -s py=python3 ➜ ~ test.py python3 test.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ➜ ~ cp grade.txt{,.bak} ➜ ~ cp grade.txt grade.txt.bak ➜ ~ ➜ ~ vim {a,b,c}file.c ➜ ~ vim afile.c bfile.c cfile.c ➜ ~ ➜ ~ wget http://linuxtoy.org/img/{1..5}.jpg 1.jpg 2.jpg 3.jpg 4.jpg 5.jpg ➜ ~ ➜ ~ echo {01..5}.txt 01.txt 02.txt 03.txt 04.txt 05.txt ➜ ~ ➜ ~ echo 0{1..5}.txt 01.txt 02.txt 03.txt 04.txt 05.txt ➜ ~ ➜ ~ echo {1..10..2}.txt 1.txt 3.txt 5.txt 7.txt 9.txt ➜ ~ ➜ ~ echo {1..10..-2}.txt 9.txt 7.txt 5.txt 3.txt 1.txt ➜ ~ ➜ ~ echo {9..1..-2}.txt 1.txt 3.txt 5.txt 7.txt 9.txt ➜ ~ ➜ ~ mkdir -p 2014/{01..12}/{baby,photo}
1 2 3 4 ➜ ~ echo $(date +'%Y%m%d' ) 20140707 ➜ ~ echo `date +'%Y%m%d' ` 20140707
1 2 3 ➜ ~ LOG=/var/log /emerge.log ➜ ~ head $LOG ➜ ~ grep -i compiling $LOG
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ➜ ~ figlet -f font-type-1 Linux ➜ ~ figlet -f font-type-2 Linux ➜ ~ figlet -f font-type-3 Linux ➜ ~ ... ➜ ~ ➜ ~ cd /usr/share/figlet ➜ ~ for font in *.flf for > do for > echo $font for > figlet -f $font Linuxfor > done ... ➜ ~ for font in *.flf; do echo $font ; figlet -f $font Linux; done ➜ ~ ➜ ~ for dev in /dev/sd{a..d} for > do for > hdparm -t $dev for > done
5. 其他 5.1 重要原则
Type less, accomplish more (少打多做);
DRY, don’t repeat yourself (不要重复你自己);
Care about your tool (关心你的工具);
5.2. 此外…
Tab
补全;
使用通配符 (*
, ?
, [a-z]
, [0-9]
);
用快捷键编辑命令行;
字符串处理;
复合命令 (;
, &&
, ||
);
5.3 扩展阅读:
ps: 关于awk
, sed
, grep
等复杂命令,以后再详解。
-EOF-