如何在 Linux 中整理磁盘碎片

Summary: 有一个神话是 linux 的磁盘从来不需要整理碎片。在大多数情况下这是真的，大多数因为是使用的是优秀的日志系统（ext3、4等等）来处理文件系统。然而，在一些特殊情况下，碎片仍旧会产生。如果正巧发生在你身上，解决方法很简单。 什么是磁盘碎片 文件系统会按块更新文件，如果这些块没有连成一整块而是分布在磁盘的各个角落中时，就会形成磁盘碎片。这对于 FAT 和 FAT32 文件系统而言是这样的。在 NTFS 中这种情况有所减轻，但在 Linux（extX）中却几乎不会发生。下面是原因： 在像 FAT 和 FAT32 这类文件系统中，文件紧挨着写入到磁盘中

命令太多，我只想说你最好能开发一个自己的，哈哈哈

# 如何在 Linux 中整理磁盘碎片

有一个神话是 linux 的磁盘从来不需要整理碎片。在大多数情况下这是真的，大多数因为是使用的是优秀的日志文件系统（ext3、4等等）来处理文件系统。然而，在一些特殊情况下，碎片仍旧会产生。如果正巧发生在你身上，解决方法很简单。

### 什么是磁盘碎片

文件系统会按块更新文件，如果这些块没有连成一整块而是分布在磁盘的各个角落中时，就会形成磁盘碎片。这对于 FAT 和 FAT32 文件系统而言是这样的。在 NTFS 中这种情况有所减轻，但在 Linux（extX）中却几乎不会发生。下面是原因：

在像 FAT 和 FAT32 这类文件系统中，文件紧挨着写入到磁盘中。文件之间没有空间来用于增长或者更新：

NTFS 中在文件之间保留了一些空间，因此有空间进行增长。但因块之间的空间是有限的，碎片也会随着时间出现。

Linux 的日志型文件系统采用了一个不同的方案。与文件相互挨着不同，每个文件分布在磁盘的各处，每个文件之间留下了大量的剩余空间。这就给文件更新和增长留下了很大的空间，碎片很少会发生。

此外，碎片一旦出现了，大多数 Linux 文件系统会尝试将文件和块重新连续起来。

### Linux 中的磁盘整理

除非你用的是一个很小的硬盘或者空间不够了，不然 Linux 很少会需要磁盘整理。一些可能需要磁盘整理的情况包括：

* 如果你编辑的是大型视频文件或者 RAW 照片，但磁盘空间有限
* 如果你使用一个老式硬件，如旧笔记本，你的硬盘会很小
* 如果你的磁盘开始满了（大约使用了85%）
* 如果你的家目录中有许多小分区

最好的解决方案是购买一个大硬盘。如果不可能，磁盘碎片整理就很有用了。

### 如何检查碎片

`fsck` 命令会为你做这个，换句话说，如果你可以在 LiveCD 中运行它，那么就可以用于**所有卸载的分区**。

这一点很重要：**在已经挂载的分区中运行 fsck 将会严重危害到你的数据和磁盘**。

你已经被警告过了。开始之前，先做一个完整的备份。

**免责声明**： 本文的作者与本站将不会对您的文件、数据、系统或者其他损害负责。你需要自己承担风险。如果你继续，你需要接受并了解这点。

你应该启动到一个 live 会话中（如使用安装磁盘，系统救援CD等）并在你**卸载**的分区上运行 `fsck` 。要检查是否有任何问题，请在使用 root 权限运行下面的命令：

```
fsck -fn [/path/to/your/partition]

```

您可以运行以下命令找到分区的路径

```
sudo fdisk -l

```

有一个在已挂载的分区中运行 `fsck`（相对）安全的方法是使用`-n`开关。这会对分区进行只读文件系统检查，而不会写入任何东西。当然，这并不能保证十分安全，你应该在创建备份之后进行。在 ext3 中，运行

```
sudo fsck.ext3 -fn /path/to/your/partition

```

这会产生大量的输出，大多数错误信息的原因是分区已经挂载了。最后会给出一个碎片相关的信息。

如果碎片率大于 20% 了，那么你应该开始整理你的磁盘碎片了。

### 如何简单地在 Linux 中整理碎片

你要做的是备份你**所有**的文件和数据到另外一块硬盘中（手动**复制**他们），格式化分区，然后重新复制回去（不要使用备份软件）。日志型文件系统会把它们作为新的文件，并将它们整齐地放置到磁盘中而不产生碎片。

要备份你的文件，运行

```
cp -afv [/path/to/source/partition]/* [/path/to/destination/folder]

```

记住星号（\*）是很重要的。

注意：通常认为复制大文件或者大量文件，使用 `dd` 或许是最好的。这是一个非常底层的操作，它会复制一切，包含空闲的空间甚至是留下的垃圾。这不是我们想要的，因此这里最好使用 `cp`。

现在你只需要删除源文件。

```
sudo rm -rf [/path/to/source/partition]/*

```

**可选**：你可以使用如下命令将空闲空间用零填充。也可以用格式化来达到这点，但是如果你并没有复制整个分区而仅仅是复制大文件（它通常会形成碎片）的话，就不应该使用格式化的方法了。

```
sudo dd if=/dev/zero of=[/path/to/source/partition]/temp-zero.txt

```

等待它结束。你可以用 `pv` 来监测进度。

```
sudo apt-get install pv
sudo pv -tpreb | of=[/path/to/source/partition]/temp-zero.txt

```

这就完成了，只要删除这个用于填充的临时文件就行。

```
sudo rm [/path/to/source/partition]/temp-zero.txt

```

待你清零了空闲空间（或者跳过了这步）。重新复制回文件，将第一个`cp`命令翻转一下：

```
cp -afv [/path/to/original/destination/folder]/* [/path/to/original/source/partition]

```

### 使用 e4defrag

如果你想要简单的方法，安装 `e2fsprogs`，

```
sudo apt-get install e2fsprogs

```

用 root 权限在分区中运行 `e4defrag`。如果你不想或不能卸载该分区，你可以使用它的挂载点而不是路径。要整理整个系统的碎片，运行：

```
sudo e4defrag  /

```

在挂载的情况下不保证成功（你也应该在它运行时不要使用你的系统），但是它比复制全部文件再重新复制回来简单多了。

### 总结

linux 系统中由于它的日志型文件系统有效的数据处理很少会出现碎片。如果你因任何原因产生了碎片，简单的方法是重新分配你的磁盘，如复制出去所有文件并复制回来，或者使用`e4defrag`。然而重要的是保证你数据的安全，因此在进行任何可能影响你全部或者大多数文件的操作之前，确保你的文件已经被备份到了另外一个安全的地方去了。

---

via: <https://www.maketecheasier.com/defragment-linux/>

作者：[Attila Orosz](https://www.maketecheasier.com/author/attilaorosz/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 Ubuntu 中安装 QGit 客户端

Summary: QGit是一款由Marco Costalba用Qt和C++写的开源的图形界面 Git 客户端。它是一款可以在图形界面环境下更好地提供浏览版本历史、查看提交记录和文件补丁的客户端。它利用git命令行来执行并显示输出。它有一些常规的功能像浏览版本历史、比较、文件历史、文件标注、归档树。我们可以格式化并用选中的提交应用补丁，在两个或多个实例之间拖拽并提交等等。它允许我们用它内置的生成器来创建自定义的按钮去执行特定的命令。 这里有简单的几步在Ubuntu 14.04 LTS "Trusty"中编译并安装QGit客户端。 1. 安装 QT4 库 首先在ubuntu中运行QGit需要先

# 如何在 Ubuntu 中安装 QGit 客户端

QGit是一款由Marco Costalba用Qt和C++写的开源的图形界面 Git 客户端。它是一款可以在图形界面环境下更好地提供浏览版本历史、查看提交记录和文件补丁的客户端。它利用git命令行来执行并显示输出。它有一些常规的功能像浏览版本历史、比较、文件历史、文件标注、归档树。我们可以格式化并用选中的提交应用补丁，在两个或多个实例之间拖拽并提交等等。它允许我们用它内置的生成器来创建自定义的按钮去执行特定的命令。

这里有简单的几步在Ubuntu 14.04 LTS "Trusty"中编译并安装QGit客户端。

### 1. 安装 QT4 库

首先在ubuntu中运行QGit需要先安装QT4库。由于apt是ubuntu默认的包管理器，同时qt4也在官方的仓库中，因此我们直接用下面的apt-get命令来安装qt4。

```
$ sudo apt-get install qt4-default

```

### 2. 下载QGit压缩包

安装完Qt4之后，我们要安装git，这样我们才能在QGit中克隆git仓库。运行下面的apt-get命令。

```
$ sudo apt-get install git

```

现在，我们要使用下面的git命令来克隆QGit客户端的仓库。

```
$ git clone git://repo.or.cz/qgit4/redivivus.git

Cloning into 'redivivus'...
remote: Counting objects: 7128, done.
remote: Compressing objects: 100% (2671/2671), done.
remote: Total 7128 (delta 5464), reused 5711 (delta 4438)
Receiving objects: 100% (7128/7128), 2.39 MiB | 470.00 KiB/s, done.
Resolving deltas: 100% (5464/5464), done.
Checking connectivity... done.

```

### 3. 编译 QGit

克隆之后，我们现在进入redivivus的目录，并创建我们编译需要的makefile文件。进入目录，运行下面的命令。

```
$ cd redivivus

```

接下来，我们运行下面的命令从qmake项目文件（qgit.pro）来生成新的Makefile。

```
$ qmake qgit.pro

```

生成Makefile之后，我们现在终于可以编译qgit的源代码并生成二进制。首先我们要安装make和g++包用于编译，因为这是一个用C++写的程序。

```
$ sudo apt-get install make g++

```

现在，我们要用make命令来编译代码了。

```
$ make

```

### 4. 安装 QGit

成功编译QGit的源码之后，我们就要在Ubuntu 14.04中安装它了，这样就可以在系统中执行它。因此我们将运行下面的命令。

```
$ sudo make install

cd src/ && make -f Makefile install
make[1]: Entering directory `/home/arun/redivivus/src'
make -f Makefile.Release install
make[2]: Entering directory `/home/arun/redivivus/src'
install -m 755 -p "../bin/qgit" "/usr/lib/x86_64-linux-gnu/qt4/bin/qgit"
strip "/usr/lib/x86_64-linux-gnu/qt4/bin/qgit"
make[2]: Leaving directory `/home/arun/redivivus/src'
make[1]: Leaving directory `/home/arun/redivivus/src'

```

接下来，我们需要从bin目录下复制qgit的二进制文件到/usr/bin/，这样我们就可以全局运行它了。

```
$ sudo cp bin/qgit /usr/bin/

```

### 5. 创建桌面文件

既然我们已经在ubuntu中成功安装了qgit，我们来创建一个桌面文件，这样QGit就可以在我们桌面环境中的菜单或者启动器中找到了。要做到这点，我们要在/usr/share/applications/创建一个新文件叫qgit.desktop。

```
$ sudo nano /usr/share/applications/qgit.desktop

```

接下来复制下面的行到文件中。

```
[Desktop Entry]
Name=qgit
GenericName=git 图形界面 viewer
Exec=qgit
Icon=qgit
Type=Application
Comment=git 图形界面 viewer
Terminal=false
MimeType=inode/directory;
Categories=Qt;Development;RevisionControl;

```

完成之后，保存并退出。

### 6. 运行 QGit 客户端

QGit安装完成之后，我们现在就可以从任何启动器或者程序菜单中启动它了。要在终端下面运行QGit，我们可以像下面那样。

```
$ qgit

```

这会打开基于Qt4框架图形界面模式的QGit。

<img src="content_image/album_201509_26_085428iwnwsshipuluu6us.png" alt="QGit Viewer" title="QGit Viewer">

### 总结

QGit是一个很棒的基于QT的git客户端。它可以在Linux、MAC OSX和 Microsoft Windows所有这三个平台中运行。它帮助我们很容易地浏览历史、版本、分支等等git仓库提供的信息。它减少了使用命令行的方式去执行诸如浏览版本、历史、比较功能的需求，并用图形化的方式来简化了这些任务。最新的qgit版本也在默认仓库中，你可以使用 **apt-get install qgit** 命令来安装。因此，QGit用它简单的图形界面使得我们的工作更加简单和快速。

---

via: <http://linoxide.com/ubuntu-how-to/install-qgit-viewer-ubuntu-14-04/>

作者：[Arun Pyasi](http://linoxide.com/author/arunp/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


RHCSA 系列（十）: Yum 包管理、Cron 自动任务计划和监控系统日志

Summary: 在这篇文章中，我们将回顾如何在 RHEL7 中安装，更新和删除软件包。我们还将介绍如何使用 cron 进行任务自动化，并完成如何查找和监控系统日志文件，以及为什么这些技能是系统管理员必备技能。  RHCSA: Yum包管理、任务计划和系统监控  Part 10 使用yum 管理包 要安装一个包以及所有尚未安装的依赖包，您可以使用： # yum -y install package_name(s)  package_name(s) 需要是至少一个真实的软件包名 例如，安装 httpd 和 mlocate（按顺序），输入。 # yum -y install httpd mlocate  注意: 字符 y 表示绕过执行下载和安装前的确认提示。

这个不应该是系列之第十篇吗

哦晕。。

不得不说，crontab 的功能不如 Windows 任务计划那样灵活和强大。

来自四川成都的 IE Mobile 10.0|Windows Phone 8.0 用户

小编没吃月饼哦

虽然没有使用过Win的计划任务，但是觉得你说的有一定的道理。试想，如果crontab加上系统计划任务脚本，或者是其他功能脚本，自动定期执行的话，会不会更灵活呢？愚人之间，请勿见笑

是不是该介绍dnf了？

dnf 之前有单独的文章介绍过，不过 RHCSA 是针对 RHEL 7的，所以还是 yum。

给个介绍 dnf 的文章链接嘛~

https://linux.cn/article-5718-1.html 其实，注册用户是可以进行站内搜索的。

原来如此。

# RHCSA 系列（十）: Yum 包管理、Cron 自动任务计划和监控系统日志

在这篇文章中，我们将回顾如何在 RHEL7 中安装，更新和删除软件包。我们还将介绍如何使用 cron 进行任务自动化，并完成如何查找和监控系统日志文件，以及为什么这些技能是系统管理员必备技能。

*RHCSA: Yum包管理、任务计划和系统监控 – Part 10*

### 使用yum 管理包

要安装一个包以及所有尚未安装的依赖包，您可以使用：

```
# yum -y install package_name(s)

```

package\_name(s) 需要是至少一个真实的软件包名

例如，安装 httpd 和 mlocate（按顺序），输入。

```
# yum -y install httpd mlocate

```

**注意**: 字符 y 表示绕过执行下载和安装前的确认提示。如果需要提示，你可以不用它。

默认情况下，yum 将安装与操作系统体系结构相匹配的包，除非通过在包名加入架构名。

例如，在 64 位系统上，`yum install package`将安装包的 x86\_64 版本，而 `yum install package.x86`（如果有的话）将安装 32 位的。

有时，你想安装一个包，但不知道它的确切名称。`search all` 选项可以在当前启用的软件库中的包名称和包描述中搜索它，或者`search`选项可以在包名称中搜索。

比如，

```
# yum search log

```

将搜索安装的软件库中名字和摘要与该词（log）类似的软件，而

```
# yum search all log

```

也将在包描述和网址中寻找寻找相同的关键字。

一旦搜索返回包列表，您可能希望在安装前显示一些信息。这时 info 选项派上了用场：

```
# yum info logwatch

```

*搜索包信息*

您可以定期用以下命令检查更新：

```
# yum check-update

```

上述命令将返回可以更新的所有已安装的软件包。在下图所示的例子中，只有 rhel-7-server-rpms 有可用更新：

*检查包更新*

然后，您可以更新该包，

```
# yum update rhel-7-server-rpms

```

如果有几个包可以一同更新，可以使用 `yum update` 一次性更新所有的包。

当你知道一个可执行文件的名称，如 ps2pdf，但不知道那个包提供了它？你可以通过 `yum whatprovides “*/[executable]”`找到:

```
# yum whatprovides “*/ps2pdf”

```

*查找文件属于哪个包*

当删除包时，你可以使用 `yum remove Package` ，很简单吧？Yum 是一个完整而强大的包管理器。

```
# yum remove httpd

```

* 参见： [20 个管理 RHEL 7 软件包的 Yum 命令](http://www.tecmint.com/20-linux-yum-yellowdog-updater-modified-commands-for-package-mangement/)

### 文本式 RPM 工具

RPM（又名 RPM 包管理器，原意是 RedHat 软件包管理器）也可用于安装或更新独立的`rpm`格式的软件包。

往往使用 `-Uvh` 表明如果这个包没有安装就安装它，如果已存在就尝试更新。这里`-U`表示更新、`-v`表示显示详细输出，用`-h`显示进度条。例如

```
# rpm -Uvh package.rpm

```

rpm 的另一个典型的使用方法是列出所有安装的软件包，

```
# rpm -qa

```

*查询所有包*

* 参见： [20 个管理 RHEL 7 软件包的 RPM 命令](http://www.tecmint.com/20-practical-examples-of-rpm-commands-in-linux/)

### 使用 Cron 调度任务

Linux 和 UNIX 类操作系统包括一个称为 Cron 的工具，允许你周期性调度任务（即命令或 shell 脚本）。cron 会每分钟定时检查 /var/spool/cron 目录中有在 /etc/passwd 帐户文件中指定用户名的文件。

执行命令时，命令输出是发送到该 crontab 的所有者（或者可以在 /etc/crontab，通过 MAILTO 环境变量中指定用户）。

crontab 文件（可以通过键入 `crontab -e`并按 Enter 键创建）的格式如下：

*crontab条目*

因此，如果我们想在每个月第二天上午2:15更新本地文件数据库（用于按名字或通配模式定位文件），我们需要添加以下 crontab 条目：

```
15 02 2 * * /bin/updatedb

```

以上的条目的意思是：”每年每月第二天的凌晨 2：15 运行 /bin/updatedb，无论是周几”，我想你也猜到了。星号作为通配符。

正如我们前面所提到的，添加一个 cron 任务后，你可以看到一个名为 root 的文件被添加在 /var/spool/cron。该文件列出了所有的 crond 守护进程应该运行的任务：

```
# ls -l /var/spool/cron

```

*检查所有cron任务*

在上图中，显示当前用户的 crontab 可以使用 `cat /var/spool/cron` 或

```
# crontab -l

```

如果你需要在一个更精细的时间上运行的任务（例如，一天两次或每月三次），cron 也可以做到。

例如，每个月1号和15号运行 /my/script 并将输出导出到 /dev/null （丢弃输出），您可以添加如下两个crontab 条目：

```
01 00 1 * * /myscript > /dev/null 2>&1
01 00 15 * * /my/script > /dev/null 2>&1

```

不过为了简单，你可以将他们合并：

```
01 00 1,15 * *  /my/script > /dev/null 2>&1

```

跟着前面的例子，我们可以在每三个月的第一天的凌晨1：30运行 /my/other/script。

```
30 01 1 1,4,7,10 * /my/other/script > /dev/null 2>&1

```

但是当你必须每隔某分钟、小时、天或月来重复某个任务时，你可以通过所需的频率来划分正确的时间。以下与前一个 crontab 条目具有相同的意义：

```
30 01 1 */3 * /my/other/script > /dev/null 2>&1

```

或者也许你需要在一个固定的频率或系统启动后运行某个固定的工作，你可以使用下列五个字符串中的一个字符串来指示你想让你的任务计划工作的确切时间：

```
@reboot     仅系统启动时运行
@yearly     一年一次, 类似与 00 00 1 1 *
@monthly    一月一次, 类似与 00 00 1 * *
@weekly     一周一次, 类似与 00 00 * * 0
@daily      一天一次, 类似与 00 00 * * *
@hourly     一小时一次, 类似与 00 * * * *

```

* 参见：[11 个在 RHEL7 中调度任务的命令](http://www.tecmint.com/11-cron-scheduling-task-examples-in-linux/)

### 定位和查看日志

系统日志存放（并轮转）在 /var/log 目录。根据 Linux 的文件系统层次标准（Linux Filesystem Hierarchy Standard），这个目录包括各种日志文件，并包含一些必要的子目录（如 audit、 httpd 或 samba ，如下图)，并由相应的系统守护进程操作：

```
# ls /var/log

```

*Linux 日志的位置*

其他感兴趣的日志比如 [dmesg](http://www.tecmint.com/dmesg-commands/)（包括了所有内核层缓冲区的消息），secure（记录要求用户认证的连接请求)，messages（系统级信息），和 wtmp（记录了所有用户的登录、登出）。

日志是非常重要的，它们让你可以看到任何时刻发生在你的系统的事情，以及已经过去的事情。他们是无价的工具，可以排错和监测一个 Linux 服务器，通常使用 `tail -f` 命令来实时显示正在发生和写入日志的事件。

举个例子，如果你想看你的内核相关的日志，你需要输入如下命令：

```
# tail -f /var/log/dmesg

```

同样的，如果你想查看你的 Web 服务器日志，你需要输入如下命令：

```
# tail -f /var/log/httpd/access.log

```

### 总结

如果你知道如何有效的管理包、调度任务、以及知道在哪寻找系统当前和过去操作的信息，你可以放松工作而不会总被吓到。我希望这篇文章能够帮你学习或回顾这些基础知识。

如果你有任何问题或意见，请使用下面的表单反馈给我们。

---

via: <http://www.tecmint.com/yum-package-management-cron-job-scheduling-monitoring-linux-logs/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[xiqingongzi](https://github.com/xiqingongzi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 中 10 个有用的命令行补全例子

Summary: 在 Linux 系统中，当你输入一个命令，再按两次 TAB 键，就会列出所有以你输入字符开头的可用命令。这并不新鲜，可能你已经知道了。这个功能被称作命令行补全bash completion。默认情况下，bash 命令行可以自动补全文件或目录名称。不过，我们可以增强 bash 命令补全功能，通过 complete 命令让它达到新的高度。  这个教程说明了我们是怎样使用可编程的命令行补全功能（programmable completion）把自动补全功能应用于选项或者命令行参数。 例如：在输入 write 命令之后，如果你按两次 TAB 按键，自动补全功能会提供可供执行 write 操作的

# Linux 中 10 个有用的命令行补全例子

在 Linux 系统中，当你输入一个命令，再按两次 `TAB` 键，就会列出所有以你输入字符开头的可用命令。这并不新鲜，可能你已经知道了。这个功能被称作<ruby> 命令行补全 <rt>  bash completion </rt></ruby>。默认情况下，bash 命令行可以自动补全文件或目录名称。不过，我们可以增强 bash 命令补全功能，通过 `complete` 命令让它达到新的高度。

<img src="content_image/album_201509_26_155653mcpob0l6u4fzdjnp.jpg" alt="" title="">

这个教程说明了我们是怎样使用<ruby> 可编程的命令行补全功能 <rp>  （ </rp> <rt>  programmable completion </rt> <rp>  ） </rp></ruby>把自动补全功能应用于选项或者命令行参数。

例如：在输入 `write` 命令之后，如果你按两次 `TAB` 按键，自动补全功能会提供可供执行 `write` 操作的用户列表。

```
$ write [TAB][TAB]
bala      raj
jason     randy
john      ritu
mayla     thomas
nisha     www-data
```

在下面的例子中，可以为 `telnet` 命令显示可用的主机名：

```
$ telnet [TAB][TAB]
localhost  dev-db  fileserver
```

要让可编程命令补全功能在你的终端起作用 ，你只需要如下执行`/etc/bash_completion`即可：

```
# . /etc/bash_completion
```

你也可以取消`/etc/bash.bashrc`（来自 Ubuntu Linux 13.04 系统）中如下的注释，这样，你就可以不需要执行上面的命令了：

```
### enable bash completion in interactive shells
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi
```

如果你没有发现这些代码，也没有找到`/etc/bash_completion`文件，那么你只需要通过使用`apt-get`命令来安装bash\_completion 包即可。

### 1. 查看已有的命令行补全

在启用可编程的命令行补全功能后，就已经有了一些定义好的命令补全功能。`complete` 命令用于定义命令行补全。

要查看已有的命令行补全，如下使用 `complete` 命令：

```
complete -p | less
```

上面例子中的 -p 选项是可选的。

### 2. 列出 bash 中标准补全功能

默认情况下，Bash 为 Linux 用户提供了下列标准补全功能。

1. 变量补全
2. 用户名补全
3. 主机名补全
4. 路径补全
5. 文件名补全

我们在之前的 [bash 标准补全](http://www.thegeekstuff.com/2013/11/bash-standard-completion/)中讨论过这些。

### 3. 定义一个命令名补全

通过 -c 选项可以将所有的可用命令作为一个命令的补全参数。在下面的例子里面，为 `which` 命令定义了一个补全（LCTT译注：在按两下 `TAB` 时，可以列出所有命令名作为可补全的参数）。

```
$ complete -c which

$ which [TAB][TAB]
Display all 2116 possibilities? (y or n)
```

如上，如果按下 ‘y’，就会列出所有的命令名。

### 4. 定义一个目录补全

通过选项 -d，可以定义一个仅包含目录名的补全参数。在下面的例子中，为 `ls` 命令定义了补全。

```
$ ls
countfiles.sh  dir1/          dir2/          dir3/

$ complete -d ls

$ ls [TAB][TAB]
dir1/          dir2/          dir3/
```

如上，连按下 `TAB` 仅会显示目录名。

### 5. 定义一个后台任务名补全

补全功能也能够以任务名作为补全参数。选项 -j 可以定义任务名作为传递给命令的参数，如下：

```
$ jobs
[1]-  Stopped                 cat
[2]+  Stopped                 sed 'p'

$ complete -j ./list_job_attrib.sh

$ ./list_job_attrib.sh [TAB][TAB]
cat   sed
```

关于后台任务，你可以参考 [Linux 后台任务](http://www.thegeekstuff.com/2010/05/unix-background-job/)中的例子了解如何管理后台任务。

### 6. 带有前缀和后缀的补全

补全功能可以为实际的补全内容定义前缀和后缀。在下面的例子中，为 list\_job\_attrib.sh 定义了补全内容的前缀和后缀。

```
$ jobs
[1]+  Stopped                 cat

$ complete -P '">' -S '<"' ./list_job_attrib.sh

$ ./list_job_attrib.sh [TAB][TAB]

$ ./list_job_attrib.sh ">cat<"
```

### 7. 带有排除的文件名和目录名补全

假如脚本运行完成后，输出目录如下：

```
$ cd output/

$ ls
all_calls.txt   incoming_calls.txt   outgoing_calls.txt   missed_calls.txt
parser_mod.tmp  extract.o
```

如上，如果你想要 `ls` 命令的补全忽略 .tmp 和 .o 文件：

```
$ export FIGNORE='.tmp:.o'

$ complete -f -d ls

$ cd output

$ ls [TAB][TAB]
all_calls.txt   incoming_calls.txt   outgoing_calls.txt   missed_calls.txt

```

`FIGNORE` 是一个环境变量，它包含了自动补全所需要排除的文件名后缀。

### 8. 通过 IFS 变量分割字符串得到补全值

可以通过 -W 选项定义补全值列表，然后通过 `IFS` 环境变量进行切分。切分结果会展开变量并作为补全显示。

```
$ export IFS=" "

$ complete -W "bubble quick" ./sort_numbers.sh

$ ./sort_numbers.sh [TAB][TAB]
bubble   quick
```

如上所述，字符串通过 `IFS` 分隔符进行切分后，内嵌的变量会被展开为变量值，所以可以如下使用变量：

```
$ echo $SORT_TYPE1
bubble

$ echo $SORT_TYPE2
quick

$ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh
$ ./sort_numbers.sh [TAB][TAB]
bubble   quick
```

### 9. 写个函数来生成补全

你可以引入一个函数来定义补全。使用 -F 选项将函数名传给 `complete` 命令，执行函数生成补全内容。例如，函数如下：

```
_parser_options()
{
  local curr_arg;

  curr_arg=${COMP_WORDS[COMP_CWORD]}

  COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) );
}
```

在上述函数中：

1. COMPREPLY : 该数组控制连按下 `TAB` 后显示的结果
2. COMP\_WORDS : 该数组包含命令行输入的单词
3. COMP\_CWORD : COMP\_WORDS 数组的索引，使用它来区分命令行可以访问的单词位置
4. compgen : -W 基于 $current\_arg 提供可能的补全及其参数

该函数放在 parser\_option 文件中，并通过 `source` 命令引入：

```
$ source parser_option
```

将该函数和你的 parser.pl 脚本关联起来：

```
$ complete -F _parser_options ./parser.pl

$ ./parser.pl [TAB][TAB]
-i       --incoming       -o       --outgoing       -m       --missed
```

如上，parser.pl 的选项是由函数 \_parser\_options() 生成的。

提示： 查看`/etc/bash_completion` 来了解更多的可编程补全函数。

### 10. 当第一个规则没有生成结果时，就使用第二个

如果定义的补全规则没有生成匹配时，可以使用 -o 选项生成补全。

```
$ complete -F _count_files -o dirnames ./countfiles.sh
```

如上，为 ./countfiles.sh 定义了 \_count\_files 补全函数。 如果 the \_count\_files() 函数没有生成任何匹配的话，就会触发目录补全。

```
$ ls
countfiles.sh    dir1/      dir2/      dir3/

$./countfiles.sh [TAB][TAB]
dir1    dir2    dir3
```


如何在 Arch Linux 中安装 DNSCrypt 和 Unbound

Summary: DNSCrypt 是一个用于对 DNS 客户端和 DNS 解析器之间通信进行加密和验证的协议。它可以阻止 DNS 欺骗或中间人攻击。 DNSCrypt 可用于大多数的操作系统，包括 Linux，Windows，MacOSX ，Android 和 iOS。而在本教程中我使用的是内核为4.1的 archlinux。 Unbound 是用来解析收到的任意 DNS 查询的 DNS 缓存服务器。如果用户请求一个新的查询，unbound 会将其存储到缓存中，并且当用户再次请求相同的请求时，unbound 将采用已经保存的缓存。这将比第一次请求查询更快。 现在我将尝试安装DNSCrypt，以确保 DNS 的通信的安全，并用Unbound加速

很好的教程，赞

还是不太明白它的运用场景.....

# 如何在 Arch Linux 中安装 DNSCrypt 和 Unbound

**DNSCrypt** 是一个用于对 DNS 客户端和 DNS 解析器之间通信进行加密和验证的协议。它可以阻止 DNS 欺骗或中间人攻击。 DNSCrypt 可用于大多数的操作系统，包括 Linux，Windows，MacOSX ，Android 和 iOS。而在本教程中我使用的是内核为4.1的 archlinux。

**Unbound** 是用来解析收到的任意 DNS 查询的 DNS 缓存服务器。如果用户请求一个新的查询，unbound 会将其存储到缓存中，并且当用户再次请求相同的请求时，unbound 将采用已经保存的缓存。这将比第一次请求查询更快。

现在我将尝试安装“DNSCrypt”，以确保 DNS 的通信的安全，并用“Unbound”加速。

### 第一步 - 安装 yaourt

Yaourt 是AUR（ARCH 用户仓库）的辅助工具之一，它可以使用户能够很容易地从 AUR 安装程序。 Yaourt 和 pacman 使用相同的语法，你可以使用 yaourt 安装该程序。下面是安装 yaourt 的简单方法：

1、 用 nano 或者 vi 编辑 arch 仓库配置文件，存放在“/etc/pacman.conf”中。

```
$ nano /etc/pacman.conf

```

2、 在 yaourt 仓库底部添加，粘贴下面的脚本：

```
[archlinuxfr]
SigLevel = Never
Server = http://repo.archlinux.fr/$arch

```

3、 用“Ctrl + x”，接着用“Y”保存。

4、 接着升级仓库数据库并用pacman安装yaourt：

```
$ sudo pacman -Sy yaourt

```

### 第二步 - 安装 DNSCrypt 和 Unbound

DNSCrypt 和 unbound 就在 archlinux 仓库中，你可以用下面的 pacman 命令安装：

```
$ sudo pacman -S dnscrypt-proxy unbound

```

接着在安装的过程中按下“Y”。

### 第三步 - 安装 dnscrypt-autoinstall

Dnscrypt-autoinstall 是一个在基于 Linux 的系统上自动安装和配置 DNSCrypt 的脚本。DNSCrypt 在 AUR 中，因此你必须使用“yaourt”命令来安装它。

```
$ yaourt -S dnscrypt-autoinstall

```

注意 :

-S = 这和 pacman -S 安装程序一样。

### 第四步 - 运行 dnscrypt-autoinstall

用 root 权限运行“dnscrypt-autoinstall”来自动配置 DNSCrypt。

```
$ sudo dnscrypt-autoinstall

```

下一步中按下“回车”，接着输入"Y"来选择你想使用的 DNS 提供者，我这里使用不带日志和 DNSSEC 的 DNSCrypt.eu。

### 第五步 - 配置 DNSCrypt 和 Unbound

1、 打开 dnscrypt 的“/etc/conf.d/dnscrypt-config” ，确认配置文件中“DNSCRYPT*LOCALIP”指向**本地ip**，“DNSCRYPT*LOCALPORT”根据你本人的意愿配置，我是用的是**40**端口。

```
$ nano /etc/conf.d/dnscrypt-config

DNSCRYPT_LOCALIP=127.0.0.1
DNSCRYPT_LOCALIP2=127.0.0.2
DNSCRYPT_LOCALPORT=40

```

保存并退出。

2、 现在你用 nano 编辑器编辑“/etc/unbound/”下 unbound 的配置文件：

```
$ nano /etc/unbound/unbound.conf

```

3、 在脚本最后添加下面的行：

```
do-not-query-localhost: no
forward-zone:
name: "."
forward-addr: 127.0.0.1@40

```

确保**forward-addr**和DNSCrypt中的“**DNSCRYPT\_LOCALPORT**”一致。如你所见，用的是**40**端口。

接着保存并退出。

### 第六步 - 运行 DNSCrypt 和 Unbound，接着添加到开机启动中

请用 root 权限运行 DNSCrypt 和 unbound，你可以用 systemctl 命令来运行：

```
$ sudo systemctl start dnscrypt-proxy unbound

```

将服务添加到启动中。你可以运行“systemctl enable”：

```
$ sudo systemctl enable dnscrypt-proxy unbound

```

命令将会创建软链接到“/usr/lib/systemd/system/”目录的服务。

### 第七步 - 配置 resolv.conf 并重启所有服务

resolv.conf 是一个在 linux 中用于配置 DNS 解析器的文件。它是一个由管理员创建的纯文本，因此你必须用 root 权限编辑并让它不能被其他人修改。

用 nano 编辑器编辑：

```
$ nano /etc/resolv.conf

```

并添加本地IP “**127.0.0.1**”。现在用“chattr”命令使他只读：

```
$ chattr +i /etc/resolv.conf

```

注意：

如果你想要重新编辑，用“chattr -i /etc/resolv.conf”加入写权限。

现在你需要重启 DNSCrypt 和 unbound 和网络；

```
$ sudo systemctl restart dnscrypt-proxy unbound netctl

```

如果你看到错误，检查配置文件。

### 测试

1、 测试 DNSCrypt

你可以通过 <https://dnsleaktest.com/> 来确认 DNSCrypt，点击“标准测试”或者“扩展测试”，然后等待程序运行结束。

现在你可以看到 DNSCrypt.eu 就已经与作为 DNS 提供商的 DNSCrypt 协同工作了。

2、 测试 Unbound

现在你应该确保 unbound 可以正确地与“dig”和“drill”命令一起工作。

这是 dig 命令的结果：

```
$ dig linoxide.com

```

我们现在看下结果，“Query time”是“533 msec”：

```
;; Query time: 533 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Aug 30 14:48:19 WIB 2015
;; MSG SIZE rcvd: 188

```

再次输入命令，我们看到“Query time”是“0 msec”。

```
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Aug 30 14:51:05 WIB 2015
;; MSG SIZE rcvd: 188

```

DNSCrypt 对 DNS 客户端和解析端之间的通讯加密做的很好，并且 Unbound 通过缓存让相同的请求在另一次请求同速度更快。

### 总结

DNSCrypt 是一个可以加密 DNS 客户端和 DNS 解析器之间的数据流的协议。 DNSCrypt 可以在不同的操作系统上运行，无论是移动端或桌面端。选择 DNS 提供商还包括一些重要的事情，应选择那些提供 DNSSEC 同时没有日志的。Unbound 可被用作 DNS 缓存，从而加快解析过程，因为 Unbound 将请求缓存，那么接下来客户端请求相同的查询时，unbound 将从缓存中取出保存的值。 DNSCrypt 和 Unbound 是针对安全性和速度的一个强大的组合。

---

via: <http://linoxide.com/tools/install-dnscrypt-unbound-archlinux/>

作者：[Arul](http://linoxide.com/author/arulm/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 有问必答：如何知道进程运行在哪个 CPU 内核上？

Summary: 问题：我有个 Linux 进程运行在多核处理器系统上。怎样才能找出哪个 CPU 内核正在运行该进程？   当你在 多核 NUMA 处理器上运行需要较高性能的 HPC（高性能计算）程序或非常消耗网络资源的程序时，CPU/memory 的亲和力是限度其发挥最大性能的重要因素之一。在同一 NUMA 节点上调度最相关的进程可以减少缓慢的远程内存访问。像英特尔 Sandy Bridge 处理器，该处理器有一个集成的 PCIe 控制器，你可以在同一 NUMA 节点上调度网络 I/O 负载（如网卡）来突破 PCI 到 CPU 亲和力限制。 作为性能优化和故障排除的一部分，你可能想知道特定的进

# Linux 有问必答：如何知道进程运行在哪个 CPU 内核上？

>
> 问题：我有个 Linux 进程运行在多核处理器系统上。怎样才能找出哪个 CPU 内核正在运行该进程？
>
>
>

当你在 [多核 NUMA 处理器上](http://xmodulo.com/identify-cpu-processor-architecture-linux.html)运行需要较高性能的 HPC（高性能计算）程序或非常消耗网络资源的程序时，CPU/memory 的亲和力是限度其发挥最大性能的重要因素之一。在同一 NUMA 节点上调度最相关的进程可以减少缓慢的远程内存访问。像英特尔 Sandy Bridge 处理器，该处理器有一个集成的 PCIe 控制器，你可以在同一 NUMA 节点上调度网络 I/O 负载（如网卡）来突破 PCI 到 CPU 亲和力限制。

作为性能优化和故障排除的一部分，你可能想知道特定的进程被调度到哪个 CPU 内核（或 NUMA 节点）上运行。

这里有几种方法可以 **找出哪个 CPU 内核被调度来运行给定的 Linux 进程或线程**。

### 方法一

如果一个进程使用 [taskset](http://xmodulo.com/run-program-process-specific-cpu-cores-linux.html) 命令明确的被固定（pinned）到 CPU 的特定内核上，你可以使用 taskset 命令找出被固定的 CPU 内核：

```
$ taskset -c -p <pid>

```

例如, 如果你对 PID 5357 这个进程有兴趣:

```
$ taskset -c -p 5357
pid 5357's current affinity list: 5
```

输出显示这个过程被固定在 CPU 内核 5上。

但是，如果你没有明确固定进程到任何 CPU 内核，你会得到类似下面的亲和力列表。

```
pid 5357's current affinity list: 0-11

```

输出表明该进程可能会被安排在从0到11中的任何一个 CPU 内核。在这种情况下，taskset 不能识别该进程当前被分配给哪个 CPU 内核，你应该使用如下所述的方法。

### 方法二

ps 命令可以告诉你每个进程/线程目前分配到的 （在“PSR”列）CPU ID。

```
$ ps -o pid,psr,comm -p <pid>
  PID PSR COMMAND
 5357  10 prog
```

输出表示进程的 PID 为 5357（名为"prog"）目前在CPU 内核 10 上运行着。如果该过程没有被固定，PSR 列会根据内核可能调度该进程到不同内核而改变显示。

### 方法三

top 命令也可以显示 CPU 被分配给哪个进程。首先，在top 命令中使用“P”选项。然后按“f”键，显示中会出现 "Last used CPU" 列。目前使用的 CPU 内核将出现在 “P”（或“PSR”）列下。

```
$ top -p 5357

```

相比于 ps 命令，使用 top 命令的好处是，你可以连续监视随着时间的改变， CPU 是如何分配的。

### 方法四

另一种来检查一个进程/线程当前使用的是哪个 CPU 内核的方法是使用 [htop 命令](/article-3141-1.html)。

从命令行启动 htop。按 键，进入"Columns"，在"Available Columns"下会添加 PROCESSOR。

每个进程当前使用的 CPU ID 将出现在“CPU”列中。

请注意，所有以前使用的命令 taskset，ps 和 top 分配CPU 内核的 IDs 为 0，1，2，...，N-1。然而，htop 分配 CPU 内核 IDs 从 1开始（直到 N）。

---

via: <http://ask.xmodulo.com/cpu-core-process-is-running.html>

作者：[Dan Nanni](http://ask.xmodulo.com/author/nanni) 译者：[strugglingyouth](https://github.com/strugglingyouth) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用 tuptime 工具查看 Linux 服务器系统的开机时间的历史和统计

Summary: 你可以使用下面的工具来查看 Linux 或类 Unix 系统运行了多长时间：  uptime ： 告诉你服务器运行了多长的时间。 lastt ： 显示重启和关机时间。 tuptime ： 报告系统的运行时间历史和运行时间统计，这是指重启之间的运行时间。和 uptime 命令类似，不过输出结果更有意思。  找出系统上次重启时间和日期 你可以使用下面的命令来获取Linux操作系统的上次重启和关机时间及日期（在OSX/类Unix系统上也可以用）： ### 显示系统重启和关机时间 who -b last reboot last shutdown ### 开机信息 uptime cat /proc/uptime awk '{ print "up " $1 /

标题多了一个t

原来还有个 tuptime

有点意思~

# 使用 tuptime 工具查看 Linux 服务器系统的开机时间的历史和统计

你可以使用下面的工具来查看 Linux 或类 Unix 系统运行了多长时间：

* uptime ： 告诉你服务器运行了多长的时间。
* lastt ： 显示重启和关机时间。
* tuptime ： 报告系统的运行时间历史和运行时间统计，这是指重启之间的运行时间。和 uptime 命令类似，不过输出结果更有意思。

### 找出系统上次重启时间和日期

你[可以使用下面的命令来获取Linux操作系统的上次重启和关机时间及日期](http://www.cyberciti.biz/hardware/howto-see-historical-statistical-uptime-on-linux-server/)（在OSX/类Unix系统上也可以用）：

```
### 显示系统重启和关机时间
who -b
last reboot
last shutdown
### 开机信息
uptime
cat /proc/uptime
awk '{ print "up " $1 /60 " minutes"}' /proc/uptime
w

```

**样例输出：**

*图01：用于找出服务器开机时间的多个Linux命令*

### 跟 tuptime 问打个招呼吧

tuptime 命令行工具可以报告基于 Linux 的系统上的下列信息：

1. 系统启动次数统计
2. 注册首次启动时间（也就是安装时间）
3. 正常关机和意外关机统计
4. 平均开机时间和故障停机时间
5. 当前开机时间
6. 首次启动以来的开机和故障停机率
7. 累积系统开机时间、故障停机时间和合计
8. 报告每次启动、开机时间、关机和故障停机时间

#### 安装

输入[下面的命令来克隆 git 仓库到 Linux 系统中](http://www.cyberciti.biz/faq/debian-ubunut-linux-download-a-git-repository/)：

```
$ cd /tmp
$ git clone https://github.com/rfrail3/tuptime.git
$ ls
$ cd tuptime
$ ls

```

**样例输出：**

*图02：克隆git仓库*

确保你安装了带有 sys，optparse，os，re，string，sqlite3，datetime，disutils 和 locale 模块的 Python v2.7。

你可以像下面这样来安装：

```
$ sudo tuptime-install.sh

```

或者，可以手工安装（基于 systemd 或非 systemd ）：

```
$ sudo cp /tmp/tuptime/latest/cron.d/tuptime /etc/cron.d/tuptime

```

如果系统是systemd的，拷贝服务文件并启用：

```
$ sudo cp /tmp/tuptime/latest/systemd/tuptime.service /lib/systemd/system/
$ sudo systemctl enable tuptime.service

```

如果系统不是systemd的，拷贝初始化文件：

```
$ sudo cp /tmp/tuptime/latest/init.d/tuptime.init.d-debian7 /etc/init.d/tuptime
$ sudo update-rc.d tuptime defaults

```

#### 运行

只需输入以下命令：

```
$ sudo tuptime

```

**样例输出：**

*图03：tuptime工作中*

在一次更新内核后，我重启了系统，然后再次输入了同样的命令：

```
$ sudo tuptime
System startups:    2   since   03:52:16 PM 08/21/2015
System shutdowns:   1 ok   -   0 bad
Average uptime:     7 days, 16 hours, 48 minutes and 3 seconds
Average downtime:   2 hours, 30 minutes and 5 seconds
Current uptime:     5 minutes and 28 seconds   since   06:23:06 AM 09/06/2015
Uptime rate:        98.66 %
Downtime rate:      1.34 %
System uptime:      15 days, 9 hours, 36 minutes and 7 seconds
System downtime:    5 hours, 0 minutes and 11 seconds
System life:        15 days, 14 hours, 36 minutes and 18 seconds

```

你可以像下面这样修改日期和时间格式：

```
$ sudo tuptime -d '%H:%M:%S %m-%d-%Y'

```

**样例输出：**

```
System startups:    1   since   15:52:16 08-21-2015
System shutdowns:   0 ok   -   0 bad
Average uptime:     15 days, 9 hours, 21 minutes and 19 seconds
Average downtime:   0 seconds
Current uptime:     15 days, 9 hours, 21 minutes and 19 seconds   since   15:52:16 08-21-2015
Uptime rate:        100.0 %
Downtime rate:      0.0 %
System uptime:      15 days, 9 hours, 21 minutes and 19 seconds
System downtime:    0 seconds
System life:        15 days, 9 hours, 21 minutes and 19 seconds

```

计算每次启动、开机时间、关机和故障停机时间：

```
$ sudo tuptime -e

```

**样例输出：**

```
Startup:  1  at  03:52:16 PM 08/21/2015
Uptime:   15 days, 9 hours, 22 minutes and 33 seconds

System startups:    1   since   03:52:16 PM 08/21/2015
System shutdowns:   0 ok   -   0 bad
Average uptime:     15 days, 9 hours, 22 minutes and 33 seconds
Average downtime:   0 seconds
Current uptime:     15 days, 9 hours, 22 minutes and 33 seconds   since   03:52:16 PM 08/21/2015
Uptime rate:        100.0 %
Downtime rate:      0.0 %
System uptime:      15 days, 9 hours, 22 minutes and 33 seconds
System downtime:    0 seconds
System life:        15 days, 9 hours, 22 minutes and 33 seconds

```

---

via: <http://www.cyberciti.biz/hardware/howto-see-historical-statistical-uptime-on-linux-server/>

作者：Vivek Gite 译者：[GOLinux](https://github.com/GOLinux) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


给新手的 10 个有用 Linux 命令行技巧

Summary: 我记得我第一次使用 Linux 的时候，我还习惯于 Windows 的图形界面，我真的很讨厌 Linux 终端。那时候我觉得命令难以记忆，不能正确使用它们。随着时间推移，我意识到了 Linux 终端的优美、灵活和可用性，说实话，我没有一天不使用它。今天，我很高兴和刚开始接触 Linux 的人一起来分享一些有用的技巧和提示，希望能帮助他们更好的向 Linux 过渡，并帮助他们学到一些新的东西（希望如此）。  10 个 Linux 命令行技巧  5 个有趣的 Linux 命令行技巧 管理 Linux 文件类型的 5 个有用命令  这篇文章希望向你展示一些不需要很高的技术就可以像

mkdir -p new_folder/{folder_1,folder_2,folder_3,folder_4,folder_5}可以这样:<br />
mkdir new_folder/folder_{1..5}

Root

来自美国的 Chrome Mobile iOS 98.0|iOS 15.3 用户

# 给新手的 10 个有用 Linux 命令行技巧

我记得我第一次使用 Linux 的时候，我还习惯于 Windows 的图形界面，我真的很讨厌 Linux 终端。那时候我觉得命令难以记忆，不能正确使用它们。随着时间推移，我意识到了 Linux 终端的优美、灵活和可用性，说实话，我没有一天不使用它。今天，我很高兴和刚开始接触 Linux 的人一起来分享一些有用的技巧和提示，希望能帮助他们更好的向 Linux 过渡，并帮助他们学到一些新的东西（希望如此）。

*10 个 Linux 命令行技巧*

* [5 个有趣的 Linux 命令行技巧](/article-5485-1.html)
* [管理 Linux 文件类型的 5 个有用命令](http://www.tecmint.com/manage-file-types-and-set-system-time-in-linux/)

这篇文章希望向你展示一些不需要很高的技术就可以像一个高手一样使用 Linux 终端的有用技巧。你只需要一个 Linux 终端和一些自由时间来体会这些命令。

### 1. 找到正确的命令

执行正确的命令对你的系统来说非常重要。然而在 Linux 中有如此多的、难以记忆的各种的命令行。那么怎样才能找到你需要的正确命令呢？答案是 apropos。你只需要运行：

```
# apropos <description>

```

其中你要用真正描述你要查找的命令的语句代替 “description”。这里有一个例子：

```
# apropos "list directory"

dir (1) - list directory contents
ls (1) - list directory contents
ntfsls (8) - list directory contents on an NTFS filesystem
vdir (1) - list directory contents

```

左边你看到的是命令，右边是它们的描述。

### 2. 执行之前的命令

很多时候你需要一遍又一遍执行相同的命令。尽管你可以重复按你键盘上的向上光标键，但你也可以用 history 命令替代。这个命令会列出自从你上次启动终端以来所有输入过的命令：

```
# history

    1  fdisk -l
    2  apt-get install gnome-paint
    3  hostname tecmint.com
    4  hostnamectl tecmint.com
    5  man hostnamectl
    6  hostnamectl --set-hostname tecmint.com
    7  hostnamectl -set-hostname tecmint.com
    8  hostnamectl set-hostname tecmint.com
    9  mount -t "ntfs" -o
   10  fdisk -l
   11  mount -t ntfs-3g /dev/sda5 /mnt
   12  mount -t rw ntfs-3g /dev/sda5 /mnt
   13  mount -t -rw ntfs-3g /dev/sda5 /mnt
   14  mount -t ntfs-3g /dev/sda5 /mnt
   15  mount man
   16  man mount
   17  mount -t -o ntfs-3g /dev/sda5 /mnt
   18  mount -o ntfs-3g /dev/sda5 /mnt
   19  mount -ro ntfs-3g /dev/sda5 /mnt
   20  cd /mnt
   ...

```

正如你上面看到的，你会得到一个你运行过的命令的列表。每一行中有一个数字表示你在第几行输入了命令。你可以通过以下方法重新调用该命令：

```
!#

```

其中要用命令的实际编号代替 #。为了更好的理解，请看下面的例子：

```
!501

```

等价于：

```
# history

```

### 3. 使用 midnight 命令

如果你不习惯使用类似 cd、cp、mv、rm 等命令，你可以使用 midnight 命令。它是一个简单的可视化 shell，你可以在上面使用鼠标：

*Midnight 命令*

借助 F1 到 F12 键，你可以轻易地执行不同任务。只需要在底部选择对应的命令。要选择文件或者目录，按下 “Insert” 键。

简而言之 midnight 就是所谓的 “mc”。要安装 mc，只需要运行：

```
$ sudo apt-get install mc        [On Debian based systems]

```

---

```
# yum install mc                 [On Fedora based systems]

```

下面是一个使用 midnight 命令器的简单例子。通过输入以下命令打开 mc：

```
# mc

```

现在使用 TAB 键选择不同的窗口 - 左和右。我有一个想要移动到 “Software” 目录的 LibreOffice 文件：

*Midnight 命令移动文件*

按 F6 按钮移动文件到新的目录。MC 会请求你确认：

*移动文件到新目录*

确认了之后，文件就会被移动到新的目标目录。

* 扩展阅读：[如何在 Linux 中使用 Midnight 命令文件管理器](http://www.tecmint.com/midnight-commander-a-console-based-file-manager-for-linux/)

### 4. 在指定时间关闭计算机

有时候你需要在下班几个小时后再关闭计算机。你可以通过使用下面的命令在指定时间关闭你的计算机：

```
$ sudo shutdown 21:00

```

这会告诉你在你指定的时间关闭计算机。你也可以告诉系统在指定分钟后关闭：

```
$ sudo shutdown +15

```

这表示计算机会在 15 分钟后关闭。

### 5. 显示已知用户的信息

你可以使用一个简单的命令列出你 Linux 系统的用户以及一些关于它们的基本信息。

```
# lslogins

```

这会输出下面的结果：

```
UID USER PWD-LOCK PWD-DENY LAST-LOGIN GECOS
0 root 0 0 Apr29/11:35 root
1 bin 0 1 bin
2 daemon 0 1 daemon
3 adm 0 1 adm
4 lp 0 1 lp
5 sync 0 1 sync
6 shutdown 0 1 Jul19/10:04 shutdown
7 halt 0 1 halt
8 mail 0 1 mail
10 uucp 0 1 uucp
11 operator 0 1 operator
12 games 0 1 games
13 gopher 0 1 gopher
14 ftp 0 1 FTP User
23 squid 0 1
25 named 0 1 Named
27 mysql 0 1 MySQL Server
47 mailnull 0 1
48 apache 0 1 Apache
...

```

### 6. 查找文件

查找文件有时候并不像你想象的那么简单。一个搜索文件的好例子是：

```
# find /home/user -type f

```

这个命令会搜索 /home/user 目录下的所有文件。find 命令真的很强大，你可以传递更多选项给它使得你的搜索更加详细。如果你想搜索超过特定大小的文件，可以使用：

```
# find . -type f -size 10M

```

上面的命令会搜索当前目录中所有大于 10M 的文件。确保不要在你 Linux 系统的根目录运行该命令，因为这可能导致你的机器 I/O 瓶颈。

我最经常和 find 命令一起使用的选项之一是 “exec”，这允许你对 find 命令的结果运行一些操作。

例如，假如我们想查找一个目录中的所有文件并更改权限。可以通过以下简单命令完成：

```
# find /home/user/files/ -type f -exec chmod 644 {} \;

```

上面的命令会递归搜索指定目录内的所有文件，并对找到的文件执行 chmod 命令。推荐你阅读 [35 个 Linux ‘find’ 命令的使用方法](http://www.tecmint.com/35-practical-examples-of-linux-find-command/)，我肯定你会发现这个命令更多的使用方法。

### 7. 用一个命令创建目录树

你很可能知道可以使用 mkdir 命令创建新的目录。因此如果你想创建一个新的目录，你可能会运行：

```
# mkdir new_folder

```

但如果你想在该目录下创建 5 个子目录呢？运行 5 次 mkdir 命令并非是一个好的选择。相反你可以类似下面这样使用 -p 选项：

```
# mkdir -p new_folder/{folder_1,folder_2,folder_3,folder_4,folder_5}

```

最后你会在 new\_folder 中有 5 个目录：

```
# ls new_folder/

folder_1 folder_2 folder_3 folder_4 folder_5

```

### 8. 复制文件到多个目录

通常使用 cp 命令进行文件复制。复制文件通常看起来类似：

```
# cp /path-to-file/my_file.txt /path-to-new-directory/

```

现在假设你需要复制该文件到多个目录：

```
# cp /home/user/my_file.txt /home/user/1
# cp /home/user/my_file.txt /home/user/2
# cp /home/user/my_file.txt /home/user/3

```

这有点荒唐。相反，你可以用简单的一行命令解决问题：

```
# echo /home/user/1/ /home/user/2/ /home/user/3/ | xargs -n 1  cp /home/user/my_file.txt

```

### 9. 删除大文件

有时候文件可能会变得很大。我看过由于缺乏管理技能一个日志文件就超过 250G 的例子。用 rm 命令可能不足以删除该文件，因为有大量的数据需要移除。应该避免这个很“笨重”的操作。相反，你可以使用一个简单的方法解决这个问题：

```
# > /path-to-file/huge_file.log

```

当然你需要根据你实际情况替换路径和文件名。上面的命令写一个空输出到该文件。用更简单的话说它会清空文件而不会导致你的系统产生大的 I/O 消耗。

### 10. 在多个 Linux 服务器上运行相同命令

最近我们的一个读者在 [LinuxSay 论坛](http://www.linuxsay.com/)提问说如何通过 ssh 在多个 Linux 服务器上执行一个命令。他机器的 IP 地址是：

```
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5

```

这里有一个简单的解决方法。将服务器的 IP 地址写到文件 list.txt 中，像上面那样一行一个。然后运行：

```
# for in $i(cat list.txt); do ssh user@$i 'bash command'; done

```

上面的命令中你需要用实际登录的用户替换 “user”，用你希望执行的实际命令替换 “bash command”。这个方法非常适用于通过[使用 SSH 密钥进行无密码验证](/article-5202-1.html)，因为这样你不需要每次都为用户输入密码。

注意取决于你 Linux 系统的设置，你可能还需要传递一些额外的参数给 SSH 命令。

### 总结

上面的例子都很简单，我希望它们能帮助你发现 Linux 的优美之处，你如何能简单实现在其它操作系统上需要更多时间的不同操作。

---

via: <http://www.tecmint.com/10-useful-linux-command-line-tricks-for-newbies/>

作者：[Marin Todorov](http://www.tecmint.com/author/marintodorov89/) 译者：[ictlyh](http://mutouxiaogui.cn/blog/) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: 简单来说，防火墙就是一个基于一系列预先定义的规则（例如流量包的目的地或来源，流量的类型等）的安全系统，它控制着一个网络中的流入和流出流量。  RHCSA: 使用 FirewallD 和 Iptables 来控制网络流量  Part 11 在本文中，我们将回顾 firewalld 和 iptables 的基础知识。前者是 RHEL 7 中的默认动态防火墙守护进程，而后者则是针对 Linux 的传统的防火墙服务，大多数的系统和网络管理员都非常熟悉它，并且在 RHEL 7 中也可以用。 FirewallD 和 Iptables 的一个比较 在后台， firewalld 和 iptables 服务都通过相同的接口来与内核中的 ne

非常不错

# RHCSA 系列（十一）: 使用 firewalld 和 iptables 来控制网络流量

简单来说，防火墙就是一个基于一系列预先定义的规则（例如流量包的目的地或来源，流量的类型等）的安全系统，它控制着一个网络中的流入和流出流量。

*RHCSA: 使用 FirewallD 和 Iptables 来控制网络流量 – Part 11*

在本文中，我们将回顾 firewalld 和 iptables 的基础知识。前者是 RHEL 7 中的默认动态防火墙守护进程，而后者则是针对 Linux 的传统的防火墙服务，大多数的系统和网络管理员都非常熟悉它，并且在 RHEL 7 中也可以用。

### FirewallD 和 Iptables 的一个比较

在后台， firewalld 和 iptables 服务都通过相同的接口来与内核中的 netfilter 框架相交流，这不足为奇，即它们都通过 iptables 命令来与 netfilter 交互。然而，与 iptables 服务相反， firewalld 可以在不丢失现有连接的情况下，在正常的系统操作期间更改设定。

在默认情况下， firewalld 应该已经安装在你的 RHEL 系统中了，尽管它可能没有在运行。你可以使用下面的命令来确认（firewall-config 是用户界面配置工具）：

```
# yum info firewalld firewall-config

```

*检查 FirewallD 的信息*

以及，

```
# systemctl status -l firewalld.service

```

*检查 FirewallD 的状态*

另一方面， iptables 服务在默认情况下没有被包含在 RHEL 系统中，但可以被安装上。

```
# yum update && yum install iptables-services

```

这两个守护进程都可以使用常规的 systemd 命令来在开机时被启动和开启：

```
# systemctl start firewalld.service | iptables-service.service
# systemctl enable firewalld.service | iptables-service.service

```

另外，请阅读：[管理 Systemd 服务的实用命令](/article-5926-1.html)

至于配置文件， iptables 服务使用 `/etc/sysconfig/iptables` 文件（假如这个软件包在你的系统中没有被安装，则这个文件将不存在）。在一个被用作集群节点的 RHEL 7 机子上，这个文件看起来是这样：

*Iptables 防火墙配置文件*

而 firewalld 则在两个目录中存储它的配置文件，即 `/usr/lib/firewalld` 和 `/etc/firewalld`：

```
# ls /usr/lib/firewalld /etc/firewalld

```

*FirewallD 的配置文件*

在这篇文章中后面，我们将进一步查看这些配置文件，在那之后，我们将在这两个地方添加一些规则。现在，是时候提醒你了，你总可以使用下面的命令来找到更多有关这两个工具的信息。

```
# man firewalld.conf
# man firewall-cmd
# man iptables

```

除了这些，记得查看一下当前系列的第一篇 [RHCSA 系列（一）: 回顾基础命令及系统文档](/article-6133-1.html)，在其中我描述了几种渠道来得到安装在你的 RHEL 7 系统上的软件包的信息。

### 使用 Iptables 来控制网络流量

在进一步深入之前，或许你需要参考 Linux 基金会认证工程师（Linux Foundation Certified Engineer,LFCE） 系列中的 [配置 Iptables 防火墙 – Part 8](http://www.tecmint.com/configure-iptables-firewall/) 来复习你脑中有关 iptables 的知识。

#### **例 1：同时允许流入和流出的网络流量**

TCP 端口 80 和 443 是 Apache web 服务器使用的用来处理常规（HTTP）和安全（HTTPS）网络流量的默认端口。你可以像下面这样在 enp0s3 接口上允许流入和流出网络流量通过这两个端口：

```
# iptables -A INPUT -i enp0s3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -o enp0s3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# iptables -A INPUT -i enp0s3 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -o enp0s3 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

```

#### **例 2：从某个特定网络中阻挡所有（或某些）流入连接**

或许有时你需要阻挡来自于某个特定网络的所有（或某些）类型的来源流量，比方说 192.168.1.0/24：

```
# iptables -I INPUT -s 192.168.1.0/24 -j DROP

```

上面的命令将丢掉所有来自 192.168.1.0/24 网络的网络包，而

```
# iptables -A INPUT -s 192.168.1.0/24 --dport 22 -j ACCEPT

```

将只允许通过端口 22 的流入流量。

#### **例 3：将流入流量重定向到另一个目的地**

假如你不仅使用你的 RHEL 7 机子来作为一个软件防火墙，而且还将它作为一个硬件防火墙，使得它位于两个不同的网络之间，那么在你的系统上 IP 转发一定已经被开启了。假如没有开启，你需要编辑 `/etc/sysctl.conf` 文件并将 `net.ipv4.ip_forward` 的值设为 1，即：

```
net.ipv4.ip_forward = 1

```

接着保存更改，关闭你的文本编辑器，并最终运行下面的命令来应用更改：

```
# sysctl -p /etc/sysctl.conf

```

例如，你可能在一个内部的机子上安装了一个打印机，它的 IP 地址为 192.168.0.10，CUPS 服务在端口 631 上进行监听（同时在你的打印服务器和你的防火墙上）。为了从防火墙另一边的客户端传递打印请求，你应该添加下面的 iptables 规则：

```
# iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 631 -j DNAT --to 192.168.0.10:631

```

请记住 iptables 会逐条地读取它的规则，所以请确保默认的策略或后面的规则不会重载上面例子中那些规则。

### FirewallD 入门

firewalld 引入的一个变化是区域（zone） （注：翻译参考了 <https://fedoraproject.org/wiki/FirewallD/zh-cn> ）。这个概念允许将网路划分为拥有不同信任级别的区域，由用户决定将设备和流量放置到哪个区域。

要获取活动的区域，使用：

```
# firewall-cmd --get-active-zones

```

在下面的例子中，public 区域是激活的，并且 enp0s3 接口被自动地分配到了这个区域。要查看有关一个特定区域的所有信息，可使用：

```
# firewall-cmd --zone=public --list-all

```

*列出所有的 Firewalld 区域*

由于你可以在 [RHEL 7 安全指南](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html) 中阅读到更多有关区域的知识，这里我们将仅列出一些特别的例子。

#### **例 4：允许服务通过防火墙**

要获取受支持的服务的列表，可以使用：

```
# firewall-cmd --get-services

```

*列出所有受支持的服务*

要立刻生效且在随后重启后都可以让 http 和 https 网络流量通过防火墙，可以这样：

```
# firewall-cmd --zone=MyZone --add-service=http
# firewall-cmd --zone=MyZone --permanent --add-service=http
# firewall-cmd --zone=MyZone --add-service=https
# firewall-cmd --zone=MyZone --permanent --add-service=https
# firewall-cmd --reload

```

假如 `-–zone` 被忽略，则使用默认的区域（你可以使用 `firewall-cmd –get-default-zone`来查看）。

若要移除这些规则，可以在上面的命令中将 `add` 替换为 `remove`。

#### **例 5：IP 转发或端口转发**

首先，你需要查看在目标区域中，伪装（masquerading）是否被开启：

```
# firewall-cmd --zone=MyZone --query-masquerade

```

在下面的图片中，我们可以看到对于外部区域，伪装已被开启，但对于公用区域则没有：

*查看伪装状态*

你可以为公共区域开启伪装：

```
# firewall-cmd --zone=public --add-masquerade

```

或者在外部区域中使用伪装。下面是使用 firewalld 来重复例 3 中的任务所需的命令：

```
# firewall-cmd --zone=external --add-forward-port=port=631:proto=tcp:toport=631:toaddr=192.168.0.10

```

不要忘了重新加载防火墙。

在 RHCSA 系列的 [第九部分](/article-6286-1.html) 你可以找到更深入的例子，在那篇文章中我们解释了如何允许或禁用通常被 web 服务器和 ftp 服务器使用的端口，以及在针对这两个服务所使用的默认端口被改变时，如何更改相应的规则。另外，你或许想参考 firewalld 的 wiki 来查看更深入的例子。

* 延伸阅读： [在 RHEL 7 中配置防火墙的几个实用的 firewalld 例子](http://www.tecmint.com/firewalld-rules-for-centos-7/)

### 总结

在这篇文章中，我们已经解释了防火墙是什么，介绍了在 RHEL 7 中用来实现防火墙的几个可用的服务，并提供了可以帮助你入门防火墙的几个例子。假如你有任何的评论，建议或问题，请随意使用下面的评论框来让我们知晓。这里就事先感谢了！

---

via: <http://www.tecmint.com/firewalld-vs-iptables-and-control-network-traffic-in-firewall/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: 无论是在数据中心还是实验室环境，Linux 服务器很少是独立的机器，很可能有时你需要安装多个以某种方式相互联系的机器。假如你将在单个服务器上手动安装 RHEL 7 所花的时间乘以你需要配置的机器数量，这将导致你必须做出一场相当长的努力，而通过使用被称为 kicksta 的无人值守安装工具则可以避免这样的麻烦。 在这篇文章中，我们将向你展示使用 kickstart 工具时所需的一切，以便在安装过程中，不用你时不时地照看处在襁褓中的服务器。  RHCSA： RHEL 7 的自动化 Kickstart 安装 Kickstart 和自动化安装简介 Kickstart 是一种被用来执行

无人值守的安装如果还需要去接触客户端，给客户端做个插U盘之类的操作，那就不叫无人值守了。使用 rhel-server-7.0-x86_64-boot.iso 来启动你的客户端这里只的是虚拟机吗。如果我机房里五百多个服务器都要同时安装呢。<br />
小编能否再续一篇。

# RHCSA 系列（十二）: 使用 Kickstart 完成 RHEL 7 的自动化安装

无论是在数据中心还是实验室环境，Linux 服务器很少是独立的机器，很可能有时你需要安装多个以某种方式相互联系的机器。假如你将在单个服务器上手动安装 RHEL 7 所花的时间乘以你需要配置的机器数量，这将导致你必须做出一场相当长的努力，而通过使用被称为 kicksta 的无人值守安装工具则可以避免这样的麻烦。

在这篇文章中，我们将向你展示使用 kickstart 工具时所需的一切，以便在安装过程中，不用你时不时地照看“处在襁褓中”的服务器。

*RHCSA： RHEL 7 的自动化 Kickstart 安装*

#### Kickstart 和自动化安装简介

Kickstart 是一种被用来执行无人值守操作系统安装和配置的自动化安装方法，主要被 RHEL（以及其他 Fedora 的副产品，如 CentOS，Oracle Linux 等）所使用。因此，kickstart 安装方法可使得系统管理员只需考虑需要安装的软件包组和系统的配置，便可以得到相同的系统，从而省去必须手动安装这些软件包的麻烦。

### 准备 Kickstart 安装

要执行 kickstart 安装，我们需要遵循下面的这些步骤：

1. 创建一个 Kickstart 文件，它是一个带有多个预定义配置选项的纯文本文件。
2. 将 Kickstart 文件保存在可移动介质上，如一个硬盘或一个网络位置。kickstart 客户端需要使用 `rhel-server-7.0-x86_64-boot.iso` 镜像文件，而你还需要可从一个网络资源上获取得到完整的 ISO 镜像 `rhel-server-7.0-x86_64-dvd.iso` ，例如通过一个 FTP 服务器的 HTTP 服务形式（在我们当前的例子中，我们将使用另一个 IP 地址为 192.168.0.18 的 RHEL 7 机器）。
3. 开始 Kickstart 安装。

要创建一个 kickstart 文件，请登录你的红帽客户门户网站（Red Hat Customer Portal）帐户，并使用 [Kickstart 配置工具](https://access.redhat.com/labs/kickstartconfig/) 来选择所需的安装选项。在向下滑动之前请仔细阅读每个选项，然后选择最适合你需求的选项：

*Kickstart 配置工具*

假如你指定安装将通过 HTTP，FTP，NFS 来执行，请确保服务器上的防火墙允许这些服务通过。

尽管你可以使用红帽的在线工具来创建一个 kickstart 文件，但你还可以使用下面的代码来作为参考手动地创建它。例如，你可以注意到，下面的代码指定了安装过程将使用英语环境，使用拉丁美洲键盘布局，并设定时区为 America/Argentina/San\_Luis 时区：

```
lang en_US
keyboard la-latin1
timezone America/Argentina/San_Luis --isUtc
rootpw $1$5sOtDvRo$In4KTmX7OmcOW9HUvWtfn0 --iscrypted
#platform x86, AMD64, or Intel EM64T
text
url --url=http://192.168.0.18//kickstart/media
bootloader --location=mbr --append="rhgb quiet crashkernel=auto"
zerombr
clearpart --all --initlabel
autopart
auth --passalgo=sha512 --useshadow
selinux --enforcing
firewall --enabled
firstboot --disable
%packages
@base
@backup-server
@print-server
%end

```

在上面的在线配置工具中，在选择以 HTTP 来作为安装源后，设置好在安装过程中使用 192.168.0.18 来作为 HTTP 服务器的地址，`/kickstart/tecmint.bin` 作为 HTTP 目录。

在上面的 kickstart 示例文件中，你需要特别注意

```
url --url=http://192.168.0.18//kickstart/media

```

这个目录是你展开 DVD 或 ISO 安装介质内容的地方。在执行解压之前，我们将把 ISO 安装文件作为一个回环设备挂载到 /media/rhel 目录下：

```
# mount -o loop /var/www/html/kickstart/rhel-server-7.0-x86_64-dvd.iso /media/rhel

```

*挂载 RHEL ISO 镜像*

接下来，复制 /media/rhel 中的全部文件到 /var/www/html/kickstart/media 目录：

```
# cp -R /media/rhel /var/www/html/kickstart/media

```

这一步做完后，/var/www/html/kickstart/media 目录中的文件列表和磁盘使用情况将如下所示：

*Kickstart 媒体文件*

现在，我们已经准备好开始 kickstart 安装了。

不管你如何选择创建 kickstart 文件的方式，在执行安装之前检查下这个文件的语法是否有误总是一个不错的主意。为此，我们需要安装 pykickstart 软件包。

```
# yum update && yum install pykickstart

```

然后使用 ksvalidator 工具来检查这个文件：

```
# ksvalidator /var/www/html/kickstart/tecmint.bin

```

假如文件中的语法正确，你将不会得到任何输出，反之，假如文件中存在错误，你得到警告，向你提示在某一行中语法不正确或出错原因未知。

### 执行 Kickstart 安装

首先，使用 rhel-server-7.0-x86\_64-boot.iso 来启动你的客户端。当初始屏幕出现时，选择安装 RHEL 7.0 ，然后按 Tab 键来追加下面这一句，接着按 Enter 键：

```
# inst.ks=http://192.168.0.18/kickstart/tecmint.bin

```

*RHEL Kickstart 安装*

其中 tecmint.bin 是先前创建的 kickstart 文件。

当你按了 Enter 键后，自动安装就开始了，且你将看到一个列有正在被安装的软件的列表（软件包的数目和名称根据你所选择的程序和软件包组而有所不同）：

*RHEL 7 的自动化 Kickstart 安装*

当自动化过程结束后，将提示你移除安装介质，接着你就可以启动到你新安装的系统中了：

*RHEL 7 启动屏幕*

尽管你可以像我们前面提到的那样，手动地创建你的 kickstart 文件，但你应该尽可能地考虑使用受推荐的方式：你可以使用在线配置工具，或者使用在安装过程中创建的位于 root 家目录下的 anaconda-ks.cfg 文件。

这个文件实际上就是一个 kickstart 文件，你或许想在选择好所有所需的选项（可能需要更改逻辑卷布局或机器上所用的文件系统）后手动地安装第一个机器，接着使用产生的 anaconda-ks.cfg 文件来自动完成其余机器的安装过程。

另外，使用在线配置工具或 anaconda-ks.cfg 文件来引导将来的安装将允许你在系统安装时以加密的形式设置 root 密码。

### 总结

既然你知道了如何创建 kickstart 文件并如何使用它们来自动完成 RHEL 7 服务器的安装，你就可以不用时时照看安装进度的过程了。这将给你时间来做其他的事情，或者若你足够幸运，你还可以用来休闲一番。

无论以何种方式，请使用下面的评论栏来让我们知晓你对这篇文章的看法。提问也同样欢迎！

另外，请阅读：[使用 PXE 和 kickstart 来自动化安装多个 RHEL/CentOS 7 发行版本](http://www.tecmint.com/multiple-centos-installations-using-kickstart/)

---

via: <http://www.tecmint.com/automatic-rhel-installations-using-kickstart/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: 在本系列的前面几篇文章中，我们已经详细地探索了至少两种访问控制方法：标准的 ugo/rwx 权限（RHCSA 系列（三）: 如何管理 RHEL7 的用户和组） 和访问控制列表（RHCSA 系列（七）: 使用 ACL（访问控制列表) 和挂载 Samba/NFS 共享）。  RHCSA 认证：SELinux 精要和控制文件系统的访问 尽管作为第一级别的权限和访问控制机制是必要的，但它们同样有一些局限，而这些局限则可以由安全增强 Linux（Security Enhanced Linux，简称为 SELinux）来处理。 这些局限的一种情形是：某个用户可能通过一个泛泛的 chmod 命令将文件或目录暴露出现了安

# RHCSA 系列（十三）： 在 RHEL 7 中使用 SELinux 进行强制访问控制

在本系列的前面几篇文章中，我们已经详细地探索了至少两种访问控制方法：标准的 ugo/rwx 权限（[RHCSA 系列（三）: 如何管理 RHEL7 的用户和组](/article-6187-1.html)） 和访问控制列表（[RHCSA 系列（七）: 使用 ACL（访问控制列表) 和挂载 Samba/NFS 共享](/article-6263-1.html)）。

*RHCSA 认证：SELinux 精要和控制文件系统的访问*

尽管作为第一级别的权限和访问控制机制是必要的，但它们同样有一些局限，而这些局限则可以由<ruby> 安全增强 Linux <rp>  （ </rp> <rt>  Security Enhanced Linux，简称为 SELinux </rt> <rp>  ） </rp></ruby>来处理。

这些局限的一种情形是：某个用户可能通过一个泛泛的 chmod 命令将文件或目录暴露出现了安全违例，从而引起访问权限的意外传播。结果，由该用户开启的任意进程可以对属于该用户的文件进行任意的操作，最终一个恶意的或有其它缺陷的软件可能会取得整个系统的 root 级别的访问权限。

考虑到这些局限性，美国国家安全局（NSA） 率先设计出了 SELinux，一种强制的访问控制方法，它根据最小权限模型去限制进程在系统对象（如文件，目录，网络接口等）上的访问或执行其他的操作的能力，而这些限制可以在之后根据需要进行修改。简单来说，系统的每一个元素只给某个功能所需要的那些权限。

在 RHEL 7 中，SELinux 被并入了内核中，且默认情况下以<ruby> 强制模式 <rp>  （ </rp> <rt>  Enforcing </rt> <rp>  ） </rp></ruby>开启。在这篇文章中，我们将简要地介绍有关 SELinux 及其相关操作的基本概念。

### SELinux 的模式

SELinux 可以以三种不同的模式运行：

* <ruby> 强制模式 <rp>  （ </rp> <rt>  Enforcing </rt> <rp>  ） </rp></ruby>：SELinux 基于其策略规则来拒绝访问，这些规则是用以控制安全引擎的一系列准则；
* <ruby> 宽容模式 <rp>  （ </rp> <rt>  Permissive </rt> <rp>  ） </rp></ruby>：SELinux 不会拒绝访问，但对于那些如果运行在强制模式下会被拒绝访问的行为进行记录；
* <ruby> 关闭 <rp>  （ </rp> <rt>  Disabled </rt> <rp>  ） </rp></ruby> (不言自明，即 SELinux 没有实际运行).

使用 `getenforce` 命令可以展示 SELinux 当前所处的模式，而 `setenforce` 命令（后面跟上一个 1 或 0） 则被用来将当前模式切换到<ruby> 强制模式 <rp>  （ </rp> <rt>  Enforcing </rt> <rp>  ） </rp></ruby>或<ruby> 宽容模式 <rp>  （ </rp> <rt>  Permissive </rt> <rp>  ） </rp></ruby>，但只对当前的会话有效。

为了使得在登出和重启后上面的设置还能保持作用，你需要编辑 `/etc/selinux/config` 文件并将 SELINUX 变量的值设为 enforcing，permissive，disabled 中之一：

```
# getenforce
# setenforce 0
# getenforce
# setenforce 1
# getenforce
# cat /etc/selinux/config

```

*设置 SELinux 模式*

通常情况下，你应该使用 `setenforce` 来在 SELinux 模式间进行切换（从强制模式到宽容模式，或反之），以此来作为你排错的第一步。假如 SELinux 当前被设置为强制模式，而你遇到了某些问题，但当你把 SELinux 切换为宽容模式后问题不再出现了，则你可以确信你遇到了一个 SELinux 权限方面的问题。

### SELinux 上下文

一个 SELinux <ruby> 上下文 <rp>  （ </rp> <rt>  Context </rt> <rp>  ） </rp></ruby>由一个访问控制环境所组成，在这个环境中，决定的做出将基于 SELinux 的用户，角色和类型（和可选的级别）：

* 一个 SELinux 用户是通过将一个常规的 Linux 用户账户映射到一个 SELinux 用户账户来实现的，反过来，在一个会话中，这个 SELinux 用户账户在 SELinux 上下文中被进程所使用，以便能够明确定义它们所允许的角色和级别。
* 角色的概念是作为域和处于该域中的 SELinux 用户之间的媒介，它定义了 SELinux 可以访问到哪个进程域和哪些文件类型。这将保护您的系统免受提权漏洞的攻击。
* 类型则定义了一个 SELinux 文件类型或一个 SELinux 进程域。在正常情况下，进程将会被禁止访问其他进程正使用的文件，并禁止对其他进程进行访问。这样只有当一个特定的 SELinux 策略规则允许它访问时，才能够进行访问。

下面就让我们看看这些概念是如何在下面的例子中起作用的。

**例 1：改变 sshd 守护进程的默认端口**

在 [RHCSA 系列（八）: 加固 SSH，设定主机名及启用网络服务](/article-6266-1.html) 中，我们解释了更改 sshd 所监听的默认端口是加固你的服务器免受外部攻击的首要安全措施。下面，就让我们编辑 `/etc/ssh/sshd_config` 文件并将端口设置为 9999：

```
Port 9999

```

保存更改并重启 sshd：

```
# systemctl restart sshd
# systemctl status sshd

```

*重启 SSH 服务*

正如你看到的那样， sshd 启动失败，但为什么会这样呢？

快速检查 `/var/log/audit/audit.log` 文件会发现 sshd 已经被拒绝在端口 9999 上开启（SELinux 的日志信息包含单词 "AVC"，所以这类信息可以被轻易地与其他信息相区分），因为这个端口是 JBoss 管理服务的保留端口：

```
# cat /var/log/audit/audit.log | grep AVC | tail -1

```

*查看 SSH 日志*

在这种情况下，你可以像先前解释的那样禁用 SELinux（但请不要这样做！），并尝试重启 sshd，且这种方法能够起效。但是， `semanage` 应用可以告诉我们在哪些端口上可以开启 sshd 而不会出现任何问题。

运行：

```
# semanage port -l | grep ssh

```

便可以得到一个 SELinux 允许 sshd 在哪些端口上监听的列表：

*Semanage 工具*

所以让我们在 `/etc/ssh/sshd_config` 中将端口更改为 9998 端口，增加这个端口到 ssh*port*t 的上下文，然后重启 sshd 服务：

```
# semanage port -a -t ssh_port_t -p tcp 9998
# systemctl restart sshd
# systemctl is-active sshd

```

*semanage 添加端口*

如你所见，这次 sshd 服务被成功地开启了。这个例子告诉我们一个事实：SELinux 用它自己的端口类型的内部定义来控制 TCP 端口号。

**例 2：允许 httpd 访问 sendmail**

这是一个 SELinux 管理一个进程来访问另一个进程的例子。假如在你的 RHEL 7 服务器上，[你要为 Apache 配置 mod\_security 和 mod\_evasive](/article-5639-1.html)，你需要允许 httpd 访问 sendmail，以便在遭受到 (D)DoS 攻击时能够用邮件来提醒你。在下面的命令中，如果你不想使得更改在重启后仍然生效，请去掉 `-P` 选项。

```
# semanage boolean -1 | grep httpd_can_sendmail
# setsebool -P httpd_can_sendmail 1
# semanage boolean -1 | grep httpd_can_sendmail

```

*允许 Apache 发送邮件*

从上面的例子中，你可以知道 SELinux 布尔设定（或者只是布尔值）分别对应于 true 或 false，被嵌入到了 SELinux 策略中。你可以使用 `semanage boolean -l` 来列出所有的布尔值，也可以管道至 grep 命令以便筛选输出的结果。

**例 3：在一个特定目录而非默认目录下提供一个静态站点服务**

假设你正使用一个不同于默认目录（`/var/www/html`）的目录来提供一个静态站点服务，例如 `/websites` 目录（这种情形会出现在当你把你的网络文件存储在一个共享网络设备上，并需要将它挂载在 /websites 目录时）。

a). 在 /websites 下创建一个 index.html 文件并包含如下的内容：

```
<html>
<h2>SELinux test</h2>
</html>

```

假如你执行

```
# ls -lZ /websites/index.html

```

你将会看到这个 index.html 已经被标记上了 default\_t SELinux 类型，而 Apache 不能访问这类文件：

*检查 SELinux 文件的权限*

b). 将 `/etc/httpd/conf/httpd.conf` 中的 DocumentRoot 改为 /websites，并不要忘了 更新相应的 Directory 块。然后重启 Apache。

c). 浏览 `http://<web server IP address>`，则你应该会得到一个 503 Forbidden 的 HTTP 响应。

d). 接下来，递归地改变 /websites 的标志，将它的标志变为 `httpd_sys_content_t` 类型，以便赋予 Apache 对这些目录和其内容的只读访问权限：

```
# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"

```

e). 最后，应用在 d) 中创建的 SELinux 策略：

```
# restorecon -R -v /websites

```

现在重启 Apache 并再次浏览到 `http://<web server IP address>`，则你可以看到被正确展现出来的 html 文件：

*确认 Apache 页面*

### 总结

在本文中，我们详细地介绍了 SELinux 的基础知识。请注意，由于这个主题的广泛性，在单篇文章中做出一个完全详尽的解释是不可能的，但我们相信，在这个指南中列出的基本原则将会对你进一步了解更高级的话题有所帮助，假如你想了解的话。

假如可以，请让我推荐两个必要的资源来入门 SELinux：[NSA SELinux 页面](https://www.nsa.gov/research/selinux/index.shtml) 和 [针对用户和系统管理员的 RHEL 7 SELinux 指南](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/part_I-SELinux.html)。

假如你有任何的问题或评论，请不要犹豫，让我们知晓吧。

---

via: <http://www.tecmint.com/selinux-essentials-and-control-filesystem-access/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


ifdex： 一个由 ESR 出品的给代码考古学家的工具

Summary: Eric Raymond 写了一个工具，用来帮助那些无畏的代码考古学家们理解古代代码的结构。它叫做ifdex，它的背后有一段故事，拿起你的 Fedora 和赶牛的鞭子，让我讲给你听  在开发 NTPsec 早期， 我们就决定替换它的构建系统它是如此的难于理解和修改严重的拖慢了我们的开发进度。 古老的 autoconf 构建方式就像一个恐怖的爬行动物，而 NTP 更是一个极端的例子。不完善的宏技术定义了太多的配置符号，为了掌握这些接口，即使你查看了 config.h 也无济于事。尤其是当你要做一些大的修改时，这更是一个问题！ 我们的一个伙计 Amar Takhar，是 waf

# ifdex： 一个由 ESR 出品的给代码考古学家的工具

Eric Raymond 写了一个工具，用来帮助那些无畏的“代码考古学家们”理解“古代”代码的结构。它叫做 [ifdex](http://www.catb.org/esr/ifdex/)，它的背后有一段故事，拿起你的 Fedora 和赶牛的鞭子，让我讲给你听……

<img src="content_image/album_201510_03_174046d8rtgljvwvtv69zt.png" alt="" title="">

在开发 NTPsec 早期， 我们就决定替换它的构建系统——它是如此的难于理解和修改——严重的拖慢了我们的开发进度。

古老的 autoconf 构建方式就像一个恐怖的爬行动物，而 NTP 更是一个极端的例子。不完善的宏技术定义了太多的配置符号，为了掌握这些接口，即使你查看了 config.h 也无济于事。尤其是当你要做一些大的修改时，这更是一个问题！

我们的一个伙计 Amar Takhar，是 waf 构建系统的专家，当他初步提出迁移的想法时得到了我的积极响应。几个月之后，他就做出了一些 waf 功能，虽然还未完成，但是已经至少可以生成用于实际测试的二进制了。

这里我说“未完成”的意思是，代码里面还有一些 waf 构建绝不会设置的 #define 。很多人绝对不会碰那些 autoconf 构建的东西，而另外一些人则不。那些从来用不到的配置开关迷失在大堆的系统头文件和编译器设置的 #define 条件中。

我这里说的不是几个或几十个，我最终统计出了有超过 670 个不同的 #define 用在 #if/#ifdef/#ifndef/#elif 条件中，而这些条件，如 John D. Bell 指出的那样，有 2430 个之多。我需要一些办法来检查它们并分成不同的类型：有的来自系统头文件、有的是配置开关，以及其它的……

所以我写了一个分析器，它可以对代码树解析每个编译时条件的符号，然后将它们分成单纯的列表或 GCC 类的文件/行错误信息，你可以用 Emacs 的编译模式逐个分析。

为了降低干扰，它掌握着一个条件符号的长列表（大概200个），这些可以忽略掉。比如像 \_\_GNUC\_\_ 符号是 GCC 预定义，而 O\_NONBLOCK 宏用于几种系统调用等等。

这些符号分成几组，你可以使用命令行选项分别忽略它们。所以，如果你希望忽略列表中所有标准的 POSIX 宏而想看到操作系统相关的任何东西，那就可以做到了。

另外一个重要的功能是你可以构造你自己的排除列表及注释。这样当我探索 NTP 编译条件的黑暗森林时，所构造的越来越大的排除列表就代表了我已经了解了的条件符号。最终（我希望）未知符号的报告将缩减为空，那么我就已经了解了所有配置开关的确切意义了。

目前为止，我已经搞定了它们之中的 300 个，还有 373 个。这是我用我的漂亮工具在一周内完成的主要工作。噢，从来没有人说过代码考古是如此的容易。

最后， ifdef 的主页是： <http://www.catb.org/esr/ifdex/> ，代码库在这里： <https://gitlab.com/esr/ifdex> 。希望你用的上。


在 CentOS 7 中安装并使用自动化工具 Ansible

Summary: Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成，类似于Chef和Puppet，但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。  本篇中我们将在CentOS 7上安装并配置Ansible，并且尝试管理两个节点。   Ansible 服务端  ansible.linuxtechi.com ( 192.168.1.15 )   节点  192.168.1.9 , 192.168.1.10   第一步： 设置EPEL仓库 Ansible仓库默认不在yum仓库中，因此我们需要使用下面的命令启用epel仓库。 # rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-r

轻量级的一个应用、ssh互信做过，使用for 循环也能达到这个效果吧。

高手

flichote [Internet Explorer 9.0|Windows 7]

你好，我做的 lacp team , 之前在centos 6/5 上面 可以使用‘ethtool bond0’ 可以看到 speed:2000Mb/s<br />
现在 centos7 使用由类似 命令可以看到 当前 Team 速率。

请问，使用ssh-copy-id命令来复制Ansible公钥到节点中这一步执行的ssh-copy-id -i root@192.168.1.10；这里必须是用root吗？@后面跟的这个IP是什么IP呢？

# 在 CentOS 7 中安装并使用自动化工具 Ansible

Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成，类似于Chef和Puppet，但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。

本篇中我们将在CentOS 7上安装并配置Ansible，并且尝试管理两个节点。

* **Ansible 服务端** – ansible.linuxtechi.com ( 192.168.1.15 )
* **节点** – 192.168.1.9 , 192.168.1.10

### 第一步： 设置EPEL仓库

Ansible仓库默认不在yum仓库中，因此我们需要使用下面的命令启用epel仓库。

```
[root@ansible ~]# rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm

```

### 第二步： 使用yum安装Ansible

```
[root@ansible ~]# yum install ansible

```

安装完成后，检查ansible版本：

```
[root@ansible ~]# ansible --version

```

### 第三步： 设置用于节点鉴权的SSH密钥

在Ansible服务端生成密钥，并且复制公钥到节点中。

```
root@ansible ~]# ssh-keygen

```

使用ssh-copy-id命令来复制Ansible公钥到节点中。

### 第四步：为Ansible定义节点的清单

文件 `/etc/ansible/hosts` 维护着Ansible中服务器的清单。

```
[root@ansible ~]# vi /etc/ansible/hosts
[test-servers]
192.168.1.9
192.168.1.10

```

保存并退出文件。

主机文件示例如下：

### 第五步：尝试在Ansible服务端运行命令

使用ping检查‘test-servers’或者ansible节点的连通性。

```
[root@ansible ~]# ansible -m ping 'test-servers'

```

#### 执行shell命令

**例子1：检查Ansible节点的运行时间（uptime）**

```
[root@ansible ~]# ansible -m command -a "uptime" 'test-servers'

```

**例子2：检查节点的内核版本**

```
[root@ansible ~]# ansible -m command -a "uname -r" 'test-servers'

```

**例子3：给节点增加用户**

```
[root@ansible ~]# ansible -m command -a "useradd mark" 'test-servers'
[root@ansible ~]# ansible -m command -a "grep mark /etc/passwd" 'test-servers'

```

**例子4：重定向输出到文件中**

```
[root@ansible ~]# ansible -m command -a "df -Th" 'test-servers' > /tmp/command-output.txt

```

---

via: <http://www.linuxtechi.com/install-and-use-ansible-in-centos-7/>

作者：[Pradeep Kumar](http://www.linuxtechi.com/author/pradeep/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


RHCSA 系列（十四）： 在 RHEL 7 中设置基于 LDAP 的认证

Summary: 在这篇文章中，我们将首先罗列一些 LDAP 的基础知识（它是什么，它被用于何处以及为什么会被这样使用），然后向你展示如何使用 RHEL 7 系统来设置一个 LDAP 服务器以及配置一个客户端来使用它达到认证的目的。  RHCSA 系列：设置 LDAP 服务器及客户端认证  Part 14 正如你将看到的那样，关于认证，还存在其他可能的应用场景，但在这篇指南中，我们将只关注基于 LDAP 的认证。另外，请记住，由于这个话题的广泛性，在这里我们将只涵盖它的基础知识，但你可以参考位于总结部分中列出的文档，以此来了解更加深入的细节。 基于相同的原因，你

拜读中……

第四步 “然后以下面的内容创建一个 LDIF 文件(ldaprootpasswd.ldif)：”  这个在哪儿创建，直接用户vi写一个  还是？求指点

vi 写一个

谢谢指点

想看下LDAP怎么架设, 试了很多次都不成功

yutou83 [Internet Explorer 11.0|Windows 7]

首先非常感谢：Gabriel Cánepa 、FSSlc 、wxy ，按照全文步骤逐步完成到第9步出现报错。

[root@huwei ~]# ldapmodify -H ldapi:/// -f ldapdomin.ldif

SASL/EXTERNAL authentication started

SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cauth

SASL SSF: 0

ldapmodify: wrong attributeType at line 5, entry "olcDatabase={1onitor,cn=config"

我现在还不太理解第五行错误在什么地方，所以决定回去看看你们https://linux.cn/article-6934-1.html 人邮的那本书，前面两张是免费的可以看看，说不准能找到答案。如果译者看到了我们的问题  也请指点。我是个纯小白

求指点

这行明明是“dn: olcDatabase={1}monitor,cn=config”

抱歉 这个报错应该是我粘贴的错。实际上报错就提示

[root@huwei ~]# ldapmodify -H ldapi:/// -f ldapdomin.ldif

SASL/EXTERNAL authentication started

SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth

SASL SSF: 0

ldapmodify: wrong attributeType at line 5, entry "olcDatabase={1}monitor,cn=config"

我有逐一检查了一下，文件中的配置。请问FSSIc你有出现过类似的问题吗？

如果说是第五行，我考虑你是否在复制的时候，丢失了该行的前缀空格。这篇原文在此处的格式不准确，我们在校对和发布过程中进行了修正。

这种配置文件采用的是类似 yaml 的格式，其中的空格缩进是有意义的。对于此格式，有如下要求要注意：

1、键值对采用冒号和一个空格分隔——空格是重要的。

2、太长的值如果换行表示的话，请用前缀空格缩进。

可参见：

https://www.digitalocean.com/community/tutorials/how-to-use-ldif-files-to-make-changes-to-an-openldap-system

请问你是怎么解决的？我也遇到同样的问题

看到配置LDAP我就笑了<br />
从来没整成功过

每一段中间要加个空行

我也出现这个问题，仔细排查后发现有些行的开始和末尾会有空格，删除空格后完美解决

我搜的没模式，全摸索，刚从坑里出来。这文章，步骤详细，清晰，算好的了，学到了，

# RHCSA 系列（十四）： 在 RHEL 7 中设置基于 LDAP 的认证

在这篇文章中，我们将首先罗列一些 LDAP 的基础知识（它是什么，它被用于何处以及为什么会被这样使用），然后向你展示如何使用 RHEL 7 系统来设置一个 LDAP 服务器以及配置一个客户端来使用它达到认证的目的。

*RHCSA 系列：设置 LDAP 服务器及客户端认证 – Part 14*

正如你将看到的那样，关于认证，还存在其他可能的应用场景，但在这篇指南中，我们将只关注基于 LDAP 的认证。另外，请记住，由于这个话题的广泛性，在这里我们将只涵盖它的基础知识，但你可以参考位于总结部分中列出的文档，以此来了解更加深入的细节。

基于相同的原因，你将注意到：为了简洁起见，我已经决定省略了几个位于 man 页中 LDAP 工具的参考，但相应命令的解释是近在咫尺的（例如，输入 man ldapadd）。

那还是让我们开始吧。

**我们的测试环境**

我们的测试环境包含两台 RHEL 7机器：

```
Server: 192.168.0.18. FQDN: rhel7.mydomain.com
Client: 192.168.0.20. FQDN: ldapclient.mydomain.com

```

如若你想，你可以使用在 [RHCSA 系列（十二）: 使用 Kickstart 完成 RHEL 7 的自动化安装](/article-6335-1.html) 中使用 Kickstart 安装的机子来作为客户端。

#### LDAP 是什么？

LDAP 代表<ruby> 轻量级目录访问协议 <rp>  （ </rp> <rt>  Lightweight Directory Access Protocol </rt> <rp>  ） </rp></ruby>，并包含在一系列协议之中，这些协议允许一个客户端通过网络去获取集中存储的信息（例如所登录的 shell 的路径，家目录的绝对路径，或者其他典型的系统用户信息），而这些信息可以从不同的地方访问到或被很多终端用户获取到（另一个例子是含有某个公司所有雇员的家庭地址和电话号码的目录）。

对于那些被赋予了权限可以使用这些信息的人来说，将这些信息进行集中管理意味着可以更容易地维护和获取。

下面的图表提供了一个简化了的关于 LDAP 的示意图，在下面将会进行更多的描述：

*LDAP 示意图*

下面是对上面示意图的一个详细解释。

* 在一个 LDAP 目录中，一个<ruby> 条目 <rp>  （ </rp> <rt>  entry </rt> <rp>  ） </rp></ruby>代表一个独立单元或信息，被所谓的<ruby> 区别名 <rp>  （ </rp> <rt>  DN，Distinguished Name </rt> <rp>  ） </rp></ruby> 唯一识别。
* 一个<ruby> 属性 <rp>  （ </rp> <rt>  attribute </rt> <rp>  ） </rp></ruby>是一些与某个条目相关的信息（例如地址，有效的联系电话号码和邮箱地址）。
* 每个属性被分配有一个或多个<ruby> 值 <rp>  （ </rp> <rt>  value </rt> <rp>  ） </rp></ruby>，这些值被包含在一个以空格为分隔符的列表中。每个条目中那个唯一的值被称为一个<ruby> 相对区别名 <rp>  （ </rp> <rt>  RDN，Relative Distinguished Name </rt> <rp>  ） </rp></ruby>。

接下来，就让我们进入到有关服务器和客户端安装的内容。

### 安装和配置一个 LDAP 服务器和客户端

在 RHEL 7 中， LDAP 由 OpenLDAP 实现。为了安装服务器和客户端，分别使用下面的命令：

```
# yum update && yum install openldap openldap-clients openldap-servers
# yum update && yum install openldap openldap-clients nss-pam-ldapd

```

一旦安装完成，我们还需要关注一些事情。除非显示地提示，下面的步骤都只在服务器上执行：

**1. 在服务器和客户端上，为了确保 SELinux 不会妨碍挡道，长久地开启下列的布尔值：**

```
# setsebool -P allow_ypbind=0 authlogin_nsswitch_use_ldap=0

```

其中 `allow_ypbind` 为基于 LDAP 的认证所需要，而 `authlogin_nsswitch_use_ldap`则可能会被某些应用所需要。

**2. 开启并启动服务：**

```
# systemctl enable slapd.service
# systemctl start slapd.service

```

记住你也可以使用 [systemctl](http://www.tecmint.com/manage-services-using-systemd-and-systemctl-in-linux/) 来禁用，重启或停止服务：

```
# systemctl disable slapd.service
# systemctl restart slapd.service
# systemctl stop slapd.service

```

**3. 由于 slapd 服务是由 ldap 用户来运行的（你可以使用 `ps -e -o pid,uname,comm | grep slapd` 来验证），为了使得服务器能够更改由管理工具创建的条目，该用户应该有目录 `/var/lib/ldap` 的所有权，而这些管理工具仅可以由 root 用户来运行（紧接着有更多这方面的内容）。**

在递归地更改这个目录的所有权之前，将 slapd 的示例数据库配置文件复制进这个目录：

```
# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
# chown -R ldap:ldap /var/lib/ldap

```

**4. 设置一个 OpenLDAP 管理用户并设置密码：**

```
# slappasswd

```

正如下一幅图所展示的那样：

*设置 LDAP 管理密码*

然后以下面的内容创建一个 LDIF 文件(`ldaprootpasswd.ldif`)：

```
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}PASSWORD

```

其中：

* PASSWORD 是先前得到的经过哈希处理的字符串。
* cn=config 指的是全局配置选项。
* olcDatabase 指的是一个特定的数据库实例的名称，并且通常可以在 `/etc/openldap/slapd.d/cn=config` 目录中发现。

根据上面提供的理论背景，`ldaprootpasswd.ldif` 文件将添加一个条目到 LDAP 目录中。在那个条目中，每一行代表一个属性键值对（其中 dn，changetype，add 和 olcRootPW 为属性，每个冒号右边的字符串为相应的键值）。

随着我们的进一步深入，请记住上面的这些，并注意到在这篇文章的余下部分，我们使用相同的<ruby> 通用名 <rp>  （ </rp> <rt>  Common Names </rt> <rp>  ） </rp></ruby> `(cn=)`，而这些余下的步骤中的每一步都将与其上一步相关。

**5. 现在，通过特别指定相对于 ldap 服务的 URI ，添加相应的 LDAP 条目，其中只有 protocol/host/port 这几个域被允许使用。**

```
# ldapadd -H ldapi:/// -f ldaprootpasswd.ldif

```

上面命令的输出应该与下面的图像相似：

*LDAP 配置*

接着从 `/etc/openldap/schema` 目录导入一个基本的 LDAP 定义：

```
# for def in cosine.ldif nis.ldif inetorgperson.ldif; do ldapadd -H ldapi:/// -f /etc/openldap/schema/$def; done

```

*LDAP 定义*

**6. 让 LDAP 在它的数据库中使用你的域名。**

以下面的内容创建另一个 LDIF 文件，我们称之为 `ldapdomain.ldif`， 然后酌情替换这个文件中的域名（在<ruby> 域名部分 <rp>  （ </rp> <rt>  Domain Component </rt> <rp>  ） </rp></ruby> dc=） 和密码：

```
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
  read by dn.base="cn=Manager,dc=mydomain,dc=com" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=mydomain,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=mydomain,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}PASSWORD

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by
  dn="cn=Manager,dc=mydomain,dc=com" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=Manager,dc=mydomain,dc=com" write by * read

```

接着使用下面的命令来加载：

```
# ldapmodify -H ldapi:/// -f ldapdomain.ldif

```

*LDAP 域名配置*

**7. 现在，该是添加一些条目到我们的 LDAP 目录的时候了。在下面的文件中，属性和键值由一个冒号`(:)` 所分隔，这个文件我们将命名为 `baseldapdomain.ldif`:**

```
dn: dc=mydomain,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: mydomain com
dc: mydomain

dn: cn=Manager,dc=mydomain,dc=com
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=mydomain,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=mydomain,dc=com
objectClass: organizationalUnit
ou: Group

```

添加条目到 LDAP 目录中：

```
# ldapadd -x -D cn=Manager,dc=mydomain,dc=com -W -f baseldapdomain.ldif

```

*添加 LDAP 域名，属性和键值*

**8. 创建一个名为 ldapuser 的 LDAP 用户(`adduser ldapuser`)，然后在`ldapgroup.ldif` 中为一个 LDAP 组创建定义。**

```
# adduser ldapuser
# vi ldapgroup.ldif

```

添加下面的内容：

```
dn: cn=Manager,ou=Group,dc=mydomain,dc=com
objectClass: top
objectClass: posixGroup
gidNumber: 1004

```

其中 gidNumber 是 ldapuser 在 `/etc/group` 中的 GID，然后加载这个文件：

```
# ldapadd -x -W -D "cn=Manager,dc=mydomain,dc=com" -f ldapgroup.ldif

```

**9. 为用户 ldapuser 添加一个带有定义的 LDIF 文件（`ldapuser.ldif`）：**

```
dn: uid=ldapuser,ou=People,dc=mydomain,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: ldapuser
uid: ldapuser
uidNumber: 1004
gidNumber: 1004
homeDirectory: /home/ldapuser
userPassword: {SSHA}fiN0YqzbDuDI0Fpqq9UudWmjZQY28S3M
loginShell: /bin/bash
gecos: ldapuser
shadowLastChange: 0
shadowMax: 0
shadowWarning: 0

```

并加载它：

```
# ldapadd -x -D cn=Manager,dc=mydomain,dc=com -W -f ldapuser.ldif

```

*LDAP 用户配置*

相似地，你可以删除你刚刚创建的用户条目：

```
# ldapdelete -x -W -D cn=Manager,dc=mydomain,dc=com "uid=ldapuser,ou=People,dc=mydomain,dc=com"

```

**10. 允许有关 ldap 的通信通过防火墙：**

```
# firewall-cmd --add-service=ldap

```

**11. 最后，但并非最不重要的是使用 LDAP 开启客户端的认证。**

为了在最后一步中对我们有所帮助，我们将使用 authconfig 工具（一个配置系统认证资源的界面）。

使用下面的命令，在通过 LDAP 服务器认证成功后，假如请求的用户的家目录不存在，则将会被创建：

```
# authconfig --enableldap --enableldapauth --ldapserver=rhel7.mydomain.com --ldapbasedn="dc=mydomain,dc=com" --enablemkhomedir --update

```

*LDAP 客户端认证*

### 总结

在这篇文章中，我们已经解释了如何利用一个 LDAP 服务器来设置基本的认证。若想对当前这个指南里描述的设置进行更深入的配置，请参考位于 RHEL 系统管理员指南里的 [第 13 章 – LDAP 的配置](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-Directory_Servers.html)，并特别注意使用 TLS 来进行安全设定。

请随意使用下面的评论框来留下你的提问。

---

via: <http://www.tecmint.com/setup-ldap-server-and-configure-client-authentication/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 内核 0.01 发布纪念日：协作的价值

Summary: Linux 社区通常对 Linux 的诞生日有两种看法：  8月25日是 Linus Torvalds 首次发布消息说他开始开发 Linux 的日期 10月5日则是第一个内核 0.01发布的日期  为了纪念1991年第一个 Linux 内核的发布，让我们来看看从第一个版本开始到现在发生了什么变化。   Linux 内核 0.01 只有 10239 行代码（来源：Wikipedia）。   发布于2015年7月的 4.1 版本，已经有了超过1900万行代码（来源： Phoronix）。   现在的 Linux 内核是已知最大的协作项目之一的成果。 根据今年二月发布的 Linux 开发报告《谁写的 Linux》的数据：   从10年前有记录起，

# Linux 内核 0.01 发布纪念日：协作的价值

Linux 社区通常对 Linux 的诞生日有两种看法：

* [8月25日是 Linus Torvalds 首次发布消息说他开始开发 Linux 的日期](/article-6092-1.html)
* **10月5日**则是第一个内核 [0.01](https://www.kernel.org/pub/linux/kernel/Historic/linux-0.01.tar.gz) 发布的日期

为了纪念1991年第一个 Linux 内核的发布，让我们来看看从第一个版本开始到现在发生了什么变化。

* Linux 内核 0.01 只有 10239 行代码（来源： [Wikipedia](https://en.wikipedia.org/wiki/Linux_kernel)）。
* 发布于2015年7月的 4.1 版本，已经有了超过1900万行代码（来源： [Phoronix](http://www.phoronix.com/scan.php?page=news_item&px=Linux-19.5M-Stats)）。

现在的 Linux 内核是已知最大的协作项目之一的成果。

根据今年二月发布的 Linux 开发报告《[谁写的 Linux](https://www.linuxfoundation.org/news-media/announcements/2015/02/linux-foundation-releases-linux-development-report)》的数据：

* 从10年前有记录起，来自超过 1200 家公司的近 12000 名开发者为 Linux 内核做出了贡献。
* Linux 开发的速度是无与伦比的。接纳到内核的更改数量是平均每小时 7.71 个，换句话说是，每天 185 个更改或每周 1300 个。

近年来，Linux 内核的飞速发展及其带来的创新鼓舞了更多人参与到其中，在适应了它的原则、做法和方法体系后，推动 Linux 成功地解决了一些当今最复杂的技术问题。

就在这周，Linux 基金会以其<ruby>   合作项目  <rp>  （ </rp> <rt>  Collaborative Projects </rt> <rp>  ） </rp></ruby>作为样本发布了[首份开源开发的价值评估报告](https://www.linuxfoundation.org/publications/linux-foundation/estimating-total-development-cost-linux-foundation-collaborative-projects)。报告的数据十分有趣，令人印象深刻，该报告表明 [Linux 基金会合作项目](http://collabprojects.linuxfoundation.org/)的综合价值超过了五亿美金 （[使用 David A. Wheeler 的模型](http://www.dwheeler.com/sloccount/sloccount.html)）。

据此报告：

* 在上个月，Linux 基金会合作项目已经有了一亿一千五百万行（115013302）源代码。
* 这些项目里包含1356名开发者花费了超过30年而重新创造的代码。
* 这些工作的经济总价值评估超过了五亿美金。

我们已经从 Linux 中学到了如此之多，没有什么能阻止我们继续获得更多。来和我们一起庆祝 Linux 的纪念日吧，请关注[Linux 基金会的 Twitter 消息](https://twitter.com/linuxfoundation)和我们下周在爱尔兰都柏林的举办的 [LinuxCon Europe](http://events.linuxfoundation.org/events/cloudopen-europe) 上的庆祝[活动](https://twitter.com/eventslf)吧。


RHCSA 系列（十五）： 虚拟化基础和使用 KVM 进行虚拟机管理

Summary: 假如你在词典中查一下单词 虚拟化（virtualize），你将会发现它的意思是 创造某些事物的一个虚拟物（而非真实的）。在计算机行业中，术语虚拟化（virtualization）指的是：在相同的物理（硬件）系统上，同时运行多个操作系统，且这几个系统相互隔离的可能性，而那个硬件在虚拟化架构中被称作宿主机（host）。  RHCSA 系列： 虚拟化基础和使用 KVM 进行虚拟机管理  Part 15 通过使用虚拟机监视器（也被称为虚拟机管理程序（hypervisor）），虚拟机（被称为 guest）由底层的硬件来供给虚拟资源（举几个例子来说，如 CPU，RAM，存储介质，网

感谢分享，顺便问下，能否在后面的内容里面把 Tecmint 里面 的 RHCE exam 内容翻译下吗？

mefirst_love [Internet Explorer 11.0|Windows 8.1]

有的。

没有找到在什么地方，能告诉下么？谢谢

mefirst_love [Microsoft Edge 12.10240|Windows 10]

啊哈，还没发呢。。我这就准备发了，一个系列。

# RHCSA 系列（十五）： 虚拟化基础和使用 KVM 进行虚拟机管理

假如你在词典中查一下单词 “<ruby> 虚拟化 <rp>  （ </rp> <rt>  virtualize </rt> <rp>  ） </rp></ruby>”，你将会发现它的意思是 “创造某些事物的一个虚拟物（而非真实的）”。在计算机行业中，术语<ruby> 虚拟化 <rp>  （ </rp> <rt>  virtualization </rt> <rp>  ） </rp></ruby>指的是：在相同的物理（硬件）系统上，同时运行多个操作系统，且这几个系统相互隔离的**可能性**，而那个硬件在虚拟化架构中被称作<ruby> 宿主机 <rp>  （ </rp> <rt>  host </rt> <rp>  ） </rp></ruby>。

*RHCSA 系列： 虚拟化基础和使用 KVM 进行虚拟机管理 – Part 15*

通过使用虚拟机监视器（也被称为<ruby> 虚拟机管理程序 <rp>  （ </rp> <rt>  hypervisor </rt> <rp>  ） </rp></ruby>），虚拟机（被称为 guest）由底层的硬件来供给虚拟资源（举几个例子来说，如 CPU，RAM，存储介质，网络接口等）。

考虑到这一点就可以清楚地看出，虚拟化的主要优点是节约成本（在设备和网络基础设施，及维护工作等方面）和显著地减少容纳所有必要硬件所需的物理空间。

由于这个简单的指南不能涵盖所有的虚拟化方法，我鼓励你参考在总结部分中列出的文档，以此对这个话题做更深入的了解。

请记住当前文章只是用于在 RHEL 7 中用命令行工具使用 [KVM](http://www.linux-kvm.org/page/Main_Page) (<ruby> Kernel-based Virtual Machine <rp>  （ </rp> <rt>  基于内核的虚拟机 </rt> <rp>  ） </rp></ruby>) 学习虚拟化基础知识的一个起点，而并不是对这个话题的深入探讨。

### 检查硬件要求并安装软件包

为了设置虚拟化，你的 CPU 必须能够支持它。你可以使用下面的命令来查看你的系统是否满足这个要求：

```
# grep -E 'svm|vmx' /proc/cpuinfo

```

在下面的截图中，我们可以看到当前的系统（带有一个 AMD 的微处理器）支持虚拟化，svm 字样的存在暗示了这一点。假如我们有一个 Intel 系列的处理器，我们将会看到上面命令的结果将会出现 vmx 字样。

*检查 KVM 支持*

另外，你需要在你宿主机的硬件（BIOS 或 UEFI）中开启虚拟化。

现在，安装必要的软件包：

* qemu-kvm 是一个开源的虚拟机程序，为 KVM 虚拟机监视器提供硬件仿真，而 qemu-img 则提供了一个操纵磁盘镜像的命令行工具。
* libvirt 包含与操作系统的虚拟化功能交互的工具。
* libvirt-python 包含一个模块，它允许用 Python 写的应用来使用由 libvirt 提供的接口。
* libguestfs-tools 包含各式各样的针对虚拟机的系统管理员命令行工具。
* virt-install 包含针对虚拟机管理的其他命令行工具。

命令如下：

```
# yum update && yum install qemu-kvm qemu-img libvirt libvirt-python libguestfs-tools virt-install

```

一旦安装完成，请确保你启动并开启了 libvirtd 服务：

```
# systemctl start libvirtd.service
# systemctl enable libvirtd.service

```

默认情况下，每个虚拟机将只能够与放在相同的物理服务器上的虚拟机以及宿主机自身通信。要使得虚拟机能够访问位于局域网或因特网中的其他机器，我们需要像下面这样在我们的宿主机上设置一个桥接接口（比如说 br0）：

1、 添加下面的一行到我们的 NIC 主配置中（类似 `/etc/sysconfig/network-scripts/ifcfg-enp0s3` 这样的文件）：

```
BRIDGE=br0

```

2、 使用下面的内容（注意，你可能需要更改 IP 地址，网关地址和 DNS 信息）为 br0 创建一个配置文件（`/etc/sysconfig/network-scripts/ifcfg-br0`）：

```
DEVICE=br0
TYPE=Bridge
BOOTPROTO=static
IPADDR=192.168.0.18
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
NM_CONTROLLED=no
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=br0
ONBOOT=yes
DNS1=8.8.8.8
DNS2=8.8.4.4

```

3、 最后在文件`/etc/sysctl.conf` 中设置：

```
net.ipv4.ip_forward = 1

```

来开启包转发并加载更改到当前的内核配置中：

```
# sysctl -p

```

注意，你可能还需要告诉 firewalld 让这类的流量应当被允许通过防火墙。假如你需要这样做，记住你可以参考这个系列的 [使用 firewalld 和 iptables 来控制网络流量](/article-6315-1.html)。

### 创建虚拟机镜像

默认情况下，虚拟机镜像将会被创建到 `/var/lib/libvirt/images` 中，且强烈建议你不要更改这个设定，除非你真的需要那么做且知道你在做什么，并能自己处理有关 SELinux 的设定（这个话题已经超出了本教程的讨论范畴，但你可以参考这个系列的第 13 部分 [使用 SELinux 来进行强制访问控制](/article-6339-1.html)，假如你想更新你的知识的话）。

这意味着你需要确保你在文件系统中分配了必要的空间来容纳你的虚拟机。

下面的命令将使用位于 `/home/gacanepa/ISOs`目录下的 rhel-server-7.0-x86\_64-dvd.iso 镜像文件和 br0 这个网桥来创建一个名为 `tecmint-virt01` 的虚拟机，它有一个虚拟 CPU，1 GB（=1024 MB）的 RAM，20 GB 的磁盘空间（由`/var/lib/libvirt/images/tecmint-virt01.img`所代表）：

```
# virt-install \
--network bridge=br0
--name tecmint-virt01 \
--ram=1024 \
--vcpus=1 \
--disk path=/var/lib/libvirt/images/tecmint-virt01.img,size=20 \
--graphics none \
--cdrom /home/gacanepa/ISOs/rhel-server-7.0-x86_64-dvd.iso
--extra-args="console=tty0 console=ttyS0,115200"

```

假如安装文件位于一个 HTTP 服务器上，而不是存储在你磁盘中的镜像中，你必须将上面的 `-cdrom` 替换为 `-location`，并明确地指出在线存储仓库的地址。

至于上面的 `–graphics none` 选项，它告诉安装程序只以文本模式执行安装过程。假如你使用一个 GUI 界面和一个 VNC 窗口来访问主虚拟机控制台，则可以省略这个选项。最后，使用 `–extra-args` 参数，我们将传递内核启动参数给安装程序，以此来设置一个串行的虚拟机控制台。

现在，所安装的虚拟机应当可以作为一个正常的（真实的）服务来运行了。假如没有，请查看上面列出的步骤。

### 管理虚拟机

作为一个系统管理员，还有一些典型的管理任务需要你在虚拟机上去完成。注：下面所有的命令都需要在你的宿主机上运行：

**1. 列出所有的虚拟机：**

```
# virsh list --all

```

你必须留意上面命令输出中的虚拟机 ID（尽管上面的命令还会返回虚拟机的名称和当前的状态），因为你需要它来执行有关某个虚拟机的大多数管理任务。

**2. 显示某个虚拟机的信息：**

```
# virsh dominfo [VM Id]

```

**3. 开启，重启或停止一个虚拟机操作系统：**

```
# virsh start | reboot | shutdown [VM Id]

```

**4. 假如网络无法连接且在宿主机上没有运行 X 服务器，可以使用下面的命令来访问虚拟机的串行控制台：**

```
# virsh console [VM Id]

```

**注**：这需要你添加一个串行控制台配置信息到 `/etc/grub.conf` 文件中（参考刚才创建虚拟机时传递给`-extra-args`选项的参数）。

**5. 修改分配的内存或虚拟 CPU：**

首先，关闭虚拟机：

```
# virsh shutdown [VM Id]

```

为 RAM 编辑虚拟机的配置：

```
# virsh edit [VM Id]

```

然后更改

```
<memory>[内存大小，注意不要加上方括号]</memory>

```

使用新的设定重启虚拟机：

```
# virsh create /etc/libvirt/qemu/tecmint-virt01.xml

```

最后，可以使用下面的命令来动态地改变内存的大小：

```
# virsh setmem [VM Id] [内存大小，这里没有括号]

```

对于 CPU，使用：

```
# virsh edit [VM Id]

```

然后更改

```
<cpu>[CPU 数目，这里没有括号]</cpu>

```

至于更深入的命令和细节，请参考 RHEL 5 虚拟化指南（这个指南尽管有些陈旧，但包括了用于管理虚拟机的 virsh 命令的详尽清单）的第 26 章里的表 26.1。

### 总结

在这篇文章中，我们涵盖了在 RHEL 7 中如何使用 KVM 和虚拟化的一些基本概念，这个话题是一个广泛且令人着迷的话题。并且我希望它能成为你在随后阅读官方的 [RHEL 虚拟化入门](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Virtualization_Getting_Started_Guide/index.html) 和 [RHEL 虚拟化部署和管理指南](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Virtualization_Deployment_and_Administration_Guide/index.html) ，探索更高级的主题时的起点教程，并给你带来帮助。

另外，为了分辨或拓展这里解释的某些概念，你还可以参考先前包含在 [KVM 系列](http://www.tecmint.com/install-and-configure-kvm-in-linux/) 中的文章。

---

via: <http://www.tecmint.com/kvm-virtualization-basics-and-guest-administration/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


看看新的 Ubuntu 15.10 默认壁纸

Summary: 全新的Ubuntu 15.10 Wily Werewolf默认壁纸已经亮相 乍一看你几乎无法发现与今天4月发布的Ubuntu 15.04中受到折纸启发的Suru设计有什么差别。但是仔细看你就会发现默认背景有一些细微差别。 其中一点是更淡，受到由左上角图片发出的橘黄色光的帮助。保持了角褶皱和色块，但是增加了块和矩形部分。 新的背景由Canonica设计团队的Alex Milazzo设计。  Ubuntu 15.10 默认桌面背景 为了凸显变化，这个是Ubuntu 15.04的默认壁纸作为比较：  Ubuntu 15.04 默认壁纸 下载Ubuntu 15.10 壁纸 如果你正运行的是Ubuntu 15.10 Wily Werewolf每日构建版

依然在使用14.04

路过帮顶

wqk317226700 [UC Browser 10.7|Android 4.4]

# 看看新的 Ubuntu 15.10 默认壁纸

**全新的Ubuntu 15.10 Wily Werewolf默认壁纸已经亮相**

乍一看你几乎无法发现与今天4月发布的Ubuntu 15.04中受到折纸启发的‘Suru’设计有什么差别。但是仔细看你就会发现默认背景有一些细微差别。

其中一点是更淡，受到由左上角图片发出的橘黄色光的帮助。保持了角褶皱和色块，但是增加了块和矩形部分。

新的背景由Canonica设计团队的Alex Milazzo设计。

*Ubuntu 15.10 默认桌面背景*

为了凸显变化，这个是Ubuntu 15.04的默认壁纸作为比较：

*Ubuntu 15.04 默认壁纸*

### 下载Ubuntu 15.10 壁纸

如果你正运行的是Ubuntu 15.10 Wily Werewolf每日构建版本，那么你无法看到这个默认壁纸：设计已经亮相但是还没有打包到Wily中。

你不必等到10月份来使用新的设计来作为你的桌面背景。你可以点击下面的按钮下载4096×2304高清壁纸。

* [下载Ubuntu 15.10新的默认壁纸](https://launchpadlibrarian.net/218258177/Wolf_Wallpaper_Desktop_4096x2304_Purple_PNG-24.png)

最后，如我们每次在有新壁纸时说的，你不必在意发布版品牌和设计细节。如果壁纸不合你的口味或者不想永远用它，轻易地就换掉，毕竟这不是Ubuntu Phone！

**你是新版本的粉丝么？在评论中让我们知道**

---

via: <http://www.omgubuntu.co.uk/2015/09/ubuntu-15-10-wily-werewolf-default-wallpaper>

作者：[Joey-Elijah Sneddon](https://plus.google.com/117485690627814051450/?rel=author) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


[新手技巧] 如何在Ubuntu中添加和删除书签

Summary: 这是一篇对完全是新手的一篇技巧，我将向你展示如何在Ubuntu文件管理器中添加书签。 现在如果你想知道为什么要这么做，答案很简单。它可以让你可以快速地在左边栏中访问。比如，我在Ubuntu中安装了Copy 云服务。它创建在/Home/Copy。先进入Home目录再进入Copy目录并不是很麻烦，但是我想要更快地访问它。因此我添加了一个书签这样我就可以直接从侧边栏访问了。 在Ubuntu中添加书签 打开Files。进入你想要保存快速访问的目录。你需要在标记书签的目录里面。 现在，你有两种方法： 方法1: 当你在Files（Ubuntu中的文件管理器）中时，查看顶

# [新手技巧] 如何在Ubuntu中添加和删除书签

这是一篇对完全是新手的一篇技巧，我将向你展示如何在Ubuntu文件管理器中添加书签。

现在如果你想知道为什么要这么做，答案很简单。它可以让你可以快速地在左边栏中访问。比如，我[在Ubuntu中安装了Copy 云服务](http://itsfoss.com/install-copy-in-ubuntu-14-04/)。它创建在/Home/Copy。先进入Home目录再进入Copy目录并不是很麻烦，但是我想要更快地访问它。因此我添加了一个书签这样我就可以直接从侧边栏访问了。

### 在Ubuntu中添加书签

打开Files。进入你想要保存快速访问的目录。你需要在标记书签的目录里面。

现在，你有两种方法：

#### 方法1:

当你在Files（Ubuntu中的文件管理器）中时，查看顶部菜单。你会看到书签按钮。点击它你会看到将当前路径保存为书签的选项。

#### 方法 2:

你可以直接按下Ctrl+D就可以将当前位置保存为书签。

如你所见，这里左边栏就有一个新添加的Copy目录：

### 管理书签

如果你不想要太多的书签或者你错误地添加了一个书签，你可以很简单地删除它。按下Ctrl+B查看所有的书签。现在选择想要删除的书签并点击删除。

这就是在Ubuntu中管理书签需要做的。我知道这对于大多数用户而言很简单，但是这也许多Ubuntu的新手而言或许还有用。

---

via: <http://itsfoss.com/add-remove-bookmarks-ubuntu/>

作者：[Abhishek](http://itsfoss.com/author/abhishek/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


5 个在 Linux 中管理文件类型和系统时间的有用命令

Summary: 对于想学习 Linux 的初学者来说要适应使用命令行或者终端可能非常困难。由于终端比图形用户界面程序更能帮助用户控制 Linux 系统，我们必须习惯在终端中运行命令。因此为了有效记忆 Linux 不同的命令，你应该每天使用终端并明白怎样将命令和不同选项以及参数一同使用。  在 Linux 中管理文件类型并设置时间 请先查看我们 Linux 小技巧系列之前的文章：  5 个有趣的 Linux 命令行技巧 给新手的 10 个有用 Linux 命令行技巧  在这篇文章中，我们打算看看终端中 5 个和文件以及时间相关的提示和技巧。 Linux 中的文件类型 在 Linux 中，一切

好！已收藏

# 5 个在 Linux 中管理文件类型和系统时间的有用命令

对于想学习 Linux 的初学者来说要适应使用命令行或者终端可能非常困难。由于终端比图形用户界面程序更能帮助用户控制 Linux 系统，我们必须习惯在终端中运行命令。因此为了有效记忆 Linux 不同的命令，你应该每天使用终端并明白怎样将命令和不同选项以及参数一同使用。

<img src="content_image/album_201510_08_082829ag3g3ajnm8ft2emz.jpg" alt="在 Linux 中管理文件类型和设置时间" title="在 Linux 中管理文件类型和设置时间">

*在 Linux 中管理文件类型和设置时间*

请先查看我们 Linux 小技巧系列之前的文章：

* [5 个有趣的 Linux 命令行技巧](/article-5485-1.html)
* [给新手的 10 个有用 Linux 命令行技巧](/article-6314-1.html)

在这篇文章中，我们打算看看终端中 5 个和文件以及时间相关的提示和技巧。

### Linux 中的文件类型

在 Linux 中，一切皆文件，你的设备、目录以及普通文件都认为是文件。

Linux 系统中文件有不同的类型：

* 普通文件：可能包含命令、文档、音频文件、视频、图像，归档文件等。
* 设备文件：系统用于访问你硬件组件。

这里有两种表示存储设备的设备文件：块文件，例如硬盘，它们以块读取数据；字符文件，以逐个字符读取数据。

* 硬链接和软链接：用于在 Linux 文件系统的任意地方访问文件。
* 命名管道和套接字：允许不同的进程之间进行交互。

#### 1. 用 ‘file’ 命令确定文件类型

你可以像下面这样使用 file 命令确定文件的类型。下面的截图显示了用 file 命令确定不同文件类型的例子。

```
tecmint@tecmint ~/Linux-Tricks $ dir
BACKUP                    master.zip
crossroads-stable.tar.gz          num.txt
EDWARD-MAYA-2011-2012-NEW-REMIX.mp3   reggea.xspf
Linux-Security-Optimization-Book.gif  tmp-link

tecmint@tecmint ~/Linux-Tricks $ file BACKUP/
BACKUP/: directory

tecmint@tecmint ~/Linux-Tricks $ file master.zip
master.zip: Zip archive data, at least v1.0 to extract

tecmint@tecmint ~/Linux-Tricks $ file crossroads-stable.tar.gz
crossroads-stable.tar.gz: gzip compressed data, from Unix, last modified: Tue Apr  5 15:15:20 2011

tecmint@tecmint ~/Linux-Tricks $ file Linux-Security-Optimization-Book.gif
Linux-Security-Optimization-Book.gif: GIF image data, version 89a, 200 x 259

tecmint@tecmint ~/Linux-Tricks $ file EDWARD-MAYA-2011-2012-NEW-REMIX.mp3
EDWARD-MAYA-2011-2012-NEW-REMIX.mp3: Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1, 192 kbps, 44.1 kHz, JntStereo

tecmint@tecmint ~/Linux-Tricks $ file /dev/sda1
/dev/sda1: block special

tecmint@tecmint ~/Linux-Tricks $ file /dev/tty1
/dev/tty1: character special

```

#### 2. 用 ‘ls’ 和 ‘dir’ 命令确定文件类型

确定文件类型的另一种方式是用 ls 和 [dir](http://www.tecmint.com/linux-dir-command-usage-with-examples/) 命令显示一长串结果。

用 ls -l 确定一个文件的类型。

当你查看文件权限时，第一个字符显示了文件类型，其它字符显示文件权限。

```
tecmint@tecmint ~/Linux-Tricks $ ls -l
total 6908
drwxr-xr-x 2 tecmint tecmint    4096 Sep  9 11:46 BACKUP
-rw-r--r-- 1 tecmint tecmint 1075620 Sep  9 11:47 crossroads-stable.tar.gz
-rwxr----- 1 tecmint tecmint 5916085 Sep  9 11:49 EDWARD-MAYA-2011-2012-NEW-REMIX.mp3
-rw-r--r-- 1 tecmint tecmint   42122 Sep  9 11:49 Linux-Security-Optimization-Book.gif
-rw-r--r-- 1 tecmint tecmint   17627 Sep  9 11:46 master.zip
-rw-r--r-- 1 tecmint tecmint       5 Sep  9 11:48 num.txt
-rw-r--r-- 1 tecmint tecmint       0 Sep  9 11:46 reggea.xspf
-rw-r--r-- 1 tecmint tecmint       5 Sep  9 11:47 tmp-link

```

使用 ls -l 确定块和字符文件

```
tecmint@tecmint ~/Linux-Tricks $ ls -l /dev/sda1
brw-rw---- 1 root disk 8, 1 Sep  9 10:53 /dev/sda1

tecmint@tecmint ~/Linux-Tricks $ ls -l /dev/tty1
crw-rw---- 1 root tty 4, 1 Sep  9 10:54 /dev/tty1

```

使用 dir -l 确定一个文件的类型。

```
tecmint@tecmint ~/Linux-Tricks $ dir -l
total 6908
drwxr-xr-x 2 tecmint tecmint    4096 Sep  9 11:46 BACKUP
-rw-r--r-- 1 tecmint tecmint 1075620 Sep  9 11:47 crossroads-stable.tar.gz
-rwxr----- 1 tecmint tecmint 5916085 Sep  9 11:49 EDWARD-MAYA-2011-2012-NEW-REMIX.mp3
-rw-r--r-- 1 tecmint tecmint   42122 Sep  9 11:49 Linux-Security-Optimization-Book.gif
-rw-r--r-- 1 tecmint tecmint   17627 Sep  9 11:46 master.zip
-rw-r--r-- 1 tecmint tecmint       5 Sep  9 11:48 num.txt
-rw-r--r-- 1 tecmint tecmint       0 Sep  9 11:46 reggea.xspf
-rw-r--r-- 1 tecmint tecmint       5 Sep  9 11:47 tmp-link

```

#### 3. 统计指定类型文件的数目

下面我们来看看在一个目录中用 ls，[grep](/article-2250-1.html) 和 [wc](http://www.tecmint.com/wc-command-examples/) 命令统计指定类型文件数目的技巧。命令之间的交互通过命名管道完成。

* grep – 用户根据给定模式或正则表达式进行搜索的命令。
* wc – 用于统计行、字和字符的命令。

**统计普通文件的数目**

在 Linux 中，普通文件用符号 `-` 表示。

```
tecmint@tecmint ~/Linux-Tricks $ ls -l | grep ^- | wc -l
7

```

**统计目录的数目**

在 Linux 中，目录用符号 `d` 表示。

```
tecmint@tecmint ~/Linux-Tricks $ ls -l | grep ^d | wc -l
1

```

**统计符号链接和硬链接的数目**

在 Linux 中，符号链接和硬链接用符号 `l` 表示。

```
tecmint@tecmint ~/Linux-Tricks $ ls -l | grep ^l | wc -l
0

```

**统计块文件和字符文件的数目**

在 Linux 中，块和字符文件用符号 `b` 和 `c` 表示。

```
tecmint@tecmint ~/Linux-Tricks $ ls -l /dev | grep ^b | wc -l
37
tecmint@tecmint ~/Linux-Tricks $ ls -l /dev | grep ^c | wc -l
159

```

#### 4. 在 Linux 系统中查找文件

下面我们来看看在 Linux 系统中查找文件一些命令，它们包括 locate、find、whatis 和 which 命令。

**用 locate 命令查找文件**

在下面的输出中，我想要定位系统中的 [Samba 服务器配置文件](http://www.tecmint.com/setup-samba-file-sharing-for-linux-windows-clients/)

```
tecmint@tecmint ~/Linux-Tricks $ locate samba.conf
/usr/lib/tmpfiles.d/samba.conf
/var/lib/dpkg/info/samba.conffiles

```

**用 find 命令查找文件**

想要学习如何在 Linux 中使用 find 命令，你可以阅读我们以下的文章，里面列出了 find 命令的 30 多个例子和使用方法。

* [Linux 中 35 个 ‘find’ 命令示例](http://www.tecmint.com/35-practical-examples-of-linux-find-command/)

**用 whatis 命令定位命令**

whatis 命令通常用于定位命令，它很特殊，因为它给出关于一个命令的信息，它还能查找配置文件和命令的帮助手册条目。

```
tecmint@tecmint ~/Linux-Tricks $ whatis bash
bash (1)             - GNU Bourne-Again SHell

tecmint@tecmint ~/Linux-Tricks $ whatis find
find (1)             - search for files in a directory hierarchy

tecmint@tecmint ~/Linux-Tricks $ whatis ls
ls (1)               - list directory contents

```

**用 which 命令定位命令**

which 命令用于定位文件系统中的命令。

```
tecmint@tecmint ~/Linux-Tricks $ which mkdir
/bin/mkdir

tecmint@tecmint ~/Linux-Tricks $ which bash
/bin/bash

tecmint@tecmint ~/Linux-Tricks $ which find
/usr/bin/find

tecmint@tecmint ~/Linux-Tricks $ $ which ls
/bin/ls

```

#### 5.处理 Linux 系统的时间

在联网环境中，保持你 Linux 系统时间准确是一个好的习惯。Linux 系统中有很多服务要求时间正确才能在联网条件下正常工作。

让我们来看看你可以用来管理你机器时间的命令。在 Linux 中，有两种方式管理时间：系统时间和硬件时间。

系统时间由系统时钟管理，硬件时间由硬件时钟管理。

要查看你的系统时间、日期和时区，像下面这样使用 date 命令。

```
tecmint@tecmint ~/Linux-Tricks $ date
Wed Sep  9 12:25:40 IST 2015

```

像下面这样用 date -s 或 date -set=“STRING” 设置系统时间。

```
tecmint@tecmint ~/Linux-Tricks $ sudo date -s "12:27:00"
Wed Sep  9 12:27:00 IST 2015

tecmint@tecmint ~/Linux-Tricks $ sudo date --set="12:27:00"
Wed Sep  9 12:27:00 IST 2015

```

你也可以像下面这样设置时间和日期。

```
tecmint@tecmint ~/Linux-Tricks $ sudo date 090912302015
Wed Sep  9 12:30:00 IST 2015

```

使用 cal 命令从日历中查看当前日期。

```
tecmint@tecmint ~/Linux-Tricks $ cal
   September 2015
Su Mo Tu We Th Fr Sa
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

```

使用 hwclock 命令查看硬件时钟时间。

```
tecmint@tecmint ~/Linux-Tricks $ sudo hwclock
Wednesday 09 September 2015 06:02:58 PM IST  -0.200081 seconds

```

要设置硬件时钟时间，像下面这样使用 hwclock –set –date=“STRING” 命令。

```
tecmint@tecmint ~/Linux-Tricks $ sudo hwclock --set --date="09/09/2015 12:33:00"

tecmint@tecmint ~/Linux-Tricks $ sudo hwclock
Wednesday 09 September 2015 12:33:11 PM IST  -0.891163 seconds

```

系统时间是由硬件时钟时间在启动时设置的，系统关闭时，硬件时间被重置为系统时间。

因此你查看系统时间和硬件时间时，它们是一样的，除非你更改了系统时间。当你的 CMOS 电量不足时，硬件时间可能不正确。

你也可以像下面这样使用硬件时钟的时间设置系统时间。

```
$ sudo hwclock --hctosys

```

也可以像下面这样用系统时钟时间设置硬件时钟时间。

```
$ sudo hwclock --systohc

```

要查看你的 Linux 系统已经运行了多长时间，可以使用 uptime 命令。

```
tecmint@tecmint ~/Linux-Tricks $ uptime
12:36:27 up  1:43,  2 users,  load average: 1.39, 1.34, 1.45

tecmint@tecmint ~/Linux-Tricks $ uptime -p
up 1 hour, 43 minutes

tecmint@tecmint ~/Linux-Tricks $ uptime -s
2015-09-09 10:52:47

```

### 总结

对于初学者来说理解 Linux 中的文件类型是一个好的尝试，同时时间管理也非常重要，尤其是在需要可靠有效地管理服务的服务器上。希望这篇指南能对你有所帮助。如果你有任何反馈，别忘了给我们写评论。和我们保持联系。

---

via: <http://www.tecmint.com/manage-file-types-and-set-system-time-in-linux/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[ictlyh](http://www.mutouxiaogui.cn/blog/) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


NGINX Plus 现在完全支持 HTTP/2

Summary: 早些时候，我们发布了支持 HTTP/2 协议的 NGINX Plus R7。作为 HTTP 协议的最新标准，HTTP/2 的设计为现在的 web 应用程序带来了更高的性能和安全性。（LCTT 译注： 开源版本的 NGINX 1.95 也支持 HTTP/2 了。） NGINX Plus 所实现的 HTTP/2 协议可与现有的网站和应用程序进行无缝衔接。只需要一点改变，不管用户选择什么样的浏览器，NGINX Plus 都能为用户同时提供 HTTP/1.x 与HTTP/2 的最佳体验。 要支持 HTTP/2 仅需通过可选的 nginx‑plus‑http2 软件包。nginx‑plus 和 nginx‑plus‑extras 软件包支持 SPDY 协议，目前推荐用于生产

# NGINX Plus 现在完全支持 HTTP/2

早些时候，我们发布了支持 HTTP/2 协议的 [NGINX Plus R7](https://www.nginx.com/blog/nginx-plus-r7-released/)。作为 HTTP 协议的最新标准，HTTP/2 的设计为现在的 web 应用程序带来了更高的性能和安全性。（LCTT 译注： [开源版本的 NGINX 1.95 也支持 HTTP/2 了](http://mailman.nginx.org/pipermail/nginx-announce/2015/000162.html)。）

NGINX Plus 所实现的 HTTP/2 协议可与现有的网站和应用程序进行无缝衔接。只需要一点改变，不管用户选择什么样的浏览器，NGINX Plus 都能为用户同时提供 HTTP/1.x 与HTTP/2 的最佳体验。

要支持 HTTP/2 仅需通过可选的 **nginx‑plus‑http2** 软件包。**nginx‑plus** 和 **nginx‑plus‑extras** 软件包支持 SPDY 协议，目前推荐用于生产站点，因为其被大多数浏览器所支持并且代码也是相当成熟了。

### 为什么要使用 HTTP/2？

HTTP/2 使数据传输更高效，对你的应用程序更安全。 HTTP/2 相比于 HTTP/1.x 有五个提高性能特点：

* **完全复用** – 在一个保持激活（keepalive）的连接上，HTTP/1.1 强制按严格的顺序来处理请求。一个请求必须在下一个请求开始前结束。 HTTP/2 消除了这一要求，允许并行和乱序来处理请求。
* **单一，持久连接** – 由于 HTTP/2 允许请求完全复用，所以可以通过单一连接并行下载网页上的所有对象。在 HTTP/1.x 中，使用多个连接来并行下载资源，从而导致使用底层 TCP 协议效率很低。
* **二进制编码** – Header 信息使用紧凑的二进制格式发送，而不是纯文本格式，节省了传输字节。
* **Header 压缩** – Headers 使用专用的 HPACK 压缩算法来进行压缩，这进一步降低数据通过网络传输的字节。
* **SSL/TLS 加密** – 在 HTTP/2 中，强制使用 SSL/TLS。在 [RFC](https://tools.ietf.org/html/rfc7540) 中并没有强制，其允许纯文本的 HTTP/2，但是当前所有实现 HTTP/2的 Web 浏览器都只支持加密。 SSL/TLS 可以使你的网站更安全，并且使用 HTTP/2 各项性能会有提升，加密和解密过程的性能损失就减少了。

要了解更多关于 HTTP/2:

* 请阅读我们的 [白皮书](https://www.nginx.com/wp-content/uploads/2015/09/NGINX_HTTP2_White_Paper_v4.pdf)，它涵盖了你需要了解HTTP/2 的一切。
* 下载由 Google 的 Ilya Grigorik 编写的 [特别版的高性能浏览器网络电子书](https://www.nginx.com/http2-ebook/) （ LCTT 译注：涵盖 HTTP/2 的部分）。

### NGINX Plus 如何实现 HTTP/2

我们的 HTTP/2 实现是基于 SPDY 支持的，它已经被广泛部署（使用了 NGINX 或 NGINX Plus 的网站近 75％ 都使用了 SPDY）。使用 NGINX Plus 部署 HTTP/2 时，几乎不会改变你应用程序的配置。本节将讨论 NGINX Plus如何实现对 HTTP/2 的支持。

#### 一个 HTTP/2 网关

NGINX Plus 作为一个 HTTP/2 网关。它与支持 HTTP/2 的客户端 Web 浏览器用 HTTP/2 通讯，而转换 HTTP/2 请求给后端服务器通信时使用 HTTP/1.x（或者 FastCGI, SCGI, uWSGI, 等等. – 取决于你目前正在使用的协议）。

#### 向后兼容性

在一段时间内，你需要同时支持 HTTP/2 和 HTTP/1.x。在撰写本文时，超过50％的用户使用的 Web 浏览器已经[支持 HTTP/2](http://caniuse.com/#feat=http2)，但这也意味着近50％的人还没有使用。

为了同时支持 HTTP/1.x 和 HTTP/2，NGINX Plus 实现了 TLS 上的 Next Protocol Negotiation (NPN)扩展。当 Web 浏览器连接到服务器时，其将所支持的协议列表发送到服务器端。如果浏览器支持的协议列表中包括 h2 - 即 HTTP/2，NGINX Plus 将使用 HTTP/2 连接到浏览器。如果浏览器不支持 NPN 或在发送支持的协议列表中没有 h2，NGINX Plus 将继续回落到 HTTP/1.x。

### 转向 HTTP/2

NGINX 公司会尽可能帮助大家无缝过渡到使用 HTTP/2。本节介绍了通过对你应用进行改变来启用对 HTTP/2 支持，其中只需对 NGINX Plus 配置进行几个变化。

#### 前提条件

使用 **nginx‑plus‑http2** 软件包升级到 NGINX Plus R7。注意现在还没有支持 HTTP/2 版本的 **nginx‑plus‑extras** 软件包。

#### 重定向所有流量到 SSL/TLS

如果你的应用尚未使用 SSL/TLS 加密，现在启用它正是一个好的时机。加密你的应用程序可以保护你免受间谍以及来自其他中间人的攻击。一些搜索引擎甚至在搜索结果中对加密站点[提高排名](http://googlewebmastercentral.blogspot.co.uk/2014/08/https-as-ranking-signal.html)。下面的配置块重定向所有的普通 HTTP 请求到该网站的加密版本。

```
server {
    listen 80;
    location / {
        return 301 https://$host$request_uri;
    }
}

```

#### 启用 HTTP/2

要启用对 HTTP/2 的支持，只需将 http2 参数添加到所有的 [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) 指令中，也要包括 SSL 参数，因为浏览器不支持不加密的 HTTP/2 请求。

```
server {
    listen 443 ssl http2 default_server;

    ssl_certificate     server.crt;
    ssl_certificate_key server.key;
    …
}

```

如果有必要，重启 NGINX Plus，例如通过运行 `nginx -s reload` 命令。要验证 HTTP/2 是否正常工作，你可以在 [Google Chrome](https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=en) 和 [Firefox](https://addons.mozilla.org/en-us/firefox/addon/spdy-indicator/) 中使用 “HTTP/2 and SPDY indicator” 插件来检查。

### 注意事项

* 在安装 **nginx‑plus‑http2** 包之前, 你必须删除配置文件中所有 listen 指令后的 SPDY 参数（使用 http2 和 ssl 参数来替换它以启用对 HTTP/2 的支持）。使用这个包后，如果 listen 指令后有 spdy 参数，NGINX Plus 将无法启动。
* 如果你在 NGINX Plus 前端使用了 Web 应用防火墙（WAF），请确保它能够解析 HTTP/2，或者把它移到 NGINX Plus 后面。
* 此版本不支持在 HTTP/2 RFC 中定义的 “Server Push” 特性。 NGINX Plus 以后的版本可能会支持它。
* NGINX Plus R7 同时支持 SPDY 和 HTTP/2（LCTT 译注：但是你只能同时使用其中一种）。在以后的版本中，我们将弃用对 SPDY 的支持。谷歌在2016年初将 [弃用 SPDY](http://blog.chromium.org/2015/02/hello-http2-goodbye-spdy-http-is_9.html)，因此同时支持这两种协议也非必要。
* 如果 [ssl\_prefer\_server\_ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers) 设置为 on 或者使用了定义在 [Appendix A: TLS 1.2 Ciper Suite Black List](https://tools.ietf.org/html/rfc7540#appendix-A) 中的 [ssl\_ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers) 列表时，浏览器会出现 handshake-errors 而无法正常工作。详细内容请参阅 [section 9.2.2 of the HTTP/2 RFC](https://tools.ietf.org/html/rfc7540#section-9.2.2)。

### 特别感谢

NGINX 公司要感谢 [Dropbox](http://dropbox.com/) 和 [Automattic](http://automattic.com/)，他们是我们软件的重度使用者，并帮助我们实现 HTTP/2。他们的贡献帮助我们加速完成这个软件，我们希望你也能支持他们。

---

via: <https://www.nginx.com/blog/http2-r7/>

作者：[Faisal Memon](https://www.nginx.com/blog/author/fmemon/) 译者：[strugglingyouth](https://github.com/strugglingyouth) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出