Linux下更高效的使用Bash——快捷键

在Linux下,Bash的地位无可忽视,日常中涉及到Linux下的管理与操作基本都是在Bash中进行,因此,为了提高Linux下工作效率,自然而然的就变成了如何高效使用Bash的问题。虽然上一篇Shell下的一些特殊字符在使用的时候,能够一定程度上提高效率,后一篇关于Bash下的历史扩展也能很大程度提高效率,但Bash上的一些快捷键才是提高效率的最简单也是最直接方式。本文正是奔着这个目标来的!

快捷键的一些说明:

  1. C = CTL = CTRL = CONTROL:这个键是指PC键盘上的Ctrl键
  2. M = ALT:这个键是PC键盘上的ALT键,如果你键盘上没有这个键,可以尝试使用ESC键代替
  3. S = SHIFT:此键是PC上的Shift键
  4. E = ESC:这个键是PC键盘上的ESC键,此键一般在键盘的左上角
  5. DEL = Backspace:此键是是PC键盘上的Backspace键,一般位于主键盘区的右上角
  6. 文中"[]"括住的为快捷键内容,"-"两边的内容是按住左边键,再按右边键获得,","逗号两边的内容是先按左边键,松开后再按右边键。如:[C-v]是表示按下Ctrl键之后,不要松开,再按下v键。
  7. 默认的情况下,的组成格式是:<Ctrl | Alt | Esc>-[Shift-]<char>。即由Ctrl,Alt,Esc之一开头,中划线,Shift,中划线,和一个字符组成。其中,中括号内的Shift和"-"有时可省略。
  8. 默认情况下,快捷键只有最后一个为字符,其他的键值均为功能键
  9. 出现[C-?]这类快捷键,由于"?"是需要使用SHIFT按键才能获得的字符,因此此类快捷键默认使用的是[C-S-?]

要注意,在里面,快捷键可能会被写成八进制或者十六进制的形式(跟在转义符后面); 脚本文件中的快捷键并不是总能起作用的。另外快捷键有个规律,Ctrl开头的快捷键一般是针对字符的,而Alt开头的快捷键一般是针对词的

Bash下,如果使用的是shell脚本文件,快捷键不一定是有的时候会出现同一个快捷键有不同的表现,这种情况一般是由于Bash所处的模式不同而引起的,你可以通过set命令来调整模式:

set -o emacs
##切到emacs模式
## set -o vi
##切到vi模式
## set -o
## 查看当前选项的设置状态

这个是Bash的option选项,你可以根据具体情况进行设置,本文使用的是emacs模式。

快捷键 快捷键说明
C-A 将光标移到行首(在命令行下)
C-B 退格 (非破坏性的),这个只是将光标位置往回移动一个位置。
C-C 中断. 终结一个前台作业.
C-D 从一个shell中退出 (类似于exit)."EOF" (文件结尾:end of file).它也用于表示标准输入(stdin)的结束.在控制台或xterm 窗口输入文本时, C-D删除在光标下的字符.如果没有字符存在,C-D 则会登录出该会话. 在一个xterm窗口中,则会产生关闭此窗口的效果。
C-E 将光标移动到行尾(命令行下)
C-F 将光标向前移动一个字符(命令行)
C-G BEL.在一些老式打印机终端上,这会引发一个响铃。在xterm终端上可能是哔的一声。
C-H 擦除(Rubout)(破坏性的退格)。在光标往回移动的时候,同时擦除光标前的一个字符。
#!/bin/bash
## 可以尝试下下面的代码
## C-H的表现也许和你想象的不一样
## 本例来自Advanced Bash-Scripting Guide
## 注意:因为中文原因,下面的^位置可能会出现漂移
a="^H^H"

echo "abcdef"
echo
echo -n "abcdef$a "       # abcd f
#  末尾有个空格     ^              ^  两次C-H的结果
echo
echo -n "abcdef$a"        # abcdef
#  末尾没有空格                        ^ 显示效果是没有按C-H?(为什么?).
                          # 这个结果和我们预期的不一致.
echo; echo

rubout="^H^H^H^H^H"       # 5个C-H.
## 来吧,让我们看看真相:
echo -n "12345678"
sleep 2
echo -n "$rubout"
sleep 2
## 现在,你知道真相了么?
C-I 水平制表符.
C-J 新行(换行[line feed]并到行首).在脚本中,也可能表示为八进制形式('\012')或十六进制形式('\x0a').
C-K 垂直制表符(Vertical tab.).在控制台或xterm 窗口输入文本时, C-K 会删除从光标所在处到行尾的所有字符。在脚本中,Ctrl-K可能会有不一样的行为,下面的例子给出其不一样的行为:
#!/bin/bash
## 一个C-K垂直制表符的例子

var=$'\x0aBottom Line\x0bTop line\x0a'
## 直接输出
echo "$var"
## 使用col来过滤控制字符
echo "$var" | col

## 上面的显示将会不一样

exit 0
C-L 跳纸,换页(Formfeed),清屏。清空终端屏幕。在终端上,这个命令的作用和clear命令一样。但当这个命令发送到打印机时,Ctrl-L会直接跳到纸张(Paper sheet)的末尾。
C-M 回车(Carriage return).
C-N 擦除从history缓冲区召回的一行文本(在命令行下)。如果当前输入是历史记录中选择的时候,这个是从这个历史记录开始,没按一次,是更接近的一条命令
C-O 产生一个新行(命令行)
C-P 从history缓冲区召回上一次的命令(命令行)。此快捷键召回的顺序是由近及远的召回,即按一次,召回的是前一次的命令,再按一次,是召回上一次之前的命令,这和C-N都是以当前的输入为起点,但是两个命令操作刚好相反,C-N是从起点开始由远及近(如果起点是历史命令的话)。
C-Q Resume (XON). 恢复/解冻,这个命令是恢复终端的stdin用的,可参见C-S
C-R 回溯搜索(Backwards search)history缓冲区内的文本(命令行),注意:按下之后,提示符会变成(reverse-i-search)'':输入的搜索内容出现在单引号内,同时冒号后面出现最近最匹配的历史命令
C-S Suspend(XOFF),挂起,这个是冻结终端的stdin。要恢复可以按C-Q。
C-T 交换光标位置与光标的前一个位置的字符内容(命令行)。比如:echo $var;,假设光标在a上,那么,按下C-T之后,v和a将会交换位置。
C-U 擦除从光标位置开始到行首的所有字符内容。在某些设置下,C-U会不以光标位置为参考而删除整行的输入。
C-V 在输入文本的时候,按下C-V之后,可以插入控制字符。比如:echo -e ‘\x0a';echo <C-V><C-J>;这两种效果一样。这点功能在文本编辑器内非常有效。
C-W 当在控制台或一个xterm窗口敲入文本时, C-W 会删除从在光标处往后(回)的第一个空白符之间的内容.在某些设置里, C-W 删除光标往后(回)到第一个非文字和数字之间的字符.
C-X 在某些文字处理程序中,这个控制字符将会剪切高亮的文本并且将它复制到剪贴板中。
C-Y 将之前已经清除的文本粘贴回来(主要针对C-U或C-W)。
C-Z 暂停一个前台的作业;在某些文本处理程序中也作为替换操作;在MSDOS文件系统中作为EOF(End-of-file)字符。
C-\ 退出。和C-C差不多,也可能dump一个"core"文件到你的工作目录下(这个文件可能对你没用)
C-/ 撤消操作,Undo。
C-_ 撤消操作
C-xx 在行首和光标两个位置间进行切换,此处是两个"x"字符
 
M-B 光标往回跳一个词,词以非字母为界(跳动到当前光标所在词的开头)。
M-F 光标往前跳一个词(移动到光标所在词的末尾)
M-D 删除光标所在位置到光标所在词的结尾位置的所有内容(如果光标是在词开头,则删除整个词)
M-Del Del是Backspace键,这个删除光标所在位置到词开头的所有内容。
M-C 将光标所在位置的字母转为大写(如果光标在一个词的起始位置或之前,则词首字母大写)
M-U 将光标所在位置到词尾的所有字母转为大写
M-L 将光标位置到词尾的所有字母转为小写
M-R 取消所有变更,并将当前行恢复到在历史记录中的原始状态(前提是当前命令是从历史记录中来的,如果是手动输入,则会清空行)。
M-T 当光标两侧都存在词的时候,交换光标两侧词的位置。如:abc <M-T>bcd -> bcd abc
M-. 使用前一次命令的最后一个词(命令本身也是一个词,参见后一篇的Bang命令中的词指示符概念)
M-_ 同M-.
M-No. M+数字,这个数字可以是正或者是负,这个键单独没有作用,必须后面再接其他内容,如果后面是字符,则表示重复次数,如:[M-10,k]则光标位置会插入10个k字符(负值在这种情况下无效);如果后面接的是命令,则数字会影响后面命令的执行结果,如:[M--10,C-D]则向C-D默认方向相反(负数)的方向执行10次操作。
M-< 移动到历史记录中的第一行命令。
M-> 移动到历史的最后一行,即当前正在输入的行(没有输入的情况下为空)
M-P 从当前行开始向前搜索,有必要则向"上"移动,移动时,使用非增量搜索查找用户提供的字符串。
M-N 从当前行开始向后搜索,如果有必要向"下"移动,移动时,使用非增量搜索查找用户提供的字符串。
M-C-Y 在标志点上插入前一个命令的第一个参数(一般是前一行的第二个词)。如果有参数n,则插入前一个命令的第n个词(前一行的词编号从0开始,见历史扩展)。负的参数将插入冲前一个命令的结尾开始的第n个词。参数n通过M-No.的方式传递,如:[M-0,M-C-Y]插入前一个命令的第0个词(命令本身).
M-Y 轮询到删除环,并复制新的顶端文本。只能在yank[C-Y]]或者yank-pop[M-Y]之后使用这个命令。
M-? 列出能够补全标志点前的条目
M-* 把possible-completions[M-?]命令能生成的所有文本条目插入到标志点前.
M-/ 试图对标志点前的文本进行文件名补全。[C-X,/]把标志点前的文本当成文件名并列出可以补全的条目。
M-~ 把标志点前的文本当成用户名并试图进行补全。[C-X,~]列出可以作为用户名补全标志点前的条目。
M-$ 把标志点前的文本当成Shell变量并试图进行补全。[C-X,$]列出可以作为变量补全标志点前的条目。
M-@ 把标志点前的文本当成主机名并试图进行补全。[C-X,@]列出可以作为主机补全标志点前的条目。
M-! 把标志点前的文本当成命令名并试图进行补全。进行命令名补全时会依次使用别名、保留字、Shell函数、shell内部命令,最后是可执行文件名。[C-X,!]把标志点前的文本当成命令名并列出可补全的条目。
M-TAB 把标志点前的文本与历史记录中的文本进行比较以寻找匹配的并试图进行补全。
M-{ 进行文件名补全,把可以补全的条目列表放在大括号之间,让shell可以使用。

 在Bash下,如果能够妥善的使用快捷键,在的操作会变得非常快捷,比如我们在使用cat创建一个文件时,我们可以使用快捷键[C-D]:

## 不用快捷键
cat >>/tmp/test<<_EOF
##这里是内容
##最后我们要在新行里面输入_EOF
##cat见到_EOF才会将内容写到文件中

##使用快捷键
cat >>/tmp/test
##这里输入内容
##输入完毕之后,直接[C-D]结束

 有的时候我们需要创建一个文件,而后对这个文件进行操作:

touch /tmp/a-test-file-from-blog.useasp.net

## 不使用快捷键,文件名要重新输入
chmod u+x /tmp/a-test-file-from-blog.useasp.net

##使用快捷键
chmod u+x <M-.>
## 快捷键[M-.]自动会将上面的最后一个参数附加

 怎么样,有没有更有效率?

当然,Bash的快捷键只有在不断的使用中,才能达到真正的高效,在开始连要用那个快捷键都要思考半天的情况下,高效是很难的——但磨刀不误砍材工,前期的投入是值得的。

如果你想自己的Bash有那么一些不同,你也可以自己自定义快捷键,使用bind命令即可,Bash中的快捷键其实是来提供的,因此,这里快捷键的设置其实就是配置Readline,Readline中分两种快捷键,一种是Readline内部的函数快捷键,另外一种是执行Shell命令,设置的时候稍有不同:

##查看Readline中可以使用的函数名称
bind -l
##查看当前绑定的案件配置与其对应的功能
bind -v
##已经绑定的快捷键
bind -p

##绑定自定义执行命令shell命令的快捷键
bind -x '"\C-x\C-l":ls -al'
## 绑定后,按[C-x,C-L]就能执行ls -al

## 绑定内置函数功能
bind "\C-x":backword-delte-char
##这个是这行Readline库中的函数backword-delte-char

 这种设置只是针对当前的会话有效,一旦会话丢失,这样设置的快捷键就会丢失,为了能够让设置的快捷键永久有效,我们就需要将快捷键的配置写入文件。在Linux系统中,能永久保存快捷键的地方有两个,全局和用户的配置文件,全局的是/etc/inputrc,而用户的是在用户的根目录下~/.inputrc,全局的会影响所有的用户,而用户根目录下的只会对相应的用户产生影响。的大概样子像下面这样:

## 本例来自CentOS6.4的默认配置文件
$if mode=emacs

# for linux console and RH/Debian xterm
"\e[1~": beginning-of-line
"\e[4~": end-of-line
# commented out keymappings for pgup/pgdown to reach begin/end of history
#"\e[5~": beginning-of-history
#"\e[6~": end-of-history
"\e[5~": history-search-backward
"\e[6~": history-search-forward
"\e[3~": delete-char
"\e[2~": quoted-insert
"\e[5C": forward-word
"\e[5D": backward-word
"\e[1;5C": forward-word
"\e[1;5D": backward-word

# for rxvt
"\e[8~": end-of-line
"\eOc": forward-word
"\eOd": backward-word

# for non RH/Debian xterm, can't hurt for RH/DEbian xterm
"\eOH": beginning-of-line
"\eOF": end-of-line

# for freebsd console
"\e[H": beginning-of-line
"\e[F": end-of-line
$endif

说明: 

  1. 在配置文件中,\C代表Ctrl,\M代表Alt,\e代表Escape[Esc],\\是反斜杆[\],\'是单引号,\"是双引号;
    \C-    control prefix
    \M-    meta prefix
    \e     an escape character
    \\     backslash
    \"     literal ", a double quote
    \’     literal ’, a single quote
  2. 如果要查看某一个功能键的字符序列可以通过[C-v]来实现,或者输入cat后回车,进入编辑中,直接按快捷键
  3. 配置文件中可能会使用八进制或者十六进制来表示字符。

如果我们针对常用的操作设置成适当的快捷键,也许以前需要巴拉巴拉敲上半天的命令,你一个快捷键就能搞定,这无疑将会大大的提高我们的工作效率!快捷键吧,骚年!

Tuesday, June 03, 2014 | Unix & Linux 编程语言

文章评论

  • # re: Linux下更高效的使用Bash——快捷键
    • Tony
    • 1/15/2017 6:23 AM
    Meta _ 应该是 Meta - (i.e. Meta + shift + _) 我在Red Hat Enterprise Linux Server release 7.2 (Maipo) 测试结果。
  • # re: Linux下更高效的使用Bash——快捷键
    @Tony:
    非常感谢提醒,在CentOS 7上测试的:M + _ 和 M + - 还是不一样的,这里是M + _ ,但在实际的键盘中要实现_的输入,可能需要同时按(Shift + -),即:Meta + Shift + -,和直接按(Meta + -)结果是不一样的。M + _ 要实现的是获取上一个命令的最后一个词。不知道我的理解是否正确?

发表评论

Please add 3 and 2 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,常年游弋于电子商务,属于互联网行业分类中的杂牌军。当前正在待业中...