<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>linux &#8211; bhzhuOS爱好者(原StartOS爱好者)</title>
	<atom:link href="https://www.bhzhu203.com/tag/linux/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.bhzhu203.com</link>
	<description>QQ群号125732839</description>
	<lastBuildDate>Tue, 24 Jan 2017 09:19:58 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.7</generator>
	<item>
		<title>vi/vim 基本使用方法</title>
		<link>https://www.bhzhu203.com/2017/01/24/vivim-%e5%9f%ba%e6%9c%ac%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95/</link>
		
		<dc:creator><![CDATA[bhzhu203]]></dc:creator>
		<pubDate>Tue, 24 Jan 2017 09:19:58 +0000</pubDate>
				<category><![CDATA[linux知识]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mode]]></category>
		<category><![CDATA[vi]]></category>
		<guid isPermaLink="false">http://www.bhzhu203.com/?p=397</guid>

					<description><![CDATA[本文介绍了vi (vim)的基本使用方法，但对于普通用户来说基本上够了！ vi编 [&#8230;]]]></description>
										<content:encoded><![CDATA[<table border="0" width="660" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td class="F14">本文介绍了vi (vim)的基本使用方法，但对于普通用户来说基本上够了！<br />
vi编辑器是所<br />
有Unix及Linux系统下标准的编辑器，它的强大不逊色于任何最新的文本编辑器，这里只是简单地介绍一下它的用法和一小部分指令。由于对Unix及<br />
Linux系统的任何版本，vi编辑器是完全相同的，因此您可以在其他任何介绍vi的地方进一步了解它。Vi也是Linux中最基本的文本编辑器，学会它<br />
后，您将在Linux的世界里畅行无阻。<br />
1、vi的基本概念<br />
基本上vi可以分为三种状态，分别是命令模式（command mode）、插入模式（Insert mode）和底行模式（last line mode），各模式的功能区分如下：<br />
1) 命令行模式command mode）<br />
控制屏幕光标的移动，字符、字或行的删除，移动复制某区段及进入Insert mode下，或者到 last line mode。<br />
2) 插入模式（Insert mode）<br />
只有在Insert mode下，才可以做文字输入，按「ESC」键可回到命令行模式。<br />
3) 底行模式（last line mode）<br />
将文件保存或退出vi，也可以设置编辑环境，如寻找字符串、列出行号……等。<br />
不过一般我们在使用时把vi简化成两个模式，就是将底行模式（last line mode）也算入命令行模式command mode）。<br />
2、vi的基本操作<br />
a) 进入vi<br />
在系统提示符号输入vi及文件名称后，就进入vi全屏幕编辑画面：<br />
$ vi myfile</p>
<p>不过有一点要特别注意，就是您进入vi之后，是处于「命令行模式（command mode）」，您要切换到「插入模式（Insert<br />
mode）」才能够输入文字。初次使用vi的人都会想先用上下左右键移动光标，结果电脑一直哔哔叫，把自己气个半死，所以进入vi后，先不要乱动，转换到<br />
「插入模式（Insert mode）」再说吧！<br />
b) 切换至插入模式（Insert mode）编辑文件<br />
在「命令行模式（command mode）」下按一下字母「i」就可以进入「插入模式（Insert mode）」，这时候你就可以开始输入文字了。<br />
c) Insert 的切换<br />
您目前处于「插入模式（Insert mode）」，您就只能一直输入文字，如果您发现输错了字！想用光标键往回移动，将该字删除，就要先按一下「ESC」键转到「命令行模式（command mode）」再删除文字。<br />
d) 退出vi及保存文件<br />
在「命令行模式（command mode）」下，按一下「：」冒号键进入「Last line mode」，例如：<br />
: w filename （输入 「w filename」将文章以指定的文件名filename保存）<br />
: wq (输入「wq」，存盘并退出vi)<br />
: q! (输入q!， 不存盘强制退出vi)<br />
3、命令行模式（command mode）功能键<br />
1）. 插入模式<br />
按「i」切换进入插入模式「insert mode」，按“i”进入插入模式后是从光标当前位置开始输入文件；<br />
按「a」进入插入模式后，是从目前光标所在位置的下一个位置开始输入文字；<br />
按「o」进入插入模式后，是插入新的一行，从行首开始输入文字。<br />
2）. 从插入模式切换为命令行模式<br />
按「ESC」键。<br />
3）. 移动光标<br />
vi可以直接用键盘上的光标来上下左右移动，但正规的vi是用小写英文字母「h」、「j」、「k」、「l」，分别控制光标左、下、上、右移一格。<br />
按「ctrl」+「b」：屏幕往“后”移动一页。<br />
按「ctrl」+「f」：屏幕往“前”移动一页。<br />
按「ctrl」+「u」：屏幕往“后”移动半页。<br />
按「ctrl」+「d」：屏幕往“前”移动半页。<br />
按数字「0」：移到文章的开头。<br />
按「G」：移动到文章的最后。<br />
按「$」：移动到光标所在行的“行尾”。<br />
按「^」：移动到光标所在行的“行首”<br />
按「w」：光标跳到下个字的开头<br />
按「e」：光标跳到下个字的字尾<br />
按「b」：光标回到上个字的开头<br />
按「#l」：光标移到该行的第#个位置，如：5l,56l。<br />
4）. 删除文字<br />
「x」：每按一次，删除光标所在位置的“后面”一个字符。<br />
「#x」：例如，「6x」表示删除光标所在位置的“后面”6个字符。<br />
「X」：大写的X，每按一次，删除光标所在位置的“前面”一个字符。<br />
「#X」：例如，「20X」表示删除光标所在位置的“前面”20个字符。<br />
「dd」：删除光标所在行。<br />
「#dd」：从光标所在行开始删除#行<br />
5）. 复制<br />
「yw」：将光标所在之处到字尾的字符复制到缓冲区中。<br />
「#yw」：复制#个字到缓冲区<br />
「yy」：复制光标所在行到缓冲区。<br />
「#yy」：例如，「6yy」表示拷贝从光标所在的该行“往下数”6行文字。<br />
「p」：将缓冲区内的字符贴到光标所在位置。注意：所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。<br />
6）. 替换<br />
「r」：替换光标所在处的字符。<br />
「R」：替换光标所到之处的字符，直到按下「ESC」键为止。<br />
7）. 回复上一次操作<br />
「u」：如果您误执行一个命令，可以马上按下「u」，回到上一个操作。按多次“u”可以执行多次回复。<br />
8）. 更改<br />
「cw」：更改光标所在处的字到字尾处<br />
「c#w」：例如，「c3w」表示更改3个字<br />
9）. 跳至指定的行<br />
「ctrl」+「g」列出光标所在行的行号。<br />
「#G」：例如，「15G」，表示移动光标至文章的第15行行首。<br />
4、Last line mode下命令简介<br />
在使用「last line mode」之前，请记住先按「ESC」键确定您已经处于「command mode」下后，再按「：」冒号即可进入「last line mode」。<br />
A) 列出行号<br />
「set nu」：输入「set nu」后，会在文件中的每一行前面列出行号。<br />
B) 跳到文件中的某一行<br />
「#」：「#」号表示一个数字，在冒号后输入一个数字，再按回车键就会跳到该行了，如输入数字15，再回车，就会跳到文章的第15行。<br />
C) 查找字符<br />
「/关键字」：先按「/」键，再输入您想寻找的字符，如果第一次找的关键字不是您想要的，可以一直按「n」会往后寻找到您要的关键字为止。<br />
「?关键字」：先按「?」键，再输入您想寻找的字符，如果第一次找的关键字不是您想要的，可以一直按「n」会往前寻找到您要的关键字为止。<br />
D) 保存文件<br />
「w」：在冒号输入字母「w」就可以将文件保存起来。<br />
E) 离开vi<br />
「q」：按「q」就是退出，如果无法离开vi，可以在「q」后跟一个「!」强制离开vi。<br />
「qw」：一般建议离开时，搭配「w」一起使用，这样在退出的时候还可以保存文件。<br />
5、vi命令列表<br />
1、下表列出命令模式下的一些键的功能：<br />
h<br />
左移光标一个字符<br />
l<br />
右移光标一个字符<br />
k<br />
光标上移一行<br />
j<br />
光标下移一行<br />
^<br />
光标移动至行首<br />
0<br />
数字“0”，光标移至文章的开头<br />
G<br />
光标移至文章的最后<br />
$<br />
光标移动至行尾<br />
Ctrl+f<br />
向前翻屏<br />
Ctrl+b<br />
向后翻屏<br />
Ctrl+d<br />
向前翻半屏<br />
Ctrl+u<br />
向后翻半屏<br />
i<br />
在光标位置前插入字符<br />
a<br />
在光标所在位置的后一个字符开始增加<br />
o<br />
插入新的一行，从行首开始输入<br />
ESC<br />
从输入状态退至命令状态<br />
x<br />
删除光标后面的字符<br />
#x<br />
删除光标后的＃个字符<br />
X<br />
(大写X)，删除光标前面的字符<br />
#X<br />
删除光标前面的#个字符<br />
dd<br />
删除光标所在的行<br />
#dd<br />
删除从光标所在行数的#行<br />
yw<br />
复制光标所在位置的一个字<br />
#yw<br />
复制光标所在位置的#个字<br />
yy<br />
复制光标所在位置的一行<br />
#yy<br />
复制从光标所在行数的#行<br />
p<br />
粘贴<br />
u<br />
取消操作<br />
cw<br />
更改光标所在位置的一个字<br />
#cw<br />
更改光标所在位置的#个字<br />
2、下表列出行命令模式下的一些指令<br />
w filename<br />
储存正在编辑的文件为filename<br />
wq filename<br />
储存正在编辑的文件为filename，并退出vi<br />
q!<br />
放弃所有修改，退出vi<br />
set nu<br />
显示行号<br />
/或?<br />
查找，在/后输入要查找的内容<br />
n<br />
与/或?一起使用，如果查找的内容不是想要找的关键字，按n或向后（与/联用）或向前（与?联用）继续查找，直到找到为止。<br />
对于第一次用vi，有几点注意要提醒一下：<br />
1、用vi打开文件，是处于「命令行模式（command<br />
2006 年  3 月  22 日<br />
<a href="http://www.ibm.com/developerworks/cn/views/linux/articles.jsp?view_by=search&amp;search_by=Vim+%E5%AE%9E%E7%94%A8%E6%8A%80%E6%9C%AF" target="_blank">本系列</a><br />
文章分三部分详细阐述了 Vim 的使用技巧、插件、定制。第一部分主要是深入分析了 Vim 的使用。<br />
0. Vim 简介<br />
作为开源世界最重要的编辑器之一（另一个是 Emacs），Vim 以其强大的功能和可定制能力被众多开发者所喜爱。不过，也许就是因为 Vim<br />
的功能太强大了，要真正用好 Vim 并不容易。本文作者在多年的实际使用中逐渐掌握了一些实用技术，在此介绍给大家。——本文并不企图对 Vim<br />
作全面而系统的介绍，但也绝非零星地点到即止；而是希望通过介绍一些重要特性和提供相关参考信息，引起大家的兴趣，去深入挖掘其能力，真正把这一强大的工<br />
具用好。<br />
下面首先对 Vim 做一下最基本的介绍，并给出一些参考信息，以方便对 Vim 不熟悉的读者也能够理解并自己查阅进一步信息。<br />
与大部分其它编辑器不同，进入 Vim 后，缺省状态下键入的字符并不会插入到所编辑的文件之中。Vim 的模式（mode，可以简单地理解为“状态”）概念非常重要。需要知道，Vim 有以下几个模式：</p>
<ul>
<li>正常（normal）模式，缺省的编辑模式；下面如果不加特殊说明，提到的命令都直接在正常模式下输入；任何其它模式中都可以通过键盘上的 Esc 键回到正常模式。</li>
<li>命令（command）模式，用于执行较长、较复杂的命令；在正常模式下输入“:”（一般命令）、“/”（正向搜索）或“?”（反向搜索）即可进入该模式；命令模式下的命令要输入回车键（Enter）才算完成。</li>
<li>插入（insert）模式，输入文本时使用；在正常模式下键入“i”（insert）或“a”（append）即可进入插入模式（也有另外一些命令，如“c”，也可以进入插入模式，但这些命令有其它的作用）。</li>
<li>可视（visual）模式，用于选定文本块；可以在正常模式下输入“v”（小写）来按字符选定，输入“V”（大写）来按行选定，或输入“Ctrl-V”来按方块选定。</li>
<li>选择（select）模式，与普通的 Windows 编辑器较为接近的选择文本块的方式；在以可视模式和选择模式之一选定文本块之后，可以使用“Ctrl-G”切换到另一模式——该模式很少在 Linux 上使用，本文中就不再介绍了。</li>
</ul>
<p>Vim 带有完整的帮助文档。在当前的 Vim 6.4 的标准发布中，有一百多章、近六十万英文词的帮助文件，进入 Vim<br />
后输入“:help”（命令模式中输入的命令要敲回车键才结束输入，下面不再说明这一点）即可访问。本文在介绍特性时，对文档中已经说明得很详细的内容只<br />
会提纲挈领地加以简短说明和提供应用范例，并提供访问相应的 Vim 文档的命令。<br />
一般的发布版中还常常带有一个简单的 30 分钟的 Vim 教程，新手在操作系统的命令行上输入“vimtutor”命令即可开始学习。除上面的简单说明外，本文并不介绍最基本的 Vim 命令，Vim 的新手应该先通过教程熟悉一下 Vim，再继续往下阅读。<br />
建议所有的 Vim 用户经常访问 Vim 的主站点 [1]。上面除了基本的发布、安装、下载等信息外，最有用的内容是用户可以上传自己写的<br />
Vim 脚本（script）和撰写自己认为有用的提示（tip），供其他 Vim 用户使用。在写这一段的时候，Vim<br />
站点上已有一千三百多个脚本，提示数刚好超过了一千。对于序号为 nn 的脚本，直接访问的 URL 是<br />
http://www.vim.org/scripts/script.php?script_id=nn；对于序号为 nn 的提示，直接访问的<br />
URL 是 http://www.vim.org/tips/tip.php?tip_id=nn。<br />
不另加说明的话，本文讨论的内容适用于 Vim 版本 6（即从 6.0 到 6.4）。建议认真的 Vim 用户升级到 Vim 6.4，最好是自己编译升级所有的补丁包。相关信息网站上都有，此处不再赘述。<br />
<img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/blue_rule.gif" alt="" border="0" /><br />
<img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/c.gif" alt="" border="0" /><br />
<img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/c.gif" alt="" border="0" /><br />
<img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/u_bold.gif" alt="" border="0" /><br />
<a href="http://www.ibm.com/developerworks/cn/linux/l-tip-vim1/#main" target="_blank"><b>回页首</b></a><br />
1. 实用技巧<br />
1.1 安装<br />
如果从 Linux 发布版直接安装 Vim，需要注意的一点是，缺省情况下系统并不一定为你安装了一个完整的 Vim。比如，在 Red<br />
Hat（以及后来的 Fedora Core）的发布版中，Vim<br />
被拆成了四个包：vim-common（公用部分），vim-minimal（最小安装），vim-enhanced（除 X Window<br />
支持外的完整安装），和 vim-X11（X Window 图形界面支持）。最小安装不能完整展示 Vim 的优点，通常只是作为 vi<br />
的替代品出现，缺少很多重要的特性如多字节语言支持、鼠标支持和脚本支持。如果装了 X Window 的话，图形界面的 gvim 也比文本模式的<br />
vim 具有更多的特性。建议大家尽可能安装完全的 Vim。<br />
如果愿意稍稍费一点功夫，自己编译 Vim 的话，可以更好地定制<br />
Vim。——附带的另一个好处是，你如果发现什么错误的话，你就可以自己动手来修复这个错误，或至少找到错误所在的位置，让 Bram（Vim<br />
的作者）可以更快地解决问题。图 1 是在 Vim 中执行“:version”的结果的一部分，可以看到 Vim<br />
有很多不同的特性（feature）可在编译时打开或关闭。如果自己编译的话，就可以选择打开需要的功能，关闭不需要的功能，来获得一个既功能强大、又小<br />
巧快速的 Vim 定制版本。<br />
<b>图 1</b><br />
<img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/Figure_01.png" alt="" border="0" /><br />
1.2 中文支持<br />
Vim 支持世界上的主要语言，当然也包括中文。如果你用 Vim 编辑中文，而中文不能正确显示，那有两种可能性：一是使用的 Vim 不完整，不含多字节语言支持（multi_byte 特性）；二是某个配置出了问题。<br />
说到多语言支持，最基本的概念有两个：一是文件的语言编码，而是环境的内部编码。在较老的操作系统中，不管 Linux 还是<br />
Windows，这两个编码都是一样的，也就意味着，一次只能处理一种编码的文件：要么只能处理西文编码（Latin1，即 ISO-8859-1<br />
[5]），要么只能处理中文编码（GB2312 [2]）。而在新的操作系统中，这两者可以是不一样的。在 Linux<br />
上，常见的情况是环境的内部编码使用 UTF-8 [6]，而 UTF-8<br />
可以同任何一种语言编码作无损转换，这就保证了系统的多语言处理能力。Vim 这方面秉承了 Unix/Linux 的传统，在内部编码使 UTF-8<br />
的时候，可以同时处理不同意语言编码的文件。<br />
以下列出了和语言编码的相关的设置：</p>
<ul>
<li>环境变量 LANG（使用的语言）；</li>
<li>环境变量 LC_CTYPE（使用的内部编码）；</li>
<li>Vim 选项 encoding（Vim 的内部编码）；</li>
<li>Vim 选项 termencoding（Vim 在与屏幕/键盘交互时使用的编码）；</li>
<li>Vim 选项 fileencoding（Vim 当前编辑的文件在存储时的编码）；</li>
<li>Vim 选项 fileencodings（Vim 打开文件时的尝试使用的编码）；</li>
<li>Vim 选项 ambiwidth（对“不明宽度”字符的处理方式；Vim 6.1.455 后引入）。</li>
</ul>
<p>如果你的环境只需要处理简体中文的话，那么，最简单的方式就是所有的设定全部使用简体中文。只需要：设定<br />
LANG=zh_CN.GB2312，不设定 LC_CTYPE（默认跟 LANG 一样），不设定与编码相关的 Vim 选项（默认由 LANG 和<br />
LC_CTYPE 决定），也无需设定 Vim 选项 ambiwidth。也就是说，我们把语言设定为中国（CN）使用的中文（zh），编码为<br />
GB2312（注意：Vim 内部并不识别国标 GB18030 [3]，所以此处只能设 GB2312；参看下面关于 UTF-8 的讨论）。<br />
不过，如果按照目前 Linux 下的惯例，内部编码一律使用 UTF-8 的话，会有一些额外的好处，其中之一就是在这种情况下 Vim<br />
支持同时编辑多种不同编码的文件，如简体中文和繁体中文（参见图 2）；另外，此时 Vim 也可以通过编码转换支持 GBK [4] 和<br />
GB18030了。这样，众多关于语言编码的 Vim 选项就有了用武之地了。下面进一步说明一下这些选项和推荐设定（如果适用的话）：<br />
<b>图 2</b><br />
<img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/Figure_02.png" alt="" border="0" /></p>
<ul>
<li>encoding=utf-8：不管文件的编码如何，不管如何显示和输入，Vim 内部使用的编码是 UTF-8；这是国际化支持的基础。</li>
<li>termencoding：<br />
取决于实际的终端或 X Window 的设定。举例来说，如果选择语言简体中文登录到 X Window，或者正在使用 CXTERM [10]<br />
的话，那么该选项应被设为 GB2312；如果使用缺省的语言（LANG=en_US.UTF-8）登录到 X Window，或者使用 PuTTY<br />
[11] 远程访问 Linux 机器、并且设定里的字符编码（配置中 Window-Translation）设为 UTF-8<br />
的话，该选项就应该设为 utf-8。从 Windows 下使用 PuTTY 远程连接 Linux 的请特别注意，测试表明，仅在使用 UTF-8<br />
的情况下，PuTTY 才能可靠地支持中文的显示和输入（显示字体必须设成中文字体）。</li>
<li>fileencoding：文件载入时，<br />
该选项被置为 Vim 认定的文件编码，因此，存储时文件的编码不会改变。此处和下面 fileencodings 可使用的编码为 libiconv<br />
支持的所有几百种编码（如果编译时包含了 iconv 特性的话），与中文相关的有<br />
gb2312、gbk、gb18030、hz-gb-2312、iso-2022-cn、big5、cp936、cp950<br />
等。如果创建新文件，你又不希望使用 UTF-8 作为文件编码时，那么，你可能需要手工设定该选项，如“:set<br />
fileencoding=gb2312”。需要注意的一点是，使用“set”来设定该选项的话会改变以后新建文件的缺省编码，而使用<br />
“setlocal”的话则只影响当前文件（参考“:help setlocal”）。</li>
<li>fileencodings=ucs-<br />
bom,utf-8,chinese：Vim 会首先判断文件的开头是否是一个 Unicode [7] 的 BOM（byte order<br />
mark）字符 [8]，是的话则把文件的其余内容解释成相应的 Unicode 序列；否的话再试图把文件内容解释成 UTF-8<br />
的序列；再失败的话，则把文件解释为简体中文（chinese 是一个跨平台的简体中文字符集的别名，Linux 下相当于 gb2312 和<br />
euc-cn；此处也可以根据需要以 gb2312、gbk 或 gb18030<br />
等编码替代）。需要注意的是，该顺序不能颠倒，并且在后面再添加其它编码如 big5、latin1 也是没有意义的，因为 Vim 不能识别 8<br />
比特编码中的错误，因此这些编码后列的编码永远不会被用到。</li>
<li>ambiwidth=double：把所有的“不明宽度”字符<br />
[9]——指的是在 Unicode<br />
字符集中某些同时在东西方语言中使用的字符，如省略号、破折号、书名号和全角引号，在西方文字中通常字符宽度等同于普通 ASCII<br />
字符，而在东方文字中通常字符宽度等同于两倍的普通 ASCII 字符，因而其宽度“不明”——的宽度置为双倍字符宽度（中文字符宽度）。此数值只在<br />
encoding 设为 utf-8 或某一 Unicode 编码时才有效。需要额外注意的是，如果你通过终端使用 Vim<br />
的话，需要令终端也将这些字符显示为双宽度。比如，XTERM [12] 的情况下应该使用选项“-cjk”，即使用命令“uxterm<br />
-cjk”来启动使用双宽度显示这些字符的 Unicode X 终端；使用 PuTTY 远程连接的话则应在配置的<br />
Window-Translation 中选中“Treat CJK ambiguous characters as wide”（参见图 3）。</p>
<p><b>图 3</b></p>
<p><img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/Figure_03.png" alt="" border="0" /></li>
</ul>
<p>需要设定的选项通常放在用户的 Vim 资源配置文件中，即在 ~/.vimrc 文件中加入：<br />
set encoding=utf-8<br />
set fileencoding=chinese<br />
set fileencodings=ucs-bom,utf-8,chinese<br />
set ambiwidth=double<br />
如果想进一步了解这些选项的话，可以使用“:help<br />
&#8216;选项&#8217;”查看帮助文档中的相关（英文）信息。帮助中也可以查到这些选项（以及命令）的缩写：本文中为方便理解，除一些极少有人使用完整拼写的命令如<br />
“:e(dit)”、“:s(ubstitute)”等之外，一般使用完整拼写而不说明或使用缩写。关于配置文件 .vimrc，可以使用“:help<br />
.vimrc”查看相关信息。<br />
在使用内部编码 UTF-8 的情况下，如需编辑 fileencodings 之外（其不能自动识别）的文件，则可以使用以下命令：“:e ++enc=编码 文件名”。详情可参考“:help ++enc”。<br />
1.3. 鼠标支持<br />
不管是文本界面还是图形界面的<br />
Vim，都支持鼠标。不过，在文本界面中，鼠标支持缺省没有被激活；这就意味着，在终端上使用鼠标，所有的功能仍和没有使用 Vim 时相同，并不受<br />
Vim 影响。要激活文本界面中的鼠标支持也很容易，只需要执行一句“:set mouse=a”即可。<br />
启用了鼠标支持之后，Vim 主要支持的鼠标操作有：</p>
<ul>
<li>单击移动光标到点击的位置；</li>
<li>在帮助的关键字上双击显示该关键字相关的帮助信息；</li>
<li>在普通文本上双击选中点击位置的单词；</li>
<li>拖动鼠标选中文本；</li>
<li>使用鼠标滚轮滚动当前缓冲区中的文本；</li>
<li>多窗口编辑时可以拖动窗口分栏的位置。</li>
</ul>
<p>进一步的信息可参看“:help &#8216;mouse&#8217;”、“:help mouse-using”和“:help scroll-mouse-wheel”。<br />
特别需要值得一提的是，在远程访问 Linux 系统时也是可以使用鼠标的。如果使用 X Window 系统，自然不必说；而使用 SSH<br />
远程连接时，大部分 Linux 下的终端客户程序，如 XTERM、GNOME-Terminal [13]、较新版本的 Konsole<br />
[14]，以及 Windows 下的 PuTTY，支持鼠标的使用：你只需简单地启动 Vim、执行一句“:set<br />
mouse=a”就可以了（当然，也可以把上面的语句去掉起始的冒号放到 .vimrc 文件中）。<br />
1.4. 空格、制表符和缩进<br />
对于编写代码，缩进是最基本的概念之一。至于缩进是使用空格还是制表符（Tab），或者缩进是否正好使用一个制表符来表示，很多程序员，特别是<br />
Windows 开发出身的程序员，很容易混淆。幸好，Vim 对于这些概念有非常完整的支持，足以应付各种复杂的情况。以下是相关的主要 Vim<br />
选项：</p>
<ul>
<li>shiftwidth（缩进的空格数）；</li>
<li>tabstop（制表符的宽度）；</li>
<li>expandtab（是否在缩进和遇到 Tab 键时使用空格替代；使用 noexpandtab 取消设置）；</li>
<li>softtabstop（软制表符宽度，设置为非零数值后使用 Tab 键和 Backspace 时光标移动的格数等于该数值，但实际插入的字符仍受 tabstop 和 expandtab 控制）；</li>
<li>autoindent（自动缩进，即每行的缩进值与上一行相等；使用 noautoindent 取消设置）；</li>
<li>cindent（使用 C 语言的缩进方式，根据特殊字符如“{”、“}”、“:”和语句是否结束等信息自动调整缩进；在编辑 C/C++ 等类型文件时会自动设定；使用 nocindent 取消设置）；</li>
<li>cinoptions（C 语言缩进的具体方式，请参考“:help cinoptions-values”）；</li>
<li>paste（粘贴模式，会取消所有上述选项的影响来保证后面的操作——通常是从剪贴板粘贴代码——保持原有代码的风格；使用 nopaste 取消设置）。</li>
</ul>
<p>下面给出一些常用的组合：</p>
<ul>
<li>shiftwidth=4 tabstop=4：很多 Windows 出身的程序员会习惯这样的设置，让缩进等于制表符宽度。</li>
<li>shiftwidth=4 tabstop=8：很多 Unix 程序员的设置，仍使用较常用的 4 格缩进，但制表符宽度为标准的 8。</li>
<li>cinoptions=&gt;4,n-2,{2,^-2,:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1<br />
shiftwidth=2 tabstop=8：标准的 GNU 编码风格的设置，对 Vim 缺省的 C 缩进风格作了很多微调，比如，if<br />
语句下的“{”、“}”要在“if”后缩进两格，但函数定义部分“{”、“}”仍和函数名一行对齐。开源软件经常使用该种缩进风格。</li>
</ul>
<p>在编辑代码时一个很有用的命令是调整代码缩进，可以很方便地增加（或减少）若干级缩进，并自动根据选项设定使用正确的空格或制表符。只需要使用<br />
“V”选中你要调整的代码行，然后键入“”）即可增加（或减少）一级缩进；在键入“”）之前键入数字则<br />
可以指定增加（或减少）的缩进级数。<br />
我们要讨论的最后一个相关的命令是“:retab”。在设定了 expandtab 选项时，该选项会把所有的制表符转换成空格。在没有设定<br />
expandtab 选项时，使用“:retab!”可把空白字符转换成制表符（可能误转换，慎用），使用“:retab n”可以把 tabstop<br />
重置为 n，并转换含制表符的连续空白字符为适当的制表符和空格的组合以保证含制表符的行看起来没有任何变化。详细信息请参看“:help<br />
:retab”。<br />
1.5. 模式行（modeline）<br />
没人愿意每次都手工输入一大堆的 Tab 和缩进设定。可是，放在 .vimrc<br />
文件中似乎也不是个好主意：如果我编辑的代码不止一种风格呢？——考虑一下，如果你参加开源软件项目，你能保证你参加的所有项目，还有你公司里的软件项<br />
目，代码风格都一样吗？——Vim 是我用过的第一个支持在文件中记录代码风格设定的编辑器。这个特性在 Vim<br />
中叫做模式行，实际上，它所做的是在打开文件时根据文件中的 Vim 指令设定相关的 Vim 选项。下面就是一个嵌在 C 源代码中的模式行：<br />
/* vim: set tabstop=4 shiftwidth=4 expandtab: */<br />
模式行有好几种形式。本文只介绍上面的这种形式（其它形式类似，请自行参考“:help<br />
modeline”）：行首的“/*”和尾部的“*/”告诉 C 编译器这是一行注释，不是代码的一部分；而 Vim<br />
可通过后面的“vim:”识别出模式行的开始（必须出现在行首或前面有一个空白字符）；后面则是“set”和空格间隔开的一串 Vim<br />
选项；“:”表示模式行结束。<br />
这种方式非常简单，功能也非常强大。另外请注意，出于安全的考虑，模式行中的选项只影响当前文件（“:help modeline-local”），也不能做任何设置选项以外的工作。<br />
1.6. 寄存器<br />
通常的编辑器有一个剪贴板，以存储复制和剪切的内容。Vim 中的类似概念叫做寄存器（register）。除了有一个无名寄存器外，Vim<br />
还有一大堆有名的寄存器，可以通过“&#8221;”（参见“:help &#8220;”）或“Ctrl-R”（参见“:help i_CTRL-R”和“:help<br />
c_CTRL-R”）加寄存器名（字母、数字和某些特殊字符，参见“:help<br />
registers”；“无名”寄存器的名字是“&#8221;”）来访问。比如，你先使用“&#8221;ayy”复制了一行，然后使用“dd”删掉了一行，然后移动光标到要复<br />
制到的位置，就可以使用“&#8221;aP”把先前复制的内容粘贴上去了。手工编辑是有名寄存器的作用还不是很大，但当你想让 Vim<br />
通过类似于宏的方式自动完成工作时，有名寄存器就变成不可缺少的重要功能了。下面我们还会用到。<br />
在使用 X Window 系统时，有两个特殊的寄存器是需要注意一下的：“&#8221;*”访问的寄存器是 X 的主选择区域（primary<br />
selection），“&#8221;+”访问的寄存器是 X 的剪贴板（clipboard）。如果你要在 Vim 和其它的 X<br />
应用程序之间复制文本内容，你可以试一下这两个寄存器。<br />
还有一个很特殊的“寄存器”：“=”。在插入模式或命令模式中，键入“Ctrl-R=”，Vim 会提示你输入一个表达式，普通的整数运算在此完全有效。如果想要进行浮点运算，请参见第 3.2 节中的技巧。<br />
1.7. 搜索、替换和正则表达式<br />
大家应该都已经知道 Vim<br />
里使用“/模式”（或“?模式”）进行搜索，使用“:s/模式/字符串/标志”进行替换，其中的“模式”是一个正则表达式。关于正则表达式，不熟悉的话可<br />
以边用边学，本节也不打算对 Vim<br />
的正则表达式作完整的阐述（那可能可以专门写一本小册子了），而只抛砖引玉式地给出一些有用的例子加以说明，以及一些实用技巧。<br />
先说一点点搜索。搜索里最最有用的一个快捷方式是“*”（向下完整匹配光标下的单词）。把光标移动到你要搜索的词（变量名、函数名等）上，比如<br />
“test”，然后按“*”，Vim 将自动产生一个对“\”（参见“:help /\”）的搜索，也就是说，搜索完整的单词“test”。不要小看这个技巧，它经常可以大幅度地提高搜索的速度。事实上，这是 Vim<br />
网站上公布的第 1<br />
号技巧，也是被评价最高的技巧。相似的技巧还有“#”（向上完整匹配光标下的单词）、“g*”（向下部分匹配光标下的单词）等，请自行查看（“:help<br />
#”等）。<br />
Vim 在搜索和替换时会对匹配成功的文本进行加亮，在已经完成搜索和替换任务后，这种加亮有时反而会妨碍显示。Vim<br />
专门提供一个命令取消这种加亮（直到用户再一次使用搜索或替换命令）：“:nohlsearch”。建议用户创建一个键盘映射（key<br />
mapping）加入到 .vimrc 中，如：<br />
nmap  :nohlsearch<br />
以上命令表示，在正常模式下按 F2 键相当于输入“:nohlsearch”后面跟一个回车，即取消搜索加亮显示。<br />
再看几个搜索替换的实用例子。</p>
<ul>
<li>去掉所有的行尾空格：“:%s/\s\+$//”。“%”表示在整个文件范围内进行替换，“\s”表示空白字符（空格和制表<br />
符），“\+”对前面的字符匹配一次或多次（越多越好），“$”匹配行尾（使用“\$”表示单纯的“$”字符）；被替换的内容为空；由于一行最多只需替换<br />
一次，不需要特殊标志。这个还是比较简单的。</li>
<li>去掉所有的空白行：“:%s/\(\s*\n\)\+/\r/”。这回多了“<br />
\(”、“\)”、“\n”、“\r”和“*”。“*”代表对前面的字符（此处为“\s”）匹配零次或多次（越多越好；使用“\*”表示单纯的“*”字<br />
符），“\n”代表换行符，“\r”代表回车符，“\(”和“\)”对表达式进行分组，使其被视作一个不可分割的整体。因此，这个表达式的完整意义是，把<br />
连续的换行符（包含换行符前面可能有的连续空白字符）替换成为一个单个的换行符。唯一很特殊的地方是，在模式中使用的是“\n”，而被替换的内容中却不能<br />
使用“\n”，而只能使用“\r”。原因是历史造成的，详情如果有兴趣的话可以查看“:help NL-used-for-Nul”。</li>
<li>去<br />
掉所有的“//”注释：“:%s!\s*//.*!!”。首先可以注意到，这儿分隔符改用了“!”，原因是在模式或字符串部分使用了“/”字符，不换用其<br />
他分隔符的话就得在每次使用“/”字符本身时写成“\/”，上面的命令得写成“:%s/\s*\/\/.*//”，可读性较低。命令本身倒是相当简单，用<br />
过正则表达式的人估计都知道“.”匹配表示除换行符之外的任何字符吧。</li>
<li>去掉所有的“/*<br />
*/”注释：“:%s!\s*/\*\_.\{-}\*/\s*! !g”。这个略有点复杂了，用到了几个不太常用的 Vim<br />
正则表达式特性。“\_.”匹配包含换行在内的所有字符；“\{-}”表示前一个字符可出现零次或多次，但在整个正则表达式可以匹配成功的前提下，匹配的<br />
字符数越少越好；标志“g”表示一行里可以匹配和替换多次。替换的结果是个空格的目的是保证像“int/* space not necessary<br />
around comments */main()”这样的表达式在替换之后仍然是合法的。</li>
</ul>
<p>希望上面的这些简单的例子能够引起你使用 Vim 的正则表达式高效完成任务的兴趣。进一步的信息可参考“:help regexp”。<br />
1.8. 自动完成和路径设定<br />
Vim 支持单词的自动完成。比如，你前面使用了一个很长的变量名，叫<br />
aLongVariable，下面你在输入时，就不用完整键入了。很可能，你只需要键入“aL”，然后按下“Ctrl-P”（向前搜索可匹配的单词并完<br />
成）就可以得到完整的变量名（没有得到想要的结果的话，多按几下“Ctrl-P”；或者前面多输入几个字符，如“aLongV”）。类似的命令还有<br />
“Ctrl-N”（向后搜索可匹配的单词并完成）、“Ctrl-X Ctrl-L”（搜索可匹配的行并完成）、“Ctrl-X<br />
Ctrl-F”（搜索可匹配的文件名并完成）等，具体可参看“:help ins-completion”。<br />
如果你并不熟悉这些功能，但也并不觉得这有什么稀奇的话，下面这个例子可能会让你觉得吃惊。请尝试打开一个空白的 C 文件（vim test.c），并输入：<br />
#include<br />
int main()<br />
{<br />
pri<br />
最后一行不要回车，直接在“pri”后面输入“Ctrl-P”，你将看到“printf”出现。是的，虽然文件里没有“printf”，但<br />
Vim 知道到哪里去寻找它！在作关键字匹配完成时，如果当前文件和其它打开的文件中没有想要的结果，Vim<br />
会自动到“#include”的文件中进行进一步的搜索（为什么是“#include”呢？请查阅“:help<br />
&#8216;include&#8217;”），搜寻的目录则由选项 path 决定，其缺省值在 Unix（含<br />
Linux）下为“.,/usr/include,,”，代表搜索的目录依次是文件所在目录、/usr/include<br />
和当前目录。根据实际情况，你可能需要在 .vimrc<br />
文件中设置该选项，加入项目相关的包含目录，注意一般要保留最后的“,,”，除非你不需要在当前目录下搜索。<br />
设置了合适的 path<br />
后，另外带来的一个便利就是可以使用“gf”命令方便地跳转到光标下的文件名所代表的文件中。在上面的例子中，把光标移到“stdio.h”的任一字符<br />
上，键入“gf”，则 Vim 会自动打开 /usr/include/stdio.h 文件。使用“Ctrl-O”（参见“:help<br />
CTRL-O”）可返回到原先的文件中。<br />
1.9. 文件跳转和 Tags<br />
大家一般都知道，在 Vim<br />
的帮助窗口中的关键字上双击鼠标或者键入“Ctrl-]”即可跳转至该关键字相关的帮助主题。不过，“跳转至匹配的关键字”这一功能并不仅仅局限于帮助文<br />
件。只要有合适的 tags 文件（参见“:help<br />
tags-file-format”），我们同样可以在源代码中使用这个方便的功能，跳转到与关键字匹配的“标记”处（通常是源代码中某一函数、类型、变<br />
量或宏的定义位置）。<br />
要产生 tags 文件，通常我们使用 Exuberant Ctags [15]。一般的 Linux 发布版中均带有这一工具。Ctags<br />
带有的选项数量极多，此处我们仅简单介绍如何在一个典型的多文件、多层目录的项目中使用其基本功能：我们只需在项目的根目录处键入“ctags -R<br />
.”，Ctags 即可自动在文件中查找、识别支持的文件格式、生成 tags 文件。目前 Exuberant Ctags 支持多达 33<br />
种编程语言 [16]，包括了 Linux 下常用的 C、C++、Java、Perl、PHP 等。有了 tags 文件，以下的 Vim<br />
命令就可以方便使用了（进一步的信息可参考“:help tags-and-searches”）：</p>
<ul>
<li>:tag 关键字（跳转到与“关键字”匹配的标记处）</li>
<li>:tselect [关键字]（显示与“关键字”匹配的标记列表，输入数字跳转到指定的标记）</li>
<li>:tjump [关键字]（类似于“:tselect”，但当匹配项只有一个时直接跳转至标记处而不再显示列表）</li>
<li>:tn（跳转到下一个匹配的标记处）</li>
<li>:tp（跳转到上一个匹配的标记处）</li>
<li>Ctrl-]（跳转到与光标下的关键字匹配的标记处；除“关键字”直接从光标位置自动获得外，功能与“:tags”相同）</li>
<li>g]（与“Ctrl-]”功能类似，但使用的命令是“:tselect”）</li>
<li>g Ctrl-]（与“Ctrl-]”功能类似，但使用的命令是“:tjump”）</li>
<li>Ctrl-T（跳转回上次使用以上命令跳转前的位置）</li>
</ul>
<p>当我们在项目的根目录下工作时，上面这些命令工作得很好。但如果我们进到多层目录的里层再运行 Vim<br />
打开文件时，这些命令的执行结果通常就变成了错误信息“E433: No tags file”。这是因为缺省 Vim<br />
只在文件所在目录和当前目录下寻找 tags 文件，而我们前面只在项目的根目录下生成了 tags 文件，Vim<br />
无法找到该文件。解决方法有好几种，我认为一般较简单的做法是对每个项目都在 .vimrc<br />
文件中增加一个路径相关设定。假设我们有两个项目，位置分别是 /home/my/proj1 和 /home/my/proj2，那我们可以使用：<br />
au BufEnter /home/my/proj1/* setlocal tags+=/home/my/proj1/tags<br />
au BufEnter /home/my/proj2/* setlocal tags+=/home/my/proj2/tags<br />
Vim 选项 tags 用于控制检查的 tags 文件，缺省值为“./tags,tags”，即前面所说的文件所在目录下和当前目录下的<br />
tags 文件。上面两行自动命令告诉 Vim，在打开项目目录下的文件时，tags 选项中的内容要增加项目的 tags<br />
文件的路径。进一步信息可参看“:help &#8216;tags&#8217;”。<br />
1.10. Make 和 grep<br />
Make [17] 和grep [18] 应当算是 Unix 世界里无人不晓的基本工具了吧。很自然的，Vim<br />
对它们有着特殊的支持。该支持主要通过访问一个特殊的快速修订窗口（quickfix window）来实现。直接在 Vim 的命令模式里输入相应的<br />
make 或 grep 命令（如“:grep foo *.c”）即可将命令的执行结果放入该窗口，同时根据返回的结果跳转到第一个错误（make<br />
的情况；在使用 grep 时是匹配成功之处）。以下是常用的“快速修订”命令：</p>
<ul>
<li>:cn（显示下一个错误）</li>
<li>:cp（显示上一个错误）</li>
<li>:cl（列出所有的错误及其编号）</li>
<li>:cc（跳转到指定编号的错误）</li>
<li>:copen（打开快速修订窗口，在其中显示所有错误，可在错误上双击鼠标或按回车键跳转至该错误；示例参见图 4）
<p><b>图 4</b></p>
<p><img decoding="async" src="file:///home/bhzhu/%E6%A1%8C%E9%9D%A2/vi_vim%20%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%20-%20%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3%20-%20%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Linux%E6%97%B6%E4%BB%A3%20-%20%E5%BC%80%E6%BA%90%E3%80%81%E8%87%AA%E7%94%B1%E3%80%81%E5%85%B1%E4%BA%AB%20-%20%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84Linux%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA_files/Figure_04.png" alt="" border="0" /></li>
<li>:cclose（关闭快速修订窗口）</li>
</ul>
<p>Vim 的这个特性也可以与 make 和 grep 以外的程序一起工作（事实上，在 Windows XP<br />
上，“:grep”命令一般调起的是“findstr /n”）。具体调用那个程序由选项 makeprg（Linux 下缺省为“make”）和<br />
grepprg（Linux 下缺省为“grep -n $* /dev/null”）控制，而如何解析返回的内容则由选项 errorformat<br />
和 grepformat 控制。鉴于在 Unix/Linux 下一般不需更改这些选项的内容，此处不再详述。<br />
1.11. 执行外部命令<br />
在“:make”这样的命令中，Vim<br />
会自动调用外部的程序。用户当然也可以自己执行外部的程序：估计很多的人都已经知道了用“:!命令”可以在 Vim<br />
中执行一个外部命令。不过，估计大部分人都不知道，还有其它一些命令可以执行外部命令，并且，即使“:!”命令里面也有一些技巧可以使用。<br />
最正规的执行外部命令的方法，如前所述，就是“:!”。比如，我们想要显示当前目录下的所有文件，就可以直接执行：“:!ls”。Vim<br />
会在一个终端窗口中进行文件列表，然后提示我们按键返回 Vim<br />
中。事实上，这种方式对于“cp”、“rm”这样基本不需要输出的命令比较实用，而对于“ls”这样关注于输出的命令并不太适用。<br />
如果想把外部命令执行的结果插入到当前编辑的缓冲区中，可以考虑使用“:r!”。比如，我们使用“:r!ls”，就可以把“ls”命令的执行结果插入到缓冲区中光标所在行下面。在使用宏时，这可能会特别有用。<br />
Vim 的“:!”命令还有一个特别强大的技巧可以使用。拿一个实际例子，我们需要对在一个文件的每一行之前插入一个编号，该怎么做呢？——用<br />
Vim 的宏或者脚本可以完成这一工作，但这不是最高效、最灵活的工作方式。Linux 下一般带有的 GNU 的<br />
nl，可以用非常灵活的方式来完成这一任务——要对所有的非空行进行编号，只需要“:%!nl”；要对包含空行的所有行进行编号？OK，“:%!nl<br />
-ba”。<br />
稍作一点解释。当使用可视模式选中文本行后然后键入“:!”（命令行上将出现“:&#8217;!”，表示命令的范围是选定的文本），或者<br />
使用“:%!”（表示命令的范围是整个缓冲区中的文本），Vim<br />
在执行后面的命令时，将把命令范围里的文本行作为后面执行的命令标准输入，并用命令执行后的标准输出替换当前缓冲区中的这些文本行。这就是上面的命令行的<br />
工作原理。<br />
1.12. 定宽文本排版<br />
在传统的 Unix 环境下，文本文件的定义是具有一定长度限制的文本行的组合 [19]。虽然 Vim<br />
本身对行的长度没有任何实际的限制，但有一些工具有这样的限制。为了最大程度的兼容性，也为了在显示、打印等处理上比较方便，一般推荐在邮件和源代码中一<br />
般不要超出 72 列（最多不超出 80 列）。Vim 在处理定宽的文本方面具有特殊的支持能力。下面是一个在 Vim 中把行宽（使用选项<br />
textwidth）设为 40 后输入 Harry Potter and the Half-Blood Prince 的第一句话的结果：<br />
It was nearing midnight and the Prime<br />
Minister was sitting alone in his<br />
office, reading a long memo that was<br />
slipping through his brain without<br />
leaving the slightest trace of meaning<br />
behind.<br />
输入时我只使用了英文字母和空格，换行符都是 Vim<br />
自动插入的。如果在某一行加入或删除了一些字符后行不就不齐了吗，该如何处理？很简单，把光标移到要重新格式化的文本开头，使用“gq”命令后面跟一个光<br />
标移动命令确定重新格式化的范围。比如“gq}”（格式化一段），“gq5j”（格式化 5 行），“gqG”（格式化至文件末尾）。<br />
除了选项 textwidth 外，选项 formatoptions 确定了跟文本格式化有关的基本选项，常用的数值有：</p>
<ul>
<li>t：根据 textwidth 自动折行；</li>
<li>c：在（程序源代码中的）注释中自动折行，插入合适的注释起始字符；</li>
<li>r：插入模式下在注释中键入回车时，插入合适的注释起始字符；</li>
<li>q：允许使用“gq”命令对注释进行格式化；</li>
<li>n：识别编号列表，编号行的下一行的缩进由数字后的空白决定（与“2”冲突，需要“autoindent”）；</li>
<li>2：使用一段的第二行的缩进来格式化文本；</li>
<li>l：在当前行长度超过 textwidth 时，不自动重新格式化；</li>
<li>m：在多字节字符处可以折行，对中文特别有效（否则只在空白字符处折行）；</li>
<li>M：在拼接两行时（重新格式化，或者是手工使用“J”命令），如果前一行的结尾或后一行的开头是多字节字符，则不插入空格，非常适合中文</li>
</ul>
<p>上面提到的注释，可以是 C/C++ 中的“//”和“/*”，也可以是邮件中引用原文使用的“&gt;”等字符（具体由 comments<br />
选项控制；参见“:help &#8216;comments&#8217;”）。Vim<br />
在遇到这些字符时，能够相当智能地进行处理，足以完成日常编辑源代码和邮件的需要。在使用一些处理纯文本不够强大的邮件客户端时，我通常使用 Vim<br />
编辑邮件（特别是英文邮件），然后把结果贴回到邮件编辑窗口中进行发送。<br />
Vim 中 formatoptions 的缺省值是“tcq”，一般我会在 .vimrc 文件中加入一行“set formatoptions+=mM”来确保 Vim 能在中文字符之间折行而不要求空格的存在，并且在大部分情况下可以正确地处理中文重新格式化。<br />
1.13. 其它小技巧<br />
也许你会觉得这些很有用：</p>
<ul>
<li>%（跳转到与之匹配的括号处）</li>
<li>.（重复上次的修改命令）</li>
<li>`.（跳转到最近修改过的位置）</li>
<li>ZQ（无条件退出）</li>
<li>ZZ（存盘退出）</li>
<li>ga（显示光标下的字符在当前使用的 encoding 下的内码）</li>
<li>guw（光标下的单词变为小写）</li>
<li>gUw（光标下的单词变为大写）</li>
<li>:TOhtml（根据 Vim 的语法加亮的方式生成 HTML 代码；在图形界面中也可以使用菜单“Syntax—Convert to HTML”达到同样效果）</li>
</ul>
<p>无聊的时候，还可以试试（呵呵！）：</p>
<ul>
<li>:help!</li>
<li>:help 42</li>
<li>:help holy-grail</li>
</ul>
<p><b>本文来自ChinaUnix博客，如果查看原文请点：</b><a href="http://blog.chinaunix.net/u3/95634/showart_2025130.html" target="_blank">http://blog.chinaunix.net/u3/95634/showart_2025130.html</a></td>
</tr>
<tr>
<td align="right" height="20"></td>
</tr>
</tbody>
</table>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>使用 Linux 文件恢复工具</title>
		<link>https://www.bhzhu203.com/2016/12/02/%e4%bd%bf%e7%94%a8-linux-%e6%96%87%e4%bb%b6%e6%81%a2%e5%a4%8d%e5%b7%a5%e5%85%b7/</link>
		
		<dc:creator><![CDATA[bhzhu203]]></dc:creator>
		<pubDate>Fri, 02 Dec 2016 05:42:56 +0000</pubDate>
				<category><![CDATA[linux知识]]></category>
		<category><![CDATA[block]]></category>
		<category><![CDATA[inode]]></category>
		<category><![CDATA[linux]]></category>
		<guid isPermaLink="false">http://www.bhzhu203.com/?p=387</guid>

					<description><![CDATA[使用 Linux 文件恢复工具 inode 和 block 首先简单介绍一下 L [&#8230;]]]></description>
										<content:encoded><![CDATA[<blockquote class="wp-embedded-content" data-secret="5cy20iQ5mX"><p><a href="https://www.aikaiyuan.com/5800.html">使用 Linux 文件恢复工具</a></p></blockquote>
<p><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" title="《 使用 Linux 文件恢复工具 》—爱开源" src="https://www.aikaiyuan.com/5800.html/embed#?secret=cquNnjBxvC#?secret=5cy20iQ5mX" data-secret="5cy20iQ5mX" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe></p>
<p>inode 和 block</p>
<p>首先简单介绍一下 Linux 文件系统的最基本单元：inode。inode 译成中文就是索引节点，每个存储设备（例如硬盘）或存储设备的分区被格式化为文件系统后，应该有两部份，一部份是 inode，另一部份是 block，block 是用来存储数据用的。而 inode 呢，就是用来存储这些数据的信息，这些信息包括文件大小、属主、归属的用户组、读写权限等。inode 为每个文件进行信息索引，所以就有了 inode 的数值。linux 操作系统下可以使用 ls –id 命令来查看文件或者目录的 inode 值，一般”root”目录的 inode 值为 2,一个分区挂载到一个目录下时，这个”root”目录的 inode 值为 2</p>
<p># mount /dev/sdb2 /tmp<br />
# ls -id /tmp<br />
2 /tmp</p>
<p>文件恢复的原理</p>
<p>本文要介绍的命令是通过文件系统的 inode 值（一般是 2 ）来获取文件系统信息。在 ext3 和 ext4 文件系统中，每个文件都是通过 inode 来描述其数据存放的具体位置，当文件被删除以后，inode 的数据指针部分被清零，文件目录区没有太多变化。文件的读写都是通过 inode 来实现，当 inode 数据指针被清零以后，即便文件内容还在，也没有办法把文件内容组合出来。当 ext3 和 ext4 文件系统中的元数据 metadata 发生变化时，相应的元数据 metadata 在日志文件会有一份拷贝。比如一个文件被删除了，它的 inode 信息会在日志文件中先保存一份，然后把要删除文件 inode 相关信息清零。这个日志文件是循环使用的，当操作过多时，删除的文件的 inode 日志记录会被新的数据替换，这就彻底丧失了根据 inode 找回数据的机会了。如果是大量文件的删除，这个日志文件会被反复循环利用多次，只留给最后删除的那些文件的恢复机会。</p>
<p>使用命令行工具恢复文件<br />
foremost 和 extundelete 简介</p>
<p>formost 是一个基于文件头和尾部信息以及文件的内建数据结构恢复文件的命令行工具。这个过程通常叫做数据挖掘（data carvubg）。formost 可以分析由 dd、Safeback、Encase 等生成的镜像文件，也可以直接分析驱动器。文件头和尾可以通过配置文件设置，也可以通过命令行开关使用 formost 内建的文件类型。formost 最初是由美国空军特别调查室（Air Force Office of Special Investigations）和信息系统安全研究中心（The Center for Information Systems Security Studies and Research）开发的，现在使用 GPL 许可。Foremost 支持恢复如下格式：avi, bmp, dll, doc, exe, gif, htm, jar, jpg, mbd, mov, mpg, pdf, png, ppt, rar, rif, sdw, sx, sxc, sxi, sxw, vis, wav, wmv, xls, zip。</p>
<p>针对 Linux 下的 ext 文件系统来说，常用的 Linux 文件删除恢复工具有 debugfs、ext3grep、extundelete 等。extundelete 是一个开源的数据恢复工具，支持 ext3、ext4 文件系统，其官方站点位于http://extundelete.sourceforce.net/，目前最新稳定版本为 0.2.0。</p>
<p>上面介绍的两种命令行工具 foremost 和 extundelete 二者相比，foremost 支持的文件系统比较多（包括 ext2、 ext3 、vfat、NTFS、ufs、jfs 等）和 extundelete 支持的文件系统较少（ext3、ext4）文件系统。不过 foremost 只能支持恢复特定格式的文件。<br />
使用 foremost</p>
<p>首先安装软件包</p>
<p>#apt-get install foremost</p>
<p>其它 Linux 发行版用户可以在 http://foremost.sourceforge.net/ 下载源代码编译安装。下面看看使用方法。</p>
<p>恢复单个类型文件</p>
<p>笔者删除一个 USB（/dev/sdba1）存储器中一个 png 文件然后使用 formost 恢复。</p>
<p>#rm -f /dev/sdb1/photo1.png<br />
#foremost -t png -i /dev/sdb1</p>
<p>恢复完成后会在当前目录建立一个 output 目录，在 output 目录下会建立 png 子目录下会包括所有可以恢复的 png 格式的文件。</p>
<p>需要说明的是 png 子目录下会包括的 png 格式的文件名称已经改变，另外 output 目录下的 audit.txt 文件是恢复文件列表。</p>
<p>恢复多个类型文件</p>
<p>#foremost -v -T -t doc,pdf,jpg,gif -i /dev/sda6 -o /media/disk/Recover</p>
<p>恢复完成后会在当前目录建立一个 output 目录，在 output 目录下会建立四个子目录（/doc,/pdf,/jpg,/gif），分别包括四种类型文件。另外 output 目录下的 audit.txt 文件是恢复文件列表。<br />
使用 extundelete</p>
<p>首先安装软件包</p>
<p>#apt-get install extundelete</p>
<p>其它 Linux 发行版用户可以在http://extundelete.sourceforce.net/下载源代码编译安装。下载安装 extundelete 之前要安装两个软件包 e2fsprogs 和 e2fslibs。下面看看使用方法</p>
<p>模拟数据误删除环境</p>
<p>这里我们使用一个分区/dev/sdd1 挂在在/backupdate 上，建立一个测试目录/delete 并建立一文件：del1.txt 。</p>
<p># mkdir –p /backupdate/deldate<br />
# mkfs.ext4 /dev/sdd1<br />
# mount /dev/sdd1 /backupdate<br />
#cd /backupdate/deldate<br />
# touch del1.txt<br />
# echo &#8221; test 1&#8243; > del1.txt<br />
获取文件校验码<br />
# md5sum del1.txt<br />
 66fb6627dbaa37721048e4549db3224d  del1.txt</p>
<p>删除文件<br />
# rm -fr /backupdate/*</p>
<p>卸载文件系统或者挂载为只读<br />
# umount /backupdate<br />
查询恢复数据信息，注意这里的&#8211;inode 2 这里会扫描分区 ：<br />
# extundelete /dev/sdd1 &#8211;inode 2<br />
&#8230;..<br />
File name                                       | Inode number | Deleted status<br />
Directory block 8657:<br />
.                                                 2<br />
..                                                2<br />
lost+found                                        11             Deleted<br />
del1.txt                                              12             Deleted</p>
<p>上面标记为 Deleted 是已经删除的文件或目录</p>
<p>开始恢复文件</p>
<p>默认恢复到当前目录下的 RECOVERED_FILES 目录中去。</p>
<p># extundelete /dev/sdd1 &#8211;restore-file del1.txt<br />
如果恢复一个目录<br />
# extundelete /dev/sdd1 &#8211;restore-directory /backupdate/deldate<br />
恢复所有文件<br />
# extundelete /dev/sdd1 &#8211;restore-all<br />
获取恢复文件校验码，对比检测是否恢复成功<br />
# md5sum RECOVERED_FILES/ del1.txt<br />
66fb6627dbaa37721048e4549db3224d  RECOVERED_FILES/del1.txt</p>
<p>查看校验码与之前的是否完全一致。</p>
<p>应用总结：笔者在现实使用过程中发现 extundelete 还是有很大的不完整性,基于整个磁盘的恢复功能较为强大,基于目录和文件的恢复还不够强大。在 Linux 下误删除了文件，当发现数据丢失以后，不要进行任何操作，保留现场。要想办法把数据丢失的文件系统经过 dd 命令或者 AIR(Automated Image Restore，http://cdnetworks-kr-2.dl.sourceforge.net/ )工具到另外的存储空间上作为最原始的备份，以便数据恢复专家现场诊断恢复。<br />
使用 scalpel</p>
<p>以上介绍的工具主要使用在 ext3 和 ext4 的文件系统，如果用户使用的那些没有日志机制的旧有文件系统，可以使用 scalpel 工具。scalpel 是一种快速文件恢复工具，它通过读取文件系统的数据库来恢复文件。它是独立于文件系统的。</p>
<p>用户可以在http://www.digitalforensicssolutions.com/Scalpel/ 下载源代码编译安装。下面看看使用方法：</p>
<p>使用 scalpel 工具之前，首先要修改配置文件： /etc/scalpel/scalpel.conf。</p>
<p>例如用户要恢复所有删除 pdf 文件，那么要在/etc/scalpel/scalpel.conf 把包括 pdf 文件格式的两行之前的# 去掉。</p>
<p>[&#8230;]<br />
        pdf     y       5000000 %PDF  %EOFx0d  REVERSE<br />
        pdf     y       5000000 %PDF  %EOFx0a  REVERSE<br />
[&#8230;]</p>
<p>然后保存文件。</p>
<p>下面看看使用方法</p>
<p># scalpel /dev/sdb1 -o /RECOVERY/</p>
<p>其中/dev/sdb1 是目标驱动器，/RECOVERY/ 是恢复文件存储目录。目录下的 audit.txt 文件是恢复文件列表。</p>
<p>使用字符终端工具 testdisk 和 phtorec<br />
testdisk 简介</p>
<p>testdisk 是分区表恢复、raid 恢复、分区恢复的开源免费工具（testdisk 支持如下文件系统: FAT12/FAT16/FAT32/NTFS/ext2/ext3/ext4）。testdisk 支持的功能: 修复分区表, 恢复已删除分区，用 FAT32 备份表恢复启动扇区，重建 FAT12/FAT16/FAT32 启动扇区，修复 FAT 表，重建 NTFS 启动扇区，用备份表恢复 NTFS 启动扇区，用 mft 镜像表(mft mirror)修复 mft 表，查找 ext2/ext3 备份的 superblock，从 FAT,NTFS 及 ext2 文件系统恢复删除文件，从已删除的 FAT,NTFS 及 ext2/ext3 分区复制文件。<br />
使用方法</p>
<p>首先安装</p>
<p>#apt-get install testdisk</p>
<p>其它 Linux 发行版用户可以在http://www.cgsecurity.org/wiki/TestDisk_Download 下载源代码编译安装。下载安装 testdisk 之前要安装几个软件包 libjpeg8 ，libncursesw5， libuuid1， zlib1g 。下面看看使用方法</p>
<p>启动 testdisk</p>
<p>#testdisk</p>
<p>testdisk 启动后的工作界面首先是选择恢复操作中的 log 文件（testdisk.log）的纪录方式见图 1。<br />
图 1.选择恢复操作中的 log 文件的纪录方式</p>
<p>image003［Create］新建</p>
<p>［Append］追加</p>
<p>［No Log］不纪录</p>
<p>选择了 log 文件的记录方式后、系统显示处于连接状态的磁盘设备见图 2。<br />
图 2.处于连接状态的磁盘设备</p>
<p>image005在列出的磁盘设备中，选择要恢复的分区，然后选择磁盘分区的种类。若是 ext4 文件系统的话,请选择 [None ] Non partitioned media 见图 3<br />
图 3.选择 [None ] Non partitioned media</p>
<p>image007说明：一般选择[Intel] Intel/PC partition（如果是 GPT 分区，请选择 EFI GPT），对于 ext4 文件系统选择 [Intel] Intel/PC partition 也能正确识别,只是分析硬盘時比较慢。</p>
<p>下面的画面中选择［Analyse］，对分区进行分析见图 4。<br />
图 4.对分区进行分析</p>
<p>image009下面显示了当前分区的状态。这是软件分析的当前分区表的分区结果，我们选择“Deep Search”进行一次深入检测见图 5。<br />
图 5.选择“Deep Search”进行一次深入检测</p>
<p>image011下面是检测完成界面见图 6<br />
图 6.检测完成界面</p>
<p>image013在这个画面时,按 P 键就可以列出硬盘上的文件见图 7<br />
图 7.红色的文件名称就是已经被删除的文件</p>
<p>image015红色的文件名称就是已经被删除的文件,选择好你要恢复的文件后,按 c 键之后,它就会问你要复制到哪个目录,这时请选择你要 复制的目地地(destination)即可。<br />
photorec 简介</p>
<p>photorec 是一款用于恢复硬盘、光盘中丢失的视频、文档、压缩包等文件，或从数码相机存储卡中恢复丢失图片的数据恢复软件（因此，该软件命名为 photo recovery 这个名字)。 photorec 忽略文件系统，能直接从介质底层恢复数据，因此，在介质的文件系统严重破坏或被重新格式化后，它也能进行数据恢复。出于安全考虑, photorec 以只读方式来访问您要恢复数据所在的磁盘或存储卡介质。提示: 一旦发现丢失或意外删除了某个图片、文件， 请不要继续往该存储设备或磁盘保存新文件；否则您可能会覆盖原来的数据。 这意味着您在使用 photorec 时，您千万不要将恢复的文件写入到原数据所存储的同一分区。<br />
使用 photorec 恢复文件</p>
<p>photorec 是 testdisk 的伴侣程序，安装 testdisk 后 photorec 就可以使用了。</p>
<p>启动 photorec</p>
<p># photorec</p>
<p>图 8 中显示了已连接磁盘设备，准备恢复的文件在那个设备上就选择它，然后在选择 Proceed 按钮继续下一步。<br />
图 8.已连接磁盘设备</p>
<p>image017接下来，选择恢复的磁盘分区格式。这里选择 ext4 见图 9。<br />
图 9.选择恢复的磁盘分区格式</p>
<p>image019画面下方［File Opt］中有可供恢复的文件种类提供被选择见图 10。<br />
图 10.可供恢复的文件种类</p>
<p>image021说明：如果只是 root 据某些文件签名要恢复部分文件类型，那么可以按 s 取消全部勾选，然后移动光标到要恢复的文件类型，可按空格来选择高亮选中的类型。</p>
<p>下面设定要分析的磁盘空间区域，可整个分区搜索，也可只搜索自由空间（相当于未分配簇）见图 11 。<br />
图 11.设定要分析的磁盘空间区域</p>
<p>image023下面选择分区所使用的文件系统类型，然后设定导出的文件目录，一般输入 Y 并回车即可。图 12 是恢复完成界面。<br />
图 12.恢复完成</p>
<p>image025恢复完了选择 Quit 退出 PhtoRec。被恢复的文件是 recup_dir.x 的若干数字子组合为文件名被保存在当前目录的/recup_dir 子目录下的。<br />
功能对比</p>
<p>表 1 是 Linux 删除文件恢复工具<br />
表 1.Linux 删除文件恢复工具<br />
工具名称/功能对比 	工作界面 	功能简介<br />
foremost 	命令行 	formost 是一个基于文件头和尾部信息以及文件的内建数据结构恢复文件的命令行工具<br />
extundelete 	命令行 	Extundelete 是 ext3、ext4 文件系统的恢复工具<br />
scalpel 	命令行 	scalpel 是一种快速文件恢复工具，它通过读取文件系统的数据库来恢复文件。它是独立于文件系统的<br />
testdisk 	字符终端 	Testdisk 支持分区表恢复、raid 恢复、分区恢复<br />
phtorec 	字符终端 	photorec 用来恢复硬盘、光盘中丢失的视频、文档、压缩包等文件，或从数码相机存储卡中恢复丢失的图片<br />
总结</p>
<p>可以使用 testdisk 进行文件恢复的场合，也就是硬盘上的分区（该分区有原有数据纪录）已经损坏的情形。但是如果损坏之后，重新再次做成了新分区的话，文件恢复的可能性比较小，很困难。photorec 不仅针对 硬盘、USB 设备、CD-ROM、SD 卡，而且还可以对其它存储设备进行应用。因此大多数常用的文件如果被误操作的话，均可利用其来进行恢复，只不过它的初衷是针对照片而制作的。<br />
相关文章</p>
<p>    Linux上最优秀的数据恢复工具<br />
    使用 Linux 安全删除工具<br />
    Oracle数据恢复 – Linux / Unix 误删除的文件恢复<br />
    sysbench Linux下的性能测试工具<br />
    Oracle数据恢复 – 使用 lsof 查看进程打开的文件列表<br />
    年终难终 – 记年底前的几则数据恢复案例</p>
<p>转载请注明：爱开源 » 使用 Linux 文件恢复工具</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Recover corrupted  PDF file in Linux-在Linux下修复损坏的PDF文件</title>
		<link>https://www.bhzhu203.com/2016/11/05/recover-corrupted-pdf-file-in-linux-%e5%9c%a8linux%e4%b8%8b%e4%bf%ae%e5%a4%8d%e6%8d%9f%e5%9d%8f%e7%9a%84pdf%e6%96%87%e4%bb%b6/</link>
		
		<dc:creator><![CDATA[bhzhu203]]></dc:creator>
		<pubDate>Sat, 05 Nov 2016 09:48:27 +0000</pubDate>
				<category><![CDATA[linux知识]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[修复]]></category>
		<guid isPermaLink="false">http://www.bhzhu203.com/?p=371</guid>

					<description><![CDATA[在Linux下修复损坏的PDF文件 现在修复损坏的PDF文件，修复效果比较不错的 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>在Linux下修复损坏的PDF文件</p>
<p>现在修复损坏的PDF文件，修复效果比较不错的只有“Recovery Toolbox for PDF ”这个软件的了，而且是收费的，很难找到破解版，只有windows版本。</p>
<p>找了很久，才发现Linux下确实有非常好的方法修复PDF文件，两种方法结合起来，效果更好：</p>
<p>1.mutool clean bad.pdf good.pdf</p>
<p>导出来的文件已经基本修复得差不多。</p>
<p>2.pdftocairo -pdf good.pdf  best.pdf</p>
<p>这样就能导出恢复效果比较好的pdf文件，当然不能保证能恢复100%的内容。</p>
<p>&#8212;&#8212; English version&#8212;&#8212;</p>
<p>The best PDF recovery software is “Recovery Toolbox for PDF” in Windows, but it is not free and no crack version.<br />
I find the useful tools for a long time, and find a best way in Linux to repair corrupted  PDF file.Combining two methods will be good:</p>
<p>1.mutool clean bad.pdf good.pdf<br />
This way pdf file is to be recovered the the most data .</p>
<p>2.pdftocairo -pdf good.pdf  best.pdf</p>
<p>这样就能导出恢复效果比较好的pdf文件，当然不能保证能恢复100%的内容。<br />
This way is to continue to recover the  visible content.</p>
<p>mutool is from http://mupdf.com/  and pdftocairo is from poppler.</p>
<p>Original Page:http://superuser.com/questions/278562/how-can-i-fix-repair-a-corrupted-pdf-file</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Snap、Flatpak 这种通吃所有发行版的打包方式真的有用吗？</title>
		<link>https://www.bhzhu203.com/2016/09/20/snap%e3%80%81flatpak-%e8%bf%99%e7%a7%8d%e9%80%9a%e5%90%83%e6%89%80%e6%9c%89%e5%8f%91%e8%a1%8c%e7%89%88%e7%9a%84%e6%89%93%e5%8c%85%e6%96%b9%e5%bc%8f%e7%9c%9f%e7%9a%84%e6%9c%89%e7%94%a8%e5%90%97/</link>
		
		<dc:creator><![CDATA[bhzhu203]]></dc:creator>
		<pubDate>Tue, 20 Sep 2016 11:19:37 +0000</pubDate>
				<category><![CDATA[linux知识]]></category>
		<category><![CDATA[flatpak]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[snap]]></category>
		<guid isPermaLink="false">http://www.bhzhu203.com/?p=369</guid>

					<description><![CDATA[对新一代的打包格式开始渗透到 Linux 生态系统中的深入观察 最近我们听到越来 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>对新一代的打包格式开始渗透到 Linux 生态系统中的深入观察</p>
<p>最近我们听到越来越多的有关于 Ubuntu 的 Snap 包和由 Red Hat 员工 Alexander Larsson 创造的 Flatpak （曾经叫做 xdg-app）的消息。</p>
<p>这两种下一代打包方法在本质上拥有相同的目标和特点：即不依赖于第三方系统功能库的独立包装。</p>
<p>这种 Linux 新技术方向似乎自然会让人脑海中浮现这样的问题：独立包的优点/缺点是什么？这是否让我们拥有更好的 Linux 系统？其背后的动机是什么？</p>
<p>为了回答这些问题，让我们先深入了解一下 Snap 和 Flatpak。<br />
动机</p>
<p>根据 Flatpak 和 Snap 的声明，背后的主要动机是使同一版本的应用程序能够运行在多个 Linux 发行版。</p>
<p>    “从一开始它的主要目标是允许相同的应用程序运行在各种 Linux 发行版和操作系统上。” —— Flatpak</p>
<p>    “……‘snap’ 通用 Linux 包格式，使简单的二进制包能够完美的、安全的运行在任何 Linux 桌面、服务器、云和设备上。” —— Snap</p>
<p>说得更具体一点，站在 Snap 和 Flatpak （以下称之为 S&#038;F）背后的人认为，Linux 平台存在碎片化的问题。</p>
<p>这个问题导致了开发者们需要做许多不必要的工作来使他的软件能够运行在各种不同的发行版上，这影响了整个平台的前进。</p>
<p>所以，作为 Linux 发行版（Ubuntu 和 Red Hat）的领导者，他们希望消除这个障碍，推动平台发展。</p>
<p>但是，是否是更多的个人收益刺激了 S&#038;F 的开发？<br />
个人收益？</p>
<p>虽然没有任何官方声明，但是试想一下，如果能够创造这种可能会被大多数发行版（即便不是全部）所采用的打包方式，那么这个项目的领导者将可能成为一个能够决定 Linux 大船航向的重要人物。<br />
优势</p>
<p>这种独立包的好处多多，并且取决于不同的因素。</p>
<p>这些因素基本上可以归为两类：<br />
用户角度</p>
<p>+ 从 Liunx 用户的观点来看：Snap 和 Flatpak 带来了将任何软件包（软件或应用）安装在用户使用的任何发行版上的可能性。</p>
<p>例如你在使用一个不是很流行的发行版，由于开发工作的缺乏，它的软件仓库只有很稀少的包。现在，通过 S&#038;F 你就可以显著的增加包的数量，这是一个多么美好的事情。</p>
<p>+ 同样，对于使用流行的发行版的用户，即使该发行版的软件仓库上有很多的包，他也可以在不改变它现有的功能库的同时安装一个新的包。</p>
<p>比方说, 一个 Debian 的用户想要安装一个 “测试分支” 的包，但是他又不想将他的整个系统变成测试版（来让该包运行在更新的功能库上）。现在，他就可以简单的想安装哪个版本就安装哪个版本，而不需要考虑库的问题。</p>
<p>对于持后者观点的人，可能基本上都是使用源文件编译他们的包的人，然而，除非你使用类似 Gentoo 这样基于源代码的发行版，否则大多数用户将从头编译视为是一个恶心到吐的事情。</p>
<p>+ 高级用户，或者称之为 “拥有安全意识的用户” 可能会觉得更容易接受这种类型的包，只要它们来自可靠来源，这种包倾向于提供另一层隔离，因为它们通常是与系统包想隔离的。</p>
<p>* 不论是 Snap 还是 Flatpak 都在不断努力增强它们的安全性，通常他们都使用 “沙盒化” 来隔离，以防止它们可能携带病毒感染整个系统，就像微软 Windows 系统中的 .exe 程序一样。（关于微软和 S&#038;F 后面还会谈到）<br />
开发者角度</p>
<p>与普通用户相比，对于开发者来说，开发 S&#038;F 包的优点可能更加清楚。这一点已经在上一节有所提示。</p>
<p>尽管如此，这些优点有：</p>
<p>+ S&#038;F 通过统一开发的过程，将多发行版的开发变得简单了起来。对于需要将他的应用运行在多个发行版的开发者来说，这大大的减少了他们的工作量。</p>
<p>++ 因此，开发者能够更容易的使他的应用运行在更多的发行版上。</p>
<p>+ S&#038;F 允许开发者私自发布他的包，不需要依靠发行版维护者在每一个/每一次发行版中发布他的包。</p>
<p>++ 通过上述方法，开发者可以不依赖发行版而直接获取到用户安装和卸载其软件的统计数据。</p>
<p>++ 同样是通过上述方法，开发者可以更好的直接与用户互动，而不需要通过中间媒介，比如发行版这种中间媒介。<br />
缺点</p>
<p>– 膨胀。就是这么简单。Flatpak 和 Snap 并不是凭空变出来它的依赖关系。相反，它是通过将依赖关系预构建在其中来代替使用系统中的依赖关系。</p>
<p>就像谚语说的：“山不来就我，我就去就山”。</p>
<p>– 之前提到安全意识强的用户会喜欢 S&#038;F 提供的额外的一层隔离，只要该应用来自一个受信任的来源。但是从另外一个角度看，对这方面了解较少的用户，可能会从一个不靠谱的地方弄来一个包含恶意软件的包从而导致危害。</p>
<p>上面提到的观点可以说是有很有意义的，虽说今天的流行方法，像 PPA、overlay 等也可能是来自不受信任的来源。</p>
<p>但是，S&#038;F 包更加增加这个风险，因为恶意软件开发者只需要开发一个版本就可以感染各种发行版。相反，如果没有 S&#038;F，恶意软件的开发者就需要创建不同的版本以适应不同的发行版。<br />
原来微软一直是正确的吗？</p>
<p>考虑到上面提到的，很显然，在大多数情况下，使用 S&#038;F 包的优点超过缺点。</p>
<p>至少对于二进制发行版的用户，或者重点不是轻量级的发行版的用户来说是这样的。</p>
<p>这促使我问出这个问题，可能微软一直是正确的吗？如果是的，那么当 S&#038;F 变成 Linux 的标准后，你还会一如既往的使用 Linux 或者类 Unix 系统吗？</p>
<p>很显然，时间会是这个问题的最好答案。</p>
<p>不过，我认为，即使不完全正确，但是微软有些地方也是值得赞扬的，并且以我的观点来看，所有这些方式在 Linux 上都立马能用也确实是一个亮点。</p>
<p>via: http://www.iwillfolo.com/ubuntus-snap-red-hats-flatpack-and-is-one-fits-all-linux-packages-useful/</p>
<p>作者：Liron 译者：Chao-zhi 校对：wxy</p>
<p>本文由 LCTT 原创翻译，Linux中国 荣誉推出</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决（续）</title>
		<link>https://www.bhzhu203.com/2016/08/04/linux%e6%9c%8d%e5%8a%a1%e5%99%a8cache%e5%8d%a0%e7%94%a8%e8%bf%87%e5%a4%9a%e5%86%85%e5%ad%98%e5%af%bc%e8%87%b4%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ad%98%e4%b8%8d%e8%b6%b3%e9%97%ae%e9%a2%98%e7%9a%84%e6%8e%92/</link>
		
		<dc:creator><![CDATA[bhzhu203]]></dc:creator>
		<pubDate>Thu, 04 Aug 2016 03:16:36 +0000</pubDate>
				<category><![CDATA[linux知识]]></category>
		<category><![CDATA[going]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memory]]></category>
		<guid isPermaLink="false">http://www.bhzhu203.com/?p=348</guid>

					<description><![CDATA[作者: 大圆那些事 &#124; 文章可以转载，请以超链接形式标明文章原始出处和作者信息  [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2></h2>
<div class="postbody">
<div id="cnblogs_post_body">
<p>作者: <a href="http://www.cnblogs.com/panfeng412/" target="_blank">大圆那些事</a> | 文章可以转载，请以超链接形式标明文章原始出处和作者信息</p>
<p>网址: <a href="http://www.cnblogs.com/panfeng412/archive/2013/12/17/drop-caches-under-linux-system-2.html">http://www.cnblogs.com/panfeng412/archive/2013/12/17/drop-caches-under-linux-system-2.html</a></p>
<p><a href="http://www.cnblogs.com/panfeng412/p/drop-caches-under-linux-system.html">前一篇文章</a>里已经描述了具体遇到的问题及一些解决方法。但是还有些疑问点没有搞清楚，进一步学习了Linux系统下内存的分配使用机制，这里有两个资料讲的比较全面：</p>
<p><a href="http://halobates.de/memorywaste.pdf">Where is the memory going? Memory waste under Linux</a></p>
<p><a href="http://www.google.com.hk/url?sa=t&amp;rct=j&amp;q=memory.ppt&amp;source=web&amp;cd=1&amp;ved=0CCgQFjAA&amp;url=http%3a%2f%2fwww-psych.stanford.edu%2f%7Ebigopp%2fMemory.ppt&amp;ei=E-ivUsOaFq2ZiAf-8IGIAg&amp;usg=AFQjCNFpJ10jtn6LJsn6ec3GeGnzfxZTqQ&amp;bvm=bv.57967247,d.aGc&amp;cad=rjt">Where is the memory going?Memory usage in the 2.6 kernel</a></p>
<p>以下记录的是进一步排查的进展情况。</p>
<h1>更深层次的原因</h1>
<p><a href="http://www.cnblogs.com/panfeng412/p/drop-caches-under-linux-system.html">前一篇文章</a>里排查到Linux系统中有大量的dentry_cache占用内存，为什么会有如此多的dentry_cache呢？</p>
<p>1. 首先，弄清楚dentry_cache的概念及作用：目录项高速缓存，是Linux为了提高目录项对象的处理效率而设计的；它记录了目录项到inode的 映射关系。因此，当应用程序发起stat系统调用时，就会创建对应的dentry_cache项（更进一步，如果每次stat的文件都是不存在的文件，那 么总是会有大量新的dentry_cache项被创建）。</p>
<p>2. 当前服务器是storm集群的节点，首先想到了storm相关的工作进程，strace一下storm的worker进程发现其中有非常频繁的stat系统调用发生，而且stat的文件总是新的文件名：</p>
<div class="cnblogs_code">
<pre>sudo strace -fp &lt;pid&gt; -e trace=stat</pre>
</div>
<p>3. 进一步观察到storm的worker进程会在本地目录下频繁的创建、打开、关闭、删除心跳文件，每秒钟一个新的文件名：</p>
<div class="cnblogs_code">
<pre>sudo strace -fp &lt;pid&gt; -e trace=open,stat,close,unlink</pre>
</div>
<p>以上就是系统中为何有如此多的dentry_cache的原因所在。</p>
<h1>一个奇怪的现象</h1>
<p>通过观察/proc/meminfo发现，slab内存分为两部分：</p>
<div class="cnblogs_code">
<pre>SReclaimable // 可回收的slab
SUnreclaim // 不可回收的slab</pre>
</div>
<p>当时服务器的现状是：slab部分占用的内存，大部分显示的都是SReclaimable，也就是说可以被回收的。</p>
<p>但是通过slabtop观察到slab内存中最主要的部分（dentry_cache）的OBJS几乎都是ACTIVE的，显示100%处于被使用状态。</p>
<div class="cnblogs_code">
<pre>  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
13926348 13926348 <strong>100%</strong>    0.21K 773686       18   3494744K dentry_cache
334040 262056  78%    0.09K   8351       40     33404K buffer_head
151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache</pre>
</div>
<p>为什么显示可回收的，但是又处于ACTIVE状态呢？求Linux内核达人看到后热心解释下：（</p>
<p>会不会由于是ACTIVE状态，导致dcache没有被自动回收释放掉呢？</p>
<h1>让系统自动回收dcache</h1>
<p>上一小节，我们已经提到，服务器上大部分的slab内存是SReclaimable可回收状态的，那么，我们能不能交给操作系统让他在某个时机自动触发回收操作呢？答案是肯定的。</p>
<p>查了一些关于Linux dcache的相关资料，发现操作系统会在到了内存临界阈值后，触发kswapd内核进程工作才进行释放，这个阈值的计算方法如下：</p>
<p>1. 首先，grep low /proc/zoneinfo，得到如下结果：</p>
<div class="cnblogs_code">
<pre>        low      1
        low      380
        low      12067</pre>
</div>
<p>2. 将以上3列加起来，乘以4KB，就是这个阈值，通过这个方法计算后发现当前服务器的回收阈值只有48MB，因此很难看到这一现象，实际中可能等不到回收，操作系统就会hang住没响应了。</p>
<p>3. 可以通过以下方法调大这个阈值：将vm.extra_free_kbytes设置为vm.min_free_kbytes和一样大，则/proc/zoneinfo中对应的low阈值就会增大一倍，同时high阈值也会随之增长，以此类推。</p>
<div class="cnblogs_code">
<pre>$ sudo sysctl -a | grep free_kbytes       
vm.min_free_kbytes = 39847
vm.extra_free_kbytes = 0
$ sudo sysctl -w vm.extra_free_kbytes=836787  ######1GB</pre>
</div>
<p>4. 举个例子，当low阈值被设置为1GB的时候，当系统free的内存小于1GB时，观察到kswapd进程开始工作（进程状态从Sleeping变为Running），同时dcache开始被系统回收，直到系统free的内存介于low阈值和high阈值之间，停止回收。</p>
<p>&nbsp;</p>
</div>
<div id="MySignature"><a href="http://weibo.com/1830487481?s=6uyXnP"> <img decoding="async" src="http://service.t.sina.com.cn/widget/qmd/1830487481/7c9f6081/1.png" /> </a></div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>LINUX屏蔽系统取消ctrl+alt+f1以及alt+F1等系统默认的功能快捷键</title>
		<link>https://www.bhzhu203.com/2016/04/28/linux%e5%b1%8f%e8%94%bd%e7%b3%bb%e7%bb%9f%e5%8f%96%e6%b6%88ctrlaltf1%e4%bb%a5%e5%8f%8aaltf1%e7%ad%89%e7%b3%bb%e7%bb%9f%e9%bb%98%e8%ae%a4%e7%9a%84%e5%8a%9f%e8%83%bd%e5%bf%ab%e6%8d%b7%e9%94%ae/</link>
		
		<dc:creator><![CDATA[bhzhu203]]></dc:creator>
		<pubDate>Thu, 28 Apr 2016 06:09:12 +0000</pubDate>
				<category><![CDATA[linux知识]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mykeys]]></category>
		<category><![CDATA[快捷键]]></category>
		<guid isPermaLink="false">http://www.bhzhu203.com/?p=92</guid>

					<description><![CDATA[适用于Linux主机系统下，操作vbox虚拟Linux系统组合键 终端去掉快捷键 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="panel-body content">
适用于Linux主机系统下，操作vbox虚拟Linux系统组合键</p>
<p><strong>终端去掉快捷键方法:</strong><br />
1、dumpkeys  &gt; mykeys<br />
2、编辑mykeys文件。去掉相应的功能项<br />
3、执行 loadkeys mykeys<br />
5、加入rc.local或者.bash_rc中<br />
<strong>图形模式去掉快捷键方法:</strong><br />
X Window有自己的keymap，会覆盖系统的默认配置，所以必须修改X的keymap。有两个办法。<br />
一个是直接修改/etc/X11/xorg.conf，添加如下片段<br />
Assembly codeSection &#8220;ServerFlags&#8221;<br />
Option &#8220;DontVTSwitch&#8221; &#8220;on&#8221;<br />
EndSection这个DontVTSwitch是默认off的，打开它会禁止掉所有的Ctrl+alt+Fn的功能。<br />
另外一个是用xmodmap。下面的命令会打印一个列表出来<br />
$ xmodmap -pke<br />
我这边的列表片段<br />
Assembly codekeycode 67 = F1 XF86_Switch_VT_1<br />
keycode 68 = F2 XF86_Switch_VT_2<br />
keycode 69 = F3 XF86_Switch_VT_3<br />
keycode 70 = F4 XF86_Switch_VT_4<br />
keycode 71 = F5 XF86_Switch_VT_5假设去掉Ctrl+alt+F1的切换功能，运行<br />
$ xmodmap -e &#8216;keycode 67 = F1&#8217;<br />
就可以了。</p>
<p>转自：<a href="http://hi.baidu.com/romea/item/2d20c220afe17f112a0f1c61" target="_blank">http://hi.baidu.com/romea/item/2d20c220afe17f112a0f1c61</a></p>
</div>
<div class="panel-footer"></div>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
