RHCSA 系列（二）: 如何进行文件和目录管理

Summary: 在本篇中，我们将回顾一些系统管理员日常任务需要的技能。  RHCSA： 运行文件以及进行文件夹管理 - 第二部分 创建、删除、复制和移动文件及目录 文件和目录管理是每一个系统管理员都应该掌握的必备技能。它包括了从头开始的创建、删除文本文件（每个程序的核心配置）以及目录（你用来组织文件和其它目录），以及识别已有文件的类型。 touch 命令 不仅仅能用来创建空文件，还能用来更新已有文件的访问时间和修改时间。  touch 命令示例 你可以使用 file 来判断一个文件的类型 (在你用文本编辑器编辑之前，判断类型将会更方便编辑)。  file

还是这篇比较好

把英文版全能翻译到这个地步，不错，辛苦了

mefirst_love [Internet Explorer 11.0|Windows 8.1]

例6：归档时同时保存原始权限和所有权

# tar cJf ApacheLogs-$(date +%Y%m%d).tar.xz /var/log/httpd/* --same-permissions --same-owner

这个好像写错了 应该使用p tar cpf ……

-p 参数相当于—same-permissions and —same-owner 。这里的代码高亮错误可能让你误会了。

汗 后面的我以为是注释呢……

# RHCSA 系列（二）: 如何进行文件和目录管理

在本篇中，我们将回顾一些系统管理员日常任务需要的技能。

*RHCSA： 运行文件以及进行文件夹管理 - 第二部分*

### 创建、删除、复制和移动文件及目录

文件和目录管理是每一个系统管理员都应该掌握的必备技能。它包括了从头开始的创建、删除文本文件（每个程序的核心配置）以及目录（你用来组织文件和其它目录），以及识别已有文件的类型。

[`touch` 命令](/article-2740-1.html) 不仅仅能用来创建空文件，还能用来更新已有文件的访问时间和修改时间。

*touch 命令示例*

你可以使用 `file [filename]`来判断一个文件的类型 (在你用文本编辑器编辑之前，判断类型将会更方便编辑)。

*file 命令示例*

使用`rm [filename]` 可以删除文件。

*rm 命令示例*

对于目录，你可以使用`mkdir [directory]`在已经存在的路径中创建目录，或者使用 `mkdir -p [/full/path/to/directory]`带全路径创建文件夹。

*mkdir 命令示例*

当你想要去删除目录时，在你使用`rmdir [directory]` 前，你需要先确保目录是空的，或者使用更加强力的命令(小心使用它！)`rm -rf [directory]`。后者会强制删除`[directory]`以及它的内容，所以使用这个命令存在一定的风险。

### 输入输出重定向以及管道

命令行环境提供了两个非常有用的功能：允许重定向命令的输入和输出为另一个文件，以及发送命令的输出到另一个命令，这分别称为重定向和管道。

为了理解这两个重要概念，我们首先需要理解三个最重要的字符输入输出流类型，以 \*nix 的话来说，它们实际上是特殊的文件。

* 标准输入 (即 stdin)，默认连接到键盘。 换句话说，键盘是输入命令到命令行的标准输入设备。
* 标准输出 (即 stdout)，默认连接到屏幕。 找个设备“接受”命令的输出，并展示到屏幕上。
* 标准错误 (即 stderr)，默认是命令的状态消息出现的地方，它也是屏幕。

在下面的例子中，`ls /var`的结果被发送到stdout(屏幕展示)，ls /tecmint 的结果也一样。但在后一种情况下，它显示在标准错误输出上。

*输入和输出命令实例*

为了更容易识别这些特殊文件，每个文件都被分配有一个文件描述符，这是用于访问它们的抽象标识。主要要理解的是，这些文件就像其它的一样，可以被重定向。这就意味着你可以从一个文件或脚本中捕获输出，并将它传送到另一个文件、命令或脚本中。这样你就可以在磁盘上存储命令的输出结果，用于稍后的分析。

要重定向 stdin (fd 0)、 stdout (fd 1) 或 stderr (fd 2)，可以使用如下操作符。

|  |  |
| --- | --- |
| **转向操作** | **效果** |
| **>** | 重定向标准输出到一个文件。如果目标文件存在，内容就会被重写。 |
| **>>** | 添加标准输出到文件尾部。 |
| **2>** | 重定向标准错误输出到一个文件。如果目标文件存在，内容就会被重写。 |
| **2>>** | 添加标准错误输出到文件尾部。 |
| **&>** | 重定向标准错误和标准输出到一个文件。如果目标文件存在，内容就会被重写。 |
| **<** | 使用特定的文件做标准输入。 |
| **<>** | 使用特定的文件做标准输入和标准输出。 |

与重定向相比，管道是通过在命令后和另外一个命令前之间添加一个竖杠`(|)`。

记得:

* *重定向*是用来定向命令的输出到一个文件，或把一个文件发送作为到一个命令的输入。
* *管道*是用来将命令的输出转发到另一个命令作为其输入。

#### 重定向和管道的使用实例

**例1：将一个命令的输出到文件**

有些时候，你需要遍历一个文件列表。要做到这样，你可以先将该列表保存到文件中，然后再按行读取该文件。虽然你可以直接遍历ls的输出，不过这个例子是用来说明重定向。

```
# ls -1 /var/mail > mail.txt

```

*将一个命令的输出重定向到文件*

**例2：重定向stdout和stderr到/dev/null**

如果不想让标准输出和标准错误展示在屏幕上，我们可以把这两个文件描述符重定向到 `/dev/null`。请注意对于同样的命令，重定向是如何改变了输出。

```
# ls /var /tecmint
# ls /var/ /tecmint &> /dev/null

```

*重定向stdout和stderr到/dev/null*

**例3：使用一个文件作为命令的输入**

[cat 命令](http://www.tecmint.com/13-basic-cat-command-examples-in-linux/)的经典用法如下

```
# cat [file(s)]

```

您还可以使用正确的重定向操作符发送一个文件作为输入。

```
# cat < mail.txt

```

*cat 命令实例*

**例4：发送一个命令的输出作为另一个命令的输入**

如果你有一个较大的目录或进程列表，并且想快速定位，你或许需要将列表通过管道传送给grep。

接下来我们会在下面的命令中使用管道，第一个管道是查找所需的关键词，第二个管道是除去产生的 `grep command`。这个例子列举了所有与apache用户有关的进程：

```
# ps -ef | grep apache | grep -v grep

```

*发送一个命令的输出作为另一个命令的输入*

### 归档，压缩，解包，解压文件

如果你需要传输、备份、或者通过邮件发送一组文件，你可以使用一个存档（或打包）工具，如 [tar](http://www.tecmint.com/18-tar-command-examples-in-linux/)，通常与gzip，bzip2，或 xz 等压缩工具配合使用。

您选择的压缩工具每一个都有自己不同的压缩速度和压缩率。这三种压缩工具，gzip是最古老和可以较小压缩的工具，bzip2提供经过改进的压缩，以及xz是最新的而且压缩最大。通常情况下，使用这些压缩工具压缩的文件的扩展名依次是.gz、.bz2或.xz。

|  |  |  |
| --- | --- | --- |
| **命令** | **缩写** | **描述** |
|  –create | c | 创建一个tar归档 |
|  –concatenate | A | 添加tar归档到另外一个归档中 |
|  –append | r | 添加非tar归档到另外一个归档中 |
|  –update | u | 添加比归档中的文件更新的文件 |
|  –diff or –compare | d | 将归档中的文件和硬盘的文件进行对比 |
|  –list | t | 列举一个tar压缩包的内容 |
|  –extract or –get | x | 从归档中提取文件 |

|  |  |  |
| --- | --- | --- |
| **操作参数** | **缩写** | **描述** |
| —directory dir |  C | 在执行操作前更改目录 |
| —same-permissions and —same-owner |  p | 分别保留权限和所有者信息 |
|  –verbose |  v | 列举所有读取或提取的文件，如果和 --list 参数一起使用，也会显示文件的大小、所有权和时间戳 |
| —exclude file |  — | 从存档中排除文件。在这种情况下，文件可以是一个实际的文件或匹配模式。 |
| —gzip or —gunzip |  z | 使用gzip压缩归档 |
|  –bzip2 |  j | 使用bzip2压缩归档 |
|  –xz |  J | 使用xz压缩归档 |

**例5：创建一个tar文件，然后使用三种压缩工具压缩**

在决定使用这个还是那个工具之前，您可能想比较每个工具的压缩效率。请注意压缩小文件或几个文件，结果可能不会有太大的差异，但可能会给你看出它们的差异。

```
# tar cf ApacheLogs-$(date +%Y%m%d).tar /var/log/httpd/*        # Create an ordinary tarball
# tar czf ApacheLogs-$(date +%Y%m%d).tar.gz /var/log/httpd/*    # Create a tarball and compress with gzip
# tar cjf ApacheLogs-$(date +%Y%m%d).tar.bz2 /var/log/httpd/*   # Create a tarball and compress with bzip2
# tar cJf ApacheLogs-$(date +%Y%m%d).tar.xz /var/log/httpd/*    # Create a tarball and compress with xz

```

*tar 命令实例*

**例6：归档时同时保存原始权限和所有权**

如果你正在从用户的主目录创建备份，你需要要存储的个人文件与原始权限和所有权，而不是通过改变它们的用户帐户或守护进程来执行备份。下面的命令可以在归档时保留文件属性。

```
# tar cJf ApacheLogs-$(date +%Y%m%d).tar.xz /var/log/httpd/* --same-permissions --same-owner

```

### 创建软连接和硬链接

在Linux中，有2种类型的链接文件：硬链接和软（也称为符号）链接。因为硬链接文件只是现存文件的另一个名字，使用相同的 inode 号，它指向实际的数据；而符号链接只是指向的文件名。

此外，硬链接不占用磁盘上的空间，而符号链接则占用少量的空间来存储的链接本身的文本。硬链接的缺点就是要求它们必须在同一个文件系统内，因为 inode 在一个文件系统内是唯一的。而符号链接没有这个限制，它们通过文件名而不是 inode 指向其它文件或目录，所以可以跨文件系统。

创建链接的基本语法看起来是相似的：

```
# ln TARGET LINK_NAME               #从LINK_NAME到Target的硬链接
# ln -s TARGET LINK_NAME            #从LINK_NAME到Target的软链接

```

**例7：创建硬链接和软链接**

没有更好的方式来形象的说明一个文件和一个指向它的硬链接或符号链接的关系，而不是创建这些链接。在下面的截图中你会看到文件和指向它的硬链接共享相同的inode，都是使用了相同的466个字节的磁盘。

另一方面，在别的磁盘创建一个硬链接将占用5个字节，这并不是说你将耗尽存储容量，而是这个例子足以说明一个硬链接和软链接之间的区别。

*软连接和硬链接之间的不同*

在Linux系统上符号链接的典型用法是指向一个带版本的文件。假设有几个程序需要访问文件fooX.Y，但麻烦是版本经常变化（像图书馆一样）。每次版本更新时我们都需要更新指向 fooX.Y 的单一引用，而更安全、更快捷的方式是，我们可以让程序寻找名为 foo 的符号链接，它实际上指向 fooX.Y。

这样的话，当你的X和Y发生变化后，你只需更新符号链接 foo 到新的目标文件，而不用跟踪每个对目标文件的使用并更新。

### 总结

在这篇文章中，我们回顾了一些基本的文件和目录管理技能，这是每个系统管理员的工具集的一部分。请确保阅读了本系列的其它部分，并将这些主题与本教程所涵盖的内容相结合。

如果你有任何问题或意见，请随时告诉我们。我们总是很高兴从读者那获取反馈.

---

via: <http://www.tecmint.com/file-and-directory-management-in-linux/>

作者：[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 新手应该知道的 26 个命令

Summary: 当你进入了 Linux 的世界，在下载、安装了某个 Linux 发行版，体验了 Linux 桌面并安装了一些你喜爱和需要的软件之后，应该去了解下 Linux 真正的魅力所在：命令行。每一个 Linux 命令其实就是一个程序，借助这些命令，我们可以办到非常多的事情。下面将会为大家介绍一下几个常用的命令。  如何寻求帮助？ 在 Linux 下遇到问题，最重要的是要自己寻求帮助，下面是三种寻求帮助的方法。 man man是 Linux 的帮助手册，即manual。因为大多数程序都会自带手册，所以可以通过man命令获取帮助。执行以后，在man page页面中按q退出。 获取ls的帮

got it

学习了！

unbuntu15.0.4输入2个tab 无法查看所有命令，怎么弄？

nano好用吗？

楼主用的什么工具  北京字体都很喜欢

nano 和 vim哪个好用？

noreliang [Internet Explorer 11.0|Windows 8.1]

vim

26个基础命令就像26个英文字母一样，虽说依然不能熟练每一个命令，但是基础是最重要的

showtime1990 [Internet Explorer 11.0|Windows 7]

一句特别喜欢的话：基础不牢，地动山摇

学习学习！~

linux boot-shell-后面的各种软件。。不熟悉shell就是不懂linux，当然现在的用户群已经很多可以不懂linux，只操作用户软件，毕竟不懂windows内核的人一样用着windows用户软件

学习学习！~

楼主用的是linux系统什么版本？？求这个版本或者上面的工具？？

来自北京的 Internet Explorer 11.0|Windows 8.1 用户

arch

在sudo /etc/vi/vimrc<br />
添加行tab=2

路过~~~

说真的，入门用什么版本的比较好呢，对于我这种英文基础几乎为零的渣渣

那就用国内的发行版，比如深度 Linux

我也是英文基础几乎为零，如果懂这些可以去告诉更多中国人民，好玩就好

最后几个有几个没有用过，哈哈，好用

vim

感觉不如 vim 好用些

感觉 都不错 VIM要输入路径 nano 直接输入名字 如果能记住文件名  nano 方便  不记得 那么只能 VIM  对吧？ (⊙v⊙)

好几年没用了，又重新学习，拿走了

linda [Internet Explorer 8.0|Windows XP]

挺不错的

应该是vim吧。

rm: cannot remove `new': No such file or directory

来自福建福州的 Microsoft Edge 13.10586|Windows 10 用户

新手，收藏了！！！感谢楼主的热心分享

tangzhe1994 [Microsoft Edge 13.10586|Windows 10]

哎哟，不错哦！

好东西就要学习了！

说明你删除的这个new不存在啊

这个毫无疑问是"vim"，vim是完全基于Unix的vi编辑器升级而来的，Unix系系统都会自带vi，新手用户熟用vim是非常好的习惯，因为一旦遇到纯内网系统，与vim几乎一致的vi可以让你很快的上手，反而nano等其他编辑器，就会感到很无奈了，毕竟只有少数系统默认自带nano等编辑器！【当然，nano比vim更加容易上手，nano命令简单好用，新手初次接触的是nano会觉得比较好用，单个人还是建议熟练使用vim比较好！】

很详细很友好赞一个

有没有优化终端界面的工具

chown 命令中

# chmod +x filename        ### 为 user ，group ，others 添加执行权限

上面??这个只是针对 user 权限吧？

# 新手指南： Linux 新手应该知道的 26 个命令

当你进入了 Linux 的世界，在[下载](/article-4130-1.html)、[安装](/article-5893-1.html) 了某个 [Linux 发行版](https://linux.cn/share/distro/)，体验了 Linux 桌面并安装了一些你喜爱和需要的[软件](/article-6042-1.html)之后，应该去了解下 Linux 真正的魅力所在：**命令行**。每一个 Linux 命令其实就是一个程序，借助这些命令，我们可以办到非常多的事情。下面将会为大家介绍一下几个常用的命令。

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

### 如何寻求帮助？

在 Linux 下遇到问题，**最重要的是要自己寻求帮助**，下面是三种寻求帮助的方法。

#### man

`man` 是 Linux 的帮助手册，即 `manual` 。因为大多数程序都会自带手册，所以可以通过 `man` 命令获取帮助。执行以后，在 **man page** 页面中按 `q` 退出。

获取 `ls` 的帮助

```
$ man ls
```

查看有多少（针对不同方面的）同名的手册

```
$ man -f ls
ls (1)               - list directory contents
ls (1p)              - list directory contents
```

查看特定的手册

```
$ man 1p ls
```

#### info

与 `man` 不同的是，可以像浏览网页一样在各个节点中跳转。

从文档首页开始浏览

```
$ info
```

获取特定程序的帮助

```
$ info program
```

#### help

除了上面的两种方法外，还有一种简单使用的方法，那就是 `--help` 参数，一般程序都会有这个参数，会输出最简单有用的介绍。

```
$ man --help       ### 获取 man 的帮助
$ info --help      ### 获取 info 的帮助
$ ls --help        ### 获取 ls 的帮助
```

### 如何简单操作？

在 `Terminal（终端）` 中，有许多操作技巧，这里就介绍几个简单的。

#### 光标

* up(方向键上) 可以调出输入历史执行记录，快速执行命令
* down(方向键下) 配合 up 选择历史执行记录
* Home 移动光标到本行开头
* End 移动光标到本行结尾
* PgUp 向上翻页
* PaDN 向下翻页
* ctrl + c 终止当前程序

#### Tab 补全

`Tab` 补全是非常有用的一个功能，可以用来自动补全命令或文件名，省时准确。

* 未输入状态下连按**两次** `Tab` 列出所有可用命令
* 已输入部分命令名或文件名，按 `Tab` 进行自动补全，多用你就肯定会喜欢的了。

### 常用命令

以下命令按照通常的使用频度排列。

#### cd

`cd` 是打开某个路径的命令，也就是打开某个文件夹，并跳转到该处。

```
$ cd path      ### path 为你要打开的路径。
```

其中 path 有绝对路径和相对路径之分，绝对路径强调从 `/` 起，一直到所在路径。相对路径则相对于当前路径来说，假设当前家目录有`etc` 文件夹（绝对路径应为 `/home/username/etc`），如果直接 `cd etc` 则进入此文件夹，但若是 `cd /etc/` 则是进入系统 `etc` ，多琢磨一下就可以理解了。另外在 Linux 中， `.` 代表当前目录， `..` 代表上级目录，因此返回上级目录可以 `cd ..` 。

#### ls

`ls` 即 **list** ，列出文件。

```
$ ls       ### 仅列出当前目录可见文件
$ ls -l    ### 列出当前目录可见文件详细信息
$ ls -hl   ### 列出详细信息并以可读大小显示文件大小
$ ls -al   ### 列出所有文件（包括隐藏）的详细信息
```

**注意**： Linux 中 以 `.` 开头的文件或文件夹均为隐藏文件或隐藏文件夹。

#### pwd

`pwd` 用于返回当前工作目录的名字，为绝对路径名。

```
$ pwd
/home
```

#### mkdir

`mkdir` 用于新建文件夹。

```
$ mkdir folder
$ mkdir -p folder/subfolder    ### -p 参数为当父目录存在时忽略，若不存在则建立，用此参数可建立多级文件夹
```

#### rm

`rm` 即 **remove** ，删除文件。

```
$ rm filename      ### 删除 filename
$ rm -i filename   ### 删除 filename 前提示，若多个文件则每次提示
$ rm -rf folder/subfolder/  ### 递归删除 subfolder 下所有文件及文件夹，包括 subfolder 自身
$ rm -d folder     ###  删除空文件夹
```

#### cp

`cp` 即 **copy** ，复制文件。

```
$ cp source dest            ### 将 source 复制到 dest
$ cp folder/*  dest         ### 将 folder 下所有文件(不含子文件夹中的文件)复制到 dest
$ cp -r folder  dest        ### 将 folder 下所有文件（包含子文件夹中的所有文件）复制到 dest
```

#### mv

`mv` 即 **move** ，移动文件。

```
$ mv source  folder        ### 将 source 移动到 folder 下，完成后则为  folder/source
$ mv -i source folder      ### 在移动时，若文件已存在则提示 **是否覆盖**
$ mv source dest           ### 在 dest 不为目录的前提下，重命名 source 为 dest
```

#### cat

`cat` 用于输出文件内容到 Terminal 。

```
$ cat /etc/locale.gen     ### 输出 locale.gen 的内容
$ cat -n /etc/locale.gen  ### 输出 locale.gen 的内容并显示行号
```

#### more

`more` 与 `cat` 相似，都可以查看文件内容，所不同的是，当一个文档太长时， `cat` 只能展示最后布满屏幕的内容，前面的内容是不可见的。这时候可用 `more` 逐行显示内容。

```
$ more /etc/locale.gen
$ more +100 /etc/locale.gen       ### 从 100 行开始显示
```

#### less

`less` 与 `more` 相似，不过 `less` 支持上下滚动查看内容，而 `more` 只支持逐行显示。

```
$ less /etc/locale.gen
$ less +100 /etc/locale.gen
```

#### nano

`nano` 是一个简单实用的文本编辑器，使用简单。

```
$ nano  filename       ### 编辑 filename 文件，若文件不存在，则新打开一个文件，若退出时保存，则创建该文件
```

编辑完后，`ctrl + X` 提示是否保存，按 `y` 确定保存即可。

**注意**：在使用过程中可用 `ctrl + G` 获取帮助。

#### reboot

`reboot` 为重启命令。

```
# reboot         ### '$' 和 '#' 的区别在于 '$' 普通用户即可执行
                 ### 而 '#' 为 root 用户才可执行，或普通用户使用 'sudo'
```

#### poweroff

`poweroff` 为关机命令。

```
# poweroff  ### 马上关机
```

#### ping

`ping` 主要用于测试网络连通，通过对目标机器发送数据包来测试两台主机是否连通，及延时情况。

```
$ ping locez.com    ### 通过域名 ping，若 DNS 未设置好，可能无法 ping 通
$ ping linux.cn
PING linux.cn (211.157.2.94) 56(84) bytes of data.
64 bytes from 211.157.2.94.static.in-addr.arpa (211.157.2.94): icmp_seq=1 ttl=53 time=41.5 ms
64 bytes from 211.157.2.94.static.in-addr.arpa (211.157.2.94): icmp_seq=2 ttl=53 time=40.4 ms
64 bytes from 211.157.2.94.static.in-addr.arpa (211.157.2.94): icmp_seq=3 ttl=53 time=41.9 ms
^C
--- linux.cn ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 40.406/41.287/41.931/0.644 ms

$ ping 211.157.2.94   ### 通过 IP 地址 ping ，若无法 ping 通可能是网络连接出现问题
```

#### grep

`grep` 主要用于返回匹配的项目，支持正则表达式。

```
$ grep PATTERN filename      ### 返回所有含有 PATTERN 的行
$ grep zh_CN /etc/locale.gen ### 返回所有含 zh_CN 的行
```

#### mount

`mount` 用于挂载一个文件系统，需要 `root` 用户执行。一个磁盘可分为若干个分区，在分区上面可以创建文件系统，而挂载点则是提供一个访问的入口，将一个分区的文件系统挂载到某个目录中，称这个目录为挂载点，并且可以通过这个挂载点访问该文件系统中的内容。

例如一块硬盘在 Linux 中表示为 `/dev/sda` 那么它上面的分区应该表示为 `/dev/sda1` 、`/dev/sda2` 。

```
# mount                       ### 输出系统目前的挂载信息
# mount /dev/sda1 /mnt        ### 将 sda1 挂载到 /mnt 中
# cd /mnt                     ### 直接通过 /mnt 访问内容
# mount -o remount,rw  /mnt   ### 重新挂载 sda1 到 /mnt 并设置为 可读写
# mount -a                    ### 挂载 fstab 文件配置好的文件系统
```

#### umount

`umount` 与 `mount` 相反，是卸载一个挂载点，即取消该入口。

```
# umount /mnt                 ### 卸载 /mnt 这个挂载点的文件系统
# umount -a                   ### 卸载所有已挂载的文件系统
```

#### tar

`tar` 主要用于创建归档文件，和解压归档文件，其本身是没有压缩功能的，但可以调用 `gzip` 、 `bzip2` 进行压缩处理。
参数解释：

* `-c` 创建归档
* `-x` 解压归档
* `-v` 显示处理过程
* `-f` 目标文件，其后必须紧跟 目标文件
* `-j` 调用 `bzip2` 进行解压缩
* `-z` 调用 `gzip` 进行解压缩
* `-t` 列出归档中的文件

```
$ tar -cvf filename.tar .       ### 将当前目录所有文件归档，但不压缩，注意后面有个 ’.‘ ，不可省略，代表当前目录的意思
$ tar -xvf filename.tar         ### 解压 filename.tar 到当前文件夹
$ tar -cvjf filename.tar.bz2 .  ### 使用 bzip2 压缩
$ tar -xvjf  filename.tar.bz2   ### 解压 filename.tar.bz2 到当前文件夹
$ tar -cvzf filename.tar.gz     ### 使用 gzip  压缩
$ tar -xvzf filename.tar.gz     ### 解压 filename.tar.gz 到当前文件夹
$ tar -tf   filename            ### 只查看 filename 归档中的文件，不解压
```

#### ln

`ln` 主要用于在两个文件中创建链接，链接又分为 `Hard Links` (硬链接)和 `Symbolic Links` (符号链接或软链接)，其中默认为创建**硬链接**，使用 `-s` 参数指定创建软链接。

* 硬链接主要是增加一个文件的链接数，只要该文件的链接数不为 `0` ，该文件就不会被物理删除，所以删除一个具有多个硬链接数的文件，必须删除所有它的硬链接才可删除。
* 软链接简单来说是为文件创建了一个类似快捷方式的东西，通过该链接可以访问文件，修改文件，但不会增加该文件的链接数，删除一个软链接并不会删除源文件，即使源文件被删除，软链接也存在，当重新创建一个同名的源文件，该软链接则指向新创建的文件。
* 硬链接只可链接两个文件，不可链接目录，而软链接可链接目录，所以软链接是非常灵活的。

```
$ ln source dest       ### 为 source 创建一个名为 dest 的硬链接
$ ln -s source dest    ### 为 source 创建一个名为 dest 的软链接
```

#### chown

`chown` 用于改变一个文件的所有者及所在的组。

```
# chown user filename        ### 改变 filename 的所有者为 user
# chown user:group filename  ### 改变 filename 的所有者为 user，组为 group
# chown -R root folder       ### 改变 folder 文件夹及其子文件的所有者为 root
```

#### chmod

`chmod` 永远更改一个文件的权限，主要有 **读取** 、 **写入** 、 **执行** ，三种权限，其中 **所有者** 、 **用户组** 、 **其他** 各占三个，因此 `ls -l` 可以看到如下的信息

```
-rwxr--r-- 1 locez users   154 Aug 30 18:09 filename
```

其中 `r=read` ， `w=write` ， `x=execute`

```
# chmod +x filename        ### 为 user ，group ，others 添加执行权限
# chmod -x filename        ### 取消 user ， group ，others 的执行权限
# chmod +w filename        ### 为 user 添加写入权限
# chmod ugo=rwx filename   ### 设置 user ，group ，others 具有 读取、写入、执行权限
# chmod ug=rw filename     ### 设置 user ，group 添加 读取、写入权限
# chmod ugo=--- filename   ### 取消所有权限
```

#### useradd

`useradd` 用于添加一个普通用户。

```
# useradd -m -g users -G audio -s /usr/bin/bash newuser
### -m 创建 home 目录， -g 所属的主组， -G 指定该用户在哪些附加组， -s 设定默认的 shell ，newuser 为新的用户名
```

#### passwd

`passwd` 用于改变用户登录密码。

```
$ passwd                 ### 不带参数更改当前用户密码
# passwd newuser         ### 更改上述新建的 newuser 的用户密码
```

#### whereis

`whereis` 用于查找文件、手册等。

```
$ whereis bash
bash: /usr/bin/bash /etc/bash.bashrc /etc/bash.bash_logout /usr/share/man/man1/bash.1.gz /usr/share/info/bash.info.gz
$ whereis -b bash       ### 仅查找 binary
bash: /usr/bin/bash /etc/bash.bashrc /etc/bash.bash_logout
$ whereis -m bash       ### 仅查找 manual
bash: /usr/share/man/man1/bash.1.gz /usr/share/info/bash.info.gz
```

#### find

`find` 也用于查找文件，但更为强大，支持正则，并且可将查找结果传递到其他命令。

```
$ find . -name PATTERN    ### 从当前目录查找符合 PATTERN 的文件
$ find /home -name PATTERN -exec ls -l {} \;  # 从 /home 文件查找所有符合 PATTERN 的文件，并交由 ls 输出详细信息
```

#### wget

`wget` 是一个下载工具，简单强大。

```
$ wget -O newname.md https://github.com/LCTT/TranslateProject/blob/master/README.md     ### 下载 README 文件并重命名为 newname.md
$ wget -c url     ### 下载 url 并开启断点续传
```

恭喜你，你已经学习了完了26 个基础的 Linux 命令。虽然这里只是一些最基础的命令，但是熟练使用这些命令就踏出了你从一位 Linux 新手成为 Linux 玩家的第一步！


4 个开源的命令行邮件客户端

# 4 个开源的命令行邮件客户端

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

无论你承认与否，email并没有消亡。对那些对命令行至死不渝的 Linux 高级用户而言，离开 shell 转而使用传统的桌面或网页版邮件客户端并不适应。归根结底，命令行最善于处理文件，特别是文本文件，能使效率倍增。

幸运的是，也有不少的命令行邮件客户端，而它们的用户大都乐于帮助你入门并回答你使用中遇到的问题。但别说我没警告过你：一旦你完全掌握了其中一个客户端，你会发现很难回到基于图形界面的客户端！

要安装下述四个客户端中的任何一个是非常容易的；主要的 Linux 发行版的软件仓库中都提供此类软件，并可通过包管理器进行安装。你也可以在其它的操作系统中寻找并安装这类客户端，但我并未尝试过也没有相关的经验。

### Mutt

* [项目主页](http://www.mutt.org/)
* [源代码](http://dev.mutt.org/trac/)
* 授权协议: [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)

许多终端爱好者都听说过甚至熟悉 Mutt 和 Alpine， 他们已经存在多年。让我们先看看 Mutt。

Mutt 支持许多你所期望 email 系统支持的功能：会话，颜色区分，支持多语言，同时还有很多设置选项。它支持 POP3 和 IMAP 这两个主要的邮件传输协议，以及许多邮箱格式。自从1995年诞生以来， Mutt 就拥有了一个活跃的开发社区，但最近几年，新版本更多的关注于修复问题和安全更新而非提供新功能。这对大多数 Mutt 用户而言并无大碍，他们钟爱这样的界面，并支持此项目的口号：“所有邮件客户端都很烂，只是这个烂的没那么彻底。”

### Alpine

* [项目主页](http://www.washington.edu/alpine/)
* [源代码](http://www.washington.edu/alpine/acquire/)
* 授权协议: [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)

Alpine 是另一款知名的终端邮件客户端，它由华盛顿大学开发，设计初衷是作为一个开源的、支持 unicode 的 Pine （也来自华盛顿大学）的替代版本。

Alpine 不仅容易上手，还为高级用户提供了很多特性，它支持很多协议 —— IMAP, LDAP, NNTP, POP, SMTP 等，同时也支持不同的邮箱格式。Alpine 内置了一款名为 Pico 的可独立使用的简易文本编辑工具，但你也可以使用你常用的文本编辑器： vi, Emacs等。

尽管 Alpine 的升级并不频繁，不过有个名为 re-alpine 的分支为不同的开发者提供了开发此项目的机会。

Alpine 支持在屏幕上显示上下文帮助，但一些用户会喜欢 Mutt 式的独立说明手册，不过它们两个的文档都很完善。用户可以同时尝试 Mutt 和 Alpine，并由个人喜好作出决定，也可以尝试以下的几个新选择。

### Sup

* [项目主页](http://supmua.org/)
* [源代码](https://github.com/sup-heliotrope/sup)
* 授权协议: [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)

Sup 是我们列表中能被称为“大容量邮件客户端”的二者之一。自称“为邮件较多的人设计的命令行客户端”，Sup 的目标是提供一个支持层次化设计并允许为会话添加标签进行简单整理的界面。

由于采用 Ruby 编写，Sup 能提供十分快速的搜索并能自动管理联系人列表，同时还允许自定义插件。对于使用 Gmail 作为网页邮件客户端的人们，这些功能都是耳熟能详的，这就使得 Sup 成为一种比较现代的命令行邮件管理方式。

### Notmuch

* [项目主页](http://notmuchmail.org/)
* [源代码](http://notmuchmail.org/releases/)
* 授权协议: [GPLv3](http://www.gnu.org/licenses/gpl.html)

"Sup? Notmuch." Notmuch 作为 Sup 的回应，最初只是重写了 Sup 的一小部分来提高性能。最终，这个项目逐渐变大并成为了一个独立的邮件客户端。

Notmuch 是一款相当精简的软件。它并不能独立的收发邮件，启用 Notmuch 的快速搜索功能的代码实际上是设计成一个程序可以调用的独立库。但这样的模块化设计也使得你能使用你最爱的工具进行写信，发信和收信，集中精力做好一件事情并有效浏览和管理你的邮件。

这个列表并不完整，还有很多 email 客户端，它们或许才是你的最佳选择。你喜欢什么客户端呢？

---

via: <http://opensource.com/life/15/8/top-4-open-source-command-line-email-clients>

作者：[Jason Baker](http://opensource.com/users/jason-baker) 译者：[KevinSJ](https://github.com/KevinSj) 校对：[wxy](https://github.com/wxy)

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


FISH：Linux 下的一个智能易用的 Shell

Summary: FISH（friendly interactive shell）是一个用户友好的命令行 shell，主要是用来进行交互式使用。shell 就是一个用来执行其他程序的程序。  FISH 特性 自动建议 fish 会根据你的历史输入和补完来提供命令建议，就像一个网络浏览器一样。注意了，就是Netscape Navigator 4.0!  漂亮的VGA 色彩 fish 原生支持 term256， 它就是一个终端技术的艺术国度。 你将可以拥有一个难以置信的、256 色的shell 来使用。 理智的脚本 fish 是完全可以通过脚本控制的，而且它的语法又是那么的简单、干净，而且一致。你甚至不需要去重写。 基于 web 的配置

Cool

不知道是否依赖X，另外参数之类的是否也能补全。

来自云南昆明的 Internet Explorer 11.0|Windows 7 用户

前两天也开始用了，最大的缺点或者说特点应该就是脚本和bash不兼容了吧

感觉做了不少亮点，估计这些也是不兼容的一个原因吧。但是其实这个不兼容，一般来说没事——对于脚本来说，都会指明自己所需要用的解释器。

恩，就是刚转过来写脚本各种不顺畅，习惯了就挺好

不错不错

来自河南郑州的 Internet Explorer 10.0|Windows 8 用户

fedora23上dnf在fish下tab不能用。可能是我个人的问题。archlinux pacman没问题。

# FISH：Linux 下的一个智能易用的 Shell

FISH（friendly interactive shell）是一个用户友好的命令行 shell，主要是用来进行交互式使用。shell 就是一个用来执行其他程序的程序。

### FISH 特性

#### 自动建议

fish 会根据你的历史输入和补完来提供命令建议，就像一个网络浏览器一样。注意了，就是Netscape Navigator 4.0!

#### 漂亮的VGA 色彩

fish 原生支持 term256， 它就是一个终端技术的艺术国度。 你将可以拥有一个难以置信的、256 色的shell 来使用。

#### 理智的脚本

fish 是完全可以通过脚本控制的，而且它的语法又是那么的简单、干净，而且一致。你甚至不需要去重写。

#### 基于 web 的配置

对于少数能使用图形计算机的幸运儿， 你们可以在网页上配置你们自己的色彩方案，以及查看函数、变量和历史记录。

#### 帮助手册补全

其它的 shell 支持可配置的补全， 但是只有 fish 可以通过自动转换你安装好的 man 手册来实现补全功能。

#### 开箱即用

fish 将会通过 tab 补全和语法高亮使你非常愉快的使用shell， 同时不需要太多的学习或者配置。

### 在ubuntu 15.04 上安装FISH

打开终端，运行下列命令：

```
sudo apt-add-repository ppa:fish-shell/release-2
sudo apt-get update
sudo apt-get install fish

```

### 使用FISH

打开终端，运行下列命令来启动FISH：

```
fish

```

欢迎来到 fish，友好的交互式shell，输入指令 help 来了解怎么使用fish。

阅读[FISH 文档](http://fishshell.com/docs/current/index.html#introduction) ，掌握使用方法。

---

via: <http://www.ubuntugeek.com/fish-a-smart-and-user-friendly-command-line-shell-for-linux.html>

作者：[ruchi](http://www.ubuntugeek.com/author/ubuntufix) 译者：[oska874](https://github.com/oska874) 校对：[wxy](https://github.com/wxy)

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


Summary: 我成功地在 Ubuntu 15.04 下用 Gnome Network Manager 创建了一个无线AP热点。接下来我要分享一下我的步骤。请注意：你必须要有一个可以用来创建AP热点的无线网卡。如果你不知道如何确认它的话，在终端(Terminal)里输入iw list。 如果你没有安装iw的话, 在Ubuntu下你可以使用sudo apt-get install iw进行安装. 在你键入iw list之后, 查看支持的接口模式， 你应该会看到类似下面的条目中看到 AP: Supported interface modes: * IBSS * managed * AP * AP/VLAN * monitor * mesh point  让我们一步步看： 1、 断开WIFI连接。使用有线网络接

没有wifi的时候可以用。但是，现在遍地都是wifi

Supported interface modes:

                 * IBSS

                 * managed

博通的网卡。。。私有驱动。。。

怎么查看连接到这个ap的设备呢？

# 如何在 Ubuntu 15.04 下创建一个可供 Android/iOS 连接的 AP

我成功地在 Ubuntu 15.04 下用 Gnome Network Manager 创建了一个无线AP热点。接下来我要分享一下我的步骤。请注意：你必须要有一个可以用来创建AP热点的无线网卡。如果你不知道如何确认它的话，在终端(Terminal)里输入`iw list`。

如果你没有安装`iw`的话, 在Ubuntu下你可以使用`sudo apt-get install iw`进行安装.

在你键入`iw list`之后, 查看“支持的接口模式”， 你应该会看到类似下面的条目中看到 AP:

```
Supported interface modes:

* IBSS
* managed
* AP
* AP/VLAN
* monitor
* mesh point

```

让我们一步步看：

1、 断开WIFI连接。使用有线网络接入你的笔记本。

2、 在顶栏面板里点击网络的图标 -> Edit Connections(编辑连接) -> 在弹出窗口里点击Add(新增)按钮。

3、 在下拉菜单内选择Wi-Fi。

4、 接下来：

a、 输入一个链接名 比如: Hotspot 1

b、 输入一个 SSID 比如: Hotspot 1

c、 选择模式(mode): Infrastructure （基础设施）

d、 设备 MAC 地址: 在下拉菜单里选择你的无线设备

5、 进入Wi-Fi安全选项卡，选择 WPA & WPA2 Personal 并且输入密码。 6、 进入IPv4设置选项卡，在Method(方法)下拉菜单里，选择Shared to other computers(共享至其他电脑)。

7、 进入IPv6选项卡，在Method(方法)里设置为忽略ignore (只有在你不使用IPv6的情况下这么做) 8、 点击 Save(保存) 按钮以保存配置。 9、 从 menu/dash 里打开Terminal。 10、 修改你刚刚使用 network settings 创建的连接。

使用 VIM 编辑器:

```
sudo vim /etc/NetworkManager/system-connections/Hotspot

```

或使用Gedit 编辑器:

```
gksu gedit /etc/NetworkManager/system-connections/Hotspot

```

把名字 Hotspot 用你在第4步里起的连接名替换掉。

a、 把 `mode=infrastructure` 改成 `mode=ap` 并且保存文件。 b、 一旦你保存了这个文件，你应该能在 Wifi 菜单里看到你刚刚建立的AP了。(如果没有的话请再顶栏里 关闭/打开 Wifi 选项一次)

11、你现在可以把你的设备连上Wifi了。已经过 Android 5.0的小米4测试。(下载了1GB的文件以测试速度与稳定性)

---

via: <http://www.linuxveda.com/2015/08/23/how-to-create-an-ap-in-ubuntu-15-04-to-connect-to-androidiphone/>

作者：[Sayantan Das](http://www.linuxveda.com/author/sayantan_das/) 译者：[jerryling315](https://github.com/jerryling315) 校对：[wxy](https://github.com/wxy)

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


请捐助伟大的 ESR 吧，让他能为这个世界继续奉献

Summary: 作为开源爱好者，你一定读过 ESR（Eric S.Raymond）的里程碑著作《大教堂与集市》，甚至在各种开源集会中多次见过他的身影。 上个月，ESR 在www.patreon.com上发起来一份捐赠众筹，请求大家帮助他，让他能继续为互联网世界奉献。以下是他的众筹全文：  Every time you use a Web browser, locate yourself on Google Maps, draw money from an ATM, or play on a game console, you rely on computer code I wrote and gave away. 每当你使用浏览器、在 Google 地图上定位、从 ATM 里面取钱、或者玩主机游戏时，你都用到了我编写和贡献的

大牛们也得生活啊

那个网页实在是～～～ 太慢了，根本打不开。

没法捐赠。网页太慢了，根本打不开。我科学上网的网速本身还是挺快的。

还好吧，我没翻墙，慢慢也打开了。。

终于赞助成功了

谢谢，这想表达心意都不容易呢——现在我大概数了数，中国人大概10%。

好难啊，如果能支付宝就好了

让人思考，面对coding，这是热爱，而程序员不去为自己寻求经济收益，真的好吗？

看生活环境，个人观念喽，<br />
至少我现在需要用编程来维持生计，获取金钱利益。但哪一天，我生活压力没有那么大时，我会用我的空闲时间创造无偿贡献。付出是一种信仰。

# 请捐助伟大的 ESR 吧，让他能为这个世界继续奉献

作为开源爱好者，你一定读过 [ESR（Eric S. Raymond）](http://esr.ibiblio.org/)的里程碑著作[《大教堂与集市》](http://www.catb.org/esr/writings/cathedral-bazaar)，甚至在各种开源集会中多次见过他的身影。

上个月，ESR 在 [www.patreon.com](https://www.patreon.com/esr?ty=h) 上发起来一份[捐赠众筹](https://www.patreon.com/esr?ty=h)，请求大家帮助他，让他能继续为互联网世界奉献。以下是他的众筹全文：

>
> Every time you use a Web browser, locate yourself on Google Maps, draw money from an ATM, or play on a game console, you rely on computer code I wrote and gave away.
>
>
> 每当你使用浏览器、在 Google 地图上定位、从 ATM 里面取钱、或者玩主机游戏时，你都用到了我编写和贡献的那些计算机代码。
>
>
> The Internet was built by people like me. We're still out there, patiently building things and fixing bugs and putting in our time to make sure your world keeps working. We're mostly volunteers, because there is no way to wrap a business model around the most essential services. We do what we do for love, and because software is our art - and because, in the Internet-dependent 21st century, we know civilization would be lost without us just as surely as if the roads and sewers and power grid stopped working.
>
>
> 互联网是由像我这样的人构建的。我们仍然在工作，耐心的建设、修复问题、花费我们的时间来让你的世界继续工作。我们大多是志愿者，因为没有办法将这些基础服务包装到一个商业模式上。我们为爱而工作，因为软件就是我们的艺术，也因为我们知道，在离不了互联网的21世纪，如果没有我们，文明就将不再，就像没有了道路、下水道和电网一样。
>
>
> It's hard to notice us, because we're not the people who write the programs you can easily see. Ours is the software behind the software - the programs and service libraries that paint pixels on your display, move bits along the wires, allow hardware to talk to other hardware. (For those of you more technically inclined, I'm talking about systems code rather than applications.)
>
>
> 你很难注意到我们，因为我们并非编写你常见程序的人。我们编写的是软件背后的软件——这些程序和服务库在你显示器上渲染像素、沿着电路移动字节、让硬件互相通讯。（说的更技术些，我这里说的是系统代码而不是应用。）
>
>
> Though I'm a techie, I'm in a situation similar to a fine artist because the market has not figured out how to value and reward the work I feel called to do. Unlike most artists, it wouldn't be difficult for me to get a well-paid job - but then I'd have to work on what an employer wants, rather than what the world actually needs.
>
>
> 虽然我是一个技术人员，但我现在的这种处境更像一位优秀的艺术家，因为市场上没有办法评估我的价值和奖励我做的事情。不像大多数艺术家，我要找一份收入不菲的工作并不困难——但是这样我就得为这份薪水而工作了，而不是真正在世界所需要的地方奉献自己。
>
>
> Pledge to me so I can keep delivering what the world actually needs.
>
>
> 请为我捐款吧，让我能继续为世界而奉献。
>
>
>

你可能会吃惊，ESR 这样伟大的人，怎么会面临生活困窘？

那是因为，奥巴马医改法案让他的妻子丢掉了全职工作及医保，另外，这个医改法案让个人健康保险费用涨到了“天上”。所以，他现在每个月要支出超过了按揭的费用。他每个月去看医生的费用就需要 $973，而这笔钱没有了着落。

如果你也愿意为我们的 ESR 捐赠一点——哪怕是 $1，那么请点此：<https://www.patreon.com/esr?ty=h> 。

截止到本文发稿时，ESR 已经达成了第一个里程碑 $500（购买测试装备来改进 NTP 互联网时间服务）。目前正在准备完成第二个里程碑 $973（每月医保支出） ，现在已经有110为捐赠者，每月达到了 $615 的捐赠。

在得到捐赠一个月之后，ESR 写了一篇[博文](http://esr.ibiblio.org/?p=6835)，讲述了他是如何支配这些钱的：

>
> 在8月2号我去度假之前，我建立了一个捐赠众筹页。这件事的背景是我现在为 NTPsec 工作并获得了一些稳定的收入，但并不多。我的书的版税持续减少，而且我的妻子 Cathy 自从奥巴马医改法案使她失去她的全职的法律工作后，接手了所有她能接到的法律合同工作，但也收入甚微。另外，我们那辆开了八年的车也出了问题，修它的费用比它自身价值都贵得多，而房子也需要一个新的屋顶了，它看起来已经破得不行了。
>
>
> （没错，我们的确有一些储蓄跟股票。但是，不，我不想碰这些资金，因为我还不想到我真的老的时候得去领救助金过活，或者因为挨冻受饿而死。况且，即便这样子做不会跟我的价值观相冲突，但是指望2035年的美国政府能够让我有足够的钱来购买食物和住所的这种想法再愚蠢不过了。）
>
>
> 稍微使我惊讶的是，在一个月的捐献中，这个页面吸引了67个赞助者，总共捐赠409.17美元，我当初想不到能得到这么多捐赠，毕竟这个网站看起来完全是面向那些头戴贝雷帽、鼻子穿环的艺术家人群的。但它确实管用，一定程度上。
>
>
> 所有这些也是为什么现在我新发布的公告出现在 Patreon 上（基本上所有的），而不是博客上。这是我最接近艺术内容的东西了，而它也确实也增加了捐赠金额。
>
>
> 第一个月份的 Patreon 捐款只够让我给 Great Beast 装额外 32GB 内存，这是为了进行 GCC 的 Subversion-to-Git 转换的工作需要的。它解决不了多少（例如说）医疗保险问题，感谢那位专权的混蛋，不断地插手干涉把医疗费用搅得齐天高。（还因此牵连了我妻子的工作--这事件在心理上对她伤害不少）
>
>
> 如果你喜欢这个博客，请慷慨地捐赠吧。无论你以“娱乐”之名，还是以“支持 GNOME 的基础建设，让文明延续下去”之名，每个人的一点点帮忙能使我们走得更远。
>
>
>


对 Linux 内核的发展方向的展望

Summary: ** Linux 4.2 内核涉及到史上最多的贡献者数量，内核开发者 Jonathan Corbet 如是说。** 西雅图报道。Linux 内核持续增长：代码量在增加，代码贡献者数量也在增加。而随之而来的一些挑战需要处理一下。以上是 Jonathan Corbet 在今年的 LinuxCon 的内核年度报告上提出的主要观点。以下是他的主要演讲内容： Linux 4.2 内核已经于上月底释出。Corbet 强调有 1569 名开发者为这个版本贡献了代码，其中 277 名是第一次提交代码。 越来越多的开发者的加入，内核更新非常快，Corbet 估计现在大概 63 天就能产生一个新的内核里程碑。 Linux 4.2

现在学习新的内核，感觉的确很臃肿，希望能将各个模块之间的耦合降低，这样看起来感觉就好点了

避免臃肿的一个办法是硬件行业的开源，即硬件制造商按照行业规则去做硬件，最终反映到系统及内核的就会是可以统一解读的数据。但这将会是一个漫长的过程，想让硬件厂商达成共识并非易事

来自117.136.77.221的 Firefox 40.0|Android 用户

# 对 Linux 内核的发展方向的展望

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

**Linux 4.2 内核涉及到史上最多的贡献者数量，内核开发者 Jonathan Corbet 如是说。**

西雅图报道。Linux 内核持续增长：代码量在增加，代码贡献者数量也在增加。而随之而来的一些挑战需要处理一下。以上是 Jonathan Corbet 在今年的 LinuxCon 的内核年度报告上提出的主要观点。以下是他的主要演讲内容：

Linux 4.2 内核已经于上月底释出。Corbet 强调有 1569 名开发者为这个版本贡献了代码，其中 277 名是第一次提交代码。

越来越多的开发者的加入，内核更新非常快，Corbet 估计现在大概 63 天就能产生一个新的内核里程碑。

Linux 4.2 涉及多方面的更新。其中一个就是引进了 OverLayFS，这是一种只读型文件系统，它可以实现在一个容器之上再放一个容器。

网络系统对小包传输性能也有了提升，这对于高频金融交易而言非常重要。提升的方面主要集中在减小处理数据包的时间的能耗。

依然有新的驱动中加入内核。在每个内核发布周期，平均会有 60 到 80 个新增或升级驱动中加入。

另一个主要更新是实时内核补丁，这个特性在 4.0 版首次引进，好处是系统管理员可以在生产环境中打上内核补丁而不需要重启系统。当补丁所需要的元素都已准备就绪，打补丁的过程会在后台持续而稳定地进行。

**Linux 安全, IoT 和其他关注点**

过去一年中，安全问题在开源社区是一个很热的话题，这都归因于那些引发高度关注的事件，比如 Heartbleed 和 Shellshock。

“我毫不怀疑 Linux 代码对这些方面的忽视会产生一些令人不悦的问题”，Corbet 原话。

他强调说过去 10 年间有超过 3 百万行代码不再被开发者修改，而产生 Shellshock 漏洞的代码的年龄已经是 20 岁了，近年来更是无人问津。

另一个关注点是 2038 问题，Linux 界的“千年虫”，如果不解决，2000 年出现过的问题还会重现。2038 问题说的是在 2038 年一些 Linux 和 Unix 机器会死机（LCTT译注：32 位系统记录的时间，在2038年1月19日星期二晚上03:14:07之后的下一秒，会变成负数）。Corbet 说现在离 2038 年还有 23 年时间，现在部署的系统都会考虑 2038 问题。

Linux 已经启动一些初步的方案来修复 2038 问题了，但做的还远远不够。“现在就要修复这个问题，而不是等 20 年后把这个头疼的问题留给下一代解决，我们却享受着退休的美好时光”。

物联网(IoT)也是 Linux 关注的领域，Linux 是物联网嵌入式操作系统的主要占有者，然而这并没有什么卵用。Corget 认为日渐臃肿的内核对于未来的物联网设备来说肯定过于庞大。

现在有一个项目就是做内核最小化的，获取足够的支持对于这个项目来说非常重要。

“除了 Linux 之外，也有其他项目可以做物联网，但那些项目不会像 Linux 一样开放”，Corbet 说，“我们不能指望 Linux 在物联网领域一直保持优势，我们需要靠自己的努力去做到这点，我们需要注意不能让内核变得越来越臃肿。”

---

via: <http://www.eweek.com/enterprise-apps/a-look-at-whats-next-for-the-linux-kernel.html>

作者：[Sean Michael Kerner](http://www.eweek.com/cp/bio/Sean-Michael-Kerner/) 译者：[bazz2](https://github.com/bazz2) 校对：[wxy](https://github.com/wxy)

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


Debian GNU/Linux，22 年未完的美妙旅程

Summary: 在2015年8月16日， Debian项目组庆祝了 Debian 的22周年纪念日；这也是开源世界历史最悠久、热门的发行版之一。 Debian项目于1993年由Ian Murdock创立。彼时，Slackware 作为最早的 Linux 发行版已经名声在外。  22岁生日快乐! Debian Linux! Ian Ashly Murdock， 一个美国职业软件工程师， 在他还是普渡大学的学生时构想出了 Debian 项目的计划。他把这个项目命名为 Debian 是由于这个名字组合了他彼时女友的名字 Debra Lynn 和他自己的名字 Ian。 他之后和 Lynn 结婚并在2008年1月离婚。  Debian 创始人:Ian Murdock Ian 目前是 ExactTa

又来挑起我的神经了……不要冲动走上这22年没完美的旅程^_^

Debian 是我近一年多以来，用的时间最长的Linux发行版。

好厉害的样子，技术正在爆炸式发展

离婚了？好可惜，曾经也是一段佳话呢

还为那些奋斗在Linux系统上的工作者们致敬

当年我也将女朋友的名字作为主模块的名字——结果你知道的。。。

# Debian GNU/Linux，22 年未完的美妙旅程

在2015年8月16日， Debian项目组庆祝了 Debian 的22周年纪念日；这也是开源世界历史最悠久、热门的发行版之一。 Debian项目于1993年由Ian Murdock创立。彼时，Slackware 作为最早的 Linux 发行版已经名声在外。

*22岁生日快乐! Debian Linux!*

Ian Ashly Murdock， 一个美国职业软件工程师， 在他还是普渡大学的学生时构想出了 Debian 项目的计划。他把这个项目命名为 Debian 是由于这个名字组合了他彼时女友的名字 Debra Lynn 和他自己的名字 Ian。 他之后和 Lynn 结婚并在2008年1月离婚。

*Debian 创始人:Ian Murdock*

Ian 目前是 ExactTarget 的平台与开发社区的副总裁。

Debian (如同Slackware一样) 都是由于当时缺乏满足合乎标准的发行版才应运而生的。 Ian 在一次采访中说：“免费提供一流的产品会是 Debian 项目的唯一使命。 尽管过去的 Linux 发行版均不尽然可靠抑或是优秀。 我印象里...比如在不同的文件系统间移动文件， 处理大型文件经常会导致内核出错。 但是 Linux 其实是很可靠的， 自由的源代码让这个项目本质上很有前途。”

"我记得过去我像其他想解决问题的人一样， 想在家里运行一个像 UNIX 的东西。 但那是不可能的， 无论是经济上还是法律上或是别的什么角度。 然后我就听闻了 GNU 内核开发项目， 以及这个项目是如何没有任何法律纷争"， Ian 补充到。 他早年在开发 Debian 时曾被自由软件基金会(FSF)资助， 这份资助帮助 Debian 取得了长足的发展； 尽管一年后由于学业原因 Ian 退出了 FSF 转而去完成他的学位。

### Debian开发历史

* **Debian 0.01 – 0.09** : 发布于 1993 年八月 – 1993 年十二月。
* **Debian 0.91** : 发布于 1994 年一月。 有了原始的包管理系统， 没有依赖管理机制。
* **Debian 0.93 rc5** : 发布于 1995 年三月。 “现代”意义的 Debian 的第一次发布， 在基础系统安装后会使用dpkg 安装以及管理其他软件包。
* **Debian 0.93 rc6**: 发布于 1995 年十一月。 最后一次 a.out 发布， deselect 机制第一次出现， 有60位开发者在彼时维护着软件包。
* **Debian 1.1**: 发布于 1996 年六月。 项目代号 – Buzz， 软件包数量 – 474， 包管理器 dpkg， 内核版本 2.0， ELF 二进制。
* **Debian 1.2**: 发布于 1996 年十二月。 项目代号 – Rex， 软件包数量 – 848， 开发者数量 – 120。
* **Debian 1.3**: 发布于 1997 年七月。 项目代号 – Bo， 软件包数量 974， 开发者数量 – 200。
* **Debian 2.0**: 发布于 1998 年七月。 项目代号 - Hamm， 支持构架 – Intel i386 以及 Motorola 68000 系列， 软件包数量: 1500+， 开发者数量: 400+， 内置了 glibc。
* **Debian 2.1**: 发布于1999 年三月九日。 项目代号 – slink， 支持构架 - Alpha 和 Sparc， apt 包管理器开始成型， 软件包数量 – 2250。
* **Debian 2.2**: 发布于 2000 年八月十五日。 项目代号 – Potato， 支持构架 – Intel i386， Motorola 68000 系列， Alpha， SUN Sparc， PowerPC 以及 ARM 构架。 软件包数量: 3900+ (二进制) 以及 2600+ (源代码)， 开发者数量 – 450。 有一群人在那时研究并发表了一篇论文， 论文展示了自由软件是如何在被各种问题包围的情况下依然逐步成长为优秀的现代操作系统的。
* **Debian 3.0**: 发布于 2002 年七月十九日。 项目代号 – woody， 支持构架新增 – HP， PA\_RISC， IA-64， MIPS 以及 IBM， 首次以DVD的形式发布， 软件包数量 – 8500+， 开发者数量 – 900+， 支持加密。
* **Debian 3.1**: 发布于 2005 年六月六日。 项目代号 – sarge， 支持构架 – 新增 AMD64（非官方渠道发布）， 内核 – 2.4 以及 2.6 系列， 软件包数量: 15000+， 开发者数量 : 1500+， 增加了诸如 OpenOffice 套件， Firefox 浏览器， Thunderbird， Gnome 2.8， 支持: RAID， XFS， LVM， Modular Installer。
* **Debian 4.0**: 发布于 2007 年四月八日。 项目代号 – etch， 支持构架 – 如前，包括 AMD64。 软件包数量: 18，200+ 开发者数量 : 1030+， 图形化安装器。
* **Debian 5.0**: 发布于 2009 年二月十四日。 项目代号 – lenny， 支持构架 – 新增 ARM。 软件包数量: 23000+， 开发者数量: 1010+。
* **Debian 6.0**: 发布于 2009 年七月二十九日。 项目代号 – squeeze， 包含的软件包: 内核 2.6.32， Gnome 2.3. Xorg 7.5， 同时包含了 DKMS， 基于依赖包支持。 支持构架 : 新增 kfreebsd-i386 以及 kfreebsd-amd64， 基于依赖管理的启动过程。
* **Debian 7.0**: 发布于 2013 年五月四日。 项目代号: wheezy， 支持 Multiarch， 私有云工具， 升级了安装器， 移除了第三方软件依赖， 全功能多媒体套件-codec， 内核版本 3.2， Xen Hypervisor 4.1.4 ，软件包数量: 37400+。
* **Debian 8.0**: 发布于 2015 年五月二十五日。 项目代号: Jessie， 将 Systemd 作为默认的初始化系统， 内核版本 3.16， 增加了快速启动(fast booting)， service进程所依赖的 cgroups 使隔离部分 service 进程成为可能， 43000+ 软件包。 Sysvinit 初始化工具在 Jessie 中可用。

**注意**: Linux的内核第一次是在1991 年十月五日被发布， 而 Debian 的首次发布则在1993 年九月十三日。 所以 Debian 已经在只有24岁的 Linux 内核上运行了整整22年了。

### Debian 的那些事

1994年管理和重整了 Debian 项目以使得其他开发者能更好地加入，所以在那一年并没有发布面向用户的更新， 当然， 内部版本肯定是有的。

Debian 1.0 从来就没有被发布过。 一家 CD-ROM 的生产商错误地把某个未发布的版本标注为了 1.0， 为了避免产生混乱， 原本的 Debian 1.0 以1.1的面貌发布了。 从那以后才有了所谓的官方CD-ROM的概念。

每个 Debian 新版本的代号都是玩具总动员里某个角色的名字哦。

Debian 有四种可用版本: 旧稳定版(old stable)， 稳定版(stable)， 测试版(testing) 以及 试验版(experimental)。 始终如此。

Debian 项目组一直工作在不稳定发行版上， 这个不稳定版本始终被叫做Sid(玩具总动员里那个邪恶的臭小孩)。 Sid是unstable版本的永久名称， 同时Sid也取自'Still In Development"(译者:还在开发中)的首字母。 Sid 将会成为下一个稳定版， 当前的稳定版本代号为 jessie。

Debian 的官方发行版只包含开源并且自由的软件， 绝无其他东西. 不过 contrib 和非自由软件包使得安装那些本身自由但是其依赖的软件包不自由(contrib)的软件和非自由软件成为了可能。

Debian 是一堆Linux 发行版之母。 举几个例子:

* Damn Small Linux
* KNOPPIX
* Linux Advanced
* MEPIS
* Ubuntu
* 64studio (不再活跃开发)
* LMDE

Debian 是世界上最大的非商业 Linux 发行版。它主要是由C编写的(32.1%)， 一并的还有其他70多种语言。

*Debian 开发语言贡献表，图片来源: [Xmodulo](http://xmodulo.com/2013/08/interesting-facts-about-debian-linux.html)*

Debian 项目包含6，850万行代码， 以及 450万行空格和注释。

国际空间站放弃了 Windows 和红帽子， 进而换成了 Debian - 在上面的宇航员使用落后一个版本的稳定发行版， 目前是 squeeze; 这么做是为了稳定程度以及来自 Debian 社区的雄厚帮助支持。

感谢上帝! 我们差点就听到来自国际空间宇航员面对 Windows Metro 界面的尖叫了 :P

#### 黑色星期三

2002 年十一月二十日， Twente 大学的网络运营中心(NOC)着火。 当地消防部门放弃了服务器区域。 NOC维护着satie.debian.org 的网站服务器， 这个网站包含了安全、非美国相关的存档、新维护者资料、数量报告、数据库等等；这一切都化为了灰烬。 之后这些服务由 Debian 重建了。

#### 未来版本

下一个待发布版本是 Debian 9， 项目代号 – Stretch， 它会带来什么还是个未知数。 满心期待吧!

有很多发行版在 Linux 发行版的历史上出现过一瞬间然后很快消失了。 在多数情况下， 维护一个日渐庞大的项目是开发者们面临的挑战。 但这对 Debian 来说不是问题。 Debian 项目有全世界成百上千的开发者、维护者。 它在 Linux 诞生的之初起便一直存在。

Debian 在 Linux 生态环境中的贡献是难以用语言描述的。 如果 Debian 没有出现过， 那么 Linux 世界将不会像现在这样丰富和用户友好。 Debian 是为数不多可以被认为安全可靠又稳定的发行版，是作为网络服务器完美选择。

这仅仅是 Debian 的一个开始。 它走过了这么长的征程， 并将一直走下去。 未来即是现在！ 世界近在眼前！ 如果你到现在还从来没有使用过 Debian， 我只想问， 你还再等什么? 快去下载一份镜像试试吧， 我们会在此守候遇到任何问题的你。

* [Debian 主页](https://www.debian.org/)

---

via: <http://www.tecmint.com/happy-birthday-to-debian-gnu-linux/>

作者：[Avishek Kumar](http://www.tecmint.com/author/avishek/) 译者：[jerryling315](http://moelf.xyz) 校对：[wxy](https://github.com/wxy)

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


如何在 CentOS 7 上安装开源 ITIL 门户 iTOP

Summary: iTOP是一个简单的基于Web的开源IT服务管理工具。它有所有的ITIL功能，包括服务台、配置管理、事件管理、问题管理、变更管理和服务管理。iTOP依赖于Apache/IIS、MySQL和PHP，因此它可以运行在任何支持这些软件的操作系统中。因为iTOP是一个Web程序，因此你不必在用户的PC端任何客户端程序。一个简单的浏览器就足够每天的IT环境操作了。 我们要在一台有满足基本需求的LAMP环境的CentOS 7上安装和配置iTOP。 下载 iTOP iTOP的下载包现在在SourceForge上，我们可以从这获取它的官方链接。  我们从这里的连接用wget命令获取压缩文件。 # wget h

# 如何在 CentOS 7 上安装开源 ITIL 门户 iTOP

iTOP是一个简单的基于Web的开源IT服务管理工具。它有所有的ITIL功能，包括服务台、配置管理、事件管理、问题管理、变更管理和服务管理。iTOP依赖于Apache/IIS、MySQL和PHP，因此它可以运行在任何支持这些软件的操作系统中。因为iTOP是一个Web程序，因此你不必在用户的PC端任何客户端程序。一个简单的浏览器就足够每天的IT环境操作了。

我们要在一台有满足基本需求的LAMP环境的CentOS 7上安装和配置iTOP。

### 下载 iTOP

iTOP的下载包现在在SourceForge上，我们可以从这获取它的官方[链接](http://www.combodo.com/spip.php?page=rubrique&id_rubrique=8)。

我们从这里的连接用wget命令获取压缩文件。

```
[root@centos-007 ~]# wget http://downloads.sourceforge.net/project/itop/itop/2.1.0/iTop-2.1.0-2127.zip

```

### iTop扩展和网络安装

使用unzip命令解压到apache根目录下的itop文件夹下。

```
[root@centos-7 ~]# ls
iTop-2.1.0-2127.zip
[root@centos-7 ~]# unzip iTop-2.1.0-2127.zip -d /var/www/html/itop/

```

列出安装包中的内容。

```
[root@centos-7 ~]# ls -lh /var/www/html/itop/
total 68K
-rw-r--r--. 1 root root 1.4K Dec 17 2014 INSTALL
-rw-r--r--. 1 root root 35K Dec 17 2014 LICENSE
-rw-r--r--. 1 root root 23K Dec 17 2014 README
drwxr-xr-x. 19 root root 4.0K Jul 14 13:10 web

```

这些是我们可以安装的扩展。

```
[root@centos-7 2.x]# ls
authent-external itop-backup itop-config-mgmt itop-problem-mgmt itop-service-mgmt-provider itop-welcome-itil
authent-ldap itop-bridge-virtualization-storage itop-datacenter-mgmt itop-profiles-itil itop-sla-computation version.xml
authent-local itop-change-mgmt itop-endusers-devices itop-request-mgmt itop-storage-mgmt wizard-icons
installation.xml itop-change-mgmt-itil itop-incident-mgmt-itil itop-request-mgmt-itil itop-tickets
itop-attachments itop-config itop-knownerror-mgmt itop-service-mgmt itop-virtualization-mgmt

```

在解压的目录下，使用如下的 cp 命令将不同的数据模型从web 下的 datamodels 目录下复制到 extensions 目录，来迁移需要的扩展。

```
[root@centos-7 2.x]# pwd
/var/www/html/itop/web/datamodels/2.x
[root@centos-7 2.x]# cp -r itop-request-mgmt itop-service-mgmt itop-service-mgmt itop-config itop-change-mgmt /var/www/html/itop/web/extensions/

```

### 安装 iTop web界面

大多数服务端设置和配置已经完成了。最后我们安装web界面来完成安装。

打开浏览器使用ip地址或者完整域名来访问iTop 的 web目录。

```
http://servers_ip_address/itop/web/

```

你会被重定向到iTOP的web安装页面。让我们按照要求配置，就像在这篇教程中做的那样。

#### 验证先决要求

这一步你就会看到验证完成的欢迎界面。如果你看到了一些警告信息，你需要先安装这些软件来解决这些问题。

这一步有一个叫php mcrypt的可选包丢失了。下载下面的rpm包接着尝试安装php mcrypt包。

```
[root@centos-7 ~]#yum localinstall php-mcrypt-5.3.3-1.el6.x86_64.rpm libmcrypt-2.5.8-9.el6.x86_64.rpm.

```

成功安装完php-mcrypt后，我们需要重启apache服务，接着刷新页面，这时验证应该已经OK。

#### 安装或者升级 iTop

现在我们要在没有安装iTOP的服务器上选择全新安装。

#### iTop 许可协议

勾选接受 iTOP所有组件的许可协议，并点击“NEXT”。

#### 数据库配置

现在我们输入数据库凭据来配置数据库连接，接着选择如下选择创建新数据库。

#### 管理员账户

这一步中我们会输入它的登录信息来配置管理员账户。

#### 杂项参数

让我们选择额外的参数来选择你是否需要安装一个带有演示内容的数据库或者使用全新的数据库，接着下一步。

### iTop 配置管理

下面的选项允许你配置在iTOP要管理的元素类型，像CMDB、数据中心设备、存储设备和虚拟化这些东西在iTOP中是必须的。

#### 服务管理

选择一个最能描述你的IT设备和环境之间的关系的选项。因此我们这里选择为服务提供商的服务管理。

#### iTop Tickets 管理

从不同的可用选项我们选择符合ITIL Tickets管理选项来管理不同类型的用户请求和事件。

#### 改变管理选项

选择不同的ticket类型以便管理可用选项中的IT设备变更。我们选择ITTL变更管理选项。

#### iTop 扩展

这一节我们选择额外的扩展来安装或者不选直接跳过。

### 准备开始web安装

现在我们开始准备安装先前先前选择的组件。我们也可以下拉这些安装参数来浏览我们的配置。

确认安装参数后点击安装按钮。

让我们等待进度条来完成安装步骤。它也许会花费几分钟来完成安装步骤。

### iTop安装完成

我们的iTOP安装已经完成了，只要如下一个简单的手动操作就可以进入到iTOP。

### 欢迎来到iTop (IT操作门户)

### iTop 面板

你这里可以配置任何东西，服务、计算机、通讯录、位置、合同、网络设备等等。你可以创建你自己的。事实是刚安装的CMDB模块是每一个IT人员的必备模块。

### 总结

ITOP是一个最棒的开源桌面服务解决方案。我们已经在CentOS 7上成功地安装和配置了。因此，iTOP最强大的一方面是它可以很简单地通过扩展来自定义。如果你在安装中遇到任何问题欢迎评论。

---

via: <http://linoxide.com/tools/setup-itop-centos-7/>

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

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


RHCSA 系列（三）: 如何管理 RHEL7 的用户和组

Summary: 和管理其它Linux服务器一样，管理一个 RHEL 7 服务器要求你能够添加、修改、暂停或删除用户帐户，并且授予他们执行其分配的任务所需的文件、目录、其它系统资源所必要的权限。  RHCSA: 用户和组管理  Part 3 管理用户帐户 如果想要给RHEL 7 服务器添加账户，你需要以root用户执行如下两条命令之一： # adduser  # useradd   当添加新的用户帐户时，默认会执行下列操作。  它/她的主目录就会被创建(一般是"/home/用户名"，除非你特别设置) 一些隐藏文件 如.bash_logout, .bash_profile 以及 .bashrc 会被复制到用户的主目录，它们会为用户

用户这块还是用ＧＵＩ比较多

yutou83 [Internet Explorer 11.0|Windows 7]

# RHCSA 系列（三）: 如何管理 RHEL7 的用户和组

和管理其它Linux服务器一样，管理一个 RHEL 7 服务器要求你能够添加、修改、暂停或删除用户帐户，并且授予他们执行其分配的任务所需的文件、目录、其它系统资源所必要的权限。

*RHCSA: 用户和组管理 – Part 3*

### 管理用户帐户

如果想要给RHEL 7 服务器添加账户，你需要以root用户执行如下两条命令之一：

```
# adduser [new_account]
# useradd [new_account]

```

当添加新的用户帐户时，默认会执行下列操作。

* 它/她的主目录就会被创建(一般是"/home/用户名"，除非你特别设置)
* 一些隐藏文件 如`.bash_logout`, `.bash_profile` 以及 `.bashrc` 会被复制到用户的主目录，它们会为用户的回话提供环境变量。你可以进一步查看它们的相关细节。
* 会为您的账号添加一个邮件池目录。
* 会创建一个和用户名同样的组（LCTT 译注：除非你给新创建的用户指定了组）。

用户帐户的全部信息被保存在`/etc/passwd`文件。这个文件以如下格式保存了每一个系统帐户的所有信息(字段以“:”分割)

```
[username]:[x]:[UID]:[GID]:[Comment]:[Home directory]:[Default shell]

```

* `[username]` 和`[Comment]` 其意自明，就是用户名和备注
* 第二个‘x’表示帐户的启用了密码保护(记录在`/etc/shadow`文件)，密码用于登录`[username]`
* `[UID]` 和`[GID]`是整数，它们表明了`[username]`的用户ID 和所属的主组ID

最后。

* `[Home directory]`显示`[username]`的主目录的绝对路径
* `[Default shell]` 是当用户登录系统后使用的默认shell

另外一个你必须要熟悉的重要的文件是存储组信息的`/etc/group`。和`/etc/passwd`类似，也是每行一个记录，字段由“:”分割

```
[Group name]:[Group password]:[GID]:[Group members]

```

* `[Group name]` 是组名
* 这个组是否使用了密码 (如果是"x"意味着没有)
* `[GID]`: 和`/etc/passwd`中一样
* `[Group members]`:用户列表，使用“,”隔开。里面包含组内的所有用户

添加过帐户后，任何时候你都可以通过 usermod 命令来修改用户账户信息，基本的语法如下:

```
# usermod [options] [username]

```

相关阅读

* [15 ‘useradd’ 命令示例](http://www.tecmint.com/add-users-in-linux/)
* [15 ‘usermod’ 命令示例](http://www.tecmint.com/usermod-command-examples/)

#### 示例1 : 设置帐户的过期时间

如果你的公司有一些短期使用的帐户或者你要在有限时间内授予访问，你可以使用 `--expiredate` 参数 ，后加YYYY-MM-DD 格式的日期。为了查看是否生效，你可以使用如下命令查看

```
# chage -l [username]

```

帐户更新前后的变动如下图所示

*修改用户信息*

#### 示例 2: 向组内追加用户

除了创建用户时的主用户组，一个用户还能被添加到别的组。你需要使用 -aG或 -append -group 选项，后跟逗号分隔的组名。

#### 示例 3: 修改用户主目录或默认Shell

如果因为一些原因，你需要修改默认的用户主目录(一般为 /home/用户名)，你需要使用 -d 或 -home 参数，后跟绝对路径来修改主目录。

如果有用户想要使用其它的shell来取代默认的bash(比如zsh)。使用 usermod ，并使用 -shell 的参数，后加新的shell的路径。

#### 示例 4: 展示组内的用户

当把用户添加到组中后，你可以使用如下命令验证属于哪一个组

```
# groups [username]
# id [username]

```

下面图片的演示了示例2到示例4

*添加用户到额外的组*

在上面的示例中:

```
# usermod --append --groups gacanepa,users --home /tmp --shell /bin/sh tecmint

```

如果想要从组内删除用户，取消 `--append` 选项，并使用 `--groups` 和你要用户属于的组的列表。

#### 示例 5: 通过锁定密码来停用帐户

如果想要关闭帐户，你可以使用 -l(小写的L)或 -lock 选项来锁定用户的密码。这将会阻止用户登录。

#### 示例 6: 解锁密码

当你想要重新启用帐户让它可以继续登录时，使用 -u 或 –unlock 选项来解锁用户的密码，就像示例5 介绍的那样

```
# usermod --unlock tecmint

```

下面的图片展示了示例5和示例6：

*锁定上锁用户*

#### 示例 7:删除组和用户

如果要删除一个组，你需要使用 groupdel ，如果需要删除用户 你需要使用 userdel (添加 -r 可以删除主目录和邮件池的内容)。

```
# groupdel [group_name]        # 删除组
# userdel -r [user_name]       # 删除用户，并删除主目录和邮件池

```

如果一些文件属于该组，删除组时它们不会也被删除。但是组拥有者的名字将会被设置为删除掉的组的GID。

### 列举，设置，并且修改标准 ugo/rwx 权限

著名的 [ls 命令](http://linux.cn/article-5349-1.html) 是管理员最好的助手. 当我们使用 -l 参数, 这个工具允许您以长格式（或详细格式)查看一个目录中的内容。

而且，该命令还可以用于单个文件中。无论哪种方式，在“ls”输出中的前10个字符表示每个文件的属性。

这10个字符序列的第一个字符用于表示文件类型：

* – (连字符): 一个标准文件
* d: 一个目录
* l: 一个符号链接
* c: 字符设备（将数据作为字节流，例如终端）
* b: 块设备（以块的方式处理数据，例如存储设备）

文件属性的接下来的九个字符，分为三个组，被称为文件模式，并注明读（r）、写（w）、和执行（x）权限授予文件的所有者、文件的所有组、和其它的用户（通常被称为“世界”）。

同文件上的读取权限允许文件被打开和读取一样，如果目录同时有执行权限时，就允许其目录内容被列出。此外，如果一个文件有执行权限，就允许它作为一个程序运行。

文件权限是通过chmod命令改变的，它的基本语法如下：

```
# chmod [new_mode] file

```

new\_mode 是一个八进制数或表达式，用于指定新的权限。随意试试各种权限看看是什么效果。或者您已经有了一个更好的方式来设置文件的权限，你也可以用你自己的方式自由地试试。

八进制数可以基于二进制等价计算，可以从所需的文件权限的文件的所有者、所有组、和世界组合成。每种权限都等于2的幂（R = 2^2，W = 2^1，x = 2^0），没有时即为0。例如：

*文件权限*

在八进制形式下设置文件的权限，如上图所示

```
# chmod 744 myfile

```

请用马上来对比一下我们以前的计算，在更改文件的权限后，我们的实际输出为：

*长列表格式*

#### 示例 8: 寻找777权限的文件

出于安全考虑，你应该确保在正常情况下，尽可能避免777权限（任何人可读、可写、可执行的文件）。虽然我们会在以后的教程中教你如何更有效地找到您的系统的具有特定权限的全部文件，你现在仍可以组合使用ls 和 grep来获取这种信息。

在下面的例子，我们会寻找 /etc 目录下的777权限文件。注意，我们要使用[第二章：文件和目录管理](https://www.linux.cn/article-6155-1.html)中讲到的管道的知识：

```
# ls -l /etc | grep rwxrwxrwx

```

*查找所有777权限的文件*

#### 示例 9: 为所有用户指定特定权限

shell脚本，以及一些二进制文件，所有用户都应该有权访问（不只是其相应的所有者和组），应该有相应的执行权限（我们会讨论特殊情况下的问题）：

```
# chmod a+x script.sh

```

**注意**: 我们可以使用表达式设置文件模式，表示用户权限的字母如“u”，组所有者权限的字母“g”，其余的为“o” ，同时具有所有权限为“a”。权限可以通过`+` 或 `-` 来授予和收回。

*为文件设置执行权限*

长目录列表还用两列显示了该文件的所有者和所有组。此功能可作为系统中文件的第一级访问控制方法：

*检查文件的所有者和所有组*

改变文件的所有者，您应该使用chown命令。请注意，您可以在同时或分别更改文件的所有组：

```
# chown user:group file

```

你可以更改用户或组，或在同时更改两个属性，但是不要忘记冒号区分，如果你想要更新其它属性，让另外的部分为空：

```
# chown :group file              # 仅改变所有组
# chown user: file               # 仅改变所有者

```

#### 示例 10:从一个文件复制权限到另一个文件

如果你想“克隆”一个文件的所有权到另一个，你可以这样做，使用–reference参数，如下：

```
# chown --reference=ref_file file

```

ref\_file的所有信息会复制给 file

*复制文件属主信息*

### 设置 SETGID 协作目录

假如你需要授予在一个特定的目录中拥有访问所有的文件的权限给一个特定的用户组，你有可能需要使用给目录设置setgid的方法。当setgid设置后，该真实用户的有效GID会变成属主的GID。

因此，任何访问该文件的用户会被授予该文件的属组的权限。此外，当setgid设置在一个目录中，新创建的文件继承组该目录的组，而且新创建的子目录也将继承父目录的setgid权限。

```
# chmod g+s [filename]

```

要以八进制形式设置 setgid，需要在基本权限前缀以2。

```
# chmod 2755 [directory]

```

### 总结

扎实的用户和组管理知识，以及标准和特殊的 Linux权限管理，通过实践，可以帮你快速解决 RHEL 7 服务器的文件权限问题。

我向你保证，当你按照本文所概述的步骤和使用系统文档(在本系列的[第一章 回顾基础命令及系统文档](http://www.tecmint.com/rhcsa-exam-reviewing-essential-commands-system-documentation/)中讲到)， 你将掌握基本的系统管理的能力。

请随时使用下面的评论框让我们知道你是否有任何问题或意见。

---

via: <http://www.tecmint.com/rhcsa-exam-manage-users-and-groups/>

作者：[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 有问必答：如何解决 Linux 上的 Wireshark 界面僵死

Summary: 问题: 当我试图在 Ubuntu 上的 Wireshark 中打开一个 pre-recorded 数据包转储时，它的界面突然死机，在我运行 Wireshark 的终端出现了下面的错误和警告。我该如何解决这个问题？  (wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GObject' (wireshark:3480): GLib-GObject-CRITICAL **: g_object_set_qdata_full: assertion 'G_IS_OBJECT (object)' failed (wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkRange' (wireshark:3480): Gtk-CRITICAL **: gtk_ran

# Linux 有问必答：如何解决 Linux 上的 Wireshark 界面僵死

>
> **问题**: 当我试图在 Ubuntu 上的 Wireshark 中打开一个 pre-recorded 数据包转储时，它的界面突然死机，在我运行 Wireshark 的终端出现了下面的错误和警告。我该如何解决这个问题？
>
>
>

```
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GObject'
(wireshark:3480): GLib-GObject-CRITICAL **: g_object_set_qdata_full: assertion 'G_IS_OBJECT (object)' failed
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkRange'
(wireshark:3480): Gtk-CRITICAL **: gtk_range_get_adjustment: assertion 'GTK_IS_RANGE (range)' failed
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkOrientable'
(wireshark:3480): Gtk-CRITICAL **: gtk_orientable_get_orientation: assertion 'GTK_IS_ORIENTABLE (orientable)' failed
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkScrollbar'
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkWidget'
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GObject'
(wireshark:3480): GLib-GObject-CRITICAL **: g_object_get_qdata: assertion 'G_IS_OBJECT (object)' failed
(wireshark:3480): Gtk-CRITICAL **: gtk_widget_set_name: assertion 'GTK_IS_WIDGET (widget)' failed

```

Wireshark 是一个基于 GUI 的数据包捕获和嗅探工具。该工具被网络管理员普遍使用，网络安全工程师或开发人员对于各种任务的数据包级的网络分析是必需的，例如在网络故障，漏洞测试，应用程序调试，或逆向协议工程是必需的。 Wireshark 允许实时记录数据包，并通过便捷的图形用户界面浏览他们的协议首部和有效负荷。

这是 Wireshark 的 UI，尤其是在 Ubuntu 桌面下运行时，当你向上或向下滚动分组列表视图时，或开始加载一个 pre-recorded 包转储文件时，有时会挂起或冻结，并出现以下错误。

显然，这个错误是由 Wireshark 和叠加滚动条之间的一些不兼容造成的，在最新的 Ubuntu 桌面还没有被解决（例如，Ubuntu 15.04 的桌面）。

一种避免 Wireshark 的 UI 卡死的办法就是 **暂时禁用叠加滚动条**。在 Wireshark 上有两种方法来禁用叠加滚动条，这取决于你在桌面上如何启动 Wireshark 的。

### 命令行解决方法

叠加滚动条可以通过设置"**LIBOVERLAY\_SCROLLBAR**"环境变量为“0”来被禁止。

所以，如果你是在终端使用命令行启动 Wireshark 的，你可以在 Wireshark 中禁用叠加滚动条，如下所示。

打开你的 .bashrc 文件，并定义以下 alias。

```
alias wireshark="LIBOVERLAY_SCROLLBAR=0 /usr/bin/wireshark"

```

### 桌面启动解决方法

如果你是使用桌面启动器启动的 Wireshark，你可以编辑它的桌面启动器文件。

```
$ sudo vi /usr/share/applications/wireshark.desktop

```

查找以"Exec"开头的行，并如下更改。

```
Exec=env LIBOVERLAY_SCROLLBAR=0 wireshark %f

```

虽然这种解决方法可以在系统级帮助到所有桌面用户，但升级 Wireshark 后被覆盖就没用了。如果你想保留修改的 .desktop 文件，如下所示将它复制到你的主目录。

```
$ cp /usr/share/applications/wireshark.desktop ~/.local/share/applications/

```

---

via: <http://ask.xmodulo.com/fix-wireshark-gui-freeze-linux-desktop.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/) 荣誉推出


LinuxCon: 服务器操作系统的转型

Summary: 西雅图报道。容器迟早要改变世界，以及改变操作系统的角色。这是 Wim Coekaerts 带来的 LinuxCon 演讲主题，Coekaerts 是 Oracle 公司 Linux 与虚拟化工程的高级副总裁。  Coekaerts 在开始演讲的时候拿出一张关于桌面之年的幻灯片，引发了现场观众的一片笑声。之后他说 2015 年很明显是容器之年，更是应用之年，应用才是容器的关键。 你需要操作系统做什么事情？，Coekaerts 回答现场观众：只需一件事：运行一个应用。操作系统负责管理硬件和资源，来让你的应用运行起来。 Coakaerts 补充说，在 Docker 容器的帮助下，我们的注意力再次集

# LinuxCon: 服务器操作系统的转型

西雅图报道。容器迟早要改变世界，以及改变操作系统的角色。这是 Wim Coekaerts 带来的 LinuxCon 演讲主题，Coekaerts 是 Oracle 公司 Linux 与虚拟化工程的高级副总裁。

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

Coekaerts 在开始演讲的时候拿出一张关于“桌面之年”的幻灯片，引发了现场观众的一片笑声。之后他说 2015 年很明显是容器之年，更是应用之年，应用才是容器的关键。

“你需要操作系统做什么事情？”，Coekaerts 回答现场观众：“只需一件事：运行一个应用。操作系统负责管理硬件和资源，来让你的应用运行起来。”

Coakaerts 补充说，在 Docker 容器的帮助下，我们的注意力再次集中在应用上，而在 Oracle，我们将注意力放在如何让应用更好地运行在操作系统上。

“许多人过去常常需要繁琐地安装应用，而现在的年轻人只需要按一个按钮就能让应用在他们的移动设备上运行起来”。

人们对安装企业版的软件需要这么复杂的步骤而感到惊讶，而 Docker 帮助他们脱离了这片苦海。

“操作系统的角色已经变了。” Coekaerts 说。

Docker 的出现不代表虚拟机的淘汰，容器化过程需要经过很长时间才能变得成熟，然后才能在世界范围内得到应用。

在这段时间内，容器会与虚拟机共存，并且我们需要一些工具，将应用在容器和虚拟机之间进行转换迁移。Coekaerts 举例说 Oracle 的 VirtualBox 就可以用来帮助用户运行 Docker，而它原来是被广泛用在桌面系统上的一项开源技术。现在 Docker 的 Kitematic 项目将在 Mac 上使用 VirtualBox 运行 Docker。

### 容器的开放计算计划和一次写随处部署

一个能让容器成功的关键是“一次写，随处部署”的概念。而在容器之间的互操作领域，Linux 基金会的开放计算计划（OCI）扮演一个非常关键的角色。

“使用 OCI，应用编译一次后就可以很方便地在多地运行，所以你可以将你的应用部署在任何地方”。

Coekaerts 总结说虽然在迁移到容器模型过程中会发生很多好玩的事情，但容器还没真正做好准备，他强调 Oracle 现在正在验证将产品运行在容器内的可行性，但这是一个非常艰难的过程。

“运行数据库很简单，难的是要搞定数据库所需的环境”，Coekaerts 说：“容器与虚拟机不一样，一些需要依赖底层系统配置的应用无法从主机迁移到容器中。”

另外，Coekaerts 指出在容器内调试问题与在虚拟机内调试问题也是不一样的，现在还没有成熟的工具来进行容器应用的调试。

Coekaerts 强调当容器足够成熟时，有一点很重要：不要抛弃现有的技术。组织和企业不能抛弃现有的部署好的应用，而完全投入新技术的怀抱。

“部署新技术是很困难的事情，你需要缓慢地迁移过去，能让你顺利迁移的技术才是成功的技术。”Coekaerts 说。

---

via: <http://www.serverwatch.com/server-news/linuxcon-the-changing-role-of-the-server-os.html>

作者：[Sean Michael Kerner](http://www.serverwatch.com/author/Sean-Michael-Kerner-101580.htm) 译者：[bazz2](https://github.com/bazz2) 校对：[wxy](https://github.com/wxy)

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


Linux 上将出现一个新的文件系统：bcachefs

Summary: 这个有 5 年历史，由 Kent Oberstreet 创建，过去属于谷歌的文件系统，最近完成了全部关键组件。Bcachefs 文件系统自称其性能和稳定性与 ext4 和 xfs 相同，而其他方面的功能又可以与 btrfs 和 zfs 相媲美。主要特性包括校验、压缩、多设备支持、缓存、快照与其他漂亮的特性。  Bcachefs 来自 bcache，这是一个块级缓存层。从 bcaceh 到一个功能完整的写时复制文件系统，堪称是一项质的转变。 对自己的问题为什么要出一个新的文件系统中，Kent Oberstreet 自问自答道：当我还在谷歌的时候，我与其他在 bcache 上工作的同事在偶然的情况下

从 bcaceh 到一个功能完整<br />
应该是bcache吧

谢谢，笔误~~马上修改。

# Linux 上将出现一个新的文件系统：bcachefs

这个有 5 年历史，由 Kent Oberstreet 创建，过去属于谷歌的文件系统，最近完成了全部关键组件。Bcachefs 文件系统自称其性能和稳定性与 ext4 和 xfs 相同，而其他方面的功能又可以与 btrfs 和 zfs 相媲美。主要特性包括校验、压缩、多设备支持、缓存、快照与其他“漂亮”的特性。

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

Bcachefs 来自 **bcache**，这是一个块级缓存层。从 bcache 到一个功能完整的[写时复制](https://en.wikipedia.org/wiki/Copy-on-write)文件系统，堪称是一项质的转变。

对自己的问题“为什么要出一个新的文件系统”中，Kent Oberstreet 自问自答道：当我还在谷歌的时候，我与其他在 bcache 上工作的同事在偶然的情况下意识到我们正在使用的东西可以成为一个成熟文件系统的功能块，我们可以用 bcache 创建一个拥有干净而优雅设计的文件系统，而最重要的一点是，bcachefs 的主要目的就是在性能和稳定性上能与 ext4 和 xfs 匹敌，同时拥有 btrfs 和 zfs 的特性。

Overstreet 邀请人们在自己的系统上测试 bcachefs，可以通过邮件列表[通告]获取 bcachefs 的操作指南。

Linux 生态系统中文件系统几乎处于一家独大状态，Fedora 在第 16 版的时候就想用 btrfs 换掉 ext4 作为其默认文件系统，但是到现在（LCTT：都出到 Fedora 22 了）还在使用 ext4。而几乎所有 Debian 系的发行版（Ubuntu、Mint、elementary OS 等）也使用 ext4 作为默认文件系统，并且这些主流的发行版都没有替换默认文件系统的意思。

---

via: <http://www.linuxveda.com/2015/08/22/linux-gain-new-file-system-bcachefs/>

作者：[Paul Hill](http://www.linuxveda.com/author/paul_hill/) 译者：[bazz2](https://github.com/bazz2) 校对：[wxy](https://github.com/wxy)

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


你知道 Linux 内核是如何构建的吗？

Summary: 介绍 我不会告诉你怎么在自己的电脑上去构建、安装一个定制化的 Linux 内核，这样的资料太多了，它们会对你有帮助。本文会告诉你当你在内核源码路径里敲下make 时会发生什么。 当我刚刚开始学习内核代码时，Makefile 是我打开的第一个文件，这个文件看起来真令人害怕 :)。那时候这个 Makefile 还只包含了1591 行代码，当我开始写本文时，内核已经是4.2.0的第三个候选版本 了。 这个 makefile 是 Linux 内核代码的根 makefile ，内核构建就始于此处。是的，它的内容很多，但是如果你已经读过内核源代码，你就会发现每个包含代码的目录都有

# 你知道 Linux 内核是如何构建的吗？

### 介绍

我不会告诉你怎么在自己的电脑上去构建、安装一个定制化的 Linux 内核，这样的[资料](https://encrypted.google.com/search?q=building+linux+kernel#q=building+linux+kernel+from+source+code)太多了，它们会对你有帮助。本文会告诉你当你在内核源码路径里敲下`make` 时会发生什么。

当我刚刚开始学习内核代码时，[Makefile](https://github.com/torvalds/linux/blob/master/Makefile) 是我打开的第一个文件，这个文件看起来真令人害怕 :)。那时候这个 [Makefile](https://en.wikipedia.org/wiki/Make_%28software%29) 还只包含了`1591` 行代码，当我开始写本文时，内核已经是[4.2.0的第三个候选版本](https://github.com/torvalds/linux/commit/52721d9d3334c1cb1f76219a161084094ec634dc) 了。

这个 makefile 是 Linux 内核代码的根 makefile ，内核构建就始于此处。是的，它的内容很多，但是如果你已经读过内核源代码，你就会发现每个包含代码的目录都有一个自己的 makefile。当然了，我们不会去描述每个代码文件是怎么编译链接的，所以我们将只会挑选一些通用的例子来说明问题。而你不会在这里找到构建内核的文档、如何整洁内核代码、[tags](https://en.wikipedia.org/wiki/Ctags) 的生成和[交叉编译](https://en.wikipedia.org/wiki/Cross_compiler) 相关的说明，等等。我们将从`make` 开始，使用标准的内核配置文件，到生成了内核镜像 [bzImage](https://en.wikipedia.org/wiki/Vmlinux#bzImage) 结束。

如果你已经很了解 [make](https://en.wikipedia.org/wiki/Make_%28software%29) 工具那是最好，但是我也会描述本文出现的相关代码。

让我们开始吧！

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

（题图来自：adafruit.com）

### 编译内核前的准备

在开始编译前要进行很多准备工作。最主要的就是找到并配置好配置文件，`make` 命令要使用到的参数都需要从这些配置文件获取。现在就让我们深入内核的根 `makefile` 吧

内核的根 `Makefile` 负责构建两个主要的文件：[vmlinux](https://en.wikipedia.org/wiki/Vmlinux) （内核镜像可执行文件）和模块文件。内核的 [Makefile](https://github.com/torvalds/linux/blob/master/Makefile) 从定义如下变量开始：

```
VERSION = 4
PATCHLEVEL = 2
SUBLEVEL = 0
EXTRAVERSION = -rc3
NAME = Hurr durr I'ma sheep

```

这些变量决定了当前内核的版本，并且被使用在很多不同的地方，比如同一个 `Makefile` 中的 `KERNELVERSION` ：

```
KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)

```

接下来我们会看到很多`ifeq` 条件判断语句，它们负责检查传递给 `make` 的参数。内核的 `Makefile` 提供了一个特殊的编译选项 `make help` ，这个选项可以生成所有的可用目标和一些能传给 `make` 的有效的命令行参数。举个例子，`make V=1` 会在构建过程中输出详细的编译信息，第一个 `ifeq` 就是检查传递给 make 的 `V=n` 选项。

```
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif

export quiet Q KBUILD_VERBOSE

```

如果 `V=n` 这个选项传给了 `make` ，系统就会给变量 `KBUILD_VERBOSE` 选项附上 `V` 的值，否则的话`KBUILD_VERBOSE` 就会为 `0`。然后系统会检查 `KBUILD_VERBOSE` 的值，以此来决定 `quiet` 和`Q` 的值。符号 `@` 控制命令的输出，如果它被放在一个命令之前，这条命令的输出将会是 `CC scripts/mod/empty.o`，而不是`Compiling .... scripts/mod/empty.o`（LCTT 译注：CC 在 makefile 中一般都是编译命令）。在这段最后，系统导出了所有的变量。

下一个 `ifeq` 语句检查的是传递给 `make` 的选项 `O=/dir`，这个选项允许在指定的目录 `dir` 输出所有的结果文件：

```
ifeq ($(KBUILD_SRC),)

ifeq ("$(origin O)", "command line")
  KBUILD_OUTPUT := $(O)
endif

ifneq ($(KBUILD_OUTPUT),)
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
                                && /bin/pwd)
$(if $(KBUILD_OUTPUT),, \
     $(error failed to create output directory "$(saved-output)"))

sub-make: FORCE
    $(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
    -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))

skip-makefile := 1
endif # ifneq ($(KBUILD_OUTPUT),)
endif # ifeq ($(KBUILD_SRC),)

```

系统会检查变量 `KBUILD_SRC`，它代表内核代码的顶层目录，如果它是空的（第一次执行 makefile 时总是空的），我们会设置变量 `KBUILD_OUTPUT` 为传递给选项 `O` 的值（如果这个选项被传进来了）。下一步会检查变量 `KBUILD_OUTPUT` ，如果已经设置好，那么接下来会做以下几件事：

* 将变量 `KBUILD_OUTPUT` 的值保存到临时变量 `saved-output`；
* 尝试创建给定的输出目录；
* 检查创建的输出目录，如果失败了就打印错误；
* 如果成功创建了输出目录，那么就在新目录重新执行 `make` 命令（参见选项`-C`）。

下一个 `ifeq` 语句会检查传递给 make 的选项 `C` 和 `M`：

```
ifeq ("$(origin C)", "command line")
  KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
  KBUILD_CHECKSRC = 0
endif

ifeq ("$(origin M)", "command line")
  KBUILD_EXTMOD := $(M)
endif

```

第一个选项 `C` 会告诉 `makefile` 需要使用环境变量 `$CHECK` 提供的工具来检查全部 `c` 代码，默认情况下会使用[sparse](https://en.wikipedia.org/wiki/Sparse)。第二个选项 `M` 会用来编译外部模块（本文不做讨论）。

系统还会检查变量 `KBUILD_SRC`，如果 `KBUILD_SRC` 没有被设置，系统会设置变量 `srctree` 为`.`：

```
ifeq ($(KBUILD_SRC),)
        srctree := .
endif

objtree := .
src     := $(srctree)
obj     := $(objtree)

export srctree objtree VPATH

```

这将会告诉 `Makefile` 内核的源码树就在执行 `make` 命令的目录，然后要设置 `objtree` 和其他变量为这个目录，并且将这些变量导出。接着就是要获取 `SUBARCH` 的值，这个变量代表了当前的系统架构（LCTT 译注：一般都指CPU 架构）：

```
SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
                  -e s/sun4u/sparc64/ \
                  -e s/arm.*/arm/ -e s/sa110/arm/ \
                  -e s/s390x/s390/ -e s/parisc64/parisc/ \
                  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
                  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )

```

如你所见，系统执行 [uname](https://en.wikipedia.org/wiki/Uname) 得到机器、操作系统和架构的信息。因为我们得到的是 `uname` 的输出，所以我们需要做一些处理再赋给变量 `SUBARCH` 。获得 `SUBARCH` 之后就要设置`SRCARCH` 和 `hfr-arch`，`SRCARCH` 提供了硬件架构相关代码的目录，`hfr-arch` 提供了相关头文件的目录：

```
ifeq ($(ARCH),i386)
        SRCARCH := x86
endif
ifeq ($(ARCH),x86_64)
        SRCARCH := x86
endif

hdr-arch  := $(SRCARCH)

```

注意：`ARCH` 是 `SUBARCH` 的别名。如果没有设置过代表内核配置文件路径的变量 `KCONFIG_CONFIG`，下一步系统会设置它，默认情况下就是 `.config` ：

```
KCONFIG_CONFIG  ?= .config
export KCONFIG_CONFIG

```

以及编译内核过程中要用到的 [shell](https://en.wikipedia.org/wiki/Shell_%28computing%29)

```
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
      else if [ -x /bin/bash ]; then echo /bin/bash; \
      else echo sh; fi ; fi)

```

接下来就要设置一组和编译内核的编译器相关的变量。我们会设置主机的 `C` 和 `C++` 的编译器及相关配置项：

```
HOSTCC       = gcc
HOSTCXX      = g++
HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89
HOSTCXXFLAGS = -O2

```

接下来会去适配代表编译器的变量 `CC`，那为什么还要 `HOST*` 这些变量呢？这是因为 `CC` 是编译内核过程中要使用的目标架构的编译器，但是 `HOSTCC` 是要被用来编译一组 `host` 程序的（下面我们就会看到）。

然后我们就看到变量 `KBUILD_MODULES` 和 `KBUILD_BUILTIN` 的定义，这两个变量决定了我们要编译什么东西（内核、模块或者两者）：

```
KBUILD_MODULES :=
KBUILD_BUILTIN := 1

ifeq ($(MAKECMDGOALS),modules)
  KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
endif

```

在这我们可以看到这些变量的定义，并且，如果们仅仅传递了 `modules` 给 `make`，变量 `KBUILD_BUILTIN` 会依赖于内核配置选项 `CONFIG_MODVERSIONS`。

下一步操作是引入下面的文件：

```
include scripts/Kbuild.include

```

文件 [Kbuild](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kbuild.txt) 或者又叫做 `Kernel Build System` 是一个用来管理构建内核及其模块的特殊框架。`kbuild` 文件的语法与 makefile 一样。文件[scripts/Kbuild.include](https://github.com/torvalds/linux/blob/master/scripts/Kbuild.include) 为 `kbuild` 系统提供了一些常规的定义。因为我们包含了这个 `kbuild` 文件，我们可以看到和不同工具关联的这些变量的定义，这些工具会在内核和模块编译过程中被使用（比如链接器、编译器、来自 [binutils](http://www.gnu.org/software/binutils/) 的二进制工具包 ，等等）：

```
AS      = $(CROSS_COMPILE)as
LD      = $(CROSS_COMPILE)ld
CC      = $(CROSS_COMPILE)gcc
CPP     = $(CC) -E
AR      = $(CROSS_COMPILE)ar
NM      = $(CROSS_COMPILE)nm
STRIP       = $(CROSS_COMPILE)strip
OBJCOPY     = $(CROSS_COMPILE)objcopy
OBJDUMP     = $(CROSS_COMPILE)objdump
AWK     = awk
...
...
...

```

在这些定义好的变量后面，我们又定义了两个变量：`USERINCLUDE` 和 `LINUXINCLUDE`。他们包含了头文件的路径（第一个是给用户用的，第二个是给内核用的）：

```
USERINCLUDE    := \
        -I$(srctree)/arch/$(hdr-arch)/include/uapi \
        -Iarch/$(hdr-arch)/include/generated/uapi \
        -I$(srctree)/include/uapi \
        -Iinclude/generated/uapi \
        -include $(srctree)/include/linux/kconfig.h

LINUXINCLUDE    := \
        -I$(srctree)/arch/$(hdr-arch)/include \
        ...

```

以及给 C 编译器的标准标志：

```
KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
           -fno-strict-aliasing -fno-common \
           -Werror-implicit-function-declaration \
           -Wno-format-security \
           -std=gnu89

```

这并不是最终确定的编译器标志，它们还可以在其他 makefile 里面更新（比如 `arch/` 里面的 kbuild）。变量定义完之后，全部会被导出供其他 makefile 使用。

下面的两个变量 `RCS_FIND_IGNORE` 和 `RCS_TAR_IGNORE` 包含了被版本控制系统忽略的文件：

```
export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o    \
              -name CVS -o -name .pc -o -name .hg -o -name .git \) \
              -prune -o
export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
             --exclude CVS --exclude .pc --exclude .hg --exclude .git

```

这就是全部了，我们已经完成了所有的准备工作，下一个点就是如果构建`vmlinux`。

### 直面内核构建

现在我们已经完成了所有的准备工作，根 makefile（注：内核根目录下的 makefile）的下一步工作就是和编译内核相关的了。在这之前，我们不会在终端看到 `make` 命令输出的任何东西。但是现在编译的第一步开始了，这里我们需要从内核根 makefile 的 [598](https://github.com/torvalds/linux/blob/master/Makefile#L598) 行开始，这里可以看到目标`vmlinux`：

```
all: vmlinux
    include arch/$(SRCARCH)/Makefile

```

不要操心我们略过的从 `export RCS_FIND_IGNORE.....` 到 `all: vmlinux.....` 这一部分 makefile 代码，他们只是负责根据各种配置文件（`make *.config`）生成不同目标内核的，因为之前我就说了这一部分我们只讨论构建内核的通用途径。

目标 `all:` 是在命令行如果不指定具体目标时默认使用的目标。你可以看到这里包含了架构相关的 makefile（在这里就指的是 [arch/x86/Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/Makefile)）。从这一时刻起，我们会从这个 makefile 继续进行下去。如我们所见，目标 `all` 依赖于根 makefile 后面声明的 `vmlinux`：

```
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE

```

`vmlinux` 是 linux 内核的静态链接可执行文件格式。脚本 [scripts/link-vmlinux.sh](https://github.com/torvalds/linux/blob/master/scripts/link-vmlinux.sh) 把不同的编译好的子模块链接到一起形成了 vmlinux。

第二个目标是 `vmlinux-deps`，它的定义如下：

```
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)

```

它是由内核代码下的每个顶级目录的 `built-in.o` 组成的。之后我们还会检查内核所有的目录，`kbuild` 会编译各个目录下所有的对应 `$(obj-y)` 的源文件。接着调用 `$(LD) -r` 把这些文件合并到一个 `build-in.o` 文件里。此时我们还没有`vmlinux-deps`，所以目标 `vmlinux` 现在还不会被构建。对我而言 `vmlinux-deps` 包含下面的文件：

```
arch/x86/kernel/vmlinux.lds arch/x86/kernel/head_64.o
arch/x86/kernel/head64.o    arch/x86/kernel/head.o
init/built-in.o             usr/built-in.o
arch/x86/built-in.o         kernel/built-in.o
mm/built-in.o               fs/built-in.o
ipc/built-in.o              security/built-in.o
crypto/built-in.o           block/built-in.o
lib/lib.a                   arch/x86/lib/lib.a
lib/built-in.o              arch/x86/lib/built-in.o
drivers/built-in.o          sound/built-in.o
firmware/built-in.o         arch/x86/pci/built-in.o
arch/x86/power/built-in.o   arch/x86/video/built-in.o
net/built-in.o

```

下一个可以被执行的目标如下：

```
$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
$(vmlinux-dirs): prepare scripts
    $(Q)$(MAKE) $(build)=$@

```

就像我们看到的，`vmlinux-dir` 依赖于两部分：`prepare` 和 `scripts`。第一个 `prepare` 定义在内核的根 `makefile` 中，准备工作分成三个阶段：

```
prepare: prepare0
prepare0: archprepare FORCE
    $(Q)$(MAKE) $(build)=.
archprepare: archheaders archscripts prepare1 scripts_basic

prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
                   include/config/auto.conf
    $(cmd_crmodverdir)
prepare2: prepare3 outputmakefile asm-generic

```

第一个 `prepare0` 展开到 `archprepare` ，后者又展开到 `archheader` 和 `archscripts`，这两个变量定义在 `x86_64` 相关的 [Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/Makefile)。让我们看看这个文件。`x86_64` 特定的 makefile 从变量定义开始，这些变量都是和特定架构的配置文件 ([defconfig](https://github.com/torvalds/linux/tree/master/arch/x86/configs)，等等)有关联。在定义了编译 [16-bit](https://en.wikipedia.org/wiki/Real_mode) 代码的编译选项之后，根据变量 `BITS` 的值，如果是 `32`， 汇编代码、链接器、以及其它很多东西（全部的定义都可以在[arch/x86/Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/Makefile)找到）对应的参数就是 `i386`，而 `64` 就对应的是 `x86_84`。

第一个目标是 makefile 生成的系统调用列表（syscall table）中的 `archheaders` ：

```
archheaders:
    $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all

```

第二个目标是 makefile 里的 `archscripts`：

```
archscripts: scripts_basic
    $(Q)$(MAKE) $(build)=arch/x86/tools relocs

```

我们可以看到 `archscripts` 是依赖于根 [Makefile](https://github.com/torvalds/linux/blob/master/Makefile)里的`scripts_basic` 。首先我们可以看出 `scripts_basic` 是按照 [scripts/basic](https://github.com/torvalds/linux/blob/master/scripts/basic/Makefile) 的 makefile 执行 make 的：

```
scripts_basic:
    $(Q)$(MAKE) $(build)=scripts/basic

```

`scripts/basic/Makefile` 包含了编译两个主机程序 `fixdep` 和 `bin2` 的目标：

```
hostprogs-y := fixdep
hostprogs-$(CONFIG_BUILD_BIN2C)     += bin2c
always      := $(hostprogs-y)

$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep

```

第一个工具是 `fixdep`：用来优化 [gcc](https://gcc.gnu.org/) 生成的依赖列表，然后在重新编译源文件的时候告诉make。第二个工具是 `bin2c`，它依赖于内核配置选项 `CONFIG_BUILD_BIN2C`，并且它是一个用来将标准输入接口（LCTT 译注：即 stdin）收到的二进制流通过标准输出接口（即：stdout）转换成 C 头文件的非常小的 C 程序。你可能注意到这里有些奇怪的标志，如 `hostprogs-y` 等。这个标志用于所有的 `kbuild` 文件，更多的信息你可以从[documentation](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/makefiles.txt) 获得。在我们这里， `hostprogs-y` 告诉 `kbuild` 这里有个名为 `fixed` 的程序，这个程序会通过和 `Makefile` 相同目录的 `fixdep.c` 编译而来。

执行 make 之后，终端的第一个输出就是 `kbuild` 的结果：

```
$ make
  HOSTCC  scripts/basic/fixdep

```

当目标 `script_basic` 被执行，目标 `archscripts` 就会 make [arch/x86/tools](https://github.com/torvalds/linux/blob/master/arch/x86/tools/Makefile) 下的 makefile 和目标 `relocs`:

```
$(Q)$(MAKE) $(build)=arch/x86/tools relocs

```

包含了[重定位](https://en.wikipedia.org/wiki/Relocation_%28computing%29) 的信息的代码 `relocs_32.c` 和 `relocs_64.c` 将会被编译，这可以在`make` 的输出中看到：

```
  HOSTCC  arch/x86/tools/relocs_32.o
  HOSTCC  arch/x86/tools/relocs_64.o
  HOSTCC  arch/x86/tools/relocs_common.o
  HOSTLD  arch/x86/tools/relocs

```

在编译完 `relocs.c` 之后会检查 `version.h`:

```
$(version_h): $(srctree)/Makefile FORCE
    $(call filechk,version.h)
    $(Q)rm -f $(old_version_h)

```

我们可以在输出看到它：

```
CHK     include/config/kernel.release

```

以及在内核的根 Makefiel 使用 `arch/x86/include/generated/asm` 的目标 `asm-generic` 来构建 `generic` 汇编头文件。在目标 `asm-generic` 之后，`archprepare` 就完成了，所以目标 `prepare0` 会接着被执行，如我上面所写：

```
prepare0: archprepare FORCE
    $(Q)$(MAKE) $(build)=.

```

注意 `build`，它是定义在文件 [scripts/Kbuild.include](https://github.com/torvalds/linux/blob/master/scripts/Kbuild.include)，内容是这样的：

```
build := -f $(srctree)/scripts/Makefile.build obj

```

或者在我们的例子中，它就是当前源码目录路径：`.`：

```
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj=.

```

脚本 [scripts/Makefile.build](https://github.com/torvalds/linux/blob/master/scripts/Makefile.build) 通过参数 `obj` 给定的目录找到 `Kbuild` 文件，然后引入 `kbuild` 文件：

```
include $(kbuild-file)

```

并根据这个构建目标。我们这里 `.` 包含了生成 `kernel/bounds.s` 和 `arch/x86/kernel/asm-offsets.s` 的 [Kbuild](https://github.com/torvalds/linux/blob/master/Kbuild) 文件。在此之后，目标 `prepare` 就完成了它的工作。 `vmlinux-dirs` 也依赖于第二个目标 `scripts` ，它会编译接下来的几个程序：`filealias`，`mk_elfconfig`，`modpost` 等等。之后，`scripts/host-programs` 就可以开始编译我们的目标 `vmlinux-dirs` 了。

首先，我们先来理解一下 `vmlinux-dirs` 都包含了那些东西。在我们的例子中它包含了下列内核目录的路径：

```
init usr arch/x86 kernel mm fs ipc security crypto block
drivers sound firmware arch/x86/pci arch/x86/power
arch/x86/video net lib arch/x86/lib

```

我们可以在内核的根 [Makefile](https://github.com/torvalds/linux/blob/master/Makefile) 里找到 `vmlinux-dirs` 的定义：

```
vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
             $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
             $(net-y) $(net-m) $(libs-y) $(libs-m)))

init-y      := init/
drivers-y   := drivers/ sound/ firmware/
net-y       := net/
libs-y      := lib/
...
...
...

```

这里我们借助函数 `patsubst` 和 `filter`去掉了每个目录路径里的符号 `/`，并且把结果放到 `vmlinux-dirs` 里。所以我们就有了 `vmlinux-dirs` 里的目录列表，以及下面的代码：

```
$(vmlinux-dirs): prepare scripts
    $(Q)$(MAKE) $(build)=$@

```

符号 `$@` 在这里代表了 `vmlinux-dirs`，这就表明程序会递归遍历从 `vmlinux-dirs` 以及它内部的全部目录（依赖于配置），并且在对应的目录下执行 `make` 命令。我们可以在输出看到结果：

```
  CC      init/main.o
  CHK     include/generated/compile.h
  CC      init/version.o
  CC      init/do_mounts.o
  ...
  CC      arch/x86/crypto/glue_helper.o
  AS      arch/x86/crypto/aes-x86_64-asm_64.o
  CC      arch/x86/crypto/aes_glue.o
  ...
  AS      arch/x86/entry/entry_64.o
  AS      arch/x86/entry/thunk_64.o
  CC      arch/x86/entry/syscall_64.o

```

每个目录下的源代码将会被编译并且链接到 `built-io.o` 里：

```
$ find . -name built-in.o
./arch/x86/crypto/built-in.o
./arch/x86/crypto/sha-mb/built-in.o
./arch/x86/net/built-in.o
./init/built-in.o
./usr/built-in.o
...
...

```

好了，所有的 `built-in.o` 都构建完了，现在我们回到目标 `vmlinux` 上。你应该还记得，目标 `vmlinux` 是在内核的根makefile 里。在链接 `vmlinux` 之前，系统会构建 [samples](https://github.com/torvalds/linux/tree/master/samples), [Documentation](https://github.com/torvalds/linux/tree/master/Documentation) 等等，但是如上文所述，我不会在本文描述这些。

```
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
    ...
    ...
    +$(call if_changed,link-vmlinux)

```

你可以看到，调用脚本 [scripts/link-vmlinux.sh](https://github.com/torvalds/linux/blob/master/scripts/link-vmlinux.sh) 的主要目的是把所有的 `built-in.o` 链接成一个静态可执行文件，和生成 [System.map](https://en.wikipedia.org/wiki/System.map)。 最后我们来看看下面的输出：

```
  LINK    vmlinux
  LD      vmlinux.o
  MODPOST vmlinux.o
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  LD      init/built-in.o
  KSYM    .tmp_kallsyms1.o
  KSYM    .tmp_kallsyms2.o
  LD      vmlinux
  SORTEX  vmlinux
  SYSMAP  System.map

```

`vmlinux` 和`System.map` 生成在内核源码树根目录下。

```
$ ls vmlinux System.map
System.map  vmlinux

```

这就是全部了，`vmlinux` 构建好了，下一步就是创建 [bzImage](https://en.wikipedia.org/wiki/Vmlinux#bzImage).

### 制作bzImage

`bzImage` 就是压缩了的 linux 内核镜像。我们可以在构建了 `vmlinux` 之后通过执行 `make bzImage` 获得`bzImage`。同时我们可以仅仅执行 `make` 而不带任何参数也可以生成 `bzImage` ，因为它是在 [arch/x86/kernel/Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/Makefile) 里预定义的、默认生成的镜像：

```
all: bzImage

```

让我们看看这个目标，它能帮助我们理解这个镜像是怎么构建的。我已经说过了 `bzImage` 是被定义在 [arch/x86/kernel/Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/Makefile)，定义如下：

```
bzImage: vmlinux
    $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
    $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
    $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@

```

在这里我们可以看到第一次为 boot 目录执行 `make`，在我们的例子里是这样的：

```
boot := arch/x86/boot

```

现在的主要目标是编译目录 `arch/x86/boot` 和 `arch/x86/boot/compressed` 的代码，构建 `setup.bin` 和 `vmlinux.bin`，最后用这两个文件生成 `bzImage`。第一个目标是定义在 [arch/x86/boot/Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/boot/Makefile) 的 `$(obj)/setup.elf`:

```
$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
    $(call if_changed,ld)

```

我们已经在目录 `arch/x86/boot` 有了链接脚本 `setup.ld`，和扩展到 `boot` 目录下全部源代码的变量 `SETUP_OBJS` 。我们可以看看第一个输出：

```
  AS      arch/x86/boot/bioscall.o
  CC      arch/x86/boot/cmdline.o
  AS      arch/x86/boot/copy.o
  HOSTCC  arch/x86/boot/mkcpustr
  CPUSTR  arch/x86/boot/cpustr.h
  CC      arch/x86/boot/cpu.o
  CC      arch/x86/boot/cpuflags.o
  CC      arch/x86/boot/cpucheck.o
  CC      arch/x86/boot/early_serial_console.o
  CC      arch/x86/boot/edd.o

```

下一个源码文件是 [arch/x86/boot/header.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S)，但是我们不能现在就编译它，因为这个目标依赖于下面两个头文件：

```
$(obj)/header.o: $(obj)/voffset.h $(obj)/zoffset.h

```

第一个头文件 `voffset.h` 是使用 `sed` 脚本生成的，包含用 `nm` 工具从 `vmlinux` 获取的两个地址：

```
#define VO__end 0xffffffff82ab0000
#define VO__text 0xffffffff81000000

```

这两个地址是内核的起始和结束地址。第二个头文件 `zoffset.h` 在 [arch/x86/boot/compressed/Makefile](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/Makefile) 可以看出是依赖于目标 `vmlinux`的：

```
$(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE
    $(call if_changed,zoffset)

```

目标 `$(obj)/compressed/vmlinux` 依赖于 `vmlinux-objs-y` —— 说明需要编译目录 [arch/x86/boot/compressed](https://github.com/torvalds/linux/tree/master/arch/x86/boot/compressed) 下的源代码，然后生成 `vmlinux.bin`、`vmlinux.bin.bz2`，和编译工具 `mkpiggy`。我们可以在下面的输出看出来：

```
  LDS     arch/x86/boot/compressed/vmlinux.lds
  AS      arch/x86/boot/compressed/head_64.o
  CC      arch/x86/boot/compressed/misc.o
  CC      arch/x86/boot/compressed/string.o
  CC      arch/x86/boot/compressed/cmdline.o
  OBJCOPY arch/x86/boot/compressed/vmlinux.bin
  BZIP2   arch/x86/boot/compressed/vmlinux.bin.bz2
  HOSTCC  arch/x86/boot/compressed/mkpiggy

```

`vmlinux.bin` 是去掉了调试信息和注释的 `vmlinux` 二进制文件，加上了占用了 `u32` （LCTT 译注：即4-Byte）的长度信息的 `vmlinux.bin.all` 压缩后就是 `vmlinux.bin.bz2`。其中 `vmlinux.bin.all` 包含了 `vmlinux.bin` 和`vmlinux.relocs`（LCTT 译注：vmlinux 的重定位信息），其中 `vmlinux.relocs` 是 `vmlinux` 经过程序 `relocs` 处理之后的 `vmlinux` 镜像（见上文所述）。我们现在已经获取到了这些文件，汇编文件 `piggy.S` 将会被 `mkpiggy` 生成、然后编译：

```
  MKPIGGY arch/x86/boot/compressed/piggy.S
  AS      arch/x86/boot/compressed/piggy.o

```

这个汇编文件会包含经过计算得来的、压缩内核的偏移信息。处理完这个汇编文件，我们就可以看到 `zoffset` 生成了：

```
  ZOFFSET arch/x86/boot/zoffset.h

```

现在 `zoffset.h` 和 `voffset.h` 已经生成了，[arch/x86/boot](https://github.com/torvalds/linux/tree/master/arch/x86/boot/) 里的源文件可以继续编译：

```
  AS      arch/x86/boot/header.o
  CC      arch/x86/boot/main.o
  CC      arch/x86/boot/mca.o
  CC      arch/x86/boot/memory.o
  CC      arch/x86/boot/pm.o
  AS      arch/x86/boot/pmjump.o
  CC      arch/x86/boot/printf.o
  CC      arch/x86/boot/regs.o
  CC      arch/x86/boot/string.o
  CC      arch/x86/boot/tty.o
  CC      arch/x86/boot/video.o
  CC      arch/x86/boot/video-mode.o
  CC      arch/x86/boot/video-vga.o
  CC      arch/x86/boot/video-vesa.o
  CC      arch/x86/boot/video-bios.o

```

所有的源代码会被编译，他们最终会被链接到 `setup.elf` ：

```
  LD      arch/x86/boot/setup.elf

```

或者：

```
ld -m elf_x86_64   -T arch/x86/boot/setup.ld arch/x86/boot/a20.o arch/x86/boot/bioscall.o arch/x86/boot/cmdline.o arch/x86/boot/copy.o arch/x86/boot/cpu.o arch/x86/boot/cpuflags.o arch/x86/boot/cpucheck.o arch/x86/boot/early_serial_console.o arch/x86/boot/edd.o arch/x86/boot/header.o arch/x86/boot/main.o arch/x86/boot/mca.o arch/x86/boot/memory.o arch/x86/boot/pm.o arch/x86/boot/pmjump.o arch/x86/boot/printf.o arch/x86/boot/regs.o arch/x86/boot/string.o arch/x86/boot/tty.o arch/x86/boot/video.o arch/x86/boot/video-mode.o arch/x86/boot/version.o arch/x86/boot/video-vga.o arch/x86/boot/video-vesa.o arch/x86/boot/video-bios.o -o arch/x86/boot/setup.elf

```

最后的两件事是创建包含目录 `arch/x86/boot/*` 下的编译过的代码的 `setup.bin`：

```
objcopy  -O binary arch/x86/boot/setup.elf arch/x86/boot/setup.bin

```

以及从 `vmlinux` 生成 `vmlinux.bin` :

```
objcopy  -O binary -R .note -R .comment -S arch/x86/boot/compressed/vmlinux arch/x86/boot/vmlinux.bin

```

最最后，我们编译主机程序 [arch/x86/boot/tools/build.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/tools/build.c)，它将会用来把 `setup.bin` 和 `vmlinux.bin` 打包成 `bzImage`:

```
arch/x86/boot/tools/build arch/x86/boot/setup.bin arch/x86/boot/vmlinux.bin arch/x86/boot/zoffset.h arch/x86/boot/bzImage

```

实际上 `bzImage` 就是把 `setup.bin` 和 `vmlinux.bin` 连接到一起。最终我们会看到输出结果，就和那些用源码编译过内核的同行的结果一样：

```
Setup is 16268 bytes (padded to 16384 bytes).
System is 4704 kB
CRC 94a88f9a
Kernel: arch/x86/boot/bzImage is ready  (#5)

```

全部结束。

### 结论

这就是本文的结尾部分。本文我们了解了编译内核的全部步骤：从执行 `make` 命令开始，到最后生成 `bzImage`。我知道，linux 内核的 makefile 和构建 linux 的过程第一眼看起来可能比较迷惑，但是这并不是很难。希望本文可以帮助你理解构建 linux 内核的整个流程。

### 链接

* [GNU make util](https://en.wikipedia.org/wiki/Make_%28software%29)
* [Linux kernel top Makefile](https://github.com/torvalds/linux/blob/master/Makefile)
* [cross-compilation](https://en.wikipedia.org/wiki/Cross_compiler)
* [Ctags](https://en.wikipedia.org/wiki/Ctags)
* [sparse](https://en.wikipedia.org/wiki/Sparse)
* [bzImage](https://en.wikipedia.org/wiki/Vmlinux#bzImage)
* [uname](https://en.wikipedia.org/wiki/Uname)
* [shell](https://en.wikipedia.org/wiki/Shell_%28computing%29)
* [Kbuild](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kbuild.txt)
* [binutils](http://www.gnu.org/software/binutils/)
* [gcc](https://gcc.gnu.org/)
* [Documentation](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/makefiles.txt)
* [System.map](https://en.wikipedia.org/wiki/System.map)
* [Relocation](https://en.wikipedia.org/wiki/Relocation_%28computing%29)

---

via: <https://github.com/0xAX/linux-insides/blob/master/Misc/how_kernel_compiled.md>

译者：[oska874](https://github.com/oska874) 校对：[wxy](https://github.com/wxy)

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


Shilpa Nair 分享的 RedHat Linux 包管理方面的面试经验

Summary: Shilpa Nair 刚于2015年毕业。她之后去了一家位于 Noida，Delhi 的国家新闻电视台，应聘实习生的岗位。在她去年毕业季的时候，常逛 Tecmint 寻求作业上的帮助。从那时开始，她就常去 Tecmint。  有关 RPM 方面的 Linux 面试题 所有的问题和回答都是 Shilpa Nair 根据回忆重写的。  大家好！我是来自 Delhi 的Shilpa Nair。我不久前才顺利毕业，正寻找一个实习的机会。在大学早期的时候，我就对 UNIX 十分喜爱，所以我也希望这个机会能适合我，满足我的兴趣。我被提问了很多问题，大部分都是关于 RedHat 包管理的基础问题。  下面就是我被

# Shilpa Nair 分享的 RedHat Linux 包管理方面的面试经验

**Shilpa Nair 刚于2015年毕业。她之后去了一家位于 Noida，Delhi 的国家新闻电视台，应聘实习生的岗位。在她去年毕业季的时候，常逛 Tecmint 寻求作业上的帮助。从那时开始，她就常去 Tecmint。**

<img src="content_image/album_201509_13_201307tx8vpzv28w0ca6z2.jpg" alt="Linux Interview Questions on RPM" title="Linux Interview Questions on RPM">

*有关 RPM 方面的 Linux 面试题*

所有的问题和回答都是 Shilpa Nair 根据回忆重写的。

>
> “大家好！我是来自 Delhi 的Shilpa Nair。我不久前才顺利毕业，正寻找一个实习的机会。在大学早期的时候，我就对 UNIX 十分喜爱，所以我也希望这个机会能适合我，满足我的兴趣。我被提问了很多问题，大部分都是关于 RedHat 包管理的基础问题。”
>
>
>

下面就是我被问到的问题，和对应的回答。我仅贴出了与 RedHat GNU/Linux 包管理相关的，也是主要被提问的。

### 1，Linux 里如何查找一个包安装与否？假设你需要确认 ‘nano’ 有没有安装，你怎么做？

**回答**：为了确认 nano 软件包有没有安装，我们可以使用 rpm 命令，配合 -q 和 -a 选项来查询所有已安装的包

```
# rpm -qa nano
或
# rpm -qa | grep -i nano

nano-2.3.1-10.el7.x86_64

```

同时包的名字必须是完整的，不完整的包名会返回到提示符，不打印任何东西，就是说这包（包名字不全）未安装。下面的例子会更好理解些：

我们通常使用 vim 替代 vi 命令。当时如果我们查找安装包 vi/vim 的时候，我们就会看到标准输出上没有任何结果。

```
# vi
# vim

```

尽管如此，我们仍然可以像上面一样运行 vi/vim 命令来清楚地知道包有没有安装。只是因为我们不知道它的完整包名才不能找到的。如果我们不确切知道完整的文件名，我们可以使用通配符：

```
# rpm -qa vim*

vim-minimal-7.4.160-1.el7.x86_64

```

通过这种方式，我们可以获得任何软件包的信息，安装与否。

### 2. 你如何使用 rpm 命令安装 XYZ 软件包？

**回答**：我们可以使用 rpm 命令安装任何的软件包（\*.rpm），像下面这样，选项 -i（安装），-v（冗余或者显示额外的信息）和 -h（在安装过程中，打印#号显示进度）。

```
# rpm -ivh peazip-1.11-1.el6.rf.x86_64.rpm

Preparing...                          ################################# [100%]
Updating / installing...
   1:peazip-1.11-1.el6.rf             ################################# [100%]

```

如果要升级一个早期版本的包，应加上 -U 选项，选项 -v 和 -h 可以确保我们得到用 # 号表示的冗余输出，这增加了可读性。

### 3. 你已经安装了一个软件包（假设是 httpd），现在你想看看软件包创建并安装的所有文件和目录，你会怎么做？

**回答**：使用选项 -l（列出所有文件）和 -q（查询）列出 httpd 软件包安装的所有文件（Linux 哲学：所有的都是文件，包括目录）。

```
# rpm -ql httpd

/etc/httpd
/etc/httpd/conf
/etc/httpd/conf.d
...

```

### 4. 假如你要移除一个软件包，叫 postfix。你会怎么做？

**回答**：首先我们需要知道什么包安装了 postfix。查找安装 postfix 的包名后，使用 -e（擦除/卸载软件包）和 -v（冗余输出）两个选项来实现。

```
# rpm -qa postfix*

postfix-2.10.1-6.el7.x86_64

```

然后移除 postfix，如下:

```
# rpm -ev postfix-2.10.1-6.el7.x86_64

Preparing packages...
postfix-2:3.0.1-2.fc22.x86_64

```

### 5. 获得一个已安装包的具体信息，如版本，发行号，安装日期，大小，总结和一个简短的描述。

**回答**：我们通过使用 rpm 的选项 -qi，后面接包名，可以获得关于一个已安装包的具体信息。

举个例子，为了获得 openssh 包的具体信息，我需要做的就是：

```
# rpm -qi openssh

[root@tecmint tecmint]# rpm -qi openssh
Name        : openssh
Version     : 6.8p1
Release     : 5.fc22
Architecture: x86_64
Install Date: Thursday 28 May 2015 12:34:50 PM IST
Group       : Applications/Internet
Size        : 1542057
License     : BSD
....

```

### 6. 假如你不确定一个指定包的配置文件在哪，比如 httpd。你如何找到所有 httpd 提供的配置文件列表和位置。

**回答**： 我们需要用选项 -c 接包名，这会列出所有配置文件的名字和他们的位置。

```
# rpm -qc httpd

/etc/httpd/conf.d/autoindex.conf
/etc/httpd/conf.d/userdir.conf
/etc/httpd/conf.d/welcome.conf
/etc/httpd/conf.modules.d/00-base.conf
/etc/httpd/conf/httpd.conf
/etc/sysconfig/httpd

```

相似地，我们可以列出所有相关的文档文件，如下：

```
# rpm -qd httpd

/usr/share/doc/httpd/ABOUT_APACHE
/usr/share/doc/httpd/CHANGES
/usr/share/doc/httpd/LICENSE
...

```

我们也可以列出所有相关的证书文件，如下：

```
# rpm -qL openssh

/usr/share/licenses/openssh/LICENCE

```

忘了说明上面的选项 -d 和 -L 分别表示 “文档” 和 “证书”，抱歉。

### 7. 你找到了一个配置文件，位于‘/usr/share/alsa/cards/AACI.conf’，现在你不确定该文件属于哪个包。你如何查找出包的名字？

**回答**：当一个包被安装后，相关的信息就存储在了数据库里。所以使用选项 -qf（-f 查询包拥有的文件）很容易追踪谁提供了上述的包。

```
# rpm -qf /usr/share/alsa/cards/AACI.conf
alsa-lib-1.0.28-2.el7.x86_64

```

类似地，我们可以查找（谁提供的）关于任何子包，文档和证书文件的信息。

### 8. 你如何使用 rpm 查找最近安装的软件列表？

**回答**：如刚刚说的，每一样被安装的文件都记录在了数据库里。所以这并不难，通过查询 rpm 的数据库，找到最近安装软件的列表。

我们通过运行下面的命令，使用选项 -last（打印出最近安装的软件）达到目的。

```
# rpm -qa --last

```

上面的命令会打印出所有安装的软件，最近安装的软件在列表的顶部。

如果我们关心的是找出特定的包，我们可以使用 grep 命令从列表中匹配包（假设是 sqlite ），简单如下：

```
# rpm -qa --last | grep -i sqlite

sqlite-3.8.10.2-1.fc22.x86_64                 Thursday 18 June 2015 05:05:43 PM IST

```

我们也可以获得10个最近安装的软件列表，简单如下：

```
# rpm -qa --last | head

```

我们可以重定义一下，输出想要的结果，简单如下：

```
# rpm -qa --last | head -n 2

```

上面的命令中，-n 代表数目，后面接一个常数值。该命令是打印2个最近安装的软件的列表。

### 9. 安装一个包之前，你如果要检查其依赖。你会怎么做？

**回答**：检查一个 rpm 包（XYZ.rpm）的依赖，我们可以使用选项 -q（查询包），-p（指定包名）和 -R（查询/列出该包依赖的包，嗯，就是依赖）。

```
# rpm -qpR gedit-3.16.1-1.fc22.i686.rpm

/bin/sh
/usr/bin/env
glib2(x86-32) >= 2.40.0
gsettings-desktop-schemas
gtk3(x86-32) >= 3.16
gtksourceview3(x86-32) >= 3.16
gvfs
libX11.so.6
...

```

### 10. rpm 是不是一个前端的包管理工具呢？

**回答**：**不是！**rpm 是一个后端管理工具，适用于基于 Linux 发行版的 RPM （此处指 Redhat Package Management）。

[YUM](http://www.tecmint.com/20-linux-yum-yellowdog-updater-modified-commands-for-package-mangement/)，全称 Yellowdog Updater Modified，是一个 RPM 的前端工具。YUM 命令自动完成所有工作，包括解决依赖和其他一切事务。

最近，[DNF](/article-5718-1.html)（YUM命令升级版）在Fedora 22发行版中取代了 YUM。尽管 YUM 仍然可以在 RHEL 和 CentOS 平台使用，我们也可以安装 dnf，与 YUM 命令共存使用。据说 DNF 较于 YUM 有很多提高。

知道更多总是好的，保持自我更新。现在我们移步到前端部分来谈谈。

### 11. 你如何列出一个系统上面所有可用的仓库列表。

**回答**：简单地使用下面的命令，我们就可以列出一个系统上所有可用的仓库列表。

```
# yum repolist
或
# dnf repolist

Last metadata expiration check performed 0:30:03 ago on Mon Jun 22 16:50:00 2015.
repo id       repo name                      status
*fedora       Fedora 22 - x86_64             44,762
ozonos        Repository for Ozon OS         61
*updates      Fedora 22 - x86_64 - Updates

```

上面的命令仅会列出可用的仓库。如果你需要列出所有的仓库，不管可用与否，可以这样做。

```
# yum repolist all
或
# dnf repolist all

Last metadata expiration check performed 0:29:45 ago on Mon Jun 22 16:50:00 2015.
repo id           repo name                       status
*fedora           Fedora 22 - x86_64              enabled: 44,762
fedora-debuginfo  Fedora 22 - x86_64 - Debug      disabled
fedora-source     Fedora 22 - Source              disabled
ozonos            Repository for Ozon OS          enabled:     61
*updates          Fedora 22 - x86_64 - Updates    enabled:  5,018
updates-debuginfo Fedora 22 - x86_64 - Updates - Debug

```

### 12. 你如何列出一个系统上所有可用并且安装了的包？

**回答**：列出一个系统上所有可用的包，我们可以这样做：

```
# yum list available
或
# dnf list available

ast metadata expiration check performed 0:34:09 ago on Mon Jun 22 16:50:00 2015.
Available Packages
0ad.x86_64                 0.0.18-1.fc22                   fedora
0ad-data.noarch            0.0.18-1.fc22                   fedora
0install.x86_64            2.6.1-2.fc21                    fedora
0xFFFF.x86_64              0.3.9-11.fc22                   fedora
2048-cli.x86_64            0.9-4.git20141214.723738c.fc22  fedora
2048-cli-nocurses.x86_64   0.9-4.git20141214.723738c.fc22  fedora
....

```

而列出一个系统上所有已安装的包，我们可以这样做。

```
# yum list installed
或
# dnf list installed

Last metadata expiration check performed 0:34:30 ago on Mon Jun 22 16:50:00 2015.
Installed Packages
GeoIP.x86_64                    1.6.5-1.fc22       @System
GeoIP-GeoLite-data.noarch       2015.05-1.fc22     @System
NetworkManager.x86_64           1:1.0.2-1.fc22     @System
NetworkManager-libnm.x86_64     1:1.0.2-1.fc22     @System
aajohan-comfortaa-fonts.noarch  2.004-4.fc22       @System
....

```

而要同时满足两个要求的时候，我们可以这样做。

```
# yum list
或
# dnf list

Last metadata expiration check performed 0:32:56 ago on Mon Jun 22 16:50:00 2015.
Installed Packages
GeoIP.x86_64                    1.6.5-1.fc22       @System
GeoIP-GeoLite-data.noarch       2015.05-1.fc22     @System
NetworkManager.x86_64           1:1.0.2-1.fc22     @System
NetworkManager-libnm.x86_64     1:1.0.2-1.fc22     @System
aajohan-comfortaa-fonts.noarch  2.004-4.fc22       @System
acl.x86_64                      2.2.52-7.fc22      @System
....

```

### 13. 你会怎么在一个系统上面使用 YUM 或 DNF 分别安装和升级一个包与一组包？

**回答**：安装一个包（假设是 nano），我们可以这样做，

```
  # yum install nano

```

而安装一组包（假设是 Haskell），我们可以这样做，

```
  # yum groupinstall 'haskell'

```

升级一个包（还是 nano），我们可以这样做，

```
  # yum update nano

```

而为了升级一组包（还是 haskell），我们可以这样做，

```
# yum groupupdate 'haskell'
```

### 14. 你会如何同步一个系统上面的所有安装软件到稳定发行版？

**回答**：我们可以一个系统上（假设是 CentOS 或者 Fedora）的所有包到稳定发行版，如下，

```
 # yum distro-sync      [在 CentOS/ RHEL]
 或
 # dnf distro-sync      [在 Fedora 20之后版本]

```

似乎来面试之前你做了相当不多的功课，很好！在进一步交谈前，我还想问一两个问题。

### 15. 你对 YUM 本地仓库熟悉吗？你尝试过建立一个本地 YUM 仓库吗？让我们简单看看你会怎么建立一个本地 YUM 仓库。

**回答**：首先，感谢你的夸奖。回到问题，我必须承认我对本地 YUM 仓库十分熟悉，并且在我的本地主机上也部署过，作为测试用。

1、 为了建立本地 YUM 仓库，我们需要安装下面三个包：

```
# yum install deltarpm  python-deltarpm  createrepo

```

2、 新建一个目录(假设 /home/$USER/rpm)，然后复制 RedHat/CentOS DVD 上的 RPM 包到这个文件夹下

```
# mkdir /home/$USER/rpm
# cp /path/to/rpm/on/DVD/*.rpm /home/$USER/rpm

```

3、 新建基本的库头文件如下。

```
# createrepo -v /home/$USER/rpm

```

4、 在路径 /etc/yum.repo.d 下创建一个 .repo 文件（如 abc.repo):

```
cd /etc/yum.repos.d && cat << EOF abc.repo
[local-installation]name=yum-local
baseurl=file:///home/$USER/rpm
enabled=1
gpgcheck=0
EOF

```

**重要**：用你的用户名替换掉 $USER。

以上就是创建一个本地 YUM 仓库所要做的全部工作。我们现在可以从这里安装软件了，相对快一些，安全一些，并且最重要的是不需要 Internet 连接。

好了！面试过程很愉快。我已经问完了。我会将你推荐给 HR。你是一个年轻且十分聪明的候选者，我们很愿意你加入进来。如果你有任何问题，你可以问我。

**我**：谢谢，这确实是一次愉快的面试，我感到今天非常幸运，可以搞定这次面试...

显然，不会在这里结束。我问了很多问题，比如他们正在做的项目。我会担任什么角色，负责什么，，，balabalabala

小伙伴们，这之后的 3 天会经过 HR 轮，到时候所有问题到时候也会被写成文档。希望我当时表现不错。感谢你们所有的祝福。

谢谢伙伴们和 Tecmint，花时间来编辑我的面试经历。我相信 Tecmint 好伙伴们做了很大的努力，必要要赞一个。当我们与他人分享我们的经历的时候，其他人从我们这里知道了更多，而我们自己则发现了自己的不足。

这增加了我们的信心。如果你最近也有任何类似的面试经历，别自己蔵着。分享出来！让我们所有人都知道。你可以使用如下的表单来与我们分享你的经历。

---

via: <http://www.tecmint.com/linux-rpm-package-management-interview-questions/>

作者：[Avishek Kumar](http://www.tecmint.com/author/avishek/) 译者：[wi-cuckoo](https://github.com/wi-cuckoo) 校对：[wxy](https://github.com/wxy)

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


Xtreme 下载管理器升级带来全新用户界面

Summary: Xtreme 下载管理器, 毫无疑问是Linux界最好的下载管理器之一 , 它的新版本名叫 XDM 2015 ，这次的新版本给我们带来了全新的外观体验！ Xtreme 下载管理器，也被称作 XDM 或 XDMAN，它是一个跨平台的下载管理器，可以用于 Linux、Windows 和 Mac OS X 系统之上。同时它兼容于主流的浏览器，如 Chrome, Firefox, Safari 等，因此当你从浏览器下载东西的时候可以直接使用 XDM 下载。 当你的网络连接超慢并且需要管理下载文件的时候，像 XDM 这种软件可以帮到你大忙。例如说你在一个慢的要死的网络速度下下载一个超大文件，或者你想要暂停和恢

依赖java，看到这一句我就醉了，感觉桌面软件依赖java的，注定很慢

越改越丑

昨天装了，今天就删掉了……

今天我想用这玩意下载ed2k连接的，结果等了半天没有任何进度，看了一下详情发现这下载器蠢萌蠢萌的，直接把ed2k前缀前面再加一个http前缀就开始试图下载了……

最后滚回百度云……

顺便，ed2k的内容是VC6安装盘，试图用以证明VC6是世界上最好的编译器，用起来崩溃出错的人都是因为没有配套用Win98，国内VC6可以用半个世纪！

然而事实上快的一笔

# Xtreme 下载管理器升级带来全新用户界面

[Xtreme 下载管理器](http://xdman.sourceforge.net/), 毫无疑问是[Linux界最好的下载管理器](http://itsfoss.com/4-best-download-managers-for-linux/)之一 , 它的新版本名叫 XDM 2015 ，这次的新版本给我们带来了全新的外观体验！

Xtreme 下载管理器，也被称作 XDM 或 XDMAN，它是一个跨平台的下载管理器，可以用于 Linux、Windows 和 Mac OS X 系统之上。同时它兼容于主流的浏览器，如 Chrome, Firefox, Safari 等，因此当你从浏览器下载东西的时候可以直接使用 XDM 下载。

当你的网络连接超慢并且需要管理下载文件的时候，像 XDM 这种软件可以帮到你大忙。例如说你在一个慢的要死的网络速度下下载一个超大文件，或者你想要暂停和恢复下载的话， XDM 可以帮助你。

XDM 的主要功能：

* 暂停和恢复下载
* [从 YouTube 下载视频](http://itsfoss.com/download-youtube-videos-ubuntu/)，其他视频网站同样适用
* 强制聚合
* 下载加速
* 计划下载
* 下载限速
* 与浏览器整合
* 支持代理服务器

下面你可以看到 XDM 新旧版本之间的差别。

*老版本XDM*

*新版本XDM*

### 在基于 Ubuntu 的 Linux 发行版上安装 Xtreme下载管理器

感谢 Noobslab 提供的 PPA，你可以使用以下命令来安装 Xtreme 下载管理器。虽然 XDM 依赖 Java，但是托 PPA 的福，你不需要对其进行单独的安装。

```
sudo add-apt-repository ppa:noobslab/apps
sudo apt-get update
sudo apt-get install xdman

```

以上的 PPA 可以在 Ubuntu 或者其他基于 Ubuntu 的发行版上使用，如 Linux Mint, elementary OS, Linux Lite 等。

#### 删除 XDM

如果你是使用 PPA 安装的 XDM ，可以通过以下命令将其删除：

```
sudo apt-get remove xdman
sudo add-apt-repository --remove ppa:noobslab/apps

```

对于其他Linux发行版，可以通过以下连接下载：

* [下载 Xtreme 下载管理器](http://xdman.sourceforge.net/download.html)

---

via: <http://itsfoss.com/xtreme-download-manager-install/>

作者：[Abhishek](http://itsfoss.com/author/abhishek/) 译者：[mr-ping](https://github.com/mr-ping) 校对：[wxy](https://github.com/wxy)

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


在 Linux 中怎样将 MySQL 迁移到 MariaDB 上

Summary: 自从甲骨文收购 MySQL 后，由于甲骨文对 MySQL 的开发和维护更多倾向于闭门的立场，很多 MySQL 的开发者和用户放弃了 MySQL。在社区驱动下，促使更多人移到 MySQL 的另一个叫 MariaDB 的分支。在原有 MySQL 开发人员的带领下，MariaDB 的开发遵循开源的理念，并确保它的二进制格式与 MySQL 兼容。Linux 发行版如 Red Hat 家族（Fedora，CentOS，RHEL），Ubuntu 和 Mint，openSUSE 和 Debian 已经开始使用，并支持 MariaDB 作为 MySQL 的直接替换品。  如果你想要将 MySQL 中的数据库迁移到 MariaDB 中，这篇文章就是你所期待的。幸运的是

如果是海量数据迁移呢？ 这个方式不太方便啊。

用MyDumper并行导出、恢复

这文章本来就没有存在的价值，mysql mariadb本质都是一样的东西，只是叫的名字不一样

这情况，以后应该是mariaDB成主流，mysql成分支了

非常佩服MariaDB的开发者

迁移到mariadb后，中文全是？改了各种地方还是问号

那是你的字符集在转换过程中没处理好。

# 在 Linux 中怎样将 MySQL 迁移到 MariaDB 上

自从甲骨文收购 MySQL 后，由于甲骨文对 MySQL 的开发和维护更多倾向于闭门的立场，很多 MySQL 的开发者和用户放弃了 MySQL。在社区驱动下，促使更多人移到 MySQL 的另一个叫 MariaDB 的分支。在原有 MySQL 开发人员的带领下，MariaDB 的开发遵循开源的理念，并确保[它的二进制格式与 MySQL 兼容](https://mariadb.com/kb/en/mariadb/mariadb-vs-mysql-compatibility/)。Linux 发行版如 Red Hat 家族（Fedora，CentOS，RHEL），Ubuntu 和 Mint，openSUSE 和 Debian 已经开始使用，并支持 MariaDB 作为 MySQL 的直接替换品。

如果你想要将 MySQL 中的数据库迁移到 MariaDB 中，这篇文章就是你所期待的。幸运的是，由于他们的二进制兼容性，MySQL-to-MariaDB 迁移过程是非常简单的。如果你按照下面的步骤，将 MySQL 迁移到 MariaDB 会是无痛的。

### 准备 MySQL 数据库和表

出于演示的目的，我们在做迁移之前在数据库中创建一个测试的 MySQL 数据库和表。如果你在 MySQL 中已经有了要迁移到 MariaDB 的数据库，跳过此步骤。否则，按以下步骤操作。

在终端输入 root 密码登录到 MySQL 。

```
$ mysql -u root -p

```

创建一个数据库和表。

```
mysql> create database test01;
mysql> use test01;
mysql> create table pet(name varchar(30), owner varchar(30), species varchar(20), sex char(1));

```

在表中添加一些数据。

```
mysql> insert into pet values('brandon','Jack','puddle','m'),('dixie','Danny','chihuahua','f');

```

退出 MySQL 数据库.

### 备份 MySQL 数据库

下一步是备份现有的 MySQL 数据库。使用下面的 mysqldump 命令导出现有的数据库到文件中。运行此命令之前，请确保你的 MySQL 服务器上启用了二进制日志。如果你不知道如何启用二进制日志，请参阅结尾的教程说明。

```
$ mysqldump --all-databases --user=root --password --master-data > backupdb.sql

```

现在，在卸载 MySQL 之前先在系统上备份 my.cnf 文件。此步是可选的。

```
$ sudo cp /etc/mysql/my.cnf /opt/my.cnf.bak

```

### 卸载 MySQL

首先，停止 MySQL 服务。

```
$ sudo service mysql stop

```

或者:

```
$ sudo systemctl stop mysql

```

或:

```
$ sudo /etc/init.d/mysql stop

```

然后继续下一步，使用以下命令移除 MySQL 和配置文件。

在基于 RPM 的系统上 (例如, CentOS, Fedora 或 RHEL):

```
$ sudo yum remove mysql* mysql-server mysql-devel mysql-libs
$ sudo rm -rf /var/lib/mysql

```

在基于 Debian 的系统上(例如, Debian, Ubuntu 或 Mint):

```
$ sudo apt-get remove mysql-server mysql-client mysql-common
$ sudo apt-get autoremove
$ sudo apt-get autoclean
$ sudo deluser mysql
$ sudo rm -rf /var/lib/mysql

```

### 安装 MariaDB

在 CentOS/RHEL 7和Ubuntu（14.04或更高版本）上，最新的 MariaDB 已经包含在其官方源。在 Fedora 上，自19 版本后 MariaDB 已经替代了 MySQL。如果你使用的是旧版本或 LTS 类型如 Ubuntu 13.10 或更早的，你仍然可以通过添加其官方仓库来安装 MariaDB。

[MariaDB 网站](https://downloads.mariadb.org/mariadb/repositories/#mirror=aasaam) 提供了一个在线工具帮助你依据你的 Linux 发行版中来添加 MariaDB 的官方仓库。此工具为 openSUSE, Arch Linux, Mageia, Fedora, CentOS, RedHat, Mint, Ubuntu, 和 Debian 提供了 MariaDB 的官方仓库.

下面例子中，我们使用 Ubuntu 14.04 发行版和 CentOS 7 配置 MariaDB 库。

**Ubuntu 14.04**

```
$ sudo apt-get install software-properties-common
$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
$ sudo add-apt-repository 'deb http://mirror.mephi.ru/mariadb/repo/5.5/ubuntu trusty main'
$ sudo apt-get update
$ sudo apt-get install mariadb-server

```

**CentOS 7**

以下为 MariaDB 创建一个自定义的 yum 仓库文件。

```
$ sudo vi /etc/yum.repos.d/MariaDB.repo

```

---

```
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/5.5/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

```

---

```
$ sudo yum install MariaDB-server MariaDB-client

```

安装了所有必要的软件包后，你可能会被要求为 MariaDB 的 root 用户创建一个新密码。设置 root 的密码后，别忘了恢复备份的 my.cnf 文件。

```
$ sudo cp /opt/my.cnf /etc/mysql/

```

现在启动 MariaDB 服务。

```
$ sudo service mariadb start

```

或:

```
$ sudo systemctl start mariadb

```

或:

```
$ sudo /etc/init.d/mariadb start

```

### 导入 MySQL 的数据库

最后，我们将以前导出的数据库导入到 MariaDB 服务器中。

```
$ mysql -u root -p < backupdb.sql

```

输入你 MariaDB 的 root 密码，数据库导入过程将开始。导入过程完成后，将返回到命令提示符下。

要检查导入过程是否完全成功，请登录到 MariaDB 服务器，并查看一些样本来检查。

```
$ mysql -u root -p

```

---

```
MariaDB [(none)]> show databases;
MariaDB [(none)]> use test01;
MariaDB [test01]> select * from pet;

```

### 结论

如你在本教程中看到的，MySQL-to-MariaDB 的迁移并不难。你应该知道，MariaDB 相比 MySQL 有很多新的功能。至于配置方面，在我的测试情况下，我只是将我旧的 MySQL 配置文件（my.cnf）作为 MariaDB 的配置文件，导入过程完全没有出现任何问题。对于配置文件，我建议你在迁移之前请仔细阅读 MariaDB 配置选项的文件，特别是如果你正在使用 MySQL 的特定配置。

如果你正在运行有海量的表、包括群集或主从复制的数据库的复杂配置，看一看 Mozilla IT 和 Operations 团队的 [更详细的指南](https://blog.mozilla.org/it/2013/12/16/upgrading-from-mysql-5-1-to-mariadb-5-5/) ，或者 [官方的 MariaDB 文档](https://mariadb.com/kb/en/mariadb/documentation/)。

### 故障排除

1、 在运行 mysqldump 命令备份数据库时出现以下错误。

```
$ mysqldump --all-databases --user=root --password --master-data > backupdb.sql

```

---

```
mysqldump: Error: Binlogging on server not active

```

通过使用 "--master-data"，你可以在导出的输出中包含二进制日志信息，这对于数据库的复制和恢复是有用的。但是，二进制日志未在 MySQL 服务器启用。要解决这个错误，修改 my.cnf 文件，并在 [mysqld] 部分添加下面的选项。（LCTT 译注：事实上，如果你并没有启用二进制日志，那取消"--master-data"即可。）

```
log-bin=mysql-bin

```

保存 my.cnf 文件，并重新启动 MySQL 服务：

```
$ sudo service mysql restart

```

或者:

```
$ sudo systemctl restart mysql

```

或:

```
$ sudo /etc/init.d/mysql restart

```

---

via: <http://xmodulo.com/migrate-mysql-to-mariadb-linux.html>

作者：[Kristophorus Hadiono](http://xmodulo.com/author/kristophorus) 译者：[strugglingyouth](https://github.com/strugglingyouth) 校对：[wxy](https://github.com/wxy)

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


守卫自由的 Linux 世界

Summary: 合作是开源的一部分。OIN 的 CEO Keith Bergelt 解释说，开放创新网络（Open Invention Network）模式允许众多企业和公司决定它们该在哪较量，在哪合作。随着开源的演变，我们需要为合作创造渠道，否则我们将会有几百个团体把数十亿美元花费到同样的技术上。 开放创新网络（Open Invention Network），即 OIN，正在全球范围内开展让 Linux 远离专利诉讼的伤害的活动。它的努力得到了一千多个公司的热烈回应，它们的加入让这股力量成为了历史上最大的反专利管理组织。 开放创新网络以白帽子组织的身份创建于2005年，目的是保护 Linux 免受

很看好Linux的情怀。

# 守卫自由的 Linux 世界

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

**合作是开源的一部分。OIN 的 CEO Keith Bergelt 解释说，开放创新网络（Open Invention Network）模式允许众多企业和公司决定它们该在哪较量，在哪合作。随着开源的演变，“我们需要为合作创造渠道，否则我们将会有几百个团体把数十亿美元花费到同样的技术上。”**

[开放创新网络（Open Invention Network）](http://www.openinventionnetwork.com/)，即 OIN，正在全球范围内开展让 Linux 远离专利诉讼的伤害的活动。它的努力得到了一千多个公司的热烈回应，它们的加入让这股力量成为了历史上最大的反专利管理组织。

开放创新网络以白帽子组织的身份创建于2005年，目的是保护 Linux 免受来自许可证方面的困扰。包括 Google、 IBM、 NEC、 Novell、 Philips、 [Red Hat](http://www.redhat.com/) 和 Sony 这些成员的董事会给予了它可观的经济支持。世界范围内的多个组织通过签署自由 OIN 协议加入了这个社区。

创立开放创新网络的组织成员把它当作利用知识产权保护 Linux 的大胆尝试。它的商业模式非常的难以理解。它要求它的成员采用免版权许可证，并永远放弃由于 Linux 相关知识产权起诉其他成员的机会。

然而，从 Linux 收购风波——想想服务器和云平台——那时起，保护 Linux 知识产权的策略就变得越加的迫切。

在过去的几年里，Linux 的版图曾经历了一场变革。OIN 不必再向人们解释这个组织的定义，也不必再解释为什么 Linux 需要保护。据 OIN 的 CEO Keith Bergelt 说，现在 Linux 的重要性得到了全世界的关注。

“我们已经见到了一场人们了解到 OIN 如何让合作受益的文化变革，”他对 LinuxInsider 说。

### 如何运作

开放创新网络使用专利权的方式创建了一个协作环境。这种方法有助于确保创新的延续。这已经使很多软件厂商、顾客、新型市场和投资者受益。

开放创新网络的专利证可以让任何公司、公共机构或个人免版权使用。这些权利的获得建立在签署者同意不会专为了维护专利而攻击 Linux 系统的基础上。

OIN 确保 Linux 的源代码保持开放的状态。这让编程人员、设备厂商、独立软件开发者和公共机构在投资和使用 Linux 时不用过多的担心知识产权的问题。这让对 Linux 进行重新打包、嵌入和使用的公司省了不少钱。

“随着版权许可证越来越广泛的使用，对 OIN 许可证的需求也变得更加的迫切。现在，人们正在寻找更加简单或更实用的解决方法”，Bergelt 说。

OIN 法律防御援助对成员是免费的。成员必须承诺不对 OIN 名单上的软件发起专利诉讼。为了保护他们的软件，他们也同意提供他们自己的专利。最终，这些保证将让几十万的交叉许可通过该网络相互连接起来，Bergelt 如此解释道。

### 填补法律漏洞

“OIN 正在做的事情是非常必要的。它提供另一层 IP （知识产权）保护，”[休斯顿法律中心大学](http://www.law.uh.edu/)的副教授 Greg R. Vetter 这样说道。

他回答 LinuxInsider 说，第二版 GPL 许可证被某些人认为提供了隐含的专利许可，但是律师们更喜欢明确的许可。

OIN 所提供的许可填补了这个空白。它还明确的覆盖了 Linux 内核。据 Vetter 说，明确的专利许可并不是 GPLv2 中的必要部分，但是这个部分被加入到了 GPLv3 中。（LCTT 译注：Linux 内核采用的是 GPLv2 的许可）

拿一个在 GPLv3 中写了10000行代码的代码编写者来说。随着时间推移，其他的代码编写者会贡献更多行的代码，也加入到了知识产权中。GPLv3 中的软件专利许可条款将基于所有参与的贡献者的专利，保护全部代码的使用，Vetter 如此说道。

### 并不完全一样

专利权和许可证在法律结构上层层叠叠互相覆盖。弄清两者对开源软件的作用就像是穿越雷区。

Vetter 说“通常，许可证是授予建立在专利和版权法律上的额外权利的法律结构。许可证被认为是给予了人们做一些的可能会侵犯到其他人的知识产权权利的事的许可。”

Vetter 指出，很多自由开源许可证（例如 Mozilla 公共许可、GNU GPLv3 以及 Apache 软件许可）融合了某些互惠专利权的形式。Vetter 指出，像 BSD 和 MIT 这样旧的许可证不会提到专利。

一个软件的许可证让其他人可以在某种程度上使用这个编程人员创造的代码。版权对所属权的建立是自动的，只要某个人写或者画了某个原创的东西。然而，版权只覆盖了个别的表达方式和衍生的作品。他并没有涵盖代码的功能性或可用的想法。

专利涵盖了功能性。专利权还可以被许可。版权可能无法保护某人如何独立地开发对另一个人的代码的实现，但是专利填补了这个小瑕疵，Vetter 解释道。

### 寻找安全通道

许可证和专利混合的法律性质可能会对开源开发者产生威胁。据 [Chaotic Moon Studios](http://www.chaoticmoon.com/) 的创办者之一、 [IEEE](http://www.ieee.org/) 计算机协会成员 William Hurley 说，对于某些人来说，即使是 GPL 也会成为威胁。

“在很久以前，开源是个完全不同的世界。被彼此间的尊重和把代码视为艺术而非资产的观点所驱动，那时的程序和代码比现在更加的开放。我相信很多为最好的愿景所做的努力几乎最后总是背负着意外的结果，”Hurley 这样告诉 LinuxInsider。

他暗示说，成员人数超越了1000人（的组织）可能会在知识产权保护重要性方面意见不一。这可能会继续搅混开源生态系统这滩浑水。

“最终，这些显现出了围绕着知识产权的常见的一些错误概念。拥有几千个开发者并不会减少风险——而是增加。给出了专利许可的开发者越多，它们看起来就越值钱，”Hurley 说。“它们看起来越值钱，有着类似专利的或者其他知识产权的人就越可能试图利用并从中榨取他们自己的经济利益。”

### 共享与竞争共存

竞合策略是开源的一部分。OIN 模型让各个公司能够决定他们将在哪竞争以及在哪合作，Bergelt 解释道。

“开源演化中的许多改变已经把我们移到了另一个方向上。我们必须为合作创造渠道。否则我们将会有几百个团体把数十亿美元花费到同样的技术上，”他说。

手机产业的革新就是个很好的例子。各个公司放出了不同的标准。没有共享，没有合作，Bergelt 解释道。

他说：“这让我们在美国接触技术的能力落后了七到十年。我们接触设备的经验远远落后于世界其他地方的人。在我们用不上 CDMA (Code Division Multiple Access 码分多址访问通信技术)时对 GSM (Global System for Mobile Communications 全球移动通信系统) 还沾沾自喜。”

### 改变格局

OIN 在去年经历了激增400个新许可的增长。这意味着着开源有了新趋势。

Bergelt 说：“市场到达了一个临界点，组织内的人们终于意识到直白地合作和竞争的需要。结果是两件事同时进行。这可能会变得复杂、费力。”

然而，这个由人们开始考虑合作和竞争的文化革新所驱动的转换过程是可以接受的。他解释说，这也是一个人们怎样拥抱开源的转变——尤其是在 Linux 这个开源社区的领导者项目。

还有一个迹象是，最具意义的新项目都没有在 GPLv3 许可下开发。

### 二个总比一个好

“GPL 极为重要，但是事实是有一堆的许可模型正被使用着。在 Eclipse、Apache 和 Berkeley 许可中，专利问题的相对可解决性通常远远低于在 GPLv3 中的。”Bergelt 说。

GPLv3 对于解决专利问题是个自然的补充——但是 GPL 自身不足以独自解决围绕专利使用的潜在冲突。所以 OIN 的设计是以能够补充版权许可为目的的，他补充道。

然而，层层叠叠的专利和许可也许并没有带来多少好处。到最后，专利在几乎所有的案例中都被用于攻击目的——而不是防御目的，Bergelt 暗示说。

“如果你不准备对其他人采取法律行动，那么对于你的知识产权来说专利可能并不是最佳的法律保护方式”，他说。“我们现在生活在一个对软件——开放的和专有的——误会重重的世界里。这些软件还被错误而过时的专利系统所捆绑。我们每天在工业化和被扼杀的创新中挣扎”，他说。

### 法院是最后的手段

想到 OIN 的出现抑制了诉讼的泛滥就感到十分欣慰，Bergelt 说，或者至少可以说 OIN 的出现扼制了特定的某些威胁。

“可以说我们让人们放下他们的武器。同时我们正在创建一种新的文化规范。一旦你入股这个模型中的非侵略专利，所产生的相关影响就是对合作的鼓励”，他说。

如果你愿意承诺合作，你的第一反应就会趋向于不急着起诉。相反的，你会想如何让我们允许你使用我们所拥有的东西并让它为你赚钱，而同时我们也能使用你所拥有的东西，Bergelt 解释道。

“OIN 是个多面的解决方式。它鼓励签署者创造双赢协议”，他说，“这让起诉成为最逼不得已的行为。那才是它的位置。”

### 底线

Bergelt 坚信，OIN 的运作是为了阻止 Linux 受到专利伤害。在这个需要 Linux 的世界里没有诉讼的地方。

唯一临近的是与微软的移动之争，这关系到行业的发展前景（原文： The only thing that comes close are the mobile wars with Microsoft, which focus on elements high in the stack. 不太理解，请指正。）。那些来自法律的挑战可能是为了提高包括使用 Linux 产品的所属权的成本，Bergelt 说。

尽管如此“这些并不是有关 Linux 诉讼”，他说。“他们的重点并不在于 Linux 的核心。他们关注的是 Linux 系统里都有些什么。”

---

via: <http://www.linuxinsider.com/story/Defending-the-Free-Linux-World-81512.html>

作者：Jack M. Germain 译者：[H-mudcup](https://github.com/H-mudcup) 校对：[wxy](https://github.com/wxy)

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