用 PGP 保护代码完整性（五）：将子密钥移到一个硬件设备中

Summary: 在这个系列教程中，将为你提供使用 PGP 和保护你的私钥的最佳体验。

在这个系列教程中，将为你提供使用 PGP 和保护你的私钥的最佳体验。

>
> 在这个系列教程中，将为你提供使用 PGP 和保护你的私钥的最佳体验。
>
>
>

![](/data/attachment/album/201901/05/001540guuubwk558wvc8sx.jpg)

在本系列教程中，我们将提供一个使用 PGP 的实用指南。如果你没有看过前面的文章，你可以通过下面的链接去查看。在这篇文章中，我们将继续讨论如何保护你的密钥，谈一谈将你的子密钥移到一个专门的硬件设备中的一些技巧。

* [第一部分：基本概念和工具](/article-9524-1.html)
* [第二部分：生成你的主密钥](/article-9529-1.html)
* [第三部分：生成 PGP 子密钥](/article-9607-1.html)
* [第四部分：将主密钥移到离线存储中](/article-10402-1.html)

#### 清单

* 取得一个 GnuPG 兼容的硬件设备（必要）
* 配置 GnuPG 在设备上工作（必要）
* 设置用户和管理员的 PIN（必要）
* 移动子密钥到设备中（必要）

#### 考虑事项

虽然现在主密钥已经不用担心泄露或失窃了，但子密钥仍然在你的家目录中。任何得到它的人都能够解密你的通讯或假冒你的签名（如果他们知道密钥的密码）。并且，每次执行一个 GnuPG 操作都要将密钥加载到操作系统内存中，这将使一些更高级的恶意软件有机会得到你的密钥（想想 Meltdown 和 Spectre）。

完全保护密钥的最好方式就是，将它移到一个专门的硬件设备中，这种硬件设备是一个可操作的智能卡。

##### 智能卡的好处

一个智能卡包含一个加密芯片，它能够存储私钥，并且直接在智能卡内部执行秘密操作。因为密钥内容从来没有离开过智能卡，计算机操作系统并不能检索你插入的智能卡上的私钥。这与前面用于备份目的的加密 USB 存储是不同的 —— 虽然 USB 设备也是插入并解密的，但操作系统是能够去访问私钥内容的。使用外置的加密 USB 介质并不能代替智能卡设备的功能。

智能卡的一些其它好处：

* 它们很便宜且易于获得
* 它们小巧且易于携带
* 它们可以用于多种设备上
* 它们中的很多都具有防篡改功能（取决于制造商）

#### 可用的智能卡设备

智能卡最初是嵌入到真实钱包大小的卡中，故而得名智能卡。你肯定可以买到并使用 GnuPG 功能的智能卡，并且它们是你能得到的最便宜的可用设备之一。但是，事实上智能卡有一个很重要的缺点：它们需要一个智能卡读卡器，只有极小数的笔记本电脑上有这种读卡器。

由于这个原因，制造商开始推出小型 USB 设备，它的大小和 U 盘类似，内置有微型智能卡，并且在芯片上简单地实现了智能卡协议特性。下面推荐几个这样的设备：

* [Nitrokey Start](https://shop.nitrokey.com/shop/product/nitrokey-start-6)：开源硬件和自由软件，可用于 GnuPG 的最便宜的选择之一，但是额外的安全特性很少。
* [Nitrokey Pro](https://shop.nitrokey.com/shop/product/nitrokey-pro-3)：类似于 Nitrokey Start，它提供防篡改及更多的安全特性（但没有 U2F，具体查看指南的 U2F 节）。
* [Yubikey 4](https://www.yubico.com/product/yubikey-4-series/)：专利硬件和软件，但比 Nitrokey Pro 便宜，并且可以用在最新的笔记本电脑上的 USB-C 接口；也提供像 U2F 这样的额外的安全特性。

我们推荐选一个同时具备智能卡功能和 U2F 的设备，在写这篇文章时，只能选择 Yubikey 4。

#### 配置智能卡设备

你的智能卡设备插入任何一台现代的 Linux 或 Mac 工作站上都应该能正常工作。你可以通过运行如下的命令去验证它：

```
$ gpg --card-status
```

如果你没有收到错误，有一个完整的卡列表，就表示一切正常。不幸的是，排除为什么设备不能正常工作的所有可能原因，已经超出了本指南的范围。如果你的智能卡使用 GnuPG 时有问题，请通过你的操作系统的常见支持通道寻求支持。

##### PIN 不一定是数字

注意，尽管名为 “PIN”（暗示你它必须是一个“数字”），不论是用户 PIN 还是管理员 PIN 都不必非要是数字。

当你收到一个新设备时，它可能设置有一个默认的用户和管理员 PIN，对于 Yubikey，它分别是 `123456` 和 `12345678`。如果它们的 PIN 不是默认的，请查看设备附带的说明书。

##### 快速设置

为配置你的智能卡，你需要使用 GnuPG 菜单系统，因此这里并没有更方便的命令行开关：

```
$ gpg --card-edit
[...omitted...]
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
```

你应该去设置用户 PIN (1)、管理员 PIN (3)、和重置码 (4)。请确保把它们记录并保存到一个安全的地方 —— 尤其是管理员 PIN 和重置码（它允许你去擦除整个智能卡内容）。你很少使用到管理员 PIN，因此如果你不记录下来，很可能会忘掉它。

返回到智能卡主菜单，你也可以设置其它值（比如名字、性别、登入日期、等等），但是这些都不是必需的，一旦你的智能卡丢失了，将导致额外的信息泄露。

#### 将子密钥移到你的智能卡中

退出卡菜单（使用 `q` 命令）保存所有更改。接下来，我们将你的子密钥移到智能卡中。将需要用到你的 PGP 密钥的密码，在大多数的智能卡操作中都将用到管理员 PIN。记住，那个 `[fpr]` 表示你的密钥的完整的 40 个字符的指纹。

```
$ gpg --edit-key [fpr]

Secret subkeys are available.

pub  rsa4096/AAAABBBBCCCCDDDD
    created: 2017-12-07  expires: 2019-12-07 usage: C
    trust: ultimate      validity: ultimate
ssb  rsa2048/1111222233334444
    created: 2017-12-07  expires: never usage: E
ssb  rsa2048/5555666677778888
    created: 2017-12-07  expires: never usage: S
[ultimate] (1). Alice Engineer <alice@example.org>
[ultimate] (2)  Alice Engineer <allie@example.net>

gpg>
```

使用 `--edit-key` 再次进入到菜单模式，你将注意到那个密钥清单有一点小差别。从现在开始，所有的命令都是在这个菜单模式下运行，它用 `gpg>` 提示符来表示。

首先，我们来选择移到智能卡中的密钥 —— 你可以通过键入 `key 1`（它表示选择清单中的第一个密钥）来实现：

```
gpg> key 1
```

这个输出会有一点细微的差别：

```
pub  rsa4096/AAAABBBBCCCCDDDD
    created: 2017-12-07  expires: 2019-12-07 usage: C
    trust: ultimate      validity: ultimate
ssb* rsa2048/1111222233334444
    created: 2017-12-07  expires: never usage: E
ssb  rsa2048/5555666677778888
    created: 2017-12-07  expires: never usage: S
[ultimate] (1). Alice Engineer <alice@example.org>
[ultimate] (2)  Alice Engineer <allie@example.net>
```

注意与密钥对应的 `ssb` 行旁边的 `*` —— 它表示这是当前选定的密钥。它是可切换的，意味着如果你再次输入 `key 1`，这个 `*` 将消失，这个密钥将不再被选中。

现在，我们来将密钥移到智能卡中：

```
gpg> keytocard
Please select where to store the key:
  (2) Encryption key
Your selection? 2
```

由于它是我们的 [E] 密钥，把它移到加密区中是有很有意义的。当你提交了你的选择之后，将会被提示输入你的 PGP 密钥的保护密码，接下来输入智能卡的管理员 PIN。如果命令没有返回错误，表示你的密钥已经被移到智能卡中了。

**重要：** 现在再次输入 `key 1` 去取消选中第一个密钥，并输入 `key 2` 去选择 [S] 密钥：

```
gpg> key 1
gpg> key 2
gpg> keytocard
Please select where to store the key:
  (1) Signature key
  (3) Authentication key
Your selection? 1
```

你可以使用 [S] 密钥同时做签名和验证，但是我们希望确保它在签名区，因此，我们选择 (`1`)。完成后，如果你的命令没有返回错误，表示操作已成功。

最后，如果你创建了一个 [A](https://www.linux.com/users/mricon) 密钥，你也可以将它移到智能卡中，但是你需要先取消选中 `key 2`。完成后，选择 `q`：

```
gpg> q
Save changes? (y/N) y
```

保存变更将把你的子密钥移到智能卡后，把你的家目录中的相应子密钥删除（没有关系，因为我们的备份中还有，如果更换了智能卡，你需要再做一遍）。

##### 验证移动后的密钥

现在，如果你执行一个`--list-secret-keys` 操作，你将看到一个稍有不同的输出：

```
$ gpg --list-secret-keys
sec#  rsa4096 2017-12-06 [C] [expires: 2019-12-06]
     111122223333444455556666AAAABBBBCCCCDDDD
uid           [ultimate] Alice Engineer <alice@example.org>
uid           [ultimate] Alice Engineer <allie@example.net>
ssb>  rsa2048 2017-12-06 [E]
ssb>  rsa2048 2017-12-06 [S]
```

在 `ssb>` 的输出中的 `>` 表示子密钥仅在智能卡上有效。如果你进入到你的密钥目录中，查看目录的内容，你将会看到那个 `.key` 文件已经被存根替换：

```
$ cd ~/.gnupg/private-keys-v1.d
$ strings *.key
```

这个输出将包含一个影子私钥，它表示那个文件仅是个存根，真正的内容在智能卡中。

#### 验证智能卡的功能

验证智能卡能否如期正常运行，你可以通过创建一个签名来验证：

```
$ echo "Hello world" | gpg --clearsign > /tmp/test.asc
$ gpg --verify /tmp/test.asc
```

首次运行这个命令时将询问你智能卡的 PIN，在你运行 `gpg —verify` 之后，它将显示 “Good signature”。

祝贺你，你已经成功将窃取你的开发者数字身份变得更加困难了！

#### 其它常见 GnuPG 操作

下面是使用你的 PGP 密钥需要做的一些常见操作的快速指南。

在下面的所有命令中，`[fpr]` 表示你的密钥指纹。

##### 挂载主密钥离线存储

下面的一些操作将需要你的主密钥，因此首先需要去挂载你的主密钥离线存储，并告诉 GnuPG 去使用它。首先，找出介质挂载路径，可以通过查看 `mount` 命令的输出找到它。接着，设置你的 GnuPG 目录为你的介质上备份的目录，并告诉 GnuPG 将那个目录做为它的家目录：

```
$ export GNUPGHOME=/media/disk/name/gnupg-backup
$ gpg --list-secret-keys
```

确保你在输出中看到的是 `sec` 而不是 `sec#`（这个 `#` 表示密钥不可用，仍然使用的是惯常的那个 Home 目录）。

##### 更新你惯常使用的那个 GnuPG 工作目录

在你的离线存储上做了任何更改之后，你应该将这些更改同步应用到你惯常使用的工作目录中：

```
$ gpg --export | gpg --homedir ~/.gnupg --import
$ unset GNUPGHOME
```

##### 延长密钥过期日期

我们创建的主密钥的默认过期日期是自创建之日起两年后。这样做都是为安全考虑，这样将使淘汰密钥最终从密钥服务器上消失。

延长你的密钥过期日期，从当前日期延长一年，只需要运行如下命令：

```
$ gpg --quick-set-expire [fpr] 1y
```

如果为了好记住，你也可以使用一个特定日期（比如，你的生日、1 月 1 日、或加拿大国庆日）：

```
$ gpg --quick-set-expire [fpr] 2020-07-01
```

记得将更新后的密钥发送到密钥服务器：

```
$ gpg --send-key [fpr]
```

##### 吊销身份

如果你需要吊销一个身份（比如，你换了雇主并且旧的邮件地址不再有效了），你可以使用一行命令搞定：

```
$ gpg --quick-revoke-uid [fpr] 'Alice Engineer <aengineer@example.net>'
```

你也可以通过使用 `gpg --edit-key [fpr]` 在菜单模式下完成同样的事情。

完成后，记得将更新后的密钥发送到密钥服务器上：

```
$ gpg --send-key [fpr]
```

下一篇文章中，我们将谈谈 Git 如何支持 PGP 的多级别集成。

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

---

via: <https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-5-moving-subkeys-hardware-device>

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

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


让 Linux 终端说出它的想法

Summary: eSpeak 是一个可在 Linux 命令行中使用的开源的 TTS 合成器。

eSpeak 是一个可在 Linux 命令行中使用的开源的 TTS 合成器。

>
> eSpeak 是一个可在 Linux 命令行中使用的开源的 TTS 合成器。
>
>
>

![](/data/attachment/album/201901/05/154129z41mh4s61bf6q0bt.png)

欢迎回到《24 天介绍 Linux 命令行小玩具》。如果这是你首次阅读本系列文章，你可能不知道什么是 Linux 命令行小玩具。无需担心，你只需要边看边体会。通常来说，它有可能是游戏或其它能让你在终端中娱乐的小程序。

或许你已经对一些玩具有了解了，不过我们相信，在本系列文章中总有那么几个你没见过的玩意。

年轻读者可能不知道，在 Alexa、Siri 或 Google Assistant 问世之前，计算机就能说话了。

我们也许永远不会忘记来自 [2001 太空漫游](https://en.wikipedia.org/wiki/2001:_A_Space_Odyssey_(film)) 中与机组人员交流的 HAL 9000。但是在 1960 年代到今天的时间里，是存在着许多能说话的计算机的。它们有些很出色，也有些不那么出色。

其中一个我最爱的是一个叫做 [eSpeak](http://espeak.sourceforge.net/) 的开源项目。它以多种形式发布，比如可以嵌入你自己项目中的库。与此同时，它也提供了可供你安装的命令行版本。在我所用的发行版中，安装十分简单，只需使用：

```
$ sudo dnf install espeak
```

你既可以与 eSpeak 交互，也可以用它来输出其它程序的信息，甚至通过简单的 `echo` 命令来使用它。[这里](http://espeak.sourceforge.net/voices.html) 有一些可供 eSpeak 使用的声音文件，你可以在无聊时切换他们。甚者你可以制作一个属于你自己的声音。

在 2015 年，一些希望继续 eSpeak 开发的开发者创建了一个名为 eSpeak NG （即 “Next Generation”，“下一代”的意思）的项目。eSpeak 目前在 GPL v3 许可证下开源，你可以在 [SourceForge](http://espeak.sourceforge.net/) 上详细了解这个项目或下载源代码。

别急，我今天还会介绍一个额外的小程序，它叫 [cava](https://github.com/karlstav/cava)。我经常希望用一张独一无二的截图作为我文章的头图，更何况今天的玩具主要是关于声音的，这就图片更少了。因此，我需要一些东西来填补这些空白。Cava 是<ruby> 基于 ALSA 的命令行音频可视化工具 <rt>  console-based audio visualizer for ALSA </rt></ruby>的简写（尽管它现在支持的比 ALSA 更多），它是一个优秀的命令行音频可视化工具，并且它正以 MIT 许可证开源。下面是一个将 eSpeak 输出可视化的命令：

```
$ echo "Rudolph, the red-nosed reindeer, had a very shiny nose." | espeak
```

![](/data/attachment/album/201901/05/154141baxmrsworrzvz1kx.gif)

你想让作者介绍你喜欢的命令行玩具吗？请前往原文下留言，作者可能会考虑介绍的。同时，你也可以去原文下评论你对文章的看法。

欢迎去看看我们昨天介绍的玩具，[在 Linux 命令行中使用 nudoku 解决谜题](https://opensource.com/article/18/12/linux-toy-nudoku)。敬请期待我们明天的文章吧！

---

via: <https://opensource.com/article/18/12/linux-toy-espeak>

作者：[Jason Baker](https://opensource.com/users/jason-baker) 选题：[lujun9972](https://github.com/lujun9972) 译者：[zhs852](https://github.com/zhs852) 校对：[wxy](https://github.com/wxy)

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


如何用 Gonimo 创建一个免费的婴儿监视系统

>
> 当你可以用两个设备、浏览器和网络连接就能免费搭建一个婴儿监视器时，谁还会花钱去买呢？
>
>
>

![](/data/attachment/album/201901/05/221707g6iiwkkuduntd5ai.jpg)

新父母和准父母很快就会知道将会有一个既长且昂贵的新生儿所需设备的清单，清单中的首位是一个婴儿监视器，借此他们可以在做其他事情时照看自己的婴儿，但这儿有一件不必消耗你的婴儿经费的设备，Gonimo 是一个可以将现有的设备转换成婴儿监控系统的自由开源解决方案，附近大型婴儿用品商店的过道中有数以千计的其他必备或时尚物品，就可以为其中某一个腾出一些婴儿的预算。

Gonimo 诞生时，它的开发者，一个有双胞胎的开源粉丝，发现现有选择存在问题：

* 现有硬件婴儿监视器价格昂贵，使用范围有限，需要您带着额外的设备。
* 虽然有移动监控应用程序，但大多数现有的 iOS / Android 婴儿监控应用程序都不可靠且不安全，不太容易找到开源产品。
* 如果您有两个小孩（例如双胞胎），您将需要两台监视器，使您的成本翻倍。

Gonimo 是作为一个解决典型的监视器的缺点的开源解决方案而创建的：

* 昂贵？不，它是免费的！
* 使用范围有限？不，它适用于互联网 / WiFi，无论您身在何处。
* 下载并安装应用程序？噢不，它适用于您现有的网络浏览器。
* 购买新设备？不用，你可以使用任何笔记本电脑、手机或平板电脑与网络浏览器和麦克风和/或相机。

（注意：遗憾的是，Apple iOS 设备尚不支持，但预计很快就会发生变化 —— 请继续阅读，了解如何帮实现这一目标。）

### 开始

将您的设备转换为婴儿监视器很容易。从您设备的浏览器（理想情况下为 Chrome），访问 [gonimo.com](https://gonimo.com/) 并单击 “Start baby monitor” 以访问该 Web 应用程序。

1、创建家庭：在首次启动的屏幕上，你会看到一只可爱的兔子在地球上奔跑。这是您创建新家庭的地方。单击 “+” 按钮并接受随机生成的姓氏或键入您自己的选择。

![Start screen](/data/attachment/album/201901/05/203202vnf9bpr29fxnbpqb.png "Start screen")

*从开始屏幕创建一个新家庭*

2、邀请设备：建立完家庭以后，下个屏幕将指示您邀请其他设备加入你的 Gonimo 家庭。您可以通过电子邮件直接发送一次性邀请链接，也可以将其复制并粘贴到消息中。对其他设备，只需打开该链接并接受邀请。对您要邀请的任何其他设备重复此过程。您的设备现在属于同一家庭，可以作为一个完全正常工作的婴儿监视器系统进行配合。

![Invite screen](/data/attachment/album/201901/05/203204d0lhtt506nfowdxz.png "Invite screen")

*邀请家庭成员*

3、启动婴儿站流：接下来，通过转到 [Gonimo 主屏](https://app.gonimo.com/)，点击带有奶嘴的按钮，并允许网络浏览器访问设备的麦克风和摄像头，选择将婴儿的音频和视频流式传输到父母的设备。调整相机以指向宝宝的床，或关闭它以节省设备电池（音频仍将流式传输）。点击“Start”。该流现在处于活动状态。

![Select baby station](/data/attachment/album/201901/05/203205iydnon5zbl7o9n7o.png "Select baby station")

*选择婴儿站*

![Press Start](/data/attachment/album/201901/05/203209dxii7ehzmi9pmimm.png "Press Start")

*按“Start”开始以流式传输视频*

4、连接到父母站流：要查看婴儿站流，请转到 Gonimo 家族中的另外的设备 —— 即父母站。点击 Gonimo 主屏幕上的 “Parent” 按钮。您将看到该系列中所有设备的列表；旁边有一个闪动的“Connect”按钮的是活跃的婴儿站。选择“Connect”，您可以通过点对点音频/视频流看到和听到您的宝宝。音量条为传输的音频流提供可视化。

![Select parent station](/data/attachment/album/201901/05/203210ybdbbipjbifj3ybf.png "Select parent station")

*选择父母站*

![Press Connect](/data/attachment/album/201901/05/203211vryczgg6rq6zqw6w.png "Press Connect")

*按下“Connect”开始观看婴儿流。*

5、恭喜！您已成功将设备直接通过网络浏览器转换为婴儿监视器，无需下载或安装任何应用程序！

有关重命名设备，从系列中删除设备或删除系列的详细信息和详细说明，请查看 gonimo.com 的[视频教程](https://gonimo.com/index.php#intro)。

### 家庭系统的灵活性

Gonimo 的优势之一是其基于家庭的系统，它为即使在商业 Android 或 iOS 应用中也无法提供的各种情况提供了极大的灵活性。要深入了解这些功能，我们假设您创建了一个由三个设备组成的家庭系统。

* 多婴儿：如果你想留意你在两个不同房间睡觉的两个小孩怎么办？在每个孩子的房间放一个设备，并将其设置为婴儿站。第三个设备将充当父母站，您可以在其上连接到两个流并通过分屏查看您的幼儿。您甚至可以通过向该家庭系统提供更多设备，并将其设置为婴儿站来将此用例扩展到两个以上的婴儿站。只要您的父母站连接到第一个婴儿站，请单击左上角的后退箭头返回“设备概述”屏幕。现在您可以连接到第二个（以及依次为第三个、第四个、第五个和第五个等）设备，并自动建立分屏。酷！
* 多父母：如果爸爸想在他上班的时候看孩子怎么办？只需邀请第四个设备（例如，他的办公室 PC ）到家庭并将其设置为父母站。父母双方都可以通过他们自己的设备同时检查他们的孩子，甚至可以独立地选择他们希望连接的孩子。
* 多家庭：单个设备也可以是几个家庭系统的一部分。当您的婴儿站与您一起时，如平板电脑，您经常访问亲戚或朋友时，这非常有用。为“奶奶的房子”或“约翰叔叔的房子”创建另一个家庭，其中包括您的婴儿站设备与奶奶或约翰叔叔的设备配对。您可以随时通过婴儿站设备的 Gonimo 主屏幕在这些家庭中切换婴儿站设备。

### 想要参加吗？

Gonimo 团队喜欢开源。代码来自社区，代码用于社区。Gonimo 的用户对我们非常重要，但它们只是 Gonimo 故事的一部分。幕后有创意的大脑是创造出色婴儿监视器体验的关键。

目前我们特别需要那些愿意成为 iOS 11 测试者的人的帮助，因为 Apple 在 iOS 11 中对 WebRTC 的支持意味着我们最终将能够支持 iOS 设备。如果可以，请帮助我们实现这个令人赞叹的里程碑。

如果您了解 Haskell 或想要了解它，您可以查看 [GitHub 上我们的代码](https://github.com/gonimo/gonimo)。欢迎发起拉取请求、审查代码以及提出问题。

最后，请通过向新父母和开源世界宣传 Gonimo 婴儿监视器是易于使用并且便携的。

### 关于作者

Robert Klotzner：我是双胞胎的父亲，一个程序员。当我听到普通人可以给计算机编程时，我买了一本 1200 页的关于 C++ 的书开始学习，我当时才十五岁。我坚持用 C++ 相当长的一段时间，学习了 Java 又回归到 C++，学习了 D、Python 等等，最终学习了 Haskell。我喜欢 Haskell 是因为它丰富的类型系统，这几乎可以避免我书写错误的代码。强壮的静态类型和性能让我爱上了 C++……

---

via: <https://opensource.com/article/17/9/gonimo>

作者：[Robert Klotzner](https://opensource.com/users/robert-klotzner) 译者：[lintaov587](https://github.com/lintaov587) 校对：[wxy](https://github.com/wxy)

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


在 Linux 上使用 tarball

>
> Tarball 提供了一种在 Linux 系统上备份和管理一组文件的通用方法。请按照以下提示了解如何创建它们，以及从中提取和删除单个文件。
>
>
>

![](/data/attachment/album/201901/05/215151s2zqe3qzcd43f3ls.jpg)

“tarball” （LCTT 译注：国内也常称为“tar 包”）一词通常用于描述备份一组选择的文件并将它们打包在一个文件中的一种文件格式。该名称来自 .tar 文件扩展名和 `tar` 命令，它用于将文件打包到一个文件中，有时还会压缩该文件，使其在移动到其它系统时更小。

tarball 通常用于备份个人或系统文件来创建存档，特别是在进行可能需要撤消的更改之前。例如，Linux 系统管理员通常会在更改应用之前创建包含一系列配置文件的 tarball，以防必须撤消这些更改。从 tarball 中解压文件通常比在备份中搜索文件快。

### 如何在 Linux 上创建 tarball

使用如下命令，你可以在单条命令中创建 tarball 并压缩它。

```
$ tar -cvzf PDFs.tar.gz *.pdf
```

其结果是一个压缩文件（gzip 压缩的），其中包含了当前目录中的所有 PDF 文件。当然，压缩是可选的。一个稍微简单的只是将 PDF 文件打包成未压缩 tarball 的命令：

```
$ tar -cvf PDFs.tar *.pdf
```

注意，选项中的 `z` 将文件变成压缩的。 `c` 表明创建文件，`v`（详细）表示你在命令运行时需要一些反馈。如果你不想查看列出的文件，请忽略 `v`。

另一个常见的命名约定是给压缩的 tarball 命名成 .tgz 而不是双扩展名 .tar.gz，如下所示：

```
$ tar cvzf MyPDFs.tgz *.pdf
```

### 如何从 tarball 中解压文件

要从 gzip 压缩包中解压所有文件，你可以使用如下命令：

```
$ tar -xvzf file.tar.gz
```

如果使用 .tgz 命名约定，该命令将如下所示：

```
$ tar -xvzf MyPDFs.tgz
```

要从 gzip 包中解压单个文件，你可以执行几乎相同的操作，只需添加文件名：

```
$ tar -xvzf PDFs.tar.gz ShenTix.pdf
ShenTix.pdf
ls -l ShenTix.pdf
-rw-rw-r-- 1 shs shs 122057 Dec 14 14:43 ShenTix.pdf
```

如果未压缩 tarball，你甚至可以从 tarball 中删除文件。例如，如果我们想从 PDFs.tar.gz 中删除我们上面解压过的文件，我们会这样做：

```
$ gunzip PDFs.tar.gz
$ ls -l PDFs.tar
-rw-rw-r-- 1 shs shs 10700800 Dec 15 11:51 PDFs.tar
$ tar -vf PDFs.tar --delete ShenTix.pdf
$ ls -l PDFs.tar
-rw-rw-r-- 1 shs shs 10577920 Dec 15 11:45 PDFs.tar
```

请注意，我们在删除 ShenTix.pdf 后，缩小了一点 tarball 文件占用的空间。如果我们想要，我们可以再次压缩文件：

```
$ gzip -f PDFs.tar
ls -l PDFs.tar.gz
-rw-rw-r-- 1 shs shs 10134499 Dec 15 11:51 PDFs.tar.gzFlickr / James St. John
```

丰富的命令行选项使得 tarball 使用起来简单方便。

---

via: <https://www.networkworld.com/article/3328840/linux/working-with-tarballs-on-linux.html>

作者：[Sandra Henry-Stocker](https://www.networkworld.com/author/Sandra-Henry_Stocker/) 选题：[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/) 荣誉推出


如何成为一名懒惰的系统管理员

Summary: 我们是聪明地工作，而不是刻苦工作，但仍能把工作做好。

我们是聪明地工作，而不是刻苦工作，但仍能把工作做好。

>
> 我们是聪明地工作，而不是刻苦工作，但仍能把工作做好。
>
>
>

![](/data/attachment/album/201901/06/225109ycdfdggifxcdg43w.png)

Linux 的系统管理员的工作总是复杂的，并且总是伴随着各种陷阱和障碍。做每件事都没有足够时间，当你想完成那个半秃头老板（PHB）给的任务时，他（只会）不停在你的后面盯着，而最核心的服务器总是在最不合时宜的时间点崩溃，问题和挑战比比皆是。而我发现，成为一名<ruby> 懒惰的系统管理员 <rt>  Lazy SysAdmin </rt></ruby>可以解决这一困境。

（LCTT 译注：<ruby> <a href="https://en.wikipedia.org/wiki/Pointy-haired_Boss">  半秃头老板 </a> <rt>  Pointy-Haired Boss </rt></ruby>（PHB），那是[呆伯特漫画](https://zh.wikipedia.org/wiki/%E5%91%86%E4%BC%AF%E7%89%B9)中的角色，缺乏一般知识常识及其职位所应具有的管理能力，爱说大话且富有向物理显示挑战的精神，大概长成下图这样。）

![](/data/attachment/album/201901/06/225349yeenfejjjmvveoyo.jpeg)

我在即将在 Apress 出版的新书 《The Linux Philosophy for SysAdmins》（LCTT 译注：暂译《系统管理员的 Linux 哲学》）中更详细地讨论如何成为一个懒惰的系统管理员，那书预计会在 9 月出版（LCTT 译注：已于 2018 年 8 月出版）。这本的部分内容摘录自该书，特别是第九章，“成为一名懒惰的系统管理员”。在我们讨论如何做到这点前，让我们简单了解一下成为一个名懒惰的系统管理员意味着什么。

![](/data/attachment/album/201901/06/225110t47tw44ibvvmvcuu.jpg)

### 真实生产力 vs. 虚假生产力

#### 虚假生产力

在我工作的地方，半秃头老板相信的管理风格叫“<ruby> 走动式管理 <rt>  management by walking around </rt></ruby>”。通过判断某人在不在他的键盘上输入东西，或者至少要看看他们显示器上显示的东西，来判断他们的工作是否有效率。这是一个糟糕的工作场所。各部门间有道很高的行政墙，这会造就了许多的、微小的沟通壁垒，大量无用的文书工作，以及获得任何事情的许可都要等待漫长的时间。因为这样、那样的原因，不可能高效地做任何事情，如果真的是这样，那是非常低效。为了看起来很忙，我们都有自己的一套<ruby> “看起来很忙”的工具包 <rt>  Look Busy Kits </rt></ruby>（LBK），可能是一些短小的、用来显示一些行为活动的 Bash 脚本，或者是 `top`、`htop`、`iotop` 之类的程序，或者是一些持续显示某些行为活动的监控工具。这种工作场所的风气让人不可能真正高效，我讨厌这种地方，也讨厌那个几乎不可能完成任何有价值的事情的事实。

这种糟糕场所对真实的系统管理员来讲是场噩梦。没有人会感到快乐。在那里花费四五个月才能完成的事，在其他地方只需的一个早晨。我们没有什么实际工作要做，却要花大量的时间干活来让自己看起来很忙。我们在默默地竞赛，看谁能创造最好的“看起来很忙”的工具包，这就是我们花费最多时间的地方了。那份工作我只做了几个月，但好像已经耗费了一生。如果你看到的这个监狱的表面，你可能会说我们是很懒，因为我们只完成了几乎为 0 的实际工作。

这是个极端的例子，它完全与我所说的“我是一个懒惰的系统管理员”的意思相反，而做一个懒惰的系统管理是件好事。

#### 真实生产力

我很幸运，曾为一些真正的管理者工作过 —— 他们明白，系统管理员的生产力并不是以每天花多少小时敲键盘来衡量。毕竟，即使一只猴子能敲击他们的键盘，但也不能说明结果的价值。

正如我书中所言：

>
> “我是一个懒惰的系统管理员，同时我也是一个高效的系统管理员。这两者看似矛盾的说法不是相互排斥的，而是会以一种非常积极的方式相辅相成……
>
>
> “系统管理员在思考的时候是最高效的 —— 思考关于如何解决现有问题和避免未来的问题；思考怎样监控 Linux 计算机，以便找到预测和预示这些未来的问题的线索；思考如何让他们的工作更有效率；思考如何自动化所有这些要执行的任务，无论是每天还是每年一次的任务。
>
>
> “系统管理员冥思苦想的那一面是不会被非系统管理员所熟知的，那些人包括很多管理着系统管理员的人，比如那个半秃头老板。系统管理员都会以不同的方式解决他们工作中苦思的部分。一些我认识的系统管理员会在沙滩、骑自行车、参加马拉松或者攀岩时找到最好的想法。另一些人会认为静坐或听音乐的时候思考得最好。还有一些会在阅读小说、学习不相关的学科、甚至在学习 Linux 系统的时候可以最佳思考。关键是我们都有不同的方式激发我们的创造力，而这些创造力的推进器中很多并不涉及键盘上的任何一个按键。我们真正的生产力对于系统管理员周围的人来说可能是完全看不见的。”
>
>
>

成为懒惰的系统管理员有一些简单的秘诀 —— 系统管理员要完成一切需要完成的事，而且更多的是，当所有人都处于恐慌的状态时要保持冷静和镇定。秘诀的一部分是高效工作，另一部分是把预防问题放在首位。

### 成为懒惰系统管理员的方法

#### 多思考

我相信关于懒惰系统管理员最重要的秘诀在于思考。正如上面的摘录所言，优秀的系统管理员会花大量的时候思考这些事情，如何更有效率地工作，在异常成为问题前如何定位，更聪明地工作，做其它事情的同时会考虑如何完成这些事情等等。

例如，除了撰写本文之外，我现在正在想一个项目，我打算在从亚马逊和本地计算机商店采购的新部件到达时才开始。我有一台不太关键的计算机上的主板坏了，最近它的崩溃更频率。但我的一台非常老的小服务器并没有出现故障，它负责处理我的电子邮件和外部网站，以及为我的网络的其余部分提供 DHCP 和 DNS 服务，但需要解决由于各种外部攻击而导致的间歇性过载。

我一开始想，我只要替换故障设备的主板及其直接部件：内存、CPU，可能还有电源。但是在考虑了一段时间之后，我决定将新部件放到服务器中，并将旧的（但仍然可用的）部件从服务器移到故障设备中。可以这样做的，只需一、两个小时就可以从服务器上移除旧部件并安装新的。然后我就可以花时间更换出故障的电脑里的部件了。太好了，所以我开始在脑海中列出要完成的任务。

然而，当我查看这个任务列表时，我意识到服务器中唯一不能替换的部件是机箱和硬盘驱动器，这两台计算机的机箱几乎完全相同。在有了这个小小的发现之后，我开始考虑用新的部件替换出了故障的计算机的部件，并将之作为我的服务器。经过一些测试之后，我只需从当前的服务器移除硬盘，并将它安装到用了新组件的机箱中，改下网络配置项，再更改 KVM 交换机端口上的主机名，并更改机箱上的主机名标签，就可以了。这将大大减少服务器停机时间，大大减少我的压力。此外，如果出现故障，我可以简单地将硬盘移回原来的服务器，直到我可以用新服务器解决问题为止。

所以，现在我在脑海中已经创建了一个完成这项工作我所需要做的任务清单。而且，我希望你能仔细观察，当我脑子里想着这一切的时候，我的手指从来没有碰过键盘。我新的心理行动计划风险很低，与我最初的计划相比，涉及的服务器停机时间要少得多。

当我在 IBM 工作的时候，我经常看到很多语言中都有写着“**思考**”的标语。思考可以节省时间和压力，是懒散的系统管理员的主要标志。

#### 做预防性维护

在 1970 年代中期，我被 IBM 聘为客户工程师，我的领地由相当多的[穿孔卡片设备](https://en.wikipedia.org/wiki/Unit_record_equipment)组成。这也就是说，它们是处理打孔卡的重型机械设备，其中一些可以追溯到 20 世纪 30 年代。因为这些机器主要是机械的，所以它们的部件经常磨损或失调。我的部分工作是在它们损坏时修复它们。我工作的主要部分，也是最重要的部分，是首先要防止它们损坏。预防性维护的目的是在磨损部件损坏之前进行更换，并对还在运行的部件进行润滑和调整，以确保它们工作正常。

正如我在《系统管理员的 Linux 哲学》中所言：

>
> “我在 IBM 的经理们明白这只是冰山一角；他们和我都知道，我的工作是让顾客满意。虽然这通常意味着修复损坏的硬件，但也意味着减少硬件损坏的次数。这对客户来说是好事，因为他们的机器在工作时工作效率更高。这对我有好处，因为我从那些快乐的客户那里接到的电话要少得多。我也睡了更多的觉，因为这样做的结果是更少的非工作时间的紧急电话。我是个懒惰的（客户工程师）。通过提前做额外的工作，从长远来看，我需要做的工作要少得多。
>
>
> “这一原则已成为系统管理员的 Linux 哲学的功能原则之一。作为系统管理员，我们的时间最好用在最大限度地减少未来工作量的任务上。”
>
>
>

在 Linux 计算机中查找要解决的问题相当于项目管理。我检查系统日志，寻找以后可能会变得非常危险的问题的迹象。如果出现了一些小问题，或者我注意到我的工作站、服务器没有做出该有的响应，或者如果日志显示了一些不寻常的东西，所有这些都可以暗示出潜在的问题，而对于用户或半秃头老板来说，这些问题并没有产生明显的症状。

我经常检查 `/var/log/` 中的文件，特别是 `messages` 和 `security` 文件。我最常见的问题之一是许多脚本小子在我的防火墙系统上尝试各种类型的攻击。而且，不，我不依赖 ISP 提供的调制解调器/路由器中的所谓的防火墙。这些日志包含了大量关于企图攻击来源的信息，非常有价值。但是要扫描不同主机上的日志并将解决方案部署到位，需要做大量的工作，所以我转向自动化。

#### 自动化

我发现我的工作有很大一部分可以通过某种形式的自动化来完成。系统管理员的 Linux 哲学的原则之一是 “自动化一切”，这包括每天扫描日志文件等枯燥乏味的任务。

像是 [Logwatch](https://www.techrepublic.com/article/how-to-install-and-use-logwatch-on-linux/) 这类的程序能够监控你的日志文件中的异常条目，并在异常条目发生时通知您。Logwatch 通常作为 cron 任务每天运行一次，并向本地主机上的 root 用户发送电子邮件。你可以从命令行运行 Logwatch，并立即在显示器上查看结果。现在我只需要每天查看 Logwatch 的电子邮件通知。

但现实是，仅仅收到通知是不够的，因为我们不能坐以待毙。有时需要立即作出反应。我喜欢的另一个程序是——它能为我做所有事（看，这就是懒惰的管理员）——它就是 [Fail2ban](https://www.fail2ban.org/wiki/index.php/Main_Page)。Fail2Ban 会扫描指定的日志文件，查找各种类型的黑客攻击和入侵尝试，如果它发现某个 IP 地址在持续做特定类型的活动，它会向防火墙添加一个条目，在指定的时间内阻止来自该 IP 地址的任何进一步的黑客尝试。默认值通常在 10 分钟左右，但我喜欢为大多数类型的攻击指定为 12 或 24 小时。每种类型的黑客攻击都是单独配置的，例如尝试通过 SSH 登录和那些 Web 服务器的攻击。

#### 写脚本

自动化是这种哲学的关键组成部分之一。一切可以自动化的东西都应该自动化的，其余的尽可能地自动化。所以，我也写了很多脚本来解决问题，也就是说我编写了脚本来完成我的大部分工作。

我的脚本帮我节省了大量时间，因为它们包含执行特定任务的命令，这大大减少了我需要输入的数量。例如，我经常重新启动我的电子邮件服务器和垃圾邮件过滤软件（当修改 SpamAssassin 的 `local.cf` 配置文件时，就需要重启）。必须按特定顺序停止并重新启动这些服务。因此，我用几个命令编写了一个简短的脚本，并将其存储在可访问的 `/usr/local/bin` 中。现在，不用键入几个命令并等待每个命令都完成，然后再键入下一个命令，更不用记住正确的命令顺序和每个命令的正确语法，我输入一个三个字符的命令，其余的留给我的脚本来完成。

#### 简化键入

另一种成为懒惰的系统管理员的方法是减少我们需要键入的数量。而且，我的打字技巧真的很糟糕（也就是说，我一点也没有，顶多是几个笨拙的手指）。导致错误的一个可能原因是我糟糕的打字技巧，所以我会尽量少打字。

绝大多数 GNU 和 Linux 核心实用程序都有非常短的名称。然而，它们都是有意义的名字。诸如用于更改目录的 `cd` 、用于列出目录内容的 `ls` 和用于磁盘转储的 `dd` 等工具都一目了然。短名字意味着更少的打字和更少的产生错误机会。我认为短的名字通常更容易记住。

当我编写 shell 脚本时，我喜欢保持名称简短而意义（至少对我来说是），比如用于 rsync 备份的 `rsbu`（LCTT 译注，Rsync Backup 的简写）。但在某些情况下，我喜欢使用更长的名称，比如 `doUpdates` 来执行系统更新。在后一种情况下，更长一点的名字让脚本的目的更明显。这可以节省时间，因为很容易记住脚本的名称。

其他减少键入的方法包括命令行别名、历史命令调回和编辑。别名只是你在 Bash shell 键入命令时才做的替换。键入 `alias` 命令会看到默认配置的别名列表。例如，当你输入命令 `ls` 时，会被条目 `alias ls='ls –color=auto'` 替成较长的命令，因此你只需键入 2 个字符而不是 14 个字符即可获得带有颜色的文件列表。还可以使用 `alias` 命令添加你自己定义的别名。

历史命令调回允许你使用键盘的向上和向下箭头键滚动浏览命令历史记录。如果需要再次使用相同的命令，只需在找到所需的命令时按回车键即可。如果在找到命令后需要更改该命令，则可以使用标准命令行编辑功能进行更改。

### 结束语

一名懒惰的系统管理员实际上也有很多的工作。但我们是聪明地工作，而不是刻苦工作。早在一堆小问题汇聚成大问题之前，我们就花时间探索我们负责的主机，并处理好所有的小问题。我们花了很多时间思考解决问题的最佳方法，我们也花了很多时间来发现新的方法，让自己更聪明地工作，成为懒惰的系统管理员。

除了这里描述的少数方法外，还有许多其他的方式可以成为懒惰的系统管理员。我相信你也有一些自己的方式；请在评论中和我们分享。

---

via: <https://opensource.com/article/18/7/how-be-lazy-sysadmin>

作者：[David Both](https://opensource.com/users/dboth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[zgj1024](https://github.com/zgj1024) 校对：[wxy](https://github.com/wxy)

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


COPR 仓库中 4 个很酷的新软件（2018.12）

Summary: COPR 是软件的个人存储库的集合，它包含那些不在标准的 Fedora 仓库中的软件。

![](/data/attachment/album/201901/06/232251f997n99953z98z8y.jpg)

COPR 是软件的个人存储库的[集合](https://copr.fedorainfracloud.org/)，它包含那些不在标准的 Fedora 仓库中的软件。某些软件不符合允许轻松打包的标准。或者它可能不符合其他 Fedora 标准，尽管它是自由开源的。COPR 可以在标准的 Fedora 包之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持，或者是由项目自己背书的。但是，它是尝试新的或实验性软件的一种很好的方法。

这是 COPR 中一组新的有趣项目。

### MindForger

[MindForger](https://www.mindforger.com/) 是一个 Markdown 编辑器和笔记本。除了你预期的 Markdown 编辑器的功能之外，MindForger 还允许你将单个文件拆分为多个笔记。组织笔记并在文件之间移动、搜索它们都很容易。我已经使用 MindForger 一段时间来记录学习笔记了，现在可以在 COPR 中找到它啦。

![](/data/attachment/album/201901/06/232251po8j8d4b14ozf8fg.png)

#### 安装说明

该仓库目前在 Fedora 29 和 Rawhide 中提供 MindForger。要安装 MindForger，请使用以下命令：

```
sudo dnf copr enable deadmozay/mindforger
sudo dnf install mindforger
```

### Clingo

[Clingo](https://potassco.org/clingo/) 是使用[回答集编程](https://en.wikipedia.org/wiki/Answer_set_programming)（ASP）建模语言解决逻辑问题的程序。使用 ASP，你可以将问题声明为一个逻辑程序，然后 Clingo 来解决。最后，Clingo 以逻辑模型的形式产生问题的解决方案，称为回答集。

#### 安装说明

该仓库目前为 Fedora 28 和 29 提供 Clingo。要安装 Clingo，请使用以下命令：

```
sudo dnf copr enable timn/clingo
sudo dnf install clingo
```

### SGVrecord

[SGVrecord](https://github.com/yucefsourani/sgvrecord) 是一个用于录制屏幕的简单工具。它允许你捕获整个屏幕或仅选择其中的一部分。此外，有没有声音都可以进行录制。SGVrecord 以 WebM 格式生成文件。

![](/data/attachment/album/201901/06/232252ofqifqkzqu0fff5u.png)

#### 安装说明

该仓库目前为 Fedora 28、29 和 Rawhide 提供 SGVrecord。要安装 SGVrecord，请使用以下命令：

```
sudo dnf copr enable youssefmsourani/sgvrecord
sudo dnf install sgvrecord
```

### Watchman

[Watchman](https://facebook.github.io/watchman/) 是一个对文件更改进行监视和记录的服务。你可以为指定 Watchman 监视的目录树，以及定义指定文件发生更改时触发的操作。

#### 安装说明

该仓库目前为 Fedora 29 和 Rawhide 提供 Watchman。要安装 Watchman，请使用以下命令：

```
sudo dnf copr enable eklitzke/watchman
sudo dnf install watchman
```

---

via: <https://fedoramagazine.org/4-try-copr-december-2018/>

作者：[Dominik Turecek](https://fedoramagazine.org) 选题：[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/) 荣誉推出


用 PGP 保护代码完整性（六）：在 Git 上使用 PGP

>
> 我们继续我们的 PGP 实践系列，来看看签名标签的标签和提交，这可以帮你确保你的仓库没有被篡改。
>
>
>

![](/data/attachment/album/201901/07/000946kbvjmw5aj6q38qr8.jpg)

在本系列教程中，我们提供了一个使用 PGP 的实用指南，包括基本概念和工具、生成和保护你的密钥。如果你错过了前面的文章，你可以查看下面的链接。在这篇文章中，我们谈一谈在 Git 中如何集成 PGP、使用签名的标签，然后介绍签名提交，最后添加签名推送的支持。

* [第一部分：基本概念和工具](/article-9524-1.html)
* [第二部分：生成你的主密钥](/article-9529-1.html)
* [第三部分：生成 PGP 子密钥](/article-9607-1.html)
* [第四部分：将主密钥移到离线存储中](/article-10402-1.html)
* [第五部分：将子密钥移到硬件设备中](/article-10415-1.html)

Git 的核心特性之一就是它的去中心化本质 —— 一旦仓库克隆到你的本地系统，你就拥有了项目的完整历史，包括所有的标签、提交和分支。然而由于存在着成百上千的克隆仓库，如何才能验证你下载的仓库没有被恶意的第三方做过篡改？你可以从 GitHub 或一些貌似官方的位置来克隆它们，但是如果有些人故意欺骗了你怎么办？

或者在你参与的一些项目上发现了后门，而 “Author” 行显示是你干的，然而你很确定 [不是你干的](https://github.com/jayphelps/git-blame-someone-else)，会发生什么情况？

为解决上述问题，Git 添加了 PGP 集成。签名的标签通过确认它的内容与创建这个标签的开发者的工作站上的内容完全一致来证明仓库的完整性，而签名的提交几乎是不可能在不访问你的 PGP 密钥的情况下能够假冒你。

#### 清单

* 了解签名的标签、提交和推送（必要）
* 配置 git 使用你的密钥（必要）
* 学习标签如何签名和验证（必要）
* 配置 git 总是签名带注释标签（推荐）
* 学习提交如何签名和验证工作（必要）
* 配置 git 总是签名提交（推荐）
* 配置 gpg-agent 选项（必要）

#### 考虑事项

git 实现了 PGP 的多级集成，首先从签名标签开始，接着介绍签名提交，最后添加签名推送的支持。

##### 了解 Git 哈希

git 是一个复杂的东西，为了你能够更好地掌握它如何集成 PGP，你需要了解什么是”哈希“。我们将它归纳为两种类型的哈希：树哈希和提交哈希。

###### 树哈希

每次你向仓库提交一个变更，对于仓库中的每个子目录，git 都会记录它里面所有对象的校验和哈希 —— 内容（blobs）、目录（trees）、文件名和许可等等。它只对每次提交中发生变更的树和内容做此操作，这样在只变更树的一小部分时就不必去重新计算整个树的校验和。

然后再计算和存储处于顶级的树的校验和，这样如果仓库的任何一部分发生变化，校验和将不可避免地发生变化。

###### 提交哈希

一旦创建了树哈希，git 将计算提交哈希，它将包含有关仓库和变更的下列信息：

* 树哈希的校验和
* 变更前树哈希的校验和（父级）
* 有关作者的信息（名字、email、创作时间）
* 有关提交者的信息（名字、email、提交时间）
* 提交信息

###### 哈希函数

在写这篇文章时，虽然研究一种更强大的、抗碰撞的算法的工作正在进行，但 git 仍然使用的是 SHA1 哈希机制去计算校验和。注意，git 已经包含了碰撞防范程序，因此认为对 git 成功进行碰撞攻击仍然是不可行的。

#### 带注释标签和标签签名

在每个 Git 仓库中，标签允许开发者标记特定的提交。标签可以是 “轻量级的” —— 几乎只是一个特定提交上的指针，或者它们可以是 “带注释的”，它自己将成为 git 树中的项目。一个带注释标签对象包含所有下列的信息：

* 成为标签的提交的哈希的校验和
* 标签名字
* 关于打标签的人的信息（名字、email、打标签时间）
* 标签信息

一个 PGP 签名的标签是一个带有将所有这些条目封装进一个 PGP 签名的带注释标签。当开发者签名他们的 git 标签时，他们实际上是向你保证了如下的信息：

* 他们是谁（以及他们为什么应该被信任）
* 他们在签名时的仓库状态是什么样：
	+ 标签包含的提交的哈希
		- 提交的哈希包含了顶级树的哈希
		- 顶级树哈希包含了所有文件、内容和子树的哈希
		- 它也包含有关作者的所有信息
		- 包含变更发生时的精确时间

当你克隆一个仓库并验证一个签名的标签时，就是向你以密码方式保证：仓库中的所有内容、包括所有它的历史，与开发者签名时在它的计算机上的仓库完全一致。

#### 签名的提交

签名的提交与签名的标签非常类似 —— PGP 签名的是提交对象的内容，而不是标签对象的内容。一个提交签名也给你提供了开发者签名时开发者树上的全部可验证信息。标签签名和提交的 PGP 签名提供了有关仓库和它的完整历史的完全一致的安全保证。

#### 签名的推送

为了完整起见，在这里包含了签名的推送这一功能，因为在你使用这个功能之前，需要在接收推送的服务器上先启用它。正如我们在上面所说过的，PGP 签名一个 git 对象就是提供了开发者的 git 树当时的可验证信息，但不提供开发者对那个树意图相关的信息。

比如，你可以在你自己复刻的 git 仓库的一个实验分支上尝试一个很酷的特性，为了评估它，你提交了你的工作，但是有人在你的代码中发现了一个恶意的 bug。由于你的提交是经过正确签名的，因此有人可能将包含有恶意 bug 的分支推入到 master 分支中，从而在生产系统中引入一个漏洞。由于提交是经过你的密钥正确签名的，所以一切看起来都是合理合法的，而当 bug 被发现时，你的声誉就会因此而受到影响。

在 `git push` 时，为了验证提交的意图而不仅仅是验证它的内容，添加了要求 PGP 推送签名的功能。

#### 配置 git 使用你的 PGP 密钥

如果在你的钥匙环上只有一个密钥，那么你就不需要再做额外的事了，因为它是你的默认密钥。

然而，如果你有多个密钥，那么你必须要告诉 git 去使用哪一个密钥。（`[fpr]` 是你的密钥的指纹）：

```
$ git config --global user.signingKey [fpr]
```

注意：如果你有一个不同的 `gpg2` 命令，那么你应该告诉 git 总是去使用它，而不是传统的版本 1 的 `gpg`：

```
$ git config --global gpg.program gpg2
```

#### 如何使用签名标签

创建一个签名的标签，只要传递一个简单地 `-s` 开关给 `tag` 命令即可：

```
$ git tag -s [tagname]
```

我们建议始终对 git 标签签名，这样让其它的开发者确信他们使用的 git 仓库没有被恶意地修改过（比如，引入后门）：

##### 如何验证签名的标签

验证一个签名的标签，只需要简单地使用 `verify-tag` 命令即可：

```
$ git verify-tag [tagname]
```

如果你要验证其他人的 git 标签，那么就需要你导入他的 PGP 公钥。请参考 “可信任的团队沟通” 一文中关于此主题的指导。

##### 在拉取时验证

如果你从项目仓库的其它复刻中拉取一个标签，git 将自动验证签名，并在合并操作时显示结果：

```
$ git pull [url] tags/sometag
```

合并信息将包含类似下面的内容：

```
Merge tag 'sometag' of [url]

[Tag message]

# gpg: Signature made [...]
# gpg: Good signature from [...]
```

#### 配置 git 始终签名带注释标签

很可能的是，你正在创建一个带注释标签，你应该去签名它。强制 git 始终签名带注释的标签，你可以设置一个全局配置选项：

```
$ git config --global tag.forceSignAnnotated true
```

或者，你始终记得每次都传递一个 `-s` 开关：

```
$ git tag -asm "Tag message" tagname
```

#### 如何使用签名的提交

创建一个签名的提交很容易，但是将它纳入到你的工作流中却很困难。许多项目使用签名的提交作为一种 “Committed-by:” 的等价行，它记录了代码来源 —— 除了跟踪项目历史外，签名很少有人去验证。在某种意义上，签名的提交用于 “篡改证据”，而不是 git 工作流的 “篡改证明”。

为创建一个签名的提交，你只需要 `git commit` 命令传递一个 `-S` 标志即可（由于它与另一个标志冲突，所以改为大写的 `-S`）：

```
$ git commit -S
```

我们建议始终使用签名提交，并要求项目所有成员都这样做，这样其它人就可以验证它们（下面就讲到如何验证）。

##### 如何去验证签名的提交

验证签名的提交需要使用 `verify-commit` 命令：

```
$ git verify-commit [hash]
```

你也可以查看仓库日志，要求所有提交签名是被验证和显示的：

```
$ git log --pretty=short --show-signature
```

##### 在 git 合并时验证提交

如果项目的所有成员都签名了他们的提交，你可以在合并时强制进行签名检查（然后使用 `-S` 标志对合并操作本身进行签名）：

```
$ git merge --verify-signatures -S merged-branch
```

注意，如果有一个提交没有签名或验证失败，将导致合并操作失败。通常情况下，技术是最容易的部分 —— 而人的因素使得项目中很难采用严格的提交验证。

##### 如果你的项目在补丁管理上采用邮件列表

如果你的项目在提交和处理补丁时使用一个邮件列表，那么一般很少使用签名提交，因为通过那种方式发送时，签名信息将会丢失。对提交进行签名仍然是非常有用的，这样其他人就能引用你托管在公开 git 树作为参考，但是上游项目接收你的补丁时，仍然不能直接使用 git 去验证它们。

尽管，你仍然可以签名包含补丁的电子邮件。

#### 配置 git 始终签名提交

你可以告诉 git 总是签名提交：

```
git config --global commit.gpgSign true
```

或者你每次都记得给 `git commit` 操作传递一个 `-S` 标志（包括 `—amend`）。

#### 配置 gpg-agent 选项

GnuPG agent 是一个守护工具，它能在你使用 gpg 命令时随时自动启动，并运行在后台来缓存私钥的密码。这种方式让你只需要解锁一次密钥就可以重复地使用它（如果你需要在一个自动脚本中签署一组 git 操作，而不想重复输入密钥，这种方式就很方便）。

为了调整缓存中的密钥过期时间，你应该知道这两个选项：

* `default-cache-ttl`（秒）：如果在 TTL 过期之前再次使用同一个密钥，这个倒计时将重置成另一个倒计时周期。缺省值是 600（10 分钟）。
* `max-cache-ttl`（秒）：自首次密钥输入以后，不论最近一次使用密钥是什么时间，只要最大值的 TTL 倒计时过期，你将被要求再次输入密码。它的缺省值是 30 分钟。

如果你认为这些缺省值过短（或过长），你可以编辑 `~/.gnupg/gpg-agent.conf` 文件去设置你自己的值：

```
# set to 30 minutes for regular ttl, and 2 hours for max ttl
default-cache-ttl 1800
max-cache-ttl 7200
```

##### 补充：与 ssh 一起使用 gpg-agent

如果你创建了一个 [A](https://www.linux.com/users/mricon)（验证）密钥，并将它移到了智能卡，你可以将它用到 ssh 上，为你的 ssh 会话添加一个双因子验证。为了与 agent 沟通你只需要告诉你的环境去使用正确的套接字文件即可。

首先，添加下列行到你的 `~/.gnupg/gpg-agent.conf` 文件中：

```
enable-ssh-support
```

接着，添加下列行到你的 `.bashrc` 文件中：

```
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
```

为了让改变生效，你需要杀掉正在运行的 gpg-agent 进程，并重新启动一个新的登入会话：

```
$ killall gpg-agent
$ bash
$ ssh-add -L
```

最后的命令将列出代表你的 PGP Auth 密钥的 SSH（注释应该会在结束的位置显示： cardno:XXXXXXXX，表示它来自智能卡）。

为了启用 ssh 的基于密钥的登入，只需要在你要登入的远程系统上添加 `ssh-add -L` 的输出到 `~/.ssh/authorized_keys` 中。祝贺你，这将使你的 SSH 登入凭据更难以窃取。

此外，你可以从公共密钥服务器上下载其它人的基于 PGP 的 ssh 公钥，这样就可以赋予他登入 ssh 的权利：

```
$ gpg --export-ssh-key [keyid]
```

如果你有让开发人员通过 ssh 来访问 git 仓库的需要，这将让你非常方便。下一篇文章，我们将提供像保护你的密钥那样保护电子邮件帐户的小技巧。

---

via: <https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-6-using-pgp-git>

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

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


10 个供管理员救急的杀手级工具

Summary: 可以让你赶快离开办公室的网络管理技巧和工具。

可以让你赶快离开办公室的网络管理技巧和工具。

>
> 可以让你赶快离开办公室的网络管理技巧和工具。
>
>
>

![](/data/attachment/album/201901/07/222713gl2xjjr2qz6rij29.png)

当工作任务堆积成山时，管理网络和系统就变得十分有压力了。没有人能真正意识到需要花费多长时间，每个人都希望在昨天就完成他们的工作。

所以难怪我们这么多人都被致力于找出有效的方法并与大家分享的开源精神所吸引。因为，当截止日期来临，并且当天没有足够多的时间时，如果你可以找到立刻施行的免费答案，那会非常有帮助。

因此，闲话少叙，下述是我的瑞士军刀，可以保证你在晚饭前离开办公室。

### 服务器配置和脚本

让我们看一看！

* [NixCraft](https://www.cyberciti.biz/)

使用该网站的搜索功能。经过十多年的定期更新，这里遍地是黄金！有用的脚本和方便的技巧可以立刻解决你的问题。这是我一般使用 Google 后的第二个选项。
* [Webmin](http://www.webmin.com/)

它提供给你了一个很好的 Web 界面来帮助你远程编辑配置文件。它减少了在处理目录路径和 `sudo nano` 上花费的大量时间，在你处理多个客户时，非常方便。
* [Windows 下的 Linux 子系统](http://wsl-guide.org/en/latest/)

现代工作场所的现实是大多数员工都运行着 Windows，而服务器机房中不断增长的设备则运行着 Linux 。因此，有些时候你会发现尝试在 Windows 桌面上执行管理任务。

你怎么做？装一个虚拟机？如果安装目前 Windows 10 中免费提供的 Linux 子系统的兼容层，实际上要快得多，配置要少的多。

这为你提供了一个 Bash 终端窗口，你可以在这个窗口中执行本地计算机上的 Bash 脚本和 Linux 二进制文件，可以完全访问 Windows 和 Linux 文件系统，以及安装网络驱动器。它包含 Ubuntu 、OpenSUSE、SLES、Debian 和 Kali 发行版。
* [mRemoteNG](https://mremoteng.org/)

当你有 100 多个服务器需要去管理时，这会是一个出色的 SSH 和远程桌面客户端。

### 设置网络，这样你就无需再这样做了。

一个设计不周的网络是厌恶加班的管理员的死敌。

* [可拓展的 IP 寻址方案](https://blog.dxmtechsupport.com.au/ip-addressing-for-a-small-business-that-might-grow/)

IP 地址耗尽的可怕之处在于，当 IP 地址耗尽时，网络已经变的足够大，而新的寻址方案是众所周知的昂贵、令人痛苦的耗时。

没有人有时间做这件事！

到了某个时候，IPv6 终将到来，来拯救这世界。但在那之前，无论世界向我们扔了多少可穿戴设备、平板电脑、智能锁、灯、安全摄像头、VoIP 耳机和浓缩咖啡机，这些以不变应万变的 IP 寻址方案都应该让我们继续前行。
* [Linux Chmod 权限备忘录](https://isabelcastillo.com/linux-chmod-permissions-cheat-sheet)

一个简短但是有用的 Bash 命令备忘录可以帮助你通过网络设置权限。所以，客户服务部的账单落入到勒索软件骗局时，你可以只恢复他们的文件，而不是整个公司的文件。
* [VLSM 子网计算器](http://www.vlsm-calc.net/)

只需要输入你想要从地址空间中创建的网络的数量，以及每个网络所需要的主机数量，它就可以计算出所有的子网掩码应该是什么。

### 单一用途的 Linux 发行版

需要一个只做一件事的 Linux 容器？如果其他人已经在一个操作系统上搞好了一个小东西，你就可以快速安装它并马上投入使用。

下面这些每一个都使得我的工作变得轻松了许多。

* [Porteus Kiosk](http://porteus-kiosk.org/)

这个工具用来帮你把一台电脑上锁定到一个浏览器上。通过稍稍一些调整，你甚至可以把浏览器锁定在一个特定的网站上。它对于公共访问机器来说非常方便。它可以与触摸屏或键盘鼠标配合使用。
* [Parted Magic](https://partedmagic.com/)

这是一个你可以从 USB 驱动器启动的，可以用来划分磁盘驱动器、恢复数据并运行基准测试工具的操作系统。
* [IPFire](https://www.ipfire.org/)

啊哈～我还是不敢相信有人把路由器/防火墙/代理组合成为“我尿火”（LCTT 译注：IPFire 和 “I pee Fire“ 同音)。这是我在这个 Linux 发行版中第二喜欢的东西。我最喜欢的是它是一个非常可靠的软件套件，设置和配置十分容易，而且有一系列的插件可以拓展它。

那么，你呢？你发现了哪些工具、资源和备忘录可以让我们的工作日更加的轻松？我很高兴知道，请在评论中分享您的工具。

---

via: <https://opensource.com/article/18/7/tools-admin>

作者：[Grant Hamono](https://opensource.com/users/grantdxm) 选题：[lujun9972](https://github.com/lujun9972) 译者：[bestony](https://github.com/bestony) 校对：[wxy](https://github.com/wxy)

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


YAML：可能并不是那么完美

Summary: 不要误解我的意思，并不是说 YAML 很糟糕 —— 它肯定不像使用 JSON 那么多的问题 —— 但它也不是非常好。

![](/data/attachment/album/201901/07/235036g8naktbcmzmnrkpm.jpg)

我之前写过[为什么将 JSON 用于人类可编辑的配置文件是一个坏主意](http://arp242.net/weblog/JSON_as_configuration_files-_please_dont.html)，今天我们将讨论 YAML 格式的一些常见问题。

### 默认情况下不安全

YAML 默认是不安全的。加载用户提供的（不可信的）YAML 字符串需要仔细考虑。

```
!!python/object/apply:os.system
args: ['ls /']
```

用 `print(yaml.load(open('a.yaml')))` 运行它，应该给你这样的东西：

```
bin   etc   lib    lost+found  opt   root  sbin  tmp  var sys
boot  dev   efi    home        lib64 mnt   proc  run  srv usr
0
```

许多其他语言（包括 Ruby 和 PHP    1  ）默认情况下也不安全（LCTT 译注：这里应该说的是解析 yaml）。[在 GitHub 上搜索 yaml.load](https://github.com/search?q=yaml.load&type=Code&utf8=%E2%9C%93) 会得到惊人的 280 万个结果，而 [yaml.safe\_load](https://github.com/search?q=yaml.safe_load&type=Code&utf8=%E2%9C%93) 只能得到 26000 个结果。

提个醒，很多这样的 `yaml.load()` 都工作的很好，在配置文件中加载 `yaml.load()` 通常没问题，因为它通常（虽然并不总是！）来自“可靠源”，而且很多都来自静态的 YAML 测试文件。但是，人们还是不禁怀疑在这 280 万个结果中隐藏了多少漏洞。

这不是一个理论问题。在 2013 年，[正是由于这个问题，所有的 Ruby on Rails 应用程序都被发现易受](https://www.sitepoint.com/anatomy-of-an-exploit-an-in-depth-look-at-the-rails-yaml-vulnerability/)远程代码执行攻击。

有人可能会反驳说这不是 YAML 格式的错误，而是那些库实现错误的的问题，但似乎大多数库默认不是安全的（特别是动态语言），所以事实上这是 YAML 的一个问题。

有些人可能会反驳认为修复它就像用 `safe_load()` 替换 `load()` 一样容易，但是很多人都没有意识到这个问题，即使你知道它，它也是很容易忘记的事情之一。这是非常糟糕的 API 设计。

### 可能很难编辑，特别是对于大文件

YAML 文件可能很难编辑，随着文件变大，这个难度会快速增大。

一个很好的例子是 Ruby on Rails 的本地化翻译文件。例如：

```
en:
   formtastic:
     labels:
       title: "Title"  # Default global value
       article:
         body: "Article content"
       post:
         new:
           title: "Choose a title..."
           body: "Write something..."
         edit:
           title: "Edit title"
           body: "Edit body"
```

看起来不错，对吧？但是如果这个文件有 100 行怎么办？或者 1,000 行？在文件中很难看到 “where”，因为它可能在屏幕外。你需要向上滚动，但是你需要跟踪缩进，即使遵循缩进指南也很难，特别是因为 2 个空格缩进是常态而且 [制表符缩进被禁止](http://www.yaml.org/faq.html)    2  。

不小心缩进出错通常不算错误，它通常只是反序列化为你不想要的东西。这样只能祝你调试快乐！

我已经愉快地编写 Python 长达十多年，所以我已经习惯了显眼的空白，但有时候我仍在和 YAML 抗争。在 Python 中，虽然没有那种长达几页的函数，但数据或配置文件的长度没有这种自然限制，这就带来了缺点和损失了清晰度。

对于小文件，这不是问题，但它确实无法很好地扩展到较大的文件，特别是如果你以后想编辑它们的话。

### 这非常复杂

在浏览一个基本的例子时，YAML 看似“简单”和“显而易见”，但事实证明并非如此。[YAML 规范](http://yaml.org/spec/1.2/spec.pdf)有 23449 个单词，为了比较，[TOML](https://github.com/toml-lang/toml) 有 3339 个单词，[Json](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf) 有 1969 个单词，[XML](https://www.w3.org/TR/REC-xml/) 有 20603 个单词。

我们中有谁读过全部规范吗？有谁读过并理解了全部？谁阅读过，理解进而**记住**所有这些？

例如，你知道[在 YAML 中编写多行字符串有 9 种方法](http://stackoverflow.com/a/21699210/660921)吗？并且它们具有细微的不同行为。

是的 :-/

如果你看一下[那篇文章的修订历史](http://stackoverflow.com/posts/21699210/revisions)，它就会变得更加有趣，因为文章的作者发现了越来越多的方法可以实现这一点，以及更多的细微之处。

它从预览开始告诉我们 YAML 规范，它表明（强调我的）：

>
> 本节简要介绍了 YAML 的表达能力。**预计初次阅读的人不可能理解所有的例子**。相反，这些选择用作该规范其余部分的动机。
>
>
>

#### 令人惊讶的行为

以下会解析成什么（[Colm O’Connor](https://github.com/crdoconnor/strictyaml/blob/master/FAQ.rst#what-is-wrong-with-implicit-typing) 提供的例子）：

```
- Don Corleone: Do you have faith in my judgment?
- Clemenza: Yes
- Don Corleone: Do I have your loyalty?
```

结果为：

```
[
    {'Don Corleone': 'Do you have faith in my judgment?'},
    {'Clemenza': True},
    {'Don Corleone': 'Do I have your loyalty?'}
]
```

那么这个呢：

```
python: 3.5.3
postgres: 9.3
```

`3.5.3` 被识别为字符串，但 `9.3` 被识别为数字而不是字符串：

```
{'python': '3.5.3', 'postgres': 9.3}
```

这个呢：

```
Effenaar: Eindhoven
013: Tilburg
```

`013` 是<ruby> 蒂尔堡 <rt>  Tilburg </rt> <rt> </rt></ruby>的一个流行音乐场地，但 YAML 会告诉你错误答案，因为它被解析为八进制数字：

```
{11: 'Tilburg', 'Effenaar': 'Eindhoven'}
```

所有这一切，以及更多，就是为什么许多经验丰富的 YAMLer 经常会将所有字符串用引号引起来的原因，即使它不是严格要求。许多人不使用引号，而且很容易忘记，特别是如果文件的其余部分（可能由其他人编写）不使用引号。

### 它不方便

因为它太复杂了，它所声称的可移植性被夸大了。例如，考虑以下这个从 YAML 规范中获取的示例：

```
? - Detroit Tigers
  - Chicago cubs
:
  - 2001-07-23

? [ New York Yankees,
    Atlanta Braves ]
: [ 2001-07-02, 2001-08-12,
    2001-08-14 ]
```

抛开大多数读者可能甚至不知道这是在做什么之外，请尝试使用 PyYAML 在 Python 中解析它：

```
yaml.constructor.ConstructorError: while constructing a mapping
  in "a.yaml", line 1, column 1
found unhashable key
  in "a.yaml", line 1, column 3
```

在 Ruby 中，它可以工作：

```
{
    ["Detroit Tigers", "Chicago cubs"] => [
        #<Date: 2001-07-23 ((2452114j,0s,0n),+0s,2299161j)>
    ],
    ["New York Yankees", "Atlanta Braves"] => [
        #<Date: 2001-07-02 ((2452093j,0s,0n),+0s,2299161j)>,
        #<Date: 2001-08-12 ((2452134j,0s,0n),+0s,2299161j)>,
        #<Date: 2001-08-14 ((2452136j,0s,0n),+0s,2299161j)>
    ]
}
```

这个原因是你不能在 Python 中使用列表作为一个字典的键：

```
>>> {['a']: 'zxc'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  TypeError: unhashable type: 'list'
```

而这种限制并不是 Python 特有的，PHP、JavaScript 和 Go 等常用语言都有此限制。

因此，在 YAML 文件中使用这种语法，你将无法在大多数语言中解析它。

这是另一个从 YAML 规范的示例部分中获取的：

```
# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey

# Team ranking
---
- Chicago Cubs
- St Louis Cardinals
```

Python 会输出：

```
yaml.composer.ComposerError: expected a single document in the stream
  in "a.yaml", line 3, column 1
but found another document
  in "a.yaml", line 8, column 1
```

然而 Ruby 输出：

```
["Mark McGwire", "Sammy Sosa", "Ken Griffey"]
```

原因是单个文件中有多个 YAML 文档（`---` 意味开始一个新文档）。在 Python 中，有一个 `load_all` 函数来解析所有文档，而 Ruby 的 `load()` 只是加载第一个文档，据我所知，它没有办法加载多个文档。

[在实现之间存在很多不兼容](https://github.com/cblp/yaml-sucks)。

### 目标实现了吗？

规范说明：

>
> YAML 的设计目标安装优先级降序排列如下：
>
>
> 1. YAML 很容易被人类阅读。
> 2. YAML 数据在编程语言之间是可移植的。
> 3. YAML 匹配敏捷语言的原生数据结构。
> 4. YAML 有一个一致的模型来支持通用工具。
> 5. YAML 支持一次性处理。
> 6. YAML 具有表现力和可扩展性。
> 7. YAML 易于实现和使用。
>
>
>

那么它做的如何呢？

>
> YAML 很容易被人类阅读。
>
>
>

只有坚持一小部分子集时才有效。完整的规则集很复杂 —— 远远超过 XML 或 JSON。

>
> YAML 数据在编程语言之间是可移植的。
>
>
>

事实并非如此，因为创建常见语言不支持的结构太容易了。

>
> YAML 匹配敏捷语言的原生数据结构。
>
>
>

参见上面。另外，为什么只支持敏捷（或动态）语言？其他语言呢？

>
> YAML 有一个一致的模型来支持通用工具。
>
>
>

我甚至不确定这意味着什么，我找不到任何详细说明。

>
> YAML 支持一次性处理。
>
>
>

这点我接受。

>
> YAML 具有表现力和可扩展性。
>
>
>

嗯，是的，但它太富有表现力（例如太复杂）。

>
> YAML 易于实现和使用。
>
>
>

```
$ cat `ls -1 ~/gocode/src/github.com/go-yaml/yaml/*.go | grep -v _test` | wc -l
9247

$ cat /usr/lib/python3.5/site-packages/yaml/*.py | wc -l
5713
```

### 结论

不要误解我的意思，并不是说 YAML 很糟糕 —— 它肯定不像[使用 JSON 那么多的问题](http://arp242.net/weblog/JSON_as_configuration_files-_please_dont.html) —— 但它也不是非常好。有一些一开始并不明显的缺点和惊喜，还有许多更好的替代品，如 [TOML](https://github.com/toml-lang/toml) 和其他更专业的格式。

就个人而言，当我有选择时，我不太可能再次使用它。

如果你必须使用 YAML，那么我建议你使用 [StrictYAML](https://github.com/crdoconnor/strictyaml)，它会删除一些（虽然不是全部）比较麻烦的部分。

### 反馈

你可以发送电子邮件至 [martin@arp242.net](mailto:martin@arp242.net) 或[创建 GitHub issue](https://github.com/Carpetsmoker/arp242.net/issues/new) 以获取反馈、问题等。

### 脚注

1. 在 PHP 中你需要修改一个 INI 设置来获得安全的行为，不能只是调用像 `yaml_safe()` 这样的东西。PHP 想尽办法让愚蠢的东西越发愚蠢。干得漂亮！ [↩](#fnref1)
2. 不要在这里做空格与制表符之争，如果这里可以用制表符的话，我可以（临时）增加制表符宽度来使它更易读——这是制表符的一种用途。 [↩](#fnref2)

---

via: <https://arp242.net/weblog/yaml_probably_not_so_great_after_all.html>

作者：[Martin Tournoij](https://arp242.net/) 选题：[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/) 荣誉推出


极客漫画：当你雇佣了一个错误的架构师

Summary: 这幅漫画讽刺了一些不懂架构的人，盲目使用复杂的、新的架构来尝试业务，建立了一堆无用的组件，但却不知道该怎么用这些组件完成需求。

太过真实

![](/data/attachment/album/201901/08/104258rb8zuiu74ubghrzu.png)

这幅漫画讽刺了一些不懂架构的人，盲目使用复杂的、新的架构来尝试业务，建立了一堆无用的组件（灯/LAMP，即常见的 Linux+Apache+MySQL+PHP 网站架构），但却不知道该怎么用这些组件完成需求。

---

via: - <http://turnoff.us/geek/wrong-architect/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者&点评：[Besony](https://github.com/bestony) 校对：[wxy](https://github.com/wxy) 合成：[Bestony](https://github.com/bestony)

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


怎样如软件工程师一样组织知识

![](/data/attachment/album/201901/08/153009n1wdrptp1i6peprq.jpg)

总体上说，软件开发和技术是以非常快的速度发展的领域，所以持续学习是必不可少的。在互联网上花几分钟找一下，在 Twitter、媒体、RSS 订阅、Hacker News 和其它专业网站和社区等地方，就可以从文章、案例研究、教程、代码片段、新应用程序和信息中找到大量有用的信息。

保存和组织所有这些信息可能是一项艰巨的任务。在这篇文章中，我将介绍一些我用来组织信息的工具。

我认为在知识管理方面非常重要的一点就是避免锁定在特定平台。我使用的所有工具都允许以标准格式（如 Markdown 和 HTML）导出数据。

请注意，我的流程并不完美，我一直在寻找新工具和方法来优化它。每个人都不同，所以对我有用的东西可能不适合你。

### 用 NotionHQ 做知识库

对我来说，知识管理的基本部分是拥有某种个人知识库或维基。这是一个你可以以有组织的方式保存链接、书签、备注等的地方。

我使用 [NotionHQ](https://www.notion.so/) 做这件事。我使用它来记录各种主题，包括资源列表，如通过编程语言分组的优秀的库或教程，为有趣的博客文章和教程添加书签等等，不仅与软件开发有关，而且与我的个人生活有关。

我真正喜欢 NotionHQ 的是，创建新内容是如此简单。你可以使用 Markdown 编写它并将其组织为树状。

这是我的“开发”工作区的顶级页面：

[![Image](/data/attachment/album/201901/08/153018k6v8fmmze8g28m0g.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--uMbaRUtu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://i.imgur.com/kRnuvMV.png)

NotionHQ 有一些很棒的其他功能，如集成了电子表格/数据库和任务板。

如果您想认真使用 NotionHQ，您将需要订阅付费个人计划，因为免费计划有所限制。我觉得它物有所值。NotionHQ 允许将整个工作区导出为 Markdown 文件。导出功能存在一些重要问题，例如丢失页面层次结构，希望 Notion 团队可以改进这一点。

作为一个免费的替代方案，我可能会使用 [VuePress](https://vuepress.vuejs.org/) 或 [GitBook](https://www.gitbook.com/?t=1) 来托管我自己的知识库。

### 用 Pocket 保存感兴趣的文章

[Pocket](https://getpocket.com/) 是我最喜欢的应用之一！使用 Pocket，您可以创建一个来自互联网上的文章的阅读列表。每当我看到一篇看起来很有趣的文章时，我都会使用 Chrome 扩展程序将其保存到 Pocket。稍后，我会阅读它，如果我发现它足够有用，我将使用 Pocket 的“存档”功能永久保存该文章并清理我的 Pocket 收件箱。

我尽量保持这个阅读清单足够小，并存档我已经处理过的信息。Pocket 允许您标记文章，以便以后更轻松地搜索特定主题的文章。

如果原始网站消失，您还可以在 Pocket 服务器中保存文章的副本，但是您需要 Pocket Premium 订阅计划。

Pocket 还具有“发现”功能，根据您保存的文章推荐类似的文章。这是找到可以阅读的新内容的好方法。

### 用 SnippetStore 做代码片段管理

从 GitHub 到 Stack Overflow 的答案，到博客文章，经常能找到一些你想要保存备用的好代码片段。它可能是一些不错的算法实现、一个有用的脚本或如何在某种语言中执行某种操作的示例。

我尝试了很多应用程序，从简单的 GitHub Gists 到 [Boostnote](https://boostnote.io/)，直到我发现 [SnippetStore](https://github.com/ZeroX-DG/SnippetStore)。

SnippetStore 是一个开源的代码片段管理应用。SnippetStore 与其他产品的区别在于其简单性。您可以按语言或标签整理片段，并且可以拥有多个文件片段。它不完美，但是可以用。例如，Boostnote 具有更多功能，但我更喜欢 SnippetStore 组织内容的简单方法。

对于我每天使用的缩写和片段，我更喜欢使用我的编辑器 / IDE 的代码片段功能，因为它更便于使用。我使用 SnippetStore 更像是作为编码示例的参考。

[Cacher](https://www.cacher.io/) 也是一个有趣的选择，因为它与许多编辑器进行了集成，他有一个命令行工具，并使用 GitHub Gists 作为后端，但其专业计划为 6 美元/月，我觉这有点太贵。

### 用 DevHints 管理速查表

[Devhints](https://devhints.io/) 是由 Rico Sta. Cruz 创建的一个速查表集合。它是开源的，是用 Jekyll 生成的，Jekyll 是最受欢迎的静态站点生成器之一。

这些速查表是用 Markdown 编写的，带有一些额外的格式化支持，例如支持列。

我非常喜欢其界面的外观，并且不像可以在 [Cheatography](https://cheatography.com/) 等网站上找到 PDF 或图像格式的速查表， Markdown 非常容易添加新内容并保持更新和进行版本控制。

因为它是开源，我创建了自己的分叉版本，删除了一些我不需要的速查表，并添加了更多。

我使用速查表作为如何使用某些库或编程语言或记住一些命令的参考。速查表的单个页面非常方便，例如，可以列出特定编程语言的所有基本语法。

我仍在尝试这个工具，但到目前为止它的工作很好。

### Diigo

[Diigo](https://www.diigo.com/index) 允许您注释和突出显示部分网站。我在研究新东西时使用它来注释重要信息，或者从文章、Stack Overflow 答案或来自 Twitter 的鼓舞人心的引语中保存特定段落！;）

---

就这些了。某些工具的功能方面可能存在一些重叠，但正如我在开始时所说的那样，这是一个不断演进的工作流程，因为我一直在尝试和寻找改进和提高工作效率的方法。

你呢？是如何组织你的知识的？请随时在下面发表评论。

谢谢你的阅读。

---

作者简介：Bruno Paz，Web 工程师，专精 #PHP 和 @Symfony 框架。热心于新技术。喜欢运动，@FCPorto 的粉丝！

---

via: <https://dev.to/brpaz/how-do-i-organize-my-knowledge-as-a-software-engineer-4387>

作者：[Bruno Paz](http://brunopaz.net/) 选题：[oska874](https://github.com/oska874) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


在 Linux 命令行中使用 nudoku 解决谜题

Summary: 数独是简单的逻辑游戏，它可以在任何地方玩，包括在 Linux 终端中。

数独是简单的逻辑游戏，它可以在任何地方玩，包括在 Linux 终端中。

>
> 数独是简单的逻辑游戏，它可以在任何地方玩，包括在 Linux 终端中。
>
>
>

![](/data/attachment/album/201901/08/183631eapvfqcd662vbpee.png)

欢迎回到我们为期 24 天的 Linux 命令行玩具日历。如果这是你第一次访问该系列，你甚至可能会问什么是命令行玩具。我们在考虑中，但一般来说，它可能是一个游戏，或任何简单的消遣，可以帮助你在终端玩得开心。

很可能你们中的一些人之前已经看过我们日历中的各种玩具，但我们希望每个人至少见到一件新事物。

每年圣诞节，我的岳母都会给我妻子一本数独日历。它接着会在我们的咖啡桌上呆上一年。每天都是一张单独的表格（星期六和星期日除外，它们合并在一页上），这样你每天都有一个新的谜题，同时还有一本能用的日历。

问题在于在实际中它是一本很好的谜题，但不是一本好的日历，因为事实证明有些日子的题目比其他日子更难，我们没有以每天一个的速度解决它们。然后，我们会在懒散的周日来解决这周堆积的谜题。

既然我在这个系列的一部分中介绍过[日历](https://opensource.com/article/18/12/linux-toy-cal)，那么在这里介绍数独也是公平的，除了我们的命令行版本是解耦的，因此将来很容易就能完成它。

我在 Fedora 的默认仓库中找到了 `nudoku`，因此安装它就像下面这样简单：

```
$ sudo dnf install nudoku
```

安装完后，只需输入 `nudoku` 即可启动它，之后的操作就很明了。如果你以前从未玩过数独，它它很容易：你只需要确保每行、每列、每个 3x3 构成的方块里都包含了 1-9 的所有数字。

你可在 [Github](https://github.com/jubalh/nudoku) 中找到 GPLv3 许可的 `nudoku` 源码

![](/data/attachment/album/201901/08/183633yzeinismsincfs7y.gif)

你有特别喜欢的命令行小玩具需要我介绍的吗？我们的日历基本上满了，但我们仍然希望在新的一年中展示一些很酷的命令行玩具。请在评论中留言，我会查看的。记得让我知道你对今天玩具的看法。

一定要看看昨天的玩具，[使用 Linux 终端庆祝丰年](https://opensource.com/article/18/12/linux-toy-figlet)，记得明天回来！

---

via: <https://opensource.com/article/18/12/linux-toy-nudoku>

作者：[Jason Baker](https://opensource.com/users/jason-baker) 选题：[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: 想让你的终端被记住么？将它打在横幅上，不要错过。

想让你的终端被记住么？将它打在横幅上，不要错过。

>
> 想让你的终端被记住么？将它打在横幅上，不要错过。
>
>
>

![](/data/attachment/album/201901/09/185007m01ysxbwrsg1r1ok.png)

欢迎再次来到为期 24 天的 Linux 命令行玩具日历。如果这是你第一次访问该系列，你甚至可能会问自己什么是命令行玩具。我们也在思考，但一般来说，它可能是一个游戏，或任何简单的消遣，可以帮助你在终端玩得开心。

很可能你们中的一些人之前已经看过我们日历中的各种玩具，但我们希望每个人至少见到一件新事物。

今天的玩具是 `figlet`，一个在 Linux 终端上以横幅形式打印文本的程序。

你可能会再标准仓库中找到 `figlet`。在我的 Fedora 上，这意味着安装就像下面这样简单：

```
$ sudo dnf install figlet
```

之后，只需使用程序的名称来调用它。你可以以交互方式使用它，或者将一些文本通过管道输入，如下所示：

```
echo "Hello world" | figlet
 _   _      _ _                            _     _
| | | | ___| | | ___   __      _____  _ __| | __| |
| |_| |/ _ \ | |/ _ \  \ \ /\ / / _ \| '__| |/ _` |
|  _  |  __/ | | (_) |  \ V  V / (_) | |  | | (_| |
|_| |_|\___|_|_|\___/    \_/\_/ \___/|_|  |_|\__,_|
```

`figlet` 有许多不同的字体。要查看可用的字体，请尝试使用命令 `showfigfonts`。在我这里显示了十几个。我在下面复制了一些我的最爱。

```
block :

_|        _|                      _|
_|_|_|    _|    _|_|      _|_|_|  _|  _|
_|    _|  _|  _|    _|  _|        _|_|
_|    _|  _|  _|    _|  _|        _|  _|
_|_|_|    _|    _|_|      _|_|_|  _|    _|

bubble :
  _   _   _   _   _   _
 / \ / \ / \ / \ / \ / \
( b | u | b | b | l | e )
 \_/ \_/ \_/ \_/ \_/ \_/

lean :

    _/
   _/    _/_/      _/_/_/  _/_/_/
  _/  _/_/_/_/  _/    _/  _/    _/
 _/  _/        _/    _/  _/    _/
_/    _/_/_/    _/_/_/  _/    _/

script :

               o
 ,   __   ,_        _ _|_
/ \_/    /  |  |  |/ \_|
 \/ \___/   |_/|_/|__/ |_/
                 /|
                 \|
```

你可以在项目的[主页](http://www.figlet.org/)上找到有关 `figlet` 的更多信息。我下载的版本是以 MIT 许可开源的。

你会发现 `figlet` 不是唯一的 Linux 终端横幅打印机。另外一个你可以选择的是 [toilet](http://caca.zoy.org/wiki/toilet)，它有一套自己的 ASCII 艺术风格的打印选项。

你有特别喜欢的命令行小玩具需要我介绍的吗？我们的日历基本上满了，但我们仍然希望在新的一年中展示一些很酷的命令行玩具。请在评论中留言，我会查看的。记得让我知道你对今天玩具的看法。

一定要看看昨天的玩具，[使用 asciiquarium 在终端中游泳](https://opensource.com/article/18/12/linux-toy-asciiquarium)，记得明天回来！

---

via: <https://opensource.com/article/18/12/linux-toy-figlet>

作者：[Jason Baker](https://opensource.com/users/jason-baker) 选题：[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/) 荣誉推出


计算机实验室之树莓派：课程 0 简介

![](/data/attachment/album/201901/09/225414hclxe1ymhcme5cmi.jpg)

这个课程简介不包含实践内容，但它解释了一个操作系统的基本概念、汇编代码、和其它很重要的一些基本原理。如果你想直接进入实践环节，跳过本课程并不会有什么问题。

### 1、操作系统

操作系统就是一个非常复杂的程序。它的任务就是组织安排计算机上的其它程序，包括共享计算机的时间、内存、硬件和其它资源。你可能听说过的一些比较大的桌面操作系统家族有 GNU/Linux、Mac OS X 和 Microsoft Windows。其它的设备比如电话，也需要操作系统，它可能使用的操作系统是 Android、iOS 和 Windows Phone。    1

由于操作系统是用来与计算机系统上的硬件进行交互的，所以它必须了解系统上硬件专有的信息。为了能让操作系统适用于各种类型的计算机，发明了 **驱动程序** 的概念。驱动程序是为了能够让操作系统与特定的硬件进行交互而添加（并可删除）到操作系统上的一小部分代码。在本课程中，我们并不涉及如何创建可删除的驱动程序，而是专注于特定的一个硬件：树莓派。

操作系统有各种不同的设计方式，在本课程中，我们只触及操作系统设计的皮毛。本课程中，我们主要专注于操作系统与各种硬件的交互部分，因为这经常是比较棘手的部分，并且也是在网络上文档和帮助最少的部分。

### 2、汇编代码

>
> 处理器每秒可以执行上百万的指令，但是这些指令必须要简单。
>
>
>

本课程几乎要完全靠汇编代码来写。汇编代码非常接近计算机的底层。计算机其实是靠一个叫处理器的设备来工作的，处理器能够执行像加法这样的简单任务，还有一组叫做 RAM 的芯片，它能够用来保存数字。当计算机通电后，处理器执行程序员给定的一系列指令，这将导致内存中的数字发生变化，以及与连接的硬件进行交互。汇编代码只是将这些机器命令转换为人类可读的文本。

常规的编程就是，程序员使用编程语言，比如 C++、Java、C#、Basic 等等来写代码，然后一个叫编译器的程序将程序员写的代码转换成汇编代码，然后进一步转换为二进制代码。   2  二进制代码才是计算机真正能够理解的东西，但它是人类无法读取的东西。汇编代码比二进制代码好一点，至少它的命令是人类可读的，但它仍然让人很沮丧。请记住，你用汇编代码写的每个命令都是处理器可以直接认识的，因此这些命令设计的很简单，因为物理电路必须能够处理每个命令。

![Compiler process](/data/attachment/album/201901/16/011504ukcpyy997wz568q9.png)

和普通编程一样，也有很多不同的汇编代码编程语言，但与普通编程不一样的是，每个汇编编程语言是面对不同的处理器的，每种处理器设计为去理解不同的语言。因此，用一个针对某种机器设计的汇编语言所写的汇编代码，是不能在其它种类的机器上运行的。很多情况下，这都是一个大灾难，因此每个程序都必须在使用它的不同种类的机器上重写一遍，但对于操作系统，这不是个问题，因为在不同的硬件上它必须得重写。尽管如此，大多数操作系统都是用 C++ 或 C 来写的，这样它们就可以很容易地在不同种类的硬件上使用，只需要重写那些必须用汇编代码来实现的部分即可。

现在，你已经准备好进入第一节课了，它是 [课程 1 OK01](https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html)。

---

1. 要查看更完整的操作系统列表，请参照：[操作系统列表 - Wikipedia](http://en.wikipedia.org/wiki/List_of_operating_systems) [↩](#fnref1)
2. 当然，我简化了普通编程的这种解释，实际上它在很大程度上取决于语言和机器。感兴趣的话，参见 [编译器 - Wikipedia](http://en.wikipedia.org/wiki/Compiler) [↩](#fnref2)

---

via: <https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/introduction.html>

作者：[Robert Mullins](http://www.cl.cam.ac.uk/%7Erdm34) 选题：[lujun9972](https://github.com/lujun9972) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


区块链的生态系统

有意思

### 介绍

在这篇文章中，我们将讨论一个典型区块链的生态系统。这里说的生态系统，指的是不同的利益相关者及其相互之间，系统和外部世界间的相互作用。我们将要探索的不同利益相关者是：

1. 用户
2. 投资者
3. 矿工
4. 开发商

了解这些利益相关者如何融入区块链生态系统，不仅可以让您更好地了解区块链的运作方式，还可以让您更好地评估其增长潜力。区块链对于上述每个利益相关者来说越有吸引力，就越有可能健康的增长。所以，不多说了，下面介绍区块链生态系统的丰富的特色。

![](/data/attachment/album/201901/10/124034f5oyfrsrgzf5ef3d.png)

### 用户

用户是使用区块链或加密货币实现某些目的的普通人，而不仅仅是投资者。为维护用户，加密货币必须具有一些实用程序（用于花费你的钱币）。让我们快速浏览三个最受欢迎的区块链，以了解它们当前和潜在的效用。

#### 比特币

比特币只有一个功能，即用于货物和服务的付款。在撰写本文时，全球约有 48,000 家（编者注：截止到 2018 年 9 月）商家接受比特币为商品和服务付款（[Coinbase](https://www.coinbase.com/clients?locale=en-US)）。事实上，包括 PayPal、Expedia、微软、赛百味、彭博、Reddit、戴尔、Steam、Whole Foods、Shopify 和 Webjet 在内的几个家用品牌和主要电子商务公司都将自己的名字添加到了不断增长的比特币商家名单中。未来十年，这个名单将不可避免地继续增长，并且在不远的将来的某个时候，比特币完全有可能像 Visa、AMEX 或万事达卡那样被广泛接受。这可以说意味着比特币目前比任何其他区块链更具实用性。与传统支付方式相比，比特币支付的优势在于：

* 更快的国际支付和交易
* 交易费用非常低
* 伪匿名
* 没有第三方介入

商家的额外好处包括：

* 没有 chargeback（编者注：Chargeback 是信用卡中的一个术语，意思是顾客可以声明一笔交易并非本人发起的。根据国家法律，这种情况往往商家或银行要负责对顾客的全额退款，是一种保护顾客的机制，但也给商家和银行增加了支付处理中的风险。）
* 额外的客户群

由于比特币的高效用，其生态系统的相当大部分由用户组成。从长期投资的角度来看，这非常好，因为它可以提高价格稳定性，并为投资者提供有详实的数据（用户增长，商家采用，交易数量等）以便预测其价格。

#### 以太坊

以太坊区块链与比特币区块链根本不同，因为它能够将智能合约嵌入区块链（见前一篇区块链历史介绍）。因此，以太坊为其用户提供了两种不同类型的应用：

货币应用：虽然不是以太坊的主要目标，但用户可以使用 Ether（以太币，以太坊区块链的加密货币）来支付商品和服务。一些公司（[TenX](https://www.tenx.tech/)、[Token Card](https://tokencard.io/)、[Monaco](https://mona.co/)）正在竞相通过其加密货币借记卡和 Coinify 等在线支付平台获取市场份额，为在线商家提供即插即用解决方案，以接受像以太币这样的加密货币作为支付。然而，目前，比特币仍然是加密货币的王者，以太和其他加密货币可能不得不追赶几年。

常规应用：这是指用户与基于以太坊区块链的 dApp 交互。已有数百个 dApp 允许用户以各种方式与以太坊区块链进行交互。例如，Numerai 是一种独特的对冲基金，它为世界各地的数据科学家提供加密市场数据，激励他们超越当前的交易算法并提高对冲基金的整体表现。还有一些彩票 dApp，以公平透明的方式提供彩票服务。然而，这只是一个开始。新的 dApp 每天都在发布，将来必定会有人开发出一款真正吸引公众注意力并引领下一波以太坊用户浪潮的 dApp。

可以在[此处](https://dapps.ethercasts.com/)找到以太坊区块链上所有 dApp 的列表。

#### 瑞波

市值排名第三的区块链是<ruby> 瑞波 <rt>  Ripple </rt></ruby>。 瑞波与比特币和以太坊的不同之处在于它的设计考虑了一个特定的目标：为金融机构提供任何规模的安全，即时和近乎免费的全球交易。瑞波也与大多数区块链不同，因为它的目标用户是金融机构而不是私人。瑞波已经宣布与渣打银行和 UniCredit 等世界上大型金融机构建立合作伙伴关系，已经在区块链市场排行榜上获得第三名。

### 投资者

几乎所有区块链生态系统中的大多数利益相关者仍然是投资者。因此，加密货币市场仍然具有高度投机性，一天内价格波动 +/- 30％ 或更多并不罕见。区块链市场如此不稳定的部分原因是，评估加密货币或 dApp 的真正价值极其困难。该技术仍然年轻，由于实用性有限导致缺乏用户，因此很难预测在大规模采用时该技术将如何。

尽管投资区块链技术存在许多陷阱，但目前的市场条件实际上是一个有吸引力的投资机会：

* 专家、顾问和投资者几乎一致同意，区块链技术市场将在未来十年内继续快速增长（[麦肯锡](http://www.mckinsey.com/industries/high-tech/our-insights/how-blockchains-could-change-the-world)、[世界经济论坛](https://www.weforum.org/whitepapers/realizing-the-potential-of-blockchain)）
* 进入壁垒仍然很高，大多数人不愿意进入市场
* 虽然区块链在 2016 年和 2017 年都经历了令人难以置信的增长，但所有公共区块链的总市值仍然相对较小，约为 150 亿美元。为了更好地理解这一点，在撰写本文时，整个区块链行业的市值将只是世界第 50 大公司，位于荷兰的消费品公司联合利华之后。[HowMuch.net](https://howmuch.net/articles/worlds-money-in-perspective) 的这篇文章将加密货币的总市值与其他类型的资产进行了比较，并且展望了未来：

![](/data/attachment/album/201901/10/124040gopedpzphdnrhi2d.png)

话虽如此，并非所有的区块链都是平等的……在接下来的几年里，我们无疑会看到很多初创公司倒闭或烧钱，导致投资者辛苦赚来的钱损失掉。我们将看到诈骗公司，其唯一目标是从愚蠢的投资者那里榨取资金。我们将看到来自成熟公司的激烈竞争，以开发自己的区块链应用程序。生活中没有任何东西是免费的。如果想把钱投入区块链，将不得不接受高风险。我们将有足够的时间在未来的博客文章中讨论投资策略，但现在我们将给您留下两个想法：

1. 在投资任何公司之前，请积极研究至少一周。向自己提出有关投资的一些棘手问题。如果您无法回答问题，请与社区和开发人员联系。如果他们采用某些主观信息来回答，要持怀疑态度。如果他们不能充分回答您的问题，那么不是说一定就要停止投资，但请注意它是一种风险，并在购买之前将其考虑在内。
2. 多样化。必须强调这一点。在接下来的几年里，很多公司都会陷入困境，如果你把所有的鸡蛋都放在一个篮子里，你不仅会冒失去钱的风险，还可能有失去对该行业中最终占据主导地位的公司投资机会的风险。

我认为在任何区块链生态系统中，有 4 种不同类型的投资者：

#### 新手

区块链市场的巨大增长和不断增加的宣传吸引了成千上万的新投资者。很大一部分投资者会被潜在的收益所吸引,而没有去充分了解这项技术。新手用自己的情绪做决定，而且没有比害怕这种情绪更强迫人行动的了。害怕失去钱，也害怕失去机会。因此，新手的买入价格经常过高。

![](/data/attachment/album/201901/10/124040jpxw6pxgx1sgg7u1.png)

同样，如果价格下跌超过其初始买入点 10-20％，由于害怕失去所有资金，新手经常会卖出。这在超级易变的区块链市场尤其危险。因此，新手经常会买高卖低卖。

![](/data/attachment/album/201901/10/124041kb5hcckhhsjsh12d.png)

[Vanguard](https://personal.vanguard.com/pdf/ISGPRINC.pdf) 的结论是：

1. 对于大多数私人非专业投资者来说，追求投机绩效常常影响回报率
2. 市场波动性越大，追逐绩效的负面影响就越大

在区块链市场上很难不扮演新手的角色。即使您有先前的投资经验，区块链市场的不确定性和极端波动性也将考验您的意志力和自制力。

#### 鲸鱼

鲸鱼是那些拥有庞大储备的大型投资者，他们可以使市场向某一个方向发展。

通常，订单约为 1-500 万美元或以上的人被视为鲸鱼。像这样的大订单足以显著影响大多数加密货币或区块链令牌。如果这种变化吸引了小玩家的注意，并对他们的钱进行相同的操作（如果价格上涨则买入，或者如果价格下降则卖出），鲸鱼可以在稍后的时间执行相反的操作以获取利润。

另一个深渊，即巨鲸。

![](/data/attachment/album/201901/10/124041vehpkdreppjdyrrj.png)

巨鲸在这里指对冲基金和比特币投资基金，通常管理约 1 亿美元以上的投资组合。他们管理的资本过于庞大，一次下单市场常无法消化。他们通常会在一周或更长时间内将成千上万的比特币注入或流出市场，从而慢慢推动价格上涨或下跌，以满足他们自己的需求。

这些听起来可能令人难以置信，但区块链市场确实具有一些特征，使其成为具有正确手段和风险承受能力的高风险对冲基金的理想场所：

* 没有规定
* 相对较少的竞争
* 小市场给大型企业带来优势
* 大量缺乏经验的投资者

还有最后一个水下野兽，一个足以完全吞噬世界巨头并永远改变区块链市场的人。这里说的是政府投资者。政府可能有一天将加密货币作为一种多样化储备货币组合的方式，这种想法非常有趣，无疑会导致之前闻所未闻的价格水平 ([Coin Telegraph](https://cointelegraph.com/news/bitcoin-price-will-skyrocket-if-it-becomes-worlds-reserve-currency-by-2020))。

#### 套利者

套利者不断寻找并利用不同在线交易所之间的小价格差距。他们与数百家交易所相连，如果有机会，他们将在澳大利亚交易所买入低价并在瑞士交易所卖出高价。你可能认为套利者正在破坏区块链生态系统，但它们实际上发挥了一个非常特别和重要的功能。它们稳定了交易所的价格。他们就像大海的清洁工一样，总是在海底搜寻，以寻找市场上的不合理处。

#### 聪明的八爪鱼

这种投资者是你想成为的人！这种聪明的八足动物买得低，卖得很高。他们在做出决定之前进行了广泛的研究，并认识到风险和潜在的回报。这种聪明的八足动物认识到，利用加密货币的短期波动操作非常困难，要关注长期回报。他们避免情绪化决策，并通过价格波动坚持他们的投资，除非他们的投资有一些根本性的变化。这种聪明的八足动物认识到在区块链这样的新兴行业中识别赢家和输家是极其困难的。他们认识到总体行业风险，关注传统公司进入市场并密切关注他们的投资。

![](/data/attachment/album/201901/10/124042esxqunxza11kvrof.png)

如果你发展出聪明的八爪鱼的特性，你将有很大机会在未来十年内为你的投资带来非常好的回报。

虽然很希望告诉你，我们属于最后一类，而且我们从未做过情绪化或恐惧驱动的决定，但事实并非如此。在这一点上，我们可能介于新手和聪明的八足动物之间。希望通过撰写此博客并继续获得区块链市场的经验，将在未来几年内把我们变成聪明的八足动物。我希望你能加入我们，成为这次旅程的积极参与者。我们可以共同学习和研究，做出更好的决策。

### 矿工

为了使区块链能够运行并保持其完整性，它需要世界各地的独立节点网络来持续维护它。在私有区块链中，中心组织拥有网络上的每个节点。而在公共区块链中，任何人都可以将其计算机设置为节点。这些计算机的所有者称为矿工。

![](/data/attachment/album/201901/10/124042wli4gqdbphmdp5rw.png)

由于区块链的完整性与网络上独立节点的数量直接相关，因此还需要一些挖矿激励。不同的区块链使用不同的采矿系统，但大多数采用以下形式：

* 激励系统：最常见的是微交易费用和块解决方案奖励的组合（比特币矿工每解决一个比特币块，获得 12.5 BTC 奖励。按照约定奖励着时间的推移逐渐减少）。
* 共识算法：所有区块链都需要一种验证广播到网络的块的方法。比特币区块链使用工作证明（PoW）。您将在下一篇文章中了解有关 PoW 如何工作的更多信息。以太坊也使用 PoW，但将更改为权益证明 (PoS）（以太坊区块链包含故意放置在代码中的 <ruby> 难度炸弹 <rt>  difficulty bomb </rt></ruby>，以强制在某些时候更改为 PoS。之后将详细介绍）。

正如您将在下一篇文章中看到的那样，挖掘一个块是非常困难的，一台计算机需要多年来实现。因此，个体矿工组建了采矿行会，将他们的资源汇集在一起并分享回报。[blockchain.info](https://blockchain.info/pools?timespan=4days) 的资料显示了过去 4 天比特币区块链中每个采矿公会的相对哈希率（工作量）。

![](/data/attachment/album/201901/10/124042alau515zmtm1mr3k.png)

因为矿工需要保持区块链的完整性，所以他们拥有很大的权力。如果比特币社区想以这种或那种方式改变比特币协议，他们将不得不说服大多数矿工采用新代码。对现有区块链协议的更改称为分叉。潜在的分叉一直是采矿论坛上讨论的热门话题，没有中央权威就很难达成共识。

### 开发商

正如上一篇文章中所讨论的，区块链有可能变得不仅仅是加密货币。区块链世界中目前有两种类型的开发人员：

* 区块链开发人员
* dApp 开发人员

![](/data/attachment/album/201901/10/124043nhf1za3j1ihfjbq5.png)

区块链开发人员构建具有不同功能级别的全新区块链。dApp 开发人员可以构建在区块链上运行的去中心化应用程序，从而为用户提供使用区块链（即实用程序）的理由。

以太坊推出的智能合约为渴望创造下一个重大事件的 dApp 开发者打开了大门。在评估区块链时，重要的是要考虑开发人员如何对其做出反应。有些问题要问自己，包括：

* 该平台允许开发人员使用哪些脚本语言？
* 社区是否有足够的活跃，能够说服开发人员花时间为该平台开发 dApp？
* 区块链中是否有一些特殊功能，当 dApp 开发人员无法在更受欢迎的区块链上创建其应用，而在这个区块链上可以？
* 区块链的可扩展性如何？如果它最终变得流行，代码是否能够处理大量的交易？

要充分利用区块链技术，您需要同时了解区块链和 dApp 开发中的最新消息。

### 结论

区块链生态系统复杂而充满活力。

了解这一点将使您能够做出更好的决策并充分利用这一新兴技术。你喜欢这篇博文吗？我们是否错过了任何利益相关者？您对不同的利益相关者及其对整个区块链生态系统的影响有何看法？你认为会看到政府在他们的储备中加入加密货币吗？

我们很乐意在下面的留言板上收到您的来信！如果您发现我们的内容有任何错误或错误，请随时通知我们，我们会及时更正。我们的下一篇文章将为您提供加密功能的概述，使区块链能够安全且伪匿名地工作。希望能在那里见到你！

---

via: <https://www.myblockchainblog.com/blog/the-blockchain-ecosystem>

作者：[Vegard Nordahl & Meghana Rao](https://www.myblockchainblog.com/blog/the-blockchain-ecosystem) 选题：[jasminepeng](https://github.com/jasminepeng) 译者：[jasminepeng](https://github.com/jasminepeng) 校对：[wxy](https://github.com/wxy)

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


用 PGP 保护代码完整性（七）：保护在线帐户

Summary: 在这个系列的最后一篇当中，我们将为你展示如何用双因子认证保护你的在线账户。

在这个系列的最后一篇当中，我们将为你展示如何用双因子认证保护你的在线账户。

>
> 在这个系列的最后一篇当中，我们将为你展示如何用双因子认证保护你的在线账户。
>
>
>

![](/data/attachment/album/201901/10/231213u5qkg5zk39n9jcc5.jpg)

到目前为止，本系列教程已经提供了 PGP 的实用指南，包括基本概念和工具、生成和保护你的密钥的步骤。如果你错过了前面的文章，可以通过下面的链接查看。在本系列的最后一篇文章中，我们将为你保护在线帐户提供一个额外的指南，保护在线帐户是当今非常重要的一件事情。

* [第一部分：基本概念和工具](/article-9524-1.html)
* [第二部分：生成你的主密钥](/article-9529-1.html)
* [第三部分：生成 PGP 子密钥](/article-9607-1.html)
* [第四部分：将主密钥移到离线存储中](/article-10402-1.html)
* [第五部分：将子密钥移到硬件设备中](/article-10415-1.html)
* [第六部分：在 Git 中使用 PGP](/article-10421-1.html)

#### 清单

* 取得一个具备 U2F 功能的设备（必要）
* 为你的在线帐户启用双因子认证（必要）
	+ GitHub/GitLab
	+ Google
	+ 社交媒体
* 使用 U2F 作为主验证机制，使用 TOTP 作为备选（必要）

#### 考虑事项

你可能注意到，很多在线开发者身份是捆绑了 email 地址的。如果有人能够访问你的邮箱，他们就能够去做一些对你会产生危害的事情，进而会损害你作为自由软件开发者的声誉。应该像保护你的 PGP 密钥那样保护你的 email 地址。

##### 使用 Fido U2F 的双因子认证

[双因子认证](https://en.wikipedia.org/wiki/Multi-factor_authentication) 是一种提升帐户安全性的机制，它除了要求用户名和密码之外，还要求一个物理令牌。它的目标是即便在有人窃取了你的密码（通过按键记录器、肩窥攻击或其它方式）的情况下，仍然能确保你的帐户安全，他们在没有得到你的一个专用的物理设备（“必备”的那个因子）的情况下，始终不能获取你的帐户。

广为人知的双因子认证机制有：

* 基于 SMS 的验证
* 借助智能手机应用程序的基于时间的一次性令牌（TOTP），比如 Google Authenticator 或类似解决方案
* 支持 Fido U2F 的硬件令牌

基于 SMS 的验证很容易配置，但是它有如下的缺点：它在没有手机信号的地方无法使用（比如，建筑物的地下室），并且如果攻击者能够阻断或转向 SMS 信息，这种方式可能就会失败，比如通过克隆你的 SIM 卡。

基于 TOTP 的多因子认证提供了比 SMS 更好的安全保护，但它也有一些重要的缺点（你要在智能手机中添加的那么多令牌中找到正确的那个）。此外，还不能避免一个事实，那就是你的密钥最终还是保存在你的智能手机中 —— 它是一个复杂的、全球连接的设备，它有可能还没有及时从制造商那儿收到安全补丁。

更重要的是，不论是使用 TOTP 还是 SMS 的方法来保护你免受诱骗攻击 —— 如果诱骗攻击者能够窃取你的帐户密码和双因子令牌，他们就可以在合法的站点上使用它们，访问你的帐户。

[Fido U2F](https://en.wikipedia.org/wiki/Universal_2nd_Factor) 是一个按标准开发的专用设备，它能够提供双因子认证机制来对付诱骗攻击。U2F 协议在 USB 令牌中保存每个站点的的唯一密钥，如果你在任何合法站点以外的地方尝试使用它，它将阻止你，以防范偶然让攻击者获得你的密码和一次性令牌。

Chrome 和 Firefox 都支持 U2F 双因子认证，希望其它浏览器也能够提供对 U2F 的支持。

#### 获得一个支持 Fido U2F 功能的令牌

支持 U2F 的硬件令牌的 [可选目标很多](http://www.dongleauth.info/dongles/)，但如果你已经订购了一个支持智能卡的物理设备，那么你最好的选择就是 Yubikey 4，它两者都支持。

#### 启用你的在线帐户的双因子认证

你要确定想启用双因子认证的在线账户，你的 email 提供商已经使用了（特别是 Google，它对 U2F 的支持非常好）。其它的站点这个功能应该是启用了：

* GitHub：当你上传你的 PGP 公钥时，你应该要想到，如果其他人能够获得访问你的帐户，他们可以用他们自己的 PGP 公钥替换掉你的 PGP 公钥。如果在 GitHub 上发布代码，你应该使用 U2F 认证来保护你的帐户安全。
* GitLab：理由同上
* Google：如果你有 google 帐户，你就惊奇地发现，许多帐户都允许以 Google 帐户来代替站点专用的认证来登入它们。
* Facebook：理由同上，许多在线站点都提供一个选择让你以 Facebook 的帐户来认证。即便你不使用 Facebook 也应该使用双因子认证来保护你的 Facebook 帐户。
* 你认为必要的其它站点。查看 [dongleauth.info](http://www.dongleauth.info/) 去找找灵感。

#### 如有可能，配置 TOTP 作为备选

许多站点都允许你配置多个双因子认证机制，推荐的设置是：

* U2F 令牌作为主认证机制
* TOTP 手机应用作为辅助认证机制

通过这种方式，即便你丢失了你的 U2F 令牌，你仍然能够重新获取对你的帐户的访问。或者，你可以注册多个 U2F 令牌（即：你可以用一个便宜的令牌仅用它做 U2F，并且将它用作备份）。

### 延伸阅读

到目前为止，你已经完成了下列的重要任务：

1. 创建你的开发者身份并使用 PGP 加密来保护它。
2. 通过将你的主密钥移到一个离线存储中并将子密钥移到一个外置硬件设备中的方式来配置你的环境，让窃取你的身份变得极为困难。
3. 配置你的 Git 环境去确保任何使用你项目的人都能够验证仓库的完整性和它的整个历史。
4. 使用双因子认证强化你的在线帐户。

在安全保护方面，你已经做的很好了，但是你还应该去阅读以下的主题：

* 如何去强化你的团队沟通。你的项目开发和治理决策的要求应该和保护提交代码那样去保护，如果不这样做，应该确保你的团队沟通是可信任的，并且所有决策的完整性是可验证的。
* 如何去强化你的工作站的安全。你的目标是尽可能减少导致项目代码被污染的危险或你的开发者身份被窃的行为。
* 如何写出安全的代码（查看相关编程语言和你项目所使用的库的各种文档）。即便引入它的提交代码上有一个 PGP 签名，糟糕的、不安全的代码仍然是糟糕的、不安全的代码！

---

via: <https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-7-protecting-online-accounts>

作者：[Konstantin Ryabitsev](https://www.linux.com/users/mricon) 选题：[lujun9972](https://github.com/lujun9972) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


5 款 Linux 街机游戏

ubuntu 下载完了 如何运行游戏呢？？？

![](/data/attachment/album/201901/11/095443vv2wgc6y3ihw43wz.jpg)

长久以来，游戏都是 Linux 的软肋。近些年，Steam、GOG 等游戏发布平台上不少商业游戏都开始支持 Linux，这对于 Linux 的游戏生态来说是件好事，但是我们能在这些平台上玩到的游戏通常是不开源的商业作品。当然，这些游戏在一个开源的操作系统上运行，但对于一个开源提倡者来说这似乎还不够纯粹。

那么，我们能找到既自由开源又能给玩家带来完整游戏体验的优质游戏吗？当然！虽然绝大多数的开源游戏很难和 3A 商业游戏大作竞争，但仍然有不少各种类型的开源游戏，不仅内容有趣而且直接可以通过几大 Linux 发行版本库中直接安装。

本文首先介绍 Linux 开源游戏中的街机类型游戏，在之后的文章中，我将介绍桌面和卡牌游戏，解谜游戏，竞速游戏，以及策略模拟游戏。

### <ruby> 太空危机 <rt>  AstroMenace </rt></ruby>

![](/data/attachment/album/201901/11/095449gvtnhvbqwsestass.png)

[太空危机](http://www.viewizard.com/) 是一个近现代太空背景下的滚动页面射击游戏。开发初期它是一个闭源游戏，但它的代码和素材而后以开源许可证发布了。游戏玩法和大多数此类游戏大同小异，但它有质量极高的 3D 画面。飞船和武器升级可以通过击杀敌人所获得的点数购买。游戏的难度可以选择，因此适合新手以及想要追求挑战的硬核玩家。

安装太空危机，你只需要在终端下运行以下指令：

* Fedora 用户： `dnf install astromenace`
* Debian/Ubuntu 用户： `apt install astromenace`

### <ruby> 坦克战役 <rt>  Battle Tanks </rt></ruby>

![](/data/attachment/album/201901/11/095500o03und01bmw0iwdv.png)

[坦克战役](http://btanks.sourceforge.net/blog/about-game) 是一个俯瞰式视角的快节奏坦克战斗游戏。玩家可以选择三种不同的陆地坦克，操纵其在地图上前行，收集道具并且尝试炸飞敌军。它有四种游戏模式，死亡竞赛（又称“死斗”）、团队死斗、夺旗模式和合作模式。死斗和夺旗模式下，分别有 9 张地图可供玩家选择，合作模式则有 4 张。该游戏支持分屏本地双人游戏，以及在线多人竞技。游戏节奏很快，默认一次战役仅 5 分钟，因此，坦克战役十分适合想要利用零碎时间快速来一局的玩家。

安装坦克战役，你只需要在终端下运行以下指令：

* Fedora 用户： `dnf install btanks`
* Debian/Ubuntu 用户： `apt install btanks`

### <ruby> 火星 <rt>  M.A.R.S. </rt></ruby>

![](/data/attachment/album/201901/11/095510bq5qmprllena99nv.png)

[火星](http://mars-game.sourceforge.net/?page_id=10) 是一个自上而下的太空射击游戏，游戏机制类似传统街机游戏 “<ruby> 爆破彗星 <rt>  Asteroids </rt></ruby>”。玩家在操控一个太空船的同时向敌方射击并躲避敌军的弹幕射击。游戏有标准的死斗和团体死斗模式，除此之外也有更新鲜的比赛形式 —— 例如在一个模式下，玩家需要控制一个球使其进入敌方母星。该游戏支持本地多人游戏，但遗憾的是不支持多人联机。该游戏的开发更新似乎已经停止，所以该游戏之后增加联机模式的几率很小，但就算没有联机支持，这个游戏仍然值得一试。

安装火星，你只需要在终端下运行以下指令：

* Fedora 用户： `dnf install marsshooter`
* Debian/Ubuntu 用户： `apt install marsshooter`

### <ruby> 不存在之球 <rt>  Neverball </rt></ruby>

![](/data/attachment/album/201901/11/095520bblchzzujhzwrnyl.png)

[不存在之球](https://neverball.org/index.php) 的游戏灵感来源自世嘉的 “<ruby> 超级猴子球 <rt>  Super Monkey Ball </rt></ruby>” ，玩家需要将一个球在 3D 球场上运动起来，但是玩家控制的不是球，而是球场。游戏任务是在规定的时限内，收集足够多的金币从而打开该关卡的出口并且将小球落进该洞中。游戏可以调整难度，从休闲到难以超乎想象，可以适应不同的玩家需求。该游戏支持键盘/鼠标以及控制杆操作。

安装不存在之球，你只需要在终端下运行以下指令:

* Fedora 用户：`dnf install neverball`
* Debian/Ubuntu 用户：`apt install neverball`

### <ruby> 超级 Tux <rt>  SuperTux </rt></ruby>

![](/data/attachment/album/201901/11/095528c0gyly0yykyokra6.png)

[超级 Tux](http://supertux.org/) 是继任天堂超级马里奥后的一款 2D 的平台跳跃游戏。Linux 的吉祥物企鹅 Tux 代替了马里奥，而鸡蛋对应着马里奥系列中的蘑菇能力提升。当 Tux 获得了鸡蛋得到了能力提升，它便可以收集花朵，而花朵可以带来新的附加特殊能力。火焰花在关卡中最为常见，收集了火焰花的 Tux 可以掷出火球。除此之外，冰冻花/空气花/土地花也在游戏的程序中。收集星星的能力提升能使 Tux 暂时变得隐形，就如同马里奥系列游戏。该游戏最基础的一组关卡，冰之岛也有 30 关之多，因此游戏的内容和流程和超级马里奥系列一般长。SuperTux 还有一些附加关卡，例如三个额外奖励小岛、一个森林之岛、一个万圣节岛、一个孵化处，以及很多测试关卡。SuperTux 有一个自带的关卡编辑器，所以玩家可以创建他们的原创关卡。

安装超级 Tux，你只需要在终端下运行以下指令:

* Fedora 用户：`dnf install supertux`
* Debian/Ubuntu 用户: `apt install supertux`

如果我没有在上文中提及你最喜欢的开源街机游戏，欢迎在评论中分享。

### 有关作者

Joshua Allen Holm - 是 Opensource.com 的社区协调者之一。他的主要兴趣有数字人文、学术开放以及公开教育资源。你可以在 GitHub、GitLab、LinkedIn 和 Zotero 上找到他。可以通过 [holmja@opensource.com](mailto:holmja@opensource.com) 联系到他。

---

via: <https://opensource.com/article/18/1/arcade-games-linux>

作者：[Joshua Allen Holm](https://opensource.com/users/holmja) 译者：[Scoutydren](https://github.com/Scoutydren) 校对：[wxy](https://github.com/wxy)

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


如何使用 Ansible 管理你的工作站配置

Summary: 在这个系列的第一篇中，学习一下管理笔记本电脑和台式机配置的基础内容。

好东西

在这个系列的第一篇中，学习一下管理笔记本电脑和台式机配置的基础内容。

>
> 在这个系列的第一篇中，学习一下管理笔记本电脑和台式机配置的基础内容。
>
>
>

![](/data/attachment/album/201901/11/224838rank1a1gj3131kma.jpg)

配置管理是服务器管理和 DevOps 的一个非常重要的方面。“<ruby> 基础架构即代码 <rt>  infrastructure as code </rt></ruby>”方法可以轻松地以各种配置部署服务器，并动态扩展组织的资源以满足用户需求。但是，对于希望自动设置自己的笔记本电脑和台式机（工作站）的个人管理员的关注较少。

在本系列中，我将向你展示如何通过 [Ansible](https://www.ansible.com/) 自动化你的工作站设置，如果你想要或需要重新安装你的机器，这可以让你轻松恢复整个配置。此外，如果你有多个工作站，则可以使用相同的方法在每个工作站上进行相同的配置。在第一篇文章中，我们将为个人或工作计算机设置基本的配置管理，并为本系列的其余部分奠定基础。到本文结束时，你将会因此得到一个可以工作的环境。本系列之后的每篇文章都会自动化更多内容并增加复杂性。

### 为什么用 Ansible？

有许多配置管理解决方案，包括 Salt Stack、Chef 和 Puppet。我更喜欢 Ansible，因为它在资源利用方面更轻量级，语法更容易阅读，并且如果正确使用它可以彻底改变你的配置管理。Ansible 的轻量级特性与这个主题特别相关，因为我们可能不希望运行一整台服务器而只是为了自动化我们的笔记本电脑和台式机的设置。一般我们总是想要快一些；我们可以使用某些东西来快速启动和运行，以在我们需要恢复的工作站或在多台机器之间同步我们的配置。我使用 Ansible 的具体方法（我将在本文中演示）非常适用于此，而不需要维护服务器。你只需下载配置并运行它。

### 我的方法

通常，Ansible 运行于中央服务器。它使用一个<ruby> 库存清单 <rt>  inventory </rt></ruby>文件，该文件是一个文本文件，其中包含我们希望 Ansible 管理的所有主机及其 IP 地址或域名的列表。这对于静态环境非常有用，但对于工作站来说并不理想。原因是我们真的不知道我们的工作站在某一时刻的状态。也许我关闭了台式电脑，或者笔记本电脑可能会被挂起并放在我的包里。在任何一种情况下，Ansible 服务器都会抱怨，因为如果它们处于脱机状态，Ansible 就无法联系到我的机器。我们更需要的是按需方式，我们通过利用 `ansible-pull` 来实现这一目标。`ansible-pull` 命令是 Ansible 的一个命令，允许你从 Git 仓库下载配置并立即应用它。你不需要维护服务器或库存清单；你只需运行 `ansible-pull` 命令，给它一个 Git 仓库 URL，它将为你完成剩下的工作。

### 起步

首先，在要管理的计算机上安装 Ansible。有一个问题是许多发行版都附带了旧版本的 Ansible。根据经验，你肯定希望获得最新版本。Ansible 中经常引入新功能，如果你运行的是旧版本，则你在网上找到的示例语法可能无法正常运行，因为它使用的功能未在你安装的版本中实现。甚至发布的小版本都有很多新功能。其中一个例子是 `dconf` 模块，它是从 Ansible 2.4 开始的新功能。如果你尝试使用使用此模块的语法，除非你使用 2.4 或更新版本，否则会失败。在 Ubuntu 及其衍生产品中，我们可以使用官方个人包存档（[PPA](https://launchpad.net/ubuntu/+ppas)）轻松安装最新版本的 Ansible。以下命令可以解决这个问题：

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

如果你没有使用 Ubuntu，请参阅 [Ansible 的文档](http://docs.ansible.com/ansible/latest/intro_installation.html) 了解如何为你的平台获取它。

接下来，我们需要一个 Git 仓库来保存我们的配置。满足此要求的最简单方法是在 GitHub 上创建一个空的仓库，或者如果有的话，也可以使用自己的 Git 服务器。为了简单起见，我假设你正在使用 GitHub，因此如果你正在使用其他仓库，请相应调整命令。在 GitHub 中创建一个仓库；你最终会得到一个与此类似的仓库 URL：

```
git@github.com:<your_user_name>/ansible.git
```

将该仓库克隆到你的本地工作目录（忽略任何抱怨仓库为空的消息）：

```
git clone git@github.com:<your_user_name>/ansible.git
```

现在我们有了一个可以使用的空仓库。将你的工作目录切换到仓库（例如 `cd ./ansible`），并在你喜欢的文本编辑器中创建名为 `local.yml` 的文件。将以下配置放在该文件中：

```
- hosts: localhost
  become: true
  tasks:
  - name: Install htop
    apt: name=htop
```

你刚刚创建的文件被称为<ruby> 剧本 <rt>  playbook </rt></ruby>，安装 `htop` 的指令（我任意选择的一个包作为例子）被称为<ruby> 动作 <rt>  play </rt></ruby>。剧本本身是一个 YAML 格式的文件，它是一种易于阅读的标记语言。对 YAML 的完整讲述超出了本文的范围，但你无需专业理解即可熟练使用 Ansible。该配置易于阅读；只需查看此文件，你就可以轻松理解我们正在安装的 `htop` 软件包。要注意一下最后一行的 `apt` 模块，它只适用于基于 Debian 的系统。如果你使用的是 Red Hat 平台，你可以将其更改为 `yum` 而不是 `apt`，或者如果你正在使用 Fedora，则将其更改为 `dnf`。`name` 行只是提供有关我们任务的信息，并将显示在输出中。因此，你需要确保名称具有描述性，以便在需要对多个动作进行故障排除时很容易找到。

接下来，让我们将新文件提交到我们的仓库：

```
git add local.yml
git commit -m "initial commit"
git push origin master
```

现在我们的新剧本应该出现在我们的 GitHub 上的仓库中。我们可以使用以下命令应用我们创建的剧本：

```
sudo ansible-pull -U https://github.com/<your_user_name>/ansible.git
```

如果执行正确，`htop`包应该会安装在你的系统上。你可能会在开头附近看到一些警告，抱怨缺少库存清单文件。这很好，因为我们没有使用库存清单文件（我们也不需要这样做）。在输出结束时，它将概述它做的内容。如果 `htop` 安装正确，你应该在输出的最后一行看到 `changed = 1`。

它是如何工作的呢？`ansible-pull` 命令使用了 `-U` 选项，它需要一个仓库 URL。出于安全考虑，我给它提供了仓库 URL 的 https 版本，因为我不希望任何主机对仓库具有写访问权限（默认情况下 https 是只读的）。`local.yml` 是预设的剧本名称，因此我们不需要为剧本提供文件名：如果它在仓库的根目录中找到名为 `local.yml` 的剧本，它将自动运行它。接下来，我们在命令前面使用了 `sudo`，因为我们正在修改系统。

让我们继续为我们的剧本添加更多的包。我将添加两个包，使它看起来像这样：

```
- hosts: localhost
  become: true
  tasks:
  - name: Install htop
    apt: name=htop

  - name: Install mc
    apt: name=mc

  - name: Install tmux
    apt: name=tmux
```

我添加了更多的动作（任务）来安装另外两个包，`mc` 和 `tmux`。在此剧本中选择安装的哪些软件包并不重要；我只是随意挑选这些。你应该安装你希望所有的系统都具有的软件包。唯一需要注意的是，在你分发前，你必须知道那个包存在于软件仓库中。

在我们提交并应用这个更新的剧本之前，我们应该整理一下它。它可以很好地工作，但（说实话）它看起来有点混乱。让我们尝试在一个动作中安装所有三个包。用下面这个替换你的 `local.yml` 的内容：

```
- hosts: localhost
  become: true
  tasks:
  - name: Install packages
    apt: name={{item}}
    with_items:
      - htop
      - mc
      - tmux
```

现在看起来更干净、更有效率了。我们使用 `with_items` 将我们的包列表合并为一个动作。如果我们想要添加其他包，我们只需添加另一个带有连字符和包名称的行。可以把 `with_items` 看做类似于 `for` 循环。我们列出的每个包都将安装。

将我们的新更改提交回仓库：

```
git add local.yml
git commit -m "added additional packages, cleaned up formatting"
git push origin master
```

现在我们可以运行我们的剧本以接受新的新配置：

```
sudo ansible-pull -U https://github.com/<your_user_name>/ansible.git
```

不可否认，这个例子还没有做多少事情；它所做的就是安装一些软件包。你可以使用包管理器更快地安装这些包。然而，随着这个系列的继续，这些例子将变得更加复杂，我们将自动化更多的东西。最后，你创建的 Ansible 配置将自动执行越来越多的任务。例如，我自己使用的那个配置可以自动安装数百个软件包、设置cron 作业、处理桌面配置等等。

从我们迄今为止所取得的成就来看，你可能已经有了大概了解。我们所要做的就是创建一个仓库，在该仓库中放置一个剧本，然后利用 `ansible-pull` 命令拉取该仓库并将其应用到我们的机器上。我们不需要设置服务器。将来，如果我们想要更改配置，我们可以拉取该仓库、更新它，然后将其推回到我们的仓库并应用它。如果我们要设置新机器，我们只需要安装 Ansible 并应用配置。

在下一篇文章中，我们将通过 cron 和一些其他项目进一步自动化。与此同时，我已将本文的代码复制到 [我的 GitHub 仓库](https://github.com/jlacroix82/ansible_article) 中，以便你可以用你的语法对比一下我的。随着我们的进展，我会不断更新代码。

---

via: <https://opensource.com/article/18/3/manage-workstation-ansible>

作者：[Jay LaCroix](https://opensource.com/users/jlacroix) 译者：[wxy](https://github.com/) 校对：[wxy](https://github.com/wxy)

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


在 Linux 终端中玩贪吃蛇

安装 Emacs，M-x snake 就能在终端玩蛇了。

>
> 有了这个 20 世纪 70 年代的经典重制游戏，Python 将不再是你在 Linux 终端能发现的唯一的“蛇”。
>
>
>

![](/data/attachment/album/201901/12/104301hucp64f1cj1o47mz.png)

欢迎回到 Linux 命令行玩具日历。如果这是你第一次访问该系列，你可能会问什么是命令行玩具。这很难确切地说，但我的定义是任何可以帮助你在终端玩得开心的东西。

我们这周都在介绍游戏，这很有趣，接着让我们看下今天的游戏，贪吃蛇！

贪吃蛇是一个古老又很好的游戏，这些年一直有各种版本。我记得我第一次玩得版本是 20 世纪 90 年代与 [QBasic](https://en.wikipedia.org/wiki/QBasic) 一起打包发布的 [Nibbles](https://en.wikipedia.org/wiki/Nibbles_(video_game))，它对我理解什么是编程语言起了很重要的作用。我有游戏的源码，我可以修改并查看会发生什么，并学习到一些组成这个编程语言的有趣词汇究竟是什么意思。

今天的[贪吃蛇](https://github.com/DyegoCosta/snake-game)是用 Go 写的，它很简单并且和原版的游戏一样有趣。像大多数简单的老游戏一样，它有很多版本可供选择。这今天的贪吃蛇中，甚至还有一个经典的 [bsdgames](https://github.com/vattam/BSDGames) 形式的包，它的发行版几乎一定有它。

但我喜欢的是用 Docker 打包的贪吃蛇，因为我可以轻松地在命令行中运行，而不用担心发行版相关的问题。这个版本使用 15 个随机的食物 emoji 图案让蛇来吃。我玩得不好。不管怎样，请试一下：

```
$ docker run -ti dyego/snake-game
```

这个贪吃蛇以 MIT 许可证开源，你可在 [Github](https://github.com/DyegoCosta/snake-game) 取得源码。

![](/data/attachment/album/201901/12/104305wewum0p6a5p9b9a6.gif)

你有特别喜欢的命令行小玩具需要我介绍的吗？这个系列要介绍的小玩具大部分已经有了落实，但还预留了几个空位置。请在评论区留言，我会查看的。如果还有空位置，我会考虑介绍它的。如果没有，但如果我得到了一些很好的意见，我会在最后做一些有价值的提及。

请查看昨天的玩具，[数字 2 的力量，Linux 的力量：在命令行中玩 2048](https://opensource.com/article/18/12/linux-toy-2048)，记得明天再来！

---

via: <https://opensource.com/article/18/12/linux-toy-snake>

作者：[Jason Baker](https://opensource.com/users/jason-baker) 选题：[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: 使用这些工具从远程了解天气、阅读资料等。

使用这些工具从远程了解天气、阅读资料等。

>
> 使用这些工具从远程了解天气、阅读资料等。
>
>
>

![](/data/attachment/album/201901/12/153112se1b7tf780eb1011.png)

我们即将结束为期 24 天的 Linux 命令行玩具日历。希望你有一直在看，如果没有，请回到[开始](https://opensource.com/article/18/12/linux-toy-boxes)，从头看过来。你会发现 Linux 终端有很多游戏、消遣和奇怪之处。

虽然你之前可能已经看过我们日历中的一些玩具，但我们希望每个人都遇见一个新事物。

今天的玩具（实际是玩具集合）有点不同。到目前为止，我主要是想把重点放在那些独立的玩具上，并且完全可在开源许可下使用。但是我从读者那里得到了一些很好的建议，利用开源工具远程访问一些开源或者不开源的东西。今天，我将介绍其中的一些。

第一个是经典之作：使用 Telnet 观看星球大战的 ASCII 演绎版本。你的系统可能已经安装了 Telnet，因此你只需运行：

```
$ telnet towel.blinkenlights.nl
```

我第一次看到它是十年之前，因此我对于它还存在有点惊奇。如果你还没看过，请留出一点时间看一下。你不会后悔的。

![](/data/attachment/album/201901/12/153112yugbh5qterctcu5u.png)

接下来，Opensource.com 的撰稿人 [Manuel Dewald](https://opensource.com/users/ntlx) 提出了一种从终端获取当地天气的方法。它很简单，你只需安装 `curl`（或者，`wget`）。

```
$ curl wttr.in
```

![](/data/attachment/album/201901/12/153116jalcacu184z1r8a8.png)

最后，在假期中虽然你可以从[命令行 Web 浏览器](https://opensource.com/article/16/12/web-browsers-linux-command-line)浏览你喜欢的网站（包括 Opensource.com），但有一些我最喜欢的网站可以通过专用客户端更轻松地浏览。其中两个是 Reddit 和 Hacker News，有人推荐给我一些它们的客户端，你可能也想尝试，它们都使用开源许可。我尝试过 [haxor-news](https://github.com/donnemartin/haxor-news) （Hacker News） 和 [rtv](https://github.com/michael-lazar/rtv) （Reddit），它们都还不错。

你有特别喜欢的命令行小玩具需要我介绍的吗？提交今年的建议有点晚了，但我们仍然希望在新的一年里有一些很酷的命令行玩具。请在下面的评论中告诉我，我会查看的。让我知道你对今天的玩具有何看法。

一定要看看昨天的玩具，[在 Linux 终端收看 Youtube 视频](https://opensource.com/users/ntlx)，明天还要再来！

---

via: <https://opensource.com/article/18/12/linux-toy-remote>

作者：[Jason Baker](https://opensource.com/users/jason-baker) 选题：[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 中移除从源代码安装的程序的一种简单的方法

![](/data/attachment/album/201901/12/235455jw7erex3e3d3cdmq.jpg)

不是所有的程序都可以在官方或者第三方库中找到，因此你不能使用常规的包管理来安装它们。有时你不得不从源代码中手动构建这些程序。就如你已经知道的一样，当你从源代码中安装一个程序的时候，这个软件包所包含的文件将会复制到本地的多个位置，例如 `/usr/local/bin`、`/usr/local/etc/`。如果从源代码中安装的程序没有内置的卸载程序，当你不再需要这个程序的时候，卸载它就会很麻烦。你可能会花费双倍（甚至更多）的时间找出这些文件然后手动删除它们。我以前一直是这样做的，直到我发现了 GNU Stow。谢天谢地，Stow 有一个很棒的方法可以轻松管理从源代码安装的程序。

引用官方网站里的一段介绍，

>
> GNU Stow 是一个符号链接归集管理器，它可以收集文件系统上不同目录中的不同软件和/或数据包，使它们看起来像是一个整体。
>
>
>

简单来说，Stow 帮助你把这些程序文件以一种容易管理的方式组织在了一起。在这个方法中，文件将不会被复制到多个位置。所有的这些文件都会被保存在一个特定的文件夹中，通常是以程序名命名的，然后 Stow 会在一个合适的位置为所有的程序文件创建符号连接。比如 `/usr/local/bin` 中会包含 `/usr/local/stow/vim/bin`、`/usr/local/stow/python/bin` 中文件的符号链接。并且同样递归地用于其他的任何的子目录，例如 `.../share`、`.../man`，等等。在这篇教程中，我将会举例教你如何轻松地使用 Stow 管理从源中安装的程序。

### 安装 GNU Stow

GNU Stow 在流行 Linux 操作系统的默认库中都可用。

在 Arch Linux 及它的衍生版本中，运行下面的命令安装 Stow。

```
$ sudo pacman -S stow
```

在 Debian、Ubuntu、Linux Mint 上：

```
$ sudo apt install stow
```

在 Fedora 上：

```
$ sudo dnf install stow
```

在 RHEL/CentOS 上：

```
$ sudo yum install epel-release
$ sudo yum install stow
```

### 在 Linux 上轻松移除从源代码安装的程序

就像我之前提到的，所有包的程序文件都将被保存在位于 `/usr/local/stow/` 的一个根文件夹。在这个根文件夹或者父目录之下，每个包都将保存在对应的子目录中。例如，如果我们从源代码中安装了 Vim 编辑器，所有关联到 Vim 的程序文件和目录都将保存在 `/usr/local/stow/vim` 文件夹之下。如果你从源代码中安装了 Python，所有关联到 python 的文件都会保存在 `/usr/local/stow/python` 之下。

我现在从源代码中来安装一个叫做 hello 的程序。

首先下载 hello 程序的压缩包。

```
$ wget http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
```

使用下面的命令解压压缩包：

```
$ tar -zxvf hello-2.10.tar.gz
```

上面的命令将会在当前工作目录下创建一个叫做 `hello-2.10` 的目录，并且提取压缩包中的所有内容到其中去。

切换到这个目录当中：

```
$ cd hello-2.10/
```

运行下面的命令，并且添加 `-prefix` 选项。

```
$ ./configure --prefix=/usr/local/stow/hello
```

上面的命令将会保存构建文件到一个指定位置，在这个例子中是 `/usr/local/stow/hello`。

最后，使用下面的命令构建并安装 hello 这个程序：

```
$ make
$ sudo make install
```

就这样。hello 这个程序就已经安装在 `/usr/local/stow/hello/` 这个位置了。你可以使用下面的 `ls` 命令确认一下。

```
$ ls /usr/local/stow/hello/
bin share
```

最后，进入 `/usr/local/stow/` 目录，运行下面的命令来生成必要的符号链接。

```
$ cd /usr/local/stow/
$ sudo stow hello
```

大功告成！

刚才那一步是将包含在 hello 这个程序中的所有文件或者目录创建了链接到 `/usr/local/` 目录中。换一种说法， `/usr/local/stow/hello/bin` 链接到 `/usr/local/share`，以及 `/usr/local/stow/hello/share/man` 链接到 `/usr/local/share`，还有 `/usr/local/stow/hello/share/man` 链接到 `/usr/local/share/man`。

你可以使用 `ls` 命令来确认一下：

```
$ ls /usr/local/bin/
hello
```

可以使用下面的命令来确认 hello 这个程序是否可以正常工作了：

```
$ hello
Hello, world!
```

很好，它已经开始工作了！！

类似地，你可以像上面描述的那样安装程序到它对应的子目录下。

下面是 Stow 根目录包含的内容：

```
$ tree /usr/local/stow/
```

![](/data/attachment/album/201901/12/235458ag4xg6pbvopfv58g.png)

看，hello 这个程序已经安装在 `/usr/local/stow/hello/` 下。同样地，所有的包都将保存在它们对应的目录之下。

下面进入主要环节，移除 hello 这个程序。首先进入 `/usr/local/stow/` 目录：

```
$ cd /usr/local/stow/
```

然后运行下面的命令：

```
$ sudo stow --delete hello
```

hello 这个程序就会被移除了。你可以使用下面的命令确认它是否真的被移除了：

```
$ hello
-bash: /usr/local/bin/hello: No such file or directory
```

![](/data/attachment/album/201901/12/235459czy34043mrjqzrec.png)

看， Hello 已经被移除了！

请注意 Stow 仅仅只移除了符号链接。所有与 hello 这个程序相关的文件或者目录还保存在 `/usr/local/stow/hello` 目录下。所以你无需再次下载源文件就可以再次安装 hello 这个程序。如果你不再需要它了，直接删除这个文件夹即可。

```
$ sudo rm -fr /usr/local/stow/hello/
```

想了解更多 Stow 的细节，请参阅 man 手册。

```
$ man stow
```

Stow 可以像安装程序一样轻松地帮你移除它。如果你想知道如何高效的管理很多从源代码中安装的程序，GNU Stow 就是一个使得这个任务更加轻松的一个选择，尝试一下，你一定不会失望的。

这就是所有的内容了，希望对你有所帮助。还有更多干活即将到来，可以期待一下的！

祝近祺！

---

via: <https://www.ostechnix.com/an-easy-way-to-remove-programs-installed-from-source-in-linux/>

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

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


如何使用 Beamer 创建演示文稿

Summary: Beamer 将 LaTeX 强大的排版功能和生态系统带进创建幻灯片中。

Beamer 将 LaTeX 强大的排版功能和生态系统带进创建幻灯片中。

>
> Beamer 将 LaTeX 强大的排版功能和生态系统带进创建幻灯片中。
>
>
>

![](/data/attachment/album/201901/13/113905one2p82t58vtqgtq.jpeg)

[Beamer](https://www.overleaf.com/learn/latex/Beamer) 是用于生成幻灯片的 LaTeX 包。它最棒的功能之一是它可以利用 LaTeX 强大的排版系统和其生态系统中的所有其他软件包。例如，我经常在包含代码的 Beamer 演示文稿中使用 LaTeX 的 [listings](https://www.overleaf.com/learn/latex/Code_listing) 包。

### 创建演示文稿

要创建一个 Beamer 文档，输入：

```
\documentclass{beamer}
```

与任何其他 LaTeX 文档一样，添加你要使用的任何包。例如，要使用 `listings` 包，请输入：

```
\usepackage{listings}
```

将所有内容放在 `document` 环境中：

```
\begin{document}
```

Beamer 文档通常时是一系列的 `frame` 环境。包含代码的 `frame` 应该被标记为 `fragile`：

```
\begin{frame}[fragile]
```

使用标题开始你的 `frame`：

```
\frametitle{Function to Do Stuff}
```

### 开始演示前测试你的代码

世上最糟糕的感受之一你在演讲中说到代码时，突然发现了一个 bug —— 也许是拼错了关键词或者漏掉了括号。

解决方法之一就是测试演示的代码。在多数演示环境中，这意味着创建一个单独的文件、编写测试接着拷贝和粘贴。

然而，在 Beamer 中有一种更好的方法。想象一下，你有一个名为 `do_stuff.py` 的文件，其中包含代码。你可以在第二个文件中编写 `do_stuff.py` 代码的测试，你可以将其命名为 `test_do_stuff.py`，并且可以使用 [pytest](https://docs.pytest.org/en/latest/) 测试。但是，`do_stuff.py` 中的大多数行都缺乏教学价值，比如定义辅助函数。

要简化你受众看到的东西，你可在演示文稿中只导入你要讨论的行到 frame 中：

```
\lstinputlisting[
    language=Python,
    firstline=8,
    lastline=15
]{do_stuff.py}
```

由于你会对这几行（从 8 到 15）进行讨论，因此幻灯片上不需要任何其他内容。结束 `frame`：

```
\end{frame}
```

在下一张幻灯片中，你想展示刚才的 `do_stuff()` 函数的用法示例：

```
\begin{frame}[fragile]
\frametitle{Calling Function to Do Stuff}
\lstinputlisting[
    language=Python,
    firstline=17,
    lastline=19
]{do_stuff.py}
\end{frame}
```

你使用相同的文件，但这次显示调用该函数的行。最后，结束 `document`：

```
\end{document}
```

假设你在 `do_stuff.py` 中有一个合适的 Python 文件，这将生成一个含有 2 页的幻灯片。

Beamer 还支持必要的功能如渐进式演示，每次给观众展示一部分以免受到前面的打扰。在行中放入 `\pause` 会将页面分成不同的部分：

```
\begin{frame}
Remember:
\begin{itemize}
\item This will show up on the first slide. \pause
\item This will show up on the
      second slide, as well as the preceding point. \pause
\item Finally, on the third slide,
       all three bullets will show up.
\end{frame}
```

### 创建讲义

Beamer 中我最喜欢的功能是可以用 `\documentclass[ignorenonframetext]{beamer}` 设置忽略 `frame` 外的所有内容。当我准备演示文稿时，我离开顶部（声明文档类的位置）并自动生成它的两个版本：我的演示稿使用 Beamer 忽略任何 `frame` 之外的所有文本，另一个含有类似这样的头：

```
\documentclass{article}
\usepackage{beamerarticle}
```

这会生成一份讲义：一份含有所有 `frame` 和它们之间文字的 PDF。

当会议组织者要求我发布我的幻灯片时，我会包含原始幻灯片作为参考，但我希望人们拿到的是讲义，它包含了所有我不想在幻灯片上写的解释部分。

在创建幻灯片时，人们经常会考虑是为演讲优化讲稿还是为之后想要阅读它的人们优化。幸运的是，Beamer 提供了两全其美的办法。

---

via: <https://opensource.com/article/19/1/create-presentations-beamer>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[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/) 荣誉推出


JSON 的兴起与崛起

Summary: 我们不禁要问为什么 XML 的噩运来的如此之快，以至于短短十来年，“异步 JavaScript 和 XML” 这个名称就成为一个很讽刺的误称。

![](/data/attachment/album/201901/14/115006ibcnakngxqxi6lnl.png)

JSON 已经占领了全世界。当今，任何两个应用程序彼此通过互联网通信时，可以打赌它们在使用 JSON。它已被所有大型企业所采用：十大最受欢迎的 web API 接口列表中（主要由 Google、Facebook 和 Twitter 提供），仅仅只有一个 API 接口是以 XML 的格式开放数据的。   1  这个列表中的 Twitter API 为此做了一个鲜活的注脚：其对 XML 格式的支持到 2013 年结束，其时发布的新版本的 API 取消 XML 格式，转而仅使用 JSON。JSON 也在程序编码级别和文件存储上被广泛采用：在 Stack Overflow（LCTT 译注：一个面向程序员的问答网站）上，现在更多的是关于 JSON 的问题，而不是其他的数据交换格式。   2

![](/data/attachment/album/201901/14/123855es5cltxoenuoc7ey.jpg)

XML 仍然在很多地方存在。网络上它被用于 SVG 和 RSS / Atom 信息流。Android 开发者想要获得用户权限许可时，需要在其 APP 的 `manifest` 文件中声明 —— 此文件是 XML 格式的。XML 的替代品也不仅仅只有 JSON，现在有很多人在使用 YAML 或 Google 的 Protocol Buffers 等技术，但这些技术的受欢迎程度远不如 JSON。目前来看，JSON 是应用程序在网络之间通信的首选协议格式。

考虑到自 2005 年来 Web 编程世界就垂涎于 “异步 JavaScript 和 XML” 而非 “异步 JavaScript 和 JSON” 的技术潜力，你可以发现 JSON 的主导地位是如此的让人惊讶。当然了，这可能与这两种通信格式的受欢迎程度无关，而仅反映出缩写 “AJAX” 似乎比 “AJAJ” 更具吸引力。但是，即使在 2005 年有些人（实际上没有太多人）已经用 JSON 来取代 XML 了，我们不禁要问 XML 的噩运来的如此之快，以至于短短十来年，“异步 JavaScript 和 XML” 这个名称就成为一个很讽刺的误称。那这十来年发生了什么？JSON 怎么会在那么多应用程序中取代了 XML？现在被全世界工程师和系统所使用、依赖的这种数据格式是谁提出的？

### JSON 之诞生

2001 年 4 月，首个 JSON 格式的消息被发送出来。此消息是从旧金山湾区某车库的一台计算机发出的，这是计算机历史上重要的的时刻。Douglas Crockford 和 Chip Morningstar 是一家名为 State Software 的技术咨询公司的联合创始人，他们当时聚集在 Morningstar 的车库里测试某个想法，发出了此消息。

在 “AJAX” 这个术语被创造之前，Crockford 和 Morningstar 就已经在尝试构建好用的 AJAX 应用程序了，可是浏览器对其兼容性不好。他们想要在初始页面加载后就将数据传递给应用程序，但其目标要针对所有的浏览器，这就实现不了。

这在今天看来不太可信，但是要记得 2001 年的时候 Internet Explorer（IE）代表了网页浏览器的最前沿技术产品。早在 1999 年的时候，Internet Explorer 5 就支持了原始形式的 `XMLHttpRequest`，开发者可以使用名为 ActiveX 的框架来访问此对象。Crockford 和 Morningstar 能够使用此技术（在 IE 中）来获取数据，但是在 Netscape 4 中（这是他们想要支持的另一种浏览器）就无法使用这种解决方案。为此 Crockford 和 Morningstar 只得使用一套不同的系统以兼容不同的浏览器。

第一条 JSON 消息如下所示：

```
<html><head><script>
    document.domain = 'fudco';
    parent.session.receive(
        { to: "session", do: "test",
          text: "Hello world" }
    )
</script></head></html>
```

消息中只有一小部分类似于今天我们所知的 JSON，本身其实是一个包含有一些 JavaScript 的 HTML 文档。类似于 JSON 的部分只是传递给名为 `receive()` 的函数的 JavaScript 对象字面量。

Crockford 和 Morningstar 决定滥用 HTML 的帧（`<frame>`）以发送数据。他们可以让一个帧指向一个返回的上述 HTML 文档的 URL。当接收到 HTML 时，JavaScript 代码段就会运行，就可以把数据对象字面量如实地传递回应用程序。只要小心的回避浏览器保护策略（即子窗口不允许访问父窗口），这种技术就可以正常运行无误。可以看到 Crockford 和 Mornginstar 通过明确地设置文档域这种方法来达到其目的。（这种基于帧的技术，有时称为隐藏帧技术，通常在 90 年代后期，即在广泛使用 XMLHttpRequest 技术之前使用。   3  ）

第一个 JSON 消息的惊人之处在于，它显然不是一种新的数据格式的首次使用。它就是 JavaScript！实际上，以此方式使用 JavaScript 的想法如此简单，Crockford 自己也说过他不是第一个这样做的人。他说 Netscape 公司的某人早在 1996 年就使用 JavaScript 数组字面量来交换信息。   4  因为消息就是 JavaScript，其不需要任何特殊解析工作，JavaScript 解释器就可搞定一切。

最初的 JSON 信息实际上与 JavaScript 解释器发生了冲突。JavaScript 保留了大量的关键字（ECMAScript 6 版本就有 64 个保留字），Crockford 和 Morningstar 无意中在其 JSON 中使用了一个保留字。他们使用了 `do` 作为了键名，但 `do` 是解释器中的保留字。因为 JavaScript 使用的保留字太多了，Crockford 做了决定：既然不可避免的要使用到这些保留字，那就要求所有的 JSON 键名都加上引号。被引起来的键名会被 JavaScript 解释器识别成字符串，其意味着那些保留字也可以放心安全的使用。这就为什么今天 JSON 键名都要用引号引起来的原因。

Crockford 和 Morningstar 意识到这技术可以应用于各类应用系统。想给其命名为 “JSML”，即 <ruby> JavaScript 标记语言 <rt>  JavaScript Markup Language </rt></ruby>的意思，但发现这个缩写已经被一个名为 Java Speech 标记语言的东西所使用了。因此他们决定采用 “JavaScript Object Notation”，缩写为 JSON。他们开始向客户推销，但很快发现客户不愿意冒险使用缺乏官方规范的未知技术。所以 Crockford 决定写一个规范。

2002 年，Crockford 买下了 [JSON.org](http://JSON.org) 域名，放上了 JSON 语法及一个解释器的实例例子。该网站仍然在运行，现在已经包含有 2013 年正式批准的 JSON ECMA 标准的显著链接。在该网站建立后，Crockford 并没有过多的推广，但很快发现很多人都在提交各种不同编程语言的 JSON 解析器实现。JSON 的血统显然与 JavaScript 相关联，但很明显 JSON 非常适合于不同语言之间的数据交换。

### AJAX 导致的误会

2005 年，JSON 有了一次大爆发。那一年，一位名叫 Jesse James Garrett 的网页设计师和开发者在博客文章中创造了 “AJAX” 一词。他很谨慎地强调：AJAX 并不是新技术，而是 “好几种蓬勃发展的技术以某种强大的新方式汇集在一起。   5  ” AJAX 是 Garrett 给这种正受到青睐的 Web 应用程序的新开发方法的命名。他的博客文章接着描述了开发人员如何利用 JavaScript 和 XMLHttpRequest 构建新型应用程序，这些应用程序比传统的网页更具响应性和状态性。他还以 Gmail 和 Flickr 网站已经使用 AJAX 技术作为了例子。

当然了，“AJAX” 中的 “X” 代表 XML。但在随后的问答帖子中，Garrett 指出，JSON 可以完全替代 XML。他写道：“虽然 XML 是 AJAX 客户端进行数据输入、输出的最完善的技术，但要实现同样的效果，也可以使用像 JavaScript Object Notation（JSON）或任何类似的结构数据方法等技术。 ”   6

开发者确实发现在构建 AJAX 应用程序时可以很容易的使用 JSON，许多人更喜欢它而不是 XML。具有讽刺意味的是，对 AJAX 的兴趣逐渐的导致了 JSON 的普及。大约在这个时候，JSON 引起了博客圈的注意。

2006 年，Dave Winer，一位高产的博主，他也是许多基于 XML 的技术（如 RSS 和 XML-RPC）背后的开发工程师，他抱怨到 JSON 毫无疑问的正在重新发明 XML。尽管人们认为数据交换格式之间的竞争不会导致某一技术的消亡。其写到：

>
> 毫无疑问，我可以编写一个例程来解析 JSON，但来看看他们要重新发明一个东西有多大的意义，出于某种原因 XML 本身对他们来说还不够好（我很想听听原因）。谁想干这荒谬之事？查找一棵树然后把节点串起来。可以立马试试。   7
>
>
>

我很理解 Winer 的挫败感。事实上并没有太多人喜欢 XML。甚至 Winer 也说过他不喜欢 XML。   8  但 XML 已被设计成一个可供任何人使用，并且可以用于几乎能想象到的所有事情。归根到底，XML 实际上是一门元语言，允许你为特定应用程序自定义该领域特定的语言。如 Web 信息流技术 RSS 和 SOAP（简单对象访问协议）就是例子。Winer 认为由于通用交换格式所带来的好处，努力达成共识非常重要。XML 的灵活性应该能满足任何人的需求，然而 JSON 格式呢，其并没有比 XML 提供更多东西，除了它抛弃了使 XML 更灵活的那些繁琐的东西。

Crockford 阅读了 Winer 的这篇文章并留下了评论。为了回应 JSON 重新发明 XML 的指责，Crockford 写到：“重造轮子的好处是可以得到一个更好的轮子。”   9

### JSON 与 XML 对比

到 2014 年，JSON 已经由 ECMA 标准和 RFC 官方正式认可。它有了自己的 MIME 类型。JSON 已经进入了大联盟时代。

为什么 JSON 比 XML 更受欢迎？

在 [JSON.org](http://JSON.org) 网站上，Crockford 总结了一些 JSON 的优势。他写到，JSON 的语法极少，其结构可预测，因此 JSON 更容易被人类和机器理解。   10  其他博主一直关注 XML 的冗长啰嗦及“尖括号负担”。   11  XML 中每个开始标记都必须与结束标记匹配，这意味着 XML 文档包含大量的冗余信息。在未压缩时，XML 文档的体积比同等信息量 JSON 文档的体积大很多，但是，更重要的，这也使 XML 文档更难以阅读。

Crockford 还声称 JSON 的另一个巨大优势是其被设计为数据交换格式。   12  从一开始，它的目的就是在应用程序间传递结构化信息的。而 XML 呢，虽然也可以使用来传递数据，但其最初被设计为文档标记语言。它演变自 SGML（通用标准标记语言），而它又是从被称为 Scribe 的标记语言演变而来，其旨在发展成类似于 LaTeX 一样的文字处理系统。XML 中，一个标签可以包含有所谓的“混合内容”，即带有围绕单词、短语的内嵌标签的文本。这会让人浮现出一副用红蓝笔记录的手稿画面，这是标记语言核心思想的形象比喻。另一方面，JSON 不支持对混合内容模型的清晰构建，但这也意味着它的结构足够简单。一份文档最好的建模就是一棵树，但 JSON 抛弃了这种文档的思想，Crockford 将 JSON 抽象限制为字典和数组，这是所有程序员构建程序时都会使用的最基本的、也最熟悉的元素。

最后，我认为人们不喜欢 XML 是因为它让人困惑。它让人迷惑的地方就是有很多不同的风格。乍一看，XML 本身及其子语言（如 RSS、ATOM、SOAP 或 SVG）之间的界限并不明显。典型的 XML 文档的第一行标识了该 XML 的版本，然后该 XML 文档应该符合特定的子语言。这就有变化需要考虑了，特别是跟 JSON 做比较，JSON 是如此简单，以至于永远不需要编写新版本的 JSON 规范。XML 的设计者试图将 XML 做为唯一的数据交换格式以支配所有格式，就会掉入那个经典的程序员陷阱：过度工程化。XML 非常笼统及概念化，所以很难于简单的使用。

在 2000 年的时候，发起了一场使 HTML 符合 XML 标准的活动，发布了一份符合 XML 标准的 HTML 开发规范，这就此后很出名的 XHTML。虽然一些浏览器厂商立即开始支持这个新标准，但也很明显，大部分基于 HTML 技术的开发者不愿意改变他们的习惯。新标准要求对 XHTML 文档进行严格的验证，而不是基于 HTML 的基准。但大多的网站都是依赖于 HTML 的宽容规则的。到 2009 年的时候，试图编写第二版本的 XHTML 标准的努力已经流产，因为未来已清晰可见，HTML 将会发展为 HTML5（一种不强制要求接受 XML 规则的标准）。

如果 XHTML 的努力取得了成功，那么 XML 可能会成为其设计者所希望的通用数据格式。想象一下，一个 HTML 文档和 API 响应具有完全相同结构的世界。在这样的世界中，JSON 可能不会像现在一样普遍存在。但我把 HTML 的失败看做是 XML 阵营的一种道义上的失败。如果 XML 不是 HTML 的最佳工具，那么对于其他应用程序，也许会有更好的工具出现。在这个世界，我们的世界，很容易看到像 JSON 格式这样的足够简单、量体裁衣的才能获得更大的成功。

如果你喜欢这博文，每两周会更新一次！ 请在 Twitter 上关注 [@TwoBitHistory](https://twitter.com/TwoBitHistory) 或订阅 [RSS feed](https://twobithistory.org/feed.xml)，以确保得到更新的通知。

---

1. <http://www.cs.tufts.edu/comp/150IDS/final_papers/tstras01.1/FinalReport/FinalReport.html#software> [↩](#fnref1)
2. <https://insights.stackoverflow.com/trends?tags=json%2Cxml%2Cprotocol-buffers%2Cyaml%2Ccsv> [↩](#fnref2)
3. Zakas, Nicholas C., et al. “What Is Ajax?” Professional Ajax, 2nd ed., Wiley, 2007. [↩](#fnref3)
4. <https://youtu.be/-C-JoyNuQJs?t=32s> [↩](#fnref4)
5. <http://adaptivepath.org/ideas/ajax-new-approach-web-applications/> [↩](#fnref5)
6. 同上 [↩](#fnref6)
7. <http://scripting.com/2006/12/20.html> [↩](#fnref7)
8. <http://blogoscoped.com/archive/2009-03-05-n15.html> [↩](#fnref8)
9. <https://scripting.wordpress.com/2006/12/20/scripting-news-for-12202006/#comment-26383> [↩](#fnref9)
10. <http://www.json.org/xml.html> [↩](#fnref10)
11. <https://blog.codinghorror.com/xml-the-angle-bracket-tax> [↩](#fnref11)
12. <https://youtu.be/-C-JoyNuQJs?t=33m50sgg> [↩](#fnref12)

---

via: <https://twobithistory.org/2017/09/21/the-rise-and-rise-of-json.html>

作者：[Two-Bit History](https://twobithistory.org) 选题：[lujun9972](https://github.com/lujun9972) 译者：[runningwater](https://github.com/runningwater) 校对：[wxy](https://github.com/wxy)

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


Termtosvg：将你在 Linux 终端中操作录制成 SVG 动画

![](/data/attachment/album/201901/14/121313jcoeexcx1di7i1xl.jpg)

一般人喜欢使用历史命令功能来查看/再次调用之前在终端中输入的命令。不幸的是，那样做只会显示先前输入的命令，而不是之前输出的内容。

在 Linux 中，有许多可以用来记录终端活动的实用工具。这种工具将会帮助我们记录用户在终端中的活动，并帮助我们识别输出中有用的信息。

在这之前，我们已经介绍了一些这类实用工具了。今天，让我们接着讨论这类工具。

如果你希望尝试其它一些记录你终端活动的工具，我推荐你试试 [script](https://www.2daygeek.com/script-command-record-save-your-terminal-session-activity-linux/) 命令和 [Terminalizer](https://www.2daygeek.com/terminalizer-a-tool-to-record-your-terminal-and-generate-animated-gif-images/) 工具。`script` 是在无头服务器中记录终端活动的最佳方式之一。`script` 是一个记录在终端中输入过的 Unix 命令的实用工具（在某些终端中，它会记录显示在你终端中的所有东西）。它会在当前工作目录下以文本文件方式储存所有终端输出。

不过，如果你在寻找 [GIF 录制器](https://www.2daygeek.com/category/gif-recorder/) ，你可以尝试 [Gifine](https://www.2daygeek.com/gifine-create-animated-gif-vedio-recorder-linux-mint-debian-ubuntu/)、[Kgif](https://www.2daygeek.com/kgif-create-animated-gif-file-active-window-screen-recorder-capture-arch-linux-mint-fedora-ubuntu-debian-opensuse-centos/) 和 [Peek](https://www.2daygeek.com/peek-create-animated-gif-screen-recorder-capture-arch-linux-mint-fedora-ubuntu/)。

### 什么是 Termtosvg

Termtosvg 是一个用 Python 编写的 Unix 终端录制器，它可以将你的命令行会话保存为 SVG 动画。

### Termtosvg 的特点

* 可以制作嵌入于项目主页的简洁美观的动画。
* 可以在 SVG 模板中自定义配色、终端 UI 和动画。
* 兼容 asciinema 录制格式。
* 要求 Python 版本为 3.5 或更高。

### 如何在 Linux 中安装 Termtosvg

它是用 Python 编写的，所以我推荐使用 `pip` 来安装它。

请确保你已经安装了 python-pip 包。如果你还没安装，请输入下面的命令。 对于 Debian 或 Ubuntu 用户，请使用 [apt](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/) 或 [apt-get](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/) 来安装 `pip`。

```
sudo apt install python-pip
```

对于 Archlinux 用户，请使用 [pacman](https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/) 来安装 `pip`。

```
sudo pacman -S python-pip
```

对于 Fedora 用户，请使用 [dnf](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/) 来安装 `pip`。

```
sudo dnf install python-pip
```

对于 CentOS 或 RHEL 用户，请使用 [yum](https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/) 来安装 `pip`。

```
sudo yum install python-pip
```

对于 openSUSE 用户，请使用 [zypper](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/) 来安装 `pip`。

```
sudo zypper install python-pip
```

最后，请执行 [pip](https://www.2daygeek.com/install-pip-manage-python-packages-linux/) 来安装 Termtosvg。

```
sudo pip3 install termtosvg pyte python-xlib svgwrite
```

### 如何使用 Termtosvg

成功安装 Termtosvg 后，请使用以下命令来开始录制。

```
$ termtosvg
Recording started, enter "exit" command or Control-D to end
```

如果只是想测试它是否正常工作，随意输入几行命令即可。

```
$ uname -a
Linux daygeek-Y700 4.19.8-2-MANJARO #1 SMP PREEMPT Sat Dec 8 14:45:36 UTC 2018 x86_64 GNU/Linux
$ hostname
daygeek-Y700
$ cat /etc/*-release
Manjaro Linux
DISTRIB_ID=ManjaroLinux
DISTRIB_RELEASE=18.0
DISTRIB_CODENAME=Illyria
DISTRIB_DESCRIPTION="Manjaro Linux"
Manjaro Linux
NAME="Manjaro Linux"
ID=manjaro
ID_LIKE=arch
PRETTY_NAME="Manjaro Linux"
ANSI_COLOR="1;32"
HOME_URL="https://www.manjaro.org/"
SUPPORT_URL="https://www.manjaro.org/"
BUG_REPORT_URL="https://bugs.manjaro.org/"
$ free -g
free: Multiple unit options doesn't make sense.
$ free -m
free: Multiple unit options doesn't make sense.
$ pip3 --version
pip 18.1 from /usr/lib/python3.7/site-packages/pip (python 3.7)
```

完成后，你可以按下 `CTRL+D` 或输入 `exit` 来停止录制。录制完后，输出文件会以一个独一无二的名字被保存在 `/tmp` 文件夹中。

```
$ exit
exit
Recording ended, SVG animation is /tmp/termtosvg_5waorper.svg
```

我们可以在任意浏览器中打开 SVG 文件。

```
firefox /tmp/termtosvg_5waorper.svg
```

![最终效果](/data/attachment/album/201901/14/121320ue7uvomrbxuxp7v9.gif)

---

via: <https://www.2daygeek.com/termtosvg-record-your-terminal-sessions-as-svg-animations-in-linux/>

作者：[Magesh Maruthamuthu](https://www.2daygeek.com/author/magesh/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[zhs852](https://github.com/zhs852) 校对：[校对者ID](https://github.com/%E6%A0%A1%E5%AF%B9%E8%80%85ID)

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


极客漫画：你准备好微服务了吗？

![](/data/attachment/album/201901/14/123302dn2g2zmgzr29g9tz.png)

微服务是个好东西，就像乐高积木一样，你可以拼成各种东西，当前，前提是你足够会玩。

从早些年的 SOA 和中间件，到现在的微服务和容器，但似乎历史总是螺旋式变化的。看起来笨拙而大而无当的独石应用，其实在很多场景，要比微服务更适合。

话说，微服务的锅该那只汤姆猫背吗？:->

---

via: <http://turnoff.us/geek/are-you-ready-for-microservices/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者&点评&校对：[wxy](https://github.com/wxy) 合成：[wxy](https://github.com/wxy)

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


Linux 上查看系统/服务器运行时间的 11 种方法

![](/data/attachment/album/201901/15/100936fvejs5lsgwkws552.jpg)

你是否想知道自己的 Linux 系统正常运行了多长时间而没有宕机？系统是什么时候启动的？

Linux 上有多个查看服务器/系统运行时间的命令，大多数用户喜欢使用标准并且很有名的 `uptime` 命令获取这些具体的信息。

服务器的运行时间对一些用户来说不那么重要，但是当服务器运行诸如在线商城<ruby> 门户 <rt>  portal </rt></ruby>、网上银行门户等<ruby> 关键任务应用 <rt>  mission-critical applications </rt></ruby>时，它对于<ruby> 服务器管理员 <rt>  server adminstrators </rt></ruby>来说就至关重要。

它必须做到零宕机，因为一旦停机就会影响到数百万用户。

正如我所说，许多命令都可以让用户看到 Linux 服务器的运行时间。在这篇教程里我会教你如何使用下面 11 种方式来查看。

<ruby> 正常运行时间 <rt>  uptime </rt></ruby>指的是服务器自从上次关闭或重启以来经过的时间。

`uptime` 命令获取 `/proc` 文件中的详细信息并输出正常运行时间，而 `/proc` 文件并不适合人直接看。

以下这些命令会输出系统运行和启动的时间。也会显示一些额外的信息。

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

`uptime` 命令会告诉你系统运行了多长时间。它会用一行显示以下信息。

当前时间、系统运行时间、当前登录用户的数量、过去 1 分钟/5 分钟/15 分钟系统负载的均值。

```
# uptime

 08:34:29 up 21 days,  5:46,  1 user,  load average: 0.06, 0.04, 0.00
```

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

`w` 命令为每个登录进系统的用户，每个用户当前所做的事情，所有活动的负载对计算机的影响提供了一个快速的概要。这个单一命令结合了多个 Unix 程序：`who`、`uptime`，和 `ps -a` 的结果。

```
# w

 08:35:14 up 21 days,  5:47,  1 user,  load average: 0.26, 0.09, 0.02
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/1    103.5.134.167    08:34    0.00s  0.01s  0.00s w
```

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

`top` 命令是 Linux 上监视实时系统进程的基础命令之一。它显示系统信息和运行进程的信息，例如正常运行时间、平均负载、运行的任务、登录用户数量、CPU 数量 & CPU 利用率、内存 & 交换空间信息。

**推荐阅读：**[TOP 命令监视服务器性能的例子](https://www.2daygeek.com/top-command-examples-to-monitor-server-performance/)

```
# top -c

top - 08:36:01 up 21 days,  5:48,  1 user,  load average: 0.12, 0.08, 0.02
Tasks:  98 total,   1 running,  97 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1872888k total,  1454644k used,   418244k free,   175804k buffers
Swap:  2097148k total,        0k used,  2097148k free,  1098140k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    1 root      20   0 19340 1492 1172 S  0.0  0.1   0:01.04 /sbin/init
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 [kthreadd]
    3 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 [migration/0]
    4 root      20   0     0    0    0 S  0.0  0.0   0:34.32 [ksoftirqd/0]
    5 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 [stopper/0]
```

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

`who` 命令列出当前登录进计算机的用户。`who` 命令与 `w` 命令类似，但后者还包含额外的数据和统计信息。

```
# who -b
system boot 2018-04-12 02:48
```

### 方法 5：使用 last 命令

`last` 命令列出最近登录过的用户。`last` 回溯 `/var/log/wtmp` 文件并显示自从文件创建后登录进（出）的用户。

```
# last reboot -F | head -1 | awk '{print $5,$6,$7,$8,$9}'
Thu Apr 12 02:48:04 2018
```

### 方法 6：使用 /proc/uptime 文件

这个文件中包含系统上次启动后运行时间的详细信息。`/proc/uptime` 的输出相当精简。

第一个数字是系统自从启动的总秒数。第二个数字是总时间中系统空闲所花费的时间，以秒为单位。

```
# cat /proc/uptime
1835457.68 1809207.16
```

### 方法 7：使用 tuptime 命令

`tuptime` 是一个汇报系统运行时间的工具，输出历史信息并作以统计，保留重启之间的数据。和 `uptime` 命令很像，但输出更有意思一些。

```
$ tuptime
```

### 方法 8：使用 htop 命令

`htop` 是运行在 Linux 上的一个交互式进程查看器，是 Hisham 使用 ncurses 库开发的。`htop` 比起 `top` 有很多的特性和选项。

**推荐阅读：** [使用 Htop 命令监控系统资源](https://www.2daygeek.com/htop-command-examples-to-monitor-system-resources/)

```
# htop

  CPU[|                         0.5%]     Tasks: 48, 5 thr; 1 running
  Mem[|||||||||||||||     165/1828MB]     Load average: 0.10 0.05 0.01
  Swp[                      0/2047MB]     Uptime: 21 days, 05:52:35

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
29166 root       20   0  110M  2484  1240 R  0.0  0.1  0:00.03 htop
29580 root       20   0 11464  3500  1032 S  0.0  0.2 55:15.97 /bin/sh ./OSWatcher.sh 10 1
    1 root       20   0 19340  1492  1172 S  0.0  0.1  0:01.04 /sbin/init
  486 root       16  -4 10780   900   348 S  0.0  0.0  0:00.07 /sbin/udevd -d
  748 root       18  -2 10780   932   360 S  0.0  0.0  0:00.00 /sbin/udevd -d
```

### 方法 9：使用 glances 命令

`glances` 是一个跨平台的基于 curses 库的监控工具，它是使用 python 编写的。可以说它非常强大，仅用一点空间就能获得很多信息。它使用 psutil 库从系统中获取信息。

`glances` 可以监控 CPU、内存、负载、进程、网络接口、磁盘 I/O、<ruby> 磁盘阵列 <rt>  RAID </rt></ruby>、传感器、文件系统（与文件夹）、容器、监视器、Alert 日志、系统信息、运行时间、<ruby> 快速查看 <rt>  Quicklook </rt></ruby>（CPU，内存、负载）等。

**推荐阅读：** [Glances （集大成）– Linux 上高级的实时系统运行监控工具](https://www.2daygeek.com/install-glances-advanced-real-time-linux-system-performance-monitoring-tool-on-centos-fedora-ubuntu-debian-opensuse-arch-linux/)

```
glances

ubuntu (Ubuntu 17.10 64bit / Linux 4.13.0-37-generic) - IP 192.168.1.6/24                Uptime: 21 days, 05:55:15

CPU  [|||||||||||||||||||||    90.6%]   CPU -    90.6%  nice:     0.0%  ctx_sw:    4K      MEM \   78.4%  active:     942M      SWAP -    5.9%      LOAD    2-core
MEM  [||||||||||||||||         78.0%]   user:    55.1%  irq:      0.0%  inter:   1797      total:  1.95G  inactive:   562M      total:   12.4G      1 min:    4.35
SWAP [|                         5.9%]   system:  32.4%  iowait:   1.8%  sw_int:   897      used:   1.53G  buffers:   14.8M      used:     749M      5 min:    4.38
                                        idle:     7.6%  steal:    0.0%                     free:    431M  cached:     273M      free:    11.7G      15 min:   3.38

NETWORK     Rx/s   Tx/s   TASKS 211 (735 thr), 4 run, 207 slp, 0 oth sorted automatically by memory_percent, flat view
docker0       0b   232b
enp0s3      12Kb    4Kb   Systemd          7    Services loaded: 197 active: 196 failed: 1
lo          616b   616b
_h478e48e     0b   232b     CPU%  MEM%  VIRT   RES   PID USER        NI S     TIME+   R/s   W/s Command
                            63.8  18.9 2.33G  377M  2536 daygeek      0 R   5:57.78     0     0 /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
DefaultGateway     83ms     78.5  10.9 3.46G  217M  2039 daygeek      0 S  21:07.46     0     0 /usr/bin/gnome-shell
                             8.5  10.1 2.32G  201M  2464 daygeek      0 S   8:45.69     0     0 /usr/lib/firefox/firefox -new-window
DISK I/O     R/s    W/s      1.1   8.5 2.19G  170M  2653 daygeek      0 S   2:56.29     0     0 /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
dm-0           0      0      1.7   7.2 2.15G  143M  2880 daygeek      0 S   7:10.46     0     0 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
sda1       9.46M    12K      0.0   4.9 1.78G 97.2M  6125 daygeek      0 S   1:36.57     0     0 /usr/lib/firefox/firefox -contentproc -childID 7 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
```

### 方法 10：使用 stat 命令

`stat` 命令显示指定文件或文件系统的详细状态。

```
# stat /var/log/dmesg | grep Modify
Modify: 2018-04-12 02:48:04.027999943 -0400
```

### 方法 11：使用 procinfo 命令

`procinfo` 从 `/proc` 文件夹下收集一些系统数据并将其很好的格式化输出在标准输出设备上。

```
# procinfo | grep Bootup
Bootup: Fri Apr 20 19:40:14 2018 Load average: 0.16 0.05 0.06 1/138 16615
```

---

via: <https://www.2daygeek.com/11-methods-to-find-check-system-server-uptime-in-linux/>

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

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