bash的全称是Bourne Again Shell,是大多数linux发行版以及OSX系统的默认shell,win10可以开启开发者模式来使用bash,因此bash是目前所有主流操作系统中都可以使用的命令行环境。

一.写在前面

这篇文章只是介绍一些非常好用,但我总是记不住的bash小技巧。按照惯例,先来做个小测验,如果你对!!,!-1,!$,!*分表代表什么了然于心,我想你应该不需要读这篇文章。

二.快捷键

bash快捷键默认使用的是readline库的Emacs模式,因此如果你是Emacs党,可以直接跳过这一节。

  • 历史命令
    一个常见的应用场景是你需要重试之前输入过的某条命令,常见的做法是不停的按上下箭头来找出那条命令,我个人则比较喜欢ctrl+p(arrow up)与ctrl+n(arrow down),也可以通过history配合grep来查找命令。而这里推荐的方法是使用Ctrl+r,然后输入你想要的命令中含有的单词,之后会出现含有这个单词的命令,如果它不是你想要的命令,就继续按Ctrl+r,直到找到你要的命令为止。中途你还可以继续输入查找字符,总之谁用谁知道。

  • 移动光标
    常见的应用场景是洋洋洒洒敲了一大串命令,结果发现命令中有几个字母输错了,又或者是忘了加sudo,这时候常见的做法是按arrow left键移动光标到指定的位置,当然也不妨尝试下面的快捷键。

    • ctrl+b 相当于arrow left
    • ctrl+f 相当于arrow right
    • alt+b 向前移动一个单词
    • alt+f 向后移动一个单词
    • ctrl+a 移至行首,相当于home
    • ctrl+e 移至行尾,相当于end
    • ctrl+xx 在命令行首和光标当前位置之间移动
  • 编辑
    像我这种手残党使用backspace删除单词时,经常不小心多按或者少按,这时候就体现出按单词删除的优越性了,但是我不仅手残,脑袋也不怎么灵光,ctrl+w与alt+d的效果经常弄混有没有?没关系,可以使用ctrl+/来撤销编辑了。下面列出我觉得比较有价值的编辑快捷键。
    • ctrl+w 向前删除一个单词
    • alt+d 向后删除一个单词
    • ctrl+k 删除当前光标到行尾的字符
    • ctrl+u 删除当前光标到行首的字符
    • alt+u 将字母转为大写(光标处至词尾)
    • alt+l 将字母转为小写(光标处至词尾)
    • alt+. 获取上条命令最后一个参数
    • ctrl+/ 撤销

三.历史扩展(History Expansion)

Bash 的历史扩展又被称为 Bang(!) 命令,是 bash 将历史命令转换到可执行命令的过程。历史扩展中操作历史命令一般有两个部分,即先从历史命令中找出相应的命令,被选中的命令称为Event,bash会将选中的Event以空格分割成Words,之后再使用单词指示器选择部分或全部的Word到当前行中。

  • 事件指示器(Event Designators)
    这次我们又行云流水的敲了一大串命令,自信回车一气呵成,结果系统提示“权限不够”,是不是很尴尬?通过上面的介绍,想必你应该马上能想到使用ctrl+p翻出上一条命令,再使用ctrl+a将光标移至行首,添加sudo执行。不过这里还有更加优雅的方式,直接执行sudo !!,这里 !! 中的第一个感叹号代表开始历史替换,而第二份感叹号则是事件指示器,下面有更详细的用法。
    • n 选择历史命令列表中第n条命令
    • -n 选择倒数第n条命令
    • ! 选择上一条命令, 相当于-1
    • string 选择最近的以string开头的命令
    • ?string[?] 选择最近的包含string的命令, 如果该指示器后面是换行符, 则可以不用输入结尾的[?]
    • # 引用目前输入的所有命令
  • 单词指示器(Word Designators)
    有时候我们只想要获取上条命令的参数,而不包含命令本身。比如说我先执行了

    1
    bower install react react-dom ...(此处省略100多个库你懂得) --save

    之后发现自己又sb了,应该改用npm来执行同样的命令,这时可以输入

    1
    npm !*

    其效果等同于

    1
    npm install react react-dom ... --save

    这里 !* 中的 * 就是单词指示器,也许你发现了这里并没有指定事件,如果没有事件指示器,则单词指示器的操作条目默认是上一条命令,因此 !* 其实相当于 !!* 。一般情况下事件指示器与单词指示器需要以 : 分隔,但如果单词指示器是以 ^,$,*,-,% 开头时,可以省略 : ,因此 !* 的完整形式是 !!:* ,下面是其它单词指示器。

    • n 选择第n个word,如果是0则选择的是命令
    • ^ 选择第一个参数,相当于1
    • $ 选择最后一个word
    • n1-n2 选择第n1到第n2个word
    • * 选择命令的所有参数, 相当于1-$
    • n* 相当于n-$
  • 修饰符(Modifiers)
    在单词指示器后面其实还可以添加修饰符,同样以 : 分隔,比如!!:*:p会打印上条命令的所有参数,但不会执行。这个特性我不是很常用,为了合理(lang)利用(de)脑容量(ji),这里就不罗列了,有兴趣的读者可以在参考链接中查看更详细的内容。

参考链接: