Emacs使用教程(八)

查找替换是任何编辑器都不可能缺少的功能,就连小小的Notepad都有快速查找,更不用说像Emacs这样的庞然大物了。其重要性这里就不多说了,接下来将一步一步给你介绍如何在Emacs中进行查找和替换。

  Emacs将查找分成了四个大类,分别是:简单查找,增量查找,词组查找和正则查找。四种方式各有特点,适用范围也不同,大家根据需要熟悉一两种即可。

​一、增量查找 

   先介绍增量查找的原因是这个是用的最多的查找方式,使用也很方便,直接C-s (isearch-forward)便进入增量查找状态,Minibuffer出现如下提示: 

 

   其实增量查找很好理解,就是边输入边查找,在输入的过程中离光标最近的匹配会用深色高亮,一屏中其它的匹配字符串会浅色高亮,参见这张图:

 

  只要是单词中包含”to” 的都会标记出来,比如tutorial。在输入查找字符串过程中可以随时用Backspace删除输入字符,当输入完成后按下回车会定位到向前最近的匹配字符串,并出现提示“Mark saved where search started”,就是说将你开始查找时光标所在位置加入了标记环,我们可以通过C-u C-@回到那个点。如果没找到字符串提示为“Failing I-search”,后接查找内容。C-s搜索时是向前进行查找,我们还可以使用C-r (isearch-backward)向后进行查找,注意这种方式的查找光标会定位到匹配字符串的最前方。虽然查找过程只会向一个方向进行,但到了文档底部或者头部还是会回到文档的头或底继续找,这就是常说的循环查找。

  在搜索的过程中并不一定第一个匹配项就是我们需要的内容,或者说我们需要找的地方不止一处,这样我们想能够快速的定位到下一个匹配项位置,解决办法也很简单,接上例我们输入”to”后不要急着按回车,而是再用C-s就会向后定位,或者用C-r 向前定位,总之停到你想要的地方为止。另外,如果你退出了这次的查找,后面又想找同一个东西,那么使用C-s C-s 即可,同理C-r C-r 。

  Emacs在多次查找的过程中会维护一个查找环(search ring) ,这是我们见到的第三个环了,前面两个是mark ring、kill ring。在输入C-s后,使用M-n和M-p可以调出查找环中上一个和下一个查找的内容。虽然这个也叫环但它是个标准的队列,有头有尾不会循环。

  在增量查找中还有些特殊的功能:通常查找时是忽略了大小写的,但如果我们输入的查找内容有小写字母还有小写字母,Emacs会自动进入大小写匹配查找状态中;也可以在查找的过程用M-c 快速切换是否大小写敏感,不过只对此次查找启用;如果我们想找回车符用C-j 代替;还可以使用M-Tab (isearch-complete)对查找进行自动完成,候选项是查找环中的东西,当然你用M-Tab 是没效果的,用了后连Emacs都不在了,我们需要对isearch-complete重新绑定;在增量查找状态中按C-h C-h 会进入增量查找的帮助,里面的内容大家可以自己研究;使用C-w 可以将光标处单词复制到查找区域中进行快速输入,这个功能比较常用;与其类似的是C-y 它能够把光标所在处直到行尾的内容都复制到查找区域,提醒一点这两个命令在复制的过程中会把所有字母变成小写;M-y 还能把kill 环里的内容复制到查找区域;C-M-w 用于删除查找区域中最后一个字符;而C-M-y 把光标处字符复制到查找区域最后;复制光标处的字符还有个方法,进入增量查找状态后,首先按M-e 定位到查找区域的最后,再使用C-f 就可以开始复制了。

 

二、简单查找

  简单查找顾名思义就是简单的查找方式(其实不一定有增量查找来的快),有时候又叫它非增量查找。使用命令是C-s RET string RET ,首先用C-s调出增量查找,然后回车取消掉进入简单查找,再输入需要查找的字符串,最后回车Emacs会向后开始找,直到第一个满足的字符串后面。大家在按命令的过程中可以观察Minibuffer中的提示,按下C-s后,会出现一个蓝色的“I-search:”,回车后变为“Search:”,当找到所输入的内容后出现提示“Mark saved where search started”,其实简单查找和增量查找大部分都没什么区别,增量查找中命令基本上这儿也能用,最大的区别就是等你输入完成后它才开始搜索,还有一点就是没有高亮。向前查找的话一回事,C-r RET string RET 。向后向前分别对应命令search-forwardsearch-backward

 

三、词组查找

  词组查找一般用在大段文本编辑中,比如写新闻、写信之类的。它在查找的过程中会忽略掉一些标点符号,比如换行符,逗号,句号之类的,查找时也是进行的增量查找,边输入边找,不过对于单词来说是全词匹配。其命令是M-s w (isearch-forward-word)。查找的示例如下图:

 

 

   我在找”it”的时候,红框圈出来的permitted并没高亮,而我输入”it under”时,逗号和回车符都忽略掉了,这些特点在查找大段句子的时候相当好用。词组查找也可以使用非增量搜索的方式,对应命令M-s w RET words RET (word-search-forward) ,向回找M-s w C-r RET words RET (word-search-backward),这里面的words就是你需要查找的词组。词组查找其余大部分使用方式和前面的类似就不多叙述了。

 

 四、正则查找

  这种查找方式使用正则表达式,功能相当的强大,其主要还是看各人正则表达式的水平了,Emacs中的正则语法放到后面再讲,这里只说下怎么调出正则查找。命令 C-M-s (isearch-forward-regexp),咳,用快捷键的时候把QQ关了,这个是向前找,命令可以看出来使用的是增量查找方式,向后是C-M-r (isearch-backward-regexp)。

 

五、替换

  本次的另一半内容就是介绍Emacs中的替换功能,就是将一个字符串变成另一个字符串。

  最简单粗暴的方式就是使用replace-string 这个命令,用法如下:M-x replace-string RET oldstring RET newstring RET,第一次回车输入需要替换的字符串,第二次回车输入想要变成的字符串,最后确认。它将会把所有匹配oldstring 的字符串全部替换掉,建议大家在没绝对把握前还是不要用这个的好。在替换的过程中Emacs对大小写有比较智能化的处理,比如输入M-x replace-string RET abc RET efg RET,所有的”abc”都变成了”efg”,但是”ABC”会替换成”EFG”,不止这样”aBc”会改为”eFg”,大写对大写,小写对小写。当然我们可能不想做这样的变化,那么把变量case-replace 设为nil 即可,还有个相关的变量case-fold-search ,设为nil后,它会在查找的时候就强制匹配大小写。

  暴力替换的正则版命令replace-regexp,用法和上面一样,只是oldstring改为正则表达式。

  实际上,我们在替换的时候并不希望所有的东西都换掉,还是想中间有个给自己判断选择的过程,在Emacs中称其为查找替换,M-% (query-replace) ,用的时候和前面一样,先输入oldstring,再输newstring,但是它是一个一个找的,对每个找到的匹配询问用户该如何处理,根据你的回答它再做出下个动作。下面这张表列出了所有可能的回答和相应。 

 

输入 响应
SPC 或者 y 替换当前匹配并前进到下一个匹配处
DEL 或者 n 忽略此次匹配并前进到下一个匹配处
. 替换当前匹配并退出
, 替换当前匹配并停在此处,再按y后前进
! 替换所有剩余匹配
^ 回到前一个匹配处
RET 或者 q 直接退出
e 修改新字符串
C-r 进入递归编辑状态
C-w 删除当前匹配并进入递归编辑状态
C-M-c 退出递归编辑状态,返回查找替换
C-] 退出递归编辑状态,同时退出查找替换
C-h 显示帮助

 

      这些命令中,相对y,n,q用的会多点。但如果按了任何其它的键都会退出查找替换状态,不小心退出后还能使用C-x ESC ESC返回。

      最后说下什么是递归编辑状态,简单的说就是你在查找替换的过程中突然发现需要修改点东西,但又不想直接退出查找替换,这时Emacs提供了一个临时的编辑状态可以让你先干刚想起的事,等你做完了还可以回到查找替换状态,这个临时的状态就叫递归编辑状态。

 

      注意看,这时mode line中的模式名外面加了一层方括号”[]”,标明进入了递归编辑状态。干完事后使用C-M-c 就可以回到前一个状态,实际上,在任何时候都可以用命令 recursive-edit 进入递归编辑,用abort-recursive-edit 或者top-level 退出,也可以用C-M-c 返回前一状态。

 

小结:

 

按键

命令

作用

C-s

isearch-forward

向前进行增量查找

C-r

isearch-backward

向后进行增量查找

M-c

 

(查找状态)切换大写敏感

C-j

newline-and-indent

(查找状态)输入换行符

M-Tab

isearch-complete (查找状态)自动匹配

C-h C-h

 

(查找状态)进入查找帮助

C-w   (查找状态)将光标处单词复制到查找区域
C-y   (查找状态)将光标处直到行尾内容复制到查找区域
M-y   (查找状态)把kill 环中最后一项复制到查找区域
C-M-w   (查找状态)删除查找区域最后一个字符
C-M-y   (查找状态)将光标处字符复制到查找区域最后
C-f   (查找状态)将光标处字符复制到查找区域最后
C-s RET search-forward 向前进行简单查找
C-r RET search-backward 向后进行简单查找
M-s w isearch-forward-word 向前进行词组查找
M-s w RET word-search-forward 向前进行词组查找(非增量方式)
M-s w C-r RET word-search-backward 向后进行词组查找(非增量方式)
C-M-s isearch-forward-regexp 向前进行正则查找
C-M-r isearch-backward-regexp 向后进行正则查找
  replace-string 全文替换
  replace-regexp 全文正则替换
M-% query-replace 查找替换
  recursive-edit 进入递归编辑
  abort-recursive-edit 退出递归编辑
  top-level 退出递归编辑

 

 

 

 

变量

作用

case-replace 设置大小写自动替换
case-fold-search 设置大小写匹配查找

 

 

 

Emacs使用教程(七)

 Emacs 在不同的操作系统中表现会有一些小的差异,这里我接着上一章所提到的粘贴复制来比较一下不同操作系统中Emacs的剪切板。

 

一、复制到剪切板

  在Emacs中我们剪切、复制文本除了使用命令之外,还可以利用工具栏上的快捷按钮或者菜单栏里面菜单项,在默认情况使用工具栏和菜单栏进行剪切复制都会把相关内容发送到系统剪切板供其它程序使用。在Windows 和Mac OS X中使用C-w 或M-w也会复制内容到剪切板,不过Linux不行。

  我们选择区域的另一种方式是使用鼠标,它也有小小的差别,如下表: 

使用鼠标选择区域
  Linux Windows Mac OS X
是否发送到系统剪切板 no yes yes
是否发送到Kill环 yes yes yes

       在Linux中想要发送到系统剪切板除了使用鼠标点工具栏还可以利用几个剪切板命令,比如clipboard-kill-region 剪切区域并发送到系统剪切板和Kill 环中,clipboard-kill-ring-save 复制区域内容到系统剪切板和Kill 环中。当然这两个命令Windows 和Mac里面也可以用。本质上这两个命令就是菜单栏中对应的剪切和复制。

 

二、从剪切板中提取

      既然从Emacs到系统剪切板有差异那从剪切板复制到Emacs里面也有些不同,直接看下表: 

从系统剪切板粘贴
  Linux Windows Max OS X
C-y粘贴 yes yes yes
工具栏粘贴按钮 yes yes no
菜单栏粘贴菜单项 yes yes no
鼠标中键 yes yes yes
M-x clipboard-yank yes yes yes

      这里解释几个地方,一是鼠标中键,有的鼠标没中键就是滑轮了,它也有粘贴功能,而命令clipboard-yank 从剪切板中粘贴对应的是菜单栏上的粘贴功能。

 

小结:

      本章内容很少,就是一些简单的对比,在以后的学习中还能见到更多的不同平台下Emacs的差异。

 

按键

命令

作用

  clipboard-kill-region 剪切区域并发送到系统剪切板和Kill 环中
  clipboard-kill-ring-save 复制区域内容到系统剪切板和Kill 环中
  clipboard-yank 从剪切板中粘贴到Emacs中

YUM保存软件包及离线下载

默认情况下,当前版本的 yum 在成功下载和安装软件包后,会把下载的文件删掉。这样可以减少 yum 占用的磁盘空间。你可以打开缓存,这样 yum 将在缓存目录保留下载到的文件。

1. 缓存优势:

  • yum 的性能可以提高

  • 只使用缓存你可以离线运行 yum 操作

  • 你可以复制缓存中的软件包以备用

默认情况下,yum 在 /var/cache/yum/ 目录保存临时文件,每个仓库都有自己的子目录。仓库目录中 packages/ 子目录包含了缓存的软件包。例如,目录/var/cache/yum/development/packages/ 包含从 development 仓库下载的软件包。

2. 启用 yum 缓存

要配置 yum 保留已下载的文件而不是删除,设置 /etc/yum.conf 中的keepcache 选项为 1:

keepcache=1

打开缓存后,每个 yum 操作都可能从仓库下载软件包数据。要保证缓存包含了软件包数据,在启用缓存后运行一个操作,例如 list 或 search 来下载软件包数据而不影响系统。

3.在只使用缓存的模式下使用 yum

要在没有网络的情况下执行 yum,只要启用了缓存,就可以用 -C 选项。这样 yum 就不会检查网络上的仓库,只使用缓存。在这个模式中,yum 只能安装已下载并缓存的软件包。

要在没有网络连接的时候搜索软件包 tsclient,输入命令:

su -c 'yum -C list tsclient'

4. 缓存带来的好处

如果你有多台机子 只须要一台机子从网上下载 软件包跟软件更新包 , 还有如果你想重装系统不想再下载的几个G的更新跟软件(前提缓存了你系统所有安装的软件的更新包).

在开启 缓存的状态下因为 yum 下载的软件包不会被删除,所以可以多次利用.(就是占硬盘空间而以, 呵呵几个G我不放在眼里,我硬盘有 1.2TB)

很简单的方法,把这台机子的 /var/cache/yum/ 目录下的所有文件包过目录. 复制到另一台机子下的相同目录. 执行.

# yum -C update
# yum -C install <软件包名>

5.清空 yum 缓存

# yum clean headers

要删除缓存中所有软件包,使用命令:

#yum clean package
[root@Iprayz ~]# rpm -ql yum    /var/cache/yum
[root@Iprayz ~]# cat /etc/yum.conf |grep  cachedir cachedir=/var/cache/yum/$basearch/$releasever
[root@Iprayz ~]# cat /etc/yum.conf |grep keep  keepcache=0
#  Fedora which don't keep old packages around. If you don't like this checking
[root@Iprayz ~]#

Maven简介

1.1 何为Maven

Maven这个词可以翻译为“知识的积累”,也可以翻译为“专 家”或“内行”。本书将介绍Maven这一跨平台的项目管理工具。作为Apache组织中的一个颇为成功的开源项目,Maven主要服务于基于Java平 台的项目构建、依赖管理和项目信息管理。无论是小型的开源类库项目,还是大型的企业级应用;无论是传统的瀑布式开发,还是流行的敏捷模式,Maven都能 大显身手。

1.1.1  何为构建

不管你是否意识到,构建(build)是每一位程序员每天都在做的工作。早上来 到公司,我们做的第一件事情就是从源码库签出最新的源码,然后进行单元测试,如果发现失败的测试,会找相关的同事一起调试,修复错误代码。接着回到自己的 工作上来,编写自己的单元测试及产品代码,我们会感激IDE随时报出的编译错误提示。
忙到午饭时间,代码编写得差不多了,测试也通过了,开心地享 用午餐,然后休息。下午先在昏昏沉沉中开了个例会,会议结束后喝杯咖啡继续工作。刚才在会上经理要求看测试报告,于是找了相关工具集成进IDE,生成了像 模像样的测试覆盖率报告,接着发了一封电子邮件给经理,松了口气。谁料QA小组又发过来了几个bug,没办法,先本地重现再说,于是熟练地用IDE生成了 一个WAR包,部署到Web容器下,启动容器。看到熟悉的界面了,遵循bug报告,一步步重现了bug……快下班的时候,bug修好了,提交代码,通知 QA小组,在愉快中结束了一天的工作。

仔细总结一下,我们会发现,除了编写源代码,我们每天有相当一部分时间花在了编 译、运行单元测试、生成文档、打包和部署等烦琐且不起眼的工作上,这就是构建。如果我们现在还手工这样做,那成本也太高了,于是有人用软件的方法让这一系 列工作完全自动化,使得软件的构建可以像全自动流水线一样,只需要一条简单的命令,所有烦琐的步骤都能够自动完成,很快就能得到最终结果。

1.1.2  Maven是优秀的构建工具

前面介绍了Maven的用途之一是服务于构建,它是一个异常强大的构建工具,能 够帮我们自动化构建过程,从清理、编译、测试到生成报告,再到打包和部署。我们不需要也不应该一遍又一遍地输入命令,一次又一次地点击鼠标,我们要做的是 使用Maven配置好项目,然后输入简单的命令(如mvn clean install),Maven会帮我们处理那些烦琐的任务。

Maven是跨平台的,这意味着无论是在Windows上,还是在Linux或者Mac上,都可以使用同样的命令。

我们一直在不停地寻找避免重复的方法。设计的重复、编码的重复、文档的重复,当 然还有构建的重复。Maven最大化地消除了构建的重复,抽象了构建生命周期,并且为绝大部分的构建任务提供了已实现的插件,我们不再需要定义过程,甚至 不需要再去实现这些过程中的一些任务。最简单的例子是测试,我们没必要告诉Maven去测试,更不需要告诉Maven如何运行测试,只需要遵循Maven 的约定编写好测试用例,当我们运行构建的时候,这些测试便会自动运行。

想象一下,Maven抽象了一个完整的构建生命周期模型,这个模型吸取了大量其 他的构建脚本和构建工具的优点,总结了大量项目的实际需求。如果遵循这个模型,可以避免很多不必要的错误,可以直接使用大量成熟的Maven插件来完成我 们的任务(很多时候我们可能都不知道自己在使用Maven插件)。此外,如果有非常特殊的需求,我们也可以轻松实现自己的插件。

Maven还有一个优点,它能帮助我们标准化构建过程。在Maven之前,十个项目可能有十种构建方式;有了Maven之后,所有项目的构建命令都是简单一致的,这极大地避免了不必要的学习成本,而且有利于促进项目团队的标准化。

综上所述,Maven作为一个构建工具,不仅能帮我们自动化构建,还能够抽象构建过程,提供构建任务实现;它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的、流行的构建工具。

1.1.3  Maven不仅仅是构建工具

Java不仅是一门编程语言,还是一个平台,通过JRuby和Jython,我 们可以在Java平台上编写和运行Ruby和Python程序。我们也应该认识到,Maven不仅是构建工具,还是一个依赖管理工具和项目信息管理工具。 它提供了中央仓库,能帮我们自动下载构件。

在这个开源的年代里,几乎任何Java应用都会借用一些第三方的开源类库,这些 类库都可通过依赖的方式引入到项目中来。随着依赖的增多,版本不一致、版本冲突、依赖臃肿等问题都会接踵而来。手工解决这些问题是十分枯燥的,幸运的是 Maven提供了一个优秀的解决方案,它通过一个坐标系统准确地定位每一个构件(artifact),也就是通过一组坐标Maven能够找到任何一个 Java类库(如jar文件)。Maven给这个类库世界引入了经纬,让它们变得有秩序,于是我们可以借助它来有序地管理依赖,轻松地解决那些繁杂的依赖 问题。

Maven还能帮助我们管理原本分散在项目中各个角落的项目信息,包括项目描 述、开发者列表、版本控制系统地址、许可证、缺陷管理系统地址等。这些微小的变化看起来很琐碎,并不起眼,但却在不知不觉中为我们节省了大量寻找信息的时 间。除了直接的项目信息,通过Maven自动生成的站点,以及一些已有的插件,我们还能够轻松获得项目文档、测试报告、静态分析报告、源码版本日志报告等 非常具有价值的项目信息。

Maven还为全世界的Java开发者提供了一个免费的中央仓库,在其中几乎可以找到任何的流行开源类库。通过一些Maven的衍生工具(如Nexus),我们还能对其进行快速地搜索。只要定位了坐标,Maven就能够帮我们自动下载,省去了手工劳动。

使用Maven还能享受一个额外的好处,即Maven对于项目目录结构、测试用 例命名方式等内容都有既定的规则,只要遵循了这些成熟的规则,用户在项目间切换的时候就免去了额外的学习成本,可以说是约定优于配置 (Convention Over Configuration)。

1.2 为什么需要Maven

Maven不是Java领域唯一的构建管理的解决方案。本节将通过一些简单的例子解释Maven的必要性,并介绍其他构建解决方案,如IDE、Make和Ant,并将它们与Maven进行比较。

1.2.1  组装PC和品牌PC

笔者初中时开始接触计算机,到了高中时更是梦寐以求希望拥有一台自己的计算机。我的第一台计算机是赛扬733的,选购是一个漫长的过程,我先阅读了大量的杂志以了解各类配件的优劣,CPU、内存、主板、显卡,甚至声卡,我都仔细地挑选,后来还跑了很多商家,调货、讨价还价,组装好后自己装操作系统和驱动程序……虽然这花费了我大量时间,但我很享受这个过程。可是事实证明,装出来的机器稳定性不怎么好。

一年前我需要配一台工作站,这时候我已经没有太多时间去研究电脑配件了。我选择了某知名PC供应商的在线商店,大概浏览了一下主流的机型,选择了我需要的配置,然后下单、付款。接着PC供应商帮我组装电脑、安装操作系统和驱动程序。一周后,物流公司将电脑送到我的家里,我接上显示器、电源、鼠标和键盘就能直接使用了。这为我节省了大量时间,而且这台电脑十分稳定,商家在把电脑发送给我之前已经进行了很好的测试。对了,我还能享受两年的售后服务。

使用脚本建立高度自定义的构建系统就像买组装PC,耗时费力,结果也不一定很好。当然,你可以享受从无到有的乐趣,但恐怕实际项目中无法给你那么多时间。使用Maven就像购买品牌PC,省时省力,并能得到成熟的构建系统,还能得到来自于Maven社区的大量支持。唯一与购买品牌PC不同的是,Maven是开源的,你无须为此付费。如果有兴趣,你还能去了解Maven是如何工作的,而我们无法知道那些PC巨头的商业秘密。

1.2.2  IDE不是万能的

当然,我们无法否认优秀的IDE能大大提高开发效率。当前主流的IDE如Eclipse和NetBeans等都提供了强大的文本编辑、调试甚至重构功能。虽然使用简单的文本编辑器和命令行也能完成绝大部分开发工作,但很少有人愿意那样做。然而,IDE是有其天生缺陷的:

  • IDE依赖大量的手工操作。编译、测试、代码生成等工作都是相互独立的,很难一键完成所有工作。手工劳动往往意味着低效,意味着容易出错。

  • 很难在项目中统一所有的IDE配置,每个人都有自己的喜好。也正是由于这个原因,一个在机器A上可以成功运行的任务,到了机器B的IDE中可能就会失败。

我们应该合理利用IDE,而不是过多地依赖它。对于构建这样的任务,在IDE中一次次地点击鼠标是愚蠢的行为。Maven是这方面的专家,而且主流IDE都集成了Maven,我们可以在IDE中方便地运行Maven执行构建。

1.2.3  Make

Make也许是最早的构建工具,它由Stuart Feldman于1977年在Bell实验室创建。Stuart Feldman也因此于2003年获得了ACM国际计算机组织颁发的软件系统奖。目前Make有很多衍生实现,包括最流行的GNU Make和BSD Make,还有Windows平台的Microsoft nmake等。

Make由一个名为Makefile的脚本文件驱动,该文件使用Make自己定义的语法格式。其基本组成部分为一系列规则(Rules),而每一条规则又包括目标(Target)、依赖(Prerequisite)和命令(Command)。Makefile的基本结构如下:

<span style="font-size: small;">TARGET… : PREREQUISITE…  
COMMAND  
…  
…  
</span>

     Make通过一系列目标和依赖将整个构建过程串联起来,同时利用本地命令完成每个目标的实际行为。Make的强大之处在于它可以利用所有系统的本地命令,尤其是UNIX/Linux系统,丰富的功能、强大的命令能够帮助Make快速高效地完成任务。

但是,Make将自己和操作系统绑定在一起了。也就是说,使用Make,就不能实现(至少很难)跨平台的构建,这对于Java来说是非常不友好的。此外,Makefile的语法也成问题,很多人抱怨Make构建失败的原因往往是一个难以发现的空格或Tab使用错误。

1.2.4  Ant

Ant不是指蚂蚁,而是意指“另一个整洁的工具”(Another Neat Tool),它最早用来构建著名的Tomcat,其作者James Duncan Davidson创作它的动机就是因为受不了Makefile的语法格式。我们可以将Ant看成是一个Java版本的Make,也正因为使用了Java,Ant是跨平台的。此外,Ant使用XML定义构建脚本,相对于Makefile来说,这也更加友好。

与Make类似,Ant有一个构建脚本build.xml,如下所示:

<?xml version="1.0"?>
<project name="Hello" default="compile">
<target name="compile" description="compile the Java source code to class files">
<mkdir dir="classes"/>
<javac srcdir="." destdir="classes"/>
</target>
<target name="jar" depends="compile" description="create a Jar file ">
<jar destfile="hello.jar">
<fileset dir="classes" includes="**/*.class"/>
<manifest>
<attribute name="Main.Class" value="HelloProgram"/>
</manifest>
</jar>
</target>
</project>

build.xml的基本结构也是目标(target)、依赖(depends),以及实现目标的任务。比如在上面的脚本中,jar目标用来创建应用程序jar文件,该目标依赖于compile目标,后者执行的任务是创建一个名为classes的文件夹,编译当前目录的java文件至classes目录。compile目标完成后,jar目标再执行自己的任务。Ant有大量内置的用Java实现的任务,这保证了其跨平台的特质,同时,Ant也有特殊的任务exec来执行本地命令。

和Make一样,Ant也都是过程式的,开发者显式地指定每一个目标,以及完成该目标所需要执行的任务。针对每一个项目,开发者都需要重新编写这一过程,这里其实隐含着很大的重复。Maven是声明式的,项目构建过程和过程各个阶段所需的工作都由插件实现,并且大部分插件都是现成的,开发者只需要声明项目的基本元素,Maven就执行内置的、完整的构建过程。这在很大程度上消除了重复。

Ant是没有依赖管理的,所以很长一段时间Ant用户都不得不手工管理依赖,这是一个令人头疼的问题。幸运的是,Ant用户现在可以借助Ivy管理依赖。而对于Maven用户来说,依赖管理是理所当然的,Maven不仅内置了依赖管理,更有一个可能拥有全世界最多Java开源软件包的中央仓库,Maven用户无须进行任何配置就可以直接享用。

1.2.5  不重复发明轮子

【该小节内容整理自网友Arthas最早在Maven中文MSN的群内的讨论,在此表示感谢】

小张是一家小型民营软件公司的程序员,他所在的公司要开发一个新的Web项目。经过协商,决定使用Spring、iBatis和Tapstry。jar包去哪里找呢?公司里估计没有人能把Spring、iBatis和Tapstry所使用的jar包一个不少地找出来。大家的做法是,先到Spring的站点上去找一个spring.with.dependencies,然后去iBatis的网站上把所有列出来的jar包下载下来,对Tapstry、Apache commons等执行同样的操作。项目还没有开始,WEB.INF/lib下已经有近百个jar包了,带版本号的、不带版本号的、有用的、没用的、相冲突的,怎一个“乱”字了得!

在项目开发过程中,小张不时地发现版本错误和版本冲突问题,他只能硬着头皮逐一解决。项目开发到一半,经理发现最终部署的应用的体积实在太大了,要求小张去掉一些没用的jar包,于是小张只能加班加点地一个个删……

小张隐隐地觉得这些依赖需要一个框架或者系统来进行管理。

小张喜欢学习流行的技术,前几年Ant十分流行,他学了,并成为了公司这方面的专家。小张知道,Ant打包,无非就是创建目录,复制文件,编译源代码,使用一堆任务,如copydir、fileset、classpath、ref、target,然后再jar、zip、war,打包就成功了。

项目经理发话了:“兄弟们,新项目来了,小张,你来写Ant脚本!”

“是,保证完成任务!”接着,小张继续创建一个新的XML文件。target clean; target compile; target jar; …… 不知道他是否想过,在他写的这么多的Ant脚本中,有多少是重复劳动,有多少代码会在一个又一个项目中重现。既然都差不多,有些甚至完全相同,为什么每次都要重新编写?

终于有一天,小张意识到了这个问题,想复用Ant脚本,于是在开会时他说:“以后就都用我这个规范的Ant脚本吧,新的项目只要遵循我定义的目录结构就可以了。”经理听后觉得很有道理:“嗯,确实是个进步。”

这时新来的研究生发言了:“经理,用Maven吧,这个在开源社区很流行,比Ant更方便。”小张一听很惊讶,Maven真比自己的“规范化Ant”强大?其实他不知道自己只是在重新发明轮子,Maven已经有一大把现成的插件,全世界都在用,你自己不用写任何代码!

为什么没有人说“我自己写的代码最灵活,所以我不用Spring,我自己实现IoC;我不用Hibernate,我自己封装JDBC”?

 

Emacs使用教程(五)

一、标记和区域

  所谓区域(region)就是平时我们使用鼠标选中的一段文字,在emacs中用样可以使用鼠标来选择一段文字表示区域,如果使用键盘操作的话需要用一个术语叫标记(mark),也就是一个基准点,或者说是区域的起点,使用命令C-SPC 用来设定标记,不幸的是这个组合键通常情况是被输入法给截获了,我们得使用C-@来代替,要多按个Shift,操作起来感觉有点别扭。OK,在设定好标记后我们可以让光标移动到任何想去的地方,在光标和标记之间就是选定的区域,emacs里面会高亮显示这个区域,参见下图,注意,这个区域是动态存在的,只要光标位置变了,区域也随着变化,只是其起点永远是那个标记。

  这个时候就可以对选中的区域进行操作了,比如说C-w (kill-region) 删除选中的区域,或者C-x C-u 将所选区域字母改成大写字母,这是个禁用命令需要确认后才能生效。还有个常用的操作是C-x C-x (exchange-point-and-mark),交换光标和标记,就是说把区域的起点改在光标所在处。取消标记和区域直接使用C-g 就可以了。

  除了这种手工选择区域之外,emacs还内置了一些快捷的选取方式。像常用的全选就是C-x h ,全选后标记在文档的最后,而光标在文档的最前面。C-x C-p 选择整页,页是由分页符界定的。选取一段使用M-h 。M-@ 从当前位置选到单词尾(中文里的单词是两个标点符号间的文字),重复按这个命令会一直往后选取单词。这四个命令有个共同的特点就是选取的区域标记在最后,光标在最前,这个和常规理解有些区别,记住就是了。

  在Emacs 23之后还有个新特性叫shift选择(shift selection),故名思意就是用shift键来快速选择区域,通过使用shift键和C-n, C-p之类的组合来选择区域,和常规选择有些区别的是,在shift选择过程中使用了任何非shift组合都会取消当前选择区域。

二、标记环

  标记的一个主要功能是界定区域,此外还有个作用就是记忆一个点供今后使用,在一个buffer里面可以用标记记忆16个点,称为“标记环”,标记环实际是个先进先出的队列。

  我们使用命令C-@ C-@ 把一个标记加入标记环,这个命令做了两件事,第一次按C-@时标记了一个点(此时已经加入标记环了),第二次按C-@时取消了当前标记的激活状态,我们可以在minibuffer中看到提示Mark deactivated。而命令C-u C-@ 来选择上一个加入标记环的标记,如果选中的标记处于激活状态,它会取消其激活。使用C-u C-@不会删除标记,仅是在标记环中不停的向前跳跃,注意这里我们只可能在当前buffer中的标记间跳跃,不会跑到其它的buffer里面去。

  如果修改变量set-mark-command-repeat-pop 为 non-nil,在按下C-u C-@后,我们可以就使用C-@在标记环中跳跃了。

  变量mark-ring-max 表示了一个buffer中标记环中的最大标记数,默认为16。

  还有变量mark-even-if-nonactive 和标记环相关,当其为nil 时,表示只能使用激活状态的标记,默认为non-nil 。

  另外在emacs中还存在一个全局标记环,C-@ C-@在把标记加入当前buffer标记环同时,也把标记加入了全局标记环,我们可以用命令C-x C-@ (pop-global-mark)在全局标记环中选择。

三、非持久性标记模式

  这个东西这里只是稍微提及一下,平时用到的地方很少,所谓非持久性标记就是指我们在选择了一个区域后,任何修改该区域的操作都会改变区域的激活状态。而我们可以将非持久性标记模式关闭,这样选择的区域永远处于激活状态,命令是transient-mark-mode ,这是个切换变量只有开启和关闭两个状态,我们每次使用M-x transient-mark-mode命令都会将其值从一个切换到另一个。关闭该模式后最显著的特点是选择区域时没有高亮(不过使用鼠标选择和shift选择高亮还是有的)。令人头疼的也是这个特点,我们根本不知道自己选择了哪些地方。

  我们会使用这个东西只有一种情况,某些命令在关闭非持久性标记模式时,其作用有少许差异,不过基本上这些差异很少去关注,所以这段大家看看就行。

小结:

按键

命令

作用

C-@ set-mark-command 设定标记
C-x C-x exchange-point-and-mark 交换标记和光标位置
C-w kill-region 删除区域中内容
C-x C-u upcase-region 将区域中字母改为大写
C-x h mark-whole-buffer 全选
C-x C-p mark-page 选取一页
M-h mark-paragraph 选取一段
M-@ mark-word 选取一个单词
C-@ C-@   加入点到标记环
C-u C-@   在标记环中跳跃
C-x C-@ pop-global-mark 在全局标记环中跳跃
(none) transient-mark-mode 非持久化标记模式

变量

作用

set-mark-command-repeat-pop 是否使用C-@连续跳跃
mark-ring-max 标记环最大容量
mark-even-if-nonactive 是否只使用激活状态标记

解决CentOS安装过程中出现的Kdump安装失败

在安装完成重启后开始进行一些初始化的配置,在最后一项是配置Kdump,但是蛋疼的问题出现了。

看到这个“没有足够的内存配置kdump”(在英文界面下提示的是“insufficient memory to configure kdump”),但是我后来分配了4G内存给虚拟机,但是还是提示这个错误。后来想起kdump还有一个图形界面配置的命令,所以在终端下输入system-config-kdump命令,会弹出下面的界面:

选择Target settings,会弹出下面的界面:

我第一次点开的时候没有红色圈住的那部分,后来就点了那个“Reload”按钮,然后再点击了“apply”按钮,在终端下输入service kdump restart终于启动成功了!真是太爽了!

赶紧测试一下,输入echo “c”>/proc/sysrq-trigger,界面会出现一些信息,类似下面一样:

过一会系统就会自动重启,这个时候就说明你的kdump已经配置成功了,重启之后/var/crash目录下就可以看到有一个文件夹,文件夹的名字是日期,里面就是你需要的core文件。至此终于神奇的误打误撞成功了。如果你还没成功,就把那几个“apply”、“reload”,“enable”,“disable”按钮来回点,多试几次,说不定也像我一样成功了。

最后总结一下整个过程:

1、完全安装CentOS 6.2,所有的包都选,一个也不要落下。
2、安装按成后忽略“没有足够的内存配置kdump”(在英文界面下提示的是“insufficient memory to configure kdump”)这个错误,进入系统后打开终端输入system-config-kdump命令,如果没有,先安装。
3、在界面中先点击reload按钮,然后在点击“apply”让配置生效,重启系统,测试看是否成功。

 

安装CentOS时提示kdump安装失败

由于测试需要,我在Ubuntu的虚拟机下安装了CentOS。安装过程中一切顺利,结果在启动的时候发现kdump启动失败。
听名字感觉kdump像个debug工具。上网搜索了一下,得知:
[codesyntax lang=”text”]

kdump是在系统崩溃、死锁或者死机的时候用来转储内存运行参数的一个工具和服务。
打个比方,如果系统一旦崩溃那么正常的内核就没有办法工作了,
在这个时候将由kdump产生一个用于capture当前运行信息的内核,
该内核会将此时的内存中的所有运行状态和数据信息收集到一个dump core
文件中以便于Red Hat工程师分析崩溃原因,一旦内存信息收集完成,系统将自动重启。
这和以前的diskdump,netdump是同样道理。只不过kdump是RHEL5特有的。

[/codesyntax]
虽然不影响设备的正常使用,启动不了老是觉得不舒服。经过我的多次研究,我是这样修复的:

编辑/etc/sysconfig/kdump文件:
设置MKDUMPRD_ARGS和KDUMP_COMMANDLINE

MKDUMPRD_ARGS="/sbin/mkdumprd"(默认时这个参数的空的)
KDUMP_COMMANDLINE="ro root=LABEL=xxx"

其中xxx是root所在的分区的卷标。查看root卷标的命令是:
ls /etc/disk/by-label

保存,然后重启。

重启之后如果还不行:
安装kexec-tools
[codesyntax lang=”bash”]

yum install kexec-tools

[/codesyntax]
其实我不知道安装这个软件是不是必须的,
对于一般用户来说,没有必要开kdump。
所以建议初次时候通过ntsysv禁止其随开机启动

Vi中常用操作

插入类操作:

i:在光标之前添加文本
I:在光标行首添加文本
a:在光标之后添加文本
A:在光标行末添加文本
o:在光标下插入新行
O:在光标上插入新行

 

命令类操作:

:set nu 回车设置行号
:set nonu 回车取消行号
:n 移至文件的第n行
:n1,n2d 删除n1到n2行的内容

 

位置类操作:

ZZ: 退出
h: 左移一个字符
j: 下移一个字符
k: 上移一个字符
l: 右移一个字符
$: 移至行尾
0: 移至行首
Enter:移至下行行尾
H: 移至屏幕上端
M: 移至屏幕中端
L: 移至屏幕下端
G: 移至文件的最后一行
nG:移至文件的第n行:
1G移至文件的第1行,
10G移至文件的第10行

 

编辑类操作:

x: 删除光标所在的一个字符(相当于向后删除)
X: 删除光标前面的一个字符(相当于向前删除)
dd: 删除光标所在的行
dG: 删除光标所在的行到末尾的内容
D: 删除光标所在处到行尾的内容
u:撤销
yy,Y: 复制当前行
nyy,nY:复制包括当前行在内的n行
p: 将已经选择复制或被删除的行放到当前行下(粘贴)
r: 取代光标所在处的字符
R: 从光标所在处开始替换字符,按ESC结束
s: 替换光标所在处字符并进入文本输入方式
S: 替换光标所在全行,按ESC结束
u: 取消上一步操作(取消到上次打开文件的点上,并不是上次保存的点上),ctrl+r取消取消的操作
U: 取消当前行的所有操作
:w 保存
:w new_filename 另存为
:wq 保存退出
:q 不保存退出
:q! 强制不保存退出
:wq!强制保存退出
:x
:x!
/string 搜索字符串
?string 搜索字符串
n 向下搜索(?向上)
N 向上搜索(?向下)
:%s/旧的字符串/新的字符串/g 将旧的内容全部替换为新的内容
:%s/旧的字符串//g 将旧的内容删除
:r 文件名
:!操作系统命令
vi -o file1 file2 同时打开多个文件(水平排列)
vi -O file1 file2 同时打开多个文件(垂直排列)
ctrl+ww 文件之前切换

 

基础级别命令汇总

今天想写个数据同步的cron命令,写完了却脑抽的忘了赋权的chmod命令了

看样子 短路的时候 总归是让人各种忧桑啊……

好吧 上网检索了一下 并将基础的一些命令给偷取过来吧^_^

1、显示日期的指令: date

2、显示日历的指令:cal



3、简单好用的计算器:bc


怎么10/100会变成0呢?这是因为bc预设仅输出整数,如果要输出小数点下位数,那么就必须要执行 scale=number ,那个number就是小数点位数,例如:

4、重要的几个热键[Tab],[ctrl]-c, [ctrl]-d

[Tab]按键—具有『命令补全』不『档案补齐』的功能

[Ctrl]-c按键—让当前的程序『停掉』

[Ctrl]-d按键—通常代表着:『键盘输入结束(End Of File, EOF 戒 End OfInput)』的意思;另外,他也可以用来取代exit

5、man

退出用q,

man -f man

6、数据同步写入磁盘:sync

输入sync,那举在内存中尚未被更新的数据,就会被写入硬盘中;所以,这个挃令在系统关机戒重新启劢乀前, 径重要喔!最好多执行几次!

7、惯用的关机指令:shutdown

此外,需要注意的是,时间参数请务必加入指令中,否则shutdown会自动跳到 run-level 1 (就是单人维护的登入情况),这样就伤脑筋了!底下提供几个时间参数的例子吧:

重启,关机: reboot, halt,poweroff

8、切换执行等级: init

Linux共有七种执行等级:

–run level 0 :关机
–run level 3 :纯文本模式
–run level 5 :含有图形接口模式
–run level 6 :重新启动

使用init这个指令来切换各模式:

如果你想要关机的话,除了上述的shutdown -h now以及poweroff之外,你也可以使用如下的指令来关机:

9、改变文件的所属群组:chgrp

10、改变文件拥有者:chown

他还可以顸便直接修改群组的名称

11、改变文件的权限:chmod

权限的设定方法有两种, 分别可以使用数字或者是符号来进行权限的变更。

–数字类型改变档案权限:

–符号类型改变档案权限:

12、查看版本信息等

13、变换目录:cd

14、显示当前所在目录:pwd

15、建立新目录:mkdir


不建议常用-p这个选项,因为担心如果你打错字,那么目录名称就回变得乱七八糟的

16、删除『空』的目录:rmdir

17、档案与目录的显示:ls


18、复制档案或目录:cp







19、移除档案或目录:rm



20、移动档案与目录,或更名:mv


21、取得路径的文件名与目录名:basename,dirname


22、由第一行开始显示档案内容:cat


23、从最后一行开始显示:tac(可以看出 tac 是 cat 的倒着写)

24、显示的时候,顺道输出行号:nl



25、一页一页的显示档案内容:more

26、与 more 类似,但是比 more 更好的是,他可以往前翻页:less

27、只看头几行:head

28、只看尾几行:tail

29、以二进制的放置读取档案内容:od


30、修改档案时间或新建档案:touch



31、档案预设权限:umask

32、配置文件档案隐藏属性:chattr



33、显示档案隐藏属性:lsattr

34、观察文件类型:file

35、寻找【执行挡】:which


36、寻找特定档案:whereis

37、寻找特定档案:locate

38、寻找特定档案:find


39、压缩文件和读取压缩文件:gzip,zcat


40、压缩文件和读取压缩文件:bzip2,bzcat


41、压缩文件和读取压缩文件:tar






Vi中输入中文乱码

Vim 有四个跟字符编码方式有关的选项,encoding、fileencoding、fileencodings、termencoding

它们的意义如下:

encoding: Vim 内部使用的字符编码方式,包括 Vim 的 buffer (缓冲区)、菜单文本、消息文本等。
fileencoding: Vim 中当前编辑的文件的字符编码方式,Vim 保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此)。
fileencodings: Vim 启动时会按照它所列出的字符编码方式逐一探测即将打开的文件的字符编码方式,并且将 fileencoding 设置为最终探测到的字符编码方式。因此最好将 Unicode 编码方式放到这个列表的最前面,将拉丁语系编码方式 latin1 放到最后面。
termencoding: Vim 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式。这个选项在 Windows 下对我们常用的 GUI 模式的 gVim 无效,而对 Console 模式的 Vim 而言就是 Windows 控制台的代码页,并且通常我们不需要改变它。 用英文菜单和提示最好,可以免去下面对菜单和提示信息(B,C部分)的设置如果用英文菜单和提示在安装gvim的时候,将支持本地语言的选项去掉。

解决vim文件乱码,打开文件乱码,菜单,提示信息乱码:

有四个跟字符编码方式有关的选项,encoding、fileencoding、fileencodings、termencoding 在linux中修改.vimrc(在win中是_vimrc)

A:设置文件的代码形式: 

set encoding=utf-8
set termencoding=utf-8
set fileencoding=utf-8
set fileencodings=ucs-bom,utf-8,chinese,cp936

B:vim的菜单乱码解决: 

同样在 _vimrc文件里以上的中文设置后加上下列命令

source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim

C:vim提示信息乱码的解决:

language messages zh_CN.utf-8