3 个控制预算的开源工具

Summary: 在这篇开源预算工具汇总中找到适合你的解决方案。另外学习有关开源的备税务软件。

在这篇开源预算工具汇总中找到适合你的解决方案。另外学习有关开源的备税务软件。

>
> 在这篇开源预算工具汇总中找到适合你的解决方案。另外学习有关开源的备税务软件。
>
>
>

![](/data/attachment/album/202004/05/092735ni323vgji9sbigq9.jpg)

鉴于目前世界上许多国家/地区的经济形势都在变化，你可能会想改造或改善财务状况和你对它的了解。或者，也许你的新年决心之一是开始预算？你并不孤单。

坚持该决心的最佳方法是定期跟踪你的支出和收入。问题是，许多流行的个人理财应用都是专有的。你是否正在寻找 Quicken、Mint 或 You Need a Budget 的开源替代方案？无论你是开源软件新手，还是预算新手，这些工具之一都将满足你的需求和舒适度。

### LibreOffice Calc

我向希望做预算的任何开源新手推荐使用 LibreOffice Calc。如果你使用过 Google Sheets 或 Microsoft Excel 等专有电子表格，那么 LibreOffice Calc 模板将非常熟悉。在此[预算教程](https://opensource.com/article/20/3/libreoffice-open-source-budget)中，作者 Jess Weichler 已经为你提供了方便、可下载的模板。该模板已经有费用类别，例如水电费、杂货、外出就餐等，但是你可以自由地根据自己的生活方式对其进行自定义。在第二篇文章中，她向你展示了如何[创建自己的模板](https://opensource.com/article/20/3/libreoffice-templates)。

### HomeBank

对于所有的开源用户来说，HomeBank 都是另一个不错的选择。HomeBank 是免费的，但它拥有许多它同类专有软件的分析和交易功能。实际上，你可以将 Quicken 文件导入到 HomeBank 中，这使得转换到它变得轻而易举。最后，你可以使用一种工具来帮助你明智地做出有关资金的决定，而无需花费更多的钱。在 Jessica Cherry 的[教程](https://opensource.com/article/20/2/open-source-homebank)中学习如何入门。

### GnuCash

就像这里提到的其他预算工具一样，GnuCash 可以在 Windows、macOS 和 Linux 上使用。它提供了大量文档，但 Don Watkins 会在[此教程](https://opensource.com/article/20/2/gnucash)中指导你在 Linux 上设置 GnuCash。GnuCash 不仅是控制个人财务的绝佳选择，而且还有开发票等功能来帮助你管理小型企业。

### 赠品：OpenTaxSolver

对许多美国人来说，可怕的税收季可能是一个压力很大的时期。许多人购买 TurboTax 或请会计师或税务服务来缴税。与普遍的看法相反，开源的备税务软件是存在的！作者 Jessica Cherry 在[本文](https://opensource.com/article/20/2/open-source-taxes)中做了研究，并向读者介绍 OpenTaxSolver。要正确使用 OpenTaxSolver，你需要特别注意细节，但是你不必担心进行复杂的数学运算。

你会尝试使用哪个开源预算应用？你是否有我在此列表中未提及的最喜欢的工具？请在评论区分享你的观点。

---

via: <https://opensource.com/article/20/3/open-source-budget>

作者：[Lauren Pritchett](https://opensource.com/users/lauren-pritchett) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在基于 Ubuntu 的发行版上安装微软 TrueType 字体

Summary: 如果你在 Linux 上用 LibreOffice 打开一些微软文档，你会发现字体看起来有一点不同。你也将注意到有些常用字体找不到，如 Times New Roman、Arial 等等。

如果你在 Linux 上用 LibreOffice 打开一些微软文档，你会发现字体看起来有一点不同。你也将注意到有些常用字体找不到，如 [Times New Roman](https://en.wikipedia.org/wiki/Times_New_Roman)、Arial 等等。

不用担心。我将向你展示如何在 Ubuntu 上和其它基于 Ubuntu 的 Linux 发行版上安装这些字体。但是在此之前，让我告诉你为什么这些字体没有被默认安装。

### 为什么微软字体不被默认安装在 Linux 中？

![](/data/attachment/album/202004/05/100617f53zekt8833t5b3u.png)

Times New Roman、Arial 等字体都是微软的，并且这些字体不是开源的。很多 Linux 发行版默认不提供专有软件，以避免授权问题。

这就是为什么在默认情况下 Ubuntu 和其它 Linux 发行版使用开源字体 “Liberation” 字体来替代微软字体的原因。[Red Hat](https://en.wikipedia.org/wiki/Red_Hat) 创建 [Liberation 字体](https://en.wikipedia.org/wiki/Liberation_fonts) 来代替 Arial、Arial Narrow、 Times New Roman 和 Courier New，因为这些字体的宽度一样。当你打开一个使用 Times New Roman 字体书写的文档时，会使用对应的 Liberation 字体来保持文档不被破坏。

不过，Liberation 字体与微软的字体并不是完全相同的，在一些情况下，你可能需要使用 Arial 或 Times New Roman。一个非常常见的情况是，在学校、大学和其他公共或私人机构中，微软的字体是唯一的选择。他们要求你使用这些字体之一来提交文档。

好在，你可以在 Ubuntu 和其它发行版上很容易地安装微软字体。以这种方式，你将增强 LibreOffice 的兼容性，并可以自由选择开源办公软件。

### 在基于 Ubuntu 的 Linux 发行版上安装微软字体

你可以自行下载字体，并[在 Ubuntu 中安装新的字体](https://itsfoss.com/install-fonts-ubuntu/)。但是由于微软字体非常受欢迎（并且是免费提供的），所以 Ubuntu 提供了一种简单的方法来安装它们。

要知道尽管微软已经免费发布了其核心字体，在其它操作系统中使用该字体依然是受到限制的。在 Ubuntu 中安装微软字体前，你必须阅读并接受 EULA (最终用户许可协议) 。

这些字体 [可在 multiverse 存储库中获得，首先要确保启用它](https://itsfoss.com/ubuntu-repositories/)：

```
sudo add-apt-repository multiverse
```

在此之后，你可以更新你的 Ubuntu 存储库缓存，并像这样安装微软字体：

```
sudo apt update && sudo apt install ttf-mscorefonts-installer
```

当微软的最终用户协议出现时，按 `tab` 键来选择 “OK” ，并按回车键。

![](/data/attachment/album/202004/05/100739fm17hnnn75cf7znc.png)

单击 “Yes” 来接受微软的协议：

![](/data/attachment/album/202004/05/100755x1uz1al1l1v88w80.png)

当安装完成后，你应该使用下面的命令来更新字体缓存：

```
sudo fc-cache -f -v
```

![](/data/attachment/album/202004/05/100810vxmeea6phx6sp0wh.png)

如果你现在打开 LibreOffice ，你将看到微软 [TrueType 字体](https://en.wikipedia.org/wiki/TrueType) 。

![](/data/attachment/album/202004/05/100825o5z8ui1ub428fi8q.png)

如果意外地拒绝了许可协议，你可以使用这个命令来重新安装安装程序：

```
sudo apt install –reinstall ttf-mscorefonts-installer
```

微软的 TrueType 字体也可以通过 [Ubuntu Restricted Extras package](https://itsfoss.com/install-media-codecs-ubuntu/) 获得，其包含用来播放 MP3 等文件的其它专有的多媒体编解码器。

>
> 不要轻视专有字体。
>
>
> 你可能认为字体有什么大不了的呢？毕竟，它只是一款字体，而不是软件的一个关键部分，对吧？但是你知道，这些年来 [Netflix 为其使用的专有字体支付了数百万美元](https://thehustle.co/nextflix-sans-custom-font/)吗？最后，他们创建了自己的自定义字体，这为他们节省了一大笔钱。
>
>
>

希望这个快速教程有用。更多的生产力教程即将上线，请在下面留下你的评论，了解更多信息请订阅我们的社交媒体！

---

via: <https://itsfoss.com/install-microsoft-fonts-ubuntu/>

作者：[Dimitrios Savvopoulos](https://itsfoss.com/author/itsfoss/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[robsean](https://github.com/robsean) 校对：[wxy](https://github.com/wxy)

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


为什么使用 GraphQL？

Summary: 以下是 GraphQL 在标准 REST API 技术上获得发展的原因。

以下是 GraphQL 在标准 REST API 技术上获得发展的原因。

>
> 以下是 GraphQL 在标准 REST API 技术上获得发展的原因。
>
>
>

![](/data/attachment/album/202004/05/105820rdnjrppprjdjddfd.jpg)

正如我[以前](/article-12070-1.html)所写，[GraphQL](https://graphql.org/) 是一种下一代 API 技术，它正在改变客户端应用程序与后端系统的通信方式以及后端系统的设计方式。

由于一开始就从创建它的组织 Facebook 获得了支持，并得到了其他技术巨头（如 Github、Twitter 和 AirBnB）的支持，因此 GraphQL 作为应用程序系统的关键技术的地位似乎是稳固的 —— 无论现在还是将来。

### GraphQL 的崛起

移动应用程序性能和组织敏捷性重要性的提高为 GraphQL 登上现代企业体系结构的顶端提供了助推器。

鉴于 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) 是一种非常流行的体系结构风格，早已提供了数据交互机制，与 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) 相比，GraphQL 这项新技术具有哪些优势呢？GraphQL 中的 “QL” 代表着查询语言，而这是一个很好的起点。

借助 GraphQL，组织内的不同客户端应用程序可以轻松地仅查询所需数据，这一点超越了其它 REST 方法，并带来了实际应用程序性能的提高。使用传统的 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API 端点，客户端应用程序将详询服务器资源，并接受包含了与请求匹配的所有数据的响应。如果来自 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API 端点的成功响应返回 35 个字段，那么客户端应用程序就会收到 35 个字段。

### 获取的问题

传统上，[REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API 没有为客户端应用程序提供简便的方法来仅检索或只更新它们关心的数据。这通常被描述为“<ruby> 过度获取 <rt>  over-fetching </rt></ruby>”的问题。随着移动应用程序在人们的日常生活中的普遍使用，过度获取问题会给现实世界带来不良后果。移动应用程序发出的每个请求、每一个字节的接受和发送，对终端用户的性能影响越来越大。数据连接速度较慢的用户尤其会受到不太好的 API 设计方案的影响。使用移动应用程序而性能体验不佳的客户更有可能不购买产品或不使用服务。低效的 API 设计只会浪费企业的钱。

并非只有“过度获取”是问题，“欠缺获取”同样也是问题。默认情况下，端点只返回客户端实际需要的部分数据，这需要客户端进行额外的调用以满足其数据需求，这就产生了额外的 HTTP 请求。由于过度和欠缺的获取问题及其对客户端应用程序性能的影响，促进有效获取的 API 技术才有机会在市场上引起轰动 —— GraphQL 大胆地介入并填补了这一空白。

### REST 的应对

[REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API 设计师不甘心不战而退，他们试图通过以下几种方式来应对移动应用程序性能问题：

* “包含”和“排除”查询参数，允许客户端应用程序通过可能较长的查询格式来指定所需的字段。
* “复合”服务，将多个端点组合在一起，以使客户端应用程序在其发出的请求数量和接收到的数据方面更高效。 尽管这些模式是 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API 社区为解决移动客户端所面临的挑战而做出的英勇尝试，但它们在以下几个关键方面仍存在不足：
* 包含和排除查询键/值对很快就会变得混乱，特别是对于需要用嵌套“点表示法”语法（或类似方法）以对目标数据进行包含和排除的深层对象图而言，更是如此。此外，在此模型中调试查询字符串的问题通常需要手动分解 URL。
* 包含和排除查询的服务器的实现往往是自定义的，因为基于服务器的应用程序没有标准的方式来处理包含和排除查询的使用，就像没有定义包含和排除查询的标准方式一样。
* 复合服务的兴起形成了更加紧密耦合的后端和前端系统，这就需要加强协调以交付项目，并且将曾经的敏捷项目转回瀑布式开发。这种协调和耦合还有一个痛苦的副作用，那就是减宦了组织的敏捷性。此外，顾名思义，组合服务不是 RESTful。

### GraphQL 的起源

对于 Facebook 来说，从其 2011-2012 年基于 HTML5 版本的旗舰移动应用程序中感受到的痛点和体验，才造就了 GraphQL。Facebook 工程师意识到提高性能至关重要，因此意识到他们需要一种新的 API 设计来确保最佳性能。可能考虑到上述 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) 的局限性，并且需要支持许多 API 客户端的不同需求，因此人们可以理解是什么导致其共同创建者 Lee Byron 和 Dan Schaeffer（那时尚是 Facebook 员工）创建了后来被称之为 GraphQL 的技术的早期种子。

通过 GraphQL 查询语言，客户端（通常是单个 GraphQL 端点）应用程序通常可以显著减少所需的网络调用数量，并确保仅检索所需的数据。在许多方面，这可以追溯到早期的 Web 编程模型，在该模型中，客户端应用程序代码会直接查询后端系统 —— 比如说，有些人可能还记得 10 到 15 年前在 JSP 上用 JSTL 编写 SQL 查询的情形吧！

现在最大的区别是使用 GraphQL，我们有了一个跨多种客户端和服务器语言和库实现的规范。借助 GraphQL 这样一种 API 技术，我们通过引入 GraphQL 应用程序中间层来解耦后端和前端应用程序系统，该层提供了一种机制，以与组织的业务领域相一致的方式来访问组织数据。

除了解决软件工程团队遇到的技术挑战之外，GraphQL 还促进了组织敏捷性的提高，特别是在企业中。启用 GraphQL 的组织敏捷性通常归因于以下因素：

* GraphQL API 设计人员和开发人员无需在客户端需要一个或多个新字段时创建新的端点，而是能够将这些字段包含在现有的图实现中，从而以较少的开发工作量和跨应用程序系统的较少更改的方式展示出新功能。
* 通过鼓励 API 设计团队将更多的精力放在定义对象图上，而不是在专注于客户端应用程序交付上，前端和后端软件团队为客户交付解决方案的速度日益解耦。 ### 采纳之前的注意事项

尽管 GraphQL 具有引人注目的优势，但 GraphQL 并非没有实施挑战。一些例子包括：

* 为 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API 建立的缓存机制更加成熟。
* 使用 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) 来构建 API 的模式更加完善。
* 尽管工程师可能更喜欢 GraphQL 等新技术，但与 GraphQL 相比，市场上的人才库更多是从事于构建基于 [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) 的解决方案。

### 结论

通过同时提高性能和组织敏捷性，GraphQL 在过去几年中被企业采纳的数量激增。但是，与 API 设计的 RESTful 生态系统相比，它确实还需要更成熟一些。

GraphQL 的一大优点是，它并不是作为替代 API 解决方案的批发替代品而设计的。相反，GraphQL 可以用来补充或增强现有的 API。因此，鼓励企业探索在 GraphQL 对其最有意义的地方逐步采用 GraphQL —— 在他们发现它对应用程序性能和组织敏捷性具有最大的积极影响的地方。

---

via: <https://opensource.com/article/19/6/why-use-graphql>

作者：[Zach Lendon](https://opensource.com/users/zachlendon/users/goncasousa/users/patrickhousley) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


如何在 Ubuntu Linux 上安装 Oracle Java 14

![](/data/attachment/album/202004/05/205313e188lsbrbgz9932d.jpg)

最近，Oracle 宣布 Java 14（或 Oracle JDK 14）公开可用。如果你想进行最新的实验或者开发的话，那么你可以试试在 Linux 系统上安装 Java 14。

Oracle JDK 14（或简称 Java 14）[发布版](https://www.oracle.com/corporate/pressrelease/oracle-announces-java14-031720.html)包含几个新功能，如果你想预览它们的话。我已添加了链接：

* [instanceof 的模式匹配](https://openjdk.java.net/jeps/305)
* [Records](https://openjdk.java.net/jeps/359)
* [Text Blocks](https://openjdk.java.net/jeps/368)

除预览功能外，它还包含一些改进和补充。在新闻中，他们还提到了其他改进：

>
> 此外，最新的 Java 版本增加了 Java 语言对 switch 表达式的支持，新增了用于持续监控 JDK Flight Recorder 数据的新 API，将低延迟 zgc 扩展到了 macOS 和 Windows，并添加在 incubator 模块中，独立的 Java 应用打包，以及为了安全、有效地访问 Java 堆外部内存的新的外部内存访问 API。
>
>
>

当然，如果你想深入了解细节，那么你应查看[官方公告](https://www.oracle.com/corporate/pressrelease/oracle-announces-java14-031720.html)。

在本教程中，我将向你展示在 Ubuntu 系统上安装 Java 14 的简便方法。请继续阅读。

**注意：**如果你选择使用 Oracle Java 11 或更高版本，那么应该了解新的 [Oracle 技术网络许可协议](https://www.oracle.com/technetwork/java/javase/overview/oracle-jdk-faqs.html)，以了解它如何影响个人用户、开发人员和商业组织。通常，它们可以免费用于开发和测试，但不能用于生产环境。

### 如何在 Ubuntu Linux 上安装 Java 14？

作为参考，我已成功在默认安装 **OpenJDK 11** 的 **Pop!\_OS 19.10** 上成功安装了它。

这里，我们将使用 [Linux Uprising](https://www.linuxuprising.com/2020/03/how-to-install-oracle-java-14-jdk14-on.html) 的 Java 14 安装程序（最初基于 WebUpd8 Java 软件包）。

只需在终端中输入以下命令即可进行安装：

```
sudo add-apt-repository ppa:linuxuprising/java
sudo apt update
sudo apt install oracle-java14-installer
```

这应该就完成了，如果你想将它设为默认，那么你可以输入以下命令：

```
sudo apt install oracle-java14-set-default
```

值得注意的是，这仅适用于基于 Ubuntu 的发行版。如果要在 Debian 和其他 Linux 发行版上安装它，那么也可以按照 [Linux Uprising 中的详细指南](https://www.linuxuprising.com/2020/03/how-to-install-oracle-java-14-jdk14-on.html)安装 Java 14。

### 总结

当然，这些会带来最新的特性，如果你不想破环原有环境，你或许会希望继续使用 Java 11。如果你想在了解风险的情况下进行试验，请继续尝试！

欢迎在下面的评论中让我知道你对 Java 14 的想法。

---

via: <https://itsfoss.com/java-14-ubuntu/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[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/) 荣誉推出


提升你的 Vim 技能的 5 个方法

Summary: 通过一些有趣的小技巧使你的文本编辑器更上一层楼。

VIM的水平，需要反复练习，多家琢磨才能提高；通常，实现一个功能，可以有很多种方法。

通过一些有趣的小技巧使你的文本编辑器更上一层楼。

>
> 通过一些有趣的小技巧使你的文本编辑器更上一层楼。
>
>
>

![](/data/attachment/album/202004/05/232434x1hnzlnhcnm3nrc7.jpg)

Vim 是最受欢迎的文本编辑器之一，因此绝对值得你花时间去学习如何使用它。就算你只是学习使用这个无处不在的 [Vi(m)](https://www.vim.org/) 命令行文本编辑器打开文件、输入和编辑一些文本、保存编辑的文件并退出程序，你都会受益匪浅。

你会发现，使用 Vim 非常方便的的场景几乎总是涉及到运行远程 Shell 操作的任务。如果你时不时地使用 ssh，比如

```
$ ssh user@hostname.provider.com
```

并在虚拟专用服务器（VPS）或本地虚拟化容器中工作，那么就可以从这些强大的 Vim 技能中受益匪浅。

### 将 Vim 设置为默认的文本编辑器

几乎所有的现代 Linux（或 BSD）发行版中，都可以在终端仿真器的 shell 命令提示符下使用 Vim。一旦在你的用户 shell 程序中将 Vim 定义为默认编辑器后，那么就可以使用熟悉的 Vim 键绑定来在内置的实用程序（例如 `man`）中导航。我将说明如何使用 Bash 和 Z shell（zsh）来实现此目的，zsh 现在是 macOS 用户的默认 shell（自 Catalina 起）。

#### 在 Bash 中将 Vim 设置为默认

Bash 通过点文件的组合来管理设置。最常见的的做法将你的编辑器添加到主目录中的 `.bashrc` 文件中，但也可以将其添加到 `.bash_profile` 中。（请阅读 [GNU Bash 文档](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html)了解两者的不同之处）。

通过在 `~/.bashrc` 中添加以下内容，将 Vim 设置为默认编辑器：

```
# set default editor to Vim
export EDITOR=vim
```

以 `#` 开头的行是可选的注释，这是一个好方法，可以提醒自己该命令的作用。

#### 在 zsh 中将 Vim 设置为默认

zsh 是一种越来越流行的终端仿真器，尤其是在苹果公司的基于 FreeBSD 的 Darwin 系统最近从 Bash 转向 zsh 以来。

zsh 点文件与 Bash 的文件相当，因此你可以在 `~/.zshrc` 或 `~/.zprofile` 之间进行选择。有关何时使用哪一个的详细信息，请参见 [zsh文档](http://zsh.sourceforge.net/Intro/intro_3.html)。

将其设置为默认：

```
# set default editor to Vim
export EDITOR=vim
```

### 优化 Vim 配置

Vim 像是终端仿真器 shell 一样，也使用点文件来设置个人偏好。如果你发现了这种模式，则可能已经猜到它是 `~/.vimrc`。

你可能要更改的第一个设置是将对传统的 Vi 兼容模式切换为“关闭”。由于 Vim 是 Vi 的超集，因此 Vi 中的所有功能在 Vim 中都是可用的，并且在 Vim 中得到了很大的改进，你可以获得许多高级功能。最新版本（8.2）允许你在分割的窗口中以子进程 shell 的方式打开一个终端。

顺便说一句，明确关闭对传统的 Vi 的兼容性看起来没有什么作用（[事实上，可能并没有什么作用](http://vimdoc.sourceforge.net/htmldoc/starting.html#compatible-default)）。当 Vim 遇到 `.vimrc` 文件时，它会暗暗地自动将兼容模式切换到关闭。但有时将其明确关闭仍然很重要。缩写 `nocp` 是 `nocompatible` 的同义词，作用是一样的。[条条大道通罗马](https://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it)，切换首选项有很多方式。

在 `.vimrc` 语法中， 以 `"` 开头的行是注释（就像 `.bashrc` 文件中的 `#` 一样），这些注释可以帮助你记住诸如为何选择了一个隐晦的设置名称之类的内容。

要关闭 Vi 兼容性，请将以下内容添加到 `~/.vimrc` 文件中：

```
" ensure that legacy compatibility mode is off
" documentation: <http://vimdoc.sourceforge.net/htmldoc/options.html\#'compatible>'
set nocp
```

### 理解模式

Vim 的 “模式”概念是非常重要的，尤其是“普通模式”和“插入模式”之间的区别。对模式的混淆是大多数新用户的困扰。模式并不是 Vim 所独有的，甚至也不是 Vi 所引入的。命令模式是如此的古老，以至于它比 70 年代发明的[复制和粘贴](https://www.npr.org/2020/02/22/808404858/remembering-the-pioneer-behind-your-computers-cut-copy-and-paste-functions)功能还要早。

#### 重要的模式

Vim 依赖于不同的模式来定义键盘的敲击行为。需要了解的重要模式有：

* 普通模式：默认模式，主要用于导航和打开文件。
* 插入模式（包括替换）：这种模式下 Vim 允许将文本输入到打开的文件中。
* 可视模式：Vim 的行为类似于基于鼠标的输入方式，如复制、编辑、替换等。
* 命令模式（包括行模式、Ex 命令模式和末行模式）：是在 Vim 中做更多事情的强大方法。

每种模式都有很多值得探索的地方。使用 [Vimtutor](http://www2.geog.ucl.ac.uk/%7Eplewis/teaching/unix/vimtutor)（`vimtutor`）可以交互式地学习移动光标、模式和在末行模式下运行 Ex 命令。一些不可缺少的生产力操作符包括：

| 操作符 | 说明 |
| --- | --- |
| `:E` | 打开资源管理器，用于定位文件和目录。 |
| `.` | 重复上次的编辑操作。 |
| `;` | 向前重复上一次的动作或移动 |
| `,` | 向后重复上一次的动作或移动。 |
| `/` | 向前搜索文档。 |
| `?` | 向后搜索文档。 |
| `*` | 查找光标所在处的单词的下一个出现的地方。 |
| `#` | 查找光标所在处的单词的上一次出现的地方。 |
| `~` | 切换大小写。 |
| `%` | 在 `()`、`[]` 和 `{}` 的开闭符号之间切换；对编码非常有用。 |
| `z=` | 提出拼写建议。 |

### 像钢琴一样弹奏 Vim

尽管把 Vim 的操作符“语言”记在记忆中是很重要的，但要想掌握它，难点在于学会像音乐家一样思考，把操作符和动作组合成“和弦”，这样你就可以像弹钢琴一样弹奏 Vim。这就是 Vim 的文本操作能力可以与另一个著名的命令行编辑器 Emacs 相媲美的地方。（虽然其中一个编辑器会让磨损掉你的 `Esc` 键，而另一个编辑器会让你的 `Ctrl` 键磨损掉。）

在描述键“和弦”时，Vim 中的传统做法是用大写字母 C 后面加上一个连字符（`C-`）来指代 `Ctrl` 键。这并不是通用的，但我将从这里开始遵循这一惯例，并在有可能引起混淆的时候加以说明。

如果你在 Vim 中键入长行，你会想把它设置成可以换行。想要根据你的工作方式对 Vim 进行个性化设置，请考虑一下这个设置：默认情况下，你希望 Vim 启动时如何处理文本换行？开还是关？我喜欢将其关闭，并将其留在运行命令文件之外。当我想让文本自动换行时，我只需在命令行模式下用 `:set wrap` 设置即可。

让 Vim 设置为默认情况下自动换行并没有错，这只是一个偏好问题 —— 它可能随着时间的推移而改变。同样你也可以控制粘贴、代码语言缩进语法和 `Tab` 键的设置（制表符还是空格？多少个空格？可也在[这里](https://opensource.com/article/18/9/vi-editor-productivity-powerhouse)深入研究这些选项）。所有这些默认行为的选项都是完全可配置和可更改的，并且在你使用命令行模式操作时可以实时更改。

你会在社区论坛、Vim 维基和文章（比如这篇文章）中找到很多关于设置 Vim 默认设置的建议。你应该很熟悉为你的个人计算环境设置首选项，Vim 也不例外。我强烈建议你从对设置进行很小的更改开始，慢慢地进行其它更改，以便你可以轻松地恢复设置。这样一来，你就可以好多年避免使用插件或完全不用插件。

### Vim 8.2 中的分割、标签和终端

有两种方法可以将你正在处理的文件分割成不同的视图：它们可以并排显示，也可以使用应用程序标签页在全屏（窗口）中切换。这些对应用程序窗口的更改是从命令模式启动的，这需要使用冒号（`:`）来调起提示符。

每个分割的窗口可以容纳一个文件进行编辑，你可以通过标签页在更多的文件之间随意切换。分割的屏幕空间有限，所以当你想分割更多的屏幕时，标签页是很方便的。想要如何设置，纯属个人喜好的问题。要水平分割一个窗口，使用 `:sp`，垂直分割时使用 `:vs`。

从 [Vim 8.2](https://www.vim.org/vim-8.2-released.php) 开始，你可以用 `:vert term` 打开一个垂直分割的终端 shell 子进程，以在你的代码旁边的命令行上进行操作。你需要键入 `exit` 来关闭你的终端进程，就像你结束一个 shell 会话一样，但你关闭这个分割的窗口和标签页的方式和关闭任何普通的 Vim 窗口一样，要用 `:q` 来关闭。

要初始化一个标签页，请使用一个特殊的编辑命令：`:tabedit`，它会自动切换到新打开的标签页。如果你给该命令一个文件名作为参数，会打开该文件并进行编辑。如果你忽略了给它一个文件名作为参数，可以在命令行模式下的使用编辑命令 `:e filename.txt`，就像在任何一个普通的 Vim 窗口中一样。可以使用下一个（`:tabn`）和上一个（`:tabp`）命令在标签页间导航。

要使用分割，你需要知道如何使用组合键 `C-w` 和你想要移动的方向的移动键，例如左（`h`）、下（`j`）、左（`k`）、右（`l`）。如果你想学习更多的组合键，请阅读 Vim 手册中的 `:help split` 和 `:help tabpage`。

### 获取帮助

虽然可以在 Vimtutor 中打开参考 Vim 手册，但用 `:help` 打开 Vim 帮助，可以让你自己把时间花在编辑器上，不用完全依赖像这样的文章，就能获得更多的成果。经验是掌握 Vim 的关键。经验有助于提高你的整体计算直觉，因为 Vim 中的很多东西都是从 Unix 宇宙中汲取的。

祝你在探索 Vim 之美的过程中玩得开心，有什么问题可以在评论中分享。

---

via: <https://opensource.com/article/20/3/vim-skills>

作者：[Detlef Johnson](https://opensource.com/users/deckart) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


Linux 防火墙 ufw 简介

>
> 我们来研究下 Linux 上的 ufw（简单防火墙），为你更改防火墙提供一些见解和命令。
>
>
>

![](/data/attachment/album/202004/06/214125xi69it9e95ke9hei.jpg)

`ufw`（<ruby> 简单防火墙 <rt>  Uncomplicated FireWall </rt></ruby>）真正地简化了 [iptables](https://www.networkworld.com/article/2716098/working-with-iptables.html)，它从出现的这几年，已经成为 Ubuntu 和 Debian 等系统上的默认防火墙。而且 `ufw` 出乎意料的简单，这对新管理员来说是一个福音，否则他们可能需要投入大量时间来学习防火墙管理。

`ufw` 也有 GUI 客户端（例如 `gufw`），但是 `ufw` 命令通常在命令行上执行的。本文介绍了一些使用 `ufw` 的命令，并研究了它的工作方式。

首先，快速查看 `ufw` 配置的方法是查看其配置文件 —— `/etc/default/ufw`。使用下面的命令可以查看其配置，使用 `grep` 来抑制了空行和注释（以 # 开头的行）的显示。

```
$ grep -v '^#\|^$' /etc/default/ufw
IPV6=yes
DEFAULT_INPUT_POLICY="DROP"
DEFAULT_OUTPUT_POLICY="ACCEPT"
DEFAULT_FORWARD_POLICY="DROP"
DEFAULT_APPLICATION_POLICY="SKIP"
MANAGE_BUILTINS=no
IPT_SYSCTL=/etc/ufw/sysctl.conf
IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"
```

正如你所看到的，默认策略是丢弃输入但允许输出。允许你接受特定的连接的其它规则是需要单独配置的。

`ufw` 命令的基本语法如下所示，但是这个概要并不意味着你只需要输入 `ufw` 就行，而是一个告诉你需要哪些参数的快速提示。

```
ufw [--dry-run] [options] [rule syntax]
```

`--dry-run` 选项意味着 `ufw` 不会运行你指定的命令，但会显示给你如果执行后的结果。但是它会显示假如更改后的整个规则集，因此你要做有好多行输出的准备。

要检查 `ufw` 的状态，请运行以下命令。注意，即使是这个命令也需要使用 `sudo` 或 root 账户。

```
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       192.168.0.0/24
9090                       ALLOW       Anywhere
9090 (v6)                  ALLOW       Anywhere (v6)
```

否则，你会看到以下内容：

```
$ ufw status
ERROR: You need to be root to run this script
```

加上 `verbose` 选项会提供一些其它细节：

```
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         ALLOW IN    192.168.0.0/24
9090                       ALLOW IN    Anywhere
9090 (v6)                  ALLOW IN    Anywhere (v6)
```

你可以使用以下命令轻松地通过端口号允许和拒绝连接：

```
$ sudo ufw allow 80         <== 允许 http 访问
$ sudo ufw deny 25              <== 拒绝 smtp 访问
```

你可以查看 `/etc/services` 文件来找到端口号和服务名称之间的联系。

```
$ grep 80/ /etc/services
http            80/tcp          www             # WorldWideWeb HTTP
socks           1080/tcp                        # socks proxy server
socks           1080/udp
http-alt        8080/tcp        webcache        # WWW caching service
http-alt        8080/udp
amanda          10080/tcp                       # amanda backup services
amanda          10080/udp
canna           5680/tcp                        # cannaserver
```

或者，你可以命令中直接使用服务的名称。

```
$ sudo ufw allow http
Rule added
Rule added (v6)
$ sudo ufw allow https
Rule added
Rule added (v6)
```

进行更改后，你应该再次检查状态来查看是否生效：

```
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       192.168.0.0/24
9090                       ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere         <==
443/tcp                    ALLOW       Anywhere         <==
9090 (v6)                  ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)    <==
443/tcp (v6)               ALLOW       Anywhere (v6)    <==
```

`ufw` 遵循的规则存储在 `/etc/ufw` 目录中。注意，你需要 root 用户访问权限才能查看这些文件，每个文件都包含大量规则。

```
$ ls -ltr /etc/ufw
total 48
-rw-r--r-- 1 root root 1391 Aug 15  2017 sysctl.conf
-rw-r----- 1 root root 1004 Aug 17  2017 after.rules
-rw-r----- 1 root root  915 Aug 17  2017 after6.rules
-rw-r----- 1 root root 1130 Jan  5  2018 before.init
-rw-r----- 1 root root 1126 Jan  5  2018 after.init
-rw-r----- 1 root root 2537 Mar 25  2019 before.rules
-rw-r----- 1 root root 6700 Mar 25  2019 before6.rules
drwxr-xr-x 3 root root 4096 Nov 12 08:21 applications.d
-rw-r--r-- 1 root root  313 Mar 18 17:30 ufw.conf
-rw-r----- 1 root root 1711 Mar 19 10:42 user.rules
-rw-r----- 1 root root 1530 Mar 19 10:42 user6.rules
```

本文前面所作的更改，为 `http` 访问添加了端口 `80` 和为 `https` 访问添加了端口 `443`，在 `user.rules` 和 `user6.rules` 文件中看起来像这样：

```
# grep " 80 " user*.rules
user6.rules:### tuple ### allow tcp 80 ::/0 any ::/0 in
user6.rules:-A ufw6-user-input -p tcp --dport 80 -j ACCEPT
user.rules:### tuple ### allow tcp 80 0.0.0.0/0 any 0.0.0.0/0 in
user.rules:-A ufw-user-input -p tcp --dport 80 -j ACCEPT
You have new mail in /var/mail/root
# grep 443 user*.rules
user6.rules:### tuple ### allow tcp 443 ::/0 any ::/0 in
user6.rules:-A ufw6-user-input -p tcp --dport 443 -j ACCEPT
user.rules:### tuple ### allow tcp 443 0.0.0.0/0 any 0.0.0.0/0 in
user.rules:-A ufw-user-input -p tcp --dport 443 -j ACCEPT
```

使用 `ufw`，你还可以使用以下命令轻松地阻止来自一个 IP 地址的连接：

```
$ sudo ufw deny from 208.176.0.50
Rule added
```

`status` 命令将显示更改：

```
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         ALLOW IN    192.168.0.0/24
9090                       ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
Anywhere                   DENY IN     208.176.0.50             <== new
9090 (v6)                  ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
443/tcp (v6)               ALLOW IN    Anywhere (v6)
```

总而言之，`ufw` 不仅容易配置，而且且容易理解。

---

via: <https://www.networkworld.com/article/3533551/linux-firewall-basics-with-ufw.html>

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


使用 Traefik 引导 Kubernetes 流量

Summary: 将流量引入 Kubernetes 树莓派集群的分步指南。

将流量引入 Kubernetes 树莓派集群的分步指南。

>
> 将流量引入 Kubernetes 树莓派集群的分步指南。
>
>
>

![](/data/attachment/album/202004/07/103035brocaxwcimcinza0.jpg)

在本文中，我们将部署几个简单的网站，并学习如何使用 Traefik 将来自外部世界的流量引入到我们的集群中。之后，我们还将学习如何删除 Kubernetes 资源。让我们开始吧！

### 准备

要继续阅读本文，你只需要我们在上一篇文章中构建的 [k3s 树莓派集群](/article-12049-1.html)。由于你的集群将从网络上拉取镜像，因此该集群需要能够访问互联网。

出于解释目的，本文将显示一些配置文件和示例 HTML 文件。所有示例文件都可以在[此处](https://gitlab.com/carpie/ingressing_with_k3s/-/archive/master/ingressing_with_k3s-master.zip)下载。

### 部署一个简单的网站

之前，我们使用 `kubectl` 进行了直接部署。但是，这不是典型的部署方法。一般情况都会使用 YAML 配置文件，这也是我们要在本文中使用的配置文件。我们将从顶部开始，并以自顶向下的方式创建该配置文件。

### 部署配置

首先是部署配置。配置如下所示，并在下面进行说明。我通常以 [Kubernetes 文档](https://kubernetes.io/docs/)中的示例为起点，然后根据需要对其进行修改。例如，下面的配置是复制了[部署文档](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment)中的示例后修改的。

创建一个文件 `mysite.yaml`，其内容如下：

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysite-nginx
  labels:
    app: mysite-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysite-nginx
  template:
    metadata:
      labels:
        app: mysite-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
```

其中大部分是样板。重要的部分，我们会将该部署命名为 `mysite-nginx`，并为其加上同名的 `app` 标签。我们指定了一个<ruby> 副本 <rt>  replica </rt></ruby>，这意味着将只创建一个 Pod。我们还指定了一个容器，我们将其命名为 `nginx`。我们将<ruby> 镜像 <rt>  image </rt></ruby>指定为 `nginx`。这意味着在部署时，k3s 将从 DockerHub 下载 `nginx` 镜像并从中创建一个 Pod。最后，我们指定了<ruby> 容器端口 <rt>  containerPort </rt></ruby>为 `80`，这只意味着在容器内部 Pod 会监听 `80` 端口。

我在上面强调了“在容器内部”，因为这是一个重要的区别。由于我们是按容器配置的，因此只能在容器内部访问它，并且进一步将其限制为内部网络。这对于允许多个容器在同一容器端口上监听所是必要的。换句话说，通过这种配置，其他一些 Pod 也可以在其容器端口 80 上侦听，并且不会与此容器冲突。为了提供对该 Pod 的正式访问权限，我们需要一个<ruby> 服务 <rt>  service </rt></ruby>配置。

### 服务配置

在 Kubernetes 中，<ruby> 服务 <rt>  service </rt></ruby>是一种抽象。它提供了一种访问 Pod 或 Pod 集合的方法。当连接到服务时，服务会路由到单个 Pod，或者如果定义了多个 Pod 副本，会通过负载均衡路由到多个 Pod。

可以在同一配置文件中指定该服务，这就是我们将在此处要做的。用 `---` 分隔配置区域，将以下内容添加到 `mysite.yaml` 中：

```
---
apiVersion: v1
kind: Service
metadata:
  name: mysite-nginx-service
spec:
  selector:
    app: mysite-nginx
  ports:
    - protocol: TCP
      port: 80
```

在此配置中，我们将服务命名为 `mysite-nginx-service`。我们提供了一个<ruby> 选择器 <rt>  selector </rt></ruby>：`app: mysite-nginx`。这是服务选择其路由到的应用程序容器的方式。请记住，我们为容器提供了 `app` 标签：`mysite-nginx` 。这就是服务用来查找我们的容器的方式。最后，我们指定服务协议为 `TCP`，在端口 `80` 上监听。

### 入口配置

<ruby> 入口 <rt>  Ingress </rt></ruby>配置指定了如何将流量从集群外部传递到集群内部的服务。请记住，k3s 预先配置了 Traefik 作为入口控制器。因此，我们将编写特定于 Traefik 的入口配置。将以下内容添加到 `mysite.yaml` 中（不要忘了用 `---` 分隔）：

```
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: mysite-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: mysite-nginx-service
          servicePort: 80
```

在此配置中，我们将入口记录命名为 `mysite-nginx-ingress`。我们告诉 Kubernetes，我们希望 `traefik` 成为我们的入口控制器，再加上 `kubernetes.io/ingress.class` 的注解。

在<ruby> 规则 <rt>  rules </rt></ruby>部分中，我们基本上是说，当 `http` 流量进入时，并且 `path` 匹配 `/`（或其下的任何内容），将其路由到由 `serviceName mysite-nginx-service` 指定的<ruby> 后端 <rt>  backend </rt></ruby>服务中，并将其路由到 `servicePort 80`。这会将传入的 HTTP 流量连接到我们之前定义的服务。

### 需要部署的东西

就配置而言，就是这样了。如果我们现在部署，我们将获得默认的 nginx 页面，但这不是我们想要的。让我们创建一些简单但可自定义的部署方式。创建具有以下内容的文件 `index.html`：

```
<html>
<head><title>K3S!</title>
  <style>
    html {
      font-size: 62.5%;
    }
    body {
      font-family: sans-serif;
      background-color: midnightblue;
      color: white;
      display: flex;
      flex-direction: column;
      justify-content: center;
      height: 100vh;
    }
    div {
      text-align: center;
      font-size: 8rem;
      text-shadow: 3px 3px 4px dimgrey;
    }
  </style>
</head>
<body>
  <div>Hello from K3S!</div>
</body>
</html>
```

我们尚未介绍 Kubernetes 中的存储机制，因此在这里我们偷懒一下，仅将该文件存储在 Kubernetes 配置映射中。这不是我们推荐的部署网站的方式，但对于我们的目的来说是可行的。运行以下命令：

```
kubectl create configmap mysite-html --from-file index.html
```

该命令从本地文件 `index.html` 创建名为 `mysite-html` 的<ruby> 配置映射 <rt>  configmap </rt></ruby>资源。这实际上是在 Kubernetes 资源中存储一个文件（或一组文件），我们可以在配置中调出该文件。它通常用于存储配置文件（因此而得名），我们在这里稍加滥用。在以后的文章中，我们将讨论 Kubernetes 中适当的存储解决方案。

创建配置映射后，让我们将其挂载在我们的 `nginx` 容器中。我们分两个步骤进行。首先，我们需要指定一个<ruby> 卷 <rt>  volume </rt></ruby>来调出配置映射。然后我们需要将该卷挂载到 `nginx` 容器中。通过在 `mysite.yaml` 中的 `container` 后面的 `spec` 标签下添加以下内容来完成第一步：

```
      volumes:
      - name: html-volume
        configMap:
          name: mysite-html
```

这告诉 Kubernetes 我们要定义一个名为 `html-volume` 的卷，并且该卷应包含名为 `html-volume`（我们在上一步中创建的）的配置映射的内容。

接下来，在 `nginx` 容器规范中的<ruby> 端口 <rt>  ports </rt></ruby>下方，添加以下内容：

```
        volumeMounts:
        - name: html-volume
          mountPath: /usr/share/nginx/html
```

这告诉 Kubernetes，对于 `nginx` 容器，我们想在容器中的 `/usr/share/nginx/html` 路径上挂载名为 `html-volume` 的卷。 为什么要使用 `/usr/share/nginx/html`？那个位置就是 `nginx` 镜像提供 HTML 服务的地方。通过在该路径上挂载卷，我们用该卷内容替换了默认内容。

作为参考，配置文件的 `deployment` 部分现在应如下所示：

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysite-nginx
  labels:
    app: mysite-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysite-nginx
  template:
    metadata:
      labels:
        app: mysite-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html-volume
        configMap:
          name: mysite-html
```

### 部署它！

现在我们准备部署！ 我们可以这样做：

```
kubectl apply -f mysite.yaml
```

你应该看到类似于以下内容：

```
deployment.apps/mysite-nginx created
service/mysite-nginx-service created
ingress.networking.k8s.io/mysite-nginx-ingress created
```

这意味着 Kubernetes 为我们指定的三个配置分别创建了资源。使用以下方法检查 Pod 的状态：

```
kubectl get pods
```

如果看到状态为 `ContainerCreating`，请给它一些时间并再次运行 `kubectl get pods`。通常，第一次会花一些时间，因为 k3s 必须下载 `nginx` 镜像来创建 Pod。一段时间后，你应该看到 `Running` 的状态。

### 尝试一下！

Pod 运行之后，就该尝试了。打开浏览器，然后在地址栏中输入 `kmaster`。

![](/data/attachment/album/202004/07/103528otyqtxqf6vfik6ik.jpg)

恭喜你！你已经在 k3s 集群上部署了一个网站！

### 另一个

因此，现在我们有了一个运行单个网站的整个 k3s 集群。但是我们可以有更多的网站！如果我们要在同一集群中提供另一个网站怎么办？让我们看看如何做到这一点。

同样，我们需要部署一些东西。碰巧我的狗有一条她想让全世界都知道的信息，她想了好久了。因此，我专门为她制作了一些 HTML（可从示例 zip 文件中获得）。同样，我们将使用配置映射的技巧来托管这些 HTML。这次我们将把整个目录（`html` 目录）放到配置映射中，但是调用是相同的。

```
kubectl create configmap mydog-html --from-file html
```

现在，我们需要为此站点创建一个配置文件。它几乎与用于 `mysite.yaml` 的完全相同，因此首先将 `mysite.yaml` 复制为 `mydog.yaml`。现在将 `mydog.yaml` 修改为：

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydog-nginx
  labels:
    app: mydog-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mydog-nginx
  template:
    metadata:
      labels:
        app: mydog-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html-volume
        configMap:
          name: mydog-html
---
apiVersion: v1
kind: Service
metadata:
  name: mydog-nginx-service
spec:
  selector:
    app: mydog-nginx
  ports:
    - protocol: TCP
      port: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: mydog-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "traefik"
    traefik.frontend.rule.type: PathPrefixStrip
spec:
  rules:
  - http:
      paths:
      - path: /mydog
        backend:
          serviceName: mydog-nginx-service
          servicePort: 80
```

我们只需进行搜索并将 `mysite` 替换为 `mydog`即可完成大多数修改。其他两个修改在入口部分中。我们将 `path` 更改为 `/mydog`，并添加了一个注解 `traefik.frontend.rule.type: PathPrefixStrip`。

`/mydog` 路径的规范指示 Traefik 将以 `/mydog` 路径开头的所有传入请求路由到 `mydog-nginx-service`。任何其他路径将继续路由到 `mysite-nginx-service`。

新的注解 `PathPrefixStrip` 告诉 Traefik 在将请求发送到 `mydog-nginx-service` 之前先去除前缀 `/mydog`。我们这样做是因为 `mydog-nginx` 应用程序不需要前缀。这意味着我们可以简单地通过更改入口记录中的前缀来更改挂载的服务的位置。

现在我们可以像以前一样进行部署：

```
kubectl apply -f mydog.yaml
```

现在，我的狗的消息应该可以在 <http://kmaster/mydog/> 上找到。

![](/data/attachment/album/202004/07/103533lxjvej94qcsebbm6.jpg)

呼！消息发出去了！也许今晚我们都可以睡一觉。

因此，现在，我们有了一个 k3s 集群，该集群托管了两个网站，Traefik 根据路径名决定将请求传递给哪个服务！但是，不仅限于基于路径的路由，我们也可以使用基于主机名的路由，我们将在以后的文章中进行探讨。

另外，我们刚刚托管的网站是标准的未加密 HTML 网站，而如今的所有内容都使用 SSL/TLS 加密。在我们的下一篇文章中，我们将为 k3s 集群添加支持以托管 SSL/TLS HTTPS 站点！

### 清理

在开始之前，由于本文主要涉及的是示例站点，因此我想向你展示如何删除内容，以防万一你不希望将这些示例丢在集群中。

对于大多数配置，只需使用与部署时使用的相同配置文件运行 `delete` 命令即可撤消配置。因此，让我们同时清理 `mysite` 和 `mydog`。

```
kubectl delete -f mysite.yaml
kubectl delete -f mydog.yaml
```

由于我们是手动创建配置映射的，因此我们也需要手动删除它们。

```
kubectl delete configmap mysite-html
kubectl delete configmap mydog-html
```

现在，如果我们执行 `kubectl get pods`，我们应该看到我们的 nginx Pod 不存在了。

```
$ kubectl get pods
No resources found in default namespace.
```

一切都清理了。

请在下面的评论中告诉我你对这个项目有什么想法。

---

via: <https://opensource.com/article/20/3/kubernetes-traefik>

作者：[Lee Carpenter](https://opensource.com/users/carpie) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


使用 Fluxbox 桌面作为你的窗口管理器

>
> 本文是 24 天 Linux 桌面特别系列的一部分。Fluxbox 对系统资源的占用非常轻量，但它拥有重要的 Linux 桌面功能，让你的用户体验轻松、高效、快捷。
>
>
>

![](/data/attachment/album/202004/07/113105p0ng5skkn5kmvdm0.jpg)

桌面的概念可谓是仁者见仁智者见智。很多人把桌面看作一个家的基地，或者一个舒适的客厅，甚至是一个字面意义上的桌面，在其中放置着他们经常使用的记事本、最好的笔和铅笔，还有他们最喜欢的咖啡杯。KDE、 GNOME、Pantheon 等等在 Linux 上提供了这种舒适的生活方式。

但是对一些用户来说，桌面只是一个空荡荡的显示器空间，这是还没有任何可以自由浮动的应用程序窗口直接投射到他们的视网膜上的副作用。对于这些用户来说，桌面是一个空的空间，他们可以在上面运行应用程序 —— 无论是大型办公软件和图形套件，还是一个简单的终端窗口，或是来管理服务的托盘小程序。这种操作 [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) 计算机的模式由来已久，该家族树的一支是 \*box 窗口管理器：Blackbox、Fluxbox 和 Openbox。

[Fluxbox](http://fluxbox.org) 是一个 X11 系统的窗口管理器，它基于一个较老的名为 Blackbox 的项目。当我发现 Linux 时，Blackbox 的开发已进入衰退期，因此我就喜欢上了 Fluxbox ，此后我至少在一个以上的常用的系统上使用过它。它是用 C++ 编写的，并在 MIT 开源许可证下授权。

### 安装 Fluxbox

你很可能会在你的 Linux 发行版的软件库中找到 Fluxbox，但是你也可以在 [Fluxbox.org](http://fluxbox.org/download/) 上找到它。如果你正在运行另外一个桌面，在同一个系统上安装 Fluxbox 是安全的，因为 Fluxbox 不会预设任何配置或附带的应用程序。

在安装 Fluxbox 后，注销你当前的桌面会话，以便你可以登录一个新的桌面会话。默认情况下，你的桌面会话管理器 (KDM、GDM、LightDM 或 XDM，取决于你的安装设置) 将继续让登录到之前的桌面，所以你在登录前必需要覆盖上一个桌面。

使用 GDM 覆盖一个桌面：

![在 GDM 中选择你的桌面会话](/data/attachment/album/202004/07/113402igy9m99zkgeykg90.jpg "Select your desktop session in GDM")

或者使用 KDM：

![使用 KDM 选择你的桌面会话](/data/attachment/album/202004/07/113404kc77wlcq6wdtp23p.jpg "Select your desktop session with KDM")

### 配置 Fluxbox 桌面

当你第一次登录到桌面时，屏幕基本是空的，因为 Fluxbox 提供的所有东西是面板（用于任务栏、系统托盘等等）和用于应用程序窗口的窗口装饰品。

![在 CentOS 7 上的默认 Fluxbox 配置](/data/attachment/album/202004/07/113406jnwiwdju8p9bwdwf.jpg "Default Fluxbox configuration on CentOS 7")

如果你的发行版提供一个简单的 Fluxbox 桌面，你可以使用 `feh` 命令（你可能需要从你的发行版的软件库中安装它）来为你的桌面设置背景。这个命令有几个用于设置背景的选项，包括使用你选择的墙纸来填充屏幕的 `--bg-fill` 选项，来按比例缩放的 `--bg-scale` 等等选项。

```
$ feh --bg-fill ~/photo/oamaru/leaf-spiral.jpg
```

![应用主题的 Fluxbox ](/data/attachment/album/202004/07/113421vzcbzvo72fojczxd.jpg "Fluxbox with a theme applied")

默认情况下，Fluxbox 自动生成一个菜单，在桌面上任意位置右键单击可用该菜单，这给予你访问应用程序的能力。根据你的发行版的不同，这个菜单可能非常小，也可能列出 `/usr/share/applications` 目录中的所有启动程序。

Fluxbox 配置是在文本文件中设置的，这些文本文件包含在 `$HOME/.fluxbox` 目录中。你可以：

* 在 `keys` 中设置键盘快捷键
* 在 `startup` 中启动的服务和应用程序
* 在 `init` 设置桌面首选项（例如工作区数量、面板位置等等）
* 在 `menu` 中设置菜单项

该文本配置文件非常易于推断，但是你也可以（并且是应该）阅读 Fluxbox 的[文档](http://fluxbox.org/features/)。

例如，这是我的典型菜单（或者说至少有它的基本结构）：

```
# 为使用你自己的菜单，复制这些文本到 ~/.fluxbox/menu，然后编辑
# ~/.fluxbox/init ，并更改 session.menuFile 文件路径到 ~/.fluxbox/menu

[begin] (fluxkbox)
 [submenu] (apps) {}
  [submenu] (txt) {}
   [exec] (Emacs 23 (text\)) { x-terminal-emulator -T "Emacs (text)" -e /usr/bin/emacs -nw} <>
   [exec] (Emacs (X11\)) {/usr/bin/emacs} <>
   [exec] (LibreOffice) {/usr/bin/libreoffice}
  [end]
  [submenu] (code) {}
   [exec] (qtCreator) {/usr/bin/qtcreator}
   [exec] (eclipse) {/usr/bin/eclipse}
  [end]
  [submenu] (graphics) {}
   [exec] (ksnapshot) {/usr/bin/ksnapshot}
   [exec] (gimp) {/usr/bin/gimp}
   [exec] (blender) {/usr/bin/blender}
  [end]
  [submenu] (files) {}
   [exec] (dolphin) {/usr/bin/dolphin}
   [exec] (konqueror) { /usr/bin/kfmclient openURL $HOME }
  [end]
  [submenu] (network) {}
   [exec] (firefox) {/usr/bin/firefox}
   [exec] (konqueror) {/usr/bin/konqueror}
  [end]
 [end]
## 更改窗口管理器或工作环境
[submenu] (environments) {}
 [restart] (flux)  {/usr/bin/startfluxbox}
 [restart] (ratpoison)  {/usr/bin/ratpoison}
 [exec] (openIndiana) {/home/kenlon/qemu/startSolaris.sh}
[end]

[config] (config)
 [submenu] (styles) {}
  [stylesdir] (/usr/share/fluxbox/styles)
  [stylesdir] (~/.fluxbox/styles)
 [end]
[workspaces] (workspaces)
[reconfig] (reconfigure)
[restart] (restart)
[exit] (exeunt)
[end]
```

该菜单也提供一些首选项设置，例如，选择一个主题，从 Fluxbox 会话中重启或注销的能力。

我使用键盘快捷键来启动大多数的应用程序，这些快捷键写入到 `keys` 配置文件中。这里有一些示例（`Mod4` 按键是 `Super` 键，我使用其来指定全局快捷键）：

```
# 打开应用程序
Mod4 t :Exec konsole
Mod4 k :Exec konqueror
Mod4 z :Exec fbrun
Mod4 e :Exec emacs
Mod4 f :Exec firefox
Mod4 x :Exec urxvt
Mod4 d :Exec dolphin
Mod4 q :Exec xscreensaver-command -activate
Mod4 3 :Exec ksnapshot
```

在这些快捷方式和一个打开的终端之间，在我工作日的大部分时间内很少使用鼠标，因此从一个控制器切换到另一个控制器不会浪费时间。并且因为 Fluxbox 很好地避开了控制器之间切换的方法，因此在其中操作没有一丝干扰。

### 为什么你应该使用 Fluxbox

Fluxbox 对系统资源的占用非常轻量，但是它拥有重要的功能，可以使你的用户体验轻松、快速、高效。它很容易定制，并且允许你定义你自己的工作流。你不必使用 Fluxbox 的面板，因为还有其它优秀的面板。你甚至可以鼠标中键点击并拖动两个独立的应用程序窗口到彼此之中，以便它们成为一个窗口，每个窗口都有自己的选项卡。

可能性是无穷的，所以今天就在你的 Linux 上尝试一下 Fluxbox 的简单稳定吧！

---

via: <https://opensource.com/article/19/12/fluxbox-linux-desktop>

作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[robsean](https://github.com/robsean) 校对：[wxy](https://github.com/wxy)

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


如何将 Ubuntu 18.04 LTS/19.10 升级到 Ubuntu 20.04 beta

Summary: 如果你还在使用 Ubuntu 18.04 LTS 版本，你会发现 Ubuntu 20.04 配合深色 Yaru 主题非常惊艳，看过 Ubuntu 20.04 的展示视频你就知道了。

yes，i love it

![](/data/attachment/album/202004/08/125043m1qyy7gzvkjazx41.jpg)

[Ubuntu 20.04 LTS 版本](https://itsfoss.com/ubuntu-20-04-release-features/)还有不到一个月就发布了，Ubuntu 在这一个版本中对视觉效果作出了大变动，同时在性能方面也有所提高。

如果你还在使用 Ubuntu 18.04 LTS 版本，你会发现 Ubuntu 20.04 配合深色 Yaru 主题非常惊艳，看过 [Ubuntu 20.04 的展示视频](https://www.youtube.com/watch?v=9u5B0njRgOw)你就知道了。

感觉确实不错。如果你想在 4 月 23 日最终稳定版正式发布前率先使用 Ubuntu 20.04，也可以在官方网站上下载 beta 版本。尽管是测试版本，但它的稳定性并不差，同时你也可以在使用这个版本的过程中帮助 Ubuntu 团队进行测试。

你可以下载<ruby> 每日构建 <rt>  daily build </rt></ruby>版并进行重新安装，如果你正在使用的是 Ubuntu 18.04 或 Ubuntu 19.10，也可以在现有系统的基础上直接升级到 Ubuntu 20.04 beta 版本。

从现有系统中升级是很方便的，因为你不会丢失系统设置和其他文件。与重新安装不同的是，你不需要从头开始重新安装所有的软件。当你切换到新版本时，你的主目录、应用程序（大部分）、文件都会保持原样。

>
> 如果你需要确认正在使用的 Ubuntu 版本，可以参考[这篇文章](/article-9872-1.html)。
>
>
>

在本文中，我将会介绍如何升级到 Ubuntu 20.04 beta 版本。

### 如何将 Ubuntu 18.04/19.10 升级到 Ubuntu 20.04 beta

在你阅读后面的内容之前，我首先说明一些关于升级到 Ubuntu beta 版本的常见问题。

* 版本升级的过程并不复杂，但在整个过程中需要有良好的网络连接，以便下载高达好几 GB 的数据。
* 版本升级的过程中，第三方存储库（比如你自行添加的 [PPA](https://itsfoss.com/ppa-guide/)）会被禁用，有些 PPA 可能也和新版本不兼容，在版本升级完毕后，你可以手动启用这些 PPA。
* 强烈建议将重要数据备份到外部的 USB 硬盘上。你只需要将各个目录下的重要文件直接复制到外部 USB 硬盘上保存即可。
* 升级到新版本之后，就无法再回滚到之前的旧版本了，如果需要旧版本的系统，只能重新安装。
* 如果你选择升级到 Ubuntu 20.04 beta 版本，那么在 Ubuntu 20.04 最终稳定版发布之后，你也不需要重新安装。只需要保持定期更新 Ubuntu 系统，届时你就可以直接用上最终稳定版了。
* Ubuntu 16.04/17/18/19.04 都无法直接升级到 Ubuntu 20.04。

了解完上面的内容之后，下面开始从 Ubuntu 18.04/19.10 升级到 Ubuntu 20.04。

#### 步骤 1：检查设置是否正确

进入“<ruby> 软件和升级 <rt>  Software & Updates </rt></ruby>”应用：

![Software & Updates application in Ubuntu](/data/attachment/album/202004/08/125139zzymex7udqppurdp.jpg)

在“<ruby> 升级 <rt>  Updates </rt></ruby>”选项卡中，设置“有任何新版本 Ubuntu 都提醒我”或“有 LTS 版本 Ubuntu 就提醒我”:

![Ubuntu Upgrade Version Settings](/data/attachment/album/202004/08/125141v5fv11kv3xksgc21.jpg)

设置完成后，系统会刷新软件库缓存。

#### 步骤 2：安装系统更新

在上面的步骤完成之后，打开终端（在 Ubuntu 中可以使用 `Ctrl+Alt+T` [快捷键](https://itsfoss.com/ubuntu-shortcuts/)），然后使用以下命令[更新 Ubuntu 系统](https://itsfoss.com/update-ubuntu/)：

```
sudo apt update && sudo apt full-upgrade
```

`apt full-upgrade` 或 `apt dist-upgrade` 的功能和 `apt upgrade` 大致相同，但对于系统版本的升级，`apt full-upgrade` 会在需要的情况下将当前已安装的软件移除掉。

更新安装完成后，系统可能会需要重新启动。在重新启动之后，就可以进入步骤 3 了。

#### 步骤 3：使用更新管理器查找开发版本

在步骤 2 中已经安装了所有必要的更新，现在通过下面的命令打开更新管理器，其中 `-d` 参数表示需要查找开发版本：

```
update-manager -d
```

整个过程可能需要好几分钟，随后会提示有新版本的 Ubuntu 可用：

![Availability of Ubuntu 20.04 in Ubuntu 19.10](/data/attachment/album/202004/08/125142kqq6zunpm3gl543m.jpg)

在 Ubuntu 18.04 上的提示是这样的：

![Availability of Ubuntu 20.04 in Ubuntu 18.04](/data/attachment/album/202004/08/125144hvo30or0nno3vltf.jpg)

然后点击对话框中的“<ruby> 升级 <rt>  upgrade </rt></ruby>”按钮。

#### 步骤 4：开始升级到 Ubuntu 20.04 beta

接下来只要等待下载更新就可以了，遇到对话框直接点击 “OK” 即可。

![](/data/attachment/album/202004/08/125144kd4ydyy9elex78pl.jpg)

点击“<ruby> 升级 <rt>  upgrade </rt></ruby>”按钮，然后按照提示进行操作。

![](/data/attachment/album/202004/08/125145yhjn5pwnwdohjmj5.jpg)

在升级过程中，可能会有提示信息告知所有第三方源都已经禁用。有时候还会提示有哪些软件包需要升级或删除，以及是否需要保留一些已经过时了的软件包。一般情况下，我会选择直接删除。

整个升级过程通常会需要几个小时，但主要还是取决于实际的网速。升级完成后，系统会提示需要重新启动。

![](/data/attachment/album/202004/08/125146osiqcddwsmltzdih.jpg)

下面的视频展示了所有相关步骤。

由此可见，这个升级流程并不复杂。欢迎体验 Ubuntu 20.04 带来的新特性。

如果你有疑问或建议，欢迎在评论区留言。

---

via: <https://itsfoss.com/upgrade-ubuntu-beta/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[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/) 荣誉推出


如何知道你的 Linux 用的哪种显卡？

Summary: 无论是 Nvidia 还是 Radeon 或者 Intel，它们的显卡都可能在 Linux 中有问题。当你要对图形问题进行故障排除时，首先要了解系统中装有哪种显卡。

无论是 [Nvidia](https://www.nvidia.com/en-us/) 还是 [Radeon](https://www.amd.com/en/graphics/radeon-rx-graphics) 或者 Intel，它们的显卡都可能在 Linux 中有问题。当你要对图形问题进行故障排除时，首先要了解系统中装有哪种显卡。

Linux 有几个命令可以检查硬件信息。你可以使用它们来检查你有哪些显卡（也称为视频卡）。让我向你展示一些命令来获取 Linux 中的 GPU 信息。

### 在 Linux 命令行中检查显卡详细信息

![](/data/attachment/album/202004/08/134159a11qu83339vb9njz.jpg)

#### 使用 lspci 命令查找显卡

`lspci` 命令显示通过 [PCI](https://en.wikipedia.org/wiki/Conventional_PCI)（<ruby> 外设组件互连 <rt>  Peripheral Component Interconnect </rt></ruby>）总线连接的设备的信息。基本上，此命令提供有关系统从键盘和鼠标到声卡、网卡和显卡的所有外设的详细信息。

默认情况下，你会有大量的此类外设列表。这就是为什么你需要用 `grep` 命令过滤出显卡的原因：

```
lspci | grep VGA
```

这应该会显示一行有关你显卡的信息：

```
abhishek@itsfoss:~$ lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 620 (rev 02)
```

如你所见，我的系统中有 Intel HD 620 显卡。

#### 在 Linux 中使用 lshw 命令获取显卡详细信息

`lspci` 命令足以查看你的显卡，但是并不能告诉你很多信息。你可以使用 `lshw` 命令获取有关它的更多信息。

此命令要求你有 root 用户权限。你需要以这种方式查找视频卡（显卡）信息：

```
sudo lshw -C video
```

正如你在下面的输出中看到的那样，此命令提供了有关显卡的更多信息，例如时钟频率、位宽、驱动等。

```
abhishek@itsfoss:~$ sudo lshw -C video
[sudo] password for abhishek:
  *-display
       description: VGA compatible controller
       product: HD Graphics 620
       vendor: Intel Corporation
       physical id: 2
       bus info: [email protected]:00:02.0
       version: 02
       width: 64 bits
       clock: 33MHz
       capabilities: pciexpress msi pm vga_controller bus_master cap_list rom
       configuration: driver=i915 latency=0
       resources: irq:139 memory:db000000-dbffffff memory:90000000-9fffffff ioport:f000(size=64) memory:c0000-dffff
```

#### 附赠技巧：以图形方式检查显卡详细信息

并非必须使用命令行在 Linux 中查找显卡详细信息。大多数 Linux 发行版（或者应该说是桌面环境）在设置中提供了必要的详细信息。

例如，如果你使用的是 [GNOME 桌面环境](https://www.gnome.org/)，那么可以进入“设置”的“关于”部分来检查详细信息。[Ubuntu 20.04](https://itsfoss.com/ubuntu-20-04-release-features/) 中看上去像这样：

![Graphics card information check graphically](/data/attachment/album/202004/08/134201mrreercwi8giff3p.jpg)

我希望这个快速技巧对你有所帮助。你也可以使用相同的命令来[查找网卡](https://itsfoss.com/find-network-adapter-ubuntu-linux/)和 [Linux 中的 CPU 信息](https://linuxhandbook.com/check-cpu-info-linux/)。

如果你有任何疑问或建议，请随时发表评论。

---

via: <https://itsfoss.com/check-graphics-card-linux/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[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/) 荣誉推出


为何你的 Python 代码应是扁平与稀疏的

>
> 本文是 Python 之禅特别系列的第三篇，此篇着眼于其中第五与第六条原则：扁平与稀疏。
>
>
>

![](/data/attachment/album/202004/08/191645uiniiy56keig95gi.jpg)

[Python 之禅](https://www.python.org/dev/peps/pep-0020/) 之所以得名，正是由于它那简明扼要的规则被设计出的意图在于让读者进行深入地思考，而绝不单是为编程提供一份易于遵守的指南。

读后不去三思其意，断然难以体会 Python 之禅的妙处。倘若 Python 之禅仅仅罗列出一组清晰的法则，那法则之间的矛盾是一种缺憾，然而作为引导读者沉思最优方案沉思的工具，矛盾却是绝佳的。

### <ruby> 扁平胜过嵌套 <rt>  Flat is better than nested </rt></ruby>

迫于对缩进的强硬要求，Python 对“扁平化”的需求显然远超它者。其余编程语言为了缓解对缩进的需求，通常会在嵌套结构里加入一种“作弊”的手段。为了理解这一点，不妨一同来看看 JavaScript。

JavaScript 本质上是异步的，这意味着程序员用 JavaScript 写的代码会用到大量的回调函数。

```
a(function(resultsFromA) {
  b(resultsFromA, function(resultsfromB) {
    c(resultsFromC, function(resultsFromC) {
      console.log(resultsFromC)
   }
  }
}
```

忽略这段代码的具体内容，只去观察这段代码的形状与缩进带来一个最右边的点的方式。这种独特的“箭头”图形在我们扫看代码时格外扎眼，这种写法也因此被视作不可取，甚至得到了“回调地狱”的绰号。不过，在 JavaScript 中，这种反映嵌套关系的缩进可以通过“作弊”来回避。

```
a(function(resultsFromA) {
b(resultsFromA,
  function(resultsfromB) {
c(resultsFromC,
  function(resultsFromC) {
    console.log(resultsFromC)
}}}
```

Python 并没有提供这种作弊手段：每一级嵌套在代码中都如实的对应着一层缩进。因此，Python 深层的嵌套关系在*视觉*上也一定是深层嵌套的。这使得“回调地狱”的问题对于 Python 而言要比在 JavaScript 中严重得多：嵌套的回调函数必定带来缩进，而绝无使用花括号来“作弊”的可能。

这项挑战与 Python 之禅的指导原则相结合后，在我参与的库中催生出了一个优雅的解决方案。我们在 [Twisted](https://twistedmatrix.com/trac/) 框架里提出了 deferred 抽象，日后 JavaScript 中流行的 promise 抽象亦是受其启发而生。正是由于 Python 对整洁代码的坚守，方能推动 Python 开发者去发掘新的、强力的抽象。

```
future_value = future_result()
future_value.addCallback(a)
future_value.addCallback(b)
future_value.addCallback(c)
```

（现代 JavaScript 程序员也许会觉得这段代码十分眼熟：promise 着实受到了 Twisted 里 deferred 抽象的深远影响。）

### <ruby> 稀疏胜过密集 <rt>  Sparse is better than dense </rt></ruby>

最易降低代码密集程度的方法是引入嵌套。这种习惯也正是有关稀疏的原则要随着前一条提出的原因：在竭尽所能地减少嵌套之后，我们往往会遗留下*密集的*代码或数据结构。此处的密集，是指塞进过量信息的小段代码，它们会导致错误发生后的解析变得困难。

这种密集性唯有通过创造性的思考方可改善，此外别无捷径。Python 之禅并不为我们提供简单的解决方案，它只会指明改善代码的方向，而非提供“如何”去做的向导。

起身走走，泡个热水澡，抑或是闻闻花香。盘坐冥思，直至灵感袭来。当你终于得到启发，便是动身写代码之时。

---

via: <https://opensource.com/article/19/12/zen-python-flat-sparse>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[caiichenr](https://github.com/caiichenr) 校对：[wxy](https://github.com/wxy)

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


如何在 Bash 中使用循环

Summary: 使用循环和查找命令批量自动对多个文件进行一系列的操作。

使用循环和查找命令批量自动对多个文件进行一系列的操作。

>
> 使用循环和查找命令批量自动对多个文件进行一系列的操作。
>
>
>

![](/data/attachment/album/202004/08/225655by8i8k7uyppp18ph.jpg)

人们希望学习批处理命令的一个普遍原因是要得到批处理强大的功能。如果你希望批量的对文件执行一些指令，构造一个可以重复运行在那些文件上的命令就是一种方法。在编程术语中，这被称作*执行控制*，`for` 循环就是其中最常见的一种。

`for` 循环可以详细描述你希望计算机对你指定的每个数据对象（比如说文件）所进行的操作。

### 一般的循环

使用循环的一个简单例子是对一组文件进行分析。这个循环可能没什么用，但是这是一个安全的证明自己有能力独立处理文件夹里每一个文件的方法。首先，创建一个文件夹然后拷贝一些文件（例如 JPEG、PNG 等类似的文件）至文件夹中生成一个测试环境。你可以通过文件管理器或者终端来完成创建文件夹和拷贝文件的操作：

```
$ mkdir example
$ cp ~/Pictures/vacation/*.{png,jpg} example
```

切换到你刚创建的那个新文件夹，然后列出文件并确认这个测试环境是你需要的：

```
$ cd example
$ ls -1
cat.jpg
design_maori.png
otago.jpg
waterfall.png
```

在循环中逐一遍历文件的语法是：首先声明一个变量（例如使用 `f` 代表文件），然后定义一个你希望用变量循环的数据集。在这种情况下，使用 `*` 通配符来遍历当前文件夹下的所有文件（通配符 `*` 匹配*所有文件*）。然后使用一个分号（`;`）来结束这个语句。

```
$ for f in * ;
```

取决于你个人的喜好，你可以选择在这里按下回车键。在语法完成前，shell 是不会尝试执行这个循环的。

接下来，定义你想在每次循环中进行的操作。简单起见，使用 `file` 命令来得到 `f` 变量（使用 `$` 告诉 shell 使用这个变量的值，无论这个变量现在存储着什么）所存储着的文件的各种信息：

```
do file $f ;
```

使用另一个分号结束这一行，然后关闭这个循环：

```
done
```

按下回车键启动 shell 对当前文件夹下*所有东西*的遍历。`for` 循环将会一个一个的将文件分配给变量 `f` 并且执行你的命令：

```
$ for f in * ; do
> file $f ;
> done
cat.jpg: JPEG image data, EXIF standard 2.2
design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
otago.jpg: JPEG image data, EXIF standard 2.2
waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
```

你也可以用这种形式书写命令：

```
$ for f in *; do file $f; done
cat.jpg: JPEG image data, EXIF standard 2.2
design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
otago.jpg: JPEG image data, EXIF standard 2.2
waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
```

对你的 shell 来说，多行和单行的格式没有什么区别，并且会输出完全一样的结果。

### 一个实用的例子

下面是一个循环在日常使用中的实用案例。假如你拥有一堆假期拍的照片想要发给你的朋友。但你的照片太大了，无法通过电子邮件发送，上传到[图片分享服务](http://nextcloud.com)也不方便。因此你想为你的照片创建小型的 web 版本，但是你不希望花费太多时间在一个一个的压缩图片体积上。

首先，在你的 Linux、BSD 或者 Mac 上使用包管理器安装 ImageMagick 命令。例如，在 Fedora 和 RHEL 上：

```
$ sudo dnf install ImageMagick
```

在 Ubuntu 和 Debian 上：

```
$ sudo apt install ImageMagick
```

在 BSD 上，使用 `ports` 或者 [pkgsrc](http://pkgsrc.org) 安装。在 Mac 上，使用 [Homebrew](http://brew.sh) 或者 [MacPorts](https://www.macports.org) 安装。

在你安装了 ImageMagick 之后，你就拥有一系列可以用来操作图片的新命令了。

为你将要创建的文件建立一个目标文件夹：

```
$ mkdir tmp
```

使用下面的循环可以将每张图片减小至原来大小的 33%。

```
$ for f in * ; do convert $f -scale 33% tmp/$f ; done
```

然后就可以在 `tmp` 文件夹中看到已经缩小了的照片了。

你可以在循环体中使用任意数量的命令，因此如果你需要对一批文件进行复杂的操作，可以将你的命令放在一个 `for` 循环的 `do` 和 `done` 语句之间。例如，假设你希望将所有处理过的图片拷贝至你的网站所托管的图片文件夹并且在本地系统移除这些文件：

```
$ for f in * ; do
  convert $f -scale 33% tmp/$f
  scp -i seth_web tmp/$f seth@example.com:~/public_html
  trash tmp/$f ;
done
```

你的计算机会对 `for` 循环中处理的每一个文件自动的执行 3 条命令。这意味着假如你仅仅处理 10 张图片，也会省下输入 30 条指令和更多的时间。

### 限制你的循环

一个循环常常不需要处理所有文件。在示例文件夹中，你可能需要处理的只是 JPEG 文件：

```
$ for f in *.jpg ; do convert $f -scale 33% tmp/$f ; done
$ ls -m tmp
cat.jpg, otago.jpg
```

或者，你希望重复特定次数的某个操作而不仅仅只处理文件。`for` 循环的变量的值是被你赋给它的（不管何种类型的）数据所决定的，所以你可以创建一个循环遍历数字而不只是文件：

```
$ for n in {0..4}; do echo $n ; done
0
1
2
3
4
```

### 更多循环

现在你了解的知识已经足够用来创建自己的循环体了。直到你对循环非常熟悉之前，尽可能的在需要处理的文件的*副本*上进行操作。使用内置的保护措施可以预防损坏自己的数据和制造不可复现的错误，例如偶然将一个文件夹下的所有文件重命名为同一个名字，就可能会导致他们的相互覆盖。

更进一步的 `for` 循环话题，请继续阅读。

### 不是所有的 shell 都是 Bash

关键字 `for` 是内置在 Bash shell 中的。许多类似的 shell 会使用和 Bash 同样的关键字和语法，但是也有某些 shell ，比如 [tcsh](https://en.wikipedia.org/wiki/Tcsh)，使用不同的关键字，例如 `foreach`。

tcsh 的语法与 Bash 类似，但是它更为严格。例如在下面的例子中，不要在你的终端的第 2、3 行键入 `foreach?` 。它只是提示你仍处在构建循环的过程中。

```
$ foreach f (*)
foreach? file $f
foreach? end
cat.jpg: JPEG image data, EXIF standard 2.2
design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
otago.jpg: JPEG image data, EXIF standard 2.2
waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
```

在 tcsh 中，`foreach` 和 `end` 都必须单独的在一行中出现。因此你不能像 Bash 或者其他类似的 shell 一样只使用一行命令创建一个 `for` 循环。

### for 循环与 find 命令

理论上，你可能会用到不支持 `for` 循环的 shell，或者你只是更想使用其他命令的一些特性来完成和循环一样的工作。

使用 `find` 命令是另一个实现 `for` 循环功能的途径。这个命令提供了多种方法来定义循环中包含哪些文件的范围以及[并行](https://opensource.com/article/18/5/gnu-parallel)处理的选项。

`find` 命令顾名思义就是帮助你查询存储在硬盘里的文件。它的用法很简单：提供一个你希望它查询的位置的路径，接着 `find` 就会查询这个路径下面的所有文件和文件夹。

```
$ find .
.
./cat.jpg
./design_maori.png
./otago.jpg
./waterfall.png
```

你可以通过添加名称的某些部分来过滤搜索结果：

```
$ find . -name "*jpg"
./cat.jpg
./otago.jpg
```

`find` 命令非常好的地方在于你可以通过 `-exec` 参数标志将它查询到的每一个文件放入循环中。例如，只对存放在你的 `example` 文件夹下的 PNG 图片进行体积压缩操作：

```
$ find . -name "*png" -exec convert {} -scale 33% tmp/{} \;
$ ls -m tmp
design_maori.png, waterfall.png
```

在 `-exec` 短语中，括号 `{}` 表示的是 `find` 正在处理的条目（换句话说，每一个被找到的以 PNG 结尾的文件）。`-exec` 短语必须使用分号结尾，但是 Bash 中常常也会使用分号。为了解决这个二义性问题，你的 `结束符` 可以使用反斜杠加上一个分号（`\;`），使得 `find` 命令可以知道这个结束符是用来标识自己结束使用的。

`find` 命令的操作非常棒，某些情况下它甚至可以表现得更棒。比如说，在一个新的进程中使用同一条命令查找 PNG 文件，你可能就会得到一些错误信息：

```
$ find . -name "*png" -exec convert {} -flip -flop tmp/{} \;
convert: unable to open image `tmp/./tmp/design_maori.png':
No such file or directory @ error/blob.c/OpenBlob/2643.
...
```

看起来 `find` 不只是定位了当前文件夹（`.`）下的所有 PNG 文件，还包括已经处理并且存储到了 `tmp` 下的文件。在一些情况下，你可能希望 `find` 查询当前文件夹下再加上其子文件夹下的所有文件。`find` 命令是一个功能强大的递归工具，特别体现在处理一些文件结构复杂的情境下（比如用来放置存满了音乐人音乐专辑的文件夹），同时你也可以使用 `-maxdepth` 选项来限制最大的递归深度。

只在当前文件夹下查找 PNG 文件（不包括子文件夹）：

```
$ find . -maxdepth 1 -name "*png"
```

上一条命令的最大深度再加 1 就可以查找和处理当前文件夹及下一级子文件夹下面的文件：

```
$ find . -maxdepth 2 -name "*png"
```

`find` 命令默认是查找每一级文件夹。

### 循环的乐趣与收益

你使用的循环越多，你就可以越多的省下时间和力气，并且可以应对庞大的任务。虽然你只是一个用户，但是通过使用循环，可以使你的计算机完成困难的任务。

你可以并且应该就像使用其他的命令一样使用循环。在你需要重复处理单个或多个文件时，尽可能的使用这个命令。无论如何，这也算是一项需要被严肃对待的编程活动，因此如果你需要在一些文件上完成复杂的任务，你应该多花点时间在规划自己的工作流上面。如果你可以在一份文件上完成你的工作，接下来将操作包装进 `for` 循环里就相对简单了，这里面唯一的“编程”的需要只是理解变量是如何工作的并且进行充分的规划工作将已处理过的文件和未处理过的文件分开。经过一段时间的练习，你就可以从一名 Linux 用户升级成一位知道如何使用循环的 Linux 用户，所以开始让计算机为你工作吧！

---

via: <https://opensource.com/article/19/6/how-write-loop-bash>

作者：[Seth Kenlon](https://opensource.com/users/seth/users/goncasousa/users/howtopamm/users/howtopamm/users/seth/users/wavesailor/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[chunibyo-wly](https://github.com/chunibyo-wly) 校对：[wxy](https://github.com/wxy)

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


使用 at 命令在 Linux 上安排任务

>
> at 命令可以很容易地安排 Linux 任务在你选择的任何时间或日期运行，让我们来看看它能为你做什么。
>
>
>

![](/data/attachment/album/202004/09/215934pf4iau5vvi4rv4vg.jpg)

当你希望命令或脚本在某个特定时间运行时，你不需要将手指放在键盘上盘旋等待按下回车键，或者是在特定时间坐在办公桌前。相反，你可以通过 `at` 命令来设置任务。在本文中，我们将研究如何使用 `at` 来安排任务，如何精确地选择任务希望运行的时间，以及如何使用 `at` 来查看安排运行的任务。

### at vs cron

对于那些使用 cron 在 Linux 系统上安排任务的人来说，`at` 命令类似于 cron，因为你可以在选定的时间调度任务，但是 cron 用于定期运行的作业 —— 甚至是每年仅一次。大多数 cron 作业的频率都设置为每天、每周或每月运行一次，不过你可以控制运行的频率和时间。

另一方面，`at` 命令用于仅运行一次的任务。想在午夜重启系统？没问题，只要你有适当的权限，`at` 可以为你完成此操作。如果你希望系统在每个星期六凌晨 2 点重启，那么改用 cron。

### 使用 at

`at` 命令很容易使用，只需记住几件事。一个简单使用 `at` 的例子类似于这样：

```
$ at 5:00PM
at> date >> thisfile
at> <EOT>
```

在输入 `at` 和应该运行命令的时间，`at` 会提示你在设定时间会运行该命令（此例中是 `date` 命令）。输入 `^D`（`Ctrl + d`）来完成请求。

假设我们在下午 5 点之前设置这个 `at` 命令，那么这个日期和时间将在当天下午 5 点添加到名为 `thisfile` 文件的末尾。否则，该命令将在第二天下午 5 点运行。

与 `at` 命令进行交互时，可以输入多个命令。如果你要同时运行多个命令，只需输入多个命令行即可：

```
$ at 6:22
warning: commands will be executed using /bin/sh
at> echo first >> thisfile
at> echo second >> thisfile
at> <EOT>
```

在上面的命令中，我们使用了一个普通的用户账户，将一些简单的文本添加到该用户主目录的文件中。如果在上午 6:22 之后运行这些命令，那么命令会在第二天运行，因为 6:22 表示上午 6:22。如果你想在下午 6:22 运行，使用 `6:22 PM` 或者 `18:22`。`6:22 PM` 这样也是可以工作的。

你也可以通过使用 `at` 来安排命令在指定的日期或时间运行，例如 `10:00AM April 15 2021` 或 `noon + 5 days`（从今天起 5 天内的中午运行），以下是一些例子：

```
at 6PM tomorrow
at noon April 15 2021
at noon + 5 days
at 9:15 + 1000 days
```

在指定要运行的命令并按下 `^D` 后，你会注意到 `at` 命令为每个请求分配了一个作业编号，这个数字将显示在 `at` 命令的作业队列中。

```
$ at noon + 1000 days
warning: commands will be executed using /bin/sh
at> date >> thisfile
at> <EOT>
job 36 at Tue Dec 27 12:00:00 2022        <== job # is 36
```

### 检查队列

你可以使用 `atq`（at queue）命令来查看 `at` 作业队列：

```
$ atq
32      Thu Apr  2 03:06:00 2020 a shs
35      Mon Apr  6 12:00:00 2020 a shs
36      Tue Dec 27 12:00:00 2022 a shs
34      Thu Apr  2 18:00:00 2020 a shs
```

如果你需要取消队列中的一个作业，使用 `atrm`（at remove）命令和作业编号：

```
$ atrm 32
$ atq
35      Mon Apr  6 12:00:00 2020 a shs
36      Tue Dec 27 12:00:00 2022 a shs
34      Thu Apr  2 18:00:00 2020 a shs
```

你可以使用 `at -c` 命令来查看安排任务的详细信息，其它详细信息（活动的搜索路径等）也可以看到，但是输出的最后一行将显示计划运行的命令。

```
$ at -c 36 | tail -6
cd /home/shs || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
date >> thisfile
```

注意，该命令显示首先会测试是否可以通过 `cd` 命令进入用户目录。如果不可以，作业将退出并显示错误。如果可以，则运行在 `at` 中指定的命令。它将命令视为 “进入 `/home/shs` 或退出并显示错误”。

### 以 root 身份运行作业

要以 root 身份运行 `at` 作业，只需将 `sudo` 与你的 `at` 命令一起使用，如下所示：

```
$ sudo at 8PM
[sudo] password for shs:
warning: commands will be executed using /bin/sh
at> reboot now
at> <EOT>
job 37 at Wed Apr  1 16:00:00 2020
```

注意，root 的任务以 `root` 作为执行者显示在队列中。

```
35      Mon Apr  6 12:00:00 2020 a shs
36      Tue Dec 27 12:00:00 2022 a shs
37      Wed Apr  1 20:00:00 2020 a root         <==
```

### 运行脚本

你还可以使用 `at` 命令来运行脚本，这里有一个例子：

```
$ at 4:30PM
warning: commands will be executed using /bin/sh
at> bin/tryme
at> <EOT>
```

### 禁止使用 at 命令

`/etc/at.deny` 文件提供了一种禁止用户使用 `at` 命令的方法。默认情况下，它可能会包含一个不允许的账户列表，例如 `ftp` 和 `nobody`。可以使用 `/etc/at.allow` 文件执行相反的操作，但是通常只配置 `at.deny` 文件。

### 总结

当你要安排一项一次性任务时，无论你是希望在今天下午或几年后运行，`at` 命令都是通用且易于使用的。

---

via: <https://www.networkworld.com/article/3535808/scheduling-tasks-on-linux-using-the-at-command.html>

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


解读 Ubuntu 里的密钥环概念

Summary:
在现实生活中你为什么要用钥匙环（也叫钥匙链）？你用它把一把或多把钥匙串到一起, 以便于携带和查找。
Linux 里也是类似的。密钥环特性使你的系统可以将各种密码放在一起，并将其保存在一个地方。

很好的文章，理解了之前的一些困惑，謝謝。

![](/data/attachment/album/202004/09/230421ufdydfttjd9882ka.png)

如果你用过 Ubuntu 或者其他的 Linux 发行版里的[自动登录功能](https://itsfoss.com/ubuntu-automatic-logon/), 你可能遇到过这种弹出消息：

>
> 请输入密码以解锁你的登录密钥环
>
>
> 登录密钥环在你登录系统时未解锁。
>
>
>

![Enter Password To Unlock Your Login Keyring Ubuntu](/data/attachment/album/202004/09/230422m0xvgv0oj4fjdk7d.jpg)

如果你一直点击取消，它会不断弹出几次才会消失。你可能想知道，为什么你会一直看到这个密钥环信息呢？

让我来告诉你吧。它其实不是错误，而是一个安全特性。

奇怪吗？下面就让我来解释下 Linux 里的密钥环概念。

### Linux 里的密钥环是什么。为什么需要它？

在现实生活中你为什么要用钥匙环（也叫[钥匙链](https://en.wikipedia.org/wiki/Keychain)）？你用它把一把或多把钥匙串到一起, 以便于携带和查找。

Linux 里也是类似的。密钥环特性使你的系统可以将各种密码放在一起，并将其保存在一个地方。

大多数 Linux 桌面环境，如 GNOME、KDE、Xfce 等采用 [GNOME 密钥环](https://wiki.archlinux.org/index.php/GNOME/Keyring)来提供这个功能。

该密钥环保存了 ssh 密钥、GPG 密钥以及使用此功能的应用程序（例如 Chromium 浏览器）的密钥。默认情况下，**“密钥环”通过主密码来保护**，该密码通常是帐户的登录密码。

系统上的每个用户都有自己的密钥环，（通常）密码与用户帐户本身的密码相同。当你使用密码登录系统时，你的密匙环将使用你帐户的密码自动解锁。

当你[启用 Ubuntu 中的自动登录功能时](https://itsfoss.com/ubuntu-automatic-logon/)时，就有问题了。这意味着你无需输入密码即可登录系统。在这种情况下，你的密钥环不会自动解锁。

#### 密钥环是一个安全特性

记得我说过密钥环是一个安全特性吗？现在想象一下你在 Linux 电脑上开启了自动登录功能。有权访问你电脑的任何人无需密码就能进入你的系统。但是你可能不会在意，因为你只是用它来访问互联网。

但是，如果你在 Ubuntu 中使用 Chromium 或 [Google Chrome](https://itsfoss.com/install-chrome-ubuntu/) 之类的浏览器，并使用它来保存各种网站的登录密码，那么你将遇到麻烦。任何人都可以使用浏览器并利用你在浏览器中保存的密码登录网站。这不很危险吗？

这就是为什么当你使用 Chrome 时，它将反复地提示你先解锁密钥环。这确保了只有知道密钥环密码（即账户密码）的人才能使用在浏览器中保存的密码来登录它们相关的网站。

如果你反复取消解锁密钥环的提示，它最终将消失，并允许你使用浏览器。但是，保存的密码将不会被解锁，你在 Chromium/Chome 浏览器上将会看到“同步暂停”的提示。

![Sync paused in Google Chrome](/data/attachment/album/202004/09/230425e6ufyzpksktk7msf.jpg)

#### 如果密钥环一直存在，为什么你从来没有见过它呢?

如果你在你的 Linux 系统上从没见过它的话，这个问题就很有道理。

如果你从没有用过自动登录功能（或者修改你的账户密码），你可能都没有意识到这个特性的存在。

这是因为当你通过你的密码登录系统时，你的密钥环被你的账户密码自动解锁了。

Ubuntu（和其他发行版）在执行普通的管理任务如修改用户、安装新软件等需要输入密码，无论你是否是自动登录的。但是对于日常任务像使用浏览器，它不需要输入密码因为密钥环已经被解锁了。

当你切换到自动登录时，你不再需要输入登录密码。这意味着密钥环没有被自动解锁，因此当你使用利用了密钥环特性的浏览器时，它将提示你来解锁密钥环。

#### 你可以轻松地管理密钥环和密码

这个密钥环放在哪里？它的核心是一个守护任务（一个后台自动运行的程序）。

别担心。你不必通过终端来操作守护任务。大多数桌面环境都自带一个可以和这个守护进程进行交互的图形化应用程序。KDE 上有 KDE 钱包，GNOME 和其他桌面上叫做“密码和密钥”（之前叫 [Seahorse](https://wiki.debian.org/Seahorse)）。

![Password And Keys App in Ubuntu](/data/attachment/album/202004/09/230425u49fevvd2284zhwh.jpg)

你可以用这个 GUI 程序来查看哪些应用程序在用密钥环来管理/保护密码。

你可以看到，我的系统有自动创建的登录密钥环。也有一个存储 GPG 和 SSH 密钥的密钥环。那个[证书](https://help.ubuntu.com/lts/serverguide/certificates-and-security.html)用来保存证书机构颁发的证书（如 HTTPS 证书）。

![Password and Keys application in Ubuntu](/data/attachment/album/202004/09/230426pr9jj9ifjsgiez9i.png)

你也可以使用这个应用程序来手动保存网站的密码。例如，我创建了一个新的叫做“Test”的被密码保护的密钥环，并手动存储了一个密码。

这比在一个文本文件中保存一批密码要好一些。至少在这种情况下，你的密码只有在你通过密码解锁了密钥环时才允许被看到。

![Saving New Password Seahorse](/data/attachment/album/202004/09/230427q8ehahh2aes6huhw.png)

这里有一个潜在的问题，如果你格式化你的系统，手动保存的密码必然会丢失。通常，你会备份你的个人文件，但并不是所有的用户特定数据，如密钥环文件。

有一种办法能解决它。密钥环数据通常保存在 `~/.local/share/keyrings` 目录。在这里你可以看到所有的密钥环，但是你不能直接看到它们的内容。如果你移除密钥环的密码（我会在这篇文章的后面描述操作步骤），你可以像一个普通的文本文件一样读取密钥环的内容。你可以将这个解锁后的密钥环文件完整地复制下来，并在其他的 Linux 机器上运行“密码和密钥”应用程序导入到其中。

总结一下目前为止所学的内容：

* 大多数 Linux 系统缺省已经安装并激活了密钥环特性
* 系统上的每个用户都拥有他自己的密钥环
* 密钥环通常是用账户密码锁定的（保护）
* 当你通过密码登录时密钥环会被自动解锁
* 对于自动登录，密钥环不会自动解锁，因此当你试图使用依赖密钥环的应用程序时会被提示先解锁它
* 并不是所有的浏览器或应用程序利用了密钥环特性
* （Linux 上）安装一个 GUI 程序可以和密钥环交互
* 你可以用密钥环来手动存储加密格式的密码
* 你可以自己修改密钥环密码
* 你可以通过导出（需要先解锁密钥环）并导入到其他计算机上的方式来获取手工保存的密码。

### 修改密钥环密码

假设你修改了你的账户密码。当你登录时，你的系统试图通过新的登录密码来自动解锁密钥环。但是密钥环还在使用老的登录密码。

这种情况下，你可以修改密钥环密码为新的登录密码，这样密码环才能在你登录系统时自动解锁。

从菜单中打开“密码和密钥”应用程序：

![Look for Password and Keys app in the menu](/data/attachment/album/202004/09/230425u49fevvd2284zhwh.jpg)

在“Login”密钥环上右击并点击“修改密码”：

![Change Keyring Password](/data/attachment/album/202004/09/230428kthx6noqhnzqnzph.png)

#### 如果你不记得老的登录密码怎么办？

你可能知道在 [Ubuntu 上重置忘记的密码很容易](https://itsfoss.com/how-to-hack-ubuntu-password/)。但是密钥环在这种场景下还是有问题。你修改了账户密码，但是你不记得仍然被密钥环使用的老的账户密码。

你不能修改它因为你不知道老的密码。怎么办？

这种情况下，你将不得不移除整个密钥环。你可以通过“密码和密钥”应用程序来操作：

![Delete Keyring Ubuntu](/data/attachment/album/202004/09/230431ng60t99gtzxhm9go.jpg)

它会提示你进行确认：

![Delete Keyring](/data/attachment/album/202004/09/230437ojzpwajfqcfwkzj6.jpg)

另外，你也可以手动删除 `~/.local/share/keyrings` 目录下的密钥环文件。

老的密钥环文件被移除后，你再打开 Chrome/Chromium 时，它会提示你创建一个新的密钥环。

![New Keyring Password](/data/attachment/album/202004/09/230438h3puukppjkopu41o.jpg)

你可以用新的登录密码，密钥环就会被自动解锁了。

### 禁用密钥环密码

在你想用自动登录但又不想手动解锁密钥环时，你可以把禁用密钥环密码作为一个规避方法。记住你正在禁用一个安全特性，因此请三思。

操作步骤和修改密钥环相似。打开“密码和密钥”应用程序，然后修改密钥环密码。

技巧在于当它提示修改密码时，不要输入新密码，而是点击“继续”按钮。这将移除密钥环的密码。

![Disable Keyring password by not setting any password at all](/data/attachment/album/202004/09/230439m4n1i2i3i723z24n.png)

这种方法，密钥环没有密码保护，并将一直处于解锁状态。

---

via: <https://itsfoss.com/ubuntu-keyring/>

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

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


Linux 上的最佳音频编辑工具推荐

在 Linux 上，有很多种音频编辑器可供你选用。不论你是一个专业的音乐制作人，还是只想学学怎么做出超棒的音乐的爱好者，这些强大的音频编辑器都是很有用的工具。

对于专业级的使用，我总是建议使用 [DAW](https://en.wikipedia.org/wiki/Digital_audio_workstation)（数码音频工作站）。但并不是每个人都需要全部的功能，所以你也应该了解一些最简单的音频编辑器。

在本文中，我们将讨论几款 DAW 和基础的音频编辑器，而且它们都是在 Linux 和（可能）其它操作系统上可以使用的**自由开源**的解决方案。

### Linux 上的最佳音频编辑器

![Best audio editors and DAW for Linux](/data/attachment/album/202004/10/174532p3vg0n3ccf4qnqqp.jpg)

我们不会关注 DAW 提供的所有功能，而只是关注基本的音频编辑功能。不过，你仍然可以把以下内容看作是 Linux 的最佳 DAW 名单。

**安装说明：**你可以在 AppCenter 或软件中心中找到所有提到的音频编辑器或 DAW。如果你在这两个地方没有找到它们，请前往它们的官方网站获取更多信息。

#### 1、Audacity

![Audacity audio editor](/data/attachment/album/202004/10/174535l52wuzkvwzvg2ebl.jpg)

[Audacity](https://www.audacityteam.org/) 是 Linux 中最基本音频编辑器之一，但是它也很强大。它是一个自由开源的跨平台工具。肯定已经有很多人了解这个软件了。

现在的它相比它最初流行的时候有了很大的改进。我记得我以前试着通过从音频中去除人声来制作卡拉 OK 伴奏。现在有些时候，你仍然可以这么做。

**特性：**

它还支持包含 VST 效果的插件。当然，你不应该期望它支持 VST 乐器。

* 通过麦克风或混音器进行现场录制
* 支持同时从多种音频格式的多个文件中批量导出/导入内容
* 支持 LADSPA、LV2、Nyquist、VST 和 Audio Unit 的效果插件
* 使用简单，带有剪切、粘贴、删除和拷贝的功能
* 可观测声音频率的频谱模式

#### 2、LMMS

![LMMS audio editor](/data/attachment/album/202004/10/174537mz7j2faqbs18kkz1.jpg)

[LMMS](https://lmms.io/) 是一个自由开源的（跨平台）数码音频工作站。它包括所有基本的音频编辑功能以及许多高级功能。

你可以混音、组合音频，或使用 VST 设备创造音频。LMMS 支持这些功能。此外，它还自带一些样本音频、预设、VST 设备和特效来帮助你起步。此外，你还可以得到一个频谱分析仪，以便进行高级的音频编辑工作。

**特性：**

* 基于 MIDI 的音符回放
* 支持 VST 设备
* 原生支持多采样
* 内置压缩器、限制器、延迟功能、混响功能、失真功能和低音增强器

#### 3、Ardour

![Ardour audio editor](/data/attachment/album/202004/10/174539vqz3v4qpqjlrjmsj.jpg)

[Ardour](https://ardour.org/) 是另一个自由开源的数码音频工作站。只要你有音频接口，Ardour 就支持它的使用。当然，你也可以无限地添加多声道音轨。这些多声道音轨也可以被指派到不同的混音带，以方便编辑和录音。

你也可以导入一个视频，编辑其中的音频，然后导出新的视频。它提供了许多内置插件，并且支持 VST 插件。

**特性：**

* 非线性编辑
* 垂直窗口堆叠，便于导航
* <ruby> 静默消除功能 <rt>  strip silence </rt></ruby>，<ruby> 推拉修剪功能 <rt>  push-pull trimming </rt></ruby>，和用以短暂片段或基于基于音符开始的编辑的 Rhythm Ferret。

#### 4、Cecilia

![Cecilia audio editor](/data/attachment/album/202004/10/174541r3go6fb2uyftmwy5.jpg)

[Cecilia](http://ajaxsoundstudio.com/software/cecilia/) 不是一个普通的音频编辑器。它的使用者一般是音效设计师或者正在努力成为音效设计师的人。 Cecilia 实际上是一个音频信号处理环境。它可以让你的作品余音绕梁。

你还可以得到内置的音效与合成模组和插件。Cecilia 为一个明确的目的而生：如果你正在找音效设计工具，这是你的不二之选！

**特性：**

* 利用模块来完成更多工作（UltimateGrainer —— 最先进的颗粒化处理工具，RandomAccumulator —— 记录变量速度的累加器，UpDistoRes——通过上采样和谐振低通滤波器创造失真效果的工具）
* 自动保存调制设定

#### 5、Mixxx

![Mixxx audio DJ](/data/attachment/album/202004/10/174547vgcxrwlxthkrgfcz.jpg)

如果你想要在混合和录制一些东西的同时能够有一个虚拟的 DJ 工具，[Mixxx](https://www.mixxx.org/) 将是完美的工具。你可以用到 BPM、音调，并使用主同步功能来匹配歌曲的节奏和节拍。另外，不要忘记它也是一个 Linux 的自由开源的软件。

它还支持自定义 DJ 设备。所以，如果你有 DJ 设备或者 MIDI，你可以用这个工具录制你的现场混音。

**特性：**

* 播送和录制你的歌曲的 DJ 混音
* 可以连接到你的设备并且现场演奏
* 音调检测和 BPM 检测

#### 6、Rosegarden

![Rosegarden audio editor](/data/attachment/album/202004/10/174552djbalxe6xmjcwofy.jpg)

[Rosegarden](https://www.rosegardenmusic.com/) 是另一个令人赞叹的 Linux 的自由开源的音频编辑器。它既不是一个功能齐全的 DAW，也不是一个基本的音频编辑工具。它是两者的混合体，并带有一些缩减的功能。

我不会向专业人士推荐这款软件，但如果你经营家庭音乐工作室或只是想体验一下，这将是 Linux 上可以安装的最好的音频编辑器之一。

**特性：**

* 乐谱编辑
* 录音、混音以及采样

### 小结

这些是你可以找到的 Linux 上的最棒的一些音频编辑器了。不论你是需要 DAW，一个剪切/粘贴的编辑工具，或者仅仅想要一个拥有基础的混音和录音功能的音频编辑工具，上述软件都能够满足你的需求。

如果在这篇文章中我们遗漏了你最喜欢的一些音频工具，可以在原文下方评论中回复告诉我们。

---

via: <https://itsfoss.com/best-audio-editors-linux>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MFGJT](https://github.com/MFGJT) 校对：[wxy](https://github.com/wxy)

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


IEEE 标准协会推出开源协作平台

Summary: IEEE 标准协会宣布了一个基于 GitLab 的开源协作平台。

IEEE 标准协会宣布了一个基于 GitLab 的开源协作平台。

>
> IEEE 标准协会宣布了一个基于 GitLab 的开源协作平台。
>
>
>

![](/data/attachment/album/202004/10/222910vjpiqd6lqqm6riqp.jpg)

[IEEE](https://www.ieee.org/about/index.html) 是世界上最大的技术专业组织，致力于推动技术的发展。<ruby> IEEE 标准协会 <rt>  the IEEE Standards Association </rt></ruby>（IEEE SA）是 IEEE 内部的一个组织，负责制定全球各行业的标准。

IEEE 标准协会（SA）提出了一个开源协作平台，即 [IEEE SA Open](https://standards.ieee.org/content/ieee-standards/en/initiatives/opensource/)。

技术上来说，它是一个自托管的 GitLab 实例，结合了 [Mattermost](https://mattermost.com/)（一个 [Slack 的替代品](https://itsfoss.com/open-source-slack-alternative/)）和 [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/)。[其官方博文](https://spectrum.ieee.org/the-institute/ieee-products-services/ieee-standards-association-launches-a-platform-for-open-source-collaboration)对此进一步解释道：

>
> 该平台使独立软件开发者、初创企业、业界、学术机构等能够在一个协作、安全、负责任的环境中创建、测试、管理和部署创新项目。
>
>
>

### 它有什么不同或有用的地方？

这个平台最主要的吸引力应该是 IEEE 的会员网络、技术专长和资源。

IEEE 主席 [Robert Fish](https://www.linkedin.com/in/robertsfish/)，也曾（在接受 Radio Kan 的采访时）简单地提到它有什么不同之处，以及为什么 IEEE 想要使用它。

>
> 如今，世界上大部分的基础设施都是由软件运行的，而这些软件需要符合通信网络、电网、农业等方面的标准。
>
>
>

这是有道理的 —— 如果我们想提高标准化技术，这在很大程度上取决于软件。所以，这听起来肯定是要对创新的开源项目进行标准化，让它们也能为潜在的资本机会做好准备。

IEEE 还澄清说：

>
> 随着软件在当今世界越来越普遍，道德规范、可靠性、透明度和民主治理成为必须具备的条件。IEEE 在赋予开源项目这些属性方面有着得天独厚的优势。
>
>
>

虽然听起来很好，但 IEEE 的开源平台究竟能提供什么？让我们一起来看看这个问题。

### IEEE SA Open 概览

![](/data/attachment/album/202004/10/222937u7i8dcrrbybdchpc.jpg)

首先，它对所有人开放并且完全免费使用。你只需要创建一个 [IEEE 帐户](https://www.ieee.org/profile/public/createwebaccount/showRegister.html)，然后[登录到这个开源平台](https://opensource.ieee.org/)就可以开始。

除了与 IEEE 广泛的会员网络相关的好处之外，你还可以期望其开源社区经理或社区成员提供指导性支持。

![Ieee Gitlab](/data/attachment/album/202004/10/222938w1rqa1tat21x1c2a.jpg)

该平台提供了标准和非标准项目的用例，你可以尝试一下。

因为选择将 GitLab 与 Mattermost 和 Pages 结合起来，你可以获得一些有用的功能，它们是：

* 项目规划和管理功能
* 源代码管理
* 测试、代码质量和持续集成功能
* Docker 容器注册库和 Kubernetes 集成
* 应用程序的发布和交付功能
* 集成了 Mattermost 聊天论坛的斜线命令（完全支持 Android 和 iPhone 应用程序）
* 能够弥合标准制定和开源社区之间的差距，以便以更快的速度推进灵活和创造性的技术解决方案
* 安全的开放空间，并有严格的行为准则。

### 小结

显然，有更多的平台来潜在地放大开源项目的曝光率是一件好事 —— 因此，IEEE 的举措听起来很有希望。

你对此有何看法？让我知道你的想法吧!

---

via: <https://itsfoss.com/ieee-open-source-collaboration-platform/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


在 Ubuntu 20.04 中完全进入深色模式

Summary: 深色模式是 Ubuntu 20.04 最受瞩目的新功能之一了。任何版本的 Ubuntu 都可以通过安装深色主题让用户界面拥有一个深色的外观，但在 Ubuntu 20.04 中，这个过程变得更简单。

2020年4月14日 星期二21:24:48<br />
网站没有明显的提示——bug太多么？

安装了gnome-tweaks 后，在shell 主题的选项处，是一个带惊叹号的三角标，没有可选项。这是为什么？

>
> 深色模式是 Ubuntu 20.04 最受瞩目的[新功能](https://itsfoss.com/ubuntu-20-04-release-features/)之一了。任何版本的 Ubuntu 都可以通过[安装深色主题](https://itsfoss.com/install-themes-ubuntu/)让用户界面拥有一个深色的外观，但在 Ubuntu 20.04 中，这个过程变得更简单。
>
>
>

![](/data/attachment/album/202004/11/200841gvvaja25jaz5z7hv.jpg)

在 Ubuntu 20.04 中，无需额外安装主题，默认主题（称为 Yaru）本身就带有三种模式，其中就包括深色模式。

下面我会展示如何将 Ubuntu 系统完全设置为深色模式。

### 在 Ubuntu 20.04 打开深色模式

这个步骤是在 GNOME 桌面上进行的，如果你[使用的是其它桌面](https://itsfoss.com/find-desktop-environment/)，你看到的可能会和下面的截图不一样。

按下 super 键（或 Windows 键），然后输入 “settings”，就可以找到系统设置。

![Search for Settings](/data/attachment/album/202004/11/200933vk5rfyk5vavz9mif.jpg)

在系统设置中，进入“<ruby> 外观 <rt>  Appearance </rt></ruby>”部分，就可以看到<ruby> 浅色 <rt>  light </rt></ruby>、<ruby> 标准 <rt>  standard </rt></ruby>和<ruby> 深色 <rt>  dark </rt></ruby>三个选项。既然要使用深色模式，那自然而然要选择“深色”这个选项了。

![Enable Dark Theme in Ubuntu](/data/attachment/album/202004/11/200935k8sk99vpp79haza7.png)

完成设置以后，使用了 GTK3 的应用程序都可以跟随深色模式。因此你会看到系统中包括文本编辑器、终端、LibreOffice 等在内的大多数应用程序都已经切换成深色了。但未使用 GTK3 的应用程序可能并没有跟随进入深色模式，下面我会展示如何更完整地进入深色模式。

### 继续调整，进入完整深色模式

这个时候你会发现，shell 主题、屏幕顶部面板中的消息托盘和系统托盘还仍然保持在原有的模式当中。

![No Dark Shell by default in Ubuntu](/data/attachment/album/202004/11/200939rqzx558t88qy8utx.jpg)

现在就需要使用 [GNOME 扩展](https://itsfoss.com/gnome-shell-extensions/)安装 Yaru 深色 shell 主题了。[在 Ubuntu 中通过 Ctrl+Alt+T 打开终端](https://itsfoss.com/ubuntu-shortcuts/)，然后执行以下这个命令安装浏览器扩展：

```
sudo apt install chrome-gnome-shell
```

进入[扩展页面](https://extensions.gnome.org/extension/19/user-themes/)启用这个扩展：

![Enable User Themes GNOME Extension](/data/attachment/album/202004/11/200940f3m4omo4roavovsl.jpg)

执行以下命令安装 [GNOME 调整工具](https://itsfoss.com/gnome-tweak-tool/)：

```
sudo apt install gnome-tweaks
```

打开 GNOME 调整工具，进入“<ruby> 外观 <rt>  Appearance </rt></ruby>”部分，就可以看到 shell 主题的选项，现在只需要把它启用就可以了。

![Enable Yaru Dark Shell Theme in Ubuntu](/data/attachment/album/202004/11/200941hnyp5f3fnzzeeo5y.jpg)

设置完之后再观察一下，桌面通知、消息托盘、系统托盘等等都已经进入深色模式了。

![Yaru Dark Shell Theme in Ubuntu](/data/attachment/album/202004/11/200941b9vyxg4f789vosyw.jpg)

现在感觉好多了。但你可能还会注意到，在使用浏览器访问网站的时候，很多网站都使用了白色的背景色。如果期望网站方提供深色模式，那是很不现实的，但我们可以自己实现这一件事。

你需要用到的东西就是诸如 [Dark Reader](https://darkreader.org/) 这样的浏览器扩展。《[在 Firefox 中启用深色模式](https://itsfoss.com/firefox-dark-mode/)》这篇文章中也有讨论过这个浏览器扩展，它的使用过程并不复杂，如果你使用的浏览器是 Firefox、Chrome 或 [Ubuntu 下的 Chromium](https://itsfoss.com/install-chromium-ubuntu/)，就可以直接安装[其官方网站](https://darkreader.org/)上列出的扩展。

Dark Reader 安装完成后，就会以深色模式打开网站了。

![It’s FOSS Homepage in Dark Mode with Dark Reader](/data/attachment/album/202004/11/200942teiez33kan2goafx.jpg)

当然，有些外部的第三方应用程序可能仍然是浅色状态。如果它们自己附带了深色模式的选项，就需要手动启用它们的深色模式。

如今，深色模式在非开发者人群中也越来越流行了。按照以上的步骤，你就可以轻松进入深色模式。

请享受深色模式。

---

via: <https://itsfoss.com/dark-mode-ubuntu/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[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/) 荣誉推出


使用 Python 读取电子表格中的数据

Summary: Python 可用于多种任务，其中包括处理逗号分隔值（CSV）数据。

如果是WIN，用VBA更好！

Python 可用于多种任务，其中包括处理逗号分隔值（CSV）数据。

![](/data/attachment/album/202004/12/093539jz81k1wgeh85akoe.jpg)

[Python](https://python.org) 是最流行、功能最强大的编程语言之一。由于它是自由开源的，因此每个人都可以使用。大多数 Fedora 系统都已安装了该语言。Python 可用于多种任务，其中包括处理逗号分隔值（CSV）数据。CSV文件一开始往往是以表格或电子表格的形式出现。本文介绍了如何在 Python 3 中处理 CSV 数据。

CSV 数据正如其名。CSV 文件按行放置数据，数值之间用逗号分隔。每行由相同的*字段*定义。简短的 CSV 文件通常易于阅读和理解。但是较长的数据文件或具有更多字段的数据文件可能很难用肉眼解析，因此在这种情况下计算机做得更好。

这是一个简单的示例，其中的字段是 `Name`、`Email` 和 `Country`。在此例中，CSV 数据将字段定义作为第一行，尽管并非总是如此。

```
Name,Email,Country
John Q. Smith,jqsmith@example.com,USA
Petr Novak,pnovak@example.com,CZ
Bernard Jones,bjones@example.com,UK
```

### 从电子表格读取 CSV

Python 包含了一个 `csv` 模块，它可读取和写入 CSV 数据。大多数电子表格应用，无论是原生（例如 Excel 或 Numbers）还是基于 Web 的（例如 Google Sheet），都可以导出 CSV 数据。实际上，许多其他可发布表格报告的服务也可以导出为 CSV（例如，PayPal）。

Python `csv` 模块有一个名为 `DictReader` 的内置读取器方法，它可以将每个数据行作为有序字典 （`OrderedDict`） 处理。它需要一个文件对象访问 CSV 数据。因此，如果上面的文件在当前目录中为 `example.csv`，那么以下代码段是获取此数据的一种方法：

```
f = open('example.csv', 'r')
from csv import DictReader
d = DictReader(f)
data = []
for row in d:
    data.append(row)
```

现在，内存中的 `data` 对象是 `OrderedDict` 对象的列表：

```
[OrderedDict([('Name', 'John Q. Smith'),
               ('Email', 'jqsmith@example.com'),
               ('Country', 'USA')]),
  OrderedDict([('Name', 'Petr Novak'),
               ('Email', 'pnovak@example.com'),
               ('Country', 'CZ')]),
  OrderedDict([('Name', 'Bernard Jones'),
               ('Email', 'bjones@example.com'),
               ('Country', 'UK')])]
```

引用这些对象很容易：

```
>>> print(data[0]['Country'])
USA
>>> print(data[2]['Email'])
bjones@example.com
```

顺便说一句，如果你需要处理没有字段名标题行的 CSV 文件，那么 `DictReader` 类可以让你定义它们。在上面的示例中，添加 `fieldnames` 参数并传递一系列名称：

```
d = DictReader(f, fieldnames=['Name', 'Email', 'Country'])
```

### 真实例子

我最近想从一长串人员名单中随机选择一个中奖者。我从电子表格中提取的 CSV 数据是一个简单的名字和邮件地址列表。

幸运的是，Python 有一个有用的 `random` 模块，可以很好地生成随机值。该模块 `Random` 类中的 `randrange` 函数正是我需要的。你可以给它一个常规的数字范围（例如整数），以及它们之间的步长值。然后，该函数会生成一个随机结果，这意味着我可以在数据的总行数范围内获得一个随机整数（或者说是行号）。

这个小程序运行良好：

```
from csv import DictReader
from random import Random

d = DictReader(open('mydata.csv'))
data = []
for row in d:
    data.append(row)

r = Random()
winner = data[r.randrange(0, len(data), 1)]
print('The winner is:', winner['Name'])
print('Email address:', winner['Email'])
```

显然，这个例子非常简单。电子表格本身包含了复杂的分析数据的方法。但是，如果你想在电子表格应用之外做某事，Python 或许是一种技巧！

题图由 [Isaac Smith](https://unsplash.com/@isaacmsmith?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 拍摄，发表于 [Unsplash](https://unsplash.com/s/photos/spreadsheets?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)。

---

via: <https://fedoramagazine.org/using-data-from-spreadsheets-in-fedora-with-python/>

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

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


在 Fedora 命令行下玩转防火墙

Summary: 本文介绍如何通过 firewall-cmd 命令修改防火墙的配置。

学习了！

本文介绍如何通过 firewall-cmd 命令修改防火墙的配置。

![](/data/attachment/album/202004/12/123040ghxuicphyhsoppch.jpg)

网络防火墙，顾名思义：为了阻止不需要的网络连接而设置的防护性屏障。在与外界建立连接或是提供网络服务时常常会用到。例如，在学校或是咖啡厅里使用笔记本电脑时，你一定不想某个陌生人窥探你的电脑。

每个 Fedora 系统都内置了一款防火墙。这是 Linux 内核网络功能的一部分。本文介绍如何通过 `firewall-cmd` 命令修改防火墙的配置。

### 网络基础

本文并不教授计算机网络的[所有知识](https://en.wikipedia.org/wiki/Portal:Internet)，但还是会简单介绍一些网络基础。

网络中的所有计算机都有一个 *IP 地址*，可以把它想象成一个邮箱地址，有了邮箱地址，邮件才知道发往何处。每台计算机还会拥有一组*端口*，端口号范围从 0 到 65535。同样的，你可以把这些端口想象成用来连接邮箱地址的连接点。

通常情况下，端口会是一个标准端口号或是根据应用程序的应答要求选定的一个端口范围。例如，一台 Web 服务器通常会保留 80 端口用于 HTTP 通信，443 端口用于 HTTPS。小于 1024 的端口主要用于系统或常见用途，1024-49151 端口是已经注册的，49152 及以上端口多为临时使用（只限短时间使用）。

互联网传输中最常见的两个协议，[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) 和 [UDP](https://en.wikipedia.org/wiki/User_Datagram_Protocol)。当要传输的数据很重要，不能有丢包时，就使用 TCP 协议，如果数据包没有按顺序到达，还需要重组为正确的顺序。UDP 协议则更多用于对时间敏感的服务，为了保证时效性，有时允许丢失部分数据。

系统中运行的应用，例如 Web 服务器，会保留一些端口（例如上文提到的 80 和 443）。在网络传输过程中，主机会为传输的两端建立一个链接，一端是源地址和源端口，另一端是目的地址和目的端口。

网络防火墙就是基于地址、端口及其他标准的一组规则集，来对网络数据的传输进行屏蔽或阻断的。通过 `firewall-cmd` 命令，我们就可以查看或修改防火墙的工作配置。

### 防火墙域（zone）

为了验证防火墙是否开启，使用 `firewall-cmd` 命令，输入时要加上 [sudo](https://fedoramagazine.org/howto-use-sudo/)。（通常，在运行了 [PolicyKit](https://en.wikipedia.org/wiki/Polkit) 的环境中，你也可以不加 `sudo`）

```
$ sudo firewall-cmd --state
running
```

firewalld 服务支持任意数量的域。每个域都可以拥有独立的配置和防护规则。一台 Fedora 工作站的外部接口（例如 WIFI 或有线网卡）其默认域为 `FedoraWorkstation`。

要看有哪些域是激活状态，可以使用 `-–get-active-zones` 选项。在本示例中，有两个网卡，有线以太网卡 `wlp2s0` 和虚拟（libvirt）桥接网卡 `virbr0`：

```
$ sudo firewall-cmd --get-active-zones
FedoraWorkstation
  interfaces: wlp2s0
libvirt
  interfaces: virbr0
```

如果想看看默认域是什么，或是直接查询所有域：

```
$ sudo firewall-cmd --get-default-zone
FedoraWorkstation
$ sudo firewall-cmd --get-zones
FedoraServer FedoraWorkstation block dmz drop external home internal libvirt public trusted work
```

查询默认域中防火墙放行了哪些系统，使用 `-–list-services` 选项。下例给出了一个定制系统的查询结果，你可以看到与常见的结果有些不同。

```
$ sudo firewall-cmd --list-services
dhcpv6-client mdns samba-client ssh
```

该系统对外开启了四个服务。每个服务都对应一个常见端口。例如 `ssh` 服务对应 22 端口。

如果要查看当前域中防火墙还开启了哪些端口，可以使用 `--list-ports` 选项。当然，你也可以随时对其他域进行查询：

```
$ sudo firewall-cmd --list-ports --zone=FedoraWorkstation
1025-65535/udp 1025-65535/tcp
```

结果表明，从 1025 到 65535 端口（包含 UDP 和 TCP）默认都是开启的。

### 修改域、端口及服务

以上的配置都是预先设计好的防火墙策略。是为了确保新手用户安装的应用都能够正常访问网络。如果你确定自己心里有数，想要一个保护性更强的策略，可以将接口放入 `FedoraServer` 域，明确禁止所有端口的访问。（**警告**：如果你的服务器之前是联网状态，这么做可能会导致连接中断，那你就得到机房里去修改更多的配置项！）

```
$ sudo firewall-cmd --change-interface=<ifname> --zone=FedoraServer
success
```

**本文并不讨论如何制定防火墙策略，Fedora 社区里已经有很多讨论了。你大可以按照自身需要来修改配置。**

如果你想要开放某个服务的常见端口，可以将该服务加入默认域（或使用 `--zone` 指定一个不同的域）。还可以一次性将其加入多个域。下例开放了 HTTP 和 HTTPS 的常见端口 80、443：

```
$ sudo firewall-cmd --add-service=http --add-service=https
success
```

并非所有的服务都有默认端口，不过大部分都是有的。使用 `-–get-services` 选项可以查看完整列表。

如果你想指定某个特定端口号，可以直接用数字和协议进行配置。（多数情况下，`-–add-service` 和 `-–add-port` 这两个选项是合在一起使用的）下例开启的是 UDP 协议的网络启动服务：

```
$ sudo firewall-cmd --add-port=67/udp
success
```

**重要**：如果想要在系统重启或是 firewalld 服务重启后，配置仍然生效，**必须**在命令中加上 `-–permanent` 选项。本文中的例子只是临时修改了配置，下次遇到系统重启或是 firewalld 服务重启，这些配置就失效了。

以上只是 `firewall-cmd` 和 firewalld 服务诸多功能中的一小部分。firewalld 项目的[主页](https://firewalld.org/)还有更多信息值得你去探索和尝试。

---

via: <https://fedoramagazine.org/control-the-firewall-at-the-command-line/>

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

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


Git 都 15 岁了，如何入门或学习点新东西

>
> 在 Git 15 周年之际，了解为什么 Git 是保持软件行业运行的重要组成部分。
>
>
>

![](/data/attachment/album/202004/13/091410k80er3mttrznc22e.jpg)

如果说过去二十年来有什么东西改变了软件，那么 [Git](https://en.wikipedia.org/wiki/Git) 肯定位列榜首。

如果你没有亲自使用过 Git，你可能会认为它只是一种技术时尚，只是因为它是由 [Linux](https://opensource.com/resources/linux) 项目的创始人创建的，所以在开发者中只是一个偶然的宠儿。这或许有一定的道理，但 Git 确实取得了一些其他行业所没有的成就。有了 Git，分布在世界各地的开发者们可以在同一时间对同一段代码进行工作，并记录下每一次修改的历史，然后将所有的工作合并到一起，形成一个成品。由于这件事情非常复杂，所以这个工具本身也会变得很复杂，但归根结底，它是维持软件行业运行的重要组成部分。

无论你是否了解 Git，如果你足够深入的研究开源软件，或者进入计算机科学领域，都有可能遇到它。无论你使用 Git 只是为了下载一个安装包，还是每天与它交互来管理代码，了解更多关于它的知识，都会对你有很大的启发和帮助。

### Git 术语

与任何专业工具一样，Git 中也有很多行话。像“<ruby> 克隆 <rt>  clone </rt></ruby>”、“<ruby> 合并 <rt>  merge </rt></ruby>”和“<ruby> 变基 <rt>  rebase </rt></ruby>”这样的术语，最起码也是神秘的，而更糟的情况下会令人感到排斥。试图理解这些术语的含义可能会让人不知所措，但如果你从 Matthew Broberg 的优秀文章《[Git 术语基础](https://opensource.com/article/19/2/git-terminology)》中得到一点指导，就不会这样了。只需快速阅读一下，你就能真正理解地听懂关于 Git 的对话。

### Git 入门

如果你需要知道如何使用 Git，那么我自己的[关于使用 Git 的入门文章系列](https://opensource.com/life/16/7/stumbling-git)是一个很好的开始。这些文章已经有几年的历史了，但就像许多 Linux 和 UNIX 技术一样，它的界面并没有发生很大的变化，所以这些文章和我写这些文章那时一样，在今天还是很有意义的。这一系列文章向你介绍了 Git 最基本的概念，并带领你完成创建仓库、提交文件、恢复文件、合并分支等过程。

### 常见的 Git 服务

Git 最常见的用途之一是公共的 Git 托管服务，比如 GitLab 和 GitHub。Kedar Vijay Kulkarni 在他的《[如何在 Git 中克隆、修改、添加和删除文件](https://opensource.com/article/18/2/how-clone-modify-add-delete-git-files)》一文中，演示了大多数开发者使用 Git 执行的日常任务。这不是非开发者的必读书目，但对于任何想在公共 Git 托管服务上为项目做贡献的人来说，这篇文章是必读的。这篇文章专门针对的是 Github，因为它是当今最常见的平台之一，但其原理也适用于任何 Git 服务的 Web 前端，包括 [GitLab](https://about.gitlab.com/install/)、[Gogs](https://gogs.io/) 和 [Gitea](https://gitea.io/en-us/) 等流行的开源框架。

### 试试这个 Git 演练

与其漫无目的的探索，你是不是更喜欢在导游的带领下学习？有时候，学习一件事最简单的方法就是模仿别人的准确步骤。你知道最终的结果是肯定成功的，所以你在进行练习的时候会有信心，而你的大脑和手指也会得到重复的好处，从而建立起记忆。如果这是你的学习风格，那就跟着 Alan Formy-Duvall 的《[Git 的实用学习练习](https://opensource.com/article/19/5/practical-learning-exercise-git)》，找出成功的 Git 课程的感觉。

### Git 应用程序

信不信由你，Git 的界面比你在终端输入的文字更多。显然，在线托管的 Git 有 Web 界面，但是你也可以在计算机上使用 Git 客户端。如果想获得更多的帮助，请阅读 Jesse Duffield 关于 [Lazygit](https://opensource.com/article/20/3/lazygit) 的文章或 Olaf Anders 关于 [Tig](https://opensource.com/article/19/6/what-tig) 的文章。要获得完整的图形应用程序体验，请阅读我有关 [Git-cola](https://opensource.com/article/20/3/git-cola)、[Sparkleshare](https://opensource.com/article/19/4/file-sharing-git) 以及[其它应用](https://opensource.com/life/16/8/graphical-tools-git)的文章。是的，甚至还有[用于你的移动设备的界面](https://opensource.com/article/19/4/calendar-git#mobile)！

### 了解更多关于 Git 的信息

知识就是力量，所以不要让 Git 对你来说像个谜。无论你是直接使用它，还是只知道它的名字，或者你以前从未听说过它，现在都是了解 Git 的好时机。这里有很多资源可以帮助你了解它的工作原理、工作原理以及人们为什么这么喜欢它。潜入其中，按照自己的节奏来学习，并学会爱上 Git 吧！

---

via: <https://opensource.com/article/20/4/get-started-git>

作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


用 k3s 轻松管理 SSL 证书

Summary: 如何在树莓派上使用 k3s 和 Let's Encrypt 来加密你的网站。

如何在树莓派上使用 k3s 和 Let's Encrypt 来加密你的网站。

>
> 如何在树莓派上使用 k3s 和 Let's Encrypt 来加密你的网站。
>
>
>

![](/data/attachment/album/202004/13/153032ncp8q55pjwdj8ppj.jpg)

在[上一篇文章](/article-12081-1.html)中，我们在 k3s 集群上部署了几个简单的网站。那些是未加密的网站。不错，它们可以工作，但是未加密的网站有点太过时了！如今，大多数网站都是加密的。在本文中，我们将安装 [cert-manager](https://cert-manager.io/) 并将其用于在集群上以部署采用 TLS 加密的网站。这些网站不仅会被加密，而且还会使用有效的公共证书，这些证书会从 [Let's Encrypt](https://letsencrypt.org/) 自动获取和更新！让我们开始吧！

### 准备

要继续阅读本文，你将需要我们在上一篇文章中构建的 [k3s 树莓派集群](/article-12049-1.html)。另外，你需要拥有一个公用静态 IP 地址，并有一个可以为其创建 DNS 记录的域名。如果你有一个动态 DNS 提供程序为你提供域名，可能也行。但是，在本文中，我们使用静态 IP 和 [CloudFlare](https://cloudflare.com/) 来手动创建 DNS 的 A 记录。

我们在本文中创建配置文件时，如果你不想键入它们，则可以在[此处](https://gitlab.com/carpie/k3s_using_certmanager/-/archive/master/k3s_using_certmanager-master.zip)进行下载。

### 我们为什么使用 cert-manager？

Traefik（在 k3s 预先捆绑了）实际上具有内置的 Let's Encrypt 支持，因此你可能想知道为什么我们要安装第三方软件包来做同样的事情。在撰写本文时，Traefik 中的 Let's Encrypt 支持检索证书并将其存储在文件中。而 cert-manager 会检索证书并将其存储在 Kubernetes 的 “<ruby> 机密信息 <rt>  secret </rt></ruby>” 中。我认为，“机密信息”可以简单地按名称引用，因此更易于使用。这就是我们在本文中使用 cert-manager 的主要原因。

### 安装 cert-manager

通常，我们只是遵循 cert-manager 的[文档](https://cert-manager.io/docs/installation/kubernetes/)在 Kubernetes 上进行安装。但是，由于我们使用的是 ARM 体系结构，因此我们需要进行一些更改，以便我们可以完成这个操作。

第一步是创建 cert-manager 命名空间。命名空间有助于将 cert-manager 的 Pod 排除在我们的默认命名空间之外，因此当我们使用自己的 Pod 执行 `kubectl get pods` 之类的操作时，我们不必看到它们。创建名称空间很简单：

```
kubectl create namespace cert-manager
```

安装说明会让你下载 cert-manager 的 YAML 配置文件并将其一步全部应用到你的集群。我们需要将其分为两个步骤，以便为基于 ARM 的树莓派修改文件。我们将下载文件并一步一步进行转换：

```
curl -sL \
https://github.com/jetstack/cert-manager/releases/download/v0.11.0/cert-manager.yaml |\
sed -r 's/(image:.*):(v.*)$/\1-arm:\2/g' > cert-manager-arm.yaml
```

这会下载配置文件，并将包含的所有 docker 镜像更新为 ARM 版本。来检查一下它做了什么：

```
$ grep image: cert-manager-arm.yaml
          image: "quay.io/jetstack/cert-manager-cainjector-arm:v0.11.0"
          image: "quay.io/jetstack/cert-manager-controller-arm:v0.11.0"
          image: "quay.io/jetstack/cert-manager-webhook-arm:v0.11.0"
```

如我们所见，三个镜像现在在镜像名称上添加了 `-arm`。现在我们有了正确的文件，我们只需将其应用于集群：

```
kubectl apply -f cert-manager-arm.yaml
```

这将安装 cert-manager 的全部。我们可以通过 `kubectl --namespace cert-manager get pods` 来检查安装何时完成，直到所有 Pod 都处于 `Running` 状态。

这就完成了 cert-manager 的安装！

### Let's Encrypt 概述

Let's Encrypt 的好处是，它免费为我们提供了经过公共验证的 TLS 证书！这意味着我们可以拥有一个完全有效的、可供任何人访问的 TLS 加密网站，这些家庭或业余的爱好活动挣不到钱，也无需自己掏腰包购买 TLS 证书！以及，当通过 cert-manager 使用 Let's Encrypt 的证书时，获得证书的整个过程是自动化的，证书的续订也是自动的！

但它是如何工作的？下面是该过程的简化说明。我们（或代表我们的 cert-manager）向 Let's Encrypt 发出我们拥有的域名的证书请求。Let's Encrypt 通过使用 ACME DNS 或 HTTP 验证机制来验证我们是否拥有该域。如果验证成功，则 Let's Encrypt 将向我们提供证书，这些证书将由 cert-manager 安装在我们的网站（或其他 TLS 加密的端点）中。在需要重复此过程之前，这些证书可以使用 90 天。但是，cert-manager 会自动为我们更新证书。

在本文中，我们将使用 HTTP 验证方法，因为它更易于设置并且适用于大多数情况。以下是幕后发生的基本过程。cert-manager 向 Let's Encrypt 发出证书请求。作为回应，Let's Encrypt 发出所有权验证的<ruby> 质询 <rt>  challenges </rt></ruby>。这个质询是将一个 HTTP 资源放在请求证书的域名下的一个特定 URL 上。从理论上讲，如果我们可以将该资源放在该 URL 上，并且让 Let's Encrypt 可以远程获取它，那么我们实际上必须是该域的所有者。否则，要么我们无法将资源放置在正确的位置，要么我们无法操纵 DNS 以使 Let's Encrypt 访问它。在这种情况下，cert-manager 会将资源放在正确的位置，并自动创建一个临时的 `Ingress` 记录，以将流量路由到正确的位置。如果 Let's Encrypt 可以读到该质询要求的资源并正确无误，它将把证书发回给 cert-manager。cert-manager 将证书存储为“机密信息”，然后我们的网站（或其他任何网站）将使用这些证书通过 TLS 保护我们的流量。

### 为该质询设置网络

我假设你要在家庭网络上进行设置，并拥有一个以某种方式连接到更广泛的互联网的路由器/接入点。如果不是这种情况，则可能不需要以下过程。

为了使质询过程正常运行，我们需要一个我们要申请证书的域名，以将其路由到端口 80 上的 k3s 集群。为此，我们需要告诉世界上的 DNS 系统它的位置。因此，我们需要将域名映射到我们的公共 IP 地址。如果你不知道你的公共 IP 地址是什么，可以访问 [WhatsMyIP](https://whatsmyip.org/) 之类的地方，它会告诉你。接下来，我们需要输入 DNS 的 A 记录，该记录将我们的域名映射到我们的公共 IP 地址。为了使此功能可靠地工作，你需要一个静态的公共 IP 地址，或者你可以使用动态 DNS 提供商。一些动态 DNS 提供商会向你颁发一个域名，你可以按照以下说明使用它。我没有尝试过，所以不能肯定地说它适用于所有提供商。

对于本文，我们假设有一个静态公共 IP，并使用 CloudFlare 来设置 DNS 的 A 记录。如果愿意，可以使用自己的 DNS 服务器。重要的是你可以设置 A 记录。

在本文的其余部分中，我将使用 [k3s.carpie.net](http://k3s.carpie.net) 作为示例域名，因为这是我拥有的域。你显然会用自己拥有的任何域名替换它。

为示例起见，假设我们的公共 IP 地址是 198.51.100.42。我们转到我们的 DNS 提供商的 DNS 记录部分，并添加一个名为 [k3s.carpie.net](http://k3s.carpie.net) 的类型为 `A` 的记录（CloudFlare 已经假定了域的部分，因此我们只需输入 `k3s`），然后输入 `198.51.100.42` 作为 IPv4 地址。

![](/data/attachment/album/202004/13/153252k3tos5tam00maywo.png)

请注意，有时 DNS 更新要传播一段时间。你可能需要几个小时才能解析该名称。在继续之前该名称必须可以解析。否则，我们所有的证书请求都将失败。

我们可以使用 `dig` 命令检查名称是否解析：

```
$ dig +short k3s.carpie.net
198.51.100.42
```

继续运行以上命令，直到可以返回 IP 才行。关于 CloudFlare 有个小注释：ClouldFlare 提供了通过代理流量来隐藏你的实际 IP 的服务。在这种情况下，我们取回的是 CloudFlare 的 IP，而不是我们的 IP。但对于我们的目的，这应该可以正常工作。

网络配置的最后一步是配置路由器，以将端口 80 和 443 上的传入流量路由到我们的 k3s 集群。可悲的是，路由器配置页面的差异很大，因此我无法确切地说明你的外观是什么样子。大多数时候，我们需要的管理页面位于“端口转发”或类似内容下。我甚至看到过它列在“游戏”之下（显然是端口转发主要用于的游戏）！让我们看看我的路由器的配置如何。

![](/data/attachment/album/202004/13/153257qb6fm6ef3udhz6kt.png)

如果你和我的环境一样，则转到 192.168.0.1 登录到路由器管理应用程序。对于此路由器，它位于 “ NAT/QoS” -> “端口转发”。在这里，我们将端口 80/TCP 协议设置为转发到 192.168.0.50（主节点 `kmaster` 的 IP）的端口 80。我们还设置端口 443 也映射到 `kmaster`。从技术上讲，这对于质询来说并不是必需的，但是在本文的结尾，我们将部署一个启用 TLS 的网站，并且需要映射 443 来进行访问。因此，现在进行映射很方便。我们保存并应用更改，应该一切顺利！

### 配置 cert-manager 来使用 Let's Encrypt（暂存环境）

现在，我们需要配置 cert-manager 来通过 Let's Encrypt 颁发证书。Let's Encrypt 为我们提供了一个暂存（例如用于测试）环境，以便审视我们的配置。这样它更能容忍错误和请求的频率。如果我们对生产环境做了错误的操作，我们很快就会发现自己被暂时禁止访问了！因此，我们将使用暂存环境手动测试请求。

创建一个文件 `letsencrypt-issuer-staging.yaml`，内容如下：

```
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # The ACME server URL
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: <your_email>@example.com
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-staging
    # Enable the HTTP-01 challenge provider
    solvers:
    - http01:
        ingress:
          class: traefik
```

请确保将电子邮件地址更新为你的地址。如果出现问题或我们弄坏了一些东西，这就是 Let's Encrypt 与我们联系的方式！

现在，我们使用以下方法创建<ruby> 发行者 <rt>  issuer </rt></ruby>：

```
kubectl apply -f letsencrypt-issuer-staging.yaml
```

我们可以使用以下方法检查发行者是否已成功创建：

```
kubectl get clusterissuers
```

`clusterissuers` 是由 cert-manager 创建的一种新的 Kubernetes 资源类型。

现在让我们手动请求一个测试证书。对于我们的网站，我们不需要这样做；我们只是在测试这个过程，以确保我们的配置正确。

创建一个包含以下内容的证书请求文件 `le-test-certificate.yaml`：

```
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: k3s-carpie-net
  namespace: default
spec:
  secretName: k3s-carpie-net-tls
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
  commonName: k3s.carpie.net
  dnsNames:
  - k3s.carpie.net
```

该记录仅表示我们要使用名为 `letsencrypt-staging`（我们在上一步中创建的）的 `ClusterIssuer` 来请求域 [k3s.carpie.net](http://k3s.carpie.net) 的证书，并在 Kubernetes 的机密信息中名为 `k3s-carpie-net-tls` 的文件中存储该证书。

像平常一样应用它：

```
kubectl apply -f le-test-certificate.yaml
```

我们可以通过以下方式查看状态：

```
kubectl get certificates
```

如果我们看到类似以下内容：

```
NAME                    READY   SECRET                  AGE
k3s-carpie-net          True    k3s-carpie-net-tls      30s
```

我们走在幸福之路！（这里的关键是 `READY` 应该是 `True`）。

### 解决证书颁发问题

上面是幸福的道路。如果 `READY` 为 `False`，我们可以等等它，然后再次花点时间检查状态。如果它一直是 `False`，那么我们就有需要解决的问题。此时，我们可以遍历 Kubernetes 资源链，直到找到一条告诉我们问题的状态消息。

假设我们执行了上面的请求，而 `READY` 为 `False`。我们可以从以下方面开始故障排除：

```
kubectl describe certificates k3s-carpie-net
```

这将返回很多信息。通常，有用的内容位于 `Events:` 部分，该部分通常位于底部。假设最后一个事件是 `Created new CertificateRequest resource "k3s-carpie-net-1256631848`。然后我们<ruby> 描述 <rt>  describe </rt></ruby>一下该请求：

```
kubectl describe certificaterequest k3s-carpie-net-1256631848
```

现在比如说最后一个事件是 `Waiting on certificate issuance from order default/k3s-carpie-net-1256631848-2342473830`。

那么，我们可以描述该顺序：

```
kubectl describe orders default/k3s-carpie-net-1256631848-2342473830
```

假设有一个事件，事件为 `Created Challenge resource "k3s-carpie-net-1256631848-2342473830-1892150396" for domain "k3s.carpie.net"`。让我们描述一下该质询：

```
kubectl describe challenges k3s-carpie-net-1256631848-2342473830-1892150396
```

从这里返回的最后一个事件是 `Presented challenge using http-01 challenge mechanism`。看起来没问题，因此我们浏览一下描述的输出，并看到一条消息 `Waiting for http-01 challenge propagation: failed to perform self check GET request ... no such host`。终于！我们发现了问题！在这种情况下，`no such host` 意味着 DNS 查找失败，因此我们需要返回并手动检查我们的 DNS 设置，正确解析域的 DNS，并进行所需的任何更改。

### 清理我们的测试证书

我们实际上想要使用的是域名的真实证书，所以让我们继续清理证书和我们刚刚创建的机密信息：

```
kubectl delete certificates k3s-carpie-net
kubectl delete secrets k3s-carpie-net-tls
```

### 配置 cert-manager 以使用 Let's Encrypt（生产环境）

现在我们已经有了测试证书，是时候移动到生产环境了。就像我们在 Let's Encrypt 暂存环境中配置 cert-manager 一样，我们现在也需要对生产环境进行同样的操作。创建一个名为 `letsencrypt-issuer-production.yaml` 的文件（如果需要，可以复制和修改暂存环境的文件），其内容如下：

```
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
 # The ACME server URL
  server: https://acme-v02.api.letsencrypt.org/directory
  # Email address used for ACME registration
  email: <your_email>@example.com
  # Name of a secret used to store the ACME account private key
  privateKeySecretRef:
    name: letsencrypt-prod
  # Enable the HTTP-01 challenge provider
  solvers:
  - http01:
      ingress:
        class: traefik
```

（如果要从暂存环境进行复制，则唯一的更改是 `server:` URL。也请不要忘记修改电子邮件！）

应用它：

```
kubectl apply -f letsencrypt-issuer-production.yaml
```

### 申请我们网站的证书

重要的是需要注意，我们到目前为止完成的所有步骤都只需要进行一次！而对于将来的任何其他申请，我们可以从这个说明开始！

让我们部署在[上一篇文章](/article-12081-1.html)中部署的同样站点。（如果仍然可用，则可以修改 YAML 文件。如果没有，则可能需要重新创建并重新部署它）。

我们只需要将 `mysite.yaml` 的 `Ingress` 部分修改为：

```
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: mysite-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "traefik"
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  rules:
  - host: k3s.carpie.net
    http:
      paths:
      - path: /
        backend:
          serviceName: mysite-nginx-service
          servicePort: 80
  tls:
  - hosts:
    - k3s.carpie.net
    secretName: k3s-carpie-net-tls
```

请注意，上面仅显示了 `mysite.yaml` 的 `Ingress` 部分。所做的更改是添加了注解 `cert-manager.io/cluster-issuer: letsencrypt-prod`。这告诉 traefik 创建证书时使用哪个发行者。 其他唯一增加的是 `tls:` 块。这告诉 traefik 我们希望在主机 [k3s.carpie.net](http://k3s.carpie.net) 上具有 TLS 功能，并且我们希望 TLS 证书文件存储在机密信息 `k3s-carpie-net-tls` 中。

请记住，我们没有创建这些证书！（好吧，我们创建了名称相似的测试证书，但我们删除了这些证书。）Traefik 将读取这些配置并继续寻找机密信息。当找不到时，它会看到注释说我们想使用 `letsencrypt-prod` 发行者来获取它。由此，它将提出请求并为我们安装证书到机密信息之中！

大功告成！ 让我们尝试一下。

它现在具有了加密 TLS 所有优点！恭喜你！

---

via: <https://opensource.com/article/20/3/ssl-letsencrypt-k3s>

作者：[Lee Carpenter](https://opensource.com/users/carpie) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


什么是 Arch 用户仓库（AUR）以及如何使用？

Summary: 如果你一直在使用 Arch Linux 或其他基于 Arch 的发行版，如 Manjaro，那么可能会遇到 AUR。你尝试安装新软件，有人建议从 AUR 中安装它。这让你感到困惑。

如果你一直在使用 [Arch Linux](https://www.archlinux.org/) 或其他基于 Arch 的发行版，如 Manjaro，那么可能会遇到 AUR。你尝试安装新软件，有人建议从 AUR 中安装它。这让你感到困惑。

什么是 AUR？为什么使用它？如何使用 AUR？我将在本文中回答这些问题。

### 什么是 AUR？

![](/data/attachment/album/202004/13/202409mu6h0u7u62og52gh.png)

AUR 表示<ruby> Arch 用户仓库 <rt>  Arch User Repository </rt></ruby>。它是针对基于 Arch 的 Linux 发行版用户的社区驱动的仓库。它包含名为 [PKGBUILD](https://wiki.archlinux.org/index.php/PKGBUILD) 的包描述，它可让你使用 [makepkg](https://wiki.archlinux.org/index.php/Makepkg) 从源代码编译软件包，然后通过 [pacman](https://wiki.archlinux.org/index.php/Pacman#Additional_commands)（Arch Linux 中的软件包管理器）安装。

创建 AUR 的目的是组织和共享社区中的新软件包，并帮助加速将流行的软件包纳入[社区仓库](https://wiki.archlinux.org/index.php/Community_repository)。

进入官方仓库的大量新软件包都从 AUR 开始。在 AUR 中，用户可以贡献自己的软件包构建（PKGBUILD 和相关文件）。

AUR 社区可以对 AUR 中的软件包进行投票。如果一个软件包变得足够流行（假设它具有兼容的许可证和良好的打包技术），那么可以将其加入 `pacman` 直接访问的社区仓库中。

>
> 简而言之，AUR 是开发人员在 Arch 仓库中正式包含新软件之前向 Arch Linux 用户提供新软件的一种方式。
>
>
>

### 你应该使用 AUR 吗？有什么风险？

使用 AUR 就像过马路一样。如果你谨慎操作，应该就没问题。

如果你刚接触 Linux，建议你在建立有关 Arch/Manjaro 和 Linux 的基础知识之前不要使用 AUR。

的确，任何人都可以将软件包上传到 AUR，但[受信任用户](https://wiki.archlinux.org/index.php/Trusted_Users)（TU）负责监视上传的内容。尽管 TU 对上传的软件包执行质量控制，但不能保证 AUR 中的软件包格式正确或没有恶意。

在实践中，AUR 似乎很安全，但理论上讲它可以造成一定程度的损害，但前提是你不小心。从 AUR 构建软件包时，聪明的 Arch 用户**总是**检查 `PKGBUILD` 和 `*.install` 文件。

此外，TU（受信任用户）还会删除 AUR 中包含在 core/extra/community 中的软件包，因此它们之间不应存在命名冲突。AUR 通常会包含软件包的开发版本（cvs/svn/git 等），但它们的名称会被修改，例如 foo-git。

对于 AUR 软件包，`pacman` 会处理依赖关系并检测文件冲突，因此，除非你默认使用 `–force` 选项，否则你不必担心用另一个包中的文件会覆盖另一个包的文件。如果这么做了，你可能会遇到比文件冲突更严重的问题。

### 如何使用 AUR？

使用 AUR 的最简单方法是通过 AUR 助手。 [AUR 助手](https://itsfoss.com/best-aur-helpers/) 是一个命令行工具（有些还有 GUI），可让你搜索在 AUR 上发布的软件包并安装。

#### 在 Arch Linux 上安装 AUR 助手

假设你要使用 [Yay AUR 助手](https://github.com/Jguer/yay)。确保在 Linux 上安装了 git。然后克隆仓库，进入目录并构建软件包。

依次使用以下命令：

```
sudo pacman -S git
sudo git clone https://aur.archlinux.org/yay-git.git
cd yay
makepkg -si
```

安装后，你可以使用 `yay` 命令来安装软件包：

```
yay -S package_name
```

并非必须使用 AUR 助手来从 AUR 安装软件包。从以下文章解如何在没有 AUR 助手的情况下使用 AUR。

#### 不使用 AUR 助手安装 AUR 软件包

如果你不想使用 AUR 助手，那么也可以自行从 AUR 安装软件包。

在 [AUR 页面](https://aur.archlinux.org/)上找到要安装的软件包后，建议确认“许可证”、“流行程度”、“最新更新”、“依赖项”等，作为额外的质量控制步骤。

```
git clone [package URL]
cd [package name]
makepkg -si
```

例如。假设你要安装 [telegram 桌面包](https://aur.archlinux.org/packages/telegram-desktop-git)：

```
git clone https://aur.archlinux.org/telegram-desktop-git.git
cd telegram-desktop-git
makepkg -si
```

#### 在 Manjaro Linux 中启用 AUR 支持

它默认情况下未启用 AUR，你必须通过 `pamac` 启用它。我的笔记本电脑运行 [Manjaro](https://manjaro.org/) Cinnamon，但是所有 Manjaro 变种的步骤都相同。

打开 Pamac（显示为 “Add/Remove Software”）：

![](/data/attachment/album/202004/13/202757a8kak498x4lk4831.png)

进入 Pamac 后，请进入如下所示的<ruby> 首选项 <rt>  preferences </rt></ruby>。

![](/data/attachment/album/202004/13/202829u9j7v8mg7g2m02nd.png)

在首选项对话框中，进入 “AUR” 选项卡，启用 AUR 支持，启用检查更新，并关闭对话框。

![](/data/attachment/album/202004/13/202852ni77vilrwzdwwype.png)

现在，你可以搜索软件包，并且可以通过软件包描述下的标签来识别属于 AUR 的软件包。

![](/data/attachment/album/202004/13/202922iu6ww7t8hsyzzasd.png)

希望本文对你有用，并关注社交媒体上即将出现的与 Arch 相关的主题。

---

via: <https://itsfoss.com/aur-arch-linux/>

作者：[Dimitrios Savvopoulos](https://itsfoss.com/author/dimitrios/) 选题：[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/) 荣誉推出


用 Chezmoi 取回你的点文件

![](/data/attachment/album/202004/14/183618dwkhe4ehx1kthxvw.jpg)

在 Linux 中，点文件是隐藏的文本文件，从 Bash、Git 到 i3 或 VSCode 等更复杂的许多应用程序，都用它存储配置设置。

这些文件大多数都放在 `~/.config` 目录中或用户主目录中。编辑这些文件使你可以自定义也许没有提供设置菜单的应用程序，并且它们可以跨设备甚至是跨其它 Linux 发行版移植。但是，整个 Linux 发烧友社区的讨论焦点是如何管理这些点文件以及如何共享它们。

我们将展示一个名为 [Chezmoi](https://www.chezmoi.io/) 的工具，该工具与其它工具略有不同。

### 点文件管理的历史

如果你在 [GitHub 上搜索“dotfiles”](https://github.com/search?q=dotfiles&type=Repositories)，那么你将看到有超过 10 万个存储库在解决一个目标：将人们的点文件存储在可共享且可重复的领地中。但是，除了都在使用 Git 之外，它们存储文件的方式各有不同。

虽然 Git 解决了代码管理问题，也将其转换为配置文件管理，但它并没有解决如何区分发行版、角色（例如家用计算机与工作计算机）、机密信息管理以及按设备配置的问题。

因此，许多用户决定制定自己的解决方案，多年来，社区已经做出了许多成果。本文将简要介绍已有的一些解决方案。

#### 在孤立的环境中进行实验

你想在封闭的环境中快速尝试以下解决方案吗？运行：

```
$ podman run --rm -it fedora
```

来创建一个 Fedora 容器尝试应用程序。退出容器时，该容器将自动删除自身。

#### 安装问题

如果将点文件存储在 Git 存储库中，你肯定希望可以让更改轻松地自动应用到主目录之中，乍一看，最简单的方法是使用符号链接，例如 `ln -s ~/.dotfies/bashrc ~/.bashrc`。这可以使你的更改在更新存储库时立即就绪。

符号链接的问题在于管理符号链接可能很麻烦。Stow 和 [RCM](https://fedoramagazine.org/managing-dotfiles-rcm/)（在 Fedora 杂志上介绍过）可以帮助你管理这些，但是这些并不是非常舒服的解决方案。下载后，需要对私有文件进行适当的修改和设置访问模式。如果你在一个系统上修改了点文件，然后将存储库下载到另一个系统，则可能会发生冲突并需要进行故障排除。

解决此问题的另一种方法是编写自己的安装脚本。这是最灵活的选项，但要权衡花费更多时间来构建自定义解决方案是否值得。

#### 机密信息问题

Git 旨在跟踪更改。如果你在 Git 存储库中存储密码或 API 密钥之类的机密信息，则会比较麻烦，并且需要重写 Git 历史记录以删除该机密信息。如果你的存储库是公开的，那么如果其他人下载了你的存储库，你的机密信息将不再保密。仅这个问题就会阻止许多人与公共世界共享其点文件。

#### 多设备配置问题

问题不在于如何将配置拉到多个设备，而是当你有多个需要不同配置的设备的问题。大多数人通过使用不同的文件夹或使用不同的<ruby> 复刻 <rt>  fork </rt></ruby>来处理此问题。这使得难以在不同设备和角色集之间共享配置。

### Chezmoi 是如何干的

Chezmoi 是一种考虑了以上问题的用于管理点文件的工具，它不会盲目地从存储库复制或符号链接文件。 Chezmoi 更像是模板引擎，可以根据系统变量、模板、机密信息管理器和 Chezmoi 自己的配置文件来生成你的点文件。

#### Chezmoi 入门

目前，Chezmoi 并不在 Fedora 的默认软件库中。你可以使用以下命令下载 Chezmoi 的当前版本。

```
$ sudo dnf install https://github.com/twpayne/chezmoi/releases/download/v1.7.17/chezmoi-1.7.17-x86_64.rpm
```

这会将预打包的 RPM 安装到你的系统中。

让我们继续使用以下方法创建你的存储库：

```
$ chezmoi init
```

它将在 `~/.local/share/chezmoi/` 中创建你的新存储库。你可以使用以下命令轻松地切换到该目录：

```
$ chezmoi cd
```

让我们添加第一个文件：

```
chezmoi add ~/.bashrc
```

这将你的 `.bashrc` 文件添加到 chezmoi 存储库。

注意：如果你的 `.bashrc` 文件实际上是一个符号链接，则需要添加 `-f` 标志以跟随它来读取实际文件的内容。

现在，你可以使用以下命令编辑该文件：

```
$ chezmoi edit ~/.bashrc
```

现在让我们添加一个私有文件，这是一个具有 600 或类似权限的文件。我在 `.ssh/config` 中有一个文件，我想通过使用如下命令添加它：

```
$ chezmoi add ~/.ssh/config
```

Chezmoi 使用特殊的前缀来跟踪隐藏文件和私有文件，以解决 Git 的限制。运行以下命令以查看它：

```
$ chezmoi cd
```

**请注意，标记为私有的文件实际上并不是私有的，它们仍会以纯文本格式保存在你的 Git 存储库中。稍后会进一步解释。**

你可以使用以下方法应用任何更改：

```
$ chezmoi apply
```

并使用如下命令检查有什么不同：

```
$ chezmoi diff
```

#### 使用变量和模板

要导出 Chezmoi 可以收集的所有数据，请运行：

```
$ chezmoi data
```

其中大多数是有关用户名、架构、主机名、操作系统类型和操作系统名称的信息。但是你也可以添加我们自己的变量。

继续，运行：

```
$ chezmoi edit-config
```

然后输入以下内容：

```
[data]
         email = "fedorauser@example.com"
         name = "Fedora Mcdora"
```

保存文件，然后再次运行 `chezmoi data`。你将在底部看到你的电子邮件和姓名已经添加成功。现在，你可以将这些与 Chezmoi 的模板一起使用。运行：

```
$ chezmoi add  -T --autotemplate ~/.gitconfig
```

来将你的 `.gitconfig` 作为模板添加到 Chezmoi 中。如果 Chezmoi 成功地正确推断了模板，你将获得以下信息：

```
[user]
         email = "{{ .email }}"
         name = "{{ .name }}"
```

如果没有，则可以将文件更改为这样。

使用以下方法检查文件：

```
$ chezmoi edit ~/.gitconfig
```

然后使用：

```
$ chezmoi cat ~/.gitconfig
```

来查看 Chezmoi 为此文件生成什么。我生成的示例如下：

```
[root@a6e273a8d010 ~]# chezmoi cat ~/.gitconfig
[user]
    email = "fedorauser@example.com"
    name = "Fedora Mcdora"
[root@a6e273a8d010 ~]#
```

它将在我们的 Chezmoi 配置中生成一个充满变量的文件。你也可以使用变量执行简单的逻辑语句。一个例子是：

```
{{- if eq .chezmoi.hostname "fsteel" }}
# 如果主机名为 "fsteel" 才包括此部分
{{- end }}
```

请注意，要使其正常工作，该文件必须是模板。你可以通过查看文件是否在 `chezmoi cd` 中的文件名后附加 `.tmpl` 或使用 `-T` 选项读取文件来进行检查。

#### 让机密信息保持机密

要对设置进行故障排除，请使用以下命令。

```
$ chezmoi doctor
```

这里重要的是它还向你显示了[所支持的密码管理器](https://www.chezmoi.io/docs/how-to/#keep-data-private)。

```
[root@a6e273a8d010 ~]# chezmoi doctor
 warning: version dev
      ok: runtime.GOOS linux, runtime.GOARCH amd64
      ok: /root/.local/share/chezmoi (source directory, perm 700)
      ok: /root (destination directory, perm 550)
      ok: /root/.config/chezmoi/chezmoi.toml (configuration file)
      ok: /bin/bash (shell)
      ok: /usr/bin/vi (editor)
 warning: vimdiff (merge command, not found)
      ok: /usr/bin/git (source VCS command, version 2.25.1)
      ok: /usr/bin/gpg (GnuPG, version 2.2.18)
 warning: op (1Password CLI, not found)
 warning: bw (Bitwarden CLI, not found)
 warning: gopass (gopass CLI, not found)
 warning: keepassxc-cli (KeePassXC CLI, not found)
 warning: lpass (LastPass CLI, not found)
 warning: pass (pass CLI, not found)
 warning: vault (Vault CLI, not found)
 [root@a6e273a8d010 ~]#
```

你可以使用这些客户端，也可以使用[通用客户端](https://www.chezmoi.io/docs/how-to/#use-a-generic-tool-to-keep-your-secrets)，也可以使用系统的[密钥环](https://www.chezmoi.io/docs/how-to/#use-a-keyring-to-keep-your-secrets)。

对于 GPG，你需要使用以下命令将以下内容添加到配置中：

```
$ chezmoi edit-config
```

```
[gpg]
   recipient = "<Your GPG keys Recipient"
```

你可以使用：

```
$ chezmoi add --encrypt
```

来添加任何文件，这些文件将在你的源存储库中加密，并且不会以纯文本格式公开。Chezmoi 会在应用时自动将其解密。

我们也可以在模板中使用它们。例如，存储在 [Pass](https://fedoramagazine.org/using-pass-to-manage-your-passwords-on-fedora/)（已在 Fedora 杂志上介绍）中的机密令牌。继续，生成你的机密信息。

在此示例中，它称为 `githubtoken`：

```
rwaltr@fsteel:~] $ pass ls
 Password Store
 └── githubtoken
 [rwaltr@fsteel:~] $
```

接下来，编辑你的模板，例如我们之前创建的 `.gitconfig` 并添加以下行。

```
token = {{ pass "githubtoken" }}
```

然后让我们使用检查：

```
$ chezmoi cat ~/.gitconfig
```

```
[rwaltr@fsteel:~] $ chezmoi cat ~/.gitconfig
 This is Git's per-user configuration file.
 [user]
           name = Ryan Walter
           email = rwalt@pm.me
           token = mysecrettoken
 [rwaltr@fsteel:~] $
```

现在，你的机密信息已在密码管理器中妥善保护，你的配置可以公开共享而没有任何风险！

### 最后的笔记

这里仅仅涉及到表面。请访问 [Chezmoi 的网站](https://www.chezmoi.io/)了解更多信息。如果你正在寻找有关如何使用 Chezmoi 的更多示例，作者还可以公开了他的[点文件](https://github.com/twpayne/dotfiles)。

---

via: <https://fedoramagazine.org/take-back-your-dotfiles-with-chezmoi/>

作者：[Ryan Walter](https://fedoramagazine.org/author/rwaltr/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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