定制嵌入式 Linux 发行版

![](/data/attachment/album/201802/08/230216ozk2ks8swoy77gkk.jpg)

便宜的物联网板的普及意味着它不仅会控制应用程序，还会控制整个软件平台。 那么，如何构建一个针对特定用途的交叉编译应用程序的自定义发行版呢？ 正如 Michael J. Hammel 在这里解释的那样，它并不像你想象的那么难。

### 为什么要定制？

以前，许多嵌入式项目都使用现成的发行版，然后出于种种原因，再将它们剥离到只剩下基本的必需的东西。首先，移除不需要的包以减少占用的存储空间。在启动时，嵌入式系统一般不需要大量的存储空间以及可用存储空间。在嵌入式系统运行时，可能从非易失性内存中拷贝大量的操作系统文件到内存中。第二，移除用不到的包可以降低可能的攻击面。如果你不需要它们就没有必要把这些可能有漏洞的包挂在上面。最后，移除用不到包可以降低发行版管理的开销。如果在包之间有依赖关系，意味着任何一个包请求从上游更新，那么它们都必须保持同步。那样可能就会出现验证噩梦。

然而，从一个现有的发行版中去移除包并不像说的那样容易。移除一个包可能会打破与其它包保持的各种依赖关系，以及可能在上游的发行版管理中改变依赖。另外，由于一些包原生集成在引导或者运行时进程中，它们并不能轻易地简单地移除。所有这些都是项目之外的平台的管理，并且有可能会导致意外的开发延迟。

一个流行的选择是使用上游发行版供应商提供的构建工具去构建一个定制的发行版。无论是 Gentoo 还是 Debian 都提供这种自下而上的构建方式。这些构建工具中最为流行的可能是 Debian 的 debootstrap 实用程序。它取出预构建的核心组件并允许用户去精选出它们感兴趣的包来构建用户自己的平台。但是，debootstrap 最初仅在 x86 平台上可用，虽然，现在有了 ARM（也有可能会有其它的平台）选项。debootstrap 和 Gentoo 的 catalyst 仍然需要从本地项目中将依赖管理移除。

一些人认为让别人去管理平台软件（像 Android 一样）要比自己亲自管理容易的多。但是，那些发行版都是多用途的，当你在一个轻量级的、资源有限的物联网设备上使用它时，你可能会再三考虑从你手中被拿走的任何资源。

### 系统引导的基石

一个定制的 Linux 发行版要求许多软件组件。其中第一个就是<ruby> 工具链 <rt>  toolchain </rt></ruby>。工具链是用于编译软件的一套工具集。包括（但不限于）一个编译器、链接器、二进制操作工具以及标准的 C 库。工具链是为一个特定的目标硬件设备专门构建的。如果一个构建在 x86 系统上的工具链想要用于树莓派，那么这个工具链就被称为交叉编译工具链。当在内存和存储都十分有限的小型嵌入式设备上工作时，最好是使用一个交叉编译工具链。需要注意的是，即便是使用像 JavaScript 这样的需要运行在特定平台的脚本语言为特定用途编写的应用程序，也需要使用交叉编译工具链编译。

![](/data/attachment/album/201802/08/230248s36qs6s336266s6s.png)

*图 1. 编译依赖和引导顺序*

交叉编译工具链用于为目标硬件构建软件组件。需要的第一个组件是<ruby> 引导加载程序 <rt>  bootloader </rt></ruby>。当计算机主板加电之后，处理器（可能有差异，取决于设计）尝试去跳转到一个特定的内存位置去开始运行软件。那个内存位置就是保存引导加载程序的地方。硬件可能有内置的引导加载程序，它可能直接从它的存储位置或者可能在它运行前首先拷贝到内存中。也可能会有多个引导加载程序。例如，第一阶段的引导加载程序可能位于硬件的 NAND 或者 NOR 闪存中。它唯一的功能是设置硬件以便于执行第二阶段的引导加载程序——比如，存储在 SD 卡中的可以被加载并运行的引导加载程序。

引导加载程序能够从硬件中取得足够的信息，将 Linux 加载到内存中并跳转到正确的位置，将控制权有效地移交到 Linux。Linux 是一个操作系统。这意味着，在这种设计中，它除了监控硬件和向上层软件（也就是应用程序）提供服务外，它实际上什么都不做。[Linux 内核](https://www.kernel.org) 中通常是各种各样的固件块。那些预编译的软件对象，通常包含硬件平台使用的设备的专用 IP（知识资产）。当构建一个定制发行版时，在开始编译内核之前，它可能会要求获得一些 Linux 内核源代码树没有提供的必需的固件块。

应用程序保存在根文件系统中，这个根文件系统是通过编译构建的，它集合了各种软件库、工具、脚本以及配置文件。总的来说，它们都提供各种服务，比如，网络配置和 USB 设备挂载，这些都是将要运行的项目应用程序所需要的。

总的来说，一个完整的系统构建要求下列的组件：

1. 一个交叉编译工具链
2. 一个或多个引导加载程序
3. Linux 内核和相关的固件块
4. 一个包含库、工具以及实用程序的根文件系统
5. 定制的应用程序

### 使用适当的工具开始构建

交叉编译工具链的组件可以手工构建，但这是一个很复杂的过程。幸运的是，现有的工具可以很容易地完成这一过程。构建交叉编译工具链的最好工具可能是 [Crosstool-NG](http://crosstool-ng.github.io)，这个工具使用了与 Linux 内核相同的 kconfig 菜单系统来构建工具链的每个细节和方面。使用这个工具的关键是，为目标平台找到正确的配置项。配置项通常包含下列内容：

1. 目标架构，比如，是 ARM 还是 x86。
2. 字节顺序：小端字节顺序（一般情况下，Intel 采用这种顺序）还是大端字节顺序（一般情况下，ARM 或者其它的平台采用这种顺序）。
3. 编译器已知的 CPU 类型，比如，GCC 可以使用 `-mcpu` 或 `--with-cpu`。
4. 支持的浮点类型，如果有的话，比如，GCC 可以使用 `-mfpu` 或 `--with-fpu`。
5. <ruby> 二进制实用工具 <rt>  binutils </rt></ruby>、C 库以及 C 编译器的特定版本信息。

![](/data/attachment/album/201802/08/230253irtdk4h4j40m8rej.png)

*图 2. Crosstool-NG 配置菜单*

前四个一般情况下可以从处理器制造商的文档中获得。对于较新的处理器，它们可能不容易找到，但是，像树莓派或者 BeagleBoards（以及它们的后代和分支），你可以在像 [嵌入式 Linux Wiki](https://elinux.org/Main_Page) 这样的地方找到相关信息。

二进制实用工具、C 库、以及 C 编译器的版本，将与任何第三方提供的其它工具链分开。首先，它们中的每一个都有多个提供者。Linaro 为最新的处理器类型提供了最先进的版本，同时致力于将该支持合并到像 GNU C 库这样的上游项目中。尽管你可以使用各种提供者的工具，你可能依然想去使用现成的 GNU 工具链或者相同的 Linaro 版本。

在 Crosstool-NG 中的另外的重要选择是 Linux 内核的版本。这个选择将得到用于各种工具链组件的<ruby> 头文件 <rt>  headers </rt></ruby>，但是它没有必要一定与你在目标硬件上将要引导的 Linux 内核相同。选择一个不比目标硬件的内核更新的 Linux 内核是很重要的。如果可能的话，尽量选择一个比目标硬件使用的内核更老的长周期支持（LTS）的内核。

对于大多数不熟悉构建定制发行版的开发者来说，工具链的构建是最为复杂的过程。幸运的是，大多数硬件平台的二进制工具链都可以想办法得到。如果构建一个定制的工具链有问题，可以在线搜索像 [嵌入式 Linux Wiki](https://elinux.org/Main_Page) 这样的地方去查找预构建工具链。

### 引导选项

在构建完工具链之后，接下来的工作是引导加载程序。引导加载程序用于设置硬件，以便于越来越复杂的软件能够使用这些硬件。第一阶段的引导加载程序通常由目标平台制造商提供，它通常被烧录到类似于 EEPROM 或者 NOR 闪存这类的在硬件上的存储中。第一阶段的引导加载程序将使设备从这里（比如，一个 SD 存储卡）开始引导。树莓派的引导加载程序就是这样的，它样做也就没有必要再去创建一个定制引导加载程序。

尽管如此，许多项目还是增加了第二阶段的引导加载程序，以便于去执行一个多样化的任务。在无需使用 Linux 内核或者像 plymouth 这样的用户空间工具的情况下提供一个启动动画，就是其中一个这样的任务。一个更常见的第二阶段引导加载程序的任务是去提供基于网络的引导或者使连接到 PCI 上的磁盘可用。在那种情况下，一个第三阶段的引导加载程序，比如 GRUB，可能才是让系统运行起来所必需的。

最重要的是，引导加载程序加载 Linux 内核并使它开始运行。如果第一阶段引导加载程序没有提供一个在启动时传递内核参数的机制，那么，在第二阶段的引导加载程序中就必须要提供。

有许多的开源引导加载程序可以使用。[U-Boot 项目](https://www.denx.de/wiki/U-Boot) 通常用于像树莓派这样的 ARM 平台。CoreBoot 一般是用于像 Chromebook 这样的 x86 平台。引导加载程序是特定于目标硬件专用的。引导加载程序的选择总体上取决于项目的需求以及目标硬件（可以去网络上在线搜索开源引导加载程序的列表）。

### 现在到了 Linux 登场的时候

引导加载程序将加载 Linux 内核到内存中，然后去运行它。Linux 就像一个扩展的引导加载程序：它进行进行硬件设置以及准备加载高级软件。内核的核心将设置和提供在应用程序和硬件之间共享使用的内存；提供任务管理器以允许多个应用程序同时运行；初始化没有被引导加载程序配置的或者是已经配置了但是没有完成的硬件组件；以及开启人机交互界面。内核也许不会配置为在自身完成这些工作，但是，它可以包含一个嵌入的、轻量级的文件系统，这类文件系统大家熟知的有 initramfs 或者 initrd，它们可以独立于内核而创建，用于去辅助设置硬件。

内核操作的另外的事情是去下载二进制块（通常称为固件）到硬件设备。固件是用特定格式预编译的对象文件，用于在引导加载程序或者内核不能访问的地方去初始化特定硬件。许多这种固件对象可以从 Linux 内核源仓库中获取，但是，还有很多其它的固件只能从特定的硬件供应商处获得。例如，经常由它们自己提供固件的设备有数字电视调谐器或者 WiFi 网卡等。

固件可以从 initramfs 中加载，也或者是在内核从根文件系统中启动 init 进程之后加载。但是，当你去创建一个定制的 Linux 发行版时，创建内核的过程常常就是获取各种固件的过程。

### 轻量级核心平台

Linux 内核做的最后一件事情是尝试去运行一个被称为 init 进程的专用程序。这个专用程序的名字可能是 init 或者 linuxrc 或者是由加载程序传递给内核的名字。init 进程保存在一个能够被内核访问的文件系统中。在 initramfs 这种情况下，这个文件系统保存在内存中（它可能是被内核自己放置到那里，也可能是被引导加载程序放置在那里）。但是，对于运行更复杂的应用程序，initramfs 通常并不够完整。因此需要另外一个文件系统，这就是众所周知的根文件系统。

![](/data/attachment/album/201802/08/230256cbbmpamzrjkak7zk.png)

*图 3. 构建 root 配置菜单*

initramfs 文件系统可以使用 Linux 内核自身构建，但是更常用的作法是，使用一个被称为 [BusyBox](https://busybox.net) 的项目去创建。BusyBox 组合许多 GNU 实用程序（比如，grep 或者 awk）到一个单个的二进制文件中，以便于减小文件系统自身的大小。BusyBox 通常用于去启动根文件系统的创建过程。

但是，BusyBox 是特意轻量化设计的。它并不打算提供目标平台所需要的所有工具，甚至提供的工具也是经过功能简化的。BusyBox 有一个“姊妹”项目叫做 [Buildroot](https://buildroot.org)，它可以用于去得到一个完整的根文件系统，提供了各种库、实用程序，以及脚本语言。像 Crosstool-NG 和 Linux 内核一样，BusyBox 和 Buildroot 也都允许使用 kconfig 菜单系统去定制配置。更重要的是，Buildroot 系统自动处理依赖关系，因此，选定的实用程序将会保证该程序所需要的软件也会被构建并安装到 root 文件系统。

Buildroot 可以用多种格式去生成一个根文件系统包。但是，需要重点注意的是，这个文件系统是被归档的。单个的实用程序和库并不是以 Debian 或者 RPM 格式打包进去的。使用 Buildroot 将生成一个根文件系统镜像，但是它的内容不是单独的包。即使如此，Buildroot 还是提供了对 opkg 和 rpm 包管理器的支持的。这意味着，虽然根文件系统自身并不支持包管理，但是，安装在根文件系统上的定制应用程序能够进行包管理。

### 交叉编译和脚本化

Buildroot 的其中一个特性是能够生成一个临时树。这个目录包含库和实用程序，它可以被用于去交叉编译其它应用程序。使用临时树和交叉编译工具链，使得在主机系统上而不是目标平台上对 Buildroot 之外的其它应用程序编译成为可能。使用 rpm 或者 opkg 包管理软件之后，这些应用程序可以在运行时使用包管理软件安装在目标平台的根文件系统上。

大多数定制系统的构建都是围绕着用脚本语言构建应用程序的想法去构建的。如果需要在目标平台上运行脚本，在 Buildroot 上有多种可用的选择，包括 Python、PHP、Lua 以及基于 Node.js 的 JavaScript。对于需要使用 OpenSSL 加密的应用程序也提供支持。

### 接下来做什么

Linux 内核和引导加载程序的编译过程与大多数应用程序是一样的。它们的构建系统被设计为去构建一个专用的软件位。Crosstool-NG 和 Buildroot 是<ruby> 元构建 <rt>  metabuild </rt></ruby>。元构建是将一系列有自己构建系统的软件集合封装为一个构建系统。可靠的元构建包括 [Yocto](https://www.yoctoproject.org) 和 [OpenEmbedded](https://www.openembedded.org/wiki/Main_Page)。Buildroot 的好处是可以将更高级别的元构建进行轻松的封装，以便于将定制 Linux 发行版的构建过程自动化。这样做之后，将会打开 Buildroot 指向到项目专用的缓存仓库的选项。使用缓存仓库可以加速开发过程，并且可以在无需担心上游仓库变化的情况下提供构建快照。

一个实现高级构建系统的示例是 [PiBox](https://www.piboxproject.com)。PiBox 就是封装了在本文中讨论的各种工具的一个元构建。它的目的是围绕所有工具去增加一个通用的 GNU Make 目标架构，以生成一个核心平台，这个平台可以构建或分发其它软件。PiBox 媒体中心和 kiosk 项目是安装在核心平台之上的应用层软件的实现，目的是用于去产生一个构建平台。[Iron Man 项目](http://redmine.graphics-muse.org/projects/ironman/wiki/Getting_Started) 是为了家庭自动化的目的而扩展了这种应用程序，它集成了语音管理和物联网设备的管理。

但是，PiBox 如果没有这些核心的软件工具，它什么也做不了。并且，如果不去深入了解一个完整的定制发行版的构建过程，那么你将无法正确运行 PiBox。而且，如果没有 PiBox 开发团队对这个项目的长期奉献，也就没有 PiBox 项目，它完成了定制发行版构建中的大量任务。

---

via: <http://www.linuxjournal.com/content/custom-embedded-linux-distributions>

作者：[Michael J.Hammel](http://www.linuxjournal.com/user/1000879) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


优化 MySQL： 3 个简单的小调整

如果你不改变 MySQL 的缺省配置，你的服务器的性能就像题图的坏在一档的法拉利一样 “虎落平阳被犬欺” …

![](/data/attachment/album/201802/09/123814odzby7s38od8u48h.png)

我并不期望成为一个专家级的 DBA，但是，在我优化 MySQL 时，我推崇 80/20 原则，明确说就是通过简单的调整一些配置，你可以压榨出高达 80% 的性能提升。尤其是在服务器资源越来越便宜的当下。

### 警告

1. 没有两个数据库或者应用程序是完全相同的。这里假设我们要调整的数据库是为一个“典型”的 Web 网站服务的，优先考虑的是快速查询、良好的用户体验以及处理大量的流量。
2. 在你对服务器进行优化之前，请做好数据库备份！

### 1、 使用 InnoDB 存储引擎

如果你还在使用 MyISAM 存储引擎，那么是时候转换到 InnoDB 了。有很多的理由都表明 InnoDB 比 MyISAM 更有优势，如果你关注性能，那么，我们来看一下它们是如何利用物理内存的：

* MyISAM：仅在内存中保存索引。
* InnoDB：在内存中保存索引**和**数据。

结论：保存在内存的内容访问速度要比磁盘上的更快。

下面是如何在你的表上去转换存储引擎的命令：

```
ALTER TABLE table_name ENGINE=InnoDB;

```

*注意：你已经创建了所有合适的索引，对吗？为了更好的性能，创建索引永远是第一优先考虑的事情。*

### 2、 让 InnoDB 使用所有的内存

你可以在 `my.cnf` 文件中编辑你的 MySQL 配置。使用 `innodb_buffer_pool_size` 参数去配置在你的服务器上允许 InnoDB 使用物理内存数量。

对此（假设你的服务器*仅仅*运行 MySQL），公认的“经验法则”是设置为你的服务器物理内存的 80%。在保证操作系统不使用交换分区而正常运行所需要的足够内存之后 ，尽可能多地为 MySQL 分配物理内存。

因此，如果你的服务器物理内存是 32 GB，可以将那个参数设置为多达 25 GB。

```
innodb_buffer_pool_size = 25600M

```

\*注意：（1）如果你的服务器内存较小并且小于 1 GB。为了适用本文的方法，你应该去升级你的服务器。 （2） 如果你的服务器内存特别大，比如，它有 200 GB，那么，根据一般常识，你也没有必要为操作系统保留多达 40 GB 的内存。 \*

### 3、 让 InnoDB 多任务运行

如果服务器上的参数 `innodb_buffer_pool_size` 的配置是大于 1 GB，将根据参数 `innodb_buffer_pool_instances` 的设置， 将 InnoDB 的缓冲池划分为多个。

拥有多于一个的缓冲池的好处有：

>
> 在多线程同时访问缓冲池时可能会遇到瓶颈。你可以通过启用多缓冲池来最小化这种争用情况：
>
>
>

对于缓冲池数量的官方建议是：

>
> 为了实现最佳的效果，要综合考虑 `innodb_buffer_pool_instances` 和 `innodb_buffer_pool_size` 的设置，以确保每个实例至少有不小于 1 GB 的缓冲池。
>
>
>

因此，在我们的示例中，将参数 `innodb_buffer_pool_size` 设置为 25 GB 的拥有 32 GB 物理内存的服务器上。一个合适的设置为 25600M / 24 = 1.06 GB

```
innodb_buffer_pool_instances = 24

```

### 注意！

在修改了 `my.cnf` 文件后需要重启 MySQL 才能生效：

```
sudo service mysql restart

```

还有更多更科学的方法来优化这些参数，但是这几点可以作为一个通用准则来应用，将使你的 MySQL 服务器性能更好。

---

作者简介:

我喜欢商业技术以及跑车 | 集团 CTO @ Parcel Monkey， Cloud Fulfilment & Kong。

---

via: <https://medium.com/@richb_/tuning-mysql-3-simple-tweaks-6356768f9b90>

作者：[Rich Barrett](https://medium.com/@richb_) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


Gerg：Meltdown 和 Spectre 影响下的 Linux 内核状况

![](/data/attachment/album/201802/09/211831lzys5xy9p0nxylxx.png)

现在（LCTT 译注：本文发表于 1 月初），每个人都知道一件关乎电脑安全的“大事”发生了，真见鬼，等[每日邮报报道](http://www.dailymail.co.uk/sciencetech/article-5238789/Intel-says-security-updates-fix-Meltdown-Spectre.html)的时候，你就知道什么是糟糕了...

不管怎样，除了告诉你这篇写的及其出色的[披露该问题的 Zero 项目的论文](https://googleprojectzero.blogspot.fr/2018/01/reading-privileged-memory-with-side.html)之外，我不打算去跟进这个问题已经被报道出来的细节。他们应该现在就直接颁布 2018 年的 [Pwnie](https://pwnies.com/) 奖，干的太棒了。

如果你想了解我们如何在内核中解决这些问题的技术细节，你可以保持关注了不起的 [lwn.net](https://lwn.net/Articles/743265/)，他们会把这些细节写成文章。

此外，这有一条很好的关于[这些公告](https://lwn.net/Articles/742999/)的摘要，包括了各个厂商的公告。

至于这些涉及的公司是如何处理这些问题的，这可以说是如何**不**与 Linux 内核社区保持沟通的教科书般的例子。这件事涉及到的人和公司都知道发生了什么，我确定这件事最终会出现，但是目前我需要去关注的是如何修复这些涉及到的问题，然后不去点名指责，不管我有多么的想去这么做。

### 你现在能做什么

如果你的 Linux 系统正在运行一个正常的 Linux 发行版，那么升级你的内核。它们都应该已经更新了，然后在接下来的几个星期里保持更新。我们会统计大量在极端情况下出现的 bug ，这里涉及的测试很复杂，包括庞大的受影响的各种各样的系统和工作任务。如果你的 Linux 发行版没有升级内核，我强烈的建议你马上更换一个 Linux 发行版。

然而有很多的系统因为各种各样的原因（听说它们比起“传统”的企业发行版更多）不是在运行“正常的” Linux 发行版上。它们依靠长期支持版本（LTS）的内核升级，或者是正常的稳定内核升级，或者是内部的某人打造版本的内核。对于这部分人，这篇介绍了你能使用的上游内核中发生的混乱是怎么回事。

### Meltdown – x86

现在，Linus 的内核树包含了我们当前所知的为 x86 架构解决 meltdown 漏洞的所有修复。开启 `CONFIG_PAGE_TABLE_ISOLATION` 这个内核构建选项，然后进行重构和重启，所有的设备应该就安全了。

然而，Linus 的内核树当前处于 4.15-rc6 这个版本加上一些未完成的补丁。4.15-rc7 版本要明天才会推出，里面的一些补丁会解决一些问题。但是大部分的人不会在一个“正常”的环境里运行 -rc 内核。

因为这个原因，x86 内核开发者在<ruby> 页表隔离 <rt>  page table isolation </rt></ruby>代码的开发过程中做了一个非常好的工作，好到要反向移植到最新推出的稳定内核 4.14 的话，我们只需要做一些微不足道的工作。这意味着最新的 4.14 版本（本文发表时是 4.14.12 版本），就是你应该运行的版本。4.14.13 会在接下来的几天里推出，这个更新里有一些额外的修复补丁，这些补丁是一些运行 4.14.12 内核且有启动时间问题的系统所需要的（这是一个显而易见的问题，如果它不启动，就把这些补丁加入更新排队中）。

我个人要感谢 Andy Lutomirski、Thomas Gleixner、Ingo Molnar、 Borislav Petkov、 Dave Hansen、 Peter Zijlstra、 Josh Poimboeuf、 Juergen Gross 和 Linus Torvalds。他们开发出了这些修复补丁，并且为了让我能轻松地使稳定版本能够正常工作，还把这些补丁以一种形式融合到了上游分支里。没有这些工作，我甚至不敢想会发生什么。

对于老的长期支持内核（LTS），我主要依靠 Hugh Dickins、 Dave Hansen、 Jiri Kosina 和 Borislav Petkov 优秀的工作，来为 4.4 到 4.9 的稳定内核代码树分支带去相同的功能。我同样在追踪讨厌的 bug 和缺失的补丁方面从 Guenter Roeck、 Kees Cook、 Jamie Iles 以及其他很多人那里得到了极大的帮助。我要感谢 David Woodhouse、 Eduardo Valentin、 Laura Abbott 和 Rik van Riel 在反向移植和集成方面的帮助，他们的帮助在许多棘手的地方是必不可少的。

这些长期支持版本的内核同样有 `CONFIG_PAGE_TABLE_ISOLATION` 这个内核构建选项，你应该开启它来获得全方面的保护。

从主线版本 4.14 和 4.15 的反向移植是非常不一样的，它们会出现不同的 bug，我们现在知道了一些在工作中遇见的 VDSO 问题。一些特殊的虚拟机安装的时候会报一些奇怪的错，但这是只是现在出现的少数情况，这种情况不应该阻止你进行升级。如果你在这些版本中遇到了问题，请让我们在稳定内核邮件列表中知道这件事。

如果你依赖于 4.4 和 4.9 或是现在的 4.14 以外的内核代码树分支，并且没有发行版支持你的话，你就太不幸了。比起你当前版本内核包含的上百个已知的漏洞和 bug，缺少补丁去解决 meltdown 问题算是一个小问题了。你现在最需要考虑的就是马上把你的系统升级到最新。

与此同时，臭骂那些强迫你运行一个已被废弃且不安全的内核版本的人，他们是那些需要知道这是完全不顾后果的行为的人中的一份子。

### Meltdown – ARM64

现在 ARM64 为解决 Meltdown 问题而开发的补丁还没有并入 Linus 的代码树，一旦 4.15 在接下来的几周里成功发布，他们就准备[阶段式地并入](https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=kpti) 4.16-rc1，因为这些补丁还没有在一个 Linus 发布的内核中，我不能把它们反向移植进一个稳定的内核版本里（额……我们有这个[规矩](https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html)是有原因的）

由于它们还没有在一个已发布的内核版本中，如果你的系统是用的 ARM64 的芯片（例如 Android ），我建议你选择 [Android 公共内核代码树](https://android.googlesource.com/kernel/common/)，现在，所有的 ARM64 补丁都并入 [3.18](https://android.googlesource.com/kernel/common/+/android-3.18)、[4.4](https://android.googlesource.com/kernel/common/+/android-4.4) 和 [4.9](https://android.googlesource.com/kernel/common/+/android-4.9) 分支 中。

我强烈建议你关注这些分支，看随着时间的过去，由于测试了已并入补丁的已发布的上游内核版本，会不会有更多的修复补丁被补充进来，特别是我不知道这些补丁会在什么时候加进稳定的长期支持内核版本里。

对于 4.4 到 4.9 的长期支持内核版本，这些补丁有很大概率永远不会并入它们，因为需要大量的先决补丁。而所有的这些先决补丁长期以来都一直在 Android 公共内核版本中测试和合并，所以我认为现在对于 ARM 系统来说，仅仅依赖这些内核分支而不是长期支持版本是一个更好的主意。

同样需要注意的是，我合并所有的长期支持内核版本的更新到这些分支后通常会在一天之内或者这个时间点左右进行发布，所以你无论如何都要关注这些分支，来确保你的 ARM 系统是最新且安全的。

### Spectre

现在，事情变得“有趣”了……

再一次，如果你正在运行一个发行版的内核，一些内核融入了各种各样的声称能缓解目前大部分问题的补丁，你的内核*可能*就被包含在其中。如果你担心这一类的攻击的话，我建议你更新并测试看看。

对于上游来说，很好，现状就是仍然没有任何的上游代码树分支合并了这些类型的问题相关的修复补丁。有很多的邮件列表在讨论如何去解决这些问题的解决方案，大量的补丁在这些邮件列表中广为流传，但是它们尚处于开发前期，一些补丁系列甚至没有被构建或者应用到任何已知的代码树，这些补丁系列彼此之间相互冲突，这是常见的混乱。

这是由于 Spectre 问题是最近被内核开发者解决的。我们所有人都在 Meltdown 问题上工作，我们没有精确的 Spectre 问题全部的真实信息，而四处散乱的补丁甚至比公开发布的补丁还要糟糕。

因为所有的这些原因，我们打算在内核社区里花上几个星期去解决这些问题并把它们合并到上游去。修复补丁会进入到所有内核的各种各样的子系统中，而且在它们被合并后，会集成并在稳定内核的更新中发布，所以再次提醒，无论你使用的是发行版的内核还是长期支持的稳定内核版本，你最好并保持更新到最新版。

这不是好消息，我知道，但是这就是现实。如果有所安慰的话，似乎没有任何其它的操作系统完全地解决了这些问题，现在整个产业都在同一条船上，我们只需要等待，并让开发者尽快地解决这些问题。

提出的解决方案并非毫不重要，但是它们中的一些还是非常好的。一些新概念会被创造出来来帮助解决这些问题，Paul Turner 提出的 Retpoline 方法就是其中的一个例子。这将是未来大量研究的一个领域，想出方法去减轻硬件中涉及的潜在问题，希望在它发生前就去预见它。

### 其他架构的芯片

现在，我没有看见任何 x86 和 arm64 架构以外的芯片架构的补丁，听说在一些企业发行版中有一些用于其他类型的处理器的补丁，希望他们在这几周里能浮出水面，合并到合适的上游那里。我不知道什么时候会发生，如果你使用着一个特殊的架构，我建议在 arch-specific 邮件列表上问这件事来得到一个直接的回答。

### 结论

再次说一遍，更新你的内核，不要耽搁，不要止步。更新会在很长的一段时间里持续地解决这些问题。同样的，稳定和长期支持内核发行版里仍然有很多其它的 bug 和安全问题，它们和问题的类型无关，所以一直保持更新始终是一个好主意。

现在，有很多非常劳累、坏脾气、缺少睡眠的人，他们通常会生气地让内核开发人员竭尽全力地解决这些问题，即使这些问题完全不是开发人员自己造成的。请关爱这些可怜的程序猿。他们需要爱、支持，我们可以为他们免费提供的他们最爱的饮料，以此来确保我们都可以尽可能快地结束修补系统。

---

via: <http://kroah.com/log/blog/2018/01/06/meltdown-status/>

作者：[Greg Kroah-Hartman](http://kroah.com) 译者：[hopefully2333](https://github.com/hopefully2333) 校对：[wxy](https://github.com/wxy)

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


为 Linux 初学者讲解 wc 命令

Summary: 在命令行工作时，有时您可能想要知道一个文件中的单词数量、字节数、甚至换行数量。

在命令行工作时，有时您可能想要知道一个文件中的单词数量、字节数、甚至换行数量。

![](/data/attachment/album/201802/09/232919mj5ahh8apsuepydt.jpg)

在命令行工作时，有时您可能想要知道一个文件中的单词数量、字节数、甚至换行数量。如果您正在寻找这样做的工具，您会很高兴地知道，在 Linux 中，存在一个命令行实用程序，它被称为 `wc` ，它为您完成所有这些工作。在本文中，我们将通过简单易懂的例子来讨论这个工具。

但是在我们开始之前，值得一提的是，本教程中提供的所有示例都在 Ubuntu 16.04 上进行了测试。

### Linux wc 命令

`wc` 命令打印每个输入文件的新行、单词和字节数。以下是该命令行工具的语法:

```
wc [OPTION]... [FILE]...

```

以下是 `wc` 的 man 文档的解释：

```
为每个文件打印新行、单词和字节数，如果指定多于一个文件，也列出总的行数。单词是由空格分隔的非零长度的字符序列。如果没有指定文件，或当文件为 `-`，则读取标准输入。

```

下面的 Q&A 样式的示例将会让您更好地了解 `wc` 命令的基本用法。

注意：在所有示例中我们将使用一个名为 `file.txt` 的文件作为输入文件。以下是该文件包含的内容：

```
hi
hello
how are you
thanks.

```

### Q1. 如何打印字节数

使用 `-c` 命令选项打印字节数.

```
wc -c file.txt

```

下面是这个命令在我们的系统上产生的输出：

[![如何打印字节数](/data/attachment/album/201802/09/232932ah1iqtgkcn1knddn.png)](https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/wc-c-option.png)

文件包含 29 个字节。

### Q2. 如何打印字符数

要打印字符数，请使用 `-m` 命令行选项。

```
wc -m file.txt

```

下面是这个命令在我们的系统上产生的输出：

[![如何打印字符数](/data/attachment/album/201802/09/232934j44lgkertkl1vtsg.png)](https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/wc-m-option.png)

文件包含 29 个字符。

### Q3. 如何打印换行数

使用 `-l` 命令选项来打印文件中的新行数：

```
wc -l file.txt

```

这里是我们的例子的输出：

[![如何打印换行数](/data/attachment/album/201802/09/232936ubbehhsephhmvv7v.png)](https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/wc-l-option.png)

### Q4. 如何打印单词数

要打印文件中的单词数量，请使用 `-w` 命令选项。

```
wc -w file.txt

```

在我们的例子中命令的输出如下：

[![如何打印字数](/data/attachment/album/201802/09/232938es50762fhnb5sa01.png)](https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/wc-w-option.png)

这显示文件中有 6 个单词。

### Q5. 如何打印最长行的显示宽度或长度

如果您想要打印输入文件中最长行的长度，请使用 `-l` 命令行选项。

```
wc -L file.txt

```

下面是在我们的案例中命令产生的结果：

[![如何打印最长行的显示宽度或长度](/data/attachment/album/201802/09/232940ovfdjojdsvufwut8.png)](https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/wc-L-option.png)

所以文件中最长的行长度是 11。

### Q6. 如何从文件读取输入文件名

如果您有多个文件名，并且您希望 `wc` 从一个文件中读取它们，那么使用`-files0-from` 选项。

```
wc --files0-from=names.txt

```

[![如何从文件读取输入文件名](/data/attachment/album/201802/09/232941aux4u1qphz4epmjg.png)](https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/wc-file0-from-option.png)

如你所见 `wc` 命令，在这个例子中，输出了文件 `file.txt` 的行、单词和字符计数。文件名为 `file.txt` 的文件在 `name.txt` 文件中提及。值得一提的是，要成功地使用这个选项，文件中的文件名应该用 NUL 终止——您可以通过键入`Ctrl + v` 然后按 `Ctrl + Shift + @` 来生成这个字符。

### 结论

正如您所认同的一样，从理解和使用目的来看， `wc` 是一个简单的命令。我们已经介绍了几乎所有的命令行选项，所以一旦你练习了我们这里介绍的内容，您就可以随时在日常工作中使用该工具了。想了解更多关于 `wc` 的信息，请参考它的 [man 文档](https://linux.die.net/man/1/wc)。

---

via: <https://www.howtoforge.com/linux-wc-command-explained-for-beginners-6-examples/>

作者：[Himanshu Arora](https://www.howtoforge.com) 译者：[stevenzdg988](https://github.com/stevenzdg988) 校对：[wxy](https://github.com/wxy)

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


Linux 内核 4.15：“一个不同寻常的发布周期”

Summary: Linus Torvalds 在周日（1 月 28 日）发布了 Linux 的 4.15 版内核，比原计划发布时间晚了一周。了解这次发行版的关键更新。

![Linux](/data/attachment/album/201802/10/095011cuxjqpmf7pyxkvh3.png "Linux")

>
> Linus Torvalds 在周日发布了 Linux 的 4.15 版内核，比原计划发布时间晚了一周。了解这次发行版的关键更新。
>
>
>

Linus Torvalds 在周日（1 月 28 日）[发布了 Linux 内核的 4.15 版](https://lkml.org/lkml/2018/1/28/173)，再一次比原计划晚了一周。延迟发布的罪魁祸首是 “Meltdown” 和 “Spectre” bug，由于这两个漏洞，使开发者不得不在这最后的周期中提交重大补丁。Torvalds 不愿意“赶工”，因此，他又给了一周时间去制作这个发行版本。

不出意外的话，这第一批补丁将是去修补前面提及的 [Meltdown 和 Spectre](https://meltdownattack.com/) 漏洞。为防范 Meltdown —— 这个影响 Intel 芯片的问题，在 x86 架构上[开发者实现了页表隔离（PTI）](https://git.kernel.org/linus/5aa90a84589282b87666f92b6c3c917c8080a9bf)。不论什么理由你如果想去关闭它，你可以使用内核引导选项 `pti=off` 去关闭这个特性。

Spectre v2 漏洞对 Intel 和 AMD 芯片都有影响，为防范它，[内核现在带来了 retpoline 机制](https://git.kernel.org/linus/76b043848fd22dbf7f8bf3a1452f8c70d557b860)。Retpoline 要求 GCC 的版本支持 `-mindirect-branch=thunk-extern` 功能。由于使用了 PTI，Spectre 抑制机制可以被关闭，如果需要去关闭它，在引导时使用 `spectre_v2=off` 选项。尽管开发者努力去解决 Spectre v1，但是，到目前为止还没有一个解决方案，因此，在 4.15 的内核版本中并没有这个 bug 的修补程序。

对于在 ARM 上的 Meltdown 解决方案也将在下一个开发周期中推送。但是，[对于 PowerPC 上的 bug，在这个发行版中包含了一个补救措施，那就是使用 L1-D 缓存的 RFI 冲刷特性](https://git.kernel.org/linus/aa8a5e0062ac940f7659394f4817c948dc8c0667)。

一个有趣的事情是，上面提及的所有受影响的新内核中，都带有一个 `/sys/devices/system/cpu/vulnerabilities/` 虚拟目录。这个目录显示了影响你的 CPU 的漏洞以及当前应用的补救措施。

芯片带 bug （以及保守秘密的制造商）的问题重新唤起了开发可行的开源替代品的呼声。这使得已经合并到主线版本的内核提供了对 [RISC-V](https://riscv.org/) 芯片的部分支持。RISC-V 是一个开源的指令集架构，它允许制造商去设计他们自己的基于 RISC-V 芯片的实现。并且因此也有了几个开源的芯片。虽然 RISC-V 芯片目前主要用于嵌入式设备，它能够去做像智能硬盘或者像 Arduino 这样的开发板，RISC-V 的支持者认为这个架构也可以用于个人电脑甚至是多节点的超级计算机上。

正如在上面提到的，[对 RISC-V 的支持](https://git.kernel.org/torvalds/c/b293fca43be544483b6488d33ad4b3ed55881064)，仍然没有全部完成，它虽然包含了架构代码，但是没有设备驱动。这意味着，虽然 Linux 内核可以在 RISC-V 芯片上运行，但是没有可行的方式与底层的硬件进行实质的交互。也就是说，RISC-V 不会受到其它闭源架构上的任何 bug 的影响，并且对它的支持的开发工作也在加速进行，因为，[RISC-V 基金会已经得到了一些行业巨头的支持](https://riscv.org/membership/)。

### 4.15 版新内核中的其它新特性

Torvalds 经常说他喜欢的事情是很无聊的。对他来说，幸运的是，除了 Spectre 和 Meltdown 引发的混乱之外，在 4.15 内核中的大部分其它东西都很普通，比如，对驱动的进一步改进、对新设备的支持等等。但是，还有几点需要重点指出，它们是：

* [AMD 对虚拟化安全加密的支持](https://git.kernel.org/linus/33e63acc119d15c2fac3e3775f32d1ce7a01021b)。它允许内核通过加密来实现对虚拟机内存的保护。加密的内存仅能够被使用它的虚拟机所解密。就算是 hypervisor 也不能看到它内部的数据。这意味着在云中虚拟机正在处理的数据，在虚拟机外的任何进程都看不到。
* 由于 [包含了*显示代码*](https://git.kernel.org/torvalds/c/f6705bf959efac87bca76d40050d342f1d212587)， AMD GPU 得到了极大的提升，这使得 Radeon RX Vega 和 Raven Ridge 显卡得到了内核主线版本的支持，并且也在 AMD 显卡中实现了 HDMI/DP 音频。
* 树莓派的爱好者应该很高兴，因为在新内核中， [7" 触摸屏现在已经得到原生支持](https://git.kernel.org/linus/2f733d6194bd58b26b705698f96b0f0bd9225369)，这将产生成百上千的有趣的项目。

要发现更多的特性，你可以去查看在 [Kernel Newbies](https://kernelnewbies.org/Linux_4.15) 和 [Phoronix](https://www.phoronix.com/scan.php?page=search&q=Linux+4.15) 上的内容。

---

via: <https://www.linux.com/blog/intro-to-linux/2018/1/linux-kernel-415-unusual-release-cycle>

作者：[PAUL BROWN](https://www.linux.com/users/bro66) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


如何启动进入 Linux 命令行

![](/data/attachment/album/201802/10/112026pnx0castr7l1ksvk.jpg)

可能有时候你启动 Linux 时需要或者希望不使用 GUI（图形用户界面），也就是没有 X，而是选择命令行。不管是什么原因，幸运的是，直接启动进入 Linux 命令行非常简单。它需要在其他内核选项之后对引导参数进行简单的更改。此更改将系统引导到指定的运行级别。

### 为什么要这样做？

如果你的系统由于无效配置或者显示管理器损坏或任何可能导致 GUI 无法正常启动的情况而无法运行 Xorg，那么启动到命令行将允许你通过登录到终端进行故障排除（假设你知道要怎么做），并能做任何你需要做的东西。引导到命令行也是一个很好的熟悉终端的方式，不然，你也可以为了好玩这么做。

### 访问 GRUB 菜单

在启动时，你需要访问 GRUB 启动菜单。如果在每次启动计算机时菜单未设置为显示，那么可能需要在系统启动之前按住 `SHIFT` 键。在菜单中，需要选择 Linux 发行版条目。高亮显示后该条目，按下 `e` 编辑引导参数。

[![zorin os grub menu](/data/attachment/album/201802/10/112027xfj784l4n8tmalto.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnu-grub_orig.png)

较老的 GRUB 版本遵循类似的机制。启动管理器应提供有关如何编辑启动参数的说明。

### 指定运行级别

会出现一个编辑器，你将看到 GRUB 会解析给内核的选项。移动到以 `linux` 开头的行（旧的 GRUB 版本可能是 `kernel`，选择它并按照说明操作）。这指定了要解析给内核的参数。在该行的末尾（可能会出现跨越多行，具体取决于你的终端分辨率），只需指定要引导的运行级别，即 `3`（多用户模式，纯文本）。

[![customize grub menu](/data/attachment/album/201802/10/112027d8emclm45bm7z47m.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_orig.png)

按下 `Ctrl-X` 或 `F10` 将使用这些参数启动系统。开机和以前一样。唯一改变的是启动的运行级别。

这是启动后的页面：

[![boot linux in command line](/data/attachment/album/201802/10/112027s4kxpnpfkw4x54pj.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_1_orig.png)

### 运行级别

你可以指定不同的运行级别，默认运行级别是 `5` （多用户图形界面）。`1` 启动到“单用户”模式，它会启动进入 root shell。`3` 提供了一个多用户命令行系统。

### 从命令行切换

在某个时候，你可能想要运行显示管理器来再次使用 GUI，最快的方法是运行这个：

```
$ sudo init 5

```

就这么简单。就我个人而言，我发现命令行比使用 GUI 工具更令人兴奋和上手。不过，这只是我的个人偏好。

---

via: <http://www.linuxandubuntu.com/home/how-to-boot-into-linux-command-line>

作者：[LinuxAndUbuntu](http://www.linuxandubuntu.com) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


cURL 与 wget：你应该选用哪一个？

![](/data/attachment/album/201802/10/113214z991g8h9g99zfd4h.jpg)

当想要直接通过 Linux 命令行下载文件，马上就能想到两个工具：wget 和 cURL。它们有很多一样的特征，可以很轻易的完成一些相同的任务。

虽然它们有一些相似的特征，但它们并不是完全一样。这两个程序适用与不同的场合，在特定场合下，都拥有各自的特性。

### cURL vs wget： 相似之处

wget 和 cURL 都可以下载内容。它们的核心就是这么设计的。它们都可以向互联网发送请求并返回请求项。这可以是文件、图片或者是其他诸如网站的原始 HTML 之类。

这两个程序都可以进行 HTTP POST 请求。这意味着它们都可以向网站发送数据，比如说填充表单什么的。

由于这两者都是命令行工具，它们都被设计成可脚本化。wget 和 cURL 都可以写进你的 [Bash 脚本](https://www.maketecheasier.com/beginners-guide-scripting-linux/) ，自动与新内容交互，下载所需内容。

### wget 的优势

![wget download](/data/attachment/album/201802/10/113216xpktn68tnvwnd1hw.jpg "wget download")

wget 简单直接。这意味着你能享受它超凡的下载速度。wget 是一个独立的程序，无需额外的资源库，更不会做其范畴之外的事情。

wget 是专业的直接下载程序，支持递归下载。同时，它也允许你下载网页中或是 FTP 目录中的任何内容。

wget 拥有智能的默认设置。它规定了很多在常规浏览器里的事物处理方式，比如 cookies 和重定向，这都不需要额外的配置。可以说，wget 简直就是无需说明，开罐即食！

### cURL 优势

![cURL Download](/data/attachment/album/201802/10/113216zp8zar8l1tgpbuku.jpg "cURL Download")

cURL是一个多功能工具。当然，它可以下载网络内容，但同时它也能做更多别的事情。

cURL 技术支持库是：libcurl。这就意味着你可以基于 cURL 编写整个程序，允许你基于 libcurl 库中编写图形环境的下载程序，访问它所有的功能。

cURL 宽泛的网络协议支持可能是其最大的卖点。cURL 支持访问 HTTP 和 HTTPS 协议，能够处理 FTP 传输。它支持 LDAP 协议，甚至支持 Samba 分享。实际上，你还可以用 cURL 收发邮件。

cURL 也有一些简洁的安全特性。cURL 支持安装许多 SSL/TLS 库，也支持通过网络代理访问，包括 SOCKS。这意味着，你可以越过 Tor 来使用cURL。

cURL 同样支持让数据发送变得更容易的 gzip 压缩技术。

### 思考总结

那你应该使用 cURL 还是使用 wget？这个比较得看实际用途。如果你想快速下载并且没有担心参数标识的需求，那你应该使用轻便有效的 wget。如果你想做一些更复杂的使用，直觉告诉你，你应该选择 cRUL。

cURL 支持你做很多事情。你可以把 cURL 想象成一个精简的命令行网页浏览器。它支持几乎你能想到的所有协议，可以交互访问几乎所有在线内容。唯一和浏览器不同的是，cURL 不会渲染接收到的相应信息。

---

via: <https://www.maketecheasier.com/curl-vs-wget/>

作者：[Nick Congleton](https://www.maketecheasier.com/author/nickcongleton/) 译者：[CYLeft](https://github.com/CYLeft) 校对：[wxy](https://github.com/wxy)

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


使用 Ansible 让你的系统管理自动化

>
> 精进你的系统管理能力和 Linux 技能，学习如何设置工具来简化管理多台机器。
>
>
>

![](/data/attachment/album/201802/10/121144exxulb5xlxeb5lau.jpg)

你是否想精进你的系统管理能力和 Linux 技能？也许你的本地局域网上跑了一些东西，而你又想让生活更轻松一点--那该怎么办呢？在本文中，我会向你演示如何设置工具来简化管理多台机器。

远程管理工具有很多，SaltStack、Puppet、Chef，以及 Ansible 都是很流行的选择。在本文中，我将重点放在 Ansible 上并会解释它是如何帮到你的，不管你是有 5 台还是 1000 台虚拟机。

让我们从多机（不管这些机器是虚拟的还是物理的）的基本管理开始。我假设你知道要做什么，有基础的 Linux 管理技能（至少要有能找出执行每个任务具体步骤的能力）。我会向你演示如何使用这一工具，而是否使用它由你自己决定。

### 什么是 Ansible？

Ansible 的网站上将之解释为 “一个超级简单的 IT 自动化引擎，可以自动进行云供给、配置管理、应用部署、服务内部编排，以及其他很多 IT 需求。” 通过在一个集中的位置定义好服务器集合，Ansible 可以在多个服务器上执行相同的任务。

如果你对 Bash 的 `for` 循环很熟悉，你会发现 Ansible 操作跟这很类似。区别在于 Ansible 是<ruby> 幕等的 <rt>  idempotent </rt></ruby>。通俗来说就是 Ansible 一般只有在确实会发生改变时才执行所请求的动作。比如，假设你执行一个 Bash 的 for 循环来为多个机器创建用户，像这样子：

```
for server in serverA serverB serverC; do ssh ${server} "useradd myuser"; done

```

这会在 serverA、serverB，以及 serverC 上创建 myuser 用户；然而不管这个用户是否存在，每次运行这个 for 循环时都会执行 `useradd` 命令。一个幕等的系统会首先检查用户是否存在，只有在不存在的情况下才会去创建它。当然，这个例子很简单，但是幕等工具的好处将会随着时间的推移变得越发明显。

#### Ansible 是如何工作的？

Ansible 会将 Ansible playbooks 转换成通过 SSH 运行的命令，这在管理类 UNIX 环境时有很多优势：

1. 绝大多数类 UNIX 机器默认都开了 SSH。
2. 依赖 SSH 意味着远程主机不需要有代理。
3. 大多数情况下都无需安装额外的软件，Ansible 需要 2.6 或更新版本的 Python。而绝大多数 Linux 发行版默认都安装了这一版本（或者更新版本）的 Python。
4. Ansible 无需主节点。他可以在任何安装有 Ansible 并能通过 SSH 访问的主机上运行。
5. 虽然可以在 cron 中运行 Ansible，但默认情况下，Ansible 只会在你明确要求的情况下运行。

#### 配置 SSH 密钥认证

使用 Ansible 的一种常用方法是配置无需密码的 SSH 密钥登录以方便管理。（可以使用 Ansible Vault 来为密码等敏感信息提供保护，但这不在本文的讨论范围之内）。现在只需要使用下面命令来生成一个 SSH 密钥，如示例 1 所示。

```
[09:44 user ~]$ ssh-keygen
Generating public/private rsa key pair。
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Created directory '/home/user/.ssh'。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa。
Your public key has been saved in /home/user/.ssh/id_rsa.pub。
The key fingerprint is:
SHA256:TpMyzf4qGqXmx3aqZijVv7vO9zGnVXsh6dPbXAZ+LUQ user@user-fedora
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|              E  |
|       o .   .。|
|   .  + S    o+。|
|  . .o * .  .+ooo|
| . .+o  o o oo+。*|
|。.ooo* o。*  .*+|
| . o+*BO.o+    .o|
+----[SHA256]-----+

```

*示例 1 ：生成一个 SSH 密钥*

在示例 1 中，直接按下回车键来接受默认值。任何非特权用户都能生成 SSH 密钥，也能安装到远程系统中任何用户的 SSH 的 `authorized_keys` 文件中。生成密钥后，还需要将之拷贝到远程主机上去，运行下面命令：

```
ssh-copy-id root@servera

```

注意：运行 Ansible 本身无需 root 权限；然而如果你使用非 root 用户，你*需要*为要执行的任务配置合适的 sudo 权限。

输入 servera 的 root 密码，这条命令会将你的 SSH 密钥安装到远程主机上去。安装好 SSH 密钥后，再通过 SSH 登录远程主机就不再需要输入 root 密码了。

### 安装 Ansible

只需要在示例 1 中生成 SSH 密钥的那台主机上安装 Ansible。若你使用的是 Fedora，输入下面命令：

```
sudo dnf install ansible -y

```

若运行的是 CentOS，你需要为 EPEL 仓库配置额外的包：

```
sudo yum install epel-release -y

```

然后再使用 yum 来安装 Ansible：

```
sudo yum install ansible -y

```

对于基于 Ubuntu 的系统，可以从 PPA 上安装 Ansible：

```
sudo apt-get install software-properties-common -y
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible -y

```

若你使用的是 macOS，那么推荐通过 Python PIP 来安装：

```
sudo pip install ansible

```

对于其他发行版，请参见 [Ansible 安装文档](http://docs.ansible.com/ansible/intro_installation.html) 。

### Ansible Inventory

Ansible 使用一个 INI 风格的文件来追踪要管理的服务器，这种文件被称之为<ruby> 库存清单 <rt>  Inventory </rt></ruby>。默认情况下该文件位于 `/etc/ansible/hosts`。本文中，我使用示例 2 中所示的 Ansible 库存清单来对所需的主机进行操作（为了简洁起见已经进行了裁剪）：

```
[arch]
nextcloud
prometheus
desktop1
desktop2
vm-host15

[fedora]
netflix

[centos]
conan
confluence
7-repo
vm-server1
gitlab

[ubuntu]
trusty-mirror
nwn
kids-tv
media-centre
nas

[satellite]
satellite

[ocp]
lb00
ocp_dns
master01
app01
infra01

```

*示例 2 ： Ansible 主机文件*

每个分组由中括号和组名标识（像这样 `[group1]` )，是应用于一组服务器的任意组名。一台服务器可以存在于多个组中，没有任何问题。在这个案例中，我有根据操作系统进行的分组（`arch`、`ubuntu`、`centos`、`fedora`），也有根据服务器功能进行的分组（`ocp`、`satellite`）。Ansible 主机文件可以处理比这复杂的多的情况。详细内容，请参阅 [库存清单文档](http://docs.ansible.com/ansible/intro_inventory.html)。

### 运行命令

将你的 SSH 密钥拷贝到库存清单中所有服务器上后，你就可以开始使用 Ansible 了。Ansible 的一项基本功能就是运行特定命令。语法为：

```
ansible -a "some command"

```

例如，假设你想升级所有的 CentOS 服务器，可以运行：

```
ansible centos -a 'yum update -y'

```

*注意：不是必须要根据服务器操作系统来进行分组的。我下面会提到，[Ansible Facts](http://docs.ansible.com/ansible/playbooks_variables.html#information-discovered-from-systems-facts) 可以用来收集这一信息；然而，若使用 Facts 的话，则运行特定命令会变得很复杂，因此，如果你在管理异构环境的话，那么为了方便起见，我推荐创建一些根据操作系统来划分的组。*

这会遍历 `centos` 组中的所有服务器并安装所有的更新。一个更加有用的命令应该是 Ansible 的 `ping` 模块了，可以用来验证服务器是否准备好接受命令了：

```
ansible all -m ping

```

这会让 Ansible 尝试通过 SSH 登录库存清单中的所有服务器。在示例 3 中可以看到 `ping` 命令的部分输出结果。

```
nwn | SUCCESS => {
    "changed":false，
    "ping":"pong"
}
media-centre | SUCCESS => {
    "changed":false，
    "ping":"pong"
}
nas | SUCCESS => {
    "changed":false，
    "ping":"pong"
}
kids-tv | SUCCESS => {
    "changed":false，
    "ping":"pong"
}
...

```

*示例 3 ：Ansible ping 命令输出*

运行指定命令的能力有助于完成快速任务（LCTT 译注：应该指的那种一次性任务），但是如果我想在以后也能以同样的方式运行同样的任务那该怎么办呢？Ansible [playbooks](http://docs.ansible.com/ansible/playbooks.html) 就是用来做这个的。

### 复杂任务使用 Ansible playbooks

Ansible <ruby> 剧本 <rt>  playbook </rt> <rt> </rt></ruby> 就是包含 Ansible 指令的 YAML 格式的文件。我这里不打算讲解类似 Roles 和 Templates 这些比较高深的内容。有兴趣的话，请阅读 [Ansible 文档](http://docs.ansible.com/ansible/playbooks_roles.html)。

在前一章节，我推荐你使用 `ssh-copy-id` 命令来传递你的 SSH 密钥；然而，本文关注于如何以一种一致的、可重复性的方式来完成任务。示例 4 演示了一种以冥等的方式，即使 SSH 密钥已经存在于目标主机上也能保证正确性的实现方法。

```
---
- hosts:all
  gather_facts:false
  vars:
    ssh_key:'/root/playbooks/files/laptop_ssh_key'
  tasks:
    - name:copy ssh key
      authorized_key:
        key:"{{ lookup('file'，ssh_key) }}"
        user:root

```

*示例 4：Ansible 剧本 “push ssh keys.yaml”*

`- hosts:` 行标识了这个剧本应该在那个主机组上执行。在这个例子中，它会检查库存清单里的所有主机。

`gather_facts:` 行指明 Ansible 是否去搜索每个主机的详细信息。我稍后会做一次更详细的检查。现在为了节省时间，我们设置 `gather_facts` 为 `false`。

`vars:` 部分，顾名思义，就是用来定义剧本中所用变量的。在示例 4 的这个简短剧本中其实不是必要的，但是按惯例我们还是设置了一个变量。

最后由 `tasks:` 标注的这个部分，是存放主体指令的地方。每个任务都有一个 `-name:`。Ansbile 在运行剧本时会显示这个名字。

`authorized_key:` 是剧本所使用 Ansible 模块的名字。可以通过命令 `ansible-doc -a` 来查询 Ansible 模块的相关信息； 不过通过网络浏览器查看 [文档](http://docs.ansible.com/ansible/modules_by_category.html)  可能更方便一些。[authorized\_key 模块](http://docs.ansible.com/ansible/authorized_key_module.html) 有很多很好的例子可以参考。要运行示例 4 中的剧本，只要运行 `ansible-playbook` 命令就行了：

```
ansible-playbook push_ssh_keys.yaml

```

如果是第一次添加 SSH 密钥，SSH 会提示你输入 root 用户的密码。

现在 SSH 密钥已经传输到服务器中去了，可以来做点有趣的事了。

### 使用 Ansible 收集信息

Ansible 能够收集目标系统的各种信息。如果你的主机数量很多，那它会特别的耗时。按我的经验，每台主机大概要花个 1 到 2 秒钟，甚至更长时间；然而有时收集信息是有好处的。考虑下面这个剧本，它会禁止 root 用户通过密码远程登录系统：

```
---
- hosts:all
  gather_facts:true
  vars:
  tasks:
    - name:Enabling ssh-key only root access
      lineinfile:
        dest:/etc/ssh/sshd_config
        regexp:'^PermitRootLogin'
        line:'PermitRootLogin without-password'
      notify:
        - restart_sshd
        - restart_ssh

  handlers:
    - name:restart_sshd
      service:
        name:sshd
        state:restarted
        enabled:true
      when:ansible_distribution == 'RedHat'
    - name:restart_ssh
      service:
        name:ssh
        state:restarted
        enabled:true
      when:ansible_distribution == 'Debian'

```

*示例 5：锁定 root 的 SSH 访问*

在示例 5 中 `sshd_config` 文件的修改是有[条件](http://docs.ansible.com/ansible/lineinfile_module.html) 的，只有在找到匹配的发行版的情况下才会执行。在这个案例中，基于 Red Hat 的发行版与基于 Debian 的发行版对 SSH 服务的命名是不一样的，这也是使用条件语句的目的所在。虽然也有其他的方法可以达到相同的效果，但这个例子很好演示了 Ansible 信息的作用。若你想查看 Ansible 默认收集的所有信息，可以在本地运行 `setup` 模块：

```
ansible localhost -m setup |less

```

Ansible 收集的所有信息都能用来做判断，就跟示例 4 中 `vars:` 部分所演示的一样。所不同的是，Ansible 信息被看成是**内置** 变量，无需由系统管理员定义。

### 更近一步

现在可以开始探索 Ansible 并创建自己的基本了。Ansible 是一个富有深度、复杂性和灵活性的工具，只靠一篇文章不可能就把它讲透。希望本文能够激发你的兴趣，鼓励你去探索 Ansible 的功能。在下一篇文章中，我会再聊聊 `Copy`、`systemd`、`service`、`apt`、`yum`、`virt`，以及 `user` 模块。我们可以在剧本中组合使用这些模块，还可以创建一个简单的 Git 服务器来存储这些所有剧本。

---

via: <https://opensource.com/article/17/7/automate-sysadmin-ansible>

作者：[Steve Ovens](https://opensource.com/users/stratusss) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


如何在 Arch Linux 中设置日语环境

![](/data/attachment/album/201802/10/223727juvyib53zbvlllo3.jpg)

在本教程中，我们将讨论如何在 Arch Linux 中设置日语环境。在其他类 Unix 操作系统中，设置日文布局并不是什么大不了的事情。你可以从设置中轻松选择日文键盘布局。然而，在 Arch Linux 下有点困难，ArchWiki 中没有合适的文档。如果你正在使用 Arch Linux 和/或其衍生产品如 Antergos、Manajaro Linux，请遵循本指南以在 Arch Linux 及其衍生系统中使用日语。

### 在 Arch Linux 中设置日语环境

首先，为了正确查看日语字符，先安装必要的日语字体：

```
sudo pacman -S adobe-source-han-sans-jp-fonts otf-ipafont
pacaur -S ttf-monapo

```

如果你尚未安装 `pacaur`，请参阅[此链接](https://www.ostechnix.com/install-pacaur-arch-linux/)。

确保你在 `/etc/locale.gen` 中注释掉了（添加 `#` 注释）下面的行。

```
#ja_JP.UTF-8

```

然后，安装 iBus 和 ibus-anthy。对于那些想知道原因的，iBus 是类 Unix 系统的输入法（IM）框架，而 ibus-anthy 是 iBus 的日语输入法。

```
sudo pacman -S ibus ibus-anthy

```

在 `~/.xprofile` 中添加以下几行（如果不存在，创建一个）：

```
# Settings for Japanese input
export GTK_IM_MODULE='ibus'
export QT_IM_MODULE='ibus'
export XMODIFIERS=@im='ibus'

#Toolbar for anthy
ibus-daemon -drx

```

`~/.xprofile` 允许我们在 X 用户会话开始时且在窗口管理器启动之前执行命令。

保存并关闭文件。重启 Arch Linux 系统以使更改生效。

登录到系统后，右键单击任务栏中的 iBus 图标，然后选择 “Preferences”。如果不存在，请从终端运行以下命令来启动 iBus 并打开偏好设置窗口。

```
ibus-setup

```

选择 “Yes” 来启动 iBus。你会看到一个像下面的页面。点击 Ok 关闭它。

![](/data/attachment/album/201802/12/114148o1fciib9ecrh39nr.png)

现在，你将看到 iBus 偏好设置窗口。进入 “Input Method” 选项卡，然后单击 “Add” 按钮。

![](/data/attachment/album/201802/12/114149eh9d18vpw9fcdy2d.png)

在列表中选择 “Japanese”：

![](/data/attachment/album/201802/12/114150lt5k6uh62kyy4vyd.png)

然后，选择 “Anthy” 并点击添加：

![](/data/attachment/album/201802/12/114151wvb5bqwibnssz5bb.png)

就是这样了。你现在将在输入法栏看到 “Japanese - Anthy”：

![](/data/attachment/album/201802/12/114152dzx4eouep04e0ec8.png)

根据你的需求在偏好设置中更改日语输入法的选项（点击 “Japanese-Anthy” -> “Preferences”）。

![](/data/attachment/album/201802/12/114153olzeexw2ul4dgbae.png)

你还可以在键盘绑定中编辑默认的快捷键。完成所有更改后，点击应用并确定。就是这样。从任务栏中的 iBus 图标中选择日语，或者按下 `SUPER + 空格键”（LCTT 译注：SUPER 键通常为`Command`或`Window` 键）来在日语和英语（或者系统中的其他默认语言）之间切换。你可以从 iBus 首选项窗口更改键盘快捷键。

现在你知道如何在 Arch Linux 及其衍生版中使用日语了。如果你发现我们的指南很有用，那么请您在社交、专业网络上分享，并支持我们。

---

via: <https://www.ostechnix.com/setup-japanese-language-environment-arch-linux/>

作者：[SK](https://www.ostechnix.com) 译者：[geekpi](https://github.com/geekpi) 校对：[Locez](https://github.com/locez)

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


使用 TLS 加密保护 VNC 服务器的简单指南

![](/data/attachment/album/201802/10/225325rqxd5dk3334zi2hx.jpg)

在本教程中，我们将学习安装 VNC 服务器并使用 TLS 加密保护 VNC 会话。

此方法已经在 CentOS 6＆7 上测试过了，但是也可以在其它的版本/操作系统上运行（RHEL、Scientific Linux 等）。

**（推荐阅读：[保护 SSH 会话终极指南](http://linuxtechlab.com/ultimate-guide-to-securing-ssh-sessions/)）**

### 安装 VNC 服务器

在机器上安装 VNC 服务器之前，请确保我们有一个可用的 GUI（图形用户界面）。如果机器上还没有安装 GUI，我们可以通过执行以下命令来安装：

```
yum groupinstall "GNOME Desktop"

```

现在我们将 tigervnc 作为我们的 VNC 服务器，运行下面的命令运行：

```
# yum install tigervnc-server

```

安装完成后，我们将创建一个新的用户访问服务器：

```
# useradd vncuser

```

并使用以下命令为其分配访问 VNC 的密码：

```
# vncpasswd vncuser

```

我们在 CentOS 6&7 上配置会有一点改变，我们首先看 CentOS 6 的配置。

#### CentOS 6

现在我们需要编辑 VNC 配置文件：

```
# vim /etc/sysconfig/vncservers

```

并添加下面这几行：

```
[ …]
VNCSERVERS= "1:vncuser"
VNCSERVERARGS[1]= "-geometry 1024×768″

```

保存文件并退出。接下来重启 vnc 服务使改动生效：

```
# service vncserver restart

```

并在启动时启用它：

```
# chkconfig vncserver on

```

#### CentOS 7

在 CentOS 7 上，`/etc/sysconfig/vncservers` 已经改为 `/lib/systemd/system/vncserver@.service`。我们将使用这个配置文件作为参考，所以创建一个文件的副本，

```
# cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service

```

接下来，我们将编辑文件以包含我们创建的用户：

```
# vim /etc/systemd/system/vncserver@:1.service

```

编辑下面 2 行中的用户：

```
ExecStart=/sbin/runuser -l vncuser -c "/usr/bin/vncserver %i"
PIDFile=/home/vncuser/.vnc/%H%i.pid

```

保存文件并退出。接下来重启服务并在启动时启用它：

```
# systemctl restart vncserver@:1.service
# systemctl enable vncserver@:1.service

```

现在我们已经设置好了 VNC 服务器，并且可以使用 VNC 服务器的 IP 地址从客户机连接到它。但是，在此之前，我们将使用 TLS 加密保护我们的连接。

### 保护 VNC 会话

要保护 VNC 会话，我们将首先配置加密方法。我们将使用 TLS 加密，但也可以使用 SSL 加密。执行以下命令在 VNC 服务器上使用 TLS 加密：

```
# vncserver -SecurityTypes=VeNCrypt,TLSVnc

```

你将被要求输入密码来访问 VNC（如果使用其他用户，而不是上述用户）。

![secure vnc server](/data/attachment/album/201802/10/225350ru74izoba4xb3fru.png)

现在，我们可以使用客户机上的 VNC 浏览器访问服务器，使用以下命令以安全连接启动 vnc 浏览器：

```
# vncviewer -SecurityTypes=VeNCrypt,TLSVnc 192.168.1.45:1

```

这里，192.168.1.45 是 VNC 服务器的 IP 地址。

![secure vnc server](/data/attachment/album/201802/10/225355u07ozq7lehqaolj6.png)

输入密码，我们可以远程访问服务器，并且也是 TLS 加密的。

这篇教程就完了，欢迎随时使用下面的评论栏提交你的建议或疑问。

---

via: <http://linuxtechlab.com/secure-vnc-server-tls-encryption/>

作者：[Shusain](http://linuxtechlab.com/author/shsuain/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


TensorFlow 的简单例子

Summary: 在本文中，我们将看一些 TensorFlow 的例子，并从中感受到在定义张量和使用张量做数学计算方面有多么容易，我还会举些别的机器学习相关的例子。

![](/data/attachment/album/201802/11/231211xv52948zv3sf242f.png)

在本文中，我们将看一些 TensorFlow 的例子，并从中感受到在定义<ruby> 张量 <rt>  tensor </rt></ruby>和使用张量做数学计算方面有多么容易，我还会举些别的机器学习相关的例子。

### TensorFlow 是什么?

TensorFlow 是 Google 为了解决复杂的数学计算耗时过久的问题而开发的一个库。

事实上，TensorFlow 能干许多事。比如：

* 求解复杂数学表达式
* 机器学习技术。你往其中输入一组数据样本用以训练，接着给出另一组数据样本基于训练的数据而预测结果。这就是人工智能了！
* 支持 GPU 。你可以使用 GPU（图像处理单元）替代 CPU 以更快的运算。TensorFlow 有两个版本： CPU 版本和 GPU 版本。

开始写例子前，需要了解一些基本知识。

### 什么是张量？

<ruby> 张量 <rt>  tensor </rt></ruby>是 TensorFlow 使用的主要的数据块，它类似于变量，TensorFlow 使用它来处理数据。张量拥有维度和类型的属性。

维度指张量的行和列数，读到后面你就知道了，我们可以定义一维张量、二维张量和三维张量。

类型指张量元素的数据类型。

### 定义一维张量

可以这样来定义一个张量：创建一个 NumPy 数组（LCTT 译注：NumPy 系统是 Python 的一种开源数字扩展，包含一个强大的 N 维数组对象 Array，用来存储和处理大型矩阵 ）或者一个 [Python 列表](https://likegeeks.com/python-list-functions/) ，然后使用 `tf_convert_to_tensor` 函数将其转化成张量。

可以像下面这样，使用 NumPy 创建一个数组：

```
import numpy as np arr = np.array([1, 5.5, 3, 15, 20])
arr = np.array([1, 5.5, 3, 15, 20])

```

运行结果显示了这个数组的维度和形状。

```
import numpy as np
arr = np.array([1, 5.5, 3, 15, 20])
print(arr)
print(arr.ndim)
print(arr.shape)
print(arr.dtype)

```

它和 Python 列表很像，但是在这里，元素之间没有逗号。

现在使用 `tf_convert_to_tensor` 函数把这个数组转化为张量。

```
import numpy as np
import tensorflow as tf
arr = np.array([1, 5.5, 3, 15, 20])
tensor = tf.convert_to_tensor(arr,tf.float64)
print(tensor)

```

这次的运行结果显示了张量具体的含义，但是不会展示出张量元素。

要想看到张量元素，需要像下面这样，运行一个会话：

```
import numpy as np
import tensorflow as tf
arr = np.array([1, 5.5, 3, 15, 20])
tensor = tf.convert_to_tensor(arr,tf.float64)
sess = tf.Session()
print(sess.run(tensor))
print(sess.run(tensor[1]))

```

### 定义二维张量

定义二维张量，其方法和定义一维张量是一样的，但要这样来定义数组：

```
arr = np.array([(1, 5.5, 3, 15, 20),(10, 20, 30, 40, 50), (60, 70, 80, 90, 100)])

```

接着转化为张量：

```
import numpy as np
import tensorflow as tf
arr = np.array([(1, 5.5, 3, 15, 20),(10, 20, 30, 40, 50), (60, 70, 80, 90, 100)])
tensor = tf.convert_to_tensor(arr)
sess = tf.Session()
print(sess.run(tensor))

```

现在你应该知道怎么定义张量了，那么，怎么在张量之间跑数学运算呢？

### 在张量上进行数学运算

假设我们有以下两个数组：

```
arr1 = np.array([(1,2,3),(4,5,6)])
arr2 = np.array([(7,8,9),(10,11,12)])

```

利用 TenserFlow ，你能做许多数学运算。现在我们需要对这两个数组求和。

使用加法函数来求和：

```
import numpy as np
import tensorflow as tf
arr1 = np.array([(1,2,3),(4,5,6)])
arr2 = np.array([(7,8,9),(10,11,12)])
arr3 = tf.add(arr1,arr2)
sess = tf.Session()
tensor = sess.run(arr3)
print(tensor)

```

也可以把数组相乘：

```
import numpy as np
import tensorflow as tf
arr1 = np.array([(1,2,3),(4,5,6)])
arr2 = np.array([(7,8,9),(10,11,12)])
arr3 = tf.multiply(arr1,arr2)
sess = tf.Session()
tensor = sess.run(arr3)
print(tensor)

```

现在你知道了吧。

三维张量
----

我们已经知道了怎么使用一维张量和二维张量，现在，来看一下三维张量吧，不过这次我们不用数字了，而是用一张 RGB 图片。在这张图片上，每一块像素都由 x、y、z 组合表示。

这些组合形成了图片的宽度、高度以及颜色深度。

首先使用 matplotlib 库导入一张图片。如果你的系统中没有 matplotlib ，可以 [使用 pip](https://likegeeks.com/import-create-install-reload-alias-python-modules/#Install-Python-Modules-Using-pip)来安装它。

将图片放在 Python 文件的同一目录下，接着使用 matplotlib 导入图片：

```
import matplotlib.image as img
myfile = "likegeeks.png"
myimage = img.imread(myfile)
print(myimage.ndim)
print(myimage.shape)

```

从运行结果中，你应该能看到，这张三维图片的宽为 150 、高为 150 、颜色深度为 3 。

你还可以查看这张图片：

```
import matplotlib.image as img
import matplotlib.pyplot as plot
myfile = "likegeeks.png"
myimage = img.imread(myfile)
plot.imshow(myimage)
plot.show()

```

真酷！

那怎么使用 TensorFlow 处理图片呢？超级容易。

### 使用 TensorFlow 生成或裁剪图片

首先，向一个占位符赋值：

```
myimage = tf.placeholder("int32",[None,None,3])

```

使用裁剪操作来裁剪图像：

```
cropped = tf.slice(myimage,[10,0,0],[16,-1,-1])

```

最后，运行这个会话：

```
result = sess.run(cropped, feed\_dict={slice: myimage})

```

然后，你就能看到使用 matplotlib 处理过的图像了。

这是整段代码：

```
import tensorflow as tf
import matplotlib.image as img
import matplotlib.pyplot as plot
myfile = "likegeeks.png"
myimage = img.imread(myfile)
slice = tf.placeholder("int32",[None,None,3])
cropped = tf.slice(myimage,[10,0,0],[16,-1,-1])
sess = tf.Session()
result = sess.run(cropped, feed_dict={slice: myimage})
plot.imshow(result)
plot.show()

```

是不是很神奇？

### 使用 TensorFlow 改变图像

在本例中，我们会使用 TensorFlow 做一下简单的转换。

首先，指定待处理的图像，并初始化 TensorFlow 变量值：

```
myfile = "likegeeks.png"
myimage = img.imread(myfile)
image = tf.Variable(myimage,name='image')
vars = tf.global_variables_initializer()

```

然后调用 transpose 函数转换，这个函数用来翻转输入网格的 0 轴和 1 轴。

```
sess = tf.Session()
flipped = tf.transpose(image, perm=[1,0,2])
sess.run(vars)
result=sess.run(flipped)

```

接着你就能看到使用 matplotlib 处理过的图像了。

```
import tensorflow as tf
import matplotlib.image as img
import matplotlib.pyplot as plot
myfile = "likegeeks.png"
myimage = img.imread(myfile)
image = tf.Variable(myimage,name='image')
vars = tf.global_variables_initializer()
sess = tf.Session()
flipped = tf.transpose(image, perm=[1,0,2])
sess.run(vars)
result=sess.run(flipped)
plot.imshow(result)
plot.show()

```

以上例子都向你表明了使用 TensorFlow 有多么容易。

---

via: <https://www.codementor.io/likegeeks/define-and-use-tensors-using-simple-tensorflow-examples-ggdgwoy4u>

作者：[LikeGeeks](https://www.codementor.io/likegeeks) 译者：[ghsgz](https://github.com/ghsgz) 校对：[wxy](https://github.com/wxy)

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


通过案例学习 xfs 文件系统相关命令

![Learn xfs commands with examples](/data/attachment/album/201802/11/232306zk2462tz72sgl77l.png)

在我们另一篇文章中，我带您领略了一下[什么是 xfs，xfs 的相关特性等内容](https://kerneltalks.com/disk-management/xfs-filesystem-in-linux/)。本文我们来看一些常用的 xfs 管理命令。我们将会通过几个例子来讲解如何创建 xfs 文件系统，如何对 xfs 文件系统进行扩容，如何检测并修复 xfs 文件系统。

### 创建 XFS 文件系统

`mkfs.xfs` 命令用来创建 xfs 文件系统。无需任何特别的参数，其输出如下：

```
root@kerneltalks # mkfs.xfs /dev/xvdf
meta-data=/dev/xvdf              isize=512    agcount=4, agsize=1310720 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=5242880, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

```

>
> 注意：一旦 XFS 文件系统创建完毕就不能在缩容而只能进行扩容了。
>
>
>

### 调整 XFS 文件系统容量

你只能对 XFS 进行扩容而不能缩容。我们使用 `xfs_growfs` 来进行扩容。你需要使用 `-D` 参数指定挂载点的新容量。`-D` 接受一个数字的参数，指定文件系统块的数量。若你没有提供 `-D` 参数，则 `xfs_growfs` 会将文件系统扩到最大。

```
root@kerneltalks # xfs_growfs /dev/xvdf -D 256
meta-data=/dev/xvdf              isize=512    agcount=4, agsize=720896 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=2883584, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data size 256 too small, old size is 2883584

```

观察上面的输出中的最后一行。由于我分配的容量要小于现在的容量。它告诉你不能缩减 XFS 文件系统。你只能对它进行扩展。

```
root@kerneltalks #  xfs_growfs /dev/xvdf -D 2883840
meta-data=/dev/xvdf              isize=512    agcount=4, agsize=720896 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=2883584, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2883584 to 2883840

```

现在我多分配了 1GB 的空间，而且也成功地扩增了容量。

**1GB 块的计算方式：**

当前文件系统 bsize 为 4096，意思是块的大小为 4MB。我们需要 1GB，也就是 256 个块。因此在当前块数，2883584 上加上 256 得到 2883840。因此我为 `-D` 传递参数 2883840。

### 修复 XFS 文件系统

可以使用 `xfs_repair` 命令进行文件系统一致性检查和修复。使用 `-n` 参数则并不对文件系统做出什么实质性的修改。它只会搜索并报告要做哪些修改。若不带 `-n` 参数，则会修改文件系统以保证文件系统的纯净。

请注意，在检查之前，你需要先卸载 XFS 文件系统。否则会报错。

```
root@kerneltalks # xfs_repair -n /dev/xvdf
xfs_repair: /dev/xvdf contains a mounted filesystem
xfs_repair: /dev/xvdf contains a mounted and writable filesystem

fatal error -- couldn't initialize XFS library

```

卸载后运行检查命令。

```
root@kerneltalks # xfs_repair -n /dev/xvdf
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
        - scan filesystem freespace and inode maps...
        - found root inode chunk
Phase 3 - for each AG...
        - scan (but don't clear) agi unlinked lists...
        - process known inodes and perform inode discovery...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - agno = 4
        - process newly discovered inodes...
Phase 4 - check for duplicate blocks...
        - setting up duplicate extent list...
        - check for inodes claiming duplicate blocks...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - agno = 4
No modify flag set, skipping phase 5
Phase 6 - check inode connectivity...
        - traversing filesystem ...
        - traversal finished ...
        - moving disconnected inodes to lost+found ...
Phase 7 - verify link counts...
No modify flag set, skipping filesystem flush and exiting.

```

你可以看到，命令在每个阶段都显示出了为了文件系统变得健康可能做出的修改。若你希望命令在扫描时实际应用这些修改，则不带任何参数运行命令即可。

```
root @ kerneltalks # xfs_repair /dev/xvdf

Phase 1 - find and verify superblock . . .
Phase 2 - using internal log
        - zero log . . .
        - scan filesystem freespace and inode maps . . .
        - found root inode chunk
Phase 3 - for each AG . . .
        - scan and clear agi unlinked lists . . .
        - process known inodes and perform inode discovery . . .
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - agno = 4
        - process newly discovered inodes . . .
Phase 4 - check for duplicate blocks . . .
        - setting up duplicate extent list . . .
        - check for inodes claiming duplicate blocks . . .
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - agno = 4
Phase 5 - rebuild AG headers and trees . . .
        - reset superblock . . .
Phase 6 - check inode connectivity . . .
        - resetting contents of realtime bitmap and summary inodes
        - traversing filesystem . . .
        - traversal finished . . .
        - moving disconnected inodes to lost + found . . .
Phase 7 - verify and correct link counts . . .
done

```

你会发现 `xfs_repair` 命令对文件系统做出了修改让其变得健康。

### 查看 XFS 版本以及它的详细信息

查看 xfs 文件系统版本很简单。使用 `-V` 参数运行 `xfs_info` 再加上挂载点就行了。

```
root@kerneltalks # xfs_info -V /shrikant
xfs_info version 4.5.0

```

若要查看 XFS 文件系统的详细信息，比如想计算扩容 XFS 文件系统时要新增多少个块，需要了解块大小，块的个数等信息，则不带任何选项运行 `xfs_info` 加上挂载点。

```
root@kerneltalks # xfs_info /shrikant
meta-data=/dev/xvdf              isize=512    agcount=5, agsize=720896 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=2883840, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

```

则会显示 XFS 文件系统的所有详细信息，就跟创建 XFS 文件系统时显示的信息一样。

此外还有一些 XFS 文件系统管理命令可以修改并管理 XFS 的元数据。我们将在另一篇文章中来讲解。

---

via: <https://kerneltalks.com/commands/xfs-file-system-commands-with-examples/>

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

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


如何更改 Linux 控制台上的字体

![](/data/attachment/album/201802/12/001611jt67znuetzupntja.jpg)

我尝试尽可能的保持心灵祥和，然而总有一些事情让我意难平，比如控制台字体太小了。记住我的话，朋友，有一天你的眼睛会退化，无法再看清你编码时用的那些细小字体，到那时你就后悔莫及了。

幸好，Linux 死忠们，你可以更改控制台的字体。按照 Linux 一贯的尿性，不断变化的 Linux 环境使得这个问题变得不太简单明了，而 Linux 上也没有字体管理这么个东西，这使得我们很容易就被搞晕了。本文，我将会向你展示，我找到的更改字体的最简方法。

### Linux 控制台是个什么鬼？

首先让我们来澄清一下我们说的到底是个什么东西。当我提到 Linux 控制台，我指的是 TTY1-6，即你从图形环境用 `Ctrl-Alt-F1` 到 `F6` 切换到的虚拟终端。按下 `Ctrl+Alt+F7` 会切回图形环境。(不过这些热键已经不再通用，你的 Linux 发行版可能有不同的键映射。你的 TTY 的数量也可能不同，你图形环境会话也可能不在 `F7`。比如，Fedora 的默认图形会话是 `F2`，它只有一个额外的终端在 `F1`。) 我觉得能同时拥有 X 会话和终端会话实在是太酷了。

Linux 控制台是内核的一部分，而且并不运行在 X 会话中。它和你在没有图形环境的<ruby> 无头 <rt>  headless </rt></ruby>服务器中用的控制台是一样的。我称呼在图形会话中的 X 终端为终端，而将控制台和 X 终端统称为终端模拟器。

但这还没完。Linux 终端从早期的 ANSI 时代开始已经经历了长久的发展，多亏了 Linux framebuffer，它现在支持 Unicode 并且对图形也有了有限的一些支持。而且出现了很多在控制台下运行的[多媒体应用](/article-9320-1.html)，这些我们在以后的文章中会提到。

### 控制台截屏

获取控制台截屏的最简单方法是让控制台跑在虚拟机内部。然后你可以在宿主系统上使用中意的截屏软件来抓取。不过借助 [fbcat](http://jwilk.net/software/fbcat) 和 [fbgrab](https://github.com/jwilk/fbcat/blob/master/fbgrab) 你也可以直接在控制台上截屏。`fbcat` 会创建一个可移植的像素映射格式（PPM）的图像； 这是一个高度可移植的未压缩图像格式，可以在所有的操作系统上读取，当然你也可以把它转换成任何喜欢的其他格式。`fbgrab` 则是 `fbcat` 的一个封装脚本，用来生成一个 PNG 文件。很多人写过多个版本的 `fbgrab`。每个版本的选项都有限而且只能创建截取全屏。

`fbcat` 的执行需要 root 权限，而且它的输出需要重定向到文件中。你无需指定文件扩展名，只需要输入文件名就行了：

```
$ sudo fbcat > Pictures/myfile

```

在 GIMP 中裁剪后，就得到了图 1。

![](/data/attachment/album/201802/15/102834n6ppkp6rtt740dt7.png)

*图 1 ： 裁剪后查看*

如果能在左边空白处有一点填充就好了，如果有读者知道如何实现请在留言框中告诉我。

`fbgrab` 还有一些选项，你可以通过 `man fbgrab` 来查看，这些选项包括对另一个控制台进行截屏，以及延时截屏等。在下面的例子中可以看到，`fbgrab` 截屏跟 `fbcat` 截屏类似，只是你无需明确进行输出重定性了：

```
$ sudo fbgrab Pictures/myOtherfile

```

### 查找字体

就我所知，除了查看字体存储目录 `/usr/share/consolefonts/`（Debian 等），`/lib/kbd/consolefonts/` （Fedora），`/usr/share/kbd/consolefonts` （openSUSE）外没有其他方法可以列出已安装的字体了。

### 更改字体

可读字体不是什么新概念。我们应该尊重以前的经验！可读性是很重要的。可配置性也很重要，然而现如今却不怎么看重了。

在 Debian/Ubuntu 等系统上，可以运行 `sudo dpkg-reconfigure console-setup` 来设置控制台字体，然后在控制台运行 `setupcon` 命令来让变更生效。`setupcon` 属于 `console-setup` 软件包中的一部分。若你的 Linux 发行版中不包含该工具，可以在 [openSUSE](https://software.opensuse.org/package/console-setup) 中下载到它。

你也可以直接编辑 `/etc/default/console-setup` 文件。下面这个例子中设置字体为 32 点大小的 Terminus Bold 字体，这是我的最爱，并且严格限制控制台宽度为 80 列。

```
ACTIVE_CONSOLES="/dev/tty[1-6]"
CHARMAP="UTF-8"
CODESET="guess"
FONTFACE="TerminusBold"
FONTSIZE="16x32"
SCREEN_WIDTH="80"

```

这里的 `FONTFACE` 和 `FONTSIZE` 的值来自于字体的文件名 `TerminusBold32x16.psf.gz`。是的，你需要反转 `FONTSIZE` 中值的顺序。计算机就是这么搞笑。然后再运行 `setupcon` 来让新配置生效。可以使用 `showconsolefont` 来查看当前所用字体的所有字符集。要查看完整的选项说明请参考 `man console-setup`。

### Systemd

Systemd 与 `console-setup` 不太一样，除了字体之外，你无需安装任何东西。你只需要编辑 `/etc/vconsole.conf` 然后重启就行了。我在 Fedora 和 openSUSE 系统中安装了一些额外的大字号的 Terminus 字体包，因为默认安装的字体最大只有 16 点而我想要的是 32 点。然后将 `/etc/vconsole.conf` 的内容修改为：

```
KEYMAP="us"
FONT="ter-v32b"

```

下周我们还将学习一些更加酷的控制台小技巧，以及一些在控制台上运行的[多媒体应用](/article-9320-1.html)。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/1/how-change-your-linux-console-fonts>

作者：[Carla Schroder](https://www.linux.com/users/cschroder) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


使用 iftop 命令监控网络带宽

Summary: iftop 是网络监控工具，它提供实时带宽监控。 iftop 测量进出各个套接字连接的总数据量，即它捕获通过网络适配器收到或发出的数据包，然后将这些数据相加以得到使用的带宽。

![](/data/attachment/album/201802/12/164336kzmi1m13swrwqdss.jpg)

系统管理员需要监控 IT 基础设施来确保一切正常运行。我们需要监控硬件，也就是内存、硬盘和 CPU 等的性能，我们也必须监控我们的网络。我们需要确保我们的网络不被过度使用，否则我们的程序，网站可能无法正常工作。在本教程中，我们将学习使用 `iftop`。

（**推荐阅读**：[**使用 Nagios** 进行资源监控](http://linuxtechlab.com/installing-configuring-nagios-server/)、[**用于检查系统信息的工具**](http://linuxtechlab.com/commands-system-hardware-info/) 、[**要监控的重要日志**](http://linuxtechlab.com/important-logs-monitor-identify-issues/) ）

`iftop` 是网络监控工具，它提供实时带宽监控。 `iftop` 测量进出各个套接字连接的总数据量，即它捕获通过网络适配器收到或发出的数据包，然后将这些数据相加以得到使用的带宽。

### 在 Debian/Ubuntu 上安装

iftop 存在于 Debian/Ubuntu 的默认仓库中，可以使用下面的命令安装：

```
$ sudo apt-get install iftop

```

### 使用 yum 在 RHEL/Centos 上安装

要在 CentOS 或 RHEL 上安装 iftop，我们需要启用 EPEL 仓库。要启用仓库，请在终端上运行以下命令：

**RHEL/CentOS 7：**

```
$ rpm -Uvh https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-10.noarch.rpm

```

**RHEL/CentOS 6（64 位）：**

```
$ rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

```

**RHEL/CentOS 6 （32 位）：**

```
$ rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

```

EPEL 仓库安装完成后，我们可以用下面的命令安装 `iftop`：

```
$ yum install iftop

```

这将在你的系统上安装 `iftop`。我们现在将用它来监控我们的网络。

### 使用 iftop

可以打开终端窗口，并输入下面的命令使用 `iftop`：

```
$ iftop

```

![network monitoring](/data/attachment/album/201802/12/164344svqhfq5ljszplcqd.jpg)

现在你将看到计算机上发生的网络活动。你也可以使用：

```
$ iftop -n

```

这将在屏幕上显示网络信息，但使用 `-n`，则不会显示与 IP 地址相关的名称，只会显示 IP 地址。这个选项能节省一些将 IP 地址解析为名称的带宽。

我们也可以看到 `iftop` 可以使用的所有命令。运行 `iftop` 后，按下键盘上的 `h` 查看 `iftop` 可以使用的所有命令。

![network monitoring](/data/attachment/album/201802/12/164345bgclbuenzk6nlgbt.jpg)

要监控特定的网络接口，我们可以在 `iftop` 后加上接口名：

```
$ iftop -I enp0s3

```

如上所述，你可以使用帮助来查看 `iftop` 可以使用的更多选项。但是这些提到的例子只是可能只是监控网络。

---

via: <http://linuxtechlab.com/monitoring-network-bandwidth-iftop-command/>

作者：[SHUSAIN](http://linuxtechlab.com/author/shsuain/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


开源软件二十年 —— 过去，现在，未来

Summary: 谨以此文纪念 “开源软件” 这个名词的二十周年纪念日，开源软件是怎么占有软件的主导地位的？以后会如何发展？

>
> 谨以此文纪念 “<ruby> 开源软件 <rt>  open source software </rt></ruby>” 这个名词的二十周年纪念日，开源软件是怎么占有软件的主导地位的？以后会如何发展？
>
>
>

![Open source software: 20 years and counting](/data/attachment/album/201802/12/171853octilrlvccr6tbff.png "Open source software: 20 years and counting")

二十年以前，在 1998 年 2 月，“<ruby> 开源 <rt>  open source </rt></ruby>” 这个词汇第一次出现在“软件”这一名词之前。不久之后，<ruby> 开源的定义 <rt>  Open Source Definition </rt></ruby>（OSD） 这一文档被创建，并成为了撒播 <ruby> 开放源代码促进会 <rt>  Open Source Initiative </rt></ruby>（OSI）的种子。正如 OSD 的作者 [Bruce Perens 所说](https://perens.com/2017/09/26/on-usage-of-the-phrase-open-source/)：

>
> “开源”是这场宣传自由软件的既有概念到商业软件，并将许可证化为一系列规则的运动的正式名称。
>
>
>

二十年后，我们能看到这一运动是非常成功的，甚至超出了当时参与这一活动的任何人的想象。 如今，开源软件无处不在。它是互联网和网络的基础。它为我们所有使用的电脑和移动设备，以及它们所连接的网络提供动力。没有它，云计算和新兴的物联网将不可能发展，甚至不可能出现。它使新的业务方式可以被测试和验证，还可以让像谷歌和 Facebook 这样的大公司在已有的基础之上继续攀登。

如任何人类的造物一样，它也有黑暗的一面。它也让反乌托邦的监视和必然导致的专制控制的出现成为了可能。它为犯罪分子提供了欺骗受害者的新的途径，还让匿名且大规模的欺凌得以存在。它让有破环性的狂热分子可以暗中组织而不会感到有何不便。这些都是开源的能力之下的黑暗投影。所有的人类工具都是如此，既可以养育人类，亦可以有害于人类。我们需要帮助下一代，让他们能争取无可取代的创新。就如 [费曼所说](https://www.brainpickings.org/2013/07/19/richard-feynman-science-morality-poem/)：

>
> 每个人都掌握着一把开启天堂之门的钥匙，但这把钥匙亦能打开地狱之门。
>
>
>

开源运动已经渐渐成熟。我们讨论和理解它的方式也渐渐的成熟。如果说第一个十年是拥护与非议对立的十年，那么第二个十年就是接纳和适应并存的十年。

1. 在第一个十年里面，关键问题就是商业模型 —— “我怎样才能自由的贡献代码，且从中受益？” —— 之后，还有更多的人提出了有关管理的难题—— “我怎么才能参与进来，且不受控制 ?”
2. 第一个十年的开源项目主要是替代现有的产品；而在第二个十年中，它们更多地是作为更大的解决方案的组成部分。
3. 第一个十年的项目往往由非正式的个人组织进行；而在第二个十年中，它们经常由创建于各个项目上的机构经营。
4. 第一个十年的开源开发者经常是投入于单一的项目，并经常在业余时间工作。 在第二个十年里，他们越来越多地受雇从事于一个专门的技术 —— 他们成了专业人员。
5. 尽管开源一直被认为是提升软件自由度的一种方式，但在第一个十年中，这个运动与那些更喜欢使用“<ruby> 自由软件 <rt>  free software </rt></ruby>”的人产生了冲突。在第二个十年里，随着开源运动的加速发展，这个冲突基本上被忽略了。

第三个十年会带来什么？

1. *更复杂的商业模式* —— 主要的商业模式涉及到将很多开源组件整合而产生的复杂性的解决方案，特别是部署和扩展方面。 开源治理的需求将反映这一点。
2. *开源拼图* —— 开源项目将主要是一系列组件，彼此衔接构成组件堆栈。由此产生的解决方案将是开源组件的拼图。
3. *项目族* —— 越来越多的项目将由诸如 Linux Foundation 和 OpenStack 等联盟/行业协会以及 Apache 和 Software Freedom Conservancy 等机构主办。
4. *专业通才* —— 开源开发人员将越来越多地被雇来将诸多技术集成到复杂的解决方案里，这将有助于一系列的项目的开发。
5. *软件自由度降低* —— 随着新问题的出现，软件自由（将四项自由应用于用户和开发人员之间的灵活性）将越来越多地应用于识别解决方案是否适用于协作社区和独立部署人员。

2018 年，我将在全球各地的主题演讲中阐述这些内容。欢迎观看 [OSI 20 周年纪念全球巡演](https://opensource.org/node/905)！

*本文最初发表于 [Meshed Insights Ltd.](https://meshedinsights.com/2017/12/21/20-years-and-counting/) ， 已获转载授权，本文，以及我在 OSI 的工作，由 [Patreon patrons](https://patreon.com/webmink) 支持*

### 关于作者

Simon Phipps - 计算机工业和开源软件专家 Simon Phipps 创办了[公共软件公司](https://publicsoftware.eu/)，这是一个欧洲开源项目的托管公司，以志愿者身份成为 OSI 的总裁，还是 The Document Foundation 的一名总监。 他的作品是由 [Patreon patrons](https://patreon.com/webmink) 赞助 —— 如果你想看更多的话，来做赞助人吧！ 在超过 30 年的职业生涯中，他一直在参与世界领先的战略层面的开发 ... [关于 Simon Phipps](https://opensource.com/users/simonphipps)

---

via: <https://opensource.com/article/18/2/open-source-20-years-and-counting>

作者：[Simon Phipps](https://opensource.com/users/simonphipps) 译者：[name1e5s](https://github.com/name1e5s) 校对：[wxy](https://github.com/wxy)

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


Manjaro Gaming：当 Manjaro 的才华遇上 Linux 游戏

唉！现在玩游戏都是在手机上了！

[![见见 Manjaro Gaming, 一个专门为游戏者设计的 Linux 发行版，带有 Manjaro 的所有才能。](/data/attachment/album/201802/12/173728u5gp47pg25e9gp51.jpg)](https://itsfoss.com/wp-content/uploads/2016/06/Manjaro-Gaming.jpg)

[在 Linux 上玩转游戏](/article-7316-1.html)? 没错，这是非常可行的，我们正致力于为游戏人群打造一个新的 Linux 发行版。

Manjaro Gaming 是一个专门为游戏人群设计的，带有 Manjaro 所有才能的发行版。之前用过 Manjaro Linux 的人一定知道为什么这对于游戏人群来说是一个如此好的一个消息。

[Manjaro](https://manjaro.github.io/) 是一个 Linux 发行版，它基于最流行的 Linux 发行版之一 —— [Arch Linux](https://www.archlinux.org/)。 Arch Linux 因它的前沿性所带来的轻量、强大、高度定制和最新的体验而闻名于世。尽管这些都非常赞，但是也正是因为 Arch Linux 提倡这种 DIY （do it yourself）方式，导致一个主要的缺点，那就是用户想用好它，需要处理一定的技术问题。

Manjaro 把这些要求全都剥离开去，让 Arch 对新手更亲切，同时也为老手提供了 Arch 所有的高端与强大功能。总之，Manjaro 是一个用户友好型的 Linux 发行版，工作起来行云流水。

Manjaro 会成为一个强大并且极度适用于游戏的原因：

* Manjaro 自动检测计算的硬件（例如，显卡）
* 自动安装必要的驱动和软件（例如，显示驱动）
* 预安装播放媒体文件的编码器
* 专用的软件库提供完整测试过的稳定软件包。

Manjaro Gaming 打包了 Manjaro 的所有强大特性以及各种小工具和软件包，以使得在 Linux 上做游戏即顺畅又享受。

![Manjaro Gaming 内部](/data/attachment/album/201802/12/173729zt6gqwyyfzt6yapp.png)

### 优化

Manjaro Gaming 做了一些优化：

* Manjaro Gaming 使用高度定制化的 XFCE 桌面环境，拥有一个黑暗风格主题。
* 禁用睡眠模式，防止用手柄上玩游戏或者观看一个长过场动画时计算机自动休眠。

### 软件

维持 Manjaro 工作起来行云流水的传统，Manjaro Gaming 打包了各种开源软件包，提供游戏人群经常需要用到的功能。其中一部分软件有：

* [KdenLIVE](https://kdenlive.org/)：用于编辑游戏视频的视频编辑软件
* [Mumble](https://www.mumble.info)：给游戏人群使用的视频聊天软件
* [OBS Studio](https://obsproject.com/)：用于录制视频或在 [Twitch](https://www.twitch.tv/) 上直播游戏用的软件
* [OpenShot](http://www.openshot.org/)：Linux 上强大的视频编辑器
* [PlayOnLinux](https://www.playonlinux.com)：使用 [Wine](https://www.winehq.org/) 作为后端，在 Linux 上运行 Windows 游戏的软件
* [Shutter](http://shutter-project.org/)：多种功能的截图工具

### 模拟器

Manjaro Gaming 自带很多的游戏模拟器：

* [DeSmuME](http://desmume.org/)：Nintendo DS 任天堂 DS 模拟器
* [Dolphin Emulator](https://dolphin-emu.org)：GameCube 和 Wii 模拟器
* [DOSBox](https://www.dosbox.com/)：DOS 游戏模拟器
* [FCEUX](http://www.fceux.com/)：任天堂娱乐系统（NES）、 红白机（FC）和 FC 磁盘系统（FDS）模拟器
* Gens/GS：世嘉模拟器
* [PCSXR](https://pcsxr.codeplex.com)：PlayStation 模拟器
* [PCSX2](http://pcsx2.net/)：Playstation 2 模拟器
* [PPSSPP](http://www.ppsspp.org/)：PSP 模拟器
* [Stella](http://stella.sourceforge.net/)：Atari 2600 VCS （雅达利）模拟器
* [VBA-M](http://vba-m.com/)：Gameboy 和 GameboyAdvance 模拟器
* [Yabause](https://yabause.org/)：世嘉土星模拟器
* [ZSNES](http://www.zsnes.com/)：超级任天堂模拟器

### 其它

还有一些终端插件 —— Color、ILoveCandy 和 Screenfetch。也包括带有 Retro Conky（LCTT 译注：复古 Conky）风格的 [Conky 管理器](https://itsfoss.com/conky-gui-ubuntu-1304/)。

注意：上面提到的所有功能并没有全部包含在 Manjaro Gaming 的现行发行版中（版本 16.03）。部分功能计划将在下一版本中纳入 —— Manjaro Gaming 16.06（LCTT 译注：本文发表于 2016 年 5 月）。

### 下载

Manjaro Gaming 16.06 将会是 Manjaro Gaming 的第一个正式版本。如果你现在就有兴趣尝试，你可以在 Sourceforge 的[项目页面](https://sourceforge.net/projects/mgame/)中下载。去那里然后下载它的 ISO 文件吧。

你觉得 Gaming Linux 发行版怎么样？想尝试吗？告诉我们！

---

via: <https://itsfoss.com/manjaro-gaming-linux/>

作者：[Munif Tanjim](https://itsfoss.com/author/munif/) 译者：[XLCYun](https://github.com/XLCYun) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux/Unix 的 Bash 中打开或关闭 ls 命令颜色显示

Summary: 大多数现代 Linux 发行版和 Unix 系统都有一个定义了文件名称颜色的别名。然后，ls 命令负责在屏幕上显示文件、目录和其他文件系统对象的颜色。

![](/data/attachment/album/201802/13/001317dzxfxxe0k6xlfxu6.jpg)

如何在 Linux 或类 Unix 操作系统上的 bash shell 中打开或关闭文件名称颜色（`ls` 命令颜色）？

大多数现代 Linux 发行版和 Unix 系统都有一个定义了文件名称颜色的别名。然后，`ls` 命令负责在屏幕上显示文件、目录和其他文件系统对象的颜色。

默认情况下，文件类型不会用颜色区分。你需要在 Linux 上将 `--color` 选项传递给 `ls` 命令。如果你正在使用基于 OS X 或 BSD 的系统，请将 `-G` 选项传递给 `ls` 命令。打开或关闭颜色的语法如下。

### 如何关闭 ls 命令的颜色

输入以下命令：

```
$ ls --color=none

```

或者用 `unalias` 命令删除别名：

```
$ unalias ls

```

请注意，下面的 bash shell 别名被定义为用 `ls` 命令显示颜色。这个组合使用 [alias 命令](https://www.cyberciti.biz/tips/bash-aliases-mac-centos-linux-unix.html "See Linux/Unix alias command examples for more info")和 [grep 命令](https://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/ "See Linux/Unix grep command examples for more info")：

```
$ alias | grep ls

```

示例输出：

```
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

```

### 如何打开 ls 命令的颜色

使用以下任何一个命令：

```
$ ls --color=auto
$ ls --color=tty

```

如果你想要的话，[可以定义 bash shell 别名](https://www.cyberciti.biz/tips/bash-aliases-mac-centos-linux-unix.html)：

```
alias ls='ls --color=auto'

```

你可以在 `~/.bash_profile` 或 [~/.bashrc 文件](https://bash.cyberciti.biz/guide/%7E/.bashrc) 中添加或删除 `ls` 别名 。使用文本编辑器（如 vi）编辑文件：

```
$ vi ~/.bashrc

```

追加下面的代码：

```
# my ls command aliases #
alias ls = 'ls --color=auto'

```

[在 Vi/Vim 文本编辑器中保存并关闭文件即可](https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/)。

### 关于 \*BSD/macOS/Apple OS X 中 ls 命令的注意点

将 `-G` 选项传递给 `ls` 命令以在 {Free、Net、Open} BSD 或 macOS 和 Apple OS X Unix 操作系统家族上启用彩色输出：

```
$ ls -G

```

示例输出：

[![How to enable colorized output for the ls command in Mac OS X Terminal](/data/attachment/album/201802/13/001348tpyyp4f8p4qpip4x.jpg)](https://www.cyberciti.biz/faq/apple-mac-osx-terminal-color-ls-output-option/)

*如何在 Mac OS X 终端中为 ls 命令启用彩色输出*

### 如何临时跳过 ls 命令彩色输出？

你可以使用以下任何一种语法[暂时禁用 bash shell 别名](https://www.cyberciti.biz/faq/bash-shell-temporarily-disable-an-alias/)：

```
\ls
/bin/ls
command ls
'ls'

```

#### 关于作者

作者是 nixCraft 的创建者，经验丰富的系统管理员，也是 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter](https://twitter.com/nixcraft)、[Facebook](https://facebook.com/nixcraft)、[Google +](https://plus.google.com/+CybercitiBiz) 上关注他。

---

via: <https://www.cyberciti.biz/faq/how-to-turn-on-or-off-colors-in-bash/>

作者：[Vivek Gite](https://www.cyberciti.biz/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何为数字货币定价

Summary: 预测数字货币价格是一场愚人游戏，然而我想试试。为了理解当前数字货币的快速发展，您必须回到 Linux 悄然兴起的时候。

![](/data/attachment/album/201802/13/004800a4z6vmd529jbjmmy.jpg)

预测数字货币价格是一场愚人游戏，然而我想试试。单一数字货币价值的驱动因素目前太多，而且含糊不清，无法根据任何一点进行评估。或许新闻正报道说比特币呈上升趋势，但与此同时，有黑客攻击或是交易所 API 错误，就让比特币的价格下跌。以太坊看起来不够智能？谁知道呢，也许第二天就建立一个新的更智能的 DAO（LCTT 译注：区块链上，基于激励的经济协调机制，以代码作为表达，通过互联网进行传输，允许人们参与数字企业的风险&回报（即分配），代币创建了 DAO 参与者之间的经济链接）将吸引大量参与者。

那么，您该如何投资呢？又或是更准确的讲，您下注在哪种数字货币上呢？

理解什么时候买卖和持有数字货币，关键是使用与评估开源项目价值的相关工具。这已经一次又一次地被提及了，但是为了理解当前数字货币的快速发展，您必须回到 Linux 悄然兴起的时候。

互联网泡沫期间，Linux 出现在大众视野中。那时候，如果您想建立一个 Web 服务器，您必须将一台 Windows 服务器或者 Sun Sparc 工作站运送到一个服务器托管机房，在那里它将为传送 Pets.com（LCTT 译注：一个在线宠物商店，借着互联网繁荣的机会崛起，在互联网泡沫破裂时倒闭）的 HTML 页面而做出努力。与此同时，Linux 就像运行在微软和 Sun 公司平行路径上的货运列车一样，可以让开发人员使用日新月异的操作系统和工具集，快速、轻松地构建一次性项目。相比之下，解决方案提供商的花费比软硬件支出少得多，很快，所有科技巨头的业务由软件转向了服务提供，例如 Sun 公司。

Linux 的萌发促使整个开源市场蓬勃发展起来。但是有一个关键的问题，您无法从开源软件中赚钱。您可以提供服务，也可以销售使用开源组件的产品，但早期开源者主要是为了提升自我，而不是为了赚钱。

数字货币几乎完全遵循 Linux 的老路，但数字货币具有一定货币价值。因此，当您在为一个区块链项目工作时，您不是为了公共利益，也不是为了编写自由软件的乐趣，而是您写它的时候期望得到一大笔钱。因此，这掩盖了许多程序员的价值判断。那些给您带来了 Python、PHP、Django 和 Node.js 的人们回来了……而现在他们正在通过编程赚钱。

### 审查代码库

今年将是代币销售和数字货币领域大清算的一年。虽然许多公司已经能够摆脱糟糕的或不可用的代码库，但我怀疑开发人员是否能让未来的公司摆脱如此云山雾罩的东西。可以肯定地说，我们可以期待[像这样详细描述 Storj 代码库不足之处的文章成为规范](https://shitcoin.com/storj-not-a-dropbox-killer-1a9f27983d70)，这些评论会让许多所谓的“ICO” 们（LCTT 译注：代币首次发行融资）陷入困境。虽然规模巨大，但 ICO 的资金渠道是有限的，在某种程度上不完整的项目会被更严格的审查。

这是什么意思呢？这意味着要了解数字货币，您必须像对待创业公司那样对待它。您要看它是否有一个好团队？它是否是一个好产品？是否能运作？会有人想要使用它吗？现在评估整个数字货币的价值还为时过早，但如果我们假设代币将成为未来计算机互相支付的方式，这就让我们摆脱了许多疑问。毕竟，2000 年没有多少人知道 Apache 会在一个竞争激烈的市场上，几乎击败其他所有的 Web 服务器，或者像 Ubuntu 一样常见以至于可以随时可以搭建和拆毁它们。

理解数字货币价值的关键是忽视泡沫、炒作、恐惧、迷惑和怀疑心理，而是关注其真正的效用。您认为有一天您的手机会为另外一个手机付款，比如游戏内的额外费用吗？ 您是否认为信用卡系统会在互联网出现后消失？您是否期望有一天，在生活中花费一点点钱，让自己过得更加舒适？然后，通过一切手段，购买并持有您认为将来可能会使您的生活过得更舒适的东西。如果您认为通过 TCP/IP 互联网的方式并不能够改善您的生活（或是您对其没有足够的了解），那么您可能就不会关注这些。纳斯达克总是开放的，至少在银行的营业时间。

好的，下面是我的预测。

### 预测

以下是我在考虑加密货币的“投资”时应该考虑的事项评估。在我们开始之前，先讲下注意事项：

* 数字货币不是真正的货币投资，而是投资在未来的技术。这就好比：当您购买数字货币时，我们像是在<ruby> 进取号星舰 <rt>  Starship Enterprise </rt></ruby>的甲板上交换“<ruby> 星际信用 <rt>  Galactic Credit </rt></ruby>”（LCTT 译注:《星球大战》电影中的一种货币）一般。 这是数字货币的唯一不可避免的未来。虽然您可以强制将数字货币附加到各种经济模式中，对其抱有乐观的态度，整个平台是技术乌托邦，并假设各种令人兴奋和不可能的事情将在未来几年来到。如果您有多余的现金，您喜欢《星球大战》，那么您就可以投资这些“黄金”。如果您的兄弟告诉您相关信息，结果您用信用卡买了比特币，那么您可能会要度过一段啃馒头的时间。
* 不要相信任何人。没有担保，除了提供不是投资建议的免责声明，而且这绝不是对任何特定数字货币的背书，甚至是普遍概念，但我们必须明白，我在这里写的任何东西都可能是错误的。事实上，任何关于数字货币的文章都可能是错误的，任何试图卖给您吹得天花乱坠的代币的人，几乎肯定是骗子。总之，每个人都是错的，每个人都想要得到您的钱，所以要非常、非常小心。
* 您也可以持有。如果您是在 18000 美元的价位买的比特币，您最好还是继续持有下去。 现在您就好像正处于帕斯卡赌注。（LCTT 译注：论述——我不知道上帝是否存在，如果他不存在，作为无神论者没有任何好处，但是如果他存在，作为无神论者我将有很大的坏处。所以，宁愿相信上帝存在）是的，也许您因为数字货币让您赔钱而生气，但也许您只是因为您的愚蠢和自大，但现在您不妨保持信仰，因为没有什么是必然的，或者您可以承认您是有点过于热切。虽然现在您被惩罚，但要相信有比特币之神在注视着您。最终您需要深吸一口气，同意这一切都相当怪异，并坚持下去。

现在回过头来评估数字货币。

**比特币** —— 预计明年的涨幅将超过目前的低点。此外，[世界各地的证券交易委员会和其他联邦机构](http://www.businessinsider.com/bitcoin-price-cryptocurrency-warning-from-sec-cftc-2018-1)也会开始以实际行动调整加密货币的买卖。现在银行开玩笑说，他们想要降低数字货币的风险。因此，比特币将成为数字黄金，成为投机者稳定，乏味但充满波动的避风港。尽管所有都不能用作真正的货币，但对于我们所需要的东西来说，这已经足够了，我们也可以期待量子计算的产品去改变最古老，最熟悉的加密货币的面貌。

**以太坊** —— 只要创造者 Vitalik Buterin 不再继续泼冷水，以太坊在价格上可以维持在上千美元。像一个懊悔的<ruby> 维克多·弗兰肯斯坦 <rt>  Victor Frankenstein </rt></ruby>（LCTT 译注：来自《维克多·弗兰肯斯坦》电影的一名角色），Buterin 倾向于做出惊人的事情，然后在网上诋毁他们，这种自我鞭策在充满泡沫和谎言的空间中实际上是非常有用的。以太坊是最接近我们有用的加密货币，但它本质上仍然是分布式应用。这是一个很有用，很聪明的方法，可以很容易地进行实验，但是，没有人用新的分布式数据存储或应用程序取代旧系统。总之，这是一个非常令人兴奋的技术，但是还没有人知道该用它做什么。

![](/data/attachment/album/201802/13/004803w1bfmgzggyng12np.png)

以太坊的价格将何去何从？它将徘徊在 1000 美元左右，今年可能高达 1500 美元，但这是一个原则性的科技项目，但却不是一个保值产品。

**竞争币**（LCTT 译注：除比特币，以太币之外的所有的数字币，亦称之为山寨币） —— 泡沫的标志之一是当普通人说“我买不起比特币，所以我买了莱特币”这样的话时。这正是我从许多人那里听到的，就好像说“我买不起汉堡，所以我买了一斤木屑，我想孩子们会吃的，对不对？”那您要自担风险。竞争币对于很多人来说是一个风险非常低游戏，就好比您根据一个算法创造出某个竞争币，在市值达到一定水平时卖出，那么您可以赚取一笔不错的利润。况且，大多数竞争币不会在一夜之间消失。 我诚实地推荐以太坊而不是竞争币，但是如果您死磕竞争币，那祝您玩得开心。

**代币** —— 这是数字货币变得有趣的地方。代币需要研究机构和高校对技术有深入的了解，才能真正的评估。我见过的许多代币都是一场赌博，价格暴涨暴跌。我不会给其命名，但是经验法则是，如果您在公开市场上买了一个代币，那么您可能已经错过了赚钱的机会。截至 2018 年 1 月，代币销售，庄家开始投资一个代币几美分，最后得到百倍的回报。虽然许多创始人谈论他们的产品的神奇之处和他们的团队的强大，但是就是为了单车变摩托，把价值 4 美分一个的代币升值为 20 美分，再升值成一美元。您将收益乘以数百万，就能看到它的吸引力了。

答案很简单：找到您喜欢的几个项目并潜藏在他们的社区中。评估团队是否有实力，并且很早就知道该如何进入。将钱投入后就当扔掉几个月或几年。但无法保证，因为代币理念太过超前，以至于无法对其评估。

您正在阅读这篇文章，是因为您希望在这错综复杂的环境下得到一个方向。没关系，我已经跟许多数字货币创始人交谈，知道现在许多人不知道的事情，并且知道合谋和肮脏交易的准则。因此，像我们这样的人，要慢慢地分批购买，就会开始明白这究竟是怎么一回事，也许会从数字货币投资中获利。当数字货币的潜力被完全发掘，我们会得到一个像 Linux 一样的时代。

---

via: <https://techcrunch.com/2018/01/22/how-to-price-cryptocurrencies/>

作者：[John Biggs](https://techcrunch.com/author/john-biggs/) 译者：[wyxplus](https://github.com/wyxplus) 校对：[wxy](https://github.com/wxy)

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


如何列出所有的 Bash Shell 内置命令

![](/data/attachment/album/201802/13/012025cjjsb4449jus4u6j.jpg)

内置命令包含在 bash shell 本身里面。我该如何在 Linux / Apple OS X / \*BSD / Unix 类操作系统列出所有的内置 bash 命令，而不用去读大篇的 bash 操作说明页？

shell 内置命令就是一个命令或一个函数，从 shell 中调用，它直接在 shell 中执行。 bash shell 直接执行该命令而无需调用其他程序。你可以使用 `help` 命令查看 Bash 内置命令的信息。以下是几种不同类型的内置命令。

### 内置命令的类型

1. Bourne Shell 内置命令：内置命令继承自 Bourne Shell。
2. Bash 内置命令：特定于 Bash 的内置命令表。
3. 修改 Shell 行为：修改 shell 属性和可选行为的内置命令。
4. 特别的内置命令：由 POSIX 特别分类的内置命令。

### 如何查看所有 bash 内置命令

有以下的命令：

```
$ help
$ help | less
$ help | grep read

```

样例输出：

```
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
These shell commands are defined internally.  Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.

A star (*) next to a name means that the command is disabled.

 job_spec [&]                            history [-c] [-d offset] [n] or hist>
 (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
 . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
 :                                       kill [-s sigspec | -n signum | -sigs>
 [ arg... ]                              let arg [arg ...]
 [[ expression ]]                        local [option] name[=value] ...
 alias [-p] [name[=value] ... ]          logout [n]
 bg [job_spec ...]                       mapfile [-n count] [-O origin] [-s c>
 bind [-lpvsPVS] [-m keymap] [-f filen>  popd [-n] [+N | -N]
 break [n]                               printf [-v var] format [arguments]
 builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
 caller [expr]                           pwd [-LP]
 case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
 cd [-L|-P] [dir]                        readarray [-n count] [-O origin] [-s>
 command [-pVv] command [arg ...]        readonly [-af] [name[=value] ...] or>
 compgen [-abcdefgjksuv] [-o option]  >  return [n]
 complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
 compopt [-o|+o option] [-DE] [name ..>  set [--abefhkmnptuvxBCHP] [-o option>
 continue [n]                            shift [n]
 coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
 declare [-aAfFilrtux] [-p] [name[=val>  source filename [arguments]
 dirs [-clpv] [+N] [-N]                  suspend [-f]
 disown [-h] [-ar] [jobspec ...]         test [expr]
 echo [-neE] [arg ...]                   time [-p] pipeline
 enable [-a] [-dnps] [-f filename] [na>  times
 eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
 exec [-cl] [-a name] [command [argume>  true
 exit [n]                                type [-afptP] name [name ...]
 export [-fn] [name[=value] ...] or ex>  typeset [-aAfFilrtux] [-p] name[=val>
 false                                   ulimit [-SHacdefilmnpqrstuvx] [limit>
 fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
 fg [job_spec]                           unalias [-a] name [name ...]
 for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [name ...]
 for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
 function name { COMMANDS ; } or name >  variables - Names and meanings of so>
 getopts optstring name [arg]            wait [id]
 hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
 help [-dms] [pattern ...]               { COMMANDS ; }

```

另外一种选择是使用下列命令：

```
compgen -b
compgen -b | more

```

### 查看 Bash 的内置命令信息

运行以下得到详细信息：

```
help command
help read

```

要仅得到所有带简短描述的内置命令的列表，执行如下:

```
$ help -d

```

### 查找内置命令的语法和其他选项

使用下列语法去找出更多的相关内置命令：

```
help name
help cd
help fg
help for
help read
help :

```

样例输出：

```
:: :
 Null command.

 No effect; the command does nothing.

 Exit Status:
 Always succeeds

```

### 找出一个命令是内部的（内置）还是外部的

使用 `type` 命令或 `command` 命令：

```
type -a command-name-here
type -a cd
type -a uname
type -a :
type -a ls

```

或者：

```
type -a cd uname : ls uname

```

样例输出：

```
cd is a shell builtin
uname is /bin/uname
: is a shell builtin
ls is aliased to `ls --color=auto'
ls is /bin/ls
l is a function
l ()
{
 ls --color=auto
}

```

或者：

```
command -V ls
command -V cd
command -V foo

```

[![View list bash built-ins command info on Linux or Unix](/data/attachment/album/201802/13/012043plctt333wtncllco.jpg)](https://www.cyberciti.biz/media/new/faq/2013/03/View-list-bash-built-ins-command-info-on-Linux-or-Unix.jpg)

### 关于作者

作者是 nixCraft 网站的发起人和经验丰富的系统管理员，以及 Linux 操作系统/Unix shell 脚本编程培训师。他与全球客户以及包括 IT、教育、国防和空间研究以及非营利部门在内的各个行业合作。可以在 [Twitter](https://twitter.com/nixcraft)、[Facebook](https://facebook.com/nixcraft)、 [Google+](https://plus.google.com/+CybercitiBiz) 上关注他。

---

via: <https://www.cyberciti.biz/faq/linux-unix-bash-shell-list-all-builtin-commands/>

作者：[Vivek Gite](https://www.cyberciti.biz) 译者：[KarenMrzhang](https://github.com/KarenMrzhang) 校对：[wxy](https://github.com/wxy)

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


Linux 中 4 个简单的找出进程 ID（PID）的方法

![](/data/attachment/album/201802/13/185715w7awbfirhr7bb4i8.jpg)

每个人都知道 PID，究竟什么是 PID？为什么你想要 PID？你打算用 PID 做什么？你脑子里有同样的问题吗？如果是这样，你就找对地方了解这些细节了。

我们查询 PID 主要是用来杀死一个没有响应的程序，它类似于 Windows 任务管理器一样。 Linux GUI 也提供相同的功能，但 CLI 是执行 `kill` 操作的有效方法。

### 什么是进程 ID?

PID 代表<ruby> 进程标识号 <rt>  process identification </rt></ruby>，它在大多数操作系统内核（如 Linux、Unix、macOS 和 Windows）中使用。它是在操作系统中创建时自动分配给每个进程的唯一标识号。一个进程是一个正在运行的程序实例。

**建议阅读：** [如何查看 Apache Web 服务器在 Linux 中的运行时间](https://www.2daygeek.com/check-find-apache-httpd-web-server-uptime-linux/)

除了 init 进程外其他所有的进程 ID 每次都会改变，因为 init 始终是系统上的第一个进程，并且是所有其他进程的父进程。它的 PID 是 1。

PID 默认的最大值是 `32768`。可以在你的系统上运行 `cat /proc/sys/kernel/pid_max` 来验证。在 32 位系统上，`32768` 是最大值，但是我们可以在 64 位系统上将其设置为最大 2<sup> 22（约</sup> 4 百万）内的任何值。

你可能会问，为什么我们需要这么多的 PID？因为我们不能立即重用 PID，这就是为什么。另外为了防止可能的错误。

系统正在运行的进程的 PID 可以通过使用 `pidof`、`pgrep`、`ps` 和 `pstree` 命令找到。

### 方法 1：使用 pidof 命令

`pidof` 用于查找正在运行的程序的进程 ID。它在标准输出上打印这些 id。为了演示，我们将在 Debian 9（stretch）系统中找出 Apache2 的进程 ID。

```
# pidof apache2
3754 2594 2365 2364 2363 2362 2361

```

从上面的输出中，你可能会遇到难以识别进程 ID 的问题，因为它通过进程名称显示了所有的 PID（包括父进程和子进程）。因此，我们需要找出父 PID（PPID），这是我们要查找的。它可能是第一个数字。在本例中，它是 `3754`，并按降序排列。

### 方法 2：使用 pgrep 命令

`pgrep` 遍历当前正在运行的进程，并将符合选择条件的进程 ID 列到标准输出中。

```
# pgrep apache2
2361
2362
2363
2364
2365
2594
3754

```

这也与上面的输出类似，但是它将结果从小到大排序，这清楚地说明父 PID 是最后一个。在本例中，它是 `3754`。

**注意：** 如果你有多个进程的进程 ID，那么在使用 `pidof` 和 `pgrep` 识别父进程 ID 时就可能不会很顺利。

### 方法 3：使用 pstree 命令

`pstree` 将运行的进程显示为一棵树。树的根是某个 pid，如果省略了 pid 参数，那么就是 init。如果在 `pstree` 命令中指定了用户名，则显示相应用户拥有的所有进程。

`pstree` 会将相同的分支放在方括号中，并添加重复计数的前缀来可视化地合并到一起。

```
# pstree -p | grep "apache2"
 |- apache2(3754) -|-apache2(2361)
 | |-apache2(2362)
 | |-apache2(2363)
 | |-apache2(2364)
 | |-apache2(2365)
 | `-apache2(2594)

```

要单独获取父进程，请使用以下格式。

```
# pstree -p | grep "apache2" | head -1
 |- apache2(3754) -|-apache2(2361)

```

`pstree` 命令非常简单，因为它分别隔离了父进程和子进程，但这在使用 `pidof` 和 `pgrep` 时命令不容易做到。

### 方法 4：使用 ps 命令

`ps` 显示活动进程的选择信息。它显示进程 ID（`pid`=PID）、与进程关联的终端（`tname`=TTY）、以 `[DD-]hh:mm:ss` 格式（`time`=TIME）显示的累计 CPU 时间、以及执行名（`ucmd` = CMD）。输出默认是未排序的。

```
# ps aux | grep "apache2"
www-data 2361 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2362 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2363 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2364 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2365 0.0 0.4 302652 8400 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2594 0.0 0.4 302652 8400 ? S 06:55 0:00 /usr/sbin/apache2 -k start
root 3754 0.0 1.4 302580 29324 ? Ss Dec11 0:23 /usr/sbin/apache2 -k start
root 5648 0.0 0.0 12784 940 pts/0 S+ 21:32 0:00 grep apache2

```

从上面的输出中，我们可以根据进程的启动日期轻松地识别父进程 ID（PPID）。在此例中，apache2 启动于 `Dec 11`，它是父进程，其他的是子进程。apache2 的 PID 是 `3754`。

---

via: <https://www.2daygeek.com/how-to-check-find-the-process-id-pid-ppid-of-a-running-program-in-linux/>

作者：[Magesh Maruthamuthu](https://www.2daygeek.com/author/magesh/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


为什么说 Python 和 Pygame 最适合编程初学者

Summary: 我们有三个理由来说明 Pygame 对初学编程者是最好的选择。

我们有三个理由来说明 Pygame 对初学编程者是最好的选择。

>
> 我们有三个理由来说明 Pygame 对初学编程者是最好的选择。
>
>
>

![What's the best game platform for beginning programmers?](/data/attachment/album/201802/13/200646ffjgf8fhl8lf1oon.png "What's the best game platform for beginning programmers?")

上个月，[Scott Nesbitt](https://opensource.com/users/scottnesbitt) 发表了一篇标题为 [Mozilla 支出 50 万美元来支持开源项目](https://opensource.com/article/17/10/news-october-14)的文章。其中一个基于 HTML/JavaScript 的游戏平台项目 Phaser 获得了 50,000 美元的奖励。整整一年里，我都在使用 Phaser 平台来教我的小女儿，用来学习的话，它是最简单也是最好的 HTML 游戏开发平台。然而，对于初学者来说，使用 [Pygame](https://www.pygame.org/news) 也许效果更好。原因如下：

### 1、 小段代码块

Pygame，基于[计算机课程中最流行的语言](https://cacm.acm.org/blogs/blog-cacm/176450-python-is-now-the-most-popular-introductory-teaching-language-at-top-u-s-universities/fulltext) Python。Python 非常适合用一小段代码来实现我们的想法，孩子们可以从单个文件和单个代码块起开始学习，在掌握函数（function）或类（class）对象之前，就可以写出意大利面条似的代码。 很像手指画，所想即所得。

以这样的方式来学习，当编写的代码越来越难于管理的时候，孩子们很自然的就会把代码分解成函数模块和类模块。在学习函数之前就学习了 Python 语言的语法，学生将掌握基本的编程知识，对了解全局作用域和局部作用域起到更好的作用。

大多数 HTML 游戏在一定程度上会将结构、样式和编程逻辑分为 HTML、CSS 和 JavaScript，并且需要 CSS 和 HTML 的知识。从长远来看，虽然拆分更好，但对初学者来说是个障碍。一旦孩子们发现他们可以用 HTML 和 CSS 快速构建网页，很有可能就会被颜色、字体和图形的视觉刺激分散注意力。即使仅仅只专注于 JavaScript 代码，也需要学习基本的文档结构模型（DOM），以使 JavaScript 代码能够嵌入进去。

### 2、 全局变量更清晰

Python 和 JavaScript 都使用动态类型变量，这意味着变量只有在赋值才能确定其类型是一个字符串、一个整数还是一个浮点数，然而在 JavaScript 更容易出错。类似于类型变量，JavaScript 和 Python 都有全局变量和局部变量之分。Python 中，如果在函数块内要使用全局变量，就会以 `global` 关键字区分出来。

要理解在 Phaser 上教授编程初学者所面临的挑战的话，让我们以基本的[制作您的第一个 Phaser 游戏教程](http://phaser.io/tutorials/making-your-first-phaser-game)为例子，它是由 Alvin Ourrad 和 Richard Davey 开发制作的。在 JavaScript 中，程序中任何地方都可以访问的全局变量很难追踪调试，常常引起 Bug 且很难解决。因为 Richard 和 Alvin 是专业程序员，所以在这儿特意使用全局变量以使程序简洁。

```
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });

function preload() {

    game.load.image('sky', 'assets/sky.png');

}

var player;
var platforms;

function create() {
    game.physics.startSystem(Phaser.Physics.ARCADE);
...

```

在他们的 Phaser 编程手册 [《Interphase》](https://phaser.io/interphase) 中，Richard Davey 和 Ilija Melentijevic 解释说：在很多 Phaser 项目中通常都会使用全局变量，原因是使用它们完成任务更容易、更快捷。

>
> “如果您开发过游戏，只要代码量到一定规模，那么（使用全局变量）这种做法会使您陷入困境的，可是我们为什么还要这样做？原因很简单，仅仅只是要使我们的 Phaser 项目容易完成，更简单而已。”
>
>
>

针对一个 Phaser 应用程序，虽然可以使用局部变量和拆分代码块来达到关注点隔离这些手段来重构代码，但要使第一次学习编程的小孩能理解，显然很有难度的。

如果您想教你的孩子学习 JavaScript，或者如果他们已经知道怎样使用像 Python 来编程的话，有个好的 Phaser 课程推荐： [完整的手机游戏开发课程](https://academy.zenva.com/product/the-complete-mobile-game-development-course-platinum-edition/)，是由 [Pablo Farias Navarro](https://gamedevacademy.org/author/fariazz/) 开发制作的。虽然标题看着是移动游戏，但实际是关于 JavaScript 和 Phaser 的。JavaScript 和 Phaser 移动应用开发已经转移到 [PhoneGap](https://phonegap.com/) 话题去了。

### 3、 Pygame 无依赖要求

由于 [Python Wheels](https://pythonwheels.com/) 的出现，Pygame 超级[容易安装](https://pypi.python.org/pypi/Pygame)。在 Fedora/Red Hat 系统下也可使用 `yum` 包管理器来安装：

```
sudo yum install python3-pygame

```

更多信息请参考官网 [Pygame 安装说明文档](http://www.pygame.org/wiki/GettingStarted#Pygame%20Installation)。

相比来说，虽然 Phaser 本身更容易安装，但需要掌握更多的知识。前面提到的，学生需要在 HTML 文档中组装他们的 JavaScript 代码，同时还需要些 CSS。除了这三种语言（HTML、CSS、JavaScript），还需要使用火狐或谷歌开发工具和编辑器。JavaScript 最常用的编辑器有 Sublime、Atom、VS Code（按使用多少排序）等。

由于[浏览器同源策略](https://blog.chromium.org/2008/12/security-in-depth-local-web-pages.html)的原因，如果您直接在浏览器中打开 HTML 文件的话，Phaser 应用是不会运行的。您必须运行 Web 服务，并通过服务访问这些文件。还好，对于大多数工程项目，可以不用在本地运行 Apache 服务，只需要运行一些轻量级的服务就可以，比如 [httpster](https://simbco.github.io/httpster/)。

### Phaser 和 JavaScript 的优势

JavaScript 和 Phaser 有着种种的不好，为什么我还继续教授他们？老实说，我考虑了很长一段时间，我在担心着学生学习<ruby> 变量申明提升 <rt>  variable hoisting </rt></ruby>和变量作用域的揪心。我开发出基于 Pygame 和 Python 的课程，随后也开发出一涛基于 Phaser 的。最终，我决定使用 Pablo 预先制定的课程作为起点。

我转用 JavaScript 有两个原因。首先，JavaScript 已经成为正式应用的正式语言。除了 Web 应用外，也可使用于移动和服务应用方面。JavaScript 无处不在，其广泛应用于孩子们每天都能看到的应用中。如果他们的朋友使用 Javascript 来编程，他们很可能也会受影响而使用之。正如我看到了 JavaScript 背后的动力，所以深入研究了可编译成 JavaScript 的替代语言，主要是 Dart 和 TypeScript 两种。虽然我不介意额外的转换步骤，但还是最喜欢 JavaScript。

最后，我选择使用 Phaser 和 JavaScript 的组合，是因为我意识到上面那些问题在 JavaScript 可以被解决，仅仅只是一些工作量而已。高质量的调试工具和一些大牛们的工作使得 JavaScript 成为教育孩子编码的可用和有用的语言。

### 最后话题: Python 对垒 JavaScript

当家长问我使用的什么语言作为孩子的入门语言时，我会立即推荐 Python 和 Pygame。因为有成千上万的课程可选，而且大多数都是免费的。我为我的儿子选择了 Al Sweigart 的 [使用 Python 和 Pygame 开发游戏](https://inventwithpython.com/makinggames.pdf) 课程，同时也在使用 Allen B. Downey 的 [Python 编程思想：如何像计算机科学家一样思考](http://greenteapress.com/thinkpython/html/index.html)。在 Android 手机上可以使用 [Tom Rothame](https://github.com/renpytom) 的 [PAPT Pyame](https://github.com/renpytom/rapt-pygame-example) 来安装 Pygame 游戏。

尽管有我的建议, 我总是怀疑孩子们很快就会搬到 JavaScript。这没关系 —— JavaScript 是一门成熟的编程语言，有很多很多辅助工具。但有多年的帮助大儿子使用 Python 创建炫酷游戏经历的我，依然钟情于 Python 和 Pygame。

### 关于作者

Craig Oda —— 东京 Linux 用户组的首位总裁和共同创始人，奥莱理日本出版的《Linux 日文环境》的共同作者。在亚洲建立了第一个 ISP 的核心团队成员之一。一个大型 Linux 公司的产品管理及市场的前任副总裁。硅谷开发者关系咨询公司 Oppkey 的合作方。[更多](https://opensource.com/users/codetricity)

---

via: <https://opensource.com/article/17/11/pygame>

作者：[Craig Oda](https://opensource.com/users/codetricity) 译者：[runningwater](https://github.com/runningwater) 校对：[wxy](https://github.com/wxy)

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


如何在 Ubuntu 上使用 ZFS 文件系统

Summary: 在 Linux 系统上，有大量的文件系统可以使用，那么我们为什么还要尝试一个新的文件系统？它们都工作的很好，不是吗？但是它们并不完全相同，其中的一些文件系统具有非常突出的优点，例如 ZFS。

![](/data/attachment/album/201802/14/005211baxhkm3vax7a5h75.jpg)

在 Linux 系统上，有大量的[文件系统](https://www.maketecheasier.com/best-linux-filesystem-for-ssd/)可以使用，那么我们为什么还要尝试一个新的文件系统？它们都工作的很好，不是吗？但是它们并不完全相同，其中的一些文件系统具有非常突出的优点，例如 ZFS。

### 为什么选择 ZFS

ZFS 非常的优秀。这是一个真正现代的文件系统，内置的功能对于处理大量的数据很有意义。

现在，如果您正在考虑将 ZFS 用于您的超高速 NVMe SSD，这可能不是一个最佳选择。 它比别的文件系统要慢，不过，这完全没有问题， 它旨在存储大量的数据并保持安全。

ZFS 消除了建立传统 RAID 阵列（LCTT 译注：独立磁盘冗余阵列）的需要。 相反，您可以创建 ZFS 池，甚至可以随时将驱动器添加到这些池中。 ZFS 池的行为操作与 RAID 几乎完全相同，但功能内置于文件系统中。

ZFS 也可以替代 LVM （LCTT 译注：逻辑盘卷管理），使您能够动态地进行分区和管理分区，而无需处理底层的细节，也不必担心相关的风险。

这也是一个 CoW （LCTT 译注：写时复制）文件系统。 这里不会提及太多的技术性，这意味着 ZFS 可以保护您的数据免受逐渐损坏的影响。 ZFS 会创建文件的校验和，并允许您将这些文件回滚到以前的工作版本。

### 安装 ZFS

![Install ZFS on Ubuntu](/data/attachment/album/201802/14/005212gem4smmvrwczhxdh.jpg "Install ZFS on Ubuntu")

在 Ubuntu 上安装 ZFS 非常简单，但对于 Ubuntu LTS （LCTT 译注：长时间支持版本）和最新版本来说，这个过程稍有不同。

**Ubuntu 16.04 LTS**

```
sudo apt install zfs

```

**Ubuntu 17.04 及以后**

```
sudo apt install zfsutils

```

当你安装好程序后，可以使用 ZFS 提供的工具创建 ZFS 驱动器和分区。

### 创建池

![Create ZFS Pool](/data/attachment/album/201802/14/005212t99r9s9pxxp4r991.jpg "Create ZFS Pool")

在 ZFS 中，池大致相当于 RAID 。 它们很灵活且易于操作。

#### RAID0

RAID0 只是把你的硬盘集中到一个池子里面，就像一个巨大的驱动器一样。 它可以提高你的驱动器速度，（LCTT 译注：数据条带化后，并行访问，可以提高文件读取速度）但是如果你的驱动器有损坏，你可能会失丢失数据。

要使用 ZFS 实现 RAID0，只需创建一个普通的池。

```
sudo zpool create your-pool /dev/sdc /dev/sdd

```

#### RAID1（镜像）

您可以在 ZFS 中使用 `mirror` 关键字来实现 RAID1 功能。 RAID1 会创建一个一对一的驱动器副本。 这意味着您的数据一直在备份。 它也提高了性能。 当然，你将一半的存储空间用于了复制。

```
sudo zpool create your-pool mirror /dev/sdc /dev/sdd

```

#### RAID5/RAIDZ1

ZFS 将 RAID5 功能实现为 RAIDZ1。 RAID5 要求驱动器至少是 3 个。并允许您通过将备份奇偶校验数据写入驱动器空间的 1/n（n 是驱动器数），留下的是可用的存储空间。 如果一个驱动器发生故障，阵列仍将保持联机状态，但应尽快更换发生故障的驱动器（LCTT 译注：与原文翻译略有不同，原文是驱动器的数目是三的倍数，根据 wiki， RAID5 至少需要 3 块驱动器，也可以从下面的命令中猜测)。

```
sudo zpool create your-pool raidz1 /dev/sdc /dev/sdd /dev/sde

```

#### RAID6/RAIDZ2

RAID6 与 RAID5 几乎完全相同，但它至少需要四个驱动器。 它将奇偶校验数据加倍，最多允许两个驱动器损坏，而不会导致阵列关闭（LCTT 译注：这里也与原文略有出入，原文是驱动器的数目是四的倍数，根据 wiki ，RAID6 至少需要四个驱动器)。

```
sudo zpool create your-pool raidz2 /dev/sdc /dev/sdd /dev/sde /dev/sdf

```

#### RAID10（条带化镜像）

RAID10 旨在通过数据条带化提高存取速度和数据冗余来成为一个两全其美的解决方案。 你至少需要四个驱动器，但只能使用一半的空间。 您可以通过在同一个池中创建两个镜像来创建 RAID10 中的池（LCTT 译注：这里也与原文略有出入，原文是驱动器的数目是四的倍数，根据 wiki， RAID10 至少需要四个驱动器）。

```
sudo zpool create your-pool mirror /dev/sdc /dev/sdd mirror /dev/sde /dev/sdf

```

### 池的操作

![ZFS pool Status](/data/attachment/album/201802/14/005212sbj96k1bozm1gbgz.jpg "ZFS pool Status")

还有一些管理工具，一旦你创建了你的池，你就必须使用它们来操作。 首先，检查你的池的状态。

```
sudo zpool status

```

#### 更新

当你更新 ZFS 时，你也需要更新你的池。 当您检查它们的状态时，您的池会通知您任何更新。 要更新池，请运行以下命令。

```
sudo zpool upgrade your-pool

```

你也可以更新全部池。

```
sudo zpool upgrade -a

```

#### 添加驱动器

您也可以随时将驱动器添加到池中。 告诉 `zpool` 池的名称和驱动器的位置，它会处理好一切。

```
sudo zpool add your-pool /dev/sdx

```

### 其它的一些想法

![ZFS in File Browser](/data/attachment/album/201802/14/005212ij3vwbvq3zllq030.jpg "ZFS in File Browser")

ZFS 会在您的池的根文件系统中创建一个目录。 您可以使用 GUI 文件管理器或 CLI 按名称浏览它们。

ZFS 非常强大，还有很多其它的东西可以用它来做，但这些都是基础。 这是一个优秀的存储负载文件系统，即使它只是一个用于文件的硬盘驱动器的 RAID 阵列。 ZFS 在 NAS 系统上也非常出色。

无论 ZFS 的稳定性和可靠性如何，在您的硬盘上实施新的功能时，最好备份您的数据。

---

via: <https://www.maketecheasier.com/use-zfs-filesystem-ubuntu-linux/>

作者：[Nick Congleton](https://www.maketecheasier.com/author/nickcongleton/) 译者：[amwps290](https://github.com/amwps290) 校对：[wxy](https://github.com/wxy)

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


哪个 Linux 内核版本是 “稳定的”？

Summary: 每次 Linus Torvalds 发布 一个新 Linux 内核的主线版本，几乎都会引起这种困惑，那就是到底哪个内核版本才是最新的“稳定版”？是新的那个 X.Y，还是前面的那个 X.Y-1.Z ？最新的内核版本是不是太“新”了？你是不是应该坚持使用以前的版本？

![Linux kernel ](/data/attachment/album/201802/14/215211tx038x3zccrs3crx.jpg "Linux kernel")

>
> Konstantin Ryabitsev 为你讲解哪个 Linux 内核版本可以被视作“稳定版”，以及你应该如何选择一个适用你的内核版本。
>
>
>

每次 Linus Torvalds 发布 [一个新 Linux 内核的主线版本](/article-9328-1.html)，几乎都会引起这种困惑，那就是到底哪个内核版本才是最新的“稳定版”？是新的那个 X.Y，还是前面的那个 X.Y-1.Z ？最新的内核版本是不是太“新”了？你是不是应该坚持使用以前的版本？

[kernel.org](https://www.kernel.org/) 网页上的信息并不会帮你解开这个困惑。目前，在该页面的最顶部，我们看到是最新稳定版内核是 4.15 — 但是在这个表格的下面，4.14.16 也被列为“<ruby> 稳定版 <rt>  stable </rt></ruby>”，而 4.15 被列为“<ruby> 主线版本 <rt>  mainline </rt></ruby>”，很困惑，是吧？

不幸的是，这个问题并不好回答。我们在这里使用“稳定”这个词有两个不同的意思：一是，作为最初发布的 Git 树的名字，二是，表示这个内核可以被视作“稳定版”，用在“生产系统”。

由于 Git 的分布式特性，Linux 的开发工作在许多 [不同的分叉仓库中](https://git.kernel.org/pub/scm/linux/kernel/git/) 进行。所有的 bug 修复和新特性也是首先由各个子系统维护者收集和准备的，然后提交给 Linus Torvalds，由 Linus Torvalds 包含进 [他自己的 Linux 树](https://git.kernel.org/torvalds/c/v4.15) 中，他的 Git 树被认为是 Git 仓库的 “master”。我们称这个树为 “主线” Linux 树。

### 候选发布版（RC）

在每个新的内核版本发布之前，它都要经过几轮的“候选发布”，它由开发者进行测试并“打磨”所有的这些很酷的新特性。基于他们这几轮测试的反馈，Linus 决定最终版本是否已经准备就绪。通常有 7 个每周预发布版本，但是，这个数字经常走到 -rc8，并且有时候甚至达到 -rc9 及以上。当 Linus 确信那个新内核已经没有问题了，他就制作最终发行版，我们称这个版本为“稳定版”，表示它不再是一个“候选发布版”。

### Bug 修复

就像任何一个由不是十全十美的人所写的复杂软件一样，任何一个 Linux 内核的新版本都包含 bug，并且这些 bug 必须被修复。Linux 内核的 bug 修复规则非常简单：所有修复必须首先进入到 Linus 的树。一旦主线仓库中的 bug 被修复后，它接着会被应用到内核开发社区仍在维护的已发布内核中。在它们被考虑回迁到已发布的稳定版本之前，所有的 bug 修复必须满足 [一套重要的标准](https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html) — 标准的其中之一是，它们 “必须已经存在于 Linus 的树中”。这是一个 [独立的 Git 仓库](https://git.kernel.org/stable/linux-stable/c/v4.14.16)，维护它的用途是回迁 bug 修复，而它也被称为“稳定”树 —— 因为它用于跟踪以前发布的稳定内核。这个树由 Greg Kroah-Hartman 策划和维护。

### 最新的稳定内核

因此，无论在什么时候，为了查看最新的稳定内核而访问 kernel.org 网站时，你应该去使用那个在大黄色按钮所说的“最新的稳定内核”。

![](/data/attachment/album/201802/14/215257g9bbamoimqqm5mmi.png)

但是，你可能会惊奇地发现 —— 4.15 和 4.14.16 都是稳定版本，那么到底哪一个更“稳定”呢？有些人不愿意使用 “.0” 的内核发行版，因为他们认为这个版本并不足够“稳定”，直到最新的是 ".1" 的为止。很难证明或者反驳这种观点的对与错，并且这两种观点都有赞成或者反对的理由，因此，具体选择哪一个取决于你的喜好。

一方面，任何一个进入到稳定树的发行版都必须首先被接受进入主线内核版本中，并且随后会被回迁到已发行版本中。这意味着内核的主线版本相比稳定树中的发行版本来说，总包含有最新的 bug 修复，因此，如果你想使用的发行版包含的“**已知 bug**”最少，那么使用 “.0” 的主线发行版是最佳选择。

另一方面，主线版本增加了所有很酷的新特性 —— 而新特性也给它们带来了**数量未知的“新 bug”**，而这些“新 bug”在老的稳定版中是**不会存在**的。而新的、未知的 bug 是否比旧的、已知的但尚未修复的 bug 更加令人担心呢？ —— 这取决于你的选择。不过需要说明的一点是，许多 bug 修复只对内核的主线版本进行了彻底的测试。当补丁回迁到旧内核时，它们**可能**会工作的很好，但是它们**很少**做与旧内核的集成测试工作。通常都假定，“以前的稳定版本”足够接近当前的确信可用于生产系统的主线版本。而实际上也确实是这样的，当然，这也更加说明了为什么选择“哪个内核版本更稳定”是件**非常困难**的事情了。

因此，从根本上说，我们并没有定量的或者定性的手段去明确的告诉你哪个内核版本更加稳定 —— 4.15 还是 4.14.16？我们能够做到的只是告诉你，它们具有“**不同的**稳定性”，（这个答案可能没有帮到你，但是，至少你明白了这些版本的差别是什么？）。

*学习更多的 Linux 的知识，可以通过来自 Linux 基金会和 edX 的免费课程 ["认识 Linux"](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 。*

---

via: <https://www.linux.com/blog/learn/2018/2/which-linux-kernel-version-stable>

作者：[KONSTANTIN RYABITSEV](https://www.linux.com/users/mricon) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


ncurses 入门指南

Summary: 怎样使用 curses 来绘制终端屏幕？

怎样使用 curses 来绘制终端屏幕？

>
> 怎样使用 curses 来绘制终端屏幕？
>
>
>

![](/data/attachment/album/201802/14/232431itpppd60pa60ps4w.jpg)

虽然图形界面非常酷，但是不是所有的程序都需要点击式的界面。例如，令人尊敬的 Vi 编辑器在第一个 GUI 出现之前在纯文本终端运行了很久。

Vi 编辑器是一个在“文本”模式下绘制的<ruby> 面向屏幕 <rt>  screen-oriented </rt></ruby>程序的例子。它使用了一个叫 curses 的库。这个库提供了一系列的编程接口来操纵终端屏幕。curses 库产生于 BSD UNIX，但是 Linux 系统通过 ncurses 库提供这个功能。

[要了解 ncurses “过去曾引起的风暴”，参见 [ncurses: Portable Screen-Handling for Linux](http://www.linuxjournal.com/article/1124), September 1, 1995, by Eric S. Raymond.]

使用 curses 创建程序实际上非常简单。在这个文章中，我展示了一个利用 curses 来在终端屏幕上绘图的示例程序。

### 谢尔宾斯基三角形

简单展示一些 curses 函数的一个方法是生成<ruby> 谢尔宾斯基三角形 <rt>  Sierpinski's Triangle </rt></ruby>。如果你对生成谢尔宾斯基三角形的这种方法不熟悉的话，这里是一些产生谢尔宾斯基三角形的规则：

1. 设置定义三角形的三个点。
2. 随机选择任意的一个点 `(x,y)`。

然后：

1. 在三角形的顶点中随机选择一个点。
2. 将新的 `x,y` 设置为先前的 `x,y` 和三角顶点的中间点。
3. 重复（上述步骤）。

所以我按照这些指令写了这个程序，程序使用 curses 函数来向终端屏幕绘制谢尔宾斯基三角形：

```
/* triangle.c */

#include <curses.h>
#include <stdlib.h>

#include "getrandom_int.h"

#define ITERMAX 10000

int main(void)
{
  long iter;
  int yi, xi;
  int y[3], x[3];
  int index;
  int maxlines, maxcols;

  /* initialize curses */

  initscr();
  cbreak();
  noecho();

  clear();

  /* initialize triangle */

  maxlines = LINES - 1;
  maxcols = COLS - 1;

  y[0] = 0;
  x[0] = 0;

  y[1] = maxlines;
  x[1] = maxcols / 2;

  y[2] = 0;
  x[2] = maxcols;

  mvaddch(y[0], x[0], '0');
  mvaddch(y[1], x[1], '1');
  mvaddch(y[2], x[2], '2');

  /* initialize yi,xi with random values */

  yi = getrandom_int() % maxlines;
  xi = getrandom_int() % maxcols;

  mvaddch(yi, xi, '.');

  /* iterate the triangle */

  for (iter = 0; iter < ITERMAX; iter++) {
      index = getrandom_int() % 3;

      yi = (yi + y[index]) / 2;
      xi = (xi + x[index]) / 2;

      mvaddch(yi, xi, '*');
      refresh();
  }

  /* done */

  mvaddstr(maxlines, 0, "Press any key to quit");

  refresh();

  getch();
  endwin();

  exit(0);
}

```

让我一边解释一边浏览这个程序。首先，`getrandom_int()` 函数是我对 Linux 系统调用 `getrandom()` 的包装器。它保证返回一个正整数（`int`）值。（LCTT 译注：`getrandom()` 系统调用按照字节返回随机值到一个变量中，值是随机的，不保证正负，使用 `stdlib.h` 的 `random()` 函数可以达到同样的效果）另外，按照上面的规则，你应该能够辨认出初始化和迭代谢尔宾斯基三角形的代码。除此之外，我们来看看我用来在终端上绘制三角形的 curses 函数。

大多数 curses 程序以这四条指令开头。 `initscr()` 函数获取包括大小和特征在内的终端类型，并设置终端支持的 curses 环境。`cbreak()` 函数禁用行缓冲并设置 curses 每次只接受一个字符。`noecho()` 函数告诉 curses 不要把输入回显到屏幕上。而 `clear()` 函数清空了屏幕：

```
  initscr();
  cbreak();
  noecho();

  clear();

```

之后程序设置了三个定义三角的顶点。注意这里使用的 `LINES` 和 `COLS`，它们是由 `initscr()` 来设置的。这些值告诉程序在终端的行数和列数。屏幕坐标从 `0` 开始，所以屏幕左上角是 `0` 行 `0` 列。屏幕右下角是 `LINES - 1` 行，`COLS - 1` 列。为了便于记忆，我的程序里把这些值分别设为了变量 `maxlines` 和 `maxcols`。

在屏幕上绘制文字的两个简单方法是 `addch()` 和 `addstr()` 函数。也可以使用相关的 `mvaddch()` 和 `mvaddstr()` 函数可以将字符放到一个特定的屏幕位置。我的程序在很多地方都用到了这些函数。首先程序绘制三个定义三角的点并标记为 `'0'`，`'1'` 和 `'2'`：

```
  mvaddch(y[0], x[0], '0');
  mvaddch(y[1], x[1], '1');
  mvaddch(y[2], x[2], '2');

```

为了绘制任意的一个初始点，程序做了类似的一个调用：

```
  mvaddch(yi, xi, '.');

```

还有为了在谢尔宾斯基三角形递归中绘制连续的点：

```
      mvaddch(yi, xi, '*');

```

当程序完成之后，将会在屏幕左下角（在 `maxlines` 行，`0` 列）显示一个帮助信息：

```
  mvaddstr(maxlines, 0, "Press any key to quit");

```

注意 curses 在内存中维护了一个版本的屏幕显示，并且只有在你要求的时候才会更新这个屏幕，这很重要。特别是当你想要向屏幕显示大量的文字的时候，这样程序会有更好的性能表现。这是因为 curses 只能更新在上次更新之后改变的这部分屏幕。想要让 curses 更新终端屏幕，请使用 `refresh()` 函数。

在我的示例程序中，我选择在“绘制”每个谢尔宾斯基三角形中的连续点时更新屏幕。通过这样做，用户可以观察三角形中的每次迭代。（LCTT 译注：由于 CPU 太快，迭代过程执行就太快了，所以其实很难直接看到迭代过程）

在退出之前，我使用 `getch()` 函数等待用户按下一个键。然后我调用 `endwin()` 函数退出 curses 环境并返回终端程序到一般控制。

```
  getch();
  endwin();

```

### 编译和示例输出

现在你已经有了你的第一个 curses 示例程序，是时候编译运行它了。记住 Linux 操作系统通过 ncurses 库来实现 curses 功能，所以你需要在编译的时候通过 `-lncurses`来链接——例如：

```
$ ls
getrandom_int.c  getrandom_int.h  triangle.c

$ gcc -Wall -lncurses -o triangle triangle.c getrandom_int.c

```

（LCTT 译注：此处命令行有问题，`-lncurses` 选项在我的 Ubuntu 16.04 系统 + gcc 4.9.3 环境下，必须放在命令行最后，否则找不到库文件，链接时会出现未定义的引用。）

在标准的 80x24 终端运行这个 `triangle` 程序并没什么意思。在那样的分辨率下你不能看见谢尔宾斯基三角形的很多细节。如果你运行终端窗口并设置非常小的字体大小，你可以更加容易地看到谢尔宾斯基三角形的不规则性质。在我的系统上，输出如图 1。

![](/data/attachment/album/201802/14/232441hbttkoalfofoiyl9.png)

*图 1. triangle 程序的输出*

虽然迭代具有随机性，但是每次谢尔宾斯基三角形的运行看起来都会很一致。唯一的不同是最初绘制到屏幕的一些点的位置不同。在这个例子中，你可以看到三角形开始的一个小圆点，在点 1 附近。看起来程序接下来选择了点 2，然后你可以看到在圆点和“2”之间的星号。并且看起来程序随机选择了点 2 作为下一个随机数，因为你可以看到在第一个星号和“2”之间的星号。从这里开始，就不能继续分辨三角形是怎样被画出来的了，因为所有的连续点都属于三角形区域。

### 开始学习 ncurses

这个程序是一个怎样使用 curses 函数绘制字符到屏幕的简单例子。按照你的程序的需要，你可以通过 curses 做得更多。在下一篇文章中，我将会展示怎样使用 curses 让用户和屏幕交互。如果你对于学习 curses 有兴趣，我建议你去读位于 <ruby> <a href="http://www.tldp.org">  Linux 文档计划 </a> <rt>  Linux Documentation Project </rt></ruby>的 Pradeep Padala 写的 [NCURSES Programming HOWTO](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO)。

### 关于作者

Jim Hall 是一个自由及开源软件的倡议者，他最有名的工作是 FreeDOS 计划，也同样致力于开源软件的可用性。Jim 是在明尼苏达州的拉姆齐县的首席信息官。

---

via: <http://www.linuxjournal.com/content/getting-started-ncurses>

作者：[Jim Hall](http://www.linuxjournal.com/users/jim-hall) 译者：[leemeans](https://github.com/leemeans) 校对：[wxy](https://github.com/wxy)

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


TLP 帮助我们的 Linux 机器节能省电

Summary: TLP - Linux 高级电源管理 是一个小巧的命令行工具，它通过对 Linux 系统执行一些调整来真正帮助延长电池的使用寿命。

我想问一下tlp和acpid冲突吗<br />
以及他们有什么关系吗

![](/data/attachment/album/201802/15/092727g08uuxsxz6exn0ll.jpg)

我发现 Linux 下电池的寿命普遍要比 Windows 下要短。尽管如此，这可是 Linux，我们总会有有办法的。

现在来讲一下这个名叫 TLP 的小工具，它能帮你的设备省点电。

**TLP - Linux 高级电源管理** 是一个小巧的命令行工具，它通过对 Linux 系统执行一些调整来真正帮助延长电池的使用寿命。

```
sudo apt install tlp

```

[![install tlp in linux](/data/attachment/album/201802/15/092728neii3i4fwmbbiukw.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/install-tlp-in-linux.jpeg)

对于其他的发行版，你可以阅读其[官方网站](http://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html)上的指南。

安装完成之后，你只有在第一次的时候需要运行下面命令来启动 tlp。TLP 会在下次启动系统时自动运行。

[![start tlp on linux](/data/attachment/album/201802/15/092728se660iub3bjtife0.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/start-tlp-on-linux.jpeg)

现在 TLP 已经被启动起来了，而且已经设置好了节省电池所需要的默认配置。我们可以查看该配置文件。文件路径为 `/etc/default/tlp`。我们需要编辑该文件来修改各项配置。

配置文件中有很多选项，要启用某个选项的话只需要删除行首的 `#` 就行了。每个选项能够赋予什么值都有说明。下面是你可能会用到的选项：

* 自动休眠 USB 设备
* 设定启动时启用/禁用无线设备
* 降低硬盘转速
* 关闭无线设备
* 设置 CPU 以性能优先还是节能优先

### 结论

TLP 是一个超棒的工具，可以延长 Linux 系统的电池使用寿命。我个人的经验是使用 TLP 能延长至少 30-40% 的电池使用寿命。

---

via: <http://www.linuxandubuntu.com/home/save-some-battery-on-our-linux-machines-with-tlp>

作者：[LinuxAndUbuntu](http://www.linuxandubuntu.com) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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