四个 Linux 上的网络信息嗅探工具

Summary: 在计算机网络中，数据是暴露的，因为数据包传输是无法隐藏的

在计算机网络中，数据是暴露的，因为数据包传输是无法隐藏的

# 四个 Linux 上的网络信息嗅探工具

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

在计算机网络中，数据是暴露的，因为数据包传输是无法隐藏的，所以让我们来使用 `whois`、`dig`、`nmcli` 和 `nmap` 这四个工具来嗅探网络吧。

请注意，不要在不属于自己的网络上运行 `nmap` ，因为这有可能会被其他人认为恶意攻击。

### 精简和详细域名信息查询

您可能已经注意到，之前我们用常用的老式 `whois` 命令查询域名信息，但现如今似乎没有提供同过去一样的详细程度。我们使用该命令查询 linux.com 的域名描述信息：

```
$ whois linux.com
Domain Name: LINUX.COM
Registry Domain ID: 4245540_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.namecheap.com
Registrar URL: http://www.namecheap.com
Updated Date: 2018-01-10T12:26:50Z
Creation Date: 1994-06-02T04:00:00Z
Registry Expiry Date: 2018-06-01T04:00:00Z
Registrar: NameCheap Inc.
Registrar IANA ID: 1068
Registrar Abuse Contact Email: abuse@namecheap.com
Registrar Abuse Contact Phone: +1.6613102107
Domain Status: ok https://icann.org/epp#ok
Name Server: NS5.DNSMADEEASY.COM
Name Server: NS6.DNSMADEEASY.COM
Name Server: NS7.DNSMADEEASY.COM
DNSSEC: unsigned
[...]

```

有很多令人讨厌的法律声明。但在哪有联系信息呢？该网站位于 `whois.namecheap.com` 站点上（见上面输出的第三行）：

```
$ whois -h whois.namecheap.com linux.com

```

我就不复制出来了，因为这实在太长了，包含了注册人，管理员和技术人员的联系信息。怎么回事啊，露西尔？（LCTT 译注：《行尸走肉》中尼根的棒子）有一些注册库，比如 .com 和 .net 是精简注册库，保存了一部分有限的域名信息。为了获取完整信息请使用 `-h` 或 `--host` 参数，该参数便会从域名的 `注册服务机构` 中获取。

大部分顶级域名是有详细的注册信息，如 .info。试着使用 `whois blockchain.info` 命令来查看。

想要摆脱这些烦人的法律声明？使用 `-H` 参数。

### DNS 解析

使用 `dig` 命令比较从不同的域名服务器返回的查询结果，去除陈旧的信息。域名服务器记录缓存各地的解析信息，并且不同的域名服务器有不同的刷新间隔。以下是一个简单的用法：

```
$ dig linux.com
<<>> DiG 9.10.3-P4-Ubuntu <<>> linux.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<<- opcode: QUERY, status: NOERROR, id: 13694
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1440
;; QUESTION SECTION:
;linux.com. IN A

;; ANSWER SECTION:
linux.com. 10800 IN A 151.101.129.5
linux.com. 10800 IN A 151.101.65.5
linux.com. 10800 IN A 151.101.1.5
linux.com. 10800 IN A 151.101.193.5

;; Query time: 92 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Tue Jan 16 15:17:04 PST 2018
;; MSG SIZE rcvd: 102

```

注意下靠近末尾的这行信息：`SERVER: 127.0.1.1#53(127.0.1.1)`，这是您默认的缓存解析器。当地址是本地时，就表明您的电脑上安装了 DNS 服务。在我看来这就是一个 Dnsmasq 工具（LCTT 译注：是一个小巧且方便地用于配置 DNS 和 DHCP 的工具），该工具被用作网络管理：

```
$ ps ax|grep dnsmasq
2842 ? S 0:00 /usr/sbin/dnsmasq --no-resolv --keep-in-foreground
--no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid
--listen-address=127.0.1.1

```

`dig` 命令默认是返回 A 记录，也就是域名。IPv6 则有 AAAA 记录：

```
$ $ dig linux.com AAAA
[...]
;; ANSWER SECTION:
linux.com. 60 IN AAAA 64:ff9b::9765:105
linux.com. 60 IN AAAA 64:ff9b::9765:4105
linux.com. 60 IN AAAA 64:ff9b::9765:8105
linux.com. 60 IN AAAA 64:ff9b::9765:c105
[...]

```

仔细检查下，发现 linux.com 有 IPv6 地址。很好！如果您的网络服务支持 IPv6 那么您就可以用 IPv6 连接。（令人难过的是，我的移动宽带则没提供 IPv6）

假设您能对您的域名做一些 DNS 改变，又或是您使用 `dig` 查询的结果有误。试着用一个公共 DNS，如 OpenNIC：

```
$ dig @69.195.152.204 linux.com
[...]
;; Query time: 231 msec
;; SERVER: 69.195.152.204#53(69.195.152.204)

```

`dig` 回应您正在的查询是来自 69.195.152.204。您可以查询各种服务并且比较结果。

### 上游域名服务器

我想知道我的上游域名服务器（LCTT 译注：此处指解析器）是谁。为了查询，我首先看下 `/etc/resolv/conf` 的配置信息:

```
$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1

```

好吧，不过我已经知道了。您的 Linux 发行版可能配置不同，您会看到您的上游服务器。接下来我们来试试网络管理器命令行工具 `nmcli`：

```
$ nmcli dev show | grep DNS
IP4.DNS[1]: 192.168.1.1

```

很好，现在我们已经知道了，其实那是我的移动热点，我能确认。我能够登录到简易管理面板，来查询上游服务器。然而许多用户级互联网网关不会让您看到或改变这些设置，因此只能尝试其他的方法，如 [我的域名服务器是什么？](http://www.whatsmydnsserver.com/)

### 查找在您的网络中 IPv4 地址

您的网络上有哪些 IPv4 地址已启用并正在使用中？

```
$ nmap -sn 192.168.1.0/24
Starting Nmap 7.01 ( https://nmap.org ) at 2018-01-14 14:03 PST
Nmap scan report for Mobile.Hotspot (192.168.1.1)
Host is up (0.011s latency).
Nmap scan report for studio (192.168.1.2)
Host is up (0.000071s latency).
Nmap scan report for nellybly (192.168.1.3)
Host is up (0.015s latency)
Nmap done: 256 IP addresses (2 hosts up) scanned in 2.23 seconds

```

每个人都想去扫描自己的局域网中开放的端口。下面的例子是寻找服务和他们的版本号：

```
$ nmap -sV 192.168.1.1/24

Starting Nmap 7.01 ( https://nmap.org ) at 2018-01-14 16:46 PST
Nmap scan report for Mobile.Hotspot (192.168.1.1)
Host is up (0.0071s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp filtered ssh
53/tcp open domain dnsmasq 2.55
80/tcp open http GoAhead WebServer 2.5.0

Nmap scan report for studio (192.168.1.102)
Host is up (0.000087s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
631/tcp open ipp CUPS 2.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 256 IP addresses (2 hosts up) scanned in 11.65 seconds

```

这些是有趣的结果。让我们尝试从不同的互联网连接进行相同的操作，以查看这些服务是否暴露于互联网中。如果您有智能手机，相当于您有第二个网络。您可以下载应用程序，还可以为您的 Linux 电脑提供热点。从热点控制面板获取广域网IP地址，然后重试：

```
$ nmap -sV 12.34.56.78

Starting Nmap 7.01 ( https://nmap.org ) at 2018-01-14 17:05 PST
Nmap scan report for 12.34.56.78
Host is up (0.0061s latency).
All 1000 scanned ports on 12.34.56.78 are closed

```

果然不出所料，结果和我想象的一样（LCTT 译注：这些服务和信息没有被暴露在公网上）。可以用手册来查询这些命令，以便了解更多有趣的嗅探技术。

了解更多 Linux 的相关知识可以从 Linux 基金会和 edX（LCTT译注：edX 是麻省理工和哈佛大学于 2012 年 4 月联手创建的大规模开放在线课堂平台）中获取免费的 [“介绍 Linux”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux)课程。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/1/4-tools-network-snooping-linux>

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

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


如何在 Linux 中安装 Ncurses 库

Summary: GNU Ncurses 是一个允许用户编写基于文本的用户界面（TUI）的编程库。许多基于文本的游戏都是使用这个库创建的。

# 如何在 Linux 中安装 Ncurses 库

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

**GNU Ncurses** 是一个允许用户编写基于文本的用户界面（TUI）的编程库。许多基于文本的游戏都是使用这个库创建的。一个受欢迎的例子是 [PacVim](https://www.ostechnix.com/pacvim-a-cli-game-to-learn-vim-commands/)，这是一款学习 VIM 命令的 CLI 游戏。在这篇简要的指南中，我将解释如何在类 Unix 操作系统中安装 Ncurses 库。

### 在 Linux 中安装 Ncurses 库

Ncurses 在大多数 Linux 发行版的默认仓库中都有。例如，你可以使用以下命令将其安装在基于 Arch 的系统上：

```
$ sudo pacman -S ncurses

```

在RHEL、CentOS 上：

```
$ sudo yum install ncurses-devel

```

在 Fedora 22 和更新版本上：

```
$ sudo dnf install ncurses-devel

```

在 Debian、Ubuntu、Linux Mint 上：

```
$ sudo apt-get install libncurses5-dev libncursesw5-dev

```

默认仓库中的 GNU ncureses 可能有点老了。如果你想要最新的稳定版本，可以从源代码进行编译和安装，如下所示。

从[这里](https://ftp.gnu.org/pub/gnu/ncurses/)下载最新的 ncurses 版本。在写这篇文章时，最新版本是 6.1。

```
$ wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz

```

解压 tar 文件：

```
$ tar xzf ncurses-6.1.tar.gz

```

这将在当前目录中创建一个名为 ncurses-6.1 的文件夹。cd 到该目录：

```
$ cd ncurses-6.1
$ ./configure --prefix=/opt/ncurses

```

最后，使用以下命令进行编译和安装：

```
$ make
$ sudo make install

```

使用命令验证安装：

```
$ ls -la /opt/ncurses

```

就是这样。Ncurses 已经安装在 Linux 发行版上。继续使用 Ncurses 创建漂亮的 TUI。

还会有更多的好东西。敬请关注！

干杯!

---

via: <https://www.ostechnix.com/how-to-install-ncurses-library-in-linux/>

作者：[SK](https://www.ostechnix.com/author/sk/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


你应该知道关于 Ubuntu 18.04 的一些事

# 你应该知道关于 Ubuntu 18.04 的一些事

[Ubuntu 18.04 版本](/article-9583-1.html) 已经到来。我可以在各种 Facebook 群组和论坛中看到许多来自 Ubuntu 用户的提问。我还在 Facebook 和 Instagram 上组织了 Q&A 会议，以了解 Ubuntu 用户对 Ubuntu 18.04 的想法。

我试图在这里回答关于 Ubuntu 18.04 的常见问题。如果您有任何疑问，我希望这能帮助您解决疑问。如果您仍有问题，请随时在下面的评论区提问。

### Ubuntu 18.04 中有什么值得期待

解释一下，这里的一些问答会受到我个人的影响。如果您是一位经验丰富或了解 Ubuntu 的用户，其中一些问题可能对您而言很简单。如果是这样的话，就请忽略这些问题。

#### 我能够在 Ubuntu 18.04 中安装 Unity 吗？

当然能够哦！

Canonical 公司知道有些人喜欢 Unity。这就是为什么它已经在 Universe 软件库（LCTT译者注：社区维护的软件库）中提供了 Unity 7。但这是一个社区维护版，官方并不直接参与开发。

不过我建议是使用默认的 GNOME，除非您真的无法容忍它，再在 [Ubuntu 18.04 上安装 Unity](https://itsfoss.com/use-unity-ubuntu-17-10/)。

#### GNOME 是什么版本？

在这次发行的 Ubuntu 18.04 版本中，GNOME 版本号是 3.28。

#### 我能够安装原装的 GNOME 吗？

当然没问题！

因为存在一些 GNOME 用户可能不喜欢 Ubuntu 18.04 中的 Unity 风格。在 Ubuntu 中的 main（LCTT译者注：官方支持的软件库）和 universe 软件库有安装包可安装，能使您在 [Ubuntu 18.04 中安装原装的 GNOME](https://itsfoss.com/vanilla-gnome-ubuntu/)。

#### GNOME 中的内存泄漏已修复了吗？

已经修复了。[GNOME 3.28 中臭名昭着的内存泄漏](https://feaneron.com/2018/04/20/the-infamous-gnome-shell-memory-leak/) 已经被修复了，并且 [Ubuntu 官方已经在测试这个修复程序](https://community.ubuntu.com/t/help-test-memory-leak-fixes-in-18-04-lts/5251)。

澄清一点，内存泄漏不是由 Ubuntu 系统引起的。它影响了所有使用 GNOME 3.28 的 Linux 发行版。GNOME 3.28.1 发布了一个新的补丁修复内存泄漏问题。

#### Ubuntu 18.04 将会被支持多久？

这是一个长期支持（LTS）版本，与任何 LTS 版本一样，官方会支持五年。这意味着 Ubuntu 18.04 将在 2023 年 4 月之前能获得安全和维护更新。这对于除 Ubuntu Studio 之外的所有基于 Ubuntu 的 Linux 发行版也一样。

#### Ubuntu 18.04 什么时候发布的？

Ubuntu 18.04 LTS 在 4 月 26 日发布。 所有基于 Ubuntu 的 Linux 发行版，如 Kubuntu、Lubuntu、Xubuntu、Budgie、MATE 等都会在同一天发布其 18.04 版本。

不过 [Ubuntu Studio 不会有 18.04 的 LTS 版本](https://www.omgubuntu.co.uk/2018/04/ubuntu-studio-plans-to-reboot)。

#### 是否能从 16.04/17.10 升级到 Ubuntu 18.04？我可以从使用 Unity 的 Ubuntu 16.04 升级到使用 GNOME 的 Ubuntu 18.04 吗？

绝对没问题。当 Ubuntu 18.04 LTS 发布后，您可以很容易的升级到最新版。

如果您使用的是 Ubuntu 17.10，请确保在“软件和更新”->“更新”中，将“有新版本时通知我”设置为“适用任何新版本”。

如果您使用的是 Ubuntu 16.04，请确保在“软件和更新”->“更新”中，将“有新版本时通知我”设置为“适用长期支持版本”。

然后您应该能获得有关新版本更新的系统通知。之后，升级到 Ubuntu 18.04 只需要点击几下鼠标而已。

即使 Ubuntu 16.04 使用的是 Unity，但您仍然可以 [升级到使用 GNOME 的 Ubuntu 18.04](https://itsfoss.com/upgrade-ubuntu-version/)。

#### 升级到 Ubuntu 18.04 意味着什么？我会丢失数据吗？

如果您使用的是 Ubuntu 17.10 或 Ubuntu 16.04，系统会提示您可升级到 Ubuntu 18.04。如果您从互联网上下载 1.5 Gb 的数据不成问题，则只需点击几下鼠标，即可在 30 分钟内升级到 Ubuntu 18.04。

您不需要通过 U 盘来重装系统。升级过程完成后，您将可以使用新的 Ubuntu 版本。

通常，您的数据和文档等在升级过程中是安全的。但是，对重要文档进行备份始终是一个好的习惯。

#### 我什么时候能升级到 Ubuntu 18.04？

如果您使用的是 Ubuntu 17.10 并且正确设置（设置方法在之前提到的问题中），那么在 Ubuntu 18.04 发布的几天内应该会通知您升级到 Ubuntu 18.04。为避免 Ubuntu 服务器在发布时的负载量过大，因此不是每个人都会在同一天收到升级提示。

对于 Ubuntu 16.04 用户，可能需要几周时间才能正式收到 Ubuntu 18.04 升级提示。通常，这将在第一次发布 Ubuntu 18.04.1 之后提示。该版本修复了 18.04 中发现的新 bug。

#### 如果我升级到 Ubuntu 18.04，我可以降级到 17.10/16.04？

抱歉，并不行。尽管升级到新版本很容易，但没有降级的选项。如果您想回到 Ubuntu 16.04，只能重新安装。

#### 我能使用 Ubuntu 18.04 在 32 位系统上吗？

可以，但最好不要这样做。

如果您已经在使用 32 位版本的 Ubuntu 16.04 或 17.10，您依旧可以升级到 Ubuntu 18.04。 但是，您找到不到 32 位的 Ubuntu 18.04 ISO 镜像。换句话说，您无法安装 32 位版本的 Ubuntu 18.04。

有一个好消息是，Ubuntu MATE、Lubuntu 等其他官方版本仍然具有其新版本的 32 位 ISO 镜像。

无论如何，如果您使用一个 32 位系统，那么很可能您的计算机硬件性能过低。在这样的电脑上使用轻量级 [Ubuntu MATE](https://ubuntu-mate.org/) 或 [Lubuntu](https://lubuntu.net/) 系统会更好。

#### 我可以在哪下载 Ubuntu 18.04？

18.04 已经发布了，您可以从其网站获得 Ubuntu 18.04 的 ISO 镜像。您既可以直接官网下载，也能用种子下载。其他官方版本将在其官方网站上提供下载。

#### 我应该重新安装 Ubuntu 18.04 还是从 16.04/17.10 升级上来？

如果您有重新安装的机会，建议备份您的数据并重新安装 Ubuntu 18.04。

从现有版本升级到 18.04 是一个方便的选择。不过，就我个人而言，它仍然保留了旧版本的依赖包。重新安装还是比较干净。

#### 对于重新安装来说，我应该安装 Ubuntu 16.04 还是 Ubuntu 18.04？

如果您要在计算机上安装 Ubuntu，请尽量使用 Ubuntu 18.04 而不是 16.04。

他们都是长期支持版本，并被支持很长一段时间。Ubuntu 16.04 会获得维护和安全更新服务直到 2021 年，而 18.04 则会到 2023 年。

不过，我建议您使用 Ubuntu 18.04。任何 LTS 版本都会在 [一段时间内获得硬件更新支持](https://www.ubuntu.com/info/release-end-of-life)（我认为是两年半的时间内）。之后，它只获得维护更新。如果您有更新的硬件，您将在 18.04 获得更好的支持。

此外，许多应用程序开发人员将很快开始关注 Ubuntu 18.04。新创建的 PPA 可能仅在几个月内支持 18.04。所以使用 18.04 比 16.04 更好。

#### 安装打印机-扫描仪驱动程序比使用 CLI 安装会更容易吗？

在打印机方面，我不是专家，所以我的观点是基于我在这方面有限的知识。大多数新打印机都支持 [IPP协议](https://www.pwg.org/ipp/everywhere.html)，因此它们应该在 Ubuntu 18.04 中能够获到很好的支持。 然而对较旧的打印机我则无法保证。

#### Ubuntu 18.04 是否对 Realtek 和其他 WiFi 适配器有更好的支持？

抱歉，没有关于这部分的具体信息。

#### Ubuntu 18.04 的系统要求？

对于默认的 GNOME 版本，最好您应该有 [4 GB 的内存以便正常使用](https://help.ubuntu.com/community/Installation/SystemRequirements)。使用过去 8 年中发布的处理器也可以运行。但任何比这性能更差的硬件建议使用 [轻量级 Linux 发行版](https://itsfoss.com/lightweight-linux-beginners/)，例如 [Lubuntu](https://lubuntu.net/)。

#### 有关 Ubuntu 18.04 的其问题？

如果还有其他疑问，请随时在下方评论区留言。如果您认为应将其他信息添加到列表中，请告诉我。

（LCTT 译注：本文原文写于 Ubuntu 18.04 LTS 发布之前，译文翻译于发布之后，因此对部分内容做了修改。）

---

via: <https://itsfoss.com/ubuntu-18-04-faq/>

作者：[Abhishek Prakash](http://itsfoss.com/author/abhishek/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wyxplus](https://github.com/wyxplus) 校对：[wxy](https://github.com/wxy)

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


微服务 vs. 整体服务：如何选择

Summary: 任何一种架构都是有利有弊的，而能满足你组织的独特需要的决策才是正确的选择。

任何一种架构都是有利有弊的，而能满足你组织的独特需要的决策才是正确的选择。

# 微服务 vs. 整体服务：如何选择

>
> 任何一种架构都是有利有弊的，而能满足你组织的独特需要的决策才是正确的选择。
>
>
>

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

对于许多初创公司来说，传统的知识认为，从单一整体架构开始，而不是使用微服务。但是，我们还有别的选择吗？

这本新书 —— 《[初创公司的微服务](https://buttercms.com/books/microservices-for-startups/)》，从许多 CIO 们理解的微服务的角度，解释了微服务的优点与缺点。

对于初创公司，虽然不同的 CTO 对此给出的建议是不同的，但是他们都一致认为环境和性能很重要。如果你正考虑你的业务到底是采用微服务还是单一整体架构更好，下面讨论的这些因素正好可以为你提供一些参考。

### 理解范围

首先，我们先来准确定义我们所谓的 “整体服务” 和 “微服务” 是什么。

微服务是一种方法，它开发一个单一的应用程序来作为构成整体服务的小服务，每个小服务都运行在它自己的进程中，并且使用一个轻量级的机制进行通讯，通常是一个 HTTP 资源的 API。这些服务都围绕业务能力来构建，并且可依赖全自动部署机制来独立部署。

一个整体应用程序是按单个的、统一的单元来构建，并且，通常情况下它是基于一个大量的代码来实现的。一般来说，一个整体服务是由三部分组成的：数据库、客户端用户界面（由 HTML 页面和/或运行在浏览器中的 JavaScript 组成）、以及服务器端应用程序。

“系统架构处于一个范围之中”，Zachary Crockett，[Particle](https://www.particle.io/Particle) 的 CTO，在一次访谈中，他说，“在讨论微服务时，人们倾向于关注这个范围的一端：许多极小的应用程序给其它应用程序传递了过多的信息。在另一端，有一个巨大的整体服务做了太多的事情。在任何现实中的系统上，在这两个极端之间有很多合适的面向服务的架构”。

根据你的情况不同，不论是使用整体服务还是微服务都有很多很好的理由。

“我们希望为每个服务使用最好的工具”，Julien Lemoine 说，他是 Algolia 的 CTO。

与很多人的想法正好相反，整体服务并不是过去遗留下来的过时的架构。在某些情况下，整体服务是非常理想的。我采访了 Steven Czerwinski 之后，更好地理解了这一点，他是 [Scaylr](https://www.scalyr.com/) 的工程主管，前谷歌员工。

“尽管我们在谷歌时有使用微服务的一些好的经验，我们现在 [在 Scalyr] 却使用的是整体服务的架构，因为一个整体服务架构意味着我们的工作量更少，我们只有两位工程师。“ 他解释说。（采访他时，Scaylr 正处于早期阶段）

但是，如果你的团队使用微服务的经验很丰富，并且你对你们的发展方向有明确的想法，微服务可能是一个很好的替代者。

Julien Lemoine，[Algolia](https://www.algolia.com/) 的 CTO，在这个问题上，他认为：“我们通常从使用微服务开始，主要目的是我们可以使用不同的技术来构建我们的服务，因为如下的两个主要原因：

* 我们想为每个服务使用最好的工具。我们的搜索 API 是在底层做过高度优化的，而 C++ 是非常适合这项工作的。他说，在任何其它地方都使用 C++ 是一种生产力的浪费，尤其是在构建仪表板方面。
* 我们希望使用最好的人才，而只使用一种技术将极大地限制我们的选择。这就是为什么在公司中有不同语言的原因。

”

如果你的团队已经准备好从一开始就使用微服务，这样你的组织从一开始就可以适应微服务环境的开发节奏。

### 权衡利弊

在你决定那种方法更适合你的组织之前，考虑清楚每种方法的优缺点是非常重要的。

### 整体服务

#### 优点：

* **很少担心横向联系：** 大多数应用程序开发者都担心横向联系，比如，日志、速度限制、以及像审计跟踪和 DoS 防护这样的安全特性。当所有的东西都运行在同一个应用程序中时，通过组件钩子来处理这些关注点就非常容易了。
* **运营开销很少：** 只需要为一个应用程序设置日志、监视、以及测试。一般情况下，部署也相对要简单。
* **性能：** 一个整体的架构可能会有更好的性能，因为共享内存的访问速度要比进程间通讯（IPC）更快。

#### 缺点：

* **紧耦合：** 整体服务的应用程序倾向于紧耦合，并且应用程序是整体进化的，分离特定用途的服务是非常困难的，比如，独立扩展或者代码维护。
* **理解起来很困难：** 当你想查看一个特定的服务或者控制器时，因为依赖、副作用、和其它的不可预见因素，整体架构理解起来更困难。

### 微服务

#### 优点：

* **非常好组织：** 微服务架构一般很好组织它们，因为每个微服务都有一个特定的工作，并且还不用考虑其它组件的工作。
* **解耦合：** 解耦合的服务是能够非常容易地进行重组织和重配置，以服务于不同的应用程序（比如，同时向 Web 客户端和公共 API 提供服务）。它们在一个大的集成系统中，也允许快速、独立分发单个部分。
* **性能：** 根据组织的情况，微服务可以提供更好的性能，因为你可以分离热点服务，并根据其余应用程序的情况来扩展它们。
* **更少的错误：** 微服务允许系统中的不同部分，在维护良好边界的前提下进行并行开发。这样将使连接不该被连接的部分变得更困难，比如，需要连接的那些紧耦合部分。

#### 缺点：

* **跨每个服务的横向联系点：** 由于你构建了一个新的微服务架构，你可能会发现在设计时没有预料到的很多横向联系的问题。这也将导致需要每个横向联系点的独立模块（比如，测试）的开销增加，或者在其它服务层面因封装横向联系点，所导致的所有流量都需要路由。最终，即便是整体服务架构也倾向于通过横向联系点的外部服务层来路由流量，但是，如果使用整体架构，在项目更加成熟之前，也不过只是推迟了工作成本。
* **更高的运营开销：** 微服务在它所属的虚拟机或容器上部署非常频繁，导致虚拟机争用激增。这些任务都是使用容器管理工具进行频繁的自动化部署的。

### 决策时刻

当你了解了每种方法的利弊之后，如何在你的初创公司使用这些信息？通过与这些 CTO 们的访谈，这里有三个问题可以指导你的决策过程：

**你是在熟悉的领域吗？**

如果你的团队有以前的一些领域的经验（比如，电子商务）和了解你的客户需求，那么分割成微服务是低风险的。如果你从未做过这些，从另一个角度说，整体服务或许是一个更安全的选择。

**你的团队做好准备了吗？**

你的团队有使用微服务的经验吗？如果明年，你的团队扩充到现在的四倍，将为微服务提供更好的环境？评估团队大小对项目的成功是非常重要的。

**你的基础设施怎么样？**

实施微服务，你需要基于云的基础设施。

David Strauss，[Pantheon](https://pantheon.io/) 的 CTO，他解释说："[以前]，你使用整体服务是因为，你希望部署在一个数据库上。每个单个的微服务都需要配置数据库服务器，然后，扩展它将是一个很重大的任务。只有大的、技术力量雄厚的组织才能做到。现在，使用像谷歌云和亚马逊 AWS 这样的云服务，为部署一个小的东西而不需要为它们中的每个都提供持久存储，对于这种需求你有很多的选择。“

### 评估业务风险

技术力量雄厚的初创公司为追求较高的目标，可以考虑使用微服务。但是微服务可能会带来业务风险。Strauss 解释说，“许多团队一开始就过度构建他们的项目。每个人都认为，他们的公司会成为下一个 ‘独角兽’，因此，他们使用微服务构建任何一个东西，或者一些其它的高扩展性的基础设施。但是这通常是一种错误的做法”。Strauss 说，在那种情况下，他们认为需要扩大规模的领域往往并不是一开始真正需要扩展的领域，最后的结果是浪费了时间和努力。

### 态势感知

最终，环境是关键。以下是一些来自 CTO 们的提示：

#### 什么时候使用整体服务

* **你的团队还在创建阶段：** 你的团队很小 —— 也就是说，有 2 到 5 位成员 —— 还无法应对大范围、高成本的微服务架构。
* **你正在构建的是一个未经证实的产品或者概念验证：** 如果你将一个全新的产品推向市场，随着时间的推移，它有可能会成功，而对于一个快速迭代的产品，整体架构是最合适的。这个提示也同样适用于概念验证，你的目标是尽可能快地学习，即便最终你可能会放弃它。
* **你没有使用微服务的经验：** 除非你有合理的理由证明早期学习阶段的风险可控，否则，一个整体的架构更适用于一个没有经验的团队。

#### 什么时候开始使用微服务

* **你需要快速、独立的分发服务：** 微服务允许在一个大的集成系统中快速、独立分发单个部分。请注意，根据你的团队规模，获取与整体服务的比较优势，可能需要一些时间。
* **你的平台中的某些部分需要更高效：** 如果你的业务要求集中处理 PB 级别的日志卷，你可能需要使用一个像 C++ 这样的更高效的语言来构建这个服务，尽管你的用户仪表板或许还是用 [Ruby on Rails](http://rubyonrails.org/) 构建的。
* **计划扩展你的团队：** 使用微服务，将让你的团队从一开始就开发独立的小服务，而服务边界独立的团队更易于按需扩展。

要决定整体服务还是微服务更适合你的组织，要坦诚并正确认识自己的环境和能力。这将有助于你找到业务成长的最佳路径。

### 关于作者

jakelumetta - Jake 是 ButterCMS 的 CEO，它是一个 [API-first CMS](https://buttercms.com/)。他喜欢搅动出黄油双峰，以及构建让开发者工作更舒适的工具，喜欢他的更多内容，请在 Twitter 上关注 [@ButterCMS](https://twitter.com/ButterCMS)，订阅 [他的博客](https://buttercms.com/blog/)。[关于他的更多信息](https://opensource.com/users/jakelumetta)……

---

via: <https://opensource.com/article/18/1/how-choose-between-monolith-microservices>

作者：[jakelumetta](https://opensource.com/users/jakelumetta)  译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


如何在无响应的 Linux 系统中杀掉内存消耗最大的进程

# 如何在无响应的 Linux 系统中杀掉内存消耗最大的进程

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

作为一名博客作者，我收藏了很多博客、网站和论坛用来寻找 Linux 和 Unix 相关的内容。有时候，我在浏览器中开启了非常多的标签页，导致操作系统会无响应好几分钟。我不能移动我的鼠标，也不能杀掉一个进程或关闭任何开启的标签页。在这种情况下，我别无选择，只能强制重启系统。当然我也用了 **OneTab** （LCTT 译注：OneTab 是一个 Chrome 的 Extension，可以将标签页转化成一个列表保存。）和 **Greate Suspender** （LCTT 译注：Great Suspender 是一个 Chrome 的 Extension， 可以自动冻结标签页）这样浏览器拓展，但它们在这里也起不到太大的作用。 我经常耗尽我的内存。而这就是 **Early OOM** 起作用的时候了。在情况严重时，它会杀掉一个未响应系统中的内存消耗最大的进程。Early OOM 每秒会检测可用内存和空余交换区 10 次，一旦两者都低于 10%，它就会把最大的进程杀死。

### 为什么用 Early OOM？为什么不用系统内置的 OOM killer？

在继续讨论下去之前，我想先简短的介绍下 OOM killer，也就是 **O**ut **O**f **M**emory killer。OOM killer 是一个由内核在可用内存非常低的时候使用的进程。它的主要任务是不断的杀死进程，直到释放出足够的内存，使内核正在运行的其它进程能顺利运行。OOM killer 会找到系统中最不重要并且能释放出最多内存的进程，然后杀掉他们。在 `/proc` 目录下的 `pid` 目录中，我们可以看到每个进程的 `oom_score`。

示例：

```
$ cat /proc/10299/oom_score
1

```

一个进程的 `oom_score` 的值越高，这个进程越有可能在系统内存耗尽的时候被 OOM killer 杀死。

Early OOM 的开发者表示，相对于内置的 OOM killer，Early OOM 有一个很大的优点。就像我之前说的那样，OOM killer 会杀掉 `oom_score` 最高的进程，而这也导致 Chrome 浏览器总是会成为第一个被杀死的进程。为了避免这种情况发生，Early OOM 使用 `/proc/*/status` 而不是 `echo f > /proc/sysrq-trigger`（LCTT 译注：这条命令会调用 OOM killer 杀死进程）。开发者还表示，手动触发 OOM killer 在最新版本的 Linux 内核中很可能不会起作用。

### 安装 Early OOM

Early OOM 在 AUR（Arch User Repository）中可以找到，所以你可以在 Arch 和它的衍生版本中使用任何 AUR 工具安装它。

使用 [Pacaur](https://www.ostechnix.com/install-pacaur-arch-linux/)：

```
pacaur -S earlyoom

```

使用 [Packer](https://www.ostechnix.com/install-packer-arch-linux-2/)：

```
packer -S earlyoom

```

使用 [Yaourt](https://www.ostechnix.com/install-yaourt-arch-linux/)：

```
yaourt -S earlyoom

```

启用并启动 Early OOM 守护进程：

```
sudo systemctl enable earlyoom
sudo systemctl start earlyoom

```

在其它的 Linux 发行版中，可以按如下方法编译安装它：

```
git clone https://github.com/rfjakob/earlyoom.git
cd earlyoom
make
sudo make install

```

### Early OOM - 杀掉无响应 Linux 系统中的最大的进程

运行如下命令启动 Early OOM：

```
earlyoom

```

如果是通过编译源代码安装的， 运行如下命令启动 Early OOM：

```
./earlyoom

```

示例输出：

```
earlyoom 0.12
mem total: 3863 MiB, min: 386 MiB (10 %)
swap total: 2047 MiB, min: 204 MiB (10 %)
mem avail: 1770 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1771 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1784 MiB (46 %), swap free: 2047 MiB (99 %)
[...]

```

就像你在上面的输出中可以看到的，Early OOM 将会显示你有多少内存和交换区，以及有多少可用的内存和交换区。记住它会一直保持运行，直到你按下 `CTRL+C`。

如果可用的内存和交换区大小都低于 10%，Early OOM 将会自动杀死最大的进程，直到系统有足够的内存可以流畅的运行。你也可以根据你的需求配置最小百分比值。

设置最小的可用内存百分比，运行：

```
earlyoom -m <PERCENT_HERE>

```

设置最小可用交换区百分比, 运行：

```
earlyoom -s <PERCENT_HERE>

```

在帮助部分，可以看到更多详细信息：

```
$ earlyoom -h
earlyoom 0.12
Usage: earlyoom [OPTION]...

 -m PERCENT set available memory minimum to PERCENT of total (default 10 %)
 -s PERCENT set free swap minimum to PERCENT of total (default 10 %)
 -M SIZE set available memory minimum to SIZE KiB
 -S SIZE set free swap minimum to SIZE KiB
 -k use kernel oom killer instead of own user-space implementation
 -i user-space oom killer should ignore positive oom_score_adj values
 -d enable debugging messages
 -v print version information and exit
 -r INTERVAL memory report interval in seconds (default 1), set to 0 to
 disable completely
 -p set niceness of earlyoom to -20 and oom_score_adj to -1000
 -h this help text

```

现在，你再也不用担心内存消耗最高的进程了。希望这能给你帮助。更多的好内容将会到来，敬请期待。

谢谢！

---

via: <https://www.ostechnix.com/kill-largest-process-unresponsive-linux-system/>

作者：[Aditya Goturu](https://www.ostechnix.com) 译者：[cizezsy](https://github.com/cizezsy) 校对：[wxy](https://github.com/wxy)

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


/dev/[u]random：对熵的解释

Summary: 当谈到 /dev/random 和 /dev/urandom 的主题时，你总是会听到这个词：“熵（Entropy）”。

# /dev/[u]random：对熵的解释

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

### 熵

当谈到 `/dev/random` 和 `/dev/urandom` 的主题时，你总是会听到这个词：“<ruby> 熵 <rt>  Entropy </rt></ruby>”。每个人对此似乎都有自己的比喻。那为我呢？我喜欢将熵视为“随机果汁”。它是果汁，随机数需要它变得更随机。

如果你曾经生成过 SSL 证书或 GPG 密钥，那么可能已经看到过像下面这样的内容：

```
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
++++++++++..+++++.+++++++++++++++.++++++++++...+++++++++++++++...++++++
+++++++++++++++++++++++++++++.+++++..+++++.+++++.+++++++++++++++++++++++++>.
++++++++++>+++++...........................................................+++++
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 290 more bytes)

```

通过在键盘上打字并移动鼠标，你可以帮助生成熵或随机果汁。

你可能会问自己……为什么我需要熵？以及为什么它对于随机数真的变得随机如此重要？那么，假设我们的熵的来源仅限于键盘、鼠标和磁盘 IO 的数据。但是我们的系统是一个服务器，所以我知道没有鼠标和键盘输入。这意味着唯一的因素是你的 IO。如果它是一个单独的、几乎不使用的磁盘，你将拥有较低的熵。这意味着你的系统随机的能力很弱。换句话说，我可以玩概率游戏，并大幅减少破解 ssh 密钥或者解密你认为是加密会话的时间。

好的，但这是很难实现的对吧？不，实际上并非如此。看看这个 [Debian OpenSSH 漏洞](http://jhurani.com/linux/2017/11/01/%22https://jblevins.org/log/ssh-vulnkey%22)。这个特定的问题是由于某人删除了一些负责添加熵的代码引起的。有传言说，他们因为它导致 valgrind 发出警告而删除了它。然而，在这样做的时候，随机数现在少了很多随机性。事实上，熵少了很多，因此暴力破解变成了一个可行的攻击向量。

希望到现在为止，我们理解了熵对安全性的重要性。无论你是否意识到你正在使用它。

### /dev/random 和 /dev/urandom

`/dev/urandom` 是一个伪随机数生成器，缺乏熵它也**不会**停止。

`/dev/random` 是一个真随机数生成器，它会在缺乏熵的时候停止。

大多数情况下，如果我们正在处理实际的事情，并且它不包含你的核心信息，那么 `/dev/urandom` 是正确的选择。否则，如果就使用 `/dev/random`，那么当系统的熵耗尽时，你的程序就会变得有趣。无论它直接失败，或只是挂起——直到它获得足够的熵，这取决于你编写的程序。

### 检查熵

那么，你有多少熵？

```
[root@testbox test]# cat /proc/sys/kernel/random/poolsize
4096
[root@testbox test]# cat /proc/sys/kernel/random/entropy_avail
2975

```

`/proc/sys/kernel/random/poolsize`，说明熵池的大小（以位为单位）。例如：在停止抽水之前我们应该储存多少随机果汁。`/proc/sys/kernel/random/entropy_avail` 是当前池中随机果汁的数量（以位为单位）。

### 我们如何影响这个数字？

这个数字可以像我们使用它一样耗尽。我可以想出的最简单的例子是将 `/dev/random` 定向到 `/dev/null` 中：

```
[root@testbox test]# cat /dev/random > /dev/null &
[1] 19058
[root@testbox test]# cat /proc/sys/kernel/random/entropy_avail
0
[root@testbox test]# cat /proc/sys/kernel/random/entropy_avail
1

```

影响这个最简单的方法是运行 [Haveged](http://www.issihosts.com/haveged/)。Haveged 是一个守护进程，它使用处理器的“抖动”将熵添加到系统熵池中。安装和基本设置非常简单。

```
[root@b08s02ur ~]# systemctl enable haveged
Created symlink from /etc/systemd/system/multi-user.target.wants/haveged.service to /usr/lib/systemd/system/haveged.service.
[root@b08s02ur ~]# systemctl start haveged

```

在流量相对中等的机器上：

```
[root@testbox ~]# pv /dev/random > /dev/null
  40 B 0:00:15 [   0 B/s] [                    <=>                                                                                ]
  52 B 0:00:23 [   0 B/s] [                           <=>                                                                                ]
  58 B 0:00:25 [5.92 B/s] [                              <=>                                                                                ]
  64 B 0:00:30 [6.03 B/s] [                                  <=>                                                                                ]
^C
[root@testbox ~]# systemctl start haveged
[root@testbox ~]# pv /dev/random > /dev/null
7.12MiB 0:00:05 [1.43MiB/s] [                <=>                                                                                ]
15.7MiB 0:00:11 [1.44MiB/s] [                                    <=>                                                                                ]
27.2MiB 0:00:19 [1.46MiB/s] [                                                               <=>                                                                                ]
  43MiB 0:00:30 [1.47MiB/s] [                                                                                <=>                                                                    ]
^C

```

使用 `pv` 我们可以看到我们通过管道传递了多少数据。正如你所看到的，在运行 `haveged` 之前，我们是 2.1 位/秒（B/s）。而在开始运行 `haveged` 之后，加入处理器的抖动到我们的熵池中，我们得到大约 1.5MiB/秒。

---

via: <http://jhurani.com/linux/2017/11/01/entropy-explained.html>

作者：[James J](https://jblevins.org/log/ssh-vulnkey) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


4 个现在就该去装的 Firefox 扩展

Summary: 合适的扩展能极大地增强你的浏览器功能，但是仔细的选择也是很重要的。

合适的扩展能极大地增强你的浏览器功能，但是仔细的选择也是很重要的。

# 4 个现在就该去装的 Firefox 扩展

>
> 合适的扩展能极大地增强你的浏览器功能，但是仔细的选择也是很重要的。
>
>
>

正如我在关于 Firefox 扩展的[原创文章](https://opensource.com/article/18/1/top-5-firefox-extensions)中提到的，web 浏览器已成为许多用户计算机体验的关键组件。现代浏览器已经发展成为功能强大且可扩展的平台，扩展可以添加或修改其功能。Firefox 的扩展是使用 WebExtensions API（一种跨浏览器开发系统）构建的。

在第一篇文章中，我问读者：“你应该安装哪些扩展？” 重申一下，这一决定主要取决于你如何使用浏览器，你对隐私的看法，你对扩展程序开发人员的信任程度以及其他个人偏好。自文章发表以来，我推荐的一个扩展（Xmarks）已经停止维护。另外，该文章收到了大量的反馈，在这篇更新中，这些反馈已经被考虑到。

我想再次指出，浏览器扩展通常需要能够阅读和（或）更改你访问的网页上的所有内容。你应该仔细考虑这一点。如果扩展程序修改了你访问的所有网页的访问权限，那么它可能成为键盘记录程序、拦截信用卡信息、在线跟踪、插入广告以及执行各种其他恶意活动。这并不意味着每个扩展程序都会暗中执行这些操作，但在安装任何扩展程序之前，你应该仔细考虑安装源，涉及的权限，风险配置文件以及其他因素。请记住，你可以使用配置文件来管理扩展如何影响你的攻击面 —— 例如，使用没有扩展的专用配置文件来执行网上银行等任务。

考虑到这一点，这里有你可能想要考虑的四个开源 Firefox 扩展。

### uBlock Origin

我的第一个建议保持不变。[uBlock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/) 是一款快速、低内存消耗、广泛的拦截器，它不仅可以拦截广告，而且还可以执行你自己的内容过滤。 uBlock Origin 的默认行为是使用多个预定义的过滤器列表来拦截广告、跟踪器和恶意软件站点。它允许你任意添加列表和规则，甚至可以锁定到默认拒绝模式。尽管它很强大，但它已被证明是高效和高性能的。它将继续定期更新，并且是该功能的最佳选择之一。

### Privacy Badger

我的第二个建议也保持不变。如果说有什么区别的话，那就是自从我上一篇文章发表以来，隐私问题更被关注了，这使得这个扩展成为一个简单的建议。顾名思义，[Privacy Badger](https://www.eff.org/privacybadger) 是一个专注于隐私的扩展，可以拦截广告和其他第三方跟踪器。这是电子前哨基金会基金会（EFF）的一个项目，他们说：

>
> Privacy Badger 的诞生是我们希望能够推荐一个单独的扩展，它可以自动分析和拦截任何违反用户同意原则的追踪器或广告；在用户没有任何设置、有关知识或配置的情况下，它可以很好地运行；它是由一个明确为其用户而不是为广告商工作的组织所产生的；它使用了算法的方法来决定什么被跟踪，什么没有被跟踪。”
>
>
>

为什么 Privacy Badger 会出现在这个列表上，它的功能与上一个扩展看起来很类似？因为一些原因：首先，它从根本上工作原理与 uBlock Origin 不同。其次，深度防御的实践是一项合理的策略。说到深度防御，EFF 还维护着 [HTTPS Everywhere](https://www.eff.org/https-everywhere) 扩展，它自动确保 https 用于许多主流网站。当你安装 Privacy Badger 时，你也可以考虑使用 HTTPS Everywhere。

如果你开始认为这篇文章只是对上一篇文章的重新讨论，那么以下是我的建议分歧。

### Bitwarden

在上一篇文章中推荐 LastPass 时，我提到这可能是一个有争议的选择。这无疑属实。无论你是否应该使用密码管理器 —— 如果你使用，那么是否应该选择带有浏览器插件的密码管理器 —— 这是一个备受争议的话题，答案很大程度上取决于你的个人风险状况。我认为大多数普通的计算机用户应该使用一个，因为它比最常见的选择要好得多：在任何地方都使用相同的弱密码！我仍然相信这一点。

[Bitwarden](https://bitwarden.com/) 自从我上次点评以后确实更成熟了。像 LastPass 一样，它对用户友好，支持双因素身份验证，并且相当安全。与 LastPass 不同的是，它是[开源的](https://github.com/bitwarden)。它可以使用或不使用浏览器插件，并支持从其他解决方案（包括 LastPass）导入。它的核心功能完全免费，它还有一个 10 美元/年的高级版本。

### Vimium-FF

[Vimium](https://addons.mozilla.org/en-US/firefox/addon/vimium-ff/) 是另一个开源的扩展，它为 Firefox 键盘快捷键提供了类似 Vim 一样的导航和控制，其称之为“黑客的浏览器”。对于 `Ctrl+x`、 `Meta+x` 和 `Alt+x`，分别对应 `<c-x>`、`<m-x>` 和 `<a-x>`，默认值可以轻松定制。一旦你安装了 Vimium，你可以随时键入 `?` 来查看键盘绑定列表。请注意，如果你更喜欢 Emacs，那么也有一些针对这些键绑定的扩展。无论哪种方式，我认为键盘快捷键是未充分利用的生产力推动力。

### 额外福利: Grammarly

不是每个人都有幸在 Opensource.com 上撰写专栏 —— 尽管你应该认真考虑为这个网站撰写文章；如果你有问题，有兴趣，或者想要一个导师，伸出手，让我们聊聊吧。但是，即使没有专栏撰写，正确的语法在各种各样的情况下都是有益的。试一下 [Grammarly](https://www.grammarly.com/)。不幸的是，这个扩展不是开源的，但它确实可以确保你输入的所有东西都是清晰的 、有效的并且没有错误。它通过扫描你文本中的常见的和复杂的语法错误来实现这一点，涵盖了从主谓一致到文章使用，到修饰词的放置这些所有内容。它的基本功能是免费的，它有一个高级版本，每月收取额外的费用。我在这篇文章中使用了它，它发现了许多我的校对没有发现的错误。

再次说明，Grammarly 是这个列表中包含的唯一不是开源的扩展，因此如果你知道类似的高质量开源替代品，请在评论中告诉我们。

这些扩展是我发现有用并推荐给其他人的扩展。请在评论中告诉我你对更新建议的看法。

---

via: <https://opensource.com/article/18/5/firefox-extensions>

作者：[Jeremy Garcia](https://opensource.com/users/jeremy-garcia) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


编写有趣且有价值的 Systemd 服务

Summary: 每次开机之后需要启动服务器，每次关机之前需要安全地关闭服务进程，十分繁琐和麻烦。

# 编写有趣且有价值的 Systemd 服务

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

让我们假设你希望搭建一个游戏服务器，运行 [Minetest](https://www.minetest.net/) 这款非常酷、开源的，以采集 & 合成为主题的沙盒游戏。你希望将游戏运行在位于客厅的服务器中，以便搭建完成后可供你的学校或朋友使用。你知道内核邮件列表的管理就不过就是如此，那么对你来说也是足够的。

但你很快发现每次开机之后需要启动服务进程，每次关机之前需要安全地关闭服务器，十分繁琐和麻烦。

最初，你可能用守护进程的方式运行服务器：

```
minetest --server &

```

记住进程 PID 以便后续使用。

接着，你还需要通过邮件或短信的方式将服务器已经启动的信息告知你的朋友。然后你就可以开始游戏了。

转眼之间，已经凌晨三点，今天的战斗即将告一段落。但在你关闭主机、睡个好觉之前，还需要做一些操作。首先，你需要通知其它玩家服务器即将关闭，找到记录我们之前提到的 PID 的纸条，然后友好地关闭 Minetest 服务进程。

```
kill -2 <PID>

```

这是因为直接关闭主机电源很可能导致文件损坏。下一步也是最后一步，关闭主机电源。

一定有方法能让事情变得更简单。

### 让 Systemd 服务拯救你

让我们从构建一个普通用户可以（手动）运行的 systemd 服务开始，然后再逐步增加内容。

不需要管理员权限即可运行的服务位于 `~/.config/systemd/user/`，故首先需要创建这个目录：

```
cd
mkdir -p ~/.config/systemd/user/

```

有很多类型的 systemd 单元 (曾经叫做 systemd 脚本)，包括“计时器”和“路径”等，但我们这里关注的是“服务”类型。在 `~/.config/systemd/user/` 目录中创建 `minetest.service` 文件，使用文本编辑器打开并输入如下内容：

```
# minetest.service

[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page

[Service]
Type= simple
ExecStart= /usr/games/minetest --server

```

可以看到该单元中包含不同的段，其中 `[Unit]` 段主要为用户提供信息，给出该单元的描述及如何获得更多相关文档。

脚本核心位于 `[Service]` 段，首先使用 `Type` 指令确定服务类型。服务[有多种类型](http://man7.org/linux/man-pages/man5/systemd.service.5.html)，下面给出两个示例。如果你运行的进程设置环境变量、调用另外一个进程（主进程）、退出运行，那么你应该使用的服务类型为 `forking`。如果你希望在你的单元对应进程结束运行前阻断其他单元运行，那么你应该使用的服务类型为 `oneshot`。

但 Minetest 服务器的情形与上面两种都不同，你希望启动服务器并使其在后台持续运行；这种情况下应该使用 `simple` 类型。

下面来看 `ExecStart` 指令，它给出 systemd 需要运行的程序。在本例中，你希望在后台运行 `minetest` 服务器。如上所示，你可以在可执行程序后面添加参数，但不能将一系列 Bash 命令通过管道连接起来。下面给出的例子无法工作：

```
ExecStart: lsmod | grep nvidia > videodrive.txt

```

如果你需要将 Bash 命令通过管道连接起来，可以将其封装到一个脚本中，然后运行该脚本。

还需要注意一点，systemd 要求你给出程序的完整路径。故如果你想使用 `simple` 类型运行类似 `ls` 的命令，你需要使用 `ExecStart= /bin/ls`。

另外还有 `ExecStop` 指令用于定制服务终止的方式。我们会在第二部分讨论这个指令，但你要了解，如果你没有指定 `ExecStop`，systemd 会帮你尽可能友好地终止进程。

`systemd.directives` 的帮助页中包含完整指令列表，另外你可以在该[网站](http://man7.org/linux/man-pages/man7/systemd.directives.7.html)上找到同样的列表，点击即可查看每个指令的具体信息。

虽然只有 6 行，但你的 `minetest.service` 已经是一个有完整功能的 systemd 单元。执行如下命令启动服务：

```
systemd --user start minetest

```

执行如下命令终止服务：

```
systemd --user stop minetest

```

选项 `--user` 告知 systemd 在你的本地目录中检索服务并用你的用户权限执行服务。

我们的服务器管理故事到此完成了第一部分。在第二部分，我们将在启动和终止服务的基础上，学习如何给用户发邮件、告知用户服务器的可用性。敬请期待。

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

---

via: <https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit>

作者：[Paul Brown](https://www.linux.com/users/bro66) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

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


在 Linux 中如何归档文件和目录

# 在 Linux 中如何归档文件和目录

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

在我们之前的教程中，我们讨论了如何[使用 gzip 和 bzip2 压缩和解压缩文件](https://www.ostechnix.com/how-to-compress-and-decompress-files-in-linux/)。在本教程中，我们将学习如何在 Linux 归档文件。归档和压缩有什么不同吗？你们中的一些人可能经常认为这些术语有相同的含义。但是，这两者完全不同。归档是将多个文件和目录（相同或不同大小）组合成一个文件的过程。另一方面，压缩是减小文件或目录大小的过程。归档通常用作系统备份的一部分，或者将数据从一个系统移至另一个系统时。希望你了解归档和压缩之间的区别。现在，让我们进入主题。

### 归档文件和目录

归档文件和目录最常见的程序是：

1. tar
2. zip

这是一个很大的话题，所以，我将分两部分发表这篇文章。在第一部分中，我们将看到如何使用 tar 命令来归档文件和目录。

### 使用 tar 命令归档文件和目录

**Tar** 是一个 Unix 命令，代表 **T**ape **A**rchive（磁带归档）。它用于将多个文件（相同或不同大小）组合或存储到一个文件中。在 tar 实用程序中有 4 种主要的操作模式。

1. `c` – 从文件或目录中建立归档
2. `x` – 提取归档
3. `r` – 将文件追加到归档
4. `t` – 列出归档的内容

有关完整的模式列表，参阅 man 手册页。

#### 创建一个新的归档

为了本指南，我将使用名为 `ostechnix` 的文件夹，其中包含三种不同类型的文件。

```
$ ls ostechnix/
file.odt image.png song.mp3

```

现在，让我们为 `ostechnix` 目录创建一个新的 tar 归档。

```
$ tar cf ostechnix.tar ostechnix/

```

这里，`c` 标志指的是创建新的归档，`f` 是指定归档文件。

同样，对当前工作目录中的一组文件创建归档文件，使用以下命令：

```
$ tar cf archive.tar file1 file2 file 3

```

#### 提取归档

要在当前目录中提取归档文件，只需执行以下操作：

```
$ tar xf ostechnix.tar

```

我们还可以使用 `C` 标志（大写字母 C）将归档提取到不同的目录中。例如，以下命令将归档文件提取到 `Downloads` 目录中。

```
$ tar xf ostechnix.tar -C Downloads/

```

或者，转到 `Downloads` 文件夹并像下面一样提取其中的归档。

```
$ cd Downloads/
$ tar xf ../ostechnix.tar

```

有时，你可能想要提取特定类型的文件。例如，以下命令提取 “.png” 类型的文件。

```
$ tar xf ostechnix.tar --wildcards "*.png"

```

#### 创建 gzip 和 bzip 格式的压缩归档

默认情况下，tar 创建归档文件以 `.tar` 结尾。另外，`tar` 命令可以与压缩实用程序 `gzip` 和 `bzip` 结合使用。文件结尾以 `.tar` 为扩展名使用普通 tar 来归档文件，文件以 `tar.gz` 或 `.tgz` 结尾使用 `gzip` 归档并压缩文件，文件以 `tar.bz2` 或 `.tbz` 结尾使用 `bzip` 归档并压缩。

首先，让我们来创建一个 gzip 归档：

```
$ tar czf ostechnix.tar.gz ostechnix/

```

或者：

```
$ tar czf ostechnix.tgz ostechnix/

```

这里，我们使用 `z` 标志来使用 gzip 压缩方法压缩归档文件。

你可以使用 `v` 标志在创建归档时查看进度。

```
$ tar czvf ostechnix.tar.gz ostechnix/
ostechnix/
ostechnix/file.odt
ostechnix/image.png
ostechnix/song.mp3

```

这里，`v` 指显示进度。

从一个文件列表创建 gzip 归档文件：

```
$ tar czf archive.tgz file1 file2 file3

```

要提取当前目录中的 gzip 归档文件，使用：

```
$ tar xzf ostechnix.tgz

```

要提取到其他文件夹，使用 `-C` 标志：

```
$ tar xzf ostechnix.tgz -C Downloads/

```

现在，让我们创建 **bzip 归档**。为此，请使用下面的 `j` 标志。

创建一个目录的归档：

```
$ tar cjf ostechnix.tar.bz2 ostechnix/

```

或

```
$ tar cjf ostechnix.tbz ostechnix/

```

从一个列表文件中创建归档：

```
$ tar cjf archive.tar.bz2 file1 file2 file3

```

或

```
$ tar cjf archive.tbz file1 file2 file3

```

为了显示进度，使用 `v` 标志。

现在，在当前目录下，让我们提取一个 bzip 归档。这样做：

```
$ tar xjf ostechnix.tar.bz2

```

或者，提取归档文件到其他目录：

```
$ tar xjf ostechnix.tar.bz2 -C Downloads

```

#### 一次创建多个目录和/或文件的归档

这是 `tar` 命令的另一个最酷的功能。要一次创建多个目录或文件的 gzip 归档文件，使用以下文件：

```
$ tar czvf ostechnix.tgz Downloads/ Documents/ ostechnix/file.odt

```

上述命令创建 `Downloads`、 `Documents` 目录和 `ostechnix` 目录下的 `file.odt` 文件的归档，并将归档保存在当前工作目录中。

#### 在创建归档时跳过目录和/或文件

这在备份数据时非常有用。你可以在备份中排除不重要的文件或目录，这是 `–exclude` 选项所能帮助的。例如你想要创建 `/home` 目录的归档，但不希望包括 `Downloads`、 `Documents`、 `Pictures`、 `Music` 这些目录。

这是我们的做法：

```
$ tar czvf ostechnix.tgz /home/sk --exclude=/home/sk/Downloads --exclude=/home/sk/Documents --exclude=/home/sk/Pictures --exclude=/home/sk/Music

```

上述命令将对我的 `$HOME` 目录创建一个 gzip 归档，其中不包括 `Downloads`、`Documents`、`Pictures` 和 `Music` 目录。要创建 bzip 归档，将 `z` 替换为 `j`，并在上例中使用扩展名 `.bz2`。

#### 列出归档文件但不提取它们

要列出归档文件的内容，我们使用 `t` 标志。

```
$ tar tf ostechnix.tar
ostechnix/
ostechnix/file.odt
ostechnix/image.png
ostechnix/song.mp3

```

要查看详细输出，使用 `v` 标志。

```
$ tar tvf ostechnix.tar
drwxr-xr-x sk/users 0 2018-03-26 19:52 ostechnix/
-rw-r--r-- sk/users 9942 2018-03-24 13:49 ostechnix/file.odt
-rw-r--r-- sk/users 36013 2015-09-30 11:52 ostechnix/image.png
-rw-r--r-- sk/users 112383 2018-02-22 14:35 ostechnix/song.mp3

```

#### 追加文件到归档

文件或目录可以使用 `r` 标志添加/更新到现有的归档。看看下面的命令：

```
$ tar rf ostechnix.tar ostechnix/ sk/ example.txt

```

上面的命令会将名为 `sk` 的目录和名为 `exmple.txt` 添加到 `ostechnix.tar` 归档文件中。

你可以使用以下命令验证文件是否已添加：

```
$ tar tvf ostechnix.tar
drwxr-xr-x sk/users 0 2018-03-26 19:52 ostechnix/
-rw-r--r-- sk/users 9942 2018-03-24 13:49 ostechnix/file.odt
-rw-r--r-- sk/users 36013 2015-09-30 11:52 ostechnix/image.png
-rw-r--r-- sk/users 112383 2018-02-22 14:35 ostechnix/song.mp3
drwxr-xr-x sk/users 0 2018-03-26 19:52 sk/
-rw-r--r-- sk/users 0 2018-03-26 19:39 sk/linux.txt
-rw-r--r-- sk/users 0 2018-03-26 19:56 example.txt

```

### TL;DR

创建 tar 归档：

* **普通 tar 归档：** `tar -cf archive.tar file1 file2 file3`
* **Gzip tar 归档：** `tar -czf archive.tgz file1 file2 file3`
* **Bzip tar 归档：** `tar -cjf archive.tbz file1 file2 file3`

提取 tar 归档：

* **普通 tar 归档：** `tar -xf archive.tar`
* **Gzip tar 归档：** `tar -xzf archive.tgz`
* **Bzip tar 归档：** `tar -xjf archive.tbz`

我们只介绍了 `tar` 命令的基本用法，这些对于开始使用 `tar` 命令足够了。但是，如果你想了解更多详细信息，参阅 man 手册页。

```
$ man tar

```

好吧，这就是全部了。在下一部分中，我们将看到如何使用 Zip 实用程序来归档文件和目录。

干杯！

---

via: <https://www.ostechnix.com/how-to-archive-files-and-directories-in-linux-part-1/>

作者：[SK](https://www.ostechnix.com/author/sk/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


Orbital Apps：新一代 Linux 程序

Summary: Orbital Apps 或 ORB（Open Runnable Bundle）apps（开放可运行程序包），一个自由的、跨平台的开源程序集合

# Orbital Apps：新一代 Linux 程序

今天，我们要了解 **Orbital Apps** 或 **ORB**（**O**pen **R**unnable **B**undle）**apps**（开放可运行程序包），一个自由的、跨平台的开源程序集合。所有 ORB 程序都是可移动的。你可以将它们安装在你的 Linux 系统或 USB 驱动器上，以便你可以在任何系统上使用相同的程序。它们不需要 root 权限，并且没有依赖关系。所有必需的依赖关系都包含在程序中。只需将 ORB 程序复制到 USB 驱动器并将其插入到任何 Linux 系统中就立即开始使用它们。所有设置和配置以及程序的数据都将存储在 USB 驱动器上。由于不需要在本地驱动器上安装程序，我们可以在联机或脱机的计算机上运行应用程序。这意味着我们不需要 Internet 来下载任何依赖。

ORB 程序压缩了 60％，因此我们甚至可以从小型 USB 驱动器存储和使用它们。所有 ORB 应用程序都使用 PGP / RSA 进行签名，并通过 TLS 1.2 进行分发。所有应用程序打包时都不做任何修改，甚至不会重新编译。以下是当前可用的便携式 ORB 应用程序列表。

* abiword
* audacious
* audacity
* darktable
* deluge
* filezilla
* firefox
* gimp
* gnome-mplayer
* hexchat
* inkscape
* isomaster
* kodi
* libreoffice
* qbittorrent
* sound-juicer
* thunderbird
* tomahawk
* uget
* vlc
* 未来还有更多

Orb 是开源的，所以如果你是开发人员，欢迎协作并添加更多程序。

### 下载并使用可移动 ORB 程序

正如我已经提到的，我们不需要安装可移动 ORB 程序。但是，ORB 团队强烈建议你使用 **ORB 启动器** 来获得更好的体验。 ORB 启动器是一个小的安装程序（小于 5MB），它可帮助你启动 ORB 程序，并获得更好，更流畅的体验。

让我们先安装 ORB 启动器。为此，[下载 ORB 启动器](https://www.orbital-apps.com/documentation/orb-launcher-all-installers)。你可以手动下载 ORB 启动器的 ISO 并将其挂载到文件管理器上。或者在终端中运行以下任一命令来安装它：

```
$ wget -O - https://www.orbital-apps.com/orb.sh | bash

```

如果你没有 wget，请运行：

```
$ curl https://www.orbital-apps.com/orb.sh | bash

```

询问时输入 root 用户和密码。

就是这样。Orbit 启动器已安装并可以使用。

现在，进入 [ORB 可移动程序下载页面](https://www.orbital-apps.com/download/portable_apps_linux/)，并下载你选择的程序。在本教程中，我会下载 Firefox。

下载完后，进入下载位置并双击 ORB 程序来启动它。点击 Yes 确认。

Firefox ORB 程序能用了！

同样，你可以立即下载并运行任何程序。

如果你不想使用 ORB 启动器，请将下载的 `.orb` 安装程序设置为可执行文件，然后双击它进行安装。不过，建议使用 ORB 启动器，它可让你在使用 ORB 程序时更轻松、更顺畅。

就我测试的 ORB 程序而言，它们打开即可使用。希望这篇文章有帮助。今天就是这些。祝你有美好的一天！

干杯！！

---

via: <https://www.ostechnix.com/orbitalapps-new-generation-ubuntu-linux-applications/>

作者：[SK](https://www.ostechnix.com/author/sk/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


Systemd 服务：比启动停止服务更进一步

# Systemd 服务：比启动停止服务更进一步

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

在上一篇[文章](/article-9700-1.html)中，我们展示了如何创建一个 systemd 服务并使普通用户可以启动和终止游戏服务器。但到目前为止，使用这个服务并不比直接运行服务器高明多少。让我们更进一步，让其可以向玩家发邮件，包括在服务器可用时通知玩家，在服务器关闭前警告玩家：

```
# minetest.service

[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page

[Service]
Type= simple

ExecStart= /usr/games/minetest --server
ExecStartPost= /home/<username>/bin/mtsendmail.sh "Ready to rumble?" "Minetest Starting up"

TimeoutStopSec= 180
ExecStop= /home/<username>/bin/mtsendmail.sh "Off to bed. Nightie night!" "
  Minetest Stopping in 2 minutes"
ExecStop= /bin/sleep 120
ExecStop= /bin/kill -2 $MAINPID

```

这里涉及几个新的指令。首先是 `ExecStartPost` 指令，该指令可以在主进程启动后马上执行任何你指定的操作。在本例中，你执行了一个自定义脚本 `mtsendmail` (内容如下)，该脚本以邮件形式通知你的朋友服务器已经启动。

```
#!/bin/bash
# mtsendmail
echo $1 | mutt -F /home/<username>/.muttrc -s "$2" my_minetest@mailing_list.com

```

我们使用 [Mutt](http://www.mutt.org/) 这个命令后邮件客户端发送消息。虽然从实际效果来看，上述脚本仅有 1 行，但 systemd 单元的参数中不能包含管道及重定向操作，故我们需要将其封装到脚本中。

顺便提一下，还有一个 `ExecStartPre` 指令，用于在服务主进程执行之前进行指定操作。

接下来我们看到，关闭服务器涉及了好几条指令。`TimeoutStopSec` 指令用于设置 systemd 友好关闭服务的最大等候时间，默认值大约是 90 秒。超过这个最大等候时间，systemd 会强制关闭服务并报错。考虑到你希望在彻底关闭服务器前给用户预留几分钟的时间，你需要将超时时间提高至 3 分钟，这样 systemd 就不会误认为服务关闭时出现问题。

接下来是关闭服务的具体指令部分。虽然没有 `ExecStopPre` 这样的指令，但你可以通过多次使用 `ExecStop` 指令实现关闭服务器前执行操作的目标。多个 `ExecStop` 指令按从上到下的顺序依次运行，这样你就可以在服务器真正关闭前向用户发送消息。

通过这个特性，你首先应该向你的朋友发邮件，警告其服务器即将关闭，然后等待两分钟，最后关闭服务器。可以使用 `Ctrl + c` 关闭 Minetest 服务器，该操作会被转换为一个中断信号（`SIGINT`）；当你执行 `kill -2 $MAINPID` 时就会发送该中断信号，其中 `$MAINPID` 是 systemd 变量，用于记录你服务中主进程的 PID 信息。

看上去好多了！如果你此时启动服务：

```
systemctl --user start minetest

```

服务会启动 Minetest 服务器并向你的用户发送邮件。关闭服务的情形基本类似，只不过会额外留给用户 2 分钟时间退出登录。

### 开机自启动

下一步我们让你的服务在主机启动后立即可用，在主机关闭时自动关闭。

我们需要将你的服务文件移动到系统服务目录，即 `/etc/systemd/system/`：

```
sudo mv /home/<username>/.config/systemd/user/minetest.service /etc/systemd/system/

```

如果你希望此时启动该服务，你需要拥有超级用户权限：

```
sudo systemctl start minetest

```

另外，可以使用如下命令检查服务状态：

```
sudo systemctl status minetest

```

你会发现服务很糟糕地处于失败状态，这是因为 systemd 不能通过上下文信息、特征、配置文件得知具体使用哪个用户运行该服务。在单元文件中增加 `User` 指令可以解决这个问题。

```
# minetest.service

[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page

[Service]
Type= simple
User= <username>

ExecStart= /usr/games/minetest --server
ExecStartPost= /home/<username>/bin/mtsendmail.sh "Ready to rumble?"
  "Minetest Starting up"

TimeoutStopSec= 180
ExecStop= /home/<username>/bin/mtsendmail.sh "Off to bed. Nightie night!"
  "Minetest Stopping in 2 minutes"
ExecStop= /bin/sleep 120
ExecStop= /bin/kill -2 $MAINPID

```

systemd 从 `User` 指令中得知应使用哪个用户的环境变量来正确运行该服务。你可以使用 root 用户，但这可能产生安全风险；使用你的个人用户会好一些，但不少管理员的做法是为服务单独创建一个用户，这样可以有效地将服务与其它用户和系统组件相互隔离。

下一步我们让你的服务在系统启动时自动启动，系统关闭时自动关闭。要达到这个目的，你需要 *启用* 你的服务；但在这之前，你还需要告知 systemd 从哪里 *安装* 它。

对于 systemd 而言，*安装* 意味着告知 systemd 在系统启动的具体哪个步骤激活你的服务。以通用 Unix 打印系统（`cups.service`）为例，它的启动在网络框架启动之后、其它打印服务启动之前。又如，`minetest.server` 需要使用用户邮件（及其它组件），需要等待网络和普通用户对应的服务就绪后才可启动。

你只需要在单元文件中添加一个新段和新指令：

```
...
[Install]
WantedBy= multi-user.target

```

你可以将其理解为“等待多用户系统的全部内容就绪”。systemd 中的“目标”类似于旧系统中的运行级别，可以用于将主机转移到一个或另一个状态，也可以像本例中这样让你的服务等待指定状态出现后运行。

你的最终 `minetest.service` 文件如下：

```
# minetest.service
[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page

[Service]
Type= simple
User= <username>

ExecStart= /usr/games/minetest --server
ExecStartPost= /home/<username>/bin/mtsendmail.sh "Ready to rumble?"
  "Minetest Starting up"

TimeoutStopSec= 180
ExecStop= /home/<username>/bin/mtsendmail.sh "Off to bed. Nightie night!"
  "Minetest Stopping in 2 minutes"
ExecStop= /bin/sleep 120
ExecStop= /bin/kill -2 $MAINPID

[Install]
WantedBy= multi-user.target

```

在尝试新的服务之前，你还需要对邮件脚本做一些调整：

```
#!/bin/bash
# mtsendmail

sleep 20
echo $1 | mutt -F /home/<username>/.muttrc -s "$2" my_minetest@mailing_list.com
sleep 10

```

这是因为系统需要一定的时间启动邮件系统（这里等待 20 秒），也需要一定时间完成邮件发送（这里等待 10 秒）。注意脚本中的等待时间数值适用于我的系统，你可能需要针对你的系统调整数值。

大功告成啦。执行如下操作：

```
sudo systemctl enable minetest

```

你的 Minetest 服务将在系统启动时自动启动，在系统关闭时友好关闭并通知你的用户。

### 总结

事实上 Debian、 Ubuntu 和一些族类的发行版提供了 `minetest-server` 这个特别的软件包，可以提供一部分上述功能，（但不包括邮件通知功能）。即使如此，你还是可以建立你独有的自定义服务；事实上，你目前建立的服务比 Debian 默认提供的服务更加通用，可以提供更多功能。

更进一步的说，我们这里描述的流程可以让你将大多数简单服务器转换为服务，类型可以是游戏、网站应用或其它应用。同时，这也是你名副其实地踏入 systemd 大师殿堂的第一步。

---

via: <https://www.linux.com/blog/learn/2018/5/systemd-services-beyond-starting-and-stopping>

作者：[Paul Brown](https://www.linux.com/users/bro66) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

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


你可以用 Linux 中的 IP 工具做 3 件有用的事情

Summary: 如何使用 IP 工具来快速轻松地找到你的 IP 地址、显示路由表等等。

如何使用 IP 工具来快速轻松地找到你的 IP 地址、显示路由表等等。

# 你可以用 Linux 中的 IP 工具做 3 件有用的事情

>
> 如何使用 IP 工具来快速轻松地找到你的 IP 地址、显示路由表等等。
>
>
>

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

`ifconfig` 命令在 Linux 上被弃用已有十多年的时间了，而 `iproute2` 项目包含了神奇的工具 `ip`。许多在线教程资源仍然采用旧的命令行工具，如 `ifconfig`、`route` 和 `netstat`。本教程的目标是分享一些可以使用 `ip` 工具轻松完成的网络相关的事情。

### 找出你的 IP 地址

```
[dneary@host]$ ip addr show
[snip]
44: wlp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 5c:e0:c5:c7:f0:f1 brd ff:ff:ff:ff:ff:ff
        inet 10.16.196.113/23 brd 10.16.197.255 scope global dynamic wlp4s0
        valid_lft 74830sec preferred_lft 74830sec
        inet6 fe80::5ee0:c5ff:fec7:f0f1/64 scope link
        valid_lft forever preferred_lft forever

```

`ip addr show` 会告诉你很多关于你的所有网络链接设备的信息。在这里，我的无线以太网卡（`wlp4s0`）是 IPv4 地址（`inet` 字段）`10.16.196.113/23`。 `/23` 表示 32 位 IP 地址中的 23 位将被该子网中的所有 IP 地址共享。子网中的 IP 地址范围从 `10.16.196.0` 到 `10.16.197.254`。子网的广播地址（IP 地址后面的 `brd` 字段）`10.16.197.255` 保留给子网上所有主机的广播流量。

我们能只使用 `ip addr show dev wlp4s0` 来显示单个设备的信息。

### 显示你的路由表

```
[dneary@host]$ ip route list
default via 10.16.197.254 dev wlp4s0 proto static metric 600
10.16.196.0/23 dev wlp4s0 proto kernel scope link src 10.16.196.113 metric 601
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

```

路由表是本地主机帮助网络流量确定去哪里的方式。它包含一组路标，将流量发送到特定的接口，以及在其旅途中的特定下一个地点。

如果你运行任何虚拟机或容器，它们将获得自己的 IP 地址和子网，这可能会使这些路由表非常复杂，但在单个主机中，通常有两条指令。对于本地流量，将其发送到本地以太网上，并且网络交换机将找出（使用称为 ARP 的协议）哪个主机拥有目标 IP 地址，并且要将流量发送到哪里。对于到互联网的流量，将其发送到本地网关节点，它将更好地了解如何到达目的地。

在上面的情况中，第一行代表外部流量的外部网关，第二行代表本地流量，第三行代表主机上运行的虚拟机的虚拟网桥，但该链接当前未激活。

### 监视你的网络配置

```
[dneary@host]$ ip monitor all
[dneary@host]$ ip -s link list wlp4s0

```

`ip monitor` 命令可用于监视路由表（网络接口上的网络寻址）的更改或本地主机上 ARP 表的更改。此命令在调试与容器和网络相关的网络问题时特别有用，如当两个虚拟机应该能彼此通信，但实际不能。

在使用 `all` 时，`ip monitor` 会报告所有的更改，前缀以 `[LINK]`（网络接口更改）、`[ROUTE]`（更改路由表）、`[ADDR]`（IP 地址更改）或 `[NEIGH]`（与马无关 —— 与邻居的 ARP 地址相关的变化）。

你还可以监视特定对象上的更改（例如，特定的路由表或 IP 地址）。

另一个适用于许多命令的有用选项是 `ip -s`，它提供了一些统计信息。添加第二个 `-s` 选项可以添加更多统计信息。上面的 `ip -s link list wlp4s0` 会给出很多关于接收和发送的数据包的信息、丢弃的数据包数量、检测到的错误等等。

### 提示：缩短你的命令

一般来说，对于 `ip` 工具，你只需要包含足够的字母来唯一标识你想要做的事情。你可以使用 `ip mon` 来代替 `ip monitor`。你可以使用 `ip a l`，而不是 `ip addr list`，并且可以使用 `ip r`来代替 `ip route`。`ip link list` 可以缩写为 `ip l ls`。要了解可用于更改命令行为的许多选项，请浏览 [ip 手册页](https://www.systutorials.com/docs/linux/man/8-ip-route/)。

---

via: <https://opensource.com/article/18/5/useful-things-you-can-do-with-IP-tool-Linux>

作者：[Dave Neary](https://opensource.com/users/dneary) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


容器化，原子化发行版以及 Linux 的未来

Summary: 容器支持者认为未来属于容器化操作系统，而其他人或许有不同看法。

容器支持者认为未来属于容器化操作系统，而其他人或许有不同看法。

# 容器化，原子化发行版以及 Linux 的未来

>
> 容器支持者认为未来属于容器化操作系统，而其他人或许有不同看法。
>
>
>

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

自从 Linus Torvalds 在 1991 年发布 Linux 以来，Linux 已历经漫长的岁月。它已经成为企业级领域的主流操作系统。同时，我们看到桌面级领域出现了很多改进和调整，但在过去的 25 年来，主流 Linux 发行版的模式很大程度上没有变化。基于软件包管理的传统模式依然统治着桌面级和服务器级市场。

但随着 Google 发布了基于 Linux 的 Chrome OS，情况出现了微妙的转变，Chrome OS 采用镜像模式。Core OS (目前归属于 Red Hat) 受 Google 启发推出了一款操作系统 Container Linux，主要面向企业级用户。

Container Linux 改变了操作系统更新的方式，也改变了应用分发和更新的方式。这会是 Linux 发行版的未来吗？这是否会取代基于软件包的传统发行版模式呢？

### 三种模式

SLE (SUSE Linux Enterprise) 的产品管理总监 Matthias Eckermann 认为目前存在 3 种模式，而不是 2 种。Eckermann 提到：“除了传统模式（RHEL/SLE）和镜像模式（RedHat 的 Atomic Host），还存在第三种模型：事务模式。[SUSE CaaS 平台](https://www.suse.com/products/caas-platform/) 及 SUSE MicroOS 就采用这种模式。”

### 差异有哪些

Linux 用户对传统模式非常熟悉，它由独立的软件包和共享库组成。这种模式有独特的优势，让应用开发者无需将共享库捆绑在应用中。由于库不会多次引入，使得系统简洁和轻便。这也让用户无需下载很多软件包，节省了带宽。发行版对软件包全权负责，通过推送系统级别的更新，可以轻松地解决安全隐患。

RHEL （Red Hat Enterprise Linux）的产品管理总监 Ron Pacheco 表示，“传统的打包方式继续为我们提供精心构建和优化操作系统的机会，以便支持需要经过时间考验的任务关键型工作负载。”

但传统模式也有一些弊端。应用开发者受限使用发行版包含的库，使其无法从发行版不支持的新软件中获益。这也可能导致不同版本之间相互冲突。最终，传统模式给管理员增加了挑战，使其难以让软件包一直处于最新版本状态。

### 镜像模式

镜像模式应运而生。Eckermann 表示，“镜像模式解决了传统模式遇到的问题，它在每次迭代更新时替换整个操作系统，而不是单个的软件包”。

Pacheco 表示，“当我们用镜像作为操作系统的代名词进行讨论时，我们真正关心的是可编程式的开发和部署以及更好的集成式生命周期管理”，基于 RHEL 搭建的 OpenShift 被他用作示例。

Pacheco 认为基于镜像的操作系统是一种延续，从手工打造并部署镜像，到可大规模管理的高度自动化基础设施；无论客户使用哪种类型，都需要运行同样的应用。他说，“你肯定不希望使用一个完全不同的部署模式，这需要重做很多工作”。

镜像模式用新的库和软件包替代来整个操作系统，但也面临一系列问题。在镜像模式中，需要重建镜像才能适应特殊环境的需求。例如，用户有特殊需求，需要安装特定硬件的驱动或安装底层监控功能，镜像模式无法满足，需要重新设计功能以实现细粒度操作。

### 事务模式

第三种模式采用事务更新，基于传统的软件包更新，但将全部的软件包视为一个镜像，就像镜像那样在一次操作中更新全部软件包。

Eckermann 表示，“由于安装或回滚时操作对象是打包在一起的单一软件包，用户在需要时能够做相应的调整，这就是差别所在。结合传统模式和镜像模式的优点，避免两种模式的缺点，事务模式给用户提供了额外的灵活性。”

Pacheco 表示，将精心构造的工作负载部署成镜像的做法越来越成为主流，因为这种部署方式具有一致性和可靠性，而且可以弹性部署。“这正是我们用户目前的做法，部署环境包括在预置设备或公有/私有云上创建并部署的虚拟机，或在传统的裸机上。”

Pacheco 建议我们将这几种模式视为操作系统角色的进化和扩展，而不是仅仅“使用场景的比较和对比”。

### 原子化更新的问世

Google 的 Chrome OS 和 Core OS 为我们普及了事务更新的概念，该模型也被 Red Hat 和 SUSE 采用。

Eckermann 表示，“我们必须认识到，用于容器主机的操作系统已经不再是关注点 —— 至少不是管理员的关注点。RedHat Atomic 主机和 SUSE CaaS 平台都解决了该问题，实现方式在用户看来很相似。”

SUSE CaaS 平台、Red Hat Atomic Host和 Container Linux （前身是 Core OS）提供的[<ruby> 不可变基础设施 <rt>  Immutable infrastructure </rt></ruby>](https://www.digitalocean.com/community/tutorials/what-is-immutable-infrastructure) 推广了事务更新的使用。Red Hat 高级技术产品经理 Ben Breard 表示，“在事务模式中，主机总是会变更到已确认正确的新状态，这让我们更有信心执行更新，进而实现更快速的功能流、安全优势以及易于采用的操作模式。”

这些新型操作系统使用 Linux 容器将应用与底层系统隔离，解除了传统模式中基础设施更新的诸多限制。

Breard 补充道，“当编排层可以智能处理更新、部署，甚至最终实现无缝操作时，我们才会真正意识到该模式的威力和好处”。

### 展望未来

Linux 的未来会是什么样子？不同的人会给出不同的回答。容器支持者认为未来属于容器化的操作系统，但依然拥有庞大市场的 Linux 供应商显然不这么认为。

当被问到原子化发行版是否会在很久以后将替换传统发行版时，Eckermann 表示，“如果我回答肯定的，那么表示我顺应潮流；如果回答是否定的，意味着我还是站在传统阵营。然而，我的回答是否定的，即 atomic 发行版在很久以后也不会替换传统发行版，传统负载和容器化负载将在数据中心、私有云以及公有云环境中共存。”

Pacheco 认为，从 Linux 的部署增长情况来看，一般情况下很难想象一种模式替换另一种模式。与其将多种模式视为相互竞争的关系，不如将原子化发行版视为操作系统进化和部署的一部分。

此外，在一些使用案例中，我们需要同时使用多种 Linux 发行版。Eckermann 表示，“想一想银行和保险公司中大量的 PL/1 和 Cobol 系统。再想一想内存数据库和核心数据总线系统。”

这些应用大多数无法进行容器化。就我们目前来看，容器化不是解决所有问题的万金油。总是会同时存在多种不同的技术。

Eckermann 相信，随着时间的推移，大量新的开发和部署将采用容器化，但仍然有不错的理由，促使我们在企业级环境中保留传统的部署方式和应用。

Pacheco 认为，“用户需要经历业务、设计和文化的转型，才能最大化基于容器的部署带来的优势。好消息是业界已经认识到并开始大规模转变，就像历史上大型机转变成 UNIX，UNIX 转变成 x86，x86 转变成虚拟化那样”。

### 结论

很明显，未来容器化负载的使用量会持续增长，也就意味着原子化发行版的需求量持续增长。与此同时，仍会有不少工作负载运行在传统发行版中。重要的是，这两类用户都在新模式上大规模投入，以便市场改变时可以做相应的策略改变。从外部观察者的视角来看，未来属于事务/原子化模式。我们已经见证了数据中心的发展，我们花了很长时间完成了从每个服务器一个应用到“函数即服务”模型的转变。Linux 发行版进入原子化时代的日子也不会太远了。

---

via: <https://www.linux.com/blog/2018/4/containerization-atomic-distributions-and-future-linux>

作者：[SWAPNIL BHARTIYA](https://www.linux.com/users/arnieswap) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

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


保护你的 Fedora 系统免受这个 DHCP 漏洞

Summary: 前几天在 dhcp-client 中发现并披露了一个严重的安全漏洞。此 DHCP 漏洞会对你的系统和数据造成高风险，尤其是在使用不受信任的网络，如非你拥有的 WiFi 接入点时。

# 保护你的 Fedora 系统免受这个 DHCP 漏洞

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

前几天在 `dhcp-client` 中发现并披露了一个严重的安全漏洞。此 DHCP 漏洞会对你的系统和数据造成高风险，尤其是在使用不受信任的网络，如非你拥有的 WiFi 接入点时。

动态主机控制协议（DHCP）能让你的系统从其加入的网络中获取配置。你的系统将请求 DHCP 数据，并且通常是由路由器等服务器应答。服务器为你的系统提供必要的数据以进行自我配置。例如，你的系统如何在加入无线网络时正确进行网络配置。

但是，本地网络上的攻击者可能会利用此漏洞。使用在 NetworkManager 下运行的 `dhcp-client` 脚本中的漏洞，攻击者可能能够在系统上以 root 权限运行任意命令。这个 DHCP 漏洞使你的系统和数据处于高风险状态。该漏洞已分配 CVE-2018-1111，并且有 [Bugzilla 来跟踪 bug](https://bugzilla.redhat.com/show_bug.cgi?id=1567974)。

### 防范这个 DHCP 漏洞

新的 dhcp 软件包包含了 Fedora 26、27 和 28 以及 Rawhide 的修复程序。维护人员已将这些更新提交到 updates-testing 仓库。对于大多数用户而言，它们应该在这篇文章的大约一天左右的时间内在稳定仓库出现。所需的软件包是：

* Fedora 26: dhcp-4.3.5-11.fc26
* Fedora 27: dhcp-4.3.6-10.fc27
* Fedora 28: dhcp-4.3.6-20.fc28
* Rawhide: dhcp-4.3.6-21.fc29

#### 更新稳定的 Fedora 系统

要在稳定的 Fedora 版本上立即更新，请[使用 sudo](https://fedoramagazine.org/howto-use-sudo/) 运行此命令。如有必要，请在提示时输入你的密码：

```
sudo dnf --refresh --enablerepo=updates-testing update dhcp-client

```

之后，使用标准稳定仓库进行更新。要从稳定的仓库更新 Fedora 系统，请使用以下命令：

```
sudo dnf --refresh update dhcp-client

```

#### 更新 Rawhide 系统

如果你的系统是 Rawhide，请使用以下命令立即下载和更新软件包：

```
mkdir dhcp && cd dhcp
koji download-build --arch={x86_64,noarch} dhcp-4.3.6-21.fc29
sudo dnf update ./dhcp-*.rpm

```

在每日的 Rawhide compose 后，只需运行 `sudo dnf update` 即可获取更新。

### Fedora Atomic Host

针对 Fedora Atomic Host 的修复程序版本为 28.20180515.1。要获得更新，请运行以下命令：

```
atomic host upgrade -r

```

此命令将重启系统以应用升级。

---

via: <https://fedoramagazine.org/protect-fedora-system-dhcp-flaw/>

作者：[Paul W. Frields](https://fedoramagazine.org/author/pfrields/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在 Ubuntu 18.04 服务器上安装和配置 KVM

Summary: 我们可以通过 virt-manager 的图形用户界面或使用 virt-install 和 virsh 命令在命令行界面来创建和管理基于 KVM 的虚拟机。

# 如何在 Ubuntu 18.04 服务器上安装和配置 KVM

**KVM**（基于内核的虚拟机）是一款为类 Linux 系统提供的开源的全虚拟化解决方案，KVM 使用虚拟化扩展（如 **Intel VT** 或 **AMD-V**）提供虚拟化功能。无论何时我们在任何 Linux 机器上安装 KVM，都会通过加载诸如 `kvm-intel.ko`（基于 Intel 的机器）和 `kvm-amd.ko`（基于 amd 的机器）的内核模块，使其成为<ruby> 管理程序 <rt>  hyervisor </rt></ruby>（LCTT 译注：一种监控和管理虚拟机运行的核心软件层）。

KVM 允许我们安装和运行多个虚拟机（Windows 和 Linux）。我们可以通过 `virt-manager` 的图形用户界面或使用 `virt-install` 和 `virsh` 命令在命令行界面来创建和管理基于 KVM 的虚拟机。

在本文中，我们将讨论如何在 Ubuntu 18.04 LTS 服务器上安装和配置 **KVM 管理程序**。我假设你已经在你的服务器上安装了 Ubuntu 18.04 LTS 。接下来登录到您的服务器执行以下步骤。

### 第一步：确认您的硬件是否支持虚拟化

执行 `egrep` 命令以验证您的服务器的硬件是否支持虚拟化，

```
linuxtechi@kvm-ubuntu18-04:~$ egrep -c '(vmx|svm)' /proc/cpuinfo
1

```

如果输出结果大于 0，就意味着您的硬件支持虚拟化。重启，进入 BIOS 设置中启用 VT 技术。

现在使用下面的命令安装 `kvm-ok` 实用程序，该程序用于确定您的服务器是否能够运行硬件加速的 KVM 虚拟机。

```
linuxtechi@kvm-ubuntu18-04:~$ sudo apt install cpu-checker

```

运行 kvm-ok 命令确认输出结果，

```
linuxtechi@kvm-ubuntu18-04:~$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

```

### 第二步：安装 KVM 及其依赖包

运行下面的 apt 命令安装 KVM 及其依赖项：

```
linuxtechi@kvm-ubuntu18-04:~$ sudo apt update
linuxtechi@kvm-ubuntu18-04:~$ sudo apt install qemu qemu-kvm libvirt-bin  bridge-utils  virt-manager

```

只要上图相应的软件包安装成功，那么你的本地用户（对于我来说是 `linuxtechi`）将被自动添加到 `libvirtd` 群组。

### 第三步：启动并启用 libvirtd 服务

我们在 Ubuntu 18.04 服务器上安装 qemu 和 libvirtd 软件包之后，它就会自动启动并启用 `libvirtd` 服务，如果 `libvirtd` 服务没有开启，则运行以下命令开启，

```
linuxtechi@kvm-ubuntu18-04:~$ sudo service libvirtd start
linuxtechi@kvm-ubuntu18-04:~$ sudo update-rc.d libvirtd enable

```

现在使用下面的命令确认 libvirtd 服务的状态，

```
linuxtechi@kvm-ubuntu18-04:~$ service libvirtd status

```

输出结果如下所示：

### 第四步：为 KVM 虚拟机配置桥接网络

只有通过桥接网络，KVM 虚拟机才能访问外部的 KVM 管理程序或主机。在Ubuntu 18.04中，网络由 `netplan` 实用程序管理，每当我们新安装一个 Ubuntu 18.04 系统时，会自动创建一个名称为 `/etc/netplan/50-cloud-init.yaml` 文件，其配置了静态 IP 和桥接网络，`netplan` 实用工具将引用这个文件。

截至目前，我已经在此文件配置了静态 IP，文件的具体内容如下：

```
network:
  ethernets:
    ens33:
      addresses: [192.168.0.51/24]
      gateway4: 192.168.0.1
      nameservers:
        addresses: [192.168.0.1]
      dhcp4: no
      optional: true
  version: 2

```

我们在这个文件中添加桥接网络的配置信息，

```
linuxtechi@kvm-ubuntu18-04:~$ sudo vi /etc/netplan/50-cloud-init.yaml

network:
  version: 2
  ethernets:
    ens33:
      dhcp4: no
      dhcp6: no

  bridges:
    br0:
      interfaces: [ens33]
      dhcp4: no
      addresses: [192.168.0.51/24]
      gateway4: 192.168.0.1
      nameservers:
        addresses: [192.168.0.1]

```

正如你所看到的，我们已经从接口（`ens33`）中删除了 IP 地址，并将该 IP 添加到 `br0` 中，并且还将接口（`ens33`）添加到 `br0`。使用下面的 `netplan` 命令使更改生效，

```
linuxtechi@kvm-ubuntu18-04:~$ sudo netplan apply

```

如果您想查看 debug 日志请使用以下命令，

```
linuxtechi@kvm-ubuntu18-04:~$ sudo netplan --debug  apply

```

现在使用以下方法确认网络桥接状态：

```
linuxtechi@kvm-ubuntu18-04:~$ sudo networkctl status -a

```

```
linuxtechi@kvm-ubuntu18-04:~$ ifconfig

```

### 第五步：创建虚拟机（使用 virt-manager 或 virt-install 命令）

有两种方式创建虚拟机：

* `virt-manager`（图形化工具）
* `virt-install`（命令行工具）

#### 使用 virt-manager 创建虚拟机

通过执行下面的命令启动 `virt-manager`：

```
linuxtechi@kvm-ubuntu18-04:~$ sudo virt-manager

```

创建一个新的虚拟机：

点击“下一步”然后选择 ISO 镜像文件，我使用的是 RHEL 7.3 iso 镜像。

点击“下一步”。

在接下来的几个窗口中，系统会提示要求您为 VM 分配内存，处理器数量和磁盘空间。

并指定虚拟机名字和桥接网络名：

点击“结束”。

接下来只需要按照屏幕指示安装系统。

#### 使用virt-install命令从命令行界面创建虚拟机

使用下面的 `virt-install` 命令从终端创建一个虚拟机，它将在命令行界面中开始安装，并根据您对虚拟机的名字，说明，ISO 文件位置和桥接配置的设置创建虚拟机。

```
linuxtechi@kvm-ubuntu18-04:~$ sudo virt-install  -n DB-Server  --description "Test VM for Database"  --os-type=Linux  --os-variant=rhel7  --ram=1096  --vcpus=1  --disk path=/var/lib/libvirt/images/dbserver.img,bus=virtio,size=10  --network bridge:br0 --graphics none  --location /home/linuxtechi/rhel-server-7.3-x86_64-dvd.iso --extra-args console=ttyS0

```

本文到此为止，我希望这篇文章能帮助你能够在 Ubuntu 18.04 服务器上成功安装 KVM。 除此之外，KVM 也是 Openstack 默认的管理程序。

阅读更多：“[如何使用 virsh 命令创建，还原和删除 KVM 虚拟机快照](https://www.linuxtechi.com/create-revert-delete-kvm-virtual-machine-snapshot-virsh-command/)”。

---

via: <https://www.linuxtechi.com/install-configure-kvm-ubuntu-18-04-server/>

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

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


使用 Quagga 实现 Linux 动态路由

Summary: 学习如何使用 Quagga 套件的路由协议去管理动态路由。

学习如何使用 Quagga 套件的路由协议去管理动态路由。

# 使用 Quagga 实现 Linux 动态路由

>
> 学习如何使用 Quagga 套件的路由协议去管理动态路由。
>
>
>

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

迄今为止，本系列文章中，我们已经在 [Linux 局域网路由新手指南：第 1 部分](/article-9657-1.html) 中学习了复杂的 IPv4 地址，在 [Linux 局域网路由新手指南：第 2 部分](/article-9675-1.html) 中学习了如何去手工创建静态路由。

今天，我们继续使用 [Quagga](https://www.quagga.net/) 去管理动态路由，这是一个安装完后就不用理它的的软件。Quagga 是一个支持 OSPFv2、OSPFv3、RIP v1 和 v2、RIPng、以及 BGP-4 的路由协议套件，并全部由 zebra 守护程序管理。

OSPF 的意思是<ruby> 最短路径优先 <rt>  Open Shortest Path First </rt></ruby>。OSPF 是一个内部网关协议（IGP）;它可以用在局域网和跨因特网的局域网互联中。在你的网络中的每个 OSPF 路由器都包含整个网络的拓扑，并计算通过网络的最短路径。OSPF 会通过多播的方式自动对外传播它检测到的网络变化。你可以将你的网络分割为区域，以保持路由表的可管理性；每个区域的路由器只需要知道离开它的区域的下一跳接口地址，而不用记录你的网络的整个路由表。

RIP，即路由信息协议，是一个很老的协议，RIP 路由器向网络中周期性多播它的整个路由表，而不是像 OSPF 那样只多播网络的变化。RIP 通过跳数来测量路由，任何超过 15 跳的路由它均视为不可到达。RIP 设置很简单，但是 OSPF 在速度、效率以及弹性方面更佳。

BGP-4 是边界网关协议版本 4。这是用于因特网流量路由的外部网关协议（EGP）。你不会用到 BGP 协议的，除非你是因特网服务提供商。

### 准备使用 OSPF

在我们的小型 KVM 测试实验室中，用两台虚拟机表示两个不同的网络，然后将另一台虚拟机配置为路由器。创建两个网络：net1 是 192.168.110.0/24 ，而 net2 是 192.168.120.0/24。启用 DHCP 是明智的，否则你要分别进入这三个虚拟机，去为它们设置静态地址。Host 1 在 net1 中，Host 2 在 net2 中，而路由器同时与这两个网络连接。设置 Host 1 的网关地址为 192.168.110.126，Host 2 的网关地址为 192.168.120.136。

* Host 1： 192.168.110.125
* Host 2：192.168.120.135
* Router：192.168.110.126 和 192.168.120.136

在路由器上安装 Quagga。在大多数 Linux 中它是 quagga 软件包。在 Debian 上还有一个单独的文档包 quagga-doc。取消 `/etc/sysctl.conf` 配置文件中如下这一行的注释去启用包转发功能：

```
net.ipv4.ip_forward=1

```

然后，运行 `sysctl -p` 命令让变化生效。

### 配置 Quagga

查看你的 Quagga 包中的示例配置文件，比如，`/usr/share/doc/quagga/examples/ospfd.conf.sample`。除非你的 Linux 版本按你的喜好做了创新，否则，一般情况下配置文件应该在 `/etc/quagga` 目录中。大多数 Linux 版本在这个目录下有两个文件，`vtysh.conf` 和 `zebra.conf`。它们提供了守护程序运行所需要的最小配置。除非你的发行版做了一些特殊的配置，否则，zebra 总是首先运行，当你启动 ospfd 的时候，它将自动启动。Debian/Ubuntu 是一个特例，稍后我们将会说到它。

每个路由器守护程序将读取它自己的配置文件，因此，我们必须创建 `/etc/quagga/ospfd.conf`，并输入如下内容：

```
!/etc/quagga/ospfd.conf
hostname router1
log file /var/log/quagga/ospfd.log
router ospf
  ospf router-id 192.168.110.15
  network 192.168.110.0/0 area 0.0.0.0
  network 192.168.120.0/0 area 0.0.0.0
access-list localhost permit 127.0.0.1/32
access-list localhost deny any
line vty
  access-class localhost

```

你可以使用感叹号（`!`）或者井号（`#`）去注释掉这些行。我们来快速浏览一下这些选项。

* `hostname` 可以是你希望的任何内容。这里不是一般意义上的 Linux 主机名，但是，当你使用 `vtysh` 或者 `telnet` 登入时，你将看到它们。
* `log file` 是你希望用于保存日志的任意文件。
* `router` 指定路由协议。
* `ospf router-id` 是任意的 32 位数字。使用路由器的一个 IP 地址就是很好的选择。
* `network` 定义你的路由器要通告的网络。
* `access-list` 限制 `vtysh` 登入，它是 Quagga 命令行 shell，它允许本地机器登入，并拒绝任何远程管理。

### Debian/Ubuntu

在你启动守护程序之前，Debian/Ubuntu 相对其它的 Debian 衍生版可能多需要一步到多步。编辑 `/etc/quagga/daemons` ，除了 `zebra=yes` 和 `ospfd=yes` 外，使其它所有的行的值为 `no`。

然后，在 Debian 上运行 `ospfd` 去启动 Quagga：

```
# systemctl start quagga

```

在大多数的其它 Linux 上，包括 Fedora 和 openSUSE，用如下命令启动 `ospfd`：

```
# systemctl start ospfd

```

现在，Host 1 和 Host 2 将可以互相 ping 通对方和路由器。

这里用了许多篇幅去描述非常简单的设置。在现实中，路由器将连接两个交换机，然后为连接到这个交换机上的所有电脑提供一个网关。你也可以在你的路由器上添加更多的网络接口，这样你的路由器就可以为更多的网络提供路由服务，或者也可以直接连接到其它路由器上，或者连接到连接其它路由器的骨干网络上。

你或许不愿意如此麻烦地手工配置网络接口。最简单的方法是使用你的 DHCP 服务器去宣告你的路由器。如果你使用了 Dnsmasq，那么你就有了一个 DHCP 和 DNS 的一体化解决方案。

还有更多的配置选项，比如，加密的密码保护。更多内容请查看 [Quagga 路由套件](https://www.quagga.net/) 的官方文档。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/3/dynamic-linux-routing-quagga>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


Audacity 快速指南：快速消除背景噪音

Summary: 在这个快速指南中，我们会学习如何使用 Fedora 中的 Audacity 快速移除音频文件中的背景噪音。

# Audacity 快速指南：快速消除背景噪音

当在笔记本电脑上录制声音时 —— 比如首次简单地录屏 —— 许多用户通常使用内置麦克风。但是，这些小型麦克风也会捕获很多背景噪音。在这个快速指南中，我们会学习如何使用 Fedora 中的 [Audacity](https://www.audacityteam.org/) 快速移除音频文件中的背景噪音。

### 安装 Audacity

Audacity 是 Fedora 中用于混合、剪切和编辑音频文件的程序。在 Fedora 上它支持各种开箱即用的格式 - 包括 MP3 和 OGG。从软件中心安装 Audacity。

如果你更喜欢终端，请使用以下命令：

```
sudo dnf install audacity

```

### 导入您的音频、样本背景噪音

安装 Audacity 后，打开程序，使用 “File > Import” 菜单项导入你的声音。这个例子使用了一个[来自 freesound.org 添加了噪音的声音](https://freesound.org/people/levinj/sounds/8323/)：

* <https://ryanlerch.fedorapeople.org/noise.ogg?_=1>

接下来，采样要滤除的背景噪音。导入音轨后，选择仅包含背景噪音的音轨区域。然后从菜单中选择 “Effect > Noise Reduction”，然后按下 “Get Noise Profile” 按钮。

### 过滤噪音

接下来，选择你要过滤噪音的音轨区域。通过使用鼠标进行选择，或者按 `Ctrl + a` 来选择整个音轨。最后，再次打开 “Effect > Noise Reduction” 对话框，然后单击确定以应用滤镜。

此外，调整设置，直到你的音轨听起来更好。这里是原始文件，接下来是用于比较的降噪音轨（使用默认设置）：

* <https://ryanlerch.fedorapeople.org/sidebyside.ogg?_=2>

---

via: <https://fedoramagazine.org/audacity-quick-tip-quickly-remove-background-noise/>

作者：[Ryan Lerch](https://fedoramagazine.org/introducing-flatpak/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


diff 与 patch 的使用

# diff 与 patch 的使用

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

### 摘要

在 Linux 的日常使用中，我们经常需要修改一些配置文件，然而在软件升级以后，经常会面临配置更新后与原配置部分不兼容的问题（当然我们更多的可能是来制作软件升级的补丁）。在这种情况下我们通常有两种选择：

* 对比现有配置，手动在新配置文件中改动
* 利用 `sed`、`awk` 等工具配合改动
* 采用 `diff` 与 `patch` 制作增量补丁的方式改动

本文主要通过一个升级`awesome` 配置的例子，对第三种方法进行介绍和讲解。

### diff 介绍

`diff` 是一个文件比较工具，可以逐行比较两个文件的不同，其中它有三种输出方式，分别是 `normal`， `context` 以及 `unified`。区别如下：

* `normal` 方式为默认输出方式，不需要加任何参数
* `context` 相较于 `normal` 模式的简单输出，`contetx` 模式会输出修改过部分的上下文，默认是前后 **3** 行。使用参数 `-c`
* `unified` 合并上下文模式则为新的上下文输出模式，同样为前后 **3** 行，只不过把上下文合并了显示了。使用参数 `-u`

**注**：本文主要介绍 `unified` 模式

其他常用参数：

* `-r` 递归处理目录
* `-N` 将缺失的文件当作空白文件处理

#### diff 语法与文件格式

```
diff [options] old new

```

先来看一个简单的例子：

```
$ cat test1
linux
linux
linux
linux

```

```
$ cat test2
locez
linux
locez
linux

```

此时输入 `diff -urN test1 test2` 会输出以下信息：

```
--- test1   2018-05-12 18:39:41.508375114 +0800
+++ test2   2018-05-12 18:41:00.124031736 +0800
@@ -1,4 +1,4 @@
+locez
 linux
-linux
-linux
+locez
 linux

```

先看前面 2 行，这两行为文件的基本信息，`---` 开头为改变前的文件，`+++` 开头为更新后的文件。

```
--- test1   2018-05-12 18:39:41.508375114 +0800
+++ test2   2018-05-12 18:41:00.124031736 +0800

```

第三行为上下文描述块，其中 `-1,4` 为旧文件的 4 行上下文，`+1,4` 为新文件的：

```
@@ -1,4 +1,4 @@

```

而具体到块里面的内容，前面有 `-` 号的则为删除，有 `+` 号为新增，不带符号则未做改变，仅仅是上下文输出。

### patch 介绍

`patch` 是一个可以将 `diff` 生成的**补丁**应用到源文件，生成一个打过补丁版本的文件。语法：

```
patch [oiption] [originalfile [patchfile]]

```

常用参数：

* `-i` 指定补丁文件
* `-pNum` 在 `diff` 生成的补丁中，第一二行是文件信息，其中文件名是可以包含路径的，例如 `--- /tmp/test1 2018-05-12 18:39:41.508375114 +0800` 其中 `-p0` 代表完整的路径 `/tmp/test1`，而 `-p1` 则指 `tmp/test1`，`-pN` 依此类推
* `-E` 删除应用补丁后为空文件的文件
* `-o` 输出到一个文件而不是直接覆盖文件

### 应用

awesome 桌面 3.5 与 4.0 之间的升级是不兼容的，所以在升级完 4.0 以后，awesome 桌面部分功能无法使用，因此需要迁移到新配置，接下来则应用 `diff` 与 `patch` 实现迁移，当然你也可以单纯使用 `diff` 找出不同，然后手动修改新配置。

现在有以下几个文件：

* `rc.lua.3.5` 3.5 版本的默认配置文件，未修改
* `rc.lua.myconfig` 基于 3.5 版本的个人配置文件
* `rc.lua.4.2` 4.2 新默认配置，未修改

思路为利用 `diff` 提取出个人配置与 3.5 默认配置文件的增量补丁，然后把补丁应用在 4.2 的文件上实现迁移。

#### 制作补丁

```
$ diff -urN rc.lua.3.5 rc.lua.myconfig  > mypatch.patch

```

#### 应用补丁

```
$ patch rc.lua.4.2 -i mypatch.patch -o rc.lua
patching file rc.lua (read from rc.lua.4.2)
Hunk #1 FAILED at 38.
Hunk #2 FAILED at 55.
Hunk #3 succeeded at 101 with fuzz 1 (offset 5 lines).
Hunk #4 succeeded at 276 with fuzz 2 (offset 29 lines).
2 out of 4 hunks FAILED -- saving rejects to file rc.lua.rej

```

显然应用没有完全成功，其中在 38 行以及 55 行应用失败，并记录在 `rc.lua.rej` 里。

```
$ cat rc.lua.rej
--- rc.lua.3.5  2018-05-12 19:15:54.922286085 +0800
+++ rc.lua.myconfig 2018-05-12 19:13:35.057911463 +0800
@@ -38,10 +38,10 @@

 -- {{{ Variable definitions
 -- Themes define colours, icons, font and wallpapers.
-beautiful.init("@AWESOME_THEMES_PATH@/default/theme.lua")
+beautiful.init("~/.config/awesome/default/theme.lua")

 -- This is used later as the default terminal and editor to run.
-terminal = "xterm"
+terminal = "xfce4-terminal"
 editor = os.getenv("EDITOR") or "nano"
 editor_cmd = terminal .. " -e " .. editor

@@ -55,18 +55,18 @@
 -- Table of layouts to cover with awful.layout.inc, order matters.
 local layouts =
 {
-    awful.layout.suit.floating,
-    awful.layout.suit.tile,
-    awful.layout.suit.tile.left,
-    awful.layout.suit.tile.bottom,
-    awful.layout.suit.tile.top,
+--    awful.layout.suit.floating,
+--    awful.layout.suit.tile,
+--    awful.layout.suit.tile.left,
+--    awful.layout.suit.tile.bottom,
+--    awful.layout.suit.tile.top,
     awful.layout.suit.fair,
     awful.layout.suit.fair.horizontal,
     awful.layout.suit.spiral,
     awful.layout.suit.spiral.dwindle,
     awful.layout.suit.max,
     awful.layout.suit.max.fullscreen,
-    awful.layout.suit.magnifier
+--    awful.layout.suit.magnifier
 }
 -- }}}

```

这里是主题，终端，以及常用布局的个人设置。

#### 修正补丁

再次通过对比补丁文件与 4.2 文件，发现 38 行区块是要删除的东西不匹配，而 55 行区块则是上下文与要删除的内容均不匹配，导致不能应用补丁，于是手动修改补丁

```
$ vim mypatch.patch

```

```
--- rc.lua.3.5  2018-05-12 19:15:54.922286085 +0800
+++ rc.lua.myconfig 2018-05-12 19:13:35.057911463 +0800
@@ -38,10 +38,10 @@

 -- {{{ Variable definitions
 -- Themes define colours, icons, font and wallpapers.
-beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
+beautiful.init("~/.config/awesome/default/theme.lua")

 -- This is used later as the default terminal and editor to run.
-terminal = "xterm"
+terminal = "xfce4-terminal"
 editor = os.getenv("EDITOR") or "nano"
 editor_cmd = terminal .. " -e " .. editor

@@ -55,18 +55,18 @@

 -- Table of layouts to cover with awful.layout.inc, order matters.
 awful.layout.layouts = {
-    awful.layout.suit.floating,
-    awful.layout.suit.tile,
-    awful.layout.suit.tile.left,
-    awful.layout.suit.tile.bottom,
-    awful.layout.suit.tile.top,
+--    awful.layout.suit.floating,
+--    awful.layout.suit.tile,
+--    awful.layout.suit.tile.left,
+--    awful.layout.suit.tile.bottom,
+--    awful.layout.suit.tile.top,
     awful.layout.suit.fair,
     awful.layout.suit.fair.horizontal,
     awful.layout.suit.spiral,
     awful.layout.suit.spiral.dwindle,
     awful.layout.suit.max,
     awful.layout.suit.max.fullscreen,
-    awful.layout.suit.magnifier,
+--    awful.layout.suit.magnifier,
     awful.layout.suit.corner.nw,
     -- awful.layout.suit.corner.ne,
     -- awful.layout.suit.corner.sw,
....
....

```

输出省略显示，有兴趣的读者可以仔细与`rc.lua.rej` 文件对比，看看笔者是怎样改的。

#### 再次应用补丁

```
$ patch rc.lua.4.2 -i mypatch.patch -o rc.lua
patching file rc.lua (read from rc.lua.4.2)
Hunk #1 succeeded at 41 (offset 3 lines).
Hunk #2 succeeded at 57 with fuzz 2 (offset 2 lines).
Hunk #3 succeeded at 101 with fuzz 1 (offset 5 lines).
Hunk #4 succeeded at 276 with fuzz 2 (offset 29 lines).
$ cp rc.lua ~/.config/awesome/rc.lua  ### 打完补丁直接使用

```

### 总结

`diff` 与 `patch` 配合使用，能当增量备份，而且还可以将补丁分发给他人使用，而且在日常的软件包打补丁也具有重要的意义，特别是内核补丁或者一些驱动补丁，打补丁遇到错误时候可以尝试自己修改，已满足自身特殊要求，修改的时候一定要抓住 2 个非常重要的要素：

1. 要修改的内容是否匹配？特别是要删除的
2. 上下文是否满足，特别是距离要修改的地方前后一行，以及上下文的行数是否满足，默认是 3 行上下文


异步决策：帮助远程团队走向成功

Summary: 更好的沟通和少量的会议并不是白日梦。这里告诉您异步决策是如何实现这一切的。

更好的沟通和少量的会议并不是白日梦。这里告诉您异步决策是如何实现这一切的。

# 异步决策：帮助远程团队走向成功

>
> 更好的沟通和少量的会议并不是白日梦。这里告诉您异步决策是如何实现这一切的。
>
>
>

异步决策能够让地理和文化上分散的软件团队更有效率地做出决策。本文就将讨论一下实现异步决策所需要的一些原则和工具。

同步决策，要求参与者实时地进行互动，而这对那些需要<ruby>   大块完整时间工作  <rt>  Maker's Schedule </rt></ruby>的人来说代价非常大，而且对于远程团队来说这也不现实。我们会发现这种会议最后浪费的时间让人难以置信。

相比之下，异步决策常应用于大型开源项目中（比如我常参与的 Apache 软件基金会 ASF）。它为团队提供了一种尽可能少开会的有效方法。很多开源项目每年只开很少的几次会议（有的甚至完全没开过会），然而开发团队却始终如一地在生产高质量的软件。

怎样才能异步决策呢？

### 所需工具

#### 中心化的异步沟通渠道

异步决策的第一步就是构建一个中心化的异步沟通渠道。你所使用的技术必须能让所有的团队成员都获得同样的信息，并能进行<ruby> 线索讨论 <rt>  threaded discussions </rt></ruby>，也就是说你要既能对一个主题进行发散也要能封禁其他主题的讨论。想一想航海专用无线电台，其中广播渠道的作用只是为了引起特定人员的注意，这些人然后再创建一个子渠道来进行详细的讨论。

很多开源项目依旧使用邮件列表作为中心渠道，不过很多新一代的软件开发者可能会觉得这个方法又古老又笨拙。邮件列表需要遵循大量的准则才能有效的管理热门项目，比如你需要进行有意义的引用，每个线索只讨论一个主题，保证 [标题与内容相吻合](https://grep.codeconsult.ch/2017/11/10/large-mailing-lists-survival-guide/)。虽然这么麻烦，但使用得当的话，再加上一个经过索引的归档系统，邮件列表依然在创建中心渠道的工具中占据绝对主导的地位。

公司团队可以从一个更加现代化的协作工具中收益，这类工具更易使用并提供了更加强大的多媒体功能。不管你用的是哪个工具，关键在于要创建一个能让大量的人员有效沟通并异步地讨论各种主题的渠道。要创建一个一致而活跃的社区，使用一个 [繁忙的渠道要好过建立多个渠道](https://grep.codeconsult.ch/2011/12/06/stefanos-mazzocchis-busy-list-pattern/)。

#### 构建共识的机制

第二个工具是一套构建共识的机制，这样你才不会陷入死循环从而确保能做出决策。做决策最理想的情况就是一致同意，而次佳的就是达成共识，也就是 “有决策权的人之间广泛形成了一致的看法”。强求完全一致的赞同或者允许一票否决都会阻碍决策的制定，因此 ASF 中只在非常有限的决策类型中允许否决权。[ASF 投票制度](http://www.apache.org/foundation/voting.html) 为类似 ASF 这样没有大老板的松散组织构建了一个久经考验的，用于达成共识的好方法。当共识无法自然产生时也可以使用该套制度。

#### 案例管理系统

如上所述，我们通常在项目的中心渠道中构建共识。但是在讨论一些复杂的话题时，使用案例管理系统这一第三方的工具很有意义。小组可以使用中心渠道专注于非正式的讨论和头脑风暴上，当讨论要转变成一个决策时将其转到一个更加结构化的案例管理系统中去。

案例管理系统能够更精确地组织决策。小型团队不用做太多决策可以不需要它，但很多团队会发现能有一个相对独立的地方讨论决策的细节并保存相关信息会方便很多。

案例管理系统不一定就是个很复杂的软件; 在 ASF 中我们所使用的只是简单的问题跟踪软件而已，这些基于网页的系统原本是创建来进行软件支持和 bug 管理的。每个案例列在一个单独的网页上，还有一些历史的注释和动作信息。该途径可以很好的追踪决策是怎么制定出来的。比如，某些非紧急的决策或者复杂的决策可能会花很长时间才会制定出来，这时有一个地方能够了解这些决策的历史就很有用了。新来的团队成员也能很快地了解到最近做出了哪些决策，哪些决策还在讨论，每个决策都有那些人参与其中，每个决策的背景是什么。

### 成功的案例

ASF 董事会中的九名董事在每个月的电话会议上只做很少的一些决策，耗时不超过 2 个小时。在准备这些会议之前，大多数的决策都预先通过异步的方式决定好了。这使得我们可以在会议上集中讨论复杂和难以确定的问题，而不是讨论那些已经达成普遍或部分共识的问题上。

软件世界外的一个有趣的案例是 [瑞士联邦委员会的周会](https://www.admin.ch/gov/en/start/federal-council/tasks/decision-making/federal-council-meeting.html)，它的运作方式跟 ASF 很类似。团队以异步决策构建共识的方式来准备会议。会议议程由一组不同颜色编码的列表组成，这些颜色标识了那些事项可以很快通过批准，那些事项需要进一步的讨论，哪些事项特别的复杂。这使得只要 7 个人就能每年忙完超过 2500 项决策，共 50 个周会，每个周会只需要几个小时时间。我觉得这个效率已经很高了。

就我的经验来看，异步决策带来的好处完全值得上为此投入的时间和工具。而且它也能让团队成员更快乐，这也是成功的关键因素之一。

---

via: <https://opensource.com/article/17/12/asynchronous-decision-making>

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

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


最小权限的容器编排

# 最小权限的容器编排

Docker 平台和容器已经成为打包、部署、和管理应用程序的标准。为了在一个集群内协调跨节点的容器，必须有一个关键的能力：一个容器编排器。

对于关键的集群化以及计划的任务，编排器是起重大作用的，比如：

* 管理容器计划和资源分配。
* 支持服务发现和无缝的应用程序部署。
* 分配应用程序运行必需的资源。

不幸的是，在这种环境下，编排器的分布式特性和资源的短暂性使得确保编排器的安全是一个极具挑战性的任务。在这篇文章中，我们将讨论容器编排器安全模型中没有考虑到的、但是很重要的这方面的详细情况，以及 Docker 企业版中如何使用内置的编排性能、Swarm 模式，去克服这些问题。

### 诱因和威胁模型

使用 swarm 模式的 Docker 企业版的其中一个主要目标是提供一个内置安全特性的编排器。为达到这个目标，我们部署了第一个在我们心目中认为的以最小权限原则设计的容器编排器。

在计算机科学中，一个分布式系统所要求的最小权限原则是，系统中的每个参与者仅仅能访问它正当目的所需要的信息和资源。不是更多，也不是更少。

>
> “一个进程必须仅仅能去访问它的正当目的所需要的信息和资源”
>
>
>

#### 最小权限原则

在一个 Docker 企业版集群中的每个节点分配的角色：既不是管理者（manager），也不是工人（worker）。这些角色为节点定义了一个很粗粒度的权限级别：分别进行管理和任务执行。尽管如此，不用理会它的角色，通过使用加密的方式，来保证一个节点仅仅有执行它的任务所需要的信息和资源。结果是，确保集群安全变得更容易了，甚至可以防止大多数的有经验的攻击者模式：攻击者控制了底层通讯网络，或者甚至攻陷了集群节点。

### 内核缺省安全

这是一个很老的安全最大化状态：如果它不是缺省的，就没人用它。Docker Swarm 模式将缺省安全这一概念融入了核心，并且使用这一机制去解决编排器生命周期中三个很难并且很重要的部分：

1. 可信引导和节点引入。
2. 节点身份发布和管理。
3. 认证、授权和加密的信息存储和传播。

我们来分别看一下这三个部分：

#### 可信引导和节点引入

确保集群安全的第一步，没有别的，就是严格控制成员和身份。管理员不能依赖它们节点的身份，并且在节点之间强制实行绝对的负载隔离。这意味着，未授权的节点不能允许加入到集群中，并且，已经是集群一部分的节点不能改变身份，突然去伪装成另一个节点。

为解决这种情况，通过 Docker 企业版 Swarm 模式管理的节点，维护了健壮的、不可改变的身份。期望的特性是，通过使用两种关键的构建块去保证加密：

1. 为集群成员使用<ruby> 安全加入令牌 <rt>  Secure join token </rt></ruby>。
2. 从一个集中化的认证机构发行的内嵌唯一身份的证书。

##### 加入 Swarm

要加入 Swarm，节点需要一份<ruby> 安全加入令牌 <rt>  Secure join token </rt></ruby>的副本。在集群内的每个操作角色的令牌都是独一无二的 —— 现在有两种类型的节点：工人（workers）和管理者（managers）。由于这种区分，拥有一个工人令牌的节点将不允许以管理者角色加入到集群。唯一得到这个特殊令牌的方式是通过 swarm 的管理 API 去向集群管理者请求一个。

令牌是安全的并且是随机生成的，它还有一个使得令牌泄露更容易被检测到的特殊语法：一个可以在你的日志和仓库中很容易监视的特殊前缀。幸运的是，即便发现一个泄露，令牌也可以很容易去更新，并且，推荐你经常去更新它们 —— 特别是，在一段时间中你的集群不进行扩大的情况下。

##### 引导信任

作为它的身份标识创建的一部分，一个新的节点将向任意一个网络管理者请求发布一个新的身份。但是，在我们下面的威胁模型中，所有的通讯可以被一个第三方拦截。这种请求存在的问题是：一个节点怎么知道与它进行对话的对方是合法的管理者？

幸运的是，Docker 有一个内置机制可以避免这种情况。这个加入令牌被主机用于加入 Swarm，包含了一个根 CA 证书的哈希串。所以，主机可以使用单向 TLS，并且使用这个哈希串去验证它加入的 Swarm 是否正确：如果管理者持有的证书没有被正确的 CA 哈希串签名，节点就知道它不可信任。

#### 节点身份发布和管理

在一个 Swarm 中，身份标识是内嵌在每个节点都单独持有的一个 x509 证书中。在一个最小权限原则的表现形式中，证书的私钥被绝对限制在主机的原始位置。尤其是，管理者不能访问除了它自己的私钥以外的任何一个私钥。

##### 身份发布

要接收它们的证书而无需共享它们的私钥，新的主机通过发布一个证书签名请求（CSR）来开始，管理者收到证书签名请求之后，转换成一个证书。这个证书成为这个新的主机的身份标识，使这个节点成为 Swarm 的一个完全合格成员！

当和安全引导机制一起使用时，发行身份标识的这个机制来加入节点是缺省安全的：所有的通讯部分都是经过认证的、授权的，并且非敏感信息从来都不会以明文方式进行交换。

##### 身份标识延期

尽管如此，给一个 Swarm 中安全地加入节点，仅仅是 “故事” 的一部分。为降低证书的泄露或者失窃造成的影响，并且移除管理 CRL 列表的复杂性，Swarm 模式为身份标识使用了较短存活周期的证书。这些证书缺省情况下三个月后将过期，但是，也可以配置为一个小时后即刻过期！

较短的证书过期时间意味着不能手动去处理证书更新，所以，通常会使用一个 PKI 系统。对于 Swarm，所有的证书是以一种不中断的方式进行自动更新的。这个过程很简单：使用一个相互认证的 TLS 连接去证明一个特定身份标识的所有者，一个 Swarm 节点定期生成一个新的公钥/私钥密钥对，并且用相关的 CSR 去签名发送，创建一个维持相同身份标识的完整的新证书。

#### 经过认证、授权、和加密的信息存储和传播。

在一个正常的 Swarm 的操作中，关于任务的信息被发送给去运行的工人（worker）节点。这里不仅仅包含将被一个节点运行的容器的信息；也包含那个容器运行所必需的资源的所有信息，包括敏感的机密信息，比如，私钥、密码和 API 令牌。

##### 传输安全

事实上，参与 Swarm 的每个节点都拥有一个独一无二的 X509 格式的证书，因此，节点之间的通讯安全是没有问题的：节点使用它们各自的证书，与另一个连接方进行相互认证、继承机密、真实性、和 TLS 的完整性。

关于 Swarm 模式的一个有趣的细节是，本质上它是使用了一个推送模式：仅管理者被允许去发送信息到工人们（workers）—— 显著降低了暴露在低权限的工人节点面前的管理者节点的攻击面。

##### 将负载严格隔离进安全区域

管理者节点的其中一个责任是，去决定发送到每个工人（worker）节点的任务是什么。管理者节点使用多种策略去做这个决定；根据每个节点和每个负载的特性，去跨 Swarm 去安排负载。

在使用 Swarm 模式的 Docker 企业版中，管理者节点通过使用附加到每个单个节点标识上的安全标签，去影响这些安排决定。这些标签允许管理者将节点组与不同的安全区域连接到一起，以限制敏感负载暴露，以及使相关机密信息更安全。

##### 安全分发机密

除了加快身份标识发布过程之外，管理者节点还有存储和分发工人节点所需要的任何资源的任务。机密信息像任何其它类型的资源一样处理，并且基于安全的 mTLS 连接，从管理者推送到工人节点。

在主机上，Docker 企业版能确保机密仅提供给它们指定的容器。在同一个主机上的其它容器并不能访问它们。Docker 以一个临时文件系统的方式显露机密给一个容器，确保机密总是保存在内存中，并且从不写入到磁盘。这种方式比其它竞争的替代者更加安全，比如，[在环境变量中存储它们](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/)。一旦这个任务完成，这个机密将永远消失。

##### 存储机密

在管理者主机上的机密总是保持加密的。缺省情况下，加密这些机密的密钥（被称为数据加密密钥，DEK）是以明文的方式存储在硬盘上的。这使得那些对安全性要求较低的人可以轻松地去使用 Docker Swarm 模式。

但是，如果你运行一个生产集群，我们推荐你启用自动锁定模式。当自动锁定模式启用后，一个重新更新过的 DEK 被一个独立的加密密钥的密钥（KEK）所加密。这个密钥从不被存储在集群中；管理者有责任将它存储在一个安全可靠的地方，并且当集群启动的时候可以提供它。这就是所谓的 “解锁” Swarm。

根据 Raft 故障容错一致性算法，Swarm 模式支持多个管理者。在这个场景中，无缝扩展了机密存储的安全性。每个管理者主机除了共享密钥之外，还有一个唯一的磁盘加密密钥。幸运的是，Raft 日志在磁盘上也是加密的，并且，在自动锁定模式下，没有 KEK 同样是不可访问的。

#### 当一个节点被攻陷后发生了什么？

在传统的编排器中，挽回一台被攻陷的主机是一个缓慢而复杂的过程。使用 Swarm 模式，恢复它就像运行一个 Docker 节点的 `rm` 命令一样容易。这是从集群中删除一个受影响的节点，而 Docker 将去处理剩下的事情，即，重新均衡负载，并且确保其它的主机已经知道，而不会去与受影响的节点通讯。

正如我们看到的那样，感谢最小权限的编排器，甚至是，如果攻击者在主机上持续活动，它们将被从剩余的网络上切断。主机的证书 —— 它的身份标识 —— 被列入黑名单，因此，管理者也不能有效访问它。

### 结论

使用 Swarm 模式的 Docker 企业版，在缺省情况下确保了编排器的所有关键区域的安全：

* 加入集群。阻止恶意节点加入到集群。
* 把主机分组为安全区域。阻止攻击者的横向移动。
* 安排任务。任务将仅被委派到允许的节点。
* 分配资源。恶意节点不能 “盗取” 其它的负载或者资源。
* 存储机密。从不明文保存并且从不写入到工人节点的磁盘上。
* 与工人节点的通讯。使用相互认证的 TLS 加密。

因为 Swarm 模式的持续改进，Docker 团队正在努力将最小权限原则进一步推进。我们正在处理的一个任务是：如果一个管理者被攻陷了，怎么去保证剩下的节点的安全？路线图已经有了，其中一些功能已经可以使用，比如，白名单功能，仅允许特定的 Docker 镜像，阻止管理者随意运行负载。这是通过 Docker 可信内容来实现的。

---

via: <https://blog.docker.com/2017/10/least-privilege-container-orchestration/>

作者：[Diogo Mónica](https://blog.docker.com/author/diogo/) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


Go 程序的持续分析

Summary: Google 最有趣的部分之一就是我们规模庞大的持续分析服务。

Google 最有趣的部分之一就是我们规模庞大的持续分析服务。

# Go 程序的持续分析

Google 最有趣的部分之一就是我们规模庞大的持续分析服务。我们可以看到谁在使用 CPU 和内存，我们可以持续地监控我们的生产服务以争用和阻止配置文件，并且我们可以生成分析和报告，并轻松地告诉我们可以进行哪些有重要影响的优化。

我简单研究了 [Stackdriver Profiler](https://cloud.google.com/profiler/)，这是我们的新产品，它填补了针对云端用户在云服务范围内分析服务的空白。请注意，你无需在 Google 云平台上运行你的代码即可使用它。实际上，我现在每天都在开发时使用它。它也支持 Java 和 Node.js。

### 在生产中分析

pprof 可安全地用于生产。我们针对 CPU 和堆分配分析的额外会增加 5% 的开销。一个实例中每分钟收集 10 秒。如果你有一个 Kubernetes Pod 的多个副本，我们确保进行分摊收集。例如，如果你拥有一个 pod 的 10 个副本，模式，那么开销将变为 0.5％。这使用户可以一直进行分析。

我们目前支持 Go 程序的 CPU、堆、互斥和线程分析。

### 为什么？

在解释如何在生产中使用分析器之前，先解释为什么你想要在生产中进行分析将有所帮助。一些非常常见的情况是：

* 调试仅在生产中可见的性能问题。
* 了解 CPU 使用率以减少费用。
* 了解争用的累积和优化的地方。
* 了解新版本的影响，例如看到 canary 和产品级之间的区别。
* 通过[关联](https://rakyll.org/profiler-labels/)分析样本以了解延迟的根本原因来丰富你的分布式经验。

### 启用

Stackdriver Profiler 不能与 `net/http/pprof` 处理程序一起使用，并要求你在程序中安装和配置一个一行的代理。

```
go get cloud.google.com/go/profiler

```

在你的主函数中，启动分析器：

```
if err := profiler.Start(profiler.Config{
   Service:        "indexing-service",
   ServiceVersion: "1.0",
   ProjectID:      "bamboo-project-606", // optional on GCP
}); err != nil {
   log.Fatalf("Cannot start the profiler: %v", err)
}

```

当你运行你的程序后，profiler 包将每分钟报告给分析器 10 秒钟。

### 可视化

当分析被报告给后端后，你将在 <https://console.cloud.google.com/profiler> 上看到火焰图。你可以按标签过滤并更改时间范围，也可以按服务名称和版本进行细分。数据将会长达 30 天。

你可以选择其中一个分析，按服务，区域和版本分解。你可以在火焰中移动并通过标签进行过滤。

### 阅读火焰图

[Brendan Gregg](http://www.brendangregg.com/flamegraphs.html) 非常全面地解释了火焰图可视化。Stackdriver Profiler 增加了一点它自己的特点。

我们将查看一个 CPU 分析，但这也适用于其他分析。

1. 最上面的 x 轴表示整个程序。火焰上的每个框表示调用路径上的一帧。框的宽度与执行该函数花费的 CPU 时间成正比。
2. 框从左到右排序，左边是花费最多的调用路径。
3. 来自同一包的帧具有相同的颜色。这里所有运行时功能均以绿色表示。
4. 你可以单击任何框进一步展开执行树。

你可以将鼠标悬停在任何框上查看任何帧的详细信息。

### 过滤

你可以显示、隐藏和高亮符号名称。如果你特别想了解某个特定调用或包的消耗，这些信息非常有用。

1. 选择你的过滤器。你可以组合多个过滤器。在这里，我们将高亮显示 `runtime.memmove`。
2. 火焰将使用过滤器过滤帧并可视化过滤后的框。在这种情况下，它高亮显示所有 `runtime.memmove` 框。

---

via: <https://medium.com/google-cloud/continuous-profiling-of-go-programs-96d4416af77b>

作者：[JBD](https://medium.com/@rakyll?source=post_header_lockup) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何使用 Arduino 制作一个绘图仪

Summary: 使用开源硬件和软件的 DIY 绘图仪可以自动地绘制、雕刻。

使用开源硬件和软件的 DIY 绘图仪可以自动地绘制、雕刻。

# 如何使用 Arduino 制作一个绘图仪

>
> 使用开源硬件和软件的 DIY 绘图仪可以自动地绘制、雕刻。
>
>
>

在上学时，科学系的壁橱里藏着一台惠普绘图仪。虽然我在上学的期间可以经常使用它，但我还是想拥有一台属于自己的绘图仪。许多年之后，步进电机已经很容易获得了，我又在从事电子产品和微控制器方面的工作，最近，我看到有人用丙烯酸塑料（acrylic）制作了一个显示器。这件事启发了我，并最终制作了我自己的绘图仪。

*我 DIY 的绘图仪；在这里看它工作的[视频](https://twitter.com/pilhuhn/status/948205323726344193)。*

由于我是一个很怀旧的人，我真的很喜欢最初的 [Arduino Uno](https://en.wikipedia.org/wiki/Arduino#Official_boards)。下面是我用到的其它东西的一个清单（仅供参考，其中一些我也不是很满意）：

* [FabScan shield](http://www.watterott.com/de/Arduino-FabScan-Shield)：承载步进电机驱动器。
* [SilentStepSticks](http://www.watterott.com/de/SilentStepStick-TMC2130)：步进电机驱动器，因为 Arduino 自身不能处理步进电机所需的电压和电流。因此我使用了一个 Trinamic TMC2130 芯片，但它是工作在单独模式。这些替换为 Pololu 4988，但是它们运转更安静。
* [SilentStepStick 保护装置](http://www.watterott.com/de/SilentStepStick-Protector)：一个防止你的电机驱动器转动过快的二极管（相信我，你肯定会需要它的）。
* 步进电机：我选择的是使用 12 V 电压的 NEMA 17 电机（如，来自 [Watterott](http://www.watterott.com/de/Schrittmotor-incl-Anschlusskabel) 和 [SparkFun](https://www.sparkfun.com/products/9238) 的型号）。
* [直线导杆](https://www.ebay.de/itm/CNC-Set-12x-600mm-Linearfuhrung-Linear-Guide-Rail-Stage-3D-/322917927292?hash=item4b2f68897c)
* 木制的基板
* 木螺丝
* GT2 皮带
* [GT2 同步滑轮](http://www.watterott.com/de/OpenBuilds-GT2-2mm-Aluminium-Timing-Pulley)

这是我作为个人项目而设计的。如果你想找到一个现成的工具套件，你可以从 German Make 杂志上找到 [MaXYposi](https://www.heise.de/make/artikel/MaXYposi-Projektseite-zum-universellen-XY-Portalroboter-von-Make-3676050.html)。

### 硬件安装

正如你所看到的，我刚开始做的太大了。这个绘图仪并不合适放在我的桌子上。但是，没有关系，我只是为了学习它（并且，我也将一些东西进行重新制作，下次我将使用一个更小的横梁）。

*带 X 轴和 Y 轴轨道的绘图仪基板*

皮带安装在轨道的侧面，并且用它将一些辅助轮和电机挂在一起：

*电机上的皮带路由*

我在 Arduino 上堆叠了几个组件。Arduino 在最下面，它之上是 FabScan shield，接着是一个安装在 1 和 2 号电机槽上的 StepStick 保护装置，SilentStepStick 在最上面。注意，SCK 和 SDI 针脚没有连接。

*Arduino 堆叠配置（[高清大图](https://www.dropbox.com/s/7bp3bo5g2ujser8/IMG_20180103_110111.jpg?dl=0)）*

注意将电机的连接线接到正确的针脚上。如果有疑问，就去查看它的数据表，或者使用欧姆表去找出哪一对线是正确的。

### 软件配置

#### 基础部分

虽然像 [grbl](https://github.com/gnea/grbl) 这样的软件可以解释诸如像装置移动和其它一些动作的 G-codes，并且，我也可以将它刷进 Arduino 中，但是我很好奇，想更好地理解它是如何工作的。（我的 X-Y 绘图仪软件可以在 [GitHub](https://github.com/pilhuhn/xy-plotter) 上找到，不过我不提供任何保修。）

使用 StepStick（或者其它兼容的）驱动器去驱动步进电机，基本上只需要发送一个高电平信号或者低电平信号到各自的针脚即可。或者使用 Arduino 的术语：

```
digitalWrite(stepPin, HIGH);
delayMicroseconds(30);
digitalWrite(stepPin, LOW);

```

在 `stepPin` 的位置上是步进电机的针脚编号：3 是 1 号电机，而 6 是 2 号电机。

在步进电机能够工作之前，它必须先被启用。

```
digitalWrite(enPin, LOW);

```

实际上，StepStick 能够理解针脚的三个状态：

* Low：电机已启用
* High：电机已禁用
* Pin 未连接：电机已启用，但在一段时间后进入节能模式

电机启用后，它的线圈已经有了力量并用来保持位置。这时候几乎不可能用手来转动它的轴。这样可以保证很好的精度，但是也意味着电机和驱动器芯片都“充满着”力量，并且也因此会发热。

最后，也是很重要的，我们需要一个决定绘图仪方向的方法：

```
digitalWrite(dirPin, direction);

```

下面的表列出了功能和针脚：

| 功能 | 1 号电机 | 2 号电机 |
| --- | --- | --- |
| 启用 | 2 | 5 |
| 方向 | 4 | 7 |
| 步进 | 3 | 6 |

在我们使用这些针脚之前，我们需要在代码的 `setup()` 节中设置它的 `OUTPUT` 模式。

```
pinMode(enPin1, OUTPUT);
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
digitalWrite(enPin1, LOW);

```

了解这些知识后，我们可以很容易地让步进电机四处移动：

```
    totalRounds = ...
    for (int rounds =0 ; rounds < 2*totalRounds; rounds++) {
       if (dir==0){ // set direction
         digitalWrite(dirPin2, LOW);
       } else {
         digitalWrite(dirPin2, HIGH);
       }
       delay(1); // give motors some breathing time
       dir = 1-dir; // reverse direction
       for (int i=0; i < 6400; i++) {
         int t = abs(3200-i) / 200;
         digitalWrite(stepPin2, HIGH);
         delayMicroseconds(70 + t);
         digitalWrite(stepPin2, LOW);
         delayMicroseconds(70 + t);
       }
    }

```

这将使滑块向左和向右移动。这些代码只操纵一个步进电机，但是，对于一个 X-Y 绘图仪，我们要考虑两个轴。

#### 命令解释器

我开始做一个简单的命令解释器去使用规范的路径，比如：

```
"X30|Y30|X-30 Y-30|X-20|Y-20|X20|Y20|X-40|Y-25|X40 Y25

```

用毫米来描述相对移动（1 毫米等于 80 步）。

绘图仪软件实现了一个 *持续模式* ，这可以允许一台 PC 给它提供一个很大的路径（很多的路径）去绘制。（在这个[视频](https://twitter.com/pilhuhn/status/949737734654124032)中展示了如何绘制 Hilbert 曲线）

### 设计一个好用的握笔器

在上面的第一张图中，绘图笔是细绳子绑到 Y 轴上的。这样绘图也不精确，并且也无法在软件中实现提笔和下笔（如示例中的大黑点）。

因此，我设计了一个更好用的、更精确的握笔器，它使用一个伺服器去提笔和下笔。可以在下面的这张图中看到这个新的、改进后的握笔器，上面视频链接中的 Hilbert 曲线就是使用它绘制的。

*图中的特写镜头就是伺服器臂提起笔的图像*

笔是用一个小夹具固定住的（图上展示的是一个大小为 8 的夹具，它一般用于将线缆固定在墙上）。伺服器臂能够提起笔；当伺服器臂放下来的时候，笔就会被放下来。

#### 驱动伺服器

驱动伺服器是非常简单的：只需要提供位置，伺服器就可以完成所有的工作。

```
#include <Servo.h>

// Servo pin
#define servoData PIN_A1

// Positions
#define PEN_UP 10
#define PEN_DOWN 50

Servo penServo;

void setup() {
  // Attach to servo and raise pen
  penServo.attach(servoData);
  penServo.write(PEN_UP);
}

```

我把伺服器接头连接在 FabScan shield 的 4 号电机上，因此，我将用 1 号模拟针脚。

放下笔也很容易：

```
  penServo.write(PEN_DOWN);

```

### 进一步扩展

我的进一步扩展的其中一项就是添加一些终止检测器，但是，我也可以不用它们，进而使用 TMC2130 的 StallGuard 模式来代替。这些检测器也可以用于去实现一个 `home` 命令。

以后，我或许还将添加一个真实的 Z 轴，这样它就可以对一个木头进行铣削雕刻，或者钻一个 PCB 板，或者雕刻一块丙烯酸塑料，或者 … （我还想到了用激光）。

这篇文章最初发布在 [Some Things to Remember](http://pilhuhn.blogspot.com/2018/01/homegrown-xy-plotter-with-arduino.html) 博客中并授权重分发。

---

via: <https://opensource.com/article/18/3/diy-plotter-arduino>

作者：[Heiko W.Rupp](https://opensource.com/users/pilhuhn) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 系统中结束进程或是中止程序

Summary: 在 Linux 中有几种使用命令行或图形界面终止一个程序的方式。

在 Linux 中有几种使用命令行或图形界面终止一个程序的方式。

# 如何在 Linux 系统中结束进程或是中止程序

>
> 在 Linux 中有几种使用命令行或图形界面终止一个程序的方式。
>
>
>

进程出错的时候，您可能会想要中止或是杀掉这个进程。在本文中，我们将探索在命令行和图形界面中终止进程或是应用程序，这里我们使用 [gedit](https://wiki.gnome.org/Apps/Gedit) 作为样例程序。

### 使用命令行或字符终端界面

#### Ctrl + C

在命令行中调用 `gedit` （如果您没有使用 `gedit &` 命令）程序的一个问题是 shell 会话被阻塞，没法释放命令行提示符。在这种情况下，`Ctrl + C` （`Ctrl` 和 `C` 的组合键） 会很管用。这会终止 `gedit` ，并且所有的工作都将丢失（除非文件已经被保存）。`Ctrl + C` 会给 `gedit` 发送了 `SIGINT` 信号。这是一个默认终止进程的停止信号，它将指示 shell 停止 `gedit` 的运行，并返回到主函数的循环中，您将返回到提示符。

```
$ gedit
^C

```

#### Ctrl + Z

它被称为挂起字符。它会发送 `SIGTSTP` 信号给进程。它也是一个停止信号，但是默认行为不是杀死进程，而是挂起进程。

下面的命令将会停止（杀死/中断） `gedit` 的运行，并返回到 shell 提示符。

```
$ gedit
^Z
[1]+  Stopped                 gedit
$

```

一旦进程被挂起（以 `gedit` 为例），将不能在 `gedit` 中写入或做任何事情。而在后台，该进程变成了一个作业，可以使用 `jobs` 命令验证。

```
$ jobs
[1]+  Stopped                 gedit

```

`jobs` 允许您在单个 shell 会话中控制多个进程。您可以终止，恢复作业，或是根据需要将作业移动到前台或是后台。

让我们在后台恢复 `gedit`，释放提示符以运行其它命令。您可以通过 `bg` 命令来做到，后跟作业 ID（注意上面的 `jobs` 命令显示出来的 `[1]`，这就是作业 ID）。

```
$ bg 1
[1]+ gedit &

```

这和直接使用 `gedit &` 启动程序效果差不多：

```
$ gedit &

```

### 使用 kill

`kill` 命令提供信号的精确控制，允许您通过指定信号名或是信号数字为进程发送信号，后跟进程 ID 或是 PID。

我喜欢 `kill` 命令的一点是它也能够根据作业 ID 控制进程。让我们使用 `gedit &` 命令在后台开启 `gedit` 服务。假设通过 `jobs` 命令我得到了一个 `gedit` 的作业 ID，让我们为 `gedit` 发送 `SIGINT` 信号：

```
$ kill -s SIGINT %1

```

作业 ID 需要使用 `%` 前缀，不然 `kill` 会将其视作 PID。

不明确指定信号，`kill` 仍然可以工作。此时，默认会发送能中断进程的 `SIGTERM` 信号。执行 `kill -l` 可以查看信号名列表，使用 `man kill` 命令阅读手册。

### 使用 killall

如果您不想使用特定的工作 ID 或者 PID，`killall` 允许您使用特定的进程名。中断 `gedit` 最简单的 `killall` 使用方式是：

```
$ killall gedit

```

它将终止所有名为 `gedit` 的进程。和 `kill` 相似，默认发送的信号是 `SIGTERM`。使用 `-I` 选项忽略进程名的大小写。

```
$ gedit &
[1] 14852

$ killall -I GEDIT
[1]+  Terminated              gedit

```

查看手册学习更多 `killall` 命令选项（如 `-u`）。

### 使用 xkill

您是否遇见过播放器崩溃，比如 [VLC](https://www.videolan.org/vlc/index.html) 灰屏或挂起？现在你可以像上面一样获得进程的 PID 来杀掉它，或者使用 `xkill` 命令终止应用程序。

`xkill` 允许您使用鼠标关闭窗口。仅需在终端执行 `xkill` 命令，它将会改变鼠标光标为一个 **X** 或是一个小骷髅图标。在你想关闭的进程窗口上点击 **x**。小心使用 `xkill`，如手册描述的一致，它很危险。我已经提醒过您了！

参阅手册，了解上述命令更多信息。您还可以接续探索 `pkill` 和 `pgrep` 命令。

---

via: <https://opensource.com/article/18/5/how-kill-process-stop-program-linux>

作者：[Sachin Patil](https://opensource.com/users/psachin) 选题：[lujun9972](https://github.com/lujun9972) 译者：[CYLeft](https://github.com/CYLeft) 校对：[wxy](https://github.com/wxy)

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


3 个 Python 模板库比较

# 3 个 Python 模板库比较

>
> 你的下一个 Python 项目需要一个模板引擎来自动生成 HTML 吗？这有几种选择。
>
>
>

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

在我的日常工作中，我花费大量的时间将各种来源的数据转化为可读的信息。虽然很多时候这只是电子表格或某种类型的图表或其他数据可视化的形式，但也有其他时候，将数据以书面形式呈现是有意义的。

但我的头疼地方就是复制和粘贴。如果你要将数据从源头移动到标准化模板，则不应该复制和粘贴。这很容易出错，说实话，这会浪费你的时间。

因此，对于我定期发送的任何遵循一个共同的模式的信息，我倾向于找到某种方法来自动化至少一部分信息。也许这涉及到在电子表格中创建一些公式，一个快速 shell 脚本或其他解决方案，以便使用从外部源提取的信息自动填充模板。

但最近，我一直在探索 Python 模板来完成从其他数据集创建报告和图表的大部分工作。

Python 模板引擎非常强大。我的简化报告创建的使用案例仅仅触及了它的皮毛。许多开发人员正在利用这些工具来构建完整的 web 应用程序和内容管理系统。但是，你并不需要有一个复杂的 web 应用程序才能使用 Python 模板工具。

### 为什么选择模板？

每个模板工具都不甚相同，你应该阅读文档以了解其确切的用法。但让我们创建一个假设的例子。假设我想创建一个简短的页面，列出我最近编写的所有 Python 主题。就像这样：

```
<html>
  <head>
    <title>My Python articles</title>
  </head>
  <body>

    <p>These are some of the things I have written about Python:</p>
    <ul>
      <li>Python GUIs</li>
      <li>Python IDEs</li>
      <li>Python web scrapers</li>
    </ul>

  </body>
</html>

```

当它仅仅是这三个项目时，维护它是很简单的。但是当我想添加第四个、第五个或第六十七个时会发生什么？我可以从包含我所有页面列表的 CSV 文件或其他数据文件生成它，而不是手动编码此页面吗？我可以轻松地为我写的每个主题创建重复内容吗？我可以以编程方式更改每个页面上的文本标题吗？这就是模板引擎可以发挥作用的地方。

有许多不同的选择，今天我将与你其中分享三个，顺序不分先后：[Mako](http://www.makotemplates.org/)、 [Jinja2](http://jinja.pocoo.org/) 和 [Genshi](https://genshi.edgewall.org/)。

### Mako

[Mako](http://www.makotemplates.org/) 是以 MIT 许可证发布的 Python 模板工具，专为快速展现而设计的（与 Jinja2 不同）。Reddit 已经使用 Mako 来展现他们的网页，它同时也是 Pyramid 和 Pylons 等 web 框架的默认模板语言。它相当简单且易于使用。你可以使用几行代码来设计模板；支持 Python 2.x 和 3.x，它是一个功能强大且功能丰富的工具，具有[良好的文档](http://docs.makotemplates.org/en/latest/)，这一点我认为是必须的。其功能包括过滤器、继承、可调用块和内置缓存系统，这些系统可以被大型或复杂的 web 项目导入。

### Jinja2

Jinja2 是另一个快速且功能全面的选项，可用于 Python 2.x 和 3.x，遵循 BSD 许可证。Jinja2 从功能角度与 Mako 有很多重叠，因此对于新手来说，你在两者之间的选择可能会归结为你喜欢的格式化风格。Jinja2 还将模板编译为字节码，并具有 HTML 转义、沙盒、模板继承和模板沙盒部分的功能。其用户包括 Mozilla、 SourceForge、 NPR、 Instagram 等，并且还具有[强大的文档](http://jinja.pocoo.org/docs/2.10/)。与 Mako 在模板内部使用 Python 逻辑不同的是，Jinja2 使用自己的语法。

### Genshi

[Genshi](https://genshi.edgewall.org/) 是我会提到的第三个选择。它是一个 XML 工具，具有强大的模板组件，所以如果你使用的数据已经是 XML 格式，或者你需要使用网页以外的格式，Genshi 可能成为你的一个很好的解决方案。HTML 基本上是一种 XML（好吧，不是精确的，但这超出了本文的范围，有点卖弄学问了），因此格式化它们非常相似。由于我通常使用的很多数据都是 XML 或其他类型的数据，因此我非常喜欢使用我可以用于多种事物的工具。

发行版目前仅支持 Python 2.x，尽管 Python 3 支持存在于主干中，但我提醒你，它看起来并没有得到有效的开发。Genshi 遵循 BSD 许可证提供。

### 示例

因此，在上面的假设示例中，我不会每次写新主题时都更新 HTML 文件，而是通过编程方式对其进行更新。我可以创建一个模板，如下所示：

```
<html>
  <head>
    <title>My Python articles</title>
  </head>
  <body>

    <p>These are some of the things I have written about Python:</p>
    <ul>
      %for topic in topics:
      <li>${topic}</li>
      %endfor
    </ul>

  </body>
</html>

```

然后我可以使用我的模板库来迭代每个主题，比如使用 Mako，像这样：

```
from mako.template import Template

mytemplate = Template(filename='template.txt')
print(mytemplate.render(topics=("Python GUIs","Python IDEs","Python web scrapers")))

```

当然，在现实世界的用法中，我不会将这些内容手动地列在变量中，而是将它们从外部数据源（如数据库或 API）中提取出来。

这些不是仅有的 Python 模板引擎。如果你正在开始创建一个将大量使用模板的新项目，那么你考虑的可能不仅仅是这三种选择。在 [Python 维基](https://wiki.python.org/moin/Templating)上查看更全面的列表，以获得更多值得考虑的项目。

---

via: <https://opensource.com/resources/python/template-libraries>

作者：[Jason Baker](https://opensource.com/users/jason-baker) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


Linux vs. Unix：有什么不同？

Summary: 深入了解这两个有许多共同的传统和相同的目标的操作系统之间的不同。

深入了解这两个有许多共同的传统和相同的目标的操作系统之间的不同。

# Linux vs. Unix：有什么不同？

>
> 深入了解这两个有许多共同的传统和相同的目标的操作系统之间的不同。
>
>
>

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

如果你是位二、三十岁的软件开发人员，那么你已经成长在一个由 Linux 主导的世界。数十年来，它一直是数据中心的重要参与者，尽管很难找到明确的操作系统市场份额报告，但 Linux 的数据中心操作系统份额可能高达 70%，而 Windows 及其变体几乎涵盖了所有剩余的百分比。使用任何主流公共云服务的开发人员都可以预期目标系统会运行 Linux。近些年来，随着 Android 和基于 Linux 的嵌入式系统在智能手机、电视、汽车和其他设备中的应用，Linux 已经随处可见。

即便如此，大多数软件开发人员，甚至是那些在这场历史悠久的 “Linux 革命”中长大的软件开发人员，也都听过说 Unix。它听起来与 Linux 相似，你可能已经听到人们互换使用这些术语。或者你也许听说过 Linux 被称为“类 Unix ”操作系统。

那么，Unix 是什么？漫画中提到了像巫师一样留着“灰胡子”，坐在发光的绿色屏幕后面，写着 C 代码和 shell 脚本，由老式的、滴灌的咖啡提供动力。但是，Unix 的历史比上世纪 70 年代那些留着胡子的 C 程序员要丰富得多。虽然详细介绍 Unix 历史和 “Unix 与 Linux” 比较的文章比比皆是，但本文将提供高级背景和列出这些互补世界之间的主要区别。

### Unix 的起源

Unix 的历史始于 20 世纪 60 年代后期的 AT&T 贝尔实验室，有一小组程序员希望为 PDP-7 编写一个多任务、多用户操作系统。这个贝尔实验室研究机构的团队中最著名的两名成员是 Ken Thompson 和 Dennis Ritchie。尽管 Unix 的许多概念都是其前身（[Multics](https://en.wikipedia.org/wiki/Multics)）的衍生物，但 Unix 团队早在 70 年代就决定用 C 语言重写这个小型操作系统，这是将 Unix 与其他操作系统区分开来的原因。当时，操作系统很少，更不要说可移植的操作系统。相反，由于它们的设计和底层语言的本质，操作系统与他们所编写的硬件平台紧密相关。而通过 C 语言重构 Unix、Unix 现在可以移植到许多硬件体系结构中。

除了这种新的可移植性，之所以使得 Unix 迅速扩展到贝尔实验室以外的其他研究和学术机构甚至商业用途，是因为操作系统设计原则的几个关键点吸引了用户和程序员们。首先是 Ken Thompson 的 [Unix 哲学](https://en.wikipedia.org/wiki/Unix_philosophy)成为模块化软件设计和计算的强大模型。Unix 哲学推荐使用小型的、专用的程序组合起来完成复杂的整体任务。由于 Unix 是围绕文件和管道设计的，因此这种“管道”模式的输入和输出程序的组合成一组线性的输入操作，现在仍然流行。事实上，目前的云功能即服务（FaaS）或无服务器计算模型要归功于 Unix 哲学的许多传统。

### 快速增长和竞争

到 70 年代末和 80 年代，Unix 成为了一个操作系统家族的起源，它遍及了研究和学术机构以及日益增长的商业 Unix 操作系统业务领域。Unix 不是开源软件，Unix 源代码可以通过与它的所有者 AT&T 达成协议来获得许可。第一个已知的软件许可证于 1975 年出售给<ruby> 伊利诺伊大学 <rt>  University of Illinois </rt></ruby>。

Unix 在学术界迅速发展，在 Ken Thompson 在上世纪 70 年代的学术假期间，伯克利成为一个重要的活动中心。通过在伯克利的各种有关 Unix 的活动，Unix 软件的一种新的交付方式诞生了：<ruby> 伯克利软件发行版 <rt>  Berkeley Software Distribution </rt></ruby>（BSD）。最初，BSD 不是 AT&T Unix 的替代品，而是一种添加类似于附加软件和功能。在 1979 年， 2BSD（第二版伯克利软件发行版）出现时，伯克利研究生 Bill Joy 已经添加了现在非常有名的程序，例如 `vi` 和 C shell（`/bin/csh`）。

除了成为 Unix 家族中最受欢迎的分支之一的 BSD 之外，Unix 的商业产品的爆发贯穿了二十世纪八、九十年代，其中包括 HP-UX、IBM 的 AIX、 Sun 的 Solaris、 Sequent 和 Xenix 等。随着分支从根源头发展壮大，“[Unix 战争](https://en.wikipedia.org/wiki/Unix_wars)”开始了，标准化成为社区的新焦点。POSIX 标准诞生于 1988 年，其他标准化后续工作也开始通过 The Open Group 在 90 年代到来。

在此期间，AT&T 和 Sun 发布了 System V Release 4（SVR4），许多商业供应商都采用了这一版本。另外，BSD 系列操作系统多年来一直在增长，最终一些开源的变体在现在熟悉的 [BSD许可证](https://en.wikipedia.org/wiki/BSD_licenses)下发布。这包括 FreeBSD、 OpenBSD 和 NetBSD，每个在 Unix 服务器行业的目标市场略有不同。这些 Unix 变体今天仍然有一些在使用，尽管人们已经看到它们的服务器市场份额缩小到个位数字（或更低）。在当今的所有 Unix 系统中，BSD 可能拥有最大的安装基数。另外，每台 Apple Mac 硬件设备从历史的角度看都可以算做是 BSD ，这是因为 OS X（现在是 macOS）操作系统是 BSD 衍生产品。

虽然 Unix 的全部历史及其学术和商业变体可能需要更多的篇幅，但为了我们文章的重点，让我们来讨论 Linux 的兴起。

### 进入 Linux

今天我们所说的 Linux 操作系统实际上是 90 年代初期的两个努力的结合。Richard Stallman 希望创建一个真正的自由而开放源代码的专有 Unix 系统的替代品。他正在以 GNU 的名义开发实用程序和程序，这是一种递归的说法，意思是“GNU‘s not Unix!”。虽然当时有一个内核项目正在进行，但事实证明这是一件很困难的事情，而且没有内核，自由和开源操作系统的梦想无法实现。而这是 Linus Torvald 的工作 —— 生产出一种可工作和可行的内核，他称之为 Linux -- 它将整个操作系统带入了生活。鉴于 Linus 使用了几个 GNU 工具（例如 GNU 编译器集合，即 [GCC](https://en.wikipedia.org/wiki/GNU_Compiler_Collection)），GNU 工具和 Linux 内核的结合是完美的搭配。

Linux 发行版采用了 GNU 的组件、Linux 内核、MIT 的 X-Windows GUI 以及可以在开源 BSD 许可下使用的其它 BSD 组件。像 Slackware 和 Red Hat 这样的发行版早期的流行给了 20 世纪 90 年代的“普通 PC 用户”一个进入 Linux 操作系统的机会，并且让他们在工作和学术生活中可以使用许多 Unix 系统特有的功能和实用程序。

由于所有 Linux 组件都是自由和开放的源代码，任何人都可以通过一些努力来创建一个 Linux 发行版，所以不久后发行版的总数达到了数百个。今天，[distrowatch.com](https://distrowatch.com/) 列出了 312 种各种形式的独特的 Linux 发行版。当然，许多开发人员通过云提供商或使用流行的免费发行版来使用 Linux，如 Fedora、 Canonical 的 Ubuntu、 Debian、 Arch Linux、 Gentoo 和许多其它变体。随着包括 IBM 在内的许多企业从专有 Unix 迁移到 Linux 上并提供了中间件和软件解决方案，商用 Linux 产品在自由和开源组件之上提供支持变得可行。红帽公司围绕 Red Hat Enterprise Linux（红帽企业版 Linux） 建立了商业支持模式，德国供应商 SUSE 使用 SUSE Linux Enterprise Server（SLES）也提供了这种模式。

### 比较 Unix 和 Linux

到目前为止，我们已经了解了 Unix 的历史以及 Linux 的兴起，以及 GNU/自由软件基金会对 Unix 的自由和开源替代品的支持。让我们来看看这两个操作系统之间的差异，它们有许多共同的传统和许多相同的目标。

从用户体验角度来看，两者差不多！Linux 的很大吸引力在于操作系统在许多硬件体系结构（包括现代 PC）上的可用性以及类似使用 Unix 系统管理员和用户熟悉的工具的能力。

由于 POSIX 的标准和合规性，在 Unix 上编写的软件可以针对 Linux 操作系统进行编译，通常只有少量的移植工作量。在很多情况下，Shell 脚本可以在 Linux 上直接使用。虽然一些工具在 Unix 和 Linux 之间有着略微不同的标志或命令行选项，但许多工具在两者上都是相同的。

一方面要注意的是，macOS 硬件和操作系统作为主要针对 Linux 的开发平台的流行可能归因于类 BSD 的 macOS 操作系统。许多用于 Linux 系统的工具和脚本可以在 macOS 终端内轻松工作。Linux 上的许多开源软件组件都可以通过 [Homebrew](https://brew.sh/) 等工具轻松获得。

Linux 和 Unix 之间的其他差异主要与许可模式有关：开源与专有许可软件。另外，在 Unix 发行版中缺少一个影响软件和硬件供应商的通用内核。对于 Linux，供应商可以为特定的硬件设备创建设备驱动程序，并期望在合理的范围内它可以在大多数发行版上运行。由于 Unix 家族的商业和学术分支，供应商可能必须为 Unix 的变体编写不同的驱动程序，并且需要许可和其他相关的权限才能访问 SDK 或软件的分发模型，以跨越多个二进制设备驱动程序的 Unix 变体。

随着这两个社区在过去十年中的成熟，Linux 的许多优点已经在 Unix 世界中被采用。当开发人员需要来自不属于 Unix 的 GNU 程序的功能时，许多 GNU 实用程序可作为 Unix 系统的附件提供。例如，IBM 的 AIX 为 Linux 应用程序提供了一个 AIX Toolbox，其中包含数百个 GNU 软件包（如 Bash、 GCC、 OpenLDAP 和许多其他软件包），这些软件包可添加到 AIX 安装包中以简化 Linux 和基于 Unix 的 AIX 系统之间的过渡。

专有的 Unix 仍然活着而且还不错，许多主要供应商承诺支持其当前版本，直到 2020 年。不言而喻，Unix 还会在可预见的将来一直出现。此外，Unix 的 BSD 分支是开源的，而 NetBSD、 OpenBSD 和 FreeBSD 都有强大的用户基础和开源社区，它们可能不像 Linux 那样显眼或活跃，但在最近的服务器报告中，在 Web 服务等领域它们远高于专有 Unix 的数量。

Linux 已经显示出其超越 Unix 的显著优势在于其在大量硬件平台和设备上的可用性。<ruby> 树莓派 <rt>  Raspberry Pi </rt></ruby>受到业余爱好者的欢迎，它是由 Linux 驱动的，为运行 Linux 的各种物联网设备打开了大门。我们已经提到了 Android 设备，汽车（包括 Automotive Grade Linux）和智能电视，其中 Linux 占有巨大的市场份额。这个星球上的每个云提供商都提供运行 Linux 的虚拟服务器，而且当今许多最受欢迎的原生云架构都是基于 Linux 的，无论你是在谈论容器运行时还是 Kubernetes，或者是许多正在流行的无服务器平台。

其中一个最显著的代表 Linux 的优势是近年来微软的转变。如果你十年前告诉软件开发人员，Windows 操作系统将在 2016 年“运行 Linux”，他们中的大多数人会歇斯底里地大笑。 但是 Windows Linux 子系统（WSL）的存在和普及，以及最近宣布的诸如 Docker 的 Windows 移植版，包括 LCOW（Windows 上的 Linux 容器）支持等功能都证明了 Linux 在整个软件世界中所产生的影响 —— 而且显然还会继续存在。

---

via: <https://opensource.com/article/18/5/differences-between-linux-and-unix>

作者：[Phil Estes](https://opensource.com/users/estesp) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


使用 GNU Parallel 提高 Linux 命令行执行效率

Summary: 将您的计算机变成一个多任务的动力室。

将您的计算机变成一个多任务的动力室。

# 使用 GNU Parallel 提高 Linux 命令行执行效率

>
> 将您的计算机变成一个多任务的动力室。
>
>
>

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

你是否有过这种感觉，你的主机运行速度没有预期的那么快？我也曾经有过这种感觉，直到我发现了 GNU Parallel。

GNU Parallel 是一个 shell 工具，可以并行执行任务。它可以解析多种输入，让你可以同时在多份数据上运行脚本或命令。你终于可以使用全部的 CPU 了！

如果你用过 `xargs`，上手 Parallel 几乎没有难度。如果没有用过，这篇教程会告诉你如何使用，同时给出一些其它的用例。

### 安装 GNU Parallel

GNU Parallel 很可能没有预装在你的 Linux 或 BSD 主机上，你可以从软件源中安装。以 Fedora 为例：

```
$ sudo dnf install parallel

```

对于 NetBSD：

```
# pkg_add parallel

```

如果各种方式都不成功，请参考[项目主页](https://www.gnu.org/software/parallel)。

### 从串行到并行

正如其名称所示，Parallel 的强大之处是以并行方式执行任务；而我们中不少人平时仍然以串行方式运行任务。

当你对多个对象执行某个命令时，你实际上创建了一个任务队列。一部分对象可以被命令处理，剩余的对象需要等待，直到命令处理它们。这种方式是低效的。只要数据够多，总会形成任务队列；但与其只使用一个任务队列，为何不使用多个更小规模的任务队列呢？

假设你有一个图片目录，你希望将目录中的图片从 JEEG 格式转换为 PNG 格式。有多种方法可以完成这个任务。可以手动用 GIMP 打开每个图片，输出成新格式，但这基本是最差的选择，费时费力。

上述方法有一个漂亮且简洁的变种，即基于 shell 的方案：

```
$ convert 001.jpeg 001.png
$ convert 002.jpeg 002.png
$ convert 003.jpeg 003.png
... 略 ...

```

对于初学者而言，这是一个不小的转变，而且看起来是个不小的改进。不再需要图像界面和不断的鼠标点击，但仍然是费力的。

进一步改进：

```
$ for i in *jpeg; do convert $i $i.png ; done

```

至少，这一步设置好任务执行，让你节省时间去做更有价值的事情。但问题来了，这仍然是串行操作；一张图片转换完成后，队列中的下一张进行转换，依此类推直到全部完成。

使用 Parallel:

```
$ find . -name "*jpeg" | parallel -I% --max-args 1 convert % %.png

```

这是两条命令的组合：`find` 命令，用于收集需要操作的对象；`parallel` 命令，用于对象排序并确保每个对象按需处理。

* `find . -name "*jpeg"` 查找当前目录下以 `jpeg` 结尾的所有文件。
* `parallel` 调用 GNU Parallel。
* `-I%` 创建了一个占位符 `%`，代表 `find` 传递给 Parallel 的内容。如果不使用占位符，你需要对 `find` 命令的每一个结果手动编写一个命令，而这恰恰是你想要避免的。
* `--max-args 1` 给出 Parallel 从队列获取新对象的速率限制。考虑到 Parallel 运行的命令只需要一个文件输入，这里将速率限制设置为 1。假如你需要执行更复杂的命令，需要两个文件输入（例如 `cat 001.txt 002.txt > new.txt`），你需要将速率限制设置为 2。
* `convert % %.png` 是你希望 Parallel 执行的命令。

组合命令的执行效果如下：`find` 命令收集所有相关的文件信息并传递给 `parallel`，后者（使用当前参数）启动一个任务，（无需等待任务完成）立即获取参数行中的下一个参数（LCTT 译注：管道输出的每一行对应 `parallel` 的一个参数，所有参数构成参数行）；只要你的主机没有瘫痪，Parallel 会不断做这样的操作。旧任务完成后，Parallel 会为分配新任务，直到所有数据都处理完成。不使用 Parallel 完成任务大约需要 10 分钟，使用后仅需 3 至 5 分钟。

### 多个输入

只要你熟悉 `find` 和 `xargs` （整体被称为 GNU 查找工具，或 `findutils`），`find` 命令是一个完美的 Parallel 数据提供者。它提供了灵活的接口，大多数 Linux 用户已经很习惯使用，即使对于初学者也很容易学习。

`find` 命令十分直截了当：你向 `find` 提供搜索路径和待查找文件的一部分信息。可以使用通配符完成模糊搜索；在下面的例子中，星号匹配任何字符，故 `find` 定位（文件名）以字符 `searchterm` 结尾的全部文件：

```
$ find /path/to/directory -name "*searchterm"

```

默认情况下，`find` 逐行返回搜索结果，每个结果对应 1 行：

```
$ find ~/graphics -name "*jpg"
/home/seth/graphics/001.jpg
/home/seth/graphics/cat.jpg
/home/seth/graphics/penguin.jpg
/home/seth/graphics/IMG_0135.jpg

```

当使用管道将 `find` 的结果传递给 `parallel` 时，每一行中的文件路径被视为 `parallel` 命令的一个参数。另一方面，如果你需要使用命令处理多个参数，你可以改变队列数据传递给 `parallel` 的方式。

下面先给出一个不那么实际的例子，后续会做一些修改使其更加有意义。如果你安装了 GNU Parallel，你可以跟着这个例子操作。

假设你有 4 个文件，按照每行一个文件的方式列出，具体如下：

```
$ echo ada > ada ; echo lovelace > lovelace
$ echo richard > richard ; echo stallman > stallman
$ ls -1
ada
lovelace
richard
stallman

```

你需要将两个文件合并成第三个文件，后者同时包含前两个文件的内容。这种情况下，Parallel 需要访问两个文件，使用 `-I%` 变量的方式不符合本例的预期。

Parallel 默认情况下读取 1 个队列对象：

```
$ ls -1 | parallel echo
ada
lovelace
richard
stallman

```

现在让 Parallel 每个任务使用 2 个队列对象：

```
$ ls -1 | parallel --max-args=2 echo
ada lovelace
richard stallman

```

现在，我们看到行已经并合并；具体而言，`ls -1` 的两个查询结果会被同时传送给 Parallel。传送给 Parallel 的参数涉及了任务所需的 2 个文件，但目前还只是 1 个有效参数：（对于两个任务分别为）“ada lovelace” 和 “richard stallman”。你真正需要的是每个任务对应 2 个独立的参数。

值得庆幸的是，Parallel 本身提供了上述所需的解析功能。如果你将 `--max-args` 设置为 `2`，那么 `{1}` 和 `{2}` 这两个变量分别代表传入参数的第一和第二部分：

```
$ ls -1 | parallel --max-args=2 cat {1} {2} ">" {1}_{2}.person

```

在上面的命令中，变量 `{1}` 值为 `ada` 或 `richard` （取决于你选取的任务），变量 `{2}` 值为 `lovelace` 或 `stallman`。通过使用重定向符号（放到引号中，防止被 Bash 识别，以便 Parallel 使用），（两个）文件的内容被分别重定向至新文件 `ada_lovelace.person` 和 `richard_stallman.person`。

```
$ ls -1
ada
ada_lovelace.person
lovelace
richard
richard_stallman.person
stallman

$ cat ada_*person
ada lovelace
$ cat ri*person
richard stallman

```

如果你整天处理大量几百 MB 大小的日志文件，那么（上述）并行处理文本的方法对你帮忙很大；否则，上述例子只是个用于上手的示例。

然而，这种处理方法对于很多文本处理之外的操作也有很大帮助。下面是来自电影产业的真实案例，其中需要将一个目录中的视频文件和（对应的）音频文件进行合并。

```
$ ls -1
12_LS_establishing-manor.avi
12_wildsound.flac
14_butler-dialogue-mixed.flac
14_MS_butler.avi
...略...

```

使用同样的方法，使用下面这个简单命令即可并行地合并文件：

```
$ ls -1 | parallel --max-args=2 ffmpeg -i {1} -i {2} -vcodec copy -acodec copy {1}.mkv

```

### 简单粗暴的方式

上述花哨的输入输出处理不一定对所有人的口味。如果你希望更直接一些，可以将一堆命令甩给 Parallel，然后去干些其它事情。

首先，需要创建一个文本文件，每行包含一个命令：

```
$ cat jobs2run
bzip2 oldstuff.tar
oggenc music.flac
opusenc ambiance.wav
convert bigfile.tiff small.jpeg
ffmepg -i foo.avi -v:b 12000k foo.mp4
xsltproc --output build/tmp.fo style/dm.xsl src/tmp.xml
bzip2 archive.tar

```

接着，将文件传递给 Parallel：

```
$ parallel --jobs 6 < jobs2run

```

现在文件中对应的全部任务都在被 Parallel 执行。如果任务数量超过允许的数目（LCTT 译注：应该是 `--jobs` 指定的数目或默认值），Parallel 会创建并维护一个队列，直到任务全部完成。

### 更多内容

GNU Parallel 是个强大而灵活的工具，还有很多很多用例无法在本文中讲述。工具的 man 页面提供很多非常酷的例子可供你参考，包括通过 SSH 远程执行和在 Parallel 命令中使用 Bash 函数等。[YouTube](https://www.youtube.com/watch?v=OpaiGYxkSuQ&list=PL284C9FF2488BC6D1) 上甚至有一个系列，包含大量操作演示，让你可以直接从 GNU Parallel 团队学习。GNU Paralle 的主要维护者还发布了官方使用指导手册，可以从 [Lulu.com](http://www.lulu.com/shop/ole-tange/gnu-parallel-2018/paperback/product-23558902.html) 获取。

GNU Parallel 有可能改变你完成计算的方式；即使没有，也会至少改变你主机花在计算上的时间。马上上手试试吧！

---

via: <https://opensource.com/article/18/5/gnu-parallel>

作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

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