从实际代码开始编写好的示例

# 从实际代码开始编写好的示例

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

当编写程序时，我花费了大量时间在编写好的示例上。我从未见过有人写过关于如何写出好的示例，所以我就写了一下如何写出一份好的示例。

基础思路就是从你写的真实代码开始，然后删除不相关的细节，使其成为一个独立的例子，而不是无中生有地想出一些例子。

我将会谈论两种示例：基于真实案例的示例和奇怪的示例

### 好的示例是真实的

为了说明为什么好的案例应该是真实的，我们就先讨论一个不真实的案例。假设我们在试图解释 Python 的 lambda 函数（这只是我想到的第一个概念）。你可以举一个例子，使用 `map` 和 lambda 来让一组数字变为原先的两倍。

```
numbers = [1, 2, 3, 4]
squares = map(lambda x: x * x, numbers)

```

我觉得这个示例不是真实的，有如下两方面的原因：

* 将一组数字作平方运算不是在真实的程序中完成的事，除非是欧拉项目或某种东西（更多的可能是针对列表的操作）
* `map` 在 Python 中并不常用，即便是做这个我也更愿意写 `[x*x for x in numbers]`

一个更加真实的 Python lambdas 的示例是使用 `sort` 函数，就像这样：

```
children = [{"name": "ashwin", "age": 12}, {"name": "radhika", "age": 3}]
sorted_children = sorted(children, key=lambda x: x['age'])

```

但是这个示例是被精心设计的（为什么我们需要对这些孩子按照年龄进行排序呢？）。所以我们如何来做一个真实的示例呢？

### 如何让你的示例真实起来：看你所写实际代码

我认为最简单的来生成一个例子的方法就是，不是凭空出现一个例子（就像我用那个`儿童`的例子），而只是从真正的代码开始！

举一个例子吧，如果我要用 `sort.+key` 来编写一串 Python 代码，我会发现很多我按某个标准对列表进行排序的真实例子，例如：

* `tasks.sort(key=lambda task: task['completed_time'])`
* `emails = reversed(sorted(emails, key=lambda x:x['receivedAt']))`
* `sorted_keysizes = sorted(scores.keys(), key=scores.get)`
* `shows = sorted(dates[date], key=lambda x: x['time']['performanceTime'])`

在这里很容易看到一个规律——这些基本是按时间排序的！因此，你可以明白如何将按时间排序的某些对象（电子邮件、事件等）的简单实例轻松地放在一起。

### 现实的例子有助于“布道”你试图解释的概念

当我试图去解释一个想法（就好比 Python Lambdas）的时候，我通常也会试图说服读者，说这是值得学习的想法。Python lambdas 是如此的有用！当我去试图说服某个人 lambdas 是很好用的时候，让他想象一下 lambdas 如何帮助他们完成一项他们将要去做的任务或是以及一项他们以前做过的任务，对说服他会很有帮助。

### 从真实代码中提炼出示例可能需要很长时间

我给出如何使用 `lambda` 和 `sort` 函数的解释例子是十分简单的，它并不需要花费我很长时间来想出来，但是将真实的代码提炼出为一个独立的示例则是会需要花费很长的时间！

举个例子，我想在这篇文章中融入一些奇怪的 CSS 行为的例子来说明创造一个奇怪的案例是十分有趣的。我花费了两个小时来解决我这周遇到的一个实际的问题，确保我理解 CSS 的实际情况，并将其变成一个小示例。

最后，它“仅仅”用了 [五行 HTML 和一点点的 CSS](https://codepen.io/wizardzines/pen/0eda7725a46c919dcfdd3fa80aff3d41) 来说明了这个问题，看起来并不想是我花费了好多小时写出来的。但是最初它却是几百行的 JS/CSS/JavaScript，它需要花费很长时间来将所有的代码化为核心的很少的代码。

但我认为花点时间把示例讲得非常简单明了是值得的——如果有成百上千的人在读你的示例，你就节省了他们这么多时间！

### 就这么多了！

我觉得还有更多关于示例可以去讲的——几种不同类型的有用示例，例如：

* 可以更多的改变人的思维而不是直接提供使用的惊喜读者的示例代码
* 易于复制粘贴以用作初始化的示例

也许有一天我还会再写一些呢？ :smiley:

---

via: <https://jvns.ca/blog/2021/07/08/writing-great-examples/>

作者：[Julia Evans](https://jvns.ca/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[zepoch](https://github.com/zepoch) 校对：[turbokernel](https://github.com/turbokernel)

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


硬核观察 #337 “Linux 随机数生成器”（LRNG） 已经开发了五年

Summary: 更多：• 新研究确认 Rust 的安全性 • 大量比特币矿工前往美国

更多：• 新研究确认 Rust 的安全性 • 大量比特币矿工前往美国

# 硬核观察 #337 “Linux 随机数生成器”（LRNG） 已经开发了五年

### “Linux 随机数生成器”（LRNG） 已经开发了五年

作为 `/dev/random` 的新替代品，“Linux 随机数生成器”（LRNG）已经进行了[第 41 次修订](https://www.phoronix.com/scan.php?page=news_item&px=LRNG-Random-2021-v41)，对它的开发了已经超过了 5 年。LRNG 是对现有随机数生成器的 API/ABI 兼容的替代品。LRNG 的目标是提高速度，以及其他各种性能优化，各种加密处理的改进，测试能力的提高，选项的更大可配置性，并且是一个更现代的设计。LRNG 是否以及何时可以[进入](https://lore.kernel.org/lkml/7822794.ITf6fX9eNu@positron.chronox.de/) Linux 主线还有待观察。

>
> 看似简单的随机数，其实是计算安全上最重要的基石之一，也可能是这个宇宙最重要的基础之一。
>
>
>

### 新研究确认 Rust 的安全性

Rust 有两种模式：其默认的安全模式和不安全模式。在其默认的安全模式下，Rust 可以防止内存错误和数据竞争。而在它的不安全模式下允许使用潜在的不安全的 C 风格的函数。验证 Rust 的安全声明的关键挑战是说明其安全和不安全代码之间的互动。

一篇发表在 4 月份的《ACM 通讯》的[文章](https://cacm.acm.org/magazines/2021/4/251364-safe-systems-programming-in-rust/fulltext)对 Rust 的安全性进行了研究。其共同作者[说](https://www.eurekalert.org/pub_releases/2021-07/su-cs071521.php)，“我们能够验证 Rust 类型系统的安全性，从而表明 Rust 是如何自动和可靠地防止这一类编程错误的。”他们开发了一个理论框架，能够证明尽管有可能写出“不安全”的代码，但 Rust 的安全主张仍然成立。他们使用一个叫做 Miri 的工具来自动测试“不安全”的 Rust 代码是否符合 Rust 规范。

>
> “不安全”的代码仍然能保证安全才是 Rust 最有趣的地方。
>
>
>

### 大量比特币矿工前往美国

美国已经迅速成为比特币挖矿世界的[新宠](https://www.cnbc.com/2021/07/17/bitcoin-miners-moving-to-us-carbon-footprint.html)。截至 2021 年 4 月，美国已经占世界所有比特币矿工的近 [17%](https://cbeci.org/mining_map)。这比 2020 年 9 月增加了 151%。此外，在中国禁止挖矿后，50 万台以前的中国矿工的矿机正在美国寻找家园。如果他们被部署，这将意味着到 2022 年底，北美将拥有接近 40% 的全球哈希率。多年来，美国一直在悄悄地建立其托管能力。美国也是地球上一些最便宜的能源的所在地，其中许多是可再生能源。大多数搬迁到北美的新矿工将使用可再生能源，或用可再生能源信贷抵消的天然气。

>
> 让这些能源消耗和风险去祸害他们去吧，对吧。
>
>
>


全程免费的 Ansible 直播训练营，今夜开播

Summary: 那么，晚上 20:30 见？

课程结束能出个视频，慢慢就有视频资源了。给大家个链接，积累成资源。国外不是也有类似得网站长期发展呢么！！！

那么，晚上 20:30 见？

# 全程免费的 Ansible 直播训练营，今夜开播

Ansible 作为企业运维领域的必备工具，成为各企业招募运维工程师的必备技能。而对于每一个运维工程师来说，学习 Ansible 可以大大节省时间，提升你的工作效率，降低你的工作时间，一本万利。

Linux 中国聚集了大量的运维工程师，也关注到了这个需求，于是联合阿里云开发者社区，开启了 “Ansible 训练营”，帮助 Linux 中国的读者学习 Ansbile。

**本次训练营全程免费，不含任何收费项目！**

**训练营采取直播的方式进行，并提供群内答疑。**

**学习过程中有任何问题，均可以在群内反馈，老师将在线答疑。**

### 训练营形式

钉钉直播(视频)+社群（答疑）

### 授课老师介绍

Bestony，Linux 中国核心合伙人，多年运维工程师，曾就职于网易杭州研究院；Ansible 课程作者。

### 面向人群

* 有一定 Linux 基础，想要针对 Ansible 进行深入进阶
* 对 IT 自动化方向感兴趣，想要成为自动化运维&初中级运维工程师
* 学过 Ansible ，但是知识结构不成体系
* 想要进入大型互联网公司，获得更好的发展，掌舵自己的人生

### 课程内容

直播课程学习：Ansible 基础信息、Ansible 配置、Ansible AdHoc 的使用、Ansible Playbook 的使用、Ansible 核心模块学习

群内答疑： Bestony 老师还将在钉钉群内，为你提供社群答疑工作，帮助你更好的学会 Ansible 。

### 课程安排

* 7.19 日，正式开营，学习 Ansible 的基础知识
* 7.20 日，基础学习，学习 Ansible 的工作模式、Invertory 等信息
* 7.21 日，实战学习，掌握 Ansbile 的 Plabook 和 adHoc 的用法
* 7.22 日，基础学习，了解 Ansible 的核心模块

每天晚上 20:30 开课；40 分钟授课时间 + 20 分钟答疑时间；

### 训练营部分 PPT 预览

那么，晚上 20:30 见？

[进营入口在此，请提前进营~](https://developer.aliyun.com/learning/trainingcamp/linux/1?utm_content=g_1000282661)


现实中的应用程序是如何丢失数据？

Summary: 优秀的云供应商不太可能丢失你的应用数据，所以有时我会被询问现在为什么还要备份？

谁翻译的，成功的让我怀疑自己的阅读能力了，以后能不能别发翻译的文章了．

优秀的云供应商不太可能丢失你的应用数据，所以有时我会被询问现在为什么还要备份？

# 现实中的应用程序是如何丢失数据？

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

现代应用程序开发的一大优点是，像硬件故障或如何设置 RAID 这类问题是由云提供商操心的。优秀的云供应商不太可能丢失你的应用数据，所以有时我会被询问现在为什么还要备份？下面是一些现实世界的故事。

### 故事之一

第一个故事来自一个数据科学项目：它基本上是一个从正在进行的研究中来收集数据的庞大而复杂的管道，然后用各种不同的方式处理以满足一些尖端模型的需要。这个面向用户的应用程序还没有推出，但是一个由数据科学家和开发人员组成的团队已经为建立这个模型和它的数据集工作了好几个月。

在项目中工作的人有他们自己的实验工作的开发环境。他们会在终端中做一些类似 `export ENVIRONMENT=simonsdev` 的事情，然后所有在终端上运行的软件都会在那个环境下运行，而不是在生产环境下。

该团队迫切需要推出一个面向用户的应用程序，以便那些花钱的人能够从他们几个月的投资中真正看到一些回报。在一个星期六，一位工程师试图赶工一些工作。他在晚上很晚的时候做完了一个实验，决定收拾东西回家。他启动了一个清理脚本来删除他的开发环境中的所有内容，但奇怪的是，这比平时花费了更长的时间。这时他意识到，他已经忘记了哪个终端被配置为指向哪个环境。（LCTT 译注：意即删除了生产环境。）

### 故事之二

第二个故事来自于一个商业的网页和手机应用。后端有一个由一组工程师负责的微服务体系结构。这意味着部署需要协调，但是使用正式的发布过程和自动化简化了一些。新代码在准备好后会被审查并合并到主干中，并且高层开发人员通常会为每个微服务标记版本，然后自动部署到临时环境。临时环境中的版本会被定期收集到一个元版本中，在自动部署到生产环境之前，该版本会得到各个人的签署（这是一个合规环境）。

有一天，一位开发人员正在开发一个复杂的功能，而其他开发该微服务的开发人员都同意将他们正在开发的代码提交到主干，也都知道它还不能被实际发布。长话短说，并不是团队中的每个人都收到了消息，而代码就进入了发布管道。更糟糕的是，那些实验性代码需要一种新的方式来表示用户配置文件数据，因此它有一个临时数据迁移，它在推出到生产环境时运行，损坏了所有的用户配置文件。

### 故事之三

第三个故事来自另一款网页应用。这个有一个更简单的架构：大部分代码在一个应用程序中，数据在数据库中。然而，这个应用程序也是在很大的截止日期压力下编写的。事实证明，在开发初期，当彻底更改的数据库架构很常见时，添加一项功能来检测此类更改并清理旧数据，这实际上对发布前的早期开发很有用，并且始终只是作为开发环境的临时功能。不幸的是，在匆忙构建应用的其余部分并推出时，我们忘记了这些代码。当然，直到有一天它在生产环境中被触发了。

### 事后分析

对于任何故障的事后分析，很容易忽视大局，最终将一切归咎于一些小细节。一个特例是发现某人犯了一些错误，然后责怪那个人。这些故事中的所有工程师实际上都是优秀的工程师（雇佣 SRE 顾问的公司不是那些在长期雇佣中偷工减料的公司），所以解雇他们，换掉他们并不能解决任何问题。即使你拥有 100 倍的开发人员，它仍然是有限的，所以在足够的复杂性和压力下，错误也会发生。最重要的解决方案是备份，无论你如何丢失数据（包括来自恶意软件，这是最近新闻中的一个热门话题），它都能帮助你。如果你无法容忍没有副本，就不要只有一个副本。

故事之一的结局很糟糕：没有备份。该项目的六个月的数据收集白干了。顺便说一句，有些地方只保留一个每日快照作为备份，这个故事也是一个很好的例子，说明了这也会出错：如果数据丢失发生在星期六，并且你准备在星期一尝试恢复，那么一日备份就只能得到星期日的一个空数据备份。

故事之二并不算好，但结果要好得多。备份是可用的，但数据迁移也是可逆的。不好的部分是发布是在推出前完成的，并且修复工作必须在生产站点关闭时进行编码。我讲这个故事的主要原因是为了提醒大家，备份并不仅仅是灾难性的数据丢失。部分数据损坏也会发生，而且可能会更加混乱。

故事之三还好。尽管少量数据永久丢失，但大部分数据可以从备份中恢复。团队中的每个人都对没有标记极其明显的危险代码感到非常难过。我没有参与早期的开发，但我感觉很糟糕，因为恢复数据所需的时间比正常情况要长得多。如果有一个经过良好测试的恢复过程，我认为该站点应该在总共不到 15 分钟的时间内重新上线。但是第一次恢复没有成功，我不得不调试它为什么不能成功，然后重试。当一个生产站点宕机了，需要你重新启动它，每过 10 秒钟都感觉过了一个世纪。值得庆幸的是，老板们比某些人更能理解我们。他们实际上松了一口气，因为这一场可能使公司沉没的一次性灾难只导致了几分钟的数据丢失和不到一个小时的停机时间。

在实践中，备份“成功”但恢复失败的情况极为普遍。很多时候，小型数据集上进行恢复测试是可以正常工作的，但在生产规模的大数据集上就会失败。当每个人都压力过大时，灾难最有可能发生，而生产站点的故障只会增加压力。在时间合适的时候测试和记录完整的恢复过程是一个非常好的主意。

---

via: <https://theartofmachinery.com/2021/06/06/how_apps_lose_data.html>

作者：[Simon Arneaud](https://theartofmachinery.com) 选题：[lujun9972](https://github.com/lujun9972) 译者：[PearFL](https://github.com/PearFL) 校对：[wxy](https://github.com/wxy)

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


不同的编程语言是如何读写数据的

Summary: 每种编程语言都有其独特的完成任务的方式，这也说明了为什么有这么多语言可供选择。

每种编程语言都有其独特的完成任务的方式，这也说明了为什么有这么多语言可供选择。

# 不同的编程语言是如何读写数据的

>
> 每种编程语言都有其独特的完成任务的方式，这也说明了为什么有这么多语言可供选择。
>
>
>

<img src="content_image/album_202107_20_065355dfr3f1zmf7fpzmw7.jpg" alt="" title="Code going into a computer.">

在 Jim Hall 的《[不同的编程语言如何完成相同的事情](https://opensource.com/article/21/4/compare-programming-languages)》文章中，他演示了 13 种不同的语言如何使用不同的语法来完成同一个任务。经验是，编程语言往往有很多相似之处。一旦你了解了一种编程语言，你就可以通过理解它的语法和结构来学习另一种。

本着同样的精神，Jim 的文章比较了不同编程语言如何读写数据。无论数据来自配置文件还是用户创建的文件，在存储设备上处理数据都是程序员的常见任务。以这种方式涵盖所有编程语言是不切实际的，但最近的 [Opensource.com](http://Opensource.com) 系列文章提供了对这些编程语言采用的不同方法的深入了解：

* [C](https://opensource.com/article/21/3/file-io-c)
* [C++](https://opensource.com/article/21/3/ccc-input-output)
* [Java](https://opensource.com/article/21/3/io-java)
* [Groovy](https://opensource.com/article/21/4/groovy-io)
* [Lua](https://opensource.com/article/21/3/lua-files)
* [Bash](https://opensource.com/article/21/3/input-output-bash)
* [Python](https://opensource.com/article/21/6/reading-and-writing-files-python)

### 读写数据

用计算机读写数据的过程和你在现实生活中读写数据的过程类似。要访问书中的数据，你首先要打开它，然后阅读单词或将生词写入书中，然后合上书。

当程序需要从文件中读取数据时，你向程序传入一个文件位置，然后计算机将该数据读入内存中并解析它。同样，当程序需要将数据写入文件时，计算机会将新数据放入系统的内存写入缓冲区，然后将其同步到存储设备上的文件中。

下面是这些操作的一些伪代码：

1. 在内存中加载文件。
2. 读取文件内容，或将数据写入文件。
3. 关闭文件。

### 从文件中读取数据

从 [Opensource.com](http://Opensource.com) 系列文章的语言中，你可以看到读取文件的三种趋势。

#### C

在 C 语言中，打开文件可能涉及检索单个字符（直到 `EOF` 指示符，表示文件结束）或一个数据块，具体取决于你的需求和方法。根据你的目标，它可能感觉像一个主要是手工的过程，但这正是其他语言所模仿的。

```
FILE *infile;
int ch;

infile = fopen(argv[1], "r");

do {
  ch = fgetc(infile);
  if (ch != EOF) {
    printf("%c", ch);
  }
 } while (ch != EOF);

fclose(infile);

```

你还可以选择将文件的某些部分加载到系统缓冲区中，然后在缓冲区外工作。

```
FILE *infile;
char buffer[300];

infile = fopen(argv[1], "r");

while (!feof(infile)) {
  size_t buffer_length;
  buffer_length = fread(buffer, sizeof(char), 300, infile);
}

printf("%s", buffer);
fclose(infile);

```

#### C++

C++ 简化了一些步骤，允许你将数据解析为字符串。

```
std::string sFilename = "example.txt";

std::ifstream fileSource(sFilename);
std::string buffer;

while (fileSource >> buffer) {
  std::cout << buffer << std::endl;
}

```

#### Java

Java 和 Groovy 类似于 C++。它们使用名为 `Scanner` 的类来设置数据流或对象，这样就会包含你选择的文件内容。你可以通过标记（字节、行、整数等）扫描文件。

```
File myFile = new File("example.txt");

Scanner myScanner = new Scanner(myFile);
  while (myScanner.hasNextLine()) {
    String line = myScanner.nextLine();
    System.out.println(line);
  }

myScanner.close();

```

#### Groovy

```
def myFile = new File('example.txt')

def myScanner = new Scanner(myFile)
  while (myScanner.hasNextLine()) {
    def line = myScanner.nextLine()
    println(line)
  }

myScanner.close()

```

#### Lua

Lua 和 Python 进一步抽象了整个过程。你不必有意识地创建数据流，你只需给一个变量赋值为 `open` 函数的返回值，然后解析该变量的内容。这种方式快速，最简且容易。

```
myFile = io.open('example.txt', 'r')

lines = myFile:read("*all")
print(lines)

myFile:close()

```

#### Python

```
f = open('example.tmp', 'r')

for line in f:
    print(line)

f.close()

```

### 向文件中写入数据

就写代码来说，写入是读取的逆过程。因此，将数据写入文件的过程与从文件中读取数据基本相同，只是使用了不同的函数。

#### C

在 C 语言中，你可以使用 `fputc` 函数将字符写入文件：

```
fputc(ch, outfile);

```

或者，你可以使用 `fwrite` 将数据写入缓冲区。

```
fwrite(buffer, sizeof(char), buffer_length, outfile);

```

#### C++

因为 C++ 使用 `ifstream` 库为数据打开缓冲区，所以你可以像 C 语言那样将数据写入缓冲区（C++ 库除外）。

```
std::cout << buffer << std::endl;

```

#### Java

在 Java 中，你可以使用 `FileWriter` 类来创建一个可以写入数据的对象。它的工作方式与 `Scanner` 类非常相似，只是方向相反。

```
FileWriter myFileWriter = new FileWriter("example.txt", true);
myFileWriter.write("Hello world\n");
myFileWriter.close();

```

#### Groovy

类似地，Groovy 使用 `FileWriter`，但使用了稍微 “groovy” 的语法。

```
new FileWriter("example.txt", true).with {
  write("Hello world\n")
  flush()
}

```

#### Lua

Lua 和 Python 很相似，都使用名为 `open` 的函数来加载文件，`writer` 函数来写入数据，`close` 函数用于关闭文件。

```
myFile = io.open('example.txt', 'a')
io.output(myFile)
io.write("hello world\n")
io.close(myFile)

```

#### Python

```
myFile = open('example.txt', 'w')
myFile.write('hello world')
myFile.close()

```

### File 模式

许多语言在打开文件时会指定一个“模式”。模式有很多，但这是常见的定义：

* **w** 表示写入
* **r** 表示读取
* **r+** 表示可读可写
* **a** 表示追加

某些语言，例如 Java 和 Groovy，允许你根据用于加载文件的类来确定模式。

无论编程语言以何种方式来确定文件模式，你都需要确保你是在 *追加* 数据，除非你打算用新数据覆盖文件。编程语言不像文件选择器那样，没有内置的提示来警告你防止数据丢失。

### 新语言和旧把戏

每种编程语言都有其独特完成任务的方式，这就是为什么有这么多语言可供选择。你可以而且应该选择最合适你的语言。但是，你一旦了解了编程的基本结构，你可以随意尝试其他语言，而不必担心不知道如何完成基本任务。通常情况下，实现目标的途径是相似的，所以只要你牢记基本概念，它们就很容易学习。

---

via: <https://opensource.com/article/21/7/programming-read-write>

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


硬核观察 #338 iPhone 被曝不安全：不点击链接也有可能被入侵

Summary: 更多：• 哈勃望远镜在经历了一个月的技术问题后恢复科学操作 • Canonical 通过了新冠疫情考验，反而扭亏为盈

# 硬核观察 #338 iPhone 被曝不安全：不点击链接也有可能被入侵

### iPhone 被曝不安全：不点击链接也有可能被入侵

一般来说，如果信息中出现未知链接或者钓鱼链接，不要点击就会很安全，但这样做对以色列 NSO Group 公司并不适用。报告发现，iPhone 如果感染 NSO Group 的恶意软件，攻击者就能窃取信息和邮件，甚至可以控制手机麦克风摄像头。NSO Group 的软件可以用苹果不知道的方法窃取数据，即使 iPhone 软件保持在最新状态，如运行 iOS 14.6 系统的 iPhone 12。

>
> 这才是专业“黑客”，简直是间谍手段。
>
>
>

### 哈勃望远镜在经历了一个月的技术问题后恢复科学操作

NASA 已经成功地[重新启动](https://www.nasa.gov/feature/goddard/2021/operations-underway-to-restore-payload-computer-on-nasas-hubble-space-telescope)了哈勃太空望远镜，此前该望远镜因技术老化而暂停科学操作一个月。6月13日，哈勃望远镜的有效载荷计算机崩溃了，它自动暂停了科学运行，并将望远镜的仪器置于安全模式。重新启动也未能使其恢复操作。最终，NASA 确定，故障在于监控电源控制单元内电压水平的调节电路。通过切换到备用组件，[开启了备用有效载荷计算机](https://www.zdnet.com/article/nasa-has-just-fixed-the-mysterious-computer-problem-with-its-famous-space-telescope/)，并为其加载飞行软件。再经过一些测试和校准，科学操作终于得以恢复。

>
> 这么老的计算机居然还能继续修复好并正常工作，简直是奇迹了。
>
>
>

### Canonical 通过了新冠疫情考验，反而扭亏为盈

早在新冠疫情之前，Ubuntu 的发行商 Canonical 就已经拥有一支分布式的全球员工队伍。于是在 Linux 生态持续蓬勃发展的大环境下，除了设法从 2019 年的亏损 200 万美元到 2020 年的实现盈利 2000 万美元，Canonical 甚至将员工数增加到了 500 人以上。

>
> 一方面，新冠疫情打乱了一些客户的规划，进而导致销售额可能持续下滑。但另一方面，公有云运营商助其实现了营收的稳定。
>
>
>


FreeDOS 简史

Summary: 经历了近 30 年的发展, FreeDOS 已经成为了世界先进的 DOS。

经历了近 30 年的发展, FreeDOS 已经成为了世界先进的 DOS。

# FreeDOS 简史

>
> 经历了近 30 年的发展, FreeDOS 已经成为了世界先进的 DOS。
>
>
>

<img src="content_image/album_202107_21_104903zzxiyc4i4gkpxiph.jpg" alt="" title="Person typing on a 1980's computer">

>
> 一个大师正在给他的一个弟子讲 [编程之道](https://www.mit.edu/~xela/tao.html)。 “编程之道包含在所有的软件中 —— 不管它多么微不足道，” 大师说道。
>
>
> “编程之道在手持计算器里面吗？” 弟子问道。
>
>
> “是的，” 大师回答道。
>
>
> “编程之道在电子游戏里面吗？” 弟子继续问道。
>
>
> “即便是电子游戏中，” 大师说。
>
>
> “那编程之道在个人电脑的 DOS 里面吗？”
>
>
> 大师咳嗽了一下，稍稍改变了一下姿势，说道，“今天的课就到这里吧。”
>
>
> ——《编程之道》，Geoffrey James，InfoBooks，1987
>
>
>

过去，计算仅限于昂贵的大型机和“大铁疙瘩”计算机系统，如 PDP 11。但是微处理器的出现在 20 世纪 70 年代带来了一场计算革命。你终于可以在家里有一台电脑了——“个人电脑”时代已经到了！

我记得看到的最早的个人电脑包括 Commodore、TRS-80 和 Apple。个人电脑成了一个热门话题，所以 IBM 决定进入这个市场。在经历了一个快速开发周期之后，IBM 于 1981 年 8 月发布了 IBM 5150 个人电脑（最初的“IBM PC”）。

从零开始创建一台计算机并非易事，因此 IBM 以用“现成”的硬件来构建 PC 而闻名，并从外部开发商那里获得了其他组件的授权。其中之一是微软授权的操作系统。反过来，微软从西雅图计算机产品公司获得了 86-DOS ，进行了各种更新，并将新版本作为 IBM PC-DOS 与 IBM PC 一起首次亮相。

### 早期的 DOS

运行在最多只有 640 千字节内存中的 DOS，除了管理硬件和允许用户启动应用程序之外，真的做不了什么。因此，PC-DOS 1.0 命令行非常贫乏，只包含了一些设置日期和时间、管理文件、控制终端和格式化软盘的命令。DOS 还包括一个 BASIC 语言解释器，这是那个时代所有个人计算机的一个标准功能。

直到 PC-DOS 2.0，DOS 才变得更加有趣，为命令行添加了新的命令，并包含了其他有用的工具。但对我来说，直到 1991 年的 MS-DOS 5.0 才有了“现代感”。微软在这个版本中对 DOS 进行了大修，更新了许多命令，并用一个新的全屏编辑器取代了老旧的 Edlin 编辑器，使之更方便用户使用。DOS 5 还包括我喜欢的其他特性，比如基于微软 QuickBASIC 编译器的新 BASIC 解释器，简称 QBASIC. 如果你曾经在 DOS 上玩过 Gorillas 游戏，那可能就是在 MS-DOS 5.0 中运行的。

尽管进行了这些升级，但我对 DOS 命令行并不完全满意。DOS 从来没有偏离原来的设计，有其局限性。DOS 为用户提供了一些工具，可以从命令行执行一些事情 —— 否则，你就得使用 DOS 命令行来启动应用程序。微软认为用户大部分时间都会花在几个关键的应用程序上，比如文字处理器或电子表格。

但是开发人员想要一个功能更强的 DOS，此时一个细分行业正在萌芽，以提供小巧优雅的工具和程序。有些是全屏应用程序，但也有许多是增强 DOS 命令环境的命令行实用程序。当我学会一点 C 语言编程时，我开始编写自己的实用程序，扩展或替换 DOS 命令行。尽管 MS-DOS 的基础相当有限，但我发现第三方实用程序加上我自己的工具创建了一个功能强大的 DOS 命令行。

### FreeDOS

1994 年初，我开始在科技杂志上看到很多对微软高管的采访，他们说下一个版本的 Windows 将完全取代 DOS。我以前使用过 Windows，但如果你还记得那个时代，你就知道 Windows 3.1 并不是一个很好的平台。Windows 3.1 很笨重，有很多毛病，如果一个应用程序崩溃，它可能会使整个 Windows 系统瘫痪。我也不喜欢 Windows 的图形用户界面。我更喜欢在命令行做我的工作，而不是用鼠标。

我考虑过 Windows，并决定，“如果 Windows 3.2 或 Windows 4.0 会像 Windows 3.1 一样，我就不会去使用它。” 但我有什么选择？此时，我已经尝试过 Linux，并认为 [Linux 很棒](https://opensource.com/article/17/5/how-i-got-started-linux-jim-hall-freedos)，但是 Linux 没有任何应用程序。我的文字处理器、电子表格和其他程序都在 DOS 上。我需要 DOS。

然后我有了个主意！我想，“如果开发人员能够在互联网上共同编写一个完整的 Unix 操作系统，那么我们当然可以对 DOS 做同样的事情。”毕竟，与 Unix 相比，DOS 是一个相当简单的操作系统。DOS 一次运行一个任务（单任务），并且有一个更简单的内存模型。编写我们自己的 DOS 应该不难。

因此，在 1994 年 6 月 29 日，我在一个名为 Usenet 的留言板网络上向 “comp.os.msdos.apps” [发布了一个公告](https://groups.google.com/g/comp.os.msdos.apps/c/oQmT4ETcSzU/m/O1HR8PE2u-EJ)：

>
> PD-DOS 项目公告：
>
>
> 几个月前，我发表了关于启动公共领域版本的 DOS 的文章。 当时大家对此的普遍支持，许多人都同意这样的说法：“开始编写吧！”所以，我就……
>
>
> 宣布首次生产 PD-DOS 的努力。我已经写了一个“清单”，描述了这样一个项目的目标和工作大纲，以及一个“任务列表”，它准确地显示了需要编写什么。我会把这些贴在这里，供大家讨论。
>
>
>

\* 关于这个名字的说明 —— 我希望这个新的 DOS 成为每个人都可以使用的东西，我天真地认为，当每个人都可以使用它时，它就是“公共领域”。我很快就意识到了这种差别，所以我们把 “PD-DOS” 改名为 “Free-DOS”，然后去掉连字符变成 “FreeDOS”。

一些开发人员联系我，提供他们为替换或增强 DOS 命令行而创建的实用程序，类似于我自己的努力。就在项目宣布几个月后，我们汇集了我们的实用程序，并创建了一个实用的系统，我们在 1994 年 9 月发布了一个 “Alpha 1” 版本。在那些日子里，发展是相当迅速的，我们在 1994 年 12 月发布了 “Alpha 2”，1995 年 1 月发布了 “Alpha 3”，1995 年 6 月发布了“Alpha 4”。

### 一个现代的 DOS

从那以后，我们一直致力于使 FreeDOS 成为 “现代” DOS。而这种现代化大部分都集中在创建一个丰富的命令行环境上。是的，DOS 仍然需要支持应用程序，但是我们相信 FreeDOS 也需要一个强大的命令行环境。这就是为什么 FreeDOS 包含了许多有用的工具，包括浏览目录、管理文件、播放音乐、连接网络的命令，……以及类似 Unix 的实用程序集合，如 `less`、`du`、`head`、`tail`、`sed` 和 `tr`。

虽然 FreeDOS 的开发已经放缓，但它并没有停止。开发人员继续为 FreeDOS 编写新程序，并向 FreeDOS 添加新功能。我对 FreeDOS 1.3 RC4 的几个重要补充感到特别兴奋，FreeDOS 1.3 RC4 是即将发布的 FreeDOS 1.3 的最新候选版本。最近的一些更新如下：

* Mateusz Viste 创建了一个新的电子书阅读器，名为 Ancient Machine Book（AMB），我们利用它作为 FreeDOS 1.3 RC4 中的新帮助系统。
* Rask Ingemann Lambertsen、Andrew Jenner、TK Chia 和其他人正在更新 GCC 的 IA-16 版本，包括一个新的libi86 库，它提供了与 Borland TurboC++ 编译器的 C 库的某种程度的兼容性。
* Jason Hood 更新了一个可卸载的 CD-ROM 重定向器，以替代微软的 MSCDEX，最多支持 10 个驱动器。
* SuperIlu 创建了 DOjS，这是一个 Javascript 开发画布，具有集成的编辑器、图形和声音输出，以及鼠标、键盘和操纵杆输入。
* Japheth 创建了一个 DOS32PAE 扩展程序，它能够通过 PAE 分页使用大量的内存。

尽管 FreeDOS 有了新的发展，我们仍然忠于我们的 DOS 根基。在我们继续朝着 FreeDOS 1.3 “最终”版本努力时，我们带着几个核心假设，包括：

* **兼容性是关键** —— 如果 FreeDOS 不能运行经典 DOS 应用程序，它就不是真正的 “DOS”。虽然我们提供了许多优秀的开源工具、应用程序和游戏，但你也可以运行你的传统的 DOS 应用程序。
* **继续在旧 PC 上运行（XT、286、386 等）** —— FreeDOS 1.3 将保持 16 位英特尔架构，但在可能的情况下将支持扩展驱动程序支持的新硬件。为此，我们继续专注于单用户命令行环境。
* **FreeDOS 是开源软件** —— 我一直说，如果人们不能访问、学习和修改源代码，FreeDOS 就不是“自由的 DOS”。FreeDOS 1.3 将包括尽可能多地包括使用公认的开源许可证的软件。但 DOS 实际上早于 GNU 通用公共许可证（1989）和开放源码定义（1998），因此一些 DOS 软件可能会使用它自己的“免费源代码”许可证，而不是标准的“开源”许可。当我们考虑将软件包纳入 FreeDOS 时，我们将继续评估任何许可证，以确保它们是合适的“开放源码”，即使它们没有得到正式承认。

我们欢迎你的帮助，使 FreeDOS 强大！请加入我们的电子邮件列表，我们欢迎所有新来者和贡献者。我们通过电子邮件列表进行交流，不过这个列表的信件量非常小，所以不太可能撑爆你的收件箱。

访问 FreeDOS 网站 [www.freedos.org](https://www.freedos.org/)。

---

via: <https://opensource.com/article/21/6/history-freedos>

作者：[Jim Hall](https://opensource.com/users/jim-hall) 选题：[lujun9972](https://github.com/lujun9972) 译者：[zxy-wyx](https://github.com/zxy-wyx) 校对：[wxy](https://github.com/wxy)

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


进阶教程：用 Python 和 NLTK 进行 NLP 分析

Summary: 进一步学习自然语言处理的基本概念

进一步学习自然语言处理的基本概念

# 进阶教程：用 Python 和 NLTK 进行 NLP 分析

>
> 进一步学习自然语言处理的基本概念
>
>
>

在 [之前的文章](https://opensource.com/article/20/8/intro-python-nltk) 里，我介绍了<ruby> 自然语言处理 <rt>  natural language processing </rt></ruby>（NLP）和宾夕法尼亚大学研发的<ruby> 自然语言处理工具包 <rt>  Natural Language Toolkit </rt></ruby> ([NLTK](http://www.nltk.org/))。我演示了用 Python 解析文本和定义<ruby> 停顿词 <rt>  stopword </rt></ruby>的方法，并介绍了<ruby> 语料库 <rt>  corpus </rt></ruby>的概念。语料库是由文本构成的数据集，通过提供现成的文本数据来辅助文本处理。在这篇文章里，我将继续用各种语料库对文本进行对比和分析。

这篇文章主要包括以下部分：

* <ruby> 词网 <rt>  WordNet </rt></ruby>和<ruby> 同义词集 <rt>  synset </rt></ruby>
* <ruby> 相似度比较 <rt>  Similarity comparison </rt></ruby>
* <ruby> 树 <rt>  Tree </rt></ruby>和<ruby> 树库 <rt>  treebank </rt></ruby>
* <ruby> 命名实体识别 <rt>  Named entity recognition </rt></ruby>

### 词网和同义词集

<ruby>   词网  <rt>  WordNet </rt></ruby> 是 NLTK 里的一个大型词汇数据库语料库。词网包含各单词的诸多<ruby> 认知同义词 <rt>  cognitive synonyms </rt></ruby>（认知同义词常被称作“<ruby> 同义词集 <rt>  synset </rt></ruby>”）。在词网里，名词、动词、形容词和副词，各自被组织成一个同义词的网络。

词网是一个很有用的文本分析工具。它有面向多种语言的版本（汉语、英语、日语、俄语和西班牙语等），也使用多种许可证（从开源许可证到商业许可证都有）。初代版本的词网由普林斯顿大学研发，面向英语，使用<ruby> 类 MIT 许可证 <rt>  MIT-like license </rt></ruby>。

因为一个词可能有多个意义或多个词性，所以可能与多个同义词集相关联。每个同义词集通常提供下列属性：

| **属性** | **定义** | **例子** |
| --- | --- | --- |
| <ruby> 名称 <rt>  Name </rt></ruby> | 此同义词集的名称 | 单词 `code` 有 5 个同义词集，名称分别是 `code.n.01`、 `code.n.02`、 `code.n.03`、`code.v.01` 和 `code.v.02` |
| <ruby> 词性 <rt>  POS </rt></ruby> | 此同义词集的词性 | 单词 `code` 有 3 个名词词性的同义词集和 2 个动词词性的同义词集 |
| <ruby> 定义 <rt>  Definition </rt></ruby> | 该词作对应词性时的定义 | 动词 `code` 的一个定义是：（计算机科学）数据或计算机程序指令的<ruby> 象征性排列 <rt>  symbolic arrangement </rt></ruby> |
| <ruby> 例子 <rt>  Example </rt></ruby> | 使用该词的例子 | `code` 一词的例子：We should encode the message for security reasons |
| <ruby> 词元 <rt>  Lemma </rt></ruby> | 与该词相关联的其他同义词集（包括那些不一定严格地是该词的同义词，但可以大体看作同义词的）；词元直接与其他词元相关联，而不是直接与<ruby> 单词 <rt>  word </rt></ruby>相关联 | `code.v.02` 的词元是 `code.v.02.encipher`、`code.v.02.cipher`、`code.v.02.cypher`、`code.v.02.encrypt`、`code.v.02.inscribe` 和 `code.v.02.write_in_code` |
| <ruby> 反义词 <rt>  Antonym </rt></ruby> | 意思相反的词 | 词元 `encode.v.01.encode` 的反义词是 `decode.v.01.decode` |
| <ruby> 上义词 <rt>  Hypernym </rt></ruby> | 该词所属的一个范畴更大的词 | `code.v.01` 的一个上义词是 `tag.v.01` |
| <ruby> 分项词 <rt>  Meronym </rt></ruby> | 属于该词组成部分的词 | `computer` 的一个分项词是 `chip` |
| <ruby> 总项词 <rt>  Holonym </rt></ruby> | 该词作为组成部分所属的词 | `window` 的一个总项词是 `computer screen` |

同义词集还有一些其他属性，在 `<你的 Python 安装路径>/Lib/site-packages` 下的 `nltk/corpus/reader/wordnet.py`，你可以找到它们。

下面的代码或许可以帮助理解。

这个函数：

```
from nltk.corpus import wordnet

def synset_info(synset):
    print("Name", synset.name())
    print("POS:", synset.pos())
    print("Definition:", synset.definition())
    print("Examples:", synset.examples())
    print("Lemmas:", synset.lemmas())
    print("Antonyms:", [lemma.antonyms() for lemma in synset.lemmas() if len(lemma.antonyms()) > 0])
    print("Hypernyms:", synset.hypernyms())
    print("Instance Hypernyms:", synset.instance_hypernyms())
    print("Part Holonyms:", synset.part_holonyms())
    print("Part Meronyms:", synset.part_meronyms())
    print()

synsets = wordnet.synsets('code')
print(len(synsets), "synsets:")
for synset in synsets:
    synset_info(synset)

```

将会显示：

```
5 synsets:
Name code.n.01
POS: n
Definition: a set of rules or principles or laws (especially written ones)
Examples: []
Lemmas: [Lemma('code.n.01.code'), Lemma('code.n.01.codification')]
Antonyms: []
Hypernyms: [Synset('written_communication.n.01')]
Instance Hpernyms: []
Part Holonyms: []
Part Meronyms: []

...

Name code.n.03
POS: n
Definition: (computer science) the symbolic arrangement of data or instructions in a computer program or the set of such instructions
Examples: []
Lemmas: [Lemma('code.n.03.code'), Lemma('code.n.03.computer_code')]
Antonyms: []
Hypernyms: [Synset('coding_system.n.01')]
Instance Hpernyms: []
Part Holonyms: []
Part Meronyms: []

...

Name code.v.02
POS: v
Definition: convert ordinary language into code
Examples: ['We should encode the message for security reasons']
Lemmas: [Lemma('code.v.02.code'), Lemma('code.v.02.encipher'), Lemma('code.v.02.cipher'), Lemma('code.v.02.cypher'), Lemma('code.v.02.encrypt'), Lemma('code.v.02.inscribe'), Lemma('code.v.02.write_in_code')]
Antonyms: []
Hypernyms: [Synset('encode.v.01')]
Instance Hpernyms: []
Part Holonyms: []
Part Meronyms: []

```

<ruby> 同义词集 <rt>  synset </rt></ruby>和<ruby> 词元 <rt>  lemma </rt></ruby>在词网里是按照树状结构组织起来的，下面的代码会给出直观的展现：

```
def hypernyms(synset):
    return synset.hypernyms()

synsets = wordnet.synsets('soccer')
for synset in synsets:
    print(synset.name() + " tree:")
    pprint(synset.tree(rel=hypernyms))
    print()

```

```
code.n.01 tree:
[Synset('code.n.01'),
 [Synset('written_communication.n.01'),
   ...

code.n.02 tree:
[Synset('code.n.02'),
 [Synset('coding_system.n.01'),
   ...

code.n.03 tree:
[Synset('code.n.03'),
   ...

code.v.01 tree:
[Synset('code.v.01'),
 [Synset('tag.v.01'),
   ...

code.v.02 tree:
[Synset('code.v.02'),
 [Synset('encode.v.01'),
   ...

```

词网并没有涵盖所有的单词和其信息（现今英语有约 17,0000 个单词，最新版的 词网 涵盖了约 15,5000 个），但它开了个好头。掌握了“词网”的各个概念后，如果你觉得它词汇少，不能满足你的需要，可以转而使用其他工具。或者，你也可以打造自己的“词网”！

#### 自主尝试

使用 Python 库，下载维基百科的 “[open source](https://en.wikipedia.org/wiki/Open_source)” 页面，并列出该页面所有单词的<ruby> 同义词集 <rt>  synset </rt></ruby>和<ruby> 词元 <rt>  lemma </rt></ruby>。

### 相似度比较

相似度比较的目的是识别出两篇文本的相似度，在搜索引擎、聊天机器人等方面有很多应用。

比如，相似度比较可以识别 `football` 和 `soccer` 是否有相似性。

```
syn1 = wordnet.synsets('football')
syn2 = wordnet.synsets('soccer')

# 一个单词可能有多个 同义词集，需要把 word1 的每个同义词集和 word2 的每个同义词集分别比较
for s1 in syn1:
    for s2 in syn2:
        print("Path similarity of: ")
        print(s1, '(', s1.pos(), ')', '[', s1.definition(), ']')
        print(s2, '(', s2.pos(), ')', '[', s2.definition(), ']')
        print("   is", s1.path_similarity(s2))
        print()

```

```
Path similarity of:
Synset('football.n.01') ( n ) [ any of various games played with a ball (round or oval) in which two teams try to kick or carry or propel the ball into each other's goal ]
Synset('soccer.n.01') ( n ) [ a football game in which two teams of 11 players try to kick or head a ball into the opponents' goal ]
   is 0.5

Path similarity of:
Synset('football.n.02') ( n ) [ the inflated oblong ball used in playing American football ]
Synset('soccer.n.01') ( n ) [ a football game in which two teams of 11 players try to kick or head a ball into the opponents' goal ]
   is 0.05

```

两个词各个同义词集之间<ruby> 路径相似度 <rt>  path similarity </rt></ruby>最大的是 0.5，表明它们关联性很大（[<ruby> 路径相似度 <rt>  path similarity </rt></ruby>](https://www.nltk.org/howto/wordnet.html)指两个词的意义在<ruby> 上下义关系的词汇分类结构 <rt>  hypernym/hypnoym taxonomy </rt></ruby>中的最短距离）。

那么 `code` 和 `bug` 呢？这两个计算机领域的词的相似度是：

```
Path similarity of:
Synset('code.n.01') ( n ) [ a set of rules or principles or laws (especially written ones) ]
Synset('bug.n.02') ( n ) [ a fault or defect in a computer program, system, or machine ]
   is 0.1111111111111111
...
Path similarity of:
Synset('code.n.02') ( n ) [ a coding system used for transmitting messages requiring brevity or secrecy ]
Synset('bug.n.02') ( n ) [ a fault or defect in a computer program, system, or machine ]
   is 0.09090909090909091
...
Path similarity of:
Synset('code.n.03') ( n ) [ (computer science) the symbolic arrangement of data or instructions in a computer program or the set of such instructions ]
Synset('bug.n.02') ( n ) [ a fault or defect in a computer program, system, or machine ]
   is 0.09090909090909091

```

这些是这两个词各同义词集之间<ruby> 路径相似度 <rt>  path similarity </rt></ruby>的最大值，这些值表明两个词是有关联性的。

NLTK 提供多种<ruby> 相似度计分器 <rt>  similarity scorers </rt></ruby>，比如：

* path\_similarity
* lch\_similarity
* wup\_similarity
* res\_similarity
* jcn\_similarity
* lin\_similarity

要进一步了解这些<ruby> 相似度计分器 <rt>  similarity scorers </rt></ruby>，请查看 [WordNet Interface](https://www.nltk.org/howto/wordnet.html) 的 Similarity 部分。

#### 自主尝试

使用 Python 库，从维基百科的 [Category: Lists of computer terms](https://en.wikipedia.org/wiki/Category:Lists_of_computer_terms) 生成一个术语列表，然后计算各术语之间的相似度。

### 树和树库

使用 NLTK，你可以把文本表示成树状结构以便进行分析。

这里有一个例子：

这是一份简短的文本，对其做预处理和词性标注：

```
import nltk

text = "I love open source"
# Tokenize to words
words = nltk.tokenize.word_tokenize(text)
# POS tag the words
words_tagged = nltk.pos_tag(words)

```

要把文本转换成树状结构，你必须定义一个<ruby> 语法 <rt>  grammar </rt></ruby>。这个例子里用的是一个基于 [Penn Treebank tags](https://www.ling.upenn.edu/courses/Fall_2003/ling001/penn_treebank_pos.html) 的简单语法。

```
# A simple grammar to create tree
grammar = "NP: {<JJ><NN>}"

```

然后用这个<ruby> 语法 <rt>  grammar </rt></ruby>创建一颗<ruby> 树 <rt>  tree </rt></ruby>：

```
# Create tree
parser = nltk.RegexpParser(grammar)
tree = parser.parse(words_tagged)
pprint(tree)

```

运行上面的代码，将得到：

```
Tree('S', [('I', 'PRP'), ('love', 'VBP'), Tree('NP', [('open', 'JJ'), ('source', 'NN')])])

```

你也可以图形化地显示结果。

```
tree.draw()

```

这个树状结构有助于准确解读文本的意思。比如，用它可以找到文本的 [主语](https://en.wikipedia.org/wiki/Subject_(grammar))：

```
subject_tags = ["NN", "NNS", "NP", "NNP", "NNPS", "PRP", "PRP$"]
def subject(sentence_tree):
    for tagged_word in sentence_tree:
        # A crude logic for this case -  first word with these tags is considered subject
        if tagged_word[1] in subject_tags:
            return tagged_word[0]

print("Subject:", subject(tree))

```

结果显示主语是 `I`：

```
Subject: I

```

这是一个比较基础的文本分析步骤，可以用到更广泛的应用场景中。 比如，在聊天机器人方面，如果用户告诉机器人：“给我妈妈 Jane 预订一张机票，1 月 1 号伦敦飞纽约的”，机器人可以用这种分析方法解读这个指令：

**动作**: 预订
**动作的对象**: 机票
**乘客**: Jane
**出发地**: 伦敦
**目的地**: 纽约
**日期**: （明年）1 月 1 号

<ruby> 树库 <rt>  treebank </rt></ruby>指由许多预先标注好的<ruby> 树 <rt>  tree </rt></ruby>构成的语料库。现在已经有面向多种语言的树库，既有开源的，也有限定条件下才能免费使用的，以及商用的。其中使用最广泛的是面向英语的宾州树库。宾州树库取材于<ruby> 华尔街日报 <rt>  Wall Street Journal </rt></ruby>。NLTK 也包含了宾州树库作为一个子语料库。下面是一些使用<ruby> 树库 <rt>  treebank </rt></ruby>的方法：

```
words = nltk.corpus.treebank.words()
print(len(words), "words:")
print(words)

tagged_sents = nltk.corpus.treebank.tagged_sents()
print(len(tagged_sents), "sentences:")
print(tagged_sents)

```

```
100676 words:
['Pierre', 'Vinken', ',', '61', 'years', 'old', ',', ...]
3914 sentences:
[[('Pierre', 'NNP'), ('Vinken', 'NNP'), (',', ','), ('61', 'CD'), ('years', 'NNS'), ('old', 'JJ'), (',', ','), ('will', 'MD'), ('join', 'VB'), ('the', 'DT'), ('board', 'NN'), ('as', 'IN'), ('a', 'DT'), ('nonexecutive', 'JJ'), ('director', 'NN'), ...]

```

查看一个句子里的各个<ruby> 标签 <rt>  tags </rt></ruby>：

```
sent0 = tagged_sents[0]
pprint(sent0)

```

```
[('Pierre', 'NNP'),
 ('Vinken', 'NNP'),
 (',', ','),
 ('61', 'CD'),
 ('years', 'NNS'),
...

```

定义一个<ruby> 语法 <rt>  grammar </rt></ruby>来把这个句子转换成树状结构：

```
grammar = '''
    Subject: {<NNP><NNP>}
    SubjectInfo: {<CD><NNS><JJ>}
    Action: {<MD><VB>}
    Object: {<DT><NN>}
    Stopwords: {<IN><DT>}
    ObjectInfo: {<JJ><NN>}
    When: {<NNP><CD>}
'''
parser = nltk.RegexpParser(grammar)
tree = parser.parse(sent0)
print(tree)

```

```
(S
  (Subject Pierre/NNP Vinken/NNP)
  ,/,
  (SubjectInfo 61/CD years/NNS old/JJ)
  ,/,
  (Action will/MD join/VB)
  (Object the/DT board/NN)
  as/IN
  a/DT
  (ObjectInfo nonexecutive/JJ director/NN)
  (Subject Nov./NNP)
  29/CD
  ./.)

```

图形化地显示：

```
tree.draw()

```

<ruby> 树 <rt>  trees </rt></ruby>和<ruby> 树库 <rt>  treebanks </rt></ruby>的概念是文本分析的一个强大的组成部分。

#### 自主尝试

使用 Python 库，下载维基百科的 “[open source](https://en.wikipedia.org/wiki/Open_source)” 页面，将得到的文本以图形化的树状结构展现出来。

### 命名实体识别

无论口语还是书面语都包含着重要数据。文本处理的主要目标之一，就是提取出关键数据。几乎所有应用场景所需要提取关键数据，比如航空公司的订票机器人或者问答机器人。 NLTK 为此提供了一个<ruby> 命名实体识别 <rt>  named entity recognition </rt></ruby>的功能。

这里有一个代码示例：

```
sentence = 'Peterson first suggested the name "open source" at Palo Alto, California'

```

验证这个句子里的<ruby> 人名 <rt>  name </rt></ruby>和<ruby> 地名 <rt>  place </rt></ruby>有没有被识别出来。照例先预处理：

```
import nltk

words = nltk.word_tokenize(sentence)
pos_tagged = nltk.pos_tag(words)

```

运行<ruby> 命名实体标注器 <rt>  named-entity tagger </rt></ruby>：

```
ne_tagged = nltk.ne_chunk(pos_tagged)
print("NE tagged text:")
print(ne_tagged)
print()

```

```
NE tagged text:
(S
  (PERSON Peterson/NNP)
  first/RB
  suggested/VBD
  the/DT
  name/NN
  ``/``
  open/JJ
  source/NN
  ''/''
  at/IN
  (FACILITY Palo/NNP Alto/NNP)
  ,/,
  (GPE California/NNP))

```

上面的结果里，命名实体被识别出来并做了标注；只提取这个<ruby> 树 <rt>  tree </rt></ruby>里的命名实体：

```
print("Recognized named entities:")
for ne in ne_tagged:
    if hasattr(ne, "label"):
        print(ne.label(), ne[0:])

```

```
Recognized named entities:
PERSON [('Peterson', 'NNP')]
FACILITY [('Palo', 'NNP'), ('Alto', 'NNP')]
GPE [('California', 'NNP')]

```

图形化地显示：

```
ne_tagged.draw()

```

NLTK 内置的<ruby> 命名实体标注器 <rt>  named-entity tagger </rt></ruby>，使用的是宾州法尼亚大学的 [Automatic Content Extraction](https://www.ldc.upenn.edu/collaborations/past-projects/ace)（ACE）程序。该标注器能够识别<ruby> 组织机构 <rt>  ORGANIZATION </rt></ruby><ruby> 、人名 <rt>  PERSON </rt></ruby><ruby> 、地名 <rt>  LOCATION </rt></ruby><ruby> 、设施 <rt>  FACILITY </rt></ruby>和<ruby> 地缘政治实体 <rt>  geopolitical entity </rt></ruby>等常见<ruby> 实体 <rt>  entites </rt></ruby>。

NLTK 也可以使用其他<ruby> 标注器 <rt>  tagger </rt></ruby>，比如 [Stanford Named Entity Recognizer](https://nlp.stanford.edu/software/CRF-NER.html). 这个经过训练的标注器用 Java 写成，但 NLTK 提供了一个使用它的接口（详情请查看 [nltk.parse.stanford](https://www.nltk.org/_modules/nltk/parse/stanford.html) 或 [nltk.tag.stanford](https://www.nltk.org/_modules/nltk/tag/stanford.html)）。

#### 自主尝试

使用 Python 库，下载维基百科的 “[open source](https://en.wikipedia.org/wiki/Open_source)” 页面，并识别出对<ruby> 开源 <rt>  open source </rt></ruby>有影响力的人的名字，以及他们为<ruby> 开源 <rt>  open source </rt></ruby>做贡献的时间和地点。

### 高级实践

如果你准备好了，尝试用这篇文章以及此前的文章介绍的知识构建一个<ruby> 超级结构 <rt>  superstructure </rt></ruby>。

使用 Python 库，下载维基百科的 “[Category: Computer science page](https://en.wikipedia.org/wiki/Category:Computer_science)”，然后：

* 找出其中频率最高的<ruby> 单词 <rt>  unigrams </rt></ruby><ruby> 、二元搭配 <rt>  bigrams </rt></ruby>和<ruby> 三元搭配 <rt>  trigrams </rt></ruby>，将它们作为一个关键词列表或者技术列表。相关领域的学生或者工程师需要了解这样一份列表里的内容。
* 图形化地显示这个领域里重要的人名、技术、日期和地点。这会是一份很棒的信息图。
* 构建一个搜索引擎。你的搜索引擎性能能够超过维基百科吗？

### 下一步？

自然语言处理是<ruby> 应用构建 <rt>  application building </rt></ruby>的典型支柱。NLTK 是经典、丰富且强大的工具集，提供了为现实世界构建有吸引力、目标明确的应用的工作坊。

在这个系列的文章里，我用 NLTK 作为例子，展示了自然语言处理可以做什么。自然语言处理和 NLTK 还有太多东西值得探索，这个系列的文章只是帮助你探索它们的切入点。

如果你的需求增长到 NLTK 已经满足不了了，你可以训练新的模型或者向 NLTK 添加新的功能。基于 NLTK 构建的新的自然语言处理库正在不断涌现，机器学习也正被深度用于自然语言处理。

---

via: <https://opensource.com/article/20/8/nlp-python-nltk>

作者：[Girish Managoli](https://opensource.com/users/gammay) 选题：[lujun9972](https://github.com/lujun9972) 译者：[tanloong](https://github.com/tanloong) 校对：[wxy](https://github.com/wxy)

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


硬核观察 #339 特斯拉投资比特币的 15 亿美元账面收益再次化为乌有

Summary: 更多：• Gmail 启用 BIMI 安全功能 • 存在 6 年的 systemd 安全漏洞被披露

# 硬核观察 #339 特斯拉投资比特币的 15 亿美元账面收益再次化为乌有

### 特斯拉投资比特币的 15 亿美元账面收益再次化为乌有

根据 CoinDesk 的数据，7 月 20 日，比特币的价格再度跌至 29600 美元，在 24 小时内下跌超过 5%。自 4 月中旬创下近 65000 美元的历史新高以来，其价格已暴跌了 50% 以上。比特币今年以来上涨了 1.87%。

今年 2 月，特斯拉宣布投资 15 亿美元购买比特币，平均价格为 32600 美元。截至一季度末，特斯拉在比特币上账面收益总计为 14.51 亿美元。6 月 22 日，比特币一度跌至 28900 美元，使特斯拉的比特币投资的账面亏损达 1.33 亿美元。7 月 20 日，比特币的价格再度跌至 29600 美元后，如果特斯拉今天卖掉这些比特币，其 15 亿美元的投资也只能做到盈亏相抵。

>
> 你猜马一龙会不会马上抛售比特币呢？
>
>
>

### Gmail 启用 BIMI 安全功能

邮件认证品牌标识（BIMI）是一项行业标准，旨在为电子邮件生态系统带来更强大的发件人身份验证。认证品牌标识的设计是当一个组织向你发送使用 DMARC 标准认证的电子邮件时，该组织的标志将显示在你的收件箱中。使用发件人政策框架（SPF）或域密钥识别邮件（DKIM）认证其电子邮件并部署 DMARC 的组织可以通过验证标记证书（VMC）向谷歌提供其验证的商标标识。

>
> 这只是使 DMARC 更用户友好而已，本质上还是依靠 DMARC 的机制。
>
>
>

### 存在 6 年的 systemd 安全漏洞被披露

Qualys [发现](https://blog.qualys.com/vulnerabilities-threat-research/2021/07/20/cve-2021-33910-denial-of-service-stack-exhaustion-in-systemd-pid-1)了一个新的 systemd 安全漏洞，使任何非特权的用户能够通过内核恐慌造成拒绝服务。几乎所有现代 Linux 发行版都使用 systemd。这个特殊的安全漏洞于 2015 年 4 月出现在 systemd 代码中。这种攻击可以由本地攻击者在很长的路径上挂载一个文件系统来[实现](https://access.redhat.com/security/cve/cve-2021-33910)。这将导致 systemd 堆栈中使用过多的内存空间，从而导致系统崩溃。systemd 的开发者已经修补了这个漏洞。

>
> 这是一个严重的安全漏洞，请尽快注意并升级。
>
>
>


作为一个写作者如何使用 Git 版本控制

评论，和编辑协作修改意见，那不就是 code review 么。<br />
你可以搭建一个私人的 gitea，或如果你对保密性没有那么高，也可以使用 GitHub 的私有仓库。

来自广东深圳的 Chrome Mobile 91.0|Android 11 用户

# 作为一个写作者如何使用 Git 版本控制

>
> 我使用 Vim 和 Git 来写小说。是的，你也可以用 Git 来完成非编码任务。
>
>
>

我相信当代的写作者们应该开始思考他们的工作流程了。

在一个注意力高度分散的世界里，作为写作者，我们必须对每天执行的任务链拥有控制权。传统上，作家们会把他们的写作放在分散注意力的事较少、注意力高度集中的时间段。不幸的是，海明威、阿特伍德们的这些建议不再真正适用于我们了。我们所生活的世界联系得更紧密了，因此对作家来说就有了更多的陷阱。这首先要求我们要有足够的自制力，不要让社交媒体或小狗和小猫的可爱视频在我们写作的时候分散我们的注意力。

但是，如果你的写作需要快速地检查事实、拼写不常见和技术性的词汇等，断开与互联网连接并不是一个现实的选项 —— 这正是我写作时的场景。另一个问题是你用于写作的应用程序本身的干扰；作为一个长期使用 MS Word 的人，我发现它越来越漂亮，但速度越来越慢，也越来越让人分心。作为当初我 [迁移到 Vim 的主要原因](https://news.itsfoss.com/how-i-started-loving-vim/) 之一，我曾详细地谈到了这一点，所以我不打算再在这个问题上大谈特谈。重点是，在现代世界中，在现代设备上进行写作，可能远非理想状态。

因为我已经详细介绍过了 [我为什么转向 Vim](https://news.itsfoss.com/configuring-vim-writing/) 和开源版本控制，在这篇文章中，我更想谈谈该 **怎么做**，特别是如何使用开源的版本控制技术，比如 Git（和 GitHub）。

### 什么是版本控制？再来一次？

上图是我们如何进行传统版本控制的一个说明。这个图中假设你有一台设备，而且你只在那台设备上写作。但对我而言，我在许多机器上写作，包括我的安卓手机和一些不同年代的笔记本电脑，我会在特定的任务、特定的位置使用到它们。我在所有这些设备上进行的一个共同任务就是写作 —— 因此，我的设备必须以合理的方式捕捉变化并控制文件的版本。不要再让我将 `file1V1_device1_date.doc` 作为文件名了。

上图也没有考虑到我们用来写作的工具。像 LibreOffice Write 这样的文字处理器可以在 Linux、Mac 和 Windows 系统上使用，但在手机上使用文字处理器将会是一段不愉快的经历。我们中的一些写作者还使用其他文本工具（包括 Gmail 或我们的电子邮件客户端）来为我们的写作打草稿。但按逻辑顺序跟踪所有这些文件和电子邮件是相当折磨人的，我就用这样的流程写过一本书，相信我：我花在弄清文件名、版本变化、评论、给自己的注释以及带有附加注释的电子邮件上的时间，足以让我精神错乱。

读到这里，你们中的一些人可能会正确地指出，有云备份技术呀。虽然云存储的好处是巨大的，而且我也在继续使用它们，但其版本控制几乎不存在，或者说并不强大。

### 一个更好的工作流程

就像地球上的其它地方一样，大流行病的开始引发了一些焦虑和一些反思。我利用这段时间在 [The Odin Project](https://www.theodinproject.com/)（强烈推荐给那些想学习 html、CSS、JavaScript/Ruby 的人）上自学了网络开发。

在课程的第一个模块中，有一个关于 Git 的介绍：什么是版本控制，以及它试图解决什么问题。读了这一章后，我豁然开朗。我立即意识到，这个 *Git* 正是我作为一个写作者所要寻找的东西。

是的，更好的方法不是本地化的版本控制，而是 *分布式* 的版本控制。“分布式”描述的是设备的分布，而我在这些设备上访问文件，以及之后进行编辑修改。下图是分布式版本控制的一个直观说明。

### 我的方法

我为写作建立一个版本控制系统的目标如下：

* 使我的稿件库可以从任何地方、任何设备上访问
* 易于使用
* 减少或消除因在写作、学习和编码各工作流程之间的场景切换而产生的摩擦 —— 尽可能使用同一工具（即 Vim）。
* 可扩展性
* 易于维护

基于以上需求，下图是我进行写作的分布式版本控制系统。

如你所见，我的版本控制系统是分布式版本控制的一个简单的适配。在我的例子中，通过将 Git 版本控制应用到云存储（[pCloud](https://itsfoss.com/recommends/pcloud/)）的一个文件夹上，我可以同时利用这两种技术的优点。因此，我的工作流程可以用下图描述：

#### 优势

1. 我用一个写作（和编码）工具
2. 我可以对我的手稿进行版本控制，无论我是从什么设备上访问文件的
3. [超级简单，几乎没有任何不便之处](https://www.youtube.com/watch?v=NtH-HhaLw-Q)
4. 易于维护

#### 缺点

你们中的写作者一定想知道这个系统存在什么缺点。以下是我在持续使用和完善这一工作流程时预计到的几个问题。

* 对草稿的评论：文字处理器的一个更有用的功能是具有评论的功能。当我希望以后再回到文本的某一部分时，我经常在这部分为自己留下一个评论。我仍然没有想出一个解决这个问题的办法。
* 协作：文字处理程序允许写作者之间进行协作。在我以前做广告相关工作的时候，我会用 Google Docs 来写文案，然后分享链接给我的设计师，从而他可以为广告和网站对文案进行摘录。现在，我的解决方法是用 Markdown 写文案，并通过 Pandoc 将 Markdown 文件导出为 .doc 文件。更关键的是，当我的手稿完成后，我仍然需要将文件以 .doc 格式发送给我的编辑。一旦我的编辑做了一些修改并把它发回来，我再尝试用 Vim 打开它就没有意义了。在这一点上，该系统的局限性变得更加明显。

我并不是说这是最好的方法，但在我职业生涯的这个阶段，这是对我来说最好的方法。我想，随着我对我的新的 [用于写作的开源工具](https://itsfoss.com/open-source-tools-writers/) 和版本控制越来越熟悉和适应，我将进一步完善这个方法。

我希望这篇文章能为那些想使用 Git 进行文档版本控制的写作者提供一个很好的介绍。这肯定不是一篇详尽的文章，但我将分享一些有用的链接，使你的旅程更容易。

1. [The Odin Project 介绍的 Git 基础知识](https://www.theodinproject.com/paths/foundations/courses/foundations/lessons/introduction-to-git)
2. [开始使用 Git](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control)
3. GitHub 的 Git 基础知识教程

---

via: <https://news.itsfoss.com/version-control-writers/>

作者：[Theena](https://news.itsfoss.com/author/theena/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[piaoshi](https://github.com/piaoshi) 校对：[wxy](https://github.com/wxy)

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


分支与发行版有什么不同?

Summary: 开源软件的发行版和分支是不一样的。了解其中的区别和潜在的风险。

开源软件的发行版和分支是不一样的。了解其中的区别和潜在的风险。

# 分支与发行版有什么不同?

>
> 开源软件的发行版和分支是不一样的。了解其中的区别和潜在的风险。
>
>
>

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

如果你们对开源软件有过一段时间的了解，一定曾在许多相关方面中听说过<ruby> 分支 <rt>  fork </rt></ruby>和<ruby> 发行版 <rt>  distribution </rt></ruby>两个词。许多人对这两个词的区别不太清楚，因此我将试着通过这篇文章为大家解答这一疑惑。

（LCTT 译注：fork 一词，按我们之前的倡议，在版本控制工作流中，为了避免和同一个仓库的 branch 一词混淆，我们建议翻译为“复刻”。但是在项目和发行版这个语境下，没有这个混淆，惯例上还是称之为“分支”。）

### 首先，一些定义

在解释分支与发行版两者的细微区别与相似之处之前，让我们先给一些相关的重要概念下定义。

**[开源软件](https://opensource.com/resources/what-open-source)** 是指具有以下特点的软件：

* 在特定的 [许可证](https://opensource.com/tags/licensing) 限制下，软件供所有人免费分发
* 在特定的许可证限制下，软件源代码可以供所有人查看与修改

开源软件可以按以下方式 **使用**：

* 以二进制或者源代码的方式下载，通常是免费的。（例如，[Eclipse 开发者环境](https://www.eclipse.org/che/getting-started/download/)）
* 作为一个商业公司的产品，有时向用户提供一些服务并以此收费。（例如，[红帽产品](https://access.redhat.com/downloads)）
* 嵌入在专有的软件解决方案中。（例如一些智能手机和浏览器用于显示字体的 [Freetype 软件](https://www.freetype.org/)）

<ruby> 自由开源软件 <rt>  free and open source software </rt></ruby>（FOSS）不一定是“零成本”的“<ruby> 免费 <rt>  free </rt></ruby>”。自由开源软件仅仅意味着这个软件在遵守软件许可证的前提下可以自由地分发、修改、研究和使用。软件分发者也可能为该软件定价。例如，Linux 可以是 Fedora、Centos、Gentoo 等免费发行版，也可以是付费的发行版，如红帽企业版 Linux（RHEL）、SUSE Linux 企业版（SLES）等。

<ruby> 社区 <rt>  community </rt></ruby>指的是在一个开源项目上协作的团体或个人。任何人或者团体都可以在遵守协议的前提下，通过编写或审查代码/文档/测试套件、管理会议、更新网站等方式为开源项目作出贡献。例如，在 [Openhub.net](http://openhub.net) 网站上，我们可以看见政府、非营利性机构、商业公司和教育团队等组织都在 [为一些开源项目作出贡献](https://www.openhub.net/explore/orgs)。

一个开源<ruby> 项目 <rt>  project </rt></ruby>是集协作开发、文档和测试的结果。大多数项目都搭建了一个中央仓库用来存储代码、文档、测试文件和目前正在开发的文件。

<ruby> 发行版 <rt>  distribution </rt></ruby>是指开源项目的一份的二进制或源代码的副本。例如，CentOS、Fedora、红帽企业版 Linux（RHEL）、SUSE Linux、Ubuntu 等都是 Linux 项目的发行版。Tectonic、谷歌的 Kubernetes 引擎（GKE）、亚马逊的容器服务和红帽的 OpenShift 都是 Kubernetes 项目的发行版。

开源项目的商业发行版经常被称作<ruby> 产品 <rt>  products </rt></ruby>，因此，红帽 OpenStack 平台是红帽 OpenStack 的产品，它是 OpenStack 上游项目的一个发行版，并且是百分百开源的。

<ruby> 主干 <rt>  trunk </rt></ruby>是开发开源项目的社区的主要工作流。

开源分支fork是开源项目主干的一个版本，它是分离自主干的独立工作流。

因此，**发行版并不等同于分支**。发行版是上游项目的一种包装，由厂商提供，经常作为产品进行销售。然而，发行版的核心代码和文档与上游项目的版本保持一致。分支，以及任何基于分支的的发行版，导致代码和文档的版本与上游项目不同。对上游项目进行了分支的用户必须自己来维护分支项目，这意味着他们失去了上游社区协同工作带来的好处。

为了进一步解释软件分支，让我来用动物迁徙作比喻。鲸鱼和海狮从北极迁徙到加利福尼亚和墨西哥；帝王斑蝶从阿拉斯加迁徙到墨西哥；并且北半球的燕子和许多其他鸟类飞翔南方去过冬。成功迁徙的关键因素在于，团队中的所有动物团结一致，紧跟领导者，找到食物和庇护所，并且不会迷路。

### 独立前行带来的风险

一只鸟、帝王蝶或者鲸鱼一旦掉队就失去了许多优势，例如团队带来的保护，以及知道哪儿有食物、庇护所和目的地。

相似地，从上游版本获取分支并且独立维护的用户和组织也存在以下风险：

1. **由于代码不同，分支用户不能够基于上游版本更新代码。** 这就是大家熟知的技术债，对分支的代码修改的越多，将这一分支重新归入上游项目需要花费的时间和金钱成本就越高。
2. **分支用户有可能运行不太安全的代码。** 由于代码不同的原因，当开源代码的漏洞被找到，并且被上游社区修复时，分支版本的代码可能无法从这次修复中受益。
3. **分支用户可能不会从新特性中获益。** 拥有众多组织和个人支持的上游版本，将会创建许多符合所有上游项目用户利益的新特性。如果一个组织从上游分支，由于代码不同，它们可能无法纳入新的功能。
4. **它们可能无法和其他软件包整合在一起。** 开源项目很少是作为单一实体开发的；相反地，它们经常被与其他项目打包在一起构成一套解决方案。分支代码可能无法与其他项目整合，因为分支代码的开发者没有与上游的其他参与者们合作。
5. **它们可能不会得到硬件平台认证。** 软件包通常被搭载在硬件平台上进行认证，如果有问题发生，硬件与软件工作人员可以合作找出并解决问题发生的根源。

总之，开源发行版只是一个来自上游的、多组织协同开发的、由供应商销售与支持的打包集合。分支是一个开源项目的独立开发工作流，有可能无法从上游社区协同工作的结果中受益。

---

via: <https://opensource.com/article/18/7/forks-vs-distributions>

作者：[Jonathan Gershater](https://opensource.com/users/jgershat) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Wlzzzz-del](https://github.com/Wlzzzz-del) 校对：[wxy](https://github.com/wxy)

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


硬核观察 340 安全黑市中出售的一半以上的漏洞是针对微软产品的

Summary: 更多：• 黑客团伙利用 SSH 暴力入侵来挖矿和 DDoS 攻击 •

更多：• 黑客团伙利用 SSH 暴力入侵来挖矿和 DDoS 攻击 •

# 硬核观察 340 安全黑市中出售的一半以上的漏洞是针对微软产品的

### 安全黑市中出售的一半以上的漏洞是针对微软产品的

一项新[研究](https://atlasvpn.com/blog/51-of-exploits-sold-on-underground-forums-are-for-microsoft-products)表明，地下网络犯罪论坛上出售的漏洞有 51% 是针对微软产品的。微软 Office 的漏洞占 23%，而 Windows 占黑客论坛上出售的漏洞的 12%。远程桌面协议（RDP）的漏洞占 10%。

>
> 所谓树大招风，公平的讲，其实 Linux 并不比 Windows 更安全，只是 Windows 影响面更大而已。
>
>
>

### 黑客团伙利用 SSH 暴力入侵来挖矿和 DDoS 攻击

据[报告](https://www.bitdefender.com/blog/labs/how-we-tracked-a-threat-group-running-an-active-cryptojacking-campaign)，从 2020 年开始活跃的一个黑客团伙正使用此前从未被记录的 SSH 暴力破解器（使用 Golang 编写），对使用 Linux 的设备发起加密劫持活动。在成功入侵之后，就会部署门罗币恶意挖矿软件。除了部署恶意程序用于挖矿之外，该团伙还连接了至少 2 个 DDoS 僵尸网络。

>
> 比较嘲讽的是，很多人使用 SSH 服务看似提供了安全连接，但是 SSH 本身并没有保护好。
>
>
>

### 谷歌正在测试基于机器学习的 DDoS 攻击防御功能

谷歌曾经历让人咋舌的大型 DDoS 攻击。比如 2017 年的那一次，就曾创下了 2.56 Tbps 的纪录。去年 11 月，谷歌推出了 Cloud Armor 自适应防护功能，并作为其 DDoS 防御和 Web 应用程序防火墙服务的一部分，为客户提供基于相同技术的防护。该技术在底层使用了机器学习模型，来分析网络服务中的信号是否存在潜在的攻击。

>
> 将机器学习用到这方面是一个好的方向，单纯按人工规则拼已经落后了。
>
>
>


将 Vim 配置成一个写作工具

Summary: 我使用 Vim 来写小说。我是这样配置它的。

我使用 Vim 来写小说。我是这样配置它的。

# 将 Vim 配置成一个写作工具

>
> 我使用 Vim 来写小说。我是这样配置它的。
>
>
>

在我的第一个专栏中，我谈到了我为什么把 [我的写作工作迁移到了 Vim 上](https://news.itsfoss.com/how-i-started-loving-vim/) —— 远离了现代写作者们的标准工具，如文字处理器（MS Word 及它的开源替代方案）、文本编辑器（记事本，因为直到去年我一直是 Windows 用户）和云存储技术。如果你是一个写作者，在继续下面的内容前，我建议你先阅读一下 [那篇文章的第一部分](https://news.itsfoss.com/how-i-started-loving-vim/) 。

基本上可以说，你使用的设备越多，你需要的写作工具就越多，最终你的工作流程就越复杂。这一点对我来说是很贴切的，因为我有四台设备，包括一部安卓手机，一台日常用的运行 Linux 的主力笔记本电脑，还有两台旧的笔记本电脑，其中一台是 Mac，我去户外拍摄时会带着它。

Vim 对于我和我的工作方式来说是一个完美的解决方案；虽然我不会说我的新的工作流程是现代写作者工作的最佳方式，但我可以说的是，对于写作者来说，拥有一个能在我们所有设备上工作的工具非常重要的，并且这个工具要足够强大以满足我们写作者每天从事的不同类型的写作需求。

从这个角度来看，Vim 的主要优势是它是跨平台的 —— 无论在什么设备上，Vim 都能工作。在苹果生态系统中使用 Vim 的情况我就不细说了，但粗略地看一下 [这个应用程序](https://apps.apple.com/us/app/ivim/id1266544660) 的评论，我就会知道，总会有人在各种地方使用 Vim，不管他们使用的是什么设备。

现在我们假设你是一个想开始使用 Vim 的写作者。当你安装了它，你该从哪里开始呢？

我在这一部分给你的并不算是教程，而是一系列的建议，包含对一个用于诗歌写作的 `.vimrc` 配置文件的解读。只要有可能，我就会链接到我学习相应内容时用到的 YouTube 上的教程。

对于 Linux 用户来说，系统已经预装了 Vim —— 通过你喜欢的终端模拟器就可以启动它。对于 Windows 和 Mac 用户，你可以从 [Vim 官方网站](https://www.vim.org/) 下载它。

### 建议

**安装/启用 Vim 后**

* 通过终端打开 Vim Tutor。（Mac 用户可以用这种方式启动，而 Windows 用户也可以用这种方法启动。[LCTT 译注：原文这里本应该有链接，可能作者忘记添加了。无论如何，在终端中， Linux 中的命令是 `vimtutor`，Windows 在安装目录下找到 `vimtutor.bat` 命令并运行；Mac？应该与 Linux 一样？我没 Mac 呀！]）在这个阶段，你不会使用 Vim 进行任何写作 —— 相反，你要每天花 15 分钟做 Vim 教程。不要多花一分钟或少花一分钟；看看在规定的 15 分钟内，你能在教程中取得多大的进展。你会发现，每天你都会在教程中取得更大的进步。在一个月内，你应该能够利用这些 15 分钟完成整个教程。
* 成为一个更好的打字员对 Vim 的使用来说有极大的好处。这不是必须的，但我正在重新学习打字，它的副作用是使 Vim 变得更加有用了。我每次都以花 15 分钟练习打字开始，作为进入 Vim 教程前的热身。

在每一天的开始，我分配了 30 分钟的时间做这两项练习进行热身，而每天晚上睡觉前再分配 30 分钟进行练习以让我安定下来。这样的做法帮我快速从旧的工具包过渡到了 Vim，但你的安排可能有所不同。

我再次强调，**除了 Vim Tutor 之外**，上述步骤都是可选的；这完全取决于你个人的动机水平。

现在我们来到了这篇文章的重点：如何配置 Vim ，使它对写作者友好？

### 如何配置用于写作的 .vimrc

在开始之前，我想在这里提醒各位读者，我不是一个技术人员 —— 我是一个小说家 —— 你在下面看到的任何错误都是我自己的；我希望有经验的 Vim 用户能提供反馈，告诉我如何进一步完善我的配置文件。

下面是我的 `.vimrc` 文件。你可以从我的 [GitHub](https://github.com/MiragianCycle/dotfiles) 上下载，并进一步完善它：

```
syntax on

set noerrorbells " 取消 Vim 的错误警告铃声，关闭它以免打扰到我们 "
set textwidth=100 " 确保每一行不超过 100 字符 "
set tabstop=4 softtabstop=4
set shiftwidth=4
set expandtab
set smartindent
set linebreak
set number
set showmatch
set showbreak=+++
set smartcase
set noswapfile
set undodir=~/.vim/undodir
set undofile
set incsearch
set spell
set showmatch
set confirm
set ruler
set autochdir
set autowriteall
set undolevels=1000
set backspace=indent,eol,start

" 下面的设置确保按写作者而不是程序员喜欢的方式折行 "

set wrap
nnoremap <F5> :set linebreak<CR>
nnoremap <C-F5> :set nolinebreak<CR>

call plug#begin('~/.vim/plugged')

"   这是颜色风格插件 "

Plug 'colepeters/spacemacs-theme.vim'
Plug 'sainnhe/gruvbox-material'
Plug 'phanviet/vim-monokai-pro'
Plug 'flazz/vim-colorschemes'
Plug 'chriskempson/base16-vim'
Plug 'gruvbox-community/gruvbox'

"   这是为了更容易的诗歌写作选择的一些插件 "

Plug 'dpelle/vim-LanguageTool'
Plug 'ron89/thesaurus_query.vim'
Plug 'junegunn/goyo.vim'
Plug 'junegunn/limelight.vim'
Plug 'reedes/vim-pencil'
Plug 'reedes/vim-wordy'

"   这一部分是为了更容易地与机器集成，用了 vim-airline 这类插件 "

Plug 'vim-airline/vim-airline'

"   这一部分外理工作区和会话管理 "

Plug 'thaerkh/vim-workspace'

"   与上面插件相关, 下面的代码将你的所有的会话文件保存到一个你工作区之外的目录 "

let g:workspace_session_directory = $HOME . '/.vim/sessions/'

"   与上面插件相关，这是一个 Vim 活动的跟踪器 "

Plug 'wakatime/vim-wakatime'

"   一个干扰因素：我在这里使用了一些 Emacs 的功能，特别是 org-mode "

Plug 'jceb/vim-orgmode'

"  这是文件格式相关插件 "

Plug 'plasticboy/vim-markdown'

call plug#end()

colorscheme pacific
set background=dark

if executable('rg')
    let g:rg_derive_root='true'
endif

```

学习如何安装 Vim 插件时，这个[教程](https://www.youtube.com/watch?v=n9k9scbTuvQ)帮助了我。我使用 Vim Plugged 插件管理器是因为在我看来它是最简单、最优雅的。

#### 对于写作者的 .vimrc 选项的整理

* `syntax on`：这可以确保 Vim 知道我在使用什么语法。做笔记、写这种文章时我主要使用 Markdown；而在写小说的时候，纯文本是我的首选格式。
* `set noerrorbells`：为了你的精神状态，我强烈建议打开这个选项。
* `set textwidth=100`：为了便于阅读，没有人愿意横向滚动一个文本文件。
* `set spell`：如果有拼写错误的话提醒你。
* `set wrap`：确保文本以写作者而不是程序员的方式进行折行。

你会注意到，我没有花更多时间讨论其他一些基本配置选项，因为我并不觉得那些对写作者来说有多重要。因为我做一些业余的编码工作，所以我的 `.vimrc` 配置反映了这一点。如果你只想在 Vim 上写作，那么上述配置就应该能让你顺利开始。

从这点上来说，你的 `.vimrc` 是一个活的文档，它能生动地反映你想用 Vim 做什么，以及你希望 Vim 如何为你做这些事情。

#### 关于插件的说明

第 43-98 行之间是我对插件的配置。如果你已经学习了关于如何安装 Vim 插件的教程，我强烈推荐你从以下专为写作开发的 Vim 插件开始：

* `vim-LanguageTool`
* `thesaurus_query.vim`
* `vim-pencil`
* `vim-wordy`
* `vim-goyo`
* `vim-markdown`

#### 总结

在这篇文章中，我们简单地[介绍](https://youtu.be/Pq3JMp3stxQ)了写作者可以怎样开始使用 Vim，以及一个在写作工作中需要的 `.vimrc` 入门配置。除了我的 `.vimrc` 之外，我还将在这里链接到我在 GitHub 上发现的其他写作者的 `.vimrc`，它们是我自己配置时的灵感来源。

请劳记，这只是一个写作者的 `.vimrc` 的入门配置。你会发现，随着你的需求的发展，Vim 也可以随之发展。因此，投入一些时间学习配置你的 `.vimrc` 是值得的。

在下一篇文章中，我将会检视我在写作时的工作流程的具体细节，这个工作流程中我使用了 Vim 和 Git 及 GitHub。

---

via: <https://news.itsfoss.com/configuring-vim-writing/>

作者：[Theena](https://news.itsfoss.com/author/theena/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[piaoshi](https://github.com/piaoshi) 校对：[wxy](https://github.com/wxy)

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


Summary: 它只专注于在出色的 Arch 发行版上提供完善的窗口管理器的选择。

它只专注于在出色的 Arch 发行版上提供完善的窗口管理器的选择。

# Hash Linux：预配置了四种平铺窗口管理器的 Arch Linux 衍生版

通过一些努力，[你能安装上 Arch Linux](https://itsfoss.com/install-arch-linux/)，也可以在你的 Arch 系统上安装一个你选择的桌面环境或窗口管理器。

这需要一些时间和精力，但肯定是可以实现的。但是，有一些项目可以减轻你的痛苦，为你提供一个预先配置好的桌面环境或窗口管理器的系统。[ArcoLinux](https://arcolinux.com/) 就是这样一个例子。

最近，我发现了另一个项目，它只专注于在出色的 Arch 发行版上提供完善的窗口管理器的选择。

[Hash 项目](https://hashproject.ga/) 提供了四种预配置有平铺式窗口管理器的 Arch 变体：Awesome、[Xmonad](https://xmonad.org/)、 i3 和 Bspwm。

如果你是一个刚刚接触窗口管理器的人，Hash 项目绝对是你应该马上尝试的。不用先投入时间去配置它，你就可以深入探索窗口管理器，并习惯由键盘驱动的系统。

在本文中，我将讨论我在使用 **Hash Linux Xmonad 版本** 时的部分体验，该版本采用 Linux 5.12 的内核。

### 安装 Hash Linux

Hash Linux 四个版本的 ISO 镜像均可 [下载](https://hashproject.ga/index.html#downloads) ，适用于 x86\_64 系统架构。

为了避免在实体机上安装时出现的各种意外错误，我在 GNOME Boxes 中创建了一个 Hash Linux Xmonad 版本的虚拟机。

当我启动到 Hash Linux 时，我注意到两件事。首先是一个面板，提供用于管理窗口和命令的快捷方式。我将在安装后讨论它。其次，是一个漂亮且易于使用的 GUI 安装程序。

像其他衍生版一样，图形化的安装程序使安装过程非常顺畅。在几个步骤的配置中，Hash Linux 已安装完毕，并准备重新启动。

### 第一印象

如果你曾经在你的 Linux 系统上安装过 Xmonad 窗口管理器，那么你重启后首先看到的是什么？空白的屏幕吧。

如果你是一个初学者，或者你不知道默认的按键绑定，你会被卡在一个屏幕上。因此，在使用任何窗口管理器之前，你必须先阅读其键盘快捷键。

如果你想把所有重要的快捷键提示都放在窗口上呢？一个备忘单可以为你节省很多时间。

因此，为了简化和方便初学者，Hash Linux 将重要的快捷键都钉在了桌面上。

所以，让我们先尝试其中的一些。从最重要的一个开始 `Super+Enter`，它可以打开默认的 termite 终端模拟器与 Z shell（ZSH）。

如果你多次按下它，你会发现默认情况下 Xmonad 遵循一个缩减布局，它首先将一个窗口固定在右边，然后以同样的方式将其余的全部安排在左边。

按下 `Super+Space`，你也可以将当前的布局改为标签式布局。甚至你可以按下 `Super+leftclick` 将窗口拖动。

要退出当前的窗口，你可以按下 `Super+Q`。

### Hash Linux 中的应用

默认情况下，Hash Linux 包含几个有用的命令行工具，如：NeoFetch、Htop、Vim、Pacman、Git 和 Speedtest-cli。

它还拥有大量的图形应用程序，如：Firefox 89、Gparted、Nitrogen、Conky、Flameshot、Geany 和 CPU-X。

`Super+D` 是 Hash Linux 中打开应用程序搜索菜单的默认快捷键。

### 主题美化

Hash Cyan 是 Hash Linux 的默认主题。除了它之外，Hash Linux 还提供了另外四个主题：Light Orange、Sweet Purple、Night Red 和 Arch Dark。

Hash Theme Selector 是一个自制的 Hash Linux 应用程序，你可以用它来配置窗口管理器的主题。

### 升级 Hash Linux

作为一个滚动发行版，你不需要下载一个新的 Hash Linux 的 ISO 来更新现有系统。你唯一需要的是在终端运行 `upgrade` 命令来升级你的系统。

### 结束语

如果你想使用一个窗口管理器来代替桌面环境，但又不想花很多时间来配置它，Hash 项目可以节省你的时间。

首先，它可以节省你大量的配置时间和精力，其次，它可以很轻松地让你适应使用键盘控制的系统。以后，你肯定可以学会根据自己的需要进行配置。

由于 Hash Linux 已经提供了 4 个带有不同的窗口管理器的 ISO，你可以开始使用任何一个版本，并找到你最喜欢的一个版本。总的来说，它是一个 [很好的 Arch Linux 衍生版](https://itsfoss.com/arch-based-linux-distros/)。

最后我还要提一下，目前 Hash Linux 的官方 [网站](https://hashproject.ga/) 并没有包含很多关于它的信息。

在发布信息中也提到了一个早期的 [网站](https://hashproject.org/)（我现在无法访问），在我上次访问时，其中包含了许多关于它的信息，包括配置细节等。

不想入 Arch 的教，只想用平铺式窗口管理器？可以试试 [Regolith Linux](https://itsfoss.com/regolith-linux-desktop/) 。它是预先配置了 i3wm 的 Ubuntu。棒极了，对吧？

---

via: <https://itsfoss.com/hash-linux-review/>

作者：[Sarvottam Kumar](https://itsfoss.com/author/sarvottam/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[mcfd](https://github.com/mcfd) 校对：[wxy](https://github.com/wxy)

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


Summary: 更多：• 奇亚硬盘矿大热让希捷 6 年来单季营收首次冲上 30 亿 • MITRE 更新 25 个最危险的软件漏洞名单

# 硬核观察 #341 谷歌的推送更新少了一个 & 字符，致使 Chrome OS 设备无法登录

### 谷歌的推送更新少了一个 & 字符，致使 Chrome OS 设备无法登录

谷歌称，本周短暂推出的 Chrome OS 版本，使用户无法登录他们的设备。Chrome OS 会自动下载更新，并在重启后切换到新版本，因此重启设备的用户会突然被锁定。受该更新影响的用户可以等待设备再次更新。

由于 Chrome OS 是开源的，所以我们可以得到更多关于修复的细节。根据[分析](https://arstechnica.com/gadgets/2021/07/google-pushed-a-one-character-typo-to-production-bricking-chrome-os-devices/)，在操作系统中保存用户加密密钥的部分，谷歌在更新中弄错了一个条件语句，在应该使用逻辑与运算符 `&&` 的地方少了一个 `&`，变成了位运算符 `&`，从而破坏了条件语句的后半部分。由于这个错误，用户无法验证其密码。

>
> 这明显是程序员手误，但这么严重的错误，是如何进入产品渠道的推送的？
>
>
>

### 奇亚硬盘矿大热让希捷 6 年来单季营收首次冲上 30 亿

今年异军突起的奇亚硬盘矿给硬盘市场带来变数，尽管现在的价格不到之前高峰期的 20%，但它还是给硬盘厂商带来了一波红利：希捷 Q4 财季营收突破 30 亿美元，同比大涨 20%。希捷出货的硬盘总容量 152EB，同比增长 30%，其中 80% 的份额都是大容量硬盘市场贡献的。

>
> 硬盘挖矿本身是否有价值先不说，硬盘厂商倒是吃饱了。这就和加密货币让显卡厂商赚的盆满钵满一样。
>
>
>

### MITRE 更新 25 个最危险的软件漏洞名单

MITRE 发布了 2021 年最危险的 25 个软件弱点榜单：[CWE Top 25](https://cwe.mitre.org/top25/archive/2021/2021_cwe_top25.html)。CWE 团队利用了美国国家漏洞数据库（NVD）中的常见漏洞和暴露（CVE）数据，以及与每个 CVE 记录相关的通用漏洞评分系统分数。在这些数据中应用了一个公式，根据普遍性和严重性对每个弱点进行评分。

>
> 感觉这两年危险的安全漏洞越来越多了。
>
>
>


IT 人的 6 个晚上放松方式

我一般都是睡觉

柔式的

刷视频

啪啪啪不可以放松吗？

# IT 人的 6 个晚上放松方式

>
> 在结束了一天的远程会议、邮件往来、写代码和其他协作工作后，你在晚上如何放松自己呢？
>
>
>

<img src="content_image/album_202107_24_100720afeq20kf2wfp4qwi.jpg" alt="" title="A farm road">

这个奇怪的时代一方面给我们放慢脚步的机会，但另一方面来说，却比以前更忙了，尤其是当你除了照顾自己还要照顾家人的时候。俗话说，空杯子倒不出酒。所以，让我们看看在关上电脑或者完成最后一件工作之后，能为自己做些什么？

1、走出家门，做几次深呼吸，不要在乎是不是下雪天，让新鲜的空气从肺部充满全身。如果可以的话，在院子里走走，或者去街上逛逛。

2、如果有时间的话，给自己沏杯茶，红茶含有咖啡因，最好不要晚上喝，可以喝绿茶或者花果茶，然后在你穿上鞋（或许还有外套）时让它稍微凉一下。把茶倒在保温杯里，在小区周围散散步。不用设置目标或者目的地，就随便走走。如果你时间不充裕的话，可以定一个 15 分钟的闹钟。

3、放一首突然想到的歌，或者听之前想听但是一直没机会听的歌。

4、如果你有时间的话，别在椅子上继续坐着，可以站起来跳一段舞活动活动，或者到床上平躺着，躺着的时候什么也不要想，放空自己，让大脑休息休息。研究表明，给大脑一段空白时间后可以更好的思考。

5、打开你的 [电子书应用](https://opensource.com/article/20/2/linux-ebook-readers) 或者拿起一本纸质书，看纸质书相对来说对眼睛好点。享受轻松的阅读，如果不能长时间阅读的话，起码给自己留出能阅读一个章节的时间。

6、制做一些美食。享受把从杂货店买到的基本的食材按照菜谱做成一份美味佳肴的成就感和兴奋感。

你也可以在晚上把其中一些综合起来做，好好放松。如果你是 IT 人，那么无论是在 [早上](https://opensource.com/article/20/10/tech-morning-rituals)、中午、晚上用这些方式放松都很有效，因为现在我们都是在家工作，远程办公，没有和同事面对面交流时的闲暇。

那么，你的晚上放松方式是什么?

---

via: <https://opensource.com/article/20/11/evening-rituals-working-tech>

作者：[Jen Wike Huger](https://opensource.com/users/jen-wike) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Arzelan](https://github.com/Arzelan) 校对：[wxy](https://github.com/wxy)

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


Ubuntu 20.10 到达生命终点，该升级啦！

# Ubuntu 20.10 到达生命终点，该升级啦！

>
> 哦！Ubuntu 20.10 将不再收到任何更新。如果你还在使用它，你的系统将面临风险，请考虑升级到 Ubuntu 21.04！
>
>
>

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

Ubuntu 20.10（Groovy Gorilla）2021 年 7 月 22 日停止支持啦。它是一个非长期支持发行版本，[带来了一些令人兴奋的新特性](https://itsfoss.com/ubuntu-20-10-features/)。

通常，非长期支持发行版维护 9 个月，所以生命周期结束意味着Ubuntu 20.10 用户将没有安全和维护更新。

你也会错过已安装应用的更新，[使用 apt 命令](https://itsfoss.com/apt-command-guide/) 安装新软件也会面临问题。如果不手动修改 `sources.list`（不推荐），使用软件中心也将是个问题。

支持周期的结束会影响所有的其他 Ubuntu 特色版本，像 Kubuntu、Lubuntu、MATE 等。

但是像 Linux Mint 和 elementary OS 这样的发行版不依赖于非长期支持发行版，你不必有任何担心。

使用下面的命令在终端 [检查下你安装的 Ubuntu 版本](https://itsfoss.com/how-to-know-ubuntu-unity-version/)是个好主意：

```
lsb_release -a

```

### 升级到 Ubuntu 21.04（Hirsute Hippo）：正是时候！

毫无疑问，你需要升级到 Ubuntu 21.04 才能获得最新的更新和安全改进。

[Ubuntu 21.10 版本](https://news.itsfoss.com/ubuntu-21-10-release-schedule/) 将在几个月后发布，所以你也可以尝试到时升级到这个版本。

现在，你可以按照我们的 [Ubuntu 升级](https://itsfoss.com/upgrade-ubuntu-version/)教程来开始升级。

我推荐你备份一下，以防升级过程中出现问题。

如果你想重新安装，也可以。

### 还在用 Ubuntu 20.10?

从技术上来说，你可以继续使用不受支持的版本，如果你不想安全问题蔓延，建议还是升级到最新的版本，比如 Ubuntu 21.04。

Ubuntu 21.04 将会提供支持到 2022 年 1 月，升级前你可能想看下 [Ubuntu 21.04 的特性](https://news.itsfoss.com/ubuntu-21-04-features/)。

---

via: <https://news.itsfoss.com/ubuntu-20-10-end-of-life/>

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

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


使用树莓派搭建下载机

Summary: 树莓派这样一个低功耗的 Linux 发行版非常适用于做下载机，来满足 PT、BT 等一些长时间挂机下载/做种的需求。

“sudo apt-get install transmisson-daemon”<br />
里面transmisson拼错了，应该是transmission

# 使用树莓派搭建下载机

我自己已经用树莓派几年了，从 3B+ 版本到 4B 版本，这样一个低功耗的 Linux 发行版非常适用于做下载机，来满足 PT、BT 等一些长时间挂机下载/做种的需求。它还可以搭配 SMB 分享、FTP 内网穿透实现个人 NAS 的一些功能。接下来我将介绍自己使用 Transmission 工具搭建的树莓派下载机。

### Transmission 安装

**Transmission** 是一款流行的 BT 下载软件，比其他客户端使用更少的资源，守护程序非常适合服务器，并且可以通过桌面 GUI、Web 界面和终端程序进行远程控制，支持本地对等发现、完全加密、DHT、µTP、PEX 和 Magnet Link 等。

首先，通过 `apt` 安装软件包，这里注意安装的是 `transmisson-daemon`：

```
sudo apt-get update
sudo apt-get install transmisson-daemon

```

然后在 `/etc/transmission-daemon/` 目录下修改配置文件 `settings.json`。修改设置前需要先关闭 `transmission` 服务：

```
sudo systemctl stop transmission-daemon.service
cd /etc/transmission-daemon/
sudo nano settings.json

```

`settings.json` 文件内容如下，`#` 后为我补充的需要修改字段的注释：

```
{
    "alt-speed-down": 50,
    "alt-speed-enabled": false,
    "alt-speed-time-begin": 540,
    "alt-speed-time-day": 127,
    "alt-speed-time-enabled": false,
    "alt-speed-time-end": 1020,
    "alt-speed-up": 50,
    "bind-address-ipv4": "0.0.0.0",
    "bind-address-ipv6": "::",
    "blocklist-enabled": false,
    "blocklist-url": "http://www.example.com/blocklist",
    "cache-size-mb": 4,
    "dht-enabled": true,
    "download-dir": "/home/pi/complete", # 下载目录
    "download-limit": 100,
    "download-limit-enabled": 0,
    "download-queue-enabled": true,
    "download-queue-size": 30,
    "encryption": 1,
    "idle-seeding-limit": 30,
    "idle-seeding-limit-enabled": false,
    "incomplete-dir": "/home/pi/incomplete", # 下载未完成文件目录
    "incomplete-dir-enabled": true,
    "lpd-enabled": false,
    "max-peers-global": 200,
    "message-level": 1,
    "peer-congestion-algorithm": "",
    "peer-id-ttl-hours": 6,
    "peer-limit-global": 1000,
    "peer-limit-per-torrent": 50,
    "peer-port": 51413,
    "peer-port-random-high": 65535,
    "peer-port-random-low": 49152,
    "peer-port-random-on-start": false,
    "peer-socket-tos": "default",
    "pex-enabled": true,
    "port-forwarding-enabled": false,
    "preallocation": 1,
    "prefetch-enabled": true,
    "queue-stalled-enabled": true,
    "queue-stalled-minutes": 30,
    "ratio-limit": 2,
    "ratio-limit-enabled": false,
    "rename-partial-files": true,
    "rpc-authentication-required": true,
    "rpc-bind-address": "0.0.0.0",
    "rpc-enabled": true,
    "rpc-host-whitelist": "",
    "rpc-host-whitelist-enabled": true,
    "rpc-password": "{525a44ba546f85ef59189a202b8d45357d17589686ReudqW", # 将双引号内修改为你要设定的密码，输入密码明文，重新启动程序后会自动加密，再打开看到的就是这样的密文了。
    "rpc-port": 9091, # 默认 Web 访问端口
    "rpc-url": "/transmission/",
    "rpc-username": "raspberrypi", # 将双引号内修改为你要设定的用户名
    "rpc-whitelist": "*.*.*.*",
    "rpc-whitelist-enabled": true,
    "scrape-paused-torrents-enabled": true,
    "script-torrent-done-enabled": false,
    "script-torrent-done-filename": "",
    "seed-queue-enabled": false,
    "seed-queue-size": 10,
    "speed-limit-down": 2048,
    "speed-limit-down-enabled": false,
    "speed-limit-up": 5,
    "speed-limit-up-enabled": true,
    "start-added-torrents": true,
    "trash-original-torrent-files": false,
    "umask": 18,
    "upload-limit": 100,
    "upload-limit-enabled": 0,
    "upload-slots-per-torrent": 14,
    "utp-enabled": true # 允许 Web 登录
}

```

`settings.json` 修改完成后，保存配置文件，重启 `transmission` 服务：

```
sudo systemctl start transmission-daemon.service

```

这样在浏览器中登录树莓派 `ip:9091` 就可以访问 Transmission Web 管理界面了。

如果下载中遇到写入权限问题，需要将目录设置为权限开放：

```
sudo chmod -R a+rw /home/pi/complete

```

### 在树莓派上挂载移动硬盘

树莓派的存储设备为 SD 卡，存储容量不会很大，不适合做 BT 的存储器，最好还是外接移动硬盘。

这里要注意的是由于树莓派供电的问题。树莓派 3B 供电不能直接外接移动硬盘，需要一个可接电源的 USB HUB 对移动硬盘单独供电。树莓派 4B 可以直接外接固态硬盘。

可以先在要挂载的目录下新建一个文件夹，然后将移动硬盘挂载即可。为了能够在树莓派重启的时候自动完成挂载操作，可以将挂载设置为系统服务。

下面是我设置的移动硬盘挂载服务，请参考 `home-pi-M_disk.mount`：

```
[Unit]
Description=Auto mount USB disk
DefaultDependencies=no
ConditionPathExists=/home/pi/M_disk
Before=sysinit.target

[Mount]
What=/dev/sda1
Where=/home/pi/M_disk
Type=ntfs

[Install]
WantedBy=multi-user.target

```

上述挂载服务会在树莓派启动后自动将移动硬盘 `/dev/sda1`（设备名称可以将移动硬盘插入树莓派后通过 `sudo fdisk -l` 查看），挂载到 `/home/pi/M_disk`（此目录为新建的挂载目录）目录下。

### 结语

这样就完成了树莓派下载机的搭建，搭配之前介绍的 SMB 分享、 FTP 内网穿透，还是能够满足个人 NAS 的一些简单需求。 Enjoy！


硬核观察 #342 iDOS 2 模拟器收到苹果商店的下架通知

Summary: 更多：• Keseya 已获得 REvil 勒索软件的通用解密器 • 16 年前的惠普打印机驱动程序漏洞影响了数亿台 Windows

# 硬核观察 #342 iDOS 2 模拟器收到苹果商店的下架通知

### iDOS 2 模拟器收到苹果商店的下架通知

iDOS 2 允许用户在 iPhone 或 iPad 设备上运行几十年前的 DOS 游戏和软件。但据开发者所述，苹果正要求其作出改变，否则将下架这款模拟器。[苹果说](https://litchie.com/2021/07/idos2-will-be-gone)，该应用安装或启动了 App Store 不允许的可执行代码。受苹果对于捆绑游戏文件的限制，开发者曾被迫四年没有更新过 iDOS 2。目前苹果要求 iDOS 2 在 14 天内整改，以剔除该应用能够运行可执行代码的能力。但这么一来，也无异于让 iDOS 2 自废武功。

>
> 这就是封闭系统的问题，他们会封杀一切他们认为可能带来威胁的东西。
>
>
>

### Keseya 已获得 REvil 勒索软件的通用解密器

利用 Kaseya VSA 远程管理软件漏洞开展的大规模勒索软件攻击，受该事件影响的设备数量达到了百万级。勒索团伙 Revil 在各方的联合打击下从暗网上消失，但这也意味着受害者缺乏被加密数据的解锁秘钥。

不过，Kaseya 现已从“受信任的第三方”那里拿到了[通用解密密钥](https://therecord.media/kaseya-obtains-revil-decryptor-starts-customer-data-recovery-operations/)，使得受害者有机会重新获得相关数据的访问权，而无需支付任何赎金。Kaseya 表示不能披露其来源信息，至于是否向勒索软件团伙支付了赎金，Kaseya 既没承认也没否认。

>
> Kaseya 总算是解决了这个问题，但是如何保证下一次呢？
>
>
>

### 16 年前的惠普打印机驱动程序漏洞影响了数亿台 Windows

研究人员公布了惠普打印机驱动程序（三星和施乐也在使用）中一个高严重性的特权升级缺陷的技术细节，该缺陷影响到[数亿台 Windows 机器](https://threatpost.com/hp-printer-driver-bug-windows/167944/)。如果被利用，网络攻击者可以绕过安全产品；查看、改变、加密或删除数据；或创建具有更广泛用户权限的新账户。这个漏洞已经在系统中潜伏了 16 年，但今年才被发现。它在 CVSS 量表上的评分为 8.8（满分 10 分），属于高严重度。

据分析，该漏洞存在于驱动程序内部的一个函数中，这个函数使用`strncpy` 从用户输入复制一个字符串，其大小参数由用户控制。

>
> 这就是典型的缓冲区溢出，这是早些年非常流行的安全缺陷，如果采用 Rust，就不会有这样的问题。
>
>
>


我家的 Linux 故事

Summary: 我们在 Linux 的第一次尝试只是一个 apt-get 的距离。

话说 linux内核好像91年才发布的~  红帽额...

是翻译的问题。原文是Back in the late 1990s，应该翻译90年代末。

我们在 Linux 的第一次尝试只是一个 apt-get 的距离。

# 我家的 Linux 故事

>
> 我们在 Linux 的第一次尝试只是一个 apt-get 的距离。
>
>
>

<img src="content_image/album_202107_25_065040z2zt9lb9fc99kcho.jpg" alt="" title="Terminal command prompt on orange background">

我在 Linux 的第一次尝试是那种“或许我应该试一试”的情况。

那是 1990 年代，我在一些软盘上找到了用某种打包方式打包的红帽发行版，我为家里的笔记本电脑买了第二个硬盘，然后开始安装它。这是一件有趣的实验，但是我记得当时家人还没有准备好在电脑上使用 Linux。转眼到了 2005 年，我最终放弃了这种做法，买了一台可爱的东芝笔记本电脑，来运行 Windows XP。在工作中，我有一台有点年头的 SUN SPARCStation 5，并且我不太喜欢当时整个 Solaris 的发展方向（基于 Motif 的桌面）。我真的想要用 GIMP 来完成一些这样或那样的项目，但是在 Solaris 上安装 GNOME 1.x（也许是 1.4？）的曲折旅程是很有挑战性的。所以，我实际上是在考虑跳槽到 Windows XP。但是在我的家用机上用了几个月之后，我发现我更不喜欢在 Solaris 上运行 GNOME，所以我安装了 Ubuntu Hoary Hedgehog 5.04，随后在我的笔记本电脑上安装了 Breezy Badger 5.10。这太棒了，那台拥有 3.2GHz 奔腾处理器、2GB 内存和 100GB 的硬盘的机器就在我的 SPARCStation 5 旁边运行。

突然之间，我不再用拼凑起来的 Solaris 安装包来试图去让东西运行起来，而只是用 apt-get 就可以了。并且这个时机也很好。我家庭和我从 2006 年 8 月到 2007 年 7 月居住在法国格勒诺布尔，当时我的妻子在休假。因为有了运行 Linux 的东芝笔记本，我可以带着我的工作一起走。那个时候我在几个大的项目上做了大量的 GIS 数据处理，我发现我可以在 PostGIS / PostgreSQL 上做同样的事情，比我们在加拿大家中使用的昂贵得多的商业 GIS 软件要快得多。大家都很开心，尤其是我。

这一路上发生的有趣的事情是，我们把另外两台电脑带到了法国 —— 我妻子的类似的东芝电脑（运行 XP，对她来说很好用）和我们孩子最近新买的东芝牌笔记本电脑，也运行 XP。也就在圣诞节过后，他们有一些朋友过来，无意中在他们的电脑上安装了一个讨厌的、无法清除的病毒。经过几个小时甚至几天后，我的一个孩子问我：“爸爸，我们就不能安装和你电脑上一样的东西吗？”然后，三个新的 Linux 用户就这样产生了。我的儿子，29 岁了，依然是一个快乐的 Linux 用户，我猜他有第四或第五台 Linux 笔记本电脑了，最后几台都是由 System 76 提供的。我的一个女儿三年前开始读法学院时被迫转换为 Windows，因为她所在的学校有一个强制性的测试框架，只能在 Windows 上运行，而且据称会检测虚拟机之类的东西（请不要让我开始骂人）。而我的另一个女儿被她的公司为她买的 Macbook Air 诱惑了。

哦，好吧，不可能全都赢了吧！

---

via: <https://opensource.com/article/21/5/my-linux-story>

作者：[Chris Hermansen](https://opensource.com/users/clhermansen) 选题：[lujun9972](https://github.com/lujun9972) 译者：[shiboi77](https://github.com/shiboi77) 校对：[wxy](https://github.com/wxy)

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


如何在 Fedora 上使用 Podman

# 如何在 Fedora 上使用 Podman

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

[Podman](https://podman.io/) 是一个无守护程序的容器引擎，用于在你的 Linux 系统上开发、管理和运行 OCI 容器。在这篇文章中，我们将介绍 Podman 以及如何用 nodejs 构建一个小型应用来使用它。该应用将是非常简单和干净的。

### 安装 Podman

Podman 的命令就与 [docker](https://www.docker.com/) 相同，如果你已经安装了 Docker，只需在终端输入 `alias docker=podman`。

在 Fedora 中，Podman 是默认安装的。但是如果你因为任何原因没有安装，你可以用下面的命令安装它：

```
sudo dnf install podman

```

对于 Fedora [silverblue](https://silverblue.fedoraproject.org/) 用户，Podman 已经安装在你的操作系统中了。

安装后，运行 “hello world” 镜像，以确保一切正常：

```
podman pull hello-world
podman run hello-world

```

如果一切运行良好，你将在终端看到以下输出：

```
Hello from Docker!
This message shows that your installation appears to be working correctly.
 To generate this message, Docker took the following steps:
  1.The Docker client contacted the Docker daemon.
  2.The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64)
  3.The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
  4.The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
 To try something more ambitious, you can run an Ubuntu container with:
  $ docker run -it ubuntu bash
 Share images, automate workflows, and more with a free Docker ID:
  https://hub.docker.com/
 For more examples and ideas, visit:
  https://docs.docker.com/get-started/

```

### 简单的 Nodejs 应用

首先，我们将创建一个文件夹 `webapp`，在终端输入以下命令：

```
mkdir webapp && cd webapp

```

现在创建文件 `package.json`，该文件包括项目运行所需的所有依赖项。在文件 `package.json` 中复制以下代码：

```
{
       "dependencies": {
               "express": "*"
       },
       "scripts": {
               "start": "node index.js"
       }
}

```

创建文件 `index.js`，并在其中添加以下代码：

```
const express = require('express')

const app = express();

app.get('/', (req, res)=> {
       res.send("Hello World!")
});
app.listen(8081, () => {
       console.log("Listing on port 8080");
});

```

你可以从 [这里](https://github.com/YazanALMonshed/webapp) 下载源代码。

### 创建 Dockerfile

首先，创建一个名为 `Dockerfile` 的文件，并确保第一个字符是大写，而不是小写，然后在那里添加以下代码：

```
FROM node:alpine
WORKDIR usr/app
COPY ./ ./
RUN npm install
CMD ["npm", "start"]

```

确保你在 `webapp` 文件夹内，然后显示镜像，然后输入以下命令：

```
podman build .

```

确保加了 `.`。镜像将在你的机器上创建，你可以用以下命令显示它：

```
podman images

```

最后一步是输入以下命令在容器中运行该镜像：

```
podman run -p 8080:8080 <image-name>

```

现在在你的浏览器中打开 `localhost:8080`，你会看到你的应用已经工作。

### 停止和删除容器

使用 `CTRL-C` 退出容器，你可以使用容器 ID 来删除容器。获取 ID 并使用这些命令停止容器：

```
podman ps -a
podman stop <container_id>

```

你可以使用以下命令从你的机器上删除镜像：

```
podman rmi <image_id>

```

在 [官方网站](https://podman.io/) 上阅读更多关于 Podman 和它如何工作的信息。

---

via: <https://fedoramagazine.org/getting-started-with-podman-in-fedora/>

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


硬核观察 #343 第一款龙芯架构的芯片的性能测试一般

Summary: 更多：• Linux 防火墙 Firewalld 十年后发布了 1.0 • GitHub 提高了 Go 模块的供应链安全性

你的数据错了393是飞腾的数据，不是龙芯的数据。3A5000是336

没错呀。我点进去看了。

# 硬核观察 #343 第一款龙芯架构的芯片的性能测试一般

### 第一款龙芯架构的芯片的性能测试一般

本周发布的龙芯 3A5000 是第一款龙芯架构的芯片，四核，时钟速度高达 2.3~2.5GHz。据称龙芯 3A5000 的性能比之前基于 MIPS 的芯片提高了 50%，同时功耗更低。

据 phoronix [报道](https://www.phoronix.com/scan.php?page=news_item&px=Loongson-3A5000-Benchmark)，龙芯 3A5000 已经在 [OpenBenchmarking.org](http://openbenchmarking.org/) 上传了一些 Phoronix 测试套件的[基准测试结果](https://openbenchmarking.org/s/Loongson-3A5000)，总的来说，如果与现代英特尔/AMD 甚至 ARM 的竞争对手相比，性能并不那么令人印象深刻。龙芯 3A5000 上的简易 [C-Ray 基准测试](https://openbenchmarking.org/result/2107199-IB-CRAYLX50092) 大约为 393 秒，在[排名](https://openbenchmarking.org/test/pts/c-ray&eval=32f6380f8c703d3d84bd215727a68137f54f31cb#metrics)上与基于 ARM 的飞腾 FT-2000 或 Core i3 8109U / Core 2 Quad Q9500 / Core i5 750 差不多。甚至用于服务器的龙芯 3A5000LL 的 [Perl 基准测试](https://openbenchmarking.org/result/2107219-IB-PELX5000L22)也是 OpenBenchmarking 上所看到的最慢的结果之一。在几个其它[基准测试](https://openbenchmarking.org/result/2106090-IB-1912047KH34)中，龙芯 3A5000 也只能与飞腾 ARMv8 SoC 相比较。

>
> 这还只是龙芯架构迈出的第一步，让我们多给它一些时间。
>
>
>

### Linux 防火墙 Firewalld 十年后发布了 1.0

[Firewalld](https://github.com/firewalld/firewalld/releases/tag/v1.0.0) 是红帽公司十年前开始的，用于通过 Netfilter 管理 Linux 的防火墙功能。在首次发布十年半之后，[发布](https://www.phoronix.com/scan.php?page=news_item&px=Firewalld-1.0-Coming)了 Firewalld 1.0。

Firewalld 1.0 带来了一些突破性的变化，包括放弃对 Python 2 的支持，默认支持区内转发，NAT 规则被移到 iNet 系列，默认目标现在类似于拒绝，废弃了旧的 IPTables 后端等等。对于终端用户来说，它可以普遍减少规则集大小。预计将在 Fedora 35 上推出。

>
> Linux 界的传统就是这么谦虚，都在生产环境用了 10 年了才发布 1.0，不过现在这个传统已经逐渐被那些飙版本号的抛弃了。
>
>
>

### GitHub 提高了 Go 模块的供应链安全性

GitHub 宣布对基于 Go 编程语言的模块进行了一系列[供应链安全升级](https://github.blog/2021-07-22-github-supply-chain-security-features-go-community/)。Go 现在是该平台上最流行的编程语言之一。根据 2020 年 [Go 开发者调查](https://blog.golang.org/survey2020-results)，76% 的受访者表示，Go 现在已经以某种形式在企业中使用，96% 的受访者表示这些模块被用于包管理。

GitHub 为 Go 模块主要提供了如下供应链安全改进：咨询建议数据库，目前包含 150 多个建议；依赖关系图，可以通过 go.mod 来监控、分析项目的依赖关系，在发现有漏洞的依赖关系时提醒用户；依赖机器人，启用自动拉动请求来修补有漏洞的 Go 模块。

>
> 通过软件仓库来解决软件供应链攻击风险是一个好的思路。
>
>
>


在 Linux 上批量处理图像的 Converseen

# 在 Linux 上批量处理图像的 Converseen

Converseen 是一个用于批量图像转换的自由开源软件。有了这个工具，你可以一次将多张图片转换成另一种格式、调整大小、改变它们的长宽比、旋转或翻转它们。

对于像我这样的人来说，这是一个很方便的工具，我必须处理多个不同大小的截图，但在上传到网站之前必须调整它们的大小。

批量转换工具在这种情况下有很大的帮助。这可以在 Linux 命令行中用不错的 [ImageMagick](https://imagemagick.org/index.php) 来完成，但在这里使用 GUI 工具要容易得多。实际上，Converseen 在基于 Qt 的图形用户界面下使用 ImageMagick。

### 用 Converseen 批量处理图像

你可以用 [Converseen](https://converseen.fasterland.net/) 通过鼠标点击来转换、调整大小、旋转和翻转多个图像。

你有很多支持批量转换的选项。你可以在你的选择中添加更多的图片，或者删除其中的一些。你可以选择只转换你选择的几张图片。

在调整图像大小时，你可以选择保持长宽比。请记住，在宽度和高度中，你最后改变/输入的那个是控制长宽比的那个。所以，如果你想在保持长宽比的情况下调整大小，但要根据宽度来调整，不要修改高度栏。

你也可以选择将转换后的图像以不同的名称保存在同一目录或其他位置，也可以覆盖现有的图像。

你不能添加文件夹，但你可以一次选择并添加多个图像。

你可以将图像转换为多种格式，如 JPEG、JPG、TIFF、SVG 等。

在改变格式的同时，还有一个选项可以给透明背景以某种颜色。你还可以设置压缩级别的质量。

Converseen 还可以导入 PDF 文件，并将整个 PDF 或其中的一部分转换为图像。然而，在 Ubuntu 21.04 中，每次我试图转换一个 PDF 文件时，它就会崩溃。

### 在 Linux 上安装 Converseen

Converseen 是一个流行的应用。它在大多数 Linux 发行版仓库中都有。

你可以在你的发行版的软件中心搜索到它：

当然，你也可以使用你的发行版的包管理器通过命令行来安装它。

在基于 Debian 和 Ubuntu 的发行版上，使用：

```
sudo apt install converseen

```

在 Fedora 上，使用：

```
sudo dnf install converseen

```

在 Arch 和 Manjaro 上，使用：

```
sudo pacman -Sy converseen

```

Converseen 也可在 Windows 和 FreeBSD 下使用。你可以在项目网站的下载页面获得相关说明。

* [下载 Converseen](https://converseen.fasterland.net/download/)

它的源码可在 GitHub 仓库 [获取](https://github.com/Faster3ck/Converseen)。

如果你正在寻找一个更简单的方法来调整一张图片的大小，你可以使用这个巧妙的技巧，[在 Nautilus 文件管理器中用右键菜单调整图片大小和旋转图片](https://itsfoss.com/resize-images-with-right-click/)。

总的来说，Converseen 是一个有用的用于批量图像转换的 GUI 工具。它并不完美，但在大多数情况下是有用的。你曾经使用过 Converseen 或者你使用类似的工具吗？你对它的体验如何？

---

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

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


硬核观察 #344 可维修的模块化“框架笔记本电脑”开始发货

Summary: 更多：• 首位公众人物因在线活动的聚合数据而暴露 • Twitter 删除了对 FLoC 的支持

# 硬核观察 #344 可维修的模块化“框架笔记本电脑”开始发货

### 可维修的模块化“框架笔记本电脑”开始发货

作为“维修权运动”的一部分，“[框架笔记本电脑](https://frame.work/)”被设计为在技术上尽可能地可定制、可升级和可维修。它有四个扩展卡插槽、可卡入 USB-C 连接器的滑入式模块、插座式存储和内存、一个可更换的带有固定的 CPU 和风扇的主板模块、电池、屏幕、键盘等。这款笔记本电脑现在正在美国和加拿大进行[预购](https://www.cnet.com/tech/computing/framework-laptop-review-a-functional-and-futureproof-13-inches/)，起价 999 美元。它还发布了所有必要的信息，让维修店或 IT 部门不仅可以交换零件，还可以进行维修，PCWorld 称其为“终极维修权笔记本电脑”。

>
> 最初电脑就是组装起来的，到了笔记本时代逐渐变成一体化的而不可拆卸，现在又回到了组装时代。
>
>
>

### 首位公众人物因在线活动的聚合数据而暴露

移动运营商会向数据中介出售位置数据，数据中介在聚合不同来源的数据之后将其出售给不同类型的买家。一家报道天主教的新闻媒体获得了 24 个月的应用使用和应用位置数据，其中就包括了 Grindr。这些数据并不是真正的匿名数据，因为其中包含唯一标识符。大多数人在他们的生活中基本上都有一个位置指纹。他们的家庭地址、工作地点，他们去的某些有限的地方。已经有研究表明，仅仅根据我们在某一周内去的几个关键位置点，我们就可以被唯一识别。

进行去匿名化之后，从中发现美国天主教主教会议的秘书长在其经常活动的位置频繁登录 Grindr，这些位置包括了天主教主教会议办公室、住宅和会议室等等。该媒体通知了天主教主教会议，该会随后宣布了秘书长[辞职](https://arstechnica.com/tech-policy/2021/07/catholic-priest-quits-after-anonymized-data-revealed-alleged-use-of-grindr/#p3)。

>
> 大数据之下，人人无可遁形。
>
>
>

### Twitter 删除了对 FLoC 的支持

Twitter 是为数不多的支持谷歌 FLoC 广告技术的网站之一，尽管这种利用 Chrome 浏览器浏览习惯来描述用户的跟踪技术受到广泛的抨击。美国 15 位总检察长已经指责谷歌试图将其“ Chrome 置于跟踪和定位的中心”；服务于世界上 40% 网站的 WordPress 已经宣布，他们将把 FLoC 视为一种安全风险。在遭到监管机构的强烈反对后，谷歌自己也放弃了在短期内强制实施 FLoC 的计划，推迟到 2023 年。根据对 Twitter 网站的分析，Twitter 从其网站上删除了对 FLoC 的支持。

>
> 谷歌在推行 FLoC 的道路上过于暴露太多的私心。
>
>
>


Linux 包管理器比较：dnf 和 apt

我觉得将很多软件组件包集合积累到发行ISO里给用户能给用户带来应用部署的真正方便。尤其在没有网络得环境里！！！

按照我的理解，已经尽力集成了。

以往分CD和DVD版本，也是按照CD和DVD的最大容量。

现在网络快了，这么做的意义不大了。

我觉得软件包、软件包管理器，还有各种镜像，是人类历史上的伟大工程。<br />
致敬。

是啊，只是方便分几个文件下载

还记得2003年安装RH9的时候，3个CD里的RPM有时候不够用，需要在网上找.rpm文件。然后自己 rpm -ivh 来安装，然后就开始依赖噩梦！

应该算到开源界的伟大工程，也是Linux普及的基础

好久没用Ubuntu，以前一直都是绑着-get一起用。现在是简化了嘛

# Linux 包管理器比较：dnf 和 apt

>
> 包管理器提供大致相同的功能：安装、管理和移除应用，但是它们还是有一些不一样的地方。
>
>
>

<img src="content_image/album_202107_27_083002sd5zzxu37yhiz6yc.jpg" alt="" title="Gift box opens with colors coming out">

[在 Linux 系统上获取一个应用](https://opensource.com/article/18/1/how-install-apps-linux) 有多种方式。例如，有新的 Flatpak 和容器方式，也有 DEB 和 RPM 这样一直以来经过考验的方式。

并没有一种通用的可以用于所有的操作系统的应用安装程序。如今，因为有无数的开发者发布软件，这导致了大部分的操作系统使用了应用商店（包括第一方和第三方）、拖放式安装，还有安装向导。不同的开发者对于他们发布的代码有不同的需求，这直接导致了他们所选择的安装方式的不同。

Linux 开创了一种通过命令行安装、管理、移除应用的包管理器的概念。`apt` 和 `dnf` 就是两种较为常见的包管理器。`apt` 命令是用来管理 DEB 格式的包，`dnf` 命令是用来管理 RPM 格式的包。这两种包管理器在理论上并不是完全互斥的，尽管在实际的实践中，Linux 发行版通常只会使用到其中的一种。理论上，这两种命令可以运行在同一个系统上，但是会造成安装包的重叠，版本控制也会更加困难，命令也会是冗余的。然而，如果你是在一个混合的 Linux 环境下工作，比如你的工作站运行的是一个发行版，同时需要与运行另外一种发行版的服务器进行交互，那么你最好同时掌握这两种包管理器。

### 搜索应用

当你通过包管理器安装一个应用时，你需要先知道包的名称。通常，应用的名称和包的名称是一样的。`dnf` 和 `apt` 验证要安装的包名的过程是完全相同的。

```
$ sudo dnf search zsh
====== Name Exactly Matched: zsh ======
zsh.x86_64 : Powerful interactive shell
[...]

```

使用 `apt`:

```
$ sudo apt search zsh
Sorting... Done
Full Text Search... Done
csh/stable 20110502-4+deb10u1 amd64
  Shell with C-like syntax

ddgr/stable 1.6-1 all
  DuckDuckGo from the terminal

direnv/stable 2.18.2-2 amd64
  Utility to set directory specific environment variables

draai/stable 20180521-1 all
  Command-line music player for MPD
[...]

```

如果想通过 `apt` 更快的获取相关的搜索结果，你可以使用 [正则表达式](https://opensource.com/article/18/5/getting-started-regular-expressions)：

```
apt search ^zsh
Sorting... Done
Full Text Search... Done
zsh/stable 5.7.1-1 amd64
  shell with lots of features
[...]

```

### 查找应用程序包

有一些命令是与其它命令捆绑在一起的，都在一个包中。在这种情况下，你可以通过包管理器去了解哪个包提供了你需要的命令。`dnf` 和 `apt` 命令在如何搜索这类元数据上是有区别的。

使用 `dnf`：

```
$ sudo dnf provides pgrep
procps-ng-3.3.15-6.el8.x86_64 : System and process monitoring utilities
Repo        : baseos
Matched from:
Filename    : /usr/bin/pgrep

```

`apt` 命令使用子命令 `apt-file`。要使用 `apt-file`，你必须先安装它，然后提示它更新缓存：

```
$ sudo apt install apt-file
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libapt-pkg-perl libexporter-tiny-perl liblist-moreutils-perl libregexp-assemble-perl
The following NEW packages will be installed:
  apt-file libapt-pkg-perl libexporter-tiny-perl liblist-moreutils-perl libregexp-assemble-perl
0 upgraded, 5 newly installed, 0 to remove and 14 not upgraded.
Need to get 297 kB of archives.
After this operation, 825 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

$ sudo apt-file update
[...]

```

你可以通过 `apt-file` 搜索命令。你可以使用此命令进行广泛的全局搜索，但假如你知道命令的执行路径，它会更准确：

```
$ sudo apt-file search /usr/bin/pgrep
pgreplay: /usr/bin/pgreplay
procps: /usr/bin/pgrep

```

### 安装应用程序

使用`apt` 和 `dnf` 安装应用程序基本上是相同的：

```
$ sudo apt install zsh

```

使用 `dnf`，你可以使用同样的方式来安装一个包：

```
$ sudo dnf install zsh

```

许多基于 RPM 的发行版都具有组包安装的特性，它会将有时表面相关的应用程序收集到一个易于安装的目标中。例如，Fedora 中的 [Design Suite](https://labs.fedoraproject.org/en/design-suite/) 组包就包含流行的创意应用程序。那些想要某一个创意应用程序的艺术家可能也想要类似的应用程序，选择安装一整个组包一个简单而快速的方法，可以合理地开始建立一个数字工作室。你可以通过 `group list` 来查看可用的组包（使用 `-v` 来查看不带空格的组名）：

```
$ sudo dnf group list -v
[...]
Available Groups:
   Container Management (container-management)
   RPM Development Tools (rpm-development-tools)
   Design Suite (design-suite)
   Development Tools (development)
[...]

```

使用 `group install` 子命令安装 RPM 组包：

```
$ sudo dnf group install design-suite

```

你可以使用 `@` 符号来减少输入：

```
$ sudo dnf install @design-suite

```

### 更新应用程序

使用包管理器的一个优点是，它知道所有已经安装的应用。这样你不必去寻找应用程序的更新版本。相反，你可以通过包管理器去获取更新的版本。

`dnf` 和 `apt` 使用的子命令略有不同。因为 `apt` 保存了一个需要定期更新的缓存信息，它使用 `upgrade` 子命令来更新应用程序：

```
$ sudo apt upgrade

```

相比之下，`dnf` 命令在你每次使用时都会更新元信息，所以 `update` 和 `upgrade` 子命令是可以互换的：

```
$ sudo dnf upgrade

```

这等同于：

```
$ sudo dnf update

```

### 移除应用程序

如果你曾经尝试在任何一个平台上手动删除一个应用程序，你就会知道，应用程序删除后，在硬盘上会残留各种文件，比如首选项文件、数据或图标。所以包管理器的另一个优点是，包管理器管理着包中安装的每一个文件，可以很方便的删除：

```
$ sudo dnf remove zsh

```

`remove` 子命令也适用于 `apt`：

```
$ sudo apt remove zsh

```

使用 `apt` 命令删除一个包并不会删除已修改的用户配置文件，以防你意外删除了包。如果你想通过 `apt` 命令删除一个应用及其配置文件，请在你之前删除过的应用程序上使用 `purge` 子命令：

```
$ sudo apt purge zsh

```

`apt` 和 `dnf` 都不会删除家目录中的数据和配置文件（即使使用 `purge` 子命令）。如果想要从家目录中删除数据，你必须手动操作（通常你可以在 `~/.config` 和 `~/.local` 文件中找到）。

### 了解包管理

无论你选择的发行版支持的是 `apt` 还是 `dnf`，这些命令的用途大致相同。它们可以帮助你安装、更新和移除包。这两种包管理器是目前最通用的包管理器。它们的语法元素在很大程度上是相同的，所以在两者之间切换非常容易。

`apt` 和 `dnf` 还有一些高级功能，例如仓库管理，但这些功能并不像你使用 `search` 和 `install` 那样频繁。

无论你更经常使用哪种包管理器，你都可以下载我们的 [apt 备忘单](https://opensource.com/downloads/apt-cheat-sheet) 和 [dnf 备忘单](https://opensource.com/downloads/dnf-cheat-sheet)，以便你在最需要的时候可以查询使用语法。

---

via: <https://opensource.com/article/21/7/dnf-vs-apt>

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

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


# 如何在 Kubuntu 21.04 中安装和升级 KDE Plasma 5.22

>
> KDE 团队启用了向后移植 PPA，你可以使用它在 Kubuntu 21.04 Hirsute Hippo 中安装和升级到 KDE Plasma 5.22。
>
>
>

KDE 团队最近发布了 KDE Plasma 5.22，其中有相当多的增强功能、错误修复以及更新的 KDE 框架和应用版本。这个版本带来了一些改进，如面板的自适应透明度，文件操作弹出时的用户友好通知，“发现”中的软件包类型显示，各种 Wayland 的变化等。在 [这里](https://www.debugpoint.com/2021/06/kde-plasma-5-22-release/) 查看更多关于功能细节。

如果你正在运行 Kubuntu 21.04 Hirsute Hippo，或者在 [Ubuntu 21.04 Hirsute Hippo](https://www.debugpoint.com/2021/04/ubuntu-21-04-hirsute-hippo-release/) 中安装了自定义的 KDE Plasma，你可以通过以下步骤升级到最新版本。目前的 Hirsute Hippo 系列提供了先前版本 KDE Plasma 5.21.04 与 KDE Framework 5.80。

### 在 Kubuntu 21.04 Hirsute Hippo 中安装 KDE Plasma 5.22 的步骤

按照下面的步骤进行。

如果你想使用图形方法，那么在“发现”中将 `ppa:kubuntu-ppa/backports` 添加到软件源，然后点击“更新”。

或者，使用下面的终端方法，以加快安装速度。

* **步骤 1**：打开一个终端，添加下面的 KDE Backports PPA。

```
sudo add-apt-repository ppa:kubuntu-ppa/backports

```
* **步骤 2**：然后运行以下程序来启动系统升级。这将在你的 Hirsute Hippo 系统中安装最新的 KDE Plasma 5.22。

```
sudo apt update
sudo apt full-upgrade

```

* **步骤 3**：更新后重新启动，你应该会看到一个更新的 KDE Plasma 5.22 桌面。

考虑到这是整个桌面环境的完整版本升级，安装可能需要一些时间。

### 在 Ubuntu 21.04 中安装 KDE Plasma 5.22

如果你正在运行基于 GNOME 的默认 Ubuntu 21.04 Hirsute Hippo 桌面，你可以使用这个 PPA 来安装最新的 KDE Plasma。下面是方法。

打开终端，添加 PPA（像上面的步骤那样）。

```
sudo add-apt-repository ppa:kubuntu-ppa/backports

```

然后，刷新软件包。

```
sudo apt update

```

然后运行下面的程序来安装 Kubuntu 桌面。

```
sudo apt install kubuntu-desktop

```

这将在 Ubuntu 21.04 中与 GNOME 一起安装 KDE Plasma 桌面。

### Ubuntu 20.04 LTS 中的 KDE Plasma 5.22

Ubuntu 20.04 LTS 版拥有早期的 KDE Plasma 5.18、KDE Framework 5.68、KDE Applications 19.12.3。所以，在它的整个生命周期中，它不会收到最新的 KDE 更新。所以，从技术上讲，你可以添加上述 PPA 并安装 KDE Plasma 5.22。但我不建议这样做，因为不兼容的软件包、框架可能会导致系统不稳定。

所以，建议你使用 Kubuntu 21.04 和上面的向后移植 PPA 或者使用 KDE neon 来体验最新的 Plasma 桌面。

### 卸载 KDE Plasma 5.22

如果你改变主意，想回到 KDE Plasma 的原始版本，那么安装 `ppa-purge` 并清除 PPA。这将使软件包降级，并启用仓库版本。

```
sudo apt install ppa-purge
sudo ppa-purge ppa:kubuntu-ppa/backports
sudo apt update

```

### 结束语

我希望这个快速指南能帮助你在 Kubuntu 21.04 Hirsute Hippo 中安装最新的 KDE Plasma 5.22。这可以让你体验到最新的 KDE 技术以及 KDE 框架和应用。然而，你应该知道，并不是所有的功能都应该在向后移植 PPA 中提供，它只有选定的功能和错误修复，这才能通过回归测试并安全使用。也就是说，你总是可以把 KDE Neon 安装成一个全新的系统来享受 KDE 的最新技术。

---

via: <https://www.debugpoint.com/2021/06/plasma-5-22-kubuntu-21-04/>

作者：[Arindam](https://www.debugpoint.com/author/admin1/) 选题：[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/) 荣誉推出


编程基础：Java 中的输入和输出

Summary: 学习 Java 如何外理数据的读与写。

学习 Java 如何外理数据的读与写。

# 编程基础：Java 中的输入和输出

>
> 学习 Java 如何外理数据的读与写。
>
>
>

<img src="content_image/album_202107_27_101854by7yizpokqyo77kk.jpg" alt="" title="Coffee beans and a cup of coffee">

当你写一个程序时，你的应用程序可能需要读取和写入存储在用户计算机上的文件。这在你想加载或存储配置选项，你需要创建日志文件，或你的用户想要保存工作以待后用的情况下是很常见的。每种语言处理这项任务的方式都有所不同。本文演示了如何用 Java 处理数据文件。

### 安装 Java

不管你的计算机是什么平台，你都可以从 [AdoptOpenJDK](https://adoptopenjdk.net) 安装 Java。这个网站提供安全和开源的 Java 构建。在 Linux 上，你的软件库中也可能找到 AdoptOpenJDK 的构建。

我建议你使用最新的长期支持（LTS）版本。最新的非 LTS 版本对希望尝试最新 Java 功能的开发者来说是最好的，但它很可能超过大多数用户所安装的版本 —— 要么是系统上默认安装的，要么是以前为其他 Java 应用安装的。使用 LTS 版本可以确保你与大多数用户所安装的版本保持一致。

一旦你安装好了 Java，就可以打开你最喜欢的文本编辑器并准备开始写代码了。你可能还想要研究一下 [Java 集成开发环境](https://opensource.com/article/20/7/ide-java)。BlueJ 是新程序员的理想选择，而 Eclipse 和 Netbeans 对中级和有经验的编码者更友好。

### 利用 Java 读取文件

Java 使用 `File` 类来加载文件。

这个例子创建了一个叫 `Ingest` 的类来读取文件中数据。当你要在 Java 中打开一个文件时，你创建了一个 `Scanner` 对象，它可以逐行扫描你提供的文件。事实上，`Scanner` 与文本编辑器中的光标是相同的概念，这样你可以用 `Scanner` 的一些方法（如 `nextLine`）来控制这个“光标”以进行读写。

```
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class Ingest {
  public static void main(String[] args) {

      try {
          File myFile = new File("example.txt");
          Scanner myScanner = new Scanner(myFile);
          while (myScanner.hasNextLine()) {
              String line = myScanner.nextLine();
              System.out.println(line);
          }
          myScanner.close();
      } catch (FileNotFoundException ex) {
          ex.printStackTrace();
      } //try
    } //main
} //class

```

这段代码首先在假设存在一个名为 `example.txt` 的文件的情况下创建了变量 `myfile`。如果该文件不存在，Java 就会“抛出一个异常”（如它所说的，这意味着它在你试图做的事情中发现了一个错误），这个异常是被非常特定的 `FileNotFoundException` 类所“捕获”。事实上，有一个专门的类来处理这个明确的错误，这说明这个错误是多么常见。

接下来，它创建了一个 `Scanner` 并将文件加载到其中。我把它叫做 `myScanner`，以区别于它的通用类模板。接着，一个 `while` 循环将 `myScanner` 逐行送入文件中，只要 *存在* 下一行。这就是 `hasNextLine` 方法的作用：它检测“光标”之后是否还有数据。你可以通过在文本编辑器中打开一个文件来模拟这个过程：你的光标从文件的第一行开始，你可以用键盘控制光标来向下扫描文件，直到你走完了所有的行。

`while` 循环创建了一个变量 `line`，并将文件当前行的数据分配给它。然后将 `line` 的内容打印出来以提供反馈。一个更有用的程序可能会解析每一行的内容，从而提取它所包含的任何重要数据。

在这个过程结束时，关闭 `myScanner` 对象。

### 运行代码

将你的代码保存到 `Ingest.java` 文件（这是一个 Java 惯例，将类名的首字母大写，并以类名来命名相应的文件）。如果你试图运行这个简单的应用程序，你可能会接收到一个错误信息，这是因为还没有 `example.txt` 文件供应用程序加载:

```
$ java ./Ingest.java
java.io.FileNotFoundException:
example.txt (No such file or directory)

```

正好可以编写一个将数据写入文件的 Java 应用程序，多么完美的时机！

### 利用 Java 将数据写入文件

无论你是存储用户使用你的应用程序创建的数据，还是仅仅存储关于用户在应用程序中做了什么的元数据（例如，游戏保存或最近播放的歌曲），有很多很好的理由来存储数据供以后使用。在 Java 中，这是通过 `FileWriter` 类实现的，这次先打开一个文件，向其中写入数据，然后关闭该文件。

```
import java.io.FileWriter;
import java.io.IOException;

public class Exgest {
  public static void main(String[] args) {
    try {
        FileWriter myFileWriter = new FileWriter("example.txt", true);
        myFileWriter.write("Hello world\n");
        myFileWriter.close();
    } catch (IOException ex) {
        System.out.println(ex);
    } // try
  } // main
}

```

这个类的逻辑和流程与读取文件类似。但它不是一个 `Scanner`，而是以一个文件的名字为参数创建的一个 `FileWriter` 对象。`FileWriter` 语句末尾的 `true` 标志告诉 `FileWriter` 将文本 *追加* 到文件的末尾。要覆盖一个文件的内容，请移除 `true` 标志。

```
`FileWriter myFileWriter = new FileWriter("example.txt", true);`

```

因为我在向文件中写入纯文本，所以我在写入文件的数据（`Hello world`）的结尾处手动添加了换行符（`\n`）。

### 试试代码

将这段代码保存到 `Exgest.java` 文件，遵循 Java 的惯例，使文件名为与类名相匹配。

既然你已经掌握了用 Java 创建和读取数据的方法，你可以按相反的顺序尝试运行你的新应用程序。

```
$ java ./Exgest.java
$ java ./Ingest.java
Hello world
$

```

因为程序是把数据追加到文件末尾，所以你可以重复执行你的应用程序以多次写入数据，只要你想把更多的数据添加到你的文件中。

```
$ java ./Exgest.java
$ java ./Exgest.java
$ java ./Exgest.java
$ java ./Ingest.java
Hello world
Hello world
Hello world
$

```

### Java 和数据

你不会经常向文件中写入原始文本；事实上，你可能会使用一个其它的类库以写入特定的格式。例如，你可能使用 XML 类库来写复杂的数据，使用 INI 或 YAML 类库来写配置文件，或者使用各种专门类库来写二进制格式，如图像或音频。

更完整的信息，请参阅 [OpenJDK 文档](https://access.redhat.com/documentation/en-us/openjdk/11/)。

---

via: <https://opensource.com/article/21/3/io-java>

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

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


硬核观察 #345 “不再索取赎金” 项目的免费解密工具节省了 10 亿美元

Summary: 更多：• 谷歌搜索返回的 PHP 教程一半含有 SQL 注入漏洞 • BLAKE3 哈希算法发布，比 SHA 算法更快更安全

# 硬核观察 #345 “不再索取赎金” 项目的免费解密工具节省了 10 亿美元

### “不再索取赎金” 项目的免费解密工具节省了 10 亿美元

“[不再索取赎金](https://www.nomoreransom.org/en/index.html)” 项目提供了 [121 个免费的勒索软件解密工具](https://www.europol.europa.eu/newsroom/news/unhacked-121-tools-against-ransomware-single-website)，可以解密 151 个勒索软件家族。他们已经帮助 600 多万勒索软件受害者免费恢复了他们的加密文件。该网站允许用户上传加密文件，以帮助确定他们成为哪种形式的勒索软件的受害者，然后在有免费解密工具的情况下将他们引向该工具。

它建议，尽管勒索软件攻击造成了破坏，但受害者不应该屈服和支付。这不仅是因为没有理由相信犯罪分子会提供合法的解密密钥，而且支付赎金只是表明勒索软件的作用，鼓励进一步的攻击。

>
> 这是一个非常有意义的措施，而且已经看到了很好的效果。
>
>
>

### 谷歌搜索返回的 PHP 教程一半含有 SQL 注入漏洞

在谷歌上搜索 PHP 编程问题，返回的结果包含了教程、技巧和代码片段，但绝大部分结果包含了有缺陷的数据库语句。据研究，30 个结果中有 16 个含有 [SQL 注入漏洞](https://waritschlager.de/sqlinjections-in-google-results.html)。如果搜索者将这些代码包含在其编写的程序中，那么最后产生的程序将是不安全的。

>
> 可能很多刚刚学习编程的人都有过 “ICP”（互联网复制与粘贴）编程阶段，但是这应该只是一个提示思路的方法，而不是编程方法。
>
>
>

### BLAKE3 哈希算法发布，比 SHA 算法更快更安全

去年宣布的 BLAKE3 是基于其前身 BLAKE2 的加密哈希函数，现在其官方实现发布了 [1.0 版本](https://github.com/BLAKE3-team/BLAKE3/releases/tag/1.0.0)。BLAKE3 比 BLAKE2 快得多，也比 SHA-1/SHA-2/SHA-3 甚至 MD5 等快得多，同时更加安全。它在如今拥有 SIMD 指令集扩展和高核数的 CPU 上是高度可并行的。

>
> 虽然比 SHA 哈希更好，但是得到推广依然需要 SHA 像 MD5 一样逐渐被淘汰才行。
>
>
>


什么是 XML？

# 什么是 XML？

>
> 了解一下 XML 吧，它是一种严格但灵活的标记语言，无论是在文档还是图像方面应用都十分广泛。
>
>
>

XML 是一种分层的标记语言。它使用打开和关闭标签来定义数据，它常用来存储和交换数据，而且由于它极大的灵活性，不论是在 [文档](https://opensource.com/article/17/9/docbook) 还是 [图像](https://opensource.com/article/17/5/coding-scalable-vector-graphics-make-steam) 中都用的非常多。

这里是一个 XML 文档的例子：

```
<xml>
  <os>
   <linux>
    <distribution>
      <name>Fedora</name>
      <release>8</release>
      <codename>Werewolf</codename>
    </distribution>

    <distribution>
      <name>Slackware</name>
      <release>12.1</release>
      <mascot>
        <official>Tux</official>
        <unofficial>Bob Dobbs</unofficial>
      </mascot>
    </distribution>
   </linux>
  </os>
</xml>

```

阅读这个示例 XML，你可能会发现这个 XML 的格式具有直观的特性。 无论你是否熟悉这个文档的主题，你都可能理解本文档中的数据。 这部分原因是因为 XML 被认为是冗长的。 它使用了很多标签，标签可以有很长的描述性名称，并且数据以分层的方式排序，这有助于解释数据之间的关系。 你可能从这个示例中了解到 Fedora 发行版和 Slackware 发行版是两个不同且不相关的 Linux 发行版，因为每个实例都“包含”在自己独立的 `<distribution>` 标签中。

XML 也非常灵活。 与 HTML 不同，它没有预定义的标签列表。 你可以自由创建你需要表示任何数据结构的标签。

### XML 的组成

数据的存在为了读取，当计算机“读取”数据时，该过程称为 *解析*。 再次使用示例 XML 数据，以下是大多数 XML 解析器认为重要的术语。

* **文档**：`<xml>` 标签标记文档的开始， `</xml>` 标签标记文档的结束。
* **节点**：`<os>`、`<distribution>`、`<mascot>` 这些都是节点，在解析术语中，节点是包含其他标签的标签。
* **元素**：像 `<name>Fedora</name>` 和 `<official>Tux</official>` 这些都是元素。从第一个`<`开始，到最后一个 `>` 结束是一个元素。
* **内容**：在两个元素标签之间的数据被称之为内容，在第一个 `<name>` 标签中，`Fedora` 字符串就是一个内容。

### XML 模式

XML 文档中的标签和标签继承性称为 *模式*。

一些模式是随意组成的（例如，本文中的示例 XML 代码纯粹是即兴创作的），而其他模式则由标准组织严格定义。 例如，可缩放矢量图形（SVG）模式 [由 W3C 定义](https://www.w3.org/TR/SVG11/)，而 [DocBook 模式](http://docbook.org) 由 Norman Walsh 定义。

模式强制执行一致性。 最基本的模式通常也是最严格的。 在我的示例 XML 代码中，将发行版名称放在 `<mascot>` 节点中是没有意义的，因为文档的隐含模式清楚地表明 `mascot` 必须是发行版的“子”元素。

### 数据对象模型（DOM）

如果你必须不断地描述标签和位置（例如，“系统部分中的 Linux 部分中第二个发行版标签的名称标签”），那么谈论 XML 会让人感到困惑，因此解析器使用文档对象模型（DOM）的概念来表示 XML 数据。 DOM 将 XML 数据放入一种“家谱”结构中，从根元素（在我的示例 XML 中，即 `os` 标记）开始并包括路径上的每个标记。

这种相同的 XML 数据结构可以表示为路径，就像 Linux 系统中的文件或互联网上网页的位置一样。 例如，`<mascot>` 标签的路径可以表示为 `//os/linux/distribution/slackware/mascot`。

两个 `<distribution>` 标签可以被表示为 `//os/linux/distribution` ，因为这里有两个发行版的节点，因此一个解析器可以直接将两个节点的内容载入到一个数组中，可以进行查询。

### 严格的 XML

XML 也以严格而著称。 这意味着大多数应用程序被设计为在遇到 XML 错误时就会故意失败。 这听起来可能有问题，但这是开发人员最欣赏 XML 的事情之一，因为当应用程序试图猜测如何解决错误时，可能会发生不可预测的事情。 例如，在 HTML 定义明确之前，大多数 Web 浏览器都包含“怪癖模式”，因此当人们试图查看糟糕的 HTML 代码时，Web 浏览器却可以加载作者可能想要的内容。 结果非常难以预测，尤其是当一个浏览器的猜测与另一个浏览器不同时。

XML 通过在出现故意错误时失败而不允许这样做。 这让作者可以修复错误，直到它们生成有效的 XML。 因为 XML 是良好定义的，所以有许多应用程序的验证器插件以及像 `xmllint` 和 `xmlstarlet` 这样的独立命令来帮助你及早定位错误。

### 转换 XML

因为 XML 通常用作数据交换，所以将 XML 转换为其他数据格式或其他 XML 模式是很常见的。 经典示例包括 XSLTProc、xmlto 和 [pandoc](https://opensource.com/article/20/5/pandoc-cheat-sheet)，但从技术上讲，还有许多其他应用程序或者至少程序的一部分就是在转换 XML。

事实上，LibreOffice 使用 XML 来布局其文字处理器和电子表格文档，因此无论何时你导出或 [从 LibreOffice 转换文件](https://opensource.com/article/21/3/libreoffice-command-line)，你都在转换 XML。

[开源 EPUB 格式的电子书](https://opensource.com/education/15/11/ebook-open-formats) 使用 XML，因此无论何时你 [将文档转换为 EPUB](https://opensource.com/life/13/8/how-create-ebook-open-source-way) 或从 EPUB 转换，你都在转换 XML。

Inkscape 是基于矢量的插图应用程序，它将其文件保存在 SVG 中，这是一种专为图形设计的 XML 模式。 任何时候你将 Inkscape 中的图像导出为 PNG 文件时，你都在转换 XML。

名单还可以一直继续下去。 XML 是一种数据存储格式，旨在确保你的数据，无论是画布上的点和线、图表上的节点，还是文档中的文字，都可以轻松准确地提取、更新和转换。

### 学习 XML

编写 XML 很像编写 HTML。 感谢 Jay Nick 的辛勤工作，[在线提供免费且有趣的 XML 课程](https://opensource.com/article/17/5/coding-scalable-vector-graphics-make-steam) 可以教你如何使用 XML 创建图形。

通常，探索 XML 所需的特殊工具很少。 由于 HTML 和 XML 之间的密切关系，你可以 [使用 Web 浏览器查看 XML](https://opensource.com/article/18/12/xml-browser)。 此外，[QXmlEdit](https://opensource.com/article/17/7/7-ways-handle-xml-qxmledit)、[NetBeans](https://opensource.com/article/20/12/netbeans) 和 [Kate](https://opensource.com/article/20/12/kate-text-editor) 等开源文本编辑器通过有用的提示、自动完成、语法验证等，使键入和阅读 XML 变得容易。

### 选择 XML

XML 起初可能看起来有很多数据，但它与 HTML 并没有太大的不同（实际上，HTML 已经 [以 XHTML 的形式重新实现为 XML](https://www.w3.org/TR/xhtml1/)）。 XML 有一个独特的好处，即构成其结构的标签也恰好是元数据，提供有关其存储内容的信息。 精心设计的 XML 模式包含并描述你的数据，使用户能够一目了然并快速解析它，并使开发人员能够使用一些库 [快速解析](https://opensource.com/article/21/6/parsing-config-files-java)。

---

via: <https://opensource.com/article/21/7/what-xml>

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

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


满足日常需求的应用（一）：Web 浏览器

# 满足日常需求的应用（一）：Web 浏览器

满足日常需求的重要应用之一是 Web 浏览器。这是因为上网是大多数人在电脑前进行的一项活动。本文将介绍一些你可以在 Fedora Linux 上使用的开源 Web 浏览器。你需要安装上述软件。本文提到的所有浏览器都已经在官方的 Fedora 软件库中提供。如果你不熟悉如何在 Fedora Linux 中添加软件包，请参阅我之前的文章 [安装 Fedora 34 工作站后要做的事情](https://fedoramagazine.org/things-to-do-after-installing-fedora-34-workstation/)。

### Firefox

<ruby> 火狐 <rt>  Firefox </rt></ruby>是一个快速且注重隐私的浏览器，可以在许多设备上使用。它是由 [Mozilla](https://www.mozilla.org/en-US/) 创建的，是一个具有完整功能的浏览器，提供许多扩展。你可以为你的火狐浏览器添加许多强大的功能和有用的特性。它只使用适量的内存来创造一个流畅的体验，使你的电脑保持对其他任务的响应。你可以创建一个账户，让你在多个设备上共享配置，所以你不需要在每个设备上设置火狐浏览器。

火狐浏览器提供以下功能：

* 隐私浏览模式
* 阻止广告跟踪器
* 密码管理器
* 设备之间的同步
* 画中画

关于火狐浏览器的更多信息可在此链接中找到：[https://www.mozilla.org/en-US/firefox](https://www.mozilla.org/en-US/firefox/)

### GNOME Web

GNOME Web 是 GNOME 桌面（Fedora 工作站的默认桌面环境）的一个浏览器。如果你使用 GNOME 作为默认桌面环境的 Fedora 工作站，它可能非常适合作为你的主浏览器。这个浏览器有一个简单、干净、漂亮的外观。GNOME Web 的功能比 Firefox 少，但对于普通用途来说已经足够了。

GNOME Web 提供了以下功能：

* 隐身模式
* GNOME 桌面集成
* 内置广告拦截器
* 智能跟踪预防

关于 GNOME Web 的更多信息可以在这个链接中找到：<https://wiki.gnome.org/Apps/Web>

### Chromium

Chromium 是一个来自 Chromium 项目的开源 Web 浏览器，它有一个极简的用户界面。它的外观与 Chrome 相似，因为它实际上是作为 Chrome 和其他几个浏览器的基础。许多人使用 Chromium 是因为他们已经习惯了 Chrome。

Chromium 提供以下功能：

* 隐身模式
* 扩展程序
* 密码的自动填写

关于 Chromium 浏览器的更多信息可在此链接中找到：<https://www.chromium.org/Home>

### qutebrowser

这个浏览与上面提到的稍有不同，qutebrowser 是一个以键盘为中心的浏览器，具有精简的 GUI。因此，你不会发现通常在其他浏览器中的按钮，如返回、主页、重新加载等。相反，你可以用键盘输入命令来运行 qutebrowser 中的功能。它使用 Vim 风格的键绑定，所以它适合 Vim 用户。如果你有兴趣在上网时获得不同的体验，你应该试试这个浏览器。

qutebrowser 提供以下功能：

* 广告屏蔽
* 隐私浏览模式
* 快速书签

关于 qutebrowser 浏览器的更多信息可在此链接中找到：<https://qutebrowser.org/>

### 总结

每个人在使用互联网时都有不同的需求，特别是在浏览方面。本文中提到的每个浏览器都有不同的功能。因此，请选择适合你日常需求和喜好的浏览器。如果你使用的是本文中提到的浏览器，请在评论中分享你的故事。如果你使用的是其他的浏览器，请说一下。希望这篇文章能帮助你选择在 Fedora 上满足你日常需求的浏览器。

---

via: <https://fedoramagazine.org/apps-for-daily-needs-part-1-web-browsers/>

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


硬核观察 #346 谷歌宣布新的游戏化漏洞赏金平台

Summary: 更多：• 中国 IPv6 活跃用户数已达网民半数 • 微软新提案让 Chrome 页面加载速度更快

IPv6那个数据感觉有问题

# 硬核观察 #346 谷歌宣布新的游戏化漏洞赏金平台

### 谷歌宣布新的游戏化漏洞赏金平台

谷歌的漏洞奖励计划（VRP）共发现 11055 个漏洞，奖励了 2022 名研究人员，总奖励金额近 3000 万美元，并有近 20 名漏洞猎人加入了谷歌 VRP 团队。为了纪念该计划的 10 周年，他们[宣布](https://security.googleblog.com/2021/07/a-new-chapter-for-googles-vulnerability.html)了一个新的平台：[bughunters.google.com](http://bughunters.google.com/)，这个新网站将谷歌所有的 VRP（谷歌、安卓、滥用、Chrome 和 Play 商店）更紧密地联系在一起。该平台将具有游戏化功能，提供更多互动或竞争的机会。将有每个国家的排行榜，并有机会获得特定错误的奖励或徽章。

>
> 加入游戏化元素后，真成了赏金猎人打怪模式了。
>
>
>

### 中国 IPv6 活跃用户数已达网民半数

网信办在回答记者问时提到：截至 2021 年 5 月，我国 IPv6 地址拥有量达到 59030 块（/32），位居世界第一，我国 IPv6 活跃用户数达 5.28 亿，占互联网网民总数的 53.39%。

按网信办《通知》要求，到 2023 年末，IPv6 活跃用户数达到 7 亿，物联网 IPv6 连接数达到 2 亿。到 2025 年末，IPv6 活跃用户数达到 8 亿，物联网 IPv6 连接数达到 4 亿。之后再用五年左右时间，完成向 IPv6 单栈的演进过渡。

>
> 在 IPv4 地址得不到满足的情况下，转而拥抱 IPv6 反而走在了其它 IPv4 富裕国家前面。
>
>
>

### 微软新提案让 Chrome 页面加载速度更快

在一个新的 Chromium 提案中，微软正通过 chrome://protocol 为获取的脚本开发新的“代码缓存”。在启用之后，能提高 Chrome 在 Windows、Linux、macOS 和其他桌面平台上的页面加载速度。在加载和执行一个脚本后，V8 可以将为该脚本生成的解释器字节码序列化。之后，如果 Blink 告诉 V8 再次运行相同的脚本，并提供以前的序列化字节码，那么 V8 可以跳过最初的解析步骤，脚本运行得更快。这对于页面加载时间来说非常重要。在使用新功能之后，微软已经观察到在新标签页上首次绘制内容的时间减少了 11%-20%。

>
> 自从微软使用 Chromium 作为 Edge 内核之后，Chromium 的改进速度就明显加快了。
>
>
>


在命令行中使用 XMLStarlet 来解析 XML

Summary: 借助终端上的 XML 工具包 XMLStarlet，你就是 XML 之星。

借助终端上的 XML 工具包 XMLStarlet，你就是 XML 之星。

# 在命令行中使用 XMLStarlet 来解析 XML

>
> 借助终端上的 XML 工具包 XMLStarlet，你就是 XML 之星。
>
>
>

<img src="content_image/album_202107_29_091327pgssat1oglrzs73z.jpg" alt="" title="Penguin with green background">

学习解析 XML 通常被认为是一件复杂的事情，但它不一定是这样。[XML 是高度严格结构化的](/article-13624-1.html)，所以也是相对来说可预测的。也有许多其他工具可以帮助你使这项工作易于管理。

我最喜欢的 XML 实用程序之一是 [XMLStarlet](https://en.wikipedia.org/wiki/XMLStarlet)，这是一个用于终端的 XML 工具包，借助这个 XML 工具包，你可以验证、解析、编辑、格式化和转换 XML 数据。XMLStarLet 是个相对较小的命令，但浏览 XML 却充满潜力，因此本文演示了如何使用它来查询 XML 数据。

### 安装

XMLStarLet 默认安装在 CentOS、Fedora，和许多其他现代 Linux 发行版上，所以你可以打开终端，输入 `xmlstarlet` 来访问它。如果 XMLStarLet 还没有被安装，你的操作系统则会为你安装它。

或者，你可以用包管理器安装 `xmlstarlet`：

```
$ sudo dnf install xmlstarlet

```

在 macOS 上，可以使用 [MacPorts](https://opensource.com/article/20/11/macports) 或 [Homebrew](https://opensource.com/article/20/6/homebrew-mac)。在 Windows 上，可以使用 [Chocolatey](https://opensource.com/article/20/3/chocolatey)。

如果都失败了，你可以从 [Sourceforge 上的源代码](http://xmlstar.sourceforge.net) 手动安装它。

### 用 XMLStarlet 解析 XML

有许多工具可以帮助解析和转换 XML 数据，包括允许你 [编写自己的解析器](https://opensource.com/article/21/6/parsing-config-files-java) 的软件库，和复杂的命令，如 `fop` 和 `xsltproc`。不过有时你不需要处理 XML 数据；你只需要一个方便的方法从 XML 数据中来提取、更新或验证重要数据。对于随手的 XML 交互，我使用 `xmlstarlet`，这是常见的处理 XML任务的一个典型的“瑞士军刀”式应用。通过运行 `--help` 命令，你可以看到它提供哪些选项：

```
$ xmlstarlet --help
Usage: xmlstarlet [<options>] <command> [<cmd-options>]
where <command> is one of:
  ed    (or edit)      - Edit/Update XML document(s)
  sel   (or select)    - Select data or query XML document(s) (XPATH, etc)
  tr    (or transform) - Transform XML document(s) using XSLT
  val   (or validate)  - Validate XML document(s) (well-formed/DTD/XSD/RelaxNG)
  fo    (or format)    - Format XML document(s)
  el    (or elements)  - Display element structure of XML document
  c14n  (or canonic)   - XML canonicalization
  ls    (or list)      - List directory as XML
[...]

```

你可以通过在这些子命令的末尾附加 `-help` 来获得进一步的帮助：

```
$ xmlstarlet sel --help
  -Q or --quiet             - do not write anything to standard output.
  -C or --comp              - display generated XSLT
  -R or --root              - print root element <xsl-select>
  -T or --text              - output is text (default is XML)
  -I or --indent            - indent output
[...]

```

#### 用 sel 命令选择数据

可以使用 `xmlstarlet select`（简称 `sel`）命令查看 XML 格式的数据。下面是一个简单的 XML 文档：

```
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
  <os>
   <linux>
    <distribution>
      <name>Fedora</name>
      <release>7</release>
      <codename>Moonshine</codename>
      <spins>
        <name>Live</name>
        <name>Fedora</name>
        <name>Everything</name>
      </spins>
    </distribution>

    <distribution>
      <name>Fedora Core</name>
      <release>6</release>
      <codename>Zod</codename>
      <spins></spins>
    </distribution>
   </linux>
  </os>
</xml>

```

在 XML 文件中查找数据时，你的第一个任务是关注要探索的节点。如果知道节点的路径，请使用 `-value of` 选项指定完整路径。你越早浏览 [文档对象模型](https://opensource.com/article/21/6/what-xml#dom)（DOM）树，就可以看到更多信息：

```
$ xmlstarlet select --template \
  --value-of /xml/os/linux/distribution \
  --nl myfile.xml
      Fedora
      7
      Moonshine

        Live
        Fedora
        Everything

      Fedora Core
      6
      Zod

```

`--nl` 代表“新的一行”，它插入大量的空白，以确保在输入结果后，终端在新的一行显示。我已经删除了样本输出中的一些多余空间。

通过进一步深入 DOM 树来凝聚关注点：

```
$ xmlstarlet select --template \
  --value-of /xml/os/linux/distribution/name \
  --nl myfile.xml
Fedora
Fedora Core

```

#### 条件选择

用于导航和解析 XML 的最强大工具之一被称为 XPath。它规范了 XML 搜索中使用的语法，并从 XML 库调用函数。XMLStarlet 能够解析 XPath 表达式，因此可以使用 XPath 函数来有条件的进行选择。XPath 具有丰富的函数，[由 W3C 提供了详细文档](https://www.w3.org/TR/1999/REC-xpath-19991116)，但我觉得 [Mozilla 的 XPath 文档](https://developer.mozilla.org/en-US/docs/Web/XPath/Functions) 更简洁。

可以使用方括号作为测试函数，将元素的内容与某个值进行比较。下面是对 `<name>` 元素的值的测试，它仅返回与特定匹配相关联的版本号。

想象一下，示例 XML 文件包含以 1 开头的所有 Fedora 版本。要查看与旧名称 “Fedora Core” 关联的所有版本号（该项目从版本 7 开始删除了名称中的 “Core”），请执行以下操作：

```
$ xmlstarlet sel --template \
  --value-of '/xml/os/linux/distribution[name = "Fedora Core"]/release' \
  --nl myfile.xml
6
5
4
3
2
1

```

通过将路径的 `--value-of` 更改为 `/xml/os/linux/distribution[name=“Fedora Core”]/codename`，你便可以查看这些版本的所有代号。

### 匹配路径和获取目标值

将 XML 标记视为节点的一个好处是，一旦找到节点，就可以将其视为当前的数据的“目录”。它不是一个真正的目录，至少不是文件系统意义上的目录，但它是一个可以查询的数据集合。为了帮助你将目标和“里面”的数据分开，XMLStarlet 把你试图用 `--match` 选项匹配的内容和用 `--value-of` 选项匹配的数据值进行了区分。

假设你知道 `<spin>` 节点包含几个元素。这就是你的目标节点。一旦到了这里，就可以使用 `--value-of` 指定想要哪个元素的值。要查看所有元素，可以使用点（`.`）来代表当前位置：

```
$ xmlstarlet sel --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '.' --nl myfile.xml \
Live
Fedora
Everything

```

与浏览 DOM 一样，可以使用 XPath 表达式来限制返回数据的范围。在本例中，我使用 `last()` 函数来检索 `spin` 节点中的最后一个元素：

```
$ xmlstarlet select --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '*[last()]' --nl myfile.xml
Everything

```

在本例中，我使用 `position()` 函数选择 `spin` 节点中的特定元素：

```
$ xmlstarlet select --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '*[position() = 2]' --nl myfile.xml
Fedora

```

`--match` 和 `--value` 选项可以重叠，因此如何将它们一起使用取决于你自己。对于示例 XML，这两个表达式执行的是相同的操作：

```
$ xmlstarlet select  --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '.' \
  --nl myfile.xml
Live
Fedora
Everything

$ xmlstarlet select --template \
  --match '/xml/os/linux/distribution' \
  --value-of 'spin' \
  --nl myfile.xml
Live
Fedora
Everything

```

### 熟悉 XML

XML 有时看起来过于冗长和笨拙，但为与之交互和构建的工具却总是让我吃惊。如果你想要好好使用 XML，那么 XMLStarlet 可能是一个很好的切入点。下次要打开 XML 文件查看其结构化数据时，请尝试使用 XMLStarlet，看看是否可以查询这些数据。当你对 XML 越熟悉时，它就越能作为一种健壮灵活的数据格式而为你服务。

---

via: <https://opensource.com/article/21/7/parse-xml-linux>

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

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