Summary: 之前，Steam 宣布要给 Steam Play 增加一个新组件，用于支持在 Linux 平台上使用 Proton 来玩 Windows 的游戏

# 在 Fedora 上使用 Steam play 和 Proton 来玩 Windows 游戏

之前，Steam [宣布](https://steamcommunity.com/games/221410/announcements/detail/1696055855739350561)要给 Steam Play 增加一个新组件，用于支持在 Linux 平台上使用 Proton 来玩 Windows 的游戏，这个组件是 WINE 的一个分支。这个功能仍然处于测试阶段，且并非对所有游戏都有效。这里有一些关于 Steam 和 Proton 的细节。

据 Steam 网站称，测试版本中有以下这些新功能：

* 现在没有 Linux 版本的 Windows 游戏可以直接从 Linux 上的 Steam 客户端进行安装和运行，并且有完整、原生的 Steamworks 和 OpenVR 的支持。
* 现在 DirectX 11 和 12 的实现都基于 Vulkan，它可以提高游戏的兼容性并减小游戏性能收到的影响。
* 全屏支持已经得到了改进，全屏游戏时可以无缝扩展到所需的显示程度，而不会干扰到显示屏本身的分辨率或者说需要使用虚拟桌面。
* 改进了对游戏控制器的支持，游戏自动识别所有 Steam 支持的控制器，比起游戏的原始版本，能够获得更多开箱即用的控制器兼容性。
* 和 vanilla WINE 比起来，游戏的多线程性能得到了极大的提高。

### 安装

如果你有兴趣，想尝试一下 Steam 和 Proton。请按照下面这些简单的步骤进行操作。（请注意，如果你已经安装了最新版本的 Steam，可以忽略启用 Steam 测试版这个第一步。在这种情况下，你不再需要通过 Steam 测试版来使用 Proton。）

打开 Steam 并登陆到你的帐户，这个截屏示例显示的是在使用 Proton 之前仅支持 22 个游戏。

现在点击客户端顶部的 “Steam” 选项，这会显示一个下拉菜单。然后选择“设置”。

现在弹出了设置窗口，选择“账户”选项，并在 “参与 Beta 测试” 旁边，点击“更改”。

现在将 “None” 更改为 “Steam Beta Update”。

点击“确定”，然后系统会提示你重新启动。

让 Steam 下载更新，这会需要一段时间，具体需要多久这要取决于你的网络速度和电脑配置。

在重新启动之后，返回到上面的设置窗口。这次你会看到一个新选项。确定勾选了“为提供支持的游戏使用 Stream Play” 、“让所有的游戏都使用 Steam Play 运行”，“使用这个工具替代 Steam 中游戏特定的选项”。这个兼容性工具应该就是 Proton。

Steam 客户端会要求你重新启动，照做，然后重新登录你的 Steam 账户，你的 Linux 的游戏库就能得到扩展了。

### 使用 Steam Play 来安装一个 Windows 游戏

现在你已经启用 Proton，开始安装游戏，选择你想要安装的游戏，然后你会发现这个安装过程类似于在 Steam 上安装一个普通游戏，如下面这些截图所示。

在下载和安装完游戏后，你就可以开始玩了。

一些游戏可能会受到 Proton 测试性质的影响，在这个叫 Chantelise 游戏中，没有了声音并且帧率很低。请记住这个功能仍然在测试阶段，Fedora 不会对结果负责。如果你想要了解更多，社区已经创建了一个 Google 文档，这个文档里有已经测试过的游戏的列表。

---

via: <https://fedoramagazine.org/play-windows-games-steam-play-proton/>

作者：[Francisco J. Vergara Torres](https://fedoramagazine.org/author/patxi/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[hopefully2333](https://github.com/hopefully2333) 校对：[wxy](https://github.com/wxy)

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


ProtectedText：一个免费的在线加密笔记

# ProtectedText：一个免费的在线加密笔记

记录笔记是我们每个人必备的重要技能，它可以帮助我们把自己听到、读到、学到的内容长期地保留下来，也有很多的应用和工具都能让我们更好地记录笔记。下面我要介绍一个叫做 **ProtectedText** 的应用，这是一个可以将你的笔记在线上保存起来的免费的加密笔记。它是一个免费的 web 服务，在上面记录文本以后，它将会对文本进行加密，只需要一台支持连接到互联网并且拥有 web 浏览器的设备，就可以访问到记录的内容。

ProtectedText 不会向你询问任何个人信息，也不会保存任何密码，没有广告，没有 Cookies，更没有用户跟踪和注册流程。除了拥有密码能够解密文本的人，任何人都无法查看到笔记的内容。而且，使用前不需要在网站上注册账号，写完笔记之后，直接关闭浏览器，你的笔记也就保存好了。

### 在加密笔记本上记录笔记

访问 <https://www.protectedtext.com/> 这个链接，就可以打开 ProtectedText 页面了（LCTT 译注：如果访问不了，你知道的）。这个时候你将进入网站主页，接下来需要在页面上的输入框输入一个你想用的名称，或者在地址栏后面直接加上想用的名称。这个名称是一个自定义的名称（例如 <https://www.protectedtext.com/mysite>），是你查看自己保存的笔记的专有入口。

如果你选用的名称还没有被占用，你就会看到下图中的提示信息。点击 “Create” 键就可以创建你的个人笔记页了。

至此你已经创建好了你自己的笔记页面，可以开始记录笔记了。目前每个笔记页的最大容量是每页 750000+ 个字符。

ProtectedText 使用 AES 算法对你的笔记内容进行加密和解密，而计算散列则使用了 SHA512 算法。

笔记记录完毕以后，点击顶部的 “Save” 键保存。

按下保存键之后，ProtectedText 会提示你输入密码以加密你的笔记内容。按照它的要求输入两次密码，然后点击 “Save” 键。

尽管 ProtectedText 对你使用的密码没有太多要求，但毕竟密码总是一寸长一寸强，所以还是最好使用长且复杂的密码（用到数字和特殊字符）以避免暴力破解。由于 ProtectedText 不会保存你的密码，一旦密码丢失，密码和笔记内容就都找不回来了。因此，请牢记你的密码，或者使用诸如 [Buttercup](https://www.ostechnix.com/buttercup-a-free-secure-and-cross-platform-password-manager/)、[KeeWeb](https://www.ostechnix.com/keeweb-an-open-source-cross-platform-password-manager/) 这样的密码管理器来存储你的密码。

在使用其它设备时，可以通过访问之前创建的 URL 就可以访问你的笔记了。届时会出现如下的提示信息，只需要输入正确的密码，就可以查看和编辑你的笔记。

一般情况下，只有知道密码的人才能正常访问笔记的内容。如果你希望将自己的笔记公开，只需要以 <https://www.protectedtext.com/yourSite?yourPassword> 的形式访问就可以了，ProtectedText 将会自动使用 `yourPassword` 字符串解密你的笔记。

ProtectedText 还有配套的 [Android 应用](https://play.google.com/store/apps/details?id=com.protectedtext.android) 可以让你在移动设备上进行同步笔记、离线工作、备份笔记、锁定/解锁笔记等等操作。

**优点**

* 简单、易用、快速、免费
* ProtectedText.com 的客户端代码可以在[这里](https://www.protectedtext.com/js/main.js)免费获取，如果你想了解它的底层实现，可以自行学习它的源代码
* 存储的内容没有到期时间，只要你愿意，笔记内容可以一直保存在服务器上
* 可以让你的数据限制为私有或公开开放

**缺点**

* 尽管客户端代码是公开的，但服务端代码并没有公开，因此你无法自行搭建一个类似的服务。如果你不信任这个网站，请不要使用。
* 由于网站不存储你的任何个人信息，包括你的密码，因此如果你丢失了密码，数据将永远无法恢复。网站方还声称他们并不清楚谁拥有了哪些数据，所以一定要牢记密码。

如果你想通过一种简单的方式将笔记保存到线上，并且需要在不需要安装任何工具的情况下访问，那么 ProtectedText 会是一个好的选择。如果你还知道其它类似的应用程序，欢迎在评论区留言！

---

via: <https://www.ostechnix.com/protectedtext-a-free-encrypted-notepad-to-save-your-notes-online/>

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

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


Caffeinated 6.828：实验工具指南

Summary: 本文将为你简单概述一下 JOS 环境和非常有用的 GDB 和 QEMU 命令。

本文将为你简单概述一下 JOS 环境和非常有用的 GDB 和 QEMU 命令。

# Caffeinated 6.828：实验工具指南

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

熟悉你的环境对高效率的开发和调试来说是至关重要的。本文将为你简单概述一下 JOS 环境和非常有用的 GDB 和 QEMU 命令。话虽如此，但你仍然应该去阅读 GDB 和 QEMU 手册，来理解这些强大的工具如何使用。

### 调试小贴士

#### 内核

GDB 是你的朋友。使用 `qemu-gdb target`（或它的变体 `qemu-gdb-nox`）使 QEMU 等待 GDB 去绑定。下面在调试内核时用到的一些命令，可以去查看 GDB 的资料。

如果你遭遇意外的中断、异常、或三重故障，你可以使用 `-d` 参数要求 QEMU 去产生一个详细的中断日志。

调试虚拟内存问题时，尝试 QEMU 的监视命令 `info mem`（提供内存高级概述）或 `info pg`（提供更多细节内容）。注意，这些命令仅显示**当前**页表。

（在实验 4 以后）去调试多个 CPU 时，使用 GDB 的线程相关命令，比如 `thread` 和 `info threads`。

#### 用户环境（在实验 3 以后）

GDB 也可以去调试用户环境，但是有些事情需要注意，因为 GDB 无法区分开多个用户环境或区分开用户环境与内核环境。

你可以使用 `make run-name`（或编辑 `kern/init.c` 目录）来指定 JOS 启动的用户环境，为使 QEMU 等待 GDB 去绑定，使用 `run-name-gdb` 的变体。

你可以符号化调试用户代码，就像调试内核代码一样，但是你要告诉 GDB，哪个符号表用到符号文件命令上，因为它一次仅能够使用一个符号表。提供的 `.gdbinit` 用于加载内核符号表 `obj/kern/kernel`。对于一个用户环境，这个符号表在它的 ELF 二进制文件中，因此你可以使用 `symbol-file obj/user/name` 去加载它。不要从任何 `.o` 文件中加载符号，因为它们不会被链接器迁移进去（库是静态链接进 JOS 用户二进制文件中的，因此这些符号已经包含在每个用户二进制文件中了）。确保你得到了正确的用户二进制文件；在不同的二进制文件中，库函数被链接为不同的 EIP，而 GDB 并不知道更多的内容！

（在实验 4 以后）因为 GDB 绑定了整个虚拟机，所以它可以将时钟中断看作为一种控制转移。这使得从底层上不可能实现步进用户代码，因为一个时钟中断无形中保证了片刻之后虚拟机可以再次运行。因此可以使用 `stepi` 命令，因为它阻止了中断，但它仅可以步进一个汇编指令。断点一般来说可以正常工作，但要注意，因为你可能在不同的环境（完全不同的一个二进制文件）上遇到同一个 EIP。

### 参考

#### JOS makefile

JOS 的 GNUmakefile 包含了在各种方式中运行的 JOS 的许多假目标。所有这些目标都配置 QEMU 去监听 GDB 连接（`*-gdb` 目标也等待这个连接）。要在运行中的 QEMU 上启动它，只需要在你的实验目录中简单地运行 `gdb` 即可。我们提供了一个 `.gdbinit` 文件，它可以在 QEMU 中自动指向到 GDB、加载内核符号文件、以及在 16 位和 32 位模式之间切换。退出 GDB 将关闭 QEMU。

* `make qemu`

在一个新窗口中构建所有的东西并使用 VGA 控制台和你的终端中的串行控制台启动 QEMU。想退出时，既可以关闭 VGA 窗口，也可以在你的终端中按 `Ctrl-c` 或 `Ctrl-a x`。
* `make qemu-nox`

和 `make qemu` 一样，但仅使用串行控制台来运行。想退出时，按下 `Ctrl-a x`。这种方式在通过 SSH 拨号连接到 Athena 上时非常有用，因为 VGA 窗口会占用许多带宽。
* `make qemu-gdb`

和 `make qemu` 一样，但它与任意时间被动接受 GDB 不同，而是暂停第一个机器指令并等待一个 GDB 连接。
* `make qemu-nox-gdb`

它是 `qemu-nox` 和 `qemu-gdb` 目标的组合。
* `make run-nam`

（在实验 3 以后）运行用户程序 name。例如，`make run-hello` 运行 `user/hello.c`。
* `make run-name-nox`,`run-name-gdb`, `run-name-gdb-nox`

（在实验 3 以后）与 `qemu` 目标变量对应的 `run-name` 的变体。

makefile 也接受几个非常有用的变量：

* `make V=1 …`

详细模式。输出正在运行的每个命令，包括参数。
* `make V=1 grade`

在评级测试失败后停止，并将 QEMU 的输出放入 `jos.out` 文件中以备检查。
* `make QEMUEXTRA=' _args_ ' …`

指定传递给 QEMU 的额外参数。

#### JOS obj/

在构建 JOS 时，makefile 也产生一些额外的输出文件，这些文件在调试时非常有用：

* `obj/boot/boot.asm`、`obj/kern/kernel.asm`、`obj/user/hello.asm`、等等。

引导加载器、内核、和用户程序的汇编代码列表。
* `obj/kern/kernel.sym`、`obj/user/hello.sym`、等等。

内核和用户程序的符号表。
* `obj/boot/boot.out`、`obj/kern/kernel`、`obj/user/hello`、等等。

内核和用户程序链接的 ELF 镜像。它们包含了 GDB 用到的符号信息。

#### GDB

完整的 GDB 命令指南请查看 [GDB 手册](http://sourceware.org/gdb/current/onlinedocs/gdb/)。下面是一些在 6.828 课程中非常有用的命令，它们中的一些在操作系统开发之外的领域几乎用不到。

* `Ctrl-c`

在当前指令处停止机器并打断进入到 GDB。如果 QEMU 有多个虚拟的 CPU，所有的 CPU 都会停止。
* `c`（或 `continue`）

继续运行，直到下一个断点或 `Ctrl-c`。
* `si`（或 `stepi`）

运行一个机器指令。
* `b function` 或 `b file:line`（或 `breakpoint`）

在给定的函数或行上设置一个断点。
* `b * addr`（或 `breakpoint`）

在 EIP 的 addr 处设置一个断点。
* `set print pretty`

启用数组和结构的美化输出。
* `info registers`

输出通用寄存器 `eip`、`eflags`、和段选择器。更多更全的机器寄存器状态转储，查看 QEMU 自己的 `info registers` 命令。
* `x/ N x addr`

以十六进制显示虚拟地址 addr 处开始的 N 个词的转储。如果 N 省略，默认为 1。addr 可以是任何表达式。
* `x/ N i addr`

显示从 addr 处开始的 N 个汇编指令。使用 `$eip` 作为 addr 将显示当前指令指针寄存器中的指令。
* `symbol-file file`

（在实验 3 以后）切换到符号文件 file 上。当 GDB 绑定到 QEMU 后，它并不是虚拟机中进程边界内的一部分，因此我们要去告诉它去使用哪个符号。默认情况下，我们配置 GDB 去使用内核符号文件 `obj/kern/kernel`。如果机器正在运行用户代码，比如是 `hello.c`，你就需要使用 `symbol-file obj/user/hello` 去切换到 hello 的符号文件。

QEMU 将每个虚拟 CPU 表示为 GDB 中的一个线程，因此你可以使用 GDB 中所有的线程相关的命令去查看或维护 QEMU 的虚拟 CPU。

* `thread n`

GDB 在一个时刻只关注于一个线程（即：CPU）。这个命令将关注的线程切换到 n，n 是从 0 开始编号的。
* `info threads`

列出所有的线程（即：CPU），包括它们的状态（活动还是停止）和它们在什么函数中。

#### QEMU

QEMU 包含一个内置的监视器，它能够有效地检查和修改机器状态。想进入到监视器中，在运行 QEMU 的终端中按入 `Ctrl-a c` 即可。再次按下 `Ctrl-a c` 将切换回串行控制台。

监视器命令的完整参考资料，请查看 [QEMU 手册](http://wiki.qemu.org/download/qemu-doc.html#pcsys_005fmonitor)。下面是 6.828 课程中用到的一些有用的命令：

* `xp/ N x paddr`

显示从物理地址 paddr 处开始的 N 个词的十六进制转储。如果 N 省略，默认为 1。这是 GDB 的 `x` 命令模拟的物理内存。
* `info registers`

显示机器内部寄存器状态的一个完整转储。实践中，对于段选择器，这将包含机器的 隐藏 段状态和局部、全局、和中断描述符表加任务状态寄存器。隐藏状态是在加载段选择器后，虚拟的 CPU 从 GDT/LDT 中读取的信息。下面是实验 1 中 JOS 内核处于运行中时的 CS 信息和每个字段的含义：

```
CS =0008 10000000 ffffffff 10cf9a00 DPL=0 CS32 [-R-]
```
* `CS =0008`

代码选择器可见部分。我们使用段 0x8。这也告诉我们参考全局描述符表（0x8&4=0），并且我们的 CPL（当前权限级别）是 0x8&3=0。
* `10000000`

这是段基址。线性地址 = 逻辑地址 + 0x10000000。
* `ffffffff`

这是段限制。访问线性地址 0xffffffff 以上将返回段违规异常。
* `10cf9a00`

段的原始标志，QEMU 将在接下来的几个字段中解码这些对我们有用的标志。
* `DPL=0`

段的权限级别。一旦代码以权限 0 运行，它将就能够加载这个段。
* `CS32`

这是一个 32 位代码段。对于数据段（不要与 DS 寄存器混淆了），另外的值还包括 `DS`，而对于本地描述符表是 `LDT`。
* `[-R-]`

这个段是只读的。
* `info mem`

（在实验 2 以后）显示映射的虚拟内存和权限。比如：

```
ef7c0000-ef800000 00040000 urw
efbf8000-efc00000 00008000 -rw
```

这告诉我们从 0xef7c0000 到 0xef800000 的 0x00040000 字节的内存被映射为读取/写入/用户可访问，而映射在 0xefbf8000 到 0xefc00000 之间的内存权限是读取/写入，但是仅限于内核可访问。
* `info pg`

（在实验 2 以后）显示当前页表结构。它的输出类似于 `info mem`，但与页目录条目和页表条目是有区别的，并且为每个条目给了单独的权限。重复的 PTE 和整个页表被折叠为一个单行。例如：

```
VPN range     Entry         Flags        Physical page
[00000-003ff]  PDE[000]     -------UWP
  [00200-00233]  PTE[200-233] -------U-P 00380 0037e 0037d 0037c 0037b 0037a ..
[00800-00bff]  PDE[002]     ----A--UWP
  [00800-00801]  PTE[000-001] ----A--U-P 0034b 00349
  [00802-00802]  PTE[002]     -------U-P 00348
```

这里各自显示了两个页目录条目、虚拟地址范围 0x00000000 到 0x003fffff 以及 0x00800000 到 0x00bfffff。 所有的 PDE 都存在于内存中、可写入、并且用户可访问，而第二个 PDE 也是可访问的。这些页表中的第二个映射了三个页、虚拟地址范围 0x00800000 到 0x00802fff，其中前两个页是存在于内存中的、可写入、并且用户可访问的，而第三个仅存在于内存中，并且用户可访问。这些 PTE 的第一个条目映射在物理页 0x34b 处。

QEMU 也有一些非常有用的命令行参数，使用 `QEMUEXTRA` 变量可以将参数传递给 JOS 的 makefile。

* `make QEMUEXTRA='-d int' ...`

记录所有的中断和一个完整的寄存器转储到 `qemu.log` 文件中。你可以忽略前两个日志条目、“SMM: enter” 和 “SMM: after RMS”，因为这些是在进入引导加载器之前生成的。在这之后的日志条目看起来像下面这样：

```
     4: v=30 e=0000 i=1 cpl=3 IP=001b:00800e2e pc=00800e2e SP=0023:eebfdf28 EAX=00000005
EAX=00000005 EBX=00001002 ECX=00200000 EDX=00000000
ESI=00000805 EDI=00200000 EBP=eebfdf60 ESP=eebfdf28
...
```

第一行描述了中断。`4:` 只是一个日志记录计数器。`v` 提供了十六进程的向量号。`e` 提供了错误代码。`i=1` 表示它是由一个 `int` 指令（相对一个硬件产生的中断而言）产生的。剩下的行的意思很明显。对于一个寄存器转储而言，接下来看到的就是寄存器信息。

注意：如果你运行的是一个 0.15 版本之前的 QEMU，日志将写入到 `/tmp` 目录，而不是当前目录下。

---

via: <https://pdos.csail.mit.edu/6.828/2018/labguide.html>

作者：[csail.mit](https://pdos.csail.mit.edu) 选题：[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/) 荣誉推出


让系统崩溃的黑天鹅分类

Summary: 在严重的故障发生之前，找到引起问题的异常事件，并修复它。

在严重的故障发生之前，找到引起问题的异常事件，并修复它。

# 让系统崩溃的黑天鹅分类

>
> 在严重的故障发生之前，找到引起问题的异常事件，并修复它。
>
>
>

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

<ruby> 黑天鹅 <rt>  Black swan </rt></ruby>用来比喻造成严重影响的小概率事件（比如 2008 年的金融危机）。在生产环境的系统中，黑天鹅是指这样的事情：它引发了你不知道的问题，造成了重大影响，不能快速修复或回滚，也不能用值班说明书上的其他标准响应来解决。它是事发几年后你还在给新人说起的事件。

从定义上看，黑天鹅是不可预测的，不过有时候我们能找到其中的一些模式，针对有关联的某一类问题准备防御措施。

例如，大部分故障的直接原因是变更（代码、环境或配置）。虽然这种方式触发的 bug 是独特的、不可预测的，但是常见的金丝雀发布对避免这类问题有一定的作用，而且自动回滚已经成了一种标准止损策略。

随着我们的专业性不断成熟，一些其他的问题也正逐渐变得容易理解，被归类到某种风险并有普适的预防策略。

### 公布出来的黑天鹅事件

所有科技公司都有生产环境的故障，只不过并不是所有公司都会分享他们的事故分析。那些公开讨论事故的公司帮了我们的忙。下列事故都描述了某一类问题，但它们绝对不是只一个孤例。我们的系统中都有黑天鹅在潜伏着，只是有些人还不知道而已。

#### 达到上限

达到任何类型的限制都会引发严重事故。这类问题的一个典型例子是 2017 年 2 月 [Instapaper 的一次服务中断](https://medium.com/making-instapaper/instapaper-outage-cause-recovery-3c32a7e9cc5f)。我把这份事故报告给任何一个运维工作者看，他们读完都会脊背发凉。Instapaper 生产环境的数据库所在的文件系统有 2 TB 的大小限制，但是数据库服务团队并不知情。在没有任何报错的情况下，数据库不再接受任何写入了。完全恢复需要好几天，而且还得迁移数据库。

资源限制有各式各样的触发场景。Sentry 遇到了 [Postgres 的最大事务 ID 限制](https://blog.sentry.io/2015/07/23/transaction-id-wraparound-in-postgres.html)。Platform.sh 遇到了[管道缓冲区大小限制](https://medium.com/@florian_7764/technical-post-mortem-of-the-august-incident-82ab4c3d6547)。SparkPost [触发了 AWS 的 DDoS 保护](https://www.usenix.org/conference/srecon18americas/presentation/blosser)。Foursquare 在他们的一个 [MongoDB 耗尽内存](https://groups.google.com/forum/#!topic/mongodb-user/UoqU8ofp134)时遭遇了性能骤降。

提前了解系统限制的一个办法是定期做测试。好的压力测试（在生产环境的副本上做）应该包含写入事务，并且应该把每一种数据存储都写到超过当前生产环境的容量。压力测试时很容易忽略的是次要存储（比如 Zookeeper）。如果你是在测试时遇到了资源限制，那么你还有时间去解决问题。鉴于这种资源限制问题的解决方案可能涉及重大的变更（比如数据存储拆分），所以时间是非常宝贵的。

说到云产品的使用，如果你的服务产生了异常的负载，或者你用的产品或功能还没有被广泛使用（比如老旧的或者新兴的），那么你遇到资源上限的风险很大。对这些云产品做一下压力测试是值得的。不过，做之前要提醒一下你的云服务提供商。

最后，知道了哪里有限制之后，要增加监控（和对应文档），这样你才能知道系统在什么时候接近了资源上限。不要寄希望于那些还在维护服务的人会记得。

#### 扩散的慢请求

>
> “这个世界的关联性远比我们想象中更大。所以我们看到了更多 Nassim Taleb 所说的‘黑天鹅事件’ —— 即罕见事件以更高的频率离谱地发生了，因为世界是相互关联的” —— [Richard Thaler](https://en.wikipedia.org/wiki/Richard_Thaler)
>
>
>

HostedGraphite 的负载均衡器并没有托管在 AWS 上，却[被 AWS 的服务中断给搞垮了](https://blog.hostedgraphite.com/2018/03/01/spooky-action-at-a-distance-how-an-aws-outage-ate-our-load-balancer/)，他们关于这次事故原因的分析报告很好地诠释了分布式计算系统之间存在多么大的关联。在这个事件里，负载均衡器的连接池被来自 AWS 上的客户访问占满了，因为这些连接很耗时。同样的现象还会发生在应用的线程、锁、数据库连接上 —— 任何能被慢操作占满的资源。

这个 HostedGraphite 的例子中，慢速连接是外部系统施加的，不过慢速连接经常是由内部某个系统的饱和所引起的，饱和与慢操作的级联，拖慢了系统中的其他部分。[Spotify 的一个事故](https://labs.spotify.com/2013/06/04/incident-management-at-spotify/)就说明了这样的传播 —— 流媒体服务的前端被另一个微服务的饱和所影响，造成健康检查失败。强制给所有请求设置超时时间，以及限制请求队列的长度，可以预防这一类故障传播。这样即使有问题，至少你的服务还能承担一些流量，而且因为整体上你的系统里故障的部分更少了，恢复起来也会更快。

重试的间隔应该用指数退避来限制一下，并加入一些时间抖动。Square 有一次服务中断是 [Redis 存储的过载](https://medium.com/square-corner-blog/incident-summary-2017-03-16-2f65be39297)，原因是有一段代码对失败的事务重试了 500 次，没有任何重试退避的方案，也说明了过度重试的潜在风险。另外，针对这种情况，[断路器](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern)设计模式也是有用的。

应该设计出监控仪表盘来清晰地展示所有资源的[使用率、饱和度和报错](http://www.brendangregg.com/usemethod.html)，这样才能快速发现问题。

#### 突发的高负载

系统在异常高的负载下经常会发生故障。用户天然会引发高负载，不过也常常是由系统引发的。午夜突发的 cron 定时任务是老生常谈了。如果程序让移动客户端同时去获取更新，这些客户端也会造成突发的大流量（当然，给这种请求加入时间抖动会好很多）。

在预定时刻同时发生的事件并不是突发大流量的唯一原因。Slack 经历过一次短时间内的[多次服务中断](https://slackhq.com/this-was-not-normal-really)，原因是非常多的客户端断开连接后立即重连，造成了突发的大负载。 CircleCI 也经历过一次[严重的服务中断](https://circleci.statuspage.io/incidents/hr0mm9xmm3x6)，当时 Gitlab 从故障中恢复了，所以数据库里积累了大量的构建任务队列，服务变得饱和而且缓慢。

几乎所有的服务都会受突发的高负载所影响。所以对这类可能出现的事情做应急预案 —— 并测试一下预案能否正常工作 —— 是必须的。客户端退避和[减载](https://www.youtube.com/watch?v=XNEIkivvaV4)通常是这些方案的核心。

如果你的系统必须不间断地接收数据，并且数据不能被丢掉，关键是用可伸缩的方式把数据缓冲到队列中，后续再处理。

#### 自动化系统是复杂的系统

>
> “复杂的系统本身就是有风险的系统”
>  —— [Richard Cook, MD](https://web.mit.edu/2.75/resources/random/How%20Complex%20Systems%20Fail.pdf)
>
>
>

过去几年里软件的运维操作趋势是更加自动化。任何可能降低系统容量的自动化操作（比如擦除磁盘、退役设备、关闭服务）都应该谨慎操作。这类自动化操作的故障（由于系统有 bug 或者有不正确的调用）能很快地搞垮你的系统，而且可能很难恢复。

谷歌的 Christina Schulman 和 Etienne Perot 在[用安全规约协助保护你的数据中心](https://www.usenix.org/conference/srecon18americas/presentation/schulman)的演讲中给了一些例子。其中一次事故是将谷歌整个内部的内容分发网络（CDN）提交给了擦除磁盘的自动化系统。

Schulman 和 Perot 建议使用一个中心服务来管理规约，限制破坏性自动化操作的速度，并能感知到系统状态（比如避免在最近有告警的服务上执行破坏性的操作）。

自动化系统在与运维人员（或其他自动化系统）交互时，也可能造成严重事故。[Reddit](https://www.reddit.com/r/announcements/comments/4y0m56/why_reddit_was_down_on_aug_11/) 遭遇过一次严重的服务中断，当时他们的自动化系统重启了一个服务，但是这个服务是运维人员停掉做维护的。一旦有了多个自动化系统，它们之间潜在的交互就变得异常复杂和不可预测。

所有的自动化系统都把日志输出到一个容易搜索的中心存储上，能帮助到对这类不可避免的意外情况的处理。自动化系统总是应该具备这样一种机制，即允许快速地关掉它们（完全关掉或者只关掉其中一部分操作或一部分目标）。

### 防止黑天鹅事件

可能在等着击垮系统的黑天鹅可不止上面这些。有很多其他的严重问题是能通过一些技术来避免的，像金丝雀发布、压力测试、混沌工程、灾难测试和模糊测试 —— 当然还有冗余性和弹性的设计。但是即使用了这些技术，有时候你的系统还是会有故障。

为了确保你的组织能有效地响应，在服务中断期间，请保证关键技术人员和领导层有办法沟通协调。例如，有一种你可能需要处理的烦人的事情，那就是网络完全中断。拥有故障时仍然可用的通信通道非常重要，这个通信通道要完全独立于你们自己的基础设施及对其的依赖。举个例子，假如你使用 AWS，那么把故障时可用的通信服务部署在 AWS 上就不明智了。在和你的主系统无关的地方，运行电话网桥或 IRC 服务器是比较好的方案。确保每个人都知道这个通信平台，并练习使用它。

另一个原则是，确保监控和运维工具对生产环境系统的依赖尽可能的少。将控制平面和数据平面分开，你才能在系统不健康的时候做变更。不要让数据处理和配置变更或监控使用同一个消息队列，比如，应该使用不同的消息队列实例。在 [SparkPost: DNS 挂掉的那一天](https://www.usenix.org/conference/srecon18americas/presentation/blosser) 这个演讲中，Jeremy Blosser 讲了一个这类例子，很关键的工具依赖了生产环境的 DNS 配置，但是生产环境的 DNS 出了问题。

### 对抗黑天鹅的心理学

处理生产环境的重大事故时会产生很大的压力。为这些场景制定结构化的事故管理流程确实是有帮助的。很多科技公司（[包括谷歌](https://landing.google.com/sre/book/chapters/managing-incidents.html)）成功地使用了联邦应急管理局事故指挥系统的某个版本。对于每一个值班的人，遇到了他们无法独立解决的重大问题时，都应该有一个明确的寻求协助的方法。

对于那些持续很长时间的事故，有一点很重要，要确保工程师不会连续工作到不合理的时长，确保他们不会不吃不睡（没有报警打扰的睡觉）。疲惫不堪的工程师很容易犯错或者漏掉了可能更快解决故障的信息。

### 了解更多

关于黑天鹅（或者以前的黑天鹅）事件以及应对策略，还有很多其他的事情可以说。如果你想了解更多，我强烈推荐你去看这两本书，它们是关于生产环境中的弹性和稳定性的：Susan Fowler 写的《[生产微服务](http://shop.oreilly.com/product/0636920053675.do)》，还有 Michael T. Nygard 的 《[Release It!](https://www.oreilly.com/library/view/release-it/9781680500264/)》。

---

via: <https://opensource.com/article/18/10/taxonomy-black-swans>

作者：[Laura Nolan](https://opensource.com/users/lauranolan) 选题：[lujun9972](https://github.com/lujun9972) 译者：[BeliteX](https://github.com/belitex) 校对：[wxy](https://github.com/wxy)

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


DevOps 应聘者应该准备回答的 20 个问题

Summary: 想要建立一个积极，富有成效的工作环境？ 在招聘过程中要专注于寻找契合点。

想要建立一个积极，富有成效的工作环境？ 在招聘过程中要专注于寻找契合点。

# DevOps 应聘者应该准备回答的 20 个问题

>
> 想要建立一个积极，富有成效的工作环境？ 在招聘过程中要专注于寻找契合点。
>
>
>

聘请一个不合适的人[代价是很高的](https://www.shrm.org/resourcesandtools/hr-topics/employee-relations/pages/cost-of-bad-hires.aspx)。根据 Link 人力资源的首席执行官 Jörgen Sundberg 的统计，招聘、雇佣一名新员工将会花费公司$240,000 之多，当你进行了一次不合适的招聘：

* 你失去了他们的知识技能。
* 你失去了他们的人脉。
* 你的团队将可能进入到一个组织发展的震荡阶段
* 你的公司将会面临组织破裂的风险

当你失去一名员工的时候，你就像丢失了公司版图中的一块。同样值得一提的是另一端的痛苦。应聘到一个错误工作岗位的员工会感受到很大的压力以及整个身心的不满意，甚至是健康问题。

另外一方面，当你招聘到合适的人时，新的员工将会：

* 丰富公司现有的文化，使你的组织成为一个更好的工作场所。研究表明一个积极的工作文化能够帮助更长久推动财务业绩增长，而且如果你在一个欢快的环境中工作，你更有可能在生活中做的更好。
* 热爱和你的组织在一起工作。当人们热爱他们所在做的，他们会趋向于做的更好。

招聘以适合或加强现有的文化在 DevOps 和敏捷团多中是必不可少的。也就是说雇佣到一个能够鼓励积极合作的人，以便来自不同背景，有着不同目标和工作方式的团队能够在一起有效的工作。你新雇佣的员工应该能够帮助团队合作来充分发挥放大他们的价值，同时也能够增加员工的满意度以及平衡组织目标的冲突。他或者她应该能够通过明智的选择工具和工作流来促进你的组织，文化就是一切。

作为我们 2017 年 11 月发布的一篇文章 [DevOps 的招聘经理应该准备回答的 20 个问题](https://opensource.com/article/17/11/inclusive-workforce-takes-work) 的回应，这篇文章将会重点关注在如何招聘最适合的人。

### 为什么招聘走错了方向

很多公司现在用的典型的雇佣策略是基于人才过剩的基础上：

* 在职位公告栏发布招聘。
* 关注具有所需才能的应聘者。
* 尽可能找多的候选者。
* 通过面试淘汰弱者。
* 通过正式的面试淘汰更多的弱者。
* 评估，投票，选择。
* 渐渐接近补偿。

职位公告栏是有成千上万失业者人才过剩的经济大萧条时期发明的。在今天的求职市场上已经没有人才过剩了，然而我们仍然在使用基于此的招聘策略。

### 雇佣最合适的人员：运用文化和情感

在人才过剩雇佣策略背后的思想是设计工作岗位然后将人员安排进去。

反而应该反过来：寻找将会积极融入你的商业文化的人才，然后为他们寻找他们热爱的最合适的岗位。要想实现这样的目标，你必须能够围绕他们热情为他们创造工作岗位。

**谁正在寻找一份工作？** 根据一份 2016 年对美国 50000 名开发者的调查显示，[85.7% 的受访对象](https://insights.stackoverflow.com/survey/2016#work-job-discovery)要么对新的机会不感兴趣，要么对于寻找新工作没有积极性。在寻找工作的那部分中，有将近 [28.3% 的求职者](https://insights.stackoverflow.com/survey/2016#work-job-discovery)来自于朋友的推荐。如果你只是在那些在找工作的人中寻找人才，你将会错过高端的人才。

**运用团队力量去发现和寻找潜力的雇员**。例如，戴安娜是你的团队中的一名开发者，她所能提供的机会是，她已经[从事编程很多年](https://research.hackerrank.com/developer-skills/2018/)而且在期间已经结识了很多从事热爱他们所从事的工作的人。难道你不认为她所推荐的潜在员工在技能、知识和智慧上要比 HR 所寻找的要优秀吗？在要求戴安娜分享她同伴之前，通知她即将到来的使命任务，向她阐明你要雇佣潜在有探索精神的团队，描述在将来会需要的知识领域。

**雇员想要什么？**一份来自千禧年婴儿潮时期出生的人的对比综合性研究显示，20% 的人所想要的是相同的：

1. 对组织产生积极的影响
2. 帮助解决社交或者环境上的挑战
3. 和一群有动力的人一起工作

### 面试的挑战

面试应该是招聘者和应聘者双方为了寻找最合适的人才进行的一次双方之间的对话。将面试聚焦在企业文化和情感对话两个问题上：这个应聘者将会丰富你的企业文化并且会热爱和你在一起工作吗？你能够在工作中帮他们取得成功吗？

**对于招聘经理来说：** 每一次的面试都是你学习如何将自己的组织变得对未来的团队成员更有吸引力，并且每次积极的面试都可能是你发现人才（即使你不会雇佣）的机会。每个人都将会记得积极有效的面试的经历。即使他们不会被雇佣，他们将会和他们的朋友谈论这次经历，你会得到一个被推荐的机会。这有很大的好处：如果你无法吸引到这个人才，你也将会从中学习吸取经验并且改善。

**对面试者来说**：每次的面试都是你释放激情的机会。

### 助你释放潜在雇员激情的 20 个问题

1. 你热爱什么？
2. “今天早晨我已经迫不及待的要去工作”，你怎么看待这句话？
3. 你曾经最快乐的是什么？
4. 你曾经解决问题的最典型的例子是什么，你是如何解决的？
5. 你如何看待配对学习？
6. 你到达办公室和离开办公室心里最先想到的是什么？
7. 你如果你有一次改变你之前或者现在的工作中的一件事的机会，将会是什么事？
8. 当你在工作的时候，你最乐于去学习什么？
9. 你的梦想是什么，你如何去实现？
10. 你在学会如何去实现你的追求的时候想要或者需要什么？
11. 你的价值观是什么？
12. 你是如何坚守自己的价值观的？
13. 在你的生活中平衡意味着什么？
14. 你最引以为傲的工作交流能力是什么？为什么？
15. 你最喜欢营造什么样的环境？
16. 你喜欢别人怎样对待你？
17. 你信任我们什么，如何验证？
18. 告诉我们你在最近的一个项目中学习到什么？
19. 我们还能知道你的其他方面的什么？
20. 如果你正在雇佣我，你将会问我什么问题？

---

via: <https://opensource.com/article/18/3/questions-devops-employees-should-answer>

作者：[Catherine Louis](https://opensource.com/users/catherinelouis) 译者：[FelixYFZ](https://github.com/FelixYFZ) 校对：[wxy](https://github.com/wxy)

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


用 Python 和 Conu 测试容器

Summary: Conu (container utilities 的简写) 是一个 Python 库，让你编写容器测试变得简单。

# 用 Python 和 Conu 测试容器

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

越来越多的开发人员使用容器开发和部署他们的应用。这意味着可以轻松地测试容器也变得很重要。[Conu](https://github.com/user-cont/conu) (container utilities 的简写) 是一个 Python 库，让你编写容器测试变得简单。本文向你介绍如何使用它测试容器。

### 开始吧

首先，你需要一个容器程序来测试。为此，以下命令创建一个包含一个容器的 Dockerfile 和一个被容器伺服的 Flask 应用程序的文件夹。

```
$ mkdir container_test
$ cd container_test
$ touch Dockerfile
$ touch app.py
```

将以下代码复制到 `app.py` 文件中。这是惯常的基本 Flask 应用，它返回字符串 “Hello Container World！”。

```
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello Container World!'

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')
```

### 创建和构建测试容器

为了构建测试容器，将以下指令添加到 Dockerfile。

```
FROM registry.fedoraproject.org/fedora-minimal:latest
RUN microdnf -y install python3-flask && microdnf clean all
ADD ./app.py /srv
CMD ["python3", "/srv/app.py"]
```

然后使用 Docker CLI 工具构建容器。

```
$ sudo dnf -y install docker
$ sudo systemctl start docker
$ sudo docker build . -t flaskapp_container
```

提示：只有在系统上未安装 Docker 时才需要前两个命令。

构建之后使用以下命令运行容器。

```
$ sudo docker run -p 5000:5000 --rm flaskapp_container
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 473-505-51
```

最后，使用 `curl` 检查 Flask 应用程序是否在容器内正确运行：

```
$ curl http://127.0.0.1:5000
Hello Container World!
```

现在，flaskapp\_container 正在运行并准备好进行测试，你可以使用 `Ctrl+C` 将其停止。

### 创建测试脚本

在编写测试脚本之前，必须安装 `conu`。在先前创建的 `container_test` 目录中，运行以下命令。

```
$ python3 -m venv .venv
$ source .venv/bin/activate
(.venv)$ pip install --upgrade pip
(.venv)$ pip install conu
$ touch test_container.py
```

然后将以下脚本复制并保存在 `test_container.py` 文件中。

```
import conu

PORT = 5000

with conu.DockerBackend() as backend:
  image = backend.ImageClass("flaskapp_container")
  options = ["-p", "5000:5000"]
  container = image.run_via_binary(additional_opts=options)

  try:
    # Check that the container is running and wait for the flask application to start.
    assert container.is_running()
    container.wait_for_port(PORT)

    # Run a GET request on / port 5000.
    http_response = container.http_request(path="/", port=PORT)

    # Check the response status code is 200
    assert http_response.ok

    # Get the response content
    response_content = http_response.content.decode("utf-8")

    # Check that the "Hello Container World!" string is served.
    assert "Hello Container World!" in response_content

    # Get the logs from the container
    logs = [line for line in container.logs()]
    # Check the the Flask application saw the GET request.
    assert b'"GET / HTTP/1.1" 200 -' in logs[-1]

  finally:
    container.stop()
    container.delete()
```

#### 测试设置

这个脚本首先设置 `conu` 使用 Docker 作为后端来运行容器。然后它设置容器镜像以使用你在本教程第一部分中构建的 flaskapp\_container。

下一步是配置运行容器所需的选项。在此示例中，Flask 应用在端口5000上提供内容。于是你需要暴露此端口并将其映射到主机上的同一端口。

最后，用这个脚本启动容器，现在可以测试了。

#### 测试方法

在测试容器之前，检查容器是否正在运行并准备就绪。示范脚本使用 `container.is_running` 和 `container.wait_for_port`。这些方法可确保容器正在运行，并且服务在预设端口上可用。

`container.http_request` 是 [request](http://docs.python-requests.org/en/master/) 库的包装器，可以方便地在测试期间发送 HTTP 请求。这个方法返回[requests.Responseobject](http://docs.python-requests.org/en/master/api/#requests.Response)，因此可以轻松地访问响应的内容以进行测试。

`conu` 还可以访问容器日志。又一次，这在测试期间非常有用。在上面的示例中，`container.logs` 方法返回容器日志。你可以使用它们断言打印了特定日志，或者，例如在测试期间没有异常被引发。

`conu` 提供了许多与容器接合的有用方法。[文档](https://conu.readthedocs.io/en/latest/index.html)中提供了完整的 API 列表。你还可以参考 [GitHub](https://github.com/user-cont/conu/tree/master/docs/source/examples) 上提供的示例。

运行本教程所需的所有代码和文件也可以在 [GitHub](https://github.com/cverna/container_test_script) 上获得。 对于想要进一步采用这个例子的读者，你可以看看使用 [pytest](https://docs.pytest.org/en/latest/) 来运行测试并构建一个容器测试套件。

---

via: <https://fedoramagazine.org/test-containers-python-conu/>

作者：[Clément Verna](https://fedoramagazine.org/author/cverna/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[GraveAccent](https://github.com/GraveAccent) 校对：[wxy](https://github.com/wxy)

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


Greg Kroah-Hartman 解释内核社区是如何使 Linux 安全的

# Greg Kroah-Hartman 解释内核社区是如何使 Linux 安全的

>
> 内核维护者 Greg Kroah-Hartman 谈论内核社区如何保护 Linux 不遭受损害。
>
>
>

由于 Linux 使用量持续扩大，内核社区去提高这个世界上使用最广泛的技术 —— Linux 内核的安全性的重要性越来越高。安全不仅对企业客户很重要，它对消费者也很重要，因为 80% 的移动设备都使用了 Linux。在本文中，Linux 内核维护者 Greg Kroah-Hartman 带我们了解内核社区如何应对威胁。

### bug 不可避免

*Greg Kroah-Hartman [Linux 基金会](https://www.linux.com/licenses/category/linux-foundation)*

正如 Linus Torvalds 曾经说过的，大多数安全问题都是 bug 造成的，而 bug 又是软件开发过程的一部分。是软件就有 bug。

Kroah-Hartman 说：“就算是 bug，我们也不知道它是安全的 bug 还是不安全的 bug。我修复的一个著名 bug，在三年后才被 Red Hat 认定为安全漏洞“。

在消除 bug 方面，内核社区没有太多的办法，只能做更多的测试来寻找 bug。内核社区现在已经有了自己的安全团队，它们是由熟悉内核核心的内核开发者组成。

Kroah-Hartman 说：”当我们收到一个报告时，我们就让参与这个领域的核心开发者去修复它。在一些情况下，他们可能是同一个人，让他们进入安全团队可以更快地解决问题“。但他也强调，内核所有部分的开发者都必须清楚地了解这些问题，因为内核是一个可信环境，它必须被保护起来。

Kroah-Hartman 说：”一旦我们修复了它，我们就将它放到我们的栈分析规则中，以便于以后不再重新出现这个 bug。“

除修复 bug 之外，内核社区也不断加固内核。Kroah-Hartman 说：“我们意识到，我们需要一些主动的缓减措施，因此我们需要加固内核。”

Kees Cook 和其他一些人付出了巨大的努力，带来了一直在内核之外的加固特性，并将它们合并或适配到内核中。在每个内核发行后，Cook 都对所有新的加固特性做一个总结。但是只加固内核是不够的，供应商们必须要启用这些新特性来让它们充分发挥作用，但他们并没有这么做。

Kroah-Hartman [每周发布一个稳定版内核](https://www.kernel.org/category/releases.html)，而为了长期的支持，公司们只从中挑选一个，以便于设备制造商能够利用它。但是，Kroah-Hartman 注意到，除了 Google Pixel 之外，大多数 Android 手机并不包含这些额外的安全加固特性，这就意味着，所有的这些手机都是有漏洞的。他说：“人们应该去启用这些加固特性”。

Kroah-Hartman 说：“我购买了基于 Linux 内核 4.4 的所有旗舰级手机，去查看它们中哪些确实升级了新特性。结果我发现只有一家公司升级了它们的内核。……我在整个供应链中努力去解决这个问题，因为这是一个很棘手的问题。它涉及许多不同的组织 —— SoC 制造商、运营商等等。关键点是，需要他们把我们辛辛苦苦设计的内核去推送给大家。”

好消息是，与消费电子产品不一样，像 Red Hat 和 SUSE 这样的大供应商，在企业环境中持续对内核进行更新。使用容器、pod 和虚拟化的现代系统做到这一点更容易了。无需停机就可以毫不费力地更新和重启。事实上，现在来保证系统安全相比过去容易多了。

### Meltdown 和 Spectre

没有任何一个关于安全的讨论能够避免提及 Meltdown 和 Spectre 缺陷。内核社区一直致力于修改新发现的和已查明的安全漏洞。不管怎样，Intel 已经因为这些事情改变了它们的策略。

Kroah-Hartman 说：“他们已经重新研究如何处理安全 bug，以及如何与社区合作，因为他们知道他们做错了。内核已经修复了几乎所有大的 Spectre 问题，但是还有一些小问题仍在处理中”。

好消息是，这些 Intel 漏洞使得内核社区正在变得更好。Kroah-Hartman 说：“我们需要做更多的测试。对于最新一轮的安全补丁，在它们被发布之前，我们自己花了四个月时间来测试它们，因为我们要防止这个安全问题在全世界扩散。而一旦这些漏洞在真实的世界中被利用，将让我们认识到我们所依赖的基础设施是多么的脆弱，我们多年来一直在做这种测试，这确保了其它人不会遭到这些 bug 的伤害。所以说，Intel 的这些漏洞在某种程度上让内核社区变得更好了”。

对安全的日渐关注也为那些有才华的人创造了更多的工作机会。由于安全是个极具吸引力的领域，那些希望在内核空间中有所建树的人，安全将是他们一个很好的起点。

Kroah-Hartman 说：“如果有人想从事这方面的工作，我们有大量的公司愿意雇佣他们。我知道一些开始去修复 bug 的人已经被他们雇佣了。”

你可以在下面链接的视频上查看更多的内容：

---

via: <https://www.linux.com/blog/2018/10/greg-kroah-hartman-explains-how-kernel-community-securing-linux-0>

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

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


如何在 Linux 上安装设备驱动程序

Summary: 学习 Linux 设备驱动如何工作，并知道如何使用它们。

lspci；中间有错误

lspci；中间有错误

maybe some mistake will be detect

来自111.18.93.29的 Chrome 95.0|GNU/Linux 用户

lspci

学习 Linux 设备驱动如何工作，并知道如何使用它们。

# 如何在 Linux 上安装设备驱动程序

>
> 学习 Linux 设备驱动如何工作，并知道如何使用它们。
>
>
>

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

对于一个熟悉 Windows 或者 MacOS 的人，想要切换到 Linux，它们都会面临一个艰巨的问题就是怎么安装和配置设备驱动。这是可以理解的，因为 Windows 和 MacOS 都有一套机制把这个过程做得非常的友好。比如说，当你插入一个新的硬件设备， Windows 能够自动检测并会弹出一个窗口询问你是否要继续驱动程序的安装。你也可以从网络上下载驱动程序，仅仅需要双击解压或者是通过设备管理器导入驱动程序即可。

而这在 Linux 操作系统上并非这么简单。第一个原因是， Linux 是一个开源的操作系统，所以有 [数百种 Linux 发行版的变体](https://en.wikipedia.org/wiki/List_of_Linux_distributions)。也就是说不可能做一个指南来适应所有的 Linux 发行版。因为每种 Linux 安装驱动程序的过程都有差异。

第二，大多数默认的 Linux 驱动程序也都是开源的，并被集成到了系统中，这使得安装一些并未包含的驱动程序变得非常复杂，即使已经可以检测大多数的硬件设备。第三，不同发行版的许可也有差异。例如，[Fedora 禁止事项](https://fedoraproject.org/wiki/Forbidden_items?rd=ForbiddenItems) 禁止包含专有的、受法律保护，或者是违反美国法律的驱动程序。而 Ubuntu 则让用户[避免使用受法律保护或闭源的硬件设备](https://www.ubuntu.com/licensing)。

为了更好的学习 Linux 驱动程序是如何工作的，我建议阅读 《Linux 设备驱动程序》一书中的 [设备驱动程序简介](https://www.xml.com/ldd/chapter/book/ch01.html)。

### 两种方式来寻找驱动程序

#### 1、 用户界面

如果是一个刚从 Windows 或 MacOS 转过来的 Linux 新手，那你会很高兴知道 Linux 也提供了一个通过向导式的程序来查看驱动程序是否可用的方法。 Ubuntu 提供了一个 [附加驱动程序](https://askubuntu.com/questions/47506/how-do-i-install-additional-drivers) 选项。其它的 Linux 发行版也提供了帮助程序，像 [GNOME 的包管理器](https://help.gnome.org/users/gnome-packagekit/stable/add-remove.html.en)，你可以使用它来检查驱动程序是否可用。

#### 2、 命令行

如果你通过漂亮的用户界面没有找到驱动程序，那又该怎么办呢？或许你只能通过没有任何图形界面的 shell？甚至你可以使用控制台来展现你的技能。你有两个选择：

1. **通过一个仓库**

这和 MacOS 中的 [homebrew](https://brew.sh/) 命令行很像。通过使用 `yum`、 `dnf`、`apt-get` 等等。你基本可以通过添加仓库，并更新包缓存。
2. **下载、编译，然后自己构建**

这通常包括直接从网络，或通过 `wget` 命令下载源码包，然后运行配置和编译、安装。这超出了本文的范围，但是你可以在网络上找到很多在线指南，如果你选择的是这条路的话。

### 检查是否已经安装了这个驱动程序

在进一步学习安装 Linux 驱动程序之前，让我们来学习几条命令，用来检测驱动程序是否已经在你的系统上可用。

[lspci](https://en.wikipedia.org/wiki/Lspci) 命令显示了系统上所有 PCI 总线和设备驱动程序的详细信息。

```
$ lscpci
```

或者使用 `grep`：

```
$ lscpci | grep SOME_DRIVER_KEYWORD
```

例如，你可以使用 `lspci | grep SAMSUNG` 命令，如果你想知道是否安装过三星的驱动。

[dmesg](https://en.wikipedia.org/wiki/Dmesg) 命令显示了所有内核识别的驱动程序。

```
$ dmesg
```

或配合 `grep` 使用：

```
$ dmesg | grep SOME_DRIVER_KEYWORD
```

任何识别到的驱动程序都会显示在结果中。

如果通过 `dmesg` 或者 `lscpi` 命令没有识别到任何驱动程序，尝试下这两个命令，看看驱动程序至少是否加载到硬盘。

```
$ /sbin/lsmod
```

和

```
$ find /lib/modules
```

技巧：和 `lspci` 或 `dmesg` 一样，通过在上面的命令后面加上 `| grep` 来过滤结果。

如果一个驱动程序已经被识别到了，但是通过 `lscpi` 或 `dmesg` 并没有找到，这意味着驱动程序已经存在于硬盘上，但是并没有加载到内核中，这种情况，你可以通过 `modprobe` 命令来加载这个模块。

```
$ sudo modprobe MODULE_NAME
```

使用 `sudo` 来运行这个命令，因为这个模块要使用 root 权限来安装。

### 添加仓库并安装

可以通过 `yum`、`dnf` 和 `apt-get` 几种不同的方式来添加一个仓库；一个个介绍完它们并不在本文的范围。简单一点来说，这个示例将会使用 `apt-get` ，但是这个命令和其它的几个都是很类似的。

#### 1、删除存在的仓库，如果它存在

```
$ sudo apt-get purge NAME_OF_DRIVER*
```

其中 `NAME_OF_DRIVER` 是你的驱动程序的可能的名称。你还可以将模式匹配加到正则表达式中来进一步过滤。

#### 2、将仓库加入到仓库表中，这应该在驱动程序指南中有指定

```
$ sudo add-apt-repository REPOLIST_OF_DRIVER
```

其中 `REPOLIST_OF_DRIVER` 应该从驱动文档中有指定（例如：`epel-list`）。

#### 3、更新仓库列表

```
$ sudo apt-get update
```

#### 4、安装驱动程序

```
$ sudo apt-get install NAME_OF_DRIVER
```

#### 5、检查安装状态

像上面说的一样，通过 `lscpi` 命令来检查驱动程序是否已经安装成功。

---

via: <https://opensource.com/article/18/11/how-install-device-driver-linux>

作者：[Bryant Son](https://opensource.com/users/brson) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Jamskr](https://github.com/Jamskr) 校对：[wxy](https://github.com/wxy)

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


Linux 中国翻译组成立项目管理委员会，向正规化管理迈出一步

加入开源也有一段时间了，第一次认识到开源项目管理协同上的重要性，很赞

这是很有必要的一步

# Linux 中国翻译组成立项目管理委员会，向正规化管理迈出一步

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

[Linux 中国翻译组（LCTT）](https://linux.cn/lctt/)成立[已逾五年](/article-9999-1.html)了，这些年来，我们在不断地改进我们的流程、管理。鉴于当前的人员规模的增大和事务的繁多，我们认为需要将管理水平更上一个台阶。因此，我们在原有的核心成员、译者两层的组织结构的基础上，吸收其它开源组织的管理经验，成立了三层结构的项目管理结构。

新的管理层级为：

* **译者**：加入 LCTT 翻译活动中，并有实际贡献者即为译者。
	+ 预备译者：加入 LCTT ，但尚未进行实际贡献者，视为预备译者。
* **核心成员**：做出重大贡献者列入核心成员。可执行日常管理任务。
	+ 荣誉成员：长期休眠的核心成员列入荣誉成员。荣誉成员被收回写入权限，但保留投票权和历史荣誉。
* **管理委员**：由核心成员中选出，对 LCTT 事务进行表决和决策，并负责日常管理任务的最终执行。
	+ 主席：由管理委员中选出，由现任管理委员进行选举。

管理委员组成管理委员会（PMC），对 LCTT 的发展事务进行决策和执行。主要负责：

* 制定和优化贡献流程和制度
* 提名和投票 LCTT 核心成员、荣誉成员和主席
* 成员管理
* 兜底负责核心成员的管理事务

而核心译者作为 LCTT 的中坚力量，除了参与翻译活动之外，还具有如下职权：

* 流程管理：PR 审核和合并
* 文档管理：Wiki 维护
* 引导新人：担任导师
* 人员选举：参选和选举管理委员

PMC 组织架构的初次建立，由原有管理者在小范围征询意见后确定。首次 PMC 成员如下：

* 管理委员：wxy、bestony、lujun9972、oska874、pityonline、geekpi、qhwdw
* 主席：wxy

管理委员会经过会议讨论，已经对一些事务形成了统一的意见，如：

* 管理章程
* Wiki 重建
* 文章的元数据结构
* 建立术语表
* 年末纪念品定制

我们希望可以通过将开源志愿者组织的管理正规化，从而提升社区的活力和可持续发展。


在 Linux 上自定义 bash 命令提示符

# 在 Linux 上自定义 bash 命令提示符

众所周知，**bash**（the **B**ourne-**A**gain **Sh**ell）是目前绝大多数 Linux 发行版使用的默认 shell。本文将会介绍如何通过添加颜色和样式来自定义 bash 命令提示符的显示。尽管很多插件或工具都可以很轻易地满足这一需求，但我们也可以不使用插件和工具，自己手动自定义一些基本的显示方式，例如添加或者修改某些元素、更改前景色、更改背景色等等。

### 在 Linux 中自定义 bash 命令提示符

在 bash 中，我们可以通过更改 `$PS1` 环境变量的值来自定义 bash 命令提示符。

一般情况下，bash 命令提示符会是以下这样的形式：

在上图这种默认显示形式当中，“sk” 是我的用户名，而 “ubuntuserver” 是我的主机名。

只要插入一些以反斜杠开头的特殊转义字符串，就可以按照你的喜好修改命令提示符了。下面我来举几个例子。

在开始之前，我强烈建议你预先备份 `~/.bashrc` 文件。

```
$ cp ~/.bashrc ~/.bashrc.bak
```

#### 更改 bash 命令提示符中的 username@hostname 部分

如上所示，bash 命令提示符一般都带有 “username@hostname” 部分，这个部分是可以修改的。

只需要编辑 `~/.bashrc` 文件：

```
$ vi ~/.bashrc
```

在文件的最后添加一行：

```
PS1="ostechnix> "
```

将上面的 “ostechnix” 替换为任意一个你想使用的单词，然后按 `ESC` 并输入 `:wq` 保存、退出文件。

执行以下命令使刚才的修改生效：

```
$ source ~/.bashrc
```

你就可以看见 bash 命令提示符中出现刚才添加的 “ostechnix” 了。

再来看看另一个例子，比如将 “username@hostname” 替换为 “Hello@welcome>”。

同样是像刚才那样修改 `~/.bashrc` 文件。

```
export PS1="Hello@welcome> "
```

然后执行 `source ~/.bashrc` 让修改结果立即生效。

以下是我在 Ubuntu 18.04 LTS 上修改后的效果。

#### 仅显示用户名

如果需要仅显示用户名，只需要在 `~/.bashrc` 文件中加入以下这一行。

```
export PS1="\u "
```

这里的 `\u` 就是一个转义字符串。

下面提供了一些可以添加到 `$PS1` 环境变量中的用以改变 bash 命令提示符样式的转义字符串。每次修改之后，都需要执行 `source ~/.bashrc` 命令才能立即生效。

#### 显示用户名和主机名

```
export PS1="\u\h "
```

命令提示符会这样显示：

```
skubuntuserver
```

#### 显示用户名和完全限定域名

```
export PS1="\u\H "
```

#### 在用户名和主机名之间显示其它字符

如果你还需要在用户名和主机名之间显示其它字符（例如 `@`），可以使用以下格式：

```
export PS1="\u@\h "
```

命令提示符会这样显示：

```
sk@ubuntuserver
```

#### 显示用户名、主机名，并在末尾添加 $ 符号

```
export PS1="\u@\h\\$ "
```

#### 综合以上两种显示方式

```
export PS1="\u@\h> "
```

命令提示符最终会这样显示：

```
sk@ubuntuserver>
```

相似地，还可以添加其它特殊字符，例如冒号、分号、星号、下划线、空格等等。

#### 显示用户名、主机名、shell 名称

```
export PS1="\u@\h>\s "
```

#### 显示用户名、主机名、shell 名称以及 shell 版本

```
export PS1="\u@\h>\s\v "
```

bash 命令提示符显示样式：

#### 显示用户名、主机名、当前目录

```
export PS1="\u@\h\w "
```

如果当前目录是 `$HOME` ，会以一个波浪线（`~`）显示。

#### 在 bash 命令提示符中显示日期

除了用户名和主机名，如果还想在 bash 命令提示符中显示日期，可以在 `~/.bashrc` 文件中添加以下内容：

```
export PS1="\u@\h>\d "
```

#### 在 bash 命令提示符中显示日期及 12 小时制时间

```
export PS1="\u@\h>\d\@ "
```

#### 显示日期及 hh:mm:ss 格式时间

```
export PS1="\u@\h>\d\T "
```

#### 显示日期及 24 小时制时间

```
export PS1="\u@\h>\d\A "
```

#### 显示日期及 24 小时制 hh:mm:ss 格式时间

```
export PS1="\u@\h>\d\t "
```

以上是一些常见的可以改变 bash 命令提示符的转义字符串。除此以外的其它转义字符串，可以在 bash 的 man 手册 PROMPTING 章节中查阅。

你也可以随时执行以下命令查看当前的命令提示符样式。

```
$ echo $PS1
```

#### 在 bash 命令提示符中去掉 username@hostname 部分

如果我不想做任何调整，直接把 username@hostname 部分整个去掉可以吗？答案是肯定的。

如果你是一个技术方面的博主，你有可能会需要在网站或者博客中上传自己的 Linux 终端截图。或许你的用户名和主机名太拉风、太另类，不想让别人看到，在这种情况下，你就需要隐藏命令提示符中的 “username@hostname” 部分。

如果你不想暴露自己的用户名和主机名，只需要按照以下步骤操作。

编辑 `~/.bashrc` 文件：

```
$ vi ~/.bashrc
```

在文件末尾添加这一行：

```
PS1="\W> "
```

输入 `:wq` 保存并关闭文件。

执行以下命令让修改立即生效。

```
$ source ~/.bashrc
```

现在看一下你的终端，“username@hostname” 部分已经消失了，只保留了一个 `~>` 标记。

如果你想要尽可能简单的操作，又不想弄乱你的 `~/.bashrc` 文件，最好的办法就是在系统中创建另一个用户（例如 “user@example”、“admin@demo”）。用带有这样的命令提示符的用户去截图或者录屏，就不需要顾虑自己的用户名或主机名被别人看见了。

**警告：**在某些情况下，这种做法并不推荐。例如像 zsh 这种 shell 会继承当前 shell 的设置，这个时候可能会出现一些意想不到的问题。这个技巧只用于隐藏命令提示符中的 “username@hostname” 部分，仅此而已，如果把这个技巧挪作他用，也可能会出现异常。

### 为 bash 命令提示符着色

目前我们也只是变更了 bash 命令提示符中的内容，下面介绍一下如何对命令提示符进行着色。

通过向 `~/.bashrc` 文件写入一些配置，可以修改 bash 命令提示符的前景色（也就是文本的颜色）和背景色。

例如，下面这一行配置可以令某些文本的颜色变成红色：

```
export PS1="\u@\[\e[31m\]\h\[\e[m\] "
```

添加配置后，执行 `source ~/.bashrc` 立即生效。

你的 bash 命令提示符就会变成这样：

类似地，可以用这样的配置来改变背景色：

```
export PS1="\u@\[\e[31;46m\]\h\[\e[m\] "
```

### 添加 emoji

大家都喜欢 emoji。还可以按照以下配置把 emoji 插入到命令提示符中。

```
PS1="\W ♤ >"
```

需要注意的是，emoji 的显示取决于使用的字体，因此某些终端可能会无法正常显示 emoji，取而代之的是一些乱码或者单色表情符号。

### 自定义 bash 命令提示符有点难，有更简单的方法吗？

如果你是一个新手，编辑 `$PS1` 环境变量的过程可能会有些困难，因为命令提示符中的大量转义字符串可能会让你有点晕头转向。但不要担心，有一个在线的 bash `$PS1` 生成器可以帮助你轻松生成各种 `$PS1` 环境变量值。

就是这个[网站](http://ezprompt.net/)：

[](http://ezprompt.net/)

只需要直接选择你想要的 bash 命令提示符样式，添加颜色、设计排序，然后就完成了。你可以预览输出，并将配置代码复制粘贴到 `~/.bashrc` 文件中。就这么简单。顺便一提，本文中大部分的示例都是通过这个网站制作的。

### 我把我的 ~/.bashrc 文件弄乱了，该如何恢复？

正如我在上面提到的，强烈建议在更改 `~/.bashrc` 文件前做好备份（在更改其它重要的配置文件之前也一定要记得备份）。这样一旦出现任何问题，你都可以很方便地恢复到更改之前的配置状态。当然，如果你忘记了备份，还可以按照下面这篇文章中介绍的方法恢复为默认配置。

* [如何将 `~/.bashrc` 文件恢复到默认配置](https://www.ostechnix.com/restore-bashrc-file-default-settings-ubuntu/)

这篇文章是基于 ubuntu 的，但也适用于其它的 Linux 发行版。不过事先声明，这篇文章的方法会将 `~/.bashrc` 文件恢复到系统最初时的状态，你对这个文件做过的任何修改都将丢失。

感谢阅读！

---

via: <https://www.ostechnix.com/hide-modify-usernamelocalhost-part-terminal/>

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

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


如何在 Anbox 上安装 Google Play 商店及启用 ARM 支持

Summary: Anbox （Anroid in a Box）是一个自由开源工具，它允许你在 Linux 上运行 Android 应用程序。默认情况下，Anbox 没有 Google Play 商店或 ARM 应用支持。

# 如何在 Anbox 上安装 Google Play 商店及启用 ARM 支持

[Anbox](https://anbox.io/) （Anroid in a Box）是一个自由开源工具，它允许你在 Linux 上运行 Android 应用程序。它的工作原理是在 LXC 容器中运行 Android 运行时环境，重新创建 Android 的目录结构作为可挂载的 loop 镜像，同时使用本机 Linux 内核来执行应用。

据其网站所述，它的主要特性是安全性、性能、集成和趋同（不同外形尺寸缩放）。

使用 Anbox，每个 Android 应用或游戏就像系统应用一样都在一个单独的窗口中启动，它们的行为或多或少类似于常规窗口，显示在启动器中，可以平铺等等。

默认情况下，Anbox 没有 Google Play 商店或 ARM 应用支持。要安装应用，你必须下载每个应用的 APK 并使用 `adb` 手动安装。此外，默认情况下不能使用 Anbox 安装 ARM 应用或游戏 —— 尝试安装 ARM 应用会显示以下错误：

```
Failed to install PACKAGE.NAME.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]

```

你可以在 Anbox 中手动设置 Google Play 商店和 ARM 应用支持（通过 libhoudini），但这是一个非常复杂的过程。为了更容易地在 Anbox 上安装 Google Play 商店和 Google Play 服务，并让它支持 ARM 应用程序和游戏（使用 libhoudini），[geeks-r-us.de](https://geeks-r-us.de/2017/08/26/android-apps-auf-dem-linux-desktop/)（文章是德语）上的人创建了一个自动执行这些任务的脚本。

在使用之前，我想明确指出，即使在集成 libhoudini 来支持 ARM 后，也并非所有 Android 应用和游戏都能在 Anbox 中运行。某些 Android 应用和游戏可能根本不会出现在 Google Play 商店中，而一些应用和游戏可能可以安装但无法使用。此外，某些应用可能无法使用某些功能。

### 安装 Google Play 商店并在 Anbox 上启用 ARM 应用/游戏支持

如果你的 Linux 桌面上尚未安装 Anbox，这些说明显然不起作用。如果你还没有，请按照[此处](https://github.com/anbox/anbox/blob/master/docs/install.md)的安装说明安装 Anbox。此外，请确保在安装 Anbox 之后，使用此脚本之前至少运行一次 `anbox.appmgr`，以避免遇到问题。另外，确保在执行下面的脚本时 Anbox 没有运行（我怀疑这是导致评论中提到的这个[问题](https://www.linuxuprising.com/2018/07/anbox-how-to-install-google-play-store.html?showComment=1533506821283#c4415289781078860898)的原因）。

1、 安装所需的依赖项（wget、lzip、unzip 和 squashfs-tools）。

在 Debian、Ubuntu 或 Linux Mint 中，使用此命令安装所需的依赖项：

```
sudo apt install wget lzip unzip squashfs-tools
```

2、 下载并运行脚本，在 Anbox 上自动下载并安装 Google Play 商店（和 Google Play 服务）和 libhoudini（用于 ARM 应用/游戏支持）。

**警告：永远不要在不知道它做什么的情况下运行不是你写的脚本。在运行此脚本之前，请查看其[代码](https://github.com/geeks-r-us/anbox-playstore-installer/blob/master/install-playstore.sh)。**

要下载脚本，使其可执行并在 Linux 桌面上运行，请在终端中使用以下命令：

```
wget https://raw.githubusercontent.com/geeks-r-us/anbox-playstore-installer/master/install-playstore.sh
chmod +x install-playstore.sh
sudo ./install-playstore.sh
```

3、要让 Google Play 商店在 Anbox 中运行，你需要启用 Google Play 商店和 Google Play 服务的所有权限

为此，请运行Anbox：

```
anbox.appmgr
```

然后进入“设置 > 应用 > Google Play 服务 > 权限”并启用所有可用权限。对 Google Play 商店也一样！

你现在应该可以使用 Google 帐户登录 Google Play 商店了。

如果未启用 Google Play 商店和 Google Play 服务的所有权限，你可能会在尝试登录 Google 帐户时可能会遇到问题，并显示以下错误消息：“Couldn’t sign in. There was a problem communicating with Google servers. Try again later“，如你在下面的截图中看到的那样：

登录后，你可以停用部分 Google Play 商店/Google Play 服务权限。

**如果你在 Anbox 上登录 Google 帐户时遇到一些连接问题**，请确保 `anbox-bride.sh` 正在运行：

启动它：

```
sudo /snap/anbox/current/bin/anbox-bridge.sh start
```

重启它：

```
sudo /snap/anbox/current/bin/anbox-bridge.sh restart
```

根据[此用户](https://github.com/anbox/anbox/issues/118#issuecomment-295270113)的说法，如果 Anbox 仍然存在连接问题，你可能还需要安装 dnsmasq 包。但是在我的 Ubuntu 18.04 桌面上不需要这样做。

---

via: <https://www.linuxuprising.com/2018/07/anbox-how-to-install-google-play-store.html>

作者：[Logix](https://plus.google.com/118280394805678839070) 选题：[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/) 荣誉推出


2018 重温 Unix 哲学

Summary: 在现代微服务环境中，构建小型、单一的应用程序的旧策略又再一次流行了起来。

在现代微服务环境中，构建小型、单一的应用程序的旧策略又再一次流行了起来。

# 2018 重温 Unix 哲学

>
> 在现代微服务环境中，构建小型、单一的应用程序的旧策略又再一次流行了起来。
>
>
>

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

1984 年，Rob Pike 和 Brian W. Kernighan 在 AT&T 贝尔实验室技术期刊上发表了名为 “[Unix 环境编程](http://harmful.cat-v.org/cat-v/)” 的文章，其中他们使用 BSD 的 `cat -v` 例子来认证 Unix 哲学。简而言之，Unix 哲学是：构建小型、单一的应用程序 —— 不管用什么语言 —— 只做一件小而美的事情，用 `stdin` / `stdout` 进行通信，并通过管道进行连接。

听起来是不是有点耳熟？

是的，我也这么认为。这就是 James Lewis 和 Martin Fowler 给出的 [微服务的定义](https://martinfowler.com/articles/microservices.html) 。

>
> 简单来说，微服务架构的风格是将单个 应用程序开发为一套小型服务的方法，每个服务都运行在它的进程中，并用轻量级机制进行通信，通常是 HTTP 资源 API 。
>
>
>

虽然一个 \*nix 程序或者是一个微服务本身可能非常局限甚至不是很有用，但是当这些独立工作的单元组合在一起的时候就显示出了它们真正的好处和强大。

### \*nix程序 vs 微服务

下面的表格对比了 \*nix 环境中的程序（例如 `cat` 或 `lsof`）与微服务环境中的程序。

|  | \*nix 程序 | 微服务 |
| --- | --- | --- |
| 执行单元 | 程序使用 `stdin`/`stdout` | 使用 HTTP 或 gRPC API |
| 数据流 | 管道 | ？ |
| 可配置和参数化 | 命令行参数、环境变量和配置文件 | JSON/YAML 文档 |
| 发现 | 包管理器、man、make | DNS、环境变量、OpenAPI |

让我们详细的看看每一行。

#### 执行单元

\*nix 系统（如 Linux）中的执行单元是一个可执行的文件（二进制或者是脚本），理想情况下，它们从 `stdin` 读取输入并将输出写入 `stdout`。而微服务通过暴露一个或多个通信接口来提供服务，比如 HTTP 和 gRPC API。在这两种情况下，你都会发现无状态示例（本质上是纯函数行为）和有状态示例，除了输入之外，还有一些内部（持久）状态决定发生了什么。

#### 数据流

传统的，\*nix 程序能够通过管道进行通信。换句话说，我们要感谢 [Doug McIlroy](https://en.wikipedia.org/wiki/Douglas_McIlroy)，你不需要创建临时文件来传递，而可以在每个进程之间处理无穷无尽的数据流。据我所知，除了我在 [2017 年做的基于 Apache Kafka 小实验](https://speakerdeck.com/mhausenblas/distributed-named-pipes-and-other-inter-services-communication)，没有什么能比得上管道化的微服务了。

#### 可配置和参数化

你是如何配置程序或者服务的，无论是永久性的服务还是即时的服务？是的，在 \*nix 系统上，你通常有三种方法：命令行参数、环境变量，或全面的配置文件。在微服务架构中，典型的做法是用 YAML（或者甚至是 JSON）文档，定制好一个服务的布局和配置以及依赖的组件和通信、存储和运行时配置。例如 [Kubernetes 资源定义](http://kubernetesbyexample.com/)、[Nomad 工作规范](https://www.nomadproject.io/docs/job-specification/index.html) 或 [Docker 编排](https://docs.docker.com/compose/overview/) 文档。这些可能参数化也可能不参数化；也就是说，除非你知道一些模板语言，像 Kubernetes 中的 [Helm](https://helm.sh/)，否则你会发现你使用了很多 `sed -i` 这样的命令。

#### 发现

你怎么知道有哪些程序和服务可用，以及如何使用它们？在 \*nix 系统中通常都有一个包管理器和一个很好用的 man 页面；使用它们，应该能够回答你所有的问题。在微服务的设置中，在寻找一个服务的时候会相对更自动化一些。除了像 [Airbnb 的 SmartStack](https://github.com/airbnb/smartstack-cookbook) 或 [Netflix 的 Eureka](https://github.com/Netflix/eureka) 等可以定制以外，通常还有基于环境变量或基于 DNS 的[方法](https://kubernetes.io/docs/concepts/services-networking/service/#discovering-services)，允许您动态的发现服务。同样重要的是，事实上 [OpenAPI](https://www.openapis.org/) 为 HTTP API 提供了一套标准文档和设计模式，[gRPC](https://grpc.io/) 为一些耦合性强的高性能项目也做了同样的事情。最后非常重要的一点是，考虑到开发者经验（DX），应该从写一份好的 [Makefile](https://suva.sh/posts/well-documented-makefiles/) 开始，并以编写符合 [风格](https://www.linux.com/news/improve-your-writing-gnu-style-checkers) 的文档结束。

### 优点和缺点

\*nix 系统和微服务都提供了许多挑战和机遇。

#### 模块性

要设计一个简洁、有清晰的目的，并且能够很好地和其它模块配合的某个东西是很困难的。甚至是在不同版本中实现并引入相应的异常处理流程都很困难的。在微服务中，这意味着重试逻辑和超时机制，或者将这些功能外包到<ruby> 服务网格 <rt>  service mesh </rt></ruby>是不是一个更好的选择呢？这确实比较难，可如果你做好了，那它的可重用性是巨大的。

#### 可观测性

在一个<ruby> 独石 <rt>  monolith </rt></ruby>（2018 年）或是一个试图做任何事情的大型程序（1984 年），当情况恶化的时候，应当能够直接的找到问题的根源。但是在一个

```
yes | tr \\n x | head -c 450m | grep n
```

或者在一个微服务设置中请求一个路径，例如，涉及 20 个服务，你怎么弄清楚是哪个服务的问题？幸运的是，我们有很多标准，特别是 [OpenCensus](https://opencensus.io/) 和 [OpenTracing](https://opentracing.io/)。如果您希望转向微服务，可预测性仍然可能是最大的问题。

#### 全局状态

对于 \*nix 程序来说可能不是一个大问题，但在微服务中，全局状态仍然是一个需要讨论的问题。也就是说，如何确保有效的管理本地化（持久性）的状态以及尽可能在少做变更的情况下使全局保持一致。

### 总结一下

最后，问题仍然是：你是否在使用合适的工具来完成特定的工作？也就是说，以同样的方式实现一个特定的 \*nix 程序在某些时候或者阶段会是一个更好的选择，它是可能在你的组织或工作过程中的一个[最好的选择](https://robertnorthard.com/devops-days-well-architected-monoliths-are-okay/)。无论如何，我希望这篇文章可以让你看到 Unix 哲学和微服务之间许多强有力的相似之处。也许我们可以从前者那里学到一些东西使后者受益。

---

via: <https://opensource.com/article/18/11/revisiting-unix-philosophy-2018>

作者：[Michael Hausenblas](https://opensource.com/users/mhausenblas) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Jamskr](https://github.com/Jamskr) 校对：[wxy](https://github.com/wxy)

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


举例说明 alias 和 unalias 命令

# 举例说明 alias 和 unalias 命令

如果不是一个命令行重度用户的话，过了一段时间之后，你就可能已经忘记了这些复杂且冗长的 Linux 命令了。当然，有很多方法可以让你 [回想起遗忘的命令](https://www.ostechnix.com/easily-recall-forgotten-linux-commands/)。你可以简单的 [保存常用的命令](https://www.ostechnix.com/save-commands-terminal-use-demand/) 然后按需使用。也可以在终端里 [标记重要的命令](https://www.ostechnix.com/bookmark-linux-commands-easier-repeated-invocation/)，然后在任何时候你想要的时间使用它们。而且，Linux 有一个内建命令 `history` 可以帮助你记忆这些命令。另外一个记住这些如此长的命令的简便方式就是为这些命令创建一个别名。你可以为任何经常重复调用的常用命令创建别名，而不仅仅是长命令。通过这种方法，你不必再过多地记忆这些命令。这篇文章中，我们将会在 Linux 环境下举例说明 `alias` 和 `unalias` 命令。

### alias 命令

`alias` 使用一个用户自定义的字符串来代替一个或者一串命令（包括多个选项、参数）。这个字符串可以是一个简单的名字或者缩写，不管这个命令原来多么复杂。`alias` 命令已经预装在 shell（包括 BASH、Csh、Ksh 和 Zsh 等） 当中。

`alias` 的通用语法是：

```
alias [alias-name[=string]...]
```

接下来看几个例子。

#### 列出别名

可能在你的系统中已经设置了一些别名。有些应用在你安装它们的时候可能已经自动创建了别名。要查看已经存在的别名，运行：

```
$ alias
```

或者，

```
$ alias -p
```

在我的 Arch Linux 系统中已经设置了下面这些别名。

```
alias betty='/home/sk/betty/main.rb'
alias ls='ls --color=auto'
alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'
alias update='newsbeuter -r && sudo pacman -Syu'
```

#### 创建一个新的别名

像我之前说的，你不必去记忆这些又臭又长的命令。你甚至不必一遍一遍的运行长命令。只需要为这些命令创建一个简单易懂的别名，然后在任何你想使用的时候运行这些别名就可以了。这种方式会让你爱上命令行。

```
$ du -h --max-depth=1 | sort -hr
```

这个命令将会查找当前工作目录下的各个子目录占用的磁盘大小，并按照从大到小的顺序进行排序。这个命令有点长。我们可以像下面这样轻易地为其创建一个 别名：

```
$ alias du='du -h --max-depth=1 | sort -hr'
```

这里的 `du` 就是这条命令的别名。这个别名可以被设置为任何名字，主要便于记忆和区别。

在创建一个别名的时候，使用单引号或者双引号都是可以的。这两种方法最后的结果没有任何区别。

现在你可以运行这个别名（例如我们这个例子中的 `du` ）。它和上面的原命令将会产生相同的结果。

这个别名仅限于当前 shell 会话中。一旦你退出了当前 shell 会话，别名也就失效了。为了让这些别名长久有效，你需要把它们添加到你 shell 的配置文件当中。

BASH，编辑 `~/.bashrc` 文件：

```
$ nano ~/.bashrc
```

一行添加一个别名：

保存并退出这个文件。然后运行以下命令更新修改：

```
$ source ~/.bashrc
```

现在，这些别名在所有会话中都可以永久使用了。

ZSH，你需要添加这些别名到 `~/.zshrc`文件中。Fish，跟上面的类似，添加这些别名到 `~/.config/fish/config.fish` 文件中。

#### 查看某个特定的命令别名

像我上面提到的，你可以使用 `alias` 命令列出你系统中所有的别名。如果你想查看跟给定的别名有关的命令，例如 `du`，只需要运行：

```
$ alias du
alias du='du -h --max-depth=1 | sort -hr'
```

像你看到的那样，上面的命令可以显示与单词 `du` 有关的命令。

关于 `alias` 命令更多的细节，参阅 man 手册页：

```
$ man alias
```

### unalias 命令

跟它的名字说的一样，`unalias` 命令可以很轻松地从你的系统当中移除别名。`unalias` 命令的通用语法是：

```
unalias <alias-name>
```

要移除命令的别名，像我们之前创建的 `du`，只需要运行：

```
$ unalias du
```

`unalias` 命令不仅会从当前会话中移除别名，也会从你的 shell 配置文件中永久地移除别名。

还有一种移除别名的方法，是创建具有相同名称的新别名。

要从当前会话中移除所有的别名，使用 `-a` 选项：

```
$ unalias -a
```

更多细节，参阅 man 手册页。

```
$ man unalias
```

如果你经常一遍又一遍的运行这些繁杂又冗长的命令，给它们创建别名可以节省你的时间。现在是你为常用命令创建别名的时候了。

这就是所有的内容了。希望可以帮到你。还有更多的干货即将到来，敬请期待！

祝近祺！

---

via: <https://www.ostechnix.com/the-alias-and-unalias-commands-explained-with-examples/>

作者：[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/) 荣誉推出


如何在终端中浏览 Stack Overflow

Summary: 你可以如你在 Google 搜索中那样直接用英语查询，然后它会使用 Google 和 Stackoverflow API 来搜索给定的查询。

# 如何在终端中浏览 Stack Overflow

前段时间，我们写了一篇关于 [SoCLI](https://www.ostechnix.com/search-browse-stack-overflow-website-commandline/) 的文章，它是一个从命令行搜索和浏览 Stack Overflow 网站的 python 脚本。今天，我们将讨论一个名为 “how2” 的类似工具。它是一个命令行程序，可以从终端浏览 Stack Overflow。你可以如你在 [Google 搜索](https://www.ostechnix.com/google-search-navigator-enhance-keyboard-navigation-in-google-search/)中那样直接用英语查询，然后它会使用 Google 和 Stackoverflow API 来搜索给定的查询。它是使用 NodeJS 编写的自由开源程序。

### 使用 how2 从终端浏览 Stack Overflow

由于 `how2` 是一个 NodeJS 包，我们可以使用 Npm 包管理器安装它。如果你尚未安装 Npm 和 NodeJS，请参考以下指南。

在安装 Npm 和 NodeJS 后，运行以下命令安装 how2。

```
$ npm install -g how2
```

现在让我们看下如何使用这个程序浏览 Stack Overflow。使用 `how2` 搜索 Stack Overflow 站点的典型用法是：

```
$ how2 <search-query>
```

例如，我将搜索如何创建 tgz 存档。

```
$ how2 create archive tgz
```

哎呀！我收到以下错误。

```
/home/sk/.nvm/versions/node/v9.11.1/lib/node_modules/how2/node_modules/devnull/transports/transport.js:59
Transport.prototype.__proto__ = EventEmitter.prototype;
 ^

 TypeError: Cannot read property 'prototype' of undefined
 at Object.<anonymous> (/home/sk/.nvm/versions/node/v9.11.1/lib/node_modules/how2/node_modules/devnull/transports/transport.js:59:46)
 at Module._compile (internal/modules/cjs/loader.js:654:30)
 at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
 at Module.load (internal/modules/cjs/loader.js:566:32)
 at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
 at Function.Module._load (internal/modules/cjs/loader.js:498:3)
 at Module.require (internal/modules/cjs/loader.js:598:17)
 at require (internal/modules/cjs/helpers.js:11:18)
 at Object.<anonymous> (/home/sk/.nvm/versions/node/v9.11.1/lib/node_modules/how2/node_modules/devnull/transports/stream.js:8:17)
 at Module._compile (internal/modules/cjs/loader.js:654:30)

```

我可能遇到了一个 bug。我希望它在未来版本中得到修复。但是，我在[这里](https://github.com/santinic/how2/issues/79)找到了一个临时方法。

要临时修复此错误，你需要使用以下命令编辑 `transport.js`：

```
$ vi /home/sk/.nvm/versions/node/v9.11.1/lib/node_modules/how2/node_modules/devnull/transports/transport.js
```

此文件的实际路径将显示在错误输出中。用你自己的文件路径替换上述文件路径。然后找到以下行：

```
var EventEmitter = process.EventEmitter;
```

并用以下行替换它：

```
var EventEmitter = require('events');
```

按 `ESC` 并输入 `:wq` 以保存并退出文件。

现在再次搜索查询。

```
$ how2 create archive tgz
```

这是我的 Ubuntu 系统的示例输出。

如果你要查找的答案未显示在上面的输出中，请按**空格键**键开始交互式搜索，你可以通过它查看 Stack Overflow 站点中的所有建议问题和答案。

使用向上/向下箭头在结果之间移动。得到正确的答案/问题后，点击空格键或回车键在终端中打开它。

要返回并退出，请按 `ESC`。

**搜索特定语言的答案**

如果你没有指定语言，它**默认为 Bash** unix 命令行，并立即为你提供最可能的答案。你还可以将结果缩小到特定语言，例如 perl、python、c、Java 等。

例如，使用 `-l` 标志仅搜索与 “Python” 语言相关的查询，如下所示。

```
$ how2 -l python linked list
```

[](http://www.ostechnix.com/wp-content/uploads/2018/04/stack-overflow-4.png)

要获得快速帮助，请输入：

```
$ how2 -h
```

### 总结

`how2` 是一个基本的命令行程序，它可以快速搜索 Stack Overflow 中的问题和答案，而无需离开终端，并且它可以很好地完成这项工作。但是，它只是 Stack overflow 的 CLI 浏览器。对于一些高级功能，例如搜索投票最多的问题，使用多个标签搜索查询，彩色界面，提交新问题和查看问题统计信息等，**SoCLI** 做得更好。

就是这些了。希望这篇文章有用。我将很快写一篇新的指南。在此之前，请继续关注！

干杯!

---

via: <https://www.ostechnix.com/how-to-browse-stack-overflow-from-terminal/>

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

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


GPL 合作承诺的发展历程

Summary: GPL 合作承诺消除了开发者对许可证失效的顾虑，从而达到促进技术创新的目的。

GPL 合作承诺消除了开发者对许可证失效的顾虑，从而达到促进技术创新的目的。

# GPL 合作承诺的发展历程

>
> <ruby> GPL 合作承诺 <rt>  GPL Cooperation Commitment </rt></ruby>消除了开发者对许可证失效的顾虑，从而达到促进技术创新的目的。
>
>
>

假如能免于顾虑，技术创新和发展将会让世界发生天翻地覆的改变。<ruby>   GPL 合作承诺  <rt>  GPL Cooperation Commitment </rt></ruby>就这样应运而生，只为通过公平、一致、可预测的许可证来让科技创新无后顾之忧。

去年，我曾经写过一篇文章，讨论了许可证对开源软件下游用户的影响。在进行研究的时候，我就发现许可证的约束力并不强，而且很多情况下是不可预测的。因此，我在文章中提出了一个能使开源许可证具有一致性和可预测性的潜在解决方案。但我只考虑到了诸如通过法律系统立法的“传统”方法。

2017 年 11 月，RedHat、IBM、Google 和 Facebook 提出了这种我从未考虑过的非传统的解决方案：GPL 合作承诺。GPL 合作承诺规定了 GPL 公平一致执行的方式。我认为，GPL 合作承诺之所以有这么深刻的意义，有以下两个原因：一是许可证的公平性和一致性对于开源社区的发展来说至关重要，二是法律对不可预测性并不容忍。

### 了解 GPL

要了解 GPL 合作承诺，首先要了解什么是 GPL。GPL 是 <ruby>   GNU 通用许可证  <rt>  GNU General Public License </rt></ruby>的缩写，它是一个公共版权的开源许可证，这就意味着开源软件的分发者必须向下游用户公开源代码。GPL 还禁止对下游的使用作出限制，要求个人用户不得拒绝他人对开源软件的使用自由、研究自由、共享自由和改进自由。GPL 规定，只要下游用户满足了许可证的要求和条件，就可以使用该许可证。如果被许可人出现了不符合许可证的情况，则视为违规。

按照第二版 GPL（GPLv2）的描述，许可证会在任何违规的情况下自动终止，这就导致了部分开发者对 GPL 有所抗拒。而在第三版 GPL（GPLv3）中则引入了“<ruby>   治愈条款  <rt>  cure provision </rt></ruby>”，这一条款规定，被许可人可以在 30 天内对违反 GPL 的行为进行改正，如果在这个缓冲期内改正完成，许可证就不会被终止。

这一规定消除了许可证被无故终止的顾虑，从而让软件的开发者和用户专注于开发和创新。

### GPL 合作承诺做了什么

GPL 合作承诺将 GPLv3 的治愈条款应用于使用 GPLv2 的软件上，让使用 GPLv2 许可证的开发者避免许可证无故终止的窘境，并与 GPLv3 许可证保持一致。

很多软件开发者都希望正确合规地做好一件事情，但有时候却不了解具体的实施细节。因此，GPL 合作承诺的重要性就在于能够对软件开发者们做出一些引导，让他们避免因一些简单的错误导致许可证违规终止。

Linux 基金会技术顾问委员会在 2017 年宣布，Linux 内核项目将会[采用 GPLv3 的治愈条款](https://www.kernel.org/doc/html/v4.16/process/kernel-enforcement-statement.html)。在 GPL 合作承诺的推动下，很多大型科技公司和个人开发者都做出了相同的承诺，会将该条款扩展应用于他们采用 GPLv2（或 LGPLv2.1）许可证的所有软件，而不仅仅是对 Linux 内核的贡献。

GPL 合作承诺的广泛采用将会对开源社区产生非常积极的影响。如果更多的公司和个人开始采用 GPL 合作承诺，就能让大量正在使用 GPLv2 或 LGPLv2.1 许可证的软件以更公平和更可预测的形式履行许可证中的条款。

截至 2018 年 11 月，包括 IBM、Google、亚马逊、微软、腾讯、英特尔、RedHat 在内的 40 余家行业巨头公司都已经[签署了 GPL 合作承诺](https://gplcc.github.io/gplcc/Company/Company-List.html)，以期为开源社区创立公平的标准以及提供可预测的执行力。GPL 合作承诺是开源社区齐心协力引领开源未来发展方向的一个成功例子。

GPL 合作承诺能够让下游用户了解到开发者对他们的尊重，同时也表示了开发者使用了 GPLv2 许可证的代码是安全的。如果你想查阅更多信息，包括如何将自己的名字添加到 GPL 合作承诺中，可以访问 [GPL 合作承诺的网站](http://gplcc.github.io/gplcc)。

---

via: <https://opensource.com/article/18/11/gpl-cooperation-commitment>

作者：[Brooke Driver](https://opensource.com/users/bdriver) 选题：[lujun9972](https://github.com/lujun9972) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)

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


i3 窗口管理器使 Linux 更美好

Summary: 通过键盘操作的 i3 平铺窗口管理器使用 Linux 桌面。

通过键盘操作的 i3 平铺窗口管理器使用 Linux 桌面。

# i3 窗口管理器使 Linux 更美好

>
> 通过键盘操作的 i3 平铺窗口管理器使用 Linux 桌面。
>
>
>

Linux（和一般的开源软件）最美好的一点是自由 —— 可以在不同的替代方案中进行选择以满足我们的需求。

我使用 Linux 已经很长时间了，但我从来没有对可选用的桌面环境完全满意过。直到去年，[Xfce](https://xfce.org/) 还是我认为在功能和性能之间的平和最接近满意的一个桌面环境。然后我发现了 [i3](https://i3wm.org/)，这是一个改变了我的生活的惊人的软件。

i3 是一个平铺窗口管理器。窗口管理器的目标是控制窗口系统中窗口的外观和位置。窗口管理器通常用作功能齐全的桌面环境 (如 GONME 或 Xfce ) 的一部分，但也有一些可以用作独立的应用程序。

平铺式窗口管理器会自动排列窗口，以不重叠的方式占据整个屏幕。其他流行的平铺式窗口管理器还有 [wmii](https://code.google.com/archive/p/wmii/) 和 [xmonad](https://xmonad.org/) 。

*带有三个的 i3 屏幕截图*

为了获得更好的 Linux 桌面体验，以下是我使用和推荐 i3 窗口管理器的五个首要原因。

### 1、极简艺术

i3 速度很快。它既不冗杂、也不花哨。它的设计简单而高效。作为开发人员，我重视这些功能，因为我可以使用更多的功能以丰富我最喜欢的开发工具，或者使用容器或虚拟机在本地测试内容。

此外， i3 是一个窗口管理器，与功能齐全的桌面环境不同，它并不规定您应该使用的应用程序。您是否想使用 Xfce 的 Thunar 作为文件管理器？GNOME 的 gedit 去编辑文本? i3 并不在乎。选择对您的工作流最有意义的工具，i3 将以相同的方式管理它们。

### 2、屏幕实际使用面积

作为平铺式窗口管理器，i3 将自动 “平铺”，以不重叠的方式定位窗口，类似于在墙上放置瓷砖。因为您不需要担心窗口定位，i3 一般会更好地利用您的屏幕空间。它还可以让您更快地找到您需要的东西。

对于这种情况有很多有用的例子。例如，系统管理员可以打开多个终端来同时监视或在不同的远程系统上工作；开发人员可以使用他们最喜欢的 IDE 或编辑器和几个终端来测试他们的程序。

此外，i3 具有灵活性。如果您需要为特定窗口提供更多空间，请启用全屏模式或切换到其他布局，如堆叠或选项卡式（标签式）。

### 3、键盘式工作流程

i3 广泛使用键盘快捷键来控制环境的不同方面。其中包括打开终端和其他程序、调整大小和定位窗口、更改布局，甚至退出 i3。当您开始使用 i3 时，您需要记住其中的一些快捷方式才能使用，随着时间的推移，您会使用更多的快捷方式。

主要好处是，您不需要经常在键盘和鼠标之间切换。通过练习，您将提高工作流程的速度和效率。

例如， 要打开新的终端，请按 `<SUPER>+<ENTER>`。由于窗口是自动定位的，您可以立即开始键入命令。结合一个很好的终端文本编辑器（如 Vim）和一个以面向键盘的浏览器，形成一个完全由键盘驱动的工作流程。

在 i3 中，您可以为所有内容定义快捷方式。下面是一些示例：

* 打开终端
* 打开浏览器
* 更改布局
* 调整窗口大小
* 控制音乐播放器
* 切换工作区

现在我已经习惯了这个工作形式，我已无法回到了常规的桌面环境。

### 4、灵活

i3 力求极简，使用很少的系统资源，但这并不意味着它不能变漂亮。i3 是灵活且可通过多种方式进行自定义以改善视觉体验。因为 i3 是一个窗口管理器，所以它没有提供启用自定义的工具，你需要外部工具来实现这一点。一些例子：

* 用 `feh` 定义桌面的背景图片。
* 使用合成器管理器，如 `compton` 以启用窗口淡入淡出和透明度等效果。
* 用 `dmenu` 或 `rofi` 以启用可从键盘快捷方式启动的可自定义菜单。
* 用 `dunst` 用于桌面通知。

i3 是可完全配置的，您可以通过更新默认配置文件来控制它的各个方面。从更改所有键盘快捷键，到重新定义工作区的名称，再到修改状态栏，您都可以使 i3 以任何最适合您需要的方式运行。

*i3 与 `rofi` 菜单和 `dunst` 桌面通知。*

最后，对于更高级的用户，i3 提供了完整的进程间通信（[IPC](https://i3wm.org/docs/ipc.html)）接口，允许您使用偏好的语言来开发脚本或程序，以实现更多的自定义选项。

### 5、工作空间

在 i3 中，工作区是对窗口进行分组的一种简单方法。您可以根据您的工作流以不同的方式对它们进行分组。例如，您可以将浏览器放在一个工作区上，终端放在另一个工作区上，将电子邮件客户端放在第三个工作区上等等。您甚至可以更改 i3 的配置，以便始终将特定应用程序分配给它们自己的工作区。

切换工作区既快速又简单。像 i3 中的惯例，使用键盘快捷方式执行此操作。按 `<SUPER>+num` 切换到工作区 `num` 。如果您养成了始终将应用程序组的窗口分配到同一个工作区的习惯，则可以在它们之间快速切换，这使得工作区成为非常有用的功能。

此外，还可以使用工作区来控制多监视器环境，其中每个监视器都有个初始工作区。如果切换到该工作区，则切换到该监视器，而无需让手离开键盘。

最后，i3 中还有另一种特殊类型的工作空间：the scratchpad（便笺簿）。它是一个不可见的工作区，通过按快捷方式显示在其他工作区的中间。这是一种访问您经常使用的窗口或程序的方便方式，如电子邮件客户端或音乐播放器。

### 尝试一下吧

如果您重视简洁和效率，并且不惮于使用键盘，i3 就是您的窗口管理器。有人说是为高级用户准备的，但情况不一定如此。你需要学习一些基本的快捷方式来度过开始的阶段，不久就会越来越自然并且不假思索地使用它们。

这篇文章只是浅浅谈及了 i3 能做的事情。欲了解更多详情，请参阅 [i3 的文档](https://i3wm.org/docs/userguide.html)。

---

via: <https://opensource.com/article/18/8/i3-tiling-window-manager>

作者：[Ricardo Gerardi](https://opensource.com/users/rgerardi) 选题：[lujun9972](https://github.com/lujun9972) 译者：[lixinyuxx](https://github.com/lixinyuxx) 校对：[wxy](https://github.com/wxy)

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


使用 Pandoc 将你的书转换成网页和电子书

Summary: 通过 Markdown 和 Pandoc，可以做到编写一次，发布两次。

通过 Markdown 和 Pandoc，可以做到编写一次，发布两次。

# 使用 Pandoc 将你的书转换成网页和电子书

>
> 通过 Markdown 和 Pandoc，可以做到编写一次，发布两次。
>
>
>

Pandoc 是一个命令行工具，用于将文件从一种标记语言转换为另一种标记语言。在我 [对 Pandoc 的简介](/article-10228-1.html) 一文中，我演示了如何把 Markdown 编写的文本转换为网页、幻灯片和 PDF。

在这篇后续文章中，我将深入探讨 [Pandoc](https://pandoc.org/)，展示如何从同一个 Markdown 源文件生成网页和 ePub 格式的电子书。我将使用我即将发布的电子书《[面向对象思想的 GRASP 原则](https://www.programmingfightclub.com/)》为例进行讲解，这本电子书正是通过以下过程创建的。

首先，我将解释这本书使用的文件结构，然后介绍如何使用 Pandoc 生成网页并将其部署在 GitHub 上；最后，我演示了如何生成对应的 ePub 格式电子书。

你可以在我的 GitHub 仓库 [Programming Fight Club](https://github.com/kikofernandez/programmingfightclub) 中找到相应代码。

### 设置图书结构

我用 Markdown 语法完成了所有的写作，你也可以使用 HTML 标记，但是当 Pandoc 将 Markdown 转换为 ePub 文档时，引入的 HTML 标记越多，出现问题的风险就越高。我的书按照每章一个文件的形式进行组织，用 Markdown 的 `H1` 标记（`＃`）声明每章的标题。你也可以在每个文件中放置多个章节，但将它们放在单独的文件中可以更轻松地查找内容并在以后进行更新。

元信息遵循类似的模式，每种输出格式都有自己的元信息文件。元信息文件定义有关文档的信息，例如要添加到 HTML 中的文本或 ePub 的许可证。我将所有 Markdown 文档存储在名为 `parts` 的文件夹中（这对于用来生成网页和 ePub 的 Makefile 非常重要）。下面以一个例子进行说明，让我们看一下目录，前言和关于本书（分为 `toc.md`、`preface.md` 和 `about.md` 三个文件）这三部分，为清楚起见，我们将省略其余的章节。

关于本书这部分内容的开头部分类似：

```
# About this book {-}

## Who should read this book {-}

Before creating a complex software system one needs to create a solid foundation.
General Responsibility Assignment Software Principles (GRASP) are guidelines to assign
responsibilities to software classes in object-oriented programming.
```

每一章完成后，下一步就是添加元信息来设置网页和 ePub 的格式。

### 生成网页

#### 创建 HTML 元信息文件

我创建的网页的元信息文件（`web-metadata.yaml`）是一个简单的 YAML 文件，其中包含 `<head>` 标签中的作者、标题、和版权等信息，以及 HTML 文件中开头和结尾的内容。

我建议（至少）包括 `web-metadata.yaml` 文件中的以下字段：

```
---
title: <a href="/grasp-principles/toc/">GRASP principles for the Object-oriented mind</a>
author: Kiko Fernandez-Reyes
rights: 2017 Kiko Fernandez-Reyes, CC-BY-NC-SA 4.0 International
header-includes:
- |
  ```{=html}
  <link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Gentium+Basic|Inconsolata" rel="stylesheet">
  ```
include-before:
- |
  ```{=html}

If you like this book, please consider
      spreading the word or

        buying me a coffee

  ```
include-after:
- |
  ```{=html}

          Designed with ❤   from Uppsala, Sweden

  ```
---
```

下面几个变量需要注意一下：

* `header-includes` 变量包含将要嵌入 `<head>` 标签的 HTML 文本。
* 调用变量后的下一行必须是 `- |`。再往下一行必须以与 `|` 对齐的三个反引号开始，否则 Pandoc 将无法识别。`{= html}` 告诉 Pandoc 其中的内容是原始文本，不应该作为 Markdown 处理。（为此，需要检查 Pandoc 中的 `raw_attribute` 扩展是否已启用。要进行此检查，键入 `pandoc --list-extensions | grep raw` 并确保返回的列表包含名为 `+ raw_html` 的项目，加号表示已启用。）
* 变量 `include-before` 在网页开头添加一些 HTML 文本，此处我请求读者帮忙宣传我的书或给我打赏。
* `include-after` 变量在网页末尾添加原始 HTML 文本，同时显示我的图书许可证。

这些只是其中一部分可用的变量，查看 HTML 中的模板变量（我的文章 [Pandoc简介](/article-10228-1.html) 中介绍了如何查看 LaTeX 的模版变量，查看 HTML 模版变量的过程是相同的）对其余变量进行了解。

#### 将网页分成多章

网页可以作为一个整体生成，这会产生一个包含所有内容的长页面；也可以分成多章，我认为这样会更容易阅读。我将解释如何将网页划分为多章，以便读者不会被长网页吓到。

为了使网页易于在 GitHub Pages 上部署，需要创建一个名为 `docs` 的根文件夹（这是 GitHub Pages 默认用于渲染网页的根文件夹）。然后我们需要为 `docs` 下的每一章创建文件夹，将 HTML 内容放在各自的文件夹中，将文件内容放在名为 `index.html` 的文件中。

例如，`about.md` 文件将转换成名为 `index.html` 的文件，该文件位于名为 `about`（`about/index.html`）的文件夹中。这样，当用户键入 `http://<your-website.com>/about/` 时，文件夹中的 `index.html` 文件将显示在其浏览器中。

下面的 `Makefile` 将执行上述所有操作：

```
# Your book files
DEPENDENCIES= toc preface about

# Placement of your HTML files
DOCS=docs

all: web

web: setup $(DEPENDENCIES)
        @cp $(DOCS)/toc/index.html $(DOCS)

# Creation and copy of stylesheet and images into
# the assets folder. This is important to deploy the
# website to Github Pages.
setup:
        @mkdir -p $(DOCS)
        @cp -r assets $(DOCS)

# Creation of folder and index.html file on a
# per-chapter basis

$(DEPENDENCIES):
        @mkdir -p $(DOCS)/$@
        @pandoc -s --toc web-metadata.yaml parts/$@.md \
        -c /assets/pandoc.css -o $(DOCS)/$@/index.html

clean:
        @rm -rf $(DOCS)

.PHONY: all clean web setup
```

选项 `- c /assets/pandoc.css` 声明要使用的 CSS 样式表，它将从 `/assets/pandoc.cs` 中获取。也就是说，在 `<head>` 标签内，Pandoc 会添加这样一行：

```
<link rel="stylesheet" href="/assets/pandoc.css">
```

使用下面的命令生成网页：

```
make
```

根文件夹现在应该包含如下所示的文件结构：

```
.---parts
|    |--- toc.md
|    |--- preface.md
|    |--- about.md
|
|---docs
    |--- assets/
    |--- index.html
    |--- toc
    |     |--- index.html
    |
    |--- preface
    |     |--- index.html
    |
    |--- about
          |--- index.html

```

#### 部署网页

通过以下步骤将网页部署到 GitHub 上：

1. 创建一个新的 GitHub 仓库
2. 将内容推送到新创建的仓库
3. 找到仓库设置中的 GitHub Pages 部分，选择 `Source` 选项让 GitHub 使用主分支的内容

你可以在 [GitHub Pages](https://pages.github.com/) 的网站上获得更多详细信息。

[我的书的网页](https://www.programmingfightclub.com/grasp-principles/) 便是通过上述过程生成的，可以在网页上查看结果。

### 生成电子书

#### 创建 ePub 格式的元信息文件

ePub 格式的元信息文件 `epub-meta.yaml` 和 HTML 元信息文件是类似的。主要区别在于 ePub 提供了其他模板变量，例如 `publisher` 和 `cover-image` 。ePub 格式图书的样式表可能与网页所用的不同，在这里我使用一个名为 `epub.css` 的样式表。

```
---
title: 'GRASP principles for the Object-oriented Mind'
publisher: 'Programming Language Fight Club'
author: Kiko Fernandez-Reyes
rights: 2017 Kiko Fernandez-Reyes, CC-BY-NC-SA 4.0 International
cover-image: assets/cover.png
stylesheet: assets/epub.css
...
```

将以下内容添加到之前的 `Makefile` 中：

```
epub:
        @pandoc -s --toc epub-meta.yaml \
        $(addprefix parts/, $(DEPENDENCIES:=.md)) -o $(DOCS)/assets/book.epub
```

用于产生 ePub 格式图书的命令从 HTML 版本获取所有依赖项（每章的名称），向它们添加 Markdown 扩展，并在它们前面加上每一章的文件夹路径，以便让 Pandoc 知道如何进行处理。例如，如果 `$（DEPENDENCIES` 变量只包含 “前言” 和 “关于本书” 两章，那么 `Makefile` 将会这样调用：

```
@pandoc -s --toc epub-meta.yaml \
parts/preface.md parts/about.md -o $(DOCS)/assets/book.epub
```

Pandoc 将提取这两章的内容，然后进行组合，最后生成 ePub 格式的电子书，并放在 `Assets` 文件夹中。

这是使用此过程创建 ePub 格式电子书的一个 [示例](https://github.com/kikofernandez/programmingfightclub/raw/master/docs/web_assets/demo.epub)。

### 过程总结

从 Markdown 文件创建网页和 ePub 格式电子书的过程并不困难，但有很多细节需要注意。遵循以下大纲可能使你更容易使用 Pandoc。

* HTML 图书：
	+ 使用 Markdown 语法创建每章内容
	+ 添加元信息
	+ 创建一个 `Makefile` 将各个部分组合在一起
	+ 设置 GitHub Pages
	+ 部署
* ePub 电子书：
	+ 使用之前创建的每一章内容
	+ 添加新的元信息文件
	+ 创建一个 `Makefile` 以将各个部分组合在一起
	+ 设置 GitHub Pages
	+ 部署

---

via: <https://opensource.com/article/18/10/book-to-website-epub-using-pandoc>

作者：[Kiko Fernandez-Reyes](https://opensource.com/users/kikofernandez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[jlztan](https://github.com/jlztan) 校对：[wxy](https://github.com/wxy)

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


什么是 SRE？它和 DevOps 是怎么关联的？

Summary: 大型企业里 SRE 角色比较常见，不过小公司也需要 SRE。

大型企业里 SRE 角色比较常见，不过小公司也需要 SRE。

# 什么是 SRE？它和 DevOps 是怎么关联的？

>
> 大型企业里 SRE 角色比较常见，不过小公司也需要 SRE。
>
>
>

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

虽然<ruby> 站点可靠性工程师 <rt>  site reliability engineer </rt></ruby>（SRE）角色在近几年变得流行起来，但是很多人 —— 甚至是软件行业里的 —— 还不知道 SRE 是什么或者 SRE 都干些什么。为了搞清楚这些问题，这篇文章解释了 SRE 的含义，还有 SRE 怎样关联 DevOps，以及在工程师团队规模不大的组织里 SRE 该如何工作。

### 什么是站点可靠性工程？

谷歌的几个工程师写的《[SRE：谷歌运维解密](http://shop.oreilly.com/product/0636920041528.do)》被认为是站点可靠性工程的权威书籍。谷歌的工程副总裁 Ben Treynor Sloss 在二十一世纪初[创造了这个术语](https://landing.google.com/sre/interview/ben-treynor.html)。他是这样定义的：“当你让软件工程师设计运维功能时，SRE 就产生了。”

虽然系统管理员从很久之前就在写代码，但是过去的很多时候系统管理团队是手动管理机器的。当时他们管理的机器可能有几十台或者上百台，不过当这个数字涨到了几千甚至几十万的时候，就不能简单的靠人去解决问题了。规模如此大的情况下，很明显应该用代码去管理机器（以及机器上运行的软件）。

另外，一直到近几年，运维团队和开发团队都还是完全独立的。两个岗位的技能要求也被认为是完全不同的。SRE 的角色想尝试把这两份工作结合起来。

在深入探讨什么是 SRE 以及 SRE 如何和开发团队协作之前，我们需要先了解一下 SRE 在 DevOps 范例中是怎么工作的。

### SRE 和 DevOps

站点可靠性工程的核心，就是对 DevOps 范例的实践。[DevOps 的定义](https://opensource.com/resources/devops)有很多种方式。开发团队（“dev”）和运维（“ops”）团队相互分离的传统模式下，写代码的团队在将服务交付给用户使用之后就不再对服务状态负责了。开发团队“把代码扔到墙那边”让运维团队去部署和支持。

这种情况会导致大量失衡。开发和运维的目标总是不一致 —— 开发希望用户体验到“最新最棒”的代码，但是运维想要的是变更尽量少的稳定系统。运维是这样假定的，任何变更都可能引发不稳定，而不做任何变更的系统可以一直保持稳定。（减少软件的变更次数并不是避免故障的唯一因素，认识到这一点很重要。例如，虽然你的 web 应用保持不变，但是当用户数量涨到十倍时，服务可能就会以各种方式出问题。）

DevOps 理念认为通过合并这两个岗位就能够消灭争论。如果开发团队时刻都想把新代码部署上线，那么他们也必须对新代码引起的故障负责。就像亚马逊的 [Werner Vogels 说的](https://queue.acm.org/detail.cfm?id=1142065)那样，“谁开发，谁运维”（生产环境）。但是开发人员已经有一大堆问题了。他们不断的被推动着去开发老板要的产品功能。再让他们去了解基础设施，包括如何部署、配置还有监控服务，这对他们的要求有点太多了。所以就需要 SRE 了。

开发一个 web 应用的时候经常是很多人一起参与。有用户界面设计师、图形设计师、前端工程师、后端工程师，还有许多其他工种（视技术选型的具体情况而定）。如何管理写好的代码也是需求之一（例如部署、配置、监控）—— 这是 SRE 的专业领域。但是，就像前端工程师受益于后端领域的知识一样（例如从数据库获取数据的方法），SRE 理解部署系统的工作原理，知道如何满足特定的代码或者项目的具体需求。

所以 SRE 不仅仅是“写代码的运维工程师”。相反，SRE 是开发团队的成员，他们有着不同的技能，特别是在发布部署、配置管理、监控、指标等方面。但是，就像前端工程师必须知道如何从数据库中获取数据一样，SRE 也不是只负责这些领域。为了提供更容易升级、管理和监控的产品，整个团队共同努力。

当一个团队在做 DevOps 实践，但是他们意识到对开发的要求太多了，过去由运维团队做的事情，现在需要一个专家来专门处理。这个时候，对 SRE 的需求很自然地就出现了。

### SRE 在初创公司怎么工作

如果你们公司有好几百位员工，那是非常好的（如果到了 Google 和 Facebook 的规模就更不用说了）。大公司的 SRE 团队分散在各个开发团队里。但是一个初创公司没有这种规模经济，工程师经常身兼数职。那么小公司该让谁做 SRE 呢？其中一种方案是完全践行 DevOps，那些大公司里属于 SRE 的典型任务，在小公司就让开发者去负责。另一种方案，则是聘请专家 —— 也就是 SRE。

让开发人员做 SRE 最显著的优点是，团队规模变大的时候也能很好的扩展。而且，开发人员将会全面地了解应用的特性。但是，许多初创公司的基础设施包含了各种各样的 SaaS 产品，这种多样性在基础设施上体现的最明显，因为连基础设施本身也是多种多样。然后你们在某个基础设施上引入指标系统、站点监控、日志分析、容器等等。这些技术解决了一部分问题，也增加了复杂度。开发人员除了要了解应用程序的核心技术（比如开发语言），还要了解上述所有技术和服务。最终，掌握所有的这些技术让人无法承受。

另一种方案是聘请专家专职做 SRE。他们专注于发布部署、配置管理、监控和指标，可以节省开发人员的时间。这种方案的缺点是，SRE 的时间必须分配给多个不同的应用（就是说 SRE 需要贯穿整个工程部门）。 这可能意味着 SRE 没时间对任何应用深入学习，然而他们可以站在一个能看到服务全貌的高度，知道各个部分是怎么组合在一起的。 这个“三万英尺高的视角”可以帮助 SRE 从系统整体上考虑，哪些薄弱环节需要优先修复。

有一个关键信息我还没提到：其他的工程师。他们可能很渴望了解发布部署的原理，也很想尽全力学会使用指标系统。而且，雇一个 SRE 可不是一件简单的事儿。因为你要找的是一个既懂系统管理又懂软件工程的人。（我之所以明确地说软件工程而不是说“能写代码”，是因为除了写代码之外软件工程还包括很多东西，比如编写良好的测试或文档。）

因此，在某些情况下让开发人员做 SRE 可能更合理一些。如果这样做了，得同时关注代码和基础设施（购买 SaaS 或内部自建）的复杂程度。这两边的复杂性，有时候能促进专业化。

### 总结

在初创公司做 DevOps 实践最有效的方式是组建 SRE 小组。我见过一些不同的方案，但是我相信初创公司（尽早）招聘专职 SRE 可以解放开发人员，让开发人员专注于特定的挑战。SRE 可以把精力放在改善工具（流程）上，以提高开发人员的生产力。不仅如此，SRE 还专注于确保交付给客户的产品是可靠且安全的。

---

via: <https://opensource.com/article/18/10/sre-startup>

作者：[Craig Sebenik](https://opensource.com/users/craig5) 选题：[lujun9972](https://github.com/lujun9972) 译者：[BeliteX](https://github.com/belitex) 校对：[wxy](https://github.com/wxy)

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


如何更换 Ubuntu 系统的 GDM 登录界面背景

# 如何更换 Ubuntu 系统的 GDM 登录界面背景

Ubuntu 18.04 LTS 桌面系统在登录、锁屏和解锁状态下，我们会看到一个纯紫色的背景。它是 GDM（<ruby> GNOME 显示管理器 <rt>  GNOME Display Manager </rt></ruby>）从 ubuntu 17.04 版本开始使用的默认背景。有一些人可能会不喜欢这个纯色的背景，想换一个酷一点、更吸睛的！如果是这样，你找对地方了。这篇短文将会告诉你如何更换 Ubuntu 18.04 LTS 的 GDM 登录界面的背景。

### 更换 Ubuntu 的登录界面背景

这是 Ubuntu 18.04 LTS 桌面系统默认的登录界面。

不管你喜欢与否，你总是会不经意在登录、解屏/锁屏的时面对它。别担心！你可以随便更换一个你喜欢的图片。

在 Ubuntu 上更换桌面壁纸和用户的资料图像不难。我们可以点击鼠标就搞定了。但更换解屏/锁屏的背景则需要修改文件 `ubuntu.css`，它位于 `/usr/share/gnome-shell/theme`。

修改这个文件之前，最好备份一下它。这样我们可以避免出现问题时可以恢复它。

```
$ sudo cp /usr/share/gnome-shell/theme/ubuntu.css /usr/share/gnome-shell/theme/ubuntu.css.bak
```

修改文件 `ubuntu.css`：

```
$ sudo nano /usr/share/gnome-shell/theme/ubuntu.css
```

在文件中找到关键字 `lockDialogGroup`，如下行：

```
#lockDialogGroup {
   background: #2c001e url(resource:///org/gnome/shell/theme/noise-texture.png);
   background-repeat: repeat;
}
```

可以看到，GDM 默认登录的背景图片是 `noise-texture.png`。

现在修改为你自己的图片路径。也可以选择 .jpg 或 .png 格式的文件，两种格式的图片文件都是支持的。修改完成后的文件内容如下：

```
#lockDialogGroup {
   background: #2c001e url(file:///home/sk/image.png);
   background-repeat: no-repeat;
   background-size: cover;
   background-position: center;
}
```

请注意 `ubuntu.css` 文件里这个关键字的修改，我把修改点加粗了。

你可能注意到，我把原来的 `... url(resource:///org/gnome/shell/theme/noise-texture.png);` 修改为 `... url(file:///home/sk/image.png);`。也就是说，你可以把 `... url(resource ...` 修改为 `.. url(file ...`。

同时，你可以把参数 `background-repeat:` 的值 `repeat` 修改为 `no-repeat`，并增加另外两行。你可以直接复制上面几行的修改到你的 `ubuntu.css` 文件，对应的修改为你的图片路径。

修改完成后，保存和关闭此文件。然后系统重启生效。

下面是 GDM 登录界面的最新背景图片：

是不是很酷，你都看到了，更换 GDM 登录的默认背景很简单。你只需要修改 `ubuntu.css` 文件中图片的路径然后重启系统。是不是很简单也很有意思.

你可以修改 `/usr/share/gnome-shell/theme` 目录下的文件 `gdm3.css` ，具体修改内容和修改结果和上面一样。同时记得修改前备份要修改的文件。

就这些了。如果有好的东东再分享了，请大家关注！

后会有期。

---

via: <https://www.ostechnix.com/how-to-change-gdm-login-screen-background-in-ubuntu/>

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

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


IssueHunt：一个新的开源软件打赏平台

# IssueHunt：一个新的开源软件打赏平台

许多开源开发者和公司都在努力解决的问题之一就是资金问题。社区中有一种假想，甚至是期望，必须免费提供自由开源软件（FOSS）。但即使是 FOSS 也需要资金来继续开发。如果我们不建立让软件持续开发的系统，我们怎能期待更高质量的软件？

我们已经写了一篇关于[开源资金平台](https://itsfoss.com/open-source-funding-platforms/)的文章来试图解决这个缺点，截至今年 7 月，市场上出现了一个新的竞争者，旨在帮助填补这个空白：[IssueHunt](https://issuehunt.io)。

### IssueHunt: 开源软件打赏平台

IssueHunt 提供了一种服务，对自由开发者的开源代码贡献进行支付。它通过所谓的赏金来实现：给予解决特定问题的任何人财务奖励。这些奖励的资金来自任何愿意捐赠以修复任何特定 bug 或添加功能的人。

如果你想修复的某个开源软件存在问题，你可以根据自己选择的方式提供奖励金额。

想要自己的产品被争抢解决么？在 IssueHunt 上向任何解决问题的人提供奖金就好了。就这么简单。

如果你是程序员，则可以浏览未解决的问题。解决这个问题（如果你可以的话），在 GitHub 存储库上提交拉取请求，如果你的拉取请求被合并，那么你就会得到了钱。

#### IssueHunt 最初是 Boostnote 的内部项目

当笔记应用 [Boostnote](https://itsfoss.com/boostnote-linux-review/) 背后的开发人员联系社区为他们的产品做出贡献时，该产品出现了。

在使用 IssueHunt 的前两年，Boostnote 通过数百名贡献者和压倒性的捐款收到了超过 8,400 个 Github star。

该产品非常成功，团队决定将其开放给社区的其他成员。

如今，[列表中在使用这个服务的项目](https://issuehunt.io/repos)提供了数千美元的赏金。

Boostnote 号称有 [$2,800 的总赏金](https://issuehunt.io/repos/53266139)，而 Settings Sync，以前称为 Visual Studio Code Settings Sync，提供了[超过 $1,600 的赏金](https://issuehunt.io/repos/47984369)。

还有其他服务提供类似于 IssueHunt 在此提供的内容。也许最引人注目的是 [Bountysource](https://www.bountysource.com/)，它提供与 IssueHunt 类似的赏金服务，同时还提供类似于 [Librepay](https://liberapay.com/) 的订阅支付处理。

#### 你怎么看待 IssueHunt？

在撰写本文时，IssueHunt 还处于起步阶段，但我非常高兴看到这个项目在这些年里的成果。

我不知道你会怎么看，但我非常乐意为 FOSS 付款。如果产品质量高，并为我的生活增添价值，那么我很乐意向开发者支付产品费用。特别是 FOSS 的开发者正在创造尊重我自由的产品。

话虽如此，我一定会关注 IssueHunt 的继续前进，我可以用自己的钱或者在需要贡献的地方传播这个它来支持社区。

但你怎么看？你是否同意我的看法，或者你认为软件应该免费提供，并且应该在志愿者的基础上做出贡献？请在下面的评论中告诉我们你的想法。

---

via: <https://itsfoss.com/issuehunt/>

作者：[Phillip Prado](https://itsfoss.com/author/phillip/) 选题：[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: 多语言编程环境是一把双刃剑，既带来好处，也带来可能威胁组织的复杂性。

多语言编程环境是一把双刃剑，既带来好处，也带来可能威胁组织的复杂性。

# 如何使用多种编程语言而又不失理智

>
> 多语言编程环境是一把双刃剑，既带来好处，也带来可能威胁组织的复杂性。
>
>
>

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

如今，随着各种不同的编程语言的出现，许多组织已经变成了<ruby> 数字多语种组织 <rt>  digital polyglots </rt></ruby>。开源打开了一个语言和技术堆栈的世界，开发人员可以使用这些语言和技术堆栈来完成他们的任务，包括开发、支持过时的和现代的软件应用。

与那些只说母语的人相比，通晓多种语言的人可以与数百万人交谈。在软件环境中，开发人员不会引入新的语言来达到特定的目的，也不会更好地交流。一些语言对于一项任务来说很棒，但是对于另一项任务来说却不行，因此使用多种编程语言可以让开发人员使用合适的工具来完成这项任务。这样，所有的开发都是多语种的；这只是野兽的本性。

多语种环境的创建通常是渐进的和情景化的。例如，当一家企业收购一家公司时，它就承担了该公司的技术堆栈 —— 包括其编程语言。或者，随着技术领导的改变，新的领导者可能会将不同的技术纳入其中。技术也有过时的时候，随着时间的推移，增加了组织必须维护的编程语言和技术的数量。

多语言环境对企业来说是一把双刃剑，既带来好处，也带来复杂性和挑战。最终，如果这种情况得不到控制，多语言将会扼杀你的企业。

### 棘手的技术绕口令

如果有多种不同的技术 —— 编程语言、过时的工具和新兴的技术堆栈 —— 就有复杂性。工程师团队花更多的时间努力改进编程语言，包括许可证、安全性和依赖性。与此同时，管理层缺乏对代码合规性的监督，无法衡量风险。

发生的情况是，企业具有不同程度的编程语言质量和工具支持的高度可变性。当你需要和十几个人一起工作时，很难成为一种语言的专家。一个能流利地说法语和意大利语的人和一个能用八种语言串成几个句子的人在技能水平上有很大差异。开发人员和编程语言也是如此。

随着更多编程语言的加入，困难只会增加，导致数字巴别塔的出现。

答案是不要拿走开发人员工作所需的工具。添加新的编程语言可以建立他们的技能基础，并为他们提供合适的设备来完成他们的工作。所以，你想对你的开发者说“是”，但是随着越来越多的编程语言被添加到企业中，它们会拖累你的软件开发生命周期（SDLC）。在规模上，所有这些语言和工具都可能扼杀企业。

企业应注意三个主要问题:

1. **可见性：** 团队聚在一起执行项目，然后解散。应用程序已经发布，但从未更新 —— 为什么要修复那些没有被破坏的东西？因此，当发现一个关键漏洞时，企业可能无法了解哪些应用程序受到影响，这些应用程序包含哪些库，甚至无法了解它们是用什么语言构建的。这可能导致成本高昂的“勘探项目”，以确保漏洞得到适当解决。
2. **更新或编码：** 一些企业将更新和修复功能集中在一个团队中。其他人要求每个“比萨团队”管理自己的开发工具。无论是哪种情况，工程团队和管理层都要付出机会成本：这些团队没有编码新特性，而是不断更新和修复开源工具中的库，因为它们移动得如此之快。
3. **重新发明轮子：** 由于代码依赖性和库版本不断更新，当发现漏洞时，与应用程序原始版本相关联的工件可能不再可用。因此，许多开发周期都被浪费在试图重新创建一个可以修复漏洞的环境上。

将你组织中的每种编程语言乘以这三个问题，开始时被认为是分子一样小的东西突然看起来像珠穆朗玛峰。就像登山者一样，没有合适的设备和工具，你将无法生存。

### 找到你的罗塞塔石碑

一个全面的解决方案可以满足 SDLC 中企业及其个人利益相关者的需求。企业可以使用以下最佳实践创建解决方案:

1. 监控生产中运行的代码，并根据应用程序中使用的标记组件（例如，常见漏洞和暴露组件）的风险做出响应。
2. 定期接收更新以保持代码的最新和无错误。
3. 使用商业开源支持来获得编程语言版本和平台的帮助，这些版本和平台已经接近尾声，并且不受社区支持。
4. 标准化整个企业中的特定编程语言构建，以实现跨团队的一致环境，并最大限度地减少依赖性。
5. 根据相关性设置何时触发更新、警报或其他类型事件的阈值。
6. 为您的包管理创建一个单一的可信来源；这可能需要知识渊博的技术提供商的帮助。
7. 根据您的特定标准，只使用您需要的软件包获得较小的构建版本。

使用这些最佳实践，开发人员可以最大限度地利用他们的时间为企业创造更多价值，而不是执行基本的工具或构建工程任务。这将在软件开发生命周期（SDLC）的所有环境中创建代码一致性。由于维护编程语言和软件包分发所需的资源更少，这也将提高效率和节约成本。这种新的操作方式将使技术人员和管理人员的生活更加轻松。

---

via: <https://opensource.com/article/18/11/multiple-programming-languages>

作者：[Bart Copeland](https://opensource.com/users/bartcopeland) 选题：[lujun9972](https://github.com/lujun9972) 译者：[heguangzhi](https://github.com/heguangzhi) 校对：[wxy](https://github.com/wxy)

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


构建满足用户需求的云环境的五个步骤

Summary: 在投入时间和资金开发你的云环境之前，确认什么是你的用户所需要的。

在投入时间和资金开发你的云环境之前，确认什么是你的用户所需要的。

# 构建满足用户需求的云环境的五个步骤

>
> 在投入时间和资金开发你的云环境之前，确认什么是你的用户所需要的。
>
>
>

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

无论你如何定义，云就是你的用户展现其在组织中的价值的另一个工具。当谈论新的范例或者技术（云是两者兼有）的时候很容易被它的新特性所分心。由一系列无止境的问题引发的对话能够很快的被发展为功能愿景清单，所有下面的这些都是你可能已经考虑到的：

* 是公有云、私有云还是混合云？
* 会使用虚拟机还是容器，或者是两者？
* 会提供自助服务吗？
* 从开发到生产是完全自动的，还是它将需要手动操作？
* 我们能以多块的速度做到？
* 关于某某工具？

这样的清单还可以列举很多。

当开始 IT 现代化，或者数字转型，无论你是如何称呼的，通常方法是开始回答更高管理层的一些高层次问题，这种方法的结果是可以预想到的：失败。经过大范围的调研并且花费了数月的时间（如果不是几年的话）部署了这个最炫的新技术，而这个新的云技术却从未被使用过，而且陷入了荒废，直到它最终被丢弃或者遗忘在数据中心的一角和预算之中。

这是因为无论你交付的是什么工具，都不是用户所想要或者需要的。更加糟糕的是，它可能是一个单一的工具，而用户真正需要的是一系列工具 —— 能够随着时间推移，更换升级为更新的、更漂亮的工具，以更好地满足其需求。

### 专注于重要的事情

问题在于关注，传统上一直是关注于工具。但工具并不是要增加到组织价值中的东西；终端用户利用它做什么才是目的。你需要将你的注意力从创建云（例如技术和工具）转移到你的人员和用户身上。

事实上，除了使用工具的用户（而不是工具本身）是驱动价值的因素之外，聚焦注意力在用户身上也是有其它原因的。工具是给用户使用去解决他们的问题并允许他们创造价值的，所以这就导致了如果那些工具不能满足那些用户的需求，那么那些工具将不会被使用。如果你交付给你的用户的工具并不是他们喜欢的，他们将不会使用，这就是人类的人性行为。

数十年来，IT 产业只为用户提供一种解决方案，因为仅有一个或两个选择，用户是没有权力去改变的。现在情况已经不同了。我们现在生活在一个技术选择的世界中。不给用户一个选择的机会的情况将不会被接受的；他们在个人的科技生活中有选择，同时希望在工作中也有选择。现在的用户都是受过教育的并且知道将会有比你所提供的更好选择。

因此，在物理上的最安全的地点之外，没有能够阻止他们只做他们自己想要的东西的方法，我们称之为“影子 IT”。如果你的组织有如此严格的安全策略和承诺策略而不允许影子 IT，许多员工将会感到灰心丧气并且会离职去其他能提供更好机会的公司。

基于以上所有的原因，你必须牢记要首先和你的最终用户设计你的昂贵又费时的云项目。

### 创建满足用户需求的云五个步骤的过程

既然我们已经知道了为什么，接下来我们来讨论一下怎么做。你如何去为终端用户创建一个云？你怎样重新将你的注意力从技术转移到使用技术的用户身上？

根据以往的经验，我们知道最好的方法中包含两件重要的事情：从你的用户中得到及时的反馈，在创建中和用户进行更多的互动。

你的云环境将继续随着你的组织不断发展。下面的五个步骤将会帮助你创建满足用户需求的云环境。

#### 1、识别谁将是你的用户

在你开始询问用户问题之前，你首先必须识别谁将是你的新的云环境的用户。他们可能包括将在云上创建开发应用的开发者；也可能是运营、维护或者或者创建该云的运维团队；还可能是保护你的组织的安全团队。在第一次迭代时，将你的用户数量缩小至人数较少的小组防止你被大量的反馈所淹没，让你识别的每个小组指派两个代表（一个主要的一个辅助的）。这将使你的第一次交付在规模和时间上都很小。

#### 2、和你的用户面对面的交谈来收获有价值的输入。

获得反馈的最佳途径是和用户直接交谈。群发的邮件会自行挑选出受访者——如果你能收到回复的话。小组讨论会很有帮助的，但是当人们有个私密的、专注的对话者时，他们会比较的坦诚。

和你的第一批用户安排个面对面的个人的会谈，并且向他们询问以下的问题：

* 为了完成你的任务，你需要什么？
* 为了完成你的任务，你想要什么？
* 你现在最头疼的技术痛点是什么？
* 你现在最头疼的政策或者流程痛点是哪个？
* 关于解决你的需求、希望或痛点，你有什么建议？

这些问题只是指导性的，并不一定适合每个组织。你不应该只询问这些问题，他们应该导向更深层次的讨论。确保告诉用户他们任何所说的和被问的都被视作反馈，所有的反馈都是有帮助的，无论是消极的还是积极的。这些对话将会帮助你设置你的开发优先级。

收集这种个性化的反馈是保持初始用户群较小的另一个原因：这将会花费你大量的时间来和每个用户交流，但是我们已经发现这是相当值得付出的投入。

#### 3、设计并交付你的解决方案的第一个版本

一旦你收到初始用户的反馈，就是时候开始去设计并交付一部分的功能了。我们不推荐尝试一次性交付整个解决方案。设计和交付的时期要短；这可以避免你花费一年的时间去构建一个你*认为*正确的解决方案，而只会让你的用户拒绝它，因为对他们来说毫无用处。创建你的云所需要的工具取决于你的组织和它的特殊需求。只需确保你的解决方案是建立在用户的反馈的基础上的，你将功能小块化的交付并且要经常的去征求用户的反馈。

#### 4、询问用户对第一个版本的反馈

太棒了，现在你已经设计并向你的用户交付了你的炫酷的新的云环境的第一个版本！你并不是花费一整年去完成它而是将它处理成小的模块。为什么将其分为小的模块如此重要呢？因为你要回到你的用户组并且向他们收集关于你的设计和交付的功能。他们喜欢什么？不喜欢什么？你正确的处理了他们所关注的吗？是技术功能上很厉害，但系统进程或者策略方面仍然欠缺吗？

再重申一次，你要问的问题取决于你的组织；这里的关键是继续前一个阶段的讨论。毕竟你正在为用户创建云环境，所以确保它对用户来说是有用的并且能够有效利用每个人的时间。

#### 5、回到第一步。

这是一个迭代的过程。你的首次交付应该是快速而小规模的，而且以后的迭代也应该是这样的。不要期待仅仅按照这个流程完成了一次、两次甚至是三次就能完成。一旦你持续的迭代，你将会吸引更多的用户从而能够在这个过程中得到更好的回报。你将会从用户那里得到更多的支持。你能够迭代的更迅速并且更可靠。到最后，你将会通过改变你的流程来满足用户的需求。

用户是这个过程中最重要的一部分，但迭代是第二重要的因为它让你能够回到用户中进行持续沟通从而得到更多有用的信息。在每个阶段，记录哪些是有效的哪些没有起到应有的效果。要自省，要对自己诚实。我们所花费的时间提供了最有价值的了吗？如果不是，在下一个阶段尝试些不同的。在每次循环中不要花费太多时间的最重要的部分是，如果某部分在这次不起作用，你能够很容易的在下一次中调整它，直到你找到能够在你组织中起作用的方法。

### 这仅仅是开始

通过许多客户约见，从他们那里收集反馈，以及在这个领域的同行的经验，我们一次次的发现在创建云的时候最重要事就是和你的用户交谈。这似乎是很明显的，但很让人惊讶的是很多组织却偏离了这个方向去花费数月或者数年的时间去创建，然后最终发现它对终端用户甚至一点用处都没有。

现在你已经知道为什么你需要将你的注意力集中到终端用户身上并且在中心节点和用户一起的互动创建云。剩下的是我们所喜欢的部分，你自己去做的部分。

这篇文章是基于一篇作者在 [Red Hat Summit 2018](https://www.redhat.com/en/summit/2018) 上发表的文章“[为终端用户设计混合云，要么失败]”。

---

via: <https://opensource.com/article/18/4/5-steps-building-your-cloud-correctly>

作者：[Cameron Wyatt](https://opensource.com/users/cameronmwyatt), [Ian Teksbury](https://opensource.com/users/itewk) 选题：[lujun9972](https://github.com/lujun9972) 译者：[FelixYFZ](https://github.com/FelixYFZ) 校对：[wxy](https://github.com/wxy)

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


Android 9.0 概览

Summary: 第九代 Android 带来了更令人满意的用户体验。

第九代 Android 带来了更令人满意的用户体验。

# Android 9.0 概览

>
> 第九代 Android 带来了更令人满意的用户体验。
>
>
>

我们来谈论一下 Android。尽管 Android 只是一款内核经过修改的 Linux，但经过多年的发展，Android 开发者们（或许包括正在阅读这篇文章的你）已经为这个平台的演变做出了很多值得称道的贡献。当然，可能很多人都已经知道，但我们还是要说，Android 并不完全开源，当你使用 Google 服务的时候，就已经接触到闭源的部分了。Google Play 商店就是其中之一，它不是一个开放的服务。不过无论 Android 开源与否，这就是一个美味、营养、高效、省电的馅饼（LCTT 译注：Android 9.0 代号为 Pie）。

我在我的 Essential PH-1 手机上运行了 Android 9.0（我真的很喜欢这款手机，也知道这家公司的境况并不好）。在我自己体验了一段时间之后，我认为它是会被大众接受的。那么 Android 9.0 到底好在哪里呢？下面我们就来深入探讨一下。我们的出发点是用户的角度，而不是开发人员的角度，因此我也不会深入探讨太底层的方面。

### 手势操作

Android 系统在新的手势操作方面投入了很多，但实际体验却不算太好。这个功能确实引起了我的兴趣。在这个功能发布之初，大家都对它了解甚少，纷纷猜测它会不会让用户使用多点触控的手势来浏览 Android 界面？又或者会不会是一个完全颠覆人们认知的东西？

实际上，手势操作比大多数人设想的要更加微妙而简单，因为很多功能都浓缩到了 Home 键上。打开手势操作功能之后，Recent 键的功能就合并到 Home 键上了。因此，如果需要查看最近打开的应用程序，就不能简单地通过 Recent 键来查看，而应该从 Home 键向上轻扫一下。（图 1）

*图 1：Android 9.0 中的”最近的应用程序“界面。*

另一个不同的地方是 App Drawer。类似于查看最近打开的应用，需要在 Home 键向上滑动才能打开 App Drawer。

而后退按钮则没有去掉。在应用程序需要用到后退功能时，它就会出现在主屏幕的左下方。有时候即使应用程序自己带有后退按钮，Android 的后退按钮也会出现。

当然，如果你不喜欢使用手势操作，也可以禁用这个功能。只需要按照下列步骤操作：

1. 打开”设置“
2. 向下滑动并进入“系统 > 手势”
3. 从 Home 键向上滑动
4. 将 On/Off 滑块（图 2）滑动至 Off 位置

*图 2：关闭手势操作。*

### 电池寿命

人工智能已经在 Android 得到了充分的使用。现在，Android 使用人工智能大大提供了电池的续航时间，这样的新技术称为自适应电池。自适应电池可以根据用户的个人使用习惯来决定各种应用和服务的耗电优先级。通过使用人工智能技术，Android 可以分析用户对每一个应用或服务的使用情况，并适当地关闭未使用的应用程序，以免长期驻留在内存中白白消耗电池电量。

对于这个功能的唯一一个警告是，如果人工智能出现问题并导致电池电量过早耗尽，就只能通过恢复出厂设置来解决这个问题了。尽管有这样的缺陷，在电池续航时间方面，Android 9.0 也比 Android 8.0 有所改善。

### 分屏功能的变化

分屏对于 Android 来说不是一个新功能，但在 Android 9.0 上，它的使用方式和以往相比略有不同，而且只对于手势操作有影响，不使用手势操作的用户不受影响。要在 Android 9.0 上使用分屏功能，需要按照下列步骤操作：

1. 从 Home 键向上滑动，打开“最近的应用程序”。
2. 找到需要放置在屏幕顶部的应用程序。
3. 长按应用程序顶部的图标以显示新的弹出菜单。（图 3）
4. 点击分屏，应用程序会在屏幕的上半部分打开。
5. 找到要打开的第二个应用程序，然后点击它添加到屏幕的下半部分。

*图 3：在 Android 9.0 上将应用添加到分屏模式中。*

使用分屏功能关闭应用程序的方法和原来保持一致。

### 应用操作

这个功能在早前已经引入了，但直到 Android 9.0 发布，人们才开始对它产生明显的关注。应用操作功能可以让用户直接从应用启动器来执行应用里的某些操作。

例如，长按 GMail 启动器，就可以执行回复最近的邮件、撰写新邮件等功能。在 Android 8.0 中，这个功能则以弹出动作列表的方式展现。在 Android 9.0 中，这个功能更契合 Google 的<ruby> 材料设计 <rt>  Material Design </rt></ruby>风格（图 4）。

*图 4：Android 应用操作。*

### 声音控制

在 Android 中，声音控制的方式经常发生变化。在 Android 8.0 对“请勿打扰”功能进行调整之后，声音控制已经做得相当不错了。而在 Android 9.0 当中，声音控制再次进行了优化。

Android 9.0 这次优化针对的是设备上快速控制声音的按钮。如果用户按下音量增大或减小按钮，就会看到一个新的弹出菜单，可以让用户控制设备的静音和震动情况。点击这个弹出菜单顶部的图标（图 5），可以在完全静音、静音和正常声音几种状态之间切换。

*图 5：Android 9.0 上的声音控制。*

### 屏幕截图

由于我要撰写关于 Android 的文章，所以我会常常需要进行屏幕截图。而 Android 9.0 有一项我最喜欢的更新，就是分享屏幕截图。Android 9.0 可以在截取屏幕截图后，直接共享、编辑，或者删除不喜欢的截图，而不需要像以前一样打开 Google 相册、找到要共享的屏幕截图、打开图像然后共享图像。

如果你想分享屏幕截图，只需要在截图后等待弹出菜单，点击分享（图 6），从标准的 Android 分享菜单中分享即可。

*图 6：共享屏幕截图变得更加容易。*

### 更令人满意的 Android 体验

Android 9.0 带来了更令人满意的用户体验。当然，以上说到的内容只是它的冰山一角。如果需要更多信息，可以查阅 Google 的官方 [Android 9.0 网站](https://www.android.com/versions/pie-9-0/)。如果你的设备还没有收到升级推送，请耐心等待，Android 9.0 值得等待。

---

via: <https://www.linux.com/learn/2018/10/overview-android-pie>

作者：[Jack Wallen](https://www.linux.com/users/jlwallen) 选题：[lujun9972](https://github.com/lujun9972) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)

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


# 如何从 Windows 7、8 和 10 创建可启动的 Linux USB 盘？

如果你想了解 Linux，首先要做的是在你的系统上安装 Linux 系统。

它可以通过两种方式实现，使用 Virtualbox、VMWare 等虚拟化应用，或者在你的系统上安装 Linux。

如果你倾向于从 Windows 系统迁移到 Linux 系统或计划在备用机上安装 Linux 系统，那么你须为此创建可启动的 USB 盘。

我们已经写过许多[在 Linux 上创建可启动 USB 盘](https://www.2daygeek.com/category/bootable-usb/) 的文章，如 [BootISO](https://www.2daygeek.com/bootiso-a-simple-bash-script-to-securely-create-a-bootable-usb-device-in-linux-from-iso-file/)、[Etcher](https://www.2daygeek.com/etcher-easy-way-to-create-a-bootable-usb-drive-sd-card-from-an-iso-image-on-linux/) 和 [dd 命令](https://www.2daygeek.com/create-a-bootable-usb-drive-from-an-iso-image-using-dd-command-on-linux/)，但我们从来没有机会写一篇文章关于在 Windows 中创建 Linux 可启动 USB 盘的文章。不管怎样，我们今天有机会做这件事了。

在本文中，我们将向你展示如何从 Windows 10 创建可启动的 Ubuntu USB 盘。

这些步骤也适用于其他 Linux，但你必须从下拉列表中选择相应的操作系统而不是 Ubuntu。

### 步骤 1：下载 Ubuntu ISO

访问 [Ubuntu 发布](http://releases.ubuntu.com/) 页面并下载最新版本。我想建议你下载最新的 LTS 版而不是普通的发布。

通过 MD5 或 SHA256 验证校验和，确保下载了正确的 ISO。输出值应与 Ubuntu 版本页面值匹配。

### 步骤 2：下载 Universal USB Installer

有许多程序可供使用，但我的首选是 [Universal USB Installer](https://www.pendrivelinux.com/universal-usb-installer-easy-as-1-2-3/)，它使用起来非常简单。只需访问 Universal USB Installer 页面并下载该程序即可。

### 步骤3：创建可启动的 Ubuntu ISO

这个程序在使用上不复杂。首先连接 USB 盘，然后点击下载的 Universal USB Installer。启动后，你可以看到类似于我们的界面。

* 步骤 1：选择 Ubuntu 系统。
* 步骤 2：选择 Ubuntu ISO 下载位置。
* 步骤 3：它默认选择的是 USB 盘，但是要验证一下，接着勾选格式化选项。

当你点击 “Create” 按钮时，它会弹出一个带有警告的窗口。不用担心，只需点击 “Yes” 继续进行此操作即可。

USB 盘分区正在进行中。

要等待一会儿才能完成。如你您想将它移至后台，你可以点击 “Background” 按钮。

好了，完成了。

现在你可以进行[安装 Ubuntu 系统](https://www.2daygeek.com/how-to-install-ubuntu-16-04/)了。但是，它也提供了一个 live 模式，如果你想在安装之前尝试，那么可以使用它。

---

via: <https://www.2daygeek.com/create-a-bootable-live-usb-drive-from-windows-using-universal-usb-installer/>

作者：[Prakash Subramanian](https://www.2daygeek.com/author/prakash/) 选题：[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/) 荣誉推出