Merge pull request #29 from LCTT/master

更新 20190806
This commit is contained in:
FSSlc 2019-08-06 14:41:55 +08:00 committed by GitHub
commit e199a0fb25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
591 changed files with 65175 additions and 13643 deletions

View File

@ -0,0 +1,138 @@
系统管理员入门:排除故障
======
![](https://img.linux.net.cn/data/attachment/album/201908/06/100659pox8xkkr8zek888r.jpg)
我通常会严格保持此博客的技术性,将观察、意见等内容保持在最低限度。但是,这篇和接下来的几篇文章将介绍刚进入系统管理/SRE/系统工程师/sysops/devops-ops无论你想称自己是什么角色的常见的基础知识。
请跟我来!
> “我的网站很慢!”
我只是随机选择了本文的问题类型,这也可以应用于任何与系统管理员相关的故障排除。我并不是要炫耀那些可以发现最多的信息的最聪明的“金句”。它也不是一个详尽的、一步步指导的、并在最后一个方框中导向“利润”一词的“流程图”。
我会通过一些例子展示常规的方法。
示例场景仅用于说明本文目的。它们有时会做一些不适用于所有情况的假设,而且肯定会有很多读者在某些时候说“哦,但我觉得你会发现……”。
但那可能会让我们错失重点。
十多年来,我一直在从事于支持工作,或在支持机构工作,有一件事让我一次又一次地感到震惊,这促使我写下了这篇文章。
**有许多技术人员在遇到问题时的本能反应,就是不管三七二十一去尝试可能的解决方案。**
*“我的网站很慢,所以”,*
* 我将尝试增大 `MaxClients`/`MaxRequestWorkers`/`worker_connections`
* 我将尝试提升 `innodb_buffer_pool_size`/`effective_cache_size`
* 我打算尝试启用 `mod_gzip`(遗憾的是,这是真实的故事)
*“我曾经看过这个问题,它是因为某种原因造成的 —— 所以我估计还是这个原因,它应该能解决这个问题。”*
这浪费了很多时间,并会让你在黑暗中盲目乱撞,胡乱鼓捣。
你的 InnoDB 的缓冲池也许达到 100 的利用率,但这可能只是因为有人运行了一段时间的一次性大型报告导致的。如果没有排除这种情况,那你就是在浪费时间。
### 开始之前
在这里,我应该说明一下,虽然这些建议同样适用于许多角色,但我是从一般的支持系统管理员的角度来撰写的。在一个成熟的内部组织中,或与规模较大的、规范管理的或“企业级”客户合作时,你通常会对一切都进行检测、测量、绘制、整理(甚至不是文字),并发出警报。那么你的方法也往往会有所不同。让我们在这里先忽略这种情况。
如果你没有这种东西,那就随意了。
### 澄清问题
首先确定实际上是什么问题。“慢”可以是多种形式的。是收到第一个字节的时间吗?从糟糕的 Javascript 加载和每页加载要拉取 15 MB 的静态内容,这是一个完全不同类型的问题。是慢,还是比通常慢?这是两个非常不同的解决方案!
在你着手做某事之前,确保你知道实际报告和遇到的问题。找到问题的根源通常很困难,但即便找不到也必须找到问题本身。
否则,这相当于系统管理员带着一把刀去参加枪战。
### 唾手可得
首次登录可疑服务器时,你可以查找一些常见的嫌疑对象。事实上,你应该这样做!每当我登录到服务器时,我都会发出一些命令来快速检查一些事情:我们是否发生了页交换(`free` / `vmstat`),磁盘是否繁忙(`top` / `iostat` / `iotop`),是否有丢包(`netstat` / `proc` / `net` / `dev`),是否处于连接数过多的状态(`netstat`),有什么东西占用了 CPU`top`),谁在这个服务器上(`w` / `who`syslog 和 `dmesg` 中是否有引人注目的消息?
如果你从 RAID 控制器得到 2000 条抱怨直写式缓存没有生效的消息,那么继续进行是没有意义的。
这用不了半分钟。如果什么都没有引起你的注意 —— 那么继续。
### 重现问题
如果某处确实存在问题,并且找不到唾手可得的信息。
那么采取所有步骤来尝试重现问题。当你可以重现该问题时,你就可以观察它。**当你能观察到时,你就可以解决。**如果在第一步中尚未显现出或覆盖了问题所在,询问报告问题的人需要采取哪些确切步骤来重现问题。
对于由太阳耀斑或只能运行在 OS/2 上的客户端引起的问题,重现并不总是可行的。但你的第一个停靠港应该是至少尝试一下!在一开始,你所知道的是“某人认为他们的网站很慢”。对于那些人,他们可能还在用他们的 GPRS 手机,也可能正在安装 Windows 更新。你在这里挖掘得再深也是浪费时间。
尝试重现!
### 检查日志
我对于有必要包括这一点感到很难过。但是我曾经看到有人在运行 `tail /var/log/...` 之后几分钟就不看了。大多数 *NIX 工具都特别喜欢记录日志。任何明显的错误都会在大多数应用程序日志中显得非常突出。检查一下。
### 缩小范围
如果没有明显的问题,但你可以重现所报告的问题,那也很棒。所以,你现在知道网站是慢的。现在你已经把范围缩小到:浏览器的渲染/错误、应用程序代码、DNS 基础设施、路由器、防火墙、网卡所有的、以太网电缆、负载均衡器、数据库、缓存层、会话存储、Web 服务器软件、应用程序服务器、内存、CPU、RAID 卡、磁盘等等。
根据设置添加一些其他可能的罪魁祸首。它们也可能是 SAN也不要忘记硬件 WAF以及…… 你明白我的意思。
如果问题是接收到第一个字节的时间,你当然会开始对 Web 服务器去应用上已知的修复程序,就是它响应缓慢,你也觉得几乎就是它,对吧?但是你错了!
你要回去尝试重现这个问题。只是这一次,你要试图消除尽可能多的潜在问题来源。
你可以非常轻松地消除绝大多数可能的罪魁祸首:你能从服务器本地重现问题吗?恭喜,你刚刚节省了自己必须尝试修复 BGP 路由的时间。
如果不能,请尝试使用同一网络上的其他计算机。如果可以的话,至少你可以将防火墙移到你的嫌疑人名单上,(但是要注意一下那个交换机!)
是所有的连接都很慢吗?虽然服务器是 Web 服务器,但并不意味着你不应该尝试使用其他类型的服务进行重现问题。[netcat][1] 在这些场景中非常有用(但是你的 SSH 连接可能会一直有延迟,这可以作为线索)! 如果这也很慢,你至少知道你很可能遇到了网络问题,可以忽略掉整个 Web 软件及其所有组件的问题。用这个知识(我不收 200 美元)再次从顶部开始,按你的方式由内到外地进行!
即使你可以在本地复现 —— 仍然有很多“因素”留下。让我们排除一些变量。你能用普通文件重现它吗? 如果 `i_am_a_1kb_file.html` 很慢,你就知道它不是数据库、缓存层或 OS 以外的任何东西和 Web 服务器本身的问题。
你能用一个需要解释或执行的 `hello_world.(py|php|js|rb..)` 文件重现问题吗?如果可以的话,你已经大大缩小了范围,你可以专注于少数事情。如果 `hello_world` 可以马上工作,你仍然学到了很多东西!你知道了没有任何明显的资源限制、任何满的队列或在任何地方卡住的 IPC 调用,所以这是应用程序正在做的事情或它正在与之通信的事情。
所有页面都慢吗?或者只是从第三方加载“实时分数数据”的页面慢?
**这可以归结为:你仍然可以重现这个问题所涉及的最少量的“因素”是什么?**
我们的示例是一个缓慢的网站,但这同样适用于几乎所有问题。邮件投递?你能在本地投递吗?能发给自己吗?能发给<常见的服务提供者>吗?使用小的、纯文本的消息进行测试。尝试直到遇到 2MB 拥堵时。使用 STARTTLS 和不使用 STARTTLS 呢?按你的方式由内到外地进行!
这些步骤中的每一步都只需要几秒钟,远远快于实施大多数“可能的”修复方案。
### 隔离观察
到目前为止,当你去除特定组件时无法重现问题时,你可能已经偶然发现了问题所在。
但如果你还没有,或者你仍然不知道**为什么**:一旦你找到了一种方法来重现问题,你和问题之间的“东西”(某个技术术语)最少,那么就该开始隔离和观察了。
请记住,许多服务可以在前台运行和/或启用调试。对于某些类别的问题,执行此操作通常非常有帮助。
这也是你的传统武器库发挥作用的地方。`strace`、`lsof`、`netstat`、`GDB`、`iotop`、`valgrind`、语言分析器cProfile、xdebug、ruby-prof ……)那些类型的工具。
一旦你走到这一步,你就很少能摆脱剖析器或调试器了。
[strace][2] 通常是一个非常好的起点。
你可能会注意到应用程序停留在某个连接到端口 3306 的套接字文件描述符上的特定 `read()` 调用上。你会知道该怎么做。
转到 MySQL 并再次从顶部开始。显而易见:“等待某某锁”、死锁、`max_connections` ……进而:是所有查询?还是只写请求?只有某些表?还是只有某些存储引擎?等等……
你可能会注意到调用外部 API 资源的 `connect()` 需要五秒钟才能完成,甚至超时。你会知道该怎么做。
你可能会注意到,在同一对文件中有 1000 个调用 `fstat()``open()` 作为循环依赖的一部分。你会知道该怎么做。
它可能不是那些特别的东西,但我保证,你会发现一些东西。
如果你只是从这一部分学到一点,那也不错;学习使用 `strace` 吧!**真的**学习它,阅读整个手册页。甚至不要跳过历史部分。`man` 每个你还不知道它做了什么的系统调用。98 的故障排除会话以 `strace` 而终结。
---------------------------------------------------------------------
via: http://northernmost.org/blog/troubleshooting-101/index.html
作者:[Erik Ljungstrom][a]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://northernmost.org
[1]:http://nc110.sourceforge.net/
[2]:https://linux.die.net/man/1/strace

View File

@ -0,0 +1,106 @@
Logreduce用 Python 和机器学习去除日志噪音
======
> Logreduce 可以通过从大量日志数据中挑选出异常来节省调试时间。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/sound-radio-noise-communication.png?itok=KMNn9QrZ)
持续集成CI作业会生成大量数据。当一个作业失败时弄清楚出了什么问题可能是一个繁琐的过程它涉及到调查日志以发现根本原因 —— 这通常只能在全部的作业输出的一小部分中找到。为了更容易地将最相关的数据与其余数据分开,可以使用先前成功运行的作业结果来训练 [Logreduce][1] 机器学习模型,以从失败的运行日志中提取异常。
此方法也可以应用于其他用例,例如,从 [Journald][2] 或其他系统级的常规日志文件中提取异常。
### 使用机器学习来降低噪音
典型的日志文件包含许多标称事件(“基线”)以及与开发人员相关的一些例外事件。基线可能包含随机元素,例如难以检测和删除的时间戳或唯一标识符。要删除基线事件,我们可以使用 [k-最近邻模式识别算法][3]k-NN
![](https://opensource.com/sites/default/files/uploads/ml-generic-workflow.png)
日志事件必须转换为可用于 k-NN 回归的数值。使用通用特征提取工具 [HashingVectorizer][4] 可以将该过程应用于任何类型的日志。它散列每个单词并在稀疏矩阵中对每个事件进行编码。为了进一步减少搜索空间,这个标记化过程删除了已知的随机单词,例如日期或 IP 地址。
![](https://opensource.com/sites/default/files/uploads/hashing-vectorizer.png)
训练模型后k-NN 搜索可以告诉我们每个新事件与基线的距离。
![](https://opensource.com/sites/default/files/uploads/kneighbors.png)
这个 [Jupyter 笔记本][5] 演示了该稀疏矩阵向量的处理和图形。
![](https://opensource.com/sites/default/files/uploads/anomaly-detection-with-scikit-learn.png)
### Logreduce 介绍
Logreduce Python 软件透明地实现了这个过程。Logreduce 的最初目标是使用构建数据库来协助分析 [Zuul CI][6] 作业的失败问题,现在它已集成到 [Software Factory 开发车间][7]的作业日志处理中。
最简单的是Logreduce 会比较文件或目录并删除相似的行。Logreduce 为每个源文件构建模型,并使用以下语法输出距离高于定义阈值的任何目标行:`distance | filename:line-number: line-content`。
```
$ logreduce diff /var/log/audit/audit.log.1 /var/log/audit/audit.log
INFO  logreduce.Classifier - Training took 21.982s at 0.364MB/s (1.314kl/s) (8.000 MB - 28.884 kilo-lines)
0.244 | audit.log:19963:        type=USER_AUTH acct="root" exe="/usr/bin/su" hostname=managesf.sftests.com
INFO  logreduce.Classifier - Testing took 18.297s at 0.306MB/s (1.094kl/s) (5.607 MB - 20.015 kilo-lines)
99.99% reduction (from 20015 lines to 1
```
更高级的 Logreduce 用法可以离线训练模型以便重复使用。可以使用基线的许多变体来拟合 k-NN 搜索树。
```
$ logreduce dir-train audit.clf /var/log/audit/audit.log.*
INFO  logreduce.Classifier - Training took 80.883s at 0.396MB/s (1.397kl/s) (32.001 MB - 112.977 kilo-lines)
DEBUG logreduce.Classifier - audit.clf: written
$ logreduce dir-run audit.clf /var/log/audit/audit.log
```
Logreduce 还实现了接口,以发现 Journald 时间范围(天/周/月)和 Zuul CI 作业构建历史的基线。它还可以生成 HTML 报告,该报告在一个简单的界面中将在多个文件中发现的异常进行分组。
![](https://opensource.com/sites/default/files/uploads/html-report.png)
### 管理基线
使用 k-NN 回归进行异常检测的关键是拥有一个已知良好基线的数据库,该模型使用数据库来检测偏离太远的日志行。此方法依赖于包含所有标称事件的基线,因为基线中未找到的任何内容都将报告为异常。
CI 作业是 k-NN 回归的重要目标,因为作业的输出通常是确定性的,之前的运行结果可以自动用作基线。 Logreduce 具有 Zuul 作业角色,可以将其用作失败的作业发布任务的一部分,以便发布简明报告(而不是完整作业的日志)。只要可以提前构建基线,该原则就可以应用于其他情况。例如,标称系统的 [SoS 报告][8] 可用于查找缺陷部署中的问题。
![](https://opensource.com/sites/default/files/uploads/baselines.png)
### 异常分类服务
下一版本的 Logreduce 引入了一种服务器模式,可以将日志处理卸载到外部服务,在外部服务中可以进一步分析该报告。它还支持导入现有报告和请求以分析 Zuul 构建。这些服务以异步方式运行分析,并具有 Web 界面以调整分数并消除误报。
![](https://opensource.com/sites/default/files/uploads/classification-interface.png)
已审核的报告可以作为独立数据集存档,其中包含目标日志文件和记录在一个普通的 JSON 文件中的异常行的分数。
### 项目路线图
Logreduce 已经能有效使用,但是有很多机会来改进该工具。未来的计划包括:
* 策划在日志文件中发现的许多带注释的异常,并生成一个公共域数据集以进行进一步研究。日志文件中的异常检测是一个具有挑战性的主题,并且有一个用于测试新模型的通用数据集将有助于识别新的解决方案。
* 重复使用带注释的异常模型来优化所报告的距离。例如,当用户通过将距离设置为零来将日志行标记为误报时,模型可能会降低未来报告中这些日志行的得分。
* 对存档异常取指纹特征以检测新报告何时包含已知的异常。因此,该服务可以通知用户该作业遇到已知问题,而不是报告异常的内容。解决问题后,该服务可以自动重新启动该作业。
* 支持更多基准发现接口,用于 SOS 报告、Jenkins 构建、Travis CI 等目标。
如果你有兴趣参与此项目,请通过 log-classify Freenode IRC 频道与我们联系。欢迎反馈!
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/quiet-log-noise-python-and-machine-learning
作者:[Tristan de Cacqueray][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/tristanc
[1]: https://pypi.org/project/logreduce/
[2]: http://man7.org/linux/man-pages/man8/systemd-journald.service.8.html
[3]: https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm
[4]: http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.HashingVectorizer.html
[5]: https://github.com/TristanCacqueray/anomaly-detection-workshop-opendev/blob/master/datasets/notebook/anomaly-detection-with-scikit-learn.ipynb
[6]: https://zuul-ci.org
[7]: https://www.softwarefactory-project.io
[8]: https://sos.readthedocs.io/en/latest/
[9]: https://www.openstack.org/summit/berlin-2018/summit-schedule/speakers/4307
[10]: https://www.openstack.org/summit/berlin-2018/

View File

@ -0,0 +1,235 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11175-1.html)
[#]: subject: (How to Install MongoDB on Ubuntu)
[#]: via: (https://itsfoss.com/install-mongodb-ubuntu)
[#]: author: (Sergiu https://itsfoss.com/author/sergiu/)
如何在 Ubuntu 上安装 MongoDB
======
> 本教程介绍了在 Ubuntu 和基于 Ubuntu 的 Linux 发行版上安装 MongoDB 的两种方法。
[MongoDB][1] 是一个越来越流行的自由开源的 NoSQL 数据库,它将数据存储在类似 JSON 的灵活文档集中,这与 SQL 数据库中常见的表格形式形成对比。
你很可能发现在现代 Web 应用中使用 MongoDB。它的文档模型使得使用各种编程语言能非常直观地访问和处理它。
![mongodb Ubuntu][2]
在本文中,我将介绍两种在 Ubuntu 上安装 MongoDB 的方法。
### 在基于 Ubuntu 的发行版上安装 MongoDB
1. 使用 Ubuntu 仓库安装 MongoDB。简单但不是最新版本的 MongoDB
2. 使用其官方仓库安装 MongoDB。稍微复杂但你能得到最新版本的 MongoDB。
第一种安装方法更容易,但如果你计划使用官方支持的最新版本,那么我建议使用第二种方法。
有些人可能更喜欢使用 snap 包。Ubuntu 软件中心提供了 snap但我不建议使用它们因为他们现在已经过期了因此我这里不会提到。
### 方法 1从 Ubuntu 仓库安装 MongoDB
这是在系统中安装 MongoDB 的简便方法,你只需输入一个命令即可。
#### 安装 MongoDB
首先,确保你的包是最新的。打开终端并输入:
```
sudo apt update && sudo apt upgrade -y
```
继续安装 MongoDB
```
sudo apt install mongodb
```
这就完成了MongoDB 现在安装到你的计算机上了。
MongoDB 服务应该在安装时自动启动,但要检查服务状态:
```
sudo systemctl status mongodb
```
![Check if the MongoDB service is running.][3]
你可以看到该服务是**活动**的。
#### 运行 MongoDB
MongoDB 目前是一个 systemd 服务,因此我们使用 `systemctl` 来检查和修改它的状态,使用以下命令:
```
sudo systemctl status mongodb
sudo systemctl stop mongodb
sudo systemctl start mongodb
sudo systemctl restart mongodb
```
你也可以修改 MongoDB 是否自动随系统启动(默认:启用):
```
sudo systemctl disable mongodb
sudo systemctl enable mongodb
```
要开始使用(创建和编辑)数据库,请输入:
```
mongo
```
这将启动 **mongo shell**。有关查询和选项的详细信息,请查看[手册][4]。
**注意:**根据你计划使用 MongoDB 的方式,你可能需要调整防火墙。不过这超出了本篇的内容,并且取决于你的配置。
#### 卸载 MongoDB
如果你从 Ubuntu 仓库安装 MongoDB 并想要卸载它(可能要使用官方支持的方式安装),请输入:
```
sudo systemctl stop mongodb
sudo apt purge mongodb
sudo apt autoremove
```
这应该会完全卸载 MongoDB。确保**备份**你可能想要保留的任何集合或文档,因为它们将被删除!
### 方法 2在 Ubuntu 上安装 MongoDB 社区版
这是推荐的安装 MongoDB 的方法,它使用包管理器。你需要多打几条命令,对于 Linux 新手而言,这可能会感到害怕。
但没有什么可怕的!我们将一步步说明安装过程。
#### 安装 MongoDB
由 MongoDB Inc. 维护的包称为 `mongodb-org`,而不是 `mongodb`(这是 Ubuntu 仓库中包的名称)。在开始之前,请确保系统上未安装 `mongodb`。因为包之间会发生冲突。让我们开始吧!
首先,我们必须导入公钥:
```
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
```
现在,你需要在源列表中添加一个新的仓库,以便你可以安装 MongoDB 社区版并获得自动更新:
```
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
```
要安装 `mongodb-org`,我们需要更新我们的包数据库,以便系统知道可用的新包:
```
sudo apt update
```
现在你可以安装**最新稳定版**的 MongoDB
```
sudo apt install -y mongodb-org
```
或者某个**特定版本**(在 `=` 后面修改版本号)
```
sudo apt install -y mongodb-org=4.0.6 mongodb-org-server=4.0.6 mongodb-org-shell=4.0.6 mongodb-org-mongos=4.0.6 mongodb-org-tools=4.0.6
```
如果你选择安装特定版本,请确保在所有位置都修改了版本号。如果你修改了 `mongodb-org=4.0.6`,你将安装最新版本。
默认情况下,使用包管理器(`apt-get`更新时MongoDB 将更新为最新的版本。要阻止这种情况发生(并冻结为已安装的版本),请使用:
```
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
```
你现在已经成功安装了 MongoDB
#### 配置 MongoDB
默认情况下,包管理器将创建 `/var/lib/mongodb``/var/log/mongodb`MongoDB 将使用 `mongodb` 用户帐户运行。
我不会去更改这些默认设置,因为这超出了本指南的范围。有关详细信息,请查看[手册][5]。
`/etc/mongod.conf` 中的设置在启动/重新启动 **mongodb** 服务实例时生效。
##### 运行 MongoDB
要启动 mongodb 的守护进程 `mongod`,请输入:
```
sudo service mongod start
```
现在你应该验证 `mongod` 进程是否已成功启动。此信息(默认情况下)保存在 `/var/log/mongodb/mongod.log` 中。我们来看看文件的内容:
```
sudo cat /var/log/mongodb/mongod.log
```
![Check MongoDB logs to see if the process is running properly.][6]
只要你在某处看到:`[initandlisten] waiting for connections on port 27017`,就说明进程正常运行。
**注意**27017 是 `mongod` 的默认端口。
要停止/重启 `mongod`,请输入:
```
sudo service mongod stop
sudo service mongod restart
```
现在,你可以通过打开 **mongo shell** 来使用 MongoDB
```
mongo
```
#### 卸载 MongoDB
运行以下命令:
```
sudo service mongod stop
sudo apt purge mongodb-org*
```
要删除**数据库**和**日志文件**(确保**备份**你要保留的内容!):
```
sudo rm -r /var/log/mongodb
sudo rm -r /var/lib/mongodb
```
### 总结
MongoDB 是一个很棒的 NoSQL 数据库,它易于集成到现代项目中。我希望本教程能帮助你在 Ubuntu 上安装它!在下面的评论中告诉我们你计划如何使用 MongoDB。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-mongodb-ubuntu
作者:[Sergiu][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/sergiu/
[b]: https://github.com/lujun9972
[1]: https://www.mongodb.com/
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/mongodb-ubuntu.jpeg?resize=800%2C450&ssl=1
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/02/mongodb_check_status.jpg?fit=800%2C574&ssl=1
[4]: https://docs.mongodb.com/manual/tutorial/getting-started/
[5]: https://docs.mongodb.com/manual/
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/02/mongodb_org_check_logs.jpg?fit=800%2C467&ssl=1

View File

@ -0,0 +1,229 @@
ddgr一个从终端搜索 DuckDuckGo 的命令行工具
======
在 Linux 中Bash 技巧非常棒,它使 Linux 中的一切成为可能。
对于开发人员或系统管理员来说,它真的很管用,因为他们大部分时间都在使用终端。你知道他们为什么喜欢这种技巧吗?
因为这些技巧可以提高他们的工作效率,也能使他们工作更快。
### 什么是 ddgr
[ddgr][1] 是一个命令行实用程序,用于从终端搜索 DuckDuckGo。如果设置了 `BROWSER` 环境变量ddgr 可以在几个基于文本的浏览器中开箱即用。
确保你的系统安装了任何一个基于文本的浏览器。你可能知道 [googler][2],它允许用户从 Linux 命令行进行 Google 搜索。
它在命令行用户中非常受欢迎,他们期望对隐私敏感的 DuckDuckGo 也有类似的实用程序,这就是 `ddgr` 出现的原因。
与 Web 界面不同,你可以指定每页要查看的搜索结果数。
**建议阅读:**
- [Googler 从 Linux 命令行搜索 Google][2]
- [Buku Linux 中一个强大的命令行书签管理器][3]
- [SoCLI 从终端搜索和浏览 StackOverflow 的简单方法][4]
- [RTVReddit 终端查看器)- 一个简单的 Reddit 终端查看器][5]
### 什么是 DuckDuckGo
DDG 即 DuckDuckGo。DuckDuckGoDDG是一个真正保护用户搜索和隐私的互联网搜索引擎。它没有过滤用户的个性化搜索结果对于给定的搜索词它会向所有用户显示相同的搜索结果。
大多数用户更喜欢谷歌搜索引擎,但是如果你真的担心隐私,那么你可以放心地使用 DuckDuckGo。
### ddgr 特性
* 快速且干净(没有广告、多余的 URL 或杂物参数),自定义颜色
* 旨在以最小的空间提供最高的可读性
* 指定每页显示的搜索结果数
* 可以在 omniprompt 中导航结果,在浏览器中打开 URL
* 用于 Bash、Zsh 和 Fish 的搜索和选项补完脚本
* 支持 DuckDuckGo Bang带有自动补完
* 直接在浏览器中打开第一个结果(如同 “Im Feeling Ducky”
* 不间断搜索:无需退出即可在 omniprompt 中触发新搜索
* 关键字支持例如filetype:mime、site:somesite.com
* 按时间、指定区域搜索,禁用安全搜索
* 支持 HTTPS 代理,支持 Do Not Track可选择禁用用户代理字符串
* 支持自定义 URL 处理程序脚本或命令行实用程序
* 全面的文档man 页面有方便的使用示例
* 最小的依赖关系
### 需要条件
`ddgr` 需要 Python 3.4 或更高版本。因此,确保你的系统应具有 Python 3.4 或更高版本。
```
$ python3 --version
Python 3.6.3
```
### 如何在 Linux 中安装 ddgr
我们可以根据发行版使用以下命令轻松安装 `ddgr`
对于 Fedora ,使用 [DNF 命令][6]来安装 `ddgr`
```
# dnf install ddgr
```
或者我们可以使用 [SNAP 命令][7]来安装 `ddgr`
```
# snap install ddgr
```
对于 LinuxMint/Ubuntu使用 [APT-GET 命令][8] 或 [APT 命令][9]来安装 `ddgr`
```
$ sudo add-apt-repository ppa:twodopeshaggy/jarun
$ sudo apt-get update
$ sudo apt-get install ddgr
```
对于基于 Arch Linux 的系统,使用 [Yaourt 命令][10]或 [Packer 命令][11]从 AUR 仓库安装 `ddgr`
```
$ yaourt -S ddgr
$ packer -S ddgr
```
对于 Debian使用 [DPKG 命令][12] 安装 `ddgr`
```
# wget https://github.com/jarun/ddgr/releases/download/v1.2/ddgr_1.2-1_debian9.amd64.deb
# dpkg -i ddgr_1.2-1_debian9.amd64.deb
```
对于 CentOS 7使用 [YUM 命令][13]来安装 `ddgr`
```
# yum install https://github.com/jarun/ddgr/releases/download/v1.2/ddgr-1.2-1.el7.3.centos.x86_64.rpm
```
对于 opensuse使用 [zypper 命令][14]来安装 `ddgr`
```
# zypper install https://github.com/jarun/ddgr/releases/download/v1.2/ddgr-1.2-1.opensuse42.3.x86_64.rpm
```
### 如何启动 ddgr
在终端上输入 `ddgr` 命令,不带任何选项来进行 DuckDuckGo 搜索。你将获得类似于下面的输出。
```
$ ddgr
```
![][16]
### 如何使用 ddgr 进行搜索
我们可以通过两种方式启动搜索。从 omniprompt 或者直接从终端开始。你可以搜索任何你想要的短语。
直接从终端:
```
$ ddgr 2daygeek
```
![][17]
从 omniprompt
![][18]
### Omniprompt 快捷方式
输入 `?` 以获得 omniprompt它将显示关键字列表和进一步使用 `ddgr` 的快捷方式。
![][19]
### 如何移动下一页、上一页和第一页
它允许用户移动下一页、上一页或第一页。
* `n` 移动到下一组搜索结果
* `p` 移动到上一组搜索结果
* `f` 跳转到第一页
![][20]
### 如何启动新搜索
`d` 选项允许用户从 omniprompt 发起新的搜索。例如,我搜索了 “2daygeek website”现在我将搜索 “Magesh Maruthamuthu” 这个新短语。
从 omniprompt
```
ddgr (? for help) d magesh maruthmuthu
```
![][21]
### 在搜索结果中显示完整的 URL
默认情况下,它仅显示文章标题,在搜索中添加 `x` 选项以在搜索结果中显示完整的文章网址。
```
$ ddgr -n 5 -x 2daygeek
```
![][22]
### 限制搜索结果
默认情况下,搜索结果每页显示 10 个结果。如果你想为方便起见限制页面结果,可以使用 `ddgr` 带有 `--num`` -n` 参数。
```
$ ddgr -n 5 2daygeek
```
![][23]
### 网站特定搜索
要搜索特定网站的特定页面,使用以下格式。这将从网站获取给定关键字的结果。例如,我们在 2daygeek 网站下搜索 “Package Manager”查看结果。
```
$ ddgr -n 5 --site 2daygeek "package manager"
```
![][24]
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/ddgr-duckduckgo-search-from-the-command-line-in-linux/
作者:[Magesh Maruthamuthu][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
选题:[lujun9972](https://github.com/lujun9972)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/magesh/
[1]:https://github.com/jarun/ddgr
[2]:https://www.2daygeek.com/googler-google-search-from-the-command-line-on-linux/
[3]:https://www.2daygeek.com/buku-command-line-bookmark-manager-linux/
[4]:https://www.2daygeek.com/socli-search-and-browse-stack-overflow-from-linux-terminal/
[5]:https://www.2daygeek.com/rtv-reddit-terminal-viewer-a-simple-terminal-viewer-for-reddit/
[6]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
[7]:https://www.2daygeek.com/snap-command-examples/
[8]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
[9]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
[10]:https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/
[11]:https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/
[12]:https://www.2daygeek.com/dpkg-command-to-manage-packages-on-debian-ubuntu-linux-mint-systems/
[13]:https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
[14]:https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
[15]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[16]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux1.png
[17]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-3.png
[18]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-2.png
[19]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-4.png
[20]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-5a.png
[21]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-6a.png
[22]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-7a.png
[23]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-8.png
[24]:https://www.2daygeek.com/wp-content/uploads/2018/03/ddgr-duckduckgo-command-line-search-for-linux-9a.png

View File

@ -0,0 +1,155 @@
PHP PDO 简单教程
======
![](http://www.theitstuff.com/wp-content/uploads/2018/04/php-language.jpg)
大约 80% 的 Web 应用程序由 PHP 提供支持。类似地SQL 也是如此。PHP 5.5 版本之前,我们有用于访问 MySQL 数据库的 mysql_ 命令,但由于安全性不足,它们最终被弃用。
弃用这件事是发生在 2013 年的 PHP 5.5 上,我写这篇文章的时间是 2018 年PHP 版本为 7.2。mysql_ 的弃用带来了访问数据库的两种主要方法mysqli 和 PDO 库。
虽然 mysqli 库是官方指定的,但由于 mysqli 只能支持 mysql 数据库,而 PDO 可以支持 12 种不同类型的数据库驱动程序,因此 PDO 获得了更多的赞誉。此外PDO 还有其它一些特性,使其成为大多数开发人员的更好选择。你可以在下表中看到一些特性比较:
| | PDO | MySQLi
---|---|---
| 数据库支持 | 12 种驱动 | 只有 MySQL
| 范例 | OOP | 过程 + OOP
| 预处理语句(客户端侧) | Yes | No
| 1命名参数 | Yes | No
现在我想对于大多数开发人员来说PDO 是首选的原因已经很清楚了。所以让我们深入研究它,并希望在本文中尽量涵盖关于 PDO 你需要的了解的。
### 连接
第一步是连接到数据库,由于 PDO 是完全面向对象的,所以我们将使用 PDO 类的实例。
我们要做的第一件事是定义主机、数据库名称、用户名、密码和数据库字符集。
```
$host = 'localhost';
$db = 'theitstuff';
$user = 'root';
$pass = 'root';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$conn = new PDO($dsn, $user, $pass);
```
之后,正如你在上面的代码中看到的,我们创建了 DSN 变量DSN 变量只是一个保存数据库信息的变量。对于一些在外部服务器上运行 MySQL 的人,你还可以通过提供一个 `port=$port_number` 来调整端口号。
最后,你可以创建一个 PDO 类的实例,我使用了 `$conn` 变量,并提供了 `$dsn`、`$user`、`$pass` 参数。如果你遵循这些步骤,你现在应该有一个名为 `$conn` 的对象,它是 PDO 连接类的一个实例。现在是时候进入数据库并运行一些查询。
### 一个简单的 SQL 查询
现在让我们运行一个简单的 SQL 查询。
```
$tis = $conn->query('SELECT name, age FROM students');
while ($row = $tis->fetch())
{
echo $row['name']."\t";
echo $row['age'];
echo "<br>";
}
```
这是使用 PDO 运行查询的最简单形式。我们首先创建了一个名为 `tis`TheITStuff 的缩写 )的变量,然后你可以看到我们使用了创建的 `$conn` 对象中的查询函数。
然后我们运行一个 `while` 循环并创建了一个 `$row` 变量来从 `$tis` 对象中获取内容,最后通过调用列名来显示每一行。
很简单,不是吗?现在让我们来看看预处理语句。
### 预处理语句
预处理语句是人们开始使用 PDO 的主要原因之一,因为它提供了可以阻止 SQL 注入的语句。
有两种基本方法可供使用,你可以使用位置参数或命名参数。
#### 位置参数
让我们看一个使用位置参数的查询示例。
```
$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(?, ?)");
$tis->bindValue(1,'mike');
$tis->bindValue(2,22);
$tis->execute();
```
在上面的例子中,我们放置了两个问号,然后使用 `bindValue()` 函数将值映射到查询中。这些值绑定到语句问号中的位置。
我还可以使用变量而不是直接提供值,通过使用 `bindParam()` 函数相同例子如下:
```
$name='Rishabh'; $age=20;
$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(?, ?)");
$tis->bindParam(1,$name);
$tis->bindParam(2,$age);
$tis->execute();
```
### 命名参数
命名参数也是预处理语句,它将值/变量映射到查询中的命名位置。由于没有位置绑定,因此在多次使用相同变量的查询中非常有效。
```
$name='Rishabh'; $age=20;
$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(:name, :age)");
$tis->bindParam(':name', $name);
$tis->bindParam(':age', $age);
$tis->execute();
```
你可以注意到,唯一的变化是我使用 `:name``:age` 作为占位符,然后将变量映射到它们。冒号在参数之前使用,让 PDO 知道该位置是一个变量,这非常重要。
你也可以类似地使用 `bindValue()` 来使用命名参数直接映射值。
### 获取数据
PDO 在获取数据时非常丰富,它实际上提供了许多格式来从数据库中获取数据。
你可以使用 `PDO::FETCH_ASSOC` 来获取关联数组,`PDO::FETCH_NUM` 来获取数字数组,使用 `PDO::FETCH_OBJ` 来获取对象数组。
```
$tis = $conn->prepare("SELECT * FROM STUDENTS");
$tis->execute();
$result = $tis->fetchAll(PDO::FETCH_ASSOC);
```
你可以看到我使用了 `fetchAll`,因为我想要所有匹配的记录。如果只需要一行,你可以简单地使用 `fetch`
现在我们已经获取了数据,现在是时候循环它了,这非常简单。
```
foreach ($result as $lnu){
echo $lnu['name'];
echo $lnu['age']."<br>";
}
```
你可以看到,因为我请求了关联数组,所以我正在按名称访问各个成员。
虽然在定义希望如何传输递数据方面没有要求,但在定义 `$conn` 变量本身时,实际上可以将其设置为默认值。
你需要做的就是创建一个 `$options` 数组,你可以在其中放入所有默认配置,只需在 `$conn` 变量中传递数组即可。
```
$options = [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
$conn = new PDO($dsn, $user, $pass, $options);
```
这是一个非常简短和快速的 PDO 介绍,我们很快就会制作一个高级教程。如果你在理解本教程的任何部分时遇到任何困难,请在评论部分告诉我,我会在那你为你解答。
--------------------------------------------------------------------------------
via: http://www.theitstuff.com/easiest-pdo-tutorial-basics
作者:[Rishabh Kandari][a]
选题:[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/) 荣誉推出
[a]:http://www.theitstuff.com/author/reevkandari

View File

@ -0,0 +1,86 @@
Adobe Lightroom 的三个开源替代品
=======
> 摄影师们:在没有 Lightroom 套件的情况下,可以看看这些 RAW 图像处理器。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/camera-photography-film.jpg?itok=oe2ixyu6)
如今智能手机的摄像功能已经完备到多数人认为可以代替传统摄影了。虽然这在傻瓜相机的市场中是个事实,但是对于许多摄影爱好者和专业摄影师看来,一个高端单反相机所能带来的照片景深、清晰度以及真实质感是口袋中的智能手机无法与之相比的。
所有的这些功能在便利性上要付出一些很小的代价;就像传统的胶片相机中的反色负片,单反照相得到的 RAW 格式文件必须预先处理才能印刷或编辑;因此对于单反相机,照片的后期处理是无可替代的,并且 首选应用就是 Adobe Lightroom。但是由于 Adobe Lightroom 的昂贵价格、基于订阅的定价模式以及专有许可证都使更多人开始关注其开源替代品。
Lightroom 有两大主要功能:处理 RAW 格式的图片文件以及数字资产管理系统DAM —— 通过标签、评星以及其他元数据信息来简单清晰地整理照片。
在这篇文章中我们将介绍三个开源的图片处理软件Darktable、LightZone 以及 RawTherapee。所有的软件都有 DAM 系统,但没有任何一个具有 Lightroom 基于机器学习的图像分类和标签功能。如果你想要知道更多关于开源的 DAM 系统的软件,可以看 Terry Hacock 的文章:“[开源项目的 DAM 管理][2]”,他分享了他在自己的 [Lunatics!][3] 电影项目研究过的开源多媒体软件。
### Darktable
![Darktable][4]
类似其他两个软件Darktable 可以处理 RAW 格式的图像并将它们转换成可用的文件格式 —— JPEG、PNG、TIFF、PPM、PFM 和 EXR它同时支持 Google 和 Facebook 的在线相册,上传至 Flikr通过邮件附件发送以及创建在线相册。
它有 61 个图像处理模块,可以调整图像的对比度、色调、明暗、色彩、噪点;添加水印;切割以及旋转;等等。如同另外两个软件一样,不论你做出多少次修改,这些修改都是“无损的” —— 你的初始 RAW 图像文件始终会被保存。
Darktable 可以从 400 多种相机型号中直接导入照片,以及有 JPEG、CR2、DNG、OpenEXR 和 PFM 等格式的支持。图像在一个数据库中显示,因此你可以轻易地过滤并查询这些元数据,包括了文字标签、评星以及颜色标签。软件同时支持 21 种语言,支持 Linux、MacOS、BSD、Solaris 11/GNOME 以及 WindowsWindows 版本是最新发布的Darktable 声明它比起其他版本可能还有一些不完备之处,有一些未实现的功能)。
Darktable 在开源许可证 [GPLv3][7] 下发布,你可以了解更多它的 [特性][8],查阅它的 [用户手册][9],或者直接去 Github 上看[源代码][10] 。
### LightZone
![LightZone's tool stack][11]
[LightZone][12] 和其他两个软件类似同样是无损的 RAW 格式图像处理工具:它是跨平台的,有 Windows、MacOS 和 Linux 版本,除 RAW 格式之外,它还支持 JPG 和 TIFF 格式的图像处理。接下来说说 LightZone 其他独特特性。
这个软件最初在 2005 年时,是以专有许可证发布的图像处理软件,后来在 BSD 证书下开源。此外,在你下载这个软件之前,你必须注册一个免费账号,以便 LightZone的 开发团队可以跟踪软件的下载数量以及建立相关社区。(许可很快,而且是自动的,因此这不是一个很大的使用障碍。)
除此之外的一个特性是这个软件的图像处理通常是通过很多可组合的工具实现的,而不是叠加滤镜(就像大多数图像处理软件),这些工具组可以被重新编排以及移除,以及被保存并且复制用到另一些图像上。如果想要编辑图片的部分区域,你还可以通过矢量工具或者根据色彩和亮度来选择像素。
想要了解更多,见 LightZone 的[论坛][13] 或者查看 Github上的 [源代码][14]。
### RawTherapee
![RawTherapee][15]
[RawTherapee][16] 是另一个值得关注的开源([GPL][17])的 RAW 图像处理器。就像 Darktable 和 LightZone它是跨平台的支持 Windows、MacOS 和 Linux一切修改都在无损条件下进行因此不论你叠加多少滤镜做出多少改变你都可以回到你最初的 RAW 文件。
RawTherapee 采用的是一个面板式的界面,包括一个历史记录面板来跟踪你做出的修改,以方便随时回到先前的图像;一个快照面板可以让你同时处理一张照片的不同版本;一个可滚动的工具面板可以方便准确地选择工具。这些工具包括了一系列的调整曝光、色彩、细节、图像变换以及去马赛克功能。
这个软件可以从多数相机直接导入 RAW 文件,并且支持超过 25 种语言,得到了广泛使用。批量处理以及 [SSE][18] 优化这类功能也进一步提高了图像处理的速度以及对 CPU 性能的利用。
RawTherapee 还提供了很多其他 [功能][19];可以查看它的 [官方文档][20] 以及 [源代码][21] 了解更多细节。
你是否在摄影中使用另外的开源 RAW 图像处理工具?有任何建议和推荐都可以在评论中分享。
------
via: https://opensource.com/alternatives/adobe-lightroom
作者:[Opensource.com][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[scoutydren](https://github.com/scoutydren)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com
[1]: https://en.wikipedia.org/wiki/Raw_image_format
[2]: https://opensource.com/article/18/3/movie-open-source-software
[3]: http://lunatics.tv/
[4]: https://opensource.com/sites/default/files/styles/panopoly_image_original/public/uploads/raw-image-processors_darkroom1.jpg?itok=0fjk37tC "Darktable"
[5]: http://www.darktable.org/
[6]: https://www.darktable.org/about/faq/#faq-windows
[7]: https://github.com/darktable-org/darktable/blob/master/LICENSE
[8]: https://www.darktable.org/about/features/
[9]: https://www.darktable.org/resources/
[10]: https://github.com/darktable-org/darktable
[11]: https://opensource.com/sites/default/files/styles/panopoly_image_original/public/uploads/raw-image-processors_lightzone1tookstack.jpg?itok=1e3s85CZ
[12]: http://www.lightzoneproject.org/
[13]: http://www.lightzoneproject.org/Forum
[14]: https://github.com/ktgw0316/LightZone
[15]: https://opensource.com/sites/default/files/styles/panopoly_image_original/public/uploads/raw-image-processors_rawtherapee.jpg?itok=meiuLxPw "RawTherapee"
[16]: http://rawtherapee.com/
[17]: https://github.com/Beep6581/RawTherapee/blob/dev/LICENSE.txt
[18]: https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
[19]: http://rawpedia.rawtherapee.com/Features
[20]: http://rawpedia.rawtherapee.com/Main_Page
[21]: https://github.com/Beep6581/RawTherapee

View File

@ -1,45 +1,46 @@
[#]: collector: (lujun9972)
[#]: translator: (robsean)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10902-1.html)
[#]: subject: (Put platforms in a Python game with Pygame)
[#]: via: (https://opensource.com/article/18/7/put-platforms-python-game)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
放置舞台到一个使用 Pygame 的 Python 游戏中
在 Pygame 游戏中放置平台
======
在这系列的第六部分中,在从零构建一个 Python 游戏时,为你的角色创建一些舞台来旅行。
> 在这个从零构建一个 Python 游戏系列的第六部分中,为你的角色创建一些平台来旅行。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/header.png?itok=iq8HFoEJ)
这是关于使用 Pygame 模块来在 Python 3 中创建电脑游戏的仍在进行的一系列文章的第六部分。先前的文章是:
这是仍在进行中的关于使用 Pygame 模块来在 Python 3 中创建电脑游戏的系列文章的第六部分。先前的文章是:
+ [通过构建一个简单的骰子游戏来学习如何用 Python 编程][24]
+ [通过构建一个简单的掷骰子游戏去学习怎么用 Python 编程][24]
+ [使用 Python 和 Pygame 模块构建一个游戏框架][25]
+ [如何添加一个玩家到你的 Python 游戏][26]
+ [使用 Pygame 来在周围移动你的游戏角色][27]
+ [没有一个坏蛋的一个英雄是什么?如何添加一个坏蛋到你的 Python 游戏][28]
+ [如何在你的 Python 游戏中添加一个玩家][26]
+ [用 Pygame 使你的游戏角色移动起来][27]
+ [如何向你的 Python 游戏中添加一个敌人][28]
一个平台类游戏需要平台。
一个舞台游戏需要舞台
在 [Pygame][1] 中,平台本身也是个妖精,正像你那个可玩的妖精。这一点是重要的,因为有个是对象的平台,可以使你的玩家妖精更容易与之互动
在 [Pygame][1] 中,舞台本身是小精灵,正像你的可玩的小精灵。这一点是重要的,因为有对象的舞台,使你的玩家小精灵很简单地与舞台一起作用。.
创建平台有两个主要步骤。首先,你必须给该对象编写代码,然后,你必须映射出你希望该对象出现的位置。
创建舞台有两个主要步骤。首先,你必须编码对象,然后,你必须设计你希望对象来出现的位置。
### 编码平台对象
### 编码舞台对象
要构建一个平台对象,你要创建一个名为 `Platform` 的类。它是一个妖精,正像你的 `Player` [妖精][2] 一样,带有很多相同的属性。
为构建一个舞台对象,你创建一个称为`Platform`的类。它是一个小精灵,正像你的[`玩家`][2] [小精灵][2],带有很多相同的属性
你的 `Platform` 类需要知道很多平台类型的信息,它应该出现在游戏世界的哪里、它应该包含的什么图片等等。这其中很多信息可能还尚不存在,这要看你为你的游戏计划了多少,但是没有关系。正如直到[移动你的游戏角色][3]那篇文章结束时,你都没有告诉你的玩家妖精移动速度有多快,你不必事先告诉 `Platform` 每一件事
你的`舞台`类需要知道很多你想要的舞台的类型的信息 ,它应该出现在游戏世界的哪里,和它应该包含的什么图片。它们中很多信息可能还尚不存在,依赖于你计划了多少游戏,但是,没有关系。正像直到[移到文章][3]的结尾时,你不告诉你的玩家小精灵多快速度移到,你没有必要告诉`Platform`预交的每一件事。
在你所写的这系列中脚本的顶部附近,创建一个新的类。在这代码示例中前三行是用于上下文,因此在注释的下面添加代码:
在这系列中你所写的脚本的开头附近,创建一个新的类。在这个代码示例中前三行是用于说明上下文,因此在注释的下面添加代码:
```
import pygame
import sys
import os
## new code below:
## 新代码如下:
class Platform(pygame.sprite.Sprite):
# x location, y location, img width, img height, img file    
@ -53,55 +54,55 @@ def __init__(self,xloc,yloc,imgw,imgh,img):
    self.rect.x = xloc
```
当被调用时,这个类在一些 X 和 Y 位置上创建一个对象 onscreen, 带有一些宽度和高度对于纹理使用一些图片文件。它非常类似于如何玩家或敌人绘制onscreen
当被调用时,这个类在某个 X 和 Y 位置上创建一个屏上对象,具有某种宽度和高度,并使用某种图像作为纹理。这与如何在屏上绘制出玩家或敌人非常类似
### 台的类型
### 台的类型
下一步是设计你所有舞台需要出现的地方。
下一步是绘制出你的平台需要出现的地方。
#### 瓷砖方
#### 瓷砖方
这里有几个不同的方法来实施一个舞台游戏世界。在最初的侧面滚动游戏,例如,马里奥超级兄弟和刺猬索尼克,这个技巧是来使用"瓷砖"意味着这里有几个块“瓷砖”来代表地面和各种各样的舞台并且这些块被使用和重复使用来制作一个层次。你仅有8或12种不同的块你排列它们在屏幕上来创建地面浮动的舞台和你游戏需要的其它的一切事物。一些人找到这最容易的方法来制作一个游戏尽管你不得不制作(或下载)一小组价值相等的有用的事物来创建很多不同的有用的事物。然而,代码需要一点更多的数学
实现平台类游戏世界有几种不同的方法。在最初的横向滚轴游戏中,例如,马里奥超级兄弟和刺猬索尼克,这个技巧是使用“瓷砖”方式,也就是说有几个代表地面和各种平台的块,并且这些块被重复使用来制作一个关卡。你只能有 8 或 12 种不同的块,你可以将它们排列在屏幕上来创建地面、浮动的平台,以及你游戏中需要的一切其它的事物。有人发现这是制作游戏最容易的方法了,因为你只需要制作(或下载)一小组关卡素材就能创建很多不同的关卡。然而,这里的代码需要一点数学知识
![Supertux, a tile-based video game][5]
[SuperTux][6] ,一个基于瓷砖的电脑游戏。
*[SuperTux][6] ,一个基于瓷砖的电脑游戏。*
#### 手工绘制方
#### 手工绘制方
另一个方法是来使各个和每一个有用的事物作为一整个图像。如果你享受为你的游戏世界创建有用的事物,在一个图形应用程序中花费时间来构建你的游戏世界的各个和每一部件是一个极好的理由。这个方法需要较少的数学,因为所有的舞台是完整的对象,并且你告诉 [Python][7] 在屏幕上放置它们的位置。
另一种方法是将每个素材作为一个整体图像。如果你喜欢为游戏世界创建素材,那你会在用图形应用程序构建游戏世界的每个部分上花费很多时间。这种方法不需要太多的数学知识,因为所有的平台都是整体的、完整的对象,你只需要告诉 [Python][7] 将它们放在屏幕上的什么位置。
每种方法都有优势和劣势,并且依赖于你的选择使用的代码是稍微不同的.我将覆盖这两方面,所以你可以在你的工程中使用一个或另一个,甚至两者的混合。
每种方法都有优势和劣势,并且根据于你选择使用的方式,代码稍有不同。我将覆盖这两方面,所以你可以在你的工程中使用一种或另一种,甚至两者的混合。
### 层次映射
### 关卡绘制
总的来说,映射出你的游戏世界是层次设计和游戏程序的一个重要的部分。这需要数学,但是没有什么太难的,而且 Python 擅长数学,因此它可以帮助一些
总的来说,绘制你的游戏世界是关卡设计和游戏编程中的一个重要的部分。这需要数学知识,但是没有什么太难的,而且 Python 擅长数学,它会有所帮助
可以发现先在纸张上设计是有益的。获取纸张的一个表格,并绘制一个方框来代表你的游戏窗体。在方框中绘制舞台,用 X 和 Y 坐标标记每一个,以及它的意欲达到的宽度和高度。在方框中的实际位置没有必要是精确的,只要你保持实际的数字。譬如,假如你的屏幕是 720 像素宽,那么你不能在一个屏幕上以 100 像素处容纳8块舞台。
也许发现先在纸张上设计是有用的。拿一张表格纸,并绘制一个方框来代表你的游戏窗体。在方框中绘制平台,并标记其每一个平台的 X 和 Y 坐标,以及它的宽度和高度。在方框中的实际位置没有必要是精确的,你只要保持数字合理即可。譬如,假设你的屏幕是 720 像素宽,那么你不能在一个屏幕上放 8 块 100 像素的平台。
当然,在你的游戏中不是所有的舞台不得不容纳在一个屏幕大小的方框,因为你的游戏将随着你的玩家行走而滚动。所以保持绘制你的游戏世界到第一屏幕的右侧,直到层次的右侧
当然,不是你游戏中的所有平台都必须容纳在一个屏幕大小的方框里,因为你的游戏将随着你的玩家行走而滚动。所以,可以继续绘制你的游戏世界到第一屏幕的右侧,直到关卡结束
如果你更喜欢精确一点,你可以使用方格纸。当设计一个带有瓷砖的游戏时,这是特别有用的,因为每个方格可以代表一个瓷砖。
如果你更喜欢精确一点,你可以使用方格纸。当设计一个瓷砖的游戏时,这是特别有用的,因为每个方格可以代表一个瓷砖。
![Example of a level map][9]
一个平面地图示例。
*一个关卡地图示例。*
#### 坐标系
你可能已经在学校中学习[笛卡尔坐标系][10]。你学习的东西应用到 Pygame除了在 Pygame 中,你的游戏世界的坐标系放置 `0,0` 在你的屏幕的左上角而不是在中间中间可能是你which is probably what you're used to from Geometry class.
你可能已经在学校中学习过[笛卡尔坐标系][10]。你学习的东西也适用于 Pygame除了在 Pygame 中你的游戏世界的坐标系的原点 `0,0` 是放置在你的屏幕的左上角而不是在中间,是你在地理课上用过的坐标是在中间的。
![Example of coordinates in Pygame][12]
在 Pygame 中的坐标示例。
*在 Pygame 中的坐标示例。*
X 轴起始于最左边的 0 无限地向右增加。Y 轴起始于屏幕顶部的 0 ,向下延伸。
X 轴起始于最左边的 0向右无限增加。Y 轴起始于屏幕顶部的 0向下延伸。
#### 图片大小
映射出一个游戏世界不是毫无意义的,如果你不知道你的玩家,敌人,舞台是多大的。你可以找到你的舞台的尺寸或在一个图形程序中的标题。在 [Krita][13] 中,例如,单击**图形**菜单,并选择**属性**。你可以在**属性**窗口的非常顶部处找到尺寸。
如果你不知道你的玩家、敌人、平台是多大的,绘制出一个游戏世界是毫无意义的。你可以在图形程序中找到你的平台或瓷砖的尺寸。例如在 [Krita][13] 中,单击“图像”菜单,并选择“属性”。你可以在“属性”窗口的最顶部处找到它的尺寸。
可选地,你可以创建一个简单点的 Python 脚本来告诉你的一个图形的尺寸。打开一个新的文本文件,并输入这些代码到其中:
另外,你也可以创建一个简单的 Python 脚本来告诉你的一个图像的尺寸。打开一个新的文本文件,并输入这些代码到其中:
```
#!/usr/bin/env python3
@ -123,44 +124,44 @@ Y   = dim.size[1]
print(X,Y)
```
保存文本文件为 `identify.py`
保存文本文件为 `identify.py`
为安装这个脚本,你必需安装安装一组额外的 Python 模块,它们包含使用在脚本中新的关键字:
要使用这个脚本,你必须安装一些额外的 Python 模块,它们包含了这个脚本中新使用的关键字:
```
$ pip3 install Pillow --user
```
一旦这些被安装,在你游戏工程目录中运行你的脚本:
一旦安装好,在你游戏工程目录中运行这个脚本:
```
$ python3 ./identify.py images/ground.png
(1080, 97)
```
在这个示例中的地面舞台的图形的大小是1080像素宽和97像素高。
在这个示例中,地面平台的图形的大小是 1080 像素宽和 97 像素高。
### 台块
### 台块
如果你选择单独地绘制每个有用的事物,你必需创建一些舞台和一些你希望插入到你的游戏世界中其它的元素,每个元素都在它自己的文件中。换句话说,你应该每个有用的事物都有一个文件,像这
如果你选择单独地绘制每个素材,你必须创建想要插入到你的游戏世界中的几个平台和其它元素,每个素材都放在它自己的文件中。换句话说,你应该让每个素材都有一个文件,像这样
![One image file per object][15]
每个对象一个图形文件。
*每个对象一个图形文件。*
你可以按照你希望的次数重复使用每个舞台,只要确保每个文件仅包含一个舞台。你不能使用一个包含每一件事物的文件,像这
你可以按照你希望的次数重复使用每个平台,只要确保每个文件仅包含一个平台。你不能使用一个文件包含全部素材,像这样
![Your level cannot be one image file][17]
你的层次不能是一个图形。
*你的关卡不能是一个图形文件。*
当你完成时,你可能希望你的游戏看起来像这样,但是如果你在一个大文件中创建你的层次,没有方法从背景中区分一个舞台,因此,要么在它们拥有的文件中绘制你的对象,要么从一个大规模文件中复制它们,并单独地保存副本。
当你完成时,你可能希望你的游戏看起来像这样,但是如果你在一个大文件中创建你的关卡,你就没有方法从背景中区分出一个平台,因此,要么把对象绘制在它们自己的文件中,要么从一个更大的文件中裁剪出它们,并保存为单独的副本。
**注意:** 如同你的其它的有用的事物,你可以使用[GIMP][18]Krita[MyPaint][19],或[Inkscape][20] 来创建你的游戏的有用的事物
**注意** 如同你的其它素材,你可以使用 [GIMP][18]、Krita、[MyPaint][19],或 [Inkscape][20] 来创建你的游戏素材
舞台出现在每个层次开始的屏幕上,因此你必需在你的`Level`类中添加一个`platform`函数。在这里特殊的情况是地面舞台,作为它自身拥有的舞台组来对待是足够重要的。通过把地面看作它自身拥有的特殊类型的舞台,你可以选择它是否滚动,或在其它舞台漂浮在它上面期间是否仍然站立。它取决于你。
平台出现在每个关卡开始的屏幕上,因此你必须在你的 `Level` 类中添加一个 `platform` 函数。在这里特例是地面平台,它重要到应该拥有它自己的一个组。通过把地面看作一组特殊类型的平台,你可以选择它是否滚动,或它上面是否可以站立,而其它平台可以漂浮在它上面。这取决于你。
添加这两个函数到你的`Level`类:
添加这两个函数到你的 `Level` 类:
```
def ground(lvl,x,y,w,h):
@ -187,15 +188,15 @@ def platform( lvl ):
    return plat_list
```
`ground` 函数需要一个 X 和 Y 位置,以便 Pygame 知道在哪里放置地面舞台。它也需要舞台的宽度和高度,这样 Pygame 知道地面延伸到每个方向有多远。该函数使用你的 `Platform` 来来生成一个对象 onscreen ,然后他就这个对象`ground_list` 组。
`ground` 函数需要一个 X 和 Y 位置,以便 Pygame 知道在哪里放置地面平台。它也需要知道平台的宽度和高度,这样 Pygame 知道地面延伸到每个方向有多远。该函数使用你的 `Platform` 类来生成一个屏上对象,然后将这个对象添加`ground_list` 组。
`platform` 函数本质上是相同的,除了其有更多的舞台来列出。在这个示例中,仅有两个,但是你可以想多少就多少。在进入一个舞台后,在列出另一个前,你必需添加它到 `plat_list` 中。如果你不添加一个舞台到组中,那么它将不出现在你的游戏中。
`platform` 函数本质上是相同的,除了其有更多的平台。在这个示例中,仅有两个平台,但是你可以想有多少就有多少。在进入一个平台后,在列出另一个前你必须添加它到 `plat_list` 中。如果你不添加平台到组中,那么它将不出现在你的游戏中。
> **提示:** 很难想象你的游戏世界的0在顶部因为在真实世界中发生的情况是相反的当估计你多高时你不要从天空下面测量你自己从脚到头的顶部来测量。
> **提示** 很难想象你的游戏世界的 0 是在顶部,因为在真实世界中发生的情况是相反的;当估计你有多高时,你不会从上往下测量你自己,而是从脚到头顶来测量。
>
> 如果对你来说从“地面”上来构建你的游戏世界更容易,它可能有助于表示 Y 轴值为负数。例如,你知道你的游戏世界的底部是 `worldy` 的值。因此 `worldy` 减去地面(97在这个示例中)的高度是你的玩家正常站立的位置。如果你的角色是64像素高那么地面减去128正好是你的玩家的两倍。事实上一个放置在128像素处舞台大约是两层楼高度相对于你的玩家。一个舞台在-320处是三层楼高。等等
> 如果对你来说从“地面”上来构建你的游戏世界更容易,将 Y 轴值表示为负数可能有帮助。例如,你知道你的游戏世界的底部是 `worldy` 的值。因此 `worldy` 减去地面的高度(在这个示例中是 97是你的玩家正常站立的位置。如果你的角色是 64 像素高,那么地面减去 128 正好是你的玩家的两倍高。事实上,一个放置在 128 像素处平台大约是相对于你的玩家的两层楼高度。一个平台在 -320 处比三层楼更高。等等。
正像你现在可能所知的,如果你不使用它们,你的类和函数是没有有价值的。添加这些代码到你的 setup 部分(第一行只是上下文,所以添加最后两行):
正像你现在可能所知的,如果你不使用它们,你的类和函数是没有价值的。添加这些代码到你的设置部分(第一行只是上下文,所以添加最后两行):
```
enemy_list  = Level.bad( 1, eloc )
@ -203,32 +204,32 @@ ground_list = Level.ground( 1,0,worldy-97,1080,97 )
plat_list   = Level.platform( 1 )
```
提交这些行到你的主循环(再一次,第一行仅用于上下文)
把这些行加到你的主循环(再一次,第一行仅用于上下文)
```
enemy_list.draw(world)  # refresh enemies
ground_list.draw(world)  # refresh ground
plat_list.draw(world)  # refresh platforms
enemy_list.draw(world)  # 刷新敌人
ground_list.draw(world)  # 刷新地面
plat_list.draw(world)  # 刷新平台
```
### 瓷砖
### 瓷砖
瓷砖游戏世界被认为更容易制作,因为你只需要绘制一些在前面的块,就能在游戏中反反复复创建每一个舞台。在网站上甚至有一组供你来使用的瓷砖,像 [OpenGameArt.org][21]
瓷砖类游戏世界更容易制作,因为你只需要在前面绘制一些块,就能在游戏中一再使用它们创建每个平台。在像 [OpenGameArt.org][21] 这样的网站上甚至有一套瓷砖供你来使用
`Platform` 类与在前面部分中的类是相同的。
`Level` 类中的 `ground``platform` 然而,必需使用循环来计算使用多少块来创建每个舞台。
`ground``platform``Level` 类中,然而,必须使用循环来计算使用多少块来创建每个平台。
如果你打算在你的游戏世界中有一个坚固的地面,地面是简单的。你仅从整个窗口一边到另一边"克隆"你的地面瓷砖。例如,你可以创建一个 X 和 Y 值的列表来规定每个瓷砖应该放置的位置,然后使用一个循环来获取每个值和绘制一个瓷砖。这仅是一个示例,所以不要添加这到你的代码:
如果你打算在你的游戏世界中有一个坚固的地面,这种地面是很简单的。你只需要从整个窗口的一边到另一边“克隆”你的地面瓷砖。例如,你可以创建一个 X 和 Y 值的列表来规定每个瓷砖应该放置的位置,然后使用一个循环来获取每个值并绘制每一个瓷砖。这仅是一个示例,所以不要添加这到你的代码:
```
# Do not add this to your code
gloc = [0,656,64,656,128,656,192,656,256,656,320,656,384,656]
```
如果你仔细看,不过,你可以看到所有的 Y 值是相同的X 值以64的增量不断地增加这是瓷砖的东西。这种类型的重复是精确地,是计算机擅长的,因此你可以使用一点数学逻辑来让计算机为你做所有的计算:
不过,如果你仔细看,你可以看到所有的 Y 值是相同的X 值以 64 的增量不断地增加 —— 这就是瓷砖的大小。这种重复是精确地,是计算机擅长的,因此你可以使用一点数学逻辑来让计算机为你做所有的计算:
添加这代你的脚本的 setup 部分:
添加这些到你的脚本的设置部分:
```
gloc = []
@ -243,9 +244,9 @@ while i <= (worldx/tx)+tx:
ground_list = Level.ground( 1,gloc,tx,ty )
```
现在不管你的窗口的大小Python 通过瓷砖的宽度 分割游戏世界的宽度,并创建一个数组列表列出每个 X 值。这不计算 Y 值,但是无论如何,从不在平的地面上更改
现在不管你的窗口的大小Python 通过瓷砖的宽度分割游戏世界的宽度,并创建一个数组列表列出每个 X 值。这里不计算 Y 值,因为在平的地面上这个从不会变化
为在一个函数中使用数组,使用一个`while`循环,查看每个条目并在适当的位置添加一个地面瓷砖:
在一个函数中使用数组,使用一个 `while` 循环,查看每个条目并在适当的位置添加一个地面瓷砖:
```
def ground(lvl,gloc,tx,ty):
@ -263,13 +264,13 @@ def ground(lvl,gloc,tx,ty):
    return ground_list
```
除了 `while` 循环,这几乎与在上面一部分中提供的块样式平台游戏 `ground` 函数的代码相同。
除了 `while` 循环,这几乎与在上面一部分中提供的瓷砖类平台的 `ground` 函数的代码相同。
对于移到舞台,原理是相似的,但是这里有一些你可以使用的技巧来使你的生活更简单。
对于移动的平台,原理是相似的,但是这里有一些技巧可以使它简单。
而不通过像素映射每个舞台,你可以通过它的起始像素(它的 X 值),从地面(它的 Y 值)的高度,绘制多少瓷砖来定义一个舞台。用那种方法,你不必担心每个舞台的宽度和高度。
你可以通过它的起始像素(它的 X 值)、距地面的高度(它的 Y 值)、绘制多少瓷砖来定义一个平台,而不是通过像素绘制每个平台。这样,你不必操心每个平台的宽度和高度。
这个技巧的逻辑有一点复杂,因此仔细复制这些代码。有一个 `while` 循环在另一个 `while` 循环的内部,因为这个函数必需考虑在每个数组入口处的所有三个值来成功地建造一个完整的舞台。在这个示例中,这里仅有三个舞台被定义为 `ploc.append` 语句,但是你的游戏可能需要更多,因此你需要多少就定义多少。当然,一些也将不出现,因为它们远在屏幕外,但是一旦你实施滚动,它们将呈现眼前。
这个技巧的逻辑有一点复杂,因此仔细复制这些代码。有一个 `while` 循环嵌套在另一个 `while` 循环的内部,因为这个函数必须考虑每个数组项的三个值来成功地建造一个完整的平台。在这个示例中,这里仅有三个平台以 `ploc.append` 语句定义,但是你的游戏可能需要更多,因此你需要多少就定义多少。当然,一些不出现,因为它们远在屏幕外,但是一旦当你进行滚动时,它们将呈现在眼前。
```
def platform(lvl,tx,ty):
@ -295,21 +296,21 @@ def platform(lvl,tx,ty):
    return plat_list
```
为获取舞台,使其出现在你的游戏世界,它们必需在你的主循环中。如果你还没有这样做,添加这些行到你的主循环(再一次,第一行仅被用于上下文)中:
要让这些平台出现在你的游戏世界,它们必须出现在你的主循环中。如果你还没有这样做,添加这些行到你的主循环(再一次,第一行仅被用于上下文)中:
```
        enemy_list.draw(world)  # refresh enemies
        ground_list.draw(world) # refresh ground
        plat_list.draw(world)   # refresh platforms
        enemy_list.draw(world)  # 刷新敌人
        ground_list.draw(world) # 刷新地面
        plat_list.draw(world)   # 刷新平台
```
启动你的游戏,根据需要调整你的舞台的放置位置。不要担心,你不能看见在屏幕外面产生的舞台;你将不久后修复
启动你的游戏,根据需要调整你的平台的放置位置。如果你看不见屏幕外产生的平台,不要担心;你不久后就可以修复它
到目前为止,这是在一个图片和在代码中游戏
到目前为止,这是游戏的图片和代码
![Pygame game][23]
到目前为止,我们的 Pygame 舞台。
*到目前为止,我们的 Pygame 平台。*
```
#!/usr/bin/env python3
@ -546,14 +547,16 @@ while main == True:
    clock.tick(fps)
```
LCTT 译注:到本文翻译完为止,该系列已经近一年没有继续更新了~
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/7/put-platforms-python-game
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[robsan](https://github.com/robsean)
校对:[校对者ID](https://github.com/校对者ID)
译者:[robsean](https://github.com/robsean)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@ -582,9 +585,9 @@ via: https://opensource.com/article/18/7/put-platforms-python-game
[21]: https://opengameart.org/content/simplified-platformer-pack
[22]: /file/403886
[23]: https://opensource.com/sites/default/files/uploads/pygame_platforms.jpg (Pygame game)
[24]: Learn how to program in Python by building a simple dice game
[25]: https://opensource.com/article/17/12/game-framework-python
[26]: https://opensource.com/article/17/12/game-python-add-a-player
[27]: https://opensource.com/article/17/12/game-python-moving-player
[28]: https://opensource.com/article/18/5/pygame-enemy
[24]: https://linux.cn/article-9071-1.html
[25]: https://linux.cn/article-10850-1.html
[26]: https://linux.cn/article-10858-1.html
[27]: https://linux.cn/article-10874-1.html
[28]: https://linux.cn/article-10883-1.html

View File

@ -0,0 +1,172 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10918-1.html)
[#]: subject: (Aliases: To Protect and Serve)
[#]: via: (https://www.linux.com/blog/learn/2019/1/aliases-protect-and-serve)
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
命令别名:保护和服务
======
> Linux shell 允许你将命令彼此链接在一起,一次触发执行复杂的操作,并且可以对此创建别名作为快捷方式。
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/prairie-path_1920.jpg?itok=wRARsM7p)
让我们将继续我们的别名系列。到目前为止,你可能已经阅读了我们的[关于别名的第一篇文章][1],并且应该非常清楚它们是如何为你省去很多麻烦的最简单方法。例如,你已经看到它们帮助我们减少了输入,让我们看看别名派上用场的其他几个案例。
### 别名即快捷方式
Linux shell 最美妙的事情之一是可以使用数以万计的选项和把命令连接在一起执行真正复杂的操作。好吧,也许这种美丽是在旁观者的眼中的,但是我们觉得这个功能很实用。
不利的一面是,你经常需要记得难以记忆或难以打字出来的命令组合。比如说硬盘上的空间非常宝贵,而你想要做一些清洁工作。你的第一步可能是寻找隐藏在你的家目录里的东西。你可以用来判断的一个标准是查找不再使用的内容。`ls` 可以帮助你:
```
ls -lct
```
上面的命令显示了每个文件和目录的详细信息(`-l`),并显示了每一项上次访问的时间(`-c`),然后它按从最近访问到最少访问的顺序排序这个列表(`-t`)。
这难以记住吗?你可能不会每天都使用 `-c``-t` 选项,所以也许是吧。无论如何,定义一个别名,如:
```
alias lt='ls -lct'
```
会更容易一些。
然后,你也可能希望列表首先显示最旧的文件:
```
alias lo='lt -F | tac'
```
![aliases][3]
*图 1使用 lt 和 lo 别名。*
这里有一些有趣的事情。首先,我们使用别名(`lt`)来创建另一个别名 —— 这是完全可以的。其次,我们将一个新参数传递给 `lt`(后者又通过 `lt` 别名的定义传递给了 `ls`)。
`-F` 选项会将特殊符号附加到项目的名称后,以便更好地区分常规文件(没有符号)和可执行文件(附加了 `*`)、目录文件(以 `/` 结尾),以及所有链接文件、符号链接文件(以 `@` 符号结尾)等等。`-F` 选项是当你回归到单色终端的日子里,没有其他方法可以轻松看到列表项之间的差异时用的。在这里使用它是因为当你将输出从 `lt` 传递到 `tac` 时,你会丢失 `ls` 的颜色。
第三件我们需要注意的事情是我们使用了管道。管道用于你将一个命令的输出传递给另外一个命令时。第二个命令可以使用这些输出作为它的输入。在包括 Bash 在内的许多 shell 里,你可以使用管道符(`|` 来做传递。
在这里,你将来自 `lt -F` 的输出导给 `tac`。`tac` 这个命令有点玩笑的意思,你或许听说过 `cat` 命令它名义上用于将文件彼此连接con`cat`),而在实践中,它被用于将一个文件的内容打印到终端。`tac` 做的事情一样,但是它是以逆序将接收到的内容输出出来。明白了吗?`cat` 和 `tac`,技术人有时候也挺有趣的。
`cat``tac` 都能输出通过管道传递过来的内容,在这里,也就是一个按时间顺序排序的文件列表。
那么,在有些离题之后,最终我们得到的就是这个列表将当前目录中的文件和目录以新鲜度的逆序列出(即老的在前)。
最后你需要注意的是,当在当前目录或任何目录运行 `lt` 时:
```
# 这可以工作:
lt
# 这也可以:
lt /some/other/directory
```
……而 `lo` 只能在当前目录奏效:
```
# 这可工作:
lo
# 而这不行:
lo /some/other/directory
```
这是因为 Bash 会展开别名的组分。当你键入:
```
lt /some/other/directory
```
Bash 实际上运行的是:
```
ls -lct /some/other/directory
```
这是一个有效的 Bash 命令。
而当你键入:
```
lo /some/other/directory
```
Bash 试图运行:
```
ls -lct -F | tac /some/other/directory
```
这不是一个有效的命令,主要是因为 `/some/other/directory` 是个目录,而 `cat``tac` 不能用于目录。
### 更多的别名快捷方式
* `alias lll='ls -R'` 会打印出目录的内容,并深入到子目录里面打印子目录的内容,以及子目录的子目录,等等。这是一个查看一个目录下所有内容的方式。
* `mkdir='mkdir -pv'` 可以让你一次性创建目录下的目录。按照 `mkdir` 的基本形式,要创建一个包含子目录的目录,你必须这样:
```
mkdir newdir
mkdir newdir/subdir
```
或这样:
```
mkdir -p newdir/subdir
```
而用这个别名你将只需要这样就行:
```
mkdir newdir/subdir
```
你的新 `mkdir` 也会告诉你创建子目录时都做了什么。
### 别名也是一种保护
别名的另一个好处是它可以作为防止你意外地删除或覆写已有的文件的保护措施。你可能听说过这个 Linux 新用户的传言,当他们以 root 身份运行:
```
rm -rf /
```
整个系统就爆了。而决定输入如下命令的用户:
```
rm -rf /some/directory/ *
```
就很好地干掉了他们的家目录的全部内容。这里不小心键入的目录和 `*` 之间的那个空格有时候很容易就会被忽视掉。
这两种情况我们都可以通过 `alias rm='rm -i'` 别名来避免。`-i` 选项会使 `rm` 询问用户是否真的要做这个操作,在你对你的文件系统做出不可弥补的损失之前给你第二次机会。
对于 `cp` 也是一样,它能够覆盖一个文件而不会给你任何提示。创建一个类似 `alias cp='cp -i'` 来保持安全吧。
### 下一次
我们越来越深入到了脚本领域,下一次,我们将沿着这个方向,看看如何在命令行组合命令以给你真正的乐趣,并可靠地解决系统管理员每天面临的问题。
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/learn/2019/1/aliases-protect-and-serve
作者:[Paul Brown][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.linux.com/users/bro66
[b]: https://github.com/lujun9972
[1]: https://linux.cn/article-10377-1.html
[2]: https://www.linux.com/files/images/fig01png-0
[3]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fig01_0.png?itok=crqTm_va (aliases)
[4]: https://www.linux.com/licenses/category/used-permission

View File

@ -0,0 +1,56 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10914-1.html)
[#]: subject: (Blockchain 2.0: Blockchain In Real Estate [Part 4])
[#]: via: (https://www.ostechnix.com/blockchain-2-0-blockchain-in-real-estate/)
[#]: author: (ostechnix https://www.ostechnix.com/author/editor/)
区块链 2.0:房地产区块链(四)
======
![](https://www.ostechnix.com/wp-content/uploads/2019/03/Blockchain-In-Real-Estate-720x340.png)
### 区块链 2.0:“更”智能的房地产
在本系列的[上一篇文章][1]中我们探讨了区块链的特征,这些区块链将使机构能够将**传统银行**和**融资系统**转换和交织在一起。这部分将探讨**房地产区块链**。房地产业正在走向革命。它是人类已知的交易最活跃、最重要的资产类别之一。然而,由于充满了监管障碍和欺诈、欺骗的无数可能性,它也是最难参与交易的之一。利用适当的共识算法的区块链的分布式分类账本功能被吹捧为这个行业的前进方向,而这个行业传统上被认为其面对变革是保守的。
就其无数的业务而言房地产一直是一个非常保守的行业。这似乎也是理所当然的。2008 年金融危机或 20 世纪上半叶的大萧条等重大经济危机成功摧毁了该行业及其参与者。然而,与大多数具有经济价值的产品一样,房地产行业具有弹性,而这种弹性则源于其保守性。
全球房地产市场由价值 228 万亿 [^1] 美元的资产类别组成,出入不大。其他投资资产,如股票、债券和股票合计价值仅为 170 万亿美元。显然,在这样一个行业中实施的交易在很大程度上都是精心策划和执行的。很多时候,房地产也因许多欺诈事件而臭名昭著,并且随之而来的是毁灭性的损失。由于其运营非常保守,该行业也难以驾驭。它受到了法律的严格监管,创造了一个交织在一起的细微差别网络,这对于普通人来说太难以完全理解,使得大多数人无法进入和参与。如果你曾参与过这样的交易,那么你就会知道纸质文件的重要性和长期性。
从一个微不足道的开始,虽然是一个重要的例子,以显示当前的记录管理实践在房地产行业有多糟糕,考虑一下[产权保险业务][2] [^3]。产权保险用于对冲土地所有权和所有权记录不可接受且从而无法执行的可能性。诸如此类的保险产品也称为赔偿保险。在许多情况下,法律要求财产拥有产权保险,特别是在处理多年来多次易手的财产时。抵押贷款公司在支持房地产交易时也可能坚持同样的要求。事实上,这种产品自 19 世纪 50 年代就已存在,并且仅在美国每年至少有 1.5 万亿美元的商业价值这一事实证明了一开始的说法。在这种情况下,这些记录的维护方式必须进行改革,区块链提供了一个可持续解决方案。根据[美国土地产权协会][4],平均每个案例的欺诈平均约为 10 万美元,并且涉及交易的所有产权中有 25 的文件存在问题。区块链允许设置一个不可变的永久数据库,该数据库将跟踪资产本身,记录已经进入的每个交易或投资。这样的分类帐本系统将使包括一次性购房者在内的房地产行业的每个人的生活更加轻松,并使诸如产权保险等金融产品基本上无关紧要。将诸如房地产之类的实物资产转换为这样的数字资产是非常规的,并且目前仅在理论上存在。然而,这种变化迫在眉睫,而不是迟到 [^5]。
区块链在房地产中影响最大的领域如上所述,在维护透明和安全的产权管理系统方面。基于区块链的财产记录可以包含有关财产、其所在地、所有权历史以及相关的公共记录的[信息][6]。这将允许房地产交易快速完成,并且无需第三方监控和监督。房地产评估和税收计算等任务成为有形的、客观的参数问题,而不是主观测量和猜测,因为可靠的历史数据是可公开验证的。[UBITQUITY][7] 就是这样一个平台,为企业客户提供定制的基于区块链的解决方案。该平台允许客户跟踪所有房产细节、付款记录、抵押记录,甚至允许运行智能合约,自动处理税收和租赁。
这为我们带来了房地产区块链的第二大机遇和用例。由于该行业受到众多第三方的高度监管,除了参与交易的交易对手外,尽职调查和财务评估可能非常耗时。这些流程主要通过离线渠道进行,文书工作需要在最终评估报告出来之前进行数天。对于公司房地产交易尤其如此,这构成了顾问所收取的总计费时间的大部分。如果交易由抵押背书,则这些过程的重复是不可避免的。一旦与所涉及的人员和机构的数字身份相结合,就可以完全避免当前的低效率,并且可以在几秒钟内完成交易。租户、投资者、相关机构、顾问等可以单独验证数据并达成一致的共识,从而验证永久性的财产记录 [^8]。这提高了验证流程的准确性。房地产巨头 RE/MAX 最近宣布与服务提供商 XYO Network Partners 合作,[建立墨西哥房上市地产国家数据库][9]。他们希望有朝一日能够创建世界上最大的(截至目前)去中心化房地产登记中心之一。
然而,区块链可以带来的另一个重要且可以说是非常民主的变化是投资房地产。与其他投资资产类别不同,即使是小型家庭投资者也可能参与其中,房地产通常需要大量的手工付款才能参与。诸如 ATLANT 和 BitOfProperty 之类的公司将房产的账面价值代币化,并将其转换为加密货币的等价物。这些代币随后在交易所出售,类似于股票和股票的交易方式。[房地产后续产生的任何现金流都会根据其在财产中的“份额”记入贷方或借记给代币所有者][4]。
然而尽管如此区块链技术仍处于房地产领域的早期采用阶段目前的法规还没有明确定义它。诸如分布式应用程序、分布式匿名组织DAO、智能合约等概念在许多国家的法律领域是闻所未闻的。一旦所有利益相关者充分接受了区块链复杂性的良好教育就会彻底改革现有的法规和指导方针这是最务实的前进方式。 同样,这将是一个缓慢而渐进的变化,但是它是一个急需的变化。本系列的下一篇文章将介绍 “智能合约”,例如由 UBITQUITY 和 XYO 等公司实施的那些是如何在区块链中创建和执行的。
[^1]: HSBC, “Global Real Estate,” no. April, 2008
[^3]: D. B. Burke, Law of title insurance. Aspen Law & Business, 2000.
[^5]: M. Swan, OReilly Blockchain. Blueprint for a New Economy 2015.
[^8]: Deloite, “Blockchain in commercial real estate The future is here! Table of contents.”
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/blockchain-2-0-blockchain-in-real-estate/
作者:[ostechnix][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/editor/
[b]: https://github.com/lujun9972
[1]: https://linux.cn/article-10689-1.html
[2]: https://www.forbes.com/sites/jordanlulich/2018/06/21/what-is-title-insurance-and-why-its-important/#1472022b12bb
[4]: https://www.cbinsights.com/research/blockchain-real-estate-disruption/#financing
[6]: https://www2.deloitte.com/us/en/pages/financial-services/articles/blockchain-in-commercial-real-estate.html
[7]: https://www.ubitquity.io/
[9]: https://www.businesswire.com/news/home/20181012005068/en/XYO-Network-Partners-REMAX-M%C3%A9xico-Bring-Blockchain

View File

@ -0,0 +1,173 @@
[#]: collector: (lujun9972)
[#]: translator: (robsean)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10916-1.html)
[#]: subject: (How to manage your Linux environment)
[#]: via: (https://www.networkworld.com/article/3385516/how-to-manage-your-linux-environment.html)
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
如何管理你的 Linux 环境变量
======
> Linux 用户环境变量可以帮助你找到你需要的命令,无须了解系统如何配置的细节而完成大量工作。而这些设置来自哪里和如何被修改它们是另一个话题。
![IIP Photo Archive \(CC BY 2.0\)][1]
在 Linux 系统上的用户账户配置以多种方法简化了系统的使用。你可以运行命令,而不需要知道它们的位置。你可以重新使用先前运行的命令,而不用发愁系统是如何追踪到它们的。你可以查看你的电子邮件,查看手册页,并容易地回到你的家目录,而不用管你在文件系统中身在何方。并且,当需要的时候,你可以调整你的账户设置,以便其更符合你喜欢的方式。
Linux 环境设置来自一系列的文件:一些是系统范围(意味着它们影响所有用户账户),一些是处于你的家目录中的配置文件里。系统范围的设置在你登录时生效,而本地设置在其后生效,所以,你在你账户中作出的更改将覆盖系统范围设置。对于 bash 用户,这些文件包含这些系统文件:
```
/etc/environment
/etc/bash.bashrc
/etc/profile
```
以及一些本地文件:
```
~/.bashrc
~/.profile # 如果有 ~/.bash_profile 或 ~/.bash_login 就不会读此文件
~/.bash_profile
~/.bash_login
```
你可以修改本地存在的四个文件的任何一个,因为它们处于你的家目录,并且它们是属于你的。
### 查看你的 Linux 环境设置
为查看你的环境设置,使用 `env` 命令。你的输出将可能与这相似:
```
$ env
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;
01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:
*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:
*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:
*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;
31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:
*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:
*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:
*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:
*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:
*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:
*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:
*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:
*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:
*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:
*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:
*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:
*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.spf=00;36:
SSH_CONNECTION=192.168.0.21 34975 192.168.0.11 22
LESSCLOSE=/usr/bin/lesspipe %s %s
LANG=en_US.UTF-8
OLDPWD=/home/shs
XDG_SESSION_ID=2253
USER=shs
PWD=/home/shs
HOME=/home/shs
SSH_CLIENT=192.168.0.21 34975 22
XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
SSH_TTY=/dev/pts/0
MAIL=/var/mail/shs
TERM=xterm
SHELL=/bin/bash
SHLVL=1
LOGNAME=shs
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
XDG_RUNTIME_DIR=/run/user/1000
PATH=/home/shs/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
LESSOPEN=| /usr/bin/lesspipe %s
_=/usr/bin/env
```
虽然你可能会看到大量的输出,上面显示的第一大部分用于在命令行上使用颜色标识各种文件类型。当你看到类似 `*.tar=01;31:` 这样的东西,这告诉你 `tar` 文件将以红色显示在文件列表中,然而 `*.jpg=01;35:` 告诉你 jpg 文件将以紫色显现出来。这些颜色旨在使它易于从一个文件列表中分辨出某些文件。你可以在《[在 Linux 命令行中自定义你的颜色][3]》处学习更多关于这些颜色的定义,和如何自定义它们。
当你更喜欢一种不加装饰的显示时,一种关闭颜色显示的简单方法是使用如下命令:
```
$ ls -l --color=never
```
这个命令可以简单地转换到一个别名:
```
$ alias ll2='ls -l --color=never'
```
你也可以使用 `echo` 命令来单独地显现某个设置。在这个命令中,我们显示在历史缓存区中将被记忆命令的数量:
```
$ echo $HISTSIZE
1000
```
如果你已经移动到某个位置,你在文件系统中的最后位置会被记在这里:
```
PWD=/home/shs
OLDPWD=/tmp
```
### 作出更改
你可以使用一个像这样的命令更改环境设置,但是,如果你希望保持这个设置,在你的 `~/.bashrc` 文件中添加一行代码,例如 `HISTSIZE=1234`
```
$ export HISTSIZE=1234
```
### “export” 一个变量的本意是什么
导出一个环境变量可使设置用于你的 shell 和可能的子 shell。默认情况下用户定义的变量是本地的并不被导出到新的进程例如子 shell 和脚本。`export` 命令使得环境变量可用在子进程中发挥功用。
### 添加和移除变量
你可以很容易地在命令行和子 shell 上创建新的变量,并使它们可用。然而,当你登出并再次回来时这些变量将消失,除非你也将它们添加到 `~/.bashrc` 或一个类似的文件中。
```
$ export MSG="Hello, World!"
```
如果你需要,你可以使用 `unset` 命令来消除一个变量:
```
$ unset MSG
```
如果变量是局部定义的,你可以通过加载你的启动文件来简单地将其设置回来。例如:
```
$ echo $MSG
Hello, World!
$ unset $MSG
$ echo $MSG
$ . ~/.bashrc
$ echo $MSG
Hello, World!
```
### 小结
用户账户是用一组恰当的启动文件设立的,创建了一个有用的用户环境,而个人用户和系统管理员都可以通过编辑他们的个人设置文件(对于用户)或很多来自设置起源的文件(对于系统管理员)来更改默认设置。
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3385516/how-to-manage-your-linux-environment.html
作者:[Sandra Henry-Stocker][a]
选题:[lujun9972][b]
译者:[robsean](https://github.com/robsean)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
[b]: https://github.com/lujun9972
[1]: https://images.idgesg.net/images/article/2019/03/environment-rocks-leaves-100792229-large.jpg
[2]: https://www.youtube.com/playlist?list=PL7D2RMSmRO9J8OTpjFECi8DJiTQdd4hua
[3]: https://www.networkworld.com/article/3269587/customizing-your-text-colors-on-the-linux-command-line.html
[4]: https://www.facebook.com/NetworkWorld/
[5]: https://www.linkedin.com/company/network-world

View File

@ -1,37 +1,37 @@
[#]: collector: (lujun9972)
[#]: translator: (StdioA)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10908-1.html)
[#]: subject: (Kubernetes on Fedora IoT with k3s)
[#]: via: (https://fedoramagazine.org/kubernetes-on-fedora-iot-with-k3s/)
[#]: author: (Lennart Jern https://fedoramagazine.org/author/lennartj/)
使用 k3s 在 Fedora IoT 上运行 Kubernetes
使用 k3s 在 Fedora IoT 上运行 K8S
======
![][1]
![](https://img.linux.net.cn/data/attachment/album/201905/28/094048yrzlik9oek5rbs5s.jpg)
Fedora IoT 是一个即将发布的、面相物联网的 Fedora 版本。去年 Fedora Magazine 中的《如何使用 Fedora IOT 点亮 LED》一文第一次介绍了它。从那以后,它与 Fedora Silverblue 一起不断改进,以提供针对面相容器的工作流程的不可变基础操作系统。
Fedora IoT 是一个即将发布的、面向物联网的 Fedora 版本。去年 Fedora Magazine 的《[如何使用 Fedora IoT 点亮 LED 灯][2]》一文第一次介绍了它。从那以后,它与 Fedora Silverblue 一起不断改进,以提供针对面向容器的工作流的不可变基础操作系统。
Kubernetes 是一个颇受欢迎的容器编排系统。它可能最常用在那些能够处理巨大负载的强劲硬件上。不过,它也能在像树莓派 3 这样轻量级的设备上运行。我们继续阅读,来了解如何运行它。
Kubernetes 是一个颇受欢迎的容器编排系统。它可能最常用在那些能够处理巨大负载的强劲硬件上。不过,它也能在像树莓派 3 这样轻量级的设备上运行。我们继续阅读,来了解如何运行它。
### 为什么用 Kubernetes
虽然 Kubernetes 在云计算领域风靡一时,但让它在小型单板机上运行可能并不是显而易见的。不过,我们有非常明确的理由来做这件事。首先,这是一个不需要昂贵硬件就可以学习并熟悉 Kubernetes 的好方法;其次,由于它的流行性,市面上有[大量应用][2]进行了预先打包,以用于在 Kubernetes 集群中运行。更不用说,当你遇到问题时,会有大规模的社区用户为你提供帮助。
虽然 Kubernetes 在云计算领域风靡一时,但让它在小型单板机上运行可能并不是见的。不过,我们有非常明确的理由来做这件事。首先,这是一个不需要昂贵硬件就可以学习并熟悉 Kubernetes 的好方法;其次,由于它的流行性,市面上有[大量应用][3]进行了预先打包,以用于在 Kubernetes 集群中运行。更不用说,当你遇到问题时,会有大规模的社区用户为你提供帮助。
最后但同样重要的是,即使是在家庭实验室这样的小规模环境中,容器编排也确实能事情变得更加简单。虽然在学习曲线方面,这一点并不明显,但这些技能在你将来与任何集群打交道的时候都会有帮助。不管你面对的是一个单节点树莓派集群,还是一个大规模的机器学习场,它们的操作方式都是类似的。
最后但同样重要的是,即使是在家庭实验室这样的小规模环境中,容器编排也确实能够使事情变得更加简单。虽然在学习曲线方面,这一点并不明显,但这些技能在你将来与任何集群打交道的时候都会有帮助。不管你面对的是一个单节点树莓派集群,还是一个大规模的机器学习场,它们的操作方式都是类似的。
#### K3s - 轻量级的 Kubernetes
一个 Kubernetes 的“正常”安装如果有这么一说的话对于物联网来说有点沉重。K8s 的推荐内存配置,是每台机器 2GB不过我们也有一些替代品其中一个新人是 [k3s][4]——一个轻量级的 Kubernetes 发行版。
一个“正常”安装的 Kubernetes如果有这么一说的话对于物联网来说有点沉重。K8s 的推荐内存配置,是每台机器 2GB不过我们也有一些替代品其中一个新人是 [k3s][4] —— 一个轻量级的 Kubernetes 发行版。
K3s 非常特殊,因为它将 etcd 替换成了 SQLite 以满足键值存储需求。还有一点,在于整个 k3s 将使用一个二进制文件分发,而不是每个组件一个。这减少了内存占用并简化了安装过程。基于上述原因,我们只需要 512MB 内存即可运行 k3s简直适合小型单板电脑!
K3s 非常特殊,因为它将 etcd 替换成了 SQLite 以满足键值存储需求。还有一点,在于整个 k3s 将使用一个二进制文件分发,而不是每个组件一个。这减少了内存占用并简化了安装过程。基于上述原因,我们只需要 512MB 内存即可运行 k3s极度适合小型单板电脑!
### 你需要的东西
1. 在虚拟机或实体设备中运行的 Fedora IoT。在[这里][5]可以看到优秀的入门指南。一台机器就足够了,不过两台可以用来测试向集群添加更多节点。
2. [配置防火墙][6],允许 6443 和 8372 端口的通信。或者,你也可以简单地运行“systemctl stop firewalld”来为这次实验关闭防火墙。
1. Fedora IoT 运行在虚拟机或实体设备中运行的。在[这里][5]可以看到优秀的入门指南。一台机器就足够了,不过两台可以用来测试向集群添加更多节点。
2. [配置防火墙][6],允许 6443 和 8372 端口的通信。或者,你也可以简单地运行 `systemctl stop firewalld` 来为这次实验关闭防火墙。
### 安装 k3s
@ -49,14 +49,14 @@ kubectl get nodes
需要注意的是,有几个选项可以通过环境变量传递给安装脚本。这些选项可以在[文档][7]中找到。当然,你也完全可以直接下载二进制文件来手动安装 k3s。
对于实验和学习来说,这样已经很棒了,不过单节点的集群也不一个集群。幸运的是,添加另一个节点并不比设置第一个节点要难。只需要向安装脚本传递两个环境变量,它就可以找到第一个节点,避免运行 k3s 的服务器部分。
对于实验和学习来说,这样已经很棒了,不过单节点的集群也不能算一个集群。幸运的是,添加另一个节点并不比设置第一个节点要难。只需要向安装脚本传递两个环境变量,它就可以找到第一个节点,而不用运行 k3s 的服务器部分。
```
curl -sfL https://get.k3s.io | K3S_URL=https://example-url:6443 \
K3S_TOKEN=XXX sh -
```
上面的 example-url 应被替换为第一个节点的 IP 地址,或一个经过完全限定域名。在该节点中,(用 XXX 表示的)令牌可以在 /var/lib/rancher/k3s/server/node-token 文件中找到。
上面的 `example-url` 应被替换为第一个节点的 IP 地址,或一个完全限定域名。在该节点中,(用 XXX 表示的)令牌可以在 `/var/lib/rancher/k3s/server/node-token` 文件中找到。
### 部署一些容器
@ -66,19 +66,19 @@ curl -sfL https://get.k3s.io | K3S_URL=https://example-url:6443 \
kubectl create deployment my-server --image nginx
```
这会从名为“nginx”的容器镜像中创建出一个名叫“my-server”的 [Deployment][8](镜像名默认使用 docker hub 注册中心,以及 latest 标签)。
这会从名为 `nginx` 的容器镜像中创建出一个名叫 `my-server` 的 [部署][8](默认使用 docker hub 注册中心,以及 `latest` 标签)。
```
kubectl get pods
```
为了接触到 pod 中运行的 nginx 服务器,首先将 Deployment 通过一个 [Service][9] 来进行暴露。以下命令将创建一个与 Deployment 同名的 Service
为了访问到 pod 中运行的 nginx 服务器,首先通过一个 [服务][9] 来暴露该部署。以下命令将创建一个与该部署同名的服务
```
kubectl expose deployment my-server --port 80
```
Service 将作为一种负载均衡器和 Pod 的 DNS 记录来工作。比如,当运行第二个 Pod 时,我们只需指定 _my-server_Service 名称)就可以通过 _curl_ 访问 nginx 服务器。有关如何操作,可以看下面的实例。
服务将作为一种负载均衡器和 Pod 的 DNS 记录来工作。比如,当运行第二个 Pod 时,我们只需指定 `my-server`(服务名称)就可以通过 `curl` 访问 nginx 服务器。有关如何操作,可以看下面的实例。
```
# 启动一个 pod在里面以交互方式运行 bash
@ -90,15 +90,15 @@ curl my-server
### Ingress 控制器及外部 IP
默认状态下,一个 Service 只能获得一个 ClusterIP只能从集群内部访问但你也可以通过把它的类型设置为 [LoadBalancer][10] 为服务申请一个外部 IP。不过并非所有应用都需要自己的 IP 地址。相反,通常可以通过基于 Host 请求头部或请求路径进行路由,从而使多个服务共享一个 IP 地址。你可以在 Kubernetes 使用 [Ingress][11] 完成此操作而这也是我们要做的。Ingress 也提供了额外的功能,比如无需配置应用即可对流量进行 TLS 加密。
默认状态下,一个服务只能获得一个 ClusterIP只能从集群内部访问但你也可以通过把它的类型设置为 [LoadBalancer][10] 为服务申请一个外部 IP。不过并非所有应用都需要自己的 IP 地址。相反,通常可以通过基于 Host 请求头部或请求路径进行路由,从而使多个服务共享一个 IP 地址。你可以在 Kubernetes 使用 [Ingress][11] 完成此操作而这也是我们要做的。Ingress 也提供了额外的功能,比如无需配置应用即可对流量进行 TLS 加密。
Kubernetes 需要入口控制器来使 Ingress 资源工作k3s 包含 [Traefik][12] 正是出于此目的。它还包含了一个简单的服务负载均衡器,可以为集群中的服务提供外部 IP。这篇[文档][13]描述了这种服务:
Kubernetes 需要 Ingress 控制器来使 Ingress 资源工作k3s 包含 [Traefik][12] 正是出于此目的。它还包含了一个简单的服务负载均衡器,可以为集群中的服务提供外部 IP。这篇[文档][13]描述了这种服务:
> k3s 包含一个使用可用主机端口的基础服务负载均衡器。比如,如果你尝试创建一个监听 80 端口的负载均衡器,它会尝试在集群中寻找一个 80 端口空闲的节点。如果没有可用端口,那么负载均衡器将保持在 Pending 状态。
>
> k3s README
入口控制器已经通过这个负载均衡器暴露在外。你可以使用以下命令找到它正在使用的 IP 地址。
Ingress 控制器已经通过这个负载均衡器暴露在外。你可以使用以下命令找到它正在使用的 IP 地址。
```
$ kubectl get svc --all-namespaces
@ -109,13 +109,13 @@ NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
kube-system traefik LoadBalancer 10.43.145.104 10.0.0.8 80:31596/TCP,443:31539/TCP 33d
```
找到名为 traefik 的 Service。在上面的例子中,我们感兴趣的 IP 是 10.0.0.8。
找到名为 `traefik` 的服务。在上面的例子中,我们感兴趣的 IP 是 10.0.0.8。
### 路由传入的请求
让我们创建一个 Ingress使它通过基于 Host 头部的路由规则将请求路由至我们的服务器。这个例子中我们使用 [xip.io][14] 来避免必要的 DNS 记录配置工作。它的工作原理是将 IP 地址作为子域包含,以使用10.0.0.8.xip.io的任何子域来达到IP 10.0.0.8。换句话说my-server.10.0.0.8.xip.io 被用于访问集群中的入口控制器。你现在就可以尝试(使用你自己的 IP而不是 10.0.0.8)。如果没有入口你应该会访问到“默认后端”只是一个写着“404 page not found”的页面。
让我们创建一个 Ingress使它通过基于 Host 头部的路由规则将请求路由至我们的服务器。这个例子中我们使用 [xip.io][14] 来避免必要的 DNS 记录配置工作。它的工作原理是将 IP 地址作为子域包含,以使用 `10.0.0.8.xip.io` 的任何子域来达到 IP `10.0.0.8`。换句话说,`my-server.10.0.0.8.xip.io` 被用于访问集群中的 Ingress 控制器。你现在就可以尝试(使用你自己的 IP而不是 10.0.0.8)。如果没有 Ingress你应该会访问到“默认后端”只是一个写着“404 page not found”的页面。
我们可以使用以下 Ingress 让入口控制器将请求路由到我们的 Web 服务器 Service
我们可以使用以下 Ingress 让 Ingress 控制器将请求路由到我们的 Web 服务器的服务
```
apiVersion: extensions/v1beta1
@ -133,17 +133,17 @@ spec:
servicePort: 80
```
将以上片段保存到 _my-ingress.yaml_ 文件中,然后运行以下命令将其加入集群:
将以上片段保存到 `my-ingress.yaml` 文件中,然后运行以下命令将其加入集群:
```
kubectl apply -f my-ingress.yaml
```
你现在应该能够在你选择的完全限定域名中访问到 nginx 的默认欢迎页面了。在我的例子中,它是 my-server.10.0.0.8.xip.io。入口控制器会通过 Ingress 中包含的信息来路由请求。对 my-server.10.0.0.8.xip.io 的请求将被路由到 Ingress 中定义为“后端”的 Service 和端口(在本例中为 my-server 和 80)。
你现在应该能够在你选择的完全限定域名中访问到 nginx 的默认欢迎页面了。在我的例子中,它是 `my-server.10.0.0.8.xip.io`。Ingress 控制器会通过 Ingress 中包含的信息来路由请求。对 `my-server.10.0.0.8.xip.io` 的请求将被路由到 Ingress 中定义为 `backend` 的服务和端口(在本例中为 `my-server``80`)。
### 那么,物联网呢?
想象如下场景:你的家伙农场周围有很多的设备。它是一个具有各种硬件功能,传感器和执行器的物联网设备的异构集合。也许某些设备拥有摄像头,天气或光线传感器。其它设备可能会被连接起来用来控制通风、灯光、百叶窗或闪烁的LED。
想象如下场景:你的家或农场周围有很多的设备。它是一个具有各种硬件功能、传感器和执行器的物联网设备的异构集合。也许某些设备拥有摄像头、天气或光线传感器。其它设备可能会被连接起来,用来控制通风、灯光、百叶窗或闪烁的 LED。
这种情况下,你想从所有传感器中收集数据,在最终使用它来制定决策和控制执行器之前,也可能会对其进行处理和分析。除此之外,你可能还想配置一个仪表盘来可视化那些正在发生的事情。那么 Kubernetes 如何帮助我们来管理这样的事情呢?我们怎么保证 Pod 在合适的设备上运行?
@ -155,13 +155,13 @@ kubectl label nodes <node-name> <label-key>=<label-value>
kubectl label nodes node2 camera=available
```
一旦它们被打上标签,我们就可以轻松地使用 [nodeSelector][15] 为你的工作负载选择合适的节点。拼图的最后一块:如果你想在_所有_合适的节点上运行 Pod那应该使用 [DaemonSet][16] 而不是 Deployment。换句话说,应为每个使用唯一传感器的数据收集应用程序创建一个 DaemonSet并使用 nodeSelectors 确保它们仅在具有适当硬件的节点上运行。
一旦它们被打上标签,我们就可以轻松地使用 [nodeSelector][15] 为你的工作负载选择合适的节点。拼图的最后一块:如果你想在*所有*合适的节点上运行 Pod那应该使用 [DaemonSet][16] 而不是部署。换句话说,应为每个使用唯一传感器的数据收集应用程序创建一个 DaemonSet并使用 nodeSelector 确保它们仅在具有适当硬件的节点上运行。
服务发现功能允许 Pod 通过 Service 名称来寻找彼此,这项功能使得这类分布式系统的管理工作变得易如反掌。你不需要为应用配置 IP 地址或自定义端口,也不需要知道它们。相反,它们可以通过集群中的具名 Service 轻松找到彼此。
服务发现功能允许 Pod 通过服务名称来寻找彼此,这项功能使得这类分布式系统的管理工作变得易如反掌。你不需要为应用配置 IP 地址或自定义端口,也不需要知道它们。相反,它们可以通过集群中的命名服务轻松找到彼此。
#### 充分利用空闲资源
随着集群的启动并运行,收集数据并控制灯光和气候可能使你觉得你已经把它完成了。不过,集群中还有大量的计算资源可以用于其它项目。这才是 Kubernetes 真正出彩的地方。
随着集群的启动并运行,收集数据并控制灯光和气候可能使你觉得你已经把它完成了。不过,集群中还有大量的计算资源可以用于其它项目。这才是 Kubernetes 真正出彩的地方。
你不必担心这些资源的确切位置,或者去计算是否有足够的内存来容纳额外的应用程序。这正是编排系统所解决的问题!你可以轻松地在集群中部署更多的应用,让 Kubernetes 来找出适合运行它们的位置(或是否适合运行它们)。
@ -182,14 +182,14 @@ via: https://fedoramagazine.org/kubernetes-on-fedora-iot-with-k3s/
作者:[Lennart Jern][a]
选题:[lujun9972][b]
译者:[StdioA](https://github.com/StdioA)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/lennartj/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2019/04/k3s-1-816x345.png
[2]: https://fedoramagazine.org/turnon-led-fedora-iot/
[2]: https://linux.cn/article-10380-1.html
[3]: https://hub.helm.sh/
[4]: https://k3s.io
[5]: https://docs.fedoraproject.org/en-US/iot/getting-started/

View File

@ -1,8 +1,8 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10903-1.html)
[#]: subject: (3 apps to manage personal finances in Fedora)
[#]: via: (https://fedoramagazine.org/3-apps-to-manage-personal-finances-in-fedora/)
[#]: author: (Paul W. Frields https://fedoramagazine.org/author/pfrields/)
@ -14,15 +14,15 @@
网上有很多可以用来管理你个人财务的服务。虽然它们可能很方便,但这通常也意味着将你最宝贵的个人数据放在你无法监控的公司。也有些人对这些不太在意。
无论你是否在意,你可能会对你自己系统上的应用感兴趣。这意味着如果你不想,你的数据永远不会离开自己的计算机。这三款之一可能就是你想找的。
无论你是否在意,你可能会对你自己系统上的应用感兴趣。这意味着如果你不想,你的数据永远不会离开自己的计算机。这三款之一可能就是你想找的。
### HomeBank
HomeBank 是一款可以管理多个账户的全功能软件。它很容易设置并保持更新。它有多种方式画出你的分类和负,以便你可以看到资金流向何处。它可以通过官方 Fedora 仓库下载。
HomeBank 是一款可以管理多个账户的全功能软件。它很容易设置并保持更新。它有多种方式画出你的分类和负,以便你可以看到资金流向何处。它可以通过官方 Fedora 仓库下载。
![A simple account set up in HomeBank with a few transactions.][2]
要安装 HomeBank请打开_软件中心_搜索 _HomeBank_然后选择该应用。单击_安装_将其添加到你的系统中。HomeBank 也可以通过 Flatpak 安装。
要安装 HomeBank请打开“软件中心”,搜索 “HomeBank”然后选择该应用。单击“安装”将其添加到你的系统中。HomeBank 也可以通过 Flatpak 安装。
### KMyMoney
@ -42,13 +42,13 @@ $ sudo dnf install kmymoney
![Checking account records shown in GnuCash.][5]
打开_软件中心_搜索 _GnuCash_然后选择应用。单击_安装_将其添加到你的系统中。或者如上所述使用 _dnf install_ 来安装 _gnucash_ 包。
打开“软件中心”,搜索 “GnuCash”然后选择应用。单击“安装”将其添加到你的系统中。或者如上所述使用 `dnf install` 来安装 “gnucash” 包。
它现在可以通过 Flathub 安装,这使得安装变得简单。如果你没有安装 Flathub请查看 [Fedora Magazine 上的这篇文章][6]了解如何使用它。这样你也可以在终端使用 _flatpak install GnuCash_ 命令。
它现在可以通过 Flathub 安装,这使得安装变得简单。如果你没有安装 Flathub请查看 [Fedora Magazine 上的这篇文章][6]了解如何使用它。这样你也可以在终端使用 `flatpak install gnucash` 命令。
* * *
照片由 _[_Fabian Blank_][7]_ 拍摄,发布在 [ _Unsplash_][8] 上。
照片由 [Fabian Blank][7] 拍摄,发布在 [Unsplash][8] 上。
--------------------------------------------------------------------------------
@ -57,7 +57,7 @@ via: https://fedoramagazine.org/3-apps-to-manage-personal-finances-in-fedora/
作者:[Paul W. Frields][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -1,28 +1,30 @@
[#]: collector: (lujun9972)
[#]: translator: (MjSeven)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10900-1.html)
[#]: subject: (API evolution the right way)
[#]: via: (https://opensource.com/article/19/5/api-evolution-right-way)
[#]: author: (A. Jesse https://opensource.com/users/emptysquare)
API 演进的正确方式
======
负责任的库作者与其用户保持的十个约定。
![Browser of things][1]
想象你是一个创造之神,为一个生物设计一个身体。出于仁慈,你希望这个生物能随着时间进化:首先,因为它必须对环境的变化作出反应,其次,因为你的智慧在增长,你想到了更好的设计。它不应该永远留在同一个身体里!
> 负责任的库作者与其用户的十个约定。
![Browser of things](https://img.linux.net.cn/data/attachment/album/201905/26/134131jnymeg7t7gmo6qcy.jpg)
想象一下你是一个造物主,为一个生物设计一个身体。出于仁慈,你希望它能随着时间进化:首先,因为它必须对环境的变化作出反应;其次,因为你的智慧在增长,你对这个小东西想到了更好的设计,它不应该永远保持一个样子。
![Serpents][2]
然而,该生物可能依赖于其目前解剖学的特征。你不能在没有警告的情况下添加翅膀或改变它的比例。它需要一个有序的过程来适应新的身体。作为一个负责任的设计师,你如何才能温柔地引导这种生物走向更大的进步呢?
然而,这个生物可能有赖于其目前解剖学的特征。你不能无所顾忌地添加翅膀或改变它的身材比例。它需要一个有序的过程来适应新的身体。作为一个负责任的设计者,你如何才能温柔地引导这种生物走向更大的进步呢?
对于负责任的库维护者也是如此。我们向依赖我们代码的人保证我们的承诺:我们发布 bug 修复和有用的新特性。如果对库的未来有利,我们有时会删除特性。我们不断创新,但我们不会破坏使用我们库的人的代码。我们怎样才能一次实现所有这些目标呢?
对于负责任的库维护者也是如此。我们向依赖我们代码的人保证我们的承诺:我们发布 bug 修复和有用的新特性。如果对库的未来有利,我们有时会删除某些特性。我们不断创新,但我们不会破坏使用我们库的人的代码。我们怎样才能一次实现所有这些目标呢?
### 添加有用的特性
你的库不应该永远保持不变:你应该添加一些特性,使你的库更适合用户。例如,如果你有一个爬行动物类,并且有翅膀飞行是有用的,那就去添加吧。
你的库不应该永远保持不变:你应该添加一些特性,使你的库更适合用户。例如,如果你有一个爬行动物类,并且如果有个可以飞行的翅膀是有用的,那就去添加吧。
```
class Reptile:
@ -47,7 +49,8 @@ bool(datetime.time(0, 0)) == False
我已经写了十多年的 Python 了,但直到上周才发现这条规则。这种奇怪的行为会在用户代码中引起什么样的 bug
考虑一个日历应用程序,它带有一个创建事件的函数。如果一个事件有一个结束时间,那么函数也应该要求它有一个开始时间。
比如说一个日历应用程序,它带有一个创建事件的函数。如果一个事件有一个结束时间,那么函数也应该要求它有一个开始时间。
```
def create_event(day,
start_time=None,
@ -55,13 +58,13 @@ def create_event(day,
if end_time and not start_time:
raise ValueError("Can't pass end_time without start_time")
# 女巫集会从午夜一直开到凌晨 4 点
# 女巫集会从午夜一直开到凌晨 4 点
create_event(datetime.date.today(),
datetime.time(0, 0),
datetime.time(4, 0))
```
不幸的是,对于女巫来说,从午夜开始的事件无法通过验。当然,一个了解午夜怪癖的细心程序员可以正确地编写这个函数。
不幸的是,对于女巫来说,从午夜开始的事件无法通过验。当然,一个了解午夜怪癖的细心程序员可以正确地编写这个函数。
```
def create_event(day,
@ -71,13 +74,13 @@ def create_event(day,
raise ValueError("Can't pass end_time without start_time")
```
但这种微妙之处令人担忧。如果一个库作者想要创建一个对用户有害的 API那么像午夜的布尔转换这样的“特性”很有效。
但这种微妙之处令人担忧。如果一个库作者想要创建一个伤害用户的 API那么像午夜的布尔转换这样的“特性”很有效。
![Man being chased by an alligator][3]
但是,负责任的创建者的目标是使你的库易于正确使用。
这个功能是由 Tim Peters 在 2002 年首次编写 datetime 模块时造成的。即时是像 Tim 这样的 Python 创始人也会犯错误。[这个怪异后来被消除了][4],现在所有时间的布尔值都是 True。
这个功能是由 Tim Peters 在 2002 年首次编写 datetime 模块时造成的。即时是像 Tim 这样的奠基 Python 的高手也会犯错误。[这个怪异之处后来被消除了][4],现在所有时间的布尔值都是 True。
```
# Python 3.5 以后
@ -86,15 +89,15 @@ bool(datetime.time(9, 30)) == True
bool(datetime.time(0, 0)) == True
```
不知道午夜古怪之处的程序员现在可以从晦涩的 bug 中解脱出来,但是一想到任何依赖于古怪的旧行为的代码现在没有注意变化,我会感到紧张。如果根本不实现这个糟糕的特性,情况会更好。这就引出了库维护者的第一个承诺:
不知道午夜怪癖的古怪之处的程序员现在可以从这种晦涩的 bug 中解脱出来,但是一想到任何依赖于古怪的旧行为的代码现在没有注意变化,我就会感到紧张。如果从来没有实现这个糟糕的特性,情况会更好。这就引出了库维护者的第一个承诺:
#### 第一个约定:避免糟糕的特性
最痛苦的变化是你必须删除一个特性。一般来说,避免糟糕特性的一种方法是添加少的特性!没有充分的理由,不要使用公共方法、类、功能或属性。因此:
最痛苦的变化是你必须删除一个特性。一般来说,避免糟糕特性的一种方法是添加特性!没有充分的理由,不要使用公共方法、类、功能或属性。因此:
#### 第二个约定:最小化特性
特性就像孩子:在充满激情的瞬间孕育,to 校正:我怀疑作者在开车,可是我没有证据)它们必须得到多年的支持。不要因为你能做傻事就去做傻事。不要画蛇添足to 校正:我认为这里内在是这个意思)
特性就像孩子:在充满激情的瞬间孕育,但是它们必须要支持多年LCTT 译注:我怀疑作者在开车,可是我没有证据)。不要因为你能做傻事就去做傻事。不要画蛇添足!
![Serpents with and without feathers][5]
@ -110,13 +113,14 @@ async def my_coroutine():
print(my_coroutine())
```
```
<coroutine object my_coroutine at 0x10bfcbac8>
```
你的代码必须 "await" 这个对象以此来运行协程。很容易忘记这一点,所以 asyncio 的开发人员想要一个“调试模式”来捕捉这个错误。但协程在没有 await 的情况下被销毁时,调试模式将打印一个警告,并在其创建的行上进行回溯。
你的代码必须 <ruby>等待<rt>await</rt></ruby>” 这个对象以此来运行协程。人们很容易忘记这一点,所以 asyncio 的开发人员想要一个“调试模式”来捕捉这个错误。当协程在没有等待的情况下被销毁时,调试模式将打印一个警告,并在其创建的行上进行回溯。
当 Yury Selivanov 实现调试模式时,他在其基础上添加了一个“协程装饰器”特性。装饰器是一个函数,它接收一个协程并返回所有内容。Yury 使用它在每个协程上安装警告逻辑,但是其他人可以使用它将协程转换为字符串 "hi!"
当 Yury Selivanov 实现调试模式时,他添加了一个“协程装饰器”的基础特性。装饰器是一个函数,它接收一个协程并返回任何内容。Yury 使用它在每个协程上接入警告逻辑,但是其他人可以使用它将协程转换为字符串 “hi!”
```
import sys
@ -131,15 +135,16 @@ async def my_coroutine():
print(my_coroutine())
```
```
hi!
```
这是一个地狱般的定制。它改变了 "async" 的含义。一次调用 `set_coroutine_wrapper` 将在全局永久改变所有的协程函数。正如 [Nathaniel Smith 所说][6]:“一个有问题的 API” 很容易被误用,必须被删除。如果异步开发人员能够更好地按照其目标来设计该特性,他们就可以避免删除该特性的痛苦。负责任的创建者必须牢记这一点:
这是一个地狱般的定制。它改变了 <ruby>异步<rt>async</rt></ruby>" 的含义。调用一次 `set_coroutine_wrapper` 将在全局永久改变所有的协程函数。正如 [Nathaniel Smith 所说][6]:“一个有问题的 API” 很容易被误用,必须被删除。如果 asyncio 开发人员能够更好地按照其目标来设计该特性,他们就可以避免删除该特性的痛苦。负责任的创建者必须牢记这一点:
#### 第三个约定:保持特性单一
幸运的是Yury 有良好的判断力,他将特性标记为临时,所以 asyncio 用户知道不能依赖它。Nathaniel 可以用更单一的功能替换 **set_coroutine_wrapper** ,该特性只定制回溯深度。
幸运的是Yury 有良好的判断力,他将特性标记为临时,所以 asyncio 用户知道不能依赖它。Nathaniel 可以用更单一的功能替换 `set_coroutine_wrapper`,该特性只定制回溯深度。
```
import sys
@ -152,6 +157,7 @@ async def my_coroutine():
print(my_coroutine())
```
```
<coroutine object my_coroutine at 0x10bfcbac8>
@ -162,27 +168,27 @@ Coroutine created at (most recent call last)
print(my_coroutine())
```
这样好多了。没有其他全局设置可以更改协程的类型,因此 asyncio 用户无需编写防御代码。神灵应该像 Yury 一样有远见。
这样好多了。没有可以更改协程的类型的其他全局设置,因此 asyncio 用户无需编写防御代码。造物主应该像 Yury 一样有远见。
#### 第四个约定:标记实验特征“临时”
如果你只是预感你的生物需要犄角和四叉舌,那就介绍一下这些特性,但将它们标记为“临时”。
如果你只是预感你的生物需要犄角和四叉舌,那就引入这些特性,但将它们标记为“临时”。
![Serpent with horns][7]
你可能会发现犄角是无关紧要的,但是四叉舌是有用的。在库的下一个版本中,你可以删除前者并标记后者。
你可能会发现犄角是无关紧要的,但是四叉舌是有用的。在库的下一个版本中,你可以删除前者并标记后者为正式的
### 删除特性
无论我们如何明智地指导我们的生物进化,总会有一天最好删除一个官方特征。例如,你可能已经创建了一只蜥蜴,现在你选择删除它的腿。也许你想把这个笨拙的家伙变成一条时尚而现代的蟒蛇。
无论我们如何明智地指导我们的生物进化,总会有一天想要删除一个正式特征。例如,你可能已经创建了一只蜥蜴,现在你选择删除它的腿。也许你想把这个笨拙的家伙变成一条时尚而现代的蟒蛇。
![Lizard transformed to snake][8]
删除特性主要有两个原因。首先,通过用户反馈或者你自己不断增长的智慧,你可能会发现某个特性是个坏主意。午夜的古怪行为就是这种情况。或者,最初该特性可能已经很好地适应了你的库环境,但现在生态环境发生了变化,也许另一个神发明了哺乳动物,你的生物想要挤进哺乳动物的小洞穴里,吃掉里面美味的哺乳动物,所以它不得不失去双腿。
删除特性主要有两个原因。首先,通过用户反馈或者你自己不断增长的智慧,你可能会发现某个特性是个坏主意。午夜怪癖的古怪行为就是这种情况。或者,最初该特性可能已经很好地适应了你的库环境,但现在生态环境发生了变化,也许另一个神发明了哺乳动物,你的生物想要挤进哺乳动物的小洞穴里,吃掉里面美味的哺乳动物,所以它不得不失去双腿。
![A mouse][9]
同样Python 标准库会根据语言本身的变化删除特性。考虑 asyncio 的 Lock 功能,在把 "await" 作为一个关键字添加进来之前,它一直在等待:
同样Python 标准库会根据语言本身的变化删除特性。考虑 asyncio 的 Lock 功能,在把 `await` 作为一个关键字添加进来之前,它一直在等待:
```
lock = asyncio.Lock()
@ -195,7 +201,7 @@ async def critical_section():
lock.release()
```
但是现在,我们可以做“锁同步”:
但是现在,我们可以做“异步锁”:
```
@ -208,18 +214,18 @@ async def critical_section():
新方法好多了!很短,并且在一个大函数中使用其他 try-except 块时不容易出错。因为“尽量找一种,最好是唯一一种明显的解决方案”,[旧语法在 Python 3.7 中被弃用][10],并且很快就会被禁止。
不可避免的是,生态变化会对你的代码产生影响,因此要学会温柔地删除特性。在此之前,请考虑删除它的成本或好处。负责任的维护者不愿意让用户更改大量代码或逻辑。(还记得 Python 3 在重新添加 "u" 字符串前缀之前删除它是多么痛苦吗?)如果代码删除是机械性的,就像一个简单的搜索和替换,或者如果该特性是危险的,那么它可能值得删除。
不可避免的是,生态变化会对你的代码产生影响,因此要学会温柔地删除特性。在此之前,请考虑删除它的成本或好处。负责任的维护者不愿意让用户更改大量代码或逻辑。(还记得 Python 3 在重新添加`u` 字符串前缀之前删除它是多么痛苦吗?)如果代码删除是机械性的动作,就像一个简单的搜索和替换,或者如果该特性是危险的,那么它可能值得删除。
#### 是否删除特性
![Balance scales][11]
Con | Pro
反对 | 支持
---|---
代码必须改变 | 改变是机械性的
逻辑必须改变 | 特性是危险的
就我们饥饿的蜥蜴而言,我们决定删除它的腿,这样它就可以滑进老鼠洞里吃掉它。我们该怎么做呢?我们可以删除 **walk** 方法,像下面一样修改代码:
就我们饥饿的蜥蜴而言,我们决定删除它的腿,这样它就可以滑进老鼠洞里吃掉它。我们该怎么做呢?我们可以删除 `walk` 方法,像下面一样修改代码:
```
class Reptile:
@ -229,7 +235,6 @@ class Reptile:
变成这样:
```
class Reptile:
def slither(self):
@ -238,7 +243,6 @@ class Reptile:
这不是一个好主意,这个生物习惯于走路!或者,就库而言,你的用户拥有依赖于现有方法的代码。当他们升级到最新库版本时,他们的代码将会崩溃。
```
# 用户的代码,哦,不!
Reptile.walk()
@ -248,7 +252,7 @@ Reptile.walk()
#### 第五条预定:温柔地删除
温柔删除一个特性需要几个步骤。从用腿走路的蜥蜴开始,首先添加新方法 "slither"。接下来,弃用旧方法。
温柔删除一个特性需要几个步骤。从用腿走路的蜥蜴开始,首先添加新方法 `slither`。接下来,弃用旧方法。
```
import warnings
@ -264,12 +268,11 @@ class Reptile:
print('slide slide slide')
```
Python 的 warnings 模块非常强大。默认情况下,它会将警告输出到 stderr每个代码位置只显示一次但你可以在其它选项中禁用警告或将其转换为异常。
Python 的 warnings 模块非常强大。默认情况下,它会将警告输出到 stderr每个代码位置只显示一次但你可以禁用警告或将其转换为异常,以及其它选项
一旦将这个警告添加到库中PyCharm 和其他 IDE 就会使用删除线呈现这个被弃用的方法。用户马上就知道该删除这个方法。
`Reptile().walk()`
<to 校正这里 walk 上有一个横线表示删除>
> Reptile().~~walk()~~
当他们使用升级后的库运行代码时会发生什么?
@ -282,10 +285,9 @@ DeprecationWarning: walk is deprecated, use slither
step step step
```
默认情况下,他们会在 stderr 上看到警告,但脚本会成功并打印 "step step step"。警告的回溯显示必须修复用户代码的哪一行。(这就是 "stacklevel" 参数的作用:它显示了用户需要更改的调用,而不是库中生成警告的行。)请注意,错误消息有指导意义,它描述了库用户迁移到新版本必须做的事情。
你的用户将希望测试他们的代码并证明他们没有调用不推荐的库方法。仅警告不会使单元测试失败但异常会失败。Python 有一个命令行选项,可以将弃用警告转换为异常。
默认情况下,他们会在 stderr 上看到警告,但脚本会成功并打印 “step step step”。警告的回溯显示必须修复用户代码的哪一行。这就是 `stacklevel` 参数的作用:它显示了用户需要更改的调用,而不是库中生成警告的行。)请注意,错误消息有指导意义,它描述了库用户迁移到新版本必须做的事情。
你的用户可能会希望测试他们的代码并证明他们没有调用弃用的库方法。仅警告不会使单元测试失败但异常会失败。Python 有一个命令行选项,可以将弃用警告转换为异常。
```
> python3 -Werror::DeprecationWarning script.py
@ -298,47 +300,44 @@ Traceback (most recent call last):
DeprecationWarning: walk is deprecated, use slither
```
现在,"step step step" 没有输出出来,因为脚本以一个错误终止。
现在,“step step step” 没有输出出来,因为脚本以一个错误终止。
因此,一旦你发布了库的一个版本,该版本会警告已启用的 "walk" 方法,你就可以在下一个版本中安全地删除它。对吧?
因此,一旦你发布了库的一个版本,该版本会警告已启用的 `walk` 方法,你就可以在下一个版本中安全地删除它。对吧?
考虑一下你的库用户在他们项目的 requirements 中可能有什么。
考虑一下你的库用户在他们项目的 `requirements` 中可能有什么。
```
# 用户的 requirements.txt 显示 reptile 包的依赖关系
reptile
```
下次他们部署代码时,他们将安装最新版本的库。如果他们尚未处理所有的弃用,那么他们的代码将会崩溃,因为代码仍然依赖 "walk"。你需要温柔一点,你必须向用户做出三个承诺:维护更改日志,选择版本方案和编写升级指南。
下次他们部署代码时,他们将安装最新版本的库。如果他们尚未处理所有的弃用,那么他们的代码将会崩溃,因为代码仍然依赖 `walk`。你需要温柔一点,你必须向用户做出三个承诺:维护更改日志,选择版本方案和编写升级指南。
#### 第六个约定:维护变更日志
你的库必须有更改日志,其主要目的是宣布用户所依赖的功能何时被弃用或删除。
---
#### 版本 1.1 中的更改
> **版本 1.1 中的更改**
>
> **新特性**
>
> * 新功能 Reptile.slither()
>
> **弃用**
>
> * Reptile.walk() 已弃用,将在 2.0 版本中删除,请使用 slither()
**新特性**
负责任的创建者会使用版本号来表示库发生了怎样的变化,以便用户能够对升级做出明智的决定。“版本化方案”是一种用于交流变化速度的语言。
* 新功能 Reptile.slither()
#### 第七个约定:选择一个版本化方案
**弃用**
* Reptile.walk() 已弃用,将在 2.0 版本中删除,请使用 slither()
---
负责任的创建者使用版本号来表示库发生了怎样的变化,以便用户能够对升级做出明智的决定。“版本方案”是一种用于交流变化速度的语言。
#### 第七个约定:选择一个版本方案
有两种广泛使用的方案,[语义版本控制][12]和基于时间的版本控制。我推荐任何库都进行语义版本控制。Python 的风格在 [PEP 440][13] 中定义,像 **pip** 这样的工具可以理解语义版本号。
有两种广泛使用的方案,[语义版本控制][12]和基于时间的版本控制。我推荐任何库都进行语义版本控制。Python 的风格在 [PEP 440][13] 中定义,像 `pip` 这样的工具可以理解语义版本号。
如果你为库选择语义版本控制,你可以使用版本号温柔地删除腿,例如:
> 1.0: First "stable" release, with walk()
> 1.1: Add slither(), deprecate walk()
> 2.0: Delete walk()
> 1.0: 第一个“稳定”版,带有 `walk()`
> 1.1: 添加 `slither()`,废弃 `walk()`
> 2.0: 删除 `walk()`
你的用户依赖于你的库的版本应该有一个范围,例如:
@ -347,33 +346,18 @@ reptile
reptile>=1,<2
```
这允许他们在主要版本中自动升级,接收错误修正并可能引发一些弃用警告,但不会升级到 _下_ 个主要版本并冒着破坏其代码的更改的风险。
这允许他们在主要版本中自动升级,接收错误修正并可能引发一些弃用警告,但不会升级到**下**个主要版本并冒着更改破坏其代码的风险。
如果你遵循基于时间的版本控制,则你的版本可能会编号:
> 2017.06.0: A release in June 2017
> 2018.11.0: Add slither(), deprecate walk()
> 2019.04.0: Delete walk()
> 2017.06.0: 2017 年 6 月的版本
> 2018.11.0: 添加 `slither()`,废弃 `walk()`
> 2019.04.0: 删除 `walk()`
用户可以依赖于你的库:
用户可以这样依赖于你的库:
```
# User's requirements.txt for time-based version.
reptile==2018.11.*
```
这允许他们在一个主要版本中自动升级,接收错误修复,并可能引发一些弃用警告,但不能升级到 _下_ 个主要版本,并冒着改变破坏代码的风险。
如果你遵循基于时间的版本控制,你的版本号可能是这样:
> 2017.06.0: A release in June 2017
> 2018.11.0: Add slither(), deprecate walk()
> 2019.04.0: Delete walk()
用户可以依赖你的库:
```
# 用户的 requirements.txt对于基于时间的版本
# 用户的 requirements.txt基于时间控制的版本
reptile==2018.11.*
```
@ -383,43 +367,40 @@ reptile==2018.11.*
下面是一个负责任的库创建者如何指导用户:
---
#### 升级到 2.0
> **升级到 2.0**
>
> **从弃用的 API 迁移**
>
> 请参阅更改日志以了解已弃用的特性。
>
> **启用弃用警告**
>
> 升级到 1.1 并使用以下代码测试代码:
>
> `python -Werror::DeprecationWarning`
>
> 现在可以安全地升级了。
**从弃用的 API 迁移**
请参阅更改日志以了解已弃用的特性。
**启用弃用警告**
升级到 1.1 并使用以下代码测试代码:
`python -Werror::DeprecationWarning`
​​​​​​现在可以安全地升级了。
---
你必须通过向用户显示命令行选项来教会用户如何处理弃用警告。并非所有 Python 程序员都知道这一点 - 当然,我每次都必须查找语法。注意,你必须 _release_ 一个版本,它输出来自每个弃用的 API 的警告以便用户可以在再次升级之前使用该版本进行测试。在本例中1.1 版本是小版本。它允许你的用户逐步重写代码,分别修复每个弃用警告,直到他们完全迁移到最新的 API。他们可以彼此独立地测试代码和库的更改并隔离 bug 的原因。
你必须通过向用户显示命令行选项来教会用户如何处理弃用警告。并非所有 Python 程序员都知道这一点 —— 我自己就每次都得查找这个语法。注意,你必须*发布*一个版本,它输出来自每个弃用的 API 的警告以便用户可以在再次升级之前使用该版本进行测试。在本例中1.1 版本是小版本。它允许你的用户逐步重写代码,分别修复每个弃用警告,直到他们完全迁移到最新的 API。他们可以彼此独立地测试代码和库的更改并隔离 bug 的原因。
如果你选择语义版本控制,则此过渡期将持续到下一个主要版本,从 1.x 到 2.0,或从 2.x 到 3.0 以此类推。删除生物腿部的温柔方法是至少给它一个版本来调整其生活方式。不要一次性把腿删掉!
![A skink][14]
版本号,弃用警告,更改日志和升级指南可以协同工作,在不违背与用户约定的情况下温柔地改进你的库。[Twisted 项目的兼容性政策][15] 解释的很漂亮:
版本号、弃用警告、更改日志和升级指南可以协同工作,在不违背与用户约定的情况下温柔地改进你的库。[Twisted 项目的兼容性政策][15] 解释的很漂亮:
> "The First One's Always Free"
> “先行者总是自由的”
>
> Any application which runs without warnings may be upgraded one minor version of Twisted.
> 运行的应用程序在没有任何警告的情况下都可以升级为 Twisted 的一个次要版本。
>
> 换句话说,任何运行其测试而不触发 Twisted 警告的应用程序应该能够将其 Twisted 版本升级至少一次,除了可能产生新警告之外没有任何不良影响。
>
> In other words, any application which runs its tests without triggering any warnings from Twisted should be able to have its Twisted version upgraded at least once with no ill effects except the possible production of new warnings.
现在,我们的造物之神已经获得了智慧和力量,可以通过添加方法来添加特性,并温柔地删除它们。我们还可以通过添加参数来添加特性,但这带来了新的难度。你准备好了吗?
现在,我们的造物已经获得了智慧和力量,可以通过添加方法来添加特性,并温柔地删除它们。我们还可以通过添加参数来添加特性,但这带来了新的难度。你准备好了吗?
### 添加参数
想象一下,你只是给了你的蛇形生物一对翅膀。现在你必须允许它选择是滑行还是飞行。目前它的 "move" 功能只接受一个参数。
想象一下,你只是给了你的蛇形生物一对翅膀。现在你必须允许它选择是滑行还是飞行。目前它的 `move` 功能只接受一个参数。
```
# 你的库代码
@ -430,8 +411,7 @@ def move(direction):
move('north')
```
你想要添加一个 "mode" 参数,但如果用户升级库,这会破坏他们的代码,因为他们只传递一个参数。
你想要添加一个 `mode` 参数,但如果用户升级库,这会破坏他们的代码,因为他们只传递了一个参数。
```
# 你的库代码
@ -443,7 +423,7 @@ def move(direction, mode):
move('north')
```
一个真正聪明的创建者者承诺不会以这种方式破坏用户的代码。
一个真正聪明的创建者者承诺不会以这种方式破坏用户的代码。
#### 第九条约定:兼容地添加参数
@ -459,7 +439,7 @@ def move(direction, mode='slither'):
move('north')
```
随着时间推移,参数是函数演化的自然历史。它们首先列出最老的,每个都有默认值。库用户可以传递关键字参数以选择特定的新行为,并接受所有其他行为的默认值。
随着时间推移,参数是函数演化的自然历史。它们首先列出最老的参数,每个都有默认值。库用户可以传递关键字参数以选择特定的新行为,并接受所有其他行为的默认值。
```
# 你的库代码
@ -481,7 +461,7 @@ move('north', extra_sinuous=True)
move('north', 'slither', False, True)
```
如果在你在库的下一个主要版本中去掉其中一个参数,例如 "turbo",会发生什么?
如果在你在库的下一个主要版本中去掉其中一个参数,例如 `turbo`,会发生什么?
```
# 你的库代码,下一个主要版本中 "turbo" 被删除
@ -495,7 +475,7 @@ def move(direction,
move('north', 'slither', False, True)
```
用户的代码仍然编译,这是一件坏事。代码停止了曲折的移动并开始呼 Lyft这不是它的本意。我相信你可以预测我接下来要说的内容删除参数需要几个步骤。当然首先弃用 "trubo" 参数。我喜欢这种技术,它可以检测任何用户的代码是否依赖于这个参数。
用户的代码仍然编译,这是一件坏事。代码停止了曲折的移动并开始呼 Lyft这不是它的本意。我相信你可以预测我接下来要说的内容删除参数需要几个步骤。当然首先弃用 `trubo` 参数。我喜欢这种技术,它可以检测任何用户的代码是否依赖于这个参数。
```
# 你的库代码
@ -516,7 +496,7 @@ def move(direction,
turbo = False
```
但是你的用户可能不会注意到警告。警告声音不是很大:它们可以在日志文件中被抑制或丢失。用户可能会漫不经心地升级到库的下一个主要版本,即删除 "turbo" 的版本。他们的代码运行将没有错误,默默做错误的事情!正如 Python 之禅所说:“错误绝不应该被默默 pass”。实际上爬行动物的听力很差所有当它们犯错误时你必须非常大声地纠正它们。
但是你的用户可能不会注意到警告。警告声音不是很大:它们可以在日志文件中被抑制或丢失。用户可能会漫不经心地升级到库的下一个主要版本——那个删除 `turbo` 的版本。他们的代码运行时将没有错误、默默做错误的事情!正如 Python 之禅所说:“错误绝不应该被默默 pass”。实际上爬行动物的听力很差所有当它们犯错误时你必须非常大声地纠正它们。
![Woman riding an alligator][16]
@ -524,7 +504,7 @@ def move(direction,
```
# 你的库代码
# All arguments after "*" must be passed by keyword.
# 所有 “*” 后的参数必须以关键字方式传输。
def move(direction,
*,
mode='slither',
@ -538,14 +518,14 @@ def move(direction,
move('north', 'slither', False, True)
```
有了这个星,以下唯一允许的语法:
有了这个星,以下唯一允许的语法:
```
# 用户代码
move('north', extra_sinuous=True)
```
现在,当你删除 "turbo" 时,你可以确定任何依赖于它的用户代码都会明显地提示失败。如果你的库也支持 Python2这没有什么大不了。你可以模拟星型语法[归功于 Brett Slatkin][17]
现在,当你删除 `turbo` 时,你可以确定任何依赖于它的用户代码都会明显地提示失败。如果你的库也支持 Python2这没有什么大不了。你可以模拟星型语法[归功于 Brett Slatkin][17]
```
# 你的库代码,兼容 Python 2
@ -562,7 +542,7 @@ def move(direction, **kwargs):
# ...
```
要求关键字参数是一个明智的选择,但它需要远见。如果允许按位置传递参数,则不能仅在以后的版本中将其转换为仅关键字。所以,现在加上星号你可以在 asyncio API 中观察到,它在构造函数、方法和函数中普遍使用星号。尽管到目前为止,"Lock" 只接受一个可选参数,但 asyncio 开发人员立即添加了星号。这是幸运的。
要求关键字参数是一个明智的选择,但它需要远见。如果允许按位置传递参数,则不能仅在以后的版本中将其转换为仅关键字。所以,现在加上星号你可以在 asyncio API 中观察到,它在构造函数、方法和函数中普遍使用星号。尽管到目前为止,`Lock` 只接受一个可选参数,但 asyncio 开发人员立即添加了星号。这是幸运的。
```
# In asyncio.
@ -579,20 +559,20 @@ class Lock:
![Rattlesnake][18]
横向!这个生物的身体看起来是一样的,但它的行为会发生变化。我们如何为这一进化步骤做好准备?
横向移动!这个生物的身体看起来是一样的,但它的行为会发生变化。我们如何为这一进化步骤做好准备?
![][19]
Image by HCA [[CC BY-SA 4.0][20]], [via Wikimedia Commons][21], 由 Opensource.com 修改
*Image by HCA [[CC BY-SA 4.0][20]], [via Wikimedia Commons][21], 由 Opensource.com 修改*
当行为在没有新函数或新参数的情况下发生更改时,负责的创建者可以从 Python 标准库中学习。很久以前os 模块引入了stat 函数来获取文件统计信息,比如创建时间。起初,这个时间总是整数。
当行为在没有新函数或新参数的情况下发生更改时,负责的创建者可以从 Python 标准库中学习。很久以前os 模块引入了 `stat` 函数来获取文件统计信息,比如创建时间。起初,这个时间总是整数。
```
>>> os.stat('file.txt').st_ctime
1540817862
```
有一天,核心开发人员决定在 os.stat 中使用浮点数来提供亚秒级精度。但他们担心现有的用户代码还没有做好准备更改。于是他们在 Python 2.3 中创建了一个设置 "stat_float_times",默认情况下是 false 。用户可以将其设置为 True 来选择浮点时间戳。
有一天,核心开发人员决定在 `os.stat` 中使用浮点数来提供亚秒级精度。但他们担心现有的用户代码还没有做好准备更改。于是他们在 Python 2.3 中创建了一个设置 `stat_float_times`,默认情况下是 `False` 。用户可以将其设置为 True 来选择浮点时间戳。
```
>>> # Python 2.3.
@ -601,7 +581,7 @@ Image by HCA [[CC BY-SA 4.0][20]], [via Wikimedia Commons][21], 由 Opensource.c
1540817862.598021
```
从 Python 2.5 开始,浮点时间成为默认值,因此 2.5 及之后版本编写的任何新代码都可以忽略该设置并期望得到浮点数。当然,你可以将其设置为 False 以保持旧行为,或将其设置为 True 以确保所有 Python 版本都得到浮点数,并为删除 stat_float_times 的那一天准备代码。
从 Python 2.5 开始,浮点时间成为默认值,因此 2.5 及之后版本编写的任何新代码都可以忽略该设置并期望得到浮点数。当然,你可以将其设置为 `False` 以保持旧行为,或将其设置为 `True` 以确保所有 Python 版本都得到浮点数,并为删除 `stat_float_times` 的那一天准备代码。
多年过去了,在 Python 3.1 中,该设置已被弃用,以便为人们为遥远的未来做好准备,最后,经过数十年的旅程,[这个设置被删除][22]。浮点时间现在是唯一的选择。这是一个漫长的过程,但负责任的神灵是有耐心的,因为我们知道这个渐进的过程很有可能于意外的行为变化拯救用户。
@ -609,22 +589,20 @@ Image by HCA [[CC BY-SA 4.0][20]], [via Wikimedia Commons][21], 由 Opensource.c
以下是步骤:
* 添加一个标志来选择新行为,默认为 False如果为 False 则发出警告
* 将默认值更改为 True表示完全弃用标记
* 删除标志
* 添加一个标志来选择新行为,默认为 `False`,如果为 `False` 则发出警告
* 将默认值更改为 `True`,表示完全弃用标记
* 删除该标志
如果你遵循语义版本控制,版本可能如下:
Library version | Library API | User code
库版本 | 库 API | 用户代码
---|---|---
| |
1.0 | 没有标志 | 期望的旧行为
1.1 | 添加标志,默认为 False如果是 False则警告 | 设置标志为 True处理新行为
2.0 | 改变默认为 True完全弃用标志 | 处理新行为
1.0 | 没有标志 | 预期的旧行为
1.1 | 添加标志,默认为 `False`,如果是 `False`,则警告 | 设置标志为 `True`,处理新行为
2.0 | 改变默认为 `True`,完全弃用标志 | 处理新行为
3.0 | 移除标志 | 处理新行为
你需要 _两_ 个主要版本来完成该操作。如果你直接从“添加标志,默认为 False如果是 False 则发出警告到“删除标志”,而没有中间版本,那么用户的代码将无法升级。为 1.1 正确编写的用户代码必须能够升级到下一个版本,除了新警告之外,没有任何不良影响,但如果在下一个版本中删除了该标志,那么该代码将崩溃。一个负责任的神明从不违反扭曲的政策:“第一个总是自由的”。
你需要**两**个主要版本来完成该操作。如果你直接从“添加标志,默认为 `False`,如果是 `False` 则发出警告”变到“删除标志”,而没有中间版本,那么用户的代码将无法升级。为 1.1 正确编写的用户代码必须能够升级到下一个版本,除了新警告之外,没有任何不良影响,但如果在下一个版本中删除了该标志,那么该代码将崩溃。一个负责任的神明从不违反扭曲的政策:“先行者总是自由的”。
### 负责任的创建者
@ -640,22 +618,18 @@ Library version | Library API | User code
4. 标记实验特征“临时”
5. 温柔删除功能
**严格记录历史**
1. 维护更改日志
2. 选择版本方案
3. 编写升级指南
**缓慢而明显地改变**
1. 兼容添加参数
2. 逐渐改变行为
如果你对你所创造的物种保持这些约定,你将成为一个负责任的创造之神。你的生物的身体可以随着时间的推移而进化,永远改善和适应环境的变化,而不是在生物没有准备好就突然改变。如果你维护一个库,请向用户保留这些承诺,这样你就可以在不破坏依赖库的人的代码的情况下对库进行更新。
如果你对你所创造的物种保持这些约定,你将成为一个负责任的造物主。你的生物的身体可以随着时间的推移而进化,一直在改善和适应环境的变化,而不是在生物没有准备好就突然改变。如果你维护一个库,请向用户保留这些承诺,这样你就可以在不破坏依赖该库的代码的情况下对库进行更新。
* * *
@ -680,7 +654,7 @@ via: https://opensource.com/article/19/5/api-evolution-right-way
作者:[A. Jesse][a]
选题:[lujun9972][b]
译者:[MjSeven](https://github.com/MjSeven)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,156 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10906-1.html)
[#]: subject: (Querying 10 years of GitHub data with GHTorrent and Libraries.io)
[#]: via: (https://opensource.com/article/19/5/chaossearch-github-ghtorrent)
[#]: author: (Pete Cheslock https://opensource.com/users/petecheslock/users/ghaff/users/payalsingh/users/davidmstokes)
用 GHTorrent 和 Libraries.io 查询 10 年的 GitHub 数据
======
> 有一种方法可以在没有任何本地基础设施的情况下使用开源数据集探索 GitHub 数据。
![magnifying glass on computer screen](https://img.linux.net.cn/data/attachment/album/201905/27/220200jlzrlz333vkfl8ok.jpg)
我一直在寻找新的数据集,以用它们来展示我们团队工作的力量。[CHAOSSEARCH][2] 可以将你的 [Amazon S3][3] 对象存储数据转换为完全可搜索的 [Elasticsearch][4] 式集群。使用 Elasticsearch API 或 [Kibana][5] 等工具,你可以查询你所要找的任何数据。
当我找到 [GHTorrent][6] 项目进行探索时我很兴奋。GHTorrent 旨在通过 GitHub API 构建所有可用数据的离线版本。如果你喜欢数据集,这是一个值得一看的项目,甚至你可以考虑[捐赠一个 GitHub API 密钥][7]。
### 访问 GHTorrent 数据
有许多方法可以访问和使用 [GHTorrent 的数据][8],它以 [NDJSON][9] 格式提供。这个项目可以以多种形式提供数据,包括用于恢复到 [MySQL][11] 数据库的 [CSV][10],可以转储所有对象的 [MongoDB][12],以及用于将数据直接导出到 Google 对象存储中的 Google Big Query免费。 有一点需要注意:这个数据集有从 2008 年到 2017 年几乎完整的数据集,但从 2017 年到现在的数据还不完整。这将影响我们确定性查询的能力,但它仍然是一个令人兴奋的信息量。
我选择 Google Big Query 来避免自己运行任何数据库那么我就可以很快下载包括用户和项目在内的完整数据库。CHAOSSEARCH 可以原生分析 NDJSON 格式,因此在将数据上传到 Amazon S3 之后我能够在几分钟内对其进行索引。CHAOSSEARCH 平台不要求用户设置索引模式或定义其数据的映射,它可以发现所有字段本身(字符串、整数等)。
随着我的数据完全索引并准备好进行搜索和聚合,我想深入了解看看我们可以发现什么,比如哪些软件语言是 GitHub 项目最受欢迎的。
(关于格式化的说明:下面这是一个有效的 JSON 查询,我们不会在这里正确格式化以避免滚动疲劳。要正确格式化它,你可以在本地复制它并发送到命令行实用程序,如 [jq][13]。)
```
{"aggs":{"2":{"date_histogram":{"field":"root.created_at","interval":"1M","time_zone":"America/New_York","min_doc_count":1}}},"size":0,"_source":{"excludes":[]},"stored_fields":["*"],"script_fields":{},"docvalue_fields":["root.created_at","root.updated_at"],"query":{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[{"match_phrase":{"root.language":{"query":""}}}]}}}
```
对于那些近年来跟踪开源语言状态的人来说,这个结果并不令人惊讶。
![Which software languages are the most popular on GitHub.][14]
[JavaScript][15] 仍然是卫冕冠军,虽然有些人认为 JavaScript 正在逐渐消失,但它仍然是 800 磅重的大猩猩,很可能会保持这种状态一段时间。[Java][16] 面临类似的谣言,但这些数据表明它是开源生态系统的重要组成部分。
考虑到像 [Docker][17] 和 [Kubernetes][18] 这样的项目的流行你可能会想“Go[Golang][19])怎么样?”这是一个提醒的好时机,这里讨论的 GitHub 数据集包含一些空缺,最明显的是在 2017 年之后我看到 Golang 项目随处可见,而这里并没有显示。我希望用完整的 GitHub 数据集重复此搜索,看看它是否会改变排名。
现在让我们来探讨项目创建的速度。 (提醒:这是为了便于阅读而合并的有效 JSON。
```
{"aggs":{"2":{"date_histogram":{"field":"root.created_at","interval":"1M","time_zone":"America/New_York","min_doc_count":1}}},"size":0,"_source":{"excludes":[]},"stored_fields":["*"],"script_fields":{},"docvalue_fields":["root.created_at","root.updated_at"],"query":{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[{"match_phrase":{"root.language":{"query":""}}}]}}}
```
我们可以看到创建新项目的速度,也会给人留下深刻的印象,从 2012 年左右开始大幅增长:
![The rate at which new projects are created on GitHub.][20]
既然我知道了创建项目的速度以及用于创建这些项目的最流行的语言,我还想知道这些项目选择的开源许可证。遗憾的是,这个 GitHub 项目数据集中并不存在这些数据,但是 [Tidelift][21] 的精彩团队在 [Libraries.io][22] [数据][23] 里发布了一个 GitHub 项目的详细列表,包括使用的许可证以及其中有关开源软件状态的其他详细信息。将此数据集导入 CHAOSSEARCH 只花了几分钟,让我看看哪些开源软件许可证在 GitHub 上最受欢迎:
(提醒:这是为了便于阅读而合并的有效 JSON。
```
{"aggs":{"2":{"terms":{"field":"Repository License","size":10,"order":{"_count":"desc"}}}},"size":0,"_source":{"excludes":[]},"stored_fields":["*"],"script_fields":{},"docvalue_fields":["Created Timestamp","Last synced Timestamp","Latest Release Publish Timestamp","Updated Timestamp"],"query":{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[{"match_phrase":{"Repository License":{"query":""}}}]}}}
```
结果显示了一些重要的异常值:
![Which open source software licenses are the most popular on GitHub.][24]
如你所见,[MIT 许可证][25] 和 [Apache 2.0 许可证][26] 的开源项目远远超过了其他大多数开源许可证,而 [各种 BSD 和 GPL 许可证][27] 则差得很远。鉴于 GitHub 的开放模式,我不能说我对这些结果感到惊讶。我猜想是用户(而不是公司)创建了大多数项目,并且他们使用 MIT 许可证可以使其他人轻松地使用、共享和贡献。而鉴于有不少公司希望确保其商标得到尊重并为其业务提供开源组件,那么 Apache 2.0 许可证数量高企的背后也是有道理的。
现在我确定了最受欢迎的许可证,我很想看看最少使用的许可证。通过调整我的上一个查询,我将前 10 名逆转为最后 10 名,并且只找到了两个使用 [伊利诺伊大学 - NCSA 开源许可证][28] 的项目。我之前从未听说过这个许可证,但它与 Apache 2.0 非常接近。看到所有 GitHub 项目中使用了多少个不同的软件许可证,这很有意思。
![The University of Illinois/NCSA open source license.][29]
之后我针对特定语言JavaScript来查看最常用的许可证。提醒这是为了便于阅读而合并的有效JSON。
```
{"aggs":{"2":{"terms":{"field":"Repository License","size":10,"order":{"_count":"desc"}}}},"size":0,"_source":{"excludes":[]},"stored_fields":["*"],"script_fields":{},"docvalue_fields":["Created Timestamp","Last synced Timestamp","Latest Release Publish Timestamp","Updated Timestamp"],"query":{"bool":{"must":[{"match_phrase":{"Repository Language":{"query":"JavaScript"}}}],"filter":[{"match_all":{}}],"should":[],"must_not":[{"match_phrase":{"Repository License":{"query":""}}}]}}}
```
这个输出有一些意外。
![The most popular open source licenses used for GitHub JavaScript projects.][30]
尽管使用 `npm init` 创建的 [NPM][31] 模块的默认许可证是来自 [Internet Systems ConsortiumISC][32] 的许可证,但你可以看到相当多的这些项目使用 MIT 以及 Apache 2.0 的开源许可证。
由于 Libraries.io 数据集中包含丰富的开源项目内容,并且由于 GHTorrent 数据缺少最近几年的数据(因此缺少有关 Golang 项目的任何细节),因此我决定运行类似的查询来查看 Golang 项目是如何许可他们的代码的。
(提醒:这是为了便于阅读而合并的有效 JSON。
```
{"aggs":{"2":{"terms":{"field":"Repository License","size":10,"order":{"_count":"desc"}}}},"size":0,"_source":{"excludes":[]},"stored_fields":["*"],"script_fields":{},"docvalue_fields":["Created Timestamp","Last synced Timestamp","Latest Release Publish Timestamp","Updated Timestamp"],"query":{"bool":{"must":[{"match_phrase":{"Repository Language":{"query":"Go"}}}],"filter":[{"match_all":{}}],"should":[],"must_not":[{"match_phrase":{"Repository License":{"query":""}}}]}}}
```
结果与 Javascript 完全不同。
![How Golang projects license their GitHub code.][33]
Golang 项目与 JavaScript 项目惊人逆转 —— 使用 Apache 2.0 的 Golang 项目几乎是 MIT 许可证的三倍。虽然很难准确地解释为什么会出现这种情况但在过去的几年中Golang 已经出现了大规模的增长,特别是在开源和商业化的项目和软件产品公司中。
正如我们上面所了解的,这些公司中的许多公司都希望强制执行其商标策略,因此转向 Apache 2.0 许可证是有道理的。
#### 总结
最后,我通过深入了解 GitHub 用户和项目的数据找到了一些有趣的结果。其中一些我肯定会猜到,但是一些结果对我来说也是惊喜,特别是像很少使用的 NCSA 许可证这样的异常值。
总而言之,你可以看到 CHAOSSEARCH 平台能够快速轻松地找到有趣问题的复杂答案。我无需自己运行任何数据库就可以深入研究这个数据集,甚至可以在 Amazon S3 上以低成本的方式存储数据,因此无需维护。 现在,我可以随时查询有关这些数据的任何其他问题。
你对数据提出了哪些其他问题,以及你使用了哪些数据集?请在评论或推特上告诉我 [@petecheslock] [34]。
本文的一个版本最初发布在 [CHAOSSEARCH][35],有更多结果可供发现。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/5/chaossearch-github-ghtorrent
作者:[Pete Cheslock][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/petecheslock/users/ghaff/users/payalsingh/users/davidmstokes
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/search_find_code_issue_bug_programming.png?itok=XPrh7fa0 (magnifying glass on computer screen)
[2]: https://chaossearch.io/
[3]: https://aws.amazon.com/s3/
[4]: https://www.elastic.co/
[5]: https://www.elastic.co/products/kibana
[6]: http://ghtorrent.org
[7]: http://ghtorrent.org/services.html
[8]: http://ghtorrent.org/downloads.html
[9]: http://ndjson.org
[10]: https://en.wikipedia.org/wiki/Comma-separated_values
[11]: https://en.wikipedia.org/wiki/MySQL
[12]: https://www.mongodb.com/
[13]: https://stedolan.github.io/jq/
[14]: https://opensource.com/sites/default/files/uploads/github-1_500.png (Which software languages are the most popular on GitHub.)
[15]: https://en.wikipedia.org/wiki/JavaScript
[16]: /resources/java
[17]: /resources/what-docker
[18]: /resources/what-is-kubernetes
[19]: https://golang.org/
[20]: https://opensource.com/sites/default/files/uploads/github-2_500.png (The rate at which new projects are created on GitHub.)
[21]: https://tidelift.com
[22]: http://libraries.io/
[23]: https://libraries.io/data
[24]: https://opensource.com/sites/default/files/uploads/github-3_500.png (Which open source software licenses are the most popular on GitHub.)
[25]: https://opensource.org/licenses/MIT
[26]: https://opensource.org/licenses/Apache-2.0
[27]: https://opensource.org/licenses
[28]: https://tldrlegal.com/license/university-of-illinois---ncsa-open-source-license-(ncsa)
[29]: https://opensource.com/sites/default/files/uploads/github-4_500_0.png (The University of Illinois/NCSA open source license.)
[30]: https://opensource.com/sites/default/files/uploads/github-5_500_0.png (The most popular open source licenses used for GitHub JavaScript projects.)
[31]: https://www.npmjs.com/
[32]: https://en.wikipedia.org/wiki/ISC_license
[33]: https://opensource.com/sites/default/files/uploads/github-6_500.png (How Golang projects license their GitHub code.)
[34]: https://twitter.com/petecheslock
[35]: https://chaossearch.io/blog/where-are-the-github-users-part-1/

View File

@ -1,18 +1,18 @@
[#]: collector: (lujun9972)
[#]: translator: (zhs852)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10897-1.html)
[#]: subject: (Change Power Modes in Ubuntu with Slimbook Battery Optimizer)
[#]: via: (https://itsfoss.com/slimbook-battry-optimizer-ubuntu/)
[#]: author: Abhishek Prakash https://itsfoss.com/author/abhishek/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
在 Ubuntu 中使用 Slimbook Battery Optimizer 切换电源模式
======
> Slimbook Battery Optimizer 是一个美观实用的指示器小程序,它可以让你在安装 Linux 的笔记本上快速切换电源模式来延长续航时间。
> Slimbook Battery Optimizer 是一个美观实用的指示器小程序,它可以让你在安装 Linux 的笔记本上快速切换电源模式来延长续航时间。
[Slimbook][1] 是一个销售 [预装 Linux 的笔电][2] 的西班牙电脑制造商,他们发布了一款好用的小程序,用来在基于 Ubuntu 的 Linux 发行版下调整电池性能。
[Slimbook][1] 是一个销售 [预装 Linux 的笔记本][2] 的西班牙电脑制造商,他们发布了一款好用的小程序,用来在基于 Ubuntu 的 Linux 发行版下调整电池性能。
因为 Slimbook 销售他们自己的 Linux 系统,所以他们制作了一些在 Linux 上用于调整他们自己硬件性能的小工具。Battery Optimizer 就是这样一个工具。
@ -46,8 +46,6 @@ Slimbook 有专门为多种电源管理参数提供的页面。如果你希望
总的来说Slimbook Battery 是一个小巧精美的软件,你可以用它来快速切换电源模式。如果你决定在 Ubuntu 及其衍生发行版上(比如 Linux Mint 或 elementary OS 等),你可以使用官方 [PPA 源][8]。
说个题外话,推荐阅读大家阅读 [Ubuntu 论坛被入侵,用户数据被盗取][9] 这篇文章。
#### 在基于 Ubuntu 的发行版上安装 Slimbook Battery
打开终端,一步一步地使用以下命令:
@ -86,7 +84,7 @@ via: https://itsfoss.com/slimbook-battry-optimizer-ubuntu/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[zhs852](https://github.com/zhs852)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,484 @@
从零写一个时间序列数据库
==================
编者按Prometheus 是 CNCF 旗下的开源监控告警解决方案,它已经成为 Kubernetes 生态圈中的核心监控系统。本文作者 Fabian Reinartz 是 Prometheus 的核心开发者,这篇文章是其于 2017 年写的一篇关于 Prometheus 中的时间序列数据库的设计思考,虽然写作时间有点久了,但是其中的考虑和思路非常值得参考。长文预警,请坐下来慢慢品味。
---
![](https://img.linux.net.cn/data/attachment/album/201906/11/180646l7cqbhazqs7nsqsn.jpg)
我从事监控工作。特别是在 [Prometheus][2] 上,监控系统包含一个自定义的时间序列数据库,并且集成在 [Kubernetes][3] 上。
在许多方面上 Kubernetes 展现出了 Prometheus 所有的设计用途。它使得<ruby>持续部署<rt>continuous deployments</rt></ruby><ruby>弹性伸缩<rt>auto scaling</rt></ruby>和其他<ruby>高动态环境<rt>highly dynamic environments</rt></ruby>下的功能可以轻易地访问。查询语句和操作模型以及其它概念决策使得 Prometheus 特别适合这种环境。但是,如果监控的工作负载动态程度显著地增加,这就会给监控系统本身带来新的压力。考虑到这一点,我们就可以特别致力于在高动态或<ruby>瞬态服务<rt>transient services</rt></ruby>环境下提升它的表现,而不是回过头来解决 Prometheus 已经解决的很好的问题。
Prometheus 的存储层在历史以来都展现出卓越的性能,单一服务器就能够以每秒数百万个时间序列的速度摄入多达一百万个样本,同时只占用了很少的磁盘空间。尽管当前的存储做的很好,但我依旧提出一个新设计的存储子系统,它可以修正现存解决方案的缺点,并具备处理更大规模数据的能力。
> 备注:我没有数据库方面的背景。我说的东西可能是错的并让你误入歧途。你可以在 Freenode 的 #prometheus 频道上对我fabxc提出你的批评。
## 问题,难题,问题域
首先,快速地概览一下我们要完成的东西和它的关键难题。我们可以先看一下 Prometheus 当前的做法 ,它为什么做的这么好,以及我们打算用新设计解决哪些问题。
### 时间序列数据
我们有一个收集一段时间数据的系统。
```
identifier -> (t0, v0), (t1, v1), (t2, v2), (t3, v3), ....
```
每个数据点是一个时间戳和值的元组。在监控中时间戳是一个整数值可以是任意数字。64 位浮点数对于计数器和测量值来说是一个好的表示方法,因此我们将会使用它。一系列严格单调递增的时间戳数据点是一个序列,它由标识符所引用。我们的标识符是一个带有<ruby>标签维度<rt>label dimensions</rt></ruby>字典的度量名称。标签维度划分了单一指标的测量空间。每一个指标名称加上一个唯一标签集就成了它自己的时间序列,它有一个与之关联的<ruby>数据流<rt>value stream</rt></ruby>
这是一个典型的<ruby>序列标识符<rt>series identifier</rt></ruby>集,它是统计请求指标的一部分:
```
requests_total{path="/status", method="GET", instance=”10.0.0.1:80”}
requests_total{path="/status", method="POST", instance=”10.0.0.3:80”}
requests_total{path="/", method="GET", instance=”10.0.0.2:80”}
```
让我们简化一下表示方法:度量名称可以当作另一个维度标签,在我们的例子中是 `__name__`。对于查询语句,可以对它进行特殊处理,但与我们存储的方式无关,我们后面也会见到。
```
{__name__="requests_total", path="/status", method="GET", instance=”10.0.0.1:80”}
{__name__="requests_total", path="/status", method="POST", instance=”10.0.0.3:80”}
{__name__="requests_total", path="/", method="GET", instance=”10.0.0.2:80”}
```
我们想通过标签来查询时间序列数据。在最简单的情况下,使用 `{__name__="requests_total"}` 选择所有属于 `requests_total` 指标的数据。对于所有选择的序列,我们在给定的时间窗口内获取数据点。
在更复杂的语句中,我们或许想一次性选择满足多个标签的序列,并且表示比相等条件更复杂的情况。例如,非语句(`method!="GET"`)或正则表达式匹配(`method=~"PUT|POST"`)。
这些在很大程度上定义了存储的数据和它的获取方式。
### 纵与横
在简化的视图中,所有的数据点可以分布在二维平面上。水平维度代表着时间,序列标识符域经纵轴展开。
```
series
^
| . . . . . . . . . . . . . . . . . . . . . . {__name__="request_total", method="GET"}
| . . . . . . . . . . . . . . . . . . . . . . {__name__="request_total", method="POST"}
| . . . . . . .
| . . . . . . . . . . . . . . . . . . . ...
| . . . . . . . . . . . . . . . . . . . . .
| . . . . . . . . . . . . . . . . . . . . . {__name__="errors_total", method="POST"}
| . . . . . . . . . . . . . . . . . {__name__="errors_total", method="GET"}
| . . . . . . . . . . . . . .
| . . . . . . . . . . . . . . . . . . . ...
| . . . . . . . . . . . . . . . . . . . .
v
<-------------------- time --------------------->
```
Prometheus 通过定期地抓取一组时间序列的当前值来获取数据点。我们从中获取到的实体称为目标。因此,写入模式完全地垂直且高度并发,因为来自每个目标的样本是独立摄入的。
这里提供一些测量的规模:单一 Prometheus 实例从数万个目标中收集数据点,每个数据点都暴露在数百到数千个不同的时间序列中。
在每秒采集数百万数据点这种规模下,批量写入是一个不能妥协的性能要求。在磁盘上分散地写入单个数据点会相当地缓慢。因此,我们想要按顺序写入更大的数据块。
对于旋转式磁盘,它的磁头始终得在物理上向不同的扇区上移动,这是一个不足为奇的事实。而虽然我们都知道 SSD 具有快速随机写入的特点,但事实上它不能修改单个字节,只能写入一页或更多页的 4KiB 数据量。这就意味着写入 16 字节的样本相当于写入满满一个 4Kib 的页。这一行为就是所谓的[写入放大][4],这种特性会损耗你的 SSD。因此它不仅影响速度而且还毫不夸张地在几天或几个周内破坏掉你的硬件。
关于此问题更深层次的资料,[“Coding for SSDs”系列][5]博客是极好的资源。让我们想想主要的用处:顺序写入和批量写入分别对于旋转式磁盘和 SSD 来说都是理想的写入模式。大道至简。
查询模式比起写入模式明显更不同。我们可以查询单一序列的一个数据点,也可以对 10000 个序列查询一个数据点,还可以查询一个序列几个周的数据点,甚至是 10000 个序列几个周的数据点。因此在我们的二维平面上,查询范围不是完全水平或垂直的,而是二者形成矩形似的组合。
[记录规则][6]可以减轻已知查询的问题,但对于<ruby>点对点<rt>ad-hoc</rt></ruby>查询来说并不是一个通用的解决方法。
我们知道我们想要批量地写入,但我们得到的仅仅是一系列垂直数据点的集合。当查询一段时间窗口内的数据点时,我们不仅很难弄清楚在哪才能找到这些单独的点,而且不得不从磁盘上大量随机的地方读取。也许一条查询语句会有数百万的样本,即使在最快的 SSD 上也会很慢。读入也会从磁盘上获取更多的数据而不仅仅是 16 字节的样本。SSD 会加载一整页HDD 至少会读取整个扇区。不论哪一种,我们都在浪费宝贵的读取吞吐量。
因此在理想情况下,同一序列的样本将按顺序存储,这样我们就能通过尽可能少的读取来扫描它们。最重要的是,我们仅需要知道序列的起始位置就能访问所有的数据点。
显然,将收集到的数据写入磁盘的理想模式与能够显著提高查询效率的布局之间存在着明显的抵触。这是我们 TSDB 需要解决的一个基本问题。
#### 当前的解决方法
是时候看一下当前 Prometheus 是如何存储数据来解决这一问题的让我们称它为“V2”。
我们创建一个时间序列的文件,它包含所有样本并按顺序存储。因为每几秒附加一个样本数据到所有文件中非常昂贵,我们在内存中打包 1Kib 样本序列的数据块一旦打包完成就附加这些数据块到单独的文件中。这一方法解决了大部分问题。写入目前是批量的样本也是按顺序存储的。基于给定的同一序列的样本相对之前的数据仅发生非常小的改变这一特性它还支持非常高效的压缩格式。Facebook 在他们 Gorilla TSDB 上的论文中描述了一个相似的基于数据块的方法,并且[引入了一种压缩格式][7],它能够减少 16 字节的样本到平均 1.37 字节。V2 存储使用了包含 Gorilla 变体等在内的各种压缩格式。
```
+----------+---------+---------+---------+---------+ series A
+----------+---------+---------+---------+---------+
+----------+---------+---------+---------+---------+ series B
+----------+---------+---------+---------+---------+
. . .
+----------+---------+---------+---------+---------+---------+ series XYZ
+----------+---------+---------+---------+---------+---------+
chunk 1 chunk 2 chunk 3 ...
```
尽管基于块存储的方法非常棒,但为每个序列保存一个独立的文件会给 V2 存储带来麻烦,因为:
* 实际上,我们需要的文件比当前收集数据的时间序列数量要多得多。多出的部分在<ruby>序列分流<rt>Series Churn</rt></ruby>上。有几百万个文件,迟早会使用光文件系统中的 [inode][1]。这种情况我们只能通过重新格式化来恢复磁盘,这种方式是最具有破坏性的。我们通常不想为了适应一个应用程序而格式化磁盘。
* 即使是分块写入,每秒也会产生数千块的数据块并且准备持久化。这依然需要每秒数千次的磁盘写入。尽管通过为每个序列打包好多个块来缓解,但这反过来还是增加了等待持久化数据的总内存占用。
* 要保持所有文件打开来进行读写是不可行的。特别是因为 99% 的数据在 24 小时之后不再会被查询到。如果查询它,我们就得打开数千个文件,找到并读取相关的数据点到内存中,然后再关掉。这样做就会引起很高的查询延迟,数据块缓存加剧会导致新的问题,这一点在“资源消耗”一节另作讲述。
* 最终,旧的数据需要被删除,并且数据需要从数百万文件的头部删除。这就意味着删除实际上是写密集型操作。此外,循环遍历数百万文件并且进行分析通常会导致这一过程花费数小时。当它完成时,可能又得重新来过。喔天,继续删除旧文件又会进一步导致 SSD 产生写入放大。
* 目前所积累的数据块仅维持在内存中。如果应用崩溃,数据就会丢失。为了避免这种情况,内存状态会定期的保存在磁盘上,这比我们能接受数据丢失窗口要长的多。恢复检查点也会花费数分钟,导致很长的重启周期。
我们能够从现有的设计中学到的关键部分是数据块的概念,我们当然希望保留这个概念。最新的数据块会保持在内存中一般也是好的主意。毕竟,最新的数据会大量的查询到。
一个时间序列对应一个文件,这个概念是我们想要替换掉的。
### 序列分流
在 Prometheus 的<ruby>上下文<rt>context</rt></ruby>中,我们使用术语<ruby>序列分流<rt>series churn</rt></ruby>来描述一个时间序列集合变得不活跃,即不再接收数据点,取而代之的是出现一组新的活跃序列。
例如由给定微服务实例产生的所有序列都有一个相应的“instance”标签来标识其来源。如果我们为微服务执行了<ruby>滚动更新<rt>rolling update</rt></ruby>,并且为每个实例替换一个新的版本,序列分流便会发生。在更加动态的环境中,这些事情基本上每小时都会发生。像 Kubernetes 这样的<ruby>集群编排<rt>Cluster orchestration</rt></ruby>系统允许应用连续性的自动伸缩和频繁的滚动更新,这样也许会创建成千上万个新的应用程序实例,并且伴随着全新的时间序列集合,每天都是如此。
```
series
^
| . . . . . .
| . . . . . .
| . . . . . .
| . . . . . . .
| . . . . . . .
| . . . . . . .
| . . . . . .
| . . . . . .
| . . . . .
| . . . . .
| . . . . .
v
<-------------------- time --------------------->
```
所以即便整个基础设施的规模基本保持不变,过一段时间后数据库内的时间序列还是会成线性增长。尽管 Prometheus 很愿意采集 1000 万个时间序列数据,但要想在 10 亿个序列中找到数据,查询效果还是会受到严重的影响。
#### 当前解决方案
当前 Prometheus 的 V2 存储系统对所有当前保存的序列拥有基于 LevelDB 的索引。它允许查询语句含有给定的<ruby>标签对<rt>label pair</rt></ruby>,但是缺乏可伸缩的方法来从不同的标签选集中组合查询结果。
例如,从所有的序列中选择标签 `__name__="requests_total"` 非常高效,但是选择  `instance="A" AND __name__="requests_total"` 就有了可伸缩性的问题。我们稍后会重新考虑导致这一点的原因和能够提升查找延迟的调整方法。
事实上正是这个问题才催生出了对更好的存储系统的最初探索。Prometheus 需要为查找亿万个时间序列改进索引方法。
### 资源消耗
当试图扩展 Prometheus或其他任何事情真的资源消耗是永恒不变的话题之一。但真正困扰用户的并不是对资源的绝对渴求。事实上由于给定的需求Prometheus 管理着令人难以置信的吞吐量。问题更在于面对变化时的相对未知性与不稳定性。通过其架构设计V2 存储系统缓慢地构建了样本数据块这一点导致内存占用随时间递增。当数据块完成之后它们可以写到磁盘上并从内存中清除。最终Prometheus 的内存使用到达稳定状态。直到监测环境发生了改变——每次我们扩展应用或者进行滚动更新序列分流都会增加内存、CPU、磁盘 I/O 的使用。
如果变更正在进行,那么它最终还是会到达一个稳定的状态,但比起更加静态的环境,它的资源消耗会显著地提高。过渡时间通常为数个小时,而且难以确定最大资源使用量。
为每个时间序列保存一个文件这种方法也使得一个单个查询就很容易崩溃 Prometheus 进程。当查询的数据没有缓存在内存中查询的序列文件就会被打开然后将含有相关数据点的数据块读入内存。如果数据量超出内存可用量Prometheus 就会因 OOM 被杀死而退出。
在查询语句完成之后,加载的数据便可以被再次释放掉,但通常会缓存更长的时间,以便更快地查询相同的数据。后者看起来是件不错的事情。
最后,我们看看之前提到的 SSD 的写入放大,以及 Prometheus 是如何通过批量写入来解决这个问题的。尽管如此,在许多地方还是存在因为批量太小以及数据未精确对齐页边界而导致的写入放大。对于更大规模的 Prometheus 服务器,现实当中会发现缩减硬件寿命的问题。这一点对于高写入吞吐量的数据库应用来说仍然相当普遍,但我们应该放眼看看是否可以解决它。
### 重新开始
到目前为止我们对于问题域、V2 存储系统是如何解决它的以及设计上存在的问题有了一个清晰的认识。我们也看到了许多很棒的想法这些或多或少都可以拿来直接使用。V2 存储系统相当数量的问题都可以通过改进和部分的重新设计来解决,但为了好玩(当然,在我仔细的验证想法之后),我决定试着写一个完整的时间序列数据库——从头开始,即向文件系统写入字节。
性能与资源使用这种最关键的部分直接影响了存储格式的选取。我们需要为数据找到正确的算法和磁盘布局来实现一个高性能的存储层。
这就是我解决问题的捷径——跳过令人头疼、失败的想法,数不尽的草图,泪水与绝望。
### V3—宏观设计
我们存储系统的宏观布局是什么?简而言之,是当我们在数据文件夹里运行 `tree` 命令时显示的一切。看看它能给我们带来怎样一副惊喜的画面。
```
$ tree ./data
./data
+-- b-000001
| +-- chunks
| | +-- 000001
| | +-- 000002
| | +-- 000003
| +-- index
| +-- meta.json
+-- b-000004
| +-- chunks
| | +-- 000001
| +-- index
| +-- meta.json
+-- b-000005
| +-- chunks
| | +-- 000001
| +-- index
| +-- meta.json
+-- b-000006
+-- meta.json
+-- wal
+-- 000001
+-- 000002
+-- 000003
```
在最顶层,我们有一系列以 `b-` 为前缀编号的<ruby><rt>block</rt></ruby>。每个块中显然保存了索引文件和含有更多编号文件的 `chunk` 文件夹。`chunks` 目录只包含不同序列<ruby>数据点的原始块<rt>raw chunks of data points</rt><ruby>。与 V2 存储系统一样,这使得通过时间窗口读取序列数据非常高效并且允许我们使用相同的有效压缩算法。这一点被证实行之有效,我们也打算沿用。显然,这里并不存在含有单个序列的文件,而是一堆保存着许多序列的数据块。
`index` 文件的存在应该不足为奇。让我们假设它拥有黑魔法,可以让我们找到标签、可能的值、整个时间序列和存放数据点的数据块。
但为什么这里有好几个文件夹都是索引和块文件的布局?并且为什么存在最后一个包含 `wal` 文件夹?理解这两个疑问便能解决九成的问题。
#### 许多小型数据库
我们分割横轴,即将时间域分割为不重叠的块。每一块扮演着完全独立的数据库,它包含该时间窗口所有的时间序列数据。因此,它拥有自己的索引和一系列块文件。
```
t0 t1 t2 t3 now
+-----------+ +-----------+ +-----------+ +-----------+
| | | | | | | | +------------+
| | | | | | | mutable | <--- write ---- Prometheus |
| | | | | | | | +------------+
+-----------+ +-----------+ +-----------+ +-----------+ ^
+--------------+-------+------+--------------+ |
| query
| |
merge -------------------------------------------------+
```
每一块的数据都是<ruby>不可变的<rt>immutable</rt></ruby>。当然,当我们采集新数据时,我们必须能向最近的块中添加新的序列和样本。对于该数据块,所有新的数据都将写入内存中的数据库中,它与我们的持久化的数据块一样提供了查找属性。内存中的数据结构可以高效地更新。为了防止数据丢失,所有传入的数据同样被写入临时的<ruby>预写日志<rt>write ahead log</rt></ruby>中,这就是 `wal` 文件夹中的一些列文件,我们可以在重新启动时通过它们重新填充内存数据库。
所有这些文件都带有序列化格式,有我们所期望的所有东西:许多标志、偏移量、变体和 CRC32 校验和。纸上得来终觉浅,绝知此事要躬行。
这种布局允许我们扩展查询范围到所有相关的块上。每个块上的部分结果最终合并成完整的结果。
这种横向分割增加了一些很棒的功能:
* 当查询一个时间范围,我们可以简单地忽略所有范围之外的数据块。通过减少需要检查的数据集,它可以初步解决序列分流的问题。
* 当完成一个块,我们可以通过顺序的写入大文件从内存数据库中保存数据。这样可以避免任何的写入放大,并且 SSD 与 HDD 均适用。
* 我们延续了 V2 存储系统的一个好的特性,最近使用而被多次查询的数据块,总是保留在内存中。
* 很好,我们也不再受限于 1KiB 的数据块尺寸,以使数据在磁盘上更好地对齐。我们可以挑选对单个数据点和压缩格式最合理的尺寸。
* 删除旧数据变得极为简单快捷。我们仅仅只需删除一个文件夹。记住,在旧的存储系统中我们不得不花数个小时分析并重写数亿个文件。
每个块还包含了 `meta.json` 文件。它简单地保存了关于块的存储状态和包含的数据,以便轻松了解存储状态及其包含的数据。
##### mmap
将数百万个小文件合并为少数几个大文件使得我们用很小的开销就能保持所有的文件都打开。这就解除了对 [mmap(2)][8] 的使用的阻碍,这是一个允许我们通过文件透明地回传虚拟内存的系统调用。简单起见,你可以将其视为<ruby>交换空间<rt>swap space</rt></ruby>,只是我们所有的数据已经保存在了磁盘上,并且当数据换出内存后不再会发生写入。
这意味着我们可以当作所有数据库的内容都视为在内存中却不占用任何物理内存。仅当我们访问数据库文件某些字节范围时,操作系统才会从磁盘上<ruby>惰性加载<rt>lazy load</rt></ruby>页数据。这使得我们将所有数据持久化相关的内存管理都交给了操作系统。通常操作系统更有资格作出这样的决定因为它可以全面了解整个机器和进程。查询的数据可以相当积极的缓存进内存但内存压力会使得页被换出。如果机器拥有未使用的内存Prometheus 目前将会高兴地缓存整个数据库,但是一旦其他进程需要,它就会立刻返回那些内存。
因此,查询不再轻易地使我们的进程 OOM因为查询的是更多的持久化的数据而不是装入内存中的数据。内存缓存大小变得完全自适应并且仅当查询真正需要时数据才会被加载。
就个人理解,这就是当今大多数数据库的工作方式,如果磁盘格式允许,这是一种理想的方式,——除非有人自信能在这个过程中超越操作系统。我们做了很少的工作但确实从外面获得了很多功能。
#### 压缩
存储系统需要定期“切”出新块并将之前完成的块写入到磁盘中。仅在块成功的持久化之后才会被删除之前用来恢复内存块的日志文件wal
我们希望将每个块的保存时间设置的相对短一些(通常配置为 2 小时),以避免内存中积累太多的数据。当查询多个块,我们必须将它们的结果合并为一个整体的结果。合并过程显然会消耗资源,一个星期的查询不应该由超过 80 个的部分结果所组成。
为了实现两者,我们引入<ruby>压缩<rt>compaction</rt></ruby>。压缩描述了一个过程:取一个或更多个数据块并将其写入一个可能更大的块中。它也可以在此过程中修改现有的数据。例如,清除已经删除的数据,或重建样本块以提升查询性能。
```
t0 t1 t2 t3 t4 now
+------------+ +----------+ +-----------+ +-----------+ +-----------+
| 1 | | 2 | | 3 | | 4 | | 5 mutable | before
+------------+ +----------+ +-----------+ +-----------+ +-----------+
+-----------------------------------------+ +-----------+ +-----------+
| 1 compacted | | 4 | | 5 mutable | after (option A)
+-----------------------------------------+ +-----------+ +-----------+
+--------------------------+ +--------------------------+ +-----------+
| 1 compacted | | 3 compacted | | 5 mutable | after (option B)
+--------------------------+ +--------------------------+ +-----------+
```
在这个例子中我们有顺序块 `[1,2,3,4]`。块 1、2、3 可以压缩在一起,新的布局将会是 `[1,4]`。或者,将它们成对压缩为 `[1,3]`。所有的时间序列数据仍然存在,但现在整体上保存在更少的块中。这极大程度地缩减了查询时间的消耗,因为需要合并的部分查询结果变得更少了。
#### 保留
我们看到了删除旧的数据在 V2 存储系统中是一个缓慢的过程,并且消耗 CPU、内存和磁盘。如何才能在我们基于块的设计上清除旧的数据相当简单只要删除我们配置的保留时间窗口里没有数据的块文件夹即可。在下面的例子中块 1 可以被安全地删除,而块 2 则必须一直保留,直到它落在保留窗口边界之外。
```
|
+------------+ +----+-----+ +-----------+ +-----------+ +-----------+
| 1 | | 2 | | | 3 | | 4 | | 5 | . . .
+------------+ +----+-----+ +-----------+ +-----------+ +-----------+
|
|
retention boundary
```
随着我们不断压缩先前压缩的块,旧数据越大,块可能变得越大。因此必须为其设置一个上限,以防数据块扩展到整个数据库而损失我们设计的最初优势。
方便的是,这一点也限制了部分存在于保留窗口内部分存在于保留窗口外的块的磁盘消耗总量。例如上面例子中的块 2。当设置了最大块尺寸为总保留窗口的 10% 后,我们保留块 2 的总开销也有了 10% 的上限。
总结一下,保留与删除从非常昂贵到了几乎没有成本。
> 如果你读到这里并有一些数据库的背景知识,现在你也许会问:这些都是最新的技术吗?——并不是;而且可能还会做的更好。
>
> 在内存中批量处理数据,在预写日志中跟踪,并定期写入到磁盘的模式在现在相当普遍。
>
> 我们看到的好处无论在什么领域的数据里都是适用的。遵循这一方法最著名的开源案例是 LevelDB、Cassandra、InfluxDB 和 HBase。关键是避免重复发明劣质的轮子采用经过验证的方法并正确地运用它们。
>
> 脱离场景添加你自己的黑魔法是一种不太可能的情况。
### 索引
研究存储改进的最初想法是解决序列分流的问题。基于块的布局减少了查询所要考虑的序列总数。因此假设我们索引查找的复杂度是 `O(n^2)`,我们就要设法减少 n 个相当数量的复杂度,之后就相当于改进 `O(n^2)` 复杂度。——恩,等等……糟糕。
快速回顾一下“算法 101”课上提醒我们的在理论上它并未带来任何好处。如果之前就很糟糕那么现在也一样。理论是如此的残酷。
实际上,我们大多数的查询已经可以相当快响应。但是,跨越整个时间范围的查询仍然很慢,尽管只需要找到少部分数据。追溯到所有这些工作之前,最初我用来解决这个问题的想法是:我们需要一个更大容量的[倒排索引][9]。
倒排索引基于数据项内容的子集提供了一种快速的查找方式。简单地说,我可以通过标签 `app="nginx"` 查找所有的序列而无需遍历每个文件来看它是否包含该标签。
为此,每个序列被赋上一个唯一的 ID ,通过该 ID 可以恒定时间内检索它(`O(1)`)。在这个例子中 ID 就是我们的正向索引。
> 示例:如果 ID 为 10、29、9 的序列包含标签 `app="nginx"`,那么 “nginx”的倒排索引就是简单的列表 `[10, 29, 9]`,它就能用来快速地获取所有包含标签的序列。即使有 200 多亿个数据序列也不会影响查找速度。
简而言之,如果 `n` 是我们序列总数,`m` 是给定查询结果的大小,使用索引的查询复杂度现在就是 `O(m)`。查询语句依据它获取数据的数量 `m` 而不是被搜索的数据体 `n` 进行缩放是一个很好的特性,因为 `m` 一般相当小。
为了简单起见,我们假设可以在恒定时间内查找到倒排索引对应的列表。
实际上,这几乎就是 V2 存储系统具有的倒排索引,也是提供在数百万序列中查询性能的最低需求。敏锐的人会注意到,在最坏情况下,所有的序列都含有标签,因此 `m` 又成了 `O(n)`。这一点在预料之中,也相当合理。如果你查询所有的数据,它自然就会花费更多时间。一旦我们牵扯上了更复杂的查询语句就会有问题出现。
#### 标签组合
与数百万个序列相关的标签很常见。假设横向扩展着数百个实例的“foo”微服务并且每个实例拥有数千个序列。每个序列都会带有标签 `app="foo"`。当然,用户通常不会查询所有的序列而是会通过进一步的标签来限制查询。例如,我想知道服务实例接收到了多少请求,那么查询语句便是 `__name__="requests_total" AND app="foo"`
为了找到满足两个标签选择子的所有序列,我们得到每一个标签的倒排索引列表并取其交集。结果集通常会比任何一个输入列表小一个数量级。因为每个输入列表最坏情况下的大小为 `O(n)`,所以在嵌套地为每个列表进行<ruby>暴力求解<rt>brute force solution</rt><ruby>下,运行时间为 `O(n^2)`。相同的成本也适用于其他的集合操作,例如取并集(`app="foo" OR app="bar"`)。当在查询语句上添加更多标签选择子,耗费就会指数增长到 `O(n^3)`、`O(n^4)`、`O(n^5)`……`O(n^k)`。通过改变执行顺序,可以使用很多技巧以优化运行效率。越复杂,越是需要关于数据特征和标签之间相关性的知识。这引入了大量的复杂度,但是并没有减少算法的最坏运行时间。
这便是 V2 存储系统使用的基本方法,幸运的是,看似微小的改动就能获得显著的提升。如果我们假设倒排索引中的 ID 都是排序好的会怎么样?
假设这个例子的列表用于我们最初的查询:
```
__name__="requests_total" -> [ 9999, 1000, 1001, 2000000, 2000001, 2000002, 2000003 ]
app="foo" -> [ 1, 3, 10, 11, 12, 100, 311, 320, 1000, 1001, 10002 ]
intersection => [ 1000, 1001 ]
```
它的交集相当小。我们可以为每个列表的起始位置设置游标,每次从最小的游标处移动来找到交集。当二者的数字相等,我们就添加它到结果中并移动二者的游标。总体上,我们以锯齿形扫描两个列表,因此总耗费是 `O(2n)=O(n)`,因为我们总是在一个列表上移动。
两个以上列表的不同集合操作也类似。因此 `k` 个集合操作仅仅改变了因子 `O(k*n)` 而不是最坏情况下查找运行时间的指数 `O(n^k)`
我在这里所描述的是几乎所有[全文搜索引擎][10]使用的标准搜索索引的简化版本。每个序列描述符都视作一个简短的“文档”,每个标签(名称 + 固定值)作为其中的“单词”。我们可以忽略搜索引擎索引中通常遇到的很多附加数据,例如单词位置和和频率。
关于改进实际运行时间的方法似乎存在无穷无尽的研究,它们通常都是对输入数据做一些假设。不出意料的是,还有大量技术来压缩倒排索引,其中各有利弊。因为我们的“文档”比较小,而且“单词”在所有的序列里大量重复,压缩变得几乎无关紧要。例如,一个真实的数据集约有 440 万个序列与大约 12 个标签,每个标签拥有少于 5000 个单独的标签。对于最初的存储版本,我们坚持使用基本的方法而不压缩,仅做微小的调整来跳过大范围非交叉的 ID。
尽管维持排序好的 ID 听起来很简单但实践过程中不是总能完成的。例如V2 存储系统为新的序列赋上一个哈希值来当作 ID我们就不能轻易地排序倒排索引。
另一个艰巨的任务是当磁盘上的数据被更新或删除掉后修改其索引。通常最简单的方法是重新计算并写入但是要保证数据库在此期间可查询且具有一致性。V3 存储系统通过每块上具有的独立不可变索引来解决这一问题,该索引仅通过压缩时的重写来进行修改。只有可变块上的索引需要被更新,它完全保存在内存中。
## 基准测试
我从存储的基准测试开始了初步的开发,它基于现实世界数据集中提取的大约 440 万个序列描述符,并生成合成数据点以输入到这些序列中。这个阶段的开发仅仅测试了单独的存储系统,对于快速找到性能瓶颈和高并发负载场景下的触发死锁至关重要。
在完成概念性的开发实施之后,该基准测试能够在我的 Macbook Pro 上维持每秒 2000 万的吞吐量 —— 并且这都是在打开着十几个 Chrome 的页面和 Slack 的时候。因此,尽管这听起来都很棒,它这也表明推动这项测试没有的进一步价值(或者是没有在高随机环境下运行)。毕竟,它是合成的数据,因此在除了良好的第一印象外没有多大价值。比起最初的设计目标高出 20 倍,是时候将它部署到真正的 Prometheus 服务器上了,为它添加更多现实环境中的开销和场景。
我们实际上没有可重现的 Prometheus 基准测试配置,特别是没有对于不同版本的 A/B 测试。亡羊补牢为时不晚,[不过现在就有一个了][11]
我们的工具可以让我们声明性地定义基准测试场景,然后部署到 AWS 的 Kubernetes 集群上。尽管对于全面的基准测试来说不是最好环境,但它肯定比 64 核 128GB 内存的专用<ruby>裸机服务器<rt>bare metal servers</rt></ruby>更能反映出我们的用户群体。
我们部署了两个 Prometheus 1.5.2 服务器V2 存储系统)和两个来自 2.0 开发分支的 Prometheus V3 存储系统)。每个 Prometheus 运行在配备 SSD 的专用服务器上。我们将横向扩展的应用部署在了工作节点上并且让其暴露典型的微服务度量。此外Kubernetes 集群本身和节点也被监控着。整套系统由另一个 Meta-Prometheus 所监督,它监控每个 Prometheus 的健康状况和性能。
为了模拟序列分流,微服务定期的扩展和收缩来移除旧的 pod 并衍生新的 pod生成新的序列。通过选择“典型”的查询来模拟查询负载对每个 Prometheus 版本都执行一次。
总体上,伸缩与查询的负载以及采样频率极大的超出了 Prometheus 的生产部署。例如,我们每隔 15 分钟换出 60% 的微服务实例去产生序列分流。在现代的基础设施上,一天仅大约会发生 1-5 次。这就保证了我们的 V3 设计足以处理未来几年的工作负载。就结果而言Prometheus 1.5.2 和 2.0 之间的性能差异在极端的环境下会变得更大。
总而言之,我们每秒从 850 个目标里收集大约 11 万份样本,每次暴露 50 万个序列。
在此系统运行一段时间之后,我们可以看一下数字。我们评估了两个版本在 12 个小时之后到达稳定时的几个指标。
> 请注意从 Prometheus 图形界面的截图中轻微截断的 Y 轴
![Heap usage GB](https://fabxc.org/tsdb/assets/heap_usage.png)
*堆内存使用GB*
内存资源的使用对用户来说是最为困扰的问题,因为它相对的不可预测且可能导致进程崩溃。
显然查询的服务器正在消耗内存这很大程度上归咎于查询引擎的开销这一点可以当作以后优化的主题。总的来说Prometheus 2.0 的内存消耗减少了 3-4 倍。大约 6 小时之后,在 Prometheus 1.5 上有一个明显的峰值,与我们设置的 6 小时的保留边界相对应。因为删除操作成本非常高,所以资源消耗急剧提升。这一点在下面几张图中均有体现。
![CPU usage cores](https://fabxc.org/tsdb/assets/cpu_usage.png)
*CPU 使用(核心/秒)*
类似的模式也体现在 CPU 使用上,但是查询的服务器与非查询的服务器之间的差异尤为明显。每秒获取大约 11 万个数据需要 0.5 核心/秒的 CPU 资源,比起评估查询所花费的 CPU 时间,我们的新存储系统 CPU 消耗可忽略不计。总的来说,新存储需要的 CPU 资源减少了 3 到 10 倍。
![Disk writes](https://fabxc.org/tsdb/assets/disk_writes.png)
*磁盘写入MB/秒)*
迄今为止最引人注目和意想不到的改进表现在我们的磁盘写入利用率上。这就清楚的说明了为什么 Prometheus 1.5 很容易造成 SSD 损耗。我们看到最初的上升发生在第一个块被持久化到序列文件中的时期,然后一旦删除操作引发了重写就会带来第二个上升。令人惊讶的是,查询的服务器与非查询的服务器显示出了非常不同的利用率。
在另一方面Prometheus 2.0 每秒仅向其预写日志写入大约一兆字节。当块被压缩到磁盘时,写入定期地出现峰值。这在总体上节省了:惊人的 97-99%。
![Disk usage](https://fabxc.org/tsdb/assets/disk_usage.png)
*磁盘大小GB*
与磁盘写入密切相关的是总磁盘空间占用量。由于我们对样本(这是我们的大部分数据)几乎使用了相同的压缩算法,因此磁盘占用量应当相同。在更为稳定的系统中,这样做很大程度上是正确地,但是因为我们需要处理高的序列分流,所以还要考虑每个序列的开销。
如我们所见Prometheus 1.5 在这两个版本达到稳定状态之前使用的存储空间因其保留操作而急速上升。Prometheus 2.0 似乎在每个序列上的开销显著降低。我们可以清楚的看到预写日志线性地充满整个存储空间,然后当压缩完成后瞬间下降。事实上对于两个 Prometheus 2.0 服务器,它们的曲线并不是完全匹配的,这一点需要进一步的调查。
前景大好。剩下最重要的部分是查询延迟。新的索引应当优化了查找的复杂度。没有实质上发生改变的是处理数据的过程,例如 `rate()` 函数或聚合。这些就是查询引擎要做的东西了。
![Query latency](https://fabxc.org/tsdb/assets/query_latency.png)
*第 99 个百分位查询延迟(秒)*
数据完全符合预期。在 Prometheus 1.5 上查询延迟随着存储的序列而增加。只有在保留操作开始且旧的序列被删除后才会趋于稳定。作为对比Prometheus 2.0 从一开始就保持在合适的位置。
我们需要花一些心思在数据是如何被采集上,对服务器发出的查询请求通过对以下方面的估计来选择:范围查询和即时查询的组合,进行更轻或更重的计算,访问更多或更少的文件。它并不需要代表真实世界里查询的分布。也不能代表冷数据的查询性能,我们可以假设所有的样本数据都是保存在内存中的热数据。
尽管如此,我们可以相当自信地说,整体查询效果对序列分流变得非常有弹性,并且在高压基准测试场景下提升了 4 倍的性能。在更为静态的环境下,我们可以假设查询时间大多数花费在了查询引擎上,改善程度明显较低。
![Ingestion rate](https://fabxc.org/tsdb/assets/ingestion_rate.png)
*摄入的样本/秒*
最后,快速地看一下不同 Prometheus 服务器的摄入率。我们可以看到搭载 V3 存储系统的两个服务器具有相同的摄入速率。在几个小时之后变得不稳定,这是因为不同的基准测试集群节点由于高负载变得无响应,与 Prometheus 实例无关。(两个 2.0 的曲线完全匹配这一事实希望足够具有说服力)
尽管还有更多 CPU 和内存资源,两个 Prometheus 1.5.2 服务器的摄入率大大降低。序列分流的高压导致了无法采集更多的数据。
那么现在每秒可以摄入的<ruby>绝对最大<rt>absolute maximum</rt></ruby>样本数是多少?
但是现在你可以摄取的每秒绝对最大样本数是多少?
我不知道 —— 虽然这是一个相当容易的优化指标,但除了稳固的基线性能之外,它并不是特别有意义。
有很多因素都会影响 Prometheus 数据流量,而且没有一个单独的数字能够描述捕获质量。最大摄入率在历史上是一个导致基准出现偏差的度量,并且忽视了更多重要的层面,例如查询性能和对序列分流的弹性。关于资源使用线性增长的大致猜想通过一些基本的测试被证实。很容易推断出其中的原因。
我们的基准测试模拟了高动态环境下 Prometheus 的压力,它比起真实世界中的更大。结果表明,虽然运行在没有优化的云服务器上,但是已经超出了预期的效果。最终,成功将取决于用户反馈而不是基准数字。
> 注意在撰写本文的同时Prometheus 1.6 正在开发当中,它允许更可靠地配置最大内存使用量,并且可能会显著地减少整体的消耗,有利于稍微提高 CPU 使用率。我没有重复对此进行测试,因为整体结果变化不大,尤其是面对高序列分流的情况。
## 总结
Prometheus 开始应对高基数序列与单独样本的吞吐量。这仍然是一项富有挑战性的任务,但是新的存储系统似乎向我们展示了未来的一些好东西。
第一个配备 V3 存储系统的 [alpha 版本 Prometheus 2.0][12] 已经可以用来测试了。在早期阶段预计还会出现崩溃,死锁和其他 bug。
存储系统的代码可以在[这个单独的项目中找到][13]。Prometheus 对于寻找高效本地存储时间序列数据库的应用来说可能非常有用,这一点令人非常惊讶。
> 这里需要感谢很多人作出的贡献,以下排名不分先后:
> Bjoern Rabenstein 和 Julius Volz 在 V2 存储引擎上的打磨工作以及 V3 存储系统的反馈,这为新一代的设计奠定了基础。
> Wilhelm Bierbaum 对新设计不断的建议与见解作出了很大的贡献。Brian Brazil 不断的反馈确保了我们最终得到的是语义上合理的方法。与 Peter Bourgon 深刻的讨论验证了设计并形成了这篇文章。
> 别忘了我们整个 CoreOS 团队与公司对于这项工作的赞助与支持。感谢所有那些听我一遍遍唠叨 SSD、浮点数、序列化格式的同学。
--------------------------------------------------------------------------------
via: https://fabxc.org/blog/2017-04-10-writing-a-tsdb/
作者:[Fabian Reinartz][a]
译者:[LuuMing](https://github.com/LuuMing)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://twitter.com/fabxc
[1]:https://en.wikipedia.org/wiki/Inode
[2]:https://prometheus.io/
[3]:https://kubernetes.io/
[4]:https://en.wikipedia.org/wiki/Write_amplification
[5]:http://codecapsule.com/2014/02/12/coding-for-ssds-part-1-introduction-and-table-of-contents/
[6]:https://prometheus.io/docs/practices/rules/
[7]:http://www.vldb.org/pvldb/vol8/p1816-teller.pdf
[8]:https://en.wikipedia.org/wiki/Mmap
[9]:https://en.wikipedia.org/wiki/Inverted_index
[10]:https://en.wikipedia.org/wiki/Search_engine_indexing#Inverted_indices
[11]:https://github.com/prometheus/prombench
[12]:https://prometheus.io/blog/2017/04/10/promehteus-20-sneak-peak/
[13]:https://github.com/prometheus/tsdb

View File

@ -0,0 +1,149 @@
[#]: collector: (lujun9972)
[#]: translator: (warmfrog)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10936-1.html)
[#]: subject: (5 projects for Raspberry Pi at home)
[#]: via: (https://opensource.com/article/17/4/5-projects-raspberry-pi-home)
[#]: author: (Ben Nuttall https://opensource.com/users/bennuttall)
5 个可在家中使用的树莓派项目
======================================
![5 projects for Raspberry Pi at home][1]
[树莓派][2] 电脑可被用来进行多种设置用于不同的目的。显然它在教育市场帮助学生在教室和创客空间中学习编程与创客技巧方面占有一席之地,它在工作场所和工厂中有大量行业应用。我打算介绍五个你可能想要在你的家中构建的项目。
### 媒体中心
在家中人们常用树莓派作为媒体中心来服务多媒体文件。它很容易搭建,树莓派提供了大量的 GPU图形处理单元运算能力来在大屏电视上渲染你的高清电视节目和电影。将 [Kodi][3](从前的 XBMC运行在树莓派上是一个很棒的方式它可以播放你的硬盘或网络存储上的任何媒体。你同样可以安装一个插件来播放 YouTube 视频。
还有几个略微不同的选择,最常见的是 [OSMC][4](开源媒体中心)和 [LibreELEC][5],都是基于 Kodi 的。它们在放映媒体内容方面表现的都非常好,但是 OSMC 有一个更酷炫的用户界面,而 LibreElec 更轻量级。你要做的只是选择一个发行版,下载镜像并安装到一个 SD 卡中(或者仅仅使用 [NOOBS][6]),启动,然后就准备好了。
![LibreElec ][7]
*LibreElec;树莓派基金会, CC BY-SA*
![OSMC][8]
*OSMC.tv, 版权所有, 授权使用*
在往下走之前,你需要决定[使用哪种树莓派][9]。这些发行版在任何树莓派1、2、3 或 Zero上都能运行视频播放在这些树莓派中的任何一个上都能胜任。除了 Pi 3和 Zero W有内置 Wi-Fi唯一可察觉的不同是用户界面的反应速度在 Pi 3 上更快。Pi 2 也不会慢太多,所以如果你不需要 Wi-Fi 它也是可以的,但是当切换菜单时,你会注意到 Pi 3 比 Pi 1 和 Zero 表现的更好。
### SSH 网关
如果你想从外部网络访问你的家庭局域网的电脑和设备,你必须打开这些设备的端口来允许外部访问。在互联网中开放这些端口有安全风险,意味着你总是你总是处于被攻击、滥用或者其他各种未授权访问的风险中。然而,如果你在你的网络中安装一个树莓派,并且设置端口映射来仅允许通过 SSH 访问树莓派,你可以这么用来作为一个安全的网关来跳到网络中的其他树莓派和 PC。
大多数路由允许你配置端口映射规则。你需要给你的树莓派一个固定的内网 IP 地址来设置你的路由器端口 22 映射到你的树莓派端口 22。如果你的网络服务提供商给你提供了一个静态 IP 地址,你能够通过 SSH 和主机的 IP 地址访问(例如,`ssh pi@123.45.56.78`)。如果你有一个域名,你可以配置一个子域名指向这个 IP 地址,所以你没必要记住它(例如,`ssh pi@home.mydomain.com`)。
![][11]
然而,如果你不想将树莓派暴露在互联网上,你应该非常小心,不要让你的网络处于危险之中。如果你遵循一些简单的步骤来使它更安全:
1. 大多数人建议你更换你的登录密码(有道理,默认密码 “raspberry” 是众所周知的),但是这不能阻挡暴力攻击。你可以改变你的密码并添加一个双重验证(所以你需要你的密码*和*一个手机生成的与时间相关的密码),这么做更安全。但是,我相信最好的方法阻止入侵者访问你的树莓派是在你的 SSH 配置中[禁止密码认证][12],这样只能通过 SSH 密匙进入。这意味着任何试图猜测你的密码尝试登录的人都不会成功。只有你的私有密匙可以访问。简单来说,很多人建议将 SSH 端口从默认的 22 换成其他的,但是通过简单的 [Nmap][13] 扫描你的 IP 地址,你信任的 SSH 端口就会暴露。
2. 最好,不要在这个树莓派上运行其他的软件,这样你不会意外暴露其他东西。如果你想要运行其他软件,你最好在网络中的其他树莓派上运行,它们没有暴露在互联网上。确保你经常升级来保证你的包是最新的,尤其是 `openssh-server` 包,这样你的安全缺陷就被打补丁了。
3. 安装 [sshblack][14] 或 [fail2ban][15] 来将任何表露出恶意的用户加入黑名单,例如试图暴力破解你的 SSH 密码。
使树莓派安全后,让它在线,你将可以在世界的任何地方登录你的网络。一旦你登录到你的树莓派,你可以用 SSH 访问本地网络上的局域网地址例如192.168.1.31)访问其他设备。如果你在这些设备上有密码,用密码就好了。如果它们同样只允许 SSH 密匙,你需要确保你的密匙通过 SSH 转发,使用 `-A` 参数:`ssh -A pi@123.45.67.89`。
### CCTV / 宠物相机
另一个很棒的家庭项目是安装一个相机模块来拍照和录视频,录制并保存文件,在内网或者外网中进行流式传输。你想这么做有很多原因,但两个常见的情况是一个家庭安防相机或监控你的宠物。
[树莓派相机模块][16] 是一个优秀的配件。它提供全高清的相片和视频,包括很多高级配置,很[容易编程][17]。[红外线相机][18]用于这种目的是非常理想的,通过一个红外线 LED树莓派可以控制的你就能够在黑暗中看见东西。
如果你想通过一定频率拍摄静态图片来留意某件事,你可以仅仅写一个简短的 [Python][19] 脚本或者使用命令行工具 [raspistill][20], 在 [Cron][21] 中规划它多次运行。你可能想将它们保存到 [Dropbox][22] 或另一个网络服务,上传到一个网络服务器,你甚至可以创建一个[web 应用][23]来显示他们。
如果你想要在内网或外网中流式传输视频,那也相当简单。在 [picamera 文档][24]中(在 “web streaming” 章节)有一个简单的 MJPEGMotion JPEG例子。简单下载或者拷贝代码到文件中运行并访问树莓派的 IP 地址的 8000 端口,你会看见你的相机的直播输出。
有一个更高级的流式传输项目 [pistreaming][25] 也可以,它通过在网络服务器中用 [JSMpeg][26] (一个 JavaScript 视频播放器)和一个用于相机流的单独运行的 websocket。这种方法性能更好并且和之前的例子一样简单但是如果要在互联网中流式传输则需要包含更多代码并且需要你开放两个端口。
一旦你的网络流建立起来,你可以将你的相机放在你想要的地方。我用一个来观察我的宠物龟:
![Tortoise ][27]
*Ben Nuttall, CC BY-SA*
如果你想控制相机位置,你可以用一个舵机。一个优雅的方案是用 Pimoroni 的 [Pan-Tilt HAT][28],它可以让你简单的在二维方向上移动相机。为了与 pistreaming 集成,可以看看该项目的 [pantilthat 分支][29].
![Pan-tilt][30]
*Pimoroni.com, Copyright, 授权使用*
如果你想将你的树莓派放到户外你将需要一个防水的外围附件并且需要一种给树莓派供电的方式。POE通过以太网提供电力电缆是一个不错的实现方式。
### 家庭自动化或物联网
现在是 2017 年LCTT 译注:此文发表时间),到处都有很多物联网设备,尤其是家中。我们的电灯有 Wi-Fi我们的面包烤箱比过去更智能我们的茶壶处于俄国攻击的风险中除非你确保你的设备安全不然别将没有必要的设备连接到互联网之后你可以在家中充分的利用物联网设备来完成自动化任务。
市场上有大量你可以购买或订阅的服务,像 Nest Thermostat 或 Philips Hue 电灯泡,允许你通过你的手机控制你的温度或者你的亮度,无论你是否在家。你可以用一个树莓派来催动这些设备的电源,通过一系列规则包括时间甚至是传感器来完成自动交互。用 Philips Hue你做不到的当你进房间时打开灯光但是有一个树莓派和一个运动传感器你可以用 Python API 来打开灯光。类似地,当你在家的时候你可以通过配置你的 Nest 打开加热系统,但是如果你想在房间里至少有两个人时才打开呢?写一些 Python 代码来检查网络中有哪些手机,如果至少有两个,告诉 Nest 来打开加热器。
不用选择集成已存在的物联网设备,你可以用简单的组件来做的更多。一个自制的窃贼警报器,一个自动化的鸡笼门开关,一个夜灯,一个音乐盒,一个定时的加热灯,一个自动化的备份服务器,一个打印服务器,或者任何你能想到的。
### Tor 协议和屏蔽广告
Adafruit 的 [Onion Pi][31] 是一个 [Tor][32] 协议来使你的网络通讯匿名,允许你使用互联网而不用担心窥探者和各种形式的监视。跟随 Adafruit 的指南来设置 Onion Pi你会找到一个舒服的匿名的浏览体验。
![Onion-Pi][33]
*Onion-pi from Adafruit, Copyright, 授权使用*
![Pi-hole][34]
可以在你的网络中安装一个树莓派来拦截所有的网络交通并过滤所有广告。简单下载 [Pi-hole][35] 软件到 Pi 中,你的网络中的所有设备都将没有广告(甚至屏蔽你的移动设备应用内的广告)。
树莓派在家中有很多用法。你在家里用树莓派来干什么?你想用它干什么?
在下方评论让我们知道。
--------------------------------------------------------------------------------
via: https://opensource.com/article/17/4/5-projects-raspberry-pi-home
作者:[Ben Nuttall][a]
选题:[lujun9972][b]
译者:[warmfrog](https://github.com/warmfrog)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/bennuttall
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry_pi_home_automation.png?itok=2TnmJpD8 (5 projects for Raspberry Pi at home)
[2]: https://www.raspberrypi.org/
[3]: https://kodi.tv/
[4]: https://osmc.tv/
[5]: https://libreelec.tv/
[6]: https://www.raspberrypi.org/downloads/noobs/
[7]: https://opensource.com/sites/default/files/libreelec_0.png (LibreElec )
[8]: https://opensource.com/sites/default/files/osmc.png (OSMC)
[9]: https://opensource.com/life/16/10/which-raspberry-pi-should-you-choose-your-project
[10]: mailto:pi@home.mydomain.com
[11]: https://opensource.com/sites/default/files/resize/screenshot_from_2017-04-07_15-13-01-700x380.png
[12]: http://stackoverflow.com/questions/20898384/ssh-disable-password-authentication
[13]: https://nmap.org/
[14]: http://www.pettingers.org/code/sshblack.html
[15]: https://www.fail2ban.org/wiki/index.php/Main_Page
[16]: https://www.raspberrypi.org/products/camera-module-v2/
[17]: https://opensource.com/life/15/6/raspberry-pi-camera-projects
[18]: https://www.raspberrypi.org/products/pi-noir-camera-v2/
[19]: http://picamera.readthedocs.io/
[20]: https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspistill.md
[21]: https://www.raspberrypi.org/documentation/linux/usage/cron.md
[22]: https://github.com/RZRZR/plant-cam
[23]: https://github.com/bennuttall/bett-bot
[24]: http://picamera.readthedocs.io/en/release-1.13/recipes2.html#web-streaming
[25]: https://github.com/waveform80/pistreaming
[26]: http://jsmpeg.com/
[27]: https://opensource.com/sites/default/files/tortoise.jpg (Tortoise)
[28]: https://shop.pimoroni.com/products/pan-tilt-hat
[29]: https://github.com/waveform80/pistreaming/tree/pantilthat
[30]: https://opensource.com/sites/default/files/pan-tilt.gif (Pan-tilt)
[31]: https://learn.adafruit.com/onion-pi/overview
[32]: https://www.torproject.org/
[33]: https://opensource.com/sites/default/files/onion-pi.jpg (Onion-Pi)
[34]: https://opensource.com/sites/default/files/resize/pi-hole-250x250.png (Pi-hole)
[35]: https://pi-hole.net/

View File

@ -0,0 +1,103 @@
为 man 手册页编写解析器的备忘录
======
![](https://img.linux.net.cn/data/attachment/album/201906/11/235607fiqfqapvpzqhh8n1.jpg)
我一般都很喜欢无所事事,但有时候太无聊了也不行 —— 2015 年的一个星期天下午就是这样,我决定开始写一个开源项目来让我不那么无聊。
在我寻求创意时,我偶然发现了一个请求,要求构建一个由 [Mathias Bynens][2] 提出的“[按 Web 标准构建的 Man 手册页查看器][1]”。没有考虑太多,我开始使用 JavaScript 编写一个手册页解析器,经过大量的反复思考,最终做出了一个 [Jroff][3]。
那时候,我非常熟悉手册页这个概念,而且使用过很多次,但我知道的仅止于此,我不知道它们是如何生成的,或者是否有一个标准。在经过两年后,我有了一些关于此事的想法。
### man 手册页是如何写的
当时令我感到惊讶的第一件事是,手册页的核心只是存储在系统某处的纯文本文件(你可以使用 `manpath` 命令检查这些目录)。
此文件中不仅包含文档,还包含使用了 20 世纪 70 年代名为 `troff` 的排版系统的格式化信息。
> troff 及其 GNU 实现 groff 是处理文档的文本描述以生成适合打印的排版版本的程序。**它更像是“你所描述的即你得到的”,而不是你所见即所得的。**
>
> - 摘自 [troff.org][4]
如果你对排版格式毫不熟悉,可以将它们视为 steroids 期刊用的 Markdown但其灵活性带来的就是更复杂的语法
![groff-compressor][5]
`groff` 文件可以手工编写,也可以使用许多不同的工具从其他格式生成,如 Markdown、Latex、HTML 等。
为什么 `groff` 和 man 手册页绑在一起是有历史原因的,其格式[随时间有变化][6]它的血统由一系列类似命名的程序组成RUNOFF > roff > nroff > troff > groff。
但这并不一定意味着 `groff` 与手册页有多紧密的关系,它是一种通用格式,已被用于[书籍][7],甚至用于[照相排版][8]。
此外,值得注意的是 `groff` 也可以调用后处理器将其中间输出结果转换为最终格式,这对于终端显示来说不一定是 ascii 一些支持的格式是TeX DVI、HTML、Canon、HP LaserJet4 兼容格式、PostScript、utf8 等等。
### 宏
该格式的其他很酷的功能是它的可扩展性,你可以编写宏来增强其基本功能。
鉴于 *nix 系统的悠久历史,有几个可以根据你想要生成的输出而将特定功能组合在一起的宏包,例如 `man`、`mdoc`、`mom`、`ms`、`mm` 等等。
手册页通常使用 `man``mdoc` 宏包编写。
区分原生的 `groff` 命令和宏的方式是通过标准 `groff` 包大写其宏名称。对于 `man` 宏包,每个宏的名称都是大写的,如 `.PP`、`.TH`、`.SH` 等。对于 `mdoc` 宏包,只有第一个字母是大写的: `.Pp`、`.Dt`、`.Sh`。
![groff-example][9]
### 挑战
无论你是考虑编写自己的 `groff` 解析器,还是只是好奇,这些都是我发现的一些更具挑战性的问题。
#### 上下文敏感的语法
表面上,`groff` 的语法是上下文无关的,遗憾的是,因为宏描述的是主体不透明的令牌,所以包中的宏集合本身可能不会实现上下文无关的语法。
这导致我在那时做不出来一个解析器生成器(不管好坏)。
#### 嵌套的宏
`mdoc` 宏包中的大多数宏都是可调用的,这差不多意味着宏可以用作其他宏的参数,例如,你看看这个:
* 宏 `Fl`Flag会在其参数中添加破折号因此 `Fl s` 会生成 `-s`
* 宏 `Ar`Argument提供了定义参数的工具
* 宏 `Op`Optional会将其参数括在括号中因为这是将某些东西定义为可选的标准习惯用法
* 以下组合 `.Op Fl s Ar file ` 将生成 `[-s file]`,因为 `Op` 宏可以嵌套。
#### 缺乏适合初学者的资源
让我感到困惑的是缺乏一个规范的、定义明确的、清晰的来源,网上有很多信息,这些信息对读者来说很重要,需要时间来掌握。
### 有趣的宏
总结一下,我会向你提供一个非常简短的宏列表,我在开发 jroff 时发现它很有趣:
`man` 宏包:
* `.TH`:用 `man` 宏包编写手册页时,你的第一个不是注释的行必须是这个宏,它接受五个参数:`title`、`section`、`date`、`source`、`manual`。
* `.BI`:粗体加斜体(特别适用于函数格式)
* `.BR`:粗体加正体(特别适用于参考其他手册页)
`mdoc` 宏包:
* `.Dd`、`.Dt`、`.Os`:类似于 `man` 宏包需要 `.TH``mdoc` 宏也需要这三个宏,需要按特定顺序使用。它们的缩写分别代表:文档日期、文档标题和操作系统。
* `.Bl`、`.It`、`.El`:这三个宏用于创建列表,它们的名称不言自明:开始列表、项目和结束列表。
--------------------------------------------------------------------------------
via: https://monades.roperzh.com/memories-writing-parser-man-pages/
作者:[Roberto Dip][a]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
选题:[lujun9972](https://github.com/lujun9972)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://monades.roperzh.com
[1]:https://github.com/h5bp/lazyweb-requests/issues/114
[2]:https://mathiasbynens.be/
[3]:jroff
[4]:https://www.troff.org/
[5]:https://user-images.githubusercontent.com/4419992/37868021-2e74027c-2f7f-11e8-894b-80829ce39435.gif
[6]:https://manpages.bsd.lv/history.html
[7]:https://rkrishnan.org/posts/2016-03-07-how-is-gopl-typeset.html
[8]:https://en.wikipedia.org/wiki/Phototypesetting
[9]:https://user-images.githubusercontent.com/4419992/37866838-e602ad78-2f6e-11e8-97a9-2a4494c766ae.jpg

View File

@ -0,0 +1,191 @@
如何使用 GParted 实用工具缩放根分区
======
今天,我们将讨论磁盘分区。这是 Linux 中的一个好话题。这允许用户来重新调整在 Linux 中的活动 root 分区。
在这篇文章中,我们将教你如何使用 GParted 缩放在 Linux 上的活动根分区。
比如说,当我们安装 Ubuntu 操作系统时,并没有恰当地配置,我们的系统仅有 30 GB 磁盘。我们需要安装另一个操作系统,因此我们想在其中制作第二个分区。
虽然不建议重新调整活动分区。然而,我们要执行这个操作,因为没有其它方法来释放系统分区。
> 注意:在执行这个动作前,确保你备份了重要的数据,因为如果一些东西出错(例如,电源故障或你的系统重启),你可以得以保留你的数据。
### Gparted 是什么
[GParted][1] 是一个自由的分区管理器,它使你能够缩放、复制和移动分区,而不丢失数据。通过使用 GParted 的 Live 可启动镜像,我们可以使用 GParted 应用程序的所有功能。GParted Live 可以使你能够在 GNU/Linux 以及其它的操作系统上使用 GParted例如Windows 或 Mac OS X 。
#### 1) 使用 df 命令检查磁盘空间利用率
我只是想使用 `df` 命令向你显示我的分区。`df` 命令输出清楚地表明我仅有一个分区。
```
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 30G 3.4G 26.2G 16% /
none 4.0K 0 4.0K 0% /sys/fs/cgroup
udev 487M 4.0K 487M 1% /dev
tmpfs 100M 844K 99M 1% /run
none 5.0M 0 5.0M 0% /run/lock
none 498M 152K 497M 1% /run/shm
none 100M 52K 100M 1% /run/user
```
#### 2) 使用 fdisk 命令检查磁盘分区
我将使用 `fdisk` 命令验证这一点。
```
$ sudo fdisk -l
[sudo] password for daygeek:
Disk /dev/sda: 33.1 GB, 33129218048 bytes
255 heads, 63 sectors/track, 4027 cylinders, total 64705504 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000473a3
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 62609407 31303680 83 Linux
/dev/sda2 62611454 64704511 1046529 5 Extended
/dev/sda5 62611456 64704511 1046528 82 Linux swap / Solaris
```
#### 3) 下载 GParted live ISO 镜像
使用下面的命令来执行下载 GParted live ISO。
```
$ wget https://downloads.sourceforge.net/gparted/gparted-live-0.31.0-1-amd64.iso
```
#### 4) 使用 GParted Live 安装介质启动你的系统
使用 GParted Live 安装介质(如烧录的 CD/DVD 或 USB 或 ISO 镜像)启动你的系统。你将获得类似于下面屏幕的输出。在这里选择 “GParted Live (Default settings)” ,并敲击回车按键。
![][3]
#### 5) 键盘选择
默认情况下,它选择第二个选项,按下回车即可。
![][4]
#### 6) 语言选择
默认情况下,它选择 “33” 美国英语,按下回车即可。
![][5]
#### 7) 模式选择(图形用户界面或命令行)
默认情况下,它选择 “0” 图形用户界面模式,按下回车即可。
![][6]
#### 8) 加载 GParted Live 屏幕
现在GParted Live 屏幕已经加载,它显示我以前创建的分区列表。
![][7]
#### 9) 如何重新调整根分区大小
选择你想重新调整大小的根分区,在这里仅有一个分区,所以我将编辑这个分区以便于安装另一个操作系统。
![][8]
为做到这一点,按下 “Resize/Move” 按钮来重新调整分区大小。
![][9]
现在,在第一个框中输入你想从这个分区中取出的大小。我将索要 “10GB”所以我添加 “10240MB”并让该对话框的其余部分为默认值然后点击 “Resize/Move” 按钮。
![][10]
它将再次要求你确认重新调整分区的大小,因为你正在编辑活动的系统分区,然后点击 “Ok”。
![][11]
分区从 30GB 缩小到 20GB 已经成功。也显示 10GB 未分配的磁盘空间。
![][12]
最后点击 “Apply” 按钮来执行下面剩余的操作。
![][13]
`e2fsck` 是一个文件系统检查实用程序,自动修复文件系统中与 HDD 相关的坏扇道、I/O 错误。
![][14]
`resize2fs` 程序将重新调整 ext2、ext3 或 ext4 文件系统的大小。它可以被用于扩大或缩小一个位于设备上的未挂载的文件系统。
![][15]
`e2image` 程序将保存位于设备上的关键的 ext2、ext3 或 ext4 文件系统的元数据到一个指定文件中。
![][16]
所有的操作完成,关闭对话框。
![][17]
现在,我们可以看到未分配的 “10GB” 磁盘分区。
![][18]
重启系统来检查这一结果。
![][19]
#### 10) 检查剩余空间
重新登录系统,并使用 `fdisk` 命令来查看在分区中可用的空间。是的,我可以看到这个分区上未分配的 “10GB” 磁盘空间。
```
$ sudo parted /dev/sda print free
[sudo] password for daygeek:
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 32.2GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
32.3kB 10.7GB 10.7GB Free Space
1 10.7GB 32.2GB 21.5GB primary ext4 boot
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility/
作者:[Magesh Maruthamuthu][a]
译者:[robsean](https://github.com/robsean)
校对:[wxy](https://github.com/wxy)
选题:[lujun9972](https://github.com/lujun9972)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/magesh/
[1]:https://gparted.org/
[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[3]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-1.png
[4]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-2.png
[5]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-3.png
[6]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-4.png
[7]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-5.png
[8]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-6.png
[9]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-7.png
[10]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-8.png
[11]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-9.png
[12]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-10.png
[13]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-11.png
[14]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-12.png
[15]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-13.png
[16]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-14.png
[17]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-15.png
[18]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-16.png
[19]:https://www.2daygeek.com/wp-content/uploads/2014/08/how-to-resize-active-primary-root-partition-in-linux-using-gparted-utility-17.png

View File

@ -0,0 +1,172 @@
BootISO从 ISO 文件中创建一个可启动的 USB 设备
======
![](https://img.linux.net.cn/data/attachment/album/201906/16/110109qq0b7atyaped3ij2.jpg)
为了安装操作系统,我们中的大多数人(包括我)经常从 ISO 文件中创建一个可启动的 USB 设备。为达到这个目的,在 Linux 中有很多自由可用的应用程序。甚至在过去我们写了几篇介绍这种实用程序的文章。
每个人使用不同的应用程序,每个应用程序有它们自己的特色和功能。在这些应用程序中,一些应用程序属于 CLI 程序,一些应用程序则是 GUI 的。
今天,我们将讨论名为 BootISO 的实用程序类似工具。它是一个简单的 bash 脚本,允许用户来从 ISO 文件中创建一个可启动的 USB 设备。
很多 Linux 管理员使用 `dd` 命令开创建可启动的 ISO ,它是一个著名的原生方法,但是与此同时,它也是一个非常危险的命令。因此,小心,当你用 `dd` 命令执行一些动作时。
建议阅读:
- [Etcher从一个 ISO 镜像中创建一个可启动的 USB 驱动器 & SD 卡的简单方法][1]
- [在 Linux 上使用 dd 命令来从一个 ISO 镜像中创建一个可启动的 USB 驱动器][2]
### BootISO 是什么
[BootISO][3] 是一个简单的 bash 脚本,允许用户来安全的从一个 ISO 文件中创建一个可启动的 USB 设备,它是用 bash 编写的。
它不提供任何图形用户界面而是提供了大量的选项,可以让初学者顺利地在 Linux 上来创建一个可启动的 USB 设备。因为它是一个智能工具,能自动地选择连接到系统上的 USB 设备。
当系统有多个 USB 设备连接,它将打印出列表。当你手动选择了另一个硬盘而不是 USB 时,在这种情况下,它将安全地退出,而不会在硬盘上写入任何东西。
这个脚本也将检查依赖关系,并提示用户安装,它可以与所有的软件包管理器一起工作,例如 apt-get、yum、dnf、pacman 和 zypper。
### BootISO 的功能
* 它检查选择的 ISO 是否是正确的 mime 类型。如果不是,那么退出。
* 如果你选择除 USB 设备以外的任何其它的磁盘本地硬盘BootISO 将自动地退出。
* 当你有多个驱动器时BootISO 允许用户选择想要使用的 USB 驱动器。
* 在擦除和分区 USB 设备前BootISO 会提示用户确认。
* BootISO 将正确地处理来自一个命令的任何错误,并退出。
* BootISO 在遇到问题退出时将调用一个清理例行程序。
### 如何在 Linux 中安装 BootISO
在 Linux 中安装 BootISO 有几个可用的方法,但是,我建议用户使用下面的方法安装。
```
$ curl -L https://git.io/bootiso -O
$ chmod +x bootiso
$ sudo mv bootiso /usr/local/bin/
```
一旦 BootISO 已经安装,运行下面的命令来列出可用的 USB 设备。
```
$ bootiso -l
Listing USB drives available in your system:
NAME HOTPLUG SIZE STATE TYPE
sdd 1 32G running disk
```
如果你仅有一个 USB 设备,那么简单地运行下面的命令来从一个 ISO 文件中创建一个可启动的 USB 设备。
```
$ bootiso /path/to/iso file
```
```
$ bootiso /opt/iso_images/archlinux-2018.05.01-x86_64.iso
Granting root privileges for bootiso.
Listing USB drives available in your system:
NAME HOTPLUG SIZE STATE TYPE
sdd 1 32G running disk
Autoselecting `sdd' (only USB device candidate)
The selected device `/dev/sdd' is connected through USB.
Created ISO mount point at `/tmp/iso.vXo'
`bootiso' is about to wipe out the content of device `/dev/sdd'.
Are you sure you want to proceed? (y/n)>y
Erasing contents of /dev/sdd...
Creating FAT32 partition on `/dev/sdd1'...
Created USB device mount point at `/tmp/usb.0j5'
Copying files from ISO to USB device with `rsync'
Synchronizing writes on device `/dev/sdd'
`bootiso' took 250 seconds to write ISO to USB device with `rsync' method.
ISO succesfully unmounted.
USB device succesfully unmounted.
USB device succesfully ejected.
You can safely remove it !
```
当你有多个 USB 设备时,可以使用 `--device` 选项指明你的设备名称。
```
$ bootiso -d /dev/sde /opt/iso_images/archlinux-2018.05.01-x86_64.iso
```
默认情况下BootISO 使用 `rsync` 命令来执行所有的动作,如果你想使用 `dd` 命令代替它,使用下面的格式。
```
$ bootiso --dd -d /dev/sde /opt/iso_images/archlinux-2018.05.01-x86_64.iso
```
如果你想跳过 mime 类型检查BootISO 实用程序带有下面的选项。
```
$ bootiso --no-mime-check -d /dev/sde /opt/iso_images/archlinux-2018.05.01-x86_64.iso
```
为 BootISO 添加下面的选项来跳过在擦除和分区 USB 设备前的用户确认。
```
$ bootiso -y -d /dev/sde /opt/iso_images/archlinux-2018.05.01-x86_64.iso
```
连同 `-y` 选项一起,启用自动选择 USB 设备。
```
$ bootiso -y -a /opt/iso_images/archlinux-2018.05.01-x86_64.iso
```
为知道更多的 BootISO 选项,运行下面的命令。
```
$ bootiso -h
Create a bootable USB from any ISO securely.
Usage: bootiso [...]
Options
-h, --help, help Display this help message and exit.
-v, --version Display version and exit.
-d, --device Select block file as USB device.
If is not connected through USB, `bootiso' will fail and exit.
Device block files are usually situated in /dev/sXX or /dev/hXX.
You will be prompted to select a device if you don't use this option.
-b, --bootloader Install a bootloader with syslinux (safe mode) for non-hybrid ISOs. Does not work with `--dd' option.
-y, --assume-yes `bootiso' won't prompt the user for confirmation before erasing and partitioning USB device.
Use at your own risks.
-a, --autoselect Enable autoselecting USB devices in conjunction with -y option.
Autoselect will automatically select a USB drive device if there is exactly one connected to the system.
Enabled by default when neither -d nor --no-usb-check options are given.
-J, --no-eject Do not eject device after unmounting.
-l, --list-usb-drives List available USB drives.
-M, --no-mime-check `bootiso' won't assert that selected ISO file has the right mime-type.
-s, --strict-mime-check Disallow loose application/octet-stream mime type in ISO file.
-- POSIX end of options.
--dd Use `dd' utility instead of mounting + `rsync'.
Does not allow bootloader installation with syslinux.
--no-usb-check `bootiso' won't assert that selected device is a USB (connected through USB bus).
Use at your own risks.
Readme
Bootiso v2.5.2.
Author: Jules Samuel Randolph
Bugs and new features: https://github.com/jsamr/bootiso/issues
If you like bootiso, please help the community by making it visible:
* star the project at https://github.com/jsamr/bootiso
* upvote those SE post: https://goo.gl/BNRmvm https://goo.gl/YDBvFe
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/bootiso-a-simple-bash-script-to-securely-create-a-bootable-usb-device-in-linux-from-iso-file/
作者:[Prakash Subramanian][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[robsean](https://github.com/robsean)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/prakash/
[1]:https://www.2daygeek.com/etcher-easy-way-to-create-a-bootable-usb-drive-sd-card-from-an-iso-image-on-linux/
[2]:https://www.2daygeek.com/create-a-bootable-usb-drive-from-an-iso-image-using-dd-command-on-linux/
[3]:https://github.com/jsamr/bootiso

View File

@ -1,21 +1,22 @@
[#]: collector: (lujun9972)
[#]: translator: (lujun9972)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10977-1.html)
[#]: subject: (Get desktop notifications from Emacs shell commands ·)
[#]: via: (https://blog.hoetzel.info/post/eshell-notifications/)
[#]: author: (Jürgen Hötzel https://blog.hoetzel.info)
Get desktop notifications from Emacs shell commands ·
让 Emacs shell 命令发送桌面通知
======
When interacting with the operating systems I always use [Eshell][1] because it integrates seamlessly with Emacs, supports (remote) [TRAMP][2] file names and also works nice on Windows.
After starting shell commands (like long running build jobs) I often lose track the task when switching buffers.
我总是使用 [Eshell][1] 来与操作系统进行交互,因为它与 Emacs 无缝整合、支持处理 (远程) [TRAMP][2] 文件,而且在 Windows 上也能工作得很好。
Thanks to Emacs [hooks][3] mechanism you can customize Emacs to call a elisp function when an external command finishes.
启动 shell 命令后 (比如耗时严重的构建任务) 我经常会由于切换缓冲区而忘了追踪任务的运行状态。
I use [John Wiegleys][4] excellent [alert][5] package to send desktop notifications:
多亏了 Emacs 的 [钩子][3] 机制,你可以配置 Emacs 在某个外部命令完成后调用一个 elisp 函数。
我使用 [John Wiegleys][4] 所编写的超棒的 [alert][5] 包来发送桌面通知:
```
(require 'alert)
@ -32,7 +33,7 @@ I use [John Wiegleys][4] excellent [alert][5] package to send desktop notificati
(add-hook 'eshell-kill-hook #'eshell-command-alert)
```
[alert][5] rules can be setup programmatically. In my case I only want to get notified if the corresponding buffer is not visible:
[alert][5] 的规则可以用程序来设置。就我这个情况来看,我只需要当对应的缓冲区不可见时得到通知:
```
(alert-add-rule :status '(buried) ;only send alert when buffer not visible
@ -40,7 +41,8 @@ I use [John Wiegleys][4] excellent [alert][5] package to send desktop notificati
:style 'notifications)
```
This even works on [TRAMP][2] buffers. Below is a screenshot showing a Gnome desktop notification of a failed `make` command.
这甚至对于 [TRAMP][2] 也一样生效。下面这个截屏展示了失败的 `make` 命令产生的 Gnome 桌面通知。
![../../img/eshell.png][6]
@ -51,7 +53,7 @@ via: https://blog.hoetzel.info/post/eshell-notifications/
作者:[Jürgen Hötzel][a]
选题:[lujun9972][b]
译者:[lujun9972](https://github.com/lujun9972)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@ -62,4 +64,4 @@ via: https://blog.hoetzel.info/post/eshell-notifications/
[3]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html (hooks)
[4]: https://github.com/jwiegley (John Wiegleys)
[5]: https://github.com/jwiegley/alert (alert)
[6]: https://blog.hoetzel.info/img/eshell.png (../../img/eshell.png)
[6]: https://blog.hoetzel.info/img/eshell.png

View File

@ -0,0 +1,56 @@
一条日志消息的现代生活
======
> 从一条日志消息的角度来巡览现代分布式系统。
![](https://img.linux.net.cn/data/attachment/album/201906/18/193030frxkcoccjhorz42o.jpg)
混沌系统往往是不可预测的。在构建像分布式系统这样复杂的东西时,这一点尤其明显。如果不加以控制,这种不可预测性会无止境的浪费时间。因此,分布式系统的每个组件,无论多小,都必须设计成以简化的方式组合在一起。
[Kubernetes][1] 为抽象计算资源提供了一个很有前景的模型 —— 但即使是它也必须与其他分布式平台(如 [Apache Kafka][2])协调一致,以确保可靠的数据传输。如果有人要整合这两个平台,它会如何运作?此外,如果你通过这样的系统跟踪像日志消息这么简单的东西,它会是什么样子?本文将重点介绍来自在 [OKD][3] 内运行的应用程序的日志消息如何通过 Kafka 进入数据仓库OKD 是为 Red Hat OpenShift 提供支持的 Kubernetes 的原初社区发行版)。
### OKD 定义的环境
这样的旅程始于 OKD因为该容器平台完全覆盖了它抽象的硬件。这意味着日志消息等待由驻留在容器中的应用程序写入 stdout 或 stderr 流。从那里,日志消息被容器引擎(例如 [CRI-O][4])重定向到节点的文件系统。
![](https://opensource.com/sites/default/files/uploads/logmessagepathway.png)
在 OpenShift 中,一个或多个容器封装在称为 pod豆荚的虚拟计算节点中。实际上在 OKD 中运行的所有应用程序都被抽象为 pod。这允许应用程序以统一的方式操纵。这也大大简化了分布式组件之间的通信因为 pod 可以通过 IP 地址和[负载均衡服务][5]进行系统寻址。因此,当日志消息由日志收集器应用程序从节点的文件系统获取时,它可以很容易地传递到在 OpenShift 中运行的另一个 pod 中。
### 在豆荚里的两个豌豆
为了确保可以在整个分布式系统中四处传播日志消息,日志收集器需要将日志消息传递到在 OpenShift 中运行的 Kafka 集群数据中心。通过 Kafka日志消息可以以可靠且容错的方式低延迟传递给消费应用程序。但是为了在 OKD 定义的环境中获得 Kafka 的好处Kafka 需要完全集成到 OKD 中。
运行 [Strimzi 操作子][6]将所有 Kafka 组件实例化为 pod并将它们集成在 OKD 环境中运行。 这包括用于排队日志消息的 Kafka 代理,用于从 Kafka 代理读取和写入的 Kafka 连接器,以及用于管理 Kafka 集群状态的 Zookeeper 节点。Strimzi 还可以将日志收集器实例化兼做 Kafka 连接器,允许日志收集器将日志消息直接提供给在 OKD 中运行的 Kafka 代理 pod。
### 在 OKD 内的 Kafka
当日志收集器 pod 将日志消息传递给 Kafka 代理时,收集器会写到单个代理分区,并将日志消息附加到该分区的末尾。使用 Kafka 的一个优点是它将日志收集器与日志的最终目标分离。由于解耦,日志收集器不关心日志最后是放在 [Elasticsearch][7]、Hadoop、Amazon S3 中的某个还是全都。Kafka 与所有基础设施连接良好,因此 Kafka 连接器可以在任何需要的地方获取日志消息。
一旦写入 Kafka 代理的分区,该日志消息就会在 Kafka 集群内的跨代理分区复制。这是它的一个非常强大的概念;结合平台的自愈功能,它创建了一个非常有弹性的分布式系统。例如,当节点变得不可用时,(故障)节点上运行的应用程序几乎立即在健康节点上生成。因此,即使带有 Kafka 代理的节点丢失或损坏,日志消息也能保证存活在尽可能多的节点上,并且新的 Kafka 代理将快速原位取代。
### 存储起来
在日志消息被提交到 Kafka 主题后,它将等待 Kafka 连接器使用它,该连接器将日志消息中继到分析引擎或日志记录仓库。在传递到其最终目的地时,可以分析日志消息以进行异常检测,也可以查询日志以立即进行根本原因分析,或用于其他目的。无论哪种方式,日志消息都由 Kafka 以安全可靠的方式传送到目的地。
OKD 和 Kafka 是正在迅速发展的功能强大的分布式平台。创建能够在不影响性能的情况下抽象出分布式计算的复杂特性的系统至关重要。毕竟,如果我们不能简化单一日志消息的旅程,我们怎么能夸耀全系统的效率呢?
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/life-log-message
作者:[Josef Karásek][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jkarasek
[1]: https://kubernetes.io/
[2]: https://kafka.apache.org/
[3]: https://www.okd.io/
[4]: http://cri-o.io/
[5]: https://kubernetes.io/docs/concepts/services-networking/service/
[6]: http://strimzi.io/
[7]: https://www.elastic.co/

View File

@ -0,0 +1,178 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10969-1.html)
[#]: subject: (GoAccess A Real-Time Web Server Log Analyzer And Interactive Viewer)
[#]: via: (https://www.2daygeek.com/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer/)
[#]: author: (Vinoth Kumar https://www.2daygeek.com/author/vinoth/)
GoAccess一个实时的 Web 日志分析器及交互式查看器
======
![](https://img.linux.net.cn/data/attachment/album/201906/12/222616h80pl0k0tt811071.jpg)
分析日志文件对于 Linux 管理员来说是一件非常令人头疼的事情,因为它记录了很多东西。大多数新手和初级管理员都不知道如何分析。如果你在分析日志方面拥有很多知识,那么你就成了 *NIX 系统高手。
Linux 中有许多工具可以轻松分析日志。GoAccess 是允许用户轻松分析 Web 服务器日志的工具之一。我们将在本文中详细讨论 GoAccess 工具。
### GoAccess
GoAccess 是一个实时 Web 日志分析器和交互式查看器,可以在 *nix 系统中的终端运行或通过浏览器访问。
GoAccess 需要的依赖极少,它是用 C 语言编写的,只需要 ncurses。
它支持 Apache、Nginx 和 Lighttpd 日志。它为需要动态可视化服务器报告的系统管理员即时提供了快速且有价值的 HTTP 统计信息。
GoAccess 可以解析指定的 Web 日志文件并将数据输出到 X 终端和浏览器。
GoAccess 被设计成一个基于终端的快速日志分析器。其核心思想是实时快速分析和查看 Web 服务器统计信息,而无需使用浏览器。
默认输出是在终端输出,它也能够生成完整的、自包含的实时 HTML 报告,以及 JSON 和 CSV 报告。
GoAccess 支持任何自定义日志格式并包含以下预定义日志格式选项Apache/Nginx 中的组合日志格式 XLF/ELFApache 中的通用日志格式 CLF但不限于此。
### GoAccess 功能
* 完全实时:所有指标在终端上每 200 毫秒更新一次,在 HTML 输出上每秒更新一次。
* 跟踪应用程序响应时间:跟踪服务请求所需的时间。如果你想跟踪减慢了网站速度的网页,则非常有用。
* 访问者:按小时或日期确定最慢运行的请求的点击量、访问者数、带宽数和指标。
* 按虚拟主机的度量标准:如果有多个虚拟主机(`Server`),它提供了一个面板,可显示哪些虚拟主机正在消耗大部分 Web 服务器资源。
### 如何安装 GoAccess
我建议用户在包管理器的帮助下从发行版官方的存储库安装 GoAccess。它在大多数发行版官方存储库中都可用。
我们知道,我们在标准发行方式的发行版中得到的是过时的软件包,而滚动发行方式的发行版总是包含最新的软件包。
如果你使用标准发行方式的发行版运行操作系统,我建议你检查替代选项,如 PPA 或 GoAccess 官方维护者存储库等,以获取最新的软件包。
对于 Debian / Ubuntu 系统,使用 [APT-GET 命令][1]或 [APT 命令][2]在你的系统上安装 GoAccess。
```
# apt install goaccess
```
要获取最新的 GoAccess 包,请使用以下 GoAccess 官方存储库。
```
$ echo "deb https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/goaccess.list
$ wget -O - https://deb.goaccess.io/gnugpg.key | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install goaccess
```
对于 RHEL / CentOS 系统,使用 [YUM 包管理器][3]在你的系统上安装 GoAccess。
```
# yum install goaccess
```
对于 Fedora 系统,使用 [DNF 包管理器][4]在你的系统上安装 GoAccess。
```
# dnf install goaccess
```
对于基于 ArchLinux / Manjaro 的系统,使用 [Pacman 包管理器][5]在你的系统上安装 GoAccess。
```
# pacman -S goaccess
```
对于 openSUSE Leap 系统,使用[Zypper 包管理器][6]在你的系统上安装 GoAccess。
```
# zypper install goaccess
# zypper ar -f obs://server:http
# zypper ref && zypper in goaccess
```
### 如何使用 GoAccess
成功安装 GoAccess 后。只需输入 `goaccess` 命令,然后输入 Web 服务器日志位置即可查看。
```
# goaccess [options] /path/to/Web Server/access.log
# goaccess /var/log/apache/2daygeek_access.log
```
执行上述命令时,它会要求您选择日志格式配置。
![][8]
我用 Apache 访问日志对此进行了测试。Apache 日志被分为十五个部分。详情如下。主要部分显示了这十五个部分的摘要。
以下屏幕截图包括四个部分,例如唯一身份访问者、请求的文件、静态请求、未找到的网址。
![][10]
以下屏幕截图包括四个部分,例如访客主机名和 IP、操作系统、浏览器、时间分布。
![][10]
以下屏幕截图包括四个部分例如来源网址、来源网站Google 的搜索引擎结果、HTTP状态代码。
![][11]
如果要生成 html 报告,请使用以下命令。最初我在尝试生成 html 报告时遇到错误。
```
# goaccess 2daygeek_access.log -a > report.html
GoAccess - version 1.3 - Nov 23 2018 11:28:19
Config file: No config file used
Fatal error has occurred
Error occurred at: src/parser.c - parse_log - 2764
No time format was found on your conf file.Parsing... [0] [0/s]
```
它说“你的 conf 文件没有找到时间格式”。要解决此问题,请为其添加 “COMBINED” 日志格式选项。
```
# goaccess -f 2daygeek_access.log --log-format=COMBINED -o 2daygeek.html
Parsing...[0,165] [50,165/s]
```
![][12]
GoAccess 也允许你访问和分析实时日志并进行过滤和解析。
```
# tail -f /var/log/apache/2daygeek_access.log | goaccess -
```
更多细节请参考其 man 手册页或帮助。
```
# man goaccess
# goaccess --help
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer/
作者:[Vinoth Kumar][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.2daygeek.com/author/vinoth/
[b]: https://github.com/lujun9972
[1]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
[2]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
[3]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
[4]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
[5]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
[6]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
[7]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[8]: https://www.2daygeek.com/wp-content/uploads/2019/01/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer-1.png
[9]: https://www.2daygeek.com/wp-content/uploads/2019/01/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer-2.png
[10]: https://www.2daygeek.com/wp-content/uploads/2019/01/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer-3.png
[11]: https://www.2daygeek.com/wp-content/uploads/2019/01/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer-4.png
[12]: https://www.2daygeek.com/wp-content/uploads/2019/01/goaccess-a-real-time-web-server-log-analyzer-and-interactive-viewer-5.png

View File

@ -0,0 +1,140 @@
[#]: collector: "lujun9972"
[#]: translator: "qfzy1233"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-11028-1.html"
[#]: subject: "Top 5 Linux Distributions for Productivity"
[#]: via: "https://www.linux.com/blog/learn/2019/1/top-5-linux-distributions-productivity"
[#]: author: "Jack Wallen https://www.linux.com/users/jlwallen"
5 个最具生产力的 Linux 发行版
======
> 如果你正在寻找一个适合开发工作的完美环境,我敢说你找不到比 Pop!_OS 更好的选择。
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_main.jpg?itok=2IKyg_7_)
必须承认的是这样的一个热门话题其实很难被总结的话题。为什么呢首先Linux 在就是一种有生产力的操作系统。由于它极强的可靠性和稳定的平台,使得完成工作变得很容易。其次为了衡量工作的效率,你需要考虑到哪项工作需要得到生产力方面的助推。是日常办公?开发类工作?学校事务?数据挖掘?或者是人力资源?你可以看到这个问题有多复杂。
然而,这并不意味着某些发行版无法更好地配置将底层操作系统呈现为一个有效的平台来完成工作。恰恰相反,许多发行版在偏离生产力这条道路上越走越远,所以你不会意识到你自己处在工作的窘境中,而是继续挖掘自己的潜力在工期结束之前拼命赶上进度。这些 Linux 发行版可以帮助你化繁为简,因此或许可以减少你工作流程中的痛点。
让我们来看一下这些发行版并为你找出适合你的最佳选择。为了更具条理,我按照生产力诉求把它们分成了几类。这项任务本身也是一种挑战,因为每个人在生产力提升上的需要是千差万别的。然而,我所关注的是下列的几项:
* 常规:适于那些只需要有效地完成多项工作的人。
* 设计:适于那些从事设计创造和图像处理的人。
* 开发:适于那些使用 Linux 桌面发行版来进行编程工作的人。
* 运维:适于那些需要一个发行版来促进其执行系统管理任务的人。
* 教育:适于那些需要桌面发行版可以助力他们在教育领域更高效的人。
诚然,有很多很多类别的发行版可供挑选,其中的很多可能用起来十分得心应手,但这五种或许是你最为需要的。
### 常规
对于常规的生产力诉求来说,你不会找到比 [Ubuntu][1] 更为高效的了。在这个类别中首推 Ubuntu 最主要的原因是因为它实现了桌面操作系统、软件、服务的无缝集成。你可能会问为什么我不选择同类别的 Linux Mint 呢?因为 Ubuntu 现在默认的的桌面环境为 GNOME 桌面,而它拥有 GNOME 许多扩展程序的优势的加成(图 1
![GNOME Clipboard][3]
*图 1运行中的 GNOME 桌面的剪切板管理工具。*
这些扩展程序在提升生产力方面做了很多努力(所以 Ubuntu 比 Linux Mint 获得了更多的认可)。但是 Ubuntu 不仅仅是装了一个普通的 GNOME 桌面。事实上,他们致力于将它改进的更为轻量化、更为高效、以及用户友好度更高、开箱即用。总而言之,由于 Ubuntu 正确的融合了多种特性,开箱即用,完善的软件支持(仅对工作方面而言),这些特性使它几乎成为了生产力领域最为完美的一个平台。
不管你是要写一篇文档制作一张电子表格写一个新的软件开发公司的网站设计商用的图形管理一个服务器或是网络抑或是在你的公司内从事人力资源管理工作Ubuntu 都可以满足你的需求。Ubuntu 桌面发行版也并不要求你耗费很大的精力才能开始开始开展工作……它直接就能使用(并且工作的十分优秀)。最后,得益于它是基于 Debian 的,使得在 Ubuntu 上安装第三方的软件十分简便。
很难不支持这一发行版独占生产力发行版列表的鳌头,尽管 Ubuntu 几乎已经成为几乎所有“某某类顶级发行版”列表的榜首。
### 设计
如果你正在寻求提升你的平面设计效率,你不能错过 [Fedora 设计套件][5]。这一 Fedora 衍生版是由负责 Fedora 相关的艺术作品的团队亲自操刀制作的。虽然其默认选择的应用程序并不是一个庞大的工具集合,但它所包含的工具都是创建和处理图像专用的。
有了 GIMP、Inkscape、Darktable、Krita、Entangle、Blender、Pitivi、Scribus 等应用程序(图 2你可以找到完成图像编辑工作所需要的一切。但是 Fedora 设计套件并不仅限于此。这个桌面平台还包括一堆教程涵盖了许多已安装的应用程序。对于任何想要尽可能提高效率的人来说这将是一些非常有用的信息。不过我要说的是GNOME 收藏夹中的教程并没有超乎[此页中][6]链接的内容。
![Fedora Design Suite Favorites][8]
*图 2Fedora 设计套件收藏夹菜单包含了许多工具,可以让你用于图形设计。*
那些使用数码相机的用户肯定会喜欢 Entangle 应用程序,它可以让你在电脑上控制单反相机。
### 开发
几乎所有的 Linux 发行版都是程序员的绝佳平台。然而,有一种特定的发行版脱颖而出,并超越了其他发行版,它将是你见过的用于编程类最有效率的工具之一。这个操作系统来自 [System76][9]LCTT 译注:一家美国的计算机制造商),名为 [Pop!\_OS][10]。Pop!\_OS 是专门为创作者定制的但不是针对艺术类。相反Pop!\_OS 面向专门从事开发、编程和软件制作的程序员。如果你需要一个既能完美的胜任开发工作又包含符合使用习惯的桌面操作系统的开发环境Pop!\_OS 将会是你的不二选择。(图 3
可能会让你感到惊讶(考虑到这个操作系统是多么“年轻”)的是 Pop!\_OS 也是你将使用的基于 GNOME 平台的最稳定系统的之一。这意味着 Pop!\_OS 不只是为创作者和创客准备的,也是为任何想要一个可靠的操作系统的人准备的。你可以下载针对你的硬件的专门 ISO 文件,这一点是许多用户十分欣赏的。如果你有英特尔硬件,[下载][10] Intel 或 AMD 的版本。如果你的显卡是 NVIDIA请下载该特定版本。不管怎样你肯定会得到针对不同平台进行特殊定制的稳定版本。
![Pop!_OS][12]
*图 3装有 GNOME 桌面的 Pop!_OS 一览。*
有趣的是,在 Pop!\_OS 中,你不会找到太多预装的开发工具。你也不会找到 IDE 或许多其他开发工具。但是,你可以在 Pop 商店中中找到所需的所有开发工具。
### 运维
如果你正在寻找适合系统管理的最具生产力的发行版,[Debian][13] 将会是你的不二之选。为什么这么说呢?因为 Debian 不仅仅拥有无与伦比的可靠性它也是众多能从苦海中将你解救出来的最好的一个发行版。Debian 是易用性和无限可能性的完美结合。最重要的是,因为它是许多其他发行版的基础,所以可以打赌,如果你需要一个任务的管理工具,那么它一定支持 Debian 系统。当然,我们讨论的是一般的系统管理任务,这意味着大多数时候你需要使用终端窗口 SSH 连接到服务器(图 4或者在浏览器上使用网络上基于 web 的 GUI 工具。既然如此为什么还要使用一个增加复杂性的桌面呢(比如 Fedora 中的 SELinux 或 openSUSE 中的 YaST所以应选择更为简洁易用的那一种。
![Debian][15]
*图 4在 Debian 系统上通过 SSH 连接到远程服务器。*
你可以选择你想要的不同的桌面(包括 GNOME、Xfce、KDE、Cinnamon、MATE、LXDE可以确保你所使用的桌面外观最适合你的工作习惯。
### 教育
如果你是一名老师或学生,抑或是其他从事与教育相关工作的人士,你需要适当的工具来提高生产力。之前,有 Edubuntu 这样的版本。这一版本位列教育类相关发行版排名的前列。然而,自从 Ubuntu 14.04 版之后这一发行版就再也没有更新。还好,现在有一款基于 openSUSE 的新的以教育为基础的发行版有望夺摘得桂冠。这一改版叫做 [openSUSE:Education-Li-f-e][16]Li-f-eLinux For Education - 图 5它基于 openSUSE Leap 42.1 (所以它可能稍微有一点过时)。
openSUSE:Education-Li-f-e 包含了以下工具:
* Brain Workshop大脑工坊一种基于 dual n-back 模式的大脑训练软件LCTT 译注dual n-back 训练是一种科学的智力训练方法,可以改善人的工作记忆和流体智力)
* GCompris一种针对青少年的教育软件包
* gElemental一款元素周期表查看工具
* iGNUit一款通用的记忆卡片工具
* Little Wizard基于 Pascal 语言的少儿编程开发环境
* Stellarium天文模拟器
* TuxMath数学入门游戏
* TuxPaint一款少儿绘画软件
* TuxType一款为少儿准备的打字入门软件
* wxMaxima一个跨平台的计算机代数系统
* Inkscape矢量图形编辑软件
* GIMP图像处理软件LCTT 译注:被誉为 Linux 上的 PhotoShop
* PencilGUI 模型制作工具
* Hugin全景照片拼接及 HDR 效果混合软件
![Education][18]
*图 5openSUSE:Education-Li-f-e 发行版拥有大量的工具可以帮你在学校中变得更为高效。*
同时还集成在 openSUSE:Education-Li-f-e 中的还有 [KIWI-LTSP Server][19] 。KIWI-LTSP 服务器是一个灵活的、经济高效的解决方案,旨在使全世界的学校、企业和组织能够轻松地安装和部署桌面工作站。虽然这可能不会直接帮助学生变得更具生产力,但它肯定会使教育机构在部署供学生使用的桌面时更有效率。有关配置 KIWI-LTSP 的更多信息,请查看 openSUSE [KIWI-LTSP 快速入门指南][20]。
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/learn/2019/1/top-5-linux-distributions-productivity
作者:[Jack Wallen][a]
选题:[lujun9972][b]
译者:[qfzy1233](https://github.com/qfzy1233)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.linux.com/users/jlwallen
[b]: https://github.com/lujun9972
[1]: https://www.ubuntu.com/
[2]: /files/images/productivity1jpg
[3]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_1.jpg?itok=yxez3X1w "GNOME Clipboard"
[4]: /licenses/category/used-permission
[5]: https://labs.fedoraproject.org/en/design-suite/
[6]: https://fedoraproject.org/wiki/Design_Suite/Tutorials
[7]: /files/images/productivity2jpg
[8]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_2.jpg?itok=ke0b8qyH "Fedora Design Suite Favorites"
[9]: https://system76.com/
[10]: https://system76.com/pop
[11]: /files/images/productivity3jpg-0
[12]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_3_0.jpg?itok=8UkCUfsD "Pop!_OS"
[13]: https://www.debian.org/
[14]: /files/images/productivity4jpg
[15]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_4.jpg?itok=c9yD3Xw2 "Debian"
[16]: https://en.opensuse.org/openSUSE:Education-Li-f-e
[17]: /files/images/productivity5jpg
[18]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_5.jpg?itok=oAFtV8nT "Education"
[19]: https://en.opensuse.org/Portal:KIWI-LTSP
[20]: https://en.opensuse.org/SDB:KIWI-LTSP_quick_start
[21]: https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@ -0,0 +1,126 @@
[#]: collector: (lujun9972)
[#]: translator: (luuming)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11004-1.html)
[#]: subject: (5 Good Open Source Speech Recognition/Speech-to-Text Systems)
[#]: via: (https://fosspost.org/lists/open-source-speech-recognition-speech-to-text)
[#]: author: (Simon James https://fosspost.org/author/simonjames)
5 款不错的开源语音识别/语音文字转换系统
======
![](https://i0.wp.com/fosspost.org/wp-content/uploads/2019/02/open-source-speech-recognition-speech-to-text.png?resize=1237%2C527&ssl=1)
<ruby>语音文字转换<rt>speech-to-text</rt></ruby>STT系统就像它名字所蕴含的意思那样是一种将说出的单词转换为文本文件以供后续用途的方式。
语音文字转换技术非常有用。它可以用到许多应用中,例如自动转录,使用自己的声音写书籍或文本,用生成的文本文件和其他工具做复杂的分析等。
在过去,语音文字转换技术以专有软件和库为主导,要么没有开源替代品,要么有着严格的限制,也没有社区。这一点正在发生改变,当今有许多开源语音文字转换工具和库可以让你随时使用。
这里我列出了 5 个。
### 开源语音识别库
#### DeepSpeech 项目
![5 Good Open Source Speech Recognition/Speech-to-Text Systems 15 open source speech recognition][1]
该项目由 Firefox 浏览器的开发组织 Mozilla 团队开发。它是 100% 的自由开源软件,其名字暗示使用了 TensorFlow 机器学习框架实现去功能。
换句话说,你可以用它训练自己的模型获得更好的效果,甚至可以用它来转换其它的语言。你也可以轻松的将它集成到自己的 Tensorflow 机器学习项目中。可惜的是项目当前默认仅支持英语。
它也支持许多编程语言,例如 Python3.6)。可以让你在数秒之内完成工作:
```
pip3 install deepspeech
deepspeech --model models/output_graph.pbmm --alphabet models/alphabet.txt --lm models/lm.binary --trie models/trie --audio my_audio_file.wav
```
你也可以通过 `npm` 安装它:
```
npm install deepspeech
```
- [项目主页][2]
#### Kaldi
![5 Good Open Source Speech Recognition/Speech-to-Text Systems 17 open source speech recognition][3]
Kaldi 是一个用 C++ 编写的开源语音识别软件,并且在 Apache 公共许可证下发布。它可以运行在 Windows、macOS 和 Linux 上。它的开发始于 2009。
Kaldi 超过其他语音识别软件的主要特点是可扩展和模块化。社区提供了大量的可以用来完成你的任务的第三方模块。Kaldi 也支持深度神经网络,并且在它的网站上提供了[出色的文档][4]。
虽然代码主要由 C++ 完成,但它通过 Bash 和 Python 脚本进行了封装。因此,如果你仅仅想使用基本的语音到文字转换功能,你就会发现通过 Python 或 Bash 能够轻易的实现。
- [项目主页][5]
#### Julius
![5 Good Open Source Speech Recognition/Speech-to-Text Systems 19 open source speech recognition][6]
它可能是有史以来最古老的语音识别软件之一。它的开发始于 1991 年的京都大学,之后在 2005 年将所有权转移到了一个独立的项目组。
Julius 的主要特点包括了执行实时 STT 的能力低内存占用20000 单词少于 64 MB能够输出<ruby>最优词<rt>N-best word</rt></ruby><ruby>词图<rt>Word-graph</rt></ruby>,能够作为服务器单元运行等等。这款软件主要为学术和研究所设计。由 C 语言写成,并且可以运行在 Linux、Windows、macOS 甚至 Android在智能手机上
它当前仅支持英语和日语。软件应该能够从 Linux 发行版的仓库中轻松安装。只要在软件包管理器中搜索 julius 即可。最新的版本[发布][7]于本文发布前大约一个半月之前。
- [项目主页][8]
#### Wav2Letter++
![5 Good Open Source Speech Recognition/Speech-to-Text Systems 21 open source speech recognition][9]
如果你在寻找一个更加时髦的那么这款一定适合。Wav2Letter++ 是一款由 Facebook 的 AI 研究团队于 2 个月之前发布的开源语言识别软件。代码在 BSD 许可证下发布。
Facebook 描述它的库是“最快、<ruby>最先进<rt>state-of-the-art</rt></ruby>的语音识别系统”。构建它时的理念使其默认针对性能进行了优化。Facebook 最新的机器学习库 [FlashLight][11] 也被用作 Wav2Letter++ 的底层核心。
Wav2Letter++ 需要你先为所描述的语言建立一个模型来训练算法。没有任何一种语言(包括英语)的预训练模型,它仅仅是个机器学习驱动的文本语音转换工具,它用 C++ 写成,因此被命名为 Wav2Letter++。
- [项目主页][12]
#### DeepSpeech2
![5 Good Open Source Speech Recognition/Speech-to-Text Systems 23 open source speech recognition][13]
中国软件巨头百度的研究人员也在开发他们自己的语音文字转换引擎叫做“DeepSpeech2”。它是一个端对端的开源引擎使用“PaddlePaddle”深度学习框架进行英语或汉语的文字转换。代码在 BSD 许可证下发布。
该引擎可以在你想用的任何模型和任何语言上训练。模型并未随代码一同发布。你要像其他软件那样自己建立模型。DeepSpeech2 的源代码由 Python 写成,如果你使用过就会非常容易上手。
- [项目主页][14]
### 总结
语音识别领域仍然主要由专有软件巨头所占据,比如 Google 和 IBM它们为此提供了闭源商业服务但是开源同类软件很有前途。这 5 款开源语音识别引擎应当能够帮助你构建应用,随着时间推移,它们会不断地发展。在几年之后,我们希望开源成为这些技术中的常态,就像其他行业那样。
如果你对清单有其他的建议或评论,我们很乐意在下面听到。
--------------------------------------------------------------------------------
via: https://fosspost.org/lists/open-source-speech-recognition-speech-to-text
作者:[Simon James][a]
选题:[lujun9972][b]
译者:[LuuMing](https://github.com/LuuMing)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fosspost.org/author/simonjames
[b]: https://github.com/lujun9972
[1]: https://i0.wp.com/fosspost.org/wp-content/uploads/2019/02/hero_speech-machine-learning2.png?resize=820%2C280&ssl=1 (5 Good Open Source Speech Recognition/Speech-to-Text Systems 16 open source speech recognition)
[2]: https://github.com/mozilla/DeepSpeech
[3]: https://i0.wp.com/fosspost.org/wp-content/uploads/2019/02/Screenshot-at-2019-02-19-1134.png?resize=591%2C138&ssl=1 (5 Good Open Source Speech Recognition/Speech-to-Text Systems 18 open source speech recognition)
[4]: http://kaldi-asr.org/doc/index.html
[5]: http://kaldi-asr.org
[6]: https://i2.wp.com/fosspost.org/wp-content/uploads/2019/02/mic_web.png?resize=385%2C100&ssl=1 (5 Good Open Source Speech Recognition/Speech-to-Text Systems 20 open source speech recognition)
[7]: https://github.com/julius-speech/julius/releases
[8]: https://github.com/julius-speech/julius
[9]: https://i2.wp.com/fosspost.org/wp-content/uploads/2019/02/fully_convolutional_ASR.png?resize=850%2C177&ssl=1 (5 Good Open Source Speech Recognition/Speech-to-Text Systems 22 open source speech recognition)
[10]: https://code.fb.com/ai-research/wav2letter/
[11]: https://github.com/facebookresearch/flashlight
[12]: https://github.com/facebookresearch/wav2letter
[13]: https://i2.wp.com/fosspost.org/wp-content/uploads/2019/02/ds2.png?resize=850%2C313&ssl=1 (5 Good Open Source Speech Recognition/Speech-to-Text Systems 24 open source speech recognition)
[14]: https://github.com/PaddlePaddle/DeepSpeech

View File

@ -0,0 +1,163 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10956-1.html)
[#]: subject: (Blockchain 2.0 Explaining Smart Contracts And Its Types [Part 5])
[#]: via: (https://www.ostechnix.com/blockchain-2-0-explaining-smart-contracts-and-its-types/)
[#]: author: (editor https://www.ostechnix.com/author/editor/)
区块链 2.0:智能合约及其类型(五)
======
![Explaining Smart Contracts And Its Types][1]
这是 区块链 2.0 系列的第 5 篇文章。本系列的前一篇文章探讨了我们如何[在房地产行业实现区块链][2]。本文简要探讨了区块链及相关技术领域内的<ruby>智能合约<rt>Smart Contract</rt></ruby>主题。智能合约是在区块链上验证和创建新“数据块”的基本协议,它被吹捧为该系统未来发展和应用的焦点。 然而,像所有“万灵药”一样,它不是一切的答案。我们将从基础知识中探索这个概念,以了解“智能合约”是什么以及它们不是什么。
### 不断发展的合同
这个世界建立在合同(合约)之上。在当前社会,没有合约的使用和再利用,地球上任何个人或公司都无法运作。订立、维护和执行合同的任务变得如此复杂,以至于整个司法和法律系统都必须以“合同法”的名义建立起来以支持它。事实上,大多数合同都是由一个“可信的”第三方监督,以确保最终的利益攸关者按照达成的条件得到妥善处理。有些合同甚至涉及到了第三方受益人。此类合同旨在对不是合同的活跃(或参与)方的第三方产生影响。解决和争论合同义务占据了民事诉讼所涉及的大部分法律纠纷。当然,更好的处理合同的方式来对于个人和企业来说都是天赐之物。更不用说它将以核查和证明的名义节省政府的巨大的[文书工作][7] [^1]。
本系列中的大多数文章都研究了如何利用现有的区块链技术。相比之下,这篇文章将更多地讲述对未来几年的预期。关于“智能合约”的讨论源于前一篇文章中提出的财产讨论。当前这篇文章旨在概述区块链自动执行“智能”可执行程序的能力。务实地处理这个问题意味着我们首先必须定义和探索这些“智能合约”是什么,以及它们如何适应现有的合同系统。我们将在下一篇题为“区块链 2.0:正在进行的项目”的文章中查看当前该领域正在进行的主要应用和项目。
### 定义智能合约
[本系列的第一篇文章][3]从基本的角度来看待区块链,将其看作由数据块组成的“分布式分类账本”,这些数据块是:
* 防篡改
* 不可否认(意味着每个数据块都是由某人显式创建的,并且该人不能否认相同的责任)
* 安全,且能抵御传统的网络攻击方法
* 几乎是永久性的(当然这取决于区块链协议层)
* 高度冗余,通过存在于多个网络节点或参与者系统上,其中一个节点的故障不会以任何方式影响系统的功能,并且,
* 根据应用的不同可以提供更快的处理速度。
由于每个数据实例都是安全存储和通过适当的凭证访问的,因此区块链网络可以为精确验证事实和信息提供简便的基础,而无需第三方监督。区块链 2.0 开发也允许“分布式应用程序DApp我们将在接下来的文章中详细介绍这个术语。这些分布式应用程序要求存在网络上并在其上运行。当用户需要它们时就会调用它们并通过使用已经过审核并存储在区块链上的信息来执行它们。
上面的最后一段为智能合约的定义提供了基础。<ruby>数字商会<rt>The Chamber for Digital Commerce</rt></ruby>提供了一个许多专家都同意的智能合约定义。
> “(智能合约是一种)计算机代码,在发生指定条件时,能够根据预先指定的功能自动运行。该代码可以在分布式分类帐本上存储和处理,并将产生的任何更改写入分布式分类帐本” [^2]。
智能合约如上所述是一种简单的计算机程序,就像 “if-then” 或 “if-else if” 语句一样工作。关于其“智能”的方面来自这样一个事实,即该程序的预定义输入来自区块链分类账本,如上所述,它是一个记录信息的安全可靠的来源。如有必要,程序可以调用外部服务或来源以获取信息,以验证操作条款,并且仅在满足所有预定义条件后才执行。
必须记住与其名称所暗示的不同智能合约通常不是自治实体严格来说也不是合同。1996 年Nick Szabo 很早就提到了智能合约,他将其与接受付款并交付用户选择的产品的自动售货机进行了比较。可以在[这里][4]查看全文。此外,人们正在制定允许智能合约进入主流合同使用的法律框架,因此目前该技术的使用仅限于法律监督不那么明确和严格的领域 [^4]。
### 智能合约的主要类型
假设读者对合同和计算机编程有基本的了解,并且基于我们对智能合约的定义,我们可以将智能合约和协议粗略地分类为以下主要类别。
#### 1、智能法律合约
这大概是最明显的一种。大多数(如果不是全部)合同都具有法律效力。在不涉及太多技术问题的情况下,智能法律合约是涉及到严格的法律追索权的合同,以防参与合同的当事人不履行其交易的目的。如前所述,不同国家和地区的现行法律框架对区块链上的智能和自动化合约缺乏足够的支持,其法律地位也不明确。但是,一旦制定了法律,就可以订立智能合约,以简化目前涉及严格监管的流程,如金融和房地产市场交易、政府补贴、国际贸易等。
#### 2、DAO
<ruby>去中心化自治组织<rt>Decentralized Autonomous Organization</rt></ruby>即DAO可以粗略地定义为区块链上存在的社区。该社区可以通过一组规则来定义这些规则通过智能合约来体现并放入代码中。然后每个参与者的每一个行动都将受到这些规则的约束其任务是在程序中断的情况下执行并获得追索权。许多智能合约构成了这些规则它们协同监管和监督参与者。
名为“创世纪 DAO” 的 DAO 是由以太坊参与者于 2016 年 5 月创建。该社区旨在成为众筹和风险投资平台。在极短的时间内,他们设法筹集了惊人的 1.5 亿美元。然而,由于黑客在系统中发现了漏洞,并设法从众筹投资者手中窃取价值约 5000 万美元的以太币。这次黑客破坏的后果导致以太坊区块链[分裂为两个][8],以太坊和以太坊经典。
#### 3、应用逻辑合约ALC
如果你已经听说过与区块链相结合的物联网,那么很可能它涉及到了<ruby>应用逻辑合约<rt>Application logic contract</rt></ruby>,即 ALC。此类智能合约包含特定于应用的代码这些代码可以与区块链上的其他智能合约和程序一起工作。它们有助于与设备进行通信并验证设备之间的通信在物联网领域。ALC 是每个多功能智能合约的关键部分,并且大多数都是在一个管理程序下工作。在这里引用的大多数例子中,它们到处都能找到[应用][9] [^6]。
*由于该领域还在开发中,因此目前所说的任何定义或标准最多只能说是变化而模糊的。*
### 智能合约是如何工作的?
为简化起见,让我们用个例子来说明。
约翰和彼得是两个争论足球比赛得分的人。他们对比赛结果持有相互矛盾的看法,他们都支持不同的球队(这是背景情况)。由于他们两个都需要去其他地方并且无法看完比赛,所以约翰认为如果 A 队在比赛中击败 B 队,他就*支付*给彼得 100 美元。彼得*考虑*之后*接受*了该赌注,同时明确表示他们必须接受这些条款。但是,他们没有兑现该赌注的相互信任,也没有时间和钱来指定第三方监督赌注。
假设约翰和彼得都使用像 [Etherparty][5] 这样的智能合约平台,它可以在合约谈判时自动结算赌注,他们都会将基于区块链的身份链接到该合约,并设置条款,明确表示一旦比赛结束,该程序将找出获胜方是谁,并自动将该金额从输家中归入获胜者银行账户。一旦比赛结束并且媒体报道同样的结果,该程序将在互联网上搜索规定的来源,确定哪支球队获胜,将其与合约条款联系起来,在这种情况下,如果 A 队赢了彼得将从约翰哪里得到钱,也就是说将约翰的 100 美元转移到彼得的账户。执行完毕后,除非另有说明,否则智能合约将终止并在未来所有的时间内处于非活动状态。
抛开例子的简单不说,这种情况涉及到一个经典的合同,而参与者选择使用智能合约实现了相同目的。所有的智能合约基本上都遵循类似的原则,对程序进行编码,以便在预定义的参数上执行,并且只抛出预期的输出。智能合同咨询的外部来源可以是有时被称为 IT 世界中的<ruby>神谕<rt>Oracle</rt></ruby>。神谕是当今全球许多智能合约系统的常见部分。
在这种情况下使用智能合约使参与者可以获得以下好处:
* 它比在一起并手动结算更快。
* 从其中删除了信任问题。
* 消除了受信任的第三方代表有关各方处理和解的必要性。
* 执行时无需任何费用。
* 在如何处理参数和敏感数据方面是安全的。
* 相关数据将永久保留在他们运行的区块链平台中,未来可以通过调用相同的函数并为其提供更多输入来设置投注。
* 随着时间的推移,假设约翰和彼得变得赌博成瘾,该程序可以帮助他们开发可靠的统计数据来衡量他们的连胜纪录。
  
现在我们知道**什么是智能合约**和**它们如何工作**,我们还没有解决**为什么我们需要它们**。
### 智能合约的需要
正如之前的例子我们重点提到过的,出于各种原因,我们需要智能合约。
#### 透明度
交易对手非常清楚所涉及的条款和条件。此外,由于程序或智能合约的执行涉及某些明确的输入,因此用户可以非常直接地核实会影响他们和合约受益人的因素。
#### 时间效率
如上所述,智能合约一旦被控制变量或用户调用所触发,就立即开始工作。由于数据是通过区块链和网络中的其它来源即时提供给系统,因此执行不需要任何时间来验证和处理信息并解决交易。例如,转移土地所有权契约,这是一个涉及手工核实大量文书工作并且需要数周时间的过程,可以在几分钟甚至几秒钟内通过智能合约程序来处理文件和相关各方。
#### 精度
由于平台基本上只是计算机代码和预定义的内容,因此不存在主观错误,所有结果都是精确的,完全没有人为错误。
#### 安全
区块链的一个固有特征是每个数据块都是安全加密的。这意味着为了实现冗余,即使数据存储在网络上的多个节点上,**也只有数据所有者才能访问以查看和使用数据**。类似地,利用区块链在过程中存储重要变量和结果,所有过程都将是完全安全和防篡改的。同样也通过按时间顺序为审计人员提供原始的、未经更改的和不可否认的数据版本,简化了审计和法规事务。
#### 信任
这个文章系列开篇说到区块链为互联网及其上运行的服务增加了急需的信任层。智能合约在任何情况下都不会在执行协议时表现出偏见或主观性,这意味着所涉及的各方对结果完全有约束力,并且可以不附带任何条件地信任该系统。这也意味着,在具有重要价值的传统合同中所需的“可信第三方”,在此处不需要。当事人之间的犯规和监督将成为过去的问题。
#### 成本效益
如示例中所强调的,使用智能合约需要最低的成本。企业通常有专门从事使其交易合法并遵守法规的行政人员。如果交易涉及多方,则重复工作是不可避免的。智能合约基本上使前者无关紧要,并且消除了重复,因为双方可以同时完成尽职调查。
### 智能合约的应用
基本上,如果两个或多个参与方使用共同的区块链平台,并就一组原则或业务逻辑达成一致,他们可以一起在区块链上创建一个智能合约,并且在没有人为干预的情况下执行。没有人可以篡改所设置的条件,如果原始代码允许,任何更改都会加上时间戳并带有编辑者的指纹,从而增加了问责制。想象一下,在更大的企业级规模上出现类似的情况,你就会明白智能合约的能力是什么,实际上从 2016 年开始的 **Capgemini 研究** 发现智能合约实际上可能是**“未来几年的”** [^8] 商业主流。商业的应用涉及保险、金融市场、物联网、贷款、身份管理系统、托管账户、雇佣合同以及专利和版税合同等用途。像以太坊这样的区块链平台,是一个设计时就考虑了智能合约的系统,它允许个人私人用户免费使用智能合约。
通过对处理智能合约的公司的探讨,本系列的下一篇文章中将更全面地概述智能合约在当前技术问题上的应用。
### 那么,它有什么缺点呢?
这并不是说对智能合约的使用没有任何顾虑。这种担忧实际上也减缓了这方面的发展。所有区块链的防篡改性质实质上使得,如果所涉及的各方需要在没有重大改革或法律追索的情况下,几乎不可能修改或添加现有条款的新条款。
其次,即使公有链上的活动是开放的,所有人都可以看到和观察。交易中涉及的各方的个人身份并不总是已知的。这种匿名性造成在任何一方违约的情况下法律有罪不罚的问题,特别是因为现行法律和立法者并不完全适应现代技术。
第三,区块链和智能合约在很多方面仍然存在安全缺陷,因为对其所以涉及的技术仍处于发展的初期阶段。 对代码和平台的这种缺乏经验最终导致了 2016 年的 DAO 事件。
所有这些都可能导致企业或公司在需要调整区块链以供其使用时需要大量的初始投资。然而,这些是最初的一次性投资,并且随之而来的是潜在的节约,这才是人们感兴趣的。
### 结论
目前的法律框架并没有真正支持一个全面的智能合约的社会,并且由于显然的原因,在不久的将来也不会支持。一个解决方案是选择**“混合”合约**,它将传统的法律文本和文件与在为此目的设计的区块链上运行的智能合约代码相结合。然而,即使是混合合约仍然很大程度上尚未得到探索,因为需要创新的立法机构才能实现这些合约。这里简要提到的应用以及更多内容将在[本系列的下一篇文章][6]中详细探讨。
[^1]: S. C. A. Chamber of Digital Commerce, “Smart contracts Is the law ready,” no. September, 2018.
[^2]: S. C. A. Chamber of Digital Commerce, “Smart contracts Is the law ready,” no. September, 2018.
[^4]: Cardozo Blockchain Project, “Smart Contracts & Legal Enforceability,” vol. 2, p. 28, 2018.
[^6]: F. Idelberger, G. Governatori, R. Riveret, and G. Sartor, “Evaluation of Logic-Based Smart Contracts for Blockchain Systems,” 2016, pp. 167183.
[^8]: B. Cant et al., “Smart Contracts in Financial Services : Getting from Hype to Reality,” Capgemini Consult., pp. 124, 2016.
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/blockchain-2-0-explaining-smart-contracts-and-its-types/
作者:[ostechnix][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/editor/
[b]: https://github.com/lujun9972
[1]: https://www.ostechnix.com/wp-content/uploads/2019/03/smart-contracts-720x340.png
[2]: https://linux.cn/article-10914-1.html
[3]: https://linux.cn/article-10650-1.html
[4]: http://www.fon.hum.uva.nl/rob/Courses/InformationInSpeech/CDROM/Literature/LOTwinterschool2006/szabo.best.vwh.net/smart_contracts_2.html
[5]: https://etherparty.com/
[6]: https://www.ostechnix.com/blockchain-2-0-ongoing-projects-the-state-of-smart-contracts-now/
[7]: http://www.legal-glossary.org/
[8]: https://futurism.com/the-dao-heist-undone-97-of-eth-holders-vote-for-the-hard-fork/
[9]: https://www.everestgrp.com/2016-10-types-smart-contracts-based-applications-market-insights-36573.html/

View File

@ -0,0 +1,127 @@
[#]: collector: (lujun9972)
[#]: translator: (tomjlw)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10939-1.html)
[#]: subject: (How to build a mobile particulate matter sensor with a Raspberry Pi)
[#]: via: (https://opensource.com/article/19/3/mobile-particulate-matter-sensor)
[#]: author: (Stephan Tetzel https://opensource.com/users/stephan)
如何用树莓派搭建一个颗粒物传感器
======
> 用树莓派、一个廉价的传感器和一个便宜的屏幕监测空气质量。
![](https://img.linux.net.cn/data/attachment/album/201906/05/005121bbveeavwgyc1i1gk.jpg)
大约一年前,我写了一篇关于如何使用树莓派和廉价传感器测量[空气质量][2]的文章。我们这几年已在学校里和私下使用了这个项目。然而它有一个缺点:由于它基于无线/有线网,因此它不是便携的。如果你的树莓派、你的智能手机和电脑不在同一个网络的话,你甚至都不能访问传感器测量的数据。
为了弥补这一缺陷,我们给树莓派添加了一块小屏幕,这样我们就可以直接从该设备上读取数据。以下是我们如何为我们的移动细颗粒物传感器搭建并配置好屏幕。
### 为树莓派搭建好屏幕
在[亚马逊][3]、阿里巴巴以及其它来源有许多可以买到的树莓派屏幕,从 ePaper 屏幕到可触控 LCD。我们选择了一个便宜的带触控功能且分辨率为 320*480 像素的[3.5英寸 LCD][3],可以直接插进树莓派的 GPIO 引脚。3.5 英寸屏幕和树莓派几乎一样大,这一点不错。
当你第一次启动屏幕打开树莓派的时候,会因为缺少驱动屏幕会保持白屏。你得首先为屏幕安装[合适的驱动][5]。通过 SSH 登入并执行以下命令:
```
$ rm -rf LCD-show
$ git clone <https://github.com/goodtft/LCD-show.git>
$ chmod -R 755 LCD-show
$ cd LCD-show/
```
为你的屏幕执行合适的命令以安装驱动。例如这是给我们 MPI3501 型屏幕的命令:
```
$ sudo ./LCD35-show
```
这行命令会安装合适的驱动并重启树莓派。
### 安装 PIXEL 桌面并设置自动启动
以下是我们想要我们项目能够做到的事情:如果树莓派启动,我们想要展现一个有我们空气质量测量数据的网站。
首先,安装树莓派的[PIXEL 桌面环境][6]
```
$ sudo apt install raspberrypi-ui-mods
```
然后安装 Chromium 浏览器以显示网站:
```
$ sudo apt install chromium-browser
```
需要自动登录以使测量数据在启动后直接显示;否则你将只会看到登录界面。然而树莓派用户并没有默认设置好自动登录。你可以用 `raspi-config` 工具设置自动登录:
```
$ sudo raspi-config
```
在菜单中选择“3 Boot Options → B1 Desktop / CLI → B4 Desktop Autologin”。
在启动后用 Chromium 打开我们的网站这块少了一步。创建文件夹 `/home/pi/.config/lxsession/LXDE-pi/`
```
$ mkdir -p /home/pi/config/lxsession/LXDE-pi/
```
然后在该文件夹里创建 `autostart` 文件:
```
$ nano /home/pi/.config/lxsession/LXDE-pi/autostart
```
并粘贴以下代码:
```
#@unclutter
@xset s off
@xset -dpms
@xset s noblank
# Open Chromium in Full Screen Mode
@chromium-browser --incognito --kiosk <http://localhost>
```
如果你想要隐藏鼠标指针,你得安装 `unclutter` 包并移除 `autostart` 文件开头的注释。
```
$ sudo apt install unclutter
```
![移动颗粒物传感器][7]
我对去年的代码做了些小修改。因此如果你之前搭建过空气质量项目,确保用[原文章][2]中的指导为 AQI 网站重新下载脚本和文件。
通过添加触摸屏,你现在拥有了一个便携的颗粒物传感器!我们在学校用它来检查教室里的空气质量或者进行比较测量。使用这种配置,你无需再依赖网络连接或 WLAN。你可以在任何地方使用这个小型测量站——你甚至可以使用移动电源以摆脱电网。
* * *
这篇文章原来在<ruby>[开源学校解决方案][8]<rt>Open Scool Solutions</rt></ruby>上发表,获得许可重新发布。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/3/mobile-particulate-matter-sensor
作者:[Stephan Tetzel][a]
选题:[lujun9972][b]
译者:[tomjlw](https://github.com/tomjlw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/stephan
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/talk_chat_team_mobile_desktop.png?itok=d7sRtKfQ (Team communication, chat)
[2]: https://linux.cn/article-9620-1.html
[3]: https://www.amazon.com/gp/search/ref=as_li_qf_sp_sr_tl?ie=UTF8&tag=openschoolsol-20&keywords=lcd%20raspberry&index=aps&camp=1789&creative=9325&linkCode=ur2&linkId=51d6d7676e10d6c7db203c4a8b3b529a
[4]: https://amzn.to/2CcvgpC
[5]: https://github.com/goodtft/LCD-show
[6]: https://linux.cn/article-8459-1.html
[7]: https://opensource.com/sites/default/files/uploads/mobile-aqi-sensor.jpg (Mobile particulate matter sensor)
[8]: https://openschoolsolutions.org/mobile-particulate-matter-sensor/

View File

@ -0,0 +1,64 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10984-1.html)
[#]: subject: (Running LEDs in reverse could cool computers)
[#]: via: (https://www.networkworld.com/article/3386876/running-leds-in-reverse-could-cool-computers.html#tk.rss_all)
[#]: author: (Patrick Nelson https://www.networkworld.com/author/Patrick-Nelson/)
反向运行 LED 能够冷却计算机
======
> 电子产品的小型化正在触及其极限,部分原因在于热量管理。许多人现在都在积极地尝试解决这个问题。其中一种正在探索的途径是反向运行的 LED。
![monsitj / Getty Images][1]
寻找更有效的冷却计算机的方法,几乎与渴望发现更好的电池化学成分一样,在科学家的研究日程中也处于重要位置。
更多的冷却手段对于降低成本至关重要。冷却技术也使得在较小的空间中可以进行更强大的处理,其有限的处理能力应该是进行计算而不是浪费热量。冷却技术可以阻止热量引起的故障,从而延长部件的使用寿命,并且可以促进环保的数据中心 —— 更少的热量意味着对环境的影响更小。
如何从微处理器中消除热量是科学家们一直在探索的一个方向他们认为他们已经提出了一个简单而不寻常、且反直觉的解决方案。他们说可以运行一个发光二极管LED的变体其电极反转可以迫使该元件表现得像处于异常低温下工作一样。如果将其置于较热的电子设备旁边然后引入纳米级间隙可以使 LED 吸收热量。
“一旦 LED 反向偏置,它就会像一个非常低温的物体一样,吸收光子,”密歇根大学机械工程教授埃德加·梅霍夫在宣布了这一突破的[新闻稿][4]中说。 “与此同时,该间隙可防止热量返回,从而产生冷却效果。”
研究人员表示LED 和相邻的电子设备(在这种情况下是热量计,通常用于测量热能)必须非常接近。他们说他们已经能够证明达到了每平方米 6 瓦的冷却功率。他们解释说,这是差不多是地球表面所接受到的阳光的能量。
物联网IoT设备和智能手机可能是最终将受益于这种 LED 改造的电子产品。这两种设备都需要在更小的空间中容纳更多的计算功率。
“从微处理器中可以移除的热量开始限制在给定空间内容纳的功率,”密歇根大学的公告说。
### 材料科学和冷却计算机
[我之前写过关于新形式的计算机冷却的文章][5]。源自材料科学的外来材料是正在探索的想法之一。美国能源部劳伦斯伯克利国家实验室表示钠铋Na3Bi可用于晶体管设计。这种新物质带电荷重要的是具有可调节性但是它不需要像超导体那样进行冷却。
事实上,这是超导体的一个问题。不幸的是,它们比大多数电子设备需要更多的冷却 —— 通过极端冷却消除电阻。
另外,[康斯坦茨大学的德国研究人员][6]表示他们很快将拥有超导体驱动的计算机,没有废热。他们计划使用电子自旋 —— 一种新的电子物理维度,可以提高效率。该大学去年在一份新闻稿中表示,这种方法“显著降低了计算中心的能耗”。
另一种减少热量的方法可能是用嵌入在微处理器上的[螺旋和回路来取代传统的散热器][7]。宾汉姆顿大学的科学家们表示,印在芯片上的微小通道可以为冷却剂提供单独的通道。
康斯坦茨大学说:“半导体技术的小型化正在接近其物理极限。”热管理现在被科学家提上了议事日程。这是“小型化的一大挑战”。
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3386876/running-leds-in-reverse-could-cool-computers.html#tk.rss_all
作者:[Patrick Nelson][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.networkworld.com/author/Patrick-Nelson/
[b]: https://github.com/lujun9972
[1]: https://images.idgesg.net/images/article/2019/02/big_data_center_server_racks_storage_binary_analytics_by_monsitj_gettyimages-944444446_3x2-100787357-large.jpg
[2]: https://www.networkworld.com/article/3242807/data-center/top-10-data-center-predictions-idc.html#nww-fsb
[3]: https://www.networkworld.com/newsletters/signup.html#nww-fsb
[4]: https://news.umich.edu/running-an-led-in-reverse-could-cool-future-computers/
[5]: https://www.networkworld.com/article/3326831/computers-could-soon-run-cold-no-heat-generated.html
[6]: https://www.uni-konstanz.de/en/university/news-and-media/current-announcements/news/news-in-detail/Supercomputer-ohne-Abwaerme/
[7]: https://www.networkworld.com/article/3322956/chip-cooling-breakthrough-will-reduce-data-center-power-costs.html
[8]: https://www.facebook.com/NetworkWorld/
[9]: https://www.linkedin.com/company/network-world

View File

@ -0,0 +1,100 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11013-1.html)
[#]: subject: (Blockchain 2.0 Ongoing Projects (The State Of Smart Contracts Now) [Part 6])
[#]: via: (https://www.ostechnix.com/blockchain-2-0-ongoing-projects-the-state-of-smart-contracts-now/)
[#]: author: (editor https://www.ostechnix.com/author/editor/)
区块链 2.0:智能合约如今的发展(六)
======
![The State Of Smart Contracts Now][1]
继续我们的[前面的关于智能合约的文章][2],这篇文章旨在讨论智能合约的发展形势,重点介绍目前正在该领域进行开发的一些项目和公司。如本系列前一篇文章中讨论的,智能合约是在区块链网络上存在并执行的程序。我们探讨了智能合约的工作原理以及它们优于传统数字平台的原因。这里描述的公司分布于各种各样的行业中,但是大多涉及到身份管理系统、金融服务、众筹系统等,因为这些是被认为最适合切换到基于区块链的数据库系统的领域。
### 开放平台
诸如 [Counterparty][8] 和 Solidity以太坊等平台是完全公用的构建模块开发者可以以之创建自己的智能合约。大量的开发人员参与此类项目使这些项目成为开发智能合约、设计自己的加密货币令牌系统以及创建区块链运行协议的事实标准。许多值得称赞的项目都来源于它们。摩根大通派生自以太坊的 [Quorum][9],就是一个例子。而瑞波是另一个例子。
### 管理金融交易
通过互联网转账加密货币被吹捧为在未来几年会成为常态。与此相关的不足之处是:
* 身份和钱包地址是匿名的。如果接收方不履行交易,则付款人没有任何第一追索权。
* 错误交易(如果无法追踪任何交易)。
* 密码生成的哈希密钥很难用于人类,人为错误是主要关注点。
在这种情况下,可以让其他人暂时接受该交易并在接受尽职调查后与接收方结算。
[EscrowMyEther][10] 和 [PAYFAIR][11] 是两个这样的托管平台。基本上,托管公司采用商定的金额并向接收方发送令牌。一旦接收方通过相同的托管平台提供付款人想要的内容,两者都会确认并最终付款。 这些得到了自由职业者和业余爱好者收藏家广泛在线使用。
### 金融服务
小额融资和小额保险项目的发展将改善世界上大多数贫穷或没有银行账户的人的银行金融服务。据估计,社会中较贫穷的“无银行账户”人群可以为银行和机构的增加 3800 亿美元收入 [^5]。这一金额要远远超过银行切换到区块链分布式账本技术DLT预期可以节省的运营费用。
位于美国中西部的 BankQu Inc. 的口号是“通过身份而尊严”。他们的平台允许个人建立他们自己的数字身份记录其中所有交易将在区块链上实时审查和处理。在底层代码上记录并为其用户构建唯一的在线标识从而实现超快速的交易和结算。BankQu 案例研究探讨了他们如何以这种方式帮助个人和公司,可以在[这里][3]看到。
[Stratumn][12] 正在帮助保险公司通过自动化早期由人类微观管理的任务来提供更好的保险服务。通过自动化、端到端可追溯性和高效的数据隐私方法,他们彻底改变了保险索赔的结算方式。改善客户体验以及显著降低成本为客户和相关的公司带来双赢局面。
法国保险公司 [AXA][14] 目前正在试行类似的努力。其产品 [fizzy][13] 允许用户以少量费用订阅其服务并输入他们的航班详细信息。如果航班延误或遇到其他问题,该程序会自动搜索在线数据库,检查保险条款并将保险金额记入用户的帐户。这样就用户或客户无需在手动检查条款后提出索赔,并且就长期而言,一旦这样的系统成为主流,就增加了航空公司的责任心。
### 跟踪所有权
理论上可以利用 DLT 中的带时间戳的数据块来跟踪媒体的创建到最终用户消费。Peertracks 公司和 Mycelia 公司目前正在帮助音乐家发布内容,而不必担心其内容被盗或被滥用。他们帮助艺术家直接向粉丝和客户销售,同时获得工作报酬,而无需通过权利和唱片公司 [^9]。
### 身份管理平台
基于区块链的身份管理平台可以将你的身份存储在分布式分类帐本中。设置帐户后,会对其进行安全加密,然后将其发送给所有参与节点。但是,作为数据块的所有者,只有该用户才能访问该数据。一旦你在网络上建立身份并开始交易,网络中的自动程序将验证与你的帐户关联的先前所有的交易,在检查要求后将其发送给监管备案,并在程序认为交易合法时自动执行结算。这里的好处是,由于区块链上的数据是防篡改的,而智能合约以零偏差(或主观性)检查输入,如前所述,交易不需要任何人的监督或批准,并且需要小心是即刻生效的。
像 [ShoCard][15] 、[Credits][16] 和 [OneName][17] 这样的初创公司目前正在推出类似的服务,目前正在与政府和社会机构进行谈判,以便将它们整合到主流用途中。
开发商的其他独立项目如 Chris Ellis 和 David Duccini 分别开发或提出了替代的身份管理系统,分别是 “[世界公民][4]”和 [IDCoin][5]。Ellis 先生甚至通过在区块链网络上创建护照来证明他的工作能力。
### 资源共享
[Share & Charge][18] ([Slock.It][19]) 是一家欧洲的区块链初创公司。他们的移动应用程序允许房主和其他个人投入资金建立充电站与其他正在寻找快速充电的人分享他们的资源。这不仅使业主能够收回他们的一些投资,而且还允许 EV 司机在其近地域获得更多的充电点,从而允许供应商以方便的方式满足需求。一旦“客户”完成对其车辆的充电,相关的硬件就会创建一个由数据组成的安全时间戳块,并且在该平台上工作的智能合约会自动将相应的金额记入所有者账户。记录所有此类交易的跟踪并保持适当的安全验证。有兴趣的读者可以看一下[这里][6],了解他们产品背后的技术角度。该公司的平台将逐步使用户能够与有需要的个人分享其他产品和服务,并从中获得被动收入。
我们在这里看到的公司,以及一个很短的正在进行中的项目的清单,这些项目利用智能合约和区块链数据库系统。诸如此类的平台有助于构建一个安全的“盒子”,其中包含仅由用户自己、其上的代码或智能合约访问的信息。基于触发器对信息进行实时审查、检查,并且算法由系统执行。这样的平台人为监督最小化,这是在安全数字自动化方面朝着正确方向迈出的急需的一步,这在以前从未被考虑过如此规模。
下一篇文章将阐述不同类型的区块链。单击以下链接以了解有关此主题的更多信息。
* [区块链 2.0:公有链与私有链的比较][7]
[^5]: B. Pani, “Blockchain Powered Financial Inclusion,” 2016.
[^9]: M. Gates, “Blockchain. Ultimate guide to understanding blockchain bitcoin cryptocurrencies smart-contracts and the future of money.pdf.” 2017.
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/blockchain-2-0-ongoing-projects-the-state-of-smart-contracts-now/
作者:[ostechnix][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/editor/
[b]: https://github.com/lujun9972
[1]: https://www.ostechnix.com/wp-content/uploads/2019/04/State-Of-Smart-Contracts-720x340.png
[2]: https://linux.cn/article-10956-1.html
[3]: https://banqu.co/case-study/
[4]: https://github.com/MrChrisJ/World-Citizenship
[5]: https://github.com/IDCoin/IDCoin
[6]: https://blog.slock.it/share-charge-smart-contracts-the-technical-angle-58b93ce80f15
[7]: https://www.ostechnix.com/blockchain-2-0-public-vs-private-blockchain-comparison/
[8]: https://counterparty.io/platform/
[9]: https://www.jpmorgan.com/global/Quorum
[10]: http://escrowmyether.com/
[11]: https://payfair.io/
[12]: https://stratumn.com/business-case/insurance-claim-automation-across-europe/
[13]: https://fizzy.axa/en-gb/
[14]: https://group.axa.com/en/newsroom/news/axa-goes-blockchain-with-fizzy
[15]: https://techcrunch.com/2015/05/05/shocard-is-a-digital-identity-card-on-the-blockchain/
[16]: https://techcrunch.com/2014/10/31/your-next-passport-could-be-on-the-blockchain/
[17]: https://wiki.namecoin.org/index.php?title=OneName
[18]: https://blog.slock.it/share-charge-launches-its-app-on-boards-over-1-000-charging-stations-on-the-blockchain-ba8275390309
[19]: https://slock.it/

View File

@ -0,0 +1,56 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10952-1.html)
[#]: subject: (5 Linux rookie mistakes)
[#]: via: (https://opensource.com/article/19/4/linux-rookie-mistakes)
[#]: author: (Jen Wike Huger https://opensource.com/users/jen-wike/users/bcotton/users/petercheer/users/greg-p/users/greg-p)
5 个 Linux 新手会犯的失误
======
> Linux 爱好者们分享了他们犯下的一些最大错误。
![](https://img.linux.net.cn/data/attachment/album/201906/09/103635akfkghwh5mp58g68.jpg)
终身学习是明智的 —— 它可以让你的思维敏捷,让你在就业市场上更具竞争力。但是有些技能比其他技能更难学,尤其是那些小菜鸟错误,当你尝试修复它们时可能会花费你很多时间,给你带来很大困扰。
以学习 [Linux][2] 为例。如果你习惯于在 Windows 或 MacOS 图形界面中工作,那么转移到 Linux要将不熟悉的命令输入到终端中可能会有很大的学习曲线。但是其回报是值得的因为已经有数以百万计的人们已经证明了这一点。
也就是说,这趟学习之旅并不是一帆风顺的。我们让一些 Linux 爱好者回想了一下他们刚开始使用 Linux 的时候,并告诉我们他们犯下的最大错误。
“不要进入[任何类型的命令行界面CLI工作]时就期望命令会以合理或一致的方式工作,因为这可能会导致你感到挫折。这不是因为设计选择不当 —— 虽然当你在键盘上敲击时就像在敲在你的脑袋上一样 —— 而是反映了这些系统是历经了几代的软件和操作系统的发展而陆续添加完成的事实。顺其自然,写下或记住你需要的命令,并且(尽量不要)在[事情不是你所期望的][3]时感到沮丧。” —— [Gina Likins] [4]
“尽可能简单地复制和粘贴命令以使事情顺利进行,首先阅读命令,至少对将要执行的操作有一个大致的了解,特别是如果有管道命令时,如果有多个管道更要特别注意。有很多破坏性的命令看起来无害 —— 直到你意识到它们能做什么(例如 `rm`、`dd`),而你不会想要意外破坏什么东西(别问我怎么知道)。” —— [Katie McLaughlin] [5]
“在我的 Linux 之旅的早期,我并不知道我所处在文件系统中的位置的重要性。我正在删除一些我认为是我的主目录的文件,我输入了 `sudo rm -rf *`,然后就删除了我系统上的所有启动文件。现在,我经常使用 `pwd` 来确保我在发出这样的命令之前确认我在哪里。幸运的是,我能够使用 USB 驱动器启动被搞坏的笔记本电脑并恢复我的文件。” —— [Don Watkins] [6]
“不要因为你认为‘权限很难理解’而你希望应用程序可以访问某些内容时就将整个文件系统的权限重置为 [777][7]。”—— [Matthew Helmke] [8]
“我从我的系统中删除一个软件包,而我没有检查它依赖的其他软件包。我只是让它删除它想删除要的东西,最终导致我的一些重要程序崩溃并变得不可用。” —— [Kedar Vijay Kulkarni] [9]
你在学习使用 Linux 时犯过什么错误?请在评论中分享。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/4/linux-rookie-mistakes
作者:[Jen Wike Huger][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jen-wike/users/bcotton/users/petercheer/users/greg-p/users/greg-p
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/mistake_bug_fix_find_error.png?itok=PZaz3dga (magnifying glass on computer screen, finding a bug in the code)
[2]: https://opensource.com/resources/linux
[3]: https://lintqueen.com/2017/07/02/learning-while-frustrated/
[4]: https://opensource.com/users/lintqueen
[5]: https://opensource.com/users/glasnt
[6]: https://opensource.com/users/don-watkins
[7]: https://www.maketecheasier.com/file-permissions-what-does-chmod-777-means/
[8]: https://twitter.com/matthewhelmke
[9]: https://opensource.com/users/kkulkarn

View File

@ -0,0 +1,108 @@
[#]: collector: "lujun9972"
[#]: translator: "fuzheng1998"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-10931-1.html"
[#]: subject: "5 open source mobile apps"
[#]: via: "https://opensource.com/article/19/4/mobile-apps"
[#]: author: "Chris Hermansen https://opensource.com/users/clhermansen/users/bcotton/users/clhermansen/users/bcotton/users/clhermansen"
5 个可以满足你的生产力、沟通和娱乐需求的开源手机应用
======
> 你可以依靠这些应用来满足你的生产力、沟通和娱乐需求。
![](https://img.linux.net.cn/data/attachment/album/201906/03/001949brnq19j5qeqn3onv.jpg)
像世界上大多数人一样,我的手似乎就没有离开过手机。多亏了我从 Google Play 和 F-Droid 安装的开源移动应用程序,让我的 Android 设备好像提供了无限的沟通、生产力和娱乐服务一样。
在我的手机上的许多开源应用程序中,当想听音乐、与朋友/家人和同事联系、或者在旅途中完成工作时,以下五个是我一直使用的。
### MPDroid
一个音乐播放器进程 (MPD)的 Android 控制器。
![MPDroid][2]
MPD 是将音乐从小型音乐服务器电脑传输到大型的黑色立体声音箱的好方法。它直连 ALSA因此可以通过 ALSA 硬件接口与数模转换器DAC对话它可以通过我的网络进行控制——但是用什么东西控制呢好吧事实证明 MPDroid 是一个很棒的 MPD 控制器。它可以管理我的音乐数据库,显示专辑封面,处理播放列表,并支持互联网广播。而且它是开源的,所以如果某些东西不好用的话……
MPDroid 可在 [Google Play][4] 和 [F-Droid][5] 上找到。
### RadioDroid
一台能单独使用及与 Chromecast 搭配使用的 Android 网络收音机。
![RadioDroid][6]
RadioDroid 是一个网络收音机,而 MPDroid 则管理我音乐的数据库从本质上讲RadioDroid 是 [Internet-Radio.com][7] 的一个前端。此外,通过将耳机插入 Android 设备,通过耳机插孔或 USB 将 Android 设备直接连接到立体声系统,或通过兼容设备使用其 Chromecast 功能,可以享受 RadioDroid。这是一个查看芬兰天气情况听取排名前 40 的西班牙语音乐,或收到到最新新闻消息的好方法。
RadioDroid 可在 [Google Play][8] 和 [F-Droid][9] 上找到。
### Signal
一个支持 Android、iOS还有桌面系统的安全即时消息客户端。
![Signal][10]
如果你喜欢 WhatsApp但是因为它与 Facebook [日益密切][11]的关系而感到困扰,那么 Signal 应该是你的下一个产品。Signal 的唯一问题是说服你的朋友们最好用 Signal 取代 WhatsApp。但除此之外它有一个与 WhatsApp 类似的界面;很棒的语音和视频通话;很好的加密;恰到好处的匿名;并且它受到了一个不打算通过使用软件来获利的基金会的支持。为什么不喜欢它呢?
Signal 可用于 [Android][12]、[iOS][13] 和 [桌面][14]。
### ConnectBot
Android SSH 客户端。
![ConnectBot][15]
有时我离电脑很远,但我需要登录服务器才能办事。[ConnectBot][16] 是将 SSH 会话搬到手机上的绝佳解决方案。
ConnectBot 可在 [Google Play][17] 上找到。
### Termux
有多种熟悉的功能的安卓终端模拟器。
![Termux][18]
你是否需要在手机上运行 `awk` 脚本?[Termux][19] 是个解决方案。如果你需要做终端类的工作,而且你不想一直保持与远程计算机的 SSH 连接,请使用 ConnectBot 将文件放到手机上,然后退出会话,在 Termux 中执行你的操作,用 ConnectBot 发回结果。
Termux 可在 [Google Play][20] 和 [F-Droid][21] 上找到。
* * *
你最喜欢用于工作或娱乐的开源移动应用是什么呢?请在评论中分享它们。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/4/mobile-apps
作者:[Chris Hermansen][a]
选题:[lujun9972][b]
译者:[fuzheng1998](https://github.com/fuzheng1998)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clhermansen/users/bcotton/users/clhermansen/users/bcotton/users/clhermansen
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003588_01_rd3os.combacktoschoolserieshe_rh_041x_0.png?itok=tfg6_I78
[2]: https://opensource.com/sites/default/files/uploads/mpdroid.jpg "MPDroid"
[3]: https://opensource.com/article/17/4/fun-new-gadget
[4]: https://play.google.com/store/apps/details?id=com.namelessdev.mpdroid&hl=en_US
[5]: https://f-droid.org/en/packages/com.namelessdev.mpdroid/
[6]: https://opensource.com/sites/default/files/uploads/radiodroid.png "RadioDroid"
[7]: https://www.internet-radio.com/
[8]: https://play.google.com/store/apps/details?id=net.programmierecke.radiodroid2
[9]: https://f-droid.org/en/packages/net.programmierecke.radiodroid2/
[10]: https://opensource.com/sites/default/files/uploads/signal.png "Signal"
[11]: https://opensource.com/article/19/3/open-messenger-client
[12]: https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms
[13]: https://itunes.apple.com/us/app/signal-private-messenger/id874139669?mt=8
[14]: https://signal.org/download/
[15]: https://opensource.com/sites/default/files/uploads/connectbot.png "ConnectBot"
[16]: https://connectbot.org/
[17]: https://play.google.com/store/apps/details?id=org.connectbot
[18]: https://opensource.com/sites/default/files/uploads/termux.jpg "Termux"
[19]: https://termux.com/
[20]: https://play.google.com/store/apps/details?id=com.termux
[21]: https://f-droid.org/packages/com.termux/

View File

@ -0,0 +1,118 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11023-1.html)
[#]: subject: (VSCodium: 100% Open Source Version of Microsoft VS Code)
[#]: via: (https://itsfoss.com/vscodium/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
VSCodium100% 开源的 VS Code
======
> VSCodium 是微软流行的 Visual Studio Code 编辑器的一个分支。它与 VS Code 完全相同唯一不同的是VSCodium 不跟踪你的使用数据。
微软的 [Visual Studio Code][1] 是一个出色的编辑器,不仅对于 Web 开发人员,也适合其他程序员。由于它的功能,它被认为是最好的开源代码编辑器之一。
是的,它是微软众多开源产品之一。因为有 DEB、RPM 和 Snap 包形式的二进制文件,你可以[在 Linux 中轻松安装 Visual Studio Code][2]。
但它存在一个问题,对于普通用户而言可能不是问题,但对于纯粹开源主义者而言是重要的。
Microsoft 说提供的二进制文件是不开源的。
感到困惑么?让我解释下。
VS Code 的源码是在 MIT 许可下开源的。你可以在 [GitHub][3] 上访问它。但是,[Microsoft 创建的安装包含专有的跟踪程序][4]。
此跟踪基本上用来收集使用数据并将其发送给 Microsoft 以“帮助改进其产品和服务”。如今,远程报告在软件产品中很常见。即使 [Ubuntu 也这样做,但它透明度更高][5]。
你可以[在 VS Code 中禁用远程报告][6],但是你能完全信任微软吗?如果答案是否定的,那你有什么选择?
你可以从源代码构建它,从而保持全都是开源的。但是如今[从源代码安装][7]并不总是最好的选择,因为我们习惯于使用二进制文件。
另一种选择是使用 VSCodium
### VSCodium100 开源形式的 Visual Studio Code
![][8]
[VSCodium][9] 是微软 Visual Studio Code 的一个分支。该项目的唯一目的是为你提供现成的二进制文件,而没有 Microsoft 的远程收集代码。
这解决了你想在去掉 Microsoft 的专有代码的情况下使用 VS Code ,而你又不习惯从源代码构建它的问题。
由于 [VSCodium 是 VS Code 的一个分支][11],它的外观和功能与 VS Code 完全相同。
这是 Ubuntu 中第一次运行 VS Code 和 VSCodium 的截图。你能分辨出来吗?
![Can you guess which is VSCode and VSCodium?][12]
如果你无法区分这两者,请看下面。
![Thats Microsoft][13]
除此之外,还有两个应用的 logo没有其他明显的区别。
![VSCodium and VS Code in GNOME Menu][14]
#### 在 Linux 上安装 VSCodium
虽然 VSCodium 存在于某些发行版(如 Parrot OS但你必须在其他 Linux 发行版中添加额外的仓库。
在基于 Ubuntu 和 Debian 的发行版上,你可以使用以下命令安装 VSCodium。
首先,添加仓库的 GPG 密钥:
```
wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg | sudo apt-key add -
```
然后添加仓库:
```
echo 'deb https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/repos/debs/ vscodium main' | sudo tee --append /etc/apt/sources.list.d/vscodium.list
```
现在更新你的系统并安装 VSCodium
```
sudo apt update && sudo apt install codium
```
你可以在它的页面上找到[其他发行版的安装说明][15]。你还应该阅读[有关从 VS Code 迁移到 VSCodium 的说明][16]。
### 你如何看待 VSCodium
就个人而言,我喜欢 VSCodium 的概念。说的老套一点,它的初心是好的。我认为,致力于开源的 Linux 发行版甚至可能开始将其包含在官方仓库中。
你怎么看?是否值得切换到 VSCodium 或者你选择关闭远程报告并继续使用 VS Code
请不要出现“我使用 Vim” 的评论 :D
--------------------------------------------------------------------------------
via: https://itsfoss.com/vscodium/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://code.visualstudio.com/
[2]: https://itsfoss.com/install-visual-studio-code-ubuntu/
[3]: https://github.com/Microsoft/vscode
[4]: https://github.com/Microsoft/vscode/issues/60#issuecomment-161792005
[5]: https://itsfoss.com/ubuntu-data-collection-stats/
[6]: https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting
[7]: https://itsfoss.com/install-software-from-source-code/
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/vscodium.png?resize=800%2C450&ssl=1
[9]: https://vscodium.com/
[11]: https://github.com/VSCodium/vscodium
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/vscodium-vs-vscode.png?resize=800%2C450&ssl=1
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/microsoft-vscode-tracking.png?resize=800%2C259&ssl=1
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/vscodium-and-vscode.jpg?resize=800%2C220&ssl=1
[15]: https://vscodium.com/#install
[16]: https://vscodium.com/#migrate

View File

@ -0,0 +1,98 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10957-1.html)
[#]: subject: (How we built a Linux desktop app with Electron)
[#]: via: (https://opensource.com/article/19/4/linux-desktop-electron)
[#]: author: (Nils Ganther https://opensource.com/users/nils-ganther)
我们是如何使用 Electron 构建 Linux 桌面应用程序的
======
> 这是借助 Electron 框架,构建一个在 Linux 桌面上原生运行的开源电子邮件服务的故事。
![document sending](https://img.linux.net.cn/data/attachment/album/201906/10/123114abz0lvbllktkulx7.jpg)
[Tutanota][2] 是一种安全的开源电子邮件服务,它可通过浏览器使用,也有 iOS 和 Android 应用。其客户端代码在 GPLv3 下发布Android 应用程序可在 [F-Droid][3] 上找到,以便每个人都可以使用完全与 Google 无关的版本。
由于 Tutanota 关注开源和 Linux 客户端开发,因此我们希望为 Linux 和其他平台发布一个桌面应用程序。作为一个小团队,我们很快就排除了为 Linux、Windows 和 MacOS 构建原生应用程序的可能性,并决定使用 [Electron][4] 来构建我们的应用程序。
对于任何想要快速交付视觉一致的跨平台应用程序的人来说Electron 是最适合的选择,尤其是如果你已经有一个 Web 应用程序,想要从浏览器 API 的束缚中摆脱出来时。Tutanota 就是这样一个案例。
Tutanota 基于 [SystemJS][5] 和 [Mithril][6],旨在为每个人提供简单、安全的电子邮件通信。 因此,它必须提供很多用户期望从电子邮件客户端获得的标准功能。
由于采用了现代 API 和标准,其中一些功能(如基本的推送通知、搜索文本和联系人以及支持双因素身份验证)很容易在浏览器中提供。其它功能(例如自动备份或无需我们的服务器中转的 IMAP 支持)需要对系统资源的限制性访问,而这正是 Electron 框架提供的功能。
虽然有人批评 Electron “只是一个基本的包装”,但它有明显的好处:
* Electron 可以使你能够快速地为 Linux、Windows 和 MacOS 桌面构造 Web 应用。事实上,大多数 Linux 桌面应用都是使用 Electron 构建的。
* Electron 可以轻松地将桌面客户端与 Web 应用程序达到同样的功能水准。
* 发布桌面应用程序后,你可以自由使用开发功能添加桌面端特定的功能,从而增强可用性和安全性。
* 最后但同样重要的是,这是让应用程序具备原生的感觉、融入用户系统,而同时保持其识别度的好方法。
  
### 满足用户的需求
Tutanota 不依靠于大笔的投资资金,而是依靠社区驱动的项目。基于越来越多的用户升级到我们的免费服务的付费计划,我们有机地发展我们的团队。倾听用户的需求不仅对我们很重要,而且对我们的成功至关重要。
提供桌面客户端是 Tutanota 用户[最想要的功能][7],我们感到自豪的是,我们现在可以为所有用户提供免费的桌面客户端测试版。(我们还实现了另一个高度要求的功能 —— [搜索加密数据][8] —— 但这是另一个主题了。)
我们喜欢为用户提供签名版本的 Tutanota 并支持浏览器中无法实现的功能,例如通过后台进程推送通知。 现在,我们计划添加更多特定于桌面的功能,例如 IMAP 支持(而不依赖于我们的服务器充当代理),自动备份和离线可用性。
我们选择 Electron 是因为它的 Chromium 和 Node.js 的组合最适合我们的小型开发团队,因为它只需要对我们的 Web 应用程序进行最小的更改。在我们开始使用时,可以将浏览器 API 用于所有功能特别有用,随着我们的进展,慢慢地用更多原生版本替换这些组件。这种方法对附件下载和通知特别方便。
### 调整安全性
我们知道有些人关注 Electron 的安全问题,但我们发现 Electron 在 Web 应用程序中微调访问的选项非常令人满意。你可以使用 Electron 的[安全文档][9]和 Luca Carettoni 的[Electron 安全清单][10]等资源,来帮助防止 Web 应用程序中不受信任的内容发生灾难性事故。
### 实现特定功能
Tutanota Web 客户端从一开始就构建了一个用于进程间通信的可靠协议。我们利用 Web 线程在加密和请求数据时保持用户界面UI响应性。当我们开始实现我们的移动应用时这就派上用场这些应用程序使用相同的协议在原生部分和 Web 视图之间进行通信。
这就是为什么当我们开始构建桌面客户端时很多用于本机推送通知、打开邮箱和使用文件系统的部分等已经存在因此只需要实现原生端Node.js
另一个便利是我们的构建过程使用 [Babel 转译器][11],它允许我们以现代 ES6 JavaScript 编写整个代码库,并在不同环境之间混合和匹配功能模块。这使我们能够快速调整基于 Electron 的桌面应用程序的代码。但是,我们也遇到了一些挑战。
### 克服挑战
虽然 Electron 允许我们很容易地与不同平台的桌面环境集成,但你不能低估投入的时间!最后,正是这些小事情占用了比我们预期更多的时间,但对完成桌面客户端项目也至关重要。
特定于平台的代码导致了大部分阻碍:
* 例如,窗口管理和托盘仍然在三个平台上以略有不同的方式处理。
* 注册 Tutanota 作为默认邮件程序并设置自动启动需要深入 Windows 注册表,同时确保以 [UAC] [12] 兼容的方式提示用户进行管理员访问。
* 我们需要使用 Electron 的 API 作为快捷方式和菜单,以提供复制、粘贴、撤消和重做等标准功能。
由于用户对不同平台上的应用程序的某些(有时不直接兼容)行为的期望,此过程有点复杂。使三个版本感觉像原生的需要一些迭代,甚至需要对 Web 应用程序进行一些适度的补充,以提供类似于浏览器中的文本搜索的功能。
### 总结
我们在 Electron 方面的经验基本上是积极的,我们在不到四个月的时间内完成了该项目。尽管有一些相当耗时的功能,但我们感到惊讶的是,我们可以轻松地为 Linux 提供一个测试版的 [Tutanota 桌面客户端][13]。如果你有兴趣,可以深入了解 [GitHub][14] 上的源代码。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/4/linux-desktop-electron
作者:[Nils Ganther][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/nils-ganther
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/email_paper_envelope_document.png?itok=uPj_kouJ (document sending)
[2]: https://tutanota.com/
[3]: https://f-droid.org/en/packages/de.tutao.tutanota/
[4]: https://electronjs.org/
[5]: https://github.com/systemjs/systemjs
[6]: https://mithril.js.org/
[7]: https://tutanota.uservoice.com/forums/237921-general/filters/top?status_id=1177482
[8]: https://tutanota.com/blog/posts/first-search-encrypted-data/
[9]: https://electronjs.org/docs/tutorial/security
[10]: https://www.blackhat.com/docs/us-17/thursday/us-17-Carettoni-Electronegativity-A-Study-Of-Electron-Security-wp.pdf
[11]: https://babeljs.io/
[12]: https://en.wikipedia.org/wiki/User_Account_Control
[13]: https://tutanota.com/blog/posts/desktop-clients/
[14]: https://www.github.com/tutao/tutanota

View File

@ -0,0 +1,135 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10921-1.html)
[#]: subject: (Be your own certificate authority)
[#]: via: (https://opensource.com/article/19/4/certificate-authority)
[#]: author: (Moshe Zadka https://opensource.com/users/moshez/users/elenajon123)
自己成为一个证书颁发机构CA
======
> 为你的微服务架构或者集成测试创建一个简单的内部 CA。
![](https://img.linux.net.cn/data/attachment/album/201905/31/091023sg9s0ss11rsoseqg.jpg)
传输层安全([TLS][2])模型(有时也称它的旧名称 SSL基于<ruby>[证书颁发机构][3]<rt>certificate authoritie</rt></ruby>CA的概念。这些机构受到浏览器和操作系统的信任从而*签名*服务器的的证书以用于验证其所有权。
但是,对于内部网络,微服务架构或集成测试,有时候*本地 CA*更有用:一个只在内部受信任的 CA然后签名本地服务器的证书。
这对集成测试特别有意义。获取证书可能会带来负担,因为这会占用服务器几分钟。但是在代码中使用“忽略证书”可能会被引入到生产环境,从而导致安全灾难。
CA 证书与常规服务器证书没有太大区别。重要的是它被本地代码信任。例如,在 Python `requests` 库中,可以通过将 `REQUESTS_CA_BUNDLE` 变量设置为包含此证书的目录来完成。
在为集成测试创建证书的例子中,不需要*长期的*证书:如果你的集成测试需要超过一天,那么你应该已经测试失败了。
因此,计算**昨天**和**明天**作为有效期间隔:
```
>>> import datetime
>>> one_day = datetime.timedelta(days=1)
>>> today = datetime.date.today()
>>> yesterday = today - one_day
>>> tomorrow = today - one_day
```
现在你已准备好创建一个简单的 CA 证书。你需要生成私钥,创建公钥,设置 CA 的“参数”然后自签名证书CA 证书*总是*自签名的。最后,导出证书文件以及私钥文件。
```
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes, serialization
from cryptography import x509
from cryptography.x509.oid import NameOID
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
builder = x509.CertificateBuilder()
builder = builder.subject_name(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, 'Simple Test CA'),
]))
builder = builder.issuer_name(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, 'Simple Test CA'),
]))
builder = builder.not_valid_before(yesterday)
builder = builder.not_valid_after(tomorrow)
builder = builder.serial_number(x509.random_serial_number())
builder = builder.public_key(public_key)
builder = builder.add_extension(
x509.BasicConstraints(ca=True, path_length=None),
critical=True)
certificate = builder.sign(
private_key=private_key, algorithm=hashes.SHA256(),
backend=default_backend()
)
private_bytes = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncrption())
public_bytes = certificate.public_bytes(
encoding=serialization.Encoding.PEM)
with open("ca.pem", "wb") as fout:
fout.write(private_bytes + public_bytes)
with open("ca.crt", "wb") as fout:
fout.write(public_bytes)
```
通常,真正的 CA 会需要[证书签名请求][4]CSR来签名证书。但是当你是自己的 CA 时,你可以制定自己的规则!可以径直签名你想要的内容。
继续集成测试的例子,你可以创建私钥并立即签名相应的公钥。注意 `COMMON_NAME` 需要是 `https` URL 中的“服务器名称”。如果你已配置名称查询,你需要服务器能响应对 `service.test.local` 的请求。
```
service_private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
service_public_key = service_private_key.public_key()
builder = x509.CertificateBuilder()
builder = builder.subject_name(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, 'service.test.local')
]))
builder = builder.not_valid_before(yesterday)
builder = builder.not_valid_after(tomorrow)
builder = builder.public_key(public_key)
certificate = builder.sign(
private_key=private_key, algorithm=hashes.SHA256(),
backend=default_backend()
)
private_bytes = service_private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncrption())
public_bytes = certificate.public_bytes(
encoding=serialization.Encoding.PEM)
with open("service.pem", "wb") as fout:
fout.write(private_bytes + public_bytes)
```
现在 `service.pem` 文件有一个私钥和一个“有效”的证书:它已由本地的 CA 签名。该文件的格式可以给 Nginx、HAProxy 或大多数其他 HTTPS 服务器使用。
通过将此逻辑用在测试脚本中,只要客户端配置信任该 CA那么就可以轻松创建看起来真实的 HTTPS 服务器。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/4/certificate-authority
作者:[Moshe Zadka][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/moshez/users/elenajon123
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_commun_4604_02_mech_connections_rhcz0.5x.png?itok=YPPU4dMj
[2]: https://en.wikipedia.org/wiki/Transport_Layer_Security
[3]: https://en.wikipedia.org/wiki/Certificate_authority
[4]: https://en.wikipedia.org/wiki/Certificate_signing_request

View File

@ -1,8 +1,8 @@
[#]: collector: "lujun9972"
[#]: translator: "FSSlc"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-10930-1.html"
[#]: subject: "Inter-process communication in Linux: Sockets and signals"
[#]: via: "https://opensource.com/article/19/4/interprocess-communication-linux-networking"
[#]: author: "Marty Kalin https://opensource.com/users/mkalindepauledu"
@ -10,21 +10,21 @@
Linux 下的进程间通信:套接字和信号
======
学习在 Linux 中进程是如何与其他进程进行同步的。
> 学习在 Linux 中进程是如何与其他进程进行同步的。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/mesh_networking_dots_connected.png?itok=ovINTRR3)
![](https://img.linux.net.cn/data/attachment/album/201906/02/234437y6gig4tg4yy94356.jpg)
本篇是 Linux 下[进程间通信][1]IPC系列的第三篇同时也是最后一篇文章。[第一篇文章][2]聚焦在通过共享存储(文件和共享内存段)来进行 IPC[第二篇文章][3]则通过管道(无名的或者名的)及消息队列来达到相同的目的。这篇文章将目光从高处(套接字)然后到低处(信号)来关注 IPC。代码示例将用力地充实下面的解释细节。
本篇是 Linux 下[进程间通信][1]IPC系列的第三篇同时也是最后一篇文章。[第一篇文章][2]聚焦在通过共享存储(文件和共享内存段)来进行 IPC[第二篇文章][3]则通过管道(无名的或者名的)及消息队列来达到相同的目的。这篇文章将目光从高处(套接字)然后到低处(信号)来关注 IPC。代码示例将用力地充实下面的解释细节。
### 套接字
正如管道有两种类型(有名和无名一样套接字也有两种类型。IPC 套接字(即 Unix domain socket)给予进程在相同设备(主机)上基于通道的通信能力;而网络套接字给予进程运行在不同主机的能力,因此也带来了网络通信的能力。网络套接字需要底层协议的支持,例如 TCP传输控制协议或 UDP用户数据报协议
正如管道有两种类型(命名和无名一样套接字也有两种类型。IPC 套接字(即 Unix 套接字)给予进程在相同设备(主机)上基于通道的通信能力;而网络套接字给予进程运行在不同主机的能力,因此也带来了网络通信的能力。网络套接字需要底层协议的支持,例如 TCP传输控制协议或 UDP用户数据报协议
与之相反IPC 套接字依赖于本地系统内核的支持来进行通信特别的IPC 通信使用一个本地的文件作为套接字地址。尽管这两种套接字的实现有所不同但在本质上IPC 套接字和网络套接字的 API 是一致的。接下来的例子将包含网络套接字的内容,但示例服务器和客户端程序可以在相同的机器上运行,因为服务器使用了 localhost127.0.0.1)这个网络地址,该地址表示的是本地机器上的本地机器地址。
与之相反IPC 套接字依赖于本地系统内核的支持来进行通信特别的IPC 通信使用一个本地的文件作为套接字地址。尽管这两种套接字的实现有所不同但在本质上IPC 套接字和网络套接字的 API 是一致的。接下来的例子将包含网络套接字的内容,但示例服务器和客户端程序可以在相同的机器上运行,因为服务器使用了 `localhost`127.0.0.1)这个网络地址,该地址表示的是本地机器上的本地机器地址。
套接字以流的形式(下面将会讨论到)被配置为双向的,并且其控制遵循 C/S客户端/服务器端)模式:客户端通过尝试连接一个服务器来初始化对话,而服务器端将尝试接受该连接。假如万事顺利,来自客户端的请求和来自服务器端的响应将通过管道进行传输,直到其中任意一方关闭该通道,从而断开这个连接。
一个`迭代服务器`(只适用于开发)将一直和连接它的客户端打交道:从最开始服务第一个客户端,然后到这个连接关闭,然后服务第二个客户端,循环往复。这种方式的一个缺点是处理一个特定的客户端可能会一直持续下去,使得其他的客户端一直在后面等待。生产级别的服务器将是并发的,通常使用了多进程或者多线程的混合。例如,我台式机上的 Nginx 网络服务器有一个 4 个 worker 的进程池,它们可以并发地处理客户端的请求。在下面的代码示例中,我们将使用迭代服务器,使得我们将要处理的问题达到一个很小的规模,只关注基本的 API而不去关心并发的问题。
一个迭代服务器(只适用于开发)将一直和连接它的客户端打交道:从最开始服务第一个客户端,然后到这个连接关闭,然后服务第二个客户端,循环往复。这种方式的一个缺点是处理一个特定的客户端可能会挂起,使得其他的客户端一直在后面等待。生产级别的服务器将是并发的,通常使用了多进程或者多线程的混合。例如,我台式机上的 Nginx 网络服务器有一个 4 个<ruby>工人<rt>worker</rt></ruby>的进程池,它们可以并发地处理客户端的请求。在下面的代码示例中,我们将使用迭代服务器,使得我们将要处理的问题保持在一个很小的规模,只关注基本的 API而不去关心并发的问题。
最后,随着各种 POSIX 改进的出现,套接字 API 随着时间的推移而发生了显著的变化。当前针对服务器端和客户端的示例代码特意写的比较简单,但是它着重强调了基于流的套接字中连接的双方。下面是关于流控制的一个总结,其中服务器端在一个终端中开启,而客户端在另一个不同的终端中开启:
@ -108,10 +108,10 @@ int main() {
上面的服务器端程序执行典型的 4 个步骤来准备回应客户端的请求,然后接受其他的独立请求。这里每一个步骤都以服务器端程序调用的系统函数来命名。
1. `socket(…)` : 为套接字连接获取一个文件描述符
2. `bind(…)` : 将套接字和服务器主机上的一个地址进行绑定
3. `listen(…)` : 监听客户端请求
4. `accept(…)` :接受一个特定的客户端请求
1. `socket(…)`为套接字连接获取一个文件描述符
2. `bind(…)`将套接字和服务器主机上的一个地址进行绑定
3. `listen(…)`监听客户端请求
4. `accept(…)`:接受一个特定的客户端请求
上面的 `socket` 调用的完整形式为:
@ -121,7 +121,7 @@ int sockfd = socket(AF_INET,      /* versus AF_LOCAL */
                    0);           /* system picks protocol (TCP) */
```
第一个参数特别指定了使用的是一个网络套接字,而不是 IPC 套接字。对于第二个参数有多种选项,但 `SOCK_STREAM``SOCK_DGRAM`(数据报)是最为常用的。基于流的套接字支持可信通道,在这种通道中如果发生了信息的丢失或者更改,都将会被报告。这种通道是双向的,并且从一端到另外一端的有效载荷在大小上可以是任意的。相反的,基于数据报的套接字大多是不可信的,没有方向性,并且需要固定大小的载荷。`socket` 的第三个参数特别指定了协议。对于这里展示的基于流的套接字只有一种协议选择TCP在这里表示的 `0`;。因为对 `socket` 的一次成功调用将返回相似的文件描述符,一个套接字将会被读写,对应的语法和读写一个本地文件是类似的。
第一个参数特别指定了使用的是一个网络套接字,而不是 IPC 套接字。对于第二个参数有多种选项,但 `SOCK_STREAM``SOCK_DGRAM`(数据报)是最为常用的。基于流的套接字支持可信通道,在这种通道中如果发生了信息的丢失或者更改,都将会被报告。这种通道是双向的,并且从一端到另外一端的有效载荷在大小上可以是任意的。相反的,基于数据报的套接字大多是不可信的,没有方向性,并且需要固定大小的载荷。`socket` 的第三个参数特别指定了协议。对于这里展示的基于流的套接字只有一种协议选择TCP在这里表示的 `0`。因为对 `socket` 的一次成功调用将返回相似的文件描述符,套接字可以被读写,对应的语法和读写一个本地文件是类似的。
`bind` 的调用是最为复杂的,因为它反映出了在套接字 API 方面上的各种改进。我们感兴趣的点是这个调用将一个套接字和服务器端所在机器中的一个内存地址进行绑定。但对 `listen` 的调用就非常直接了:
@ -131,9 +131,9 @@ if (listen(fd, MaxConnects) < 0)
第一个参数是套接字的文件描述符,第二个参数则指定了在服务器端处理一个拒绝连接错误之前,有多少个客户端连接被允许连接。(在头文件 `sock.h``MaxConnects` 的值被设置为 `8`。)
`accept` 调用默认将是一个塞等待:服务器端将不做任何事情直到一个客户端尝试连接它,然后进行处理。`accept` 函数返回的值如果是 `-1` 则暗示有错误发生。假如这个调用是成功的,则它将返回另一个文件描述符,这个文件描述符被用来指代另一个可读可写的套接字,它与 `accept` 调用中的第一个参数对应的接收套接字有所不同。服务器端使用这个可读可写的套接字来从客户端读取请求然后写回它的回应。接收套接字只被用于接受客户端的连接。
`accept` 调用默认将是一个塞等待:服务器端将不做任何事情直到一个客户端尝试连接它,然后进行处理。`accept` 函数返回的值如果是 `-1` 则暗示有错误发生。假如这个调用是成功的,则它将返回另一个文件描述符,这个文件描述符被用来指代另一个可读可写的套接字,它与 `accept` 调用中的第一个参数对应的接收套接字有所不同。服务器端使用这个可读可写的套接字来从客户端读取请求然后写回它的回应。接收套接字只被用于接受客户端的连接。
在设计上,一个服务器端可以一直运行下去。当然服务器端可以通过在命令行中使用 `Ctrl+C` 来终止它。
在设计上,服务器端可以一直运行下去。当然服务器端可以通过在命令行中使用 `Ctrl+C` 来终止它。
#### 示例 2. 使用套接字的客户端
@ -207,25 +207,25 @@ int main() {
if (connect(sockfd, (struct sockaddr*) &saddr, sizeof(saddr)) < 0)
```
`connect` 的调用可能因为多种原因而导致失败,例如客户端拥有错误的服务器端地址或者已经有太多的客户端连接上了服务器端。假如 `connect` 操作成功,客户端将在一个 `for` 循环中,写入它的响应然后读取返回的响应。在经过会话后,服务器端和客户端都将调用 `close` 去关闭可读可写套接字,尽管其中一个关闭操作已经足以关闭他们之间的连接,但此时客户端可能就此关闭,但正如前面提到的那样,服务器端将一直保持开放以处理其他事务。
`connect` 的调用可能因为多种原因而导致失败,例如客户端拥有错误的服务器端地址或者已经有太多的客户端连接上了服务器端。假如 `connect` 操作成功,客户端将在一个 `for` 循环中,写入它的请求然后读取返回的响应。在会话后,服务器端和客户端都将调用 `close` 去关闭这个可读可写套接字,尽管任何一边的关闭操作就足以关闭它们之间的连接。此后客户端可以退出了,但正如前面提到的那样,服务器端可以一直保持开放以处理其他事务。
从上面的套接示例中,我们看到了请求信息被回给客户端,这使得客户端和服务器端之间拥有进行丰富对话的可能性。也许这就是套接字的主要魅力。在现代系统中,客户端应用(例如一个数据库客户端)和服务器端通过套接字进行通信非常常见。正如先前提及的那样,本地 IPC 套接字和网络套接字只在某些实现细节上面有所不同一般来说IPC 套接字有着更低的消耗和更好的性能。它们的通信 API 基本是一样的。
从上面的套接示例中,我们看到了请求信息被回给客户端,这使得客户端和服务器端之间拥有进行丰富对话的可能性。也许这就是套接字的主要魅力。在现代系统中,客户端应用(例如一个数据库客户端)和服务器端通过套接字进行通信非常常见。正如先前提及的那样,本地 IPC 套接字和网络套接字只在某些实现细节上面有所不同一般来说IPC 套接字有着更低的消耗和更好的性能。它们的通信 API 基本是一样的。
### 信号
一个信号中断一个正在执行的程序,在这种意义下,就是用信号与这个程序进行通信。大多数的信号要么可以被忽略(阻塞)或者被处理(通过特别设计的代码)。`SIGSTOP` (暂停)和 `SIGKILL`(立即停止)是最应该提及的两种信号。符号常数拥有整数类型的值,例如 `SIGKILL` 对应的值为 `9`
信号中断一个正在执行的程序,在这种意义下,就是用信号与这个程序进行通信。大多数的信号要么可以被忽略(阻塞)或者被处理(通过特别设计的代码)。`SIGSTOP` (暂停)和 `SIGKILL`(立即停止)是最应该提及的两种信号。这种符号常量有整数类型的值,例如 `SIGKILL` 对应的值为 `9`
信号可以在与用户交互的情况下发生。例如,一个用户从命令行中敲了 `Ctrl+C`从命令行中终止一个程序;`Ctrl+C` 将产生一个 `SIGTERM` 信号。针对终止,`SIGTERM` 信号可以被阻塞或者被处理,而不像 `SIGKILL` 信号那样。一个进程也可以通过信号和另一个进程通信,这样使得信号也可以作为一种 IPC 机制。
信号可以在与用户交互的情况下发生。例如,一个用户从命令行中敲了 `Ctrl+C`终止一个从命令行中启动的程序;`Ctrl+C` 将产生一个 `SIGTERM` 信号。`SIGTERM` 意即终止,它可以被阻塞或者被处理,而不像 `SIGKILL` 信号那样。一个进程也可以通过信号和另一个进程通信,这样使得信号也可以作为一种 IPC 机制。
考虑一下一个多进程应用,例如 Nginx 网络服务器是如何被另一个进程优雅地关闭的。`kill` 函数:
```
int kill(pid_t pid, int signum); /* declaration */
```
bei
可以被一个进程用来终止另一个进程或者一组进程。假如 `kill` 函数的第一个参数是大于 `0` 的,那么这个参数将会被认为是目标进程的 pid进程 ID假如这个参数是 `0`,则这个参数将会被识别为信号发送者所属的那组进程。
`kill` 的第二个参数要么是一个标准的信号数字(例如 `SIGTERM``SIGKILL`),要么是 `0` ,这将会对信号做一次询问,确认第一个参数中的 pid 是否是有效的。这样将一个多进程应用的优雅地关闭就可以通过向组成该应用的一组进程发送一个终止信号来完成,具体来说就是调用一个 `kill` 函数,使得这个调用的第二个参数是 `SIGTERM`Nginx 主进程可以通过调用 `kill` 函数来终止其他 worker 进程,然后再停止自己。)就像许多库函数一样,`kill` 函数通过一个简单的可变语法拥有更多的能力和灵活性。
可以被一个进程用来终止另一个进程或者一组进程。假如 `kill` 函数的第一个参数是大于 `0` 的,那么这个参数将会被认为是目标进程的 `pid`(进程 ID假如这个参数是 `0`,则这个参数将会被视作信号发送者所属的那组进程。
`kill` 的第二个参数要么是一个标准的信号数字(例如 `SIGTERM``SIGKILL`),要么是 `0` ,这将会对信号做一次询问,确认第一个参数中的 `pid` 是否是有效的。这样优雅地关闭一个多进程应用就可以通过向组成该应用的一组进程发送一个终止信号来完成,具体来说就是调用一个 `kill` 函数,使得这个调用的第二个参数是 `SIGTERM`Nginx 主进程可以通过调用 `kill` 函数来终止其他工人进程,然后再停止自己。)就像许多库函数一样,`kill` 函数通过一个简单的可变语法拥有更多的能力和灵活性。
#### 示例 3. 一个多进程系统的优雅停止
@ -290,9 +290,9 @@ int main() {
上面的停止程序模拟了一个多进程系统的优雅退出,在这个例子中,这个系统由一个父进程和一个子进程组成。这次模拟的工作流程如下:
* 父进程尝试去 fork 一个子进程。假如这个 fork 操作成功了,每个进程就执行它自己的代码:子进程就执行函数 `child_code`,而父进程就执行函数 `parent_code`
* 子进程将会进入一个潜在的无限循环,在这个循环中子进程将睡眠一秒,然后打印一个信息,接着再次进入睡眠状态,以此循环往复。来自父进程的一个 `SIGTERM` 信号将引起子进程去执行一个信号处理回调函数 `graceful`。这样这个信号就使得子进程可以跳出循环,然后进行子进程和父进程之间的优雅终止。在终止之前,进程将打印一个信息。
* 在 fork 一个子进程后,父进程将睡眠 5 秒,使得子进程可以执行一会儿;当然在这个模拟中,子进程大多数时间都在睡眠。然后父进程调用 `SIGTERM` 作为第二个参数的 `kill` 函数,等待子进程的终止,然后自己再终止。
* 父进程尝试去 `fork` 一个子进程。假如这个 `fork` 操作成功了,每个进程就执行它自己的代码:子进程就执行函数 `child_code`,而父进程就执行函数 `parent_code`
* 子进程将会进入一个潜在的无限循环,在这个循环中子进程将睡眠一秒,然后打印一个信息,接着再次进入睡眠状态,以此循环往复。来自父进程的一个 `SIGTERM` 信号将引起子进程去执行一个信号处理回调函数 `graceful`。这样这个信号就使得子进程可以跳出循环,然后进行子进程和父进程之间的优雅终止。在终止之前,进程将打印一个信息。
* 在 `fork` 一个子进程后,父进程将睡眠 5 秒,使得子进程可以执行一会儿;当然在这个模拟中,子进程大多数时间都在睡眠。然后父进程调用 `SIGTERM` 作为第二个参数的 `kill` 函数,等待子进程的终止,然后自己再终止。
下面是一次运行的输出:
@ -309,22 +309,23 @@ Parent sleeping for a time...
My child terminated, about to exit myself...
```
对于信号的处理,上面的示例使用了 `sigaction` 库函数POSIX 推荐的用法)而不是传统的 `signal` 函数,`signal` 函数有轻便性问题。下面是我们主要关心的代码片段:
对于信号的处理,上面的示例使用了 `sigaction` 库函数POSIX 推荐的用法)而不是传统的 `signal` 函数,`signal` 函数有移植性问题。下面是我们主要关心的代码片段:
* 假如对 `fork` 的调用成功了,父进程将执行 `parent_code` 函数,而子进程将执行 `child_code` 函数。在给子进程发送信号之前,父进程将会等待 5 秒:
* 假如对 `fork` 的调用成功了,父进程将执行 `parent_code` 函数,而子进程将执行 `child_code` 函数。在给子进程发送信号之前,父进程将会等待 5 秒:
```
puts("Parent sleeping for a time...");
```
puts("Parent sleeping for a time...");
sleep(5);
if (-1 == kill(cpid, SIGTERM)) {
...sleepkillcpidSIGTERM...
```
假如 `kill` 调用成功了,父进程将在子进程终止时做等待,使得子进程不会变成一个僵尸进程。在等待完成后,父进程再退出。
* `child_code` 函数首先调用 `set_handler` 然后进入它的可能永久睡眠的循环。下面是我们将要查看的 `set_handler` 函数:
假如 `kill` 调用成功了,父进程将在子进程终止时做等待,使得子进程不会变成一个僵尸进程。在等待完成后,父进程再退出。
```
void set_handler() {
* `child_code` 函数首先调用 `set_handler` 然后进入它的可能永久睡眠的循环。下面是我们将要查看的 `set_handler` 函数:
```
void set_handler() {
  struct sigaction current;            /* current setup */
  sigemptyset(&current.sa_mask);       /* clear the signal set */
  current.sa_flags = 0;                /* for setting sa_handler, not sa_action */
@ -333,21 +334,22 @@ if (-1 == kill(cpid, SIGTERM)) {
}
```
上面代码的前三行在做相关的准备。第四个语句将为 `graceful` 设定 handler ,它将在调用 `_exit` 来停止之前打印一些信息。第 5 行和最后一行的语句将通过调用 `sigaction` 来向系统注册上面的 handler。`sigaction` 的第一个参数是 `SIGTERM` ,用作终止;第二个参数是当前的 `sigaction` 设定,而最后的参数(在这个例子中是 `NULL` )可被用来保存前面的 `sigaction` 设定,以备后面的可能使用。
上面代码的前三行在做相关的准备。第四个语句将为 `graceful` 设定为句柄,它将在调用 `_exit` 来停止之前打印一些信息。第 5 行和最后一行的语句将通过调用 `sigaction` 来向系统注册上面的句柄。`sigaction` 的第一个参数是 `SIGTERM` ,用作终止;第二个参数是当前的 `sigaction` 设定,而最后的参数(在这个例子中是 `NULL` )可被用来保存前面的 `sigaction` 设定,以备后面的可能使用。
使用信号来作为 IPC 的确是一个很轻量的方法,但确实值得尝试。通过信号来做 IPC 显然可以被归入 IPC 工具箱中。
### 这个系列的总结
在这个系列中,我们通过三篇有关 IPC 的文章,用示例代码介绍了如下机制:
* 共享文件
* 共享内存(通过信号量)
* 管道(名和无名)
* 管道(名和无名)
* 消息队列
* 套接字
* 信号
甚至在今天,在以线程为中心的语言,例如 Java、C# 和 Go 等变得越来越流行的情况下IPC 仍然很受欢迎,因为相比于使用多线程,通过多进程来实现并发有着一个明显的优势:默认情况下,每个进程都有它自己的地址空间,除非使用了基于共享内存的 IPC 机制(为了达到安全的并发,竞争条件在多线程和多进程的时候必须被加上锁),在多进程中可以排除掉基于内存的竞争条件。对于任何一个写过甚至是通过共享变量来通信的基本多线程程序的人来说TA 都会知道想要写一个清晰、高效、线程安全的代码是多么具有挑战性。使用单线程的多进程的确是很有吸引力的,这是一个切实可行的方式,使用它可以利用好今天多处理器的机器,而不需要面临基于内存的竞争条件的风险。
甚至在今天,在以线程为中心的语言,例如 Java、C# 和 Go 等变得越来越流行的情况下IPC 仍然很受欢迎,因为相比于使用多线程,通过多进程来实现并发有着一个明显的优势:默认情况下,每个进程都有它自己的地址空间,除非使用了基于共享内存的 IPC 机制(为了达到安全的并发,竞争条件在多线程和多进程的时候必须被加上锁),在多进程中可以排除掉基于内存的竞争条件。对于任何一个写过即使是基本的通过共享变量来通信的多线程程序的人来说,他都会知道想要写一个清晰、高效、线程安全的代码是多么具有挑战性。使用单线程的多进程的确是很有吸引力的,这是一个切实可行的方式,使用它可以利用好今天多处理器的机器,而不需要面临基于内存的竞争条件的风险。
当然,没有一个简单的答案能够回答上述 IPC 机制中的哪一个更好。在编程中每一种 IPC 机制都会涉及到一个取舍问题:是追求简洁,还是追求功能强大。以信号来举例,它是一个相对简单的 IPC 机制,但并不支持多个进程之间的丰富对话。假如确实需要这样的对话,另外的选择可能会更合适一些。带有锁的共享文件则相对直接,但是当要处理大量共享的数据流时,共享文件并不能很高效地工作。管道,甚至是套接字,有着更复杂的 API可能是更好的选择。让具体的问题去指导我们的选择吧。
@ -360,13 +362,13 @@ via: https://opensource.com/article/19/4/interprocess-communication-linux-networ
作者:[Marty Kalin][a]
选题:[lujun9972][b]
译者:[FSSlc](https://github.com/FSSlc)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/mkalindepauledu
[b]: https://github.com/lujun9972
[1]: https://en.wikipedia.org/wiki/Inter-process_communication
[2]: https://opensource.com/article/19/4/interprocess-communication-ipc-linux-part-1
[3]: https://opensource.com/article/19/4/interprocess-communication-ipc-linux-part-2
[2]: https://linux.cn/article-10826-1.html
[3]: https://linux.cn/article-10845-1.html
[4]: http://condor.depaul.edu/mkalin

View File

@ -0,0 +1,69 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10926-1.html)
[#]: subject: (4 open source apps for plant-based diets)
[#]: via: (https://opensource.com/article/19/4/apps-plant-based-diets)
[#]: author: (Joshua Allen Holm https://opensource.com/users/holmja)
4 款“吃草”的开源应用
======
> 这些应用使素食者、纯素食主义者和那些想吃得更健康的杂食者找到可以吃的食物。
![](https://img.linux.net.cn/data/attachment/album/201906/01/193302nompumppxnmnxirz.jpg)
减少对肉类、乳制品和加工食品的消费对地球来说更好,也对你的健康更有益。改变你的饮食习惯可能很困难,但是一些开源的 Android 应用可以让你吃的更清淡。无论你是参加[无肉星期一][2]、践行 Mark Bittman 的 [6:00 前的素食][3]指南,还是完全切换到<ruby>[植物全食饮食][4]<rt>whole-food, plant-based diet</rt></ruby>WFPB这些应用能帮助你找出要吃什么、发现素食和素食友好的餐馆并轻松地将你的饮食偏好传达给他人来助你更好地走这条路。所有这些应用都是开源的可从 [F-Droid 仓库][5]下载。
### Daily Dozen
![Daily Dozen app][6]
[Daily Dozen][7] 提供了医学博士、美国法医学会院士FACLM Michael Greger 推荐的项目清单作为健康饮食和生活方式的一部分。Greger 博士建议食用由多种食物组成的基于植物的全食饮食,并坚持日常锻炼。该应用可以让你跟踪你吃的每种食物的份数,你喝了多少份水(或其他获准的饮料,如茶),以及你是否每天锻炼。每类食物都提供食物分量和属于该类别的食物清单。例如,十字花科蔬菜类包括白菜、花椰菜、抱子甘蓝等许多其他建议。
### Food Restrictions
![Food Restrictions app][8]
[Food Restrictions][9] 是一个简单的应用,它可以帮助你将你的饮食限制传达给他人,即使这些人不会说你的语言。用户可以输入七种不同类别的食物限制:鸡肉、牛肉、猪肉、鱼、奶酪、牛奶和辣椒。每种类别都有“我不吃”和“我过敏”选项。“不吃”选项会显示带有红色 X 的图标。“过敏” 选项显示 “X” 和小骷髅图标。可以使用文本而不是图标显示相同的信息,但文本仅提供英语和葡萄牙语。还有一个选项可以显示一条文字信息,说明用户是素食主义者或纯素食主义者,它比选择选项更简洁、更准确地总结了这些饮食限制。纯素食主义者的文本清楚地提到不吃鸡蛋和蜂蜜,这在选择选项中是没有的。但是,就像选择选项方式的文字版本一样,这些句子仅提供英语和葡萄牙语。
### OpenFoodFacts
![Open Food Facts app][10]
购买杂货时避免买入不必要的成分可能令人沮丧,但 [OpenFoodFacts][11] 可以帮助简化流程。该应用可让你扫描产品上的条形码,以获得有关产品成分和是否健康的报告。即使产品符合纯素产品的标准,产品仍然可能非常不健康。拥有成分列表和营养成分可让你在购物时做出明智的选择。此应用的唯一缺点是数据是用户贡献的,因此并非每个产品都可有数据,但如果你想回馈项目,你可以贡献新数据。
### OpenVegeMap
![OpenVegeMap app][12]
使用 [OpenVegeMap][13] 查找你附近的纯素食或素食主义餐厅。此应用可以通过手机的当前位置或者输入地址来搜索。餐厅分类为仅限纯素食者、适合纯素食者,仅限素食主义者,适合素食者,非素食和未知。该应用使用来自 [OpenStreetMap][14] 的数据和用户提供的有关餐馆的信息,因此请务必仔细检查以确保所提供的信息是最新且准确的。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/4/apps-plant-based-diets
作者:[Joshua Allen Holm][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/holmja
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003588_01_rd3os.combacktoschoolserieshe_rh_041x_0.png?itok=tfg6_I78
[2]: https://www.meatlessmonday.com/
[3]: https://www.amazon.com/dp/0385344740/
[4]: https://nutritionstudies.org/whole-food-plant-based-diet-guide/
[5]: https://f-droid.org/
[6]: https://opensource.com/sites/default/files/uploads/daily_dozen.png (Daily Dozen app)
[7]: https://f-droid.org/en/packages/org.nutritionfacts.dailydozen/
[8]: https://opensource.com/sites/default/files/uploads/food_restrictions.png (Food Restrictions app)
[9]: https://f-droid.org/en/packages/br.com.frs.foodrestrictions/
[10]: https://opensource.com/sites/default/files/uploads/openfoodfacts.png (Open Food Facts app)
[11]: https://f-droid.org/en/packages/openfoodfacts.github.scrachx.openfood/
[12]: https://opensource.com/sites/default/files/uploads/openvegmap.png (OpenVegeMap app)
[13]: https://f-droid.org/en/packages/pro.rudloff.openvegemap/
[14]: https://www.openstreetmap.org/

View File

@ -0,0 +1,59 @@
[#]: collector: (lujun9972)
[#]: translator: (ninifly)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11009-1.html)
[#]: subject: (Edge computing is in most industries future)
[#]: via: (https://www.networkworld.com/article/3391016/edge-computing-is-in-most-industries-future.html)
[#]: author: (Anne Taylor https://www.networkworld.com/author/Anne-Taylor/)
边缘计算是大多数行业的未来
======
> 几乎每个行业都可以利用边缘计算来加速数字化转型。
![](https://img.linux.net.cn/data/attachment/album/201906/23/231224cdl3kwedn0hw2lie.jpg)
边缘计算的发展将取得一次巨大的飞跃。[据 Gartner 数据][2],现在公司有 10% 的数据是在传统数据中心或云之外生成的。但在未来六年内,这一比例将升至 75%。
这很大程度上取决于处理来自设备数据的需要比如物联网IoT数据传感器。早期采用这一方法的包括
* **制造商**:设备与传感器似乎是这个行业特有的,因此需要为产生的数据找到更快速的方法也就不足为奇。一份 [Automation World][3] 最近的研究发现 43% 的制造商已经部署了边缘计算项目。最常用用途包括生产/制造数据分析与设备数据分析。
* **零售商**:与大多数深受数字化运营需求影响的产业一样,零售商也不得不革新了其客户体验。为此,这些组织“正在积极投资贴近于买家的计算能力”,施耐德电气公司 IT 部门执行副总裁 [Dave Johnson][4] 如是说。他列举了一些例子例如在试衣间的增强现实AR镜子提供了不同的服装选择而不用顾客试用这些服装。又如用于显示店内导航的基于信标的热图。
* **医疗保健机构**:随着医疗保健成本的不断上升,这一行业已经具备了提高生产能力与成本效率方面的创新能力。管理咨询公司[麦肯锡已经确定][5],至少有 11 个有益于患者、医疗机构或两者的医疗保健用例。举两个例子:提高护理效率并有助于优化设备的跟踪移动医疗设备;跟踪用户锻炼并提供健康建议的可穿戴设备。
虽然以上这些是明显的用例,随着边缘计算市场的扩大,采用它的行业也会增加。
### 数字化转型的优势
随着边缘计算的快速处理能力完全符合数字化转型的目标:提高效率、生产能力和加速产品上市和客户体验。以下是一些有潜力的应用及将被边缘计算改变的行业:
**农业**:农民和组织已经使用无人机将农田和气候环境传给灌溉设备。其他的应用可能包括了对工人、牲畜和设备的监测与位置跟踪,从而改善生产能力、效率和成本。
**能源**:在这一领域有许多的潜在的应用,可以使消费者与供应商都受益。例如,智能电表有助于业主更好地管理能源使用,同时减少电网运营商对手动抄表的需求。同样的,水管上的传感器能够监测到漏水,同时提供实时漏水数据。
**金融服务**:银行正在采取交互式 ATM 机,这种交互式 ATM 机能够快速地处理数据以提供更好的用户体验。在管理层次,可以更快速地分析交易数据中的欺诈行为。
**物流**:由于消费者需要更快速地交付商品和服务,物流公司将需要转换其地图和寻路功能以获取实时数据,尤其在最后一公里计划和跟踪方面。这可能涉及到基于街道、包裹及汽车的传感器数据传输处理过程。
得益于边缘计算,所有行业都有转型的潜力。但是,这将取决于他们如何处理计算基础设施。可以在 [APC.com][6] 找到如何克服任何 IT 阻碍的解决方案。
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3391016/edge-computing-is-in-most-industries-future.html
作者:[Anne Taylor][a]
选题:[lujun9972][b]
译者:[ninifly](https://github.com/ninifly)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.networkworld.com/author/Anne-Taylor/
[b]: https://github.com/lujun9972
[1]: https://images.idgesg.net/images/article/2019/04/istock-1019389496-100794424-large.jpg
[2]: https://www.gartner.com/smarterwithgartner/what-edge-computing-means-for-infrastructure-and-operations-leaders/
[3]: https://www.automationworld.com/article/technologies/cloud-computing/its-not-edge-vs-cloud-its-both
[4]: https://blog.schneider-electric.com/datacenter/2018/07/10/why-brick-and-mortar-retail-quickly-establishing-leadership-edge-computing/
[5]: https://www.mckinsey.com/industries/high-tech/our-insights/new-demand-new-markets-what-edge-computing-means-for-hardware-companies
[6]: https://www.apc.com/us/en/solutions/business-solutions/edge-computing.jsp

View File

@ -0,0 +1,137 @@
[#]: collector: (lujun9972)
[#]: translator: (Modrisco)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10968-1.html)
[#]: subject: (Epic Games Store is Now Available on Linux Thanks to Lutris)
[#]: via: (https://itsfoss.com/epic-games-lutris-linux/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
有了 LutrisLinux 现在也可以启动 Epic 游戏商城
======
> 开源游戏平台 Lutris 现在使你能够在 Linux 上使用 Epic 游戏商城。我们使用 Ubuntu 19.04 版本进行了测试,以下是我们的使用体验。
[在 Linux 上玩游戏][1] 正变得越来越容易。Steam [正在开发中的][3] 特性可以帮助你实现 [在 Linux 上玩 Windows 游戏][2]。
如果说 Steam 在 Linux 运行 Windows 游戏领域还是新玩家,而 Lutris 却已从事多年。
[Lutris][4] 是一款为 Linux 开发的开源游戏平台,提供诸如 Origin、Steam、战网等平台的游戏安装器。它使用 Wine 来运行 Linux 不能支持的程序。
Lutris 近期宣布你可以通过它来运行 Epic 游戏商店。
### Lutris 为 Linux 带来了 Epic 游戏
![Epic Games Store Lutris Linux][5]
[Epic 游戏商城][6] 是一个类似 Steam 的电子游戏分销平台。它目前只支持 Windows 和 macOS。
Lutris 团队付出了大量努力使 Linux 用户可以通过 Lutris 使用 Epic 游戏商城。虽然我不用 Epic 商城,但可以通过 Lutris 在 Linux 上运行 Epic 商城终归是个好消息。
> 好消息! 你现在可以通过 Lutris 安装获得 [@EpicGames][7] 商城在 Linux 下的全功能支持!没有发现任何问题。 <https://t.co/cYmd7PcYdG>[@TimSweeneyEpic][8] 可能会很喜欢 😊
>
> ![pic.twitter.com/7mt9fXt7TH][9]
>
> — Lutris Gaming (@LutrisGaming) [April 17, 2019][10]
作为一名狂热的游戏玩家和 Linux 用户,我立即得到了这个消息,并安装了 Lutris 来运行 Epic 游戏。
**备注:** 我使用 [Ubuntu 19.04][11] 来测试 Linux 环境下的游戏运行情况。
### 通过 Lutris 在 Linux 下使用 Epic 游戏商城
为了在你的 Linux 系统中安装 Epic 游戏商城,请确保你已经安装了 Wine 和 Python 3。接下来[在 Ubuntu 中安装 Wine][12] ,或任何你正在使用的 Linux 发行版本也都可以。然后, [从官方网站下载 Lutris][13].
#### 安装 Epic 游戏商城
Lutris 安装成功后,直接启动它。
当我尝试时,我遇到了一个问题(当我用 GUI 启动时却没有遇到)。当我尝试在命令行输入 `lutris` 来启动时,我发现了下图所示的错误:
![][15]
感谢 Abhishek我了解到了这是一个常见问题 (你可以在 [GitHub][16] 上查看这个问题)。
总之,为了解决这个问题,我需要在命令行中输入以下命令:
```
export LC_ALL=C
```
当你遇到同样的问题时,只要你输入这个命令,就能正常启动 Lutris 了。
**注意**:每次启动 Lutris 时都必须输入这个命令。因此,最好将其添加到 `.bashrc` 文件或环境变量列表中。
上述操作完成后,只要启动并搜索 “Epic Games Store” 会显示以下图片中的内容:
![Epic Games Store in Lutris][17]
在这里,我已经安装过了,所以你将会看到“安装”选项,它会自动询问你是否需要安装需要的包。只需要继续操作就可以成功安装。就是这样,不需要任何黑科技。
#### 玩一款 Epic 游戏商城中的游戏
![Epic Games Store][18]
现在我们已经通过 Lutris 在 Linux 上安装了 Epic 游戏商城,启动它并登录你的账号就可以开始了。
但这真会奏效吗?
*是的Epic 游戏商城可以运行。* **但是所有游戏都不能玩。**LCTT 译注:莫生气,请看文末的进一步解释!)
好吧我并没有尝试过所有内容但是我拿了一个免费的游戏Transistor —— 一款回合制 ARPG 游戏)来检查它是否工作。
![Transistor Epic Games Store][19]
很不幸,游戏没有启动。当我运行时界面显示了 “Running” 不过什么都没有发生。
到目前为止,我还不知道有什么解决方案 —— 所以如果我找到解决方案,我会尽力让你们知道最新情况。
### 总结
通过 Lutris 这样的工具使 Linux 的游戏场景得到了改善,这终归是个好消息 。不过,仍有许多工作要做。
对于在 Linux 上运行的游戏来说,无障碍运行仍然是一个挑战。其中可能就会有我遇到的这种问题,或者其它类似的。但它正朝着正确的方向发展 —— 即使还存在着一些问题。
你有什么看法吗?你是否也尝试用 Lutris 在 Linux 上启动 Epic 游戏商城?在下方评论让我们看看你的意见。
### 补充
Transistor 实际上有一个原生的 Linux 移植版。到目前为止,我从 Epic 获得的所有游戏都是如此。所以我会试着压下我的郁闷,而因为 Epic 只让你玩你通过他们的商店/启动器购买的游戏,所以在 Linux 机器上用 Lutris 玩这个原生的 Linux 游戏是不可能的。这简直愚蠢极了。Steam 有一个原生的 Linux 启动器虽然不是很理想但它可以工作。GOG 允许你从网站下载购买的内容,可以在你喜欢的任何平台上玩这些游戏。他们的启动器完全是可选的。
我对此非常恼火,因为我在我的 Epic 库中的游戏都是可以在我的笔记本电脑上运行得很好的游戏,当我坐在桌面前时,玩起来很有趣。但是因为那台桌面机是我唯一拥有的 Windows 机器……
我选择使用 Linux 时已经知道会存在兼容性问题,并且我有一个专门用于游戏的 Windows 机器,而我通过 Epic 获得的游戏都是免费的所以我在这里只是表示一下不满。但是他们两个作为最著名的竞争对手Epic 应该有在我的 Linux 机器上玩原生 Linux 移植版的机制。
--------------------------------------------------------------------------------
via: https://itsfoss.com/epic-games-lutris-linux/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[Modrisco](https://github.com/Modrisco)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://linux.cn/article-7316-1.html
[2]: https://linux.cn/article-10061-1.html
[3]: https://linux.cn/article-10054-1.html
[4]: https://lutris.net/
[5]: https://itsfoss.com/wp-content/uploads/2019/04/epic-games-store-lutris-linux-800x450.png
[6]: https://www.epicgames.com/store/en-US/
[7]: https://twitter.com/EpicGames?ref_src=twsrc%5Etfw
[8]: https://twitter.com/TimSweeneyEpic?ref_src=twsrc%5Etfw
[9]: https://pbs.twimg.com/media/D4XkXafX4AARDkW?format=jpg&name=medium
[10]: https://twitter.com/LutrisGaming/status/1118552969816018948?ref_src=twsrc%5Etfw
[11]: https://itsfoss.com/ubuntu-19-04-release-features/
[12]: https://itsfoss.com/install-latest-wine/
[13]: https://lutris.net/downloads/
[14]: https://itsfoss.com/ubuntu-mate-entroware/
[15]: https://itsfoss.com/wp-content/uploads/2019/04/lutris-error.jpg
[16]: https://github.com/lutris/lutris/issues/660
[17]: https://itsfoss.com/wp-content/uploads/2019/04/lutris-epic-games-store-800x520.jpg
[18]: https://itsfoss.com/wp-content/uploads/2019/04/epic-games-store-800x450.jpg
[19]: https://itsfoss.com/wp-content/uploads/2019/04/transistor-game-epic-games-store-800x410.jpg
[20]: https://itsfoss.com/skpe-alpha-linux/

View File

@ -1,26 +1,25 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: translator: (tomjlw)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10955-1.html)
[#]: subject: (How to identify same-content files on Linux)
[#]: via: (https://www.networkworld.com/article/3390204/how-to-identify-same-content-files-on-linux.html#tk.rss_all)
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
How to identify same-content files on Linux
如何在 Linux 上识别同样内容的文件
======
Copies of files sometimes represent a big waste of disk space and can cause confusion if you want to make updates. Here are six commands to help you identify these files.
> 有时文件副本相当于对硬盘空间的巨大浪费,并会在你想要更新文件时造成困扰。以下是用来识别这些文件的六个命令。
![Vinoth Chandar \(CC BY 2.0\)][1]
In a recent post, we looked at [how to identify and locate files that are hard links][2] (i.e., that point to the same disk content and share inodes). In this post, we'll check out commands for finding files that have the same _content_ , but are not otherwise connected.
在最近的帖子中,我们看了[如何识别并定位硬链接的文件][2](即,指向同一硬盘内容并共享 inode。在本文中我们将查看能找到具有相同*内容*,却不相链接的文件的命令。
Hard links are helpful because they allow files to exist in multiple places in the file system while not taking up any additional disk space. Copies of files, on the other hand, sometimes represent a big waste of disk space and run some risk of causing some confusion if you want to make updates. In this post, we're going to look at multiple ways to identify these files.
硬链接很有用是因为它们能够使文件存放在文件系统内的多个地方却不会占用额外的硬盘空间。另一方面,有时文件副本相当于对硬盘空间的巨大浪费,在你想要更新文件时也会有造成困扰之虞。在本文中,我们将看一下多种识别这些文件的方式。
**[ Two-Minute Linux Tips:[Learn how to master a host of Linux commands in these 2-minute video tutorials][3] ]**
### 用 diff 命令比较文件
### Comparing files with the diff command
Probably the easiest way to compare two files is to use the **diff** command. The output will show you the differences between the two files. The < and > signs indicate whether the extra lines are in the first (<) or second (>) file provided as arguments. In this example, the extra lines are in backup.html.
可能比较两个文件最简单的方法是使用 `diff` 命令。输出会显示你文件的不同之处。`<` 和 `>` 符号代表在当参数传过来的第一个(`<`)或第二个(`>`)文件中是否有额外的文字行。在这个例子中,在 `backup.html` 中有额外的文字行。
```
$ diff index.html backup.html
@ -30,18 +29,18 @@ $ diff index.html backup.html
> </pre>
```
If diff shows no output, that means the two files are the same.
如果 `diff` 没有输出那代表两个文件相同。
```
$ diff home.html index.html
$
```
The only drawbacks to diff are that it can only compare two files at a time, and you have to identify the files to compare. Some commands we will look at in this post can find the duplicate files for you.
`diff` 的唯一缺点是它一次只能比较两个文件并且你必须指定用来比较的文件,这篇帖子中的一些命令可以为你找到多个重复文件。
### Using checksums
### 使用校验和
The **cksum** (checksum) command computes checksums for files. Checksums are a mathematical reduction of the contents to a lengthy number (like 2819078353 228029). While not absolutely unique, the chance that files that are not identical in content would result in the same checksum is extremely small.
`cksum`checksum 命令计算文件的校验和。校验和是一种将文字内容转化成一个长数字例如2819078353 228029的数学简化。虽然校验和并不是完全独有的但是文件内容不同校验和却相同的概率微乎其微。
```
$ cksum *.html
@ -50,11 +49,11 @@ $ cksum *.html
4073570409 227985 index.html
```
In the example above, you can see how the second and third files yield the same checksum and can be assumed to be identical.
在上述示例中,你可以看到产生同样校验和的第二个和第三个文件是如何可以被默认为相同的。
### Using the find command
### 使用 find 命令
While the find command doesn't have an option for finding duplicate files, it can be used to search files by name or type and run the cksum command. For example:
虽然 `find` 命令并没有寻找重复文件的选项,它依然可以被用来通过名字或类型寻找文件并运行 `cksum` 命令。例如:
```
$ find . -name "*.html" -exec cksum {} \;
@ -63,9 +62,9 @@ $ find . -name "*.html" -exec cksum {} \;
4073570409 227985 ./index.html
```
### Using the fslint command
### 使用 fslint 命令
The **fslint** command can be used to specifically find duplicate files. Note that we give it a starting location. The command can take quite some time to complete if it needs to run through a large number of files. Here's output from a very modest search. Note how it lists the duplicate files and also looks for other issues, such as empty directories and bad IDs.
`fslint` 命令可以被特地用来寻找重复文件。注意我们给了它一个起始位置。如果它需要遍历相当多的文件,这就需要花点时间来完成。注意它是如何列出重复文件并寻找其它问题的,比如空目录和坏 ID。
```
$ fslint .
@ -86,15 +85,15 @@ index.html
-------------------------Non Stripped executables
```
You may have to install **fslint** on your system. You will probably have to add it to your search path, as well:
你可能需要在你的系统上安装 `fslint`。你可能也需要将它加入你的命令搜索路径:
```
$ export PATH=$PATH:/usr/share/fslint/fslint
```
### Using the rdfind command
### 使用 rdfind 命令
The **rdfind** command will also look for duplicate (same content) files. The name stands for "redundant data find," and the command is able to determine, based on file dates, which files are the originals — which is helpful if you choose to delete the duplicates, as it will remove the newer files.
`rdfind` 命令也会寻找重复(相同内容的)文件。它的名字意即“重复数据搜寻”,并且它能够基于文件日期判断哪个文件是原件——这在你选择删除副本时很有用因为它会移除较新的文件。
```
$ rdfind ~
@ -111,7 +110,7 @@ Totally, 223 KiB can be reduced.
Now making results file results.txt
```
You can also run this command in "dryrun" (i.e., only report the changes that might otherwise be made).
你可以在 `dryrun` 模式中运行这个命令 (换句话说,仅仅汇报可能会另外被做出的改动)。
```
$ rdfind -dryrun true ~
@ -128,7 +127,7 @@ Removed 9 files due to unique sizes from list.2 files left.
(DRYRUN MODE) Now making results file results.txt
```
The rdfind command also provides options for things such as ignoring empty files (-ignoreempty) and following symbolic links (-followsymlinks). Check out the man page for explanations.
`rdfind` 命令同样提供了类似忽略空文档(`-ignoreempty`)和跟踪符号链接(`-followsymlinks`)的功能。查看 man 页面获取解释。
```
-ignoreempty ignore empty files
@ -146,7 +145,7 @@ The rdfind command also provides options for things such as ignoring empty files
-n, -dryrun display what would have been done, but don't do it
```
Note that the rdfind command offers an option to delete duplicate files with the **-deleteduplicates true** setting. Hopefully the command's modest problem with grammar won't irritate you. ;-)
注意 `rdfind` 命令提供了 `-deleteduplicates true` 的设置选项以删除副本。希望这个命令语法上的小问题不会惹恼你。;-)
```
$ rdfind -deleteduplicates true .
@ -154,11 +153,11 @@ $ rdfind -deleteduplicates true .
Deleted 1 files. <==
```
You will likely have to install the rdfind command on your system. It's probably a good idea to experiment with it to get comfortable with how it works.
你将可能需要在你的系统上安装 `rdfind` 命令。试验它以熟悉如何使用它可能是一个好主意。
### Using the fdupes command
### 使用 fdupes 命令
The **fdupes** command also makes it easy to identify duplicate files and provides a large number of useful options — like **-r** for recursion. In its simplest form, it groups duplicate files together like this:
`fdupes` 命令同样使得识别重复文件变得简单。它同时提供了大量有用的选项——例如用来迭代的 `-r`。在这个例子中,它像这样将重复文件分组到一起:
```
$ fdupes ~
@ -173,7 +172,7 @@ $ fdupes ~
/home/shs/hideme.png
```
Here's an example using recursion. Note that many of the duplicate files are important (users' .bashrc and .profile files) and should clearly not be deleted.
这是使用迭代的一个例子,注意许多重复文件是重要的(用户的 `.bashrc``.profile` 文件)并且不应被删除。
```
# fdupes -r /home
@ -204,7 +203,7 @@ Here's an example using recursion. Note that many of the duplicate files are imp
/home/shs/PNGs/Sandra_rotated.png
```
The fdupe command's many options are listed below. Use the **fdupes -h** command, or read the man page for more details.
`fdupe` 命令的许多选项列如下。使用 `fdupes -h` 命令或者阅读 man 页面获取详情。
```
-r --recurse recurse
@ -229,15 +228,11 @@ The fdupe command's many options are listed below. Use the **fdupes -h** command
-h --help displays help
```
The fdupes command is another one that you're like to have to install and work with for a while to become familiar with its many options.
`fdupes` 命令是另一个你可能需要安装并使用一段时间才能熟悉其众多选项的命令。
### Wrap-up
### 总结
Linux systems provide a good selection of tools for locating and potentially removing duplicate files, along with options for where you want to run your search and what you want to do with duplicate files when you find them.
**[ Also see:[Invaluable tips and tricks for troubleshooting Linux][4] ]**
Join the Network World communities on [Facebook][5] and [LinkedIn][6] to comment on topics that are top of mind.
Linux 系统提供能够定位并(潜在地)能移除重复文件的一系列的好工具,以及能让你指定搜索区域及当对你所发现的重复文件时的处理方式的选项。
--------------------------------------------------------------------------------
@ -245,8 +240,8 @@ via: https://www.networkworld.com/article/3390204/how-to-identify-same-content-f
作者:[Sandra Henry-Stocker][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
译者:[tomjlw](https://github.com/tomjlw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@ -258,3 +253,4 @@ via: https://www.networkworld.com/article/3390204/how-to-identify-same-content-f
[4]: https://www.networkworld.com/article/3242170/linux/invaluable-tips-and-tricks-for-troubleshooting-linux.html
[5]: https://www.facebook.com/NetworkWorld/
[6]: https://www.linkedin.com/company/network-world

View File

@ -0,0 +1,146 @@
[#]: collector: (lujun9972)
[#]: translator: (cycoe)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10929-1.html)
[#]: subject: (Monitoring CPU and GPU Temperatures on Linux)
[#]: via: (https://itsfoss.com/monitor-cpu-gpu-temp-linux/)
[#]: author: (It's FOSS Community https://itsfoss.com/author/itsfoss/)
在 Linux 上监控 CPU 和 GPU 温度
======
> 本篇文章讨论了在 Linux 命令行中监控 CPU 和 GPU 温度的两种简单方式。
由于 [Steam][1](包括 [Steam Play][2],即 Proton和一些其他的发展GNU/Linux 正在成为越来越多计算机用户的日常游戏平台的选择。也有相当一部分用户在遇到像[视频编辑][3]或图形设计等Kdenlive 和 [Blender][4] 是这类应用程序中很好的例子)资源消耗型计算任务时,也会使用 GNU/Linux。
不管你是否是这些用户中的一员或其他用户,你也一定想知道你的电脑 CPU 和 GPU 能有多热(如果你想要超频的话更会如此)。如果是这样,那么继续读下去。我们会介绍两个非常简单的命令来监控 CPU 和 GPU 温度。
我的装置包括一台 [Slimbook Kymera][5] 和两台显示器(一台 TV 和一台 PC 监视器),使得我可以用一台来玩游戏,另一台来留意监控温度。另外,因为我使用 [Zorin OS][6],我会将关注点放在 Ubuntu 和 Ubuntu 的衍生发行版上。
为了监控 CPU 和 GPU 的行为,我们将利用实用的 `watch` 命令在每几秒钟之后动态地得到读数。
![][7]
### 在 Linux 中监控 CPU 温度
对于 CPU 温度,我们将结合使用 `watch``sensors` 命令。一篇关于[此工具的图形用户界面版本][8]的有趣文章已经在 It's FOSS 中介绍过了。然而,我们将在此处使用命令行版本:
```
watch -n 2 sensors
```
`watch` 保证了读数会在每 2 秒钟更新一次(当然,这个周期值能够根据你的需要去更改):
```
Every 2,0s: sensors
iwlwifi-virtual-0
Adapter: Virtual device
temp1: +39.0°C
acpitz-virtual-0
Adapter: Virtual device
temp1: +27.8°C (crit = +119.0°C)
temp2: +29.8°C (crit = +119.0°C)
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +37.0°C (high = +82.0°C, crit = +100.0°C)
Core 0: +35.0°C (high = +82.0°C, crit = +100.0°C)
Core 1: +35.0°C (high = +82.0°C, crit = +100.0°C)
Core 2: +33.0°C (high = +82.0°C, crit = +100.0°C)
Core 3: +36.0°C (high = +82.0°C, crit = +100.0°C)
Core 4: +37.0°C (high = +82.0°C, crit = +100.0°C)
Core 5: +35.0°C (high = +82.0°C, crit = +100.0°C)
```
除此之外,我们还能得到如下信息:
* 我们有 5 个核心正在被使用(并且当前的最高温度为 37.0℃)。
* 温度超过 82.0℃ 会被认为是过热。
* 超过 100.0℃ 的温度会被认为是超过临界值。
根据以上的温度值我们可以得出结论,我的电脑目前的工作负载非常小。
### 在 Linux 中监控 GPU 温度
现在让我们来看看显卡。我从来没使用过 AMD 的显卡,因此我会将重点放在 Nvidia 的显卡上。我们需要做的第一件事是从 [Ubuntu 的附加驱动][10] 中下载合适的最新驱动。
在 UbuntuZorin 或 Linux Mint 也是相同的)中,进入“软件和更新 > 附加驱动”选项,选择最新的可用驱动。另外,你可以添加或启用显示卡的官方 ppa通过命令行或通过“软件和更新 > 其他软件”来实现)。安装驱动程序后,你将可以使用 “Nvidia X Server” 的 GUI 程序以及命令行工具 `nvidia-smi`Nvidia 系统管理界面)。因此我们将使用 `watch``nvidia-smi`
```
watch -n 2 nvidia-smi
```
与 CPU 的情况一样,我们会在每两秒得到一次更新的读数:
```
Every 2,0s: nvidia-smi
Fri Apr 19 20:45:30 2019
+-----------------------------------------------------------------------------+
| Nvidia-SMI 418.56 Driver Version: 418.56 CUDA Version: 10.1 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 106... Off | 00000000:01:00.0 On | N/A |
| 0% 54C P8 10W / 120W | 433MiB / 6077MiB | 4% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 1557 G /usr/lib/xorg/Xorg 190MiB |
| 0 1820 G /usr/bin/gnome-shell 174MiB |
| 0 7820 G ...equest-channel-token=303407235874180773 65MiB |
+-----------------------------------------------------------------------------+
```
从这个表格中我们得到了关于显示卡的如下信息:
* 它正在使用版本号为 418.56 的开源驱动。
* 显示卡的当前温度为 54.0℃,并且风扇的使用量为 0%。
* 电量的消耗非常低:仅仅 10W。
* 总量为 6GB 的 vram视频随机存取存储器只使用了 433MB。
* vram 正在被 3 个进程使用,他们的 ID 分别为 1557、1820 和 7820。
大部分这些事实或数值都清晰地表明,我们没有在玩任何消耗系统资源的游戏或处理大负载的任务。当我们开始玩游戏、处理视频或其他类似任务时,这些值就会开始上升。
#### 结论
即便我们有 GUI 工具,但我还是发现这两个命令对于实时监控硬件非常的顺手。
你将如何去使用它们呢?你可以通过阅读他们的 man 手册来学习更多关于这些工具的使用技巧。
你有其他偏爱的工具吗?在评论里分享给我们吧 ;)。
玩得开心!
--------------------------------------------------------------------------------
via: https://itsfoss.com/monitor-cpu-gpu-temp-linux/
作者:[Alejandro Egea-Abellán][a]
选题:[lujun9972][b]
译者:[cycoe](https://github.com/cycoe)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/itsfoss/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/install-steam-ubuntu-linux/
[2]: https://itsfoss.com/steam-play-proton/
[3]: https://itsfoss.com/best-video-editing-software-linux/
[4]: https://www.blender.org/
[5]: https://slimbook.es/
[6]: https://zorinos.com/
[7]: https://itsfoss.com/wp-content/uploads/2019/04/monitor-cpu-gpu-temperature-linux-800x450.png
[8]: https://itsfoss.com/check-laptop-cpu-temperature-ubuntu/
[9]: https://itsfoss.com/best-command-line-games-linux/
[10]: https://itsfoss.com/install-additional-drivers-ubuntu/
[11]: https://itsfoss.com/review-googler-linux/
[12]: https://itsfoss.com/wp-content/uploads/2019/04/EGEA-ABELLAN-Alejandro.jpg

View File

@ -0,0 +1,112 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10919-1.html)
[#]: subject: (Installing Budgie Desktop on Ubuntu [Quick Guide])
[#]: via: (https://itsfoss.com/install-budgie-ubuntu/)
[#]: author: (Atharva Lele https://itsfoss.com/author/atharva/)
在 Ubuntu 上安装 Budgie 桌面
======
> 在这个逐步的教程中学习如何在 Ubuntu 上安装 Budgie 桌面。
在所有[各种 Ubuntu 版本][1]中,[Ubuntu Budgie][2] 是最被低估的版本。它外观优雅,而且需要的资源也不多。
阅读这篇 《[Ubuntu Budgie 点评][3]》或观看下面的视频,了解 Ubuntu Budgie 18.04 的外观如何。
- [Ubuntu 18.04 Budgie Desktop Tour [It's Elegant]](https://youtu.be/KXgreWOK33k)
如果你喜欢 [Budgie 桌面][5]但你正在使用其他版本的 Ubuntu例如默认 Ubuntu 带有 GNOME 桌面,我有个好消息。你可以在当前的 Ubuntu 系统上安装 Budgie 并切换桌面环境。
在这篇文章中,我将告诉你到底该怎么做。但首先,对那些不了解 Budgie 的人进行一点介绍。
Budgie 桌面环境主要由 [Solus Linux 团队开发][6]。它的设计注重优雅和现代使用。Budgie 适用于所有主流 Linux 发行版可以让用户在其上尝试体验这种新的桌面环境。Budgie 现在非常成熟,并提供了出色的桌面体验。
> 警告
>
> 在同一系统上安装多个桌面可能会导致冲突,你可能会遇到一些问题,如面板中缺少图标或同一程序的多个图标。
>
> 你也许不会遇到任何问题。是否要尝试不同桌面由你决定。
### 在 Ubuntu 上安装 Budgie
此方法未在 Linux Mint 上进行测试,因此我建议你 Mint 上不要按照此指南进行操作。
对于正在使用 Ubuntu 的人Budgie 现在默认是 Ubuntu 仓库的一部分。因此,我们不需要添加任何 PPA 来下载 Budgie。
要安装 Budgie只需在终端中运行此命令即可。我们首先要确保系统已完全更新。
```
sudo apt update && sudo apt upgrade
sudo apt install ubuntu-budgie-desktop
```
下载完成后,你将看到选择显示管理器的提示。选择 “lightdm” 以获得完整的 Budgie 体验。
![Select lightdm][7]
安装完成后,重启计算机。然后,你会看到 Budgie 的登录页面。输入你的密码进入主屏幕。
![Budgie Desktop Home][8]
### 切换到其他桌面环境
![Budgie login screen][9]
你可以单击登录名旁边的 Budgie 图标获取登录选项。在那里你可以在已安装的桌面环境DE之间进行选择。就我而言我看到了 Budgie 和默认的 UbuntuGNOME桌面。
![Select your DE][10]
因此,无论何时你想登录 GNOME都可以使用此菜单执行此操作。
### 如何删除 Budgie
如果你不喜欢 Budgie 或只是想回到常规的以前的 Ubuntu你可以如上节所述切换回常规桌面。
但是,如果你真的想要删除 Budgie 及其组件,你可以按照以下命令回到之前的状态。
**在使用这些命令之前先切换到其他桌面环境:**
```
sudo apt remove ubuntu-budgie-desktop ubuntu-budgie* lightdm
sudo apt autoremove
sudo apt install --reinstall gdm3
```
成功运行所有命令后,重启计算机。
现在,你将回到 GNOME 或其他你有的桌面。
### 你对 Budgie 有什么看法?
Budgie 是[最佳 Linux 桌面环境][12]之一。希望这个简短的指南帮助你在 Ubuntu 上安装了很棒的 Budgie 桌面。
如果你安装了 Budgie你最喜欢它的什么请在下面的评论中告诉我们。像往常一样欢迎任何问题或建议。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-budgie-ubuntu/
作者:[Atharva Lele][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/atharva/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/which-ubuntu-install/
[2]: https://ubuntubudgie.org/
[3]: https://itsfoss.com/ubuntu-budgie-18-review/
[4]: https://www.youtube.com/c/itsfoss?sub_confirmation=1
[5]: https://github.com/solus-project/budgie-desktop
[6]: https://getsol.us/home/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/budgie_install_select_dm.png?fit=800%2C559&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/budgie_homescreen.jpg?fit=800%2C500&ssl=1
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/budgie_install_lockscreen.png?fit=800%2C403&ssl=1
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/budgie_install_lockscreen_select_de.png?fit=800%2C403&ssl=1
[11]: https://itsfoss.com/snapd-error-ubuntu/
[12]: https://itsfoss.com/best-linux-desktop-environments/

View File

@ -1,8 +1,8 @@
[#]: collector: (lujun9972)
[#]: translator: (way-ww)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10923-1.html)
[#]: subject: (How To Install/Uninstall Listed Packages From A File In Linux?)
[#]: via: (https://www.2daygeek.com/how-to-install-uninstall-listed-packages-from-a-file-in-linux/)
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
@ -10,25 +10,17 @@
如何在 Linux 上安装/卸载一个文件中列出的软件包?
======
在某些情况下,你可能想要将一个服务器上的软件包列表安装到另一个服务器上。
在某些情况下,你可能想要将一个服务器上的软件包列表安装到另一个服务器上。例如,你已经在服务器 A 上安装了 15 个软件包并且这些软件包也需要被安装到服务器 B、服务器 C 上等等。
例如你已经在服务器A 上安装了 15 个软件包并且这些软件包也需要被安装到服务器B服务器C 上等等。
我们可以手动去安装这些软件但是这将花费大量的时间。你可以手动安装一俩个服务器,但是试想如果你有大概十个服务器呢。在这种情况下你无法手动完成工作,那么怎样才能解决问题呢?
我们可以手动去安装这些软件但是这将花费大量的时间。
你可以手动安装一俩个服务器,但是试想如果你有大概十个服务器呢。
在这种情况下你无法手动完成工作,那么怎样才能解决问题呢?
不要担心我们可以帮你摆脱这样的情况和场景。
我们在这篇文章中增加了四种方法来克服困难。
不要担心我们可以帮你摆脱这样的情况和场景。我们在这篇文章中增加了四种方法来克服困难。
我希望这可以帮你解决问题。我已经在 Centos7 和 Ubuntu 18.04 上测试了这些命令。
我也希望这可以在其他发行版上工作。这仅仅需要使用该发行版的官方包管理器命令替代本文中的包管理器命令就行了。
如果想要 **[检查 Linux 系统上已安装的软件包列表][1]** 请点击链接。
如果想要 [检查 Linux 系统上已安装的软件包列表][1],请点击链接。
例如,如果你想要在基于 RHEL 系统上创建软件包列表请使用以下步骤。其他发行版也一样。
@ -53,11 +45,9 @@ apr-util-1.5.2-6.el7.x86_64
apr-1.4.8-3.el7_4.1.x86_64
```
### 方法一 : 如何在 Linux 上使用 cat 命令安装文件中列出的包?
### 方法一如何在 Linux 上使用 cat 命令安装文件中列出的包?
为实现这个目标,我将使用简单明了的第一种方法。
为此,创建一个文件并添加上你想要安装的包列表。
为实现这个目标,我将使用简单明了的第一种方法。为此,创建一个文件并添加上你想要安装的包列表。
出于测试的目的,我们将只添加以下的三个软件包名到文件中。
@ -69,7 +59,7 @@ mariadb-server
nano
```
只要简单的运行 **[apt 命令][2]** 就能在 Ubuntu/Debian 系统上一次性安装所有的软件包。
只要简单的运行 [apt 命令][2] 就能在 Ubuntu/Debian 系统上一次性安装所有的软件包。
```
# apt -y install $(cat /tmp/pack1.txt)
@ -138,20 +128,19 @@ Processing triggers for install-info (6.5.0.dfsg.1-2) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
```
使用 **[yum 命令][3]** 在基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上安装文件中列出的软件包。
使用 [yum 命令][3] 在基于 RHEL (如 Centos、RHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上安装文件中列出的软件包。
```
# yum -y install $(cat /tmp/pack1.txt)
```
使用以命令在基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上卸载文件中列出的软件包。
使用以命令在基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上卸载文件中列出的软件包。
```
# yum -y remove $(cat /tmp/pack1.txt)
```
使用以下 **[dnf 命令][4]** 在 Fedora 系统上安装文件中列出的软件包。
使用以下 [dnf 命令][4] 在 Fedora 系统上安装文件中列出的软件包。
```
# dnf -y install $(cat /tmp/pack1.txt)
@ -163,7 +152,7 @@ Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# dnf -y remove $(cat /tmp/pack1.txt)
```
使用以下 **[zypper 命令][5]** 在 openSUSE 系统上安装文件中列出的软件包。
使用以下 [zypper 命令][5] 在 openSUSE 系统上安装文件中列出的软件包。
```
# zypper -y install $(cat /tmp/pack1.txt)
@ -175,7 +164,7 @@ Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# zypper -y remove $(cat /tmp/pack1.txt)
```
使用以下 **[pacman 命令][6]** 在基于 Arch Linux (如 Manjaro 和 Antergos) 的系统上安装文件中列出的软件包。
使用以下 [pacman 命令][6] 在基于 Arch Linux (如 Manjaro 和 Antergos) 的系统上安装文件中列出的软件包。
```
# pacman -S $(cat /tmp/pack1.txt)
@ -188,36 +177,35 @@ Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# pacman -Rs $(cat /tmp/pack1.txt)
```
### 方法二 : 如何使用 cat 和 xargs 命令在 Linux 中安装文件中列出的软件包。
### 方法二如何使用 cat 和 xargs 命令在 Linux 中安装文件中列出的软件包。
甚至,我更喜欢使用这种方法,因为这是一种非常简单直接的方法。
使用以下 apt 命令在基于 Debian 的系统 (如 DebianUbuntu和Linux Mint) 上安装文件中列出的软件包。
使用以下 `apt` 命令在基于 Debian 的系统 (如 Debian、Ubuntu 和 Linux Mint) 上安装文件中列出的软件包。
```
# cat /tmp/pack1.txt | xargs apt -y install
```
使用以下 apt 命令 从基于 Debian 的系统 (如 DebianUbuntu和Linux Mint) 上卸载文件中列出的软件包。
使用以下 `apt` 命令 从基于 Debian 的系统 (如 Debian、Ubuntu 和 Linux Mint) 上卸载文件中列出的软件包。
```
# cat /tmp/pack1.txt | xargs apt -y remove
```
使用以下 yum 命令在基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上安装文件中列出的软件包。
使用以下 `yum` 命令在基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上安装文件中列出的软件包。
```
# cat /tmp/pack1.txt | xargs yum -y install
```
使用以命令从基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上卸载文件中列出的软件包。
使用以命令从基于 RHEL (如 CentosRHEL (Redhat) 和 OEL (Oracle Enterprise Linux)) 的系统上卸载文件中列出的软件包。
```
# cat /tmp/pack1.txt | xargs yum -y remove
```
使用以下 dnf 命令在 Fedora 系统上安装文件中列出的软件包。
使用以下 `dnf` 命令在 Fedora 系统上安装文件中列出的软件包。
```
# cat /tmp/pack1.txt | xargs dnf -y install
@ -229,7 +217,7 @@ Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# cat /tmp/pack1.txt | xargs dnf -y remove
```
使用以下 zypper 命令在 openSUSE 系统上安装文件中列出的软件包。
使用以下 `zypper` 命令在 openSUSE 系统上安装文件中列出的软件包。
```
@ -242,7 +230,7 @@ Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# cat /tmp/pack1.txt | xargs zypper -y remove
```
使用以下 pacman 命令在基于 Arch Linux (如 Manjaro 和 Antergos) 的系统上安装文件中列出的软件包。
使用以下 `pacman` 命令在基于 Arch Linux (如 Manjaro 和 Antergos) 的系统上安装文件中列出的软件包。
```
# cat /tmp/pack1.txt | xargs pacman -S
@ -254,17 +242,17 @@ Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# cat /tmp/pack1.txt | xargs pacman -Rs
```
### 方法三 : 如何使用 For Loop 在 Linux 上安装文件中列出的软件包?
我们也可以使用 For 循环命令来实现此目的。
### 方法三 : 如何使用 For 循环在 Linux 上安装文件中列出的软件包
安装批量包可以使用以下一条 For 循环的命令。
我们也可以使用 `for` 循环命令来实现此目的。
安装批量包可以使用以下一条 `for` 循环的命令。
```
# for pack in `cat /tmp/pack1.txt` ; do apt -y install $i; done
```
要使用 shell 脚本安装批量包,请使用以下 For 循环。
要使用 shell 脚本安装批量包,请使用以下 `for` 循环。
```
# vi /opt/scripts/bulk-package-install.sh
@ -275,7 +263,7 @@ do apt -y remove $pack
done
```
为 bulk-package-install.sh 设置可执行权限。
`bulk-package-install.sh` 设置可执行权限。
```
# chmod + bulk-package-install.sh
@ -287,17 +275,17 @@ done
# sh bulk-package-install.sh
```
### 方法四 : 如何使用 While 循环在 Linux 上安装文件中列出的软件包
### 方法四如何使用 While 循环在 Linux 上安装文件中列出的软件包
我们也可以使用 While 循环命令来实现目的。
我们也可以使用 `while` 循环命令来实现目的。
安装批量包可以使用以下一条 While 循环的命令。
安装批量包可以使用以下一条 `while` 循环的命令。
```
# file="/tmp/pack1.txt"; while read -r pack; do apt -y install $pack; done < "$file"
```
要使用 shell 脚本安装批量包,请使用以下 While 循环。
要使用 shell 脚本安装批量包,请使用以下 `while` 循环。
```
# vi /opt/scripts/bulk-package-install.sh
@ -309,7 +297,7 @@ do apt -y remove $pack
done < "$file"
```
为 bulk-package-install.sh 设置可执行权限。
`bulk-package-install.sh` 设置可执行权限。
```
# chmod + bulk-package-install.sh
@ -328,13 +316,13 @@ via: https://www.2daygeek.com/how-to-install-uninstall-listed-packages-from-a-fi
作者:[Magesh Maruthamuthu][a]
选题:[lujun9972][b]
译者:[way-ww](https://github.com/way-ww)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.2daygeek.com/author/magesh/
[b]: https://github.com/lujun9972
[1]: https://www.2daygeek.com/check-installed-packages-in-rhel-centos-fedora-debian-ubuntu-opensuse-arch-linux/
[1]: https://linux.cn/article-10116-1.html
[2]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
[3]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
[4]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/

Some files were not shown because too many files have changed in this diff Show More