优化终端——一些小技巧与命令行工具 - 张再筵的博客

/ 1评 / 0

终端小技巧

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. 终端快捷键

终端下几个常见的快捷键:

一个典型场景,输了一大串命令A还未执行,发现需要执行另一条命令B,又不想开启一个新的终端,怎么保存当前输入的内容A呢,有两种方式:

  1. 使用ctrl-u剪切整行内容A,执行完B命令后,使用ctrl-y恢复,在此之前不能有其它剪切操作,否则内容会被覆盖.
  2. 使用ctrl-a移动光标到行首,输入#注释当前行内容后直接回车,这相当于注释了当前行,但在history中依然会有记录,恢复时只需要使用ctrl-p找到刚刚的命令,去掉#即可。

命令行工具

ag

比grep、ack更快地递归搜索文件内容。

ag

tig

字符模式下交互查看git项目。

tig

mycli

mysql客户端,支持语法高亮和命令补全,效果类似ipython,可以替代mysql命令,效果如图:

mycli demo

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 demo

使用jq还可以应用各种filter,从而只输出我们感兴趣的字段:

jq filter

shellcheck

shell脚本静态检查工具,能够识别语法错误以及不规范的写法。

比如有以下shell脚本test.sh:

#!/bin/bash
a=1
b=2
for i in @; do
    echoi
done
echo $a

使用shellcheck检查结果如下:

shellcheck

yapf

Google开发的python代码格式规范化工具,支持pep8以及Google代码风格。

yapf -i --style pep8 --recursive src/

mosh

可以替代ssh,连接更稳定,即使IP变了,也能自动重连。

fzf

命令行下模糊搜索工具,能够交互式智能搜索并选取文件或者内容。

fzf

fzf

该命令还有一个最经典的应用是历史命令搜索,按下CTRL-R,结果如下:

fzf history search

PathPicker(fpp)

在命令行输出中自动识别目录和文件,交互式选择后使用EDTOR打开.

git diff HEAD~8 --stat

输出如下:

git-diff

git diff HEAD~8 --stat | fpp

可以光标选择文件打开或者执行命令:

fpp-demo

绿色显示的表示我们选中的文件,此时输入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命令,提供更美观、更方便的进程监控工具。

htop

axel

多线程下载工具,下载大文件时可以替代curl、wget。

axel -n 20 http://centos.ustc.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso

axel

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

会弹出本地文件管理工具,选择需要传输的文件,能够快速传输到当前服务器工作目录下。

注意:

cloc

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!

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

参考

  1. vim-sdf13
  2. 所需即所获:像 IDE 一样使用 vim
  1. jiyouzhan说道:

    这篇文章写得深入浅出,让我这个小白也看懂了!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注