终端小技巧
1. sudo !!
主要是利用了shell(bash)的History Expansion
,我们使用history命令时能够列举执行的历史命令列表:
$ history
1 tar cvf etc.tar /etc/
2 cp /etc/passwd /backup
3 ps -ef | grep http
4 service sshd restart
5 /usr/local/apache2/bin/apachectl restart
每个命令前面是命令编号,如果要重复执行某个命令,只需要输入!
加命令编号即可,比如以上需要再次重启sshd服务,只需要执行:
!4
!
后面如果是负数,则表示执行前第N个命令,比如!-1
表示执行上一个命令,!-5
则表示执行倒数第5个命令,执行上一个命令也可以使用!!
替代,即!-1
和!!
是等价的,通常使用!!
会更便捷。一个典型的场景是执行一条命令时需要root权限,忘记输入sudo
了,只需要执行以下命令即可:
sudo !!
关于bash的History Expansion参考Linux Bash History Expansion Examples You Should Know。
2. ^status^restart
我们经常可能需要重复执行上一条命令,但需要修改个别参数,比如我们使用systemctl
查看nova-compute服务状态:
systemctl status openstack-nova-compute
如果我们发现服务异常,紧接下来的操作很可能是想重启下服务,此时只需要执行以下命令即可:
^status^restart
以上命令会自动替换为:
systemctl restart openstack-nova-compute
3. 使用编辑器编辑长命令
我们经常遇到需要输入非常长的命令的情况,此时如果在shell里直接输入会特别麻烦,并且不好处理换行情况,此时可以调用本地编辑器编辑命令,输入ctrl-x
+ ctrl-e
即可。
4. 终端快捷键
终端下几个常见的快捷键:
ctrl-a
: 移动光标到行首。ctrl-e
: 移动光标到行尾。ctrl-w
: 剪切光标前一个单词(注意是剪切,不是彻底删除,可以通过ctrl-y
粘贴。ctrl-u
: 剪切光标之前的所有内容,如果光标位于行尾,则相当于剪切整行内容。ctrl-k
: 剪切光标之后的所有内容,有点类似vim的D
命令。ctrl-y
:粘贴剪切的内容。ctrl-p
、ctrl-n
:向前/向后查看历史命令,和方向键的UP和Down等价。ctrl-l
: 清屏,相当于执行clear
命令,注意不会清除当前行内容。ctrl-h
: 向前删除一个字符,相当于回退键。
一个典型场景,输了一大串命令A还未执行,发现需要执行另一条命令B,又不想开启一个新的终端,怎么保存当前输入的内容A呢,有两种方式:
- 使用
ctrl-u
剪切整行内容A,执行完B命令后,使用ctrl-y
恢复,在此之前不能有其它剪切操作,否则内容会被覆盖. - 使用
ctrl-a
移动光标到行首,输入#
注释当前行内容后直接回车,这相当于注释了当前行,但在history中依然会有记录,恢复时只需要使用ctrl-p
找到刚刚的命令,去掉#
即可。
命令行工具
ag
比grep、ack更快地递归搜索文件内容。
tig
字符模式下交互查看git项目。
mycli
mysql客户端,支持语法高亮和命令补全,效果类似ipython,可以替代mysql命令,效果如图:
jq
json文件格式化处理以及高亮显示,可以替换python -m json.tool
, 比如有以下json数据:
{"migration_status": null, "attachments": [{"server_id": "80380c28-c765-448a-aa9a-c9bd5b10d64c", "attachment_id": "ba0d25c9-1066-4c49-9f05-3096d2596a44", "attached_at": "2017-03-28T02:56:24.000000", "host_name": null, "volume_id": "8cbea52c-be0d-4bf1-86f8-890b538d0771", "device": "/dev/vdb", "id": "8cbea52c-be0d-4bf1-86f8-890b538d0771"}], "links": [{"href": "http://192.168.0.156:8776/v2/abca38105b4345acbaad30d7fbf59e7d/volumes/8cbea52c-be0d-4bf1-86f8-890b538d0771", "rel": "self"}, {"href": "http://192.168.0.156:8776/abca38105b4345acbaad30d7fbf59e7d/volumes/8cbea52c-be0d-4bf1-86f8-890b538d0771", "rel": "bookmark"}], "availability_zone": "nova", "os-vol-host-attr:host": "cinder@ssd-ceph#ssd-ceph", "encrypted": false, "updated_at": "2017-03-28T02:56:24.000000", "replication_status": "disabled", "snapshot_id": null, "id": "8cbea52c-be0d-4bf1-86f8-890b538d0771", "size": 100, "user_id": "33ec3ec44f5440bca7760771b1f20ea6", "os-vol-tenant-attr:tenant_id": "abca38105b4345acbaad30d7fbf59e7d", "os-vol-mig-status-attr:migstat": null, "metadata": {"readonly": "False", "attached_mode": "rw"}, "status": "in-use", "volume_image_metadata": {}, "description": null, "multiattach": false, "source_volid": null, "consistencygroup_id": null, "os-vol-mig-status-attr:name_id": null, "name": "swift-1", "bootable": "false", "created_at": "2017-03-28T02:43:57.000000", "volume_type": null}
使用jq格式化输出如图:
使用jq还可以应用各种filter,从而只输出我们感兴趣的字段:
shellcheck
shell脚本静态检查工具,能够识别语法错误以及不规范的写法。
比如有以下shell脚本test.sh
:
#!/bin/bash
a=1
b=2
for i in @; do
echoi
done
echo $a
使用shellcheck检查结果如下:
yapf
Google开发的python代码格式规范化工具,支持pep8以及Google代码风格。
yapf -i --style pep8 --recursive src/
mosh
可以替代ssh,连接更稳定,即使IP变了,也能自动重连。
fzf
命令行下模糊搜索工具,能够交互式智能搜索并选取文件或者内容。
fzf
该命令还有一个最经典的应用是历史命令搜索,按下CTRL-R,结果如下:
PathPicker(fpp)
在命令行输出中自动识别目录和文件,交互式选择后使用EDTOR打开.
git diff HEAD~8 --stat
输出如下:
git diff HEAD~8 --stat | fpp
可以光标选择文件打开或者执行命令:
绿色显示的表示我们选中的文件,此时输入enter键将调用编辑器打开选中的文件,也可以按c进入命令模式,可以输入执行的命令,选中的文件将作为命令的输入文件。
pandoc
Markdown,HTML,PDF,LaTEX等文档格式之间的命令行转换工具。
支持PDF转化需要依赖pdflatex:
brew cask install mactex
把README.md
转化为PDF格式:
pandoc -f markdown_github -t latex -o README.pdf README.md
htop
可以代替top命令,提供更美观、更方便的进程监控工具。
axel
多线程下载工具,下载大文件时可以替代curl、wget。
axel -n 20 http://centos.ustc.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso
yum、gentoo partage等包管理工具能配置axel为下载工具替代curl。
CentOS系统需要安装yum-axelget插件,安装和配置过程如下:
yum install axel yum-plugin-fastestmirror yum-axelget
修改/etc/yum/pluginconf.d/axelget.conf
配置文件,根据需求调整maxconn
值。
Homebrew从2013年开始提出使用axel作为下载工具,但目前好像尚未实现,参考#19802。
sz/rz
ssh登录到服务器后经常需要传输文件, 通常我们会使用scp/rsync工具,或者使用ftp/nc等命令,临时解决办法还可以使用python -m SimpleHTTPServer
或者python3 -m http.server
开启HTTP服务器使用浏览器下载。
sz/rz能够提供更简单的交互式接口快速地和本地主机进行文件传输,也就是上传和下载文件到服务器和本地。
运行:
sz a.txt b.txt c.txt
会立即弹出本地文件管理窗口选择保存位置,不需要输入密码。
同样地,运行:
rz
会弹出本地文件管理工具,选择需要传输的文件,能够快速传输到当前服务器工作目录下。
注意:
- sz/rz目前不支持tmux(加上
-e
参数也无效), 因此不能在tmux session下执行rz/sz,否则会hang住。 - Windows下使用xshell登录服务器,只需要在远程服务器安装lrzsz包即可,不需要在本地windows做任何配置。
- 在Mac下,本地和远程服务器都需要安装lrzsz包,并且iterm2需要配置,参考ZModem integration for iTerm 2
cloc
cloc是代码统计工具,能够统计代码的空行数、注释行、编程语言等,如图:
you-get
从网页中自动捕捉视频、音频、图片并下载到本地,支持youtube、google+、优酷、芒果TV、腾讯视频、秒拍等。
$ you-get 'https://www.youtube.com/watch?v=jNQXAC9IVRw'
site: YouTube
title: Me at the zoo
stream:
- itag: 43
container: webm
quality: medium
size: 0.5 MiB (564215 bytes)
# download-with: you-get --itag=43 [URL]
Downloading zoo.webm ...
100.0% ( 0.5/0.5 MB) ├████████████████████████████████████████┤[1/1] 7 MB/s
Saving Me at the zoo.en.srt ...Done.
thefuck
命令输错,fuck!
script/scriptreplay
视频录制有很多工具,但如果是终端录制则使用script非常方便。
开始录制:
script -t 2>time.txt session.typescript # 开始录制
[root@mistral ~]# ls
dotfiles mistral mistral-actions openrc session.typescript time.txt workbook.yaml workflows
[root@mistral ~]# date
Wed May 3 20:21:14 CST 2017
[root@mistral ~]# cal
May 2017
Su Mo Tu We Th Fr Sa
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 26 27
28 29 30 31
[root@mistral ~]# exit #结束录制
session回放:
scriptreplay -t time.txt session.typescript
cheat
命令笔记,保存一些有用但是老是记不住的命令。
比如OpenStack的nova
命令,只需要把有用的命令保存到~/.cheat/nova
文件中:
➜ nova git:(mitaka) ✗ cat ~/.cheat/nova
# To list VMs on current tenant:
nova list
# To list VMs of all tenants (admin user only):
nova list --all-tenants
# To boot a VM on a specific host:
nova boot --nic net-id=<net_id> \
--image <image_id> \
--flavor <flavor> \
--availability-zone nova:<host_name> <vm_name>
# To stop a server
nova stop <server>
# To start a server
nova start <server>
# To attach a network interface to a specific VM:
nova interface-attach --net-id <net_id> <server>
要用的时候,使用cheat
查询:
➜ nova git:(mitaka) ✗ cheat nova
# To list VMs on current tenant:
nova list
# To list VMs of all tenants (admin user only):
nova list --all-tenants
# To boot a VM on a specific host:
nova boot --nic net-id=<net_id> \
--image <image_id> \
--flavor <flavor> \
--availability-zone nova:<host_name> <vm_name>
# To stop a server
nova stop <server>
# To start a server
nova start <server>
# To attach a network interface to a specific VM:
nova interface-attach --net-id <net_id> <server>
如果连命令都忘了,cheat还支持模糊搜索:
➜ nova git:(mitaka) ✗ cheat -s 'nov'
nova:
nova list
nova list --all-tenants
nova boot --nic net-id=<net_id> \
--availability-zone nova:<host_name> <vm_name>
nova stop <server>
nova start <server>
nova interface-attach --net-id <net_id> <server>
cheat还收集了一些常用的命令,比如tar
:
# To extract an uncompressed archive:
tar -xvf /path/to/foo.tar
# To create an uncompressed archive:
tar -cvf /path/to/foo.tar /path/to/foo/
# To extract a .gz archive:
tar -xzvf /path/to/foo.tgz
# To create a .gz archive:
tar -czvf /path/to/foo.tgz /path/to/foo/
# To list the content of an .gz archive:
tar -ztvf /path/to/foo.tgz
# To extract a .bz2 archive:
tar -xjvf /path/to/foo.tgz
# To create a .bz2 archive:
tar -cjvf /path/to/foo.tgz /path/to/foo/
# To list the content of an .bz2 archive:
tar -jtvf /path/to/foo.tgz
# To create a .gz archive and exclude all jpg,gif,... from the tgz
tar czvf /path/to/foo.tgz --exclude=\*.{jpg,gif,png,wmv,flv,tar.gz,zip} /path/to/foo/
# To use parallel (multi-threaded) implementation of compression algorithms:
tar -z ... -> tar -Ipigz ...
tar -j ... -> tar -Ipbzip2 ...
tar -J ... -> tar -Ipixz ...
Mac专有的命令行工具
say
文本朗读工具,支持各种怪异(恐怖)的声音和语气。在终端下跑这个命令体验所有的声音,小心别被吓着了:
for i in `say -v '?' | cut -d ' ' -f 1`; do echo i && say -v "i" 'Hello World';done
pbcopy/pbpaste
pbcopy把终端输出通过管道传到系统粘贴板:
cat test.sh | pbcopy
pbpaste把系统粘贴板内容输出到终端:
pbpaste
这篇文章写得深入浅出,让我这个小白也看懂了!