1. 请教emacs中退出term的方法
在想要执行的命令前面加上 C-c 的前缀。例如,如果你想执行 C-x C-b 来查看 Buffer 列表,就输入 C-c C-x C-b。另外,可以用 C-c C-h 来查看以 C-c 开头的快捷键。
2. emacs编写c++
第一步,输入命令emacs main.cpp 编写c++代码
第二步,在emacs软件下依次输入Control+x,Control+s,这是保存cpp文件
第三步,在emacs软件下依次输入Control+x,Control+c,这是退出emacs编辑软件
第四步,在main.cpp文件所在的路径下,输入g++ -o main main.cpp,这是对cpp文件进行编译,此步会生成一个可执行文件main
第五步,输入./main 即可运行所编译的可执行文件
3. Emacs基本的按键与命令
C- :表示键盘上的 Ctrl 键
M- :表示键盘上的 Alt 键
S- :表示键盘上的 Shift 键
DEL :表示键盘上的 Backspace 键,注意,不是 Delete 键
RET :表示键盘上的 Enter 键
SPC :表示键盘上的 Space 键
ESC :表示键盘上的 Esc 键
TAB :表示键盘上的 Tab 键
C-x C-f :打开一个文件,或者创建一个不存在的文件
M-x find-file :作用同上
C-x k :关闭一个 buffer ,作用等于关闭已经打开的文件
C-x C-s :保存文件内容,即将修改的文件内容写入磁盘
M-x save-buffer :作用同上
C-x C-w :将当前文档保存为另一个文件,即另存为
M-x write-file :作用同上
C-x b :切换文件,即切换缓冲区 buffer
说明:实际上在 Emacs 中,文件与 buffer 是不同的实体,文件一般指的是磁盘上的数据体,而 buffer 是 Emacs 中作为文件修改临时缓存的缓冲区,注意区别。
Emacs具有一个被称为 ido 的模式,全称为 interactively do things ,在 ido 模式下,可以更加方便地选择列表元素,相比使用Tab进行自动补全更加便利。
M-x ido-mode :使能或者禁止 ido 模式
可以在 Emacs 的启动配置中添加以下语句,以默认打开 ido 模式:
(setq ido-enable-flex-matching t) (setq ido-everywhere t) (ido-mode 1)
C-x C-b :列出buffer列表
M-x list-buffers :作用同上
在 Emacs 中,还存在功能更灵活的 buffer 管理模式,被称为 ibuffer 。可以通过以下命令进入 ibuffer :
M-x ibuffer :进入 ibuffer 管理模式
一般我们可以在Emacs的配置文件中进行ibuffer的命令键绑定:
(global-set-key (kbd "C-x C-b") 'ibuffer)
ibuffer 的过滤命令包括:
/m :以 major mode 方式添加过滤
/n :以 buffer 名称的方式添加过滤
/c :以 buffer 内容的方式添加过滤
/f :以文件名称的方式添加过滤
/> :以 buffer 大小的方式添加过滤
/< :以 buffer 大小的方式添加过滤
// :删除当前所有有效的过滤
ibuffer 的过滤组的命令包括:
/g :创建一个过滤组
TAB :移动到下一个过滤组
M-p :移动到上一个过滤组
/ :删除当前所有的过滤组
/S :将当前过滤组保存为一个名称
/R :恢复之前保存的过滤组
/X :删除之前保存的过滤组
ibuffer的排序命令包括:
s a :以字母顺序排序
s f :以文件名称顺序排序
s v :以上次访问时间排序
s s :以 buffer 大小排序
s m :以 major mode 排序
s i :反序当前的 buffer 顺序
可以在文件的任何地方设置书签,后续可快速跳转到书签处,书签相关的命令为:
C-x r m :在当前光标处设置书签,需输入书签名称
M-x bookmark-set :作用同上
C-x r b :跳转到某个书签处
M-x bookmark-jump :作用同上
C-x r l :列出当前所有的书签列表
M-x bookmark-bmenu-list :作用同上
在书签列表状态下,可以使用以下的命令:
RET :打开书签标识的区域
s :将当前书签列表保存至文件中
r :修改光标所在的书签的名称
d :将书签打上删除标识
x :删除已打标识的书签
u :取消已经打标识的书签
主要的光标移动操作命令包括:
C-f :向前移动一个字符, f 表示为 forward
C-b :向后移动一个字符, b 表示 backward
C-p :向上移动一行, p 表示 previous
C-n :向下移动一行, n 表示 next
C-a :移动至行首
C-e :移动至行尾
M-f :向前移动一个单词
M-b :向后移动一个单词
C-v :向前滚动一个屏幕的内容
M-v :向后滚动一个屏幕的内容
M-a :移动至句首
M-e :移动至句尾
C-l :将光标重定位至屏幕中间一行,光标所在内容位置不变
M-r :将光标重定位至屏幕的顶部,中部,底部,光标所在内容位置不变
M-< :移动至 buffer 的开头处,注意,按键 < 可能需要 Shift 键
M-> :移动至 buffer 的结尾处,注意,按键 > 可能需要 Shift 键
M-g c n :移动至第 n 个字符
M-g g n :移动至第 n 行(高于23.2版本的 Emacs 有效)
C-M-f :向前移动一个整的表达式,比如,光标可从函数开头的左 { 处移动到函数结尾的 } 处,按键绑定的命令是 forward-sexp
C-M-b :向后移动一个整的表达式,比如,光标可从函数结尾的右 } 处移动到函数开头的 { 处,按键绑定的命令是 backward-sexp
C-M-k :剪切一个整的表达式,按键绑定的命令是 kill-sexp
C-M-@ :选择一个整的表达式,按键绑定的命令是 mark-sexp
在 Emacs 中, kill 的意思就是 cut ,即剪切,剪切操作的命令包括:
C-d :剪切当前光标所在的字符
C-S-DEL :剪切整个行, DEL 就是键盘上的 Backspace 键
M-d :剪切光标当前位置至词结尾的内容
M-DEL :剪切光标当前位置至词开头的内容
M- :剪切光标所在的所有空白符
M-SPC :剪切光标所在的所有空白符,除了光标所在的位置
C-k :剪切光标当前位置至行尾
M-k :剪切当前的整个句
C-y :粘贴操作
一般在 Emacs 中,默认的选择操作,需要使用 C-SPC 按键,但是通常在 Win 中,此按键与系统默认的切换输入法的按键冲突,如果无法修改系统的按键,则可以修改 C-SPC 按键,在 Emacs 的启动脚本中添加以下的语句:
(global-unset-key (kbd "C-SPC")) (global-set-key (kbd "M-SPC") 'set-mark-command)
以下以 M-SPC 作为默认的选择命令:
M-SPC :以光标所在位置为起点,移动光标,所选区域被高亮选中
C-w :剪切高亮选中的区域
M-w :复制高亮选中的区域
C-y :粘贴高亮选中的区域
C-/ :撤销操作
C-x u :作用同上
Emacs 具有多种查找方式。
增量查找 :通过按键 C-s 来执行增量查找,反复执行 C-s ,可逐个定位各个匹配点。
C-s :执行增量查找,输入查找字符后,重复执行 C-s 可逐个定位匹配点,按键绑定的命令是 isearch-forward
C-r :执行增量查找,是从文档的后端往前查找,重复执行 C-r 可逐个定位匹配点,按键绑定的命令是 isearch-backward
C-u C-s :按照正则表达式执行增量查找
Occur查找 :使用增量查找,若匹配点比较多,只能通过反复执行按键,逐个越过各个匹配点,才能定位到我们需要的匹配点,为了解决这个问题, Emacs 提供了 Occur 查找,执行后,可在 Occur 缓冲区列出一个匹配点的列表,可更加直观地查看所有的匹配点。
M-s o :执行Occur查找
M-g n :定位到下一个匹配点
M-g p :定位到上一个匹配点
在 Occur 缓存区,可以执行的命令主要包括:
C-n :移动至下一行
C-p :移动至上一行
o :跳转至匹配点,光标也移动至匹配点
C-o :跳转至匹配点,但是光标还停留在 Occur 缓冲区
e :编辑当前的 Occur 缓冲区
C-c C-c :退出编辑 Occur 缓冲区
M-% :执行查找替换,该命令需要两个输入,即需要被替换的字符串,与替换后的字符串。输入字符串后执行 RET , Emacs 会询问是否确定执行替换操作,若输入 ! ,则执行所有匹配点的替换,若输入 yes ,则只执行当前光标所在的匹配点的替换。注意,输入 % 可能需要执行 Shift 键
C-x 2 :将当前窗口切为上下两个窗口,该按键绑定了命令 split-window-below
C-x 3 :将当前窗口切为左右两个窗口,该按键绑定了命令 split-window-right
C-x o :在多个窗口之间切换,注意,按键中的是小写字母 o ,该按键绑定了命令 other-window
C-x 1 :关闭其他的窗口,只保留当前光标所在的窗口
Emacs 具有一个内置的 Dired 模块,是 Directory Editor 的简称,顾名思义,该模块是对目录进行管理编辑的模块。
Dired 模块的主要命令包括:
C-x d :选择一个目录,并在那个目录上启动 Dired
C-x C-f :选择当前目录下的某个目录,并在那个目录上启动 Dired
在 Dired 目录下可以执行:
n :向下移动一个
p :向上移动一个
C-s :使用增量查找,查询 Dired 入口
C-x C-f :创建一个新的文件
f :打开光标所在的文件
e :作用同上
RET :作用同上
o :在另一个窗口上打开光标所在的文件
C-o :在另一个窗口上打开光标所在的文件,但是光标不会移动到新的窗口
v :以只读的方式打开文件
^ :在新的Dired Buffer中打开父目录
m :标识文件或者目录入口
%m :标识那些名称匹配正则表达式的文件
%g :标识那些内容匹配正则表达式的文件
C :拷贝文件(或者是 S-c ),拷贝的是当前光标所在的文件,或者已经标识的文件
R :移动文件(或者是 S-r ),移动的是当前光标所在的文件,或者已经标识的文件
H :创建一个硬链接(或者是 S-h )
S :创建一个符号链接(或者是 S-s )
M :改变文件的权限位(或者是 S-m ),改变的文件是当前光标所在的文件,或者已经标识的文件
d :将文件打上删除的标识
u :删除文件已经打上的标识
x :确认并执行删除已经打上删除标识的文件
~ :给所有的 backup 文件打上标识
= :比较文件
4. emacs 高手进
你可以用c-x 2或c-x 3把窗口分成两个,再用c-x o(这个是字母O)切到另外一个窗口,然后按m-x(m就是ALT了)输入shell回车,emacs会在当前窗口调用shell(windows的话就是cmd了),现在就可以把这个窗口当cmd窗口来用了,你直接打入要执行的文件名,比如asdf.exe,就可以看到运行情况。
由于这是个shell窗口,只要你的gdb在环境变量中,你在这里也可以直接调用gdb来调试程序,要是你的gdb是insight的那个版本,就更爽了,一个单独的调试窗口会弹出来,全部图形化的调试,否则就在命令行下用gdb调了,它的功能都可以正常使用。
5. 如何让emacs的光标回到上次光标处
用vi命令打开文件直接跳到最后一行的方法如下:
:$ 跳到文件最后一行
:0或:1 跳到文件第一行
或 另外一组命令:
gg 跳到文件第一行
Shift + g 跳到文件最后一行
常用的操作:
查看当前目录:pwd 修改密码:passwd 更换模式:csh,bash
远程登陆:telnet 服务器ip 回到上级目录:cd ..
查看该目录下的文件夹:ls 打开文件:vi /文件夹/文件
文件显示的格式:root:x:0:root„:/root;/bin/bash 用户名,加密,序号,组,默认路径 退出:esc shift+: q! quit exit 清空:clear
显示当前目录所有文件:ls –a
显示当前目录所有文件和详细信息:ls –al 新建文件:vi 文件名
文件的权限:chmod g –(+)r w x u g o s
新建文件(不能编辑)更新文件的访问时间,如果存在文件,更新,不存在,建立:touch 文件名 创建目录:mkdir 目录名/目录名
创建多个目录:mkdir 目录名 目录名„..
在主目录创建下目录:mkdir ~/目录名 创建多级目录:mkdir –p 目录名/目录名 在覆盖文件前做个提示:cp –I 文件和文件内容间的拷贝:cp 复制目录:cp –r 目录 目录 复制文件:cp 文件 文件
移动文件:mv 要移动的文件 要移动到的目录 移动目录:mv -fi要移动的目录 要移动到的目录 修改文件或目录的名字:mv 文件 名字 删除文件:rm rm –I提示
删除目录中的所有内容包括目录:rm –r 要删除的文件夹
连接:软连接:相当于创建快捷方式,作用:修改linux内核会用到他 in 硬连接:如果删除源文件,被连接的文件内容还存在 帮助:man 命令
进入vi的命令 :
vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件,并将光标置于第n行首 vi + filename :打开文件,并将光标置于最后一行首
vi +/pattern filename:打开文件,并将光标置于第一个与pattern匹配的串处 vi -r filename :在上次正用vi编辑时发生系统崩溃,恢复filename vi filename....filename :打开多个文件,依次进行编辑。
6. emacs怎么编写c程序
emacs 的 compile 命令是调用 make 来编译的,而make是需要makefile的,你只有.c,没有写makefile,所以无法编译。
关于 make/makefile 是另外一个很大的课题,这里不多说。
写好代码后, C-x C-s 保存,然后自己打开一个shell, 如bash,然后用
gcc myc.c -o myc
来编译,然后用 ./myc 来执行即可。
如果想在 emacs 中启动shell,也可以用 M-x shell 命令,然后重复上面的编译和执行命令。
7. ubuntu里的emacs快捷键设置
把上面这些配置行,
(global-set-key[f5] 'compile);
(global-set-key[f6] 'gdb);
添加到你的用户主目录中(也就是./home目录下,如果多用户的话,则在再下一层有你用户名的目录)的emacs配置文件'.emacs'中,该文件是隐藏文件,gnome下进入用户主目录后Ctrl-h即可显示所有隐藏文件,找到后可添加;若没有的话自己新建一个.emacs文件。然后在打开emacs时就可以自动加载配置了。
具体配置快捷键可参考 http://xahlee.org/emacs/keyboard_shortcuts.html
8. texlive 怎样使用emacs
以前,我多次试图从 vim 转变到 emacs 都失败了。原因很多,主要原因是 vim 的确一个很强大的 editor 不愧为 emacs 的主要竞争对手,vim 很多强大的功能,很难在 emacs 中找到相应的功能,那个时候还没有水木Emacs版,如果有的话,情况会好一些, 还有一个原因就是我周围几乎没有人用 emacs ,现在也是。 emacs 的入门比较 vim 要困难很多,我指的入门不是指简单的使用,而是高效的使用。vim 的很多操作几乎不需要配置就可以完成了,但是如果离开我那些复杂的 .emacs 文件,我认为 emacs 并不比 vim好。有了我的 .emacs , emacs 绝对是最好的 platform (not only an editor) ,因为他是我的软件,一些我常用的功能,都是按照我的方式工作的,而且我可以随时实现我喜欢的功能,也许别人不喜欢这样的操作,但是我喜欢,我可以让 emacs 让我喜欢的方式操作。几乎没有其它软件可以做到这一点。我转变到 emacs 是一个痛苦和偶然的过程。我曾经煞有介事的“学习” emacs , 写了很多笔记,现在看来,很傻,emacs 不是学出来的,是用出来的,很多功能不是用脑子记住的,而是用手记住的,我们不得不承认,有的时候肌肉的记忆能力,要比脑子的记忆能力强,而且快速,实用。很多体育运动员不就是用大量的训练提高肌肉对动作的记忆吗?一次偶然的机会我发现了几个 vim 无法代替的几个功能,于是我开始真正喜欢 emacs 了。(注:笔者做此文时,vim版本为6.2)首先是编写 TeX 文件的时候,很多数学符号可以快速的输入,可以方便的生成 dvi 文件,可以快速的输入 TeX 特有的特殊符号。然后是 python mode ,他是非常好的 Python 的 IDE ,可以很容易的编写 Python 程序,尤其是 Python 程序中用缩进来表示语法结构,在Emacs中很容易处理缩进。很容易把一段代码放入到Python 的解释器中执行,然后在解释器中交互的测试程序。参见 我的Python 学习笔记一个编辑 C or C++ 的时候的一些功能,例如 auto insert 功能,hungry delete, M-SPC(M-x just-on-space) indent 功能 (TAB) ,在 emacs 中写出来的程序,是最漂亮的格式。最重要的是还可以选择自己喜欢的 c style 。 当然 vim 中也可以,但是默认的是用 tab 键格式化 ,这样的缺点就是不能保证程序在所有的编辑器中都是一样的效果,但是我以前也用 TAB 来 indent ,原因是我不愿意输入很多 space 。而且 vim 对重新 indent 一段代码的功能也不是很好,尽管 g= 等等键也可以工作,但是不如 emacs 中的好。vim 中的很多编辑命令要比 emacs 快的多,只要输入很少的键。但是, 我认为中 emacs 的理念是,有很多工作,做好不要让用户记住那些快键,按照用户的习惯,猜想用户(主人)的意思,默默的做好(讨好用户)就行了。例如,在 C 中,我们习惯用 tab 键来 indent 程序。那么就用 tab 键来 完成 M-x indent-line 的功能。我们经常在输入分号之后, 输入一个回车,那好,emacs 就根据上下文猜测应该回车的地方,自动回车。你想删除很多空格,那好,emacs 就会根据上下文,只留下一个空格(M-x just-on-line) 或者空行(M-x delete-blank-line) ,如果你在只有一个空行下还要 M-x delete-blank-line ,那么就把single blank line 也删掉。还有的功能也很好用。View Code LISP 12 C-c C-c (M-x comment-region)C-u C-c C-c uncomment-region 还有自动补齐右边括号,补齐引号的功能,还有补齐大花括号的功能。 参见Emacs 中自动添加有半边括号的功能和写C程序,输入左大花扩号自动补齐很多东西还有abbrivate 扩展的功能。还有fly spell 的功能。 emacs 知道主人是个粗心的人自动提示主人错了,但是 emacs 从来不把主人当傻瓜,不会自作聪明的改动,只有主人真的承认说,我错了 (按M-$)(注:我记不住具体的M-x 命令了,可以用C-h k 查一个键的bind 的函数,记做 help key bind , 也可以用 C-h w 记做 help where, 查找一个函数的快键是什么 ) ,emacs 就提示很多可选的单词,供主人选择。 我记得有一个着名的把用户当作傻瓜的软件,总是把句子的行首单词Capitalize,而且自动把他认为错了的单词改过来,每次我都要费尽心机想办法,怎么把这个功能关掉。还有auto fill 的功能, M-q 也总能干正确的事情。还有version control 的功能,emacs 几乎不用主人亲自备份文件了,他知道应该在合适的时候,备份文件。还有auto insert 的功能,他会自动根据环境,把当前的文件增加可执行权限,参见在保存文件的时候,会自动给脚本增加可执行权限还可以自动增加#!/bin/bash or #!/bin/perl #!/bin/python 。
参见Emacs 在创建文件的时候,自动添加 template 的内容header.el的扩展还可以自动插入和更新 C 文件中的开头的一些信息,包括文件名称,创建日期,改动次数,纪录谁在什么时候为什么做了修改。还有公司信息,作者信息,版权信息等等。
9. emacs 的使用:哪些是真正有用的组合键
早期的 Shell 直接运行在各种各样的 Terminal 里面,随着时间的推移,我们有了 X Window。大量的 Shell 开始运行 Xterm 里面。对于笔者来说呢,更加喜欢让 Shell 运行在 Emacs 里面。将 Shell 运行在 Emacs 里面与运行在 Xterm 里面到底有什么不同呢?相信我,将 Shell 从 Xterm 里面搬出来绝对不是一个赚取眼球,标新立异的决定。这篇文章介绍了将 Shell 从 Xterm 里面搬到 Emacs 里面带来的各种改变。这篇文章适合 Emacs 的初级与中级用户,需要读者具有一定的 Shell 使用经验。最好具有较长时间的 Shell 使用经历,以更加充分的体会到 Emacs 带来的变化。文章中的内容谨代表作者的个人观点。不代表 IBM 的任何官方观点。所附代码仅在运行于 Cygwin 环境下的 GNU Emacs 当中测试通过。 您可以访问“Emacs 编辑环境“系列教程来了解更多和 Emacs 相关的内容: Emacs 编辑环境 为什么要使用 Shell? 我不也太清楚,但是,在这样一个 Windows 横行的年代里,总是有着无数的 Unix 管理员在遍布全球的各个角落里默默奉献,保证着我们的世界继续运行。那么,为什么要在 Emacs 里面使用 Shell? 在Emacs 里面使用 Shell 和在其他地方相比,比如说 xterm,甚至是 Windows 的命令行窗口里面使用 Shell 有什么不一样呢?这个问题,我个人认为不是一个技术问题,而是一个生活舒适度的问题。之所以选择在 Emacs 里面使用 Shell,就是因为在 Emacs 里面会使你的生活的更加舒适。 生活舒适度的问题 信不信由你,人们总是希望生活的更加舒适。那么,把 Shell 搬到Emacs 环境里究竟能够带来那些生活舒适度的提高呢?在回答这个问题之前,让我们先进行一个简单的热身运动。 大家都知道,现代的 Bourn Again Shell(bash) 要比古老的 Bourn Shell(sh) 用起来舒服多了。因为 Bourn Again Shell(Bash) 引入了很多非常舒服的新的特性。比如说历史 (History) 功能,比如说命令行编辑功能。这些都是大家非常喜欢的功能。不是吗?但是,问题是,如果你想在 Shell 的世界中生活的更加舒适,就会发现很多时候他都不能真正的让你满意。 通常来说,但凡有过在古老的 Bourn Shell(sh) 或者某些缺乏历史功能的 Korn Shell(ksh) 环境下的使用经验的人来说,Bourn Again Shell(bash) 的历史 (History) 功能都是一个非常可爱的功能。它提供了很多很好的重复历史命令的有趣方式,我们可以使用 ! 命令去全部或者部分的引用上一条刚刚执行过的命令,我们可以使用 ^^ 命令简单编辑上一条命令并且生成一条新的命令,我们可以也使用向上的箭头键去回朔查找许久以前曾经执行过的命令,然后使用命令行编辑功能随心所欲的编辑这条命令。但是这里面有一个非常隐蔽的问题:所有这一切,都是集中在“命令行”这个概念中的。说白了,各种各样的不同的 Shell 版本提供给我们的就是一个命令解释器,外加一个命令行编辑环境。 这样有什么不对吗?对,但是欲望总是没有止境的。为什么不能够全屏幕编辑呢? 让我们来看看一个很简单的例子。我有一个 Omegamon XE for Messaging 的安装。这是 IBM Tivoli 旗下的一款监控产品。通过与 IBM Tivoli Monitor 产品的集成,实现对 WebSphere MQ,WebSphere Message Broker 产品的运行监控,以及对 WebSphere MQ 产品的修改与配置。由于某种需要,现在我需要将一个 MQ Monitoring agent 停止下来。我不想将那个漫长的命令从头到尾输入一遍,因为我知道我可以使用 history | grep ‘itmcmd agent’ 命令从已经存在的命令历史里面找到曾经启动这个 agent 的命令,然后我所要做的,仅仅只是在原来命令的基础上将 start 参数修改为 stop 就可以了。但是……事实上 Shell 并没有给我一个修改这条命令的机会。 图1 事实上我必须先用鼠标将屏幕上的第 437 条命令复制到剪贴板里面,然后把它粘贴到我的命令提示符后面,之后再使用 bash 的命令行编辑功能,将那个可爱的 start 参数修改为 stop。说实话,我的某些同事每天就是这样做的,另一些则是干脆将停止命令从头到尾再输入一遍。回答我一个问题,你有没有曾经也像我一样,在看到 history | grep 的输出的时候,曾经梦想过,能够直接在第 437 条命令上面改几个字母,然后就直接敲下回车呢?现在你可以了--在 Emacs 里面。在 Emacs 里面,你可以将你的 Shell“扩展”到全屏幕编辑。 让我们重新查找刚才提到的那条命令。这一次,我们不用 history | grep 的方法。是的,这个方法仍然管用。但是既然是在 Emacs 里面,我希望介绍一些更加 Emacs 化的使用方法,我们使用 Ctrl-r 组合键。如果你已经使用过 Emacs,但是从来还没有在 Emacs 里面看到过 shell 提示符的话,不妨跟我一起来,在 Emacs 当中输入 ESC-x 组合键,然后在提示缓冲区里面输入 shell(全部字母小写)回车,然后你就会在 Emacs 的编辑缓冲区里面看到熟悉的 shell 提示符了。在接下来的例子里面我们假设你已经执行过启动 MQ Monitoring agent 的那条命令了,大约是在 4 个小时前或者别的什么时候。现在要做的,就是把这个特定的 agent 停止下来。跟我一起在 Emacs 里面输入 Ctrl-r 组合键,这个时候你会在提示缓冲区里面看到 I-search backward: 这样的字样。没错,这个组合键对应的就是 Emacs 当中的回朔查找的功能。我们所要做的,就是像通常在一篇文档里面查找一个句子一样,在回朔查找提示符的后面输入 itmcmd agent,Emacs 非常迅速的就把光标定位到了曾经执行过的 bin/itmcmd agent –o QM_106 start mq 这一行命令上面。就在这里,让我们把 start 修改为 stop,然后,直接就在这里按下回车键--修改以后的命令会自动的被复制到正确的 shell 提示符后面并且被执行。无穷无尽的拷贝与粘贴终于被终结了。 更理想的情况下,如果你想修改的命令还仍然显示在你当前的屏幕范围内(这在我的工作当中覆盖了大多数情况),甚至可以省略使用 Ctrl-r 组合进进行查找的过程,直接移动光标到你需要的命令,修改,或者回车就是了。 图2回页首 技术性击倒 上面提到的还只是一些很简单的事情。或者说是一些使用习惯方面的事情。每个人都有自己的生活习惯。我就见过一些人,他们甚至很少使用 History 功能。他们执行每一条命令都会从头到尾输入进去。如果中间有什么东西写错了,他们会停下来再输一遍。我只能承认我没有他们那么勤奋了。 下面我们要谈论一些真正技术性的问题。一个实际工作中的案例问题。我在上面提到过,我的日常工作的一部分就是使用 Omegamon XE for Messaging 产品,既然他是监控 WebSphere MQ 的一款产品,那么同样意味着我也会频繁使用 WebSphere MQ 产品。一天,我需要处理这样一个问题,我有 11 个处于停止状态的队列管理器(Queue Manager),他们全部需要启动起来。 图3 通常在 shell 环境下,会有两个选择。第一个选择,一条一条的编写 11 条strmqm 命令,将所有这些队列管理器一个一个地启动起来。第二个选择,我可以使用 SED 实用工具编写一些小脚本,利用 dspmq 命令产生的输出内容来生成这 11 条命令,并把它们输出到一个文件里面。是的,在使用 Emacs 之前我是使用这第二种方法的。现在,在 Emacs 里面,我可以使用第三种选择,一种所见即所得的选择。Emacs 不仅提供了全屏幕编辑的全套功能,而且还提供了超越传统编辑方式的矩形编辑功能。使用这个功能,你可以把屏幕上的任何内容作为一个矩形块进行剪切或粘贴操作。现在跟我一起,把光标定位到 QM_100 的字母 Q 的位置,并输入 Ctrl-@ 组合键设置起始的标记位。接下来把光标移动到 QM_110 的数字 0 的后面,输入 Ctrl-x r k 组合键(对,一共是 4 个按键。但是仍然非常容易记忆,只要记住中间的 r 是rectangle 的缩写就行了,所有的矩形编辑命令都会有这个 r 字母加入)。看看屏幕上面发生了什么?是的,所有的队列管理器的名字全都不见了。他们被作为一个矩形块剪切进了 Emacs 的删除环(king-ring)当中。 图4 接下来,让我们将这些剪切下来的队列管理器的名字粘贴到一个用来启动这些队列管理器的脚本文件中去。在这里我们使用最简单的 here 文档的功能 cat <<eof >strmqm.sh,创建一个空白的脚本文件。然后,在 Emacs 当中输入 Ctrl-x r y 组合键,这个组合键的作用是将删除环里面的矩形文本块作为一个矩形,粘贴回去。下面的截图就是你在屏幕上所看到的结果。 图5 没错,你注意到了,我们真正需要的并不是队列管理器的名字列表,而是一连串 strmqm QM_100 这样的 shell 命令。没问题,接下来让我们继续使用 Emacs 的矩形编辑功能来完成这些命令。再次把光标移动到 QM_100 的字母 Q 的位置,输入 Ctrl-@ 组合键设置标志,然后移动光标到 QM_110 的字母 Q 的位置,输入 Ctrl-x r p 组合键。这个组合键的作用是在选定的位置前面填充一个矩形区域,填充的内容在提示缓冲区里面输入。现在在提示缓冲区里面 string insert rectangle: 的提示符后面输入 strmqm 加空格。下面的截图就是这个时候你在屏幕上所看到的结果。 图6 这里面有一个小秘密需要提示一下,因为在 here 文档的提示符下事实上是不可能进行这样的修改的。但是,直到目前为止 Emacs 还没有将编辑缓冲区里的内容传递给 here 文档提示符。以上所做的一切还都仅仅发生在 Emacs 内部。 现在输入一个回车键,已经编辑好的 11 条strmqm QM_1xx 命令就已经传递给 here 文档提示符了。最后输入 eof 结束文档编辑。一个简单清晰的队列管理器启动脚本就已经完成了。只要在 shell 提示符下通过 bash strmqm.sh 命令运行它,就可以启动所有这 11 个队列管理器了。 图7回页首 一些有趣的小技巧 第一个小技巧:在 Emacs 里面同时打开多个 shell 会话 这听起来应该是理所当然的,既然 Emacs 可以同时运行多个窗口……但是即使是在我买的那本关于 Emacs 的书里面也没有提到如何能够真的打开多个 shell 会话。让我们试试看,输入 ESC-x shell 启动shell 会话,在 shell 提示符下执行 cd /tmp 命令,然后输入 Ctrl-x 2 组合键将屏幕切分成上下两个窗口,然后再次输入 ESC-x shell 启动shell 会话,你会发现 Emacs 不为所动。在上下两个窗口里面仍然还是 cd /tmp 命令执行后的结果,也就是说仍然还是原先的那个 shell 会话。说起来 O’reilly 公司应该退还我一部分书钱,因为他们没有将我想知道的问题讲明白。后来我终于发现了解决的办法。只要我将当前的 shell 会话所在的缓冲区重新命名,然后就可以再次启动一个新的 shell 会话。让我们来试试看。输入 ESC-x rename-buffer,在 Rename buffer (to new name): 提示符后输入一个新名字,例如 *shellA*。这个时候你会看到上下两个窗口中的缓冲区都被重命名为 *shellA* 了,是的,他们显示的是同一个缓冲区。现在在任意一个窗口里面输入 ESC-x shell 启动shell 会话,这时你会看到一个新的 *shell* 缓冲区创建了出来,并且有了一个新的 shell 提示符。现在让我们在这个新的 shell 提示符下执行 cd / 命令,你会发现,缓冲区 *shellA* 当中的 shell 会话并没有受到新的命令的影响,因为他们是两个不同的 shell 会话。重复同样的方法,可以得到更多的 shell 会话,满足你的使用需要。 图8 第二个小技巧:history | grep 的输出结果可以直接输入回车使用 让我们再回到当初提到过的第 437 条命令。如果需要再次运行这条命令,你只需要把光标定位到这条命令所在行,删除掉命令前面的 437 这个号码,然后直接输入回车,Emacs 会提你把它复制到正确的 shell 提示符后并且启动执行。似乎这个方式描述起来并没有 shell 本身提供的 !437 命令来的迅速,但是他毕竟提供了一个更加直观的操作可能。另外,如果希望在运行之前对于这条命令进行一些修改,我指的是删除,例如删除掉某个参数,或者单词,你也尽可以尽情删除,然后在最终的删除结果上面输入回车,告诉 Emacs 去复制运行就是了。这个状况目前似乎还没有发现 ! 命令有可以搞定的可能。另外,如果希望在运行之前对于这条命令进行一些添加性质的修改,例如添加一些新的参数,或者把第 437 条命令中的 start 单词删掉,添加上 stop 单词,在目前的 Emacs 里面还没有提供直接的支持。但是我们可以通过增加一步操作来实现它。第一步,让我们首先把光标定位到第 437 条命令的位置,然后输入回车,这个时候命令不会成功运行,一行提示信息 bash: 437: command not found 会显示在你的 shell 提示符下面。没关系,让我们稍微修改一下刚刚运行失败的这条命令。重新定位光标到刚刚执行过的这条命令所在的行,然后把命令中的 start 参数修改为 stop 参数,并且删除命令前面的 437 这个号码,再次输入回车,修改之后的命令就会成功运行了。这里增加的第一步操作实际上代替了通常情况下需要的拷贝粘贴操作,拷贝和粘贴事实上是交由 Emacs 替我们实现了。 图9 第三个小技巧,整理你的屏幕 在前面讲到生活舒适度话题的时候,我们曾经提到过在 Emacs 里面使用 shell 的一个很常用的方法就是在屏幕上已有的命令上面稍作修改,或者直接回车来复用已经执行过的历史命令。但是如果你所感兴趣的命令因为种种原因已经不在当前屏幕显示的范围之内了,除了不断的通过使用 Ctrl-r 组合键进行回朔查找以外,还有没有什么更方便的办法呢?答案是有,而且还有不止一种选择。如果在你的当前提示符和你感兴趣的命令之间仅仅只是由于时间的关系隔着太多无关的命令记录,那么你尽可以简单的将这些多余的内容删除掉就行了。不要担心,这些内容仅仅只是在 *shell* 编辑缓冲区里的普通文本内容而已,将他们删除和将一篇文档里面的文本删除没有什么区别。如果这些中间的命令记录并不是完全无用了,仅仅只是在现在这段时间不感兴趣的话,你还可以选择使用 hide-region-hide 命令将这些中间的命令记录作为一个文本块隐藏起来。这些隐藏起来的内容仅仅只是不再在屏幕上显示而已,他们仍然存留在原有的编辑缓冲区里面,以后当你再次需要他们的时候,可是使用 hide-region-unhide 命令再把他们重新显示出来。还有一种情况就是仅仅因为你刚刚执行了一个产生大量输出的命令而已,比如说使用 cat 命令书出了一个较大的日志文件,从而导致你感兴趣的历史命令被日志文件的内容冲出了当前屏幕显示范围,这个时候只需要输入 Ctrl-c Ctrl-o 组合键,将刚刚执行过的那条命令的屏幕输出清除掉就是了。通常我在每次 cat 日志文件或者列出一个含有较多文件的目录之后都会使用 Ctrl-c Ctrl-o 组合键来清理一下我的屏幕。 最后我们再来说一个非常有用的小技巧,使用缩写词 Emacs 的强大的缩写词(abbrev)功能,这些缩写词功能同样可以应用到 Emacs 当中的 shell 环境里来。通常在使用 Emacs 便写文章的时候,我们会使用缩写词功能来减少频繁输入冗长的单词或者语句时候的击键次数,或者使用缩写词功能避免一些可能的拼写错误。当我们在 Emacs 里面使用 shell 的时候,我们同样可以使用缩写词功能来缩写一些冗长的命令,路径,和避免一些常见的输入错误,这样在每天的工作当中会为我节省大量的击键次数。有些读者看到这里一定会想到 shell 本身提供的别名(Alias)功能也能完成命令的缩写,但是,别名功能有很多局限性。首先,别名功能缩写的命令只能通过别名单独引用,无法和其他 shell 命令一同组合运行。例如我可以定义一个别名来进入常用的 IBM Tivoli Monitoring 产品的安装目录,alias cditm=’cd /opt/IBM/ITM’, 然后输入 cditm 执行这条命令来进入 IBM Tivoli Monitoring 产品的安装目录。但是我不能够定义一个别名来缩写这个目录本身,alias itmm=’/opt/IBM/ITM’, 然后输入 cd itmm 执行这条命令来进入这个目录,或者输入 itmm/bin/cinfo –r 来直接引用该目录下的可执行文件。还有一个问题,通过别名定义的命令缩写只能够直接引用执行,没有可能对于很多相似的命令定义通用的一个“别名模板”,然后每次使用的时候引用模板,然后稍作修改之后运行。例如启动 Omegamon XE for Messaging 产品中的 MQ Monitoring agent 的常用命令,bin/itmcmd agent –o QM_101 start mq。我可以把它定义为一个别名,alias strkmq_QM101=’bin/itmcmd agent –o QM_101 start mq’, 但是事实上每次在启动一个 MQ Monitoring Agent 的时候,其中的队列管理器(Queue Manager)的名称都是不同的,我不可能为每一个队列管理器都定义一个单独的别名。况且还有其他的 agent,这样的话别名的数量将会相当可观。Emacs 的缩写词功能在这里提供了两步走的设计方法,避免了以上提到的所有问题。让我们还是以上面提到的目录和命令的两个例子来了解一下在 Emacs 里面如何使用缩写词功能来解决这些问题。首先是常用目录的缩写词定义。在 shell 提示符下输入 cd /opt/IBM/ITM 命令,不用专门为了缩写词去输入这条命令,就在你日常工作当中需要的时候输入就是了,只是记得先不要输入回车,然后,让我们数一数究竟有多少个单词将被包含在这个缩写词定义当中,在这里是 3 个单词,分别是 opt, IBM 和ITM,现在输入 Ctrl-u 3 Ctrl-x a l 组合键,稍微有点儿复杂,我在这里简单解释一下,Ctrl-u 在Emacs 里面是一个非常有用的组合键,它代表一个通用前缀,通常在后面跟一个数字参数,表示随后输入的命令将被重复多少单元,在这个例子里是 3 个单元,后面的 Ctrl-x a l 组合键代表在当前主模式下添加缩写词定义(add-mode-abbrev)命令,其中的 l 代表将该缩写词的定义添加到当前的主模式中,如果希望这个缩写词定义在任何主模式下都可以使用,那么将组合键中的 l 替换成 g,即 Ctrl-x a g, 代表add-global-abbrev 命令。然后,在提示缓冲区确认定义无误之后,输入希望的缩写单词,itmm,即可完成缩写词定义。 图10 接下来我们来使用这个缩写词。例如我们需要进入到 IBM Tivoli Monitoring 产品的安装目录,在 shell 提示符下输入 cd /itmm 加空格,你会发现 Emacs 立刻将这条命令扩展成为 cd /opt/IBM/ITM 显示在刚才的输入位置。现在我们要执行 IBM Tivoli Monitoring 产品目录下的 cinfo 可执行程序,在 shell 提示符下输入 /itmm 加空格,Emacs 立刻将这条命令扩展成为 /opt/IBM/ITM 显示在刚才的输入位置,然后我们只需要输入一个退格键删掉刚才那个空格,继续在后面输入 bin/cinfo –r 就可以了。事实上由于在我的工作当中 , 对于cinfo 命令来说,-r 这个参数非常常用,所以在我的 Emacs 里,bin/cinfo –r 已经被缩写成了 rcinfo 这个缩写词了。那么在我的 Emacs 里面我只需要输入 /itmm 空格键,退格键和 rcinfo 就可以实现完整的 /opt/IBM/ITM/bin/cinfo –r 这条命令了。 再下来我们来看看启动 MQ Monitoring Agent 的命令的缩写词。在 shell 提示符下输入 bin/itmcmd agent –o start mq 命令,注意,在–o 参数后面没有提供队列管理器的名字。因为每次执行这条命令的时候,队列管理器的名字都有可能变化,因此我们不把它定义到缩写词内部。输入 Ctrl-u 6 Ctrl-x a l 组合键,然后,在提示缓冲区确认定义无误之后,输入希望的缩写单词,strkmq 即可完成缩写词定义。 图11 现在让我们来使用这个缩写词。首先我们需要使用 itmm 这个缩写词进入到 IBM Tivoli Monitoring 产品的安装目录,然后,在 shell 提示符后面输入 strkmq 空格,Emacs 立刻将这条命令扩展成为 bin/itmcmd agent –o start mq 显示在刚才的输入位置,现在移动光标到–o 参数后面,输入队列管理器的名称并且回车,你就会看到希望的命令得到运行。 发明一个完美无缺的 shell 是一件相当困难的事情,但是将现有的资源整合起来却会产生很多意想不到的效果。