Bash 行操作

    这个库默认采用 Emacs 快捷键,也可以改成 Vi 快捷键。

    下面的命令可以改回 Emacs 快捷键。

    如果想永久性更改编辑模式(Emacs / Vi),可以将命令写在~/.inputrc文件,这个文件是 Readline 的配置文件。

    1. set editing-mode vi

    本章介绍的快捷键都属于 Emacs 模式。Vi 模式的快捷键,读者可以参考 Vi 编辑器的教程。

    Bash 默认开启这个库,但是允许关闭。

    1. $ bash --noediting

    上面命令中,--noediting参数关闭了 Readline 库,启动的 Bash 就不带有行操作功能。

    光标移动

    Readline 提供快速移动光标的快捷键。

    • Ctrl + a:移到行首。
    • Ctrl + b:向行首移动一个字符,与左箭头作用相同。
    • Ctrl + e:移到行尾。
    • Ctrl + f:向行尾移动一个字符,与右箭头作用相同。
    • Alt + f:移动到当前单词的词尾。
    • Alt + b:移动到当前单词的词首。

    上面快捷键的 Alt 键,也可以用 ESC 键代替。

    Ctrl + l快捷键可以清除屏幕,即将当前行移到屏幕的第一行,与clear命令作用相同。

    编辑操作

    下面的快捷键可以编辑命令行内容。

    • Ctrl + d:删除光标位置的字符(delete)。
    • Ctrl + w:删除光标前面的单词。
    • Ctrl + t:光标位置的字符与它前面一位的字符交换位置(transpose)。
    • Alt + t:光标位置的词与它前面一位的词交换位置(transpose)。
    • Alt + l:将光标位置至词尾转为小写(lowercase)。
    • Alt + u:将光标位置至词尾转为大写(uppercase)。

    使用Ctrl + d的时候,如果当前行没有任何字符,会导致退出当前 Shell,所以要小心。

    剪切和粘贴快捷键如下。

    • Ctrl + k:剪切光标位置到行尾的文本。
    • Ctrl + u:剪切光标位置到行首的文本。
    • Alt + d:剪切光标位置到词尾的文本。
    • Alt + Backspace:剪切光标位置到词首的文本。
    • Ctrl + y:在光标位置粘贴文本。

    同样地,Alt 键可以用 Esc 键代替。

    如果符合条件的命令或路径有多个,就需要连续按两次 Tab 键,Bash 会提示所有符合条件的命令或路径。

    除了命令或路径,Tab 还可以补全其他值。如果一个值以$开头,则按下 Tab 键会补全变量;如果以~开头,则补全用户名;如果以@开头,则补全主机名(hostname),主机名以列在/etc/hosts文件里面的主机为准。

    自动补全相关的快捷键如下。

    • Alt + ?:列出可能的补全,与连按两次 Tab 键作用相同。
    • Alt + /:尝试文件路径补全。
    • Ctrl + x /:先按Ctrl + x,再按/,等同于Alt + ?,列出可能的文件路径补全。
    • Alt + !:命令补全。
    • Ctrl + x !:先按Ctrl + x,再按!,等同于Alt + !,命令补全。
    • Alt + ~:用户名补全。
    • Ctrl + x ~:先按Ctrl + x,再按~,等同于Alt + ~,用户名补全。
    • Alt + $:变量名补全。
    • Ctrl + x $:先按Ctrl + x,再按$,等同于Alt + $,变量名补全。
    • Alt + @:主机名补全。
    • :先按Ctrl + x,再按@,等同于Alt + @,主机名补全。
    • Alt + *:在命令行一次性插入所有可能的补全。
    • Alt + Tab:尝试用.bash_history里面以前执行命令,进行补全。

    上面的Alt键也可以用 ESC 键代替。

    操作历史

    Bash 会保留用户的操作历史,即用户输入的每一条命令都会记录。退出当前 Shell 的时候,Bash 会将用户在当前 Shell 的操作历史写入~/.bash_history文件,该文件默认储存500个操作。

    环境变量HISTFILE总是指向这个文件。

    有了操作历史以后,就可以使用方向键的,快速浏览上一条和下一条命令。

    下面的方法可以快速执行以前执行过的命令。

    1. $ echo Hello World
    2. Hello World
    3. $ echo Goodbye
    4. Goodbye
    5. $ !e
    6. echo Goodbye
    7. Goodbye

    上面例子中,!e表示找出操作历史之中,最近的那一条以e开头的命令并执行。Bash 会先输出那一条命令echo Goodbye,然后直接执行。

    同理,!echo也会执行最近一条以echo开头的命令。

    1. $ !echo
    2. echo Goodbye
    3. Goodbye
    4. $ !echo H
    5. echo Goodbye H
    6. Goodbye H
    7. echo Goodbye H G
    8. Goodbye H G

    注意,!string语法只会匹配命令,不会匹配参数。所以!echo H不会执行echo Hello World,而是会执行echo Goodbye,并把参数H附加在这条命令之后。同理,!echo H G也是等同于echo Goodbye命令之后附加H G

    最后,按下Ctrl + r会显示操作历史,可以用方向键上下移动,选择其中要执行的命令。也可以键入命令的首字母,Shell 就会自动在历史文件中,查询并显示匹配的结果。

    history命令能显示操作历史,即.bash_history文件的内容。

    1. $ history
    2. ...
    3. 498 echo Goodbye
    4. 499 ls ~
    5. 500 cd

    通过定制环境变量HISTTIMEFORMAT,可以显示每个操作的时间。

    上面代码中,%F相当于%Y - %m - %d%T相当于%H : %M : %S

    只要设置HISTTIMEFORMAT这个环境变量,就会在.bash_history文件保存命令的执行时间戳。如果不设置,就不会保存时间戳。

    如果不希望保存本次操作的历史,可以设置环境变量HISTSIZE等于0。

    1. export HISTSIZE=0

    如果HISTSIZE=0写入用户主目录的~/.bashrc文件,那么就不会保留该用户的操作历史。如果写入/etc/profile,整个系统都不会保留操作历史。

    如果想搜索某个以前执行的命令,可以配合grep命令搜索操作历史。

    1. $ history | grep /usr/bin

    上面命令返回.bash_history文件里面,那些包含/usr/bin的命令。

    操作历史的每一条记录都有编号。知道了命令的编号以后,可以用感叹号 + 编号执行该命令。如果想要执行.bash_history里面的第8条命令,可以像下面这样操作。

    1. $ !8

    history命令的-c参数可以清除操作历史。

    下面是一些与操作历史相关的快捷键。

    • Ctrl + p:显示上一个命令,与向上箭头效果相同(previous)。
    • Ctrl + n:显示下一个命令,与向下箭头效果相同(next)。
    • Alt + <:显示第一个命令。
    • Alt + >:显示最后一个命令,即当前的命令。
    • Ctrl + o:执行历史文件里面的当前条目,并自动显示下一条命令。这对重复执行某个序列的命令很有帮助。

    感叹号!的快捷键如下。

    • !!:执行上一个命令。
    • !n:执行历史文件里面行号为n的命令。
    • !-n:执行当前命令之前n条的命令。
    • !string:执行最近一个以指定字符串string开头的命令。
    • !?string:执行最近一条包含字符串string的命令。
    • ^string1^string2:执行最近一条包含string1的命令,将其替换成string2
    • Ctrl + j:等同于回车键(LINEFEED)。
    • Ctrl + m:等同于回车键(CARRIAGE RETURN)。
    • Ctrl + o:等同于回车键,并展示操作历史的下一个命令。
    • Ctrl + v:将下一个输入的特殊字符变成字面量,比如回车变成^M
    • Ctrl + [:等同于 ESC。
    • Alt + .:插入上一个命令的最后一个词。
    • Alt + _:等同于Alt + .

    上面的Alt + .快捷键,对于很长的文件路径,有时会非常方便。因为 Unix 命令的最后一个参数通常是文件路径。

    1. $ mkdir foo_bar
    2. $ cd #按下 Alt + .

    上面例子中,在cd命令后按下,就会自动插入foo_bar