Linux Bash Shell学习(四):编辑命令

  本文也即《Learning the bash Shell》3rd Edition的第二章 Command-Line Editing之读书笔记。但我们将不限于此。

  我一般的使用方式,就是直接敲,如果敲错了,用左右光标箭回去修改,或者使用上下光标键直接使用以前的命令或在以前的命令进行修改。似乎仅此而已。我用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,放弃整行,不执行

 

相关链接: 我的Linux操作相关文章


你可能感兴趣的:(读书笔记,Linux)