Arch Linux：DIY 用户的终极圣地，纯粹主义者的最后避难所

arch linux折腾党的福音！当然还有gentoo，不过我没玩过，更不用说lfs了，哈哈

双系统菜鸟表示虽然喜欢arch，但是不敢轻易尝试全字符界面安装。

Archlinux is best rolling linux disturbtion

你可以试试manjaro

了解了一下，先等等看，现在用着xubuntu感觉也不错。

自从用上了这个系统，我再也没有换过别的系统

同，换了很多个发行版，直到碰到arch，就再也没有换过了

可以用。用arch或gentoo应该很少会把系统弄坏到不能修复。

验证码有问题啊。

"验证码正在验证中……"

用ArchLinux三年多了，从来没有因为更新而导致系统无法启动，换了三个电脑，每次换电脑全都装arch。每天上班来第一件事儿就是pacupg，天天更新。<br />
第一次装Arch是在虚拟机里，鼓捣了大概一周的时间才鼓捣出图形界面，然后开始在主机上装，之后windows就变成了虚拟机里的系统。Arch的安装并没有想象中那么难，按照wiki上的教程一步步的来就可以了，欢迎更多的人加入Arch的队伍

arch用了6年多了，每次开机就先pacman -Syu 保持最新版<br />
现在都是拿来做开发主机用，一般ssh过去很少用到桌面

非要拿自己的工具来给自己贴金，这是很多linux使用者的装13习惯

稍安勿躁，我想用win10装啊。我怕装得一半蓝屏，那就尴尬了,,ԾㅂԾ,,

第一次接触linux用的是ubuntu，但是用了没几个礼拜就听说了archlinux感觉特别高大上，就开始了折腾，搞了大概两个下午，终于搞定了。也因此学会了很多命令，比如Mount之类的，这是我在接触ubuntu时只用图形时学不到的。

我从 ubuntu 用到debian 现在就是arch

赞，这就是 Arch 的意义！

之前用的Arch，某次更新后，中文输入法无效，无奈换回了ubuntu

标榜什么圣地和纯粹，都是强行装13的派头，然后对别人跟自己不一样的地方嗤之以鼻。

用什么系统跟diy完全没有关系好么？？？自己编译或者自己解决bug就叫DIY了？？？你怎么不从沙子里面提炼Si自己做CPU？？？？

也跟纯粹没有关系，用原作者的代码就叫纯粹了？？？“（Arch）面向的是专业的 Linux 用户，或者是有 DIY 精神，愿意查资料并解决问题的人”。”那些晦涩难懂的专有软件方面的经验恰恰能反映出用户高深的技术能力。“这简直就是瞎折腾的Linuxer的YY与自我安慰，为自己在折腾上面浪费的时间找点存在感。

别说自己用了XXX才学会了XXX，这些知识看本书不行么？而且有些知识没必要学，好好做自己现在的事情就行，不要强迫一个画家或者会计学这个linux命令好么？？？一个男的需要花时间学如何分娩么？？？

软件有bug或者系统出问题，都是稀松平常的事情，解决了就行了，非要拿这个来标榜自己，Set up a flag，也真是幼稚啊！

哈哈，用自己的观点来强行架在别人身上来彰显自己成熟是否也是幼稚的一种表现？

熟悉了Arch会让你受益匪浅，其他的版本都能很容易上手

我来泼一些冷水吧。

客观认识一个事物的标志就是，对于他的优点和缺点都有所了解。

Arch的灵活性是有代价的。增加了学习的负担和出错的概率。

不是说灵活性不好，而是往往很难能够在同时保持简单性。

简单即是美。

http://www.yinwang.org/blog-cn/2012/05/18/user-friendliness

http://www.yinwang.org/blog-cn/2013/03/07/linux-windows-mac

我选择debian

从Ubuntu9.04开始使用linux，后转到Fedora，现在使用Archlinux。感觉Archlinux安装过程略有点麻烦，但照着wiki也是比较容易的，可能比较幸运，安装配置也非常顺利。使用快一年了，暂时还没有出现滚挂的情况！软件神马的短时间就能升到上游最新版，强迫症患者表示非常舒服！

arch linux..很好用可以打dota..看kodi..

我也用了3年多..很少有问题..

唯一最头痛的是nvidia的driver...因为arch有时出最新的kernel时..nvidia会不support...

linux还是反应慢呀

装个arch有那么难？跟按自己的喜好装修屋子差不了多少，能有多折腾？不想折腾的可以买精装房。各有所爱，不知道你在喷个什么劲

让我们翻过一页页 Linux 的新闻报道，你会发现其中对一些冷门的 Linux 发行版的报道数量却出乎预料的多。像 Elementary OS 和 Solus 这样的新发行版因其华丽的界面而被大家所关注，而搭载 MATE 桌面环境的那些系统则因其简洁性而被广泛报道。

感谢像《黑客军团》这样的电视节目，我完全可以预料到关于 Kali Linux 系统的报道很快就会增加。

尽管有很多关于 Linux 系统的报道，然而有一个被广泛使用的 Linux 发行版几乎被大家完全遗忘了：Arch Linux 系统！

关于 Arch 的新闻报道很少的原因有很多，不仅仅是因为它很难安装，而且你还得能在命令行下娴熟地完成各种配置以使其正常运行。更糟糕的是，以大多数的用户的观点来看，其困难是设计之初就没有考虑过其复杂的安装过程会令无数的菜鸟们望而却步。

这的确很遗憾，在我看来，实际上一旦安装完成后，Arch 比我用过的其它 Linux 发行版易用得多。

确实如此，Arch 的安装过程很让人蛋疼。有些发行版的安装过程只需要点击“安装”后就可以放手地去干其它事了。Arch 相对来说要花费更多的时间和精力去完成手动分区、手动挂载、生成 fstab 文件等。但是从 Arch 的安装过程中，我们学到很多。它掀开帷幕，让我们弄明白很多背后的东西。事实上，这层掩盖底层细节的帷幕已经彻底消失了，在 Arch 的世界里，你就是帷幕背后的主宰。

除了大家所熟知的难于安装外，Arch 甚至没有自己默认的桌面环境，虽然这有些让人难以理解，但是 Arch 也因其可定制化而被广泛推崇。你可以自行决定在 Arch 的基础软件包上安装的任何东西。

![](/data/attachment/album/201612/11/142449kjg2iarg1ia8al21.jpg)

虽然你可以视之为无限可定制性，但也可以说它完全没有定制化。比如，不像 Ubuntu 系统那样，Arch 中几乎没有修改过或是定制开发过的软件包。Arch 的开发者从始至终都使用的是上游开发者提供的软件包。对于部分用户来说，这种情况非常棒。比如，你可以使用“纯粹”的 GNOME 桌面环境。但是，在某些情况下，定制的补丁可以解决一些上游开发者没有处理的很多的缺陷。

由于 Arch 缺乏一些默认的应用程序和桌面系统，以至于很难形成一致的看法——或者根本不会有什么真正的看法，因为我安装的毫无疑问和你安装的不会一样。我可能选择安装最小化安装配置 Openbox、tint2 和 dmenu，你可能却是使用了最新版的 GNOME 桌面系统。我们都在使用 Arch，但我们的体验却是大相径庭。对于任何发行版来说也有这种情况，但是其它大多数的 Linux 系统都至少有个默认的桌面环境。

然而对 Arch 的看法还是由很多共性的元素的。比如说，我使用 Arch 系统的主要原因是因为它是一个滚动更新的发行版。这意味着两件事情。首先，Arch 会尽可能的使用最新的内核，只要它们可用，被认为稳定就行。这就意味着我可以在 Arch 系统里测试一些在其它 Linux 发行版中难于测试的东西。滚动版另外一个最大的好处就是所有软件更新就绪就会被即时发布出来。这不仅意味着软件包更新速度更快，而且意味着不会出现破坏掉系统的大规模更新。

很多用户因为 Arch 是一个滚动发行版认为它不太稳定。但是在我使用了 9 个多月之后，我并不赞同这种观点。

然而，我从未因为一次升级系统而搞坏过任何东西。我确实有过回滚，因为系统启动分区 /boot 没有挂载，但是后来我发现那完全是自己操作上的失误，我更新后而忘记写入改变。一些暴露出来的缺陷（比如我关于戴尔 XPS 笔记本触摸板又出现以前解决过的问题）很快被修复，并且更新速度要比其它非滚动发行版快得多。总的来说，我认为 Arch 滚动更新的发布模式比其它我在用的发行版要稳定得多。唯一一点我要强调的是查阅维基上的资料，多关注你要更新的内容。

我怀疑 Arch 之所以没那么受欢迎，主要原因就是你必须要随时小心你的操作。盲目的更新 Arch 系统是极其危险的。但是任何一个发行版的更新都有风险，你只是认为它没有风险而已——因为你别无选择。

[Arch 的哲学理念](https://wiki.archlinux.org/index.php/Arch_Linux)是我支持它的另外一个最主要的原因。我认为 Arch 最吸引用户的一点就是：“（Arch）面向的是专业的 Linux 用户，或者是有 DIY 精神，愿意查资料并解决问题的人”。

随着 Linux 进一步纳入主流，开发者们更需要顺利地渡过每一个艰难的技术领域。那些晦涩难懂的专有软件方面的经验恰恰能反映出用户高深的技术能力。

尽管在这个时代听起来有些怪怪的，但是事实上我们很多人更愿意自己动手装配一些东西。在这种情形下，Arch 将会是Linux DIY 用户的终极圣地。

---

via: <http://www.theregister.co.uk/2016/11/02/arch_linux_taster/>

作者：[Scott Gilbertson](http://www.theregister.co.uk/Author/1785) 译者：[rusking](https://github.com/rusking) 校对：[wxy](https://github.com/wxy)

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


一周开源新闻：信不信由你，Windows XP 上个月市场份额上升

Summary:
更多：
- Xen 4.8 Hypervisor 发布
- KDE Frameworks 5 发布 Snap 格式

我大xp威武！

苟延残喘

随着时代的变迁，80后、90后、00后到来，XP只是一个过去式。

时间好快，还记得小学的电脑第一次从 98 换成 xp 的那种兴奋的感觉……

wow，LinuxCN 这评论好看多了

给你点一个大大的赞！

那叫情怀，懂不懂？！

### 信不信由你,Windows XP 上个月市场份额上升

![](/data/attachment/album/201612/12/081356d5krpaqpgwewwkpk.png)

![](/data/attachment/album/201612/12/081406uxfkmkx7k23xu2x9.jpg)

*最近几个月 Windows XP 市场表现*

微软自 2014 年 4 月停止了对 Windows XP 的支持，即便如此，已存在 15 年的 Windows XP 仍然在全世界很多地方使用着。而且，最近，Windows XP 的市场份额还在上升。

从 NetMarketShare 提供的统计看， 2016 年 11 月显示 Windows XP 不但不在下降，反而还在上升。考虑到该系统已不再被支持，这个现象是令人惊讶和担忧的。

现在， Windows 7 以 47.17% 的市场占有率成为市场的领导者，紧跟其后的是 Windows 10，23.72%。15 年前发行的 Windows XP 为第三常用桌面操作系统，8.63%，甚至要高于 Windows 8.1， 8.01%。

Windows XP 今年初市场占有率为 11.42%，然后逐渐降到 7 月份 9.78%。之后开始上升，8月到达 10.34% 后又开始下降。11 月市场再次抬头，根据之前的市场表现，预计从 12 月之后 Windows XP 可能会失去部分市场份额。

谁还在使用 Windows XP? 你可能好奇，既然从 2014 年之后不再提供更新和安全补丁，现在什么人还在使用 Windows XP 呢？答案很简单： 政府部门以及一些不想更换新电脑的老硬件电脑主人。 大多情况下，仍在使用 Windows XP 的政府和组织之所以延迟升级到新系统，是因为需要更换硬件以及兼容性问题，之前为 Windows XP 开发的关键应用也需要移植到新操作系统。

仍旧运行 Windows XP 将用户和他们的数据置于某些风险之下，而且现在它的市场份额仍在增长绝对不是什么好消息。

### 开源的 Xen 4.8 Hypervisor 发布

![](/data/attachment/album/201612/12/081407ozctit4tggi4nit5.gif)

2016 年 12 月 6日, Linux 基金会主持的 Xen 项目[宣布](https://xenproject.org/about/in-the-news/201-xen-480.html)发布 Xen 4.8 hypervisor，它是强大的虚拟化开源工业标准。

距离 Xen 4.7 系列发布已过去 5 个多月，开发组继续改进软件，增加新功能。Xen 4.8 是最新的稳定版本，重点在高级嵌入式使用用例并增强了对基于 ARMv8-A 的服务器的支持。

Xen 4.8 hypervisor 的大的改进包括开始支持 ARM server Live Patching，也就是说，允许用户无需重启即可应用安全补丁， 支持带有 MSI 能力的 GICv2m 中断控制器，以及 包含特定缓存需求的 mmio-sram 和 IO 内存区。

### Ubuntu Linux 上 KDE Frameworks 5 发布 Snap 格式

KDE Frameworks 5 发布 Snap 格式的软件包，KDE 开发人员可以用它来开发 KDE 应用。

![](/data/attachment/album/201612/12/081408xbxfwyzm380x09o0.jpg)

KDE 社区开发者 Harald Sitter 最近一直在致力于做一个共享版的 KDE Frameworks Snap, 使 Ubuntu 和其他 GNU/Linux 发布版本的 KDE 应用打包更加简单。

在最近博客中，他说到，他成功将 KDE 应用捆绑为 Snap，以使它们尽可能小。Snap 和 Flatpak 二进制包过大，对大多数用户来说都是一个问题。为了让多数人接受 Snaps 和 Flatpaks，它们必须足够小。感谢 Harald Sitter 的辛苦工作， 现在 Ubuntu Store 有一个 KDE Frameworks 5 contect Snap 可以使用，主要思想是通过共享一个公用库和其他跨平台的内容，使应用本身尽可能小。例如， KCalc 就只有 312 KB。

具体请参见 Harald Sitter 的[完整博文](https://apachelog.wordpress.com/2016/12/02/snapping-kde-applications/)。

### Canonical 和 System76 继续增强 Ubuntu Linux 对 Unity7 HiDPI 支持

2016 年 12 月 5 日,Canonical的 Michael Hall [宣布](https://developer.ubuntu.com/en/blog/2016/12/05/improving-hidpi-support/)，System76 在与 Canonical 合作，正在共同致力于提升 Ubuntu Linux 对 HiDPI 的支持。

最近几周以来，Ubuntu 和 System76 的开发人员一直在努力合作，以对 Ubuntu Linux 的 Unity 7 用户界面增强 HiDPI 支持，现在他们已经有一些补丁，目前我们还不知道哪些 Ubuntu 版本将接受这些补丁，不过估计至少应该在 Ubuntu 16.04 LTS (Xenial Xerus) 和 Ubuntu 16.10 (Yakkety Yak)中可用。

### Devuan GNU/Linux 继续推动不带 Systemd 的 Debian 的发展

[Devuan GNU/Linux](https://files.devuan.org/) 1.0.0 新的开发版本 Beta 2， 也是第一个稳定版本, 在 2016 年 11 月的最后一天发布。

“做了一些重要的修复和更新，我们继续提供不带 systemd 的 Debian，并宣布发布 Devuan Jessie Beta2。” [邮件列表](https://lists.dyne.org/lurker/message/20161129.235004.ff04e844.en.html)中写道。

Devuan 开发人员同时指出，Devuan GNU/Linux 1.0.0 的开发周期会在 2017 年继续，先是 RC 版本，之后预计几周后发布最终版本。好消息是 Devuan GNU/Linux 1.0.0 正式版将在 2017 初发布。


Linux 内核 4.9 正式发布，这才是有史以来最大的版本

Summary: Linus 称，“我估计这是我们开发的最大的发布版本，至少从提交数上来说是这样的。”

so Nvidia, FUCK YOU!!

越来越好

没有里程碑式的改变

GOOGLE BBR TCP 流控制算法

按照预期计划，Linus Torvalds 在 2016 年 12 月 11 日发布了 Linux 内核 4.9 的正式版本，这次主要带来了一些新的功能和一些驱动更新，当然，还有一些底层的改进。

![](/data/attachment/album/201612/12/110509ntn0x09rxisrws9g.jpg)

Linux 内核 4.9 的开发始于 10 月中旬，这次缩短了合并窗口的截止期，以避免出现 4.8 时发生的在最后一刻提交的 PR 导致的内核错误。Linux 内核 4.9 是最新的主线内核，一些滚动发行版，比如 Arch Linux、Solus、openSUSE Tumbleweed 等都会很快将这个内核推送到它们的用户手中。

Linus [称](http://lkml.iu.edu/hypermail/linux/kernel/1612.1/01831.html)，“我估计这是我们开发的最大的发布版本，至少从提交数上来说是这样的。从变更的行数看，之前有过更大的版本，但是那些是因为一些特殊的原因（比如说，4.2 因 AMD GPU 寄存器定义文件而增加了大量变更行数。之前也因为一些代码重组而导致了大量变更行数： 3.2 是因为 staging 太大，3.7 是因为解离了自动 uapi 头文件，等等情况 ）。以差异来说，4.9 才是最大的。”

### Linux 内核 4.9 的主要变化

Linux 内核 4.9 中带来了许多新的功能，不过最激动人心的可能是对较老的 AMD Radeon 显卡的试验性支持。此外，这个版本也改进了对新的 AMD Radeon GPU 的支持，比如虚拟显示支持和更好的重置支持。对于 Intel GPU，也有对 DMA-BUF 方面的改进。

在这个版本中，对硬件和文件系统方面的改进也很多，涉及到 Btrfs、XFS、F2FS、OverlayFS 的 UBIFS 支持、FUSE 支持 POSIX ACL、OverlayFS SELinux 等方面。

### 相关情况

随着 4.9 内核的正式发布，4.10 （不是 5.x）内核的合并窗口也同时打开了。

此外，前几天发布了 4.8.13 之后仅仅两天，又发布了 4.8.14；而长期支持版本 4.4.38 LTS 也是在前一个版本发布两天后同期发布的。


不常见但是很有用的 GCC 命令行选项（二）

Summary: 开发者们通常用来生成警告的 -Wall 选项，并不包括一些特殊的警告。如果你不了解这些特殊警告，并且不知道如何生成它们，不用担心，我将在这篇文章中详细讲解关于它们所有的细节。

gcc 编译器提供了几乎数不清的命令行选项列表。当然，没有人会使用过或者精通它所有的命令行选项，但是有一些命令行选项是每一个 gcc 用户都应该知道的 - 即使不是必须知道。它们中有一些很常用，其他一些不太常用，但不常用并不意味着它们的用处没前者大。

![](/data/attachment/album/201612/13/084321p0tmmzbm0x8xlcyk.jpg)

在这个系列的文章中，我们集中于一些不常用但是很有用的 gcc 命令行选项，在[第一节](/article-8025-1.html)已经讲到几个这样的命令行选项。

不知道你是否能够回想起，在这个系列教程的第一部分的开始，我简要的提到了开发者们通常用来生成警告的 `-Wall` 选项，并不包括一些特殊的警告。如果你不了解这些特殊警告，并且不知道如何生成它们，不用担心，我将在这篇文章中详细讲解关于它们所有的细节。

除此以外，这篇文章也将涉及与浮点值相关的 gcc 警告选项，以及在 gcc 命令行选项列表变得很大的时候如何更好的管理它们。

在继续之前，请记住，这个教程中的所有例子、命令和指令都已在 Ubuntu 16.04 LTS 操作系统和 gcc 5.4.0 上测试过。

### 生成 -Wall 选项不包括的警告

尽管 gcc 编译器的 `-Wall` 选项涵盖了绝大多数警告标记，依然有一些警告不能生成。为了生成它们，请使用 `-Wextra` 选项。

比如，下面的代码：

```
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i=0;
    /* ...
       some code here
       ...
    */

    if(i);
        return 1;
     return 0;
}

```

我不小心在 `if` 条件后面多打了一个分号。现在，如果使用下面的 gcc 命令来进行编译，不会生成任何警告。

```
gcc -Wall test.c -o test

```

但是如果同时使用 `-Wextra` 选项来进行编译：

```
gcc -Wall -Wextra test.c -o test

```

会生成下面这样一个警告：

```
test.c: In function ‘main’:
test.c:10:8: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
 if(i);

```

从上面的警告清楚的看到， `-Wextra` 选项从内部启用了 `-Wempty-body` 选项，从而可以检测可疑代码并生成警告。下面是这个选项启用的全部警告标记。

* `-Wclobbered`
* `-Wempty-body`
* `-Wignored-qualifiers`
* `-Wmissing-field-initializers`
* `-Wmissing-parameter-type` （仅针对 C 语言）
* `-Wold-style-declaration` （仅针对 C 语言）
* `-Woverride-init`
* `-Wsign-compare`
* `-Wtype-limits`
* `-Wuninitialized`
* `-Wunused-parameter` （只有和 `-Wunused` 或 `-Wall` 选项使用时才会启用）
* `-Wunused-but-set-parameter (只有和`-Wunused`或`-Wall` 选项使用时才会生成）

如果想对上面所提到的标记有更进一步的了解，请查看 [gcc 手册](https://linux.die.net/man/1/gcc)。

此外，遇到下面这些情况， `-Wextra` 选项也会生成警告：

* 一个指针和整数 `0` 进行 `<`， `<=`， `>`， 或 `>=` 比较
* （仅 C++）一个枚举类型和一个非枚举类型同时出现在一个条件表达式中
* （仅 C++）有歧义的虚拟基底
* （仅 C++）寄存器类型的数组加下标
* （仅 C++）对寄存器类型的变量进行取址
* （仅 C++）基类没有在派生类的复制构建函数中进行初始化

### 浮点值的等值比较时生成警告

你可能已经知道，浮点值不能进行确切的相等比较（如果不知道，请阅读与浮点值比较相关的 [FAQ](https://isocpp.org/wiki/faq/newbie))。但是如果你不小心这样做了， gcc 编译器是否会报出错误或警告？让我们来测试一下：

下面是一段使用 `==` 运算符进行浮点值比较的代码：

```
#include<stdio.h>

void compare(float x, float y)
{
    if(x == y)
    {
        printf("\n EQUAL \n");
    }
}

int main(void)
{
    compare(1.234, 1.56789);

    return 0;
}

```

使用下面的 gcc 命令（包含 `-Wall` 和 `-Wextra` 选项）来编译这段代码：

```
gcc -Wall -Wextra test.c -o test

```

遗憾的是，上面的命令没有生成任何与浮点值比较相关的警告。快速看一下 gcc 手册，在这种情形下可以使用一个专用的 `-Wfloat-equal` 选项。

下面是包含这个选项的命令：

```
gcc -Wall -Wextra -Wfloat-equal test.c -o test

```

下面是这条命令产生的输出：

```
test.c: In function ‘compare’:
test.c:5:10: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
 if(x == y)

```

正如上面你所看到的输出那样， `-Wfloat-equal` 选项会强制 gcc 编译器生成一个与浮点值比较相关的警告。

这儿是[gcc 手册](https://linux.die.net/man/1/gcc)关于这一选项的说明：

>
> 这背后的想法是，有时，对程序员来说，把浮点值考虑成近似无限精确的实数是方便的。如果你这样做，那么你需要通过分析代码，或者其他方式，算出这种计算方式引入的最大或可能的最大误差，然后进行比较时（以及产生输出时，不过这是一个不同的问题）允许这个误差。特别要指出，不应该检查是否相等，而应该检查两个值是否可能出现范围重叠；这是用关系运算符来做的，所以等值比较可能是搞错了。
>
>
>

### 如何更好的管理 gcc 命令行选项

如果在你使用的 gcc 命令中，命令行选项列表变得很大而且很难管理，那么你可以把它放在一个文本文件中，然后把文件名作为 gcc 命令的一个参数。之后，你必须使用 `@file` 命令行选项。

比如，下面这行是你的 gcc 命令：

```
gcc -Wall -Wextra -Wfloat-equal test.c -o test

```

然后你可以把这三个和警告相关的选项放到一个文件里，文件名叫做 `gcc-options`：

```
$ cat gcc-options
-Wall -Wextra -Wfloat-equal

```

这样，你的 gcc 命令会变得更加简洁并且易于管理：

```
gcc @gcc-options test.c -o test

```

下面是 gcc 手册关于 `@file` 的说明：

>
> 从文件中读取命令行选项。读取到的选项随之被插入到原始 `@file` 选项所在的位置。如果文件不存在或者无法读取，那么这个选项就会被当成文字处理，而不会被删除。
>
>
> 文件中的选项以空格分隔。选项中包含空白字符的话，可以用一个由单引号或双引号包围完整选项。任何字符（包括反斜杠: '\'）均可能通过一个 '\' 前缀而包含在一个选项中。如果该文件本身包含额外的 `@file` 选项，那么它将会被递归处理。
>
>
>

### 结论

在这个系列的教程中，我们一共讲解了 5 个不常见但是很有用的 gcc 命令行选项： `-Save-temps`、`-g`、 `-Wextra`、`-Wfloat-equal` 以及 `@file`。记得花时间练习使用每一个选项，同时不要忘了浏览 gcc 手册上面所提供的关于它们的全部细节。

你是否知道或使用其他像这样有用的 gcc 命令行选项，并希望把它们在全世界范围内分享？请在下面的评论区留下所有的细节。

---

via: <https://www.howtoforge.com/tutorial/uncommon-but-useful-gcc-command-line-options-2/>

作者：[Ansh](https://twitter.com/howtoforgecom) 译者：[ucasFL](https://github.com/ucasFL) 校对：[jasminepeng](https://github.com/jasminepeng)

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


我们大学机房使用的 Fedora 系统

我们学校什么时候才能推行Linux啊。一天天盗版软件横行

这所学校歧视非计算机专业的学生么？

从照片上的桌面壁纸看系统是 Fedora 24.

天朝：这货xxx上可以用就行了

非计算机专业的学生就不会用Fedora了？ 你这是在歧视非计算机专业的学生么？

你的windows10是正版的嘛？？

大多数中国的学校是不会这么干的，因为老师们自己都不会，又不愿意去学……

计算机系学生就应该这么搞，很赞！！

大部分学生都不知道linux为何物，就算他们学过操作系统

来自117.152.74.93的 Chrome 55.0|GNU/Linux 用户

这评论亮了

其实应该用 CentOS 7 的，Fedora 半年一个版本，太频繁了，维护起来麻烦。

第一句就说了这是某个学院的机房，不是整个学校的。。。

没什么麻烦的，ssh采用密钥连接，有条件的弄个本地源，再写个运维脚本轻松+愉快！这些是Windows用户无法理解的！！

说得好！在fedora上你来给房建专业的学生装一个鲁班ibm软件，你来给金融专业的学生装一个T3会计软件,我就服你。你用着计算机专业最新的fedora，他们甚至不能安装本专业最前沿的软件，不是歧视？可笑。

说的好像 Windows 不能跨版本，本地升级似的。喜欢一个系统，也不要轻视另一个系统。

如果fedora是静默升经或许你都感觉不到什么，现在的windows10静默升级也很频繁

你NB，来把1000台WindosXP电脑给我升级到Windows10试试！Linux只需要一行命令可以完成所有机器的升级，Windows行吗？

内部升级和单纯的联网升级感念是不一样的，其介质未必是经过局域网，也可以是移动存储器。而像 Fedora 的联网升级还不是重启后进入一个特殊的更新模式，如果期间强制重启或关机，根据网上一些网友的反馈看，其结果也不会太好看。

建议多了解一下 Windows 客户端集中升级的方法(不止一种哦)，真正大规模集中升级，无论是何种系统，绝对不是照本宣科，必须结合实际情况来考虑。而且你的比方不适当，对于这篇文章来说，Fedora 升级应该是从 23 到 24（从照片看），而 XP 到 10 跨了多少版本？要类比也是 8.1 到 10 才对。

行，这世界就你最了解Windows行了吧，你以为我会告诉你可以直接从Fedora 20升级到25，中间跨了几个版本？比XP到10少？Fedora 可以升级后系统体积不增加，Windows 行吗？行了，说这些没用，你说的这些普及吗？Fedora可以在任何规模的机房使用，而且还免费，免费……

看了你过往在 linux.cn 的评论，我觉得自己的回复真是多余。20 的映像和包只在 archives.fedoraproject.org 有，mirrors 都移除了。20 没有三个版本之分，升级到 25，选哪个版本？ 随着系统的日常使用，占用的体积是会逐渐增加，如果磁盘空间不足，我看你怎么一条命令升？还不说用户可能会对系统进行一定程度上的更改，这种更改可不在 fedoraproject 控制范围内，所以存在升级后出现问题的可能。你可以看看网上外国网友做的在虚拟机中从最初的 MS-DOS 系统一路升级到 Windows 7 还是 8 的视频。

“Fedora可以在任何规模的机房使用，而且还免费，免费……，”现实中选择部署一套系统，是需要仔细论证的，绝非仅仅免费这么简单。如果单说免费，Linux 一众发行版为何单选 Fedora？放着提供 LTS 版的 Ubuntu 不选，放着针对老机器进行优化的轻量级发行版不选。

事实上fedora Gnu/Linux发行版最好玩的也就是workstation，版本分化本身就消耗了自己的内力，没啥意义

来自陕西西安的 Chrome Mobile 55.0|Android 6.0 用户

fedora！good

我用Linux跑开发环境，休闲上网，Windows跑Photoshop，Office，这一点别说什么替代品，就是不喜欢用LiberOffice、Gimp，和MS Office、PS根本不是一个量级。哪有评论里面那些个什么好不好，只是适合不适合工作需要外加个人喜好

你说得对，这一切的确需要论证，绝非免费这么简单，那我们就从运维的角度来讲，Windows确实有批量管理和运维的平台，可是有几个企业会花钱购买？国内的普遍现象是能用人完成的工作，都不愿意花钱去做，因为他们在计算成本的时候是不会计算人力成本的，同时他们认为没有给钱的系统用起来不忠实，因为没有给钱，出了问题没有问责的对象，很多运维在给领导推荐Linux解决方案的时候往往被领导一句：出了问题你负责吧！之类的话吓退，那么问题来了，领导觉得我们的劳动不值钱，我们是不是也必须认为不值钱呢？我们是不是可以考虑说服领导接受其它既可以减少我们的工作量，又可以不让公司支付更多费用的方案呢？打个比方，在我刚到我现在的公司的时候，我们的领导根本就不知道有Linux的解决方案，在我给他们提Linux解决方案的时候同样有领导问我出了问题是不是我负责，那我也没有办法啊，出了问题我有可能也负不起责，不过，虽然领导没买帐，我还是做了替换方案的全面测试并将测试报告放到了领导的办公桌上，也许是我运气好，半年后终于领导最信赖的Windows平台出了件大事，导致他们集体到老板办公室背书1个月，这时候他突然想起了我的解决方案，报着试试看的态度，用到了现在（5年），也没出什么问题。而且现在我们只要上新的项目，领导都会问乙方，有没有Linux平台的解决方案；所以，很多时候，领导也是需要教育的。<br />
至于你说的我为什么不选Ubuntu LTS版的问题，我只想说，萝卜白菜，各有所爱，我喜欢Fedora，所以选Fedora，你爱选什么是你的事，我不拦着，不过还是要提一句，Ubuntu的第一个LTS发行版到现在也没满5年，你去看看它的支持情况，再看看Fedora的。

关于第一个 LTS 版具体是哪个？如何做好维护不是光靠买现成的产品，用现成的产品，还包括自己给做出解决方案，好的方案，是能够有四两拨千斤的效果。对于 Linux 总提免费是片面的，不然 Redhat 靠什么赚钱？

我去！居然开论战了！

行，你行，在你眼里TLS版本就是NB，因为它有个TLS光环，于是乎厂商更不更新都无所谓，出不出补丁都没关系是吗？因为它有光环，可以免疫一切伤害，所以可以4两拨千斤，我算是长见识了<br />
Redhat是卖服务的，不是卖软件的，换句话说，如果你们公司用Redhat的系统，只要你不要他们的服务，是不收费的，同时也不用担心Redhat会告你们使用盗版，不了解Redhat就别乱说好吗？容易误导消费者。

又在答非所问，我问得是 Ubuntu 第一个发行版是哪个？=> "The first LTS releases were supported for three years on the desktop and five years on the server; since Ubuntu 12.04 LTS, desktop support for LTS releases was increased to five years as well."<br />
Redhat 的运营模式也是针对你的 Linux 免费论。

如果 TA 最初的回复谦逊些，就没这回事了。

为什么不用deepin

好吧，其实只要互相理解，克制些，正常的辩论其实有助于让大家更多的思考。

因为我也一直看大家的辩论，觉得之前的评论展示方式，尤其是盖楼的情况展示不是很好，所以专门做了一些样式调整。

如果争论不欢而散，那么必有一方是虚伪的<br />
https://www.zhihu.com/question/22639556/answer/22110907

行，我在答非所问，其实我也觉得我是在对牛弹琴，道不同不相为谋，你不要再回了，我也不想跟你争，就这样！！～

我深知要说服一个人很难，但还想说，你的评论真是很糟糕，除了引战，没有什么有意义的成分在里面，对于推广 Linux 还是 Fedora 都没有意义，甚至还起反作用。

说服？弄了半天原来你只是想要说服某些人跟认同你的观点而已？你就这么缺乏认同感？你的存在是需要别人认同的？你的评论到是不会引战，就对Linux 的推广有意义了？你以为你坐在那里发表那些所谓不会“引战”的评论Linux就推广起来了？告诉你，你太天真了，不要指望广大用户（特别是国内用户）会主动去了解和接受Linux，更别指望微软的销售团队帮你推广（他们不想尽一切办法消灭Linux就不错了），如果Linux不通过一大批愿意付出愿意去抗争的人进行推广，你以为你今天还有机会在这里跟我讨论有关Linux如何如何的问题？

没有想过说服谁，就是说单纯的仔细像表达自己的一种看法一种观点。对你过往的评论，在我映像中没有什么技术方面的内容，有映像的都是一些非常情绪化的言语。我以为在一个以技术为导向的网站，回复还是要有技术上的支持，不能过于掺杂个人情绪，这样才有意义。

说别人之前先回头看看自己说过的话，好吗？我不否认有时候会带些情绪，至于你说的技术上的支持，我实在想不到就人家说学校用了Fedora的文章，我需要什么样的回复才能算得上是技术上支持？还请赐教！

就事论事，非得要写一句“这些是Windows用户无法理解的！！”。可以简单一下说说你批量部署 Fedora 的方案，就像这篇译文 “一台电脑安装配置好后，我们使用一个...24 台电脑。”一段。好写不写，加一句挑事的话，有意思吗？当然也可以写写，如果原来有过批量部署 Windows 遇到的不愉快遭遇。写出来，未必有人会给出建议，当然即便给出建议也为时已晚，但这样发牢骚的方式，也比你之前那样要好很多。

看了你这句话真TMD恶心，我支持fedora的用户！记住，在我面前谦逊点，不要让我骂你！！！

哟，一个人还是两个人？怎么又冒出一个更暴躁的了？还这么的语无伦次。

好了，都克制点，再吵起来就要第一次关评了。

deepin个人感觉只是UI好，软件商店有些软件好像都比较老

WangYueScream [Baidu Spark 8.6|Windows 7]

不管什么系统，什么编程语言，只是我们实现想法的工具。我们是使用工具。最终目的是实现想法。说Windows不好的，你要电竞选手在Linux上比赛？

![](/data/attachment/album/201612/13/180300lwzwdzpj8wwmddn7.jpg)

在[塞尔维亚共和国诺维萨德大学的自然科学系和数学与信息学系](http://www.dmi.rs/)，我们教学生很多东西。从编程语言的入门到机器学习，所有开设的课程最终目的是让我们的学生能够像专业的开发者和软件工程师一样思考。课程时间紧凑而且学生众多，所以我们必须对现有可利用的资源进行合理调整以满足正常的教学。最终我们决定将机房计算机系统换为 Fedora。

### 以前的设置

我们过去的解决方案是在 Ubuntu 系统上面安装 Windows [虚拟机](https://en.wikipedia.org/wiki/Virtual_machine)并在虚拟机下安装好教学所需的开发软件。这在当时看起来是一个很不错的主意。然而，这种方法有很多弊端。首先，运行虚拟机导致了严重的计算机性能的浪费，因此导致操作系统性能和运行速度降低。此外，虚拟机有时候会在另一个用户会话里面同时运行。这会导致计算机工作严重缓慢。我们不得不在启动电脑和启动虚拟机上花费宝贵的时间。最后，我们意识到我们的大部分教学所需软件都有对应的 Linux 版本。虚拟机不是必需的。我们需要寻找一个更好的解决办法。

### 进入 Fedora!

![Computer lab in Serbia powered by Fedora](/data/attachment/album/201612/13/180311pzcs3pdktdsklx35.jpg)

*默认运行 Fedora 工作站版本的一个机房的照片*

我们考虑使用一种简洁的安装替代以前的 Windows 虚拟机方案。我们最终决定使用 Fedora，这有很多原因。

#### 发展的前沿

在我们所教授的课程中，我们会用到很多各种各样的开发工具。因此，能够及时获取可用的最新、最好的开发工具很重要。在 Fedora 下，我们发现我们用到的开发工具有 95% 都能够在官方的软件仓库中找到！只有少量的一些工具，我们才需要手动安装。这在 Fedora 下很简单，因为你能获取到几乎所有的现成的开发工具。

在这个过程中我们意识到我们使用了大量自由、开源的软件和工具。保证这些软件总是能够及时更新通常需要做大量的工作，然而 Fedora 没有这个问题。

#### 硬件兼容性

我们机房选择 Fedora 的第二个原因是硬件兼容性。机房现在的电脑还是比较崭新的。过去比较低的内核版本总有些问题。在 Fedora 下，我们总能获得最新的内核版本。正如我们预期的那样，一切运行良好，没有任何问题。

我们决定使用带有 [GNOME 桌面环境](https://www.gnome.org/)的 Fedora [工作站版本](https://getfedora.org/workstation/)。学生们发现它很容易、直观，可以快速上手。对我们来说，学生有一个简单的环境很重要，这样他们会更多的关注自己的任务和课程本身，而不是一个复杂的或者运行缓慢的用户界面。

#### 自主的技术支持

最后一个原因，我们院系高度赞赏自由、开放源代码的软件。使用这些软件，学生们即便在毕业后和工作的时候，仍然能够继续自由地使用它们。在这个过程中，他们通常也对 Fedora 和自由、开源的软件有了一定了解。

### 转换机房

我们找来其中的一台电脑，完全手动安装好。包括准备所有必要的脚本和软件，设置远程控制权限和一些其他的重要组成部分。我们也为每一门课程单独设置一个用户账号以方便学生存储他们的文件。

一台电脑安装配置好后，我们使用一个强大的、免费的、开源的叫做 [CloneZilla](http://clonezilla.org/) 的工具。 CloneZilla 能够制作硬盘镜像以做恢复用。镜像大小约为 11 G。我们用一些带有高速 USB 3.0 接口的闪存来还原磁盘镜像到其余的电脑。我们仅仅利用若干个闪存设备花费了 75 分钟设置好其余的 24 台电脑。

### 将来的工作

我们机房现在所有的电脑都完全使用 Fedora （没有虚拟机）。剩下的工作是设置一些管理脚本方便远程安装软件，电脑的开关等等。

我们由衷地感谢所有 Fedora 的维护人员、软件包管理人员和其他贡献者。我们希望我们的工作能够鼓励其他的学校和大学像我们一样将机房电脑的操作系统转向 Fedora。我们很高兴地确认 Fedora 完全适合我们，同时我们也保证 Fedora 同样会适合您！

---

via: <https://fedoramagazine.org/fedora-computer-lab-university/>

作者：[Nemanja Milošević](https://fedoramagazine.org/author/nmilosev/) 译者：[WangYueScream](https://github.com/WangYueScream)，[LemonDemo](https://github.com/LemonDemo) 校对：[jasminepeng](https://github.com/jasminepeng)

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


监控微服务的五原则

Summary:
- 监控容器及其里面的东西。
- 在服务性能上做监控，而不是容器性能。
- 监控弹性和多地部署的服务。
- 监控 API。
- 将您的监控映射到您的组织结构。

![](/data/attachment/album/201612/13/213611u1bh6f0xbj0188jj.jpg)

我们对微服务的需求可以归纳为一个词：速度。这种更快提供功能完善且可靠的软件的需求，彻底改变了软件开发模式。毫无疑问，这个改变对软件管理，包括系统监控的方式，都产生了影响。在这篇文章里，我们将重点关注放在有效地监控产品环境中的微服务所需做出的主要改变。我们将为这一新的软件架构拟定 5 条指导性原则来调整你的监控方法。

监控是微服务控制系统的关键部分，你的软件越复杂，那么你就越难了解其性能及问题排障。鉴于软件交付发生的巨大改变，监控系统同样需要进行彻底的改造，以便在微服务环境下表现更好。下面我们将介绍监控微服务的 5 条原则，如下：

1. 监控容器及其里面的东西。
2. 在服务性能上做监控，而不是容器性能。
3. 监控弹性和多地部署的服务。
4. 监控 API。
5. 将您的监控映射到您的组织结构。

利用这 5 条原则，你可以在向微服务前进的道路上，建立更有效的对微服务的监控。这些原则，可以让你应对随着微服务而来的技术变化和组织变化。

### 微服务监控的原则

#### 1、监控容器及其里面的东西

容器因构建微服务而凸显其重要性，容器的速度、可移植性和隔离特性让开发者很容易就爱上了微服务模型。容器的好处已经写的够多了，毋庸赘述。

容器对于其外围的系统来说就像是黑盒子。这对于开发来说大有裨益，从开发环境到生产环境，甚至从开发者的笔记本到云端，为它们带来高度的可移植性。但是当运行起来后，监控和解决服务问题时，这个黑盒子让常规的方法难以奏效了，我们会想：容器里到底在运行着什么？程序和代码运行性能如何？它有什么重要的输出指标吗？从 DevOps 的视角，你需要对容器有更深的了解而不是仅仅知道有一些容器的存在。

![](/data/attachment/album/201612/13/213612f0valz71evlfve81.jpg)

非容器环境下衡量的典型做法，是让一个代理程序运行在主机或者虚机上的用户空间里，但这并不适用于容器。因为容器的优点是小，将各种进程分离开来，并尽可能的减少依赖关系。

而且，从规模上看，成千上万的监测代理，对即使是一个中等大小的部署都是一个昂贵的资源浪费和管理的噩梦。对于容器有两个潜在的解决方案：1）要求你的开发人员直接监控他们的代码，或者2）利用一个通用的内核级的检测方法来查看主机上的所有应用程序和容器活动。这里我们不会深入说明，但每一种方法都有其优点和缺点。

#### 2、 利用业务流程系统提醒服务性能

理解容器容器中的运行数据并不容易，一个单一容器相比组成一个功能或服务的容器聚合，测量复杂度要低得多。

这特别适用于应用程序级别的信息，比如哪个请求拥有最短响应时间，或者哪些 URL 遇到最多的错误，但它同样也适用于架构级别的监测，比如哪个服务的容器使用 CPU 资源超过了事先分配的资源数。

越来越多的软件部署需要一个<ruby> 编排系统 <rt>  orchestration system </rt></ruby>，将应用程序的逻辑规划转化到物理的容器中。常见的编排系统包括 Kubernetes、Mesosphere DC/OS 和 Docker Swarm。团队可以用一个编排系统来（1）定义微服务（2）理解部署的每个服务的当前状态。你可以认为编排系统甚至比容器还重要。容器是短暂的，只有满足你的服务需求才会存在。

DevOps 团队应该将告警重点放到运行特征上，以尽可能贴近监控服务的体验。如果应用受到了影响，这些告警是评估事态的第一道防线。但是获得这些告警并不容易，除非你的监控系统是基于原生于容器的。

<ruby>   原生容器  <rt>  Container-native </rt></ruby>解决方案利用<ruby> 编排元数据 <rt>  orchestration metadata </rt></ruby>来动态聚合容器和应用程序数据，并按每个服务计算监控度量。根据您的编排工具，您可能想在不同层次进行深入检测。比如，在 Kubernetes 里，你通常有 Namespace、ReplicaSet、Pod 和一些其他容器。聚合这些不同的层，对排除逻辑故障是很有必要的，与构成服务的容器的物理部署无关。

![](/data/attachment/album/201612/13/213612y3shzl99kk9lozxx.jpg)

#### 3、 监控<ruby> 弹性 <rt>  Elastic </rt></ruby>和<ruby> 多地部署 <rt>  Multi-Location </rt></ruby>的服务

弹性服务不是一个新概念，但是它在原生容器环境中的变化速度比在虚拟环境中快的多。迅速的变化会严重影响检测系统的正常运行。

监测传统的系统经常需要根据软件部署，手动调整检查指标。这种调整可以是具体的，如定义要捕获的单个指标，或基于应用程序在一个特定的容器中的操作配置要收集的数据。在小规模上（比如几十个容器）我们可以接受，但是再大规模就难以承受了。微服务的集中监控必须能够自由的随弹性服务而增长和缩减，无需人工干预。

比如，如果 DevOps 团队必须手动定义容器包含哪个服务需要监控，他们毫无疑问会失手，因为 Kubernetes 或者 Mesos 每天都会定期创建新的容器。同样，如果代码发布并置于生产环境时要求运维团队安装一个<ruby> 定制的状态端点 <rt>  custom stats endpoint </rt></ruby>，也给开发者从 Docker 仓库获取基础镜像带来更多的挑战。

在生产环境中，建立面向跨越多个数据中心或多个云的复杂部署的监控，比如，如果你的服务跨越私有数据中心和 AWS，那么亚马逊的 AWS CloudWatch 就很难做到这一点。这就要求我们建立一个跨不同地域的监控系统，并可在动态的原生容器环境下运行。

#### 4、 监控 API

在微服务环境中，API 接口是通用的。本质上，它们是将服务暴露给其它团队的唯一组件。事实上，API 的响应和一致性可以看作是“内部 SLA”，即使还没有定义一个正式的 SLA（服务等级协议）。

因此，API 接口的监控也是必要的。API 监控可以有不同的形式，但是很显然它绝对不是简单的二进制上下检查。例如，了解像时间函数这样的最常使用的<ruby> 端点 <rt>  endpoint </rt></ruby>是有价值的。这使得团队可以看到服务使用的变化，无论是由于设计变更或用户的改变。

你也可以记录服务最缓慢的端点，这些可能揭示出重大的问题，或者至少指向需要在系统中做优化的区域。

最后，跟踪系统服务响应的能力是另一个很重要的能力，它主要是开发者使用，也能帮助你了解整体用户体验，同时将信息基于底层和应用程序视角分成两大部分。

#### 5、 将您的监控映射到您的组织结构

这篇文章着重在微服务和监控上，像其他科技文章一样，这是因为很多人都关注此层面。

对于那些熟悉<ruby>   康威定律  <rt>  Conway’s law </rt></ruby>的人来说，系统的设计是基于开发团队的组织结构。创造更快，更敏捷的软件的压力推动了团队去思考重新调整他们的开发组织和管理它的规则。

![](/data/attachment/album/201612/13/213613hr4t2l920r19u9t6.jpg)

所以，如果他们想从这个新的软件架构（微服务）上获益，他们的团队必须将微服务映射到团队自身中。也就是说，他们需要更小的更松散耦合的团队，可以选择自己的方向只要能够满足整个需求即可。在每一个团队中，对于开发语言的使用，bug 的提交甚至工作职责都会有更大的控制能力。

DevOps 团队对此可以启用一个监控平台：让每一个微服务团队可以有自己的警报，度量指标，和控制面板，同时也要给出整体系统的视图。

### 总结

让微服务流行起来的是快捷。开发组织要想更快的为客户提供更多的功能，然后微服务技术就来了，架构转向微服务并且容器的流行让快捷开发成为可能，所有相关的进程理所当然的搭上了这辆火车。

最后，基本的监控原则需要适应伴随微服务而来的技术和结构。越早认识到这种转变的开发团队，能更早更容易的适应微服务这一新的架构。

---

via: <http://thenewstack.io/five-principles-monitoring-microservices/>

作者：[Apurva Dave](http://thenewstack.io/author/apurvadave/) ，[Loris Degioanni](http://thenewstack.io/author/lorisdegioanni/) 译者：[jiajia9linuxer](https://github.com/jiajia9linuxer) 校对：[jasminepeng](https://github.com/jasminepeng)

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


为什么我们的微信文章版式比较好看？

赞一个，排版确实很好看，这是吸引人的一方面

怎么这么666

来自河南郑州的 Chrome Mobile 37.0|Android 5.1 用户

厉害

为网站设计与维护的人员点赞！

<ruby和<rt>标签的确对于显示双语对比的内容的确很好用，比普通的中文名称后面加一个括号包着英文好多了，而且对于用于日语名称的显示也挺友好（指用于日语汉字的假名注音）。不过<ruby>标签的使用是很简单，但是显得累赘，特别是在源代码上看上去好像都混杂在一起，不知有没有插件能够把正文和标注的内容分开，然后网页渲染时能够自动嵌入

我们的 CMS  就是弄了一个简单的插件来做这个。

确实不错 支持一哈

不知道多少次了，我在微信公众号后台收到询问“你们的微信文章版式是怎么做的”等问题了。其实，我本来觉得这没什么值得问的，也不值得保密，但是总是有人问，我觉得还是写一篇小文来介绍一下吧，下次有人问我，我就直接丢链接好了~

我本身不是做美工和 UI/UE 出身的，但是我们的（前）联合创始人 DeadFire 是专门做这个的，奈何他再也不可能为 Linux 中国做任何的 UE 调整了，/cry。不过我们的 UE 在他的努力之下，目前还算不错，也仅以这些样式来纪念他吧。

下面我来说说我们的微信文章版式的几个算是亮点的地方吧。

![](/data/attachment/album/201612/13/232022xzcqicpol777qpq7.jpg)

先说一个前提，Linux 中国的文章都是通过自身网站的 CMS 进行编辑的，并没有使用外部的那些第三方的微信编辑器。因此，如果你有一个可以编辑内容并形成网页的 CMS，那么以下技巧可能就比较适合你使用；如果你没有 CMS ，理论上说你手工编辑 HTML 页面也是可以的；或者，其实你可以复制我们的文章的格式到一个可视化 HTML 编辑器中，修改内容也可以。

### 1、代码高亮

作为技术网站，刊载的文章中出现代码是必不可少的，之前我们也用过一些代码高亮插件，但是因一些不足后来就放弃了。

目前我们使用的代码高亮插件是 Google 的 [code-prettify](https://github.com/google/code-prettify)，最初它是放在 Google Code 上的，现在也托管到了 GitHub： <https://github.com/google/code-prettify> 。

code-prettify 的优点是体积小，使用简单，而且自动识别所高亮的语言（虽然有时候识别的不对，但是其实没几个人真的在意对不对，大致能区分不同的语言成分就好了）。目前这个软件已经有比较长的时间不更新了，虽然还有 bug，不过大致上的功能没有什么问题。

使用方法很简单，首先你得在页面中引入 code-prettify 的 js 文件，然后在你要高亮代码外使用 `<pre class="prettyprint">...</pre>` 或 `<code class="prettyprint">...</code>` 标签即可。比如：

```
<script src="run_prettify.js"></script>
<pre class="prettyprint">class Voila {
public:
  // Voila
  static const string VOILA = "Voila";
}</pre>
```

然后看起来效果就是：

```
class Voila {
public:
  // Voila
  static const string VOILA = "Voila";
}
```

可能你使用了 code-prettify 之后也发现和我们的代码样式不同，其实，这只是我们使用了自己定制的一个 CSS 样式罢了，稍微研究下我们的页面代码，你就能找到这个 [CSS](https://img.linux.net.cn/static/js/prettify/prettify.css) 的，你可以根据你的喜好进行修改。

当你做好了一个可以在浏览器中满意呈现的页面之后，你只需要复制该页面内容，贴到你的微信后台的编辑器中即可。

### 2、英文注释标签

我们经常会发布各种英文文章的译文，但是有时候，一些词汇需要附上英文才能比较好的避免歧义。通常大家的做法都是在中文后面用括号圈上对应的英文，但是随着 HTML5 规范的普遍支持，其实还有另外一种新的标签可以更好的用于这种情况。那就是 RUBY 标签。

RUBY 是振假名的意思，用于在 HTML 中标注注音。各个浏览器对 RUBY 标签的支持程度不同，不过最基本的用法都是支持的，包括微信内的浏览器。

简单的来说，RUBY 标签的基本格式如下：`<ruby>这里写中文<rt>English here<rt><ruby>`，这个标签用浏览器看的效果是这样的：<ruby> 这里写中文 <rp>  （ </rp> <rt>  English here </rt> <rp>  ） </rp></ruby>。

当然，实际上 RUBY 标签还许多子标签和不同的格式变体，但是一方面各个浏览器支持效果不同，另外一方面对微信浏览器而言仅支持这种基本格式。需要深入研究的同学可以自行搜索。

目前应该还没有支持 RUBY 的 CMS，所以，一般情况下你需要手工编辑你的页面的 HTML 来插入这种标签——当然，我是自己开发了一个我的 CMS 的插件。

此外， RUBY 标签也是可以嵌入链接的，这种情况也比较常见。你可以自行摸索下。

最后，RUBY 标签自然有默认的显示样式，显然，作为在意用户体验的你，肯定会给它单独调整下 CSS 的，是吧？

### 3、其它

实际上，除了以上两点，我们并没有特别不同的地方，不过用户体验的细节还是有所调整的，但是这些就是见仁见智的地方了，大家可以根据需要参考我们或其它一些在页面体验方面有所特长的页面进行学习。

除此以外，做了几年的微信文章发布，我还有一点点小经验可以分享给大家：

* 不建议调整正文字号，就用默认的 16px 即可，虽然看起来比较大——但是现在移动设备分辨率越来越高了，所以较小的字号可能会让部分用户看起来比较累。当然，也可以考虑使用 14px，如果你的文章不全是密密麻麻的字的话。
* 正文文字的颜色不要出现太多，除了黑色以外，最多有两种为宜。此外，在特殊情况下，你还可以考虑使用加粗，甚至斜体效果。
* 中英文混排时，以及掺杂数字时，尽量在英文单词与汉字之间加个空格，关于这方面，网上有篇《[中文排版指北](https://github.com/mzlogin/chinese-copywriting-guidelines)》，会有更详细的建议，不过我认为最重要、最基本的就是这条了。
* 文内配图，如果有可能尽量尺寸一致，最少要考虑保证图片宽度一致比较好。配图下方，必要时可以用另外一种文字样式来做图片说明。比如我们就是用斜体、灰色、下划线样式的字体作为图片说明。模糊的配图不要也罢，除非必要，用动图会显得很 low——有些老网友或许还记得 20 年前的网页上的那种 GIF 动画展览吧？
* 题图，如果你的标题不够好，那就选张好的题图吧，如果你能有一张切题的壁纸级题图，那显然会让你的公众号订阅者更高兴一些——如果细心的话，或许你可以放上这张壁纸级题图的高分辨率原图的 URL 地址？
* 微信后台的文章编辑器对很多 HTML 标签是不支持的，比如 `DIV`。所以，大家如果采用 div 布局的话，会发现桌面浏览器上看的好好的样式，复制到微信后台的编辑器中会变得惨不忍睹。这种情况下，你可以考虑用一些新的块级元素，比如 `SECTION`。
* 链接，微信文章仅在一些特定的情况下支持文内链接，所以，对于大部分公众号的微信文章来说，都是没办法在文内加上链接的。但是作为 Web 世界，有时候明明有链接的地方你不提供链接，你可以想象读者的怒火。这时候，我们有两种方式可以稍微补救。
	1. 对链接的文字加上特定样式（如加上下划线），以暗示此处有链接，然后在后面加个上标，比如<sup> [1]</sup>，并在文末单独对这个上标提供链接，这样需要的读者可以复制该链接访问。不过要注意的是，微信文章不支持 `SUP` 标签，你可以用 `SPAN` 标签来达成类似效果。
	2. 如果文内链接不多，链接本身也不算长，你可以用括号圈起来写上链接，不过如果链接太多，也太长时，这会影响正文阅读效果的。其实这两种方式都是仿照纸质书籍这种无法做到超链接的出版物的。
* 对于长文章，你应该考虑在文内提供不同层次的大小标题。如果有可能，你还应该在页首提供一个目录、摘要等信息。当然，我们使用了 CMS，这种信息是自动提取生成的，可能要方便一些。

好了，大致我就总结这些，希望对大家有所帮助，如果有什么问题，请留言讨论，也欢迎大家分享自己的经验。

（题图来自：[picswalls.com](http://s1.picswalls.com/wallpapers/2015/12/12/awesome-beautiful-wallpaper_124413582_294.jpg)）


用数据科学搭建一个实时推荐引擎

Summary: 实时推荐引擎是 Neo4j 中最广泛的用途之一，也是使它如此强大并且容易使用的原因之一。为了探索这个东西，我将通过使用示例数据集来阐述如何将统计学方法并入这些引擎中。

编者注：本文是 2016 年 4 月 Nicole Whilte 在欧洲 [GraphConnect](http://graphconnect.com/) 时所作。这儿我们快速回顾一下她所涉及的内容：

* 图数据库推荐基础
* 社会化推荐
* 相似性推荐
* 集群推荐

今天我们将要讨论的内容是数据科学和<ruby> 图推荐 <rp>  （ </rp> <rt>  graph recommendations </rt> <rp>  ） </rp></ruby>：

![](/data/attachment/album/201612/14/165430ads2yka5a5lcyx2z.jpg)

我在 [Neo4j](http://neo4j.com/product/) 任职已经两年了，但实际上我已经使用 Neo4j 和 [Cypher](http://neo4j.com/blog/why-database-query-language-matters/#cypher) 工作三年了。当我首次发现这个特别的<ruby> 图数据库 <rp>  （ </rp> <rt>  graph database </rt> <rp>  ） </rp></ruby>的时候，我还是一个研究生，那时候我在奥斯丁的德克萨斯大学攻读关于社交网络的统计学硕士学位。

[实时推荐引擎](https://neo4j.com/use-cases/real-time-recommendation-engine/)是 Neo4j 中最广泛的用途之一，也是使它如此强大并且容易使用的原因之一。为了探索这个东西，我将通过使用示例数据集来阐述如何将统计学方法并入这些引擎中。

第一个很简单 - 将 Cypher 用于社交推荐。接下来，我们将看一看相似性推荐，这涉及到可被计算的相似性度量，最后探索的是集群推荐。

### 图数据库推荐基础

下面的数据集包含所有达拉斯 Fort Worth 国际机场的餐饮场所，达拉斯 Fort Worth 国际机场是美国主要的机场枢纽之一：

![](/data/attachment/album/201612/14/165806sjtqx55hqh152522.png)

我们把节点标记成黄色并按照出入口和航站楼给它们的位置建模。同时我们也按照食物和饮料的主类别将地点分类，其中一些包括墨西哥食物、三明治、酒吧和烤肉。

让我们做一个简单的推荐。我们想要在机场的某一确定地点找到一种特定食物，大括号中的内容表示是的用户输入，它将进入我们的假想应用程序中。

![](/data/attachment/album/201612/14/165810ymp4n22enwdalo9d.png)

这个英文句子表示成 Cypher 查询：

![](/data/attachment/album/201612/14/165815bllxxkz5e0lyflx2.png)

这将提取出该类别中用户所请求的所有地点、航站楼和出入口。然后我们可以计算出用户所在位置到出入口的准确距离，并以升序返回结果。再次说明，这个非常简单的 Cypher 推荐仅仅依据的是用户在机场中的位置。

### <ruby> 社交推荐 <rp>  （ </rp> <rt>  Social Recommendations </rt> <rp>  ） </rp></ruby>

让我们来看一下社交推荐。在我们的假想应用程序中，用户可以登录并且可以用和 Facebook 类似的方式标记自己“喜好”的地点，也可以在某地签到。

![](/data/attachment/album/201612/14/165818vsahvs9reydjsh7k.png)

考虑位于我们所研究的第一个模型之上的数据模型，现在让我们在下面的分类中找到用户的朋友喜好的航站楼里面离出入口最近的餐饮场所：

![](/data/attachment/album/201612/14/165821galadt9lallaqiul.png)

`MATCH` 子句和我们第一次 Cypher 查询的 `MATCH` 子句相似，只是现在我们依据喜好和朋友来匹配：

![](/data/attachment/album/201612/14/165828la8ai8aoa9zbf05c.png)

前三行是完全一样的，但是现在要考虑的是那些登录的用户，我们想要通过 `:FRIENDS_WITH` 这一关系来找到他们的朋友。仅需通过在 Cypher 中增加一些行内容，我们现在已经把社交层面考虑到了我们的推荐引擎中。

再次说明，我们仅仅显示了用户明确请求的类别，并且这些类别中的地点与用户进入的地方是相同的航站楼。当然，我们希望按照登录并做出请求的用户来滤过这些目录，然后返回地点的名字、位置以及所在目录。我们也要显示出有多少朋友已经“喜好”那个地点以及那个地点到出入口的确切距离，然后在 `RETURN` 子句中同时返回所有这些内容。

### <ruby> 相似性推荐 <rp>  （ </rp> <rt>  Similarity Recommendations </rt> <rp>  ） </rp></ruby>

现在，让我们看一看相似性推荐引擎：

![](/data/attachment/album/201612/14/165834eplgtsi6pchxghid.png)

和前面的数据模型相似，用户可以标记“喜好”的地点，但是这一次他们可以用 1 到 10 的整数给地点评分。这是通过前期在 Neo4j 中增加一些属性到关系中建模实现的。

这将允许我们找到其他相似的用户，比如以上面的 Greta 和 Alice 为例，我们已经查询了他们共同喜好的地点，并且对于每一个地点，我们可以看到他们所设定的权重。大概地，我们可以通过他们的评分来确定他们之间的相似性大小。

![](/data/attachment/album/201612/14/165838eouuq78bvuyt1hdu.png)

现在我们有两个向量：

![](/data/attachment/album/201612/14/165839ut226t22t09rszj5.png)

现在让我们按照<ruby> 欧几里得距离 <rp>  （ </rp> <rt>  Euclidean distance </rt> <rp>  ） </rp></ruby>的定义来计算这两个向量之间的距离：

![](/data/attachment/album/201612/14/165840b9z3oub59bgssrub.png)

我们把所有的数字带入公式中计算，然后得到下面的相似度，这就是两个用户之间的“距离”：

![](/data/attachment/album/201612/14/165841iug5l99col5bpgb1.png)

你可以很容易地在 Cypher 中计算两个特定用户的“距离”，特别是如果他们仅仅同时“喜好”一个很小的地点子集。再次说明，这儿我们依据两个用户 Alice 和 Greta 来进行匹配，并尝试去找到他们同时“喜好”的地点：

![](/data/attachment/album/201612/14/165844p0qe3mkemqv08xa0.png)

他们都有对最后找到的地点的 `:LIKES` 关系，然后我们可以在 Cypher 中很容易的计算出他们之间的欧几里得距离，计算方法为他们对各个地点评分差的平方求和再开平方根。

在两个特定用户的例子中上面这个方法或许能够工作。但是，在实时情况下，当你想要通过和实时数据库中的其他用户比较，从而由一架飞机上的一个用户推断相似用户时，这个方法就不一定能够工作。不用说，至少它不能够很好的工作。

为了找到解决这个问题的好方法，我们可以预先计算好距离并存入实际关系中：

![](/data/attachment/album/201612/14/165848gf8w1f4cuf4m9fbf.png)

当遇到一个很大的数据集时，我们需要成批处理这件事，在这个很小的示例数据集中，我们可以按照所有用户的<ruby> 迪卡尔乘积 <rp>  （ </rp> <rt>  Cartesian product </rt> <rp>  ） </rp></ruby>和他们共同“喜好”的地点来进行匹配。当我们使用 `WHERE id(u1) < id(u2)` 作为 Cypher 询问的一部分时，它只是来确定我们在左边和右边没有找到相同的对的一个技巧。

通过用户之间的欧几里得距离，我们创建了他们之间的一种关系，叫做 `:DISTANCE`，并且设置了一个叫做 `euclidean` 的欧几里得属性。理论上，我们可以也通过用户间的一些关系来存储其他相似度从而获取不同的相似度，因为在确定的环境下某些相似度可能比其他相似度更有用。

在 Neo4j 中，的确是对关系属性建模的能力使得完成像这样的事情无比简单。然而，实际上，你不会希望存储每一个可能存在的单一关系，因为你仅仅希望返回离他们“最近”的一些人。

因此你可以根据一些临界值来存入前几个，从而你不需要构建完整的连通图。这允许你完成一些像下面这样的实时的数据库查询，因为我们已经预先计算好了“距离”并存储在了关系中，在 Cypher 中，我们能够很快的攫取出数据。

![](/data/attachment/album/201612/14/165850qu9qhweqkhho9qqe.png)

在这个查询中，我们依据地点和类别来进行匹配：

![](/data/attachment/album/201612/14/165853anumtugnrhhgn4tt.png)

再次说明，前三行是相同的，除了登录用户以外，我们找出了和他们有 `:DISTANCE` 关系的用户。这是我们前面查看的关系产生的作用 - 实际上，你只需要存储处于前几位的相似用户 `:DISTANCE` 关系，因此你不需要在 `MATCH` 子句中攫取大量用户。相反，我们只攫取和那些用户“喜好”的地方有 `:DISTANCE` 关系的用户。

这允许我们用少许几行内容表达较为复杂的模型。我们也可以攫取 `:LIKES` 关系并把它放入到变量中，因为后面我们将使用这些权重来评分。

在这儿重要的是，我们可以依据“距离”大小将用户按照升序进行排序，因为这是一个距离测度。同时，我们想要找到用户间的最小距离因为距离越小表明他们的相似度最大。

通过其他按照欧几里得距离大小排序好的用户，我们得到用户评分最高的三个地点并按照用户的平均评分高低来推荐这些地点。换句话说，我们先找出一个活跃用户，然后依据其他用户“喜好”的地点找出和他最相似的其他用户，接下来按照这些相似用户的平均评分把那些地点排序在结果的集合中。

本质上，我们通过把所有评分相加然后除以收集的用户数目来计算出平均分，然后按照平均评分的升序进行排序。其次，我们按照出入口距离排序。假想地，我猜测应该会有交接点，因此你可以按照出入口距离排序然后再返回名字、类别、出入口和航站楼。

### <ruby> 集群推荐 <rp>  （ </rp> <rt>  Cluster Recommendations </rt> <rp>  ） </rp></ruby>

我们最后要讲的一个例子是集群推荐，在 Cypher 中，这可以被想像成一个作为临时解决方案的离线计算工作流。这可能完全基于在[欧洲 GraphConnect 上宣布的新方法](https://neo4j.com/blog/neo4j-3-0-massive-scale-developer-productivity/)，但是有时你必须进行一些 Cypher 2.3 版本所没有的算法逼近。

在这儿你可以使用一些统计软件，把数据从 Neo4j 取出然后放入像 Apache Spark、R 或者 Python 这样的软件中。下面是一段把数据从 Neo4j 中取出的 R 代码，运行该程序，如果正确，写下程序返回结果的给 Neo4j，可以是一个属性、节点、关系或者一个新的标签。

通过持续把程序运行结果放入到图表中，你可以在一个和我们刚刚看到的查询相似的实时查询中使用它：

![](/data/attachment/album/201612/14/165855lss9sbi9b5r34srz.png)

下面是用 R 来完成这件事的一些示例代码，但是你可以使用任何你最喜欢的软件来做这件事，比如 Python 或 Spark。你需要做的只是登录并连接到图表。

在下面的例子中，我基于用户的相似性把他们聚合起来。每个用户作为一个观察点，然后得到他们对每一个目录评分的平均值。

![](/data/attachment/album/201612/14/165857r7f3zi9fcjj9w37g.png)

假定用户对酒吧类评分的方式和一般的评分方式相似。然后我攫取出喜欢相同类别中的地点的用户名、类别名、“喜好”关系的平均权重，比如平均权重这些信息，从而我可以得到下面这样一个表格：

![](/data/attachment/album/201612/14/165900saw16a1a2anl5ln3.png)

因为我们把每一个用户都作为一个观察点，所以我们必须巧妙的处理每一个类别中的数据，这些数据的每一个特性都是用户对该类中餐厅评分的平均权重。接下来，我们将使用这些数据来确定用户的相似性，然后我将使用<ruby> 聚类 <rp>  （ </rp> <rt>  clustering </rt> <rp>  ） </rp></ruby>算法来确定在不同集群中的用户。

在 R 中这很直接：

![](/data/attachment/album/201612/14/165902n6vqnqq68pv6vg56.png)

在这个示例中我们使用<ruby> K-均值 <rp>  （ </rp> <rt>  k-means </rt> <rp>  ） </rp></ruby>聚类算法，这将使你很容易攫取集群分配。总之，我通过运行聚类算法然后分别得到每一个用户的集群分配。

Bob 和 David 在一个相同的集群中 - 他们在集群二中 - 现在我可以实时查看哪些用户被放在了相同的集群中。

接下来我把集群分配写入 CSV 文件中，然后存入图数据库：

![](/data/attachment/album/201612/14/165905a1iulczzc20zzve2.png)

我们只有用户和集群分配，因此 CSV 文件只有两列。 `LOAD CSV` 是 Cypher 中的内建语法，它允许你从一些其他文件路径或者 URL 调用 CSV ，并给它一个别名。接下来，我们将匹配图数据库中存在的用户，从 CSV 文件中攫取用户列然后合并到集群中。

我们在图表中创建了一个新的标签节点：`Cluster ID`， 这是由 K-平均聚类算法给出的。接下来我们创建用户和集群间的关系，通过创建这个关系，当我们想要找到在相同集群中的实际推荐用户时，就会很容易进行查询。

我们现在有了一个新的集群标签，在相同集群中的用户和那个集群存在关系。新的数据模型看起来像下面这样，它比我们前面探索的其他数据模型要更好：

![](/data/attachment/album/201612/14/165908d61pprs00ov26hys.png)

现在让我们考虑下面的查询：

![](/data/attachment/album/201612/14/165912qo90f0nofoi0wfoi.png)

通过这个 Cypher 查询，我们在更远处找到了在同一个集群中的相似用户。由于这个原因，我们删除了“距离”关系：

![](/data/attachment/album/201612/14/165918mf77g2g7pqhhhmz8.png)

在这个查询中，我们取出已经登录的用户，根据用户-集群关系找到他们所在的集群，找到他们附近和他们在相同集群中的用户。

我们把这些用户分配到变量 `c1` 中，然后我们得到其他被我取别名为 `neighbor` 变量的用户，这些用户和那个相同集群存在着用户-集群关系，最后我们得到这些附近用户“喜好”的地点。再次说明，我把“喜好”放入了变量 r 中，因为我们需要从关系中攫取权重来对结果进行排序。

在这个查询中，我们所做的改变是，不使用相似性距离，而是攫取在相同集群中的用户，然后对类别、航站楼以及我们所攫取的登录用户进行声明。我们收集所有的权重：来自附近用户“喜好”地点的“喜好”关系，得到的类别，确定的距离值，然后把它们按升序进行排序并返回结果。

在这些例子中，我们可以进行一个相当复杂的处理并且将其放到图数据库中，然后我们就可以使用实时算法结果-聚类算法和集群分配的结果。

我们更喜欢的工作流程是更新这些集群分配，更新频率适合你自己就可以，比如每晚一次或每小时一次。当然，你可以根据直觉来决定多久更新一次这些集群分配是可接受的。

---

via: <https://neo4j.com/blog/real-time-recommendation-engine-data-science/>

作者：[Nicole White](https://neo4j.com/blog/contributor/nicole-white/) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


Linux 中的 DTrace ：BPF 进入 4.9 内核

Summary: 随着 BPF 追踪系统（基于时间采样）最后一个主要功能被合并至 Linux 4.9-rc1 版本的内核中，现在 Linux 内核拥有类似 DTrace 的原生追踪功能。这个帖子将告诉你怎么去用这些 BPF 提供的前端工具，以及畅谈这项技术将会何去何从。

翻译辛苦了

Linux内核击败其他操作系统的主要原因就是其强大的生命力，从内核对新事物的接受能力就可见一斑。

>
> 本文作者 [Brendan Gregg](http://www.brendangregg.com/) 目前是 Netflix 的高级性能架构师 ，他在那里做大规模计算机性能设计、分析和调优。他是《Systems Performance》等技术书的作者，因在系统管理员方面的成绩，获得过 2013年 USENIX LISA 大奖。他之前是 SUN 公司是性能领头人和内核工程师，研究存储和网络性能。他也发明和开发过一大波性能分析工具，很多已集成到操作系统中了 。
>
>
>

随着 BPF 追踪系统（基于时间采样）最后一个主要功能被合并至 Linux 4.9-rc1 版本的内核中，现在 Linux 内核拥有类似 DTrace 的原生追踪功能。DTrace 是 Solaris 系统中的高级追踪器。对于长期使用 DTrace 的用户和专家，这将是一个振奋人心的里程碑！现在在 Linux 系统上，你可以在生产环境中使用安全的、低负载的定制追踪系统，通过执行时间的柱状图和频率统计等信息，分析应用的性能以及内核。

![](/data/attachment/album/201612/15/122148mch4g3sfkk7uc9hf.jpg)

用于 Linux 的追踪项目有很多，但是这个最终被合并进 Linux 内核的技术从一开始就根本不是一个追踪项目：它是最开始是用于<ruby> 伯克利包过滤器 <rp>  （ </rp> <rt>  Berkeley Packet Filter </rt> <rp>  ） </rp></ruby>（BPF）的增强功能。这些补丁允许 BPF 重定向数据包，从而创建软件定义网络（SDN）。久而久之，对事件追踪的支持就被添加进来了，使得程序追踪可用于 Linux 系统。

尽管目前 BPF 没有像 DTrace 一样的高级语言，但它所提供的前端已经足够让我创建很多 BPF 工具了，其中有些是基于我以前的 [DTraceToolkit](https://github.com/opendtrace/toolkit)。这个帖子将告诉你怎么去用这些 BPF 提供的前端工具，以及畅谈这项技术将会何去何从。

![](/data/attachment/album/201612/15/122242u33plex1xg11xk8p.png)

### 示例

我已经将基于 BPF 的追踪工具添加到了开源的 [bcc](https://github.com/iovisor/bcc) 项目里（感谢 PLUMgrid 公司的 Brenden Blanco 带领 bcc 项目的发展）。详见 [bcc 安装](https://github.com/iovisor/bcc/blob/master/INSTALL.md) 手册。它会在 `/usr/share/bcc/tools` 目录下添加一系列工具，包括接下来的那些工具。

捕获新进程：

```
# execsnoop
PCOMM            PID    RET ARGS
bash             15887    0 /usr/bin/man ls
preconv          15894    0 /usr/bin/preconv -e UTF-8
man              15896    0 /usr/bin/tbl
man              15897    0 /usr/bin/nroff -mandoc -rLL=169n -rLT=169n -Tutf8
man              15898    0 /usr/bin/pager -s
nroff            15900    0 /usr/bin/locale charmap
nroff            15901    0 /usr/bin/groff -mtty-char -Tutf8 -mandoc -rLL=169n -rLT=169n
groff            15902    0 /usr/bin/troff -mtty-char -mandoc -rLL=169n -rLT=169n -Tutf8
groff            15903    0 /usr/bin/grotty

```

硬盘 I/O 延迟的柱状图：

```
# biolatency -m
Tracing block device I/O... Hit Ctrl-C to end.
^C
     msecs           : count     distribution
       0 -> 1        : 96       |************************************  |
       2 -> 3        : 25       |*********                             |
       4 -> 7        : 29       |***********                           |
       8 -> 15       : 62       |***********************               |
      16 -> 31       : 100      |**************************************|
      32 -> 63       : 62       |***********************               |
      64 -> 127      : 18       |******                                |

```

追踪慢于 5 毫秒的 ext4 常见操作：

```
# ext4slower 5
Tracing ext4 operations slower than 5 ms
TIME     COMM           PID    T BYTES   OFF_KB   LAT(ms) FILENAME
21:49:45 supervise      3570   W 18      0           5.48 status.new
21:49:48 supervise      12770  R 128     0           7.55 run
21:49:48 run            12770  R 497     0          16.46 nsswitch.conf
21:49:48 run            12770  R 1680    0          17.42 netflix_environment.sh
21:49:48 run            12770  R 1079    0           9.53 service_functions.sh
21:49:48 run            12772  R 128     0          17.74 svstat
21:49:48 svstat         12772  R 18      0           8.67 status
21:49:48 run            12774  R 128     0          15.76 stat
21:49:48 run            12777  R 128     0           7.89 grep
21:49:48 run            12776  R 128     0           8.25 ps
21:49:48 run            12780  R 128     0          11.07 xargs
21:49:48 ps             12776  R 832     0          12.02 libprocps.so.4.0.0
21:49:48 run            12779  R 128     0          13.21 cut
[...]

```

追踪新建的 TCP 活跃连接（`connect()`）:

```
# tcpconnect
PID    COMM         IP SADDR            DADDR            DPORT
1479   telnet       4  127.0.0.1        127.0.0.1        23
1469   curl         4  10.201.219.236   54.245.105.25    80
1469   curl         4  10.201.219.236   54.67.101.145    80
1991   telnet       6  ::1              ::1              23
2015   ssh          6  fe80::2000:bff:fe82:3ac fe80::2000:bff:fe82:3ac 22

```

通过跟踪 `getaddrinfo()`/`gethostbyname()` 库的调用来追踪 DNS 延迟：

```
# gethostlatency
TIME      PID    COMM          LATms HOST
06:10:24  28011  wget          90.00 www.iovisor.org
06:10:28  28127  wget           0.00 www.iovisor.org
06:10:41  28404  wget           9.00 www.netflix.com
06:10:48  28544  curl          35.00 www.netflix.com.au
06:11:10  29054  curl          31.00 www.plumgrid.com
06:11:16  29195  curl           3.00 www.facebook.com
06:11:25  29404  curl          72.00 foo
06:11:28  29475  curl           1.00 foo

```

按类别划分 VFS 操作的时间间隔统计：

```
# vfsstat
TIME         READ/s  WRITE/s CREATE/s   OPEN/s  FSYNC/s
18:35:32:       231       12        4       98        0
18:35:33:       274       13        4      106        0
18:35:34:       586       86        4      251        0
18:35:35:       241       15        4       99        0

```

对一个给定的 PID，通过内核和用户堆栈轨迹来追踪 CPU 处理之外的时间（由内核进行统计）：

```
# offcputime -d -p 24347
Tracing off-CPU time (us) of PID 24347 by user + kernel stack... Hit Ctrl-C to end.
^C
[...]
    ffffffff810a9581 finish_task_switch
    ffffffff8185d385 schedule
    ffffffff81085672 do_wait
    ffffffff8108687b sys_wait4
    ffffffff81861bf6 entry_SYSCALL_64_fastpath
    --
    00007f6733a6b64a waitpid
    -                bash (24347)
        4952

    ffffffff810a9581 finish_task_switch
    ffffffff8185d385 schedule
    ffffffff81860c48 schedule_timeout
    ffffffff810c5672 wait_woken
    ffffffff8150715a n_tty_read
    ffffffff815010f2 tty_read
    ffffffff8122cd67 __vfs_read
    ffffffff8122df65 vfs_read
    ffffffff8122f465 sys_read
    ffffffff81861bf6 entry_SYSCALL_64_fastpath
    --
    00007f6733a969b0 read
    -                bash (24347)
        1450908

```

追踪 MySQL 查询延迟（通过 USDT 探针）：

```
# mysqld_qslower `pgrep -n mysqld`
Tracing MySQL server queries for PID 14371 slower than 1 ms...
TIME(s)        PID          MS QUERY
0.000000       18608   130.751 SELECT * FROM words WHERE word REGEXP '^bre.*n$'
2.921535       18608   130.590 SELECT * FROM words WHERE word REGEXP '^alex.*$'
4.603549       18608    24.164 SELECT COUNT(*) FROM words
9.733847       18608   130.936 SELECT count(*) AS count FROM words WHERE word REGEXP '^bre.*n$'
17.864776      18608   130.298 SELECT * FROM words WHERE word REGEXP '^bre.*n$' ORDER BY word

```

监测 pam 库并使用多种追踪工具观察登录请求：

```
# trace 'pam:pam_start "%s: %s", arg1, arg2'
TIME     PID    COMM         FUNC             -
17:49:45 5558   sshd         pam_start        sshd: root
17:49:47 5662   sudo         pam_start        sudo: root
17:49:49 5727   login        pam_start        login: bgregg

```

bcc 项目里的很多工具都有帮助信息（`-h` 选项），并且都应该包含有示例的 man 页面和文本文件。

### 必要性

2014 年，Linux 追踪程序就有一些内核相关的特性（来自 `ftrace` 和 `pref_events`），但是我们仍然要转储并报告进程数据，这种几十年前的老技术有很多的限制。你不能频繁地访问进程名、函数名、堆栈轨迹或内核中的任意的其它数据。你不能在将变量保存到一个监测事件里，又在另一个事件里访问它们，这意味着你不能在你需要的地方计算延迟（或者说时间增量）。你也不能创建一个内核内部的延迟柱状图，也不能追踪 USDT 探针，甚至不能写个自定义的程序。DTrace 可以做到所有这些，但仅限于 Solaris 或 BSD 系统。在 Linux 系统中，有些不在主线内核的追踪器，比如 SystemTap 就可以满足你的这些需求，但它也有自身的不足。（理论上说，你可以写一个基于探针的内核模块来满足需求-但实际上没人这么做。）

2014 年我加入了 Netflix cloud performance 团队。做了这么久的 DTrace 方面的专家，转到 Linux 对我来说简直不可思议。但我确实这么做了，而且遇到了巨大的挑战：在应用快速变化、采用微服务架构和分布式系统的情况下，调优 Netflix cloud。有时要用到系统追踪，而我之前是用的 DTrace。在 Linux 系统上可没有 DTrace，我就开始用 Linux 内核内建的 `ftrace` 和 `perf_events` 工具，构建了一个追踪工具（[perf-tools](https://github.com/brendangregg/perf-tools)）。这些工具很有用，但有些工作还是没法完成，尤其是延迟柱状图以及堆栈踪迹计数。我们需要的是内核追踪的可程序化。

### 发生了什么？

BPF 将程序化的功能添加到现有的内核追踪工具中（`tracepoints`、`kprobes`、`uprobes`）。在 Linux 4.x 系列的内核里，这些功能大大加强了。

时间采样是最主要的部分，它被 Linux 4.9-rc1 所采用（[patchset](https://lkml.org/lkml/2016/9/1/831)）。十分感谢 Alexei Starovoitov（在 Facebook 致力于 BPF 的开发），他是这些 BPF 增强功能的主要开发者。

Linux 内核现在内建有以下这些特性（自 2.6 版本到 4.9 版本之间增加）：

* 内核级的动态追踪（BPF 对 `kprobes` 的支持）
* 用户级的动态追踪（BPF 对 `uprobes` 的支持）
* 内核级的静态追踪（BPF 对 `tracepoints` 的支持）
* 时间采样事件（BPF 的 `pref_event_open`）
* PMC 事件（BPF 的 `pref_event_open`）
* 过滤器（通过 BPF 程序）
* 调试输出（`bpf_trace_printk()`）
* 按事件输出（`bpf_perf_event_output()`）
* 基础变量（全局的和每个线程的变量，基于 BPF 映射）
* 关联数组（通过 BPF 映射）
* 频率计数（基于 BPF 映射）
* 柱状图（2 的冥次方、线性及自定义，基于 BPF 映射）
* 时间戳和时间增量（`bpf_ktime_get_ns()`，和 BPF 程序）
* 内核态的堆栈轨迹（BPF 栈映射）
* 用户态的堆栈轨迹 (BPF 栈映射)
* 重写 ring 缓存（`pref_event_attr.write_backward`）

我们采用的前端是 bcc，它同时提供 Python 和 lua 接口。bcc 添加了：

* 用户级静态追踪（基于 `uprobes` 的 USDT 探针）
* 调试输出（Python 中调用 `BPF.trace_pipe()` 和 `BPF.trace_fields()` 函数 ）
* 按事件输出（`BPF_PERF_OUTPUT` 宏和 `BPF.open_perf_buffer()`）
* 间隔输出（`BPF.get_table()` 和 `table.clear()`）
* 打印柱状图（`table.print_log2_hist()`）
* 内核级的 C 结构体导航（bcc 重写器映射到 `bpf_probe_read()` 函数）
* 内核级的符号解析（`ksym()`、 `ksymaddr()`）
* 用户级的符号解析（`usymaddr()`）
* BPF 跟踪点支持（通过 `TRACEPOINT_PROBE`）
* BPF 堆栈轨迹支持（包括针对堆栈框架的 `walk` 方法）
* 其它各种辅助宏和方法
* 例子（位于 `/examples` 目录）
* 工具（位于 `/tools` 目录）
* 教程（`/docs/tutorial*.md`）
* 参考手册（`/docs/reference_guide.md`）

直到最新也是最主要的特性被整合进来，我才开始写这篇文章，现在它在 4.9-rc1 内核中。我们还需要去完成一些次要的东西，还有另外一些事情要做，但是现在我们所拥有的已经值得欢呼了。现在 Linux 拥有了内建的高级追踪能力。

### 安全性

设计 BPF 及其增强功能时就考虑到生产环境级安全，它被用在大范围的生产环境里。不过你想的话，你还是可以找到一个挂起内核的方法。这种情况是偶然的，而不是必然，类似的漏洞会被快速修复，尤其是当 BPF 合并入了 Linux。因为 Linux 可是公众的焦点。

在开发过程中我们碰到了一些非 BPF 的漏洞，它们需要被修复：rcu 不可重入，这可能导致内核由于 funccount 挂起，在 4.6 内核版本中这个漏洞被 “bpf: map pre-alloc” 补丁集所修复，旧版本内核的漏洞 bcc 有个临时处理方案。还有一个是 uprobe 的内存计算问题，这导致 uprobe 分配内存失败，在 4.8 内核版本这个漏洞由 “uprobes: Fix the memcg accounting” 补丁所修复，并且该补丁还将被移植到之前版本的内核中（例如，它现在被移植到了 4.4.27 和 4.4.0-45.66 版本中）。

### 为什么 Linux 追踪用了这么久才加进来？

首要任务被分到了若干追踪器中间：这些不是某个追踪器单个的事情。想要了解更多关于这个或其它方面的问题，可以看一看我在 2014 年 [tracing summit 上的讲话](http://www.slideshare.net/brendangregg/from-dtrace-to-linux)。我忽视了部分方案的反面影响：有些公司发现其它追踪器（SystemTap 和 LTTng）能满足他们的需求，尽管他们乐于听到 BPF 的开发进程，但考虑到他们现有的解决方案，帮助 BPF 的开发就不那么重要了。

BPF 仅在近两年里在追踪领域得到加强。这一过程原本可以更快的，但早期缺少全职从事于 BPF 追踪的工程师。Alexei Starovoitov (BPF 领导者)，Brenden Blanco (bcc 领导者)，我还有其它一些开发者，都有其它的事情要做。我在 Netflix 公司花了大量时间（志愿地），大概有 7% 的时间是花在 BPF 和 bcc 上。某种程度上这不是我的首要任务，因为我还有自己的工作（包括我的 perf-tools，一个可以工作在旧版本内核上的程序）。

现在BPF 追踪器已经推出了，已经有科技公司开始寻找会 BPF 的人了。但我还是推荐 [Netflix 公司](http://www.brendangregg.com/blog/2016-03-30/working-at-netflix-2016.html)。（如果你为了 BPF 而要聘请我，那我还是十分乐于待在 Netflix 公司的！）

### 使用简单

DTrace 和 bcc/BPF 现在的最大区别就是哪个更好使用。这取决于你要用 BPF 追踪做什么了。如果你要

* **使用 BPF 工具/度量**：应该是没什么区别的。工具的表现都差不多，图形用户界面都能取得类似度量指标。大部分用户通过这种方式使用 BPF。
* **开发工具/度量**：bcc 的开发可难多了。DTrace 有一套自己的简单语言，D 语音，和 awk 语言相似，而 bcc 使用已有的语言（C 语言，Python 和 lua）及其类库。一个用 C 和 Python 写的 bcc 工具与仅仅用 D 语言写出来的工具相比，可能要多十多倍行数的代码，或者更多。但是很多 DTrace 工具用 shell 封装来提供参数和差错检查，会让代码变得十分臃肿。编程的难处是不同的：重写 bcc 更需要巧妙性，这导致某些脚本更加难开发。（尤其是 `bpf_probe_read()` 这类的函数，需要了解更多 BPF 的内涵知识）。当计划改进 bcc 时，这一情形将得到改善。
* **运行常见的命令**：十分相近。通过 `dtrace` 命令，DTrace 能做很多事，但 bcc 有各种工具，`trace`、`argdist`、`funccount`、`funclatency` 等等。
* **编写自定义的特殊命令**：使用 DTrace 的话，这就没有必要了。允许定制消息快速传递和系统快速响应，DTrace 的高级分析很快。而 bcc 现在受限于它的多种工具以及它们的适用范围。

简单来说，如果你只使用 BPF 工具的话，就不必关注这些差异了。如果你经验丰富，是个开发者（像我一样），目前 bcc 的使用更难一些。

举一个 bcc 的 Python 前端的例子，下面是追踪硬盘 I/O 并打印出 I/O 大小的柱状图代码：

```
from bcc import BPF
from time import sleep

# load BPF program
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>

BPF_HISTOGRAM(dist);

int kprobe__blk_account_io_completion(struct pt_regs *ctx, struct request *req)
{
    dist.increment(bpf_log2l(req->__data_len / 1024));
    return 0;
}
""")

# header
print("Tracing... Hit Ctrl-C to end.")

# trace until Ctrl-C
try:
    sleep(99999999)
except KeyboardInterrupt:
    print

# output
b["dist"].print_log2_hist("kbytes")

```

注意 Python 代码中嵌入的 C 语句（`text=`）。

这就完成了任务，但仍有改进的空间。好在我们有时间去做：人们使用 Linux 4.9 并能用上 BPF 还得好几个月呢，所以我们有时间来制造工具和前端。

### 高级语言

前端越简单，比如高级语言，所改进的可能就越不如你所期望的。绝大多数人使用封装好的工具（和图形界面），仅有少部分人能写出这些工具。但我不反对使用高级语言，比如 SystemTap，毕竟已经开发出来了。

```
#!/usr/bin/stap
/*
 * opensnoop.stp    Trace file open()s.  Basic version of opensnoop.
 */

probe begin
{
    printf("\n%6s %6s %16s %s\n", "UID", "PID", "COMM", "PATH");
}

probe syscall.open
{
    printf("%6d %6d %16s %s\n", uid(), pid(), execname(), filename);
}

```

如果拥有整合了语言和脚本的 SystemTap 前端与高性能的内置在内核中的 BPF 后端，会不会令人满意呢？RedHat 公司的 Richard Henderson 已经在进行相关工作了，并且发布了 [初代版本](https://lkml.org/lkml/2016/6/14/749)！

这是 [ply](https://wkz.github.io/ply/)，一个完全新颖的 BPF 高级语言：

```
#!/usr/bin/env ply

kprobe:SyS_*
{
    $syscalls[func].count()
}

```

这也是一份承诺。

尽管如此，我认为工具开发者的实际难题不是使用什么语言：而是要了解要用这些强大的工具做什么？

### 如何帮助我们

* **推广**：BPF 追踪器目前还没有什么市场方面的进展。尽管有公司了解并在使用它（Facebook、Netflix、Github 和其它公司），但要广为人知尚需时日。你可以分享关于 BPF 的文章和资源给业内的其它公司来帮助我们。
* **教育**：你可以撰写文章，发表演讲，甚至参与 bcc 文档的编写。分享 BPF 如何解决实际问题以及为公司带来收益的实例。
* **解决 bcc 的问题**：参考 [bcc issue list](https://github.com/iovisor/bcc/issues)，这包含了错误和需要的特性。
* **提交错误**：使用 bcc/BPF，提交你发现的错误。
* **创造工具**：有很多可视化的工具需要开发，但请不要太草率，因为大家会先花几个小时学习使用你做的工具，所以请尽量把工具做的直观好用（参考我的[文档](https://github.com/iovisor/bcc/blob/master/CONTRIBUTING-SCRIPTS.md)）。就像 Mike Muuss 提及到他自己的 [ping](http://ftp.arl.army.mil/%7Emike/ping.html) 程序：“要是我早知道这是我一生中最出名的成就，我就多开发一两天，添加更多选项。”
* **高级语言**：如果现有的 bcc 前端语言让你很困扰，或许你能弄门更好的语言。要是你想将这门语言内建到 bcc 里面，你需要使用 libbcc。或者你可以帮助 SystemTap BPF 或 ply 的工作。
* **整合图形界面**：除了 bcc 可以使用的 CLI 命令行工具，怎么让这些信息可视呢？延迟热点图，火焰图等等。

### 其它追踪器

那么 SystemTap、ktap、sysdig、LTTng 等追踪器怎么样呢？它们有个共同点，要么使用了 BPF，要么在自己的领域做得更好。会有单独的文章介绍它们自己。

至于 DTrace ？我们公司目前还在基于 FreeBSD 系统的 CDN 中使用它。

### 更多 bcc/BPF 的信息

我已经写了一篇《[bcc/BPF 工具最终用户教程](https://github.com/iovisor/bcc/blob/master/docs/tutorial.md)》，一篇《[bcc Python 开发者教程](https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md)》，一篇《[bcc/BPF 参考手册](https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md)》，并提供了一些有用的[工具](https://github.com/iovisor/bcc/tree/master/tools)，每一个工具都有一个 [example.txt](https://github.com/iovisor/bcc/tree/master/tools) 文件和 [man page](https://github.com/iovisor/bcc/tree/master/man/man8)。我之前写过的关于 bcc 和 BPF 的文章有：

* [eBPF: One Small Step](http://www.brendangregg.com/blog/2015-05-15/ebpf-one-small-step.html) （后来就叫做 BPF）
* [bcc: Taming Linux 4.3+ Tracing Superpowers](http://www.brendangregg.com/blog/2015-09-22/bcc-linux-4.3-tracing.html)
* [Linux eBPF Stack Trace Hack](http://www.brendangregg.com/blog/2016-01-18/ebpf-stack-trace-hack.html) （现在官方支持追踪堆栈了）
* [Linux eBPF Off-CPU Flame Graph](http://www.brendangregg.com/blog/2016-01-20/ebpf-offcpu-flame-graph.html)
* [Linux Wakeup and Off-Wake Profiling](http://www.brendangregg.com/blog/2016-02-01/linux-wakeup-offwake-profiling.html)
* [Linux Chain Graph Prototype](http://www.brendangregg.com/blog/2016-02-05/ebpf-chaingraph-prototype.html)
* [Linux eBPF/bcc uprobes](http://www.brendangregg.com/blog/2016-02-08/linux-ebpf-bcc-uprobes.html)
* [Linux BPF Superpowers](http://www.brendangregg.com/blog/2016-03-05/linux-bpf-superpowers.html)
* [Ubuntu Xenial bcc/BPF](http://www.brendangregg.com/blog/2016-06-14/ubuntu-xenial-bcc-bpf.html)
* [Linux bcc Tracing Security Capabilities](http://www.brendangregg.com/blog/2016-10-01/linux-bcc-security-capabilities.html)
* [Linux MySQL Slow Query Tracing with bcc/BPF](http://www.brendangregg.com/blog/2016-10-04/linux-bcc-mysqld-qslower.html)
* [Linux bcc ext4 Latency Tracing](http://www.brendangregg.com/blog/2016-10-06/linux-bcc-ext4dist-ext4slower.html)
* [Linux bcc/BPF Run Queue (Scheduler) Latency](http://www.brendangregg.com/blog/2016-10-08/linux-bcc-runqlat.html)
* [Linux bcc/BPF Node.js USDT Tracing](http://www.brendangregg.com/blog/2016-10-12/linux-bcc-nodejs-usdt.html)
* [Linux bcc tcptop](http://www.brendangregg.com/blog/2016-10-15/linux-bcc-tcptop.html)
* [Linux 4.9's Efficient BPF-based Profiler](http://www.brendangregg.com/blog/2016-10-21/linux-efficient-profiler.html)

我在 Facebook 的 Performance@Scale [Linux BPF Superpowers](http://www.brendangregg.com/blog/2016-03-05/linux-bpf-superpowers.html) 大会上发表过一次演讲。十二月份，我将在 Boston 发表关于 BPF/bcc 在 [USENIX LISA](https://www.usenix.org/conference/lisa16) 方面的演讲和教程。

### 致谢

* Van Jacobson 和 Steve McCanne，他们创建了最初用作过滤器的 BPF 。
* Barton P. Miller，Jeffrey K. Hollingsworth，and Jon Cargille，发明了动态追踪，并发表论文《Dynamic Program Instrumentation for Scalable Performance Tools》，可扩展高性能计算协议 （SHPCC），于田纳西州诺克斯维尔市，1994 年 5 月发表。
* kerninst (ParaDyn, UW-Madison)，展示了动态跟踪的价值的早期动态跟踪工具（上世纪 90 年代后期）
* Mathieu Desnoyers (在 LTTng)，内核的主要开发者，主导 tracepoints 项目。
* IBM 开发的作为 DProbes 一部分的 kprobes，DProbes 在 2000 年时曾与 LTT 一起提供 Linux 动态追踪，但没有整合到一起。
* Bryan Cantrill, Mike Shapiro, and Adam Leventhal (Sun Microsystems)，DTrace 的核心开发者，DTrace 是一款很棒的动态追踪工具，安全而且简单（2004 年）。对于动态追踪技术，DTrace 是科技的重要转折点：它很安全，默认安装在 Solaris 以及其它以可靠性著称的系统里。
* 来自 Sun Microsystems 的各部门的许多员工，促进了 DTrace，为我们带来了高级系统追踪的意识。
* Roland McGrath (在 Red Hat)，utrace 项目的主要开发者，utrace 变成了后来的 uprobes。
* Alexei Starovoitov (PLUMgrid， 后来是 Facebook)，加强版 BPF（可编程内核部件）的主要开发者。
* 那些帮助反馈、提交代码、测试以及针对增强版 BPF 补丁（请在 lkml 搜索 BPF）的 Linux 内核工程师： Wang Nan、 Daniel Borkmann、 David S. Miller、 Peter Zijlstra 以及其它很多人。
* Brenden Blanco (PLUMgrid)，bcc 的主要开发者。
* Sasha Goldshtein (Sela) 开发了 bcc 中的跟踪点支持，和功能最强大的 bcc 工具 trace 及 argdist，帮助 USDT 项目的开发。
* Vicent Martí 和其它 Github 上的工程师，为 bcc 编写了基于 lua 的前端，帮助 USDT 部分项目的开发。
* Allan McAleavy、 Mark Drayton，和其他的改进 bcc 的贡献者。

感觉 Netflix 提供的环境和支持，让我能够编写 BPF 和 bcc 跟踪器并完成它们。我已经编写了多年的追踪工具（使用 TNF/prex、DTrace、SystemTap、ktap、ftrace、perf，现在是 bcc/BPF），并写书、博客以及评论，

最后，感谢 [Deirdré](http://www.brendangregg.com/blog/2016-07-23/deirdre.html) 编辑了另外一篇文章。

### 总结

Linux 没有 DTrace（语言），但它现在有了，或者说拥有了 DTraceTookit（工具）。

通过增强内置的 BPF 引擎，Linux 4.9 内核拥有了用来支持现代化追踪的最后一项能力。内核支持这一最难的部分已经做完了。今后的任务包括更多的命令行执行工具，以及高级语言和图形用户界面。

对于性能分析产品的客户，这也是一件好事：你能查看延迟柱状图和热点图，CPU 处理和 CPU 之外的火焰图，拥有更好的时延断点和更低耗的工具。在用户空间按包跟踪和处理是没有效率的方式。

那么你什么时候会升级到 Linux 4.9 呢？一旦官方发布，新的性能测试工具就来了：`apt-get install bcc-tools` 。

开始享受它吧!

Brendan

---

via: <http://www.brendangregg.com/blog/2016-10-27/dtrace-for-linux-2016.html>

作者：[Brendan Gregg](http://www.brendangregg.com/) 译者：[GitFuture](https://github.com/GitFuture) 校对：[wxy](https://github.com/wxy)

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


httpstat：一个检查网站性能的 curl 统计分析工具

good 先收藏！

[root@iZ94cozr2 ~]# python  httpstat1.py ""url"""

  File "httpstat1.py", line 110

    grayscale = {(i - 232): make_color('38;5;' + str(i)) for i in xrange(232, 256)}

                                                           ^

SyntaxError: invalid syntax

url不让发，

httpstat 是一个 Python 脚本，它以美妙妥善的方式反映了 curl 统计分析，它是一个单一脚本，兼容 Python 3 ，在用户的系统上不需要安装额外的软件（依赖）。

![](/data/attachment/album/201612/16/062646xyjbihhlhgybtj8m.jpg)

从本质上来说它是一个 cURL 工具的封装，意味着你可以在 URL 后使用几个有效的 cURL 选项，但是不包括 `-w`、 `-D`、 `-o`、 `-s` 和 `-S` 选项，这些已经被 httpstat 使用了。

![httpstat Curl Statistics Tool ](/data/attachment/album/201612/16/062701hi6cma6cfimimmfk.png)

*httpstat Curl 统计分析工具*

你可以看到上图的一个 ASCII 表显示了每个过程消耗多长时间，对我来说最重要的一步是“<ruby> 服务器处理 <rp>  （ </rp> <rt>  server processing </rt> <rp>  ） </rp></ruby>” – 如果这个数字很高，那么你需要[优化你网站服务器来加速访问速度](http://www.tecmint.com/apache-performance-tuning/)。

网站或服务器优化你可以查看我们的文章：

1. [5 个优化 Apache Web 服务器性能的技巧](http://www.tecmint.com/apache-performance-tuning/)
2. [使 Apache 和 Nginx 性能提升 10 倍](http://www.tecmint.com/install-mod_pagespeed-to-boost-apache-nginx-performance/)
3. [如何使用 Gzip 模块提高 Nginx 性能](http://www.tecmint.com/increase-nginx-performance-enable-gzip-compression-module/)
4. [15 个优化 MySQL/MariaDB 性能的建议](/article-5730-1.html)

使用下面安装说明和用法来获取 httpstat 检查出你的网站速度。

### 在 Linux 系统中安装 httpstat

你可以使用两种合理的方法安装 httpstat ：

1. 使用 [wget 命令](/article-4129-1.html)直接从它的 Github 仓库获取如下：

```
$ wget -c https://raw.githubusercontent.com/reorx/httpstat/master/httpstat.py

```

1. 使用 `pip`（这个方法允许 httpstat 作为命令安装到你的系统中）像这样：

```
$ sudo pip install httpstat

```

注：确保 `pip` 包已经在系统上安装了，如果没使用你的发行版包管理器 [yum](/article-2272-1.html) 或 [apt](/article-7364-1.html)安装它。

### 在 Linux 中如何使用 httpstat

`httpstat` 可以根据你安装它的方式来使用，如果你直接下载了它，进入下载目录使用下面的语句运行它：

```
$ python httpstat.py url cURL_options

```

如果你使用 `pip` 来安装它，你可以作为命令来执行它，如下表：

```
$ httpstat url cURL_options

```

查看 `httpstat` 帮助页，命令如下：

```
$ python httpstat.py --help
或
$ httpstat --help

```

`httpstat` 帮助：

```
Usage: httpstat URL [CURL_OPTIONS]
httpstat -h | --help
httpstat --version
Arguments:
URL     url to request, could be with or without `http(s)://` prefix
Options:
CURL_OPTIONS  any curl supported options, except for -w -D -o -S -s,
which are already used internally.
-h --help     show this screen.
--version     show version.
Environments:
HTTPSTAT_SHOW_BODY    Set to `true` to show response body in the output,
note that body length is limited to 1023 bytes, will be
truncated if exceeds. Default is `false`.
HTTPSTAT_SHOW_IP      By default httpstat shows remote and local IP/port address.
Set to `false` to disable this feature. Default is `true`.
HTTPSTAT_SHOW_SPEED   Set to `true` to show download and upload speed.
Default is `false`.
HTTPSTAT_SAVE_BODY    By default httpstat stores body in a tmp file,
set to `false` to disable this feature. Default is `true`
HTTPSTAT_CURL_BIN     Indicate the curl bin path to use. Default is `curl`
from current shell $PATH.
HTTPSTAT_DEBUG        Set to `true` to see debugging logs. Default is `false`

```

从上面帮助命令的输出，你可以看出 `httpstat` 已经具备了一些可以影响其行为的环境变量。

使用它们，只需输出适当的值的这些变量到 `.bashrc` 或 `.zshrc` 文件。

例如：

```
export  HTTPSTAT_SHOW_IP=false
export  HTTPSTAT_SHOW_SPEED=true
export  HTTPSTAT_SAVE_BODY=false
export  HTTPSTAT_DEBUG=true

```

你一旦添加完它们，保存文件然后运行下面的命令使改变生效：

```
$ source  ~/.bashrc

```

你可以指定使用 cURL 执行文件的路径，默认使用的是当前 shell 的 [$PATH 环境变量](http://www.tecmint.com/set-unset-environment-variables-in-linux/)。

下面是一些展示 `httpstat` 如何工作的例子。

```
$ python httpstat.py google.com
或
$ httpstat google.com

```

![httpstat - Showing Website Statistics](/data/attachment/album/201612/16/062702lnaq6hfe87bbyq70.png)

*httpstat – 展示网站统计分析*

接下来的命令中：

1. `-X` 命令标记指定一个客户与 HTTP 服务器连接的请求方法。
2. `--data-urlencode` 这个选项将会把数据（这里是 a=b）按 URL 编码的方式编码后再提交。
3. `-v` 开启详细模式。

```
$ python httpstat.py httpbin.org/post -X POST --data-urlencode "a=b" -v

```

![httpstat - Custom Post Request](/data/attachment/album/201612/16/062702t66dkrlbr4wk9lq6.png)

*httpstat – 定制提交请求*

你可以查看 cURL 的帮助获取更多有用的高级选项，或者浏览 `httpstat` 的 Github 仓库： <https://github.com/reorx/httpstat>

这篇文章中，我们讲述了一个有效的工具，它以简单和整洁方式来查看 cURL 统计分析。如果你知道任何类似的工具，别犹豫，让我们知道，你也可以问问题或评论这篇文章或 httpstat，通过下面反馈。

---

via: <http://www.tecmint.com/httpstat-curl-statistics-tool-check-website-performance/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[wyangsun](https://github.com/wyangsun) 校对：[wxy](https://github.com/wxy)

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


修复 Ubuntu 中“Unable to lock the administration directory (/var/lib/dpkg/)”的

Summary: 一共有几种方法处理这个错误，但是本篇中我们会用两种或许是最简单和最有效的方法来解决它。

这主要是因为Ubuntu有一个自动更新的软件，每次启动都会查找更新，其它发行版如openSUSE with KDE environment desktop也有类似的问题。如果是Debian Stable/Testing，这个问题就不怎么会碰到，更多的是强制关闭一个进行中的apt进程后，再次启用的时候会碰到。在openSUSE下，我会关闭有关启动项，Ubuntu不知道该怎么弄，deb系统我用Debian^_^

elementaryOS也会有这个问题，不过两个方法都不能解决，但是我sudo su换成root之后可以安装，，，，

no,no,no，杀apt进程的时候，先用Kill试试，不行再用kill -9。

来自江苏南京的 Microsoft Edge 14.14393|Windows 10 用户

这个问题只是在安装了图形界面才会出现的，redhat系也存在这个问题，尤其是更新源慢的情况下更为突出。

对于桌面版的ubuntu，可以试试如下的命令取消后台更新服务：

systemctl stop apt-daily.service

systemctl stop apt-daily.timer

不行再杀apt进程:)

可以重新ssh到终端在执行apt update即可

可以重新ssh到终端在执行apt update即可

![](/data/attachment/album/201612/16/064920miua88zhhkah0k8k.jpg)

在 Ubuntu 或者它的衍生版如 Linux Mint（我已经作为日常工作使用的系统）中使用 [apt-get 命令](/article-4933-1.html)或者其相对更新的[APT 管理工具](/article-7364-1.html)时，你可能会在命令行中看到一个 `unable to lock the administration directory (/var/lib/dpkg/) is another process using it` 的错误。

这个错误尤其对那些对这个错误原因不了解的 Linux（Ubuntu）新手而言更加恼人。

下面是一个例子，展示了出现在 Ubuntu 16.10 上的文件锁定错误：

```
tecmint@TecMint:~$ sudo apt install neofetch
[sudo] password for tecmint:
E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg), is another process using it?

```

下面的输出是另外一个可能显示的错误：

```
E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)
E: Unable to lock directory /var/lib/apt/lists/
E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

```

你将来遇到这个错误该怎么去解决？有好几种方法处理这个错误，但是本篇中我们会用两种或许是最简单和最有效的方法来解决它。

### 1、找出并杀掉所有 apt-get 或者 apt 进程

运行下面的命令来[生成所有含有 apt 的进程列表](http://www.tecmint.com/find-linux-processes-memory-ram-cpu-usage/)，你可以使用 `ps` 和 [grep 命令](http://www.tecmint.com/linux-grep-commands-character-classes-bracket-expressions/)并用管道组合来得到含有 apt 或者 apt-get 的进程。

```
$ ps -A | grep apt

```

 [![Find apt and apt-get Processes](/data/attachment/album/201612/16/064950d1g4d5cs429zsaz9.png)](http://www.tecmint.com/wp-content/uploads/2016/11/find-apt-processes.png)

*找出 apt 以及 apt-get 进程*

你可以看到上面命令输出的每个 apt-get 或者 apt 进程，使用下面的命令[杀掉每个进程](http://www.tecmint.com/find-and-kill-running-processes-pid-in-linux/)。

上面截图中的第一列是进程 ID（PID）。

```
$ sudo kill -9 processnumber
或者
$ sudo kill -SIGKILL processnumber

```

比如，下面命令中的`9`是 `SIGKILL` 的信号数，它会杀掉第一个 apt 进程：

```
$ sudo kill -9 13431
或者
$ sudo kill -SIGKILL 13431

```

### 2、 删除锁定的文件

锁定的文件会阻止 Linux 系统中某些文件或者数据的访问，这个概念也存在于 Windows 或者其他的操作系统中。

一旦你运行了 apt-get 或者 apt 命令，锁定文件将会创建于 `/var/lib/apt/lists/`、`/var/lib/dpkg/`、`/var/cache/apt/archives/` 中。

这有助于运行中的 apt-get 或者 apt 进程能够避免被其它需要使用相同文件的用户或者系统进程所打断。当该进程执行完毕后，锁定文件将会删除。

重要提醒：万一你在没有看到 apt-get 或者 apt 进程的情况下在上面两个不同的文件夹中看到了锁定文件，这是因为进程由于某个原因被杀掉了，因此你需要删除锁定文件来避免该错误。

首先运行下面的命令来移除 `/var/lib/dpkg/` 文件夹下的锁定文件：

```
$ sudo rm /var/lib/dpkg/lock

```

之后像下面这样强制重新配置软件包：

```
$ sudo dpkg --configure -a

```

也可以删除 `/var/lib/apt/lists/` 以及缓存文件夹下的锁定文件：

```
$ sudo rm /var/lib/apt/lists/lock
$ sudo rm /var/cache/apt/archives/lock

```

接下来，更新你的软件包源列表：

```
$ sudo apt update
或者
$ sudo apt-get update

```

总结一下，对于 Ubuntu（以及它的衍生版）用户在使用 apt-get 或者 apt 也叫 [aptitude 命令](http://www.tecmint.com/difference-between-apt-and-aptitude/)时遇到的问题，我们已经用两种方法来解决了。

你有什么可以分享出来的有效的方法来处理这个错误么？在下面的评论区联系我们。

除此之外，你可能还希望了解[如何找出并杀掉运行的进程](http://www.tecmint.com/find-and-kill-running-processes-pid-in-linux/)，你可以阅读这篇[用 kill、pkill、killall 来中止进程](http://www.tecmint.com/how-to-kill-a-process-in-linux/)指南来了解。

---

via: <http://www.tecmint.com/fix-unable-to-lock-the-administration-directory-var-lib-dpkg-lock>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 中复制文件到多个目录中

Summary: 在学习 Linux 的过程中，对于新手而言总是会使用几个命令来完成一个简单的任务。对正在熟悉使用终端的人这是很容易理解的行为。然而，如果你想要成为一个老手，学习我说的“快捷命令”会显著减少时间浪费。

可以只用 cp 实现。

for d in {/,}; do cp --verbose --archive demo "$d"; done

for d in {~,~/Downloads}; do cp --verbose --archive demo "$d"; done

for d in {'dir 01','dir 02'}; do cp --verbose --archive demo "$d"; done

for 是 bash 的一个关键字。上述例子演示了如何用 cp 一次复制一个或多个到特定目录，包含还有空格的目录。如果把 cp 改成 \cp，则直接覆盖已有文件。

可以只用 cp 实现。

for d in {/,}; do cp --verbose --archive demo "$d"; done

for d in {~,~/Downloads}; do cp --verbose --archive demo "$d"; done

for d in {'dir 01','dir 02'}; do cp --verbose --archive demo "$d"; done

for 是 bash 的一个关键字。上述例子演示了如何用 cp 一次复制文件到一个或多个特定目录，包含还有空格的目录。如果把 cp 改成 \cp，则直接覆盖已有文件。

因为第一个回复有问题，干脆改成这样。

for d in {/,}; do \cp --verbose --archive {demo001,demo002} "$d"; done

for d in {~,~/Downloads}; do \cp --verbose --archive {demo001,demo002} "$d"; done

for d in {'dir 01','dir 02'}; do \cp --verbose --archive {demo001,demo002} "$d"; done

上述三个例子展示了如用 cp 命令结合 bash 内部关键字 for，实现一次将一个或多个文件无须交互确认直接复制到一个或多个目录中。

特别需要注意的是，用于分割文件或目录的逗号，其前后不能有空格。

特别是意外创建了一个名字是 “~”的目录，那处理起来的小心，不然，对于用户的主目录就来不及说再见

其实我自己日常更习惯直接使用 Tab 的自动拼写完成，将一个文件或文件名类似的多个文件，单次复制到一个目录中。用上面的命令，打字多不说，如果遇到拼写错误，复制失败倒还好，就怕复制到错误的目录，撤销起来会挺麻烦。除非用心编写一个脚本，但似乎没有这个必要。<br />
特别是如意外创建了一个名字就是 “~”的目录，那删除该目录得非常小心，不然，对于用户的主目录就来不及说再见

[在学习 Linux 的过程中](http://www.tecmint.com/free-online-linux-learning-guide-for-beginners/)，对于新手而言总是会使用几个命令来完成一个简单的任务。对正在熟悉使用终端的人这是很容易理解的行为。然而，如果你想要成为一个老手，学习我说的“快捷命令”会显著减少时间浪费。

在本篇中，我们会用一个简单的方法在 Linux 中用一个命令来将目录复制到多个文件夹中。

![](/data/attachment/album/201612/17/151005k2142h0wv2vahe00.jpg)

在 Linux 中，[cp 命令](http://www.tecmint.com/advanced-copy-command-shows-progress-bar-while-copying-files/)常被用于从一个文件夹中复制文件到另一个文件夹中，最简单的语法如下：

```
# cp [options….] source(s) destination

```

另外，你也可以使用[高级复制命令](http://www.tecmint.com/advanced-copy-command-shows-progress-bar-while-copying-files/)，它可以在复制[大的文件或文件夹](http://www.tecmint.com/find-top-large-directories-and-files-sizes-in-linux/)时显示进度条。

看下下面的命令，通常你会使用两个不同的命令来将相同的文件复制到不同的文件夹中：

```
# cp -v /home/aaronkilik/bin/sys_info.sh /home/aaronkilik/test
# cp -v /home/aaronkilik/bin/sys_info.sh /home/aaronkilik/tmp

```

![Copy Files to Multiple Directories](/data/attachment/album/201612/17/151017j3gl2gjewwiez7gg.png)

*复制文件到多个文件夹中*

假设你想要复制一个特定文件到 5 个或者更多的文件夹中，这意味着你需要输入 5 次或者更多的cp命令么？

要摆脱这个问题，你可以用 cp 命令与 [echo命令](http://www.tecmint.com/echo-command-in-linux/)、管道、xargs 命令一起使用：

```
# echo /home/aaronkilik/test/ /home/aaronkilik/tmp | xargs -n 1 cp -v /home/aaronkilik/bin/sys_info.sh

```

上面的命令中，目录的路径（dir1、dir2、dir3...dirN）被管道作为输入到 xargs 命令中，含义是：

1. `-n 1` - 告诉 xargs 命令每个命令行最多使用一个参数，并发送到 cp 命令中。
2. `cp` – 用于复制文件。
3. `-v` – 启用详细模式来显示更多复制细节。

![Copy File to Multiple Locations in Linux](/data/attachment/album/201612/17/151021auuxxnpmo9v95e5n.png)

*在 Linux 中复制文件到多个位置中*

试试阅读 `cp`、 `echo` 和 `xargs` 的 man 页面来找出所有有用和高级的用法信息：

```
$ man cp
$ man echo
$ man xargs

```

就是这样了，你可以在下面的评论区给我们发送主题相关的问题或者反馈。你也可以阅读有关 [progress 命令](http://www.tecmint.com/progress-monitor-check-progress-of-linux-commands/)来帮助监控运行中的（cp、mv、dd、[tar](http://www.tecmint.com/18-tar-command-examples-in-linux/) 等等）的进度。

---

![](/data/attachment/album/201612/17/151022hzscclmuuud7juks.jpg)

作者简介：

Aaron Kili 是一个 Linux 及 F.O.S.S 热衷者，即将成为 Linux 系统管理员、web 开发者，目前是 TecMint 的内容创作者，他喜欢用电脑工作，并坚信分享知识。

---

via: <http://www.tecmint.com/copy-file-to-multiple-directories-in-linux/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


慢动作输出 Linux 命令结果并用彩色显示

Summary: lolcat 命令可以满足上面的需求。它基本上通过与 cat 命令类似的方式将文件或标准输入定向到标准输出来运行，覆盖某个命令的默认屏幕输出颜色，并为其添加彩色。

个人趣味

来自湖北武汉华中科技大学的 Chrome Mobile 46.0|Android 6.0 用户

screenfetch | lolcat

来自117.136.70.49的 Firefox 50.0|GNU/Linux 用户

echo "||||||||||||||||||||||||||||＼(・ω・)／" | lolcat -ad 400

M-x nyan-mode

哟呵

本篇中，我们会展示一个很酷及简单的方法在屏幕中显示彩色的输出，并且可以为了某个原因减慢输出的速度。

[lolcat 命令](/article-5798-1.html)可以满足上面的需求。它基本上通过与 [cat 命令](http://www.tecmint.com/13-basic-cat-command-examples-in-linux/)类似的方式将文件或标准输入定向到标准输出来运行，覆盖某个命令的默认屏幕输出颜色，并为其添加彩色。

![](/data/attachment/album/201612/17/152819ixmji7o5it8dx46o.jpg)

### 如何在 Linux 中安装 lolcat 程序

lolcat 可以在大多数现代 Linux 发行版的默认仓库中得到，但是可用的版本有点老。你可以使用下面的指导来从 git 仓库中安装最新的 lolcat 版本。

* [安装 lolcat 来在 Linux 中显示彩色输出](/article-5798-1.html)

lolcat 安装后，基本的 lolcat 语法是：

```
$ lolcat [options] [files] ...

```

有几个选项可以控制它的行为，下面是一些我们在本指导中会强调的几个最重要的标志：

1. `-a` - 将每行输出都显示动态效果。
2. `-d` – 指定动画效果间隔（显示下一行之前的帧），默认是 12。
3. `-s` – 它指定了动画效果的速度（帧速-每秒的显示帧数），默认是 20。
4. `-f` – 强制显示彩色以防止标准输出不是 tty。

你可以在 lolcat 的 man 页可以找到更多的选项：

```
$ man lolcat

```

### 如何在 Linux 中使用 lolcat

要使用 lolcat，直接将相关命令的输出通过管道给 lolcat，即可见证魔法。

比如：

```
$ ls -l | lolcat -as 25

```

![colorful Linux Terminal Output](/data/attachment/album/201612/17/152851sllb8bcnriq8bw8x.gif)

除此之外你也可以改变默认速度，在下面的命令中，我们会使用一个相对较慢的速度，每秒显示 10 帧：

```
$ ls -l | lolcat -as 10

```

你可以使用任何命令结合 lolcat 在 Linux 终端中输出彩色结果，比如 `ps`、`date` 和 `cal`：

```
$ ps | lolcat
$ date | lolcat
$ cal | lolcat

```

本篇中，我们了解了如何显著降低屏幕输出的速度，并显示彩色效果。

通常上，你可以在下面的评论栏中留下任何关于本篇的问题或评论。最后，你可以留下任何你发现的有用命令。

---

via: <http://www.tecmint.com/add-colors-to-command-output-terminal-linux/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


安卓编年史（13）：Android 2.2 Froyo——更快更华丽

![](/data/attachment/album/201612/18/154408zkyuk8qsskqxk6q3.jpg)

### Android 2.2 Froyo——更快更华丽

[安卓 2.2](http://arstechnica.com/information-technology/2010/07/android-22-froyo/) 在 2010 年 5 月，也就是 2.1 发布后的四个月后亮相。Froyo（冻酸奶）的亮点主要是底层优化，只为更快的速度。Froyo 最大的改变是增加了 JIT 即时编译。JIT 自动在运行时将 java 字节码转换为原生码，这会给系统全面带来显著的性能改善。

浏览器同样得到了性能改善，这要感谢整合了来自 Chrome 的 V8 Javascript 引擎。这是安卓浏览器从 Chrome 借鉴的许多特性中的第一个，最终系统内置的浏览器会被移动版 Chrome 彻底替代掉。在那之前，安卓团队还是需要提供一个浏览器。从 Chrome 借鉴特性是条升级的捷径。

在谷歌专注于让它的平台更快的同时，苹果正在让它的平台更全面。这位谷歌的竞争对手在一个月前发布了 10 英寸的 iPad，先行进入了平板时代。尽管有些搭载 Froyo 和 Gingerbread 的安卓平板发布，但谷歌的官方回应——安卓 3.0 Honeycomb（蜂巢）以及摩托罗拉 Xoom——在 9 个月后才来到。

![Froyo底部添加了双图标停靠栏以及全局搜索。](/data/attachment/album/201612/18/154621ldvvxokwr64dntgb.png)

*Froyo 底部添加了双图标停靠栏以及全局搜索。 [Ron Amadeo 供图]*

Froyo 主屏幕最大的变化是底部的新停靠栏，电话和浏览器图标填充了先前抽屉按钮左右的空白空间。这些新图标都是现有图标的白色定制版本，并且用户没办法自己设置图标。

默认布局移除了所有图标，屏幕上只留下一个使用提示小部件，引导你点击启动器图标以访问你的应用。谷歌搜索小部件得到了一个谷歌 logo，它同时也是个按钮。点击它可以打开一个搜索界面，你可以限制搜索范围是在互联网、应用或是联系人之内。

![下载页面有了“更新所有”按钮，这是个 Flash 应用，一个 flash 驱动的一切皆有可能的网站，以及“移动到 SD”按钮。 ](/data/attachment/album/201612/18/154623nzl15fsm5cv7fkoy.jpg)

*下载页面有了“更新所有”按钮，这是个 Flash 应用，一个 flash 驱动的一切皆有可能的网站，以及“移动到 SD”按钮。 [[Ryan Paul](http://arstechnica.com/information-technology/2010/07/android-22-froyo/) 供图]*

还有一些优秀的新功能加入了 Froyo，安卓市场加入了更多的下载控制。有个新的“更新所有”按钮固定在了下载页面底部。谷歌还添加了自动更新特性，只要应用权限没有改变就能够自动安装应用；尽管如此，自动更新默认是关闭的。

第二张图展示了 Adobe Flash 播放器，它是 Froyo 独有的。这个应用作为插件加入了浏览器，让浏览器能够有“完整的网络”体验。在 2010 年，这意味着网页充满了 Flash 导航和视频。Flash 是安卓相比于 iPhone 最大的不同之一。史蒂夫·乔布斯展开了一场对抗 Flash 的圣战，声称它是一个被淘汰的、充满 bug 的软件，并且苹果不会允许它在 iOS 存在。所以安卓接纳了 Flash 并且让它在安卓上运行，给予用户在安卓上拥有接近可用的 flash 实现。

在那时，Flash 甚至能够让桌面电脑崩溃，所以在移动设备上一直保持打开状态会带来可怕的体验。为了解决这个问题，安卓浏览器上的 Flash 可以设置为“按需打开”——除非用户点击 Flash 占位图标，否则不会加载 Flash 内容。对 Flash 的支持将会持续到安卓 4.1，Adobe 在那时放弃并且结束了这个项目。Flash 从头到尾从未在安卓上完美运行过。而 Flash在 iPhone 这个最流行的移动设备上的缺失，推动了互联网最终放弃了这个平台。

最后一张图片显示的是新增的移动应用到 SD 卡功能，在那个手机只有 512 MB内置存储的时代，这个功能十分的必要的。

![驾驶模式应用。相机现在可以旋转了。](/data/attachment/album/201612/18/154653jitetznemmqbabkb.png)

*驾驶模式应用。相机现在可以旋转了。 [Ron Amadeo 供图]*

相机应用终于更新支持纵向模式了。相机设置被从抽屉中移出，变成一条半透明的按钮带，放在了快门按钮和其他控制键旁边。这个新设计看起来从 Cooliris 相册中获得了许多灵感，半透明的、有弹性的聊天气泡弹出窗口。看到更现代的Cooliris 风格 UI 设计被嫁接到皮革装饰的相机应用确实十分奇怪——从审美上来说一点都不搭。

![半残缺的Facebook应用是个常见的2x3导航页面的优秀范例。谷歌Goggles被包含了进来但同样是残缺的。](/data/attachment/album/201612/18/154703bhgzll0wk0ju1v1c.png)

*半残缺的 Facebook 应用是个常见的 2x3 导航页面的优秀范例。谷歌 Goggles 被包含了进来但同样是残缺的。 [Ron Amadeo 供图]*

不像在安卓 2.0 和 2.1 中包含的 Facebook 客户端，2.2 版本的仍然部分能够工作并且可以登录 Facebook 服务器。Facebook 应用是谷歌那时候设计指南的优秀范例，它建议应用拥有一个含有 3x2 图标方阵的导航页并作为应用主页。

这是谷歌的第一个标准化尝试，将导航元素从菜单按钮里移到屏幕上，以便用户找到它们。这个设计很实用，但它在打开应用和使用应用之间增加了额外的障碍。谷歌不久后会意识到当用户打开一个应用，显示应用内容而不是中间导航页是个更好的主意。以 Facebook 为例，打开应用直接打开信息订阅会更合适。并且不久后应用设计将会把导航降级到二层位置——先是作为顶部的标签之一，后来谷歌放在了“导航抽屉”，一个含有应用所有功能位置的滑出式面板。

还有个预装到 Froyo 的应用是谷歌 Goggles，一个视觉搜索应用，它会尝试辨别图片上的主体。它在辨别艺术品、地标以及条形码时很实用，但差不多也就这些了。最先的两个设置屏幕，以及相机界面，这是应用里仅有的现在还能运行的了。由于客户端太旧了，实际上你如今并不能完成一个搜索。应用里也没什么太多可看的，也就一个会返回搜索结果页的相机界面而已。

![Twitter应用，一个充满动画的谷歌和Twitter的合作成果。](/data/attachment/album/201612/18/154715w78jkl5636932zz5.png)

*Twitter 应用，一个充满动画的谷歌和 Twitter 的合作成果。 [Ron Amadeo 供图]*

Froyo 拥有首个安卓 Twitter 应用，实际上它是谷歌和 Twitter 的合作成果。那时，Twitter 应用是安卓应用阵容里的大缺憾之一。开发者们更偏爱 iPhone，加上苹果占领先机和严格的设计要求，App Store 里可选择的应用远比安卓的有优势。但是谷歌需要一个 Twitter 应用，所以它和 Twitter 合作组建团队让第一个版本问世。

这个应用代表了谷歌的新设计语言，这意味着它有个中间导航页以及对动画要求的“技术演示”。Twitter 应用甚至比 Cooliris 相册用的动画效果还多——所有东西一直都在动。所有页面顶部和底部的云朵以不同速度持续滚动，底部的 Twitter 小鸟拍动它的翅膀并且左右移动它的头。

Twitter 应用实际上有点 Action Bar 早期前身的特性，在安卓 3.0 中引入了一条顶部对齐的连续控制条。沿着所有屏幕的顶部有条拥有 Twitter 标志以及如搜索、刷新和发推这样的按钮的蓝色横栏。它和后来的 Action Bar 之间大的区别在于 Twitter / 谷歌这里的设计的右上角缺少“上一级”按钮，实际上它在应用里用了完整的第二个栏位显示你当前所在位置。在上面的第二张图里，你可以看到整条带有“Tweets”标签的专用于显示位置的栏（当然，还有持续滚动的云朵）。第二个栏的 Twitter 标志扮演着另一个导航元素，有时候在当前部分显示额外的下拉区域，有时候显示整个顶级快捷方式集合。

2.3 Tweet 流看起来和今天的并没有什么不同，除了隐藏的操作按钮（回复，转推等），都在右对齐的箭头按钮里。它们弹出来的是一个聊天气泡菜单，看起来就像导航弹窗。仿 Action Bar 在发推页面有重要作用。它安置着 twitter 标志，剩余字数统计，以及添加照片、拍照，以及提到联系人按钮。

Twitter 应用甚至还有一对主屏幕小部件，大号的那个占据 8 格，提供了发推栏、更新按钮、一条推文，以及左右箭头来查看更多的推文。小号的显示一条推文以及回复按钮。点击大号的小部件的发推栏立即打开了“新推文”主窗口，这让“更新”按钮变得没有价值。

![Google Talk和新USB对话框。](/data/attachment/album/201612/18/154734oymu0nogzgk4uguk.png)

*Google Talk 和新 USB 对话框。 [Ron Amadeo 供图]*

其他部分，Google Talk（以及没有截图的短信应用）从暗色主题变成了浅色主题，这让它们看起来和现在的更接近现代的应用。USB 存储界面会在你设备接入电脑的时候从一个简单的对话框进入全屏界面。这个界面现在有个一个异形安卓机器人 / USB 闪存盘混合体，而不是之前的纯文字设计。

尽管安卓 2.2 在用户互动方式上没有什么新特性，但大的 UI 调整会在下两个版本到来。然而在所有的 UI 工作之前，谷歌希望先改进安卓的核心部分。

### **语音操作——口袋里的超级电脑**

2010 年 8 月，作为语音搜索应用的一项新功能，“[语音命令](http://arstechnica.com/gadgets/2010/08/google-beefs-up-voice-search-mobile-sync/)”登陆了安卓市场。语音命令允许用户向他们的手机发出语音命令，然后安卓会试着去理解他们并完成任务。像“导航至[地址]”这样的命令会打开谷歌地图并且开始逐向导航至你所陈述的目的地。你还可以仅仅通过语音来发送短信或电子邮件、拨打电话、打开网站、获取方向，或是在地图上查看一个地点。

语音命令是谷歌新应用设计哲学的顶峰。语音命令是那时候最先进的语音控制软件，秘密在于谷歌并不在设备上做任运算。一般来说，语音识别是 CPU 密集型任务。实际上，许多语音识别程序仍然有“速度与准确性”设置，用户可以选择他们愿意为语音识别算法运行等待的时间——更多的 CPU 处理意味着更加准确。

谷歌的创新在于没有劳烦手机上能力有限的处理器来进行语音识别运算。当说出一个命令时，用户的声音会被打包并通过互联网发送到谷歌云服务器。在那里，谷歌超算中心的超级计算机分析并解释语音，然后发送回手机。这是很长的一段旅程，但互联网最终还是有足够快的速度在一两秒内完成像这样的任务。

很多人抛出词语“云计算”来表达“所有东西都被存储在服务器上”，但这才是真正的云计算。谷歌在云端进行这些巨量的运算操作，又因为在这个问题上投入了看似荒唐的 CPU 资源数目，所以语音识别准确性的唯一限制就是算法本身了。软件不需要由每个用户独立“训练”，因为所有使用语音操作的人无时不刻都在训练它。借助互联网的力量，安卓在你的口袋里放了一部超级电脑，同时相比于已有的解决方案，把语音识别这个工作量从口袋大小的电脑转移到房间大小的电脑上大大提高了准确性。

语音识别作为谷歌的项目已经有一段时间了，它的出现都是因为一个 800 号码。[1-800-GOOG-411](http://arstechnica.com/business/2007/04/google-rolls-out-free-411-service/)是个谷歌从 2007 年 4 月起开通的免费电话信息服务。它就像 411 信息服务一样工作了多年——用户可以拨打这个号码询问电话号码——但是谷歌免费提供这项服务。查询过程中没有人工的干预，411 服务由语音识别和文本语音转换引擎驱动。在人们教谷歌如何去听之后，又用了三年才有实现语音命令的可能。

语音识别是谷歌长远思考的极佳范例——公司并不怕在一个可能成不了商业产品的项目上投资多年。今天，语音识别驱动的产品遍布谷歌。它被用在谷歌搜索应用的输入，安卓的语音输入，以及 Google.com。同时它还是 Google Glass 和 [Android Wear](http://arstechnica.com/gadgets/2014/03/in-depth-with-android-wear-googles-quantum-leap-of-a-smartwatch-os/) 的默认输入界面。

谷歌甚至还在输入之外的地方使用语音识别。谷歌的语音识别技术被用在了转述 Youtube 视频上，它能自动生成字幕供听障用户观看。生成的字幕甚至被谷歌做成了索引，所以你可以搜索某句话在视频的哪里说过。语音是许多产品的未来，并且这项长期计划将谷歌带入了屈指可数的拥有自家语音识别服务的公司行列。大部分其它的语音识别产品，像苹果的 Siri 和三星设备，只能使用 Nuance 的语音识别，并且为其支付了授权费。

在计算机听觉系统设立运行之后，谷歌下一步将把这项策略应用到计算机视觉上。这就是为什么像 Google Goggles，Google 图像搜索和 [Project Tango](http://arstechnica.com/gadgets/2014/02/googles-project-tango-is-a-smartphone-with-kinect-style-computer-vision/) 这样的项目存在的原因。就像 GOOG-411 的那段日子，这些项目还处在早期阶段。当[谷歌的机器人部门](http://arstechnica.com/gadgets/2013/12/google-robots-former-android-chief-will-lead-google-robotics-division/)造出了机器人，它会需要看和听，谷歌的计算机视觉和听觉项目会给谷歌一个先机。

---

![](/data/attachment/album/201612/06/172630v978lo4o997cailj.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron是Ars Technica的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。 [@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/13/>

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

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


Oracle 勒紧 Java 脖子上的绞索，Java SE 用户面临巨大恐慌

Summary: Java 是免费的？你想多了。Oracle 的律师已经在赶来的路上了。

openJDK崛起！！！

JAVA是想宰一波就完蛋吗

openjdk崛起

openjdk是开发用的吧。用户端怎么办？

装oracle的jre就好了啊，jdk和jre都是免费的，但oracle把收费的软件和jdk捆绑在一起了

用不到jdk和jre免费的就可以了

openjdk是有jre的

oracle想钱想疯了

钻利流氓

debian linux中有openjdk-jre,windows不知道哪里下。

早知如此何必当初

zulu.org 有给win打包好的openjdk

可惜，这原本都是SUN的东西

这大概就是Redhat要跟Oracle闹掰的原因之一吧，性格不合！

所以，当年 IBM 和 Google 没有买下 SUN 的恶果就这样呈现了。

养费了，就下手了

PHP/C#或成最大赢家

Java要收网了，MySQL还会远吗

来自36.149.15.160的 Chrome Mobile 37.0|Android 6.0 用户

Java 是免费的？你想多了。Oracle 的律师已经在赶来的路上了。

>
> Java 是免费的？你想多了。Oracle 的律师已经在赶来的路上了。
>
>
>

### Oracle 开始追索 Java SE 许可费用

在收购了 Sun 微系统公司六年之后，Oracle 终于开始大张旗鼓地审计 Java 客户，他们接触了越来越多的 Oracle 客户和合作伙伴（没错，包括合作伙伴），宣称它们违背了它的许可协议！

![](/data/attachment/album/201612/18/215414pg1ga6ww7ikwnwji.jpg)

2010 年，随着 Oracle 收购 Sun 微系统公司的同时，它也拥有了 Java，但直到现在，它的<ruby> 许可管理服务部门 <rp>  （ </rp> <rt>  License Management Services </rt> <rp>  ） </rp></ruby>（LMS）才开始追着人们讨债。

这家数据库巨头今年在全球雇佣了 20 名雇员，他们的唯一的工作就是向违反了他们的 Java 许可协议的企业追索费用。作为呼应，行业合规专家组也在扩招人马，雇佣 Java 专家，预计 2017 年会有来自 LMS 针对 Java 的更多行动。此举牵扯到大笔金额，而使用 Java 的客户们则面临数万乃至于数十万美元的追缴。

这次引起争论的 Java 版本是 Java SE，有三个付费的分支版本，每用户付费为 $40 到 $300，每处理器付费为 $5000 到 $15000。

据 *The Register* 消息，某零售业拥有八万台 PC 的客户已经接到了 Oracle 通知，声称其违背了 Java 协议。 Oracle 还告诉另一个 Java 客户它欠了十万美金 – 不过这个帐单后来被砍到了三万美金。

某不具名专家称，“Oracle 已经将此事定性为是一个<ruby> 问题 <rt>  issue </rt></ruby>。”。更令人吃惊的是，据 Palisade Compliance 的 CEO 兼创始人 Craig Guarente 说，Oracle 此举不只针对客户，连合作伙伴也一视同仁。

“Oracle 也同样针对了其合作伙伴。这使人们感到愤怒，因为他们在一直在帮助 Oracle 啊！” 他告诉我们。合作伙伴们想知道：“Oracle 怎么可以这样对待我们？！”

### Java 是开源的，但是 Java SE 的安装包不是免费的

导致这一切的根本原因是大家对 Java 错误的认知，都认为 Java 是“免费”的！

这种观点可以追溯到 Sun 时代； Sun 下的 Java 是免费可用的，在 Oracle 下也是！但是 Sun 也确实曾对 IBM 和蓝光播放器制作商等收取许可证费用，尽管对绝大多数的使用者是不收费的。这是因为 Sun 利用 Java 作为“楔子的尖端”，帮助其推动销售它的系统。

而 Oracle 决定让 Java 商业化的步伐迈得更大——至于会不会扯着什么，谁知道呢。

Java SE 是一个泛称，它的下载版本有很多，包括 Oracle 在 2014 年 2 月推出的 Java SE Advanced Desktop，以及在 2011 年 5 月推出的 Java SE Advanced 和 Java SE Suite。Java SE 是免费的没错，但是这几个版本都是付费的。

Java SE 包括免费的 JDK 和 JRE，但是 Advanced Desktop、Java SE Advanced 和 Java SE Suite 具备额外的功能，比如 Java Mission Control 和 Flight Recorder （也叫 JRockit Mission Control 和 JRockit Flight Recorder）。

此外还有用于大规模 Java 部署的 Microsoft Windows Installer Enterprise JRE Installer。

Java SE 在用于 Oracle 所谓的“通用计算”的场合时是免费的 – 用其许可协议中的话来说，涉及到的设备包括桌面电脑、笔记本、智能手机和平板电脑。但在 Oracle 许可协议定义为“用于智能系统中专业嵌入式计算机”场合使用时，不是免费的，后来 Oracle 又进一步对此作了补充定义，除了移动电话、手持设备、网络交换机以及蓝光播放器等。

听起来很简单，不是吗？但是正是在这些通用设备上的客户在受到 LMS 的打击。**原因是没有办法在下载时将那些需要付费的 Java SE 子产品从免费的 Java SE 封装之中剥离开来**，因为 Oracle 并没有提供单独的安装软件。当你只想用其中的一部分功能时，你只能成为 Java SE Suite 这个大套件的指定用户，然后相应付费。

如果你根据你的 app 开发情况，想要大规模的部署 Java SE，则需要 Microsoft Windows Installer Enterprise JRE Installer 这个工具 ，然而这也不是免费 Java SE 的一部分。

“人们没有意识到，他们以为 Jave 是免费的 - 因为它是开源的，所以你可以使用它。不是合约不清晰，而是这里有一个基本的误解。”Guarente 告诉我们。

某不愿具名的合规专家也补充说：

>
> 如果你下载了 Java，你就得到了全部软件，你需要确保**只**安装你被授权的组件，而且要将不使用的部分移除。“商业用途”是指对任何付费功能的使用。“通用目的”是很含糊的定义，因此导致了很多争议。
>
>
> 一旦你作为一个组织分发了一些 Java 的东西给终端用户 – 越来越多的公司在这样做，他们发布 app，用户可以获得产品和服务 - 这就不再称为“通用目的”了...Oracle 要从中收取费用。
>
>
>

### 为什么 Oracle 现在才收网？

为什么 Oracle 现在才行动，在通过收购 Sun 获得 Java 所有权的六年以后？

人们普遍认为，LMS 用了很长的时间来设计审计方法并详细了解客户 Java 的使用状态，等待猪养肥了。

LMS 现在已经做好准备，要在 2017 年向 Java SE 用户开刀了。

“我预计 Oracle 2017 年会继续更加关注此事。所有趋势显示，Oracle 的 LMS 审计团队在变得更加强势，他们在试图得到比往年更高的收入。我不认为 2017 年 Oracle 会变得温和仁慈。”Guarente 说道。

### 你们该怎么做呢？

专家们现在建议下载 Java SE 时要格外小心，而那些已经下载过的客户则要重新审视下使用的方式，在 LMS 找上门来之前做好准备。 据闻，2016 下半年被 LMS 接触过的客户数量有了较大增长，他们纷纷寻求 Java 许可方面的帮助。

“如果你下载了 Java，你就得到了全部软件，你需要确保只安装你被授权的组件，而且要将不使用的部分移除。”专家警告说。“如果你已经有了 Java 应用，先确定你实际使用的特定组件，以及你们在怎样使用它们，然后基于这些，在 Oracle 找到你们前，验证你们是否有使用问题。”

截止到现在，仍未看到 Oracle 对此的官方回应。

参考：[The Register](http://www.theregister.co.uk/2016/12/16/oracle_targets_java_users_non_compliance/)，[LMS](http://www.oracle.com/us/corporate/license-management-services/index.html)


如何在 Shell 脚本中执行语法检查调试模式

Summary: 在本系列的这一部分，我们将了解如何使用语法检查调试模式。记住我们之前在本系列的第一部分中解释了不同的调试选项，在这里，我们将使用它们来执行脚本调试。

我们开启了 Shell 脚本调试系列文章，先是解释了不同的调试选项，下面介绍[如何启用 Shell 调试模式](/article-8028-1.html)。

写完脚本后，建议在运行脚本之前先检查脚本中的语法，而不是查看它们的输出以确认它们是否正常工作。

在本系列的这一部分，我们将了解如何使用语法检查调试模式。记住我们之前在本系列的[第一部分](/article-8028-1.html)中解释了不同的调试选项，在这里，我们将使用它们来执行脚本调试。

![](/data/attachment/album/201612/19/091411hx24y6u67y7xv258.jpg)

### 启用 verbose 调试模式

在进入本指导的重点之前，让我们简要地探索下 **verbose 模式**。它可以用 `-v` 调试选项来启用，它会告诉 shell 在读取时显示每行。

要展示这个如何工作，下面是一个示例脚本来[批量将 PNG 图片转换成 JPG 格式](/article-8014-1.html)。

将下面内容输入（或者复制粘贴）到一个文件中。

```
#!/bin/bash
#convert
for image in *.png; do
convert  "$image"  "${image%.png}.jpg"
echo "image $image converted to ${image%.png}.jpg"
done
exit 0

```

接着保存文件，并用下面的命令使脚本可执行：

```
$ chmod +x script.sh

```

我们可以执行脚本并显示它被 Shell 读取到的每一行：

```
$ bash -v script.sh

```

![Display All Lines in Shell Script](/data/attachment/album/201612/19/091926fbqqc4xv0d0qjfxr.png)

*显示shell脚本中的所有行*

### 在 Shell 脚本中启用语法检查调试模式

回到我们主题的重点，`-n` 激活语法检查模式。它会让 shell 读取所有的命令，但是不会执行它们，它（shell）只会检查语法。

一旦 shell 脚本中发现有错误，shell 会在终端中输出错误，不然就不会显示任何东西。

激活语法检查的命令如下：

```
$ bash -n script.sh

```

因为脚本中的语法是正确的，上面的命令不会显示任何东西。所以，让我们尝试删除结束 for 循环的 `done` 来看下是否会显示错误：

下面是修改过的含有 bug 的批量将 png 图片转换成 jpg 格式的脚本。

```
#!/bin/bash
#script with a bug
#convert
for image in *.png; do
convert  "$image"  "${image%.png}.jpg"
echo "image $image converted to ${image%.png}.jpg"
exit 0

```

保存文件，接着运行该脚本并执行语法检查：

```
$ bash -n script.sh

```

![Check Syntax in Shell Script](/data/attachment/album/201612/19/091927q88zeu688keopklc.png)

*检查 shell 脚本语法*

从上面的输出中，我们看到我们的脚本中有一个错误，for 循环缺少了一个结束的 `done` 关键字。shell 脚本从头到尾检查文件，一旦没有找到它（`done`），shell 会打印出一个语法错误：

```
script.sh: line 11: syntax error: unexpected end of file

```

我们可以同时结合 verbose 模式和语法检查模式：

```
$ bash -vn script.sh

```

![Enable Verbose and Syntax Checking in Script](/data/attachment/album/201612/19/091928t72tl80lt3b8j8yb.png)

*在脚本中同时启用 verbose 检查和语法检查*

另外，我们可以通过修改脚本的首行来启用脚本检查，如下面的例子：

```
#!/bin/bash -n
#altering the first line of a script to enable syntax checking
#convert
for image in *.png; do
convert  "$image"  "${image%.png}.jpg"
echo "image $image converted to ${image%.png}.jpg"
exit 0

```

如上所示，保存文件并在运行中检查语法：

```
$ ./script.sh
script.sh: line 12: syntax error: unexpected end of file

```

此外，我们可以用内置的 set 命令来在脚本中启用调试模式。

下面的例子中，我们只检查脚本中的 for 循环语法。

```
#!/bin/bash
#using set shell built-in command to enable debugging
#convert
#enable debugging
set -n
for image in *.png; do
convert  "$image"  "${image%.png}.jpg"
echo "image $image converted to ${image%.png}.jpg"
#disable debugging
set +n
exit 0

```

再一次保存并执行脚本：

```
$ ./script.sh

```

总的来说，我们应该保证在执行 Shell 脚本之前先检查脚本语法以捕捉错误。

请在下面的反馈栏中，给我们发送关于这篇指导的任何问题或反馈。在这个系列的第三部分中，我们会解释并使用 shell 追踪调试模式。

---

作者简介：

![](/data/attachment/album/201612/19/091929ioey7fbu7gm762im.jpg)

Aaron Kili 是一个 Linux 及 F.O.S.S 热衷者，即将是 Linux 系统管理员、web 开发者，目前是 TecMint 的内容创作者，他喜欢用电脑工作，并热心分享知识。

---

via: <http://www.tecmint.com/check-syntax-in-shell-script/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[jasminepeng](https://github.com/jasminepeng)

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


一周开源新闻：Linux 杀毒软件发现的漏洞可使得黑客获得 root 权限

Summary:
- CentOS Linux 7 (1611) 发布；
- CoreOS Linux 更名为 Container Linux
- openSUSE Leap 42.3 进入开放开发阶段

openSUSE 用起来异常稳定，甚至打破我对所有linux 发行版的印象，软件偶而崩溃正常，但是换用openSUSE将近一年0崩溃，用了centos 做桌面近6年，从5系用起，对一些小的崩溃也习惯了，不影响用，直到centos被红帽收编，cenos7 做桌面大不如从前，最常用的gnote, glade, vim-X11, nautilus，gimp 崩溃成了家常便饭，严重影响工作，centos 7  的图形安装界面都崩溃过几次，提交bugzilla 多数无果而终，多数都是上游的问题之类的回答，这么长时间的使用时间总结出一点经验，centos 在图形界面上不怎么上心，7.3 1611 问题一样多，常用的vim-X11

### Linux 安全软件发现的漏洞可使得黑客获得 Root 权限

![](/data/attachment/album/201612/19/093202bp21006x0e2y0ju7.jpg)

McAfee VirusScan Enterprise for Linux 版本中的远程代码执行缺陷，使黑客可以获得 root 权限，安全研究人员称只需欺骗该 app 使用恶意更新服务器即可实现。

来自 MIT Lincoln Laboratory 的 Andrew Fasano 在他的[帖子](https://nation.state.actor/mcafee.html)中提到，他大概在 6 个月前发现了 McAfee 方案的漏洞，但是该安全公司只在本月初才打了补丁。

“第一眼看，McAfee VirusScan Enterprise for Linux 具备漏洞研究者喜欢的所有特征：它以 root 身份运行, 它宣称可使你的机器更安全，它不是特别流行，而且看起来它很久不更新。” 他写道。

在他的帖子中，Fasano 解释说一旦该 app 连接到被攻破的更新服务器，McAfee VirusScan Enterprise for Linux 就允许部署一个脚本，该脚本可使用 root 权限在目标机上启动。

McAfee 的 Linux 安全解决方案中有 10 个不同的漏洞，但研究人员说只需其中 4 个就可成功的攻陷 Linux 系统。

所有这些漏洞已在版本 1.9.2 到 2.0.2 中得到确认，建议所有 Linux 系统升级到 McAfee 本月发布的最新版本。

### 基于 Red Hat Enterprise Linux 7.3 的 CentOS Linux 7 (1611) 发布

2016 年 12 月 12 日, CentOS 维护人员 Karanbir Singh 高兴的宣布，期待已久的基于 Red Hat Enterprise Linux 的 CentOS Linux 7 (1611) 系统发布。

Red Hat 上个月[宣布](http://news.softpedia.com/news/red-hat-enterprise-linux-7-3-released-with-new-container-signing-capability-509938.shtml)发布 Red Hat Enterprise Linux 7.3 系统，显然 CentOS Linux 7 是在它的基础上由 Karanbir Singh 和其他的优秀开发人员共同完成的。

“这个版本是用来自于 git.centos.org 的源文件编译的。此外，作为此次构建副产品的 SRPM（在代码和 buildsys 过程中很重要）也一同公布，以与我们发布的每一个二进制 RPM 匹配，” Karanbir Singh 在[邮件列表](https://lists.centos.org/pipermail/centos-announce/2016-December/022172.html)中写到。

[点击这里](http://wiki.centos.org/Manuals/ReleaseNotes/CentOS7)查看此次发布的[发布公告](http://wiki.centos.org/Manuals/ReleaseNotes/CentOS7)，包括此版本的重要信息，以及来自 CentOS QA 团队的关于此版本某些内容的细节说明。

现在已有 64 位上的 CentOS Linux 7 (1611) 可下载，可从[这里](http://linux.softpedia.com/get/System/Operating-Systems/Linux-Distributions/CentOS-906.shtml)下载。

### 面向安全的 CoreOS Linux 更名为 Container Linux

2016 年 12 月 12 日，CoreOS 开发者 Alex Polvi 宣布 CoreOS 这个面向安全的 GNU/Linux 发布版更名为 Container Linux by CoreOS。

![](/data/attachment/album/201612/19/093202o7eoklrri77fk4dk.png)

更名的决定是在早些时候，CoreOS 主持的 2016 Tectonic 峰会上决定的，当时该团队还公布了下一代 CoreOS Tectonic enterprise Kubernetes 解决方案，以部署和管理大规模的容器，它基于 Kubernetes 1.5 版本来实现自驱动能力。

好消息是可以继续免费使用 10 个节点以内的 CoreOS Tectonic。 在此公告后 Kubernetes 1.5 很快会发布，建议您如果好奇它有什么新特性的话，看看它的[发布公告](https://coreos.com/blog/tectonic-self-driving.html)。同时可以下载最新的 [Container Linux](http://linux.softpedia.com/get/Linux-Distributions/CoreOS-103458.shtml)。

### 基于 SUSE Linux Enterprise 12 SP3 的 openSUSE Leap 42.3 进入开放开发阶段

2016 年 12 月 13 日，openSUSE Linux 开发者 Ludwig Nussel 宣布，openSUSE Leap 系统的下一个大版本进入开发阶段。

很多人还刚刚定制完崭新的 openSUSE Leap 42.2 的安装，开来这个开发团队是没有时间休息了。

openSUSE Leap 42.2 是基于 SUSE Linux Enterprise 12 Service Pack 2 (SP2) 系统，显然下一个大版本，openSUSE Leap 42.3，将基于 SUSE Linux Enterprise 12 Service Pack 3 (SP3)， 预计 2017 年第三季度某个时候发布。

根据 Ludwig Nussel，SUSE Linux Enterprise 12 SP 3 比预计的 11 月发布早了一点，这也是 openSUSE Leap 42.3 现在开放开发，准备接收提交的新的包，bug 修复，以及最新 GNU/Linux 技术的原因。


双赢：开源 .Net ，微软收获了大批开发者

Summary: 不管微软积极拥抱开源背后的想法是什么，或许是想通过开源销售更多的软件或者云服务，也有可能是想吸引更多的开发者到微软平台上，但是目前看起来微软这步棋是下对了。从微软开源 .Net 和  ASP.Net 之后的分析看，微软的开源战略已经值回票价了。

微软或成为最大赢家！

C# for  xamarin写C#代码，一次编写，却可以同时编译 成iOS、android的原生代码，这个应该是最厉害的了。还是就是用C#开发Unity游戏也是厉害了,.net core 的跨平台也是非常厉害的，我还是觉得，主要是换了CEO带来的改变是前所未有的。

来自江西南昌的 Microsoft Edge 14.14393|Windows 10 用户

不得不承认微软在某些软件细节上做的比某些厂商强太多，对，说的就是Oracle

如果微软能开源windows多好,  windows版本肯定能蹭蹭蹭地往上涨,

就在两年前，微软做了一件令人意想不到的事情：[它宣称将开源其 .Net 开发框架](/article-4209-1.html)，这包括 [.Net Core](/article-4821-1.html) 及 [ASP.Net](/article-4940-1.html) 等。这份公告非常令人吃惊，因为微软长久以来一直仇视开源项目，担忧开源软件破坏其软件生态。

随着微软 CEO 纳德拉宣称“[微软爱 Linux](/article-4923-1.html)”，微软在[开源方面的举措频频](/article-6774-1.html)，不仅仅在 GitHub 上其名下的几个[仓库活跃非凡](/article-7776-1.html)，而且也和各种开源厂商积极[展开合作](/article-6528-1.html)。

![](/data/attachment/album/201612/19/201801d54yyzqajmpay0aj.png)

不管微软积极拥抱开源背后的想法是什么，或许是想通过开源销售更多的软件或者云服务，也有可能是想吸引更多的开发者到微软平台上，但是目前看起来微软这步棋是下对了。从微软[开源 .Net](/article-6727-1.html) 和  [ASP.Net](/article-6921-1.html) 之后的分析看，微软的开源战略已经值回票价了。

微软现在将 .Net Core 定位为跨平台开发框架，不只是 Windows，而且也延伸到了 MacOS 和 Linux 平台之上。.Net Core RC1 是 2015 年 11 月发布到 GitHub 上的，而今年 6 月就发布了 1.0 版本。开发者们对此表示认可，微软合作伙伴总监项目经理 Scott Hunter 如是说：

>
> “40% 的 .Net Core 客户是新进入该平台的用户，这就是我们（开源）的目的，我们希望吸引新的用户。”
>
>
>

由于 .Net Core 的开源，过去一年以来， .Net 的开发者增加了 61%。 Hunter 在 11 月的一次讲演中提到，GitHub 上 .Net 上的开发活跃度增长极快。
虽然 .Net Core 并没有直接给微软带来收入，但是其潜在地增加了收益。Rob Sanfilippo 说，“可以说，这项技术间接地通过 Azure 服务和微软开发者工具增加了微软的收入。”。

### 程序员们表现活跃

.Net 程序员和博客作者 [Matt Warren](http://mattwarren.org/) 把.Net 的开源称之为“成功”。[其数据](/article-6921-1.html)明确地显示社区积极地参与了微软在 GitHub 上开源的多个仓库的活动。

“开源社区汇报了问题和建议，并通过发送拉取请求（PR）而实际贡献了代码，经过一段时间之后，这些代码就会被包括到产品里面，而社区的贡献量还在持续增长”，Warren 说，“我积极跟踪和参与了 [CoreCLR](https://github.com/dotnet/coreclr/) 和 [.Net Core Lab](https://github.com/dotnet/corefxlab/) 这些仓库的讨论，因此获得了社区贡献的第一手资料。”

微软的举措是否完全成功还不能完全定论，未来或许还有变数，但是这终究是从封闭走向开放的一步。他说，“我的意思是，他们并不是仅仅把源代码放在那里就行了，而是努力让社区可以参与进来。”

### 微软最近发布的 Visual Studio for Mac 也为 .Net Core 带来了利好

“这是 Visual Studio IDE 首次发布到非 Windows 平台上（Visual Studio Code 是不同的技术，而且它根本不算 IDE），它是基于微软收购的 Xamarin 的技术，重点关注于 .Net Core 开发”，Sanfillippo 说，“这次发布近一步带动了 .Net Core 的发展。”

微软最近也准备在 Visual Studio 2017 IDE 中增强 .Net Core 工具，包括简化 .Net Core 项目文件的格式。

微软开源 .Net 让外界对它的观感有所改变， Warren 说，“现在感觉（微软）更开放和更平易近人了。”

相对于某些公司，虽然开源社区还对微软抱有一定的疑虑，但是显然，微软已经不是开源社区最敌视的公司了。

参考：[CIO](http://www.cio.com/article/3150814/application-development/win-win-open-source-net-pays-off-for-devs.html)、 [Matt Warren](http://mattwarren.org/)、[microsoft](https://www.microsoft.com/)


CentOS 7.3 安装指南

这种文章还有发上来的必要？？？？

这个种方法到是简单，楼主能测试一个硬盘安装法么，用分享一下GRUB2菜单，在centos7.2测试了好多grub2菜单都不得行，不知道7.3有没有新进展

确实没有必要，因为能在这里看文章的都不是什么连装系统都不会的小白。

哦，7.3发布了

我倒是觉得如果以后发带多图的文章，对于移动设备默认不显示图片，要看图手动点。

当我还是个小白的时候，就是来这看教程

小白鼎力支持

当我还是个小白的时候，就是来这看教程

好经典啊

想问一下这样重启之后出来的是带有图形界面的系统吗？

大佬，这个教程真好用

我还真是一个小白 这些文章就是给小白看的  没有人一下子就是大神

小白可以通过百度搜索进来

基于 Red Hat 企业版的源代码的最新版本的 CentOS 7 在今年的 12月[发布了 CentOS Linux 7 (1611)](/article-8046-1.html#3_1420) ，包含了许多 bug 修复、新的包更新，比如 Samba、Squid、libreoffice、SELinux、systemd 及其它软件，并支持第七代 Intel 酷睿 i3、i5、i7 处理器。

本指南会向你展示如何在 UEFI 的机器上使用 DVD ISO 镜像来安装 CentOS 7.3。

![](/data/attachment/album/201612/19/222453uzu2ulkkgfhxl0ug.png)

如果你要是用 RHEL，看下我们的 [RHEL 7.3 安装指南](/article-8067-1.html)。

#### 要求

* [下载 CentOS 7.3 ISO 镜像](http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso)

要在 UEFI 的机器上正确安装 CentOS 7.3，首先按下键（`F2`、`F11` 或 `F12`，取决与你的主板类型）进入主板的 UEFI 设置，并且确保 QuickBoot/FastBoot 以及 Secure Boot 已被禁用。

### CentOS 7.3 安装

1、 在你从上面的链接下载完成镜像之后，使用 [Rufus](https://rufus.akeo.ie/)将它烧录到 DVD 或者创建一个可启动的 UEFI 兼容 USB 盘。

将 USB/DVD 放入主板上连接的驱动器中，重启电脑并用特定的功能键（`F12`、 `F10`，取决于主板类型）让 BIOS/UEFI 从 DVD/USB 启动。

ISO 镜像启动完成后，你机器上会显示如下首屏。在菜单中选择 “Install CentOS 7”并按下回车继续。

![CentOS 7.3 Boot Menu](/data/attachment/album/201612/19/222502lddcqvm0jiviooqv.png)

*CentOS 7.3 启动菜单*

2、 在安装镜像加载到内存完成后，会显示一个欢迎页面。选择你在安装中使用的语言并按下“<ruby> 继续 <rp>  （ </rp> <rt>  Continue </rt> <rp>  ） </rp></ruby>”按钮。

![Select CentOS 7.3 Installation Language](/data/attachment/album/201612/19/222503ajzabjzivvgijhli.png)

*选择 CentOS 7.3 安装语言*

3、 在下一个页面点击“<ruby> 日期和时间 <rp>  （ </rp> <rt>  Date and Time </rt> <rp>  ） </rp></ruby>”，从地图中选择你的地理位置。确认日期和时间正确配置了并点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮来回到主安装界面。

![CentOS 7.3 Installation Summary ](/data/attachment/album/201612/19/222504bqz36oz2lnld2noh.png)

*CentOS 7.3 安装总结*

![Select Date and Time](/data/attachment/album/201612/19/222505epk5zs6vvuq04pjp.png)

*选择日期和时间*

4、 点击“<ruby> 键盘 <rp>  （ </rp> <rt>  Keyboard </rt> <rp>  ） </rp></ruby>”菜单进入键盘布局页面。选择或者添加一个键盘布局并点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮继续。

![Select Keyboard Layout](/data/attachment/album/201612/19/222506fyupnzfu2uucfyeo.png)

*选择键盘布局*

5、 接下来，为你的系统添加或者配置一个语言并点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮进入下一步。

![Select Language Support](/data/attachment/album/201612/19/222507sn8ncbqyq1ucuqe6.png)

*选择语言支持*

6、 在这步中，你可以通过选择列表中安全配置来设置你的系统“<ruby> 安全策略 <rp>  （ </rp> <rt>  Security Policy </rt> <rp>  ） </rp></ruby>”。

点击选择配置按钮来选择你想要的安全配置并点击“<ruby> 应用安全策略 <rp>  （ </rp> <rt>  Apply security policy </rt> <rp>  ） </rp></ruby>”按钮到 On。点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮后继续安装流程。

![Enable CentOS 7.3 Security Policy](/data/attachment/album/201612/19/222508bzf1354tnzzlw30c.png)

*启用 CentOS 7.3 安全策略*

7、 下一步中你可以点击“<ruby> 软件选择 <rp>  （ </rp> <rt>  Software Selection </rt> <rp>  ） </rp></ruby>”按钮来配置你的基础机器环境。

左边的列表是你可以选择安装桌面环境（Gnome、KDE Plasma 或者创意工作站）或者安装一个服务器环境（Web 服务器、计算节点、虚拟化主机、基础设施服务器、带图形界面的服务器或者文件及打印服务器）或者执行一个最小化的安装。

为了随后能自定义你的系统，选择最小化安装并附加兼容库，点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮继续。

![CentOS 7.3 Software Selection](/data/attachment/album/201612/19/222509pxit1pmupi8t98mt.png)

*CentOS 7.3 软件选择*

对于完整的 Gnome 或者 KDE 桌面环境，使用下面的截图作为指引。

![Gnome Desktop Software Selection](/data/attachment/album/201612/19/222510vezu2x2ue2jeaee8.png)

*Gnome 桌面软件选择*

![KDE Desktop Software Selection](/data/attachment/album/201612/19/222512nd8yd8q8jc1cyguh.png)

*KDE 桌面软件选择*

8、 假设你要在服务器上安装一个图形界面，选择左边那栏“<ruby> 带 GUI 的服务器 <rp>  （ </rp> <rt>  Server with GUI </rt> <rp>  ） </rp></ruby>”那项，并在右边那栏中根据你需要提供给客户端的服务选择合适的附加软件。

你可以选择的服务是非常多样化的，从备份、DNS 或者 e-mail 服务到文件存储服务、FTP、HA 或者监控工具。只选择对你网络设置最重要的服务。

![Select Server with GUI](/data/attachment/album/201612/19/222514vukcu0ccxuojcuu0.png)

*选择带 GUI 的服务器*

9、 如果你不使用特定的网络协议比如 HTTP、HTTPS、FTP 或者 NFS 的额外仓库，安装源保持默认，并点击“<ruby> 安装位置 <rp>  （ </rp> <rt>  Installation Destination </rt> <rp>  ） </rp></ruby>”来创建一个磁盘分区。

在“<ruby> 设备选择 <rp>  （ </rp> <rt>  Device selection </rt> <rp>  ） </rp></ruby>”页面，确保你已经选择了本地磁盘。同样，在“<ruby> 其他存储选项 <rp>  （ </rp> <rt>  Other Storage Options </rt> <rp>  ） </rp></ruby>”中确保选择了“<ruby> 自动配置分区 <rp>  （ </rp> <rt>  Automatically configure partitioning </rt> <rp>  ） </rp></ruby>”。

这个选项可以确保你的磁盘会恰当地根据磁盘空间和 Linux 文件系统层次结构进行分区。它会为你自动创建 `/（root）`、`/home`和 swap 分区。点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”来应用磁盘分区方案并回到主安装界面。

重要提醒：如果你想要创建自定义分区及自定义分区大小，你可以选择“<ruby> 我要配置分区 <rp>  （ </rp> <rt>  I will configure partitioning </rt> <rp>  ） </rp></ruby>”选项来创建自定义分区。

![Select CentOS 7.3 Installation Destination](/data/attachment/album/201612/19/222514u8pd8dzsjkgi3v9s.png)

*安装 CentOS 7.3 安装位置*

10、 接下来，如果你想要释放系统内存，点击 KDUMP 选项并禁用它。点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”并回到主安装界面。

![Kdump Selection](/data/attachment/album/201612/19/222515kesiyqvp55p5fy5v.png)

*Kdump 选择*

11、 在下一步中设置你的主机名并启用网络服务。点击“<ruby> 网络和主机名 <rp>  （ </rp> <rt>  Network & Hostname </rt> <rp>  ） </rp></ruby>”，在主机名中输入你的 FQDN（完整限定网域名称），如果你在局域网中有一个 DHCP 服务器，将以太网按钮从 OFF 切换到 ON 来激活网络接口。

![Set Network and Hostname](/data/attachment/album/201612/19/222517ya1zjdv5wj669y8y.png)

*设置网络及主机名*

12、 为了静态配置你的网络接口，点击“<ruby> 配置 <rp>  （ </rp> <rt>  Configure </rt> <rp>  ） </rp></ruby>”按钮，手动如截图所示添加 IP 设置，并点击“<ruby> 保存 <rp>  （ </rp> <rt>  Save </rt> <rp>  ） </rp></ruby>”按钮来应用更改。完成后，点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮来回到主安装菜单。

![Configure Network and IP Address](/data/attachment/album/201612/19/222518ek4lql64ypkaguwc.png)

*配置网络和 IP 地址*

13、 最后检查下所有到目前为止的配置，如果一切没问题，点击“<ruby> 开始安装 <rp>  （ </rp> <rt>  Begin Installation </rt> <rp>  ） </rp></ruby>”按钮开始安装。

![Begin CentOS 7.3 Installation Guide](/data/attachment/album/201612/19/222520oi7k1i3d498a54lo.png)

*开始 CentOS 7.3 安装向导*

14、 开始安装后，一个新的设置用户界面会显示出来。首先点击 “<ruby> root 密码 <rp>  （ </rp> <rt>  ROOT PASSWORD </rt> <rp>  ） </rp></ruby>”并添加一个强密码。

root 账户是每个 Linux 系统的最高管理账户密码，它拥有所有的权限。设置完成后点击完成按回到用户设置界面。

![Select Root Password](/data/attachment/album/201612/19/222522a23168d6v8b1cz81.png)

*选择 root 密码*

![Set Root Password](/data/attachment/album/201612/19/222525c9o4rozj39g3n9a3.png)

*设置 root 密码*

15、 用 root 账户运行系统是非常不安全和危险的，因此建议你点击“<ruby> 创建用户 <rp>  （ </rp> <rt>  User Creation </rt> <rp>  ） </rp></ruby>”按钮创建一个新的系统账户来[执行每日的系统任务](http://www.tecmint.com/file-and-directory-management-in-linux/)。

添加新的用户，并同时选择下面的两个选项来授予用户 root 权限以及每次在登录系统时手动输入密码。

当你完成最后一项点击“<ruby> 完成 <rp>  （ </rp> <rt>  Done </rt> <rp>  ） </rp></ruby>”按钮并等待安装完成。

![Create User Account](/data/attachment/album/201612/19/222526j4f6l3s88s4g4og1.png)

*创建用户账户*

16、 几分钟后安装程序会报告 CentOS 已经成功安装在你机器中。要使用系统，你只需要移除安装媒介并重启机器。

![CentOS 7.3 Installation Complete](/data/attachment/album/201612/19/222527eqllw6fubk6kkqkq.png)

*CentOS 7.3 安装完成*

17、 重启之后，使用安装中创建的用户登录系统，并且用 root 权限执行下面的命令来执行系统更新。

```
$ sudo yum update

```

![Update CentOS 7.3](/data/attachment/album/201612/19/222528x0g6e0ufz8zpp836.png)

*更新 CentOS 7.3*

所有 [yum 管理器](http://www.tecmint.com/20-linux-yum-yellowdog-updater-modified-commands-for-package-mangement/)的问题都选择`yes`，最后再次重启电脑（使用 `sudo init 6`）来应用新的内核升级。

```
$ sudo init 6

```

就是这样！在你的机器中享受最新的 CentOS 7.3 吧。

---

作者简介:

![](/data/attachment/album/201612/19/222529ahugkh0a0mk061jg.jpg)

Matei Cezar

我是一个电脑上瘾的家伙，一个开源和 Linux 系统软件的粉丝，有大约 4 年的 Linux 桌面、服务器和 bash 脚本的经验。

---

via: <http://www.tecmint.com/centos-7-3-installation-guide/>

作者：[Matei Cezar](http://www.tecmint.com/author/cezarmatei/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


Ubuntu 调查发现，大部分人从不更新他们的物联网设备

物联网是什么？能吃吗？

物联网设备，具体是指哪些设备呢？

对于功能更新，如果不是生产系统，我都是能更就更，可也出了不少问题，但如果出了问题自己不能解决，那还是谨慎一些比较好。对于安全更新当然要更了，但问题是去哪更？厂商会提供吗

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

许多物联网设备的用户鲜于更新他们的联网设备，而这正是造成许多物联网安全漏洞的根本原因。

Ubuntu 最近调查了 2000 名消费者以了解其是如何使用他们的联网设备的。该调查结果披露了令人吃惊的结果，仅有 31% 的人会在设备有固件更新后尽快进行更新，而近 40% 的人则从不会主动对设备固件进行更新！换句话说，这部分用户让他们的设备开着，暴露在 DDoS 和各种窃取隐私的攻击之下。

![](/data/attachment/album/201612/20/092256c2e0dvd7zf2d77kc.jpg)

消费者们不能（也不应该）预料到每个重要的软件更新，虽然这很简单，但是并不现实。几乎没有消费者会去专门看看他们遇到的问题是否解决了。根据投票结果，近 2/3 的消费者认为更新固件不是他们的责任，22% 的人认为这是软件开发者的工作，而 18% 的人认为这是设备厂商的责任。

显然，自动更新是一个解决方案，但是自动更新也会带来一些安全隐患。而且，很多厂商很少更新他们的设备固件，尤其是比较老的设备，更是更新频度极少。

那么你对物联网设备安全及设备固件更新方面有什么看法？