Linux Bash Shell学习(四):编辑命令
转自:http://blog.csdn.net/flowingflying/archive/2009/10/07/4640465.aspx
我一般的使用方式,就是直接敲,如果敲错了,用左右光标箭回去修改,或 者使用上下光标键直接使用以前的命令或在以前的命令进行修改。似乎仅此而已。我用vi,几乎不使用emacs。这本书的作者说可以如同使用vi或者 emacs那样编译命令,期待中,我还专门在cygwin上装了emacs。
历史命令记录在~/.bash_history,这是由HISTFILE决定的。可以用echo $HISTFILE来查看。当我们登录login或者打开某个terminal进行shell人机交互的使用,bash从.bash_history中取 出以前的历史命令。在cgywin中,当我们exit窗口时,会进行保存,不是每个bash实时保存,但是对于其他linux,不能确定。我们用上下光标 键可以得到历史命令,可以通过history命令将他们全部列出(包括尚未写入HISTFILE的命令)。
Emacs模式
缺省的,bash使用emacs模式进行编译,可以用set –o emacs|vi,来指定我们使用的方式。下面介绍一下编译方式:
一、对字符的操作 :这本书介绍的主要基于keybroad的操作,比较古老的方式,例如没有光标键,也例如在某些远程操作中,例如串口连接,无法使用光标键的情况。这些情 况在现在已经比较少出现,所以我们并不需要去记忆他们。下面仅做抄录。当我们修订好,无需将光标移到最后,可以之间按回车键执行命令。
- CTRL-B,光标后移(左移),相当于左向光标
- CTRL-F,光标前移(右移),相当于右向光标
- DEL,删除后面一个字符(其实就是删除当前字符,光标前移)
- CTRL-D,删除前面一个字符(其实就是删除当前字符,光标后移),这个需要小心,因为如果什么都没有,按CTRL-D,相当于logout或 者关闭这个terminal。
二、对word的操作 :我一直都没有使用过基于word的操作,都是土土地使用字符方式,其实也没什么关系,it still works。对于emacs模式,字幕和数字作为一个word,如果中间使用“-”,会认为是两个word。
- ESC-B,光标向后移动一个word
- ESC-F,光标向前移动一个word
- ESC-DEL,删除当前或者后面的word,实际上我在cgywin里面并没有起作用
- ESC-CTRL-H,删除前面的word,或者word的光标前面部分
- ESC-D,删除后面的word,或者word的光标后面部分
- CTRL-W,删除前面的word,或者word的光标前面部分
- CTRL-Y,回复之前删除的部分。
三、对行的操作 :如下:
- CTRL-A,光标移到最前,相当于Home,所以不必要记忆那么多
- CTRL-E,光标移到最后,相当于End,所以不必要记忆那么多
- CTRL-K,删除当前光标到最后的内容,可以用CTRL-Y进行恢复。实际上CTRL-Y,将上次操作被删除的部分记忆下来,在当前光标出 parse。
四、对历史命令的操作 :这是非常常用的,实际上,我们简单地通过上下光标键就可以实现,下面作为记录:
- CTRL-P,前一命令,同上光标键
- CTRL-N,后一命令,同下光标键
- CTRL-R,查询,如果没有查到,会发出beep
- ESC-<,history的第一条命令,我在cgywin中实验,无效
- ESC->,history的最后一条命令,我在cgywin中实验,不太稳定
五、完整文字的操作 :我们不希望敲一个很长的命令,或者很长的文件名字,我们只需要敲入前面的字母,在没有歧义的情况下,可以自动显示完整的word,我只会用TAB。包括 路径、命令、function都可以使用这种方式来简化我们的输入,command和function比路径(文件名)有更高的优先权。除了给出 prefix外,我们可以直接按tab,给出后面匹配的内容,或者经可能长地给出后面匹配的内容,例如我们有两个文件abc123和abcdef,我们按 tab,可以得到abc,后面无法精确匹配。如果我们不清楚具体的名字,我们可以再按tab,则系统给出abc123,abcdef,供我们参考。
- ESC-?,可以显示可能用于完善的命令,作用类似于连续的tab
- ESC-/,尝试文件名完整
- CTRL-X /,显示可能的完整文件名
- ESC-~,尝试可能的完整用户名(实际上要按三个键,因为~需要按shift键)
- CTRL-X ~,显示可能的完整用户名,我在cgywin中实验,无效
- ESC-~,尝试vairable 完整,不确定什么意思
- CTRL-~,列出vairable 完整,不确定什么意思
- ESC-@,尝试hostname的完整
- CTRL-@,列出hostname的完整
- ESC-!,尝试命令完整
- CTRL-X !,这个表示先按CTRL-X,后按!(shift-1),列出所有可能的命令完整
- ESC-TAB,尝试根据history list来完整命令
六、其他一些操作 :我觉得如斯之操作,估计都是记不住的,仅在此记录下来,让我们了解一些bash能提供多少编辑能力。
- CTRL-J,等同于RETURN,即回车,在ASCII中为LINEFEED,UNIX中允许用之来替代RETURN
- CTRL-L,类似于clear,清空屏幕,并放置在屏幕的最上端
- CTRL-M,等同于RETURN,即回车
- CTRL-O,等同于RETURN,然后显示在history中下一条命令
- CTRL-T,将两个字符交换位置
- CTRL-U,删除开始到光标所在处
- CTRL-V,加入quote,但是我在cgywin中无效
- CTRL-[,等同于Esc
- ESC-C,将字母变为大写,并光标移到下一个word处
- ESC-U,将word的位于光标即后面的字母变为大写,并光标移到下一个word处
- ESC-L,将word的位于光标即后面的字母变为小写,并光标移到下一个word处
- ESC-.,将上一命令的最后的word加入光标所在处
- ESC-_,同ESC-.
Vi模式
vi模式不是缺省的方式,需要通过set –o vi进入。 vi是很好的文本编译器,例如用于C编程,但是在bash上,可能会比Emacs要敲更多的键。分为输入模式和控制模式。
输入模式 下包括:
- DEL:删除字符,光标后移
- CTRL-W:删除之前的word
- CTRL-V:Quote the next character,在cgywin中无效
- ESC:进入控制模式
在控制模式 中,可以进行下面的编译方式。在vi中word分两种方式,一种叫non-blank,这是用空格作为划分的word,一种是有字母数字组成的word, 缺省我们指后面一种。
控制模式——移动
- h,左移一个字符
- l,右移一个字符
- b,左移一个word
- w,右移一个word
- W,移到下一个non-blank的word
- B,移到上一个non-blank的word
- e,移到当前word的最后
- E,移到当前non-blank的word的最后
- 0,移动行最前
- ^,移到行第一个non-blank的word
- $,移到行最后
出来最后三个方式,我们可以用数字表示重复的操作,例如7h,相当于连续按了7次h。
控制模式——重新进入input: 我们进入control模式后,希望退出,重新进入input模式,可以通过下面几种方式:
- i,表示当前插入
- a,表示后面加入
- I,表示在行最开始加入
- A,表示在行最后加入
- R,表示重写(r表示更换某个字符,仍然在控制模式下)
控制模式——删除: vi模式提供了很强大的删除功能,即使我非常熟悉vi,有一些仍然是我少用的。记录如下:
- dh:删除一个字符,光标后移
- dl:删除一个字符,光标前移
- db:删除当前光标所在word的前面部分,如果光标不位于word中删除光标的前一个word
- dw:删除当前光标所在word的后面部分,如果光标不位于word中删除光标的后一个word
- dB:删除当前光标所在non-blank word的前面部分,如果光标不位于non-blank word中删除光标的前一个non-blank word
- dW:删除当前光标所在non-blank word的后面部分,如果光标不位于non-blank word中删除光标的后一个non-blank word
- d$:删除光标到最后的部分
- d0:删除开始到光标的部分
如果我们用c代替d,则执行删除命令后,进入input模式。,另外还可以使用一些缩写:
- D:相当于d$,删除光标到最后的部分
- dd:相当于0d$,即删除整行
- c:相当于c$,即删除后面部分,并进入input模式
- cc:相当于0c$,即删除整行,并进入input模式
- X:相当于dl,删除一个字符,光标前移
- x:相当于dh,删除一个字符,光标后移
所有好的编辑器都提供un-delete的方式。在vi模式中,用u可以回复之前的操作,能一直追溯。对于删除命令中,如果我们用y代替d,我 们将记录原来使用d命令所要删除的部分,当时并不实际删除,用p(光标之后)或者P(光标之前)命令可以将这个记录内容粘帖出来。
控制模式——History命令: 如下
- k或者-,之前命令,相当于向上光标,可以使用3k表示重复3次
- j或者+,之后命令,相当于向下光标,可以使用3j表示重复3次
- G,Move to line given by repeat count,不确定含义
- /string,向后查找含有string的历史命令,而^string,用于查询开头是string的历史命令,可以用/进行继续查找
- ?string,向前查找含有string的历史命令,可以用?进行继续查找
- n,继续原来的方向继续查找
- N,在原来相反的方向继续查找
我们看到使用h、j、k、l,实际上他们就是最古老的光标键。这种键盘在很久以前见过。不记得买的第一个键盘是怎么样子的,只记得第一个显示器 在一声巨雷后,冒出霭霭白烟,报废了,还好,当时不是坐在电脑前。
控制模式——查找字符: 下面是查找的方式,x表示某个字符。下面的这些命令在前面都可以加上重复操作的次数n,例如4fa,向后查找第4个a字母
- fx,查找下一个字符x,光标移到该x上
- Fx,查找上一个字符x,光标移到该x上
- tx,查找下一个字符x,光标移到该x的前一个字符上
- Tx,查找上一个字符x,光标移到该x的后一个字符上
- ;,重新操作上个查找命令
- ,,重新操作上个查找命令,但是查找的方向相反
此外我们还可以根据column,即第N个字符来查找,即n|。如果只敲|,则为第一个字符。
控制模式——完整操作 :
- \,等同于emacs模式的TAB,可以完整后面的命令、function、文件名
- *,完整文件名,如果有多个选择,将他们都列出来(在命令行中列出)
- =,完整文件名,如果有多个选择,将他们都列出来。
控制模式——其他操作
- ~,更换当前字母的大小写,光标后移
- -,给出上个命令的最后word,并进入input模式,在cgywin中,不太灵光
- CTRL-L,清屏
- #,这个会自动加最前面,命令将不会被进行,但会被记录在history中。
fc处理历史命令
fc是个很有趣的命令。这个命令我以前没用过,我使用history,或者上下光标箭头来查阅或者获取历史命令。
- fc -l,显示历史命令,后面可以更参数,如果数字,表示第N个命令,如果是字符串,表示最近以该字符串开头的命令。如果有两个参数,则表示显示范围内的命 令,例如fc -l 5 8,显示第5-8的命令,如果只有一个参数,表示从该命令开始显示,例如fc -l 5,显示第5到最后的历史命令。
- 出来显示历史命令,还可以直接编译历史命令,例如编译第45号命令,fc 45,编译最近以c开头的命令,fc c,这样,这个命令就进入vi的编译模式,我们在那里很方便编译。如果我们给出两个参数,我们就可以编译一个名字组,退出vi模式后,依 次执行这些命令 。
其他
书中还介绍了一些扩展的历史命令的处理方式,我觉得看看就可以了,谁记得这么多的东西,就像中文打字一样,以前学过什么自然码,但是真正能记住 的就是拼音。而且我在cgywin中实验,并没有起什么效果。这一章节的关键在于我们能够方便对bash进行编译,就可以了。
bash的edit接口成为readline,我们可以通过~/.inputrc的修改来修订readline,从而设定我们自己特色的按键方式。 这类文件称为startup文件。文件中,将一个(组)key和一个macro或者readline的function向关联。例如我们想增加CTRL- T,将光标放置行后面,我们在.inputrc中加入:
#wei test
“\C-t”: end-of-line
其中”\C-t”是key名字,\C表示Control键的前缀,后面end-of-line是readline的function,有操作 60这种这样的功能。第一行加#表示注释。这也可以提供一种快捷的方式,例如“\C-t”: “Hello”,则当我使用CTRL-T,等同于敲入Hello。
- \C-:CTRL键
- \M-:Escape键(Meta(Escape) key prefix)
- \e:escape charater,在实验中,和\M-没有什么区别
- \\:表示\;\”,表示”,\’表示’
我们可以加入一些条件控制,例如只针对某种edit模式,某类teminal或者某些应用。条件控制使用$if,$else,$endif,例如上 面例子只出现在emacs模式下。
$if mode=emacs
“\C-t”: end-of-line
$endif
对于一些快捷键,可以用bind -P 来查看。在.inputrc文件中修改,需要在下次login时有效,但是有时我们不希望永久修订,只希望临时能够起效,可以使用bind ‘“\C-t”: end-of-line’的方式,bind后面的设置同startup文件中的处理,但是需要加上’’。bind只在本次登录有效。清除捆绑,使用 bind –u ,所有该function的捆绑都清楚,可以用bind -P来确认。bind –r ,该快捷键失效。bind -x用于捆绑shell命令,例如bind –x ‘"\C-l":ls'。删除特定的捆绑,正如我们使用bind来增加绑定一样。 bind -p比较有趣,按.inputrc中的格式显示,可以导入.inputrc中,也可以copy一下放入bind命令中。如果我们需要自定义很多的这类的命 令,而又不想放入.inputrc中,我们可以将它们写入某个文件,通过bind -f 导入。
我们也可以通过set方式来设定一些readline的参数,有很多参数可以设置,具体阅读《Learning the bash Shell》,这里我列一下我感兴趣的:
set bell-style none|visible|audible,缺省是audible,这个设置用于处理beep的情况,例如tab没有匹配会发出beep,如果在办公室, 老是beep beep的,挺烦的,可以关闭none,visible的方式在cgywin中和audible没有区别。
总结
实际上,即使我们经常使用linux,我们仍很难记住这么多的东东,而且现在的键盘已经相当方便,或许在一些串口的teminal中会有一些限 制。一般来讲,我们使用如下的基本上足够:
- 左右光标键,Home和End将光标移至行头和行尾
- 上下光标键,翻看历史命令
- tab键,自动尽量补齐完整的词
- Del或者backspace进行删除
- CTRL-C,放弃整行,不执行