归档 202110

This commit is contained in:
Xingyu Wang
2021-11-01 08:52:05 +08:00
parent 240e1b6f9c
commit a8a1db90d3
59 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
[#]: collector: (lujun9972)
[#]: translator: (unigeorge)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13891-1.html)
[#]: subject: (How to process real-time data with Apache)
[#]: via: (https://opensource.com/article/20/2/real-time-data-processing)
[#]: author: (Simon Crosby https://opensource.com/users/simon-crosby)
如何使用 Apache 软件处理实时数据
======
> 开源以丰富的项目画布引领着处理实时事件的方向。
![](https://img.linux.net.cn/data/attachment/album/202110/17/105502opl53qrmj950j3mv.jpg)
在“永不下线”的未来,入网设备规模可能会达到数十亿。存储原始数据,日后再进行分析的方案将不再能满足需求,因为用户需要实时且准确的响应。要对故障等对环境敏感的状况进行预测,实时处理数据也必不可少 —— 数据到达数据库后再处理肯定是来不及的。
有人可能会说,“云可扩展性”能够满足实时处理流数据的需求,但一些简单的例子就能表明它永远无法满足对无界数据流进行实时响应的需求。从移动设备到物联网,都需要一种新的范式来满足需求。尽管云计算依赖于对大数据“先存储后分析”的方案,但也迫切需要一种能够处理持续、杂乱和海量数据流的软件框架,并在数据流到达时立即对其进行处理,以保证实时的响应、预测和对数据的洞悉。
例如,在加利福尼亚州的帕洛阿尔托市,每天从基础交通设施产生的流数据比 Twitter Firehose 还要多。这是很大的数据量。为 Uber、Lyft 和 FedEx 等消费者预测城市交通需要实时的分析、学习和预测。云处理不可避免地导致每个事件大约会有半秒的延迟。
我们需要一个简单而强大的编程范式,让应用程序在类似下面的情况时能够动态处理无界数据流:
* 数据量巨大,或原始数据的移动成本很高。
* 数据由广泛分布的资产(例如移动设备)生成。
* 数据具有转瞬即逝的价值,即时分析迫在眉睫。
* 需要始终洞悉最新数据情况,外推法行不通。
### 发布和订阅
事件驱动系统领域中有一个关键架构模式:<ruby>发布/订阅<rt>publish/subscribe</rt></ruby> 消息传递模式。这是一种异步通信方法,其中消息会从 _发布者_(数据产生方)传递到 _订阅者_(处理数据的应用程序)。发布/订阅模式可以将消息发送者与消费者分离开来。
在发布/订阅模式中,消息源会 _发布_ 针对某个 <ruby>主题<rt>topic</rt></ruby> 的 <ruby>事件<rt>event</rt></ruby> 至 <ruby>服务端<rt>broker</rt></ruby>,后者按接收顺序存储它们。应用程序可以 _订阅_ 一个或多个 _主题_,然后 _服务端_ 会转发匹配的事件。 Apache Kafka 和 Pulsar 以及 CNCF NATS 是发布/订阅系统。 发布/订阅的云服务包括 Google Pub/Sub、AWS Kinesis、Azure Service Bus、Confluent Cloud 等。LCTT 译注:本段部分术语英文名称更为泛用,针对这些术语,采用了中英文标注。)
发布/订阅系统不会 _运行_ 订阅者应用程序,它们只是 _传递_ 数据给相应主题的订阅者。
流数据通常包含应用程序或基础架构状态更新的事件。在选择架构来处理数据时,发布/订阅框架等数据分发系统的作用是有限的。消费者应用程序的“处理方式”超出了发布/订阅系统的范围。这让开发人员的管理变得极具复杂性。所谓的流处理器是一种特殊的订阅者,可以动态分析数据并将结果返回给同一个服务端。
### Apache Spark
[Apache Spark][2] 是用于大规模数据处理的统一分析引擎。通常将 Apache Spark Streaming 用作流处理器例如给机器学习模型提供新数据。Spark Streaming 将数据分成小批量,每个小批量都由 Spark 模型或其他系统独立分析。事件流可以被分组成小批量以进行分析,但流处理器本身必须具有弹性:
* 流处理器必须能够根据数据速率进行扩展,甚至要能够跨越服务器和云,并且还可以跨实例实现负载均衡,以确保弹性和其他应用层的需求。
* 它必须能够分析来自不同来源的数据,这些数据源的报告速率可能相差很大。这意味着它必须是有状态的,或者将状态存储在数据库中。当使用 Spark Streaming 作为流处理器时,通常会使用后一种方法,这种方法在需要超低延迟响应时可能会存在性能问题。
相关项目 [Apache Samza][3] 也提供了一种处理实时事件流的方法,并使用 [Hadoop Yarn][4] 或 [Apache Mesos][5] 来管理计算资源,以便进行弹性扩展。
### 解决数据扩展问题
需要注意的是,即使是 Samza 也不能完全减轻开发人员的数据处理需求。扩展数据规模意味着处理事件的任务需要跨多个实例进行负载均衡,而使用数据库是实例间共享结果应用层状态的唯一方法。然而,当应用程序任务之间的状态协调转移到数据库时,对性能会产生不可避免的连锁反应。此外,数据库的选择也至关重要。随着系统的扩展,数据库的集群管理会成为下一个潜在的瓶颈。
这个问题可以通过有状态、有弹性的替代方案来解决并且这样的解决方案可以用来代替流处理器。在应用程序级别容器或实例内这些解决方案依据流的更新动态构建并发、互连的“web 代理”的有状态模型。代理是并发的“微服务”,它们消费单一来源的原始数据并维护它们的状态。基于数据中发现的源之间的真实关系(如包含和临近),代理实现互连以共享状态。代理也因此形成了一个并发服务图,可以分析它们自己的状态和链接到的代理的状态。数据源将原始数据转换为状态,并根据自身及其链接子图的变化进行分析、学习和预测,每个代理都为单个这样的数据源提供微服务。
这些解决方案允许大量的代理(真实数据源的数字类比)分布,甚至还有在应用层使代理互连的分布式图,从而简化了应用架构。这是因为代理之间互连的本质,是映射到解决方案的当前运行时执行实例和代理本身的 URL。通过这种方式应用程序可以跨实例无缝扩展而无需担心 DevOps 问题。代理消费数据并维护状态,还会计算自己和其他代理的状态。由于代理是有状态的,因此不需要数据库,并且数据洞察是以内存速度计算的。
### 使用开源阅读数据世界
我们查看数据的方式正在发生翻天覆地的变化:不再将数据库用作记录系统,取而代之的是现实世界,现实世界事物的数字类比可以不断地传输它们的状态。幸运的是,开源社区在处理实时事件的项目丰富度方面处于领先地位。从发布/订阅模式(其中最活跃的社区是 Apache Kafka、Pulsar 和 CNCF NATS到持续处理流数据的分析框架包括 Apache Spark、[Flink][6]、[Beam][7]、Samza以及 Apache 许可的 [SwimOS][8] 和 [Hazelcast][9],对开发人员来说,可选择项目非常之多。可以说,没有什么地方比开源社区的专有软件框架更多了。试看软件的未来,必是开源的天下。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/2/real-time-data-processing
作者:[Simon Crosby][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/simon-crosby
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/clocks_time.png?itok=_ID09GDk (Alarm clocks with different time)
[2]: https://spark.apache.org/
[3]: https://samza.apache.org/
[4]: https://hadoop.apache.org/
[5]: http://mesos.apache.org/
[6]: https://flink.apache.org/
[7]: https://beam.apache.org
[8]: https://github.com/swimos/swim
[9]: https://hazelcast.com/

View File

@@ -0,0 +1,141 @@
[#]: collector: (lujun9972)
[#]: translator: (unigeorge)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13908-1.html)
[#]: subject: (Define and optimize data partitions in Apache Cassandra)
[#]: via: (https://opensource.com/article/20/5/apache-cassandra)
[#]: author: (Anil Inamdar https://opensource.com/users/anil-inamdar)
在 Apache Cassandra 中定义和优化数据分区
======
> 速度和可扩展性是 Apache Cassandra 不变的追求;来学习一下如何充分发挥它的专长吧。
![](https://img.linux.net.cn/data/attachment/album/202110/22/103651gse3iyiajyaagk34.jpg)
Apache Cassandra 是一个数据库但又不是一个简单的数据库它是一个复制数据库专为可扩展性、高可用性、低延迟和良好性能而设计调整。Cassandra 可以帮你的数据在区域性中断、硬件故障时,以及很多管理员认为数据量过多的情况下幸免于难。
全面掌握数据分区知识,你就能让 Cassandra 集群实现良好的设计、极高的性能和可扩展性。在本文中我将探究如何定义分区Cassandra 如何使用这些分区,以及一些你应该了解的最佳实践方案和已知问题。
基本概念是这样的: 供数据库关键函数(如数据分发、复制和索引化)使用的原子单元,单个这样的数据块就是一个分区。分布式数据系统通常会把传入的数据分配到这些分区中,使用简单的数学函数(例如 identity 或 hashing 函数)执行分区过程,并用得到的 “分区键” 对数据分组,进一步再形成分区。例如,假设传入数据是服务器日志,使用 “identity” 分区函数和每个日志的时间戳(四舍五入到小时值)作为分区键,我们可以对这些数据进行分区,实现每个分区各保存一小时的日志的目的。
### Cassandra 中的数据分区
Cassandra 作为分布式系统运行,并且符合前述数据分区原则。使用 Cassandra数据分区依赖于在集群级别配置的算法和在表级别配置的分区键。
![Cassandra data partition][2]
Cassandra 查询语言CQL使用大家很熟悉的 SQL 表、行、列等术语。在上面的示例图中,表配置的主键中包含了分区键,具体格式为:<ruby>主键<rt>Primary Key</rt></ruby> = <ruby>分区键<rt>Partition Key</rt></ruby> + [<ruby>聚簇列<rt>Clustering Columns</rt></ruby>] 。
Cassandra 中的主键既定义了唯一的数据分区,也包含着分区内的数据排列依据信息。数据排列信息取决于聚簇列(非必需项)。每个唯一的分区键代表着服务器(包括其副本所在的服务器)中管理的若干行。
### 在 CQL 中定义主键
接下来的四个示例演示了如何使用 CQL 语法表示主键。定义主键会让数据行分到不同的集合里,通常这些集合就是分区。
#### 定义方式 1分区键log_hour聚簇列
```
CREATE TABLE server_logs(
   log_hour TIMESTAMP PRIMARYKEY,
   log_level text,
   message text,
   server text
   )
```
这里,有相同 `log_hour` 的所有行都会进入同一个分区。
#### 定义方式 2分区键log_hour聚簇列log_level
```
CREATE TABLE server_logs(
   log_hour TIMESTAMP,
   log_level text,
   message text,
   server text,
   PRIMARY KEY (log_hour, log_level)
   )
```
此定义方式与方式 1 使用了相同的分区键,但此方式中,每个分区的所有行都会按 `log_level` 升序排列。
#### 定义方式 3分区键log_hourserver聚簇列
```
CREATE TABLE server_logs(
   log_hour TIMESTAMP,
   log_level text,
   message text,
   server text,
   PRIMARY KEY ((log_hour, server))
   )
```
在此定义中,`server``log_hour` 字段都相同的行才会进入同一个分区。
#### 定义方式 4分区键log_hourserver聚簇列log_level
```
CREATE TABLE server_logs(
   log_hour TIMESTAMP,
   log_level text,
   message text,
   server text,
   PRIMARY KEY ((log_hour, server),log_level)
   )WITH CLUSTERING ORDER BY (column3 DESC);
```
此定义方式与方式 3 分区相同,但分区内的行会依照 `log_level` 降序排列。
### Cassandra 如何使用分区键
Cassandra 依靠分区键来确定在哪个节点上存储数据以及在需要时定位数据。Cassandra 通过查看表中的分区键来执行这些读取和写入操作,并使用<ruby>令牌<rt>tokens</rt></ruby>(一个 $-2^{63}$ 到 $+2^{63}-1$ 范围内的 long 类型值来进行数据分布和索引。这些令牌通过分区器映射到分区键分区器使用了将分区键转换为令牌的分区函数。通过这种令牌机制Cassandra 集群的每个节点都拥有一组数据分区。然后分区键在每个节点上启用数据索引。
![Cassandra cluster with 3 nodes and token-based ownership][3]
图中显示了一个三节点的 Cassandra 集群以及相应的令牌范围分配。这只是一个简单的示意图:具体实现过程使用了 [Vnodes][4]。
### 数据分区对 Cassandra 集群的影响
用心的分区键设计对于实现用例的理想分区大小至关重要。合理的分区可以实现均匀的数据分布和强大的 I/O 性能。分区大小对 Cassandra 集群有若干需要注意的影响:
* 读取性能 —— 为了在磁盘上的 SSTables 文件中找到分区Cassandra 使用缓存、索引和索引摘要等数据结构。过大的分区会降低这些数据结构的维护效率从而对性能产生负面影响。Cassandra 新版本在这方面取得了长足的进步:特别是 3.6 及其以上版本的 Cassandra 引擎引入了存储改进,针对大型分区,可以提供更好的性能,以及更强的应对内存问题和崩溃的弹性。
* 内存使用 —— 大分区会对 JVM 堆产生更大的压力,同时分区的增大也降低了垃圾收集机制的效率。
* Cassandra 修复 —— 大分区使 Cassandra 执行修复维护操作(通过跨副本比较数据来保持数据一致)时更加困难。
* “墓碑”删除 —— 听起来可能有点骇人Cassandra 使用称为“<ruby>墓碑<rt>tombstones</rt></ruby>”的独特标记来记录要删除的数据。如果没有合适的数据删除模式和压缩策略,大分区会使删除过程变得更加困难。
虽然这些影响可能会让人更倾向于简单地设计能产生小分区的分区键,但数据访问模式对理想的分区大小也有很大影响(有关更多信息,请阅读关于 [Cassandra 数据建模][5] 的深入讲解)。数据访问模式可以定义为表的查询方式,包括表的所有 `select` 查询。 理想情况下CQL 选择查询应该在 `where` 子句中只使用一个分区键。也就是说当查询可以从单个分区而不是许多较小的分区获取所需数据时Cassandra 是最有效率的。
### 分区键设计的最佳实践
遵循分区键设计的最佳实践原则这会帮你得到理想的分区大小。根据经验Cassandra 中的最大分区应保持在 100MB 以下。理想情况下,它应该小于 10MB。虽然 Cassandra 3.6 及其以上版本能更好地支持大分区,但也必须对每个工作负载进行仔细的测试和基准测试,以确保分区键设计能够支持所需的集群性能。
具体来说,这些最佳实践原则适用于任何分区键设计:
* 分区键的目标必须是将理想数量的数据放入每个分区,以支持其访问模式的需求。
* 分区键应禁止无界分区:那些大小可能随着时间无限增长的分区。例如,在上面的 `server_logs` 示例中,随着服务器日志数量的不断增加,使用服务器列作为分区键就会产生无界分区。相比之下,使用 `log_hour` 将每个分区限制为一个小时数据的方案会更好。
* 分区键还应避免产生分区倾斜,即分区增长不均匀,有些分区可能随着时间的推移而不受限制地增长。在 `server_logs` 示例中,在一台服务器生成的日志远多于其他服务器的情况下使用服务器列会产生分区倾斜。为了避免这种情况,可以从表中引入另一个属性来强制均匀分布,即使要创建一个虚拟列来这样做,也是值得的。
* 使用时间元素和其他属性的组合分区键,这对时间序列数据分区很有帮助。这种方式可以防止无界分区,使访问模式能够在查询特定数据时使用时间属性,而且能够对特定时间段内的数据进行删除。上面的每个示例都使用了 `log_hour` 时间属性来演示这一点。
还有一些工具可用于帮助测试、分析和监控 Cassandra 分区,以检查所选模式是否高效。通过仔细设计分区键,使解决方案的数据和需求保持一致,并遵循最佳实践原则来优化分区大小,你就可以充分利用数据分区,更好地发挥 Cassandra 的可扩展性和性能潜力。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/5/apache-cassandra
作者:[Anil Inamdar][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/anil-inamdar
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_metrics_analytics_desktop_laptop.png?itok=9QXd7AUr (Person standing in front of a giant computer screen with numbers, data)
[2]: https://opensource.com/sites/default/files/uploads/apache_cassandra_1_0.png (Cassandra data partition)
[3]: https://opensource.com/sites/default/files/uploads/apache_cassandra_2_0.png (Cassandra cluster with 3 nodes and token-based ownership)
[4]: https://www.instaclustr.com/cassandra-vnodes-how-many-should-i-use/
[5]: https://www.instaclustr.com/resource/6-step-guide-to-apache-cassandra-data-modelling-white-paper/

View File

@@ -0,0 +1,363 @@
[#]: collector: (lujun9972)
[#]: translator: (YungeG)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13881-1.html)
[#]: subject: (Managing resources with cgroups in systemd)
[#]: via: (https://opensource.com/article/20/10/cgroups)
[#]: author: (David Both https://opensource.com/users/dboth)
在 systemd 中使用控制组管理资源
======
> 控制组可以按照应用管理资源,而不是按照组成应用的单个进程。
![](https://img.linux.net.cn/data/attachment/album/202110/14/114622by5jdu87u4vng272.jpg)
作为一个系统管理员,没有事情比意外地耗尽计算资源让我更觉得沮丧。我曾不止一次填满了一个分区的所有可用磁盘空间、耗尽内存、以及没有足够的 CPU 时间在合理的时间内处理我的任务。资源管理是系统管理员最重要的工作之一。
资源管理的关键是保证所有的进程能够相对公平的访问需要的系统资源。资源管理还包括确保在需要时添加内存、硬盘驱动器空间、还有 CPU 处理能力;或者在无法添加时限制资源的使用。此外,应该阻止独占系统资源的用户,无论其是否有意。
系统管理员可以通过一些工具监控和管理不同的系统资源。例如,[top][2] 和类似的工具允许你监控内存、I/O、存储磁盘、SSD 等、网络、交换空间、CPU 的用量等。这些工具,尤其是那些以 CPU 为中心的工具,大部分基于以运行的进程为基本单位进行控制的模型。它们最多只是提供了一种方式来调整 `nice` 数字,从而修改优先级,或者杀死一个运行的进程。(要了解 `nice` 数字的信息,查看 [使用 Glances 监控 Linux 和 Windows 主机][3])。
SystemV 环境中基于传统的资源管理的其他工具,由 `/etc/security/limits.conf` 文件和 `/etc/security/limits.d` 中的本地配置文件控制。资源可以按照用户或组以一种相对粗糙但实用的方式限制。可以管理的资源包括内存的各个方面、每日的总 CPU 时间、数据总量、优先级、`nice` 数字、并发登录的数量、进程数、文件大小的最大值等。
### 使用控制组管理进程
[systemd 和 SystemV][4] 之间的一个主要差异是管理进程的方式。SystemV 将每个进程视作一个独立的实体。systemd 将相关的进程集中到一个控制组,简写做 [cgroup][5],并将控制组作为一个整体管理系统资源。这意味着资源能够基于应用管理,而不是由组成应用的各个进程来管理。
控制组的控制单元称作<ruby>切片单元<rt>slice unit</rt></ruby>。切片是允许 systemd 以树状格式控制程序次序,从而简化管理的概念化。
### 查看控制组
我将从一些允许你查看不同类型控制组信息的命令开始。 `systemctl status <service>` 命令显示一个特定服务的切片信息,包括服务的切片。这个例子展示了 `at` 守护进程:
```
[root@testvm1 ~]# systemctl status atd.service
● atd.service - Deferred execution scheduler
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-09-23 12:18:24 EDT; 1 day 3h ago
Docs: man:atd(8)
Main PID: 1010 (atd)
Tasks: 1 (limit: 14760)
Memory: 440.0K
CPU: 5ms
CGroup: /system.slice/atd.service
└─1010 /usr/sbin/atd -f
Sep 23 12:18:24 testvm1.both.org systemd[1]: Started Deferred execution scheduler.
[root@testvm1 ~]#
```
这是一个我感到 systemd 比 SystemV 和旧的初始化程序更好用的原因的绝佳示例。这里的信息远比 SystemV 能够提供的丰富。`CGroup` 项包括的层级结构中,`system.slice` 是 systemdPID 1`atd.service` 在下一层,是 `system.slice` 的一部分。`CGroup` 项的第二行还显示了进程 IDPID和启动守护进程使用的命令。
`systemctl` 命令可以列出多个控制组项,`--all` 参数列出所有的切片,包括当前没有激活的切片:
```
[root@testvm1 ~]# systemctl -t slice --all
UNIT LOAD ACTIVE SUB DESCRIPTION
-.slice loaded active active Root Slice
system-getty.slice loaded active active system-getty.slice
system-lvm2\x2dpvscan.slice loaded active active system-lvm2\x2dpvscan.slice
system-modprobe.slice loaded active active system-modprobe.slice
system-sshd\x2dkeygen.slice loaded active active system-sshd\x2dkeygen.slice
system-systemd\x2dcoredump.slice loaded inactive dead system-systemd\x2dcoredump.slice
system-systemd\x2dfsck.slice loaded active active system-systemd\x2dfsck.slice
system.slice loaded active active System Slice
user-0.slice loaded active active User Slice of UID 0
user-1000.slice loaded active active User Slice of UID 1000
user.slice loaded active active User and Session Slice
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
11 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
[root@testvm1 ~]#
```
关于这个数据,第一个需要注意的是数据显示了 UID 0root和 UID 1000 的用户切片UID 1000 是我登录的用户。这里列出了组成每个切片的切片部分,而不是服务。还说明了每个用户登录时都会为其创建一个切片,这为将一个用户的所有任务作为单个控制组项进行管理提供了一种方式。
### 探索控制组的层次结构
目前为止一切顺利,但是控制组是分层的,所有的服务单元作为其中一个控制组的成员运行。要查看这个层次结构很简单,使用一个旧命令和 systemd 的一个新命令即可。
`ps` 命令可以用于映射进程的和其所处的控制组层次。注意使用 `ps` 命令时需要指明想要的数据列。我大幅削减了下面命令的输出数量,但是试图保留足够的数据,以便你能够对自己系统上的输出有所感受:
```
[root@testvm1 ~]# ps xawf -eo pid,user,cgroup,args
PID USER CGROUP COMMAND
2 root - [kthreadd]
3 root - \_ [rcu_gp]
4 root - \_ [rcu_par_gp]
6 root - \_ [kworker/0:0H-kblockd]
9 root - \_ [mm_percpu_wq]
10 root - \_ [ksoftirqd/0]
11 root - \_ [rcu_sched]
12 root - \_ [migration/0]
13 root - \_ [cpuhp/0]
14 root - \_ [cpuhp/1]
<删节>
625406 root - \_ [kworker/3:0-ata_sff]
625409 root - \_ [kworker/u8:0-events_unbound]
1 root 0::/init.scope /usr/lib/systemd/systemd --switched-root --system --deserialize 30
588 root 0::/system.slice/systemd-jo /usr/lib/systemd/systemd-journald
599 root 0::/system.slice/systemd-ud /usr/lib/systemd/systemd-udevd
741 root 0::/system.slice/auditd.ser /sbin/auditd
743 root 0::/system.slice/auditd.ser \_ /usr/sbin/sedispatch
764 root 0::/system.slice/ModemManag /usr/sbin/ModemManager
765 root 0::/system.slice/NetworkMan /usr/sbin/NetworkManager --no-daemon
767 root 0::/system.slice/irqbalance /usr/sbin/irqbalance --foreground
779 root 0::/system.slice/mcelog.ser /usr/sbin/mcelog --ignorenodev --daemon --foreground
781 root 0::/system.slice/rngd.servi /sbin/rngd -f
782 root 0::/system.slice/rsyslog.se /usr/sbin/rsyslogd -n
<删节>
893 root 0::/system.slice/sshd.servi sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
1130 root 0::/user.slice/user-0.slice \_ sshd: root [priv]
1147 root 0::/user.slice/user-0.slice | \_ sshd: root@pts/0
1148 root 0::/user.slice/user-0.slice | \_ -bash
1321 root 0::/user.slice/user-0.slice | \_ screen
1322 root 0::/user.slice/user-0.slice | \_ SCREEN
1323 root 0::/user.slice/user-0.slice | \_ /bin/bash
498801 root 0::/user.slice/user-0.slice | | \_ man systemd.resource-control
498813 root 0::/user.slice/user-0.slice | | \_ less
1351 root 0::/user.slice/user-0.slice | \_ /bin/bash
123293 root 0::/user.slice/user-0.slice | | \_ man systemd.slice
123305 root 0::/user.slice/user-0.slice | | \_ less
1380 root 0::/user.slice/user-0.slice | \_ /bin/bash
625412 root 0::/user.slice/user-0.slice | | \_ ps xawf -eo pid,user,cgroup,args
625413 root 0::/user.slice/user-0.slice | | \_ less
246795 root 0::/user.slice/user-0.slice | \_ /bin/bash
625338 root 0::/user.slice/user-0.slice | \_ /usr/bin/mc -P /var/tmp/mc-root/mc.pwd.246795
625340 root 0::/user.slice/user-0.slice | \_ bash -rcfile .bashrc
1218 root 0::/user.slice/user-1000.sl \_ sshd: dboth [priv]
1233 dboth 0::/user.slice/user-1000.sl \_ sshd: dboth@pts/1
1235 dboth 0::/user.slice/user-1000.sl \_ -bash
<删节>
1010 root 0::/system.slice/atd.servic /usr/sbin/atd -f
1011 root 0::/system.slice/crond.serv /usr/sbin/crond -n
1098 root 0::/system.slice/lxdm.servi /usr/sbin/lxdm-binary
1106 root 0::/system.slice/lxdm.servi \_ /usr/libexec/Xorg -background none :0 vt01 -nolisten tcp -novtswitch -auth /var/run/lxdm/lxdm-:0.auth
370621 root 0::/user.slice/user-1000.sl \_ /usr/libexec/lxdm-session
370631 dboth 0::/user.slice/user-1000.sl \_ xfce4-session
370841 dboth 0::/user.slice/user-1000.sl \_ /usr/bin/ssh-agent /bin/sh -c exec -l bash -c "/usr/bin/startxfce4"
370911 dboth 0::/user.slice/user-1000.sl \_ xfwm4 --display :0.0 --sm-client-id 2dead44ab-0b4d-4101-bca4-e6771f4a8ac2
370930 dboth 0::/user.slice/user-1000.sl \_ xfce4-panel --display :0.0 --sm-client-id 2ce38b8ef-86fd-4189-ace5-deec1d0e0952
370942 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libsystray.so 6 23068680 systr
ay Notification Area Area where notification icons appear
370943 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libpulseaudio-plugin.so 8 2306
8681 pulseaudio PulseAudio Plugin Adjust the audio volume of the PulseAudio sound system
370944 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libxfce4powermanager.so 9 2306
8682 power-manager-plugin Power Manager Plugin Display the battery levels of your devices and control the brightness of your display
370945 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libnotification-plugin.so 10 2
3068683 notification-plugin Notification Plugin Notification plugin for the Xfce panel
370948 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libactions.so 14 23068684 acti
ons Action Buttons Log out, lock or other system actions
370934 dboth 0::/user.slice/user-1000.sl \_ Thunar --sm-client-id 2cfc809d8-4e1d-497a-a5c5-6e4fa509c3fb --daemon
370939 dboth 0::/user.slice/user-1000.sl \_ xfdesktop --display :0.0 --sm-client-id 299be0608-4dca-4055-b4d6-55ec6e73a324
370962 dboth 0::/user.slice/user-1000.sl \_ nm-applet
<删节>
```
你可以使用 `systemd-cgls` 命令查看整个层次结构,这个命令不需要任何的复杂参数,更加简单。
我也大幅缩短了这个树状结构,但是保留了足够多的输出,以便你能够了解在自己的系统上执行这个命令时应该看到的数据总量和条目类型。我在我的一个虚拟机上执行了这个命令,输出大概有 200 行;我的主要工作站的输出大概有 250 行。
```
[root@testvm1 ~]# systemd-cgls
Control group /:
-.slice
├─user.slice
│ ├─user-0.slice
│ │ ├─session-1.scope
│ │ │ ├─ 1130 sshd: root [priv]
│ │ │ ├─ 1147 sshd: root@pts/0
│ │ │ ├─ 1148 -bash
│ │ │ ├─ 1321 screen
│ │ │ ├─ 1322 SCREEN
│ │ │ ├─ 1323 /bin/bash
│ │ │ ├─ 1351 /bin/bash
│ │ │ ├─ 1380 /bin/bash
│ │ │ ├─123293 man systemd.slice
│ │ │ ├─123305 less
│ │ │ ├─246795 /bin/bash
│ │ │ ├─371371 man systemd-cgls
│ │ │ ├─371383 less
│ │ │ ├─371469 systemd-cgls
│ │ │ └─371470 less
│ │ └─user@0.service …
│ │ ├─dbus-broker.service
│ │ │ ├─1170 /usr/bin/dbus-broker-launch --scope user
│ │ │ └─1171 dbus-broker --log 4 --controller 12 --machine-id 3bccd1140fca488187f8a1439c832f07 --max-bytes 100000000000000 --max-fds 25000000000000 --max->
│ │ ├─gvfs-daemon.service
│ │ │ └─1173 /usr/libexec/gvfsd
│ │ └─init.scope
│ │ ├─1137 /usr/lib/systemd/systemd --user
│ │ └─1138 (sd-pam)
│ └─user-1000.slice
│ ├─user@1000.service …
│ │ ├─dbus\x2d:1.2\x2dorg.xfce.Xfconf.slice
│ │ │ └─dbus-:1.2-org.xfce.Xfconf@0.service
│ │ │ └─370748 /usr/lib64/xfce4/xfconf/xfconfd
│ │ ├─dbus\x2d:1.2\x2dca.desrt.dconf.slice
│ │ │ └─dbus-:1.2-ca.desrt.dconf@0.service
│ │ │ └─371262 /usr/libexec/dconf-service
│ │ ├─dbus-broker.service
│ │ │ ├─1260 /usr/bin/dbus-broker-launch --scope user
│ │ │ └─1261 dbus-broker --log 4 --controller 11 --machine-id
<删节>
│ │ └─gvfs-mtp-volume-monitor.service
│ │ └─370987 /usr/libexec/gvfs-mtp-volume-monitor
│ ├─session-3.scope
│ │ ├─1218 sshd: dboth [priv]
│ │ ├─1233 sshd: dboth@pts/1
│ │ └─1235 -bash
│ └─session-7.scope
│ ├─370621 /usr/libexec/lxdm-session
│ ├─370631 xfce4-session
│ ├─370805 /usr/bin/VBoxClient --clipboard
│ ├─370806 /usr/bin/VBoxClient --clipboard
│ ├─370817 /usr/bin/VBoxClient --seamless
│ ├─370818 /usr/bin/VBoxClient --seamless
│ ├─370824 /usr/bin/VBoxClient --draganddrop
│ ├─370825 /usr/bin/VBoxClient --draganddrop
│ ├─370841 /usr/bin/ssh-agent /bin/sh -c exec -l bash -c "/usr/bin/startxfce4"
│ ├─370910 /bin/gpg-agent --sh --daemon --write-env-file /home/dboth/.cache/gpg-agent-info
│ ├─370911 xfwm4 --display :0.0 --sm-client-id 2dead44ab-0b4d-4101-bca4-e6771f4a8ac2
│ ├─370923 xfsettingsd --display :0.0 --sm-client-id 261b4a437-3029-461c-9551-68c2c42f4fef
│ ├─370930 xfce4-panel --display :0.0 --sm-client-id 2ce38b8ef-86fd-4189-ace5-deec1d0e0952
│ ├─370934 Thunar --sm-client-id 2cfc809d8-4e1d-497a-a5c5-6e4fa509c3fb --daemon
│ ├─370939 xfdesktop --display :0.0 --sm-client-id 299be0608-4dca-4055-b4d6-55ec6e73a324
<删节>
└─system.slice
├─rngd.service
│ └─1650 /sbin/rngd -f
├─irqbalance.service
│ └─1631 /usr/sbin/irqbalance --foreground
├─fprintd.service
│ └─303383 /usr/libexec/fprintd
├─systemd-udevd.service
│ └─956 /usr/lib/systemd/systemd-udevd
<删节>
├─systemd-journald.service
│ └─588 /usr/lib/systemd/systemd-journald
├─atd.service
│ └─1010 /usr/sbin/atd -f
├─system-dbus\x2d:1.10\x2dorg.freedesktop.problems.slice
│ └─dbus-:1.10-org.freedesktop.problems@0.service
│ └─371197 /usr/sbin/abrt-dbus -t133
├─sshd.service
│ └─893 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
├─vboxservice.service
│ └─802 /usr/sbin/VBoxService -f
├─crond.service
│ └─1011 /usr/sbin/crond -n
├─NetworkManager.service
│ └─765 /usr/sbin/NetworkManager --no-daemon
├─switcheroo-control.service
│ └─787 /usr/libexec/switcheroo-control
<删节>
```
这个树状视图显示了所有的用户和系统切片,以及每个控制组内正在运行的服务和程序。注意叫作 `scope`(范围)的单元,它将相关的程序组成一个管理单元,在上面列出的结果中就是 `user-1000.slice``user-1000.slice/session-7.scope` 控制组包含了 GUI 桌面程序层次结构,以 LXDM 显示管理器会话和其所有的子任务开始,包括像 Bash 命令行解释器和 Thunar GUI 文件管理器之类的程序。
配置文件中不定义范围单元,而是作为启动相关程序组的结果程序化生成的。范围单元不创建或启动作为控制组的组成部分运行的进程。范围内的所有进程都是平等的,没有内部的层次结构。一个范围的生命周期在第一个进程创建时开始,在最后一个进程销毁时结束。
在你的桌面打开多个窗口比如终端模拟器、LibreOffice、或者任何你想打开的然后切换到一个可用的虚拟控制台启动类似 `top` 或 [Midnight Commander][11] 的程序。在主机运行 `systemd-cgls` 命令,留意整体的层次结构和范围单元。
`systemd-cgls` 命令提供的控制组层次结构表示(以及组成控制组单元的细节),比我见过的其他任何指令都要完整。和 `ps` 命令提供的输出相比,我喜欢 `systemd-cgls` 命令更简洁的树形表示。
### 来自朋友们的一点帮助
介绍完这些基础知识后,我曾计划过深入研究控制组的更多细节,以及如何使用,但是我在 Opensource.com 的姐妹网站 [Enable Sysadmin][13] 上发现了一系列四篇优秀文章,由 Red Hat 公司的 [Steve Ovens][12] 所作。与其从头重写 Steve 的文章,我觉得倒不如通过链接到这些文章,利用他的控制组专业知识:
1. [一个 Linux 系统管理员对控制组的介绍][14]
2. [如何用 CPUShares 管理控制组][15]
3. [用更难的方式,手动管理控制组][16]
4. [用 systemd 管理控制组][17]
像我一样享受这些文章并从中汲取知识吧。
### 其他资源
互联网上充斥着大量关于 systemd 的信息,但大部分都简短生硬、愚钝、甚至令人误解。除了本文提到的资源,下面的网页提供了关于 systemd 启动更详细可靠的信息。自从我开始这一系列的文章来反映我所做的研究以来,这个的列表已经变长了。
* Fedora 项目有一个优质实用的 [systemd 指南][18],几乎有你使用 systemd 配置、管理、维护一个 Fedora 计算机需要知道的一切。
* Fedora 项目还有一个好用的 [速查表][19],交叉引用了古老的 SystemV 命令和对应的 systemd 命令。
* [systemd.unit(5) 手册页][20] 包含了一个不错的单元文件中各个节的列表,以及这些节的配置选项和简洁的描述。
* Red Hat 文档包含了一个 [单元文件结构][21] 的有用描述,还有一些其他的重要信息。
* 要获取 systemd 的详细技术信息和创立的原因,查看 Freedesktop.org 的 [systemd 描
述][22]。这个使我发现过的最棒页面之一,因为其中包含了许多指向其他重要准确文档的链接。
* Linux.com 上 “systemd 的更多乐趣” 提供了更高级的 systemd [信息和提示][23]。
* 查看 [systemd.resource-control(5)][24] 的手册页
* 查看 [_Linux 内核用户和管理员指南_][25] 中的 [控制组 v2 条目][26]。
还有一系列针对系统管理员的深度技术文章,由 systemd 的设计者和主要开发者 Lennart
Poettering 所作。这些文章写于 2010 年 4 月到 2011 年 9 月之间,但在当下仍然像当时一样有
价值。关于 systemd 及其生态的许多其他优秀的作品都是基于这些文章的。
* [Rethinking PID 1][27]
* [systemd for Administrators, Part I][28]
* [systemd for Administrators, Part II][29]
* [systemd for Administrators, Part III][30]
* [systemd for Administrators, Part IV][31]
* [systemd for Administrators, Part V][32]
* [systemd for Administrators, Part VI][33]
* [systemd for Administrators, Part VII][34]
* [systemd for Administrators, Part VIII][35]
* [systemd for Administrators, Part IX][36]
* [systemd for Administrators, Part X][37]
* [systemd for Administrators, Part XI][38]
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/10/cgroups
作者:[David Both][a]
选题:[lujun9972][b]
译者:[YungeG](https://github.com/YungeG)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/dboth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
[2]: https://en.wikipedia.org/wiki/Top_(software)
[3]: https://opensource.com/article/19/11/monitoring-linux-glances
[4]: https://opensource.com/article/20/4/systemd
[5]: https://en.wikipedia.org/wiki/Cgroups
[6]: mailto:user@0.service
[7]: mailto:user@1000.service
[8]: mailto:1.2-org.xfce.Xfconf@0.service
[9]: mailto:1.2-ca.desrt.dconf@0.service
[10]: mailto:1.10-org.freedesktop.problems@0.service
[11]: https://midnight-commander.org/
[12]: https://www.redhat.com/sysadmin/users/steve-ovens
[13]: https://www.redhat.com/sysadmin/
[14]: https://www.redhat.com/sysadmin/cgroups-part-one
[15]: https://www.redhat.com/sysadmin/cgroups-part-two
[16]: https://www.redhat.com/sysadmin/cgroups-part-three
[17]: https://www.redhat.com/sysadmin/cgroups-part-four
[18]: https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html
[19]: https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet
[20]: https://man7.org/linux/man-pages/man5/systemd.unit.5.html
[21]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-services-with-systemd_configuring-basic-system-settings#Managing_Services_with_systemd-Unit_File_Structure
[22]: https://www.freedesktop.org/wiki/Software/systemd/
[23]: https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/
[24]: https://man7.org/linux/man-pages/man5/systemd.resource-control.5.html
[25]: https://www.kernel.org/doc/html/latest/admin-guide/index.html
[26]: https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
[27]: http://0pointer.de/blog/projects/systemd.html
[28]: http://0pointer.de/blog/projects/systemd-for-admins-1.html
[29]: http://0pointer.de/blog/projects/systemd-for-admins-2.html
[30]: http://0pointer.de/blog/projects/systemd-for-admins-3.html
[31]: http://0pointer.de/blog/projects/systemd-for-admins-4.html
[32]: http://0pointer.de/blog/projects/three-levels-of-off.html
[33]: http://0pointer.de/blog/projects/changing-roots
[34]: http://0pointer.de/blog/projects/blame-game.html
[35]: http://0pointer.de/blog/projects/the-new-configuration-files.html
[36]: http://0pointer.de/blog/projects/on-etc-sysinit.html
[37]: http://0pointer.de/blog/projects/instances.html
[38]: http://0pointer.de/blog/projects/inetd.html

View File

@@ -0,0 +1,130 @@
[#]: collector: (lujun9972)
[#]: translator: (unigeorge)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13849-1.html)
[#]: subject: (Learn Fortran by writing a "guess the number" game)
[#]: via: (https://opensource.com/article/21/1/fortran)
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
通过写“猜数字”游戏学习 Fortran
======
> Fortran 是在打孔卡时代编写的语言,因此它的语法非常有限。但你仍然可以用它编写有用和有趣的程序。
![](https://img.linux.net.cn/data/attachment/album/202110/04/125311k6uwzpybabayyoag.jpg)
Fortran 77 是我学习的第一门编译型编程语言。一开始时,我自学了如何在 Apple II 上用 BASIC 编写程序,后来又学会在 DOS 上用 QBasic 编写程序。但是当我去大学攻读物理学时,我又学习了 [Fortran][2]。
Fortran 曾经在科学计算中很常见。曾几何时,所有计算机系统都有一个 Fortran 编译器。Fortran 曾经像今天的 Python 一样无处不在。因此,如果你是像我这样的物理学专业学生,在 1990 年代工作,那你肯定学习了 Fortran。
我一直认为 Fortran 与 BASIC 有点相似,所以每当我需要编写一个简短程序,来分析实验室数据或执行其他一些数值分析时,我都会很快想到 Fortran。我在空闲时用 Fortran 编写了一个“猜数字”游戏,其中计算机会在 1 到 100 之间选择一个数字,并让我猜这个数字。程序会一直循环,直到我猜对了为止。
“猜数字”程序练习了编程语言中的几个概念:如何为变量赋值、如何编写语句以及如何执行条件判断和循环。这是学习新编程语言时一个很好的的实践案例。
### Fortran 编程基础
虽然 Fortran 这些年来一直在更新,但我最熟悉的还是 Fortran 77这是我多年前学习的实现版本。Fortran 是程序员还在打孔卡上编程的年代创建的,因此“经典” Fortran 仅限于处理可以放在打孔卡上的数据。这意味着你只能编写符合以下限制条件的经典 Fortran 程序LCTT 译注:后来的 Fortran 95 等版本已经对这些限制做了很大的改进,如有兴趣**建议直接学习新版**
* 每张卡只允许一行源代码。
* 仅识别第 1-72 列最后八列73-80保留给卡片分类器
* 行号(“标签”)位于第 1-5 列。
* 程序语句在第 7-72 列。
* 要表示跨行,请在第 6 列中输入一个连续字符(通常是 `+`)。
* 要创建注释行,请在第 1 列中输入 `C``*`
* 只有字符 `A``Z`(大写字母)、`0``9`(数字)和特殊字符 `= + - * / ( ) , . $ ' :` 和空格能够使用。
虽然有这些限制,你仍然可以编写非常有用和有趣的程序。
### 在 Fortran 中猜数字
通过编写“猜数字”游戏来探索 Fortran。这是我的实现代码
```
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C     PROGRAM TO GUESS A NUMBER 1-100
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      PROGRAM GUESSNUM
      INTEGER SEED, NUMBER, GUESS
      PRINT *, 'ENTER A RANDOM NUMBER SEED'
      READ *, SEED
      CALL SRAND(SEED)
      NUMBER = INT( RAND(0) * 100 + 1 )
      PRINT *, 'GUESS A NUMBER BETWEEN 1 AND 100'
 10   READ *, GUESS
      IF (GUESS.LT.NUMBER) THEN
         PRINT *, 'TOO LOW'
      ELSE IF (GUESS.GT.NUMBER) THEN
         PRINT *, 'TOO HIGH'
      ENDIF
      IF (GUESS.NE.NUMBER) GOTO 10
      PRINT *, 'THATS RIGHT!'
      END
```
如果你熟悉其他编程语言,你大概可以通过阅读源代码来弄清楚这个程序在做什么。前三行是注释块,表示程序的功能。第四行 `PROGRAM GUESSNUM` 将其标识为一个 <ruby><rb>程序</rb><rt>program</rt></ruby>,并由最后一行的 `END` 语句关闭。
定义变量后程序会提示用户输入随机数种子。Fortran 程序无法从操作系统初始化随机数生成器,因此你必须始终使用“种子”值和 `SRAND` <ruby><rb>子程序</rb><rt>subroutine</rt></ruby> 启动随机数生成器。
Fortran 使用 `RAND(0)` 函数生成 0 到 0.999…… 之间的随机数。参数 `0` 告诉 `RAND` 函数生成一个随机数。将此随机数乘以 100 以生成 0 到 99.999…… 之间的数字,然后加 1 得到 1 到 100.999…… 之间的值。`INT` 函数将结果截断为整数;因此,变量 `NUMBER` 就是一个介于 1 到 100 之间的随机数。
程序会给出提示然后进入一个循环。Fortran 不支持更现代的编程语言中可用的 `while``do-while` 循环LCTT 译注Fortran 95 等新版支持,也因此在一定程度上减少了 `GOTO` 的使用)。相反,你必须使用标签(行号)和 `GOTO` 语句来构建自己的循环。这就是 `READ` 语句有一个行号的原因:你可以在循环末尾使用 `GOTO` 跳转到此标签。
穿孔卡片没有 `<`(小于)和 `>`(大于)符号,因此 Fortran 采用了另一种语法来进行值比较。要测试一个值是否小于另一个值,请使用 `.LT.`(小于)。要测试一个值是否大于另一个值,请使用 `.GT.`(大于)。等于和不等于分别是 `.EQ.``.NE.`
在每次循环中,程序都会验证用户的猜测值。如果用户的猜测值小于随机数,程序打印 `TOO LOW`,如果猜测大于随机数,程序打印 `TOO HIGH`。循环会一直持续,直到用户的猜测值等于目标随机数为止。
当循环退出时,程序打印 `THATS RIGHT!` 并立即结束运行。
```
$ gfortran -Wall -o guess guess.f
$ ./guess
 ENTER A RANDOM NUMBER SEED
93759
 GUESS A NUMBER BETWEEN 1 AND 100
50
 TOO LOW
80
 TOO HIGH
60
 TOO LOW
70
 TOO LOW
75
 TOO HIGH
73
 TOO LOW
74
 THATS RIGHT!
```
每次运行程序时,用户都需要输入不同的随机数种子。如果你总是输入相同的种子,程序给出的随机数也会一直不变。
### 在其他语言中尝试
在学习一门新的编程语言时,这个“猜数字”游戏是一个很好的入门程序,因为它以非常简单的方式练习了几个常见的编程概念。通过用不同的编程语言实现这个简单的游戏,你可以弄清一些核心概念以及比较每种语言的细节。
你有最喜欢的编程语言吗?如何用你最喜欢的语言来编写“猜数字”游戏?跟随本系列文章来查看你可能感兴趣的其他编程语言示例吧。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/fortran
作者:[Jim Hall][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jim-hall
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/1980s-computer-yearbook.png?itok=eGOYEKK- (Person typing on a 1980's computer)
[2]: https://en.wikipedia.org/wiki/Fortran

View File

@@ -0,0 +1,186 @@
[#]: subject: (Comparing Linux Mint and Fedora: Which One Should You Use?)
[#]: via: (https://itsfoss.com/linux-mint-vs-fedora/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Linux Mint 和 Fedora应该使用哪一个
======
![](https://img.linux.net.cn/data/attachment/album/202110/04/123523kzzm3x4yr2ppmfj9.jpg)
Linux Mint 是一个 [为初学者定制的流行的 Linux 发行版][1],同时为用户提供了与 Windows 类似的体验。事实上,它有 [一些地方比 Ubuntu 做的更好][2],这使它成为每一类用户的合适选择。
它是基于 Ubuntu 的,完全由社区所支持。
另一方面Fedora 是一个尝鲜发行版,它专注于纳入令人兴奋的变化,最终使其成为红帽企业 LinuxRHEL的一部分。
与 Linux Mint 不同Fedora 并不完全专注于个人(或非开发者)使用。即使他们提供了一个工作站版本,其目标也是开发者和有经验的 Linux 用户。
### Fedora 或 Mint应该根据什么选择
虽然我们知道 Fedora 并不是完全面向 Linux 新手的,但许多用户喜欢使用 Fedora 作为他们的日常系统。因此,在这篇文章中,我们将阐明两者之间的一些区别,以帮助你选择一个在你的台式机上使用的操作系统。
#### 系统要求 & 硬件兼容性
![][3]
在选择任何 Linux 发行版之前,你都应该看一下它的系统要求,并检查硬件兼容性。
在这方面Linux Mint 和 Fedora 都需要至少 2GB 的内存、20GB 的磁盘空间,以及 1024 x 768 分辨率的显示器来获得入门级的体验。
是的,官方文件可能提到 1GB 内存就可以起步,但要看实际使用情况。除非你有一台复古的电脑,想为一个特定的目的恢复它,否则它就不在考虑范围之内。
![Linux Mint 资源使用情况][4]
在技术上,两者都支持现代的和陈旧的硬件,你只有在安装时才会知道软件/驱动是否支持它。除非你有一个特殊的外围设备或具有特殊功能的硬件组件,否则硬件支持可能不是什么大问题。
Linux Mint 19 系列仍然提供了对 32 位系统的支持,你可以使用它到 2023 年 4 月。而 Fedora 已经不支持 32 位系统了。
#### 软件更新周期
![Linux Mint 更新管理器][5]
Linux Mint 专注于长期发布版LTS支持时间为五年。它的维护方式与 Ubuntu 相同。但没有像 Ubuntu 那样提供付费的扩展支持。
Fedora 不提供 LTS 版本,而是每 6 个月推送一次新的更新,每个版本都会得到 13 个月的软件支持。如果你愿意,你可以跳过一个版本。
如果你只是想安装一个可以使用多年的 Linux 发行版,而不在乎是不是最新的技术/功能,那么 Linux Mint 是个不错的选择。
但是,如果你想要最新的和最伟大的 Linux 技术(在一些罕见的情况下,这也可能破坏你的计算体验),并接受适应 Fedora 推动的重大变化Fedora 可以是一个选择。
#### 桌面环境的选择
![Linux Mint Cinnamon 版][6]
Linux Mint 提供三种不同的 [桌面环境][7]MATE、Cinnamon 和 Xfce。它们有相同的更新周期并从发布之日起支持 5 年。
尽管 Fedora 不提供 LTS 版本,但你可以通过 Fedora spins 的形式选择各种桌面。你可以得到 KDE、LXQt、MATE、Cinnamon、LXDE以及一个内置 i3 平铺窗口管理器的版本。
![Fedora 34 with GNOME 40][8]
所以如果你想有更多的选择Fedora 可以是一个相当令人激动的选择。
#### 软件可用性
![Linux Mint 的软件中心和软件包管理器][9]
Linux Mint或 Ubuntu的默认软件库提供了大量可以安装的软件而 Fedora 的默认软件库只坚持提供开源软件。
不仅仅限于此Linux Mint 还配备了 [Synaptic 软件包管理器][10],这是一个令人印象深刻的安装软件的轻量级工具。
尽管你可以 [在 Fedora 中启用第三方软件库][11]但这又是一个额外的步骤。而且RPM Fusion 存储库可能没有 Ubuntu 的 universe 存储库那么庞大。
![Fedora 34 软件中心][12]
所以,对于 Linux Mint 来说,总的来说,你可以得到更多可安装的软件包和各种安装软件的方法,开箱即用。
#### 使用和安装的便利性
对于一个 Linux 的新嫩用户来说Ubuntu 或任何基于 Ubuntu 的发行版通常都是一个很好的开端。
从 [Ubuntu 的安装体验][13],到 [安装软件][14] 的简便性,同时还可以选择 LTS 版本,这让初学者觉得很方便。
而且,借助 Ubiquity 安装程序Linux Mint 自然也有与 Ubuntu 相同的好处,因此,它的学习曲线最小,易于安装,易于使用。
虽然从表面上看 Fedora 并不复杂,但安装选项、软件包管理器以及默认存储库中缺乏的软件可能是一个耗时的因素。
如果你没有尝试过,我建议你试试我们的 [VirtualBox 版的 Fedora 安装指南][15]。这是一个测试安装体验的好方法,然后再在你的任何生产系统上进行尝试。
#### 开箱即用的体验
最省事的体验通常是令人愉快的选择。嗯,对大多数人来说。
现在,你需要明白,根据硬件配置的不同,每个用户最终可能会有不同的“开箱即用”体验。
但是,作为参考,让我给你举个 Fedora 和 Linux Mint 的例子。
考虑到我的电脑上使用的是 NVIDIA GPU我需要安装专有的驱动程序以获得最佳性能。
![][16]
而且,当我启动 Linux Mint 时,使用“驱动程序管理器”应用程序,安装驱动程序相当容易。
但是,对于 Fedora即使我按照我们的 [在 Fedora 中安装 Nvidia 驱动程序][17] 的指南,我在重启时还是出现了一个错误。
![在 Fedora 中安装 NVIDIA 驱动程序][18]
不仅如此,由于某些原因,我的有线网络似乎没有被激活,因此,我没有互联网连接。
是的,当你遇到问题时,你总是可以尝试着去排除故障,但是对于 Linux Mint我不需要这么做。所以根据我的经验我会推荐 Linux Mint它有更好的开箱体验。
#### 文档
如果你依赖于文档资源并想在这个过程中挑战自己,获得不错的学习经验,我推荐你去看看 [Fedora 的文档][19]。
你会发现最近和最新的 Fedora 版本的最新信息,这是件好事。
另一方面,[Linux Mint 的文档][20] 没有定期更新,但在你想深入挖掘时很有用。
#### 社区支持
你会得到一个良好的社区支持。[Linux Mint 的论坛][21] 是一个很基础的平台,容易使用并能解决问题。
[Fedora 的论坛][22] 是由 Discourse 驱动的,它是最 [流行的现代开源论坛软件][23] 之一。
#### 企业与社区的角度
Fedora 得到了最大的开源公司 [红帽][24] 的支持 —— 因此你可以得到良好的持续创新和长期的支持。
然而,正因为 Fedora 并不是为日常电脑用户而建立的,每一个版本的选择都可能完全影响你的用户体验。
另一方面Linux Mint 完全由一个充满激情的 Linux 社区所支持,专注于使 Linux 在日常使用中更加容易和可靠。当然,它依赖于 Ubuntu 作为基础但如果社区不喜欢上游的东西Linux Mint 也会做出大胆的改变。
例如Linux Mint 与 Ubuntu 官方发行版不同,默认情况下禁用了 snap。所以如果你想使用它们你就必须 [在 Linux Mint 中启用 snap][25]。
### 总结
如果你想为你的家用电脑选择一个没有问题的、易于使用的操作系统,我的建议是 Linux Mint。但是如果你想体验最新的、最伟大的 Linux 操作系统,同时在你的 Linux 学习经历中进行一次小小的冒险Fedora 可以是一个不错的选择。
虽然每个操作系统都需要某种形式的故障排除,没有什么能保证你的硬件完全不出问题,但我认为 Linux Mint 对大多数用户来说可能没有问题。
在任何情况下,你可以重新审视上面提到的比较点,看看什么对你的电脑最重要。
你怎么看?你会选择 Fedora 而不是 Mint 吗?还有,为什么?请在下面的评论中告诉我。
--------------------------------------------------------------------------------
via: https://itsfoss.com/linux-mint-vs-fedora/
作者:[Ankush Das][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://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-linux-beginners/
[2]: https://itsfoss.com/linux-mint-vs-ubuntu/
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/05/fedora-34-about.png?resize=1020%2C709&ssl=1
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/05/linux-mint-resources.png?resize=800%2C293&ssl=1
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/05/linux-mint-update-manager.png?resize=819%2C612&ssl=1
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/05/linux-mint-cinnamon-desktop.png?resize=800%2C450&ssl=1
[7]: https://itsfoss.com/best-linux-desktop-environments/
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/05/fedora-34-desktop.png?resize=800%2C478&ssl=1
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/05/linux-mint-software-sources.png?resize=800%2C385&ssl=1
[10]: https://itsfoss.com/synaptic-package-manager/
[11]: https://itsfoss.com/fedora-third-party-repos/
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/05/fedora-34-software.png?resize=1055%2C691&ssl=1
[13]: https://itsfoss.com/install-ubuntu/
[14]: https://itsfoss.com/remove-install-software-ubuntu/
[15]: https://itsfoss.com/install-fedora-in-virtualbox/
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-driver-manager.jpg?resize=800%2C548&ssl=1
[17]: https://itsfoss.com/install-nvidia-drivers-fedora/
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/05/fedora-nvidia-driver-installation.png?resize=706%2C516&ssl=1
[19]: https://docs.fedoraproject.org/en-US/docs/
[20]: https://linuxmint.com/documentation.php
[21]: https://forums.linuxmint.com
[22]: https://ask.fedoraproject.org
[23]: https://itsfoss.com/open-source-forum-software/
[24]: https://www.redhat.com/en
[25]: https://itsfoss.com/enable-snap-support-linux-mint/

View File

@@ -0,0 +1,180 @@
[#]: subject: (Top 5 Chrome-like Browsers That Are Better Than Google Chrome in 2021)
[#]: via: (https://news.itsfoss.com/chrome-like-browsers-2021/)
[#]: author: (Jacob Crume https://news.itsfoss.com/author/jacob/)
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13858-1.html)
Linux 上 5 个基于 Chromium 的浏览器
======
> 谷歌浏览器可能不是 Linux 用户的最佳浏览器。在这里,我们探讨了 Linux 平台的其他潜在选择。
![](https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/06/chrome-alternatives-2021.png?w=1200&ssl=1)
想摆脱谷歌?想为你的 Linux 系统寻找可能比谷歌浏览器(和类似的)更好的浏览器?
幸运的是,有多个谷歌浏览器的替代品,你可以试试。
它们中的每一个都带来了一些有趣的东西,同时也保持了 Chrome 所特有的奇妙兼容性。请继续阅读,了解这些浏览器的更多信息。
### 比谷歌浏览器更好的选择
> 注:虽然 [自由和开源软件在取代科技巨头方面扮演着关键角色][1]但除了谷歌浏览器之外Linux 上的任何选择都是一个好的开始。因此,你也会发现一些非 FOSS 的选择。
在我看来Chrome 的最佳替代品是基于 Chromium 的浏览器,这意味着它们与 Chrome 共享相同的基因。这样做的好处是,它们已经拥有与 Chrome 相同的功能,同时有更多时间来增加自己的功能。
另外,如果你愿意,你可以了解一下不基于 Chromium 的 [Chrome 开源替代品][2]。
无论如何,即使谷歌浏览器的替代品对你来说并不优越,也值得尝试远离科技巨头。
我们收集了一些在各方面与 Chrome 相当或更好的浏览器。闲话少说,以下是我挑选的五款比 Chrome 本身更好的类似 Chrome 的浏览器:
* UnGoogled Chromium
* Brave
* Edge
* Vivaldi
* Opera
这份名单没有排名顺序。
### 1、UnGoogled Chromium
![][13]
特点:
* 移除针对谷歌域名的功能
* 在运行时阻止对 Google 的内部请求
* 从源代码中剥离谷歌的二进制文件
* 许多新的命令行开关和 `chrome://flags` 条目
* 强制所有弹出式窗口为标签
对于那些隐私爱好者来说,[UnGoogled Chromium][4] 浏览器将是一个天赐良机。虽然它可能看起来与 Chrome 相同,但它有许多隐私方面的调整。
顾名思义,对于 Chrome 浏览器的用户来说,最大的倒退将是没有谷歌的服务集成。但这也意味着不再有对谷歌的内部请求、谷歌网址跟踪等等。
它没有吹嘘任何非凡的东西来保护你的隐私,但它应该比谷歌浏览器更好。
你也可以选择通过 `chrome://flags` 设置来探索和切换隐私设置。
总而言之UnGoogled Chromium 提供了一种熟悉的浏览体验,同时还加入了一套隐私功能。它是可靠的,而且还与 Chrome 扩展程序庞大的生态系统兼容。
### 2、Brave
![][14]
特点:
* 内置广告拦截器
* 更快的页面加载时间
* Brave 奖励计划
* 能够在设备之间进行同步
* 支持 Chrome Web 商店
当 [Brave][6] 在 2016 年首次登上舞台时,世界各地的人们都震惊于它的隐私和性能特点。在发布时,这包括了一个内置的广告屏蔽器和一个新的用户界面。
从那时起,该浏览器有了更多的功能,包括奖励计划和 [Tor][5] 整合。这使得它成为增长最快的浏览器之一。
### 3、Edge
![][15]
特点:
* 支持 Chrome Web 商店
* 儿童浏览模式(额外的保护和更简单的用户界面)
* 良好的 PDF 编辑工具
* 内置优惠券搜索器
* 阅读模式
* 内置密码生成器
当微软 [Edge][7] 在 2015 年首次与 Windows 10 一起发布时,它因缓慢和有缺陷而被广泛批评。然而,在 2020 年初,它使用 Chromium Web 引擎完全重新制作了。
这也是 Chrome 浏览器所基于的引擎,这提供了现代和快速的浏览体验。这种转变的一个好处是 Web 浏览器能够在许多不同的平台上运行,从 Windows 7 和 macOS 到 Ubuntu 和其他基于 Linux 的发行版。
我知道,如果你因为某些原因讨厌微软,这可能不会吸引你 —— 但 Linux 版的微软 Edge 是谷歌 Chrome 浏览器的一个重要替代品。
### 4、Vivaldi
![][16]
特点:
* 内置翻译器
* Vivaldi EmailBeta
* Feed 阅读器Beta
* Vivaldi 日历Beta
* 可高度定制的用户界面
* 内置广告拦截器
* 支持 Chrome Web 商店
* 标签分组
* 分屏标签
[Vivaldi][11] 于 2016 年首次发布,它在浏览器大战中迅速崛起。它最初是为对 [Presto][8] [布局引擎][9] 过渡不满的 Opera 用户设计的,它已经成功地重新实现了 Opera 过渡到 Chromium 期间失去的许多功能。
令人惊讶的是,它在基于 Chromium 的情况下还能做到这一点(正是 Opera 放弃这些功能的原因)。
最新的 [Vivaldi 4.0 版本][10] 也为高级用户提供了一些功能。
虽然它不是 100% 的自由软件,但其 93% 的源代码是可用的,只有用户界面是专有的。考虑到 Vivaldi 的开发团队积极关注着 Linux 用户的改进Vivaldi 提供了大量的功能,这可能是一个值得权衡的结果。
### 5、Opera
![][17]
特点:
* 内置虚拟专用网络
* 轻松访问社交媒体
* 内置加密货币钱包
* 欺诈和恶意软件保护
* 高度可见的网站安全徽章
虽然 [Opera][12] 从未成为 Web 浏览器之王,但它一直存在于关于使用何种浏览器的争论中。它最初是基于其内部的 Presto 布局引擎的,在 2013 年切换到 Chromium。
不幸的是,这一转换意味着 Opera 团队被迫放弃了其最知名的一些功能,为 Vivaldi 和 Firefox 等替代品填补 Opera 留下的空间铺平道路。
这并不是说 Opera 缺乏功能,它包含了许多功能。
### 总结
在这里,我们列出了为 Linux 桌面平台上用户量身定做的浏览器。
无论你是想要更多的功能、更好的用户界面,还是想要帮助你摆脱谷歌的束缚,都有一个选择适合你。
由于所有这些浏览器都是基于 Chromium 的,它们都能像 Chrome 一样提供良好的兼容性和用户体验。因此,请切换到这些类似 Chrome 的浏览器中,享受它们各自赋予的自由吧。
2021 年,你最喜欢的 Linux 上谷歌浏览器的替代品是什么?请在下面的评论中告诉我。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/chrome-like-browsers-2021/
作者:[Jacob Crume][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://news.itsfoss.com/author/jacob/
[b]: https://github.com/lujun9972
[1]: https://news.itsfoss.com/save-privacy-with-foss/
[2]: https://itsfoss.com/open-source-browsers-linux/
[4]: https://github.com/Eloston/ungoogled-chromium
[5]: https://itsfoss.com/tor-guide/
[6]: https://brave.com
[7]: https://www.microsoftedgeinsider.com/en-us/download
[8]: https://en.wikipedia.org/wiki/Presto_(browser_engine)
[9]: https://en.wikipedia.org/wiki/Browser_engine
[10]: https://news.itsfoss.com/vivaldi-4-0-release/
[11]: https://vivaldi.com
[12]: https://www.opera.com
[13]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/05/ungoogled-chromium-screenshot.png?w=1366&ssl=1
[14]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/06/brave-homepage.png?w=1366&ssl=1
[15]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/06/edge-homepage.png?w=1366&ssl=1
[16]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/06/vivaldi-4.0-homepage.png?w=1366&ssl=1
[17]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/06/opera-homepage.png?w=1366&ssl=1

View File

@@ -0,0 +1,263 @@
[#]: subject: (Creating a PKGBUILD to Make Packages for Arch Linux)
[#]: via: (https://itsfoss.com/create-pkgbuild/)
[#]: author: (Hunter Wittenborn https://itsfoss.com/author/hunter/)
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13843-1.html)
Arch Linux 软件包制作入门
======
![](https://img.linux.net.cn/data/attachment/album/202110/02/130702ybexb5tsvkx1xbs1.jpg)
`PKGBUILD` 文件是为 Arch Linux 及其衍生版(如 Manjaro构建和创建软件包的方式。
如果你曾经使用过 [AUR][1](即 Arch Linux 的用户维护的 `PKGBUILD` 存储库),你甚至可能也遇到过它们。
但是,到底是如何从 `PKGBUILD` 到可安装软件包的呢?这两者之间到底发生了什么,如何把自己的软件制作成软件包呢?你将在这篇文章中了解这些。
### PKGBUILD 基础知识
对于那些熟悉 Bash 或其他 shell 的人来说,你可能知道,`PKGBUILD` 就是一个带有一些变量的 shell 脚本。
`PKGBUILD` 文件由变量和函数组成,所有这些都是用来定义软件包本身,以及如何构建它。
为了从 `PKGBUILD` 中创建一个软件包,需要使用 `makepkg` 命令行工具。在获得 `PKGBUILD` 文件后,你只需在包含 `PKGBUILD` 的目录中运行 `makepkg',就可以得到一个可安装的软件包了。
![][2]
在本教程中,你将会看到我刚刚制作的软件包,它在运行时打印出 “Hello World!”。
![][3]
### 准备
为了继续学习本教程,你需要创建几个文件。
首先,你需要创建一个名为 `PKGBUILD` 的文件,它将作为构建你的软件包的“配方”。
你需要做的另一个文件是一个叫 `hello-world.sh` 的文件。我稍后会解释它的用途。
你也可以用一个命令来创建这两个文件:
```
touch PKGBUILD hello-world.sh
```
你可以用 `ls` 命令检查这些文件是否被创建。
![][4]
然后你就可以开始了!
### 设置你的 PKGBUILD 文件
我不会让你复制粘贴整个文件,而是和你一起键入每一行,这样你就能更好地理解每一行的目的。如果你不喜欢这种学习方式,我强烈推荐 [Arch 维基][5] 中为 Arch Linux 创建软件包的文章。
这篇文章也没有介绍 `PKGBUILD` 中可以设置的每一个选项,只是介绍了一些常用的选项,以便你能尽快上手。
说完了这些,打开你的文本编辑器,让我们直接进入正题吧。
#### pkgname
首先是 `pkgname` 变量。这是安装时定义软件包名称的东西,也是 [Arch Linux 的软件包管理器 pacman][6] 跟踪软件包的方式。
这个变量(以及其他一些变量)的格式是 `variable=value`,变量名在左边,变量的值在右边,用等号隔开。
要设置包的名称,请在 `PKGBUILD` 中输入以下内容:
```
pkgname="hello-world"
```
* 要设置一个不同的软件包名称,用你的软件包的名称替换 `hello-world`。
* 这并不设置用于运行程序的命令,这将在下面的 `package()` 部分中处理。
#### pkgver
正如变量名称本身所述,它设置了你的软件包的版本(即 `1.0.0`)。这在用户更新他们的系统时很有用,因为设置更高的版本会提示用户升级。
要设置版本号,请在 `PKGBUILD` 中输入以下内容(在前一行之后):
```
pkgver="1.0.0"
```
#### pkgrel
这与 `pkgver` 变量有关,通常不需要知道。不过和 `pkgver` 变量一样,如果它被换到一个更高的数字,就将通知用户进行升级。
它适用于任何需要保持 `pkgver` 不变的情况下,例如 `PKGBUILD` 本身发生了变化。如果你为一个你使用的程序创建了一个 `PKGBUILD`(并希望保持软件包的版本相同),而你需要修复 `PKGBUILD` 本身的一个错误,这将是非常有用的。
要设置这个变量,请在 `PKGBUILD` 中输入以下内容:
```
pkgver="1"
```
这个变量应该 **总是** 从 `1` 开始,然后一次一次地向上移动。当 `pkgver` 本身向上移动时,这个变量可以(也应该)重置为 `1`,因为 `pkgver` 本身会通知用户升级。
#### pkgdesc
这将设置软件包的描述,用于帮助更好地识别该软件包。
要设置它,只需将描述放在引号内:
```
pkgdesc="Hello world in your terminal!"
```
#### arch
这个变量设置软件包所兼容的 [硬件架构][7]。如果你不明白什么是架构,那也没关系,因为在大多数情况下,这个变量几乎是无用的。
无论如何,`makepkg` 仍然需要设置它,这样它就知道这个软件包与我们的系统是兼容的。
这个变量支持设置多个值,所以 `makepkg` 需要一个不同的语法,如下所示。
要设置它,请在 `PKGBUILD` 中输入以下内容:
```
arch=("x86_64")
```
如果你要设置多个值,需要用空格和引号分隔每个值,像这样。`arch=(“x86_x64" "arm")`。
#### depends
这列出了提供了我们的软件包所需功能的所有软件包。与 `arch` 一样,它也可以包含多个值,因此必须使用括号语法。
由于我们的软件包没有任何依赖关系,所以我们不需要在 `PKGBUILD` 中输入这个字段。然而,如果我们的软件包有依赖关系,我们就会使用与 `arch` 相同的语法。
#### optdepends
这里列出了那些并不是提供所需功能而是额外功能的软件包。
这与 `depends` 的语法相同。
#### conflicts
这告诉 `pacman` 哪些软件包会导致我们的软件包出现问题,或者以我们不希望的方式行事。
这里列出的任何软件包都会在我们的软件包被安装之前被卸载。
这与 `depends` 的语法相同。
#### license
这定义了你的程序所采用的 [软件许可证][8]。如果你需要帮助你选择一个许可证,[Arch 维基][9] 提供了一些信息。如果你不知道该怎么设置,将其设置为 `custom` 也可以。
这与 `arch` 和 `depends` 的语法相同:
```
license=("custom")
```
#### source
这就是 `makepkg` 如何知道要用什么文件来构建我们的软件包。它可以包含各种不同类型的源,包括本地文件和 URL。
在添加本地文件时,要输入相对于 `PKGBUILD` 文件的文件路径,比如以下目录布局:
```
PKGBUILD
file.txt
src/file.sh
```
如果你想在我们的 `PKGBUILD` 中包括 `file.sh`,你需要输入 `src/file.sh` 作为其名称。
当输入 URL 时,你只需输入完整的 URL即 `https://mirrors.creativecommons.org/presskit/logos/cc.logo.large.png`。
你的这个软件包只需要 `hello-world.sh` 文件,由于它和 `PKGBUILD` 在同一个目录中,你只需输入它的名字作为 `source` 的值。
这个变量也使用与 `arch` 和 `depends` 相同的语法:
```
source=("hello-world.sh")
```
#### sha512sums
这是用来验证 `source` 中的文件没有被修改或下载错误。如何获得这个值的信息可以在 [Arch 维基关于 PKGBUILD 的文章][10] 中找到。
如果你宁愿不设置这个(或者你只是不需要,例如对于本地文件),你可以为 `source` 变量中的每个文件输入 `SKIP`
```
sha512sums=("SKIP")
```
#### package()
这是最后一个,也是实际制作我们的包的最重要的部分。在处理这个问题时,知道两个变量很重要。
* `${srcdir}`:这是 `makepkg` 放置 `source` 变量中文件的地方。在这个目录中,你可以与这些文件进行交互,并对文件进行任何其他需要的修改。
* `${pkgdir}`:这是我们放置将被安装在系统中的文件的地方。
`${pkgdir}` 的文件夹结构是按照实际系统中的情况设置的(例如,使用 `pacman` 安装时,`${pkgdir}/usr/bin/hello-world` 会创建文件 `/usr/bin/hello-world`)。
`package()` 包含一个用于创建软件包的命令列表。
因此,如果(假设)你需要有个在 `/usr/share/motto.txt` 写着 “Linux is superior to Windows ”的文件,你会运行这样的东西:
```
package() {
mkdir -p "${pkgdir}/usr/share"
echo "Linux is superior to Windows" | tee "${pkgdir}/usr/share/motto.txt"
}
```
关于上述命令的一些说明:
* `${pkgdir}` 里面最初是 **不包含** 目录的。如果你跳过了 [mkdir 命令][11]`tee` 会输出一个错误,说这个目录不存在。
* 在指定目录时,**总是** 在它们前面加上 `${pkgdir}` 或 `${srcdir}` 变量。如果输入 `/usr/share/motto.txt`,就会按照字面意义指向你当前运行的系统中的 `/usr/share/motto.txt`。
对于你的 `PKGBUILD`,你将把 `hello-world.sh` 文件放在目标系统的 `/usr/bin/hello-world` 中。你还将使该文件在运行时说 “Hello to you!”。
要做到这一点,请在 `PKGBUILD` 中输入以下内容:
```
package() {
echo 'Hello to you!' > "${srcdir}/hello-world.sh"
mkdir -p "${pkgdir}/usr/bin"
cp "${srcdir}/hello-world.sh" "${pkgdir}/usr/bin/hello-world"
chmod +x "${pkgdir}/usr/bin/hello-world"
}
```
然后就完成了!用 `makepkg -si` 构建和安装软件包,然后在终端运行 `hello-world`,查看其输出。
![][12]
### 总结
就这样,你已经制作了你的第一个 `PKGBUILD`!你走在了为自己甚至是为 AUR 制作实际的软件包的路上。
有什么问题,或者有什么地方不对吗?请随时在下面的评论区发表。
--------------------------------------------------------------------------------
via: https://itsfoss.com/create-pkgbuild/
作者:[Hunter Wittenborn][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://itsfoss.com/author/hunter/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/aur-arch-linux/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/05/image.png?resize=748%2C689&ssl=1
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/05/image-2.png?resize=682%2C260&ssl=1
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/05/image-3.png?resize=682%2C265&ssl=1
[5]: https://wiki.archlinux.org/title/Creating_packages
[6]: https://itsfoss.com/pacman-command/
[7]: https://www.quora.com/What-is-CPU-architecture
[8]: https://en.wikipedia.org/wiki/Software_license
[9]: https://wiki.archlinux.org/title/PKGBUILD#license
[10]: https://wiki.archlinux.org/title/PKGBUILD#Integrity
[11]: https://linuxhandbook.com/mkdir-command/
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/06/image-1.png?resize=561%2C281&ssl=1

View File

@@ -0,0 +1,215 @@
[#]: subject: (Run GitHub Actions on Fedora CoreOS)
[#]: via: (https://fedoramagazine.org/run-github-actions-on-fedora-coreos/)
[#]: author: (Clément Verna https://fedoramagazine.org/author/cverna/)
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13846-1.html)
在 Fedora CoreOS 上运行 GitHub Actions
======
![][1]
[GitHub Actions][3] 是一项为快速建立持续集成和交付CI/CD工作流程而提供的服务。这些工作流程在被称为“<ruby>运行器<rt>runner</rt></ruby>”的主机上运行。GitHub 提供的 [托管运行器][4] 的操作系统的选择是有限的Windows Server、Ubuntu、MacOS
另一个选择是使用 [自托管][5] 的运行器,这让仓库管理员对运行器有更多控制。自托管的运行程序是专门为某个存储库或组织服务的。下面的文章介绍了使用 Fedora CoreOS 配置自托管运行程序的步骤。
### 入门
Fedora CoreOS 是一个精简的操作系统旨在便于大规模的部署和维护。该操作系统会自动更新并默认提供运行容器所需的工具。由于这些原因Fedora CoreOS 是运行 CI/CD 工作流程的一个极佳选择。
配置和配备 Fedora CoreOS 机器的第一步是生成一个 [Ignition][6] 文件。[Butane][7] 允许你使用更友好的格式YAML生成 Ignition 文件。
#### 配置一个 Fedora CoreOS 运行器
要在 Fedora CoreOS 上执行 GitHub Actions托管主机需要用于注册和运行该运行器的二进制文件和脚本。从 [Actions 运行器项目][8] 下载二进制文件和脚本,并部署在 `/usr/local/sbin/actions-runner` 下。
```
version: "1.3.0"
variant: fcos
storage:
directories:
- path: /usr/local/sbin/actions-runner
mode: 0755
user:
name: core
group:
name: core
files:
- path: /usr/local/sbin/actions-runner/actions-runner-linux.tar.gz
overwrite: true
contents:
source: https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz
mode: 0755
user:
name: core
group:
name: core
```
#### 注册和删除令牌
为一个项目配置运行器需要一个“<ruby>令牌<rt>token</rt></ruby>”。这可以防止在没有正确权限的情况下从项目中注册或删除自托管的运行器。GitHub 提供的令牌有一个小时的过期时间。如果运行器在这个时间之后重新启动,它将需要一个新的注册令牌。
该令牌可能出问题,特别是在 Fedora CoreOS 自动更新时。更新过程希望托管主机在收到新数据后至少每隔几周重启一次。
幸运的是,可以使用 GitHub REST API 来获取这些令牌,并在托管主机每次重启时自动配置运行器。下面的 `manage-runner.sh` 脚本使用 API 来获取令牌,删除任何已经配置好的运行器,并用新的令牌注册运行器。
```
#!/bin/bash
# Handles the Github Action runner configuration.
# Remove and Registration token expires after 1 hour, if we want our runner
# to work after a reboot (auto update) we need to refresh the tokens.
# First remove the runner with a fresh remove token
REMOVE_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/remove-token | jq -r '.token')
/usr/local/sbin/actions-runner/config.sh remove --token ${REMOVE_TOKEN}
# Then register the runner with a fresh registration token
REGISTRATION_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/registration-token | jq -r '.token')
/usr/local/sbin/actions-runner/config.sh --url https://github.com/cverna/fcos-actions-runner --token ${REGISTRATION_TOKEN} --labels fcos --unattended
```
上面的脚本使用了一些环境变量,包含 GitHub 用户名和用于验证 REST API 请求的 <ruby>[个人访问令牌][9]<rt>Personal Access Token</rt></ruby>。个人访问令牌需要存储库权限,以便成功检索运行器的注册和移除令牌。该令牌是安全敏感信息,所以最好将其存储在一个具有更严格权限的不同文件中。在这个例子中,这个文件是 `actions-runner`
```
GITHUB_USER=<user>
GITHUB_REPO=<repo>
GITHUB_TOKEN=<personal_access_token>
```
以下是创建这两个文件 `manage-runner.sh``actions-runner` 的 Butane 片段。
```
- path: /usr/local/sbin/actions-runner/manage-runner.sh
contents:
local: manage-runner.sh
mode: 0755
user:
name: core
group:
name: core
- path: /etc/actions-runner
contents:
local: actions-runner
mode: 0700
user:
name: core
group:
name: core
```
### 在 Fedora CoreOS 上运行 Actions
最后,创建用于配置和启动运行器的 systemd 服务。在 Butane 配置文件中定义这些服务。
```
systemd:
units:
- name: github-runner-configure.service
enabled: true
contents: |
[Unit]
Description=Configure the github action runner for a repository
After=network-online.target boot-complete.target
Requires=boot-complete.target
[Service]
EnvironmentFile=/etc/actions-runner
Type=oneshot
RemainAfterExit=yes
User=core
WorkingDirectory=/usr/local/sbin/actions-runner
ExecStartPre=tar xvf actions-runner-linux.tar.gz --no-same-owner
ExecStart=/usr/local/sbin/actions-runner/manage-runner.sh
[Install]
WantedBy=multi-user.target
- name: github-runner.service
enabled: true
contents: |
[Unit]
Description=Run the github action runner
After=github-runner-configure.service
[Service]
WorkingDirectory=/usr/local/sbin/actions-runner
User=core
ExecStart=/usr/local/sbin/actions-runner/run.sh
[Install]
WantedBy=multi-user.target
```
这将创建两个服务:`github-runner-configure.service`(在主机启动完成后运行一次)和 `github-runner.service`(运行 Actions 运行器二进制文件并等待新的 CI/CD 作业)。
现在 Butane 配置已经完成,从中生成一个 Ignition 文件并配备一个 Fedora CoreOS Actions 运行器。
```
$ podman run -i --rm -v $PWD:/code:z --workdir /code quay.io/coreos/butane:release --pretty --strict --files-dir /code config.yaml -o config.ignition
```
一旦 Ignition 文件生成,它就可以用来在 [支持][10] Fedora CoreOS 的平台上配备一个运行器。
### 配置一个 Action 来使用一个自托管的运行器
下面的测试 Action 工作流程将测试 FCOS 的自托管的运行器。在你的 git 存储库中创建以下文件 `.github/workflows/main.yml`
```
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
pull_request:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: fcos
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Runs a single command using the runners shell
- name: Run a one-line script
run: podman run --rm fedora-minimal:34 echo Hello World !
```
请注意,`runs-on` 的配置被设置为使用标签为 `fcos` 的运行器。
本文介绍的代码可以在 [这里][12] 中找到。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/run-github-actions-on-fedora-coreos/
作者:[Clément Verna][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://fedoramagazine.org/author/cverna/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/07/modern-times-816x345.jpg
[2]: https://commons.wikimedia.org/wiki/File:Chaplin_-_Modern_Times.jpg
[3]: https://docs.github.com/en/actions
[4]: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
[5]: https://docs.github.com/en/actions/hosting-your-own-runners
[6]: https://github.com/coreos/ignition
[7]: https://github.com/coreos/butane
[8]: https://github.com/actions/runner
[9]: https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token
[10]: https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/
[11]: https://fedoramagazine.org/getting-started-with-fedora-coreos/
[12]: https://github.com/cverna/fcos-actions-runner

View File

@@ -0,0 +1,354 @@
[#]: subject: (Kernel tracing with trace-cmd)
[#]: via: (https://opensource.com/article/21/7/linux-kernel-trace-cmd)
[#]: author: (Gaurav Kamathe https://opensource.com/users/gkamathe)
[#]: collector: (lujun9972)
[#]: translator: (mengxinayan)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13852-1.html)
使用 trace-cmd 追踪内核
======
> trace-cmd 是一个易于使用,且特性众多、可用来追踪内核函数的命令。
![](https://img.linux.net.cn/data/attachment/album/202110/05/145818d2i9tgjetzj8itqg.jpg)
在 [之前的文章][2] 里,我介绍了如何利用 `ftrace` 来追踪内核函数。通过写入和读出文件来使用 `ftrace` 会变得很枯燥,所以我对它做了一个封装来运行带有选项的命令,以启用和禁用追踪、设置过滤器、查看输出、清除输出等等。
[trace-cmd][3] 命令是一个可以帮助你做到这一点的工具。在这篇文章中,我使用 `trace-cmd` 来执行我在 `ftrace` 文章中所做的相同任务。由于会经常参考那篇文章,建议在阅读这篇文章之前先阅读它。
### 安装 trace-cmd
本文中所有的命令都运行在 root 用户下。
因为 `ftrace` 机制被内置于内核中,因此你可以使用下面的命令进行验证它是否启用:
```
# mount | grep tracefs
none on /sys/kernel/tracing type tracefs (rw,relatime,seclabel)
```
不过,你需要手动尝试安装 `trace-cmd` 命令:
```
# dnf install trace-cmd -y
```
### 列出可用的追踪器
当使用 `ftrace` 时,你必须查看文件的内容以了解有哪些追踪器可用。但使用 `trace-cmd`,你可以通过以下方式获得这些信息:
```
# trace-cmd list -t
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
```
### 启用函数追踪器
在我 [之前的文章][2] 中,我使用了两个追踪器,在这里我也会这么做。用 `function` 启用你的第一个追踪器:
```
$ trace-cmd start -p function
  plugin 'function'
```
### 查看追踪输出
一旦追踪器被启用,你可以通过使用 `show` 参数来查看输出。这只显示了前 20 行以保持例子的简短(见我之前的文章对输出的解释):
```
# trace-cmd show | head -20
## tracer: function
#
# entries-in-buffer/entries-written: 410142/3380032 #P:8
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
gdbus-2606 [004] ..s. 10520.538759: __msecs_to_jiffies <-rebalance_domains
gdbus-2606 [004] ..s. 10520.538760: load_balance <-rebalance_domains
gdbus-2606 [004] ..s. 10520.538761: idle_cpu <-load_balance
gdbus-2606 [004] ..s. 10520.538762: group_balance_cpu <-load_balance
gdbus-2606 [004] ..s. 10520.538762: find_busiest_group <-load_balance
gdbus-2606 [004] ..s. 10520.538763: update_group_capacity <-update_sd_lb_stats.constprop.0
gdbus-2606 [004] ..s. 10520.538763: __msecs_to_jiffies <-update_group_capacity
gdbus-2606 [004] ..s. 10520.538765: idle_cpu <-update_sd_lb_stats.constprop.0
gdbus-2606 [004] ..s. 10520.538766: __msecs_to_jiffies <-rebalance_domains
```
### 停止追踪并清除缓冲区
追踪将会在后台继续运行,你可以继续用 `show` 查看输出。
要停止追踪,请运行带有 `stop` 参数的 `trace-cmd` 命令:
```
# trace-cmd stop
```
要清除缓冲区,用 `clear` 参数运行它:
```
# trace-cmd clear
```
### 启用函数调用图追踪器
运行第二个追踪器,通过 `function_graph` 参数来启用它。
```
# trace-cmd start -p function_graph
Plugin 'function_graph'
```
再次使用 `show` 参数查看输出。正如预期的那样,输出与第一次追踪输出略有不同。这一次,它包括一个**函数调用**链:
```
# trace-cmd show | head -20
## tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
4) 0.079 us | } /* rcu_all_qs */
4) 0.327 us | } /* __cond_resched */
4) 0.081 us | rcu_read_unlock_strict();
4) | __cond_resched() {
4) 0.078 us | rcu_all_qs();
4) 0.243 us | }
4) 0.080 us | rcu_read_unlock_strict();
4) | __cond_resched() {
4) 0.078 us | rcu_all_qs();
4) 0.241 us | }
4) 0.080 us | rcu_read_unlock_strict();
4) | __cond_resched() {
4) 0.079 us | rcu_all_qs();
4) 0.235 us | }
4) 0.095 us | rcu_read_unlock_strict();
4) | __cond_resched() {
```
使用 `stop``clear` 命令来停止追踪和清除缓存区:
```
# trace-cmd stop
# trace-cmd clear
```
### 调整追踪以增加深度
如果你想在函数调用中看到更多的深度,你可以对追踪器进行调整:
```
# trace-cmd start -p function_graph --max-graph-depth 5
plugin 'function_graph'
```
现在,当你将这个输出与你之前看到的进行比较时,你应该看到更多的嵌套函数调用:
```
# trace-cmd show | head -20
## tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
6) | __fget_light() {
6) 0.804 us | __fget_files();
6) 2.708 us | }
6) 3.650 us | } /* __fdget */
6) 0.547 us | eventfd_poll();
6) 0.535 us | fput();
6) | __fdget() {
6) | __fget_light() {
6) 0.946 us | __fget_files();
6) 1.895 us | }
6) 2.849 us | }
6) | sock_poll() {
6) 0.651 us | unix_poll();
6) 1.905 us | }
6) 0.475 us | fput();
6) | __fdget() {
```
### 了解可被追踪的函数
如果你想只追踪某些函数而忽略其他的,你需要知道确切的函数名称。你可以用 `list -f` 参数来得到它们。例如搜索常见的内核函数 `kmalloc`,它被用来在内核中分配内存:
```
# trace-cmd list -f | grep kmalloc
bpf_map_kmalloc_node
mempool_kmalloc
__traceiter_kmalloc
__traceiter_kmalloc_node
kmalloc_slab
kmalloc_order
kmalloc_order_trace
kmalloc_large_node
__kmalloc
__kmalloc_track_caller
__kmalloc_node
__kmalloc_node_track_caller
[...]
```
下面是我的测试系统中可被追踪的函数总数:
```
# trace-cmd list -f | wc -l
63165
```
### 追踪内核模块相关的函数
你也可以追踪与特定内核模块相关的函数。假设你想追踪 `kvm` 内核模块相关的功能,你可以通过以下方式来实现。请确保该模块已经加载:
```
# lsmod | grep kvm_intel
kvm_intel 335872 0
kvm 987136 1 kvm_intel
```
再次运行 `trace-cmd`,使用 `list` 参数,并从输出结果中,`grep` 查找以 `]` 结尾的行。这将过滤掉内核模块。然后 `grep` 内核模块 `kvm_intel` ,你应该看到所有与该内核模块有关的函数。
```
# trace-cmd list -f | grep ]$ | grep kvm_intel
vmx_can_emulate_instruction [kvm_intel]
vmx_update_emulated_instruction [kvm_intel]
vmx_setup_uret_msr [kvm_intel]
vmx_set_identity_map_addr [kvm_intel]
handle_machine_check [kvm_intel]
handle_triple_fault [kvm_intel]
vmx_patch_hypercall [kvm_intel]
[...]
vmx_dump_dtsel [kvm_intel]
vmx_dump_sel [kvm_intel]
```
### 追踪特定函数
现在你知道了如何找到感兴趣的函数,请用一个例子把这些内容用于时间。就像前面的文章一样,试着追踪与文件系统相关的函数。我的测试系统上的文件系统是 `ext4`
这个过程略有不同;你在运行命令时,不使用 `start` 参数,而是在 `record` 参数后面加上你想追踪的函数的“模式”。你还需要指定你想要的追踪器;在这种情况下,就是 `function_graph`。该命令会继续记录追踪,直到你用 `Ctrl+C` 停止它。所以几秒钟后,按 `Ctrl+C` 停止追踪:
```
# trace-cmd list -f | grep ^ext4_
# trace-cmd record -l ext4_* -p function_graph
plugin 'function_graph'
Hit Ctrl^C to stop recording
^C
CPU0 data recorded at offset=0x856000
8192 bytes in size
[...]
```
### 查看追踪记录
要查看你之前的追踪记录,运行带有 `report` 参数的命令。从输出结果来看,很明显过滤器起作用了,你只看到 `ext4` 相关的函数追踪:
```
# trace-cmd report | head -20
[...]
cpus=8
trace-cmd-12697 [000] 11303.928103: funcgraph_entry: | ext4_show_options() {
trace-cmd-12697 [000] 11303.928104: funcgraph_entry: 0.187 us | ext4_get_dummy_policy();
trace-cmd-12697 [000] 11303.928105: funcgraph_exit: 1.583 us | }
trace-cmd-12697 [000] 11303.928122: funcgraph_entry: | ext4_create() {
trace-cmd-12697 [000] 11303.928122: funcgraph_entry: | ext4_alloc_inode() {
trace-cmd-12697 [000] 11303.928123: funcgraph_entry: 0.101 us | ext4_es_init_tree();
trace-cmd-12697 [000] 11303.928123: funcgraph_entry: 0.083 us | ext4_init_pending_tree();
trace-cmd-12697 [000] 11303.928123: funcgraph_entry: 0.141 us | ext4_fc_init_inode();
trace-cmd-12697 [000] 11303.928123: funcgraph_exit: 0.931 us | }
trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.081 us | ext4_get_dummy_policy();
trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.133 us | ext4_get_group_desc();
trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.115 us | ext4_free_inodes_count();
trace-cmd-12697 [000] 11303.928124: funcgraph_entry: 0.114 us | ext4_get_group_desc();
```
### 追踪一个特定的 PID
假设你想追踪与一个进程PID有关的函数。打开另一个终端注意运行中的 shell 的PID
```
# echo $$
10885
```
再次运行 `record` 命令,用 `-P` 选项传递PID。这一次让终端运行也就是说先不要按 `Ctrl+C`
```
# trace-cmd record -P 10885 -p function_graph
Plugin 'function_graph'
Hit Ctrl^C to stop recording
```
### 在 shell 上运行一些命令
移动到另一个终端,在那里你有一个以特定 PID 运行的 shell并运行任何命令例如`ls` 命令用来列出文件:
```
# ls
Temp-9b61f280-fdc1-4512-9211-5c60f764d702
tracker-extract-3-files.1000
v8-compile-cache-1000
[...]
```
移动到你启用追踪的终端,按 `Ctrl+C` 停止追踪:
```
# trace-cmd record -P 10885 -p function_graph
plugin 'function_graph'
Hit Ctrl^C to stop recording
^C
CPU1 data recorded at offset=0x856000
618496 bytes in size
[...]
```
在追踪的输出中,你可以看到左边是 PID 和 Bash shell右边是与之相关的函数调用。这对于缩小你的追踪范围是非常方便的
```
# trace-cmd report | head -20
cpus=8
<idle>-0 [001] 11555.380581: funcgraph_entry: | switch_mm_irqs_off() {
<idle>-0 [001] 11555.380583: funcgraph_entry: 1.703 us | load_new_mm_cr3();
<idle>-0 [001] 11555.380586: funcgraph_entry: 0.493 us | switch_ldt();
<idle>-0 [001] 11555.380587: funcgraph_exit: 7.235 us | }
bash-10885 [001] 11555.380589: funcgraph_entry: 1.046 us | finish_task_switch.isra.0();
bash-10885 [001] 11555.380591: funcgraph_entry: | __fdget() {
bash-10885 [001] 11555.380592: funcgraph_entry: 2.036 us | __fget_light();
bash-10885 [001] 11555.380594: funcgraph_exit: 3.256 us | }
bash-10885 [001] 11555.380595: funcgraph_entry: | tty_poll() {
bash-10885 [001] 11555.380597: funcgraph_entry: | tty_ldisc_ref_wait() {
bash-10885 [001] 11555.380598: funcgraph_entry: | ldsem_down_read() {
bash-10885 [001] 11555.380598: funcgraph_entry: | __cond_resched() {
```
### 试一试
这些简短的例子显示了使用 `trace-cmd` 命令而不是底层的 `ftrace` 机制,是如何实现既容易使用又拥有丰富的功能,许多内容本文并没有涉及。要想了解更多信息并更好地使用它,请查阅它的手册,并尝试使用其他有用的命令。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/7/linux-kernel-trace-cmd
作者:[Gaurav Kamathe][a]
选题:[lujun9972][b]
译者:[萌新阿岩](https://github.com/mengxinayan)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/gkamathe
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
[2]: https://linux.cn/article-13752-1.html
[3]: https://lwn.net/Articles/410200/

View File

@@ -0,0 +1,579 @@
[#]: subject: "NMState: A declarative networking config tool"
[#]: via: "https://fedoramagazine.org/nmstate-a-declarative-networking-config-tool/"
[#]: author: "Maurizio Garcia https://fedoramagazine.org/author/malgnuz/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13861-1.html"
NMState一个声明式网络配置工具
======
![](https://img.linux.net.cn/data/attachment/album/202110/08/145714mqcyh6sshchomyot.jpg)
这篇文章描述并演示了 NMState这是一个使用声明式方法配置主机的网络管理器。这意味着你可以通过 API 定义所需的配置状态,而工具则通过<ruby>提供者<rt>provider</rt></ruby>来应用配置。
### 配置方法:命令式与声明式
网络管理有时候是一项非常复杂的任务,这取决于环境的规模和多样性。在 IT 的早期,网络管理依赖于网络管理员在网络设备上手动执行命令。如今,<ruby>基础设施即代码<rt>Infrastructure as Code</rt></ruby>IaC允许以不同的方式将这些任务自动化。z这基本上有两种方法命令式或声明式。
在命令式方法中,你会定义“如何”达到所需的配置状态。而在声明式范式里则定义了“什么”是所需的配置状态,所以它不确定哪些步骤是必需的,也不确定它们必须以何种顺序执行。这种方法目前正在聚集更多的人员参与,你可以在目前使用的大多数管理和编排工具上找到它。
### NMState一个声明式的工具
NMState 是一个网络管理器,允许你按照声明式方法配置主机。这意味着你通过一个北向的声明式 API 定义所需的配置状态,这个工具通过南向的<ruby>提供者<rt>provider</rt></ruby>应用配置。
目前 NMState 支持的唯一的提供者是 NetworkManager它是为 Fedora Linux 提供网络功能的主要服务。不过NMState 的开发计划中将逐渐增加其他提供者。
关于 NMState 的进一步信息,请访问其项目 [站点][4] 或 GitHub [仓库][5]。
### 安装
NMState 在 Fedora Linux 29+ 上可用,需要在系统上安装并运行 NetworkManager 1.26 或更高版本。下面是在 Fedora Linux 34 上的安装情况:
```
$ sudo dnf -y install nmstate
...
输出节略
...
Installed:
NetworkManager-config-server-1:1.30.4-1.fc34.noarch gobject-introspection-1.68.0-3.fc34.x86_64 nispor-1.0.1-2.fc34.x86_64 nmstate-1.0.3-2.fc34.noarch
python3-gobject-base-3.40.1-1.fc34.x86_64 python3-libnmstate-1.0.3-2.fc34.noarch python3-nispor-1.0.1-2.fc34.noarch python3-varlink-30.3.1-2.fc34.noarch
Complete!
```
这样,你可以使用 `nmstatectl` 作为 NMState 的命令行工具。请参考 `nmstatectl -help``man nmstatectl` 以了解关于这个工具的进一步信息。
### 使用 NMstate
首先要检查系统中安装的 NMState 版本:
```
$ nmstatectl version
1.0.3
```
检查一个网络接口的当前配置,例如 `eth0` 的配置:
```
$ nmstatectl show eth0
2021-06-29 10:28:21,530 root DEBUG NetworkManager version 1.30.4
2021-06-29 10:28:21,531 root DEBUG Async action: Retrieve applied config: ethernet eth0 started
2021-06-29 10:28:21,531 root DEBUG Async action: Retrieve applied config: ethernet eth1 started
2021-06-29 10:28:21,532 root DEBUG Async action: Retrieve applied config: ethernet eth0 finished
2021-06-29 10:28:21,533 root DEBUG Async action: Retrieve applied config: ethernet eth1 finished
---
dns-resolver:
config: {}
running:
search: []
server:
- 192.168.122.1
route-rules:
config: []
routes:
config: []
running:
- destination: fe80::/64
metric: 100
next-hop-address: ''
next-hop-interface: eth0
table-id: 254
- destination: 0.0.0.0/0
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: eth0
table-id: 254
- destination: 192.168.122.0/24
metric: 100
next-hop-address: ''
next-hop-interface: eth0
table-id: 254
interfaces:
- name: eth0
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 192.168.122.238
prefix-length: 24
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
dhcp: true
ipv6:
enabled: true
address:
- ip: fe80::c3c9:c4f9:75b1:a570
prefix-length: 64
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
autoconf: true
dhcp: true
lldp:
enabled: false
mac-address: 52:54:00:91:E4:4E
mtu: 1500
```
正如你在上面看到的,这个网络配置显示了四个主要部分:
* `dns-resolver`:这部分是这个接口的名字服务器配置。
* `route-rules`:它说明了路由规则。 
* `routes`:它包括动态和静态路由。
* `interfaces`:这部分描述了 ipv4 和 ipv6 设置。
### 修改配置
你可以在两种模式下修改所需的配置状态:
* 交互式:通过 `nmstatectl edit` 编辑接口配置。这个命令调用环境变量 `EDITOR` 定义的文本编辑器,因此可以用 yaml 格式编辑网络状态。完成编辑后NMState 将应用新的网络配置,除非有语法错误。
* 基于文件的:使用 `nmstatectl apply` 应用接口配置,它从先前创建的 yaml 或 json 文件中导入一个所需的配置状态。
下面几节告诉你如何使用 NMState 来改变网络配置。这些改变可能会对系统造成破坏,所以建议在测试系统或客户虚拟机上执行这些任务,直到你对 NMState 有更好的理解。
这里使用的测试系统有两个以太网接口,`eth0``eth1`
```
$ ip -br -4 a
lo UNKNOWN 127.0.0.1/8
eth0 UP 192.168.122.238/24
eth1 UP 192.168.122.108/24
```
#### 互动配置模式的例子
使用 `nmstatectl edit` 命令将 `eth0` 接口的 MTU 改为 9000 字节,如下所示:
```
$ sudo nmstatectl edit eth0
---
dns-resolver:
config: {}
running:
search: []
server:
- 192.168.122.1
route-rules:
config: []
routes:
config: []
running:
- destination: fe80::/64
metric: 100
next-hop-address: ''
next-hop-interface: eth0
table-id: 254
- destination: 0.0.0.0/0
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: eth0
table-id: 254
- destination: 192.168.122.0/24
metric: 100
next-hop-address: ''
next-hop-interface: eth0
table-id: 254
interfaces:
- name: eth0
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 192.168.122.123
prefix-length: 24
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
dhcp: true
ipv6:
enabled: true
address:
- ip: fe80::c3c9:c4f9:75b1:a570
prefix-length: 64
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
autoconf: true
dhcp: true
lldp:
enabled: false
mac-address: 52:54:00:91:E4:4E
mtu: 9000
```
在保存并退出编辑器后NMState 应用新的网络期望状态:
```
2021-06-29 11:29:05,726 root DEBUG Nmstate version: 1.0.3
2021-06-29 11:29:05,726 root DEBUG Applying desire state: {'dns-resolver': {'config': {}, 'running': {'search': [], 'server': ['192.168.122.1']}}, 'route-rules': {'config': []}, 'routes': {'config': [], 'running': [{'destination': 'fe80::/64', 'metric': 102, 'next-hop-address': '', 'next-hop-interface': 'eth0', 'table-id': 254}, {'destination': '0.0.0.0/0', 'metric': 102, 'next-hop-address': '192.168.122.1', 'next-hop-interface': 'eth0', 'table-id': 254}, {'destination': '192.168.122.0/24', 'metric': 102, 'next-hop-address': '', 'next-hop-interface': 'eth0', 'table-id': 254}]}, 'interfaces': [{'name': 'eth0', 'type': 'ethernet', 'state': 'up', 'ipv4': {'enabled': True, 'address': [{'ip': '192.168.122.238', 'prefix-length': 24}], 'auto-dns': True, 'auto-gateway': True, 'auto-route-table-id': 0, 'auto-routes': True, 'dhcp': True}, 'ipv6': {'enabled': True, 'address': [{'ip': 'fe80::5054:ff:fe91:e44e', 'prefix-length': 64}], 'auto-dns': True, 'auto-gateway': True, 'auto-route-table-id': 0, 'auto-routes': True, 'autoconf': True, 'dhcp': True}, 'lldp': {'enabled': False}, 'mac-address': '52:54:00:91:E4:4E', 'mtu': 9000}]}
--- output omitted ---
2021-06-29 11:29:05,760 root DEBUG Async action: Update profile uuid:2bdee700-f62b-365a-bd1d-69d9c31a9f0c iface:eth0 type:ethernet started
2021-06-29 11:29:05,792 root DEBUG Async action: Update profile uuid:2bdee700-f62b-365a-bd1d-69d9c31a9f0c iface:eth0 type:ethernet finished
```
现在,使用 `ip` 命令和 `eth0` 的配置文件来检查 `eth0``MTU` 是不是 9000 字节。
```
$ ip link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:91:e4:4e brd ff:ff:ff:ff:ff:ff
altname enp1s0
$ sudo cat /etc/NetworkManager/system-connections/eth0.nmconnection
[sudo] password for admin:
[connection]
id=eth0
uuid=2bdee700-f62b-365a-bd1d-69d9c31a9f0c
type=ethernet
interface-name=eth0
lldp=0
permissions=
[ethernet]
cloned-mac-address=52:54:00:91:E4:4E
mac-address-blacklist=
mtu=9000
[ipv4]
dhcp-client-id=mac
dhcp-timeout=2147483647
dns-search=
method=auto
[ipv6]
addr-gen-mode=eui64
dhcp-duid=ll
dhcp-iaid=mac
dhcp-timeout=2147483647
dns-search=
method=auto
ra-timeout=2147483647
[proxy]
```
#### 基于文件的配置模式的例子
让我们使用基于文件的方法来设置一个新的配置状态。这里我们禁用 `eth1` 接口的 IPv6 配置。
首先,创建一个 yaml 文件来定义 `eth1` 接口的期望状态。使用 `nmstatectl show` 来保存当前设置,然后使用 `nmstatectl edit` 来禁用 IPv6。
```
$ nmstatectl show eth1 > eth1.yaml
$ vi eth1.yaml
---
dns-resolver:
config: {}
running:
search: []
server:
- 192.168.122.1
route-rules:
config: []
routes:
config: []
running:
- destination: fe80::/64
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
- destination: 0.0.0.0/0
metric: 101
next-hop-address: 192.168.122.1
next-hop-interface: eth1
table-id: 254
- destination: 192.168.122.0/24
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
interfaces:
- name: eth1
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 192.168.122.108
prefix-length: 24
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
dhcp: true
ipv6:
enabled: false
address:
- ip: fe80::5054:ff:fe3c:9b04
prefix-length: 64
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
autoconf: true
dhcp: true
lldp:
enabled: false
mac-address: 52:54:00:3C:9B:04
mtu: 1500
```
保存新的配置后,用它来应用新的状态:
```
$ sudo nmstatectl apply eth1.yaml
2021-06-29 12:17:21,531 root DEBUG Nmstate version: 1.0.3
2021-06-29 12:17:21,531 root DEBUG Applying desire state: {'dns-resolver': {'config': {}, 'running': {'search': [], 'server': ['192.168.122.1']}}, 'route-rules': {'config': []}, 'routes': {'config': [], 'running': [{'destination': 'fe80::/64', 'metric': 101, 'next-hop-address': '', 'next-hop-interface': 'eth1', 'table-id': 254}, {'destination': '0.0.0.0/0', 'metric': 101, 'next-hop-address': '192.168.122.1', 'next-hop-interface': 'eth1', 'table-id': 254}, {'destination': '192.168.122.0/24', 'metric': 101, 'next-hop-address': '', 'next-hop-interface': 'eth1', 'table-id': 254}]}, 'interfaces': [{'name': 'eth1', 'type': 'ethernet', 'state': 'up', 'ipv4': {'enabled': True, 'address': [{'ip': '192.168.122.108', 'prefix-length': 24}], 'auto-dns': True, 'auto-gateway': True, 'auto-route-table-id': 0, 'auto-routes': True, 'dhcp': True}, 'ipv6': {'enabled': False}, 'lldp': {'enabled': False}, 'mac-address': '52:54:00:3C:9B:04', 'mtu': 1500}]}
--- output omitted ---
2021-06-29 12:17:21,582 root DEBUG Async action: Update profile uuid:5d7244cb-673d-3b88-a675-32e31fad4347 iface:eth1 type:ethernet started
2021-06-29 12:17:21,587 root DEBUG Async action: Update profile uuid:5d7244cb-673d-3b88-a675-32e31fad4347 iface:eth1 type:ethernet finished
--- output omitted ---
Desired state applied:
---
dns-resolver:
config: {}
running:
search: []
server:
- 192.168.122.1
route-rules:
config: []
routes:
config: []
running:
- destination: fe80::/64
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
- destination: 0.0.0.0/0
metric: 101
next-hop-address: 192.168.122.1
next-hop-interface: eth1
table-id: 254
- destination: 192.168.122.0/24
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
interfaces:
- name: eth1
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 192.168.122.108
prefix-length: 24
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
dhcp: true
ipv6:
enabled: false
lldp:
enabled: false
mac-address: 52:54:00:3C:9B:04
mtu: 1500
```
你可以检查看到 `eth1` 接口没有配置任何 IPv6
```
$ ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.122.238/24 fe80::5054:ff:fe91:e44e/64
eth1 UP 192.168.122.108/24
$ sudo cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
uuid=5d7244cb-673d-3b88-a675-32e31fad4347
type=ethernet
interface-name=eth1
lldp=0
permissions=
[ethernet]
cloned-mac-address=52:54:00:3C:9B:04
mac-address-blacklist=
mtu=1500
[ipv4]
dhcp-client-id=mac
dhcp-timeout=2147483647
dns-search=
method=auto
[ipv6]
addr-gen-mode=eui64
dhcp-duid=ll
dhcp-iaid=mac
dns-search=
method=disabled
[proxy]
```
#### 临时应用改变
NMState 的一个有趣的功能允许你临时配置一个期望的网络状态。如果你对这个配置感到满意,你可以事后提交。否则,当超时(默认为 60 秒)过后,它将回滚。
修改前面例子中的 `eth1` 配置,使它有一个 IPv4 静态地址,而不是通过 DHCP 动态获得。
```
$ vi eth1.yaml
---
dns-resolver:
config: {}
running:
search: []
server:
- 192.168.122.1
route-rules:
config: []
routes:
config: []
running:
- destination: fe80::/64
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
- destination: 0.0.0.0/0
metric: 101
next-hop-address: 192.168.122.1
next-hop-interface: eth1
table-id: 254
- destination: 192.168.122.0/24
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
interfaces:
- name: eth1
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 192.168.122.110
prefix-length: 24
auto-dns: true
auto-gateway: true
auto-route-table-id: 0
auto-routes: true
dhcp: false
ipv6:
enabled: false
lldp:
enabled: false
mac-address: 52:54:00:3C:9B:04
mtu: 1500
```
现在,使用选项 `no-commit` 临时应用这个配置,让它只在 30 秒内有效。这可以通过添加选项 `timeout` 来完成。同时,我们将运行 `ip -br a` 命令三次,看看配置在 `eth1` 接口的 IPv4 地址是如何变化的,然后配置就会回滚。
```
$ ip -br a && sudo nmstatectl apply --no-commit --timeout 30 eth1.yaml && sleep 10 && ip -br a && sleep 25 && ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.122.238/24 fe80::5054:ff:fe91:e44e/64
eth1 UP 192.168.122.108/24
2021-06-29 17:29:18,266 root DEBUG Nmstate version: 1.0.3
2021-06-29 17:29:18,267 root DEBUG Applying desire state: {'dns-resolver': {'config': {}, 'running': {'search': [], 'server': ['192.168.122.1']}}, 'route-rules': {'config': []}, 'routes': {'config': [], 'running': [{'destination': 'fe80::/64', 'metric': 101, 'next-hop-address': '', 'next-hop-interface': 'eth1', 'table-id': 254}, {'destination': '0.0.0.0/0', 'metric': 101, 'next-hop-address': '192.168.122.1', 'next-hop-interface': 'eth1', 'table-id': 254}, {'destination': '192.168.122.0/24', 'metric': 101, 'next-hop-address': '', 'next-hop-interface': 'eth1', 'table-id': 254}]}, 'interfaces': [{'name': 'eth1', 'type': 'ethernet', 'state': 'up', 'ipv4': {'enabled': True, 'address': [{'ip': '192.168.122.110', 'prefix-length': 24}], 'dhcp': False}, 'ipv6': {'enabled': False}, 'lldp': {'enabled': False}, 'mac-address': '52:54:00:3C:9B:04', 'mtu': 1500}]}
--- output omitted ---
Desired state applied:
---
dns-resolver:
config: {}
running:
search: []
server:
- 192.168.122.1
route-rules:
config: []
routes:
config: []
running:
- destination: fe80::/64
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
- destination: 0.0.0.0/0
metric: 101
next-hop-address: 192.168.122.1
next-hop-interface: eth1
table-id: 254
- destination: 192.168.122.0/24
metric: 101
next-hop-address: ''
next-hop-interface: eth1
table-id: 254
interfaces:
- name: eth1
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 192.168.122.110
prefix-length: 24
dhcp: false
ipv6:
enabled: false
lldp:
enabled: false
mac-address: 52:54:00:3C:9B:04
mtu: 1500
Checkpoint: NetworkManager|/org/freedesktop/NetworkManager/Checkpoint/7
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.122.238/24 fe80::5054:ff:fe91:e44e/64
eth1 UP 192.168.122.110/24
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.122.238/24 fe80::5054:ff:fe91:e44e/64
eth1 UP 192.168.122.108/24
```
从上面可以看到,`eth1` 的 IP 地址从 `192.168.122.108` 暂时变成了 `192.168.122.110`,然后在超时结束后又回到了 `192.168.122.108`
### 总结
NMState 是一个声明式的网络配置工具,目前可以通过 NetworkManager API 在主机中应用所需的网络配置状态。这种状态既可以用文本编辑器交互式地定义,也可以用基于文件的方法创建一个 yaml 或 json 文件。
这种工具提供了“基础设施即代码”,它可以自动化网络任务,也减少了使用传统配置方法可能出现的潜在错误配置或不稳定的网络情况。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/nmstate-a-declarative-networking-config-tool/
作者:[Maurizio Garcia][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://fedoramagazine.org/author/malgnuz/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/07/magic-816x345.jpg
[2]: https://unsplash.com/@marigard?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/magic?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://nmstate.io/
[5]: https://github.com/nmstate/nmstate

View File

@@ -0,0 +1,666 @@
[#]: subject: "Code memory safety and efficiency by example"
[#]: via: "https://opensource.com/article/21/8/memory-programming-c"
[#]: author: "Marty Kalin https://opensource.com/users/mkalindepauledu"
[#]: collector: "lujun9972"
[#]: translator: "unigeorge"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13845-1.html"
实例讲解代码之内存安全与效率
======
> 了解有关内存安全和效率的更多信息。
![](https://img.linux.net.cn/data/attachment/album/202110/03/101238cd0hgdrhamzab7hj.jpg)
C 是一种高级语言,同时具有“<ruby>接近金属<rt>close-to-the-metal</rt></ruby>”LCTT 译注:即“接近人类思维方式”的反义词)的特性,这使得它有时看起来更像是一种可移植的汇编语言,而不像 Java 或 Python 这样的兄弟语言。内存管理作为上述特性之一,涵盖了正在执行的程序对内存的安全和高效使用。本文通过 C 语言代码示例,以及现代 C 语言编译器生成的汇编语言代码段,详细介绍了内存安全性和效率。
尽管代码示例是用 C 语言编写的,但安全高效的内存管理指南对于 C++ 是同样适用的。这两种语言在很多细节上有所不同例如C++ 具有 C 所缺乏的面向对象特性和泛型),但在内存管理方面面临的挑战是一样的。
### 执行中程序的内存概述
对于正在执行的程序(又名 _<ruby>进程<rt>process</rt></ruby>_),内存被划分为三个区域:**<ruby>栈<rt>stack</rt></ruby>**、**<ruby>堆<rt>heap</rt></ruby>** 和 **<ruby>静态区<rt>static area</rt></ryby>**。下文会给出每个区域的概述,以及完整的代码示例。
作为通用 CPU 寄存器的替补_栈_ 为代码块(例如函数或循环体)中的局部变量提供暂存器存储。传递给函数的参数在此上下文中也视作局部变量。看一下下面这个简短的示例:
```
void some_func(int a, int b) {
   int n;
   ...
}
```
通过 `a``b` 传递的参数以及局部变量 `n` 的存储会在栈中,除非编译器可以找到通用寄存器。编译器倾向于优先将通用寄存器用作暂存器,因为 CPU 对这些寄存器的访问速度很快(一个时钟周期)。然而,这些寄存器在台式机、笔记本电脑和手持机器的标准架构上很少(大约 16 个)。
在只有汇编语言程序员才能看到的实施层面,栈被组织为具有 `push`(插入)和 `pop`(删除)操作的 LIFO后进先出列表。 `top` 指针可以作为偏移的基地址;这样,除了 `top` 之外的栈位置也变得可访问了。例如,表达式 `top+16` 指向堆栈的 `top` 指针上方 16 个字节的位置,表达式 `top-16` 指向 `top` 指针下方 16 个字节的位置。因此,可以通过 `top` 指针访问实现了暂存器存储的栈的位置。在标准的 ARM 或 Intel 架构中,栈从高内存地址增长到低内存地址;因此,减小某进程的 `top` 就是增大其栈规模。
使用栈结构就意味着轻松高效地使用内存。编译器(而非程序员)会编写管理栈的代码,管理过程通过分配和释放所需的暂存器存储来实现;程序员声明函数参数和局部变量,将实现过程交给编译器。此外,完全相同的栈存储可以在连续的函数调用和代码块(如循环)中重复使用。精心设计的模块化代码会将栈存储作为暂存器的首选内存选项,同时优化编译器要尽可能使用通用寄存器而不是栈。
**堆** 提供的存储是通过程序员代码显式分配的,堆分配的语法因语言而异。在 C 中,成功调用库函数 `malloc`(或其变体 `calloc` 等)会分配指定数量的字节(在 C++ 和 Java 等语言中,`new` 运算符具有相同的用途)。编程语言在如何释放堆分配的存储方面有着巨大的差异:
* 在 Java、Go、Lisp 和 Python 等语言中,程序员不会显式释放动态分配的堆存储。
例如,下面这个 Java 语句为一个字符串分配了堆存储,并将这个堆存储的地址存储在变量 `greeting` 中:
```
String greeting = new String("Hello, world!");
```
Java 有一个垃圾回收器它是一个运行时实用程序如果进程无法再访问自己分配的堆存储回收器可以使其自动释放。因此Java 堆释放是通过垃圾收集器自动进行的。在上面的示例中,垃圾收集器将在变量 `greeting` 超出作用域后,释放字符串的堆存储。
* Rust 编译器会编写堆释放代码。这是 Rust 在不依赖垃圾回收器的情况下,使堆释放实现自动化的开创性努力,但这也会带来运行时复杂性和开销。向 Rust 的努力致敬!
* 在 C和 C++)中,堆释放是程序员的任务。程序员调用 `malloc` 分配堆存储,然后负责相应地调用库函数 `free` 来释放该存储空间(在 C++ 中,`new` 运算符分配堆存储,而 `delete` 和 `delete[]` 运算符释放此类存储)。下面是一个 C 语言代码示例:
```
char* greeting = malloc(14);       /* 14 heap bytes */
strcpy(greeting, "Hello, world!"); /* copy greeting into bytes */
puts(greeting);                    /* print greeting */
free(greeting);                    /* free malloced bytes */
```
C 语言避免了垃圾回收器的成本和复杂性,但也不过是让程序员承担了堆释放的任务。
内存的 **静态区** 为可执行代码(例如 C 语言函数、字符串文字例如“Hello, world!”)和全局变量提供存储空间:
```
int n;                       /* global variable */
int main() {                 /* function */
   char* msg = "No comment"; /* string literal */
   ...
}
```
该区域是静态的,因为它的大小从进程执行开始到结束都固定不变。由于静态区相当于进程固定大小的内存占用,因此经验法则是通过避免使用全局数组等方法来使该区域尽可能小。
下文会结合代码示例对本节概述展开进一步讲解。
### 栈存储
想象一个有各种连续执行的任务的程序,任务包括了处理每隔几分钟通过网络下载并存储在本地文件中的数字数据。下面的 `stack` 程序简化了处理流程(仅是将奇数整数值转换为偶数),而将重点放在栈存储的好处上。
```
#include <stdio.h>
#include <stdlib.h>
#define Infile   "incoming.dat"
#define Outfile  "outgoing.dat"
#define IntCount 128000  /* 128,000 */
void other_task1() { /*...*/ }
void other_task2() { /*...*/ }
void process_data(const char* infile,
          const char* outfile,
          const unsigned n) {
  int nums[n];
  FILE* input = fopen(infile, "r");
  if (NULL == infile) return;
  FILE* output = fopen(outfile, "w");
  if (NULL == output) {
    fclose(input);
    return;
  }
  fread(nums, n, sizeof(int), input); /* read input data */
  unsigned i;
  for (i = 0; i < n; i++) {
    if (1 == (nums[i] & 0x1))  /* odd parity? */
      nums[i]--;               /* make even */
  }
  fclose(input);               /* close input file */
  fwrite(nums, n, sizeof(int), output);
  fclose(output);
}
int main() {
  process_data(Infile, Outfile, IntCount);
  
  /** now perform other tasks **/
  other_task1(); /* automatically released stack storage available */
  other_task2(); /* ditto */
  
  return 0;
}
```
底部的 `main` 函数首先调用 `process_data` 函数,该函数会创建一个基于栈的数组,其大小由参数 `n` 给定(当前示例中为 128,000。因此该数组占用 `128000 * sizeof(int)` 个字节,在标准设备上达到了 512,000 字节(`int` 在这些设备上是四个字节)。然后数据会被读入数组(使用库函数 `fread`),循环处理,并保存到本地文件 `outgoing.dat`(使用库函数 `fwrite`)。
当 `process_data` 函数返回到其调用者 `main` 函数时,`process_data` 函数的大约 500MB 栈暂存器可供 `stack` 程序中的其他函数用作暂存器。在此示例中,`main` 函数接下来调用存根函数 `other_task1` 和 `other_task2`。这三个函数在 `main` 中依次调用,这意味着所有三个函数都可以使用相同的堆栈存储作为暂存器。因为编写栈管理代码的是编译器而不是程序员,所以这种方法对程序员来说既高效又容易。
在 C 语言中,在块(例如函数或循环体)内定义的任何变量默认都有一个 `auto` 存储类,这意味着该变量是基于栈的。存储类 `register` 现在已经过时了,因为 C 编译器会主动尝试尽可能使用 CPU 寄存器。只有在块内定义的变量可能是 `register`,如果没有可用的 CPU 寄存器,编译器会将其更改为 `auto`。基于栈的编程可能是不错的首选方式,但这种风格确实有一些挑战性。下面的 `badStack` 程序说明了这点。
```
#include <stdio.h>;
const int* get_array(const unsigned n) {
  int arr[n]; /* stack-based array */
  unsigned i;
  for (i = 0; i < n; i++) arr[i] = 1 + 1;
  return arr;  /** ERROR **/
}
int main() {
  const unsigned n = 16;
  const int* ptr = get_array(n);
  
  unsigned i;
  for (i = 0; i < n; i++) printf("%i ", ptr[i]);
  puts("\n");
  return 0;
}
```
`badStack` 程序中的控制流程很简单。`main` 函数使用 16LCTT 译注:原文为 128应为作者笔误作为参数调用函数 `get_array`,然后被调用函数会使用传入参数来创建对应大小的本地数组。`get_array` 函数会初始化数组并返回给 `main` 中的数组标识符 `arr`。 `arr` 是一个指针常量,保存数组的第一个 `int` 元素的地址。
当然,本地数组 `arr` 可以在 `get_array` 函数中访问,但是一旦 `get_array` 返回,就不能合法访问该数组。尽管如此,`main` 函数会尝试使用函数 `get_array` 返回的堆栈地址 `arr` 来打印基于栈的数组。现代编译器会警告错误。例如,下面是来自 GNU 编译器的警告:
```
badStack.c: In function 'get_array':
badStack.c:9:10: warning: function returns address of local variable [-Wreturn-local-addr]
return arr;  /** ERROR **/
```
一般规则是,如果使用栈存储实现局部变量,应该仅在该变量所在的代码块内,访问这块基于栈的存储(在本例中,数组指针 `arr` 和循环计数器 `i` 均为这样的局部变量)。因此,函数永远不应该返回指向基于栈存储的指针。
### 堆存储
接下来使用若干代码示例凸显在 C 语言中使用堆存储的优点。在第一个示例中,使用了最优方案分配、使用和释放堆存储。第二个示例(在下一节中)将堆存储嵌套在了其他堆存储中,这会使其释放操作变得复杂。
```
#include <stdio.h>
#include <stdlib.h>
int* get_heap_array(unsigned n) {
  int* heap_nums = malloc(sizeof(int) * n); 
  
  unsigned i;
  for (i = 0; i < n; i++)
    heap_nums[i] = i + 1;  /* initialize the array */
  
  /* stack storage for variables heap_nums and i released
     automatically when get_num_array returns */
  return heap_nums; /* return (copy of) the pointer */
}
int main() {
  unsigned n = 100, i;
  int* heap_nums = get_heap_array(n); /* save returned address */
  
  if (NULL == heap_nums) /* malloc failed */
    fprintf(stderr, "%s\n", "malloc(...) failed...");
  else {
    for (i = 0; i < n; i++) printf("%i\n", heap_nums[i]);
    free(heap_nums); /* free the heap storage */
  }
  return 0; 
}
```
上面的 `heap` 程序有两个函数: `main` 函数使用参数(示例中为 100调用 `get_heap_array` 函数,参数用来指定数组应该有多少个 `int` 元素。因为堆分配可能会失败,`main` 函数会检查 `get_heap_array` 是否返回了 `NULL`;如果是,则表示失败。如果分配成功,`main` 将打印数组中的 `int` 值,然后立即调用库函数 `free` 来对堆存储解除分配。这就是最优的方案。
`get_heap_array` 函数以下列语句开头,该语句值得仔细研究一下:
```
int* heap_nums = malloc(sizeof(int) * n); /* heap allocation */
```
`malloc` 库函数及其变体函数针对字节进行操作;因此,`malloc` 的参数是 `n` 个 `int` 类型元素所需的字节数(`sizeof(int)` 在标准现代设备上是四个字节)。`malloc` 函数返回所分配字节段的首地址,如果失败则返回 `NULL` .
如果成功调用 `malloc`,在现代台式机上其返回的地址大小为 64 位。在手持设备和早些时候的台式机上,该地址的大小可能是 32 位,或者甚至更小,具体取决于其年代。堆分配数组中的元素是 `int` 类型,这是一个四字节的有符号整数。这些堆分配的 `int` 的地址存储在基于栈的局部变量 `heap_nums` 中。可以参考下图:
```
                 heap-based
 stack-based        /
     \        +----+----+   +----+
 heap-nums--->|int1|int2|...|intN|
              +----+----+   +----+
```
一旦 `get_heap_array` 函数返回,指针变量 `heap_nums` 的栈存储将自动回收——但动态 `int` 数组的堆存储仍然存在,这就是 `get_heap_array` 函数返回这个地址(的副本)给 `main` 函数的原因:它现在负责在打印数组的整数后,通过调用库函数 `free` 显式释放堆存储:
```
free(heap_nums); /* free the heap storage */
```
`malloc` 函数不会初始化堆分配的存储空间,因此里面是随机值。相比之下,其变体函数 `calloc` 会将分配的存储初始化为零。这两个函数都返回 `NULL` 来表示分配失败。
在 `heap` 示例中,`main` 函数在调用 `free` 后会立即返回,正在执行的程序会终止,这会让系统回收所有已分配的堆存储。尽管如此,程序员应该养成在不再需要时立即显式释放堆存储的习惯。
### 嵌套堆分配
下一个代码示例会更棘手一些。C 语言有很多返回指向堆存储的指针的库函数。下面是一个常见的使用情景:
1、C 程序调用一个库函数,该函数返回一个指向基于堆的存储的指针,而指向的存储通常是一个聚合体,如数组或结构体:
```
SomeStructure* ptr = lib_function(); /* returns pointer to heap storage */
```
2、 然后程序使用所分配的存储。
3、 对于清理而言,问题是对 `free` 的简单调用是否会清理库函数分配的所有堆分配存储。例如,`SomeStructure` 实例可能有指向堆分配存储的字段。一个特别麻烦的情况是动态分配的结构体数组,每个结构体有一个指向又一层动态分配的存储的字段。下面的代码示例说明了这个问题,并重点关注了如何设计一个可以安全地为客户端提供堆分配存储的库。
```
#include <stdio.h>
#include <stdlib.h>
typedef struct {
  unsigned id;
  unsigned len;
  float*   heap_nums;
} HeapStruct;
unsigned structId = 1;
HeapStruct* get_heap_struct(unsigned n) {
  /* Try to allocate a HeapStruct. */
  HeapStruct* heap_struct = malloc(sizeof(HeapStruct));
  if (NULL == heap_struct) /* failure? */
    return NULL;           /* if so, return NULL */
  /* Try to allocate floating-point aggregate within HeapStruct. */
  heap_struct->heap_nums = malloc(sizeof(float) * n);
  if (NULL == heap_struct->heap_nums) {  /* failure? */
    free(heap_struct);                   /* if so, first free the HeapStruct */
    return NULL;                         /* then return NULL */
  }
  /* Success: set fields */
  heap_struct->id = structId++;
  heap_struct->len = n;
  return heap_struct; /* return pointer to allocated HeapStruct */
}
void free_all(HeapStruct* heap_struct) {
  if (NULL == heap_struct) /* NULL pointer? */
    return;                /* if so, do nothing */
  
  free(heap_struct->heap_nums); /* first free encapsulated aggregate */
  free(heap_struct);            /* then free containing structure */  
}
int main() {
  const unsigned n = 100;
  HeapStruct* hs = get_heap_struct(n); /* get structure with N floats */
  /* Do some (meaningless) work for demo. */
  unsigned i;
  for (i = 0; i < n; i++) hs->heap_nums[i] = 3.14 + (float) i;
  for (i = 0; i < n; i += 10) printf("%12f\n", hs->heap_nums[i]);
  free_all(hs); /* free dynamically allocated storage */
  
  return 0;
}
```
上面的 `nestedHeap` 程序示例以结构体 `HeapStruct` 为中心,结构体中又有名为 `heap_nums` 的指针字段:
```
typedef struct {
  unsigned id;
  unsigned len;
  float*   heap_nums; /** pointer **/
} HeapStruct;
```
函数 `get_heap_struct` 尝试为 `HeapStruct` 实例分配堆存储,这需要为字段 `heap_nums` 指向的若干个 `float` 变量分配堆存储。如果成功调用 `get_heap_struct` 函数,并将指向堆分配结构体的指针以 `hs` 命名,其结果可以描述如下:
```
hs-->HeapStruct instance
        id
        len
        heap_nums-->N contiguous float elements
```
在 `get_heap_struct` 函数中,第一个堆分配过程很简单:
```
HeapStruct* heap_struct = malloc(sizeof(HeapStruct));
if (NULL == heap_struct) /* failure? */
  return NULL;           /* if so, return NULL */
```
`sizeof(HeapStruct)` 包括了 `heap_nums` 字段的字节数32 位机器上为 464 位机器上为 8`heap_nums` 字段则是指向动态分配数组中的 `float` 元素的指针。那么,问题关键在于 `malloc` 为这个结构体传送了字节空间还是表示失败的 `NULL`;如果是 `NULL``get_heap_struct` 函数就也返回 `NULL` 以通知调用者堆分配失败。
第二步尝试堆分配的过程更复杂,因为在这一步,`HeapStruct` 的堆存储已经分配好了:
```
heap_struct->heap_nums = malloc(sizeof(float) * n);
if (NULL == heap_struct->heap_nums) {  /* failure? */
  free(heap_struct);                   /* if so, first free the HeapStruct */
  return NULL;                         /* and then return NULL */
}
```
传递给 `get_heap_struct` 函数的参数 `n` 指明动态分配的 `heap_nums` 数组中应该有多少个 `float` 元素。如果可以分配所需的若干个 `float` 元素,则该函数在返回 `HeapStruct` 的堆地址之前会设置结构的 `id` 和 `len` 字段。 但是,如果尝试分配失败,则需要两个步骤来实现最优方案:
1、 必须释放 `HeapStruct` 的存储以避免内存泄漏。对于调用 `get_heap_struct` 的客户端函数而言,没有动态 `heap_nums` 数组的 `HeapStruct` 可能就是没用的;因此,`HeapStruct` 实例的字节空间应该显式释放,以便系统可以回收这些空间用于未来的堆分配。
2、 返回 `NULL` 以标识失败。
如果成功调用 `get_heap_struct` 函数,那么释放堆存储也很棘手,因为它涉及要以正确顺序进行的两次 `free` 操作。因此,该程序设计了一个 `free_all` 函数,而不是要求程序员再去手动实现两步释放操作。回顾一下,`free_all` 函数是这样的:
```
void free_all(HeapStruct* heap_struct) {
  if (NULL == heap_struct) /* NULL pointer? */
    return;                /* if so, do nothing */
  
  free(heap_struct->heap_nums); /* first free encapsulated aggregate */
  free(heap_struct);            /* then free containing structure */  
}
```
检查完参数 `heap_struct` 不是 `NULL` 值后,函数首先释放 `heap_nums` 数组,这步要求 `heap_struct` 指针此时仍然是有效的。先释放 `heap_struct` 的做法是错误的。一旦 `heap_nums` 被释放,`heap_struct` 就可以释放了。如果 `heap_struct` 被释放,但 `heap_nums` 没有被释放,那么数组中的 `float` 元素就会泄漏:仍然分配了字节空间,但无法被访问到——因此一定要记得释放 `heap_nums`。存储泄漏将一直持续,直到 `nestedHeap` 程序退出,系统回收泄漏的字节时为止。
关于 `free` 库函数的注意事项就是要有顺序。回想一下上面的调用示例:
```
free(heap_struct->heap_nums); /* first free encapsulated aggregate */
free(heap_struct);            /* then free containing structure */
```
这些调用释放了分配的存储空间——但它们并 _不是_ 将它们的操作参数设置为 `NULL``free` 函数会获取地址的副本作为参数;因此,将副本更改为 `NULL` 并不会改变原地址上的参数值)。例如,在成功调用 `free` 之后,指针 `heap_struct` 仍然持有一些堆分配字节的堆地址,但是现在使用这个地址将会产生错误,因为对 `free` 的调用使得系统有权回收然后重用这些分配过的字节。
使用 `NULL` 参数调用 `free` 没有意义,但也没有什么坏处。而在非 `NULL` 的地址上重复调用 `free` 会导致不确定结果的错误:
```
free(heap_struct);  /* 1st call: ok */
free(heap_struct);  /* 2nd call: ERROR */
```
### 内存泄漏和堆碎片化
“内存泄漏”是指动态分配的堆存储变得不再可访问。看一下相关的代码段:
```
float* nums = malloc(sizeof(float) * 10); /* 10 floats */
nums[0] = 3.14f;                          /* and so on */
nums = malloc(sizeof(float) * 25);        /* 25 new floats */
```
假如第一个 `malloc` 成功,第二个 `malloc` 会再将 `nums` 指针重置为 `NULL`(分配失败情况下)或是新分配的 25 个 `float` 中第一个的地址。最初分配的 10 个 `float` 元素的堆存储仍然处于被分配状态,但此时已无法再对其访问,因为 `nums` 指针要么指向别处,要么是 `NULL`。结果就是造成了 40 个字节(`sizeof(float) * 10`)的泄漏。
在第二次调用 `malloc` 之前,应该释放最初分配的存储空间:
```
float* nums = malloc(sizeof(float) * 10); /* 10 floats */
nums[0] = 3.14f;                          /* and so on */
free(nums);                               /** good **/
nums = malloc(sizeof(float) * 25);        /* no leakage */
```
即使没有泄漏,堆也会随着时间的推移而碎片化,需要对系统进行碎片整理。例如,假设两个最大的堆块当前的大小分别为 200MB 和 100MB。然而这两个堆块并不连续进程 `P` 此时又需要分配 250MB 的连续堆存储。在进行分配之前,系统可能要对堆进行 _碎片整理_ 以给 `P` 提供 250MB 连续存储空间。碎片整理很复杂,因此也很耗时。
内存泄漏会创建处于已分配状态但不可访问的堆块,从而会加速碎片化。因此,释放不再需要的堆存储是程序员帮助减少碎片整理需求的一种方式。
### 诊断内存泄漏的工具
有很多工具可用于分析内存效率和安全性,其中我最喜欢的是 [valgrind][11]。为了说明该工具如何处理内存泄漏,这里给出 `leaky` 示例程序:
```
#include <stdio.h>
#include <stdlib.h>
int* get_ints(unsigned n) {
  int* ptr = malloc(n * sizeof(int));
  if (ptr != NULL) {
    unsigned i;
    for (i = 0; i < n; i++) ptr[i] = i + 1;
  }
  return ptr;
}
void print_ints(int* ptr, unsigned n) {
  unsigned i;
  for (i = 0; i < n; i++) printf("%3i\n", ptr[i]);
}
int main() {
  const unsigned n = 32;
  int* arr = get_ints(n);
  if (arr != NULL) print_ints(arr, n);
  /** heap storage not yet freed... **/
  return 0;
}
```
`main` 函数调用了 `get_ints` 函数,后者会试着从堆中 `malloc` 32 个 4 字节的 `int`,然后初始化动态数组(如果 `malloc` 成功)。初始化成功后,`main` 函数会调用 `print_ints`函数。程序中并没有调用 `free` 来对应 `malloc` 操作;因此,内存泄漏了。
如果安装了 `valgrind` 工具箱,下面的命令会检查 `leaky` 程序是否存在内存泄漏(`%` 是命令行提示符):
```
% valgrind --leak-check=full ./leaky
```
绝大部分输出都在下面给出了。左边的数字 207683 是正在执行的 `leaky` 程序的进程标识符。这份报告给出了泄漏发生位置的详细信息,本例中位置是在 `main` 函数所调用的 `get_ints` 函数中对 `malloc` 的调用处。
```
==207683== HEAP SUMMARY:
==207683==   in use at exit: 128 bytes in 1 blocks
==207683==   total heap usage: 2 allocs, 1 frees, 1,152 bytes allocated
==207683== 
==207683== 128 bytes in 1 blocks are definitely lost in loss record 1 of 1
==207683==   at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==207683==   by 0x109186: get_ints (in /home/marty/gc/leaky)
==207683==   by 0x109236: main (in /home/marty/gc/leaky)
==207683== 
==207683== LEAK SUMMARY:
==207683==   definitely lost: 128 bytes in 1 blocks
==207683==   indirectly lost: 0 bytes in 0 blocks
==207683==   possibly lost: 0 bytes in 0 blocks
==207683==   still reachable: 0 bytes in 0 blocks
==207683==   suppressed: 0 bytes in 0 blocks
```
如果把 `main` 函数改成在对 `print_ints` 的调用之后,再加上一个对 `free` 的调用,`valgrind` 就会对 `leaky` 程序给出一个干净的内存健康清单:
```
==218462== All heap blocks were freed -- no leaks are possible
```
### 静态区存储
在正统的 C 语言中,函数必须在所有块之外定义。这是一些 C 编译器支持的特性,杜绝了在另一个函数体内定义一个函数的可能。我举的例子都是在所有块之外定义的函数。这样的函数要么是 `static` ,即静态的,要么是 `extern`,即外部的,其中 `extern` 是默认值。
C 语言中,以 `static` 或 `extern` 修饰的函数和变量驻留在内存中所谓的 **静态区** 中,因为在程序执行期间该区域大小是固定不变的。这两个存储类型的语法非常复杂,我们应该回顾一下。在回顾之后,会有一个完整的代码示例来生动展示语法细节。在所有块之外定义的函数或变量默认为 `extern`;因此,函数和变量要想存储类型为 `static` ,必须显式指定:
```
/** file1.c: outside all blocks, five definitions  **/
int foo(int n) { return n * 2; }     /* extern by default */
static int bar(int n) { return n; }  /* static */
extern int baz(int n) { return -n; } /* explicitly extern */
int num1;        /* extern */
static int num2; /* static */
```
`extern` 和 `static` 的区别在于作用域:`extern` 修饰的函数或变量可以实现跨文件可见(需要声明)。相比之下,`static` 修饰的函数仅在 _定义_ 该函数的文件中可见,而 `static` 修饰的变量仅在 _定义_ 该变量的文件(或文件中的块)中可见:
```
static int n1;    /* scope is the file */
void func() {
   static int n2; /* scope is func's body */
   ...
}
```
如果在所有块之外定义了 `static` 变量,例如上面的 `n1`,该变量的作用域就是定义变量的文件。无论在何处定义 `static` 变量,变量的存储都在内存的静态区中。
`extern` 函数或变量在给定文件中的所有块之外定义,但这样定义的函数或变量也可以在其他文件中声明。典型的做法是在头文件中 _声明_ 这样的函数或变量,只要需要就可以包含进来。下面这些简短的例子阐述了这些棘手的问题。
假设 `extern` 函数 `foo` 在 `file1.c` 中 _定义_有无关键字 `extern` 效果都一样:
```
/** file1.c **/
int foo(int n) { return n * 2; } /* definition has a body {...} */
```
必须在其他文件(或其中的块)中使用显式的 `extern` _声明_ 此函数才能使其可见。以下是使 `extern` 函数 `foo` 在文件 `file2.c` 中可见的声明语句:
```
/** file2.c: make function foo visible here **/
extern int foo(int); /* declaration (no body) */
```
回想一下,函数声明没有用大括号括起来的主体,而函数定义会有这样的主体。
为了便于查看,函数和变量声明通常会放在头文件中。准备好需要声明的源代码文件,然后就可以 `#include` 相关的头文件。下一节中的 `staticProg` 程序演示了这种方法。
至于 `extern` 的变量,规则就变得更棘手了(很抱歉增加了难度!)。任何 `extern` 的对象——无论函数或变量——必须 _定义_ 在所有块之外。此外,在所有块之外定义的变量默认为 `extern`
```
/** outside all blocks **/
int n; /* defaults to extern */
```
但是,只有在变量的 _定义_ 中显式初始化变量时,`extern` 才能在变量的 _定义_ 中显式修饰LCTT 译注:换言之,如果下列代码中的 `int n1;` 行前加上 `extern`,该行就由 _定义_ 变成了 _声明_
```
/** file1.c: outside all blocks **/
int n1;             /* defaults to extern, initialized by compiler to zero */
extern int n2 = -1; /* ok, initialized explicitly */
int n3 = 9876;      /* ok, extern by default and initialized explicitly */
```
要使在 `file1.c` 中定义为 `extern` 的变量在另一个文件(例如 `file2.c`)中可见,该变量必须在 `file2.c` 中显式 _声明_ 为 `extern` 并且不能初始化(初始化会将声明转换为定义):
```
/** file2.c **/
extern int n1; /* declaration of n1 defined in file1.c */
```
为了避免与 `extern` 变量混淆,经验是在 _声明_ 中显式使用 `extern`(必须),但不要在 _定义_ 中使用(非必须且棘手)。对于函数,`extern` 在定义中是可选使用的,但在声明中是必须使用的。下一节中的 `staticProg` 示例会把这些点整合到一个完整的程序中。
### staticProg 示例
`staticProg` 程序由三个文件组成:两个 C 语言源文件(`static1.c` 和 `static2.c`)以及一个头文件(`static.h`),头文件中包含两个声明:
```
/** header file static.h **/
#define NumCount 100               /* macro */
extern int global_nums[NumCount];  /* array declaration */
extern void fill_array();          /* function declaration */
```
两个声明中的 `extern`一个用于数组另一个用于函数强调对象在别处“外部”_定义_数组 `global_nums` 在文件 `static1.c` 中定义(没有显式的 `extern`),函数 `fill_array` 在文件 `static2.c` 中定义(也没有显式的 `extern`)。每个源文件都包含了头文件 `static.h`。`static1.c` 文件定义了两个驻留在内存静态区域中的数组(`global_nums` 和 `more_nums`)。第二个数组有 `static` 修饰,这将其作用域限制为定义数组的文件 (`static1.c`)。如前所述, `extern` 修饰的 `global_nums` 则可以实现在多个文件中可见。
```
/** static1.c **/
#include <stdio.h>
#include <stdlib.h>
#include "static.h"             /* declarations */
int global_nums[NumCount];      /* definition: extern (global) aggregate */
static int more_nums[NumCount]; /* definition: scope limited to this file */
int main() {
  fill_array(); /** defined in file static2.c **/
  unsigned i;
  for (i = 0; i < NumCount; i++)
    more_nums[i] = i * -1;
  /* confirm initialization worked */
  for (i = 0; i < NumCount; i += 10) 
    printf("%4i\t%4i\n", global_nums[i], more_nums[i]);
    
  return 0;  
}
```
下面的 `static2.c` 文件中定义了 `fill_array` 函数,该函数由 `main`(在 `static1.c` 文件中)调用;`fill_array` 函数会给名为 `global_nums` 的 `extern` 数组中的元素赋值,该数组在文件 `static1.c` 中定义。使用两个文件的唯一目的是凸显 `extern` 变量或函数能够跨文件可见。
```
/** static2.c **/
#include "static.h" /** declarations **/
void fill_array() { /** definition **/
  unsigned i;
  for (i = 0; i < NumCount; i++) global_nums[i] = i + 2;
}
```
`staticProg` 程序可以用如下编译:
```
% gcc -o staticProg static1.c static2.c
```
### 从汇编语言看更多细节
现代 C 编译器能够处理 C 和汇编语言的任意组合。编译 C 源文件时,编译器首先将 C 代码翻译成汇编语言。这是对从上文 `static1.c` 文件生成的汇编语言进行保存的命令:
```
% gcc -S static1.c
```
生成的文件就是 `static1.s`。这是文件顶部的一段代码,额外添加了行号以提高可读性:
```
    .file    "static1.c"          ## line  1
    .text                         ## line  2
    .comm    global_nums,400,32   ## line  3
    .local    more_nums           ## line  4
    .comm    more_nums,400,32     ## line  5
    .section    .rodata           ## line  6
.LC0:                             ## line  7
    .string    "%4i\t%4i\n"       ## line  8
    .text                         ## line  9
    .globl    main                ## line 10
    .type    main, @function      ## line 11
main:                             ## line 12
...
```
诸如 `.file`(第 1 行)之类的汇编语言指令以句点开头。顾名思义,指令会指导汇编程序将汇编语言翻译成机器代码。`.rodata` 指令(第 6 行)表示后面是只读对象,包括字符串常量 `"%4i\t%4i\n"`(第 8 行),`main` 函数(第 12 行)会使用此字符串常量来实现格式化输出。作为标签引入(通过末尾的冒号实现)的 `main` 函数(第 12 行),同样也是只读的。
在汇编语言中,标签就是地址。标签 `main:`(第 12 行)标记了 `main` 函数代码开始的地址,标签 `.LC0:`(第 7 行)标记了格式化字符串开头所在的地址。
`global_nums`(第 3 行)和 `more_nums`(第 4 行数组的定义包含了两个数字400 是每个数组中的总字节数32 是每个数组(含 100 个 `int` 元素)中每个元素的比特数。(第 5 行中的 `.comm` 指令表示 `common name`,可以忽略。)
两个数组定义的不同之处在于 `more_nums` 被标记为 `.local`(第 4 行),这意味着其作用域仅限于其所在文件 `static1.s`。相比之下,`global_nums` 数组就能在多个文件中实现可见,包括由 `static1.c` 和 `static2.c` 文件翻译成的汇编文件。
最后,`.text` 指令在汇编代码段中出现了两次(第 2 行和第 9 行。术语“text”表示“只读”但也会涵盖一些读/写变量,例如两个数组中的元素。尽管本文展示的汇编语言是针对 Intel 架构的,但 Arm6 汇编也非常相似。对于这两种架构,`.text` 区域中的变量(本例中为两个数组中的元素)会自动初始化为零。
### 总结
C 语言中的内存高效和内存安全编程准则很容易说明,但可能会很难遵循,尤其是在调用设计不佳的库的时候。准则如下:
* 尽可能使用栈存储,进而鼓励编译器将通用寄存器用作暂存器,实现优化。栈存储代表了高效的内存使用并促进了代码的整洁和模块化。永远不要返回指向基于栈的存储的指针。
* 小心使用堆存储。C和 C++)中的重难点是确保动态分配的存储尽快解除分配。良好的编程习惯和工具(如 `valgrind`)有助于攻关这些重难点。优先选用自身提供释放函数的库,例如 `nestedHeap` 代码示例中的 `free_all` 释放函数。
* 谨慎使用静态存储,因为这种存储会自始至终地影响进程的内存占用。特别是尽量避免使用 `extern` 和 `static` 数组。
本文 C 语言代码示例可在我的网站(<https://condor.depaul.edu/mkalin>)上找到。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/8/memory-programming-c
作者:[Marty Kalin][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[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://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82 (Code going into a computer.)
[2]: http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html
[3]: http://www.opengroup.org/onlinepubs/009695399/functions/fclose.html
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/fread.html
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/fwrite.html
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/puts.html
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html
[9]: http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
[10]: http://www.opengroup.org/onlinepubs/009695399/functions/free.html
[11]: https://www.valgrind.org/

View File

@@ -0,0 +1,110 @@
[#]: subject: "below: a time traveling resource monitor"
[#]: via: "https://fedoramagazine.org/below-a-time-traveling-resource-monitor/"
[#]: author: "Daniel Xu https://fedoramagazine.org/author/dxuu/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13854-1.html"
Below一个时间旅行的资源监控器
======
![](https://img.linux.net.cn/data/attachment/album/202110/06/093522hdsb82nm1cb4b4b6.jpg)
在这篇文章中,我们将介绍 `below`:一个用于现代 Linux 系统的 Apache 2.0 许可的资源监视器。`below` 可以让你重放以前记录的数据。
![][1]
### 背景
内核的主要职责之一是调度对资源的访问。有时这可能意味着分配物理内存,使多个进程可以共享同一主机。其他时候,它可能意味着确保 CPU 时间的公平分配。在这些场景里,内核提供了机制,而将策略留给了“别人”。近来,这个“别人”通常是 systemd 或 dockerd 这样的运行时。运行时接受来自调度器或最终用户的输入(类似于运行什么和如何运行)并在内核上转动正确的旋钮和拉动正确的杠杆,从而使工作负载能够*好好*工作。
在一个完美的世界里,故事就到此结束了。然而,现实情况是,资源管理是一个复杂的、相当不透明的技术混合体,在几十年里计算技术不断发展。尽管其中一些技术有各种缺陷和死角,但最终的结果是,容器运作得比较好。虽然用户通常不需要关心这些细节,但对于基础设施运营商来说,对他们的技术架构拥有可见性是至关重要的。可见性和可调试性对于检测和调查错误的配置、问题和系统性故障至关重要。
让事情变得更加复杂的是,资源中断往往难以重现。经常需要花费数周时间等待一个问题重新出现,以便调查其根本原因。规模的扩大进一步加剧了这个问题:我们不能在*每台*主机上运行一个自定义脚本,希望在错误再次发生时记录下关键状态的片段。因此,需要更复杂的工具。这就出现了 `below`
### 动机
历史上Facebook 一直是 [atop][5] 的忠实用户。`atop` 是一个用于 Linux 的性能监视器,能够报告所有进程的活动以及各种系统级活动。与 `htop` 等工具相比,`atop` 最引人注目的功能之一是能够作为一个守护程序记录历史数据。这听起来是一个简单的功能,但在实践中,这使得调试无数的生产问题成为可能。有了足够长的数据保留,就有可能在时间上回溯,查看在问题或故障发生之前、期间和之后的主机状态。
不幸的是,随着时间的推移,人们发现`atop` 有某些不足之处。首先,<ruby>[控制组][6]<rt>cgroup</rt></ruby> 已经成为控制和监视 Linux 机器上资源的实际方式。`atop` 仍然缺乏对这一基本构建模块的支持。第二,`atop` 用自定义的 delta 压缩方法在磁盘上存储数据。这在正常情况下运行良好,但在沉重的资源压力下,主机很可能会丢失数据点。由于使用了 delta 压缩,在数据最重要的时间段内,数据可能会大面积丢失。第三,用户体验有一个陡峭的学习曲线。我们经常听到 `atop` 的资深用户说,他们喜欢密集的布局和众多的键盘绑定。然而,这也是一把双刃剑。当一个刚进入这个领域的人想要调试一个生产问题时,他们现在要同时解决两个问题:手头的问题和如何使用 `atop`
`below` 是由 Facebook 的资源控制团队为其设计和开发的,并得到了 `atop` 生产环境用户的支持。顾名思义,资源控制团队负责的是规模化的资源管理。该团队由内核开发人员、容器运行时开发人员和硬件人员组成。认识到下一代系统监控器的机会,我们在设计 `below` 时考虑到以下几点:
* 易用性:`below` 必须既能为新用户提供直观的体验,又能为日常用户提供强大的功能。
*有意义的统计数据:`below` 显示准确和有用的统计数据。即便可以,但我们尽量避免收集和倾倒统计数字。
* 灵活性:当默认设置不合适时,我们允许用户自定义他们的体验。例如包括可配置的键绑定、可配置的默认视图,以及脚本界面(默认为终端用户接口)。
### 安装
安装该软件包:
```
# dnf install -y below
```
打开记录守护进程:
```
# systemctl enable --now below
```
### 快速介绍
`below` 最常用的模式是重放模式。顾名思义,重放模式是重放以前记录的数据。假设你已经启动了记录守护程序,那么通过运行以下程序启动一个会话:
```
$ below replay --time "5 minutes ago"
```
然后你会看到控制组视图:
![][2]
如果你不知道该怎么操作,或者忘记了一个键位,按 `?` 可以进入帮助菜单。
屏幕的最上方是状态栏。状态栏显示关于当前样本的信息。你可以通过按 `t``T` 分别向前和向后移动样本。中间的部分是系统概览。系统概览包含了关于整个系统的统计数据,一般来说,这些数据总是很有用的。第三部分也是最下面的部分是多用途视图。上面的图片显示了控制组视图。此外,还有进程和系统视图,分别通过按 `p`` s` 来访问。
`↑``↓` 来移动列表选择。按回车键来折叠和展开控制组。假设你发现了一个感兴趣的控制组,你想看看它里面有哪些进程在运行。要放大进程视图,选择控制组并按 `z`
![][3]
再按 `z` 返回到控制组视图。这个视图有时会有点长。如果你对你要找的东西有一个模糊的概念,你可以通过按 `/` 并输入一个过滤器来过滤控制组名称。
![][4]
在这一点上,你可能已经注意到了一个我们还没有探索过的标签系统。要在标签中向前和向后循环,可以分别按 `Tab``Shift` + `Tab`。我们把这个问题留给读者去做练习。
### 其他功能
在底层,`below` 有一个强大的设计和架构。Facebook 正在不断升级到更新的内核,所以我们从不假设数据源是可用的。这种默契的假设使得内核和 `below `版本之间能够完全向前和向后兼容。此外,每个数据点都用 zstd 压缩并完整地存储。这解决了我们看到的 `atop` 在大规模时的 delta 压缩问题。根据我们的测试,我们的每个样本压缩可以达到平均 5 倍的压缩率。
`below` 也使用 [eBPF][8] 来收集关于短暂进程(生存时间短于数据收集间隔的进程)的信息。相比之下,`atop` 使用 BSD 进程核算来实现这一功能,这是一个已知缓慢且容易发生优先级转换的内核接口。
对于用户来说,`below` 还支持实时模式和一个转储接口。实时模式将记录守护程序和 TUI 会话合并到一个进程中。这对于浏览系统状态是很方便的,不需要为数据存储投入长期运行的守护程序或磁盘空间。转储接口是一个可编写脚本的接口,用于所有的 `below` 数据存储。转储既强大又灵活,详细的数据以 CSV、JSON 和人类可读格式提供。
### 总结
`below` 是一个 Apache 2.0 许可的开源项目,我们(`below` 的开发者)认为它比资源监控领域的现有工具具有引人注目的优势。我们已经花了大量的精力来准备 `below`,以提供开源使用,所以我们希望读者和社区有机会尝试 `below`,并报告错误和功能要求。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/below-a-time-traveling-resource-monitor/
作者:[Daniel Xu][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://fedoramagazine.org/author/dxuu/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/08/below_resource_monitor-816x345.jpg
[2]: https://fedoramagazine.org/wp-content/uploads/2021/08/image-1024x800.png
[3]: https://fedoramagazine.org/wp-content/uploads/2021/08/image-1-1024x800.png
[4]: https://fedoramagazine.org/wp-content/uploads/2021/08/image-2-1024x800.png
[5]: <https://www.atoptool.nl/>
[6]: <https://en.wikipedia.org/wiki/Cgroups>
[7]: <https://ebpf.io/>

View File

@@ -0,0 +1,181 @@
[#]: subject: "How to use BusyBox on Linux"
[#]: via: "https://opensource.com/article/21/8/what-busybox"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13840-1.html"
如何在 Linux 上使用 BusyBox
======
> BusyBox 是一个开源GPL项目提供了近 400 个常用命令的简单实现。
![](https://img.linux.net.cn/data/attachment/album/202110/01/185208x6ckkmvi0silk3vk.jpg)
我们很容易认为 Linux 的命令是理所当然的。当你安装 Linux 时,它们与系统捆绑在一起,而我们常常不问为什么它们会在那里。一些基本的命令,如 [cd][2]、[kill][3] 和 echo并不总是独立的应用程序而是实际上内置于你的 shell 中。其他如 [ls][4]、[mv][5] 和 [cat][6] 是核心工具包(通常是 GNU `coreutils`)的一部分。但在开源的世界里,总是有一些替代品,其中最有趣的是 [BusyBox][7]。
### Linux 中的 BusyBox 简介
BusyBox 是一个开源GPL项目提供近 400 个常用命令的简单实现,包括 `ls``mv``ln``mkdir``more``ps``gzip``bzip2``tar``grep`。它还包含了编程语言 `awk`、流编辑器 `sed`、文件系统检查工具 `fsck``rpm``dpkg` 软件包管理器,当然还有一个可以方便的访问所有这些命令的 shell`sh`)。简而言之,它包含了所有 POSIX 系统需要的基本命令,以执行常见的系统维护任务以及许多用户和管理任务。
事实上,它甚至包含一个 `init` 命令,可以作为 PID 1 启动以作为所有其它系统服务的父进程。换句话说BusyBox 可以作为 [systemd][8]、OpenRC、sinit、init 和其他初始化系统的替代品。
BusyBox 非常小。作为一个可执行文件,它不到 1MB所以它在 [嵌入式][9]、[边缘计算][10] 和 [物联网][11] 领域很受欢迎,因为这些场景的存储空间是很宝贵的。在容器和云计算的世界里,它作为精简的 Linux 容器镜像的基础镜像也很受欢迎。
### 极简主义
BusyBox 的部分魅力在于它的极简主义。它的所有命令都被编译到一个二进制文件里(`busybox`),它的手册只有 81 页(根据我对 `man` 送到 `pr` 管道的计算),但它涵盖了近 400 条命令。
作为一个例子的比较,这是 “原版” 的 `useradd —help` 的输出:
```
 -b, --base-dir BASE_DIR       base directory for home
 -c, --comment COMMENT         GECOS field of the new account
 -d, --home-dir HOME_DIR       home directory of the new account
 -D, --defaults                print or change the default config
 -e, --expiredate EXPIRE_DATE  expiration date of the new account
 -f, --inactive INACTIVE       password inactivity
 -g, --gid GROUP               name or ID of the primary group
 -G, --groups GROUPS           list of supplementary groups
 -h, --help                    display this help message and exit
 -k, --skel SKEL_DIR           alternative skeleton dir
 -K, --key KEY=VALUE           override /etc/login.defs
 -l, --no-log-init             do not add the user to the lastlog
 -m, --create-home             create the user's home directory
 -M, --no-create-home          do not create the user's home directory
 -N, --no-user-group           do not create a group with the user's name
 -o, --non-unique              allow users with non-unique UIDs
 -p, --password PASSWORD       encrypted password of the new account
 -r, --system                  create a system account
 -R, --root CHROOT_DIR         directory to chroot into
 -s, --shell SHELL             login shell of the new account
 -u, --uid UID                 user ID of the new account
 -U, --user-group              create a group with the same name as a user
```
而这是是同一命令的 BusyBox 版本:
```
 -h DIR    Home directory
 -g GECOS  GECOS field
 -s SHELL  Login shell
 -G GRP    Group
 -S            Create a system user
 -D            Don't assign a password
 -H            Don't create home directory
 -u UID    User id
 -k SKEL   Skeleton directory (/etc/skel)
```
这种差异是一种特性还是一种限制,取决于你是喜欢你的命令拥有 20 个选项还是 10 个选项。对于一些用户和某些用例来说BusyBox 的极简主义刚刚满足所需。对于其他人来说,它是一个很好的最小化环境,可以作为一个后备工具,或者作为安装更强大的工具的基础,比如 [Bash][12]、[Zsh][13]、GNU [Awk][14] 等等。
### 安装 BusyBox
在 Linux 上,你可以使用你的软件包管理器安装 BusyBox。例如在 Fedora 及类似发行版:
```
$ sudo dnf install busybox
```
在 Debian 及其衍生版:
```
$ sudo apt install busybox
```
在 MacOS 上,可以使用 [MacPorts][15] 或 [Homebrew][16]。在 Windows 上,可以使用 [Chocolatey][17]。
你可以将 BusyBox 设置为你的 shell使用 `chsh —shell` 命令,然后再加上 BusyBox `sh` 应用程序的路径。我把 BusyBox 放在 `/lib64` 中,但它的位置取决于你的发行版的安装位置。
```
$ which busybox
/lib64/busybox/busybox
$ chsh --shell /lib64/busybox/sh
```
用 BusyBox 全盘替换所有常见的命令要复杂一些,因为大多数发行版都是“硬接线”,会在特定的软件包寻找特定的命令。换句话说,虽然技术上可以用 BusyBox 的 `init` 替换系统的 `init`,但你的软件包管理器可能会拒绝让你删除包含 `init` 的软件包,以免你担心删除会导致系统无法启动。有一些发行版是建立在 BusyBox 之上的,所以从新环境开始可能是体验 BusyBox 系统的最简单方法。
### 试试 BusyBox
你不必为了尝试 BusyBox 而将你的 shell 永久改为 BusyBox。你可以从你当前的 shell 中启动一个 BusyBox shell。
```
$ busybox sh
~ $
```
不过你的系统仍然有安装的非 BusyBox 版本的命令,所以要体验 BusyBox 的工具,你必须把命令作为参数发给 `busybox` 可执行文件:
```
~ $ busybox echo $0
sh
~ $ busybox ls --help
BusyBox vX.YY.Z (2021-08-25 07:31:48 NZST) multi-call binary.
Usage: ls [-1AaCxdLHRFplinshrSXvctu] [-w WIDTH] [FILE]...
List directory contents
 -1  One column output
 -a  Include entries that start with .
 -A  Like -a, but exclude . and ..
 -x  List by lines
[...]
```
为了获得“完整”的 BusyBox 体验,你可以为每个命令创建一个 `busybox` 的符号链接。这很容易,只要你使用 [for 循环][18] 就行:
```
$ mkdir bbx
$ for i in $(bbx --list); do \
ln -s /path/to/busybox bbx/$i \
done
```
在你的 [路径][19] 的 _开头_ 添加这个符号链接目录,并启动 BusyBox
```
$ PATH=$(pwd)/bbx:$PATH bbx/sh
```
### 用起来
BusyBox 是一个有趣的项目,也是一个可以实现 _极简_ 计算的例子。无论你是把 BusyBox 作为 [你唤醒的][21] [古老的计算机][20] 的轻量级环境,还是作为 [嵌入式设备][22] 的用户界面,抑或试用一个新的初始化系统,就算是为了好奇,让自己重新认识那些熟悉而又陌生的命令,都会很有意思。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/8/what-busybox
作者:[Seth Kenlon][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/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bash_command_line.png?itok=k4z94W2U (bash logo on green background)
[2]: https://opensource.com/article/21/8/navigate-linux-directories
[3]: https://opensource.com/article/18/5/how-kill-process-stop-program-linux
[4]: https://opensource.com/article/19/7/master-ls-command
[5]: https://opensource.com/article/19/8/moving-files-linux-depth
[6]: https://opensource.com/article/19/2/getting-started-cat-command
[7]: https://www.busybox.net
[8]: https://opensource.com/article/20/4/systemd
[9]: https://opensource.com/article/21/3/rtos-embedded-development
[10]: https://opensource.com/article/17/9/what-edge-computing
[11]: https://opensource.com/article/21/3/iot-measure-raspberry-pi
[12]: https://opensource.com/article/20/4/bash-sysadmins-ebook
[13]: https://opensource.com/article/19/9/getting-started-zsh
[14]: https://opensource.com/article/20/9/awk-ebook
[15]: https://opensource.com/article/20/11/macports
[16]: https://opensource.com/article/20/6/homebrew-mac
[17]: https://opensource.com/article/20/3/chocolatey
[18]: https://opensource.com/article/19/10/programming-bash-loops
[19]: https://opensource.com/article/17/6/set-path-linux
[20]: https://opensource.com/article/20/2/restore-old-computer-linux
[21]: https://opensource.com/article/19/7/how-make-old-computer-useful-again
[22]: https://opensource.com/article/20/6/open-source-rtos

View File

@@ -0,0 +1,200 @@
[#]: subject: "Play with model trains in OpenTTD"
[#]: via: "https://opensource.com/article/21/9/model-trains-openttd"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "unigeorge"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13924-1.html"
在 OpenTTD 中玩模型火车
======
> 想玩实体模型火车,却没有足够大的空间?试试 OpenTTD 中的虚拟火车吧。
![](https://img.linux.net.cn/data/attachment/album/202110/27/100255emc3x33icci0cacc.jpg)
我父亲一直很喜欢火车模型,我记得我小时候,曾看着他在圣诞树周围建了一整条轨道。当 [乐高][2] 火车套装发布时,因其便利性和固有可扩展性,我们转而投向了乐高火车的怀抱。多年来,我们热衷于建造和改装乐高火车及单轨轨道。我经常想象,未来我会有一个车库或地下室,专门用于微型景观和电动汽笛火车。强调一下,我沉迷于另一个爱好的可能性非常低,所以当发现 _虚拟_ 模型铁路可以为我提供相同的满足感时,我很开心。我的虚拟爱好引擎是 [OpenTTD][3],这是一款基于名为 **Transport Tycoon Deluxe** 的 90 年代老游戏的开源模拟游戏。
### 安装 OpenTTD
你可以在 [openttd.org/downloads][4] 下载适用于 Linux、macOS 和 Windows 的 OpenTTD。
如果你正使用 Debian Linux 或其衍生产品,甚至是[在使用 Chromebook][5],你可以下载 `.deb` 包。使用 `apt` 命令安装它:
```
$ sudo apt install ./openttd*deb
```
如果你在使用其他 Linux 发行版,请下载通用安装程序,并使用 [tar 命令][6]解压缩包:
```
$ tar xvf openttd-x.yy.z-linux*.tar.xz
```
OpenTTD 已经在 Linux、macOS 和 Windows 的 [Steam][7] 中上架Steam 是一个非开源的,但是很常见的跨平台游戏客户端)。
### 启动 OpenTTD
如果你安装了 OpenTTD可以从应用程序菜单启动它。
如果你是下载了通用包,可以切换到游戏目录,使用本地的 `openttd` 命令启动游戏:
```
$ cd openttd*
$ ./openttd &amp;
```
首次启动 OpenTTD 时,游戏会提示必须下载图像集,在 Steam 版中会自动安装,但在独立应用程序中需要单击一下鼠标。无论如何,因为 OpenTTD 是开源的,经过了很好的改进,所以在默认图像之外,你最终还会下载的还有很多其他图像。
下载图像集后,你会看到一个古色古香的小型界面。我觉得 640x480 的界面有点小,虽然旧图像界面确实更有年代感(那时计算能力还比较弱),但一些适配现代屏幕的轻度升级还是很好用的。因此,你的第一步操作就是点击“<ruby>检查在线内容<rt>Check online content</rt></ruby>”按钮。
### 加载模组
“<ruby>内容下载<rt>Content downloading</rt></ruby>”界面是一个查看已通过审查的 OpenTTD <ruby>模组<rt>mod</rt></ruby>的窗口,可以提供个性化的改进图像界面、全新音乐、火车模型和地图名称。我使用了新西兰全套配置,所以对我来说,生成的所有城市都很熟悉,尽管 2020 年我转而开始使用“辐射 3”套装了。模组 _非常多_,可以使用右上角的搜索栏来缩小选择范围。
下面是一些个人认为必备的模组:
* **abase** - 高分辨率图像。将近 300 MB这可能是你玩此游戏需要的最大一次下载游戏本身只有 50 MB
* **OpenSFX** - 一个声音合集。让你能听到城市中的交通声、船运的喇叭声以及很棒的火车汽笛声。
* **Town names** - 城镇名称。默认的城市名称很有趣,但我认为记一些本地化的名称更容易。
* **Trains** - 火车模组。OpenTTD 有一组运行良好的默认火车模型,但如果你已经是一名火车观察员,那你可能会喜欢下载一些额外的火车模型。我使用的是 NZR 火车合集,但还有很多火车也是可用的,包括来自英国、美国、奥地利、比利时、捷克共和国的车,以及按字母表顺序排列的许多其他火车。
* **Beginner tutorial** - 新手教程。是一个帮你学习游戏及界面的引导场景。
### 游戏引擎默认值
下载新素材后,你需要将它们设置为默认值。有两个设置的地方:游戏引擎默认值、游戏内脚本与素材。
![OpenTTD main menu][8]
*OpenTTD 菜单Seth Kenlon, [CC BY-SA 4.0][9]*
单击“<ruby>游戏选项<rt>Game Options</rt></ruby>”按钮。 在游戏选项屏幕中,调整以下设置:
* 将<ruby>屏幕分辨率<rt>screen resolution</rt></ruby>设置为你喜欢的界面尺寸。
* 将<ruby>基础图像集 <rt>base graphics set</rt></ruby>设置为 **abase**
* 将<ruby>基础声音设置<rt>base sounds set</rt></ruby>设置为 **OpenSFX**
关闭游戏选项屏幕。你的改动会自动保存。
### 游戏选项
在主菜单界面,单击“<ruby>NewGRF 设置<rt>NewGRF Settings</rt></ruby>”按钮。
![NewGRF settings window][10]
*NewGRF 设置菜单Seth Kenlon, [CC BY-SA 4.0][9]*
未活动的模组显示在 NewGRF 设置窗口的下半部分。要激活一个未活动的模组,请选择它并单击左下角的“<ruby>添加<rt>Add</rt></ruby>”按钮。选择要激活的模组后,再单击“<ruby>应用<rt>Apply</rt></ruby>”按钮。
### 教程
如果你下载了“<ruby>初学者教程<rt>Beginner tutorial</rt></ruby>”场景,可以通过它来学习 OpenTTD。开始教程请单击主菜单屏幕顶部附近的“<ruby>播放场景<rt>Play scenario</rt></ruby>” 按钮,然后选择该教程并开始。
初学者教程有着游戏界面的完整浏览流程,全部完成需要花费一些时间。
### 快速开始
现在我们快速介绍一下,此处你要了解以下内容:车辆出自仓库,一切活动都需要时间表。记住这两条规则,你可以立即开始建造火车(以及道路、海港和机场)。
#### 建造车站
要在两个城市之间建立一条简单的铁路线,请单击顶部图标栏中的铁路轨道图标。
![New icon bar - railway option][11]
*新建图标栏——铁路选项Seth Kenlon, [CC BY-SA 4.0][9]*
铁路以车站开始和结束,所以我通常在预定线路的两端各放置一个车站。单击火车站图标(将鼠标悬停在其上方可查看其标签)。一个火车站要服务于一个地区,其作用范围必须与该地区尽量多地重叠。要查看车站的覆盖范围,请通过单击车站对话框底部的“<ruby>开启<rt>On</rt></ruby>”按钮以启用<ruby>覆盖区域高亮<rt>Coverage area highlight</rt></ruby>功能。
![Station coverage window][12]
*车站覆盖信息窗口Seth Kenlon, [CC BY-SA 4.0][9]*
黑色网格表示覆盖范围,而白色网格显示车站的物理占据范围。当你将鼠标悬停在一个区域上时,车站的覆盖范围所需耗材会在弹出窗口中列出。从简单的开始,创建一个单轨 4 辆车的站台。在地图上的两个城市之间重复执行此操作两次。
![create station menu][13]
*创建车站菜单Seth Kenlon, [CC BY-SA 4.0][9]*
### 铺设铁轨
接下来,用铁轨连接车站。 OpenTTD 的等距视图需要一些时间来适应但是在单击铁路图标并在地图上单击拖动之后你就开始大概有所了解了。X-rail 图标提供了“自动轨道”模式,该模式会根据用户单击的方块位置对齐轨道。
铺设导轨时要细心。OpenTTD 是不可撤回的,所以一旦点击一个正方形,轨道就会被构造出来。你必须使用炸药图标来移除导轨。和现实生活中一样,没有撤消按钮。
### 火车车库
火车来自<ruby>车库<rt>depot</rt></ruby>。因此,要在铁路上添加火车,必须在沿线的某处添加一个车库。单击车库图标并在现有铁路附近放置。将车库连接到现有轨道,以确保你的火车可以从车库到达适当线路的(在此简单示例中,线路是唯一的)。
![create depot menu][14]
*建造车库菜单Seth Kenlon, [CC BY-SA 4.0][9]*
### 模型火车
终于,你可以将虚拟模型火车添加到虚拟铁路中了。要创建火车,请单击车库。
单击站点窗口底部的“<ruby>新建车辆<rt>New Vehicle</rt></ruby>”按钮,会列出可用的火车引擎和汽车。列表会部分取决于你从可下载内容中添加的模型。一般来说,发动机分为三种:蒸汽发动机、柴油发动机和电动发动机。游戏内时间从 1950 年开始,所以早期你只有蒸汽可选。随着时间推进,你会获得可用于升级的创新型新模型。
![create train menu][15]
*创建火车菜单Seth Kenlon, [CC BY-SA 4.0][9]*
现在创建一个简单的火车,其中包括一节引擎、一节客车和一节邮车。如果想添加其他类型的车厢,请单击站点以确认它们的可提供车型(由其覆盖区域决定)
### 创建火车时刻表
现在有了铁路和火车,还需要创建一个火车时刻表。时间表与车辆关联,因此无论何时添加新车,都要记得添加时间表,以让新车投入使用。
要为火车添加时刻表,请单击其车库列表中列车左侧的编号。这样可以打开火车视口,窗口右侧会有按钮。单击箭头图标即可查看该列车的时刻表。
![create schedule menu][16]
*创建时刻表菜单Seth Kenlon, [CC BY-SA 4.0][9]*
要创建时间表,请单击时间表窗口底部的“<ruby>前往<rt>Go To</rt></ruby>”按钮,然后单击要设置成第一个目的地的车站。然后点击下一站。你可以在时间表中选择一个停靠点,浏览“<ruby>满载<rt>Full load</rt></ruby>”和“<ruby>卸载<rt>Unload</rt></ruby>”下拉菜单中的选项,以此调整装卸要求,并且可以在“<ruby>无停靠<rt>Non-stop</rt></ruby>”下拉菜单中调整路线(如果开发了新路线)。选项有很多,随着城市发展和地图完善,你可能需要随时调整策略。
但是现在,单击火车视口底部的红色“<ruby>已停止<rt>Stopped</rt></ruby>”按钮,让火车投入使用吧!
![train moving from station to station][17]
*在役中的火车Seth Kenlon, [CC BY-SA 4.0][9]*
### 试试 OpenTTD 吧
OpenTTD 是一个模拟器,同时也是一个游戏,所以确实会有一些限制,比如你可能想要优化的预算和参数。例如,你可以单击一个城市、农场或工厂,了解其可接受的进出口类型。你可以通过单击 OpenTTD 窗口右下角的预算按钮来借钱。它不仅仅是一个虚拟的火车集合游戏。你还可以建造道路、机场、海港等。记得所有车辆都需要车库和时间表,你就在实现虚拟企业的路上成功了一半。
OpenTTD 有着活跃而热情的社区,以及[详细的维基][18],并且有大量的资源和教程在线可用。下载游戏并试试吧!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/model-trains-openttd
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/train-plane-speed-big-machine.png?itok=f377dXKs (Old train)
[2]: https://opensource.com/article/20/6/open-source-virtual-lego
[3]: http://openttd.org
[4]: https://www.openttd.org/downloads/openttd-releases/latest.html
[5]: https://opensource.com/article/21/2/chromebook-linux
[6]: https://opensource.com/article/17/7/how-unzip-targz-file
[7]: https://store.steampowered.com/app/1536610/OpenTTD/
[8]: https://opensource.com/sites/default/files/openttd-menu.jpg (OpenTTD menu)
[9]: https://creativecommons.org/licenses/by-sa/4.0/
[10]: https://opensource.com/sites/default/files/openttd-newgrf.jpg (The NewGRF settings menu)
[11]: https://opensource.com/sites/default/files/openttd-iconbar-railway.jpg (The new icon bar - railway option)
[12]: https://opensource.com/sites/default/files/openttd-window-station.jpg (Station coverage information window)
[13]: https://opensource.com/sites/default/files/openttd-create-station.jpg (The create station menu)
[14]: https://opensource.com/sites/default/files/openttd-create-depot.jpg (Create depot menu)
[15]: https://opensource.com/sites/default/files/openttd-create-train.jpg (The create train menu)
[16]: https://opensource.com/sites/default/files/openttd-create-schedule.png (The create schedule menu)
[17]: https://opensource.com/sites/default/files/openttd-train.jpg (Train in service)
[18]: https://wiki.openttd.org/en/

View File

@@ -0,0 +1,151 @@
[#]: subject: "Install AnyDesk on Ubuntu Linux [GUI and Terminal Methods]"
[#]: via: "https://itsfoss.com/install-anydesk-ubuntu/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13839-1.html"
在 Ubuntu Linux 上安装 AnyDesk
======
> 这个初学者的教程讨论了在基于 Ubuntu 的 Linux 发行版上安装 AnyDesk 的 GUI 和终端方法。
![](https://img.linux.net.cn/data/attachment/album/202110/01/165758y9aaiix7yu88ayui.jpg)
[AnyDesk][1] 是一个流行的远程桌面软件,可用于 Linux、Windows、BSD、macOS 和移动平台。
有了 AnyDesk你可以用它远程访问其他电脑或者让别人远程访问你的系统。不是每个人都可以访问它因为需要两台设备都使用 AnyDesk。你必须接受传入的连接和/或提供一个安全连接的密码。
这对于向朋友、家人、同事甚至客户提供技术支持很有帮助。
在本教程中,我将向你展示在 Ubuntu 上安装 AnyDesk 的图形和命令行两种方法。你可以根据自己的喜好使用这两种方法。这两种方法都会在你的 Ubuntu 系统上安装相同的 AnyDesk 版本。
同样的方法应该适用于 Debian 和其他基于 Debian 和 Ubuntu 的发行版,如 Linux MintLinux Lite 等。
> **非 FOSS 警告!**
>
> AnyDesk 不是开源软件。这里涉及它是因为它在 Linux 上可用,而文章的重点是 Linux。
### 方法 1使用终端在 Ubuntu 上安装 AnyDesk
在你的系统上 [打开终端程序][2]。你需要一个像 `wget` 这样的工具来 [在终端下载文件][3],使用以下命令:
```
sudo apt update
sudo apt install wget
```
下一步是下载 AnyDesk 仓库的 GPG 密钥,并将其添加到你的系统的可信密钥中。这样,你的系统就会信任来自这个[外部仓库][4]的软件。
```
wget -qO - https://keys.anydesk.com/repos/DEB-GPG-KEY | sudo apt-key add -
```
你可以暂时忽略关于 `apt-key` 命令的废弃警告。下一步是将 AnyDesk 仓库添加到系统的仓库源中:
```
echo "deb http://deb.anydesk.com/ all main" | sudo tee /etc/apt/sources.list.d/anydesk-stable.list
```
更新包缓存,这样你的系统就能通过新添加的仓库了解到新应用的可用性。
```
sudo apt update
```
现在,你可以安装 AnyDesk 了:
```
sudo apt install anydesk
```
完成后,你可以从系统菜单或从终端本身启动 AnyDesk
```
anydesk
```
你现在可以享受 AnyDesk 了。
![AnyDesk running in Ubuntu][5]
### 方法 2在 Ubuntu 上以图形方式安装 AnyDesk
如果你不习惯使用命令行,不用担心。你也可以不进入终端安装 AnyDesk。
你可以从 AnyDesk 官网下载 Ubuntu 上的 AnyDesk
- [下载 Linux 上的 Anydesk][6]
你会看到一个“Download Now”的按钮。点击它。
![Download AnyDesk][7]
当你点击下载按钮时,它会给你提供各种 Linux 发行版的选项。选择 Ubuntu 的那个:
![Download the appropriate file][8]
它将下载 AnyDesk 的 DEB 文件。[安装 DEB 文件][9]很简单。要么双击它,要么右击并使用软件安装打开。
![Right click on deb file and open with software center][10]
软件中心应用将被打开,你可以在那里安装它。
![Installing AnyDesk in Ubuntu software center][11]
安装后,在系统菜单中搜索它并从那里开始。
![AnyDesk installed in Ubuntu][12]
这就好了。不是太难,是吗?
我不打算展示使用 AnyDesk 的步骤。我想你已经对这个问题有了一些了解。如果没有,请参考 [这篇文章][13]。
#### 故障排除提示
当我试图从系统菜单中运行 AnyDesk 时,它没有启动。于是,我从终端启动它,它显示了这个错误:
```
[email protected]:~$ anydesk
anydesk: error while loading shared libraries: libpangox-1.0.so.0: cannot open shared object file: No such file or directory
```
如果你看到 “[error while loading shared libraries][14]” 信息,你要安装它所报错的软件包。在我的例子中,我是这样做的:
```
sudo apt install libpangox-1.0-0
```
这解决了我的问题,我希望它也能为你解决。
如果你有任何与此主题相关的问题,请在评论区告诉我。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-anydesk-ubuntu/
作者:[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://anydesk.com/en
[2]: https://itsfoss.com/open-terminal-ubuntu/
[3]: https://itsfoss.com/download-files-from-linux-terminal/
[4]: https://itsfoss.com/adding-external-repositories-ubuntu/
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/anydesk-running-in-ubuntu.png?resize=800%2C418&ssl=1
[6]: https://anydesk.com/en/downloads/linux
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/any-desk-ubuntu-download.webp?resize=800%2C312&ssl=1
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/any-desk-ubuntu-download-1.webp?resize=800%2C427&ssl=1
[9]: https://itsfoss.com/install-deb-files-ubuntu/
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/install-anaydesk-ubuntu.png?resize=800%2C403&ssl=1
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/installing-anydesk-in-ubuntu-software-center.png?resize=781%2C405&ssl=1
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/anydesk-installed-in-ubuntu.png?resize=759%2C196&ssl=1
[13]: https://support.anydesk.com/Access
[14]: https://itsfoss.com/solve-open-shared-object-file-quick-tip/

View File

@@ -0,0 +1,173 @@
[#]: subject: "Build your website with Jekyll"
[#]: via: "https://opensource.com/article/21/9/build-website-jekyll"
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
[#]: collector: "lujun9972"
[#]: translator: "perfiffer"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13875-1.html"
使用 Jekyll 构建你的网站
======
> Jekyll 是一个开源的静态网站生成器。你可以使用 Markdown 编写内容,使用 HTML/CSS 来构建和展示Jekyll 会将其编译为静态的 HTML。
![](https://img.linux.net.cn/data/attachment/album/202110/12/145349rblj459naj74j5nr.jpg)
近年来开始流行静态网站生成器和 JAMStack而且理由很充分它们不需要复杂的后端只需要静态的 HTML、CSS 和 Javascript。没有后端意味着更好的安全性、更低的运营开销和更便宜的托管。双赢
在本文中,我将讨论 Jekyll。在撰写本文时[我的个人网站使用的是 Jekyll][2]。Jekyll 使用 Ruby 引擎将用 Markdown 编写的文章转换成 HTML。[Sass][3] 可以将复杂的 CSS 规则应用到普通文本文件中。[Liquid][4] 允许对静态内容进行编程控制。
### 安装 Jekyll
[Jekyll 网站][5] 提供了 Linux、MacOS 和 Windows 安装说明。安装完成之后,[快速引导][6] 将会安装一个基础的 Hello-World 项目。
现在在你的浏览器访问 `http://localhost:4000`,你可以看到你的默认“真棒”博客。
![Default "awesome" blog][7]
### 目录结构
这个默认站点包含以下的文件和文件夹:
* `_posts`: 你的博客文章。
* `_site`: 最终编译成的静态网站文件。
* `about.markdown`: “关于页”的内容。
* `index.markdown`: “主页”的内容。
* `404.html`: “404 页”的内容。
* `_config.yml`: Jekyll 的全站配置文件。
### 创建新的博客帖子
创建帖子很简单。你需要做的就是在 `_post` 目录下使用正确的格式和扩展名创建一个新文件,这样就完成了。
有效的文件名像 `2021-08-29-welcome-to-jekyll.markdown` 这样。一个博客文件必须包含 Jekyll 所谓的 YAML <ruby>卷首块<rt>Front Matter</rt></ruby>。它是文件开头的一个包含元数据的特殊部分。如果你查看默认的帖子,你可以看到以下内容:
```
---
layout: post
title: "Welcome to Jekyll!"
date:  2021-08-29 11:28:12 +0530
categories: jekyll update
---
```
Jekyll 会使用上面的元数据,你也可以自定义 `key: value` 键值对。如果你需要一些提示,[请查看我的网站的卷首][9]。除了前面的问题,你还可以 [使用内置的 Jekyll 变量][10] 来自定义你的网站。
让我们创建一个新的帖子。在 `_posts` 文件夹下创建 `2021-08-29-ayushsharma.markdown`。内容如下:
```
---
layout: post
title:  "Check out ayushsharma.in!"
date:   2021-08-29 12:00:00 +0530
categories: mycategory
---
This is my first post.
# This is a heading.
## This is another heading.
This is a [link](<http://notes.ayushsharma.in>)
This is my category:
```
如果 `jekyll serve` 命令仍在运行,刷新页面,你将看到下面的新帖子。
![New blog entry][11]
恭喜你创建了你的第一篇帖子!这个过程看起来很简单,但是你可以通过 Jekyll 做很多事情。使用简单的 Markdown你可以归档博客、高亮显示代码片段以及分类管理帖子。
### 草稿
如果你还没准备好发布你的内容,你可以创建一个 `_drafts` 文件夹。此文件夹中的 Markdown 文件仅通过传递 `--drafts--` 参数来呈现。
### 布局和包含
请注意 `_post` 文件夹中两篇文章的卷首块,你将在其中看到 `layout: post``_layout` 文件夹中包含所有布局。你不会在源代码中找到它们,因为 Jekyll 默认加载它们。Jekyll 使用的默认源代码在 [这里][12]。如果你点击该链接,你可以看到 `post` 的布局使用了默认(`default`)布局。默认布局包含的代码 `{{ content }}` 是注入内容的地方。布局文件还将包含 `include` 指令。它们从 [`include` 文件夹][14] 加载文件,并使用不同的组件组成页面。
总的来说,这就是布局的工作方式:你在卷首块定义它们并将你的内容注入其中。而包含则提供了页面的其它部分以组成整个页面。这是一种标准的网页设计技术:定义页眉、页脚、旁白和内容元素,然后在其中注入内容。这就是静态站点生成器的真正威力,完全以编程的方式控制,将你的网站组装起来并最终编译成静态的 HTML。
### 页面
你网站上的所有内容并不都是文章或博客。你需要“关于”页面、“联系”页面、“项目”页面或“作品”页面。这就是“页面”的用武之地。它们的工作方式与“帖子”完全一样,这意味着它们是带有卷首块的 Markdown 文件。但它们不会放到 `_posts` 目录。它们要么保留在你的项目根目录中,要么保留在它们自己的文件夹中。对于布局和包含,你可以使用与帖子相同的布局或创建新帖子。 Jekyll 非常灵活,你可以随心所欲地发挥你的创意!你的默认博客已经有 `index.markdown``about.markdown`。请随意自定义它们。
### 数据文件
数据文件位于 `_data` 目录中,可以是 `.yml``.json``.csv` 等格式的文件。例如,一个 `_data/members.yml` 文件可能包含:
```
- name: A
 github: a@a
- name: B
 github: b@b
- name: C
 github: c@c
```
Jekyll 在网站生成的时候读取这些内容。你可以通过 `site.data.members` 访问它们。
```
<ul>
{ % for member in site.data.members % }
 <li>
 <a href="https://github.com">
      { { member.name } }
 </a>
 </li>
{ % endfor %}
</ul>
```
### 永久链接
你的 `_config.yml` 文件定义了永久链接的格式。你可以使用各种默认变量来组合你自己的自定义永久链接。
### 构建你最终的网站
命令 `jekyll serve` 非常适合本地测试。但是一旦你完成了本地测试,你将需要构建要发布的最终工作。命令 `jekyll build --source source_dir --destination destination_dir` 将你的网站构建到 `_site` 文件夹中。请注意,此文件夹在每次构建之前都会被清理,所以不要将重要的东西放在那里。生成内容后,你可以将其托管在你的静态托管服务上。
你现在应该对 Jekyll 的功能以及主要部分的功能有一个全面的了解。如果你正在寻找灵感,官方 [JAMStack 网站上有一些很棒的例子][17]。
![Example Jekyll sites from JAMStack][18]
编码快乐。
本文首发于 [作者个人博客][19],经授权改编。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/build-website-jekyll
作者:[Ayush Sharma][a]
选题:[lujun9972][b]
译者:[perfiffer](https://github.com/perfiffer)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/ayushsharma
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
[2]: https://gitlab.com/ayush-sharma/ayushsharma-in
[3]: https://sass-lang.com/
[4]: https://shopify.github.io/liquid/
[5]: https://jekyllrb.com/docs/installation/
[6]: https://jekyllrb.com/docs/
[7]: https://opensource.com/sites/default/files/uploads/2016-08-15-introduction-to-jekyll-welcome-to-jekyll.png (Default "awesome" blog)
[8]: https://creativecommons.org/licenses/by-sa/4.0/
[9]: https://gitlab.com/ayush-sharma/ayushsharma-in/-/blob/2.0/_posts/2021-07-15-the-evolution-of-ayushsharma-in.md
[10]: https://jekyllrb.com/docs/variables/
[11]: https://opensource.com/sites/default/files/uploads/2016-08-15-introduction-to-jekyll-new-article.png (New blog entry)
[12]: https://github.com/jekyll/minima/blob/master/_layouts/post.html
[13]: https://github.com/jekyll/minima/blob/master/_layouts/default.html#L12
[14]: https://github.com/jekyll/minima/tree/master/_includes
[15]: https://github.com/"\>
[16]: https://jekyllrb.com/docs/permalinks/
[17]: https://jamstack.org/examples/
[18]: https://opensource.com/sites/default/files/uploads/2016-08-15-introduction-to-jekyll-jamstack-examples.png (Example Jekyll sites from JAMStack)
[19]: https://notes.ayushsharma.in/2021/08/introduction-to-jekyll

View File

@@ -0,0 +1,117 @@
[#]: subject: "Install Java from your Linux distribution's repositories"
[#]: via: "https://opensource.com/article/21/9/install-java-linux-repositories"
[#]: author: "Chris Hermansen https://opensource.com/users/clhermansen"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13864-1.html"
如何从 Linux 发行版的仓库中安装 Java
======
> 无论你喜欢哪个发行版和包管理器,都可以都很容易地在你的 Linux 系统上安装 Java。
![](https://img.linux.net.cn/data/attachment/album/202110/09/092717ean17be0alz10kt5.jpg)
把 Java 安装到你的 Linux 桌面上有多种方法。一个明显的方式是使用你的 Linux 发行版中提供的软件包。请注意,这并不适合所有人。例如,有些用户可能需要一个非常具体的 Java 版本。
在你开始之前,你必须确定你需要“哪种 Java”。你是否只需要运行一些 `.class` 文件或 `.jar` 文件?还是你正在编写一些需要编译的代码?
就我而言,我运行的大部分 Java 都是我自己(至少部分)编写的 Java所以安装完整的 Java 开发工具包(或称 JDK总是有意义的它包含了 Java 编译器、库和一些非常有用的工具。当然,在这里,我们更倾向于使用开源的 JDK称为 [OpenJDK][2]。
由于我主要在 Ubuntu Linux 发行版上工作,我的软件包管理器是 `apt`。我可以用 `apt` 来查找哪些 OpenJDK 包是可用的:
```
apt list OpenJDK\*
```
这个命令的输出看起来像这样:
```
Listing... Done
openjdk-11-dbg/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-dbg/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-demo/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-demo/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-doc/hirsute-updates,hirsute-updates,hirsute-security,hirsute-security 11.0.11+9-0ubuntu2 all
openjdk-11-jdk-headless/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-jdk-headless/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-jdk/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-jdk/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-jre-dcevm/hirsute 11.0.10+1-1 amd64
openjdk-11-jre-headless/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-jre-headless/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-jre-zero/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-jre-zero/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-jre/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 amd64
openjdk-11-jre/hirsute-updates,hirsute-security 11.0.11+9-0ubuntu2 i386
openjdk-11-source/hirsute-updates,hirsute-updates,hirsute-security,hirsute-security 11.0.11+9-0ubuntu2 all
openjdk-15-dbg/hirsute 15.0.3+3-1 amd64
openjdk-15-dbg/hirsute 15.0.3+3-1 i386
openjdk-15-demo/hirsute 15.0.3+3-1 amd64
...
openjdk-8-jre/hirsute-updates,hirsute-security 8u292-b10-0ubuntu1 i386
openjdk-8-source/hirsute-updates,hirsute-updates,hirsute-security,hirsute-security 8u292-b10-0ubuntu1 all
```
我在上面用 `...` 省略了不少行。
事实证明,即使限制在 OpenJDK 中,我仍然有很多选择:
* 不同的架构在我的例子中i386 还是 amd64
* 不同的 Java 版本(就我而言,有 8、11、15、16、17 等)。
* 纯粹的 OpenJDK 或无头版本。
* Java 运行时环境JRE
* 用于调试、演示,以及是否包含源代码等。
同样,在我的情况中,我主要对纯粹的普通 OpenJDK 感兴趣。
假设我想为我的 amd64 架构安装 Java 11 版本的普通 OpenJDK我可以输入
```
sudo apt install -a=amd64 openjdk-11-jdk
```
几分钟后,我就可以编译、运行、调试和打包我的 Java 代码了。
注意,很有可能需要同时安装多个版本的 Java有时甚至是必要的。在 Ubuntu 中,有一个有用的工具,叫做 `update-java-alternatives`,它可以 [显示并配置在使用哪个 Java 环境][3]。
那些使用不同 Linux 发行版的人,一般来说,可以采取类似的方法。其他的几个发行版(如 Debian 和 Mint也使用 `apt` ,尽管可用的软件包可能不同。发行版可能使用不同的软件包管理器。例如, [Fedora 安装 Java 的文档页面][4] 显示了如何使用 Fedora `dnf` 包管理器来处理安装。首先,为了显示可用的版本,输入:
```
dnf search openjdk
```
接下来,要安装完整的开发 x86_64 架构版本,请输入:
```
sudo dnf install java-11-openjdk-devel.x86_64
```
同样地Fedora 提供了 `alternatives` 工具来 [显示和配置 Java 环境][5]。
再比如,[很棒的 Arch Linux 维基][6] 显示对应的软件包是 `jdk11-openjdk`。该维基还解释了许多在 Arch 中使用 Java 的其他重要细节,比如使用 `archlinux-java` 工具来显示安装了哪些 Java 环境或选择一个不同的默认环境。Arch 使用一个叫 `pacman` 的包管理器,它也有文档 [在 Arch Linux 维基上][7]。
不管你喜欢哪个发行版和软件包管理器,在你的 Linux 系统上获得 Java 是很容易的。当然,在安装之前,要考虑版本和功能。还要记住,在同一台电脑上有管理两个或多个 Java 版本的方法。我的大多数例子都使用了 `apt`,但也要记得可以选择使用 `dnf`
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/install-java-linux-repositories
作者:[Chris Hermansen][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/clhermansen
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/java-coffee-mug.jpg?itok=Bj6rQo8r (Coffee beans and a cup of coffee)
[2]: https://openjdk.java.net/
[3]: http://manpages.ubuntu.com/manpages/hirsute/man8/update-java-alternatives.8.html
[4]: https://docs.fedoraproject.org/en-US/quick-docs/installing-java/
[5]: https://tecadmin.net/install-java-on-fedora/
[6]: https://wiki.archlinux.org/title/java#OpenJDK
[7]: https://wiki.archlinux.org/title/pacman#Querying_package_databases

View File

@@ -0,0 +1,100 @@
[#]: subject: "Dialect: An Open-Source Translation App for Linux"
[#]: via: "https://itsfoss.com/dialect/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13868-1.html"
DialectLinux 下的开源翻译应用
======
![](https://img.linux.net.cn/data/attachment/album/202110/10/115724t5xgx8agu8asag0u.jpg)
> Dialect 是一个简单明了的应用,可以让你使用 Web 服务进行语言间的翻译。想要了解更多的话,让我们来一窥究竟。
虽然你可以启动 Web 浏览器并直接使用任何翻译服务来完成工作,但桌面应用有时会派上用场。
Dialect 是一个简单的翻译应用,可以利用 Web 服务进行翻译,同时给你一些额外的能力。
### 使用谷歌翻译和 LibreTranslate 的开源翻译应用
![][1]
Dialect 是一个主要为 GNOME 桌面定制的应用,但它在其他桌面环境下也应该能正常工作。
它可以让你快速翻译语言,同时还有一些额外的选项。
在其核心部分,你可以选择谷歌翻译或 LibreTranslate 翻译服务。
尽管 LibreTranslate 达不到谷歌翻译的准确性,但把它作为一个选项来切换是一个很好的补充。至少,对于一些基本的用法,如果用户不想利用谷歌的服务,你的桌面上就有一个备选方案。
### Dialect 的特点
![][2]
除了切换翻译服务外,你还能得到如下个功能:
* 发音
* 文本到语音TTS功能谷歌
* 黑暗模式
* 翻译快捷方式
* 实时翻译
* 剪贴板按钮可快速复制/粘贴
* 翻译历史(撤销/重做)
正如你在截图中所注意到的,实时翻译功能可能会因为滥用 API 而使你的 IP 地址被禁止使用服务。
![][3]
我试着使用 LibreTranslate如上图所示和谷歌翻译并启用实时翻译功能它工作得很好。
也许,如果你经常依赖翻译,你可能想避免这个实时翻译。但是,对于我的临时使用,在相当多的测试中,该服务并没有导致 IP 地址被禁止。
重要的是要注意,如果你想,你可以指定一个自定义的 LibreTranslate 实例。默认情况下,它使用 “translate.astian.org” 作为实例。
你可能找不到一个单独显示的翻译历史区域,但窗口左上角的箭头按钮会让你看到你以前的翻译,以及翻译设置。
所以,它也可以作为一个重做/撤销的功能。
### 在 Linux 中安装 Dialect
[Dialect][7] 是以 [Flatpak][4] 的形式提供的。所以,你应该能够在你选择的任何 Linux 发行版上安装它。如果你是新手,你可能想看看我们的 [Flatpak 指南][5] 以获得帮助。
首先,添加 Flathub 仓库:
```
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
```
然后安装应用:
```
flatpak install flathub com.github.gi_lom.dialect
```
安装后,在系统菜单中寻找它,并从那里启动它。
你也可以浏览它的 [GitHub 页面][6] 了解更多信息。
--------------------------------------------------------------------------------
via: https://itsfoss.com/dialect/
作者:[Ankush Das][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/ankush/
[b]: https://github.com/lujun9972
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/dialect-screenshot.png?resize=800%2C331&ssl=1
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/dialect-app-options.png?resize=800%2C470&ssl=1
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/dialect-libretranslate.png?resize=800%2C326&ssl=1
[4]: https://itsfoss.com/what-is-flatpak/
[5]: https://itsfoss.com/flatpak-guide/
[6]: https://github.com/dialect-app/dialect/
[7]: https://flathub.org/apps/details/com.github.gi_lom.dialect

View File

@@ -0,0 +1,118 @@
[#]: subject: "Install Java manually on Linux"
[#]: via: "https://opensource.com/article/21/9/install-java-manually-linux"
[#]: author: "Alan Formy-Duval https://opensource.com/users/alanfdoss"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13869-1.html"
如何在 Linux 上手动安装 Java
======
> 手动安装可以让用户更好的控制 Java 运行时环境。
![](https://img.linux.net.cn/data/attachment/album/202110/10/143844wm2x4d18b1mb8md1.jpg)
[使用 Linux 发行版的软件包管理工具来安装 Java 软件包][6] 是很容易的。然而,有时你需要手动安装 Java。这对基于 Java 的应用服务器(如 Tomcat 或 JBoss的管理员特别重要。许多开源和专有软件产品都依赖于这些服务。
### 开发者或运行时套件?
<ruby>Java 虚拟机<rt>Java Virtual Machine</rt></ruby>JVM以两种不同的形式提供<ruby>Java 开发工具包<rt>Java Development Kit</rt></ruby>JDK或 <ruby>Java 运行时环境<rt>Java Runtime Environment</rt></ruby>JRE
软件开发人员通常需要 JDK。它包含编译、运行和测试源代码所需的二进制文件。部署一个预先建立的 Java 应用程序通常只需要 JRE。它不包括编译器和其他开发工具。由于安全性的提高和空间的限制通常在生产环境中安装 JRE。
### 获取 Java
你可以从网上下载开源的 Java 软件。你可以在 [Red Hat Developer][2]、[Adoptium.net][3] 下载 OpenJDK 打包文件,或从 Azul 下载 [Zulu 社区版][4] 。
### 安装 Java
设置一个目录来存放 Java 文件。我喜欢创建一个简单的名为 `java` 的目录,这样我就可以在一个专门的目录中下载并解压打包文件:
```
$ mkdir -p java/jdk
```
让我们在这个例子中使用 JDK。将下载的文件保存到 `jdk` 目录下。然后换到该目录:
```
$ cd java/jdk
$ ls
OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz
```
提取该打包文件。注意,`tar` 会创建一个新的目录:
```
$ tar xvzf OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz
$ ls
jdk-11.0.12+7 OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz
```
使用 `-version` 选项确认新 JVM 的版本。
```
$ cd jdk-11.0.12+7/bin
$ ./java -version
```
JVM 的版本输出看起来类似这样:
```
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment Temurin-11.0.12+7 (build 11.0.12+7)
OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (build 11.0.12+7, mixed mode)
```
#### 环境变量
为了确保一个特定的应用程序能够正常工作,它需要确切地知道如何定位 JVM。有两个主要的变量需要设置`JAVA_HOME``PATH`
```
$ echo $JAVA_HOME
$ echo $PATH
```
这些可以在用户的 `.bashrc` 文件中设置。确保这些变量出现在 [任何设置 PATH 的现有代码][5] 之后:
```
#Set the JAVA_HOME
export JAVA_HOME=~/java/jdk/jdk-11.0.12+7
#Add the JAVA_HOME to the PATH
export PATH="$JAVA_HOME/bin:$PATH"
```
### 手动安装的情况
有几种情况需要手动安装 Java。请考虑以下三种情况
一种情况可能是要求使用不同的,也许是较早的,在你的 Linux 发行版的软件库中已经没有的 Java 版本。
另一个例子可能是由安全推动的决定,即 Java 不会被默认安装在操作系统上或在“根级别”上。
第三种情况是可能需要几个不同版本的 Java通常是因为 J2EE Web 应用程序的多个实例在同一台服务器上运行。由于越来越多地使用虚拟机和容器来隔离进程,这种操作系统共享在今天已经不太常见了。然而,由于需要维护不同的容器镜像,对手动安装的理解仍然至关重要。
### 总结
我演示了我手动安装 Java 运行时环境的方式,但你可以制定一个最适合你需求的惯例。最终,手动安装让用户可以更好的控制 Java 运行时环境。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/install-java-manually-linux
作者:[Alan Formy-Duval][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/alanfdoss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
[2]: https://developers.redhat.com/products/openjdk/download
[3]: https://adoptium.net/
[4]: https://www.azul.com/downloads/zulu-community
[5]: https://opensource.com/article/17/6/set-path-linux
[6]: https://linux.cn/article-13864-1.html

View File

@@ -0,0 +1,129 @@
[#]: subject: "How I use Ansible and anacron for automation"
[#]: via: "https://opensource.com/article/21/9/ansible-anacron-automation"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13879-1.html"
我如何使用 Ansible 和 anacron 实现自动化
======
> 有了 anacron我可以把脚本和 Ansible 剧本放到合适的地方,以完成各种琐碎的任务。
![](https://img.linux.net.cn/data/attachment/album/202110/13/155036tc0c7th906cc96mm.jpg)
自动化是伟大的 IT 和 DevOps 理想,但根据我的经验,可能根本不存在什么不方便的东西。有很多次,我为某些任务想出了一个很好的解决方案,我甚至会编写脚本,但我没有让它真正实现自动化,因为在我工作的机器上不存在易于自动化的基础设施。
我最喜欢的简易自动化工具曾经是 cron 系统它古老、可靠、面向用户而且简单除了一个我永远无法记住的调度语法之外。然而cron 的问题是,它假定一台电脑每天 24 小时都在工作。在错过了太多预定的备份之后,我发现了 [anacron][2],一个基于时间戳而非预定时间的 cron 系统。如果你的电脑在通常情况下运行时处于关闭状态anacron 会确保它在电脑重新开启时运行。创建一个作业只需要简单地把一个 shell 脚本放到三个目录中:`cron.day``cron.weekly` 或者 `cron.monthly` (如果你想的话,你可以定义更多)。有了 anacron我发现自己把脚本和 Ansible 剧本用在了各种琐碎的任务中,包括弹出到期和事件提醒。
这是一个现代问题的简单而明显的解决方案,但如果 anacron 没有安装在电脑上,那它对我就没有用。
### 用 Ansible 进行软件设置
任何时候我设置一台新的计算机,无论是笔记本电脑、工作站还是服务器,我都会安装 anacron。这很简单但是 anacron 的安装只提供了 `anacron` 命令。它并没有设置 anacron 的用户环境。所以我创建了一个 Ansible 剧本来设置用户需要什么来使用 anacron 并安装 `anacron` 命令。
首先,标准的 Ansible 模板:
```
---
- hosts: localhost
tasks:
```
### 用 Ansible 创建目录
接下来,我创建了用于 Anacron 的目录树。你可以把它看成是一种透明的 crontab。
```
- name: create directory tree
ansible.builtin.file:
path: "{{ item }}"
state: directory
with_items:
- '~/.local/etc/cron.daily'
- '~/.local/etc/cron.weekly'
- '~/.local/etc/cron.monthly'
- '~/.var/spool/anacron'
```
这个语法可能看起来有点奇怪,但它实际上是一个循环。`with_items:` 指令定义了四个要创建的目录Ansible 在 `ansible.buildin.file:` 指令中为每个目录迭代一次(目录名填充了 `{{ item }}` 变量)。与 Ansible 中的一切一样,如果目录已经存在,不会有错误或冲突。
### 用 Ansible 复制文件
`ansible.buildin.copy` 模块将文件从一个地方复制到另一个地方。为了让它工作,我需要创建一个叫做 `anacrontab` 的文件。它不是 Ansible 剧本,所以我把它放在我的 `~/Ansible/data` 目录下,那里是我的剧本的支持文件。
```
- name: copy anacrontab into place
ansible.builtin.copy:
src: ~/Ansible/data/anacrontab
dest: ~/.local/etc/anacrontab
mode: '0755'
```
我的 `anacrontab` 文件很简单,模仿了一些发行版默认安装在 `/etc/anacron` 中的文件:
```
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
1 0 cron.day run-parts $HOME/.local/etc/cron.daily/
7 0 cron.wek run-parts $HOME/.local/etc/cron.weekly/
30 0 cron.mon run-parts $HOME/.local/etc/cron.monthly/
```
### 登录时运行 anacron
大多数 Linux 发行版将 anacron 配置为从 `/etc/anacron` 读取作业。我主要是作为一个普通用户使用 anacron所以我从我的登录账号 `~/.profile` 启动 anacron。我不想让自己记住这些配置所以我让 Ansible 来做。我使用 `ansible.buildin.lineinfile` 模块,它会在 `~/.profile` 不存在时创建它,并插入 anacron 的启动行。
```
- name: add local anacrontab to .profile
ansible.builtin.lineinfile:
path: ~/.profile
regexp: '^/usr/sbin/anacron'
line: '/usr/sbin/anacron -t ~/.local/etc/anacrontab'
create: true
```
### 用 Ansible 安装 anacron
对于我的大多数系统来说,`dnf` 模块可以用来安装软件包,但我的工作站运行的是 Slackware使用 `slackpkg`),有时不同的 Linux 发行版也会进入我的收藏。`ansible.buildin.package` 模块提供了一个安装软件包的通用接口,所以我把它用在这个剧本上。幸运的是,我还没有遇到一个名为 `anacron` 的仓库不是 `anacron`,所以现在,我不必考虑软件包名称的潜在差异。
这实际上是一个单独的剧本,因为软件包的安装需要权限升级,它由 `becomes: true` 指令提供。
```
- hosts: localhost
become: true
tasks:
- name: install anacron
ansible.builtin.package:
name: anacron
state: present
```
### 使用 anacron 和 Ansible 实现轻松自动化
为了用 Ansible 安装 anacron我运行该剧本
```
$ ansible-playbook ~/Ansible/setup-anacron.yaml
```
从此,我就可以编写 shell 脚本来执行一些琐碎但重复的任务,然后把它复制到 `~/.local/etc/cron.daily`,让它每天自动运行一次(或者大约如此)。我还为诸如 [清理下载文件夹][3] 之类的任务编写了 Ansible 剧本。我把我的剧本放在 `~/Ansible` 里,这是我保存 Ansible 剧本的地方,然后在 `~/.local/etc/cron.daily` 里创建一个 shell 脚本来执行这个剧本。这很简单,不费吹灰之力,而且很快成为习惯。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/ansible-anacron-automation
作者:[Seth Kenlon][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/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming-code-keyboard-laptop-music-headphones.png?itok=EQZ2WKzy (Woman programming)
[2]: https://opensource.com/article/21/2/linux-automation
[3]: https://opensource.com/article/21/9/keep-folders-tidy-ansible

View File

@@ -0,0 +1,154 @@
[#]: subject: "Make YAML as easy as it looks"
[#]: via: "https://opensource.com/article/21/9/yaml-cheat-sheet"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13842-1.html"
让 YAML 变得像它看起来一样简单
======
> YAML 看起来很简单,为什么它这么难写呢?了解成功使用 YAML 的两个秘诀。
![](https://img.linux.net.cn/data/attachment/album/202110/02/101824shamurmpvldpu29a.jpg)
如果你曾经尝试过写 YAML你可能一开始会对它看起来很容易感到高兴。乍一看经常用于配置文件、Ansible 剧本和普通文件数据库的 YAML 看起来就像购物清单一样直观。然而YAML 的结构中有很多细微的差别它隐藏着一个危险的秘密YAML 实际上是一种高度精确、结构化和令人惊讶的严格语言。好消息是,你只需要了解两件事就可以知道 YAML 的工作原理。
关于 YAML 的真相是YAML 中只有两种数据结构:<ruby>序列<rt>sequence</rt></ruby>和<ruby>映射<rt>mapping</rt></ruby>。这是两个花哨的名字,你会发现它代表了你非常熟悉的概念。这篇文章解释了这两种结构,更重要的是,介绍了它们是如何协同工作,使 YAML 成为表示你所关心的数据的强大方式。
### YAML 序列
YAML 序列是一个列表。在其最简单的形式中,每行有一个项目,每行以破折号和空格开始。
下面是一个例子:
```
---
- Linux
- BSD
- Illumos
```
不同的语言有不同的方式来表示这种数据。例如,在 Python 中,同一个列表可以写成 `['Linux', 'BSD', 'Illumos']`。当你在现实生活中写一个列表时,例如在你去买菜之前,你写的可能近似于 YAML 序列。
### YAML 映射
YAML 映射是一个关键术语与该术语的定义相结合。在其他语言中,映射被称为“键值对”或“词典”。
这里有一个例子:
```
---
Kernel: Linux
CPU: AMD
RAM: '16 GB'
```
不同的语言有不同的方式来表示这种数据。[在 Python 中][2],例如,同样的数据可以写成 `{"Kernel": "Linux", "CPU": "AMD", "RAM": "16 GB"}`。在现实生活中,你可能会使用这种结构来计划,例如,与朋友的游戏之夜。一个朋友报名带零食,另一个报名带一副牌,另一个报名带一个棋盘游戏,等等。
### 组合序列和映射
你现在知道 YAML 的语法了。序列和映射是 YAML 中仅有的两种构件,你想在 YAML 中表示的任何东西都可以放在序列或映射中。
或者同时使用这二者!
是的,序列和映射可以被组合和嵌套,这就是 YAML 看起来很直观但同时又感觉很复杂的原因之一。不过只有四种可能的组合一旦你学会如何看它们YAML 就会觉得像它看起来一样简单。
### 序列的映射
当你想让一个键项有许多值时,你可以使用一个序列的映射。也就是说,你从一个映射(键)开始,但是给值一个列表:
```
---
Linux:
  - Fedora
  - Slackware
BSD:
 - FreeBSD
  - NetBSD
```
在这个示例代码中,`Linux` 是第一个键,它的值是一个序列,其中包含 `Fedora``Slackware`。第二个键是 `BSD`,它的值是一个序列,包含 `FreeBSD``NetBSD`
### 映射的映射
当你想让一个键项的值中既有键又有值时,你可以使用映射的映射。也就是说,你从一个映射(键)开始,但是给值另一个映射。
这可能有点欺骗性,但它揭示了 YAML 中使用特定术语的原因:因为你只不过是创建了一个映射的列表,并不意味着你创建了一个序列。这里是一个映射的映射:
```
---
Desktop:
  CPU: RISC-V
  RAM: '32 GB'
Laptop:
  CPU: AMD
  RAM: '16 GB'
```
对大多数人来说,这看起来像一个列表。而且从技术上讲,它是一个列表。但重要的是要认识到,它不是 YAML 序列。它是一个映射,其中包含映射。作为半个 YAML 专家,你可以从明显缺少破折号的地方看出区别。
在 Ansible 剧本的所有结构中,我发现这个结构最容易欺骗人。作为人类,我们喜欢列表,当我们看到一个数据结构 _在字面上_ 是列表时,大多数人会把它当成 YAML 序列。但是在 YAML 中,虽然序列是列表,但是列表并不总是序列。
### 序列的序列
就像你可以嵌套映射一样,你可以将一个序列嵌套到一个序列中:
```
---
- [Linux, FreeBSD, Illumos]
- [YAML, XML, JSON]
```
这可能是我在 YAML 的实际使用中遇到的最不常见的数据结构,但有时你需要一个列表的列表。
### 映射的序列
你也可以创建一个包含映射的序列。对于人类排序数据的方式来说,这并不太常见,但对于计算机来说,这可能是一个重要的结构。
这里有一个例子:
```
---
-
  CPU: AMD
  RAM: '16 GB'
-
  CPU: Intel
  RAM: '16 GB'
```
对于 YAML这可能是最不直观的语法。我发现它在 Python 中呈现时更清晰:
```
[{"CPU": "AMD", "RAM": "16 GB"}, {"CPU": "Intel", "RAM": "16 GB"}]
```
方括号代表一个列表结构,这个列表包含两个字典。每个字典都包含键值对。
### 构建更好的 YAML
现在你知道了 YAML 的两个组成部分,以及它们如何被组合起来以表示复杂的数据结构。问题是:你要用 YAML 构建什么?
和很多人一样,我也使用 YAML 来编写 Ansible 剧本。我还用它作为一种简单的配置格式、作为 D&D 的角色表、表示项目组织所需的目录结构,等等。只要你能适应序列和映射的概念,你会发现 YAML 是一种很容易编写、阅读和(如果有合适的库)解析的格式。
如果你发现自己经常使用 YAML请下载我们的 [YAML 速查表][3],以帮助你直观地了解基本数据结构及其组合,并帮助你记住一些额外的语法约定。通过一点点的练习,你会发现 YAML 真的和它看起来一样简单!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/yaml-cheat-sheet
作者:[Seth Kenlon][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/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
[2]: https://opensource.com/article/21/3/dictionary-values-python
[3]: https://opensource.com/downloads/yaml-cheat-sheet

View File

@@ -0,0 +1,77 @@
[#]: subject: "/e/ cloud is a deGoogled Alternative to Google Drive"
[#]: via: "https://news.itsfoss.com/e-cloud/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13874-1.html"
/e/ 云:一个去谷歌化的 Google Drive 替代方案
======
![](https://img.linux.net.cn/data/attachment/album/202110/12/122933awf0z9vnqdzslv1q.jpg)
> /e/ 云是 e.foundation 使用 Nextcloud 等开源工具创立的,以作为 Google Drive 和 Gmail 的替代品。
![](https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ecloud-ft.png?w=1200&ssl=1)
Google Drive 是一种流行的云存储服务,在大多数情况下效果很好。
然而,它可能不是最关注隐私的选择。因此,要完全控制你的数据,最好的办法是启动一个 [Nextcloud][1] 实例,存储你的基本数据,并可以访问其他协作工具。
虽然这听起来不错,但不是每个人都能投入精力来创建和维护他们的实例。这就是 /e/ 云上场的时候了,它是由 [去谷歌化的安卓操作系统 /e/ 操作系统][2] 背后的同一个团队建立的。
/e/ 云主要将自己定位为一个新的 Google Drive 私人替代品,并提供一个取代 Gmail 的邮箱。
### /e/ 云:带有邮箱的 Nextcloud 及 OnlyOffice
![][3]
当你创建一个 /e/ 账户时,它会给你一个私人电子邮件地址 [xyz@e.email][4]。
而且,同邮箱地址一起,你会得到 1GB 的免费 /e/ 云存储空间和一个由 Nextcloud 和 OnlyOffice 为核心的协作平台。
因此,如果你想利用 Nextcloud 和 OnlyOffice 来取代谷歌的工具套件,而不需要自己全部设置,/e/ 云可以成为一个引人注目的以隐私为中心的选择。
![][5]
除了 OnlyOffice 的文件存储和文档支持外,你还可以使用日历,存储笔记,并添加任务。
因此,它也可以成为一个正式的以隐私为中心的协作平台,你可以免费使用。
如果你想要更多的存储空间,你可以将你的订阅升级到付费计划,你可以根据需要选择 20 到 1TB 的存储空间,并按月/年计费。定价计划起价低至 3 美元/月。
毫无疑问,如果你在手机上使用 /e/ 操作系统或使用一个 /e/ 智能电话,这应该是一种无缝体验。
但是,你也可以使用第三方邮件客户端和 Nextcloud 移动应用在任何设备上使用它。
- [注册 /e/ 云][6]
### 总结
考虑到它相对较新,正计划增加几个功能,包括端到端加密,从 Google Drive 迁移等。
你可以注册一个帐户并免费试用。
对于像 /e/ 云这样以 Nextcloud 为核心的主流解决方案,除了电子邮件和协作服务外,还能帮助你安全地管理/存储文件,你觉得怎么样?
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/e-cloud/
作者:[Ankush Das][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://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/nextcloud/
[2]: https://itsfoss.com/e-os-review/
[3]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ecloud.png?resize=1568%2C772&ssl=1
[4]: mailto:xyz@e.email
[5]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ecloud-files.png?resize=1568%2C787&ssl=1
[6]: https://e.foundation/e-email-invite/

View File

@@ -0,0 +1,97 @@
[#]: subject: "8 reasons why I learned Core Java"
[#]: via: "https://opensource.com/article/21/10/why-i-learned-core-java"
[#]: author: "Shantam Sahai https://opensource.com/users/shantam-sahai"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13855-1.html"
学习 Core Java 的 8 个原因
======
> 在学习建立在 Java 之上的所有相关工具时,了解 Core Java 会给你带来很大的优势。
![](https://img.linux.net.cn/data/attachment/album/202110/06/094720iax1d49c5sc0sd48.jpg)
计算机编程(也被称为 *编码*)的重点不是使用哪种编程语言,而是发展编程逻辑和学习像程序员一样思考。你一开始使用的编程语言应该是在这一努力过程中对你帮助最大的语言。因此,你必须问自己一个问题,“作为一个程序员,你想开发什么?”
例如,如果你想从事安卓应用开发、视频游戏开发、桌面 GUI 应用,或者只是一般的软件开发,我认为学习 Java 是一个很好的选择。我选择的语言是 Java它为我提供了一个完整的编程世界。在我居住的印度Java 程序员的平均工资约为每年 59 万印度卢比LPA根据你的经验可以高达 100 LPA
不过Java 是一种庞大的语言有很多框架和变体可供选择。Core Java 是科技行业发展出来的术语,指的是 Java 语言的中心组件,人们用它来编写框架,并围绕 Java 发展了丰富的产业。我认为Core Java 是你能获得的最强大的技能之一,因为在学习建立在它之上的所有相关工具时,了解 Java 的基础知识会给你带来巨大的优势。
以下是我选择 Core Java 的八大理由,我想你也会认可:
### 1、Java 是一种不断发展的编程语言
Java 有重要的企业支持,但 Java 开发中最重要的组成部分是 [OpenJDK][2],这是个开源的 Java 开发工具包。OpenJDK 社区以促进和维护开发源码、开放创新和开放标准为使命,致力于改进和维护 Java 及其工具链的开源实现。
它的每一个版本都会增加创新和便利,使 Java 对开发者和用户都更容易。例如,就在 Java 11 中,他们增加了运行 .java 文件的能力。现在,运行一个单文件的 Java 应用程序所需要的只是 `java` 命令,不需要进行编译:
```
$ java ./hello.java
Hello world
```
你可以使用 Java 做 Web、移动或桌面的应用程序编程。它是一种高度通用的语言。它有许多有趣的特点如动态编码、多种安全功能、平台无关的特点和以网络为中心的设计。
### 2、Java 锚定了安卓应用开发
你可以使用 Java 来创建安卓用程序。安卓市场巨大,对移动程序员的需求只会越来越大。即使你对成为一个专业的应用程序开发人员不感兴趣,定制你的移动体验的能力也是很强大的,而 Java 使之成为可能。
而且,这比你想象的要容易得多!学习 Core Java 可以让你轻松地掌握安卓开发工具包或可以输出到移动平台的框架,如 [Processing][3]。
### 3、丰富的 API 使得 Java 易于使用
Java 的 API<ruby>应用编程接口<rt>Application Programming Interface</rt></ruby>包括类、包、接口等。Java 主要有三种类型的 API
* 官方的 Java Core API
* 最佳的官方 Java API
* 非官方的 API
API 使编程更容易,因为你可以在不知道其内部实现的情况下构建应用程序。根据我的经验,许多公司喜欢用 Java 而不是其他选择,就是因为 Java API 的力量。
### 4、开源库
几乎有无穷无尽的 Java 开源库,包括 Maven、Guava、Apache Commons、Jhipster等等。你可以复制、学习和分享这些库的资源。它们使编程更容易获得、更快、更便宜也更有教育意义。
### 5、Java 有可靠的开发工具
Java 有一些我最喜欢的 IDE<ruby>集成开发环境<rt>Integrated Development Environments</rt></ruby>),包括 [Eclipse][4]、[NetBeans][5]、[BlueJ][6] 和 IntelliJ IDEA。它们提供了调试、语法高亮、代码补完、语言支持、自动重构等功能。简而言之IDE 在 Java 的成功和你在 Java 学习中起着至关重要的作用!
### 6、印度对 Java 开发人员的需求
谷歌、Netflix 和 Instagram 等巨头都使用 Java 进行后台开发。印度公司正在积极寻找雇用 Java 程序员来开发安卓应用程序、新的 API 和云上的微服务。这种需求转化为更多的工作机会。
### 7、Java 有庞大的编程社区
Java 程序员的社区庞大,囊括了从初学者到专家的所有人。我发现这个社区很热情待人,当你寻求支持的时候,他们会给予帮助。最重要的是,通过参与在线讨论,我学到了大量的新技巧。作为社区的一分子,这是我了解最新趋势、学习更多语言和跟上发展的重要途径。
### 8、Java 是独立于平台
Java 是平台无关的这一点使它具有很高的价值。Java 源代码被编译成字节码,在 Java 虚拟机JVM上运行。任何运行 JVM 的平台(支持所有主要平台)都可以运行你的 Java 应用程序。你只需写一次就可以在任何地方运行这并不只是理论上的Java 实际上已经实现了这一点。你可以在你开发的任何平台上编写 Java并将其交付给你的所有目标平台。
网上有很多学习 Java 的资源,包括 Opensource.com 上有一个 [速查表][7]。还有一个很好的 [在线 Java 课程][8],可以用印地语免费学习。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/why-i-learned-core-java
作者:[Shantam Sahai][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/shantam-sahai
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/studying-books-java-couch-education.png?itok=C9gasCXr (Learning and studying technology is the key to success)
[2]: https://developer.ibm.com/components/open-jdk/
[3]: http://processing.org/
[4]: https://opensource.com/article/20/12/eclipse
[5]: https://opensource.com/article/20/12/netbeans
[6]: https://opensource.com/article/20/7/ide-java#bluej
[7]: https://opensource.com/downloads/java-cheat-sheet
[8]: https://www.learnvern.com/course/core-java-programming-tutorial

View File

@@ -0,0 +1,160 @@
[#]: subject: "How to Install Google Chrome on Debian and Kali Linux"
[#]: via: "https://itsfoss.com/install-chrome-debian-kali-linux/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13895-1.html"
如何在 Debian 和 Kali Linux 上安装 Chrome 浏览器
======
> Debian 和基于 Debian 的 Kali Linux 将 Firefox 作为默认的网页浏览器。但这并不意味着你不能在其中安装其他网页浏览器。
![](https://img.linux.net.cn/data/attachment/album/202110/18/175716cfvxnvf05b5je1ax.jpg)
Chrome 浏览器非常流行,你可能已经在其他系统上使用它了。如果你想在 Debian 上安装 Chrome你肯定可以这样做。
你在 Debian 的软件库中找不到 Chrome因为它不是开源软件但你可以从 Chrome 网站下载并安装它。
在本教程中,我将向你展示在 Debian 上安装 Chrome 的两种方法:
* GUI 方法
* 命令行方法
让我们先从 GUI 方法开始。
> 注意:我在这里的例子中使用的是 Debian但由于 Kali Linux 是基于 Debian 的,所以同样的方法也适用于 Kali Linux。
### 方法 1: 在 Debian 上以图形方式安装 Chrome 浏览器
这是一个不费吹灰之力的方法。你去 Chrome 网站,下载 deb 文件,然后双击它来安装它。我将详细地展示这些步骤,这样你就能很容易地掌握了。
前往 Chrome 的网站。
[Get Google Chrome][1]
你会看到下载 Chrome 的选项。
![Click on the Download Chrome button][2]
当你点击下载按钮时,它会给你两个下载安装文件的选项。选择写着 Debian/Ubuntu 的那个。
![Download the Chrome installer file for Debian][3]
**请注意Chrome 浏览器不适用于 32 位系统。**
接下来,你应该选择将文件保存到电脑中,而不是在软件中心打开进行安装。这样一来,下载的文件将被保存在下载文件夹中,而不是临时目录中。
![Save the downloaded DEB file for Google Chrome][4]
进入下载文件夹,右击下载的 DEB 文件,选择用 “Software Install” 打开它。
![Right click on the downloaded DEB file and open with Software Install][5]
它将打开软件中心,你应该看到现在安装 Chrome 浏览器的选项。点击安装按钮。
![Click on the install button][6]
你会被要求输入账户的密码。这是你用来登录系统的同一密码。
![Enter your accounts password][7]
在不到一分钟的时间里Chrome 就会安装完毕。你现在应该看到一个删除选项,这表明软件已经安装完毕。
![Chrome is now installed][8]
当 Chrome 在 Debian 上安装完毕,在系统菜单中搜索它并启动它。
![Start Google Chrome][9]
它将要求成为你的默认浏览器,并将崩溃报告发送给谷歌。你可以取消勾选这两个选项。然后你就可以看到谷歌浏览器的窗口。
![][10]
如果你登录了你的谷歌账户,你应该可以在这里同步你的密码、书签和其他浏览数据。好好体验吧!
还有一点,安装完 Chrome 后,你可以从系统中删除下载的 DEB 文件。不再需要它了,甚至在卸载 Chrome 时也不需要。
### 方法 2在 Debian 上从终端安装 Chrome
你刚才看到的内容可以在终端中轻松实现。
首先,确保你的软件包缓存已经刷新,并且你已经安装了 `wget`,用于 [在终端中从网上下载文件][11]。
```
sudo apt update && sudo apt install wget
```
接下来是下载 Chrome 的 .deb 文件。
```
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
```
下载后,你可以用 `apt` 命令 [在终端安装 deb 文件][12],像这样:
```
sudo apt install ./google-chrome-stable_current_amd64.deb
```
安装完成后,你就可以开始使用 Chrome 了。
### 额外提示:更新 Chrome
这两种方法都会将谷歌的软件库添加到你的系统中。你可以在你的 `sources.list.d` 目录中看到它:
```
cat /etc/apt/sources.list.d/google-chrome.list
```
这意味着 Chrome 将与 Debian 和 Kali Linux 中的其他系统更新一起被更新。你知道 [如何在命令行中更新你的 Kali Linux][13] 或 Debian 系统么?只要使用这个命令:
```
sudo apt update && sudo apt upgrade -y
```
### 从你的系统中卸载 Chrome
即使你选择用 GUI 方法在 Debian 上安装 Chrome你也必须使用终端来删除它。
不要担心。这其实只是一个命令:
```
sudo apt purge google-chrome-stable
```
根据要求输入你的账户密码。当你输入密码时,屏幕上没有任何显示。这没关系。输入它并按回车键,确认删除。
![][14]
好了,就这些了。我希望你觉得这个教程有帮助。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-chrome-debian-kali-linux/
作者:[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://www.google.com/chrome/
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/download-chrome-on-debian.webp?resize=800%2C344&ssl=1
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/downloading-google-chrome.webp?resize=800%2C512&ssl=1
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/save-downloaded-chrome-installer-file-debian.webp?resize=800%2C430&ssl=1
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/open-deb-file-with-software-install.webp?resize=800%2C419&ssl=1
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/installing-chrome-debian.webp?resize=800%2C408&ssl=1
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/enter-account-password-while-installing-deb-file.webp?resize=800%2C420&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/chrome-installed-debian.webp?resize=800%2C384&ssl=1
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/start-chrome-debian.webp?resize=800%2C276&ssl=1
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/Chrom-in-Debian.webp?resize=800%2C450&ssl=1
[11]: https://itsfoss.com/download-files-from-linux-terminal/
[12]: https://itsfoss.com/install-deb-files-ubuntu/
[13]: https://linuxhandbook.com/update-kali-linux/
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/remove-google-chrome-ubuntu.webp?resize=800%2C450&ssl=1

View File

@@ -0,0 +1,128 @@
[#]: subject: "The Official Raspberry Pi 4 Case Sucks! Heres What You Can do to Reduce the Overheating"
[#]: via: "https://itsfoss.com/raspberry-pi-case-overheating/"
[#]: author: "Avimanyu Bandyopadhyay https://itsfoss.com/author/avimanyu/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13851-1.html"
官方的树莓派 4 外壳很烂!怎么样减少过热?
======
![](https://img.linux.net.cn/data/attachment/album/202110/04/201826ghpecyb43cxehi4y.jpg)
[树莓派 4][1] 绝对是数百万人的最爱,特别是在极客社区里,我也不例外。但是你知道树莓派在没有适当冷却的情况下会限制性能吗?
在这里,我将介绍 [树莓派 4 官方外壳][2] 的一些严重缺点,同时也分享一些缓解这些缺点的方法。
![树莓派 4 官方外壳][3]
在第一次启动后,我的安装在 [树莓派 4 官方外壳][2] 内的树莓派 48GB 内存版),在无人值守的升级启动时,会高达 80℃。我在 Ubuntu 上进行了所有的 [固件更新][4],显然是为了 [解决发热问题][5]。
就算在空闲时,这个烫手的香草和草莓蛋糕也绝不会低于 75℃。
我几乎无法使用它,直到我取下外壳顶部的白色盖子。它闲置时的温度降到只有 67℃ 左右 —— 你相信吗?即使是在我重新启动一段时间后再次检查也是这样。很明显,这仍然是不太可接受。如果我买了这个外壳并打算长期使用,我为什么要一直把盖子打开?
为什么会发生这样的事情?这都是因为官方的树莓派外壳的设计非常糟糕。
### 官方的树莓派 4 外壳是一个发热怪物!
简单地说,[热节流][6] 就是降低你的树莓派处理器CPU的性能以使温度不超过极限高温如 80℃而 [导致损坏][7]。
这个外壳是由塑料制成的,它是热的不良导体(简单的 [传统物理学][8] 知识),因此无法将热量有效地散布到整个外壳和板子之外。因此,板上的处理器会发热,一旦温度达到惊人的程度,它的性能就会被降到一个极低的水平。我注意到,在第一次开机后,在**无人值守**的情况下进行升级时CPU 的温度为 80℃CPU 的使用率为 100%。
虽然这个官方的外壳看起来很美,但它对树莓派的性能造成了很大的影响。
如果你真的想让你的树莓派发挥最大的性能,你也必须负责它的冷却。这些发热问题不能被简单地忽视。
#### 热量被困在内部
一旦你把树莓派安装在这个外壳里,它甚至没有一个通风口可以让多余的热量排出。所以热量就一直在里面积累,直到达到那些疯狂的温度并触发了节流阀。
#### 没有风扇通风口(非常需要)
顶部的白色盖子上可以有一个圆形的通风口,至少可以把 [树莓派 4 的官方风扇][9] 放在上面使用。
#### 没有被动冷却
如果外壳是金属的,它就可以作为散热器,有效地将树莓派板上的处理器的热量散发出去。
#### 除了发热问题之外,还有其他的缺点
树莓派 4 官方外壳还有一些缺点:
1. 不便于 SD 卡管理:将树莓派板子装入外壳内,并将 SD 卡端口放在正确的方向上,以便以后能够换卡,这不是很方便。
2. 没有螺丝钉系统:没有提供螺丝,也许是因为它可能会破坏机箱底座上的假支架,这些假支架看起来就像你可以用四颗螺丝把板子牢牢地固定在底座上。
### 你可以做什么来控制树莓派 4 的过热?
在做了一些紧张的研究之后,我找到了市场上一些最好的冷却解决方案 —— 这一切都要归功于我们了不起的改装社区。
#### 使用冰塔式冷却器
我首先发现了 [Jeff Geerling's][10] 对各种树莓派散热器的深入性能评估,他在网上被称为 [geerlingguy][11]。在看完温度统计后,我直接选择了冰塔式散热器,并组装了它:
![树莓派 4 冰塔冷却器][12]
它空闲和低载时的温度下降到 30℃现在保持在 45℃ 左右。我还没有为它改装一个合适的外壳。我准备找个给冷却器提供了足够的空间的现成外壳。也许可以在亚马逊或其他网上商店找到这种外壳。
但我没有找到这种产品。
#### 使用铝制散热器进行被动散热
网上也有一个关于 [被动冷却][17] 的出色视频,测评了一个用铝制散热片做的外壳。
它提供了一个热垫,它相当于台式机处理器上使用的散热膏。按照视频中显示的方式放置它,热量就会从树莓派板上的处理器散发到整个外壳内。这就是科学的神奇之处!
#### 改装官方的树莓派外壳
如果你仍然想买官方的外壳,建议你至少要做一个风扇的改装。
### 潜在的制造解决方案
这里有一些解决方案,通过应用 [DevOps][21] 启发的改进,可以使整个制造过程更容易。
* 想一想,从外壳顶部切下的那块圆形塑料可以回收,用来制造更多的树莓派 4 外壳,不是吗?这显然会是一个双赢的局面,同时也降低了成本!
* 铝是地球上最丰富的金属,但 [全球供应中断][22] 可能是一个挑战。即使如此,还有其他的 [导电性解决方案][23] 来探索用于设计案例的材料!
### 总结
希望这篇文章能帮助你从树莓派 4 中获得最大的收益。我很想知道你的想法、建议和经验,请在下面的评论中留言。请不要犹豫地分享。
--------------------------------------------------------------------------------
via: https://itsfoss.com/raspberry-pi-case-overheating/
作者:[Avimanyu Bandyopadhyay][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://itsfoss.com/author/avimanyu/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/raspberry-pi-4/
[2]: https://www.raspberrypi.org/products/raspberry-pi-4-case/
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-4-official-case.webp?resize=800%2C533&ssl=1
[4]: https://www.einfochips.com/blog/understanding-firmware-updates-the-whats-whys-and-hows/
[5]: https://www.seeedstudio.com/blog/2019/11/29/raspberry-pi-4-firmware-update-pi-4-now-runs-cooler-than-ever/
[6]: https://www.pcmag.com/encyclopedia/term/thermal-throttling
[7]: https://www.pcgamer.com/cpu-temperature-overheat/
[8]: https://thermtest.com/stay-colder-for-longer-in-a-container-made-of-plastic-or-metal
[9]: https://www.raspberrypi.org/products/raspberry-pi-4-case-fan/
[10]: https://www.jeffgeerling.com/blog/2019/best-way-keep-your-cool-running-raspberry-pi-4
[11]: https://www.jeffgeerling.com/about
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-4-ice-tower-cooler.webp?resize=480%2C360&ssl=1
[13]: https://i0.wp.com/m.media-amazon.com/images/I/51g9gQC9k7L._SL160_.jpg?ssl=1
[14]: https://www.amazon.com/dp/B07V35SXMC?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (GeeekPi Raspberry Pi Cooling Fan, Raspberry Pi ICE Tower Cooler, RGB Cooling Fan with Raspberry Pi Heatsink for Raspberry Pi 4 Model B & Raspberry Pi 3B+ & Raspberry Pi 3 Model B)
[15]: https://www.amazon.com/gp/prime/?tag=chmod7mediate-20 (Amazon Prime)
[16]: https://www.amazon.com/dp/B07V35SXMC?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (Buy on Amazon)
[17]: https://buildabroad.org/2016/11/05/passive-cooling/
[18]: https://i2.wp.com/m.media-amazon.com/images/I/41XGLQONCVS._SL160_.jpg?ssl=1
[19]: https://www.amazon.com/dp/B07VD568FB?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 (Geekworm Raspberry Pi 4 Armor Case, Raspberry Pi 4 Computer Model B Armor Aluminum Alloy Passive Cooling Case Compatible with Raspberry Pi 4 Model B Only)
[20]: https://www.amazon.com/dp/B07VD568FB?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 (Buy on Amazon)
[21]: https://linuxhandbook.com/what-is-devops/
[22]: https://www.reuters.com/article/global-metals-idUSL1N2Q90GA
[23]: https://news.mit.edu/2018/engineers-turn-plastic-insulator-heat-conductor-0330

View File

@@ -0,0 +1,104 @@
[#]: subject: "Monitor your Java on Linux with jconsole"
[#]: via: "https://opensource.com/article/21/10/monitor-java-linux-jconsole"
[#]: author: "Alan Formy-Duval https://opensource.com/users/alanfdoss"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13860-1.html"
用 jconsole 在 Linux 上监控你的 Java
======
> 如何使用 Java 开发工具包中的 Java 监控和管理控制台。
![](https://img.linux.net.cn/data/attachment/album/202110/08/131129bf3h3gv18388fl11.jpg)
Java 开发工具包JDK提供了开发 Java 应用程序的二进制文件、工具和编译器。其中一个有用的工具是 `jconsole`
为了演示,我将使用 WildFly J2EE 应用服务器,它是 JBOSS 开源应用服务器项目的一部分。首先,我启动了一个独立的实例。
```
~/wildfly/24.0.1/bin$ ./standalone.sh
=========================================================================
  JBoss Bootstrap Environment
  JBOSS_HOME: /home/alan/wildfly/24.0.1
  JAVA: /usr/lib/jvm/java-11-openjdk-11.0.11.0.9-5.fc34.x86_64/bin/java
```
现在,在另一个终端,输入 `jconsole`
```
$ jconsole
```
启动后jconsole 会列出本地实例。选择“<ruby>本地进程<rt>Local Process</rt></ruby>”,然后选择进程的名称并点击“<ruby>连接<rt>Connect</rt></ruby>”。这就是连接并开始使用运行中的 Java 虚拟机JVM的 jconsole 的全部过程。
![jconsole 与本地进程的新连接屏幕][2]
### 概述
这个 Java 监控和管理控制台在仪表板的顶部显示进程标识符PID。“<ruby>概述<rt>Overview</rt></ruby>”标签有四个图表,显示“<ruby>堆内存使用情况<rt>Heap Memory Usage</rt></ruby>”、“<ruby>线程<rt>Threads</rt></ruby>”、“<ruby>类<rt>Classes</rt></ruby>”和“<ruby>CPU 使用情况<rt>CPU Usage</rt></ruby>”的重要信息。
![jconsole 仪表板显示堆内存使用量、线程、类和 CPU 使用量][4]
沿着顶部的标签提供每个区域的更详细的视图。
### 内存
“<ruby>内存<rt>Memory</rt></ruby>”标签显示 JVM 所使用的内存的各个方面的图表。分配给 JVM 的服务器系统内存量被称为“<ruby>堆<rt>Heap</rt></ruby>”。这个屏幕还提供了关于堆的内部组件使用情况的详细信息,例如 “<ruby>伊甸园<rt>Eden Space</rt></ruby>”、“<ruby>老年代<rt>Old Gen</rt></ruby>” 和 “<ruby>幸存者区<rt>Survivor Space</rt></ruby>”。你也可以手动请求一个垃圾收集动作。
![jconsole 内存标签][5]
### 线程
“<ruby>线程<rt>Threads</rt></ruby>”标签显示有多少线程在运行。你也可以手动检查是否存在死锁。
![jconsole 线程仪表板显示了随时间变化的线程数量和滚动的线程列表][6]
### 类
“<ruby>类<rt>Classes</rt></ruby>”标签告诉你有多少类被加载,有多少被卸载。
![jconsole 类标签显示随着时间推移加载的类数量][7]
### 虚拟机摘要
“<ruby>虚拟机摘要<rt>VM Summary</rt></ruby>”标签提供了许多关于应用程序和主机系统的细节。你可以了解你所处的操作系统和架构、系统内存总量、CPU 数量,甚至交换空间。
![jconsole 虚拟机摘要标签][8]
摘要中显示的关于 JVM 的进一步细节,包括当前和最大的堆大小以及正在使用的垃圾收集器的信息。底部的窗格列出了传递给 JVM 的所有参数。
### MBeans
最后一个标签MBeans让你通过所有的 MBeans 向下钻取,以查看每个 MBeans 的属性和值。
![MBeans 标签][9]
### 总结
Java 已经存在了很长时间,它将继续为全球数百万的系统提供动力。有很多开发环境和监控系统可以使用,但像 `jconsole` 这样的包含在基本工具包中的工具非常有价值。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/monitor-java-linux-jconsole
作者:[Alan Formy-Duval][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/alanfdoss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
[2]: https://opensource.com/sites/default/files/uploads/jconsole_new_connection_local.png (new connection)
[3]: https://creativecommons.org/licenses/by-sa/4.0/deed.ast
[4]: https://opensource.com/sites/default/files/uploads/jconsole_tab_overview.png (tab overview)
[5]: https://opensource.com/sites/default/files/uploads/jconsole_tab_memory.png (memory tab)
[6]: https://opensource.com/sites/default/files/uploads/jconsole_tab_threads.png (threads tab)
[7]: https://opensource.com/sites/default/files/uploads/jconsole_tab_classes.png (classes tab)
[8]: https://opensource.com/sites/default/files/uploads/jconsole_tab_vm-summary.png (VMsummary tab )
[9]: https://opensource.com/sites/default/files/uploads/jconsole_tab_mbeans.png (MBeans tab)

View File

@@ -0,0 +1,57 @@
[#]: subject: "Open Source Changed Linux Otherwise It Was Done: Linus Torvalds"
[#]: via: "https://news.itsfoss.com/open-source-changed-linux-torvalds/"
[#]: author: "Abhishek https://news.itsfoss.com/author/root/"
[#]: collector: "lujun9972"
[#]: translator: "zd200572"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13890-1.html"
Linus Torvalds :开源改变了 Linux, 否则它就完了
======
> Linux 本来会像其他业余项目一样被抛在后面,但开源改变了这一点。
![](https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/torvalds-linux-kernel.png?w=1200&ssl=1)
你可能已经知道这个故事30 年前,芬兰学生 Linus Torvalds 开发了一个业余项目,创建了一个类 UNIX 操作系统。
你不知道的是Torvalds 认为这个业余项目已经完成了,他本想把它抛在脑后,做一些新的、有趣的项目。
那么,是什么让他在这个“业余项目”上工作了 30 年呢?答案是开源。
### 开源改变了 Linux
在最近结束的 [北美开源峰会][1] 上Linus Torvalds 分享了一些关于 Linux 项目过去、现在和未来的见解。
当回忆起这个项目的最初情况时,[Torvalds 说][2] 他本以为会以“已完成的状态”抛下 Linux 这个项目,而去做些新的、有趣的事情。
> 显然是开源改变了这一切。这个项目,如果是由我来决定,我可能会把它抛在一边,但是突然间,我开始收到各种问题,最后还有人们提交的补丁,这使得我的动力不断持续。现在 30 年过去了,这仍然是动力所在。
Torvalds 还补充说就他而言Linux 在过去 29 年里已经完成了。以后添加的每一个其他的功能,都是其他人需要、想要或感兴趣的。
许多开发人员都会遇到这种情况。你在一个项目上工作,认为它已经达到“完成”的状态了,如果这个项目没有足够的吸引力,你就会对它失去兴趣,转而去做一些“新的、有趣的”事情。实际上继续这个项目的真正动力来自用户和认可。
当被问及 Linux 50 周年要做些什么时Torvalds 说,他不认为自己在 70 岁的时候还能继续做内核编程。然后他还补充说,他也没想过自己在 50 岁还在做内核编程,但他现在却在做这个事情。
> “不知何故,我不认为我 70 岁还能做内核编程。但是另一方面,几年前,我也没想到自己 50 岁还在做内核编程,所以……我们拭目以待。”
我们总是愿意听 Torvalds 谈论 Linux作为一个热心的 Linux 用户,我们还有如此多需要学习和交流的东西!
来源:[The News Stack][2]
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/open-source-changed-linux-torvalds/
作者:[Abhishek][a]
选题:[lujun9972][b]
译者:[zd200572](https://github.com/zd200572)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://news.itsfoss.com/author/root/
[b]: https://github.com/lujun9972
[1]: https://events.linuxfoundation.org/open-source-summit-north-america/
[2]: https://thenewstack.io/linus-torvalds-on-community-rust-and-linuxs-longevity/

View File

@@ -0,0 +1,364 @@
[#]: subject: "Tools to explore BGP"
[#]: via: "https://jvns.ca/blog/2021/10/05/tools-to-look-at-bgp-routes/"
[#]: author: "Julia Evans https://jvns.ca/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13857-1.html"
由 Facebook 事故引发的 BGP 工具探索
======
![](https://img.linux.net.cn/data/attachment/album/202110/07/093743krr8ftrpvgfrvffx.jpg)
昨天Facebook 发生了由 BGP 引起的离线事故。我对学习更多关于 BGP 的知识已经隐约感兴趣了很长时间,所以我阅读了一些文章。
我感到很沮丧,因为没有一篇文章告诉我如何在我的电脑上实际查找与 BGP 有关的信息,因此我 [写了一条询问有关工具的推特][1]。
我一如既往地得到了一堆有用的回复,所以这篇博文展示了一些你可以用来查询 BGP 信息的工具。这篇文章中可能会有较多的错误,因为我对 BGP 不是很了解。
### 我不能发布 BGP 路由
我从来没有了解过 BGP 的原因之一是,据我所知,我没有在互联网上发布 BGP 路由的权限。
对于大多数网络协议,如果需要,你可以非常轻松地自己实现该协议。例如,你可以:
* 发行你自己的 TLS 证书
* 编写你自己的 HTTP 服务器
* 编写你自己的 TCP 实现
* 为你的域名编写你自己的权威 DNS 服务器(我现在正在为一个小项目尝试这样做)
* 建立你自己的证书机构CA
但是对于 BGP我认为除非你拥有自己的 ASN否则你不能自己发布路由你*可以*在你的家庭网络上实现 BGP但这对我来说有点无聊当我做实验的时候我希望它们真的在真正的互联网上
无论如何,尽管我不能用它做实验,但我仍然认为它超级有趣,因为我喜欢网络,所以我将向你展示我找到的一些用来学习 BGP 的工具。
首先我们来谈谈 BGP 的一些术语。我打算很快掠过,因为我对工具更感兴趣,而且网上有很多关于 BGP 的高水平解释(比如这篇 [cloudflare 的文章][2])。
### AS 是什么?
我们首先需要了解的是 AS“<ruby>自治系统<rt>autonomous system</rt></ruby>”)。每个 AS
1. 由一个组织拥有(通常是一个大型组织,如你的 ISP、政府、大学、Facebook 等)。
2. 控制一组特定的 IP 地址(例如,我的 ISP 的 AS 包括 247,808 个 IP 地址)。
3. 有一个编号 ASN如 1403
下面是我通过做一些实验对 AS 的一些观察:
* 一些相当大的科技公司并没有自己的 AS。例如我在 BGPView 上查看了 Patreon就我所知他们没有自己的 AS他们的主要网站`patreon.com`[104.16.6.49][3])在 Cloudflare 的 AS 中。
* 一个 AS 可以包括许多国家的 IP。Facebook 的 AS[AS32934][4])肯定有新加坡、加拿大、尼日利亚、肯尼亚、美国和其他国家的 IP 地址。
* 似乎 IP 地址可以在一个以上的 AS 中。例如,如果我查找 [209.216.230.240][5],它有 2 个 ASN 与之相关:`AS6130``AS21581`。显然,当这种情况发生时,更具体的路线会被优先考虑 —— 所以到该 IP 的数据包会被路由到 `AS21581`
### 什么是 BGP 路由?
互联网上有很多的路由器。例如,我的 ISP 就有路由器。
当我给我的 ISP 发送一个数据包时(例如通过运行 `ping 129.134.30.0`),我的 ISP 的路由器需要弄清楚如何将我的数据包实际送到 IP 地址 `129.134.30.0`
路由器计算的方法是,它有一个**路由表**:这是个有一堆 IP 地址范围的列表(比如 `129.134.30.0/23`),以及它知道的到达该子网的路由。
下面是一个 `129.134.30.0/23` Facebook 的一个子网)的真实路由的例子。这不是来自我的 ISP。
```
11670 32934
206.108.35.2 from 206.108.35.254 (206.108.35.254)
Origin IGP, metric 0, valid, external
Community: 3856:55000
Last update: Mon Oct 4 21:17:33 2021
```
我认为这是在说通往 `129.134.30.0` 的一条路径是通过机器 `206.108.35.2`,这是在它的本地网络上。所以路由器接下来可能会把我的 ping 包发送到 `206.108.35.2`,然后 `206.108.35.2` 会知道如何把它送到 Facebook。开头的两个数字`11670 32934`)是 ASN。
### BGP 是什么?
我对 BGP 的理解非常浅薄,它是一个公司用来公布 BGP 路由的协议。
昨天发生在 Facebook 身上的事情基本上是他们发布了一个 BGP 公告,撤销了他们所有的 BGP 路由,所以世界上的每个路由器都删除了所有与 Facebook 有关的路由,没有流量可以到达那里。
好了,现在我们已经涵盖了一些基本的术语,让我们来谈谈你可以用来查看 AS 和 BGP 的工具吧!
### 工具 1用 BGPView 查看你的 ISP 的 AS
为了使 AS 这个东西不那么抽象,让我们用一个叫做 [BGPView][6]的 工具来看看一个真实的 AS。
我的 ISPEBOX拥有 [AS 1403][7]。这是 [我的 ISP 拥有的 IP 地址][8]。如果我查找我的计算机的公共 IPv4 地址,我可以看到它是我的 ISP 拥有的IP地址之一它在 `104.163.128.0/17` 块中。
BGPView 也有这个图,显示了我的 ISP 与其他 AS 的连接情况。
![][9]
### 工具 2traceroute -A 和 mtr -z
好了,我们感兴趣的是 AS 。让我们看看我从哪些 AS 中穿过。
`traceroute``mtr` 都有选项可以告诉你每个 IP 的 ASN。其选项分别是 `traceroute -A``mtr -z`
让我们看看我用 `mtr` 在去 `facebook.com` 的路上经过了哪些 AS
```
$ mtr -z facebook.com
1. AS??? LEDE.lan
2. AS1403 104-163-190-1.qc.cable.ebox.net
3. AS??? 10.170.192.58
4. AS1403 0.et-5-2-0.er1.mtl7.yul.ebox.ca
5. AS1403 0.ae17.er2.mtl3.yul.ebox.ca
6. AS1403 0.ae0.er1.151fw.yyz.ebox.ca
7. AS??? facebook-a.ip4.torontointernetxchange.net
8. AS32934 po103.psw01.yyz1.tfbnw.net
9. AS32934 157.240.38.75
10. AS32934 edge-star-mini-shv-01-yyz1.facebook.com
```
这很有意思,看起来我们直接从我的 ISP 的 AS`1403`)到 Facebook 的 AS`32934`),中间有一个“互联网交换”。
> 我不确定 <ruby>[互联网交换][10]<rt>internet exchange</rt></ruby>IX是什么但我知道它是互联网的一个极其重要的部分。不过这将是以后的事了。我猜是它是互联网中实现“对等”的部分就假设它是一个有巨大的交换机的机房里面有无限的带宽一堆不同的公司把他们的电脑放在里面这样他们就可以互相发送数据包。
#### mtr 用 DNS 查找 ASN
我对 `mtr` 如何查找 ASN 感到好奇,所以我使用了 `strace`。我看到它看起来像是在使用 DNS所以我运行了 [dnspeep][11],然后就看到了!
```
$ sudo dnspeep
...
TXT 1.190.163.104.origin.asn.cymru.com 192.168.1.1 TXT: 1403 | 104.163.176.0/20 | CA | arin | 2014-08-14, TXT: 1403 | 104.163.160.0/19 | CA | arin | 2014-08-14, TXT: 1403 | 104.163.128.0/17 | CA | arin | 2014-08-14
...
```
所以,看起来我们可以通过查找 `1.190.163.104.origin.asn.cymru.com` 上的 `txt` 记录找到 `104.163.190.1` 的 ASN像这样
```
$ dig txt 1.190.163.104.origin.asn.cymru.com
1.190.163.104.origin.asn.cymru.com. 13911 IN TXT "1403 | 104.163.160.0/19 | CA | arin | 2014-08-14"
1.190.163.104.origin.asn.cymru.com. 13911 IN TXT "1403 | 104.163.128.0/17 | CA | arin | 2014-08-14"
1.190.163.104.origin.asn.cymru.com. 13911 IN TXT "1403 | 104.163.176.0/20 | CA | arin | 2014-08-14"
```
这很好!让我们继续前进吧。
### 工具 3数据包交换所的观察镜
PCH“<ruby>数据包交换所<rt>packet clearing house</rt></ruby>”)是运行大量互联网交换点的组织。“<ruby>观察镜<rt>looking glass</rt></ruby>”似乎是一个通用术语,指的是让你从另一个人的计算机上运行网络命令的 Web 表单。有一些观察镜不支持 BGP但我只对那些能显示 BGP 路由信息的观察镜感兴趣。
这里是 PCH 的观察镜: <https://www.pch.net/tools/looking_glass/> 。
在该网站的 Web 表单中,我选择了多伦多 IX“TORIX”因为 `mtr` 说我是用它来访问 `facebook.com` 的。
#### 操作 1显示 ip bgp 摘要
下面是输出结果。我修改了其中的一些内容:
```
IPv4 Unicast Summary:
BGP router identifier 74.80.118.4, local AS number 3856 vrf-id 0
BGP table version 33061919
RIB entries 513241, using 90 MiB of memory
Peers 147, using 3003 KiB of memory
Peer groups 8, using 512 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
...
206.108.34.248 4 1403 484672 466938 0 0 0 05w3d03h 50
...
206.108.35.2 4 32934 482088 466714 0 0 0 01w6d07h 38
206.108.35.3 4 32934 482019 466475 0 0 0 01w0d06h 38
...
Total number of neighbors 147
```
我的理解是,多伦多 IX“TORIX”直接连接到我的 ISP EBOXAS 1403和 FacebookAS 32934
#### 操作 2显示 ip bgp 129.134.30.0
这是筛选自 `show ip bgp``129.134.30.0`Facebook 的一个 IP 地址)的输出:
```
BGP routing table entry for 129.134.30.0/23
Paths: (4 available, best #4, table default)
Advertised to non peer-group peers:
206.220.231.55
11670 32934
206.108.35.2 from 206.108.35.254 (206.108.35.254)
Origin IGP, metric 0, valid, external
Community: 3856:55000
Last update: Mon Oct 4 21:17:33 2021
11670 32934
206.108.35.2 from 206.108.35.253 (206.108.35.253)
Origin IGP, metric 0, valid, external
Community: 3856:55000
Last update: Mon Oct 4 21:17:31 2021
32934
206.108.35.3 from 206.108.35.3 (157.240.58.225)
Origin IGP, metric 0, valid, external, multipath
Community: 3856:55000
Last update: Mon Oct 4 21:17:27 2021
32934
206.108.35.2 from 206.108.35.2 (157.240.58.182)
Origin IGP, metric 0, valid, external, multipath, best (Older Path)
Community: 3856:55000
Last update: Mon Oct 4 21:17:27 2021
```
这似乎是在说,从该 IX 到 Facebook 有 4 条路线。
**魁北克 IX 似乎对 Facebook 一无所知**
我也试过从魁北克 IX“QIX”它可能离我更近因为我住在蒙特利尔而不是多伦多做同样的事情。但 QIX 似乎对 Facebook 一无所知:当我输入`129.134.30.0` 时,它只是说 “% 网络不在表中”。
所以我想这就是为什么我被送到多伦多 IX 而不是魁北克的 IX。
#### 更多的 BGP 观察镜
这里还有一些带观察镜的网站,可以从其他角度给你类似的信息。它们似乎都支持相同的 `show ip bgp` 语法,也许是因为他们运行的是同一个软件?我不太确定。
* <http://www.routeviews.org/routeviews/index.php/collectors/>
* <http://www.routeservers.org/>
* <https://lg.he.net/>
似乎有很多这样的观察镜服务,远不止这 3 个列表。
这里有一个与这个列表上的一个服务器进行会话的例子:`route-views.routeviews.org`。这次我是通过 telnet 连接的,而不是通过 Web 表单,但输出的格式看起来是一样的。
```
$ telnet route-views.routeviews.org
route-views>show ip bgp 31.13.80.36
BGP routing table entry for 31.13.80.0/24, version 1053404087
Paths: (23 available, best #2, table default)
Not advertised to any peer
Refresh Epoch 1
3267 1299 32934
194.85.40.15 from 194.85.40.15 (185.141.126.1)
Origin IGP, metric 0, localpref 100, valid, external
path 7FE0C3340190 RPKI State valid
rx pathid: 0, tx pathid: 0
Refresh Epoch 1
6939 32934
64.71.137.241 from 64.71.137.241 (216.218.252.164)
Origin IGP, localpref 100, valid, external, best
path 7FE135DB6500 RPKI State valid
rx pathid: 0, tx pathid: 0x0
Refresh Epoch 1
701 174 32934
137.39.3.55 from 137.39.3.55 (137.39.3.55)
Origin IGP, localpref 100, valid, external
path 7FE1604D3AF0 RPKI State valid
rx pathid: 0, tx pathid: 0
Refresh Epoch 1
20912 3257 1299 32934
212.66.96.126 from 212.66.96.126 (212.66.96.126)
Origin IGP, localpref 100, valid, external
Community: 3257:8095 3257:30622 3257:50001 3257:53900 3257:53904 20912:65004
path 7FE1195AF140 RPKI State valid
rx pathid: 0, tx pathid: 0
Refresh Epoch 1
7660 2516 1299 32934
203.181.248.168 from 203.181.248.168 (203.181.248.168)
Origin IGP, localpref 100, valid, external
Community: 2516:1030 7660:9001
path 7FE0D195E7D0 RPKI State valid
rx pathid: 0, tx pathid: 0
```
这里有几个路由的选择:
* `3267 1299 32934`
* `6939 32934`
* `701 174 32934`
* `20912 3257 1299 32934`
* `7660 2516 1299 32934`
我想这些都有不止一个 AS 的原因是,`31.13.80.36` 是 Facebook 在多伦多的 IP 地址,所以这个服务器(可能在美国西海岸,我不确定)不能直接连接到它,它需要先到另一个 AS。所以所有的路由都有一个或多个 ASN。
最短的是 `6939`“Hurricane Electric”它是一个 “全球互联网骨干”。他们也有自己的 [Hurricane Electric 观察镜][12] 页面。
### 工具 4BGPlay
到目前为止,所有其他的工具都只是向我们展示了 Facebook 路由的当前状态,其中一切正常,但这第四个工具让我们看到了这个 Facebook BGP 互联网灾难的历史。这是一个 GUI 工具,所以我将包括一堆屏幕截图。
该工具在 <https://stat.ripe.net/special/bgplay>。我输入了 IP 地址 `129.134.30.12`Facebook 的一个 IP如果你想一起试试。
首先,让我们看看一切出错之前的状态。我点击了在 10 月 4 日 13:11:28 的时间线,得到了这个结果:
![][13]
我最初发现这很让人不知所措。发生了什么事?但后来有人在推特上指出,下一个要看的地方是点击 Facebook 灾难发生后的时间线10 月 4 日 18 点 38 分)。
![][14]
很明显,这张图有问题:所有的 BGP 路线都不见了!哦,不要!
顶部的文字显示了最后一条 Facebook BGP 路由的消失:
```
Type: W > withdrawal Involving: 129.134.30.0/24
Short description: The route 50869, 25091, 32934 has been withdrawn.
Date and time: 2021-10-04 16:02:33 Collected by: 20-91.206.53.12
```
如果我再点击“<ruby>快进<rt>fast forward</rt></ruby>”按钮,我们看到 BGP 路由开始回来了。
![][15]
第一个宣告的是 `137409 32934`。但我不认为这实际上是第一个宣布的,在同一秒内有很多路由宣告(在 2021-10-04 21:00:40我认为 BGPlay 内部的排序是任意的。
如果我再次点击“<ruby>快进<rt>fast forward</rt></ruby>”按钮,越来越多的路由开始回来,路由开始恢复正常。
我发现在 BGPlay 里看这个故障真的很有趣,尽管一开始界面很混乱。
### 也许了解一下 BGP 是很重要的?
我在这篇文章的开头说,你不能改变 BGP 路由,但后来我想起在 2016 年或 2017 年,有一个 [Telia 路由问题][16],给我们的工作造成了一些小的网络问题。而当这种情况发生时,了解为什么你的客户无法到达你的网站其实是很有用的,即使它完全不受你控制。当时我不知道这些工具,但我希望能知道!
我认为对于大多数公司来说,应对由其他人的错误 BGP 路由造成的中断你所能做的就是“什么都不做等待它得到修复”但能够_自信地_什么都不做是很好的。
### 一些发布 BGP 路由的方法
如果你想(作为一个业余爱好者)真正发布 BGP 路由,这里有一些评论中的链接:
* [获取你自己的 ASN 的指南][17]
* [dn42][18] 似乎有一个 BGP 的实验场(它不在公共互联网上,但确实有其他人在上面,这似乎比自己在家里做 BGP 实验更有趣)
### 目前就这些了
我想还有很多 BGP 工具(比如 PCH 有一堆 [路由数据的每日快照][19],看起来很有趣),但这篇文章已经很长了,而且我今天还有其他事情要做。
我对我作为一个普通人可以得到这么多关于 BGP 的信息感到惊讶,我一直认为它是一个“秘密的网络巫师”这样的东西,但显然有各种公共机器,任何人都可以直接 telnet 到它并用来查看路由表!没想到!
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2021/10/05/tools-to-look-at-bgp-routes/
作者:[Julia Evans][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://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://twitter.com/b0rk/status/1445199475195236356
[2]: https://blog.cloudflare.com/october-2021-facebook-outage/
[3]: https://bgpview.io/ip/104.16.6.49
[4]: https://bgpview.io/asn/32934#prefixes-v4
[5]: https://bgpview.io/ip/209.216.230.240
[6]: https://bgpview.io
[7]: https://bgpview.io/asn/1403
[8]: https://bgpview.io/asn/1403#prefixes-v4
[9]: https://jvns.ca/images/ebox-graph.png
[10]: https://en.wikipedia.org/wiki/Internet_exchange_point
[11]: https://github.com/jvns/dnspeep/
[12]: https://lg.he.net/
[13]: https://jvns.ca/images/bgplay-before.png
[14]: https://jvns.ca/images/bgplay-after.png
[15]: https://jvns.ca/images/bgplay-return.png
[16]: https://news.ycombinator.com/item?id=14246888
[17]: https://labs.ripe.net/author/samir_jafferali/build-your-own-anycast-network-in-nine-steps/
[18]: https://dn42.eu/Home
[19]: https://www.pch.net/resources/Routing_Data/IPv4_daily_snapshots/

View File

@@ -0,0 +1,70 @@
[#]: subject: "Check Java processes on Linux with the jps command"
[#]: via: "https://opensource.com/article/21/10/check-java-jps"
[#]: author: "Alan Formy-Duval https://opensource.com/users/alanfdoss"
[#]: collector: "lujun9972"
[#]: translator: "unigeorge"
[#]: reviewer: "turbokernel"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13871-1.html"
在 Linux 上使用 jps 命令检查 Java 进程
======
> 系统上运行着诸多进程,通过 `jps` 命令能够快速有效识别 Java 进程。
![](https://img.linux.net.cn/data/attachment/album/202110/11/102806lhhtyalq2lv2vbte.jpg)
在 Linux 中,有一些用于查看系统上运行进程的命令。进程是指由内核管理的正在进行的事件。每启动一个应用程序时,就会产生一个进程,但也有许多在计算机后台运行的进程,如保持系统时间准确的进程、监听新文件系统的进程、索引化文件的进程等。有一些可以用来监测这些进程的实用程序,比如包含在 [procps-ng 包][2] 中的程序,但它们往往都是对各种进程通用的。它们会查看计算机上的所有进程,你可以根据需要过滤结果列表。
在 Linux 中,可以通过 `ps` 命令查看进程。这是查看当前系统上运行进程最简单的方法。
```
$ ps
    PID TTY          TIME CMD
   4486 pts/0    00:00:00 bash
  66930 pts/0    00:00:00 ps
```
你也可以通过 `ps` 命令,并配合结果输出管道符进行 `grep`,从而查看系统上运行的 Java 进程,。
```
$ ps ax |grep java
67604 pts/1 Sl+ 0:18 /usr/lib/jvm/java-11-openjdk-11.0.12.0.7-4.fc34.x86_64/bin/java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.desktop/sun.awt=ALL-UNNAMED --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED -Dorg.jboss.boot.log.file=/home/alan/wildfly/24.0.1/standalone/log/server.log -Dlogging.configuration=file:/home/alan/wildfly/24.0.1/standalone/configuration/logging.properties -jar /home/alan/wildfly/24.0.1/jboss-modules.jar -mp /home/alan/wildfly/24.0.1/modules org.jboss.as.standalone -Djboss.home.dir=/home/alan/wildfly/24.0.1 -Djboss.server.base.dir=/home/alan/wildfly/24.0.1/standalone
```
然而OpenJDK 有自己专属的进程监视器。<ruby>Java 虚拟机进程状态<rt>Java Virtual Machine Process Status</rt></ruby>jps工具可以帮你扫描系统上所有运行的 Java 虚拟机JVM实例。
要想实现与 `ps` 命令类似的输出,可以使用 `-v` 选项。这很实用,这与 `ps` 相比,可以减少你的输入。
```
$ jps -v
67604 jboss-modules.jar -D[Standalone] -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.desktop/sun.awt=ALL-UNNAMED --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED -Dorg.jboss.boot.log.file=/home/alan/wildfly/24.0.1/standalone/log/server.log -Dlogging.configuration=file:/home/alan/wildfly/24.0.1/standalone/configuration/logging.properties
```
`jps` 命令的默认输出包含进程标识符,类名或 Jar 文件名。
```
$ jps
67604 jboss-modules.jar
69430 Jps
```
**注意:** `jps` 的手册页指出此命令是试验性且不受支持的。尽管如此,它仍然是一个不错的选择,因为一个系统通常运行着许多进程,这种只识别 Java 进程的快速方法是很有用的。
当下的 Java 仍然是一种流行的语言,所以熟悉 Java 开发工具包和运行时环境仍然很重要。它们包含着许多适用于 Java 应用程序开发和维护的工具。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/check-java-jps
作者:[Alan Formy-Duval][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[turbokernel](https://github.com/turbokernel)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/alanfdoss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/java-coffee-beans.jpg?itok=3hkjX5We (Coffee beans)
[2]: https://opensource.com/article/21/8/linux-procps-ng

View File

@@ -0,0 +1,94 @@
[#]: subject: "DirectX 11/12 Games like Cyberpunk 2077 Can Use NVIDIA DLSS With Proton Experimental on Linux"
[#]: via: "https://news.itsfoss.com/nvidia-dlss-dx-11-12-proton/"
[#]: author: "Rishabh Moharir https://news.itsfoss.com/author/rishabh/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13865-1.html"
《赛博朋克 2077》等 DirectX 11/12 游戏可在 Linux 上体验 DLSS 了
======
> 通过 Steam Proton 的实验版本,期待已久的 Nvidia DLSS 支持在 Linux 上的 DirectX 11/12 大作中出现。
![](https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/nvidia-dlss-proton.png?w=1200&ssl=1)
6 月,英伟达 [宣布][1] 通过 Steam Proton 支持 Linux 中的 DLSS并为基于 Vulkan 的游戏提供了测试版驱动程序。
DLSS 是指<ruby>深度学习超级采样<rt>Deep Learning Super Sampling</rt></ruby>。它利用由 RTX GPU 中的 Tensor 核心提供支持的深度学习算法来提升游戏中的图像。这将使图像更清晰、更锐利,并提高帧率。
![来源:英伟达][2]
这种 [升级技术][3] 类似于 AMD 的 Fidelity FX甚至更接近于英特尔即将推出的 XeSS与 DLSS 不同的是这两者都是开源的。玩家已经可以通过 [GloriousEggroll][4] 的定制 Proton GE 版本体验到 Fidelity FX。
此外,英伟达还计划在今年秋天之前将支持范围扩大到 DirectX 游戏。
而且,随着最新的 Proton 实验性支持,这一切终于实现了。使用英伟达 GPU 的 Linux 游戏玩家现在可以用 DLSS 玩他们最喜欢的基于 DX11/12 的游戏。
考虑到我们很快就能在 Linux 上玩各种多人游戏,并且 [Proton 中添加了对 BattleEye & Easy-Anti Cheat 的支持][5],这是进行这项添加的最好时机。
### Steam Porton 的重大更新
几天前,伴随着 Proton 6.3-7 的一波改进Valve 终于设法将 DLSS 支持添加到 Proton 的 DirectX 11/12 游戏实验分支中。
在此之前,需要一个测试版驱动程序才能将 DLSS 用于基于 Vulkan 的游戏,例如 DOOM Eternal。
但是,现在不再如此 —— 尽管推荐使用最新的驱动程序。
作为补充DXVK 和 Steamworks SDK 也已经更新到最新的开发版本。此外,还修复了特定游戏的性能问题和其他错误。
你可以查看 Proton 的 [官方 GitHub 更新日志][6] 来了解到目前为止支持的所有游戏的改进列表。
### 为 DX11/12 游戏启用 DLSS
启用 DLSS 是一个简单明了的过程。
首先,你必须确保你的 Windows 游戏可以在 Proton Experimental 上运行。
这可以通过右键点击游戏并选择“<ruby>属性<rt>Properties</rt></ruby>”来完成。然后在“<ruby>兼容性<rt>Compatibility</rt></ruby>”下,你需要勾选“<ruby>强制使用特定的 Steam Play 兼容工具<rt>Force the use of a specific Steam Play compatibility tool</rt></ruby>”复选框。接下来,从下拉菜单中选择 “Proton Experimental”。
![][7]
最后,你需要在“<ruby>启动选项<rt>Launch Options</rt></ruby>”中插入命令:`PROTON_HIDE_NVIDIA_GPU=0 PROTON_ENABLE_NVAPI=1 %command%`
![][8]
这就行了。你就可以用 DLSS 玩你的游戏了!
### 总结
英伟达 DLSS 对于许多游戏来说是一个非常需要的功能,因为它的作用很大。
Linux 从一开始就没有对 DLSS 的全面支持。但是,看起来它很快就会在未来的 Proton 稳定版本中提供,并进行必要的改进。
Linux 玩家终于可以用基于 RTX 的 GPU 在许多游戏中体验到更好的帧率和视觉质量。
虽然我在 AMD 显卡上使用 Fidelity FX但我仍然渴望在 RTX GPU 上尝试 DLSS
你对英伟达 DLSS 的到来有什么感觉?你会很快尝试它吗?欢迎在下面分享你的评论。
转自:[GamingOnLinux][9]。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/nvidia-dlss-dx-11-12-proton/
作者:[Rishabh Moharir][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://news.itsfoss.com/author/rishabh/
[b]: https://github.com/lujun9972
[1]: https://www.nvidia.com/en-us/geforce/news/june-2021-rtx-dlss-game-update/
[2]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/DLSS_RDD2.jpg?w=800&ssl=1
[3]: https://news.itsfoss.com/intel-xess-open-source/
[4]: https://github.com/GloriousEggroll/proton-ge-custom
[5]: https://news.itsfoss.com/easy-anti-cheat-linux/
[6]: https://github.com/ValveSoftware/Proton/wiki/Changelog
[7]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/Compatibility.png?w=836&ssl=1
[8]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/Commands-1.png?w=831&ssl=1
[9]: https://www.gamingonlinux.com/2021/10/proton-experimental-expands-nvidia-dlss-support-on-linux-to-directx-11-titles

View File

@@ -0,0 +1,218 @@
[#]: subject: "Rotate and archive logs with the Linux logrotate command"
[#]: via: "https://opensource.com/article/21/10/linux-logrotate"
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
[#]: collector: "lujun9972"
[#]: translator: "perfiffer"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13909-1.html"
使用 logrotate 命令轮转和归档日志
======
> 使用此 Linux 命令保持日志文件更新。
![](https://img.linux.net.cn/data/attachment/album/202110/22/113833i6ikk4dzdm3y3hkk.jpg)
日志非常适合找出应用程序在做什么或对可能的问题进行故障排除。几乎我们处理的每个应用程序都会生成日志,我们希望我们自己开发的应用程序也生成日志。日志越详细,我们拥有的信息就越多。但放任不管,日志可能会增长到无法管理的大小,反过来,它们可能会成为它们自己的问题。因此,最好将它们进行裁剪,保留我们需要的那些,并将其余的归档。
### 基本功能
`logrotate` 实用程序在管理日志方面非常出色。它可以轮转日志、压缩日志、通过电子邮件发送日志、删除日志、归档日志,并在你需要时开始记录最新的。
运行 `logrotate` 非常简单——只需要运行 `logrotate -vs state-file config-file`。在上面的命令中,`v` 选项开启详细模式,`s` 指定一个状态文件,最后的 `config-file` 是配置文件,你可以指定需要做什么。
### 实战演练
让我们看看在我们的系统上静默运行的 `logrotate` 配置,它管理我们在 `/var/log` 目录中找到的大量日志。查看该目录中的当前文件。你是否看到很多 `*.[number].gz` 文件?这就是 `logrotate` 正在做的。你可以在 `/etc/logrotate.d/rsyslog` 下找到此配置文件。我的配置文件如下:
```
/var/log/syslog
{
        rotate 7
        daily
        missingok
        notifempty
        delaycompress
        compress
        postrotate
                reload rsyslog > /dev/null 2>&1 || true
        endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
        rotate 4
        weekly
        missingok
        notifempty
        compress
        delaycompress
        sharedscripts
        postrotate
                reload rsyslog > /dev/null 2>&1 || true
        endscript
}
```
该文件首先定义了轮转 `/var/log/syslog` 文件的说明,这些说明包含在后面的花括号中。以下是它们的含义:
* `rotate 7`: 保留最近 7 次轮转的日志。然后开始删除超出的。
* `daily`: 每天轮转日志,与 `rotate 7` 一起使用,这意味着日志将保留过去 7 天。其它选项是每周、每月、每年。还有一个大小参数,如果日志文件的大小增加超过指定的限制(例如,大小 10k、大小 10M、大小 10G 等),则将轮转日志文件。如果未指定任何内容,日志将在运行 `logrotate` 时轮转。你甚至可以在 cron 中运行 `logrotate` 以便在更具体的时间间隔内使用它。
* `missingok`: 如果日志文件缺失也没关系。不要惊慌。
* `notifempty`: 日志文件为空时不轮转。
* `compress`: 开启压缩,使用 `nocompress` 关闭它。
* `delaycompress`: 如果压缩已打开,则将压缩延迟到下一次轮转。这允许至少存在一个轮转但未压缩的文件。如果你希望昨天的日志保持未压缩以便进行故障排除,那么此配置会很有用。如果某些程序在重新启动/重新加载之前可能仍然写入旧文件,这也很有帮助,例如 Apache。
* `postrotate/endscript`: 轮转后运行此部分中的脚本。有助于做清理工作。还有一个 `prerotate/endscript` 用于在轮转开始之前执行操作。
你能弄清楚下一节对上面配置中提到的所有文件做了什么吗?第二节中唯一多出的参数是 `sharedscripts`,它告诉 `logrotate` 在所有日志轮转完成之前不要运行 `postrotate/endscript` 中的部分。它可以防止脚本在每一次轮转时执行,只在最后一次轮转完成时执行。
### 看点新的东西
我使用下面的配置来处理我系统上的 `Nginx` 的访问和错误日志。
```
/var/log/nginx/access.log
/var/log/nginx/error.log  {
        size 1
        missingok
        notifempty
        create 544 www-data adm
        rotate 30
        compress
        delaycompress
        dateext
        dateformat -%Y-%m-%d-%s
        sharedscripts
        extension .log
        postrotate
                service nginx reload
        endscript
}
```
上面的脚本可以使用如下命令运行:
```
logrotate -vs state-file /tmp/logrotate
```
第一次运行该命令会给出以下输出:
```
reading config file /tmp/logrotate
extension is now .log
Handling 1 logs
rotating pattern: /var/log/nginx/access.log
/var/log/nginx/error.log   1 bytes (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
  log needs rotating
considering log /var/log/nginx/error.log
  log does not need rotating
rotating log /var/log/nginx/access.log, log-&gt;rotateCount is 30
Converted ' -%Y-%m-%d-%s' -&gt; '-%Y-%m-%d-%s'
dateext suffix '-2021-08-27-1485508250'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
renaming /var/log/nginx/access.log to /var/log/nginx/access-2021-08-27-1485508250.log
creating new /var/log/nginx/access.log mode = 0544 uid = 33 gid = 4
running postrotate script
* Reloading nginx configuration nginx
```
第二次运行它:
```
reading config file /tmp/logrotate
extension is now .log
Handling 1 logs
rotating pattern: /var/log/nginx/access.log
/var/log/nginx/error.log   1 bytes (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
  log needs rotating
considering log /var/log/nginx/error.log
  log does not need rotating
rotating log /var/log/nginx/access.log, log-&gt;rotateCount is 30
Converted ' -%Y-%m-%d-%s' -&gt; '-%Y-%m-%d-%s'
dateext suffix '-2021-08-27-1485508280'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
compressing log with: /bin/gzip
renaming /var/log/nginx/access.log to /var/log/nginx/access-2021-08-27-1485508280.log
creating new /var/log/nginx/access.log mode = 0544 uid = 33 gid = 4
running postrotate script
* Reloading nginx configuration nginx
```
第三次运行它:
```
reading config file /tmp/logrotate
extension is now .log
Handling 1 logs
rotating pattern: /var/log/nginx/access.log
/var/log/nginx/error.log   1 bytes (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
  log needs rotating
considering log /var/log/nginx/error.log
  log does not need rotating
rotating log /var/log/nginx/access.log, log-&gt;rotateCount is 30
Converted ' -%Y-%m-%d-%s' -&gt; '-%Y-%m-%d-%s'
dateext suffix '-2021-08-27-1485508316'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
compressing log with: /bin/gzip
renaming /var/log/nginx/access.log to /var/log/nginx/access-2021-08-27-1485508316.log
creating new /var/log/nginx/access.log mode = 0544 uid = 33 gid = 4
running postrotate script
* Reloading nginx configuration nginx
```
状态文件的内容如下所示:
```
logrotate state -- version 2
"/var/log/nginx/error.log" 2021-08-27-9:0:0
"/var/log/nginx/access.log" 2021-08-27-9:11:56
```
- [下载 Linux logrotate 备忘单][2]
本文首发于[作者个人博客][3],经授权改编。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/linux-logrotate
作者:[Ayush Sharma][a]
选题:[lujun9972][b]
译者:[perfiffer](https://github.com/perfiffer)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/ayushsharma
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/oliver-paaske-unsplash.jpg?itok=bv0sZSSB (Logs stacked up and to the right in front of a green tree forest)
[2]: https://opensource.com/downloads/logrotate-cheat-sheet
[3]: https://notes.ayushsharma.in/2017/01/fiddling-with-logrotate

View File

@@ -0,0 +1,72 @@
[#]: subject: "3 new features of the latest OpenPGP.js version"
[#]: via: "https://opensource.com/article/21/10/openpgpjs"
[#]: author: "Daniel Huigens https://opensource.com/users/twiss"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13888-1.html"
最新 OpenPGP.js 版本的 3 个新功能
======
> OpenPGP.js 是一个实现了 OpenPGP 标准的密码学库,最常用于电子邮件加密。
![](https://img.linux.net.cn/data/attachment/album/202110/16/115721k1vi1ekzip1kpqkg.jpg)
[OpenPGP.js][2] 是一个实现了 [OpenPGP 标准][3] 的密码学库最常用于电子邮件加密。ProtonMail、Mailvelope 和 FlowCrypt 都使用 OpenPGP.js这还仅仅是其中一些。也就是说 OpenPGP.js 库对数百万用户的信息进行了加密。
OpenPGP 标准首次发布于 20 世纪 90 年代,像几乎任何东西一样,需要维护和更新,以保证安全和可用性。该标准的“加密刷新” [正在进行中][4],它增加了现代的加密算法并废除了过时的算法。为了提高可用性,各种电子邮件应用程序现在允许用户无缝加密他们的通信,用户无需管理他们的密钥或他们的联系人的密钥。
OpenPGP.js 于 2014 年首次发布,开始基于一个名为 GPG4Browsers 的早期原型,该原型基于 Herbert Hanewinkel以及其他贡献者的几个脚本。OpenPGP.js 的第二个版本于 2016 年发布,完全重新设计,使用 Uint8Arrays 而不是字符串(这大大增加了其性能),并在内部使用现代 ES6 模块而不是 CommonJS 模块。第 3 和第 4 版都是在 2018 年发布的分别增加了对椭圆曲线加密法ECC和流的支持。
我和我的团队继续在 OpenPGP.js 上工作,以确保其发展为一个易于使用的强加密库。
### 1、默认的椭圆曲线加密
在 OpenPGP.js 第 4 版中,生成新密钥时默认使用 RSA。虽然 ECC 更快、更安全,但 Curve25519 还没有在 OpenPGP 规范中得到标准化。加密刷新草案包括了 Curve25519并且预计它将“按原样”包含在下一版本的 OpenPGP 规范中,因此 OpenPGP.js 第 5 版现在默认使用 ECC 生成密钥。
### 2、只导入你需要的模块
同样,虽然 OpenPGP.js 内部使用 ES6 模块多年,但第 4 版仍然没有发布一个合适的 ES6 模块。相反,它只发布了一个<ruby>通用模块定义<rt>Univeral Module Definition</rt></ruby>UMD模块可以在浏览器和 Node.js 上运行。在第 5 版中,这种情况有所改变,为浏览器和 Node.js 发布了单独的模块(包括 ES6 和非 ES6使库用户更容易在所有平台上导入 OpenPGP.js ,且(当使用 ES6 模块时)只导入他们需要的部分。这在很大程度上是通过将构建系统切换到 [rollup][5] 来实现的。
### 3、拒绝弱加密技术
还有许多其他的安全改进。例如1024 位 RSA 密钥、ElGamal 和 DSA 密钥被认为是不安全的,并被默认拒绝。此外,第 4 版已经默认使用 AES 加密,第 5 版现在完全默认拒绝使用较弱的算法进行加密,即使公钥声称只支持较弱的算法。相反,它假定所有的 OpenPGP 实现都支持 AES这种情况已经存在很长时间了
### OpenPGP.js 的下一步是什么?
展望未来,有一些安全方面的改进要做。用于识别公钥的密钥指纹仍然使用 SHA-1尽管在加密技术更新中计划对此进行修复。同时建议使用不同的方法来确定用于加密的任何公钥的真实性例如使用提议的 <ruby>[网络密钥目录][6]<rt>Web Key Directory</rt></ruby>WKD标准直接从收件人的域中获取整个密钥这已经由各种 [电子邮件提供商][7] 实现。WKD 支持内置于 OpenPGP.js 第 4 版,但在第 5 版中是一个单独的模块,以保持主库的精简。
同样,当用密码而不是公钥加密信息或文件时(例如:在使用 OpenPGP 进行电子邮件加密时不常见,但在用于加密备份时更常见),密码会使用相对较弱的<ruby>密钥衍生函数<rt>Key Derivation Function</rt></ruby>KDF转换为对称密钥。因此建议应用在将用户的密码传递给 OpenPGP.js 之前,先通过一个强大的 KDF如 [Argon2][8] 或 [scrypt][9]。希望加密刷新草案会包括这些算法中的一种,以便在未来的 OpenPGP.js 版本中实现。
### 如何使用 OpenPGP.js 第 5 版
不过现在OpenPGP.js 第 5 版已经 [发布][10] 到 npm 仓库。如果你喜欢,可以随时试用!欢迎在 GitHub 的 [讨论版][11] 中进行反馈。然而,请注意,虽然 OpenPGP.js 是一个通用的加密库,但它的主要使用情况是在需要与 OpenPGP 规范兼容的情况下(例如,在发送或接收 PGP 加密的电子邮件时)。对于其他的使用情况,不同的库可能是一个更合适或性能更好的选择。当然,总的来说,在尝试使用任何加密技术时都要小心。
感谢阅读,这里是保护电子邮件的未来!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/openpgpjs
作者:[Daniel Huigens][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/twiss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/newsletter_email_mail_web_browser.jpg?itok=Lo91H9UH (email or newsletters via inbox and browser)
[2]: https://github.com/openpgpjs/openpgpjs
[3]: https://tools.ietf.org/html/rfc4880
[4]: https://datatracker.ietf.org/doc/charter-ietf-openpgp/
[5]: https://rollupjs.org/
[6]: https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service
[7]: https://wiki.gnupg.org/WKD#Mail_Service_Providers_offering_WKD
[8]: https://en.wikipedia.org/wiki/Argon2
[9]: https://en.wikipedia.org/wiki/Scrypt
[10]: https://www.npmjs.com/package/openpgp
[11]: https://github.com/openpgpjs/openpgpjs/discussions

View File

@@ -0,0 +1,161 @@
[#]: subject: "How to Install Vivaldi Browser on Ubuntu and Other Linux Distributions"
[#]: via: "https://itsfoss.com/install-vivaldi-ubuntu-linux/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "imgradeone"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13877-1.html"
[初级] 如何在 Ubuntu 中安装 Vivaldi 浏览器
======
![](https://img.linux.net.cn/data/attachment/album/202110/13/142545reotvtqgqpfvmmvp.jpg)
> 你将在本篇新手教程中学习如何在 Ubuntu、Debian 及其他 Linux 发行版中安装 Vivaldi 网页浏览器,同时本教程也将介绍如何更新和卸载该软件。
[Vivaldi][1] 是一款日益流行的网页浏览器。它基于 Chromium 内核,因此它拥有和 Chrome 类似的功能,但它也新增了一些其他特色功能,让这款浏览器与众不同、更为直观。
它内置了标签组、广告拦截、鼠标手势、笔记管理,甚至还有命令连锁。你甚至可以借助切分视图来一次性浏览多个页面。当然,相比于 ChromeVivaldi 更加尊重你的隐私。
![标签平铺,一次性分割浏览多个页面][2]
[Manjaro Linux 近期使用 Vivaldi 取代 Firefox 作为其部分变体的默认浏览器][3],你可以从这件事来了解 Vivaldi 浏览器的受欢迎程度。
如果你想尝试一下这款浏览器的话,接下来让我告诉你,如何在 Linux 上安装 Vivaldi。你将了解到
* 安装 Vivaldi 的 GUI 和命令行方式
* 将 Vivaldi 更新到最新版本的技巧
* 在 Ubuntu 中卸载 Vivaldi 的方式
> **非自由软件警告!**
>
> Vivaldi 并非完全的开源软件。它的 UI 界面是闭源的。之所以在这里介绍这款浏览器,是因为 Vivaldi 团队正努力让该软件在 Linux 平台上可用。
### 方式 1在 Ubuntu 中安装 Vivaldi [GUI 方式]
好消息是Vivaldi 提供了预先构建好的安装包,包括 Ubuntu/Debian 的 DEB 文件,以及 Fedora、Red Hat、SUSE 的 RPM 文件。
它支持 32 位和 64 位平台,也支持 [像树莓派之类的 ARM 设备][4]。
![Vivaldi 为各类 Linux 发行版提供了安装包][5]
安装过程非常简单。你只需要前往 Vivaldi 的官网下载正确的安装包文件,双击打开,然后安装,大功告成。
我将详细介绍在 Ubuntu/Debian 下的安装过程。对于其他类型的发行版,你可以使用类似的步骤。
#### 第 1 步:下载 Vivaldi
前往 Vivaldi 的下载页面,下载支持 Ubuntu 的 DEB 格式安装包。
- [下载 Vivaldi][6]
![下载支持 Ubuntu/Debian 的 DEB 安装包][7]
#### 第 2 步:安装刚刚下载的 DEB 文件
前往你刚刚下载 DEB 文件的下载文件夹。[安装 DEB 文件][8] 非常简单,只需要双击打开,或者右键后使用软件中心打开即可。
![右键点击下载的 DEB 文件并用软件中心打开以安装][9]
这将打开软件中心,在这里可以看到安装 Vivaldi 的选项。点击安装按钮即可。
![点击安装按钮][10]
你将需要输入系统账户的密码输入密码授权后Vivaldi 很快就能完成安装,随后安装按钮也变成了移除按钮。这表明 Vivaldi 已经安装完成了。
#### 第 3 步:使用 Vivaldi
按下 `Super``Windows`)键打开系统菜单,搜索 Vivaldi然后单击 Vivaldi 的图标。
![在系统菜单中搜索 Vivaldi][11]
首次启动时,你将看到如下界面。
![运行于 Ubuntu 的 Vivaldi][12]
既然你已经知道了这个方法,那我接下来将展示在 Ubuntu/Debian 使用终端安装 Vivaldi 的方法。
### 方式 2借助终端在 Ubuntu/Debian 上安装 Vivaldi
打开终端,确认你已经安装了用于 [在命令行下下载文件][13] 的 `wget`
```
sudo apt install wget
```
接下来,获取 Vivaldi 仓库的公钥并添加到系统,以让系统信任该来源的软件包。如果你感兴趣的话,你可以阅读 [关于在 Ubuntu 添加第三方软件仓库的文章][14]。
```
wget -qO- https://repo.vivaldi.com/archive/linux_signing_key.pub | sudo apt-key add -
```
添加完该密钥后,再添加 Vivaldi 的仓库:
```
sudo add-apt-repository 'deb https://repo.vivaldi.com/archive/deb/ stable main'
```
现在距离完成也只有一步之遥了。更新软件仓库缓存并安装 Vivaldi。
```
sudo apt update && sudo apt install vivaldi-stable
```
大功告成。现在,前往系统菜单搜索并启动 Vivaldi 吧。
### 在 Ubuntu 中更新 Vivaldi
GUI 和命令行这两种方式都会在系统里添加 Vivaldi 的仓库。这意味着,只要 Vivaldi 发布了新版本,你就可以在系统更新中一并获取 Vivaldi 的更新。
![已添加到系统中的 Vivaldi 仓库][15]
一般情况下,你更新 Ubuntu 系统时,如果 Vivaldi 发布了新版本,那么 Vivaldi 也同时会被更新。
![Vivaldi 浏览器会跟随系统更新][16]
### 在 Ubuntu 中卸载 Vivaldi
如果你不喜欢 Vivaldi 或者不再使用,你可以直接卸载。现在,如果你想 [在 Ubuntu 中卸载软件][17],你可能会想到软件中心,但软件中心不会查找到外部和第三方的软件包。
目前你必须使用终端卸载 Vivaldi即便你是使用 GUI 方式安装的。其实这也很简单,打开终端,输入以下命令:
```
sudo apt remove vivaldi-stable
```
`sudo` 会 [在 Ubuntu 中给予你 root 权限][18]。你需要输入当前账户的密码。输入密码时,你可能不会在屏幕上看见输入密码的痕迹。这是正常现象,直接输入密码即可,随后 Vivaldi 将被卸载。
希望这篇关于如何在 Linux 安装 Vivaldi 的教程对你有用。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-vivaldi-ubuntu-linux/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[imgradeone](https://github.com/imgradeone)
校对:[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://vivaldi.com/
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/tab-tiling.webp?resize=800%2C448&ssl=1
[3]: https://news.itsfoss.com/vivaldi-replaces-firefox-manjaro/
[4]: https://itsfoss.com/raspberry-pi-alternatives/
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/downloading-vivaldi-linux.webp?resize=800%2C541&ssl=1
[6]: https://vivaldi.com/download/
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/vivaldi-download-linux.webp?resize=800%2C438&ssl=1
[8]: https://itsfoss.com/install-deb-files-ubuntu/
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/installing-vivaldi-ubuntu.webp?resize=800%2C466&ssl=1
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/install-vivaldi-ubuntu-software.png?resize=800%2C407&ssl=1
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/running-vivaldi-in-ubuntu.png?resize=703%2C229&ssl=1
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/Vivaldi-in-Ubuntu.webp?resize=800%2C450&ssl=1
[13]: https://itsfoss.com/download-files-from-linux-terminal/
[14]: https://itsfoss.com/adding-external-repositories-ubuntu/
[15]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/Vivaldi-repo-ubuntu.png?resize=800%2C403&ssl=1
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/06/chrome-edge-update-ubuntu.png?resize=716%2C421&ssl=1
[17]: https://itsfoss.com/uninstall-programs-ubuntu/
[18]: https://itsfoss.com/root-user-ubuntu/

View File

@@ -0,0 +1,193 @@
[#]: subject: "Best Linux Distributions Based on KDE"
[#]: via: "https://itsfoss.com/best-kde-distributions/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13872-1.html"
基于 KDE 的最佳 Linux 发行版
======
![](https://img.linux.net.cn/data/attachment/album/202110/11/115436wngdi7vndoodjnfd.jpg)
KDE 是目前最具定制性和最快速的桌面环境之一。虽然你可以随时安装 KDE但最好选择一个 KDE 开箱即用的 Linux 发行版。
在这里,让我列出一些最好的基于 KDE 的 Linux 发行版。
无论你选择什么作为你的首选发行版,你都可以参考我们的 [KDE 定制指南][1] 来调整你的体验。
注意:该列表没有特定的排名顺序。
### 1、KDE Neon
![][2]
主要亮点:
* 官方 KDE 发行版
* 最新的 KDE Plasma 稳定版
* 专注于最新的 KDE 软件
* 不是桌面发行版的完美替代品
如果你想获得 KDE Plasma 的最新体验,[KDE Neon][4] 是最佳选择之一。
即使它是建立在稳定版的 Ubuntu LTS 基础之上,你也总是能在最新的 KDE 版本发布后立即得到交付。
与其他发行版不同,它不注重完整的桌面用户体验,而是重点关注在 KDE 软件包上。所以,它可能不是每个人的完美桌面替代品。然而,如果你希望使用最新的 KDE 软件KDE Neon 是一个不错的选择。
其“用户版”应该是你需要的,但如果你愿意尝试预先发布的功能,你也可以选择尝试“测试版”或“不稳定版”。
如果你想知道它与 Kubuntu 有什么不同,你应该查看 [KDE Neon vs Kubuntu][3] 的比较来探索它。
### 2、Kubuntu
![][5]
主要亮点:
* 基于 Ubuntu 的以桌面为重点的 Linux 发行版
* 提供 LTS 和非 LTS 版本
* 良好的硬件兼容性
如果 KDE 软件套件不是你关注的重点,那么 Kubuntu 应该是你可以作为 Linux 桌面使用的一个优秀发行版。
Kubuntu 是 Ubuntu 的一个官方版本,它为其 LTS 版本提供了三年的更新支持。与 KDE Neon 不同的是,你可以得到对各种应用程序更好的支持,而不仅仅是局限于 KDE 软件。
你可以选择 LTS 版或非 LTS 版来获得最新的 Ubuntu 功能。
与其他一些基于 KDE 的发行版相比Kubuntu 具有更好的硬件兼容性。考虑到它可以为各种笔记本电脑提供动力,如 Kubuntu Focus、Slimbook 等,其硬件兼容性是你可以信赖的。
### 3、Manjaro KDE
![][6]
主要亮点:
* 基于 Arch 的 Linux 发行版
* 滚动式发布更新
* 对于新的 Linux 用户来说学习难度不大
Manjaro 是一个基于 Arch Linux 的发行版,它使得使用 Arch 作为桌面 Linux 平台变得容易。
它按照滚动发布的时间表进行发布,这应该有助于你快速获得最新的软件包,而不必担心软件更新时间。
如果你是一个新的 Linux 用户,你可以考虑一直使用 Flatpak 或 Snaps 来安装各种应用程序。虽然 Manjaro 让你很容易使用 Arch但它对新用户来说多多少少还是有一点学习曲线。所以你可能需要查看 [Arch 维基][7] 来了解更多信息。
### 4、Fedora KDE Spin
主要亮点:
* 一个独特的基于 KDE 的 Linux 发行版(如果你不喜欢主流的 Ubuntu/Arch 发行版)
* 为工作站和服务器量身定做
* 对于新的 Linux 用户来说可能需要适应
* 硬件兼容性可能是个问题
Fedora 是一个独立的发行版(不基于 Ubuntu/Arch作为 Red Hat Enterprise Linux 的上游。
而 Fedora Spin 版为用户提供了各种备用的桌面。如果你想要 KDE你需要下载 Fedora 的 KDE Spin。
像 KDE Neon 一样Fedora 并不专注于提供一个最佳的桌面体验,而是旨在实验对工作站或服务器有用的最新技术。
因此,如果你有信心解决 Linux 发行版上较新技术实现所带来的任何问题/挑战,[Fedora KDE Spin][8] 是一个不错的选择。
### 5、openSUSE
![][9]
主要亮点:
* 适用于需要使用多种工具的系统管理员和开发人员
* 有两个不同的版本,包括稳定版和滚动版
[openSUSE][10] 是另一个独立的 Linux 发行版,默认采用 KDE 桌面。虽然它把自己定位为桌面用户的选择之一,但我在过去曾遇到过硬件兼容性问题。
然而,对于想在桌面上使用 YaST、Open Build Service、Kiwi 等工具的系统管理员或开发者来说,它是一个很好的选择,开箱即用。
它提供了一个稳定版和一个滚动发布版。根据你的要求选择最适合你的。
### 6、Garuda Linux
![][11]
主要亮点:
* 滚动发布的发行版
* BTRFS 作为默认文件系统
* 预装了基本的 GUI 工具,使 Arch Linux 的使用变得简单
[Garuda Linux][12] 是一个基于 Arch 的现代发行版,专注于开箱即用的定制体验。
KDE 版本(或 Dr460nized 版本)提供了漂亮的体验,同时可使用类似 macOS 的工作流程进行调整。
当然,如果你是一个有经验的 Linux 用户,你可以定制你现有的发行版来模仿同样的体验。
锦上添花的是Garuda Linux 还提供了其 KDE 版本的不同变体,一个预装了游戏工具,一个用于渗透测试,另一个作为基本的 Linux 桌面系统。
### 7、Nitrux OS
![][13]
主要亮点:
* 基于 Debian 的发行版,不同的风格
* 独特的桌面体验
一个基于 Debian 的 Linux 发行版,具有开箱即用的 KDE。与 Kubuntu 不同Nitrux 最终可能提供的是一个更快的 KDE Plasma 更新和较新的 Linux 内核升级。
[Nitrux OS][14] 在以其 NX 桌面为特色的同时,提供了一个美丽而独特的体验。
如果你想尝试一些不同的 KDE 搭载Nitrux OS 将是一个不错的选择。
### 8、MX Linux KDE
![][15]
主要亮点:
* 基于 Debian 的发行版
* 轻量级
* 预装了有用的 MX 工具
不在意外观,但想要一个简单的、可定制的、基于 Debian 的 KDE 桌面?[MX Linux KDE 版][16] 应该是一个很好的选择,因为它以迅捷的性能和预装的基本工具而闻名。
如果你想调整默认的用户体验,你还可以得到几个 KDE 主题。
### 总结
在这个列表之外,其他几个 Linux 发行版也将 KDE 桌面作为他们的首选。
总体来说Nitrux OS 应该是一个独特的选择,如果你想远离基于 Ubuntu 的发行版,还有像 Garuda Linux 和 Manjaro 这样基于 Arch 的可靠发行版可以尝试。
你最喜欢的基于 KDE 的 Linux 发行版是什么?你是专注于开箱即用的定制,还是喜欢自己定制 KDE 体验?
--------------------------------------------------------------------------------
via: https://itsfoss.com/best-kde-distributions/
作者:[Ankush Das][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://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/kde-customization
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/08/kde-neon-information-20-04.jpg?resize=800%2C397&ssl=1
[3]: https://itsfoss.com/kde-neon-vs-kubuntu/
[4]: https://neon.kde.org/index
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/kubuntu-kde.jpg?resize=800%2C450&ssl=1
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/manjaro-20-desktop.jpeg?resize=800%2C440&ssl=1
[7]: https://wiki.archlinux.org
[8]: https://spins.fedoraproject.org/en/kde/
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/opensuse-kde.png?resize=800%2C423&ssl=1
[10]: https://www.opensuse.org
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/Garuda-Linux-review.png?resize=800%2C450&ssl=1
[12]: https://garudalinux.org
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/nitrux-os-kde.png?resize=800%2C450&ssl=1
[14]: https://nxos.org
[15]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/08/mx-linux-19-2-kde.jpg?resize=800%2C452&ssl=1
[16]: https://mxlinux.org

View File

@@ -0,0 +1,113 @@
[#]: subject: "What is a hostname?"
[#]: via: "https://opensource.com/article/21/10/what-hostname"
[#]: author: "Alan Formy-Duval https://opensource.com/users/alanfdoss"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13897-1.html"
浅谈主机名
======
> 主机名是人类用来指代特定计算机的标签。
![](https://img.linux.net.cn/data/attachment/album/202110/19/134329lwni9tlq9h3u4f4o.jpg)
计算机有网络地址,但人类通常很难记住它们。主机名是帮助人类参考特定计算机的标签。例如,你可能不会导航到 `192.168.1.4`,而是导航到 `linuxlaptop``linuxlaptop.local`
### 地址和名称
所有联网的计算机(也被称为<ruby>主机<rt>host</rt></ruby>)都需要一个地址:一个与之相关的唯一数字,以使数据报文能够在它们之间进行正确的数据通信。这就是所谓的<ruby>互联网协议<rt>Internet Protocol</rt></ruby>IP地址。数字 `54.204.39.132` 是一个<ruby>互联网协议第四版<rt>Internet Protocol version 4</rt></ruby>IPv4地址。较新的 IPv6 地址要长得多,像这样:`2001:0db6:3c4d:0017:0000:0000:2a2f:1a2b`。 哇!这将是很难记住的!
```
$ ip addr show
```
计算机也可以被赋予标签。被称为<ruby>主机名<rt>hostname</rt></ruby>,这些是友好的名称,便于参考。我可以把我的计算机的主机名设置为 `copperhead`。只要这个名字在网络上是唯一的,所有其他用户和计算机都可以把 `copperhead` 作为地址,而不是 IP 地址。
```
$ hostname -s
```
你可以更新你的计算机的主机名。
阅读 Seth Kenlon 的文章 [如何在 Linux 上更改主机名][2],了解如何在 Linux 上这样做。
#### 完全限定域名
从技术上讲,主机名包括一个域名。如果我的域名是 `mycompany.com`,那么我的计算机的主机名是 `copperhead.mycompany.com`,以句点分隔。这就形成了一个<ruby>完全限定域名<rt>fully qualified domain name</rt></ruby>FQDN。这很重要因为 IP 地址可以解析为 FQDN。
```
host.domain.topleveldomain
```
例如:`www.example.com` 是一个完全限定域名。
你的域名一般已经确定了,所以你只负责提供主机部分。本文的重点是主机。
#### 名称解析
将 IP 地址转换为相应的主机名的过程被称为名称解析。这个过程首先发生在本地主机表中。Linux 使用文件 `/etc/hosts` 来存储这个表。
```
cat /etc/hosts
```
还有一个分层的、去中心化的基于网络的系统提供解析,称为<ruby>域名系统<rt>Domain Name System</rt></ruby>DNS。这时 FQDN 变得非常重要。
```
$ dig www.opensource.com
```
### 名称的乐趣
为我们的计算机起名字可能很有趣。如果你有很多,你可以使用一个主题。我曾经为一家公司工作,该公司将所有的服务器都以蛇命名。
后来我工作的一家公司,我是一个数据中心经理,使用啤酒品牌。当我们收到一个新的服务器时,这很令人兴奋,因为我会给开发团队发邮件征求建议。我们大约有 100 台服务器。这些提供了一个有趣的清单,反映了公司的多样性。我们有从库尔斯和百威到阿姆斯特尔和浅粉象的一切。我们有虎牌啤酒、胜狮啤酒和札幌啤酒等等!
我们认为这很酷!然后,想象一下,当你试图记住卢云堡是拥有最多内存的虚拟化服务器,佩罗尼是 SQL 数据库服务器,喜力是新的域控制器时,会发生什么,特别是对于一个快速发展的公司的新员工。
### 惯例
当然,主机名是所有者的选择,所以请尽情发挥。然而,根据环境的不同,使用容易记忆的名字或基于命名惯例的名字可能更有意义,因为这些名字有利于描述主机。
#### 有用的名字
如果你想放弃有趣的东西,并对你的系统进行有益的命名,也许可以考虑它们的功能。数据库服务器可以被命名为 `database1``database2``database3` 等等。Web 服务器可以命名为 `webserver1``webserver2` 等等。
#### 位置名称
我在许多客户那里使用了一种技术用一组字符的位置来命名服务器主机这些字符描述了该系统的一个方面有助于识别。例如如果我正在为内政部DOI开发一个业务流程管理BPM系统我就会在命名规则中加入他们的缩写词。
此外,就像许多大型企业、金融机构和政府一样,他们可能有不同的数据中心,位于不同的地理位置,以达到性能或灾难恢复的目的。因此,比如说,位于北美大陆东海岸的数据中心被称为 EDEast Data center而位于西海岸的数据中心则是 WDWest Data center
所有这些信息将汇集到一个名称中,如 `doibpm1ed``doibpm1wd`。因此,虽然这些名字看起来不长,但在这个项目上工作的人可以很容易地识别它们的目的和位置,而且这个名字甚至可以对潜在的恶意者混淆它们的用途。换句话说,业主可以选择只对内部人员有意义的命名方式
### 互联网标准
有几个标准管理着主机名。你可以在<ruby>互联网工程任务组<rt>Internet Engineering Task Force</rt></ruby>IETF维护的<ruby>意见征求<rt>Requests for Comment</rt></ruby>RFC中找到这些标准。由此请遵守以下规定
* 主机名的长度应该在 1 到 63 个 ASCII 字符之间
* 一个 FQDN 的最大长度为 253 个 ASCII 字符
* 不区分大小写
* 允许的字符:`a``z``0``9``-`(连字符),和 `_`(下划线)。
我希望这篇文章能帮助你澄清主机名。玩得开心,发挥创意。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/what-hostname
作者:[Alan Formy-Duval][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/alanfdoss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_screen_windows_files.png?itok=kLTeQUbY (Computer screen with files or windows open)
[2]: https://opensource.com/article/21/10/how-change-hostname-linux

View File

@@ -0,0 +1,92 @@
[#]: subject: "Seahorse: Manage Your Passwords & Encryption Keys in Linux"
[#]: via: "https://itsfoss.com/seahorse/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13884-1.html"
Seahorse在 Linux 中管理你的密码和加密密钥
======
![](https://img.linux.net.cn/data/attachment/album/202110/15/120409ltfmw33c5xpw5bcx.jpg)
> Seahorse 是一个简洁的开源密码和加密密钥管理器,让我们来探讨一下它的功能和如何安装它。
我们经常倾向于忽视许多默认/预装的应用,尤其是在内置了大量工具和实用程序时。
你可以在各种 Linux 发行版上使用的这样一个有用的工具是 **GNOME 的 Seahorse**
### SeahorseGNOME 的密码及加密密钥管理器
![][1]
主要来说Seahorse 是一个预装在 GNOME 桌面的应用,并为其量身定做。
然而,你可以在你选择的任何 Linux 发行版上使用它。它是一个简单而有效的工具,可以在本地管理你的密码和加密密钥/钥匙环。
如果你是第一次使用,你可能想读一下 [Linux 中钥匙环的概念][2]。
如果你不喜欢基于云的密码管理器Seahorse 可以很好地解决你的要求。尽管它看起来很简单,但有几个基本功能你可能会觉得很有用。
当然,如果你的不太涉及管理加密密钥(或本地存储),你也应该探索一些 [可用于 Linux 的最佳密码管理器][3] 。
### Seahorse 的特点
虽然你可以很容易地把它作为一个本地(离线)密码管理器,但在处理加密密钥时,你也可以用 Seahorse 做一些事情来加强你的安全管理。
![][4]
一些关键的亮点是:
* 能够存储 SSH 密钥(用于访问远程计算机/服务器)
* 存储用于保护电子邮件和文件的 GPG 密钥
* 支持为应用和网络添加密码钥匙环
* 安全地存储证书的私钥
* 存储一个密码/密语
* 能够导入文件并快速存储它们
* 查找远程密钥
* 同步和发布密钥
* 能够查找/复制 VPN 密码
![][5]
### 在 Linux 中安装 Seahorse
如果你使用的是基于 GNOME 的发行版,你应该已经安装了它。你可以搜索 “Seahorse” 或者 “Passwords” 来找到它。
在其他情况下,你可以在软件中心搜索到它。根据我的快速测试,它在 KDE、LXQt 和不同的桌面环境下应该可以正常工作。
![][6]
此外,你可以找到它的 [Flatpak 包][7]。所以,无论你使用的是哪种 Linux 发行版,都可以安装 Seahorse。
如果你使用的是 Arch Linux你也应该在 [AUR][8] 中找到它。
- [Seahorse][9]
你对使用 Seahorse 来取代其他密码管理器有何看法?你是否已经用它来管理加密密钥?请在下面的评论中告诉我你的想法。
--------------------------------------------------------------------------------
via: https://itsfoss.com/seahorse/
作者:[Ankush Das][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/ankush/
[b]: https://github.com/lujun9972
[1]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/seahorse-password-keys.png?resize=800%2C613&ssl=1
[2]: https://itsfoss.com/ubuntu-keyring/
[3]: https://itsfoss.com/password-managers-linux/
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/seahorse-login.png?resize=800%2C583&ssl=1
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/seahorse-keys.png?resize=800%2C579&ssl=1
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/seahorse-software.png?resize=800%2C508&ssl=1
[7]: https://www.flathub.org/apps/details/org.gnome.seahorse.Application
[8]: https://itsfoss.com/aur-arch-linux/
[9]: https://wiki.gnome.org/Apps/Seahorse/

View File

@@ -0,0 +1,83 @@
[#]: subject: "5 markdown editors I recommend trying"
[#]: via: "https://opensource.com/article/21/10/markdown-editors"
[#]: author: "Don Watkins https://opensource.com/users/don-watkins"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13904-1.html"
我推荐尝试的 5 个 Markdown 编辑器
======
> 每个人都有自己喜欢的 Markdown 编辑器。这里有几个我已经试过的。
![](https://img.linux.net.cn/data/attachment/album/202110/21/095837n8q1s3hqc1og1fsq.jpg)
你可以用 Markdown 做任何事情:给网站排版、编写书籍和撰写技术文档只是它的一些用途。我喜欢它创建富文本文档可以如此简单。每个人都有自己喜欢的 Markdown 编辑器。在我的 Markdown 之旅中,我使用了好几个。下面是我考虑过的五个 Markdown 编辑器。
### Abricotine
[Abricotine][2] 是一个在 [GPLv][3] 下发布的开源编辑器。你可以手动输入格式,或者使用菜单插入 [GitHub 风格的 Markdown][4]。Abricotine 允许你在输入时预览文本元素,如标题、图片、数学、嵌入式视频和待办事项。该编辑器只能将文件导出为 HTML。你可以在 Linux、macOS 和 Windows 上使用 Abricotine。
![Abricontine][5]
### MarkText
[MarkText][7] 是一个简单的 Markdown 编辑器。它有很多功能,而且在处理 Markdown 格式的文件方面做得很好。MarkText 也支持 GitHub 风格的 Markdown它允许你添加表格和带有语法高亮的代码块。它支持实时预览并且有一个简单的界面。MarkText 是在 [MIT][8] 下授权的。它支持 HTML 和 PDF 格式的输出。MarkText 可以在 Linux、macOS 和 Windows 上使用。
![MarkText][9]
### Ghostwriter
[Ghostwriter][10] 是一个用于 Linux 和 Windows 的 Markdown 编辑器。根据其网站用户的说法。“享受无干扰的写作体验,包括全屏模式和简洁的界面。有了 Markdown你可以现在写以后再格式化”。它有内置的默认的浅色和深色主题或者你可以自己编写。你可以将文件实时按 HTML 预览你可以直接复制和粘贴到博客中或导出为其他格式。Ghostwriter 是在 [GPLv3][11] 下发布的。
![Ghostwriter][12]
### Atom
[Atom][13] 被称为 21 世纪的可自定义文本编辑器。它也可以作为一个 Markdown 编辑器使用。它可以在 Linux、Windows 和 macOS上运行并以 [MIT][14] 许可证发布。它支持 GitHub 风格的 Markdown并且按下 `Ctrl+Shift+M` 可以打开一个预览面板,这样你就可以轻松地看到 HTML 预览。你可以通过创建一个文件并以 `.md` 文件扩展名保存来轻松入门。这告诉 Atom 它是一个 Markdown 文件。Atom 会自动应用正确的包和语法高亮。
![Atom][15]
### VSCodium
[VSCodium][16] 是微软的 VSCode 编辑器的自由开源版本,没有内置在微软产品中的遥测技术。它以 [MIT][17] 许可证发布,并提供了 VSCode 的所有功能而没有专有特性。除了其他功能外VSCodium 还可以作为一个 Markdown 编辑器。创建一个新文件,点击 “选择一个语言”,选择 “Markdown”然后开始写你的代码。通过按 `Ctrl-Shift+V` 轻松预览文本,然后再切换回编辑器。你也可以通过添加一个扩展来轻松地扩展 Markdown 编辑器。我最喜欢的插件是 [Markdown editor][18],它是 [MIT][19] 许可证。
![VSCodium][20]
你最喜欢的 Markdown 编辑器是什么? 让我们在评论中知道。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/markdown-editors
作者:[Don Watkins][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/don-watkins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-docdish-typewriter-pink.png?itok=OXJBtyYf (A pink typewriter)
[2]: https://abricotine.brrd.fr/
[3]: https://github.com/brrd/abricotine/blob/develop/LICENSE
[4]: https://guides.github.com/features/mastering-markdown/
[5]: https://opensource.com/sites/default/files/uploads/1_abricontine.png (Abricontine)
[6]: https://creativecommons.org/licenses/by-sa/4.0/
[7]: https://marktext.app/
[8]: https://github.com/marktext/marktext/blob/develop/LICENSE
[9]: https://opensource.com/sites/default/files/uploads/2_marktext.png (MarkText)
[10]: https://wereturtle.github.io/ghostwriter/
[11]: https://github.com/wereturtle/ghostwriter/blob/master/COPYING
[12]: https://opensource.com/sites/default/files/uploads/3_ghostwriter.png (Ghostwriter)
[13]: https://atom.io/
[14]: https://github.com/atom/atom/blob/master/LICENSE.md
[15]: https://opensource.com/sites/default/files/uploads/4_atom.png (Atom)
[16]: https://vscodium.com/
[17]: https://github.com/VSCodium/vscodium/blob/master/LICENSE
[18]: https://github.com/zaaack/vscode-markdown-editor
[19]: https://github.com/zaaack/vscode-markdown-editor/blob/master/LICENSE
[20]: https://opensource.com/sites/default/files/uploads/5_vscodium.png (VSCodium)

View File

@@ -0,0 +1,405 @@
[#]: subject: "5 common bugs in C programming and how to fix them"
[#]: via: "https://opensource.com/article/21/10/programming-bugs"
[#]: author: "Jim Hall https://opensource.com/users/jim-hall"
[#]: collector: "lujun9972"
[#]: translator: "unigeorge"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13894-1.html"
C 语言编程中的 5 个常见错误及对应解决方案
======
> 增强 C 语言程序的弹性和可靠性的五种方法。
![](https://img.linux.net.cn/data/attachment/album/202110/18/174123p4cz99skp9zz4nf4.jpg)
即使是最好的程序员也无法完全避免错误。这些错误可能会引入安全漏洞、导致程序崩溃或产生意外操作,具体影响要取决于程序的运行逻辑。
C 语言有时名声不太好,因为它不像近期的编程语言(比如 Rust那样具有内存安全性。但是通过额外的代码一些最常见和严重的 C 语言错误是可以避免的。下文讲解了可能影响应用程序的五个错误以及避免它们的方法:
### 1、未初始化的变量
程序启动时,系统会为其分配一块内存以供存储数据。这意味着程序启动时,变量将获得内存中的一个随机值。
有些编程环境会在程序启动时特意将内存“清零”,因此每个变量都得以有初始的零值。程序中的变量都以零值作为初始值,听上去是很不错的。但是在 C 编程规范中,系统并不会初始化变量。
看一下这个使用了若干变量和两个数组的示例程序:
```
#include <stdio.h>
#include <stdlib.h>
int
main()
{
int i, j, k;
int numbers[5];
int *array;
puts("These variables are not initialized:");
printf(" i = %d\n", i);
printf(" j = %d\n", j);
printf(" k = %d\n", k);
puts("This array is not initialized:");
for (i = 0; i < 5; i++) {
printf(" numbers[%d] = %d\n", i, numbers[i]);
}
puts("malloc an array ...");
array = malloc(sizeof(int) * 5);
if (array) {
puts("This malloc'ed array is not initialized:");
for (i = 0; i < 5; i++) {
printf(" array[%d] = %d\n", i, array[i]);
}
free(array);
}
/* done */
puts("Ok");
return 0;
}
```
这个程序不会初始化变量,所以变量以系统内存中的随机值作为初始值。在我的 Linux 系统上编译和运行这个程序,会看到一些变量恰巧有“零”值,但其他变量并没有:
```
These variables are not initialized:
i = 0
j = 0
k = 32766
This array is not initialized:
numbers[0] = 0
numbers[1] = 0
numbers[2] = 4199024
numbers[3] = 0
numbers[4] = 0
malloc an array ...
This malloc'ed array is not initialized:
array[0] = 0
array[1] = 0
array[2] = 0
array[3] = 0
array[4] = 0
Ok
```
很幸运,`i``j` 变量是从零值开始的,但 `k` 的起始值为 32766。在 `numbers` 数组中,大多数元素也恰好从零值开始,只有第三个元素的初始值为 4199024。
在不同的系统上编译相同的程序,可以进一步显示未初始化变量的危险性。不要误以为“全世界都在运行 Linux”你的程序很可能某天在其他平台上运行。例如下面是在 FreeDOS 上运行相同程序的结果:
```
These variables are not initialized:
i = 0
j = 1074
k = 3120
This array is not initialized:
numbers[0] = 3106
numbers[1] = 1224
numbers[2] = 784
numbers[3] = 2926
numbers[4] = 1224
malloc an array ...
This malloc'ed array is not initialized:
array[0] = 3136
array[1] = 3136
array[2] = 14499
array[3] = -5886
array[4] = 219
Ok
```
永远都要记得初始化程序的变量。如果你想让变量将以零值作为初始值,请额外添加代码将零分配给该变量。预先编好这些额外的代码,这会有助于减少日后让人头疼的调试过程。
### 2、数组越界
C 语言中,数组索引从零开始。这意味着对于长度为 10 的数组,索引是从 0 到 9长度为 1000 的数组,索引则是从 0 到 999。
程序员有时会忘记这一点,他们从索引 1 开始引用数组,产生了<ruby>“大小差一”<rt>off by one</rt></ruby>错误。在长度为 5 的数组中程序员在索引“5”处使用的值实际上并不是数组的第 5 个元素。相反,它是内存中的一些其他值,根本与此数组无关。
这是一个数组越界的示例程序。该程序使用了一个只含有 5 个元素的数组,但却引用了该范围之外的数组元素:
```
#include <stdio.h>
#include <stdlib.h>
int
main()
{
int i;
int numbers[5];
int *array;
/* test 1 */
puts("This array has five elements (0 to 4)");
/* initalize the array */
for (i = 0; i < 5; i++) {
numbers[i] = i;
}
/* oops, this goes beyond the array bounds: */
for (i = 0; i < 10; i++) {
printf(" numbers[%d] = %d\n", i, numbers[i]);
}
/* test 2 */
puts("malloc an array ...");
array = malloc(sizeof(int) * 5);
if (array) {
puts("This malloc'ed array also has five elements (0 to 4)");
/* initalize the array */
for (i = 0; i < 5; i++) {
array[i] = i;
}
/* oops, this goes beyond the array bounds: */
for (i = 0; i < 10; i++) {
printf(" array[%d] = %d\n", i, array[i]);
}
free(array);
}
/* done */
puts("Ok");
return 0;
}
```
可以看到,程序初始化了数组的所有值(从索引 0 到 4然后从索引 0 开始读取,结尾是索引 9 而不是索引 4。前五个值是正确的再后面的值会让你不知所以
```
This array has five elements (0 to 4)
  numbers[0] = 0
  numbers[1] = 1
  numbers[2] = 2
  numbers[3] = 3
  numbers[4] = 4
  numbers[5] = 0
  numbers[6] = 4198512
  numbers[7] = 0
  numbers[8] = 1326609712
  numbers[9] = 32764
malloc an array ...
This malloc'ed array also has five elements (0 to 4)
  array[0] = 0
  array[1] = 1
  array[2] = 2
  array[3] = 3
  array[4] = 4
  array[5] = 0
  array[6] = 133441
  array[7] = 0
  array[8] = 0
  array[9] = 0
Ok
```
引用数组时,始终要记得追踪数组大小。将数组大小存储在变量中;不要对数组大小进行<ruby>硬编码<rt>hard-code</rt></ruby>。否则,如果后期该标识符指向另一个不同大小的数组,却忘记更改硬编码的数组长度时,程序就可能会发生数组越界。
### 3、字符串溢出
字符串只是特定类型的数组。在 C 语言中,字符串是一个由 `char` 类型值组成的数组,其中用一个零字符表示字符串的结尾。
因此,与数组一样,要注意避免超出字符串的范围。有时也称之为 _字符串溢出_
使用 `gets` 函数读取数据是一种很容易发生字符串溢出的行为方式。`gets` 函数非常危险,因为它不知道在一个字符串中可以存储多少数据,只会机械地从用户那里读取数据。如果用户输入像 `foo` 这样的短字符串,不会发生意外;但是当用户输入的值超过字符串长度时,后果可能是灾难性的。
下面是一个使用 `gets` 函数读取城市名称的示例程序。在这个程序中,我还添加了一些未使用的变量,来展示字符串溢出对其他数据的影响:
```
#include <stdio.h>
#include <string.h>
int
main()
{
char name[10]; /* Such as "Chicago" */
int var1 = 1, var2 = 2;
/* show initial values */
printf("var1 = %d; var2 = %d\n", var1, var2);
/* this is bad .. please don't use gets */
puts("Where do you live?");
gets(name);
/* show ending values */
printf("<%s> is length %d\n", name, strlen(name));
printf("var1 = %d; var2 = %d\n", var1, var2);
/* done */
puts("Ok");
return 0;
}
```
当你测试类似的短城市名称时,该程序运行良好,例如伊利诺伊州的 `Chicago` 或北卡罗来纳州的`Raleigh`
```
var1 = 1; var2 = 2
Where do you live?
Raleigh
<Raleigh> is length 7
var1 = 1; var2 = 2
Ok
```
威尔士的小镇 `Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch` 有着世界上最长的名字之一。这个字符串有 58 个字符,远远超出了 `name` 变量中保留的 10 个字符。结果,程序将值存储在内存的其他区域,覆盖了 `var1``var2` 的值:
```
var1 = 1; var2 = 2
Where do you live?
Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
<Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch> is length 58
var1 = 2036821625; var2 = 2003266668
Ok
Segmentation fault (core dumped)
```
在运行结束之前,程序会用长字符串覆盖内存的其他部分区域。注意,`var1``var2` 的值不再是起始的 `1``2`
避免使用 `gets` 函数,改用更安全的方法来读取用户数据。例如,`getline` 函数会分配足够的内存来存储用户输入,因此不会因输入长值而发生意外的字符串溢出。
### 4、重复释放内存
“分配的内存要手动释放”是良好的 C 语言编程原则之一。程序可以使用 `malloc` 函数为数组和字符串分配内存,该函数会开辟一块内存,并返回一个指向内存中起始地址的指针。之后,程序可以使用 `free` 函数释放内存,该函数会使用指针将内存标记为未使用。
但是,你应该只使用一次 `free` 函数。第二次调用 `free` 会导致意外的后果,可能会毁掉你的程序。下面是一个针对此点的简短示例程序。程序分配了内存,然后立即释放了它。但为了模仿一个健忘但有条理的程序员,我在程序结束时又一次释放了内存,导致两次释放了相同的内存:
```
#include <stdio.h>
#include <stdlib.h>
int
main()
{
int *array;
puts("malloc an array ...");
array = malloc(sizeof(int) * 5);
if (array) {
puts("malloc succeeded");
puts("Free the array...");
free(array);
}
puts("Free the array...");
free(array);
puts("Ok");
}
```
运行这个程序会导致第二次使用 `free` 函数时出现戏剧性的失败:
```
malloc an array ...
malloc succeeded
Free the array...
Free the array...
free(): double free detected in tcache 2
Aborted (core dumped)
```
要记得避免在数组或字符串上多次调用 `free`。将 `malloc``free` 函数定位在同一个函数中,这是避免重复释放内存的一种方法。
例如,一个纸牌游戏程序可能会在主函数中为一副牌分配内存,然后在其他函数中使用这副牌来玩游戏。记得在主函数,而不是其他函数中释放内存。将 `malloc``free` 语句放在一起有助于避免多次释放内存。
### 5、使用无效的文件指针
文件是一种便捷的数据存储方式。例如,你可以将程序的配置数据存储在 `config.dat` 文件中。Bash shell 会从用户家目录中的 `.bash_profile` 读取初始化脚本。GNU Emacs 编辑器会寻找文件 `.emacs` 以从中确定起始值。而 Zoom 会议客户端使用 `zoomus.conf` 文件读取其程序配置。
所以,从文件中读取数据的能力几乎对所有程序都很重要。但是假如要读取的文件不存在,会发生什么呢?
在 C 语言中读取文件,首先要用 `fopen` 函数打开文件,该函数会返回指向文件的流指针。你可以结合其他函数,使用这个指针来读取数据,例如 `fgetc` 会逐个字符地读取文件。
如果要读取的文件不存在或程序没有读取权限,`fopen` 函数会返回 `NULL` 作为文件指针,这表示文件指针无效。但是这里有一个示例程序,它机械地直接去读取文件,不检查 `fopen` 是否返回了 `NULL`
```
#include <stdio.h>
int
main()
{
FILE *pfile;
int ch;
puts("Open the FILE.TXT file ...");
pfile = fopen("FILE.TXT", "r");
/* you should check if the file pointer is valid, but we skipped that */
puts("Now display the contents of FILE.TXT ...");
while ((ch = fgetc(pfile)) != EOF) {
printf("<%c>", ch);
}
fclose(pfile);
/* done */
puts("Ok");
return 0;
}
```
当你运行这个程序时,第一次调用 `fgetc` 会失败,程序会立即中止:
```
Open the FILE.TXT file ...
Now display the contents of FILE.TXT ...
Segmentation fault (core dumped)
```
始终检查文件指针以确保其有效。例如,在调用 `fopen` 打开一个文件后,用类似 `if (pfile != NULL)` 的语句检查指针,以确保指针是可以使用的。
人都会犯错,最优秀的程序员也会产生编程错误。但是,遵循上面这些准则,添加一些额外的代码来检查这五种类型的错误,就可以避免最严重的 C 语言编程错误。提前编写几行代码来捕获这些错误,可能会帮你节省数小时的调试时间。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/programming-bugs
作者:[Jim Hall][a]
选题:[lujun9972][b]
译者:[unigeorge](https://github.com/unigeorge)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jim-hall
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bug_software_issue_tracking_computer_screen.jpg?itok=6qfIHR5y (Bug tracking magnifying glass on computer screen)
[2]: http://www.opengroup.org/onlinepubs/009695399/functions/puts.html
[3]: http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/free.html
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/gets.html
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html
[9]: http://www.opengroup.org/onlinepubs/009695399/functions/fgetc.html
[10]: http://www.opengroup.org/onlinepubs/009695399/functions/fclose.html

View File

@@ -0,0 +1,126 @@
[#]: subject: "KDE Plasma 5.23 Release Marks its 25th Anniversary With Exciting Improvements"
[#]: via: "https://news.itsfoss.com/kde-plasma-5-23-release/"
[#]: author: "Jacob Crume https://news.itsfoss.com/author/jacob/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13885-1.html"
纪念 25 周年KDE Plasma 5.23 发布
======
![](https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/kde-plasma-5-23-ft.png?w=1200&ssl=1)
多年来KDE Plasma 一直是最常用的桌面环境之一。这是因为它似乎有无穷无尽的定制选项、华丽的外观和有料的更新。
随着 KDE Plasma 5.23 的发布,这个桌面环境已经工作了 25 年。因此,这个版本也被称为 “Plasma 25 周年版”。
让我们回想一下1996 年 10 月 14 日KDE 的创始人 Matthias Ettrich [向一个新闻组][1] 发出了呼唤,为他的 “<ruby>Kool 桌面环境<rt>Kool Desktop Environment</rt></ruby>KDE” 项目寻求其他程序员的帮助。
而你看KDE 现在呢?
在这次更新中,我们可以看到包括 Plasma 内部和第三方应用程序在内的一些重大 UI 改进。
### KDE Plasma 5.23: 有什么新东西?
这次更新带来了许多改进,包括:
* 桌面重点颜色
* 新的 Breeze 主题
* 新的电源管理快速控制
* 应用程序启动器有更多的自定义选项
* 数以百计的错误修复
在这里,我们将看到所有这些新的改进:
![视频](https://youtu.be/RMXViPlehAo)
#### 桌面重点颜色
![][3]
在系统设置中,你会发现有一个可以改变你的桌面重点颜色的选项,你可以选择一个你喜欢的自定义颜色或与默认应用的主题相融合的颜色。
#### 新的 Breeze 主题
![][4]
这次更新带来了全新的 Breeze 主题Breeze - Blue Ocean。默认主题经过多年的改进这一次它侧重于使视觉效果更加清晰和易于识别。
总的来说,新的主题提供了顺滑的外观。除了主题之外,图标也变得更加突出;增加了一个加载齿轮图标。而且,许许多多这样的细微变化已经进入了 KDE Plasma 5.23,以增强桌面的外观和感觉。
正如开发者 Nate Graham 在测试版发布时所说:
> 还有很多时间可以根据需要调整最终的外观,但总的来说,我认为它真的很棒了,我希望你和我一样喜欢它。
#### 系统设置中增强的搜索功能
为了更容易找到你要找的东西KDE Plasma 5.23 增加了更多的关键词组合,以使你使用搜索栏寻找时可以快速提示你相关设置。
#### 系统托盘的改进
![][5]
虽然系统托盘已经提供了许多控制,但现在监控你连接的网络以及访问剪贴板有了更精细的选项。
系统托盘也改进了显示正在播放的活动媒体时的整体外观。
#### 新的电源管理快速控制
随着 Linux 5.12 的发布增加了一个电源管理功能。现在KDE 引入了一种简单的调整方式,它出现在新的快速控制中。
它有三个选项:节电、平衡和性能。只需要一次点击就可以节省电池电力并根据需要调整性能。
#### 应用程序启动器的改进
![][6]
在 Plasma 5.21 中KDE 引入了一个新的应用程序启动器,叫做 Kickoff。虽然它受到了普遍欢迎但一些用户也抱怨与旧的启动器相比自定义选项较少。
好在 Plasma 5.23 解决了这个问题,为 Kickoff 引入了一些全新的自定义选项。这些选项包括以下能力:
* 图标化电源和用户控件
* 所有项目都采用选择列表或网格视图,而不仅仅是收藏夹菜单
* 新的键盘快捷键 `CTRL+F` 可以快速聚焦到搜索栏
* 在右上角添加了一个新的按针状按钮,以保持应用程序启动器处于活动状态
总的来说,我预计用户会相当受欢迎这些新选项,特别是那些因为它有如此之多的定制选项而使用 KDE 的用户。
### 其他改进措施
其他的常规改进包括:
* 优化了 Wayland 会话
* 通过“反馈”程序提高了数据透明度
* 改进了 KDE 的 Discover应用中心的性能
要探索更多关于该版本的信息,你可以查看 [官方公告][7] 及其 [更新日志][8]。
### 总结
虽然不是有史以来最大的版本,但这是一个重要的版本,具有纪念其 25 周年的宝贵补充。像往常一样,你应该在未来几个月内的某个时候收到更新,这取决于你的发行版。
你对 KDE Plasma 5.23 的改进有什么看法?请在下面的评论中告诉我。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/kde-plasma-5-23-release/
作者:[Jacob Crume][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://news.itsfoss.com/author/jacob/
[b]: https://github.com/lujun9972
[1]: https://groups.google.com/g/de.comp.os.linux.misc/c/SDbiV3Iat_s/m/zv_D_2ctS8sJ?pli=1
[2]: https://i0.wp.com/i.ytimg.com/vi/RMXViPlehAo/hqdefault.jpg?w=780&ssl=1
[3]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/system-settings-accent-colour.png?w=743&ssl=1
[4]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/breeze-application-style.png?w=368&ssl=1
[5]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/plasma-nm.png?w=466&ssl=1
[6]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/kickoff.png?w=699&ssl=1
[7]: https://kde.org/announcements/plasma/5/5.23.0/
[8]: https://kde.org/announcements/changelogs/plasma/5/5.22.5-5.23.0/

View File

@@ -0,0 +1,135 @@
[#]: subject: "Ubuntu 21.10 is Available Now! Finally Brings the Much Awaited GNOME 40 With Ubuntu Twist"
[#]: via: "https://news.itsfoss.com/ubuntu-21-10-release/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13887-1.html"
Ubuntu 21.10 版现已发布!终于带来了 Ubuntu 特色的 GNOME 40
======
![](https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-21-10-release-date.png?w=1200&ssl=1)
> Ubuntu 21.10 是一个激动人心的版本,包含了 GNOME 40 和几个显著的变化。准备已经驶向了 Ubuntu 22.04 LTS 吗?
Ubuntu 21.10 是下一个大型 LTS 更新之前的最后一个非 LTS 版本。代号为 Impish Indri 的 Ubuntu 21.10 将被支持**九个月,直到 2022 年 7 月**。
除非你想尝试最新和最棒的功能,否则你应该坚持使用 Ubuntu 20.04 LTS 并等待 Ubuntu 22.04 LTS。
现在你可以下载 Ubuntu 21.10 并在你的系统上安装,让我重点介绍一下这次更新的几个亮点。
### Ubuntu 21.10 “Impish Indri” 有何新变化?
![][1]
Ubuntu 21.10 出炉时有几个重大变化。一些最有影响的改进包括:
* 新的安装程序
* 增加了 GNOME 40
* 抛弃了混合主题,选择了浅色/深色主题
* 包括 Linux 内核 5.13
* 加入了支持蓝牙 LDAC 的 PulseAudio 15
* 带有 Nvidia 专有驱动程序的 Wayland 会话
GNOME 40 可以说是 Ubuntu 中令人耳目一新的变化,但你只有在体验之后才能知道。为了让你快速感受一下,下面是这个版本中你可以期待的所有变化。
#### 粉饰一新的安装程序
![][2]
虽然 Ubuntu 的安装程序很容易使用,对新手也很友好,但 Canonical 希望通过对安装程序进行视觉和技术上的改造,使其更上一层楼。
开发团队利用 Flutter 使安装程序在所有其他 Ubuntu 口味和系统配置中保持一致。
![][3]
#### GNOME 40
![][5]
Ubuntu 的桌面体验与 GNOME 40 融为一体,没有提供任何混乱的布局。停靠区依然存在,水平活动概览也与之无缝衔接。
当然,[GNOME 40][4] 中的所有改进,如核心应用程序的更新、工作区的改变等等,都会延续到 Ubuntu 21.10 中,只是 Canonical 做了一些改动。
就我个人而言,我并不喜欢 GNOME 40 的工作流程,但你可能会想体验一下。
#### 主题的变化
![][9]
我喜欢改进后的颜色方案,其目的是为了更好地与 Canonical 的 Ubuntu 品牌相融合。
然而,当涉及到与应用程序和整体主题选择的一致性时,混合(标准)主题是有点问题的。
在 Ubuntu 21.10 中,你会看到深色和浅色主题,而浅色是开箱即用的默认选择。如果你想进一步了解,你可以阅读我们的 [过去的报道以更多了解这一变化][6]。
#### Linux 内核 5.13
Linux 内核 5.13 的加入增加了对未来的英特尔和 AMD 芯片的支持,以及对苹果 M1 的初步支持。
你可以就一步了解 [Linux 内核 5.13][7] 的信息,但总的来说,它应该给你更好的硬件兼容性。
#### PulseAudio 15 支持蓝牙 LDAC
考虑到现在有更多的蓝牙耳机支持 LDAC当你在桌面上使用 Ubuntu 21.10 时,你可以利用这一功能。
别担心,如果你不想尝试非 LTS 版本Ubuntu 22.04 LTS 将包括同样的改进。所以,你必须耐心等待,直到明年才能利用这一点。
除此之外PulseAudio 15 还带来了一系列的改进,你可以参考它的 [官方更新日志以了解更多信息][8] 。
#### Wayland 会话与 NVIDIA 专有驱动程序
现在,即使你使用 NVIDIA 专有的驱动程序,如果你需要也可以切换到 Wayland 会话。
#### Ubuntu 21.10 中的其他变化
![][14]
Ubuntu 21.10 版本为其云镜像、树莓派支持和安全性带来了一系列高质量的变化。
其中一些值得注意的变化包括:
* [Firefox 默认采用 Snap][10]
* LibreOffice、Thunderbird 更新
* Ubuntu Sever 的改进
* 新的 PHP 默认为 8.0.8
如果你想探索所有的技术细节,你可能想参考一下 [官方发布说明][11]。
### 下载并升级到 Ubuntu 21.10
你可以选择全新安装或使用软件升级器 [从 Ubuntu 21.04 升级][12] 到 Ubuntu 21.10。
请注意,如果你正在使用 Ubuntu 20.04 LTS建议等待下一个 LTS 版本,除非你知道自己在做什么。
- [下载Ubuntu 21.10][13]
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/ubuntu-21-10-release/
作者:[Ankush Das][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://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-21-10-full.png?w=1200&ssl=1
[2]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/02/new-ubuntu-installer.png?w=1012&ssl=1
[3]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-new-installer.png?w=960&ssl=1
[4]: https://news.itsfoss.com/gnome-40-release/
[5]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-21-10-new-gnome-40.png?resize=1568%2C776&ssl=1
[6]: https://news.itsfoss.com/ubuntu-21-10-theme-change/
[7]: https://news.itsfoss.com/linux-kernel-5-13-release/
[8]: https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/15.0/
[9]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-21-10-appearance.png?w=1062&ssl=1
[10]: https://news.itsfoss.com/ubuntu-firefox-snap-default/
[11]: https://discourse.ubuntu.com/t/impish-indri-release-notes/21951
[12]: https://itsfoss.com/upgrade-ubuntu-to-newer-version/
[13]: https://releases.ubuntu.com/21.10/
[14]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-21-10-about.png?w=1054&ssl=1

View File

@@ -0,0 +1,123 @@
[#]: subject: "How to Find and Kill Zombie Process in Linux"
[#]: via: "https://itsfoss.com/kill-zombie-process-linux/"
[#]: author: "Marco Carmona https://itsfoss.com/author/marco/"
[#]: collector: "lujun9972"
[#]: translator: "zengyi1001"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13919-1.html"
如何找到并杀掉 Linux 系统中的僵尸进程
======
![][5]
> 这是一个关于如何寻找 Linux 系统僵尸进程并杀死它们的小知识。你也可以从中了解到关于进程和僵尸进程的一些知识。
在了解僵尸进程之前,让我们来复习一下什么是 Linux 进程。
简而言之,[进程][1] 是一个程序的运行实例。它可能运行在前端(比如有交互的进程),也可能运行在后端(比如无交互或自动运行的进程)。它可能是一个父进程(运行期间创建了其他进程),也可能是一个子进程(由其他进程所创建)。
在 Linux 系统中,除 PID 为 0 的第一个 `init` 进程(或 `systemd`)外,其余进程都有父进程。进程也可以拥有自己的子进程。
不相信?可以试试在终端中使用 `pstree` 命令查看进程的树型结构,你能看到系统各个进程的“家族树”。
### Linux系统里的僵尸进程是什么
子进程死亡后,它的父进程会接收到通知去执行一些清理操作,如释放内存之类。然而,若父进程并未察觉到子进程死亡,子进程就会进入到“<ruby>僵尸<rt>zombie</rt></ruby>”状态。从父进程角度看,子进程仍然存在,即使子进程实际上已经死亡。这就是“<ruby>僵尸进程<rt>zombie process</rt></ruby>”(也被称为“<ruby>已消失进程<rt>defunct process</rt></ruby>”)是如何产生并存在于系统中的。
这里有一个来自 [Turnoff.us](https://turnoff.us/geek/zombie-processes/) 的关于僵尸进程的非常有趣的看法:
![Image credit: Turnoff.us][2]
### 你真的需要关心僵尸进程吗?
重点要说的是,僵尸进程并没有像它的名称那样看起来可怕。
但如果系统的内存已经所剩不多或者有太多的僵尸进程在吃掉内存,问题会变得糟糕。同样,大部分 Linux 系统进程最大 PID 设置为 32768如果过多僵尸进程导致其他重要任务没有 PID 可用,你的系统会发生崩溃。
这是真实可能发生的,它有一定的概率,特别当存在一个编码糟糕的程序开始大量产生僵尸进程的时候。
在这种情况下,找到并杀死僵尸进程是一个明智的做法。
### 如何找到僵尸进程
Linux 系统中的进程可能处于如下状态中的一种:
* `D` = 不可中断的休眠
* `I` = 空闲
* `R` = 运行中
* `S` = 休眠
* `T` = 被调度信号终止
* `t` = 被调试器终止
* `Z` = 僵尸状态
那如何查看进程和它的当前状态呢?一个简单的方法是在终端中使用 [top 命令][3]。
![Top command show processes and their status][4]
正如你在上面截图中看到的,截图中共有 250 个任务(进程),其中 1 个处在 “<ruby>运行中<rt>running</rt></ruby>” 状态248 个进程处于 “<ruby>休眠<rt>sleep</rt></ruby>” 状态,还有一个处于 “<ruby>僵尸<rt>zombie</rt></ruby>” 状态。
现在问题进入下一步,如何杀死 “僵尸” 进程?
### 如何找到并杀死一个僵尸进程?僵尸进程能被杀死吗?
僵尸进程已经死了,要如何才能杀死一个已经死亡的进程呢?
在僵尸电影中,你可以射击僵尸的头部或烧掉它们,但在这里是行不通的。你可以一把火烧了系统来杀死僵尸进程,但这并不是一个可行的方案。
一些人建议发送 `SIGCHLD` 给父进程,但这个信号很可能会被忽略。还有一个方法是杀死父进程来杀死僵尸进程,这听起来很野蛮,但它却是唯一能确保杀死僵尸进程的方法。
首先,通过在终端中 [使用 ps 命令][6] 我们列举僵尸进程,得到它们的进程 ID
```
ps ux | awk '{if($8=="Z+") print}'
```
`ps ux` 命令输出的第 8 列显示了进程状态。上述命令只会打印所有处在 Z+ 状态(表示僵尸状态)的进程。
确认了进程 ID 后,我们可以得到它的父进程 ID
```
ps -o ppid= -p <child_id>
```
你也可以将上述两个命令结合在一起,直接得到僵尸进程的 PID 及其父进程的 PID
```
ps -A -ostat,pid,ppid | grep -e '[zZ]'
```
现在你得到了父进程 ID使用命令行和得到的 ID 号 [终于可以杀死进程了][7]
```
kill -9 <parent_process_ID>
```
![Killing parent process][8]
再次运行 `ps` 命令或 `top` 命令,你可以验证僵尸进程是否已经被杀死。
恭喜!现在你知道怎么清理僵尸进程了。
--------------------------------------------------------------------------------
via: https://itsfoss.com/kill-zombie-process-linux/
作者:[Marco Carmona][a]
选题:[lujun9972][b]
译者:[zengyi1001](https://github.com/zengyi1001)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/marco/
[b]: https://github.com/lujun9972
[1]: https://tldp.org/LDP/tlk/kernel/processes.html
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/zombies-turnoff.webp?resize=800%2C467&ssl=1
[3]: https://linuxhandbook.com/top-command/
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/top-command-view.png?resize=800%2C474&ssl=1
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/kill-zombie-process-linux.jpg?resize=800%2C450&ssl=1
[6]: https://linuxhandbook.com/ps-command/
[7]: https://itsfoss.com/how-to-find-the-process-id-of-a-program-and-kill-it-quick-tip/
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/killing-parent-process.png?resize=800%2C180&ssl=1

View File

@@ -0,0 +1,67 @@
[#]: subject: "How to Upgrade to Ubuntu 21.10 Right Now"
[#]: via: "https://itsfoss.com/upgrade-ubuntu-to-newer-version/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13902-1.html"
如何现在就升级到 Ubuntu 21.10
======
[Ubuntu 21.10 “Impish Indri” 刚刚发布][1]。如果你正在使用 Ubuntu 21.04,你应该有升级到 Ubuntu 21.10 的选项。
![](https://img.linux.net.cn/data/attachment/album/202110/20/105035l6ig4lkjnk5cipuw.jpg)
然而,这种推出将是逐步的。这意味着不是每个人都会立即得到新版本可用的通知。在你看到升级选项之前,可能需要几周的时间。
但是,如果你迫不及待地想获得带有 GNOME 40 和其他新功能的 Ubuntu 21.10 呢?你真的需要等待吗?不用。
### 现在就从 Ubuntu 21.04 升级到 Ubuntu 21.10
以下是你要做的。打开“<ruby>软件和更新<rt>Software & Updates</rt></ruby>”应用:
![Start the Software & Updates application][3]
并确保你在“<ruby>更新<rt>Updates</rt></ruby>”标签下将“<ruby>通知我新的 Ubuntu 版本<rt>Notify me of a new Ubuntu version</rt></ruby>”设置为“<ruby>任何新版本<rt>For any new version</rt></ruby>”。
![Make sure that settings are right for new Ubuntu version notification][4]
现在打开终端,输入以下命令,以确保你的系统已经更新:
```
sudo apt update && sudo apt upgrade
```
当你的 Ubuntu 21.04 系统安装了所有的更新,运行更新管理器来寻找开发版本(本例中为 Ubuntu 21.10)。
```
update-manager -d
```
它将打开寻找更新的“<ruby>更新管理器<rt>Update Manager</rt></ruby>”。由于你已经更新了系统,它不会找到新的更新来安装。然而,它将看到 Ubuntu 21.10 现在已经可用。
![Hit the upgrade button][2]
你可以点击“<ruby>升级<rt>Upgrade</rt></ruby>”按钮,按照屏幕上的选项开始升级程序。你需要有良好的网络速度来下载 2GB 的更新。确保你的系统在升级过程中保持与电源的连接。
享受 Ubuntu 21.10
--------------------------------------------------------------------------------
via: https://itsfoss.com/upgrade-ubuntu-to-newer-version/
作者:[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://linux.cn/article-13887-1.html
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/upgrade-to-Ubuntu-21-10.webp?resize=797%2C287&ssl=1
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/software-and-updates.webp?resize=800%2C166&ssl=1
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/ubuntu-upgrade-settings.webp?resize=800%2C338&ssl=1

View File

@@ -0,0 +1,111 @@
[#]: subject: "helloSystem, the Mac-like FreeBSD OS, Takes Another Step Towards Full Release"
[#]: via: "https://news.itsfoss.com/hellosystem-towards-first-release/"
[#]: author: "John Paul Wohlscheid https://news.itsfoss.com/author/john/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13915-1.html"
helloSystem一款类似 Mac 的 FreeBSD 系统
======
![](https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/hello-system-bsd.jpg?w=1200&ssl=1)
最近helloSystem 的开发者发布了他们操作系统的最新版本。helloSystem 是一个较新的项目,希望以 FreeBSD 为基础创建一个简单易用的操作系统。让我们来看看这对你我意味着什么。
### helloSystem 简介
![helloSystem 的关于屏幕][1]
你们中的大多数人可能以前从未听说过 [helloSystem][2]。该项目是由 [AppImage 的创建者][3] [Simon Peter][4] 在去年年初启动的。Simon 的目标是创建一个“友好的 [自由桌面][5] 操作系统,重点是简单、简约优雅和可用性。”
Simon 从上世纪 80 、90 年代更为简单的操作系统中获得了灵感,特别是 **早期的 MacOS**,比如 [System 1][6]。如果你只是看一下系统运行的截图,你可能会想说,“我不明白这有什么好大惊小怪的。有一堆 Linux 发行版或主题,看起来就像 MacOS。”
该项目不仅仅是看起来像 MacOS它想回归到更简单、更容易使用的设计。据 [其网站][7] 上讲“helloSystem 是一个面向创作者的桌面系统,注重简单、优雅和实用性。它的设计遵循 ‘少而精’ 的理念。它的目的是为 ‘普通人’ 提供一个系统,欢迎从 Mac 切换过来的人”。你可以通过观看 Simon 在 [FOSDEM 21][8] 上的演讲,了解更多关于他对 helloSystem 计划的想法。
就像 [Suckless 项目][9] 一样Simon 创建了一个 “[欢迎和不欢迎的技术][10]” 列表。被批准的技术清单包括:
* Qt
* mDNSResponder
* Python
* Go
![helloSystem 的欢迎屏幕][12]
“不受欢迎的技术”清单包括 Simon 认为“太复杂或被认为不美观”的东西。这些技术包括:
* 触摸
* btrfs
* Gnome
* GTK
* 客户端窗口装饰
* Wayland
* Pipewire
* XDG 桌面规范
* 与原始字体在度量上兼容的字体,但不试图在视觉上与原始字体相似
* 最终用户应用程序的包管理器
* 配置文件、IP 地址
* D-Bus
* 通过限制用户或应用程序可以做的事情而提供的安全性
* Polkit
* 大写锁定键
* 本地文件的 URI
![在 helloSystem 上安装 Inkscape][13]
### helloSystem 如何工作
我最好解释一下 helloSystem 的工作方式。就像 MacOS 一样,桌面在屏幕顶部有一个全局菜单,底部有一个 Dock。与 MacOS 的 Finder 一样helloSystem 也有一个文件管理器(名为 Filer它也负责窗口管理。
在左上方,你会发现一个 “<ruby>系统<rt>System</rt></ruby>” 菜单你可以用它来访问应用程序。你也可以在左上角的搜索框中输入应用程序的名称。helloSystem 只安装了几个开箱即用的基本应用程序。如果你点击一个未安装的应用程序helloSystem 会下载并安装该应用程序的 AppImage。
helloSystem 基于 FreeBSD 12.2。它默认启用了 ZFS。它没有密码或用户账户系统但这并不意味着他们无视安全。据 [其网站][10] 讲,“这并不是说一般的安全问题不重要。而是说它需要以一种不会限制设备的合法用户(所有者)真正 ‘拥有’ 该设备的方式来实现。”
### 最新版本中的新功能
![helloSystem 的实用程序窗口][14]
最新版本的 helloSystem 包括不少图形方面的更新和小的变化,包括:
* 从 Openbox 切换到 KWin 窗口管理器
* 合理的窗口标题居中
* 当窗口被拖到屏幕边缘时,会缩放到一定大小,类似于 “Aero Snap”。
* 简化了 “<ruby>桌面设置<rt>Desktop Settings</rt></ruby>” 的用户界面;现在更改会立即应用
* 移除文件管理器中的标签以简化用户界面
* 为菜单添加新的电池小程序,以显示电池充电量
* 桌面上的垃圾箱图标不再有 “<ruby>移动到垃圾箱<rt>Move to Trash</rt></ruby>” 的上下文菜单项
* 最小化窗口和取消最小化窗口时的动画
* 窗口大小调整时的动画
* 调整内核配置以优化声音
* 简化了文件管理器中的 “<ruby>获取信息<rt>Get Info</rt></ruby>” 对话框
你可以在 [这里][11] 看到其余的变化。你也可以从同一个链接下载最新的 .iso 文件。试一试,让我们知道你的想法。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/hellosystem-towards-first-release/
作者:[John Paul Wohlscheid][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://news.itsfoss.com/author/john/
[b]: https://github.com/lujun9972
[1]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/hello-about.jpg?w=850&ssl=1
[2]: https://github.com/helloSystem/hello
[3]: https://itsfoss.com/appimage-interview/
[4]: https://github.com/probonopd
[5]: https://medium.com/@probonopd/bring-back-the-ease-of-80s-and-90s-personal-computing-393738c5e2a1
[6]: https://github.com/helloSystem/hello/wiki#design-principles
[7]: https://hellosystem.github.io/docs/
[8]: https://fosdem.org/2021/schedule/event/hello_bsd/
[9]: https://suckless.org/sucks/
[10]: https://github.com/helloSystem/hello/wiki/Welcome-and-unwelcome-technologies
[11]: https://github.com/helloSystem/ISO/releases/tag/r0.6.0
[12]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/hello-welcome.jpg?w=850&ssl=1
[13]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/hello-install.jpg?w=850&ssl=1
[14]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/hello-utillities.jpg?w=850&ssl=1

View File

@@ -0,0 +1,116 @@
[#]: subject: "4 Linux tools to erase your data"
[#]: via: "https://opensource.com/article/21/10/linux-tools-erase-data"
[#]: author: "Don Watkins https://opensource.com/users/don-watkins"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13913-1.html"
4 个用来擦除数据的 Linux 工具
======
> 用这些开源工具从你的硬盘驱动器中擦除数据。
![](https://img.linux.net.cn/data/attachment/album/202110/23/113918sdojp6sj0odgis16.jpg)
保持数据安全的最好方法之一是只向加密的硬盘驱动器写入数据。在一个标准的硬盘上,只要把硬盘挂载就可以查看数据,就像 U 盘一样,甚至可以用 [Scalpel][2] 和 [Testdisk][3] 等工具显示和恢复已删除的数据。但是在一个加密的驱动器上,如果没有解密密钥(通常是你在挂载驱动器时输入的密码),数据是无法被读取的。
加密可以在你安装操作系统时建立,有些操作系统甚至可以在安装后的任何时候激活加密功能。
但是,当你卖掉一台电脑或更换一个一开始就没有被加密的驱动器时,你该怎么办呢?
与从一开始就加密你的数据相比,最好的办法是在你用完硬盘后删除数据。
### 负责任的看管者
我经常被要求帮助客户升级一台旧电脑。无一例外,他们更愿意帮助我回收它们,使它们能被别人使用。我很乐意翻新这些旧电脑,用较新的固态驱动器来改装它们,极大地提高性能。
然而,把一个旧驱动器扔进垃圾桶并不是一个好主意。它需要被擦除,然后被妥善处理。我没有把硬盘留在原来的电脑里,而是把它们取出来,放在一个硬盘盒里,然后把它们连接到我的 Linux 电脑上。有几个 Linux 工具可以很容易地完成这个任务。其中一个是 **Gnu Shred**
### GNU Shred
```
$ sudo shred -vfz /dev/sdX
```
Shred 有许多选项:
* `-n` - 覆盖的次数。默认是三次。
* `-u` - 覆盖并删除。
* `-s` - 要粉碎的字节数。
* `-v` - 显示扩展信息。
* `-f` - 必要时强制改变权限以允许写入。
* `-z` - 最后用 0 覆盖来隐藏粉碎。
使用 `shred --help` 获取更多信息
### ShredOS
ShredOS 是一个<ruby>即用<rt>Live</rt></ruby> Linux 发行版,它的唯一目的是清除驱动器的全部内容。它是在一个名为 DBAN 的类似发行版停止维护后开发的。它使用 `nwipe` 应用,它是 DBAN 的 `dwipe` 的一个分叉。你可以通过下载 32 位或 64 位镜像,并在 Linux 和 macOS 上使用 `dd` 命令将其写入驱动器来制作一个可启动的 USB 驱动器:
```
$ sudo dd if=shredos.img of=/dev/sdX bs=4M status=progress
```
另外,你可以在 Linux、macOS 和 Windows 上使用 [Etcher][4] 工具烧录。
### dd 命令
清除驱动器的一个常见方法是使用 Linux 的 `dd` 命令。几乎所有的 Linux 安装都安装了 `dd` 工具。确保该驱动器没有被挂载。
```
$ sudo umount /dev/sdXY -l
```
如果你想在整个目标磁盘上写零,执行以下命令。这可能需要一个整个通宵。
```
$ sudo dd if=/dev/urandom of=/dev/sdX bs=10M
```
**警告**:请确保你知道你在系统中的位置,并以正确的驱动器为目标,这样你就不会意外地删除自己的数据。
### Nvme-cli
如果你的计算机包含一个较新的 NVMe 驱动器,你可以安装 [nvme-cli][5] 程序,并使用 `sanitize` 选项来清除你的驱动器。
`nvme sanitize help` 命令提供了选项列表:
* `--no-dealloc``-d` - 净化后不解除分配。
* `--oipbp``-i` - 每次覆写后反转模式。
* `--owpass=``-n` - 覆写次数。
* `--ause``-u` - 允许无限制净化退出。
* `--sanact=``-a` - 净化动作。
* `--ovrpat=``-p` - 覆写模式。
下面是我使用的命令:
```
$ sudo nvme sanitize /dev/nvme0nX
```
这里的警告与格式化过程相同:首先备份重要的数据,因为这个命令会擦除这些数据!
### 信息管理
你保存在计算机上的信息是很重要的。它属于你,也属于其他任何人。当你卖掉一台电脑或处理一个硬盘时,确保你已经用这些很棒的工具之一清除了你的数据。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/linux-tools-erase-data
作者:[Don Watkins][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/don-watkins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cloud_tools_hardware.png?itok=PGjJenqT (Tools in a cloud)
[2]: https://www.redhat.com/sysadmin/find-lost-files-scalpel
[3]: https://www.redhat.com/sysadmin/recover-partition-files-testdisk
[4]: https://opensource.com/article/18/7/getting-started-etcherio
[5]: https://opensource.com/article/21/9/nvme-cli

View File

@@ -0,0 +1,113 @@
[#]: subject: "Get memory use statistics with this Linux command-line tool"
[#]: via: "https://opensource.com/article/21/10/memory-stats-linux-smem"
[#]: author: "Tomasz Waraksa https://opensource.com/users/tomasz"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13918-1.html"
用 smem 命令获取内存使用统计信息
======
> smem 命令允许你快速查看你的网页应用的内存使用情况。
![](https://img.linux.net.cn/data/attachment/album/202110/25/101843emjjkmvk88gvyqgv.jpg)
在我的编程工作中,我经常需要了解网页应用的内存使用情况。在深入研究细节和浏览器剖析工具之前,一个粗略的估计通常就足够了。
为了了解 Linux 或 macOS 上的内存使用情况,人们通常使用 [top][2] 或 [htop][3]。我很想看到一个单一的数字:一个进程占用了多少内存。但这些工具所显示的统计数据可能很难理解。对于网页浏览器来说,它甚至更加复杂,因为它们经常运行许多独立的进程。它们在 `top` 输出中显示为一个长长的列表,每一个都有自己的单独指标。
![Memory usage using htop][4]
### smem 命令
幸运的是有 [smem][6],另一个用于查看内存使用统计的命令行工具。用你选择的包管理器安装它,例如:
```
sudo apt install smem
```
要获得 [Firefox][7] 的总内存使用量,请执行:
```
smem -c pss -P firefox -k -t | tail -n 1
```
这些开关做了什么?
* `-c` 开关指定要显示的列。我只对 `pss` 列感兴趣,它显示一个进程分配的内存。
* `-P` 开关过滤进程,只包括那些名字里有 `firefox` 的进程。
* `-k` 开关显示以 MB/GB 为单位的内存使用情况,而不是单纯的字节数。
* `-t` 开关显示总数。
* `tail -n 1` 过滤器只输出最后一行,也就是总数的地方。
输出是非常简单的:
```
$ smem -t -k -c pss -P firefox | tail -n 1
4.9G
```
开门见山!而且,经过又一天忙碌的工作,打开了 50 多个选项卡Firefox 仍然只使用 5 GB。看看吧Google Chrome。
#### 用一个脚本更容易
为了方便起见,我创建一个名为 `memory-use` 的小脚本,它将进程名称作为参数。我把所有的脚本都放在 `~/bin` 里,所以:
```
echo 'smem -c pss -P "$1" -k -t | tail -n 1' > ~/bin/memory-use && chmod +x ~/bin/memory-use
```
现在我可以很容易地测量任何应用的内存使用:
```
memory-use firefox
memory-use chrome
memory-use slack
```
#### 还有更多!
该工具不仅可以显示总的内存使用情况。它甚至可以生成图形输出。
比如:
```
smem --pie name -c pss
```
显示类似这样的内容:
![Pie chart output from smem][8]
关于更多的细节,我建议查看 [smem 手册页][6]。
你可以在 <https://linoxide.com/memory-usage-reporting-smem/> 上找到另一个很棒的教程。
希望你喜欢!
本文最初发表在[作者的博客][9]上,并经许可转载。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/memory-stats-linux-smem
作者:[Tomasz Waraksa][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/tomasz
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_code_keyboard_orange_hands.png?itok=G6tJ_64Y (Programming at a browser, orange hands)
[2]: https://linux.die.net/man/1/top
[3]: https://linux.die.net/man/1/htop
[4]: https://opensource.com/sites/default/files/uploads/1_htop.png (Memory usage using htop)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://linux.die.net/man/8/smem
[7]: https://www.mozilla.org/en-US/firefox/
[8]: https://opensource.com/sites/default/files/uploads/2_smem-pie-chart.png (Pie chart output from smem)
[9]: https://letsdebug.it/post/26-measure-application-memory-use-on-linux/

View File

@@ -0,0 +1,114 @@
[#]: subject: "PinePhone Pro is an Affordable Linux Flagship Smartphone That Could Replace Your Android"
[#]: via: "https://news.itsfoss.com/pinephone-pro-introduced/"
[#]: author: "Jacob Crume https://news.itsfoss.com/author/jacob/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13901-1.html"
PinePhone Pro一款价位适中的 Linux 旗舰智能手机
======
> 售价 399 美元的 PinePhone Pro 是一款 Linux 智能手机,或许有潜力取代一些预算相当的 Android 设备。但作为消费者,还需要等待几个月。
![](https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/PinePhone-Pro-ft.png?w=1200&ssl=1)
早在 2019 年,当 Pine64 宣布推出 PinePhone 时没有人想到它会变得如此受欢迎。在短短两年间Pine64 已经成功建立了一个由数万名开发者和用户组成的社区,大家一起努力使 Linux 完美地跑在了手机上。
现在,随着 PinePhone Pro 的宣布Pine64 正在扩大 Linux 手机的受众范围。这个设备有许多令人难以置信的新功能,所有这些都使它可以与许多中档 Android 手机相提并论。
- [视频](https://img.linux.net.cn/static/video/Meet%20the%20PinePhone%20Pro%20_%20PINE64-wP2-6Z74W44.mp4)
### PinePhone Pro 功能
![][1]
与原来的 PinePhone 相比PinePhone Pro 带来了巨大的升级。这些升级中最值得注意的是使用了 Rockchip 的六核 RK3399S SoC 芯片,这应该能显著地提升性能。其他一些值得注意的功能和升级还有:
* 4GB LPDDR4 内存
* 128GB 存储 + microSD 卡插槽
* 6 英寸 IPS 显示屏,采用 **大猩猩 4 号玻璃**
* 1300 万像素(后置)+ 500 万像素(前置)的摄像头
让我们来探讨一下这方面的更多细节。
#### 性能更好
![][2]
到目前为止,最重要的升级是 RK3399S SoC 的加入,它是 Pine64 和 Rockchip 合作的结果。这个令人印象深刻的强大 SoC 包含 6 个 CPU 核心,以及一个四核 Mali T860 GPU。
这一组合带来了显著的性能提升,使得 PinePhone Pro 的性能与大多数中档安卓手机相当。这带来了一个更快的系统,能够运行许多桌面级应用程序,如用于照片编辑的 GIMP 和用于仿真游戏的 RetroArch。
总的来说,这次升级将大大改善开发者和消费者的用户体验。
#### 内存更多
考虑到智能手机已经开始提供 6GB 内存作为基本变体时Linux 智能手机也应该使用更多的内存来保持流畅。虽然在优化方面已经做了很多工作,但更多的内存总是有益的。
PinePhone Pro 提供了 4GB 的内存,当放在基座上时可以有更大的通用性,当作为手机使用时可以多打开几个应用程序。我对此感到非常兴奋,因为它应该能够模拟更多的游戏,增加 PinePhone Pro 作为娱乐设备的吸引力。
#### 存储空间升级
我的原版的 PinePhone 面临的最大挑战之一是存储空间不足。从看电影到玩仿真游戏,我不得不不断地删除文件以获得足够的存储空间。
然而,在 PinePhone Pro 上Pine64 已经解决了这个问题,它提供了 128GB 的闪存,这对任何人来说都足够了。
#### 显示屏改进
![][4]
虽然这并不是原版 PinePhone 的痛点,但 PinePhone Pro 的显示屏已经升级,变得更大,采用了大猩猩 4 号玻璃。这是非常值得欢迎的,这款手机现在应该可以提供明显改善的防刮伤性能和更多可用的屏幕空间。
虽然 AMOLED 面板会很好,但这在一定程度上会提高价格,可能会降低设备的吸引力。总的来说,我对这次升级很满意,我相信许多用户也是这样。
#### 相机升级
至少对我来说,原版的 PinePhone 的摄像头是一个相当大的痛点。主摄像头只有 500 万像素,还有一个小小的 200 万像素的前置摄像头,这两个摄像头都不能拍出非常高质量的图像。
原版的 PinePhone 的主摄像头已被移到 PinePhone Pro 的前面。它与一个 1300 万像素的索尼摄像头传感器相配,能够录制 4K 视频和提供更高的图像质量。
用户终于可以用他们的 Linux 智能手机来拍摄照片,在社交媒体平台上分享了。
### 你可以升级你的原版 PinePhone 吗?
这是我看到该公告时问的第一个问题。不幸的是,将你的 PinePhone 升级到 PinePhone Pro 主板是不可行的。我认为 Pine64 解释得很好:
> 虽然 PinePhone Pro 的主板尺寸适合 PinePhone但机框、IPS 显示面板、摄像头、子板和散热系统都不同。例如PinePhone Pro 的摄像头就不适合 PinePhone 的机框,而且与 PinePhone Pro 的主板在电气上不兼容。散热是另一个重要的考虑因素,因为在原来的 PinePhone 的机框中,较高的热量输出可能不能简单地忽略,这需要克服解决。
虽然 Pine64 不建议升级你原来的 PinePhone 的主板但我认为尝试一下还是很有意思的。虽然令人失望但也应该注意到Pine64 并不打算停止原来的 PinePhone 开发,因为它对于想要一个便宜的 Linux 手机作为基本用途的人来说是完美的。
### 总结
总的来说,我非常兴奋地看到又一个设备进入 Linux 手机市场,尤其是像 PinePhone Pro 这样将得到良好支持(希望是这样)的设备。尽管其价格是 399 美元,但我认为很多人都会蜂拥而至购买这款手机。
如果你认为你可能是这些人中的一员,但你得等待几个月后的正式发布。
然而,想要获得早期设备的开发者现在可以点击下面的按钮来预购 PinePhone Pro。
- [预购PinePhone Pro][6]
关于 PinePhone Pro 的可用性和规格的更多细节,你应该去他们的 [官方网站][5] 看看。
你要买 PinePhone Pro 吗?请在下面的评论中告诉我!
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/pinephone-pro-introduced/
作者:[Jacob Crume][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://news.itsfoss.com/author/jacob/
[b]: https://github.com/lujun9972
[1]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/pinephone-pro.png?w=1024&ssl=1
[2]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/pinephoneProMainBoard.jpg?w=1024&ssl=1
[3]: https://i0.wp.com/i.ytimg.com/vi/pCxDcMdr_fo/hqdefault.jpg?w=780&ssl=1
[4]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/PinePhonePro.png?w=465&ssl=1
[5]: https://www.pine64.org/pinephonepro/
[6]: https://preorder.pine64.org/

View File

@@ -0,0 +1,69 @@
[#]: subject: "Dash to Dock is Finally Available for GNOME 40"
[#]: via: "https://news.itsfoss.com/dash-to-dock-gnome-40/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13905-1.html"
Dash to Dock 终于可以在 GNOME 40 上使用了
======
> Dash to Dock v70 增加了对 GNOME 40 的支持,并放弃了对较旧版本的 GNOME Shell 的支持。但是,你可以继续使用旧版本。
![](https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/ubuntu-dock.png?w=1200&ssl=1)
Dash to Dock 是多年来最 [有用的 GNOME 扩展][1] 之一。随着 [GNOME 40][2] 的引入,很多人都没能让这个扩展在它上面工作起来。
当然,作为一个流行的扩展,对 GNOME 40 的支持预计很快就会被加入。终于,它来了!
如果你不知道GNOME 40 包括一个水平工作区视图,这影响了一些人的工作流程,但 Ubuntu 即使在 GNOME 40 中也没有移动 Dock 的打算。
所以,你仍然可以使用 Dash to Dock 来从概览区得到一个水平的 Dock。
### Dash to Dock v70 放弃了对旧的 GNOME Shell 的支持
![][3]
Dash to Dock v70对 GNOME 40 和特定的 3.34 版的 GNOME Shell 提供了支持。
然而,为了支持 GNOME 40 而对扩展所做的技术修改也意味着新版本的扩展不能再与旧版本的 GNOME Shell 一起工作。
如果你没有运行 GNOME 40你仍然可以使用旧的 v69它应该可以很好地工作。而且除了增加了对 GNOME 40 的支持,在功能上也没有什么不同。
该扩展的未来发展可能很有趣,他们是否会考虑为不同的 GNOME Shell 版本而增加不同的扩展软件包,并提供新的功能?让我们拭目以待。
### 安装 Dash to Dock 的方法
![][4]
你可以从 [GNOME 扩展网站][5] 中通过简单的切换按钮来安装这个扩展。如果你是新手,我建议通过我们的 [GNOME 扩展安装指南][6] 来开始。
- [Dash to Dock GNOME 扩展][5]
值得注意的是,你需要使用一个兼容的网页浏览器来安装这个扩展。虽然它应该可以在大多数浏览器上使用([基于 Chromium 的浏览器][7] 应该可以),但正如 [OMG! Ubuntu][8] 最初报道的那样Ubuntu 21.10 中 Snap 打包的 Firefox 浏览器可能无法使用。
你试过这个扩展了吗?欢迎在下面的评论中告诉我你的想法。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/dash-to-dock-gnome-40/
作者:[Ankush Das][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://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-gnome-extensions/
[2]: https://news.itsfoss.com/gnome-40-release/
[3]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/dash-to-dock.jpeg?w=1366&ssl=1
[4]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/gnome-dash-dock-extension.png?w=1259&ssl=1
[5]: https://extensions.gnome.org/extension/307/dash-to-dock/
[6]: https://itsfoss.com/gnome-shell-extensions/
[7]: https://news.itsfoss.com/chrome-like-browsers-2021/
[8]: https://www.omgubuntu.co.uk/2021/10/dash-to-dock-official-gnome-40-support?

View File

@@ -0,0 +1,114 @@
[#]: subject: "Linux Tablets: What are Your Options?"
[#]: via: "https://itsfoss.com/linux-tablets/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13929-1.html"
有哪些 Linux 平板电脑可供选择
======
![](https://img.linux.net.cn/data/attachment/album/202110/28/180114mism33m44sibmsc9.jpg)
有很多 [基于 Linux 的笔记本电脑][1],也有 [预装了 Linux 的迷你 PC][2],而市场上还有一些 [基于 Linux 的智能手机][3]。
那平板电脑呢?有没有一些不错的基于 Linux 的平板电脑?这可能不能用一句话说清楚。
许多仅使用 Linux 的系统制造商专注于制造台式电脑。这主要是由于触摸设备上的 Linux 体验与安卓和 iOS 提供的体验相距甚远。
但这是否意味着你不能在平板电脑上使用 Linux并非如此。对于早期尝试用户和 DIY 爱好者来说,还有一些选择的。让我们来看看在这些 Linux 平板电脑中,你有哪些选择。
### Ubuntu Touch
![BQ 平板电脑上的 Ubuntu Touch 操作系统][4]
好吧!这不是一个平板电脑,而是一个操作系统。但它确实让你可以在一些旧的安卓平板电脑上安装一个适合触摸操作的 Ubuntu 版本。
注意“一些”这个词。Ubuntu Touch 官方 [支持][5] Nexus 7、联想 M10、Xperia Z4 和 BQ Aquaris 平板。你甚至可以尝试在你的其他平板电脑上安装 Ubuntu Touch。它可能无法 100% 工作,但仍然非常有用。
[Ubuntu Touch][8] 是 Ubuntu 团队的一个项目,但是他们 [在 2017 年中止了它][6]。[UBports][7] 承担了继续这个项目的责任,他们在有限的资源下做的很棒。
总而言之如果你喜欢各种实验想让你的旧安卓平板电脑获得新生Ubuntu Touch 可能是你的周末项目。
### PineTab
![PineTab][9]
Pine64 始于其单板计算机 Pine A64以作为 [树莓派的替代品][10]。随着时间的推移,它推出了几个 Pine 品牌的产品。这份名单里包括低调的 [PineTime 智能手表][11]、PineBook 笔记本电脑、PinePhone 智能手机和 PineTab 平板电脑。
这些 Pine 设备通常价格低廉,并允许用户对这些小设备进行完全控制。这种可魔改的特性帮助它聚集了一大批开源 DIY 爱好者的粉丝。
[PineTab][12] 基本上使用了与带有触摸屏和键盘的 Pine64 单板计算机相同的组件。它不是看起来最漂亮的平板电脑,也不打算成为这样的。
它的规格很一般,有一个高清 IPS 电容式触摸屏、全志 A64 芯片组、四核 CPU 和 2GB 内存。
它无法与 iPad 或 Galaxy Tab 竞争,但它允许你安装你选择的发行版,并按你的要求进行配置。
请记住Pine 的库存有限,所以如果你能看到这个设备可以购买,那你很幸运。
### PineNote
![PineNote][13]
另一个 Pine 设备,与你在上一节看到的 PineTab 略有不同。
PineTab 是一款用于浏览互联网、使用应用程序和玩游戏的 Linux 平板电脑,而 [PineNote][14] 是用来做笔记和阅读书籍和文件的。
它有一个电子墨水显示屏,你可能在 Kindle 等电子书阅读器上见过。除了电子书阅读器之外PineNote 还可以你用 Wacom 笔做笔记。
PineNote 拥有四核 Rockchip、多点触控电子墨水面板、4GB 内存和 128GB eMMC 存储。它也是为数不多的价格高于通常的 399 美元的平板点之一。
请记住PineNote 正处于早期开发阶段,只接受开发者的订单。
### RasPad
![RasPad][18]
[RasPad][19] 是一个用于树莓派设备的套件,可以把它变成一个基于触摸功能的设备。与普通的平板不同,这不是一个扁平的设备,而是有一个楔形的身体。这使得它更容易在办公桌上使用。
RasPad 是专门为树莓派设备创建的,你可以轻松使用它的大部分端口。它有一个专门的 RasPad 操作系统,但你可以自由使用常规的树莓派操作系统或 Ubuntu 或任何其他适合树莓派的操作系统。在选择操作系统时请考虑触控友好性。
请记住,树莓派设备不包括在套件中。你必须要单独购买。
### 你的选择是什么?
我知道我们离一个优秀的 Linux 平板电脑还很远,但它们至少可以和市场上的安卓平板电脑竞争。至少我们有一些可用的选择,这也是一线希望。
你是否已经拥有以上列出的设备之一了?你的体验如何?
如果你只能选择其中之一,那么你选择哪一款 Linux 平板电脑?
--------------------------------------------------------------------------------
via: https://itsfoss.com/linux-tablets/
作者:[Abhishek Prakash][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://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://linux.cn/article-13672-1.html
[2]: https://itsfoss.com/linux-based-mini-pc/
[3]: https://linux.cn/article-13711-1.html
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/ubuntu-touch.jpg?resize=755%2C537&ssl=1
[5]: https://devices.ubuntu-touch.io/
[6]: https://itsfoss.com/ubuntu-unity-shutdown/
[7]: https://ubports.com/
[8]: https://ubuntu-touch.io/
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/PineTab.jpg?resize=800%2C742&ssl=1
[10]: https://itsfoss.com/raspberry-pi-alternatives/
[11]: https://itsfoss.com/pinetime-linux-smartwatch/
[12]: https://pine64.com/product/pinetab-10-1-linux-tablet-with-detached-backlit-keyboard/?v=0446c16e2e66
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/PineNote-tab.jpg?resize=800%2C615&ssl=1
[14]: https://www.pine64.org/pinenote/
[15]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/jingpad-keyboard-angle.webp?resize=800%2C600&ssl=1
[16]: https://itsfoss.com/jingpad-a1-review/
[17]: https://en.jingos.com/jingpad-a1/
[18]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/raspad.webp?resize=800%2C614&ssl=1
[19]: https://raspad.com/products/raspadv3

View File

@@ -0,0 +1,92 @@
[#]: subject: "Why Mark Text is my favorite markdown editor"
[#]: via: "https://opensource.com/article/21/10/mark-text-markdown-editor"
[#]: author: "Don Watkins https://opensource.com/users/don-watkins"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13926-1.html"
Mark Text我最喜欢的 Markdown 编辑器
======
> Mark Text 拥有的工具使得撰写 Markdown 变得容易,同时又提供了一个不会打扰我的简单的界面。
![](https://img.linux.net.cn/data/attachment/album/202110/27/141244m9os557ss7au6oas.jpg)
几年前,当我开始使用 Jupyter 笔记本时,我接触到了 Markdown 格式。许多作者都知道 Markdown但这是我不熟悉的一种技能。
Markdown 是一种标准的文本写作方式,在这种方式中,你可以用精简的符号来标记你想要的文本样式。例如,你不用点击一个按钮来使一个词变粗体,而是用两个星号(`**word**`)包围这个词。这有两种效果:
* 当作为纯文本查看时,视觉上显示出强调的文本
* 如果有一个好的文本转换器或渲染器(如 Pandoc 或一个好的 Markdown 文本编辑器),就会显示为加粗。
Markdown 最大的优点之一是它的大部分符号都是直观的,并且来自我们大多数人已有的习惯。它使得用星号强调单词,用字符标记标题以区分它们等等变得很自然。
每个人都对它评价很高,但我不确定为什么我需要学习和使用 Markdown。然而我是一个好奇的人我开始探索 Markdown以及它如何在我的写作中发挥作用。
### 学习 Markdown
我很喜欢在学习时使用 [Markdown 速查表][2]。我发现 Markdown 是一个很好的工具,可以写任何内容,而且我很喜欢甚至不需要一个专门的 Markdown 编辑器这一点。任何文本编辑器都可以写 Markdown因为 Markdown 使用标准文本来表示样式。我开始使用简单的编辑器,如 Vim 或 gedit或任何其他编辑器并查阅这个速查表以记住简单的格式化规则。
今年我一直在写日记,作为组织我的想法和学习更多关于 Markdown 的方法。我最近尝试了 [Ghostwriter][3] 文本编辑器,这是一个优秀的编辑器,有一些额外的 Markdown 特定功能。Markdown 现在已经变得非常流行了,许多编辑器都加入了语法高亮、提示和其他使 Markdown 编写变得容易的功能,或者将其作为重点。它们不是必须的功能,但当你拥有它们时,还是很好的。 
### 尝试 Mark Text
在阅读一个博客时,我发现了 [Mark Text][4]。Mark Text 使写 Markdown 变得很容易同时提供了一个简单的界面而且又不影响我。Mark Text 有六个主题,三个浅色和三个深色主题。深色主题对我来说更容易使用。它的 [用户文档][5] 非常好,而且也提供了 Markdown 的 [语法帮助][6]。 
### Markdown 的实时预览
Mark Text 以简洁的界面提供了实时预览功能。它支持 [Commonmark][7] 规范、Github 风格的 Markdown 规范,以及 Pandoc Markdown。据其网站说Mark Text 还支持 KaTex、front matter 和 emoji 等 Markdown 扩展。它还可以输出 HTML 和 PDF 文件。 
Mark Text 有各种编辑模式,如打字模式、源代码模式和专注模式。添加图片是一件很容易的事,因为你可以简单地从剪贴板上复制和粘贴它们。
在 Mark Text 窗口的左上方有一个弹出窗口,显示迄今为止输入的字符和段落数量。作为一个作家,这真的很有帮助。
从 Mark Text 窗口左上方的菜单或使用 `Ctrl+S` 保存文件很容易。事实上Mark Text 的菜单对任何习惯于基本文本编辑器或文字处理器的人来说都是友好和熟悉的。
![Mark Text 文件菜单][8]
我喜欢 Mark Text 用简单的快捷键支持各种格式,包括表格块、图表、行内格式、数学公式块和其他代码块。
你可以从以下链接中为你的操作系统下载 Mark Text
* [Linux][10]
* [macOS][11]
* [Windows][12]
Mark Text 以 [MIT][13] 许可证开源。你可以随时 [下载][14] 最新的版本。
另外,你可以用 `brew install --cask mark-text` 在 macOS 上安装 Mark Text在 Windows 上用 [Chocolatey][15] 输入 `choco install marktext` 来安装它。
Mark Text 一直在寻找赞助商和开发者。该项目有一个给贡献者的 [指南][16]。此外,你可以在 Patreon 和 Open Collective 上支持该项目。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/mark-text-markdown-editor
作者:[Don Watkins][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/don-watkins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-docdish-typewriterkeys-3.png?itok=NyBwMdK_ (Typewriter keys in multicolor)
[2]: https://opensource.com/downloads/cheat-sheet-markdown
[3]: https://wereturtle.github.io/ghostwriter/
[4]: https://marktext.app/
[5]: https://github.com/marktext/marktext/blob/master/docs/README.md
[6]: https://github.com/marktext/marktext/blob/master/docs/MARKDOWN_SYNTAX.md
[7]: https://commonmark.org/
[8]: https://opensource.com/sites/default/files/uploads/mark-test-file-menu.png (Mark Text file menu)
[9]: https://creativecommons.org/licenses/by-sa/4.0/
[10]: https://github.com/marktext/marktext/releases/latest/download/marktext-x86_64.AppImage
[11]: https://github.com/marktext/marktext/releases/latest/download/marktext.dmg
[12]: https://github.com/marktext/marktext/releases/latest/download/marktext-setup.exe
[13]: https://github.com/marktext/marktext/blob/develop/LICENSE
[14]: https://github.com/marktext/marktext/releases
[15]: https://chocolatey.org/
[16]: https://github.com/marktext/marktext/blob/develop/CONTRIBUTING.md

View File

@@ -0,0 +1,102 @@
[#]: subject: "GitUI: A Blazing Fast Terminal Client for Git Written in Rust"
[#]: via: "https://itsfoss.com/gitui/"
[#]: author: "Marco Carmona https://itsfoss.com/author/marco/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13922-1.html"
GitUI: 用 Rust 编写的 Git 的快速命令行客户端
======
![](https://img.linux.net.cn/data/attachment/album/202110/26/111605achvngqr6ix6vv0p.jpg)
[基本的 Git 命令][1] 对于通常的克隆、添加、提交推送已经足够好了。
但如果你在一个有多个贡献者的大型项目上工作你可能需要将事情可视化。GUI 工具可以让你更好地了解 `diff``stash``blame` 的情况。
但是,如果你常用终端,又想要 Git 的舒适性,我为你准备了一个好工具。
它叫 GitUI它提供了类似于 Git GUI 的用户体验和舒适度,但就在你的终端中。它是可移植的、快速的、自由而开源的。
### GitUI一个基于终端的 Git 工具
[GitUI][2] 并不是第一个用于 Linux 终端的 Git 客户端。那么,是什么让 GitUI 与其他类似项目如 [lazygit][3] 或 [tig][4] 不同?
GitUI 的开发者在项目的 README 文件中分享了一些基准数据。
名称 | 时间 |内存GB| 二进制MB| 冻结 | 崩溃
---|---|---|---|---|---
gitui | 24 s | 0.17 | 1.4 | 否 | 否
lazygit | 57 s | 2.6 | 16 | 是 | 有时
tig | 4 m 20 s | 1.3 | 0.6 | 有时 | 否
*GitUI、LazyGit 和 Tig 之间的比较。*
这种优化大部分来自于 Rust 语言的使用。
**注意:该程序处于早期开发阶段,还没有为生产做好准备。**
### 在 Linux 上安装 GitUI
不用说,你应该已经 [在你的系统上安装了 Git][5]。
要使用 GitUI首先需要 [为你的 Linux 发行版安装 Rust 支持][6]。
在终端中,使用以下命令:
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
![Installing Rust on Linux][7]
当你被要求选择时,请选择选项 1。当脚本完成安装后用这个命令正确设置配置
```
source $HOME/.cargo/env
```
现在你已经安装了 Rust 和它的包管理器 Cargo使用 Cargo 命令来安装 GitUI
```
cargo install gitui
```
然后你就可以使用 GitUI了只需在终端输入 `gitui` 就可以运行了。我做了一些示例文件来测试 Git 和 GitUI。
![Starting gitui on terminal][8]
值得一提的是,这个界面有一个快速而直观的纯键盘控制。一切都很简单,只需输入正确的字母即可将文件暂存、提交、分支或推送到 git 仓库中。
真正让我兴奋的是,你不仅可以做之前的四个动作,还可以**编辑**每个文件,**拉取**它,**追溯** 它,在其中**导航**等等,这一切都无需退出界面。 很棒,不是吗?
![More functions inside the interface][9]
祝贺你! 现在你知道了如何安装 GitUI 以及它在你的终端中的样子。
如果你喜欢这个项目,请在 [GitHub][2] 上点赞它的仓库。如果你使用其他工具来管理 Git请在评论区提出你的建议。
--------------------------------------------------------------------------------
via: https://itsfoss.com/gitui/
作者:[Marco Carmona][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/marco/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/basic-git-commands-cheat-sheet/
[2]: https://github.com/Extrawurst/gitui
[3]: https://github.com/jesseduffield/lazygit
[4]: https://jonas.github.io/tig/
[5]: https://itsfoss.com/install-git-ubuntu/
[6]: https://itsfoss.com/install-rust-cargo-ubuntu-linux/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/Installing-Rust-step-1.png?resize=800%2C471&ssl=1
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/Starting-GitUI-on-terminal.png?resize=800%2C471&ssl=1
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/More-functions-inside-the-interface.png?resize=800%2C471&ssl=1

View File

@@ -0,0 +1,174 @@
[#]: subject: "How to Install Rust and Cargo on Ubuntu and Other Linux Distributions"
[#]: via: "https://itsfoss.com/install-rust-cargo-ubuntu-linux/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "perfiffer"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13938-1.html"
如何在 Ubuntu 和其它的 Linux 发行版安装 Rust 和 Cargo
======
> 了解在 Linux 上安装 Rust 编程语言及其包管理器 Cargo 的各种方法。
![](https://img.linux.net.cn/data/attachment/album/202110/31/150031j9e0xgeg9jpxeip0.jpg)
自从 Mozilla 贡献了 [Rust][1] 语言之后,它就获得了更加突出和受欢迎的地位。口说无凭。[Rust 将被使用在 Linux 内核中][2],它是继 C 语言之后的第二种编程语言。
许多开发人员也开始使用 Rust 语言制作很棒的基于命令行的工具。这些工具通常可以通过 [Cargo 包管理器][3] 获得。
这就是为什么在 Linux 中安装 Rust 支持对程序员和最终用户都很重要的原因。
官方 Rust 文档建议通过以下这种方式下载并执行安装程序脚本在 Linux 中安装 Rust
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
这是可行的。但是,你的发行版可能已经打包了 Rust。使用你的发行版的 [包管理器][4] 也是一种选择。
让我向你介绍官方 Rust 方式和包管理器方式的 Rust 安装步骤。
### 方法1使用官方方法在任意的 Linux 上安装 Rust
这种方法有几个优点:
* 你可以获取最新的 Rust 和 Cargo 版本
* Rust 仅仅是为当前的用户安装,并不是所有用户
* 你并不需要 root 用户或者 `sudo` 权限就可以为自己安装 Rust
一些人不喜欢从互联网下载并 [运行 shell][5] 脚本,即使它来自官方。但是,由于它不需要 root 访问权限并且脚本来自官方,因此以这种方式安装它应该是安全的。
首先,确保你已经安装了 `curl`。如果没安装,使用你的发行版的包管理器安装它。你可以使用 `apt` 命令在 [Ubuntu 和 Debian 上安装 Curl][6]。
```
sudo apt install curl
```
接下来,使用这条命令下载脚本并运行它:
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
![][7]
它会询问你输入所需的安装类型。选择选项 `1`
![][8]
脚本完成安装后,你需要获取配置文件的来源,以使更改应用于你的 shell。
![][9]
应用文件:
```
source $HOME/.cargo/env
```
完成后,通过检查已安装的版本来验证 Rust 是否可用:
```
rustc --version
```
![Verifying Rust installation][10]
太酷了。如果 Rust 发布了新版本,你可以使用如下命令更新已安装的版本:
```
rustup update
```
在你看到其它安装方法之前,让我快速展示如何移除以这种方式安装的 Rust。
#### 删除以官方方式安装的 Rust
在终端中,使用如下的命令从系统中移除 Rust
```
rustup self uninstall
```
询问时按 `Y`,你将从系统中删除 Rust。
![Removing Rust from Linux][11]
官方方式安装已经完成。让我们看看如何使用 `apt` 命令在 Ubuntu 上安装 Rust。
### 方法2使用 apt 命令在 Ubuntu 上安装 Rust
为什么要使用包管理器?
* 它在整个系统范围内安装 Rust可供系统上的所有用户使用
* 它与其它系统更新一起集中更新(如果你的发行版添加了新版本的 Rust
Ubuntu 中有两个主要的 Rust 包:
* `rustc`:用于 Rust 编程语言的 Rust 编译器
* `cargo`Cargo 是 Rust 的包管理器,它会自动安装 `rustc`
作为一个普通用户,你将使用 Cargo 来安装基于 Rust 的应用程序。作为程序员,你需要 Cargo 来获取其它 Rust 包或创建自己的包。
由于 `cargo` 包含 `rustc`,所以我建议安装它,以便一次性安装所有必需的软件包。
```
sudo apt install cargo
```
系统会要求你输入账号密码。
![][12]
当然,你可以自由使用 `apt install rustc`,只安装 Rust。这取决于你的选择。
你可以验证是否为你和所有其他用户安装了 Rust如果你愿意
![][13]
很好。让我也快速展示卸载步骤。
#### 使用 apt remove 移除 Rust
要移除 Rust你可以先移除 Cargo然后使用 `autoremove` 命令移除随它安装的依赖项。
```
sudo apt remove cargo
```
现在运行 `autoremove`
```
sudo apt autoremove
```
就是这样。你现在了解了在 Ubuntu 和其它 Linux 发行版上安装 Rust 的所有基本知识。随时欢迎提出问题和建议。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-rust-cargo-ubuntu-linux/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[perfiffer](https://github.com/perfiffer)
校对:[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://www.rust-lang.org/
[2]: https://www.zdnet.com/article/rust-in-the-linux-kernel-why-it-matters-and-whats-happening-next/
[3]: https://crates.io/
[4]: https://itsfoss.com/package-manager/
[5]: https://itsfoss.com/run-shell-script-linux/
[6]: https://itsfoss.com/install-curl-ubuntu/
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/installing-rust-linux-1.png?resize=800%2C448&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/installing-rust-linux-2.png?resize=800%2C448&ssl=1
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/installing-rust-linux-3.png?resize=800%2C448&ssl=1
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/verify-rust-version.png?resize=800%2C236&ssl=1
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/remove-rust-linux.png?resize=800%2C378&ssl=1
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/install-rust-using-apt-ubuntu.png?resize=759%2C481&ssl=1
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/verify-rust-install-ubuntu.png?resize=741%2C329&ssl=1

View File

@@ -0,0 +1,133 @@
[#]: subject: "How to Convert a Webpage to PDF in Linux"
[#]: via: "https://itsfoss.com/convert-webpage-pdf-linux/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13928-1.html"
如何在 Linux 下将网页转换为 PDF 文件
======
![](https://img.linux.net.cn/data/attachment/album/202110/28/111738tncncbml6jwcz6s8.jpg)
当你将某些资源存档或用于教育目的时,将网页保存为 PDF 是很方便的。
但是,你如何在 Linux 中把一个网页转换成 PDF
你可以选择使用每个 Linux 发行版上的网页浏览器GUI或者使用终端将网页变成 PDF 文件。
在这里,我将提到这两种方法来帮助你完成工作。
### 方法 1使用网页浏览器将网页转换为 PDF 文件
尽管我在本教程中使用的是 Mozilla Firefox但你也可以用任何 [可用于 Linux 的最佳浏览器][1] 做同样的事情。
![][2]
1、加载你想转换的网页。
2、在浏览器菜单中找到“**打印**”选项,或使用键盘快捷键 `Ctrl + P`
3、默认情况下它应该让你把它保存为 PDF。你需要点击“保存”然后选择目的地并保存网页。
![Save webpage as PDF in Mozilla Firefox][3]
这种简单方法的一个主要问题是,它包括页面上的所有元素。这可能包括评论、页脚等。你可以用一个 PDF 编辑器来删除部分内容,但这是一个额外的任务。
更好的选择是利用一个浏览器扩展,如 [Print Friendly][4]。它允许你在下载 PDF 之前编辑和删除网页的部分内容。
### 方法 2使用终端将网页转换为 PDF 或图片
你可能已经知道,你可以 [在 Linux 终端浏览互联网][5],甚至 [使用命令行下载文件][6]。这并不奇怪,因为你可以在终端中做更多的事情,包括将网页下载为 PDF。
一个灵巧的开源命令行工具 `wkhtmltopdf``wkhtmltoimage` 可以帮到你,让你把任何 HTML 网页转换成 PDF 或图像文件。
它使用 Qt WebKit 渲染引擎来完成这个任务。你可以浏览它的 [GitHub页面][7] 了解更多信息。
你应该能够从你的 Linux 发行版的默认仓库中安装它。对于基于 Ubuntu 的发行版,你可以输入以下命令:
```
sudo apt install wkhtmltopdf
```
无论你想把它转换为 PDF 还是图像文件,它的使用都是非常直接的:
![][8]
要将一个网页转换成 PDF请输入
```
wkhtmltopdf URL/domain filename.pdf
```
比如,类似于这样:
```
wkhtmltopdf linuxmint.com mint.pdf
```
你可以选择使用 `https://linuxmint.com` 这样完整的 URL 或使用域名,如上面的例子所示。
默认情况下,生成的文件将保存在主目录下。
在转换网页时,你还可以得到一些好玩的选项。
例如,你可以**对 PDF 文件应用灰度过滤器**,在同一文件中**制作多个页面副本**,以及在转换过程中**排除**图像。
灰度过滤器不一定对每个网页都有效,但你可以用命令试试:
```
wkhtmltopdf -g google.com googlepage.pdf
```
要在同一个 PDF 文件中复制多个页面,命令是:
```
wkhtmltopdf --copies 2 linuxmint.com mint.pdf
```
而且,如果你想排除网页中的图像,只需输入:
```
wkhtmltopdf --no-images linuxmint.com mint.pdf
```
此外,如果你想把一个网页转换为图像,命令是这样的:
```
wkhtmltoimage linuxmint.com mint.png
```
注意,与使用浏览器的 GUI 方法不同,通过终端使用这些工具有其局限性。它似乎不能成功转换利用任何 `<iframe>` 代码片段的网页。
像我们的网站,甚至 DuckDuckGo 都没有转换为 PDF 或图像。然而,简单的 HTML 网站,如 Linuxmint.com、Ubuntu.com、Google.com 则非常有效。
### 总结
使用浏览器将网页保存为 PDF 似乎是个好办法。但是,如果你想有更多的选择并通过终端,`wkhtmltopdf` 工具应该会派上用场。
你喜欢如何在 Linux 中把网页转换为 PDF欢迎在评论中分享你的想法。
--------------------------------------------------------------------------------
via: https://itsfoss.com/convert-webpage-pdf-linux/
作者:[Ankush Das][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/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-browsers-ubuntu-linux/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/mozilla-save-webpage-pdf.png?resize=800%2C536&ssl=1
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/mozilla-firefox-print-pdf-1.png?resize=602%2C584&ssl=1
[4]: https://www.printfriendly.com/
[5]: https://itsfoss.com/terminal-web-browsers/
[6]: https://itsfoss.com/download-files-from-linux-terminal/
[7]: https://github.com/wkhtmltopdf/wkhtmltopdf
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/htmltopdf-mint.png?resize=736%2C344&ssl=1

View File

@@ -0,0 +1,87 @@
[#]: subject: "MX Linux 21 Stable Release is Finally Here Introducing a Fluxbox Edition"
[#]: via: "https://news.itsfoss.com/mx-linux-21-release/"
[#]: author: "Omar Maarof https://news.itsfoss.com/author/omar/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13912-1.html"
MX Linux 21 稳定版发布
======
> 基于 Debian 的 MX Linux 21 现已经推出,带来了一些不错的改进。
![](https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/09/mx-linux-21-release-ft.png?w=1200&ssl=1)
[MX Linux][1] 是一个基于 Debian 的 Linux/GNU 发行版,旨在追求优雅、稳定和性能。
我们之前报道过它的 [尚处于测试阶段的新 Fluxbox 版][2],但现在稳定版出来了。让我们来探讨一下 MX Linux 21 “Wildflower” 的新内容。
### MX Linux 21 主要亮点
![][3]
MX Linux 21 基于 Debian 11 “Bullseye”运行 Linux 5.10LTS 内核。在这次的新更新中,你可以发现一些新的应用和对当前应用的升级。
![][4]
“Wildflower” 系列包括一个带有 Fluxbox 1.3.7 的新版本它可以使旧电脑重新焕发活力。补充一下Fluxbox 是一个窗口管理器,可以在高端计算机上无缝工作,但资源占用很少。
它的安装程序有一个新的分区选择区,支持 LVM逻辑卷管理器
![MX Linux 21 有一个漂亮的图形化安装程序][3]
当启动系统时,无论你是使用<ruby>临时启动<rt>live boot</rt></ruby>还是持久化使用,你都可以选择使用新的 UEFI 临时系统启动菜单,而不是旧的控制台菜单。
对于桌面环境Xfce 4.16 和 KDE Plasma 5.20 都是最新版本。
然而,还没有 Xfce 版。
它新提供的一个方便的工具是在管理任务中默认使用管理员密码。然而,如果你不需要它,你可以把它关掉。
### 其他改进
* 安装程序和临时系统已经更新到最新版本。
* 大部分的翻译仍在进行中。另一方面,有些部分的翻译工作完成的很好的。
* 默认软件包集现在包括 [Mesa Vulkan][5] 驱动。
* 对某些 Realtek 硬件的 Wi-Fi 有了更好的支持。
* 已默认启用 Debian 安全库。
* Xfce 有了一些改进,其中之一是为 Thunar 文件管理器增加了一个 samba 共享插件。
* KDE 对其文件管理器 Dolphin 进行了修复。
![][3]
### 总结
MX Linux 21 是它目前最新的稳定版本。更加优雅,性能更强,因此更加适合作为日常使用。
尽管与其他流行的选择相比MX Linux 是一个相对较新的 Linux/GNU 发行版,但它在提供一个由 Debian、MX 存储库和 [antiX Linux][6] 支持的完整操作系统方面有很大的潜力。
你可以参考 [官方公告][7] 了解更多细节。
- [下载 MX Linux 21][8]
你对这个版本有什么看法?你碰巧在使用 MX Linux 吗?请在下面的评论中分享你的想法。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/mx-linux-21-release/
作者:[Omar Maarof][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://news.itsfoss.com/author/omar/
[b]: https://github.com/lujun9972
[1]: https://mxlinux.org/
[2]: https://news.itsfoss.com/mx-linux-21-fluxbox-beta-release/
[3]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/09/MX_Linux_21-1.png?w=1366&ssl=1
[4]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/mx-linux-21-fluxbox.png?w=902&ssl=1
[5]: https://www.mesa3d.org/
[6]: https://antixlinux.com/
[7]: https://mxlinux.org/blog/mx-21-wildflower-released/
[8]: https://mxlinux.org/download-links/

View File

@@ -0,0 +1,115 @@
[#]: subject: "How to Install themes on Xubuntu and Other Distros Using Xfce Desktop Environment"
[#]: via: "https://itsfoss.com/install-themes-xfce-xubuntu/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13932-1.html"
如何在使用 Xfce 桌面环境的 Xubuntu 上安装主题
======
![](https://img.linux.net.cn/data/attachment/album/202110/29/103958hrv6vruu163zrtvr.png)
> 这是一个循序渐进的初学者教程,展示了如何在 Xubuntu 和其他使用 Xfce 桌面环境的 Linux 发行版中安装主题和图标。
在 Xubuntu 上安装主题与 Ubuntu 或其他 Linux 发行版类似。你把主题文件放在 `~/.themes` 文件夹中,然后用一个工具来改变它。
然而,考虑到 Xubuntu 使用 [Xfce 桌面环境][1],一些选项或用户界面看起来会有所不同。这就是为什么我创建了这个教程,用适当的截图来展示步骤。
### 在 XubuntuXfce中安装新主题
开始前,你需要在主目录下创建一个 `.themes` 文件夹。注意文件夹名称前的点(`.`)。它很重要,可以从正常的视图中隐藏该文件夹。
要检查你是否已经有了它,你可以 [启用查看隐藏文件][2],然后在它不存在的时候创建它。
![][3]
完成后,你需要下载一个主题。
1、你可以在 [Xfce-look][4] 门户网站上浏览 XFCE 主题。你所要做的就是下载存档(压缩)文件。
2、接下来你需要 [解压缩文件][5],如下面的截图所示。
![][6]
3、解压后你会发现出现一个文件夹你要复制它。
![][7]
4、然后你要把这个文件夹粘贴到你最初创建的 `.themes` 目录中。
![][8]
5、最后你需要到外观设置中找到它并选择它/应用它以使其生效。
![][9]
正如你在下面的截图中注意到的,新的主题已经被添加和应用:
![][10]
除了主题之外,如果你需要定制你的 Xubuntu 桌面的图标,你需要在主目录中创建另一个 `.icons` 文件夹。
就像你安装主题一样,你将不得不遵循一个类似的过程来应用图标主题。
为了给你一个例子,让我在这里强调这些步骤:
### 在 XubuntuXfce 中添加图标主题
你可以浏览同样的 [xfce-look portal][11] 来寻找完整的图标主题。
或者,你可以寻找一些最好的 [可用于 Ubuntu 的图标主题][12],它们应该也适用于 Xubuntu。
一旦你找到了你喜欢的,就下载它,并按下面的方式解压。
![][13]
接下来,你需要把这个文件夹复制并粘贴到 `.icons` 文件夹中。
![][14]
现在,你可以回到外观设置中,找到列在“图标”下的可用图标。
为了向你展示区别,**我把默认的 Xubuntu 主题改为 adwaita-dark**,你可以在这里看到:
![][15]
**注意**:一些图标或主题文件可能包含有不同变体的嵌套文件夹。你会注意到它们并没有出现在外观工具中。如果是这种情况,直接将内部文件夹复制到 `~/.themes``~/.icons` 文件夹中。
### 总结
通过对风格和图标的调整,你可以 [定制你的 Xubuntu 体验][16] 以融入你的品味。
你是喜欢默认的 Xubuntu 外观还是使用不同的主题/图标来定制它的外观?请在评论中告诉我你的想法。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-themes-xfce-xubuntu/
作者:[Ankush Das][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/ankush/
[b]: https://github.com/lujun9972
[1]: https://xfce.org/
[2]: https://itsfoss.com/hide-folders-and-show-hidden-files-in-ubuntu-beginner-trick/
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/xubuntu-hidden-files.png?resize=674%2C300&ssl=1
[4]: https://www.xfce-look.org/browse?cat=138&ord=latest
[5]: https://itsfoss.com/unzip-linux/
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/extract-xubuntu-theme.png?resize=719%2C537&ssl=1
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/extracted-xubuntu-theme.png?resize=709%2C272&ssl=1
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/copy-theme-xubuntu.png?resize=705%2C328&ssl=1
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/appearance-xfce.png?resize=703%2C544&ssl=1
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/xpro-xubuntu-theme.png?resize=1162%2C599&ssl=1
[11]: https://www.xfce-look.org/browse?cat=132&ord=latest
[12]: https://itsfoss.com/best-icon-themes-ubuntu-16-04/
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/xubuntu-icon-theme.png?resize=756%2C560&ssl=1
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/xubuntu-icon-theme-selection.png?resize=739%2C534&ssl=1
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/xubuntu-icon-theme-change.png?resize=1154%2C619&ssl=1
[16]: https://itsfoss.com/customize-xfce/

View File

@@ -0,0 +1,280 @@
[#]: subject: "Use Rust for embedded development"
[#]: via: "https://opensource.com/article/21/10/rust-embedded-development"
[#]: author: "Alan Smithee https://opensource.com/users/alansmithee"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13921-1.html"
使用 Rust 进行嵌入式开发
======
> Rust 的高性能、高可靠性和高生产力使它适合于嵌入式系统。
![](https://img.linux.net.cn/data/attachment/album/202110/26/103848djcdhjk0d2z1hc52.jpg)
在过去的几年里Rust 在程序员中获得了热情的追捧。技术潮流来来去去,所以很难将仅仅因为某项新技术而产生的兴奋与对某项技术的优点的兴奋区分开来,但我认为 Rust 是一种真正设计良好的语言。它的目标是帮助开发者建立可靠和高效的软件,而且它从一开始就是为这个目的设计的。你可能听过一些 Rust 的关键特性,在这篇文章中,我会证明这些特性正是 Rust 也恰好适合嵌入式系统的原因。比如:
* 高性能:它速度快,内存利用率高
* 可靠性:在编译过程中可以消除内存错误
* 生产力:很棒的文档,友好的编译器,有用的错误信息,以及一流的工具化。它有一个集成的包管理器和构建工具,智能的多编辑器支持自动补完和类型检查、自动格式化等等。
### 为什么使用 Rust 进行嵌入式开发?
Rust 的设计是为了保证安全和高性能。嵌入式软件会出现的问题主要是内存的问题。从某种程度上说Rust 是一种面向编译器的语言,所以你可以确保在编译时安全使用内存。以下是使用 Rust 在嵌入式设备上开发的一些好处:
* 强大的静态分析
* 灵活的内存
* 无畏的并发性
* 互操作性
* 可移植性
* 社区驱动
在这篇文章中,我使用开源的 [RT-Thread 操作系统][2] 来演示如何使用 Rust 进行嵌入式开发。
### 如何在 C 语言中调用 Rust
在 C 代码中调用 Rust 代码时,你必须将 Rust 源代码打包成静态库文件。当 C 代码编译时,将其链接进去。
#### 用 Rust 创建一个静态库
在这个过程中,有两个步骤:
1、使用 `cargo init --lib rust_to_c` 在 Clion 中建立一个 `lib` 库。在 `lib.rs` 中加入以下代码。下面的函数计算两个类型为 `i32` 的值的总和并返回结果:
```
#![no_std]
use core::panic::PanicInfo;
#[no_mangle]
pub extern "C" fn sum(a: i32, b: i32) -> i32 {
a + b
}
#[panic_handler]
fn panic(_info:&PanicInfo) -> !{
loop{}
}
```
2、在你的 `Cargo.toml` 文件中添加以下代码,以告诉 Rustc 要生成什么类型的库:
```
[lib]
name = "sum"
crate-type = ["staticlib"]
path = "src/lib.rs"
```
#### 交叉编译
你可以针对你的目标平台进行交叉编译。假设你的嵌入式系统是基于 Arm 的,步骤很简单:
```
$ rustup target add armv7a-none-eabi
```
生成静态库文件:
```
$ cargo build --target=armv7a-none-eabi --release --verbose
Fresh rust_to_c v0.1.0
Finished release [optimized] target(s) in 0.01s
```
#### 生成头文件
你也需要头文件:
1、安装 [cbindgen][3]。`cbindgen` 工具会从 Rust 库中生成一个 C 或 C++11 的头文件:
```
$ cargo install --force cbindgen
```
2、在你的项目文件夹下创建一个新的 `cbindgen.toml` 文件。
3、生成一个头文件
```
$ cbindgen --config cbindgen.toml --crate rust_to_c --output sum.h
```
#### 调用 Rust 库文件
现在你可以对你的 Rust 库进行调用了。
1、把生成的 `sum.h``sum.a` 文件放到 `rt-thread/bsp/qemu-vexpress-a9/applications` 目录下。
2、修改 `SConscript` 文件并添加一个静态库:
```
   from building import *
   
   cwd     = GetCurrentDir()
   src     = Glob('*.c') + Glob('*.cpp')
   CPPPATH = [cwd]
   
   LIBS = ["libsum.a"]
   LIBPATH = [GetCurrentDir()]
   
   group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, LIBS = LIBS, LIBPATH = LIBPATH)
   
   Return('group')
```
3、在主函数中调用 `sum` 函数,得到返回值,并 `printf` 该值:
```
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtthread.h>
#include "sum.h"
int main(void)
{
int32_t tmp;
tmp = sum(1, 2);
printf("call rust sum(1, 2) = %d\n", tmp);
return 0;
}
```
4、在 RT-Thread [Env][4] 环境中,使用 `scons` 来编译项目并运行:
```
$ scons -j6
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
[...]
scons: done building targets.
$ qemu.sh
\ | /
- RT - Thread Operating System
/ | \ 4.0.4 build Jul 28 2021
2006 - 2021 Copyright by rt-thread team
lwIP-2.1.2 initialized!
[...]
call rust sum(1, 2) = 3
```
### 加、减、乘、除
你可以在 Rust 中实现一些复杂的数学运算。在 `lib.rs` 文件中,使用 Rust 语言来实现加、减、乘、除:
```
#![no_std]
use core::panic::PanicInfo;
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
#[no_mangle]
pub extern "C" fn subtract(a: i32, b: i32) -> i32 {
a - b
}
#[no_mangle]
pub extern "C" fn multiply(a: i32, b: i32) -> i32 {
a * b
}
#[no_mangle]
pub extern "C" fn divide(a: i32, b: i32) -> i32 {
a / b
}
#[panic_handler]
fn panic(_info:&PanicInfo) -> !{
loop{}
}
```
构建你的库文件和头文件,并把它们放在应用程序目录中。使用 `scons` 来编译。如果在链接过程中出现错误,请在官方 [Github 页面][5] 中找到解决方案。
修改 `rtconfig.py` 文件,并添加链接参数 `--allow-multiple-definition`
```
DEVICE = ' -march=armv7-a -marm -msoft-float'
CFLAGS = DEVICE + ' -Wall'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ -I.'
LINK_SCRIPT = 'link.lds'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors,--allow-multiple-definition'+\
' -T %s' % LINK_SCRIPT
CPATH = ''
LPATH = ''
```
编译并运行 QEMU 来看看你的工作。
### 在 Rust 中调用 C 语言
Rust 可以在 C 代码中调用,但是如何在你的 Rust 代码中调用 C 呢?下面是一个在 Rust 代码中调用 `rt_kprintf` C 函数的例子。
首先,修改 `lib.rs` 文件:
```
// The imported rt-thread functions list
extern "C" {
pub fn rt_kprintf(format: *const u8, ...);
}
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
unsafe {
rt_kprintf(b"this is from rust\n" as *const u8);
}
a + b
}
```
接下来,生成库文件:
```
$ cargo build --target=armv7a-none-eabi --release --verbose
Compiling rust_to_c v0.1.0
Running `rustc --crate-name sum --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type staticlib --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no -C metadata=a
Finished release [optimized] target(s) in 0.11s
```
而现在,要运行代码,将 Rust 生成的库文件复制到应用程序目录中,然后重新构建:
```
$ scons -j6 scons: Reading SConscript files ... scons: done reading SConscript files. [...]
scons: Building targets ... scons: done building targets.
```
再次运行 QEMU可以在你的嵌入式镜像中看到结果。
### 你可以拥有这一切
在你的嵌入式开发中使用 Rust你可以获得 Rust 的所有功能,而不需要牺牲灵活性或稳定性。今天就在你的嵌入式系统上试试 Rust 吧。关于嵌入式 Rust 的过程(以及 RT-Thread 本身)的更多信息,请查看 RT-Thread 项目的 [YouTube 频道][6]。请记住,嵌入式也可以是开放的。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/rust-embedded-development
作者:[Alan Smithee][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/alansmithee
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rust_programming_crab_sea.png?itok=2eWLz8A5 (Ferris the crab under the sea, unofficial logo for Rust programming language)
[2]: https://github.com/RT-Thread/rt-thread
[3]: https://github.com/eqrion/cbindgen
[4]: https://www.rt-thread.io/download.html?download=Env
[5]: https://github.com/rust-lang/compiler-builtins/issues/353
[6]: https://www.youtube.com/channel/UCdDHtIfSYPq4002r27ffqP

View File

@@ -0,0 +1,118 @@
[#]: subject: "Fixing “Unable to acquire dpkg frontend lock. Are You Root?” Error on Ubuntu and Other Linux Distributions"
[#]: via: "https://itsfoss.com/fixed-are-you-root-error/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13936-1.html"
修复在 Ubuntu 上 “Unable to acquire dpkg frontend lock. Are You Root?” 的错误
======
![](https://img.linux.net.cn/data/attachment/album/202110/30/092452w21q1lyl1ntyy7t3.jpg)
我假设你对 Linux 很陌生。
你按照网上的一些教程,告诉你要安装某个程序或运行某个命令。可能是与服务器有关的东西。
但当你运行这个命令时,你遇到了这个错误:
```
E: Could not open lock file /var/lib/dpkg/lock-frontend open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
```
或者类似的错误:
```
dpkg: error: required read/write access to the dpkg database directory /var/lib/dpkg
E: Sub-process dpkg set-selections returned an error code (2)
E: Executing dpkg failed. Are you root?
```
这两个错误都在问你同一个问题:你是 root 吗?而这就是这个问题的答案。成为 root。
### 成为 root 以避免这个错误
你如何 [在 Ubuntu][1] 或 Debian 中成为 root你使用 `sudo` 命令。
是的,就是这样。无论你在运行什么命令,只要在它前面加上 `sudo` 即可。
```
sudo your_command
```
![Running command with sudo][2]
它将要求你输入你的用户账户密码。请记住,当你输入密码时,屏幕上不会显示任何东西,这也没关系。
你的系统没有任何问题。在大多数 Linux 系统中,输入密码时不会显示通常的星号或其他东西是一种“安全特性”。
只要输入密码,并在密码后按下回车键即可。如果密码输入正确,你现在应该可以运行该命令了。
你甚至可以使用这个方便的 [Linux 命令行技巧][3],用 `sudo` 运行以前的命令:
```
sudo !!
```
这很简单,而且立即生效,除非你没有 sudo 权限。然后,你会看到一个不同的错误。
### 看到一个 “User is not in sudoer file” 的错误?
![Some users cannot run commands with sudo][4]
当你 [安装 Ubuntu][5] 时,你必须创建一个用户账户。这个用户被自动授予 `sudo` 权限,在需要时以 root 身份运行命令。
这发生在 Ubuntu 桌面上,而不是服务器上。大多数服务器发行版会有一个单独的 root 账户。如果你单独创建了一个普通账户,你就必须把这个用户添加到 `sudoer` 中,以便这个普通用户可以使用 `sudo`
在上面的截图中,我已经创建了这个额外的用户,但没有将其添加到 sudo 组中。这意味着这里的用户 `prakash` 没有使用 `sudo` 命令的权限,因此系统抱怨 “prakash is not in sudoers file”。
#### 该事件在哪里报告?
错误的 `sudo` 尝试会被添加到系统日志中。它记录了用户名、虚拟终端号、运行命令的位置和运行的命令。
![Incorrect sudo attempts are logged into the system][6]
这些日志的位置在不同的发行版中有所不同。
通常,在 Ubuntu 中你可以在 `journalctl` 日志或 `/var/log/auth.log` 文件中找到它,在 Fedora 中可以在 `/var/log/audit/audit.log` 文件中找到它。
#### 如果一个用户不在 sudoer 列表中,你能做什么?
当你不能用当前的用户账户使用 `sudo` 时,你能做什么?首先,[验证该用户是否有 sudo 权限。如果没有,你可以有一些选择][7]
* 以 root 身份登录或切换 root 身份(如果你有 root 密码)。
* [将该用户加入 sudoer 列表][8] (如果你有其他用户账户的管理或 `sudo` 权限)。
* 如果你在多用户的 Linux 系统中,自己没有 root 或 `sudo` 权限,请你的系统管理员授予你的用户 sudo 权限或安装你想安装的应用。
### 这有帮助吗?
`sudo` 是一个非常全面的安全机制,它不仅仅是允许一个普通用户成为 root。它有助于对系统进行审计了解哪个用户用 `sudo` 运行了哪个命令。它还可以被配置为只允许某个用户用 `sudo` 运行某些命令。
你不会在桌面 Linux 上看到如此细化的 `sudo` 配置,在桌面 Linux 上,它被预先配置为允许 `sudo` 组中的任何用户以 `root` 的身份运行任何命令。关于 `sudo` 的更多信息,请参见其他文章。
我希望在解决这个经典的初学者问题时,你能对 `sudo` 命令有一些初步的了解。如果你对这个主题有进一步的问题,请在评论区告诉我。
--------------------------------------------------------------------------------
via: https://itsfoss.com/fixed-are-you-root-error/
作者:[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://itsfoss.com/root-user-ubuntu/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/running-commands-with-sudo.webp?resize=800%2C450&ssl=1
[3]: https://itsfoss.com/linux-command-tricks/
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/not-in-sudoer-file-error-800x289.png?resize=800%2C289&ssl=1
[5]: https://itsfoss.com/install-ubuntu/
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/sudo-incident-reported.png?resize=800%2C339&ssl=1
[7]: https://linuxhandbook.com/check-if-user-has-sudo-rights/
[8]: https://linuxhandbook.com/create-sudo-user/

View File

@@ -0,0 +1,112 @@
[#]: subject: "Raspberry Pi Zero 2 W is Here!"
[#]: via: "https://news.itsfoss.com/raspberry-pi-zero-2-w-launch/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13931-1.html"
树莓派 Zero 2 W 来了!
======
> 树莓派 Zero W 的继任者来了!仅售 15 美元,它包括一些承诺的升级和改进。
![](https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/raspberry-pi-zero-2-w-ft.png?w=1200&ssl=1)
树莓派 Zero W 是最实惠的包括了无线和蓝牙连接的单板计算机之一。
虽然 [树莓派 Zero 与树莓派 Zero W][1] 之间有一些区别,但考虑到它们分别以 5 美元和 10 美元的价格推出,两者都是靠谱的选择。
现在,树莓派在大约 6 年后推出了这个系列的继任者,即树莓派 Zero 2 W售价为 **$15**。
即使 [树莓派提高了价格][2],我想说 15 美元买一块改进了多线程性能的新一代电路板应该是个不错的选择。
让我们来看看它有什么优点和新的东西。
### 树莓派 Zero 2 W 的规格
![][3]
树莓派 Zero 2 W 使用了在树莓派 3 发布版中使用的相同芯片。
虽然频率略微降低到了 1GHz它仍然能够保证其性能是原来树莓派 Zero 的 5 倍。
下面是它的规格:
* 博通 BCM2710A1四核 64 位SoCArm Cortex-A53 @ 1GHz
* 512MB LPDDR2 SDRAM
* 2.4GHz IEEE 802.11b/g/n 无线网络、蓝牙 4.2BLE
* 1×USB 2.0 接口,带 OTG
* 与 HAT 兼容的 40 针 I/O 针脚
* MicroSD 卡插槽
* mini HDMI 接口
* 复合的视频和复位引脚焊点
* CSI-2 相机连接器
* H.264MPEG-4 解码1080p30H.264 编码1080p30
* OpenGL ES 1.12.0 图形
看看这些规格,考虑到它的外形尺寸,它足够令人印象深刻。不要忘了,他们增加了更多的铜覆层来处理升级后的处理器产生的热量。
![][4]
此外,无线电路是用金属屏蔽密封的,这应该使它容易用于商业终端产品。
![video][5]
如果你已经有了树莓派 Zero 的外壳,那么它应该很有可能适用于 Zero 2 W。
根据 [官方公告][6],树莓派提到:
> 与 Zero 相比,确切的性能提升因工作负载而异,但对于多线程的 [sysbench][7] 来说,它几乎正好是五倍的速度。
小巧的外形和性能的提升应该使它成为安全摄像机和许多其他物联网项目的理想板卡。你可以了解一下我们的 [树莓派 Zero W 的 DIY 项目][8] 清单,看看有什么灵感。
### 一个新的 USB 电源
![][9]
除了新的电路板,树莓派还推出了一个改进的 USB 电源,峰值电流为 2.5A。
该电源配备了一个 micro USB 接口,而不是 USB-C。尽管这不是为新的 Zero 2 W 准备的,而是为树莓派 3B 或 3B+ 准备的。
### 可用性 & 价格
![][10]
树莓派基金会已经澄清,他们在 2026 年 1 月之前不会停产树莓派 Zero 和 Zero W。
因此,如果你想省钱做实验,你可以继续使用旧板。
新的 Zero 2 W 将在官方经销商处以 15 美元的价格出售。目前供货范围仅限于英国、欧盟、美国、加拿大和香港。
它应该在 11 月在澳大利亚和新西兰上市,在接下来的几个月里会有更多国家加入。
- [树莓派 Zero 2 W][11]
你对最新的微型树莓派 Zero 2 W 有什么看法?欢迎在下面的评论中分享你的想法。
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/raspberry-pi-zero-2-w-launch/
作者:[Ankush Das][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://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/raspberry-pi-zero-vs-zero-w/
[2]: https://news.itsfoss.com/raspberry-pi-price-hike/
[3]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/Raspberry-Pi-Zero-2-W.jpg?w=800&ssl=1
[4]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/raspberry-pi-zero-2-w-wireless.jpg?w=800&ssl=1
[5]: https://youtu.be/V2frBYX62LU
[6]: https://www.raspberrypi.com/news/new-raspberry-pi-zero-2-w-2/
[7]: https://github.com/akopytov/sysbench
[8]: https://itsfoss.com/raspberry-pi-zero-projects/
[9]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/rp-power-supply.png?w=800&ssl=1
[10]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/Raspberry-Pi-Zero-2-W-Lifestyle.jpg?w=800&ssl=1
[11]: https://www.raspberrypi.com/products/raspberry-pi-zero-2-w/

View File

@@ -0,0 +1,89 @@
[#]: subject: "Microsoft Edge Stable Build is Now Available to Download for Linux"
[#]: via: "https://news.itsfoss.com/microsoft-edge-stable-release/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13935-1.html"
现可下载微软 Edge 的 Linux 稳定版了
=====
![](https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/microsoft-edge-beta-linux-ft.png?w=1200&ssl=1)
> 微软 Edge 的 Linux 最终版本终于亮相了。对于涉足 Linux 的 Windows 用户来说,这似乎是一个值得考虑的选择。
早在 5 月,[微软就启动了 Linux 版的 Edge 的公开测试][1]。
现在,就在正式宣布之前,其稳定版已经被推送到官方仓库。
![][2]
注意:微软 Edge 不是一个开源的浏览器,但它基于开源的组件。我们报道这个是因为它可以用于 Linux。
### 微软 Edge 的 Linux 版本:有什么值得喜欢的?
![][3]
微软 Edge 基于开源的 Chromium这一点并不奇怪。所以是的它只是又一个 [基于 Chromium 的 Linux 浏览器][4]。
然而,与谷歌 Chrome 浏览器相比,微软 Edge 提供了良好的用户体验和一些对 Windows 用户来说可能很方便的额外功能。
根据我在 Windows 10 上的经验,与谷歌 Chrome 浏览器相比,微软 Edge 似乎性能更好,但我还没有为此比较过任何基准。
那么,它对 Linux 是否有用?有什么理由让你去尝试吗?
当然,如果你不喜欢使用微软的服务,那就完全是另一回事了。但是,总的来说,微软 Edge 看起来是一个有前途的基于 Chromium 的浏览器,具有一些有用的功能。
一些可用于 Linux 的关键功能包括:
* 睡眠标签(以节省资源)
* 垂直标签
* 收藏
* 防止跟踪
![][5]
虽然它在配置你的微软账户时也支持家庭安全选项,但并不是每项功能都适用于 Linux。
此外,我没有发现可以派上用场的 Linux 的“儿童模式”。
而且,如果你在使用 Linux 的同时还使用其他桌面平台,微软 Edge 可以是跨平台冒险的一个好选择。
但如果你只想在 Linux 上试用它,你可能想在作出决定之前将它与其他浏览器进行比较。
### 下载微软 Edge Linux 版
想知道 [如何在 Linux 上安装微软 Edge 浏览器][6]?尽管 [微软 Edge 的官方网站][7] 没有列出 Linux 版本,但你可以在他们的官方资源库中找到它。
DEB 和 RPM 两种软件包都是可用的。你可以使用下面的链接下载这些软件包:
- [微软 Edge (deb)][8]
- [微软 Edge (rpm)][9]
Via: [Sophos][10]
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/microsoft-edge-stable-release/
作者:[Ankush Das][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://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://news.itsfoss.com/microsoft-edge-beta/
[2]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/microsoft-edge-download.png?w=829&ssl=1
[3]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/microsoft-edge-linux.png?w=1097&ssl=1
[4]: https://news.itsfoss.com/chrome-like-browsers-2021/
[5]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/10/microsoft-edge-linux-privacy.png?w=1277&ssl=1
[6]: https://itsfoss.com/microsoft-edge-linux/
[7]: https://www.microsoft.com/en-us/edge
[8]: https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/
[9]: https://packages.microsoft.com/yumrepos/edge/
[10]: https://nakedsecurity.sophos.com/2021/10/29/microsoft-edge-finally-arrives-on-linux-official-build-lands-in-repos/

View File

@@ -0,0 +1,194 @@
[#]: subject: "Print a Halloween greeting with ASCII art on Linux"
[#]: via: "https://opensource.com/article/21/10/ascii-linux-halloween"
[#]: author: "Jim Hall https://opensource.com/users/jim-hall"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13939-1.html"
在 Linux 上用 ASCII 艺术打印万圣节问候语
======
> 使用 Linux 或 FreeDOS 从一个 C 程序中生成彩色的 ASCII 艺术。
![FreeDOS 上的庆祝万圣节 ASCII 艺术][1]
利用扩展 ASCII 字符集和它的绘画元素集合的全彩 ASCII 艺术在 DOS 上曾经相当流行。你可以在你的下一个 FreeDOS 程序中加入 ASCII 艺术,作为一个很酷的“欢迎”屏幕,或者作为一个提供了更多程序信息的彩色“退出”屏幕,来增加一点视觉上的乐趣。
但是,这种 ASCII 艺术的风格并不仅仅局限于 FreeDOS 程序。你可以在 Linux 终端模式的程序中使用同样的方法。虽然 Linux 使用 [ncurses][2] 来控制屏幕,而不是 DOS 的 [conio][3],但相关的概念也适用于 Linux 程序。本文探讨了如何从 C 语言程序中生成彩色 ASCII 艺术。
### ASCII 艺术文件
你可以使用各种工具来绘制你的 ASCII 艺术。在这个例子中,我使用了一个叫做 TheDraw 的老式 DOS 应用程序,但是你可以在 Linux 上找到现代的开源 ASCII 艺术程序,比如 [Moebius][4]Apache 许可证)或者 [PabloDraw][5]MIT 许可证)。只要你知道保存的数据是什么样子的,你使用什么工具并不重要。
下面是一个 ASCII 艺术文件样本的一部分,以 C 源代码保存。请注意,这个代码片段定义了几个值。`IMAGEDATA_WIDTH``IMAGEDATA_DEPTH` 定义了屏幕上的列数和行数。在这里,它是一个 80x25 的 ASCII 艺术“图像”。`IMAGEDATA_LENGTH` 定义了 `IMAGEDATA` 数组中的条目数量。ASCII 艺术画面中的每个字符可以用两个字节的数据表示。要显示的字符和包含该字符的前景和背景颜色的颜色属性。对于一个 80x25 的屏幕,每个字符都与一个属性配对,该数组包含 4000 个条目(即 `80*25*2=4000`)。
```
#define IMAGEDATA_WIDTH 80
#define IMAGEDATA_DEPTH 25
#define IMAGEDATA_LENGTH 4000
unsigned char IMAGEDATA [] = {
    '.', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
    ' ', 0x08,  ' ', 0x08,  '.', 0x0F,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
    ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  '.', 0x0F,
    ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
    ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
```
数组的其它部分依此类推。
为了在屏幕上显示这种 ASCII 艺术,你需要写一个小小的程序来读取数组并以正确的颜色打印每个字符。
### 设置一个颜色属性
这个 ASCII 艺术文件中的颜色属性在一个字节中定义了背景和前景的颜色,用十六进制的值表示,如 `0x08``0x6E`。十六进制是适合表达这样的颜色“对”的紧凑方式。
像 Linux 上的 ncurses 或 DOS 上的 conio 这样的字符模式系统 [只能显示 16 种颜色][6]。这就是十六种可能的文本颜色和八种背景颜色。用二进制计算十六个值(从 0 到 15只需要四个二进制位。
> `1111` 是二进制的 15
而且方便的是,十六进制可以用一个字符表示 0 到 15`0``1``2``3``4``5``6``7``8``9``A``B``C``D``E``F`。所以十六进制的值 `F` 是数字 15或二进制的 `1111`
通过颜色对,你可以用一个八位的字节来编码背景和前景的颜色。这就是文本颜色的四个二进制位(十六进制中的 0 到 15 或 0 到 F和背景颜色的三个二进制位十六进制中的 0 到 7 或 0 到 E。字节中剩余的二进制位在这里没有使用所以我们可以忽略它。
为了将颜色对或属性转换成你的程序可以使用的颜色值,你需要 [使用位掩码][7],只指定用于文字颜色或背景颜色的位。使用 FreeDOS 上的 OpenWatcom C 编译器,你可以编写这个函数,从颜色属性中适当地设置颜色。
```
void
textattr(int newattr)
{
_settextcolor(newattr & 15); /* 0000xxxx */
_setbkcolor((newattr >> 4) & 7); /* 0xxx0000 */
}
```
`_settextcolor` 函数只设置文本颜色,`_setbkcolor` 函数设置背景颜色。两者都定义在 `graph.h` 中。注意,由于颜色属性在一个字节值中包括了背景色和前景色,`textattr` 函数使用 `&`(二进制的“与”运算)来设置一个位掩码,只隔离了属性中的最后四个位。这就是颜色对存储前景颜色的值 0 到 15 的地方。
为了得到背景色,该函数首先执行了一个位移,将位“推”到右边。这就把“上”位放到了“下”位范围,所以任何像 `0xxx0000` 这样的位都变成了 `00000xxx`。我们可以用另一个的位掩码 7二进制 `0111`)来挑选出背景颜色值。
### 显示 ASCII 艺术
`IMAGEDATA` 数组包含整个 ASCII 艺术屏幕和每个字符的颜色值。为了在屏幕上显示 ASCII 艺术,你的程序需要扫描该数组,设置颜色属性,然后一次在屏幕上显示一个字符。
让我们在屏幕的底部留出空间,以便向用户提供单独的信息或提示。也就是说,我不想显示一个 80 列 ASCII 屏幕的所有 25 行,而只想显示前 24 行。
```
/* print one line less than the 80x25 that's in there:
80 x 24 x 2 = 3840 */
for (pos = 0; pos < 3840; pos += 2) {
...
}
```
`for` 循环里面我们需要设置颜色然后打印字符。OpenWatcom C 编译器提供了一个函数 `_outtext` 来显示带有当前颜色值的文本。然而,这需要传递一个字符串,如果我们需要一个一个地处理每个字符,在一行中的每个字符需要不同颜色的情况下,效率就会很低。
相反OpenWatcom 有一个类似的函数,叫做 `_outmem`,允许你指示要显示多少个字符。对于一次一个字符,我们可以在 `IMAGEDATA` 数组中提供一个字符值的指针,并告诉 `_outtext` 只显示一个字符。这将使用当前的颜色属性显示该字符,这就是我们需要的。
```
for (pos = 0; pos < 3840; pos += 2) {
ch = &IMAGEDATA[pos]; /* pointer assignment */
attr = IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}
```
这个更新的 `for` 循环通过向 `IMAGEDATA` 数组分配一个指针来设置字符 `ch`。接下来, 循环设置文本属性, 然后用 `_outmem` 显示字符.
### 整合起来
有了 `textattr` 函数和处理数组的 `for` 循环, 我们可以编写一个完整的程序来显示 ASCII 艺术文件的内容。对于这个例子,将 ASCII 艺术文件保存为 `imgdata.inc`,并用 `#include` 语句将其包含在源文件中。
```
#include <stdio.h>
#include <conio.h>
#include <graph.h>
#include "imgdata.inc"
void
textattr(int newattr)
{
_settextcolor(newattr & 15); /* 0000xxxx */
_setbkcolor((newattr >> 4) & 7); /* 0xxx0000 */
}
int
main()
{
char *ch;
int attr;
int pos;
if (_setvideomode(_TEXTC80) == 0) {
fputs("Error setting video mode", stderr);
return 1;
}
/* draw the array */
_settextposition(1, 1); /* top left */
/* print one line less than the 80x25 that's in there:
80 x 24 x 2 = 3840 */
for (pos = 0; pos < 3840; pos += 2) {
ch = &IMAGEDATA[pos]; /* pointer assignment */
attr = IMAGEDATA[pos + 1];
textattr(attr);
_outmem(ch, 1);
}
/* done */
_settextposition(25, 1); /* bottom left */
textattr(0x0f);
_outtext("Press any key to quit");
getch();
textattr(0x00);
return 0;
}
```
在 FreeDOS 上使用 OpenWatcom C 编译器编译该程序,你会得到一个显示这个节日信息的新程序。
![ASCII艺术中的万圣节信息][8]
*万圣节快乐Jim Hall, [CC-BY-SA 4.0][9])*
万圣节快乐,各位!
- [在此下载 inc 代码文件][10]
- [在此下载 C 代码文件][11]
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/ascii-linux-halloween
作者:[Jim Hall][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/jim-hall
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/freedos-halloween-4x3.jpg?itok=6e_42rs9 (Happy Halloween ASCII art on FreeDOS)
[2]: https://opensource.com/article/21/8/ncurses-linux
[3]: https://opensource.com/article/21/9/programming-dos-conio
[4]: https://blocktronics.github.io/moebius/
[5]: https://github.com/blocktronics/pablodraw
[6]: https://opensource.com/article/21/6/freedos-sixteen-colors
[7]: https://opensource.com/article/21/8/binary-bit-fields-masks
[8]: https://opensource.com/sites/default/files/freedos-halloween-4x3.png
[9]: https://creativecommons.org/licenses/by-sa/4.0/
[10]: https://opensource.com/sites/default/files/uploads/imgdata.inc_.txt
[11]: https://opensource.com/sites/default/files/uploads/hallown.c.txt