mirror of
https://github.com/LCTT/TranslateProject.git
synced 2026-09-04 04:32:49 +08:00
@@ -0,0 +1,146 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (YungeG)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13691-1.html)
|
||||
[#]: subject: (Managing your attached hardware on Linux with systemd-udevd)
|
||||
[#]: via: (https://opensource.com/article/20/2/linux-systemd-udevd)
|
||||
[#]: author: (David Clinton https://opensource.com/users/dbclinton)
|
||||
|
||||
在 Linux 使用 systemd-udevd 管理你的接入硬件
|
||||
======
|
||||
|
||||
> 使用 udev 管理你的 Linux 系统处理物理设备的方式。
|
||||
|
||||

|
||||
|
||||
Linux 能够出色地自动识别、加载、并公开接入的无数厂商的硬件设备。事实上,很多年以前,正是这个特性说服我,坚持让我的雇主将整个基础设施转换到 Linux。痛点在于 Redmond 的某家公司(LCTT 译注:指微软)不能在我们的 Compaq 台式机上加载集成网卡的驱动,而 Linux 可以轻松实现这一点。
|
||||
|
||||
从那以后的岁月里,Linux 的识别设备库随着该过程的复杂化而与日俱增,而 [udev][2] 就是解决这个问题的希望之星。udev 负责监听 Linux 内核发出的改变设备状态的事件。它可能是一个新 USB 设备被插入或拔出,也可能是一个无线鼠标因浸入洒出的咖啡中而脱机。
|
||||
|
||||
udev 负责处理所有的状态变更,比如指定访问设备使用的名称和权限。这些更改的记录可以通过 [dmesg][3] 获取。由于 dmesg 的输出通常有几千行,对结果进行过滤通常是聪明的选择。下面的例子说明了 Linux 如何识别我的 WiFi 接口。这个例子展示了我的无线设备使用的芯片组(`ath9k`)、启动过程早期阶段分配的原始名称(`wlan0`)、以及正在使用的又臭又长的永久名称(`wlxec086b1ef0b3`):
|
||||
|
||||
```
|
||||
$ dmesg | grep wlan
|
||||
[ 5.396874] ath9k_htc 1-3:1.0 wlxec086b1ef0b3: renamed from wlan0
|
||||
```
|
||||
|
||||
在这篇文章中,我会讨论为何有人想要使用这样的名称。在这个过程中,我会探索剖析 udev 的配置文件,然后展示如何更改 udev 的设置,包括编辑系统命名设备的方式。这篇文件基于我的新课程中《[Linux 系统优化][4]》的一个模块。
|
||||
|
||||
### 理解 udev 配置系统
|
||||
|
||||
使用 systemd 的机器上,udev 操作由 `systemd-udevd` 守护进程管理,你可以通过常规的 systemd 方式使用 `systemctl status systemd-udevd` 检查 udev 守护进程的状态。
|
||||
|
||||
严格来说,udev 的工作方式是试图将它收到的每个系统事件与 `/lib/udev/rules.d/` 和 `/etc/udev/rules.d/` 目录下找到的规则集进行匹配。规则文件包括匹配键和分配键,可用的匹配键包括 `action`、`name` 和 `subsystem`。这意味着如果探测到一个属于某个子系统的、带有特定名称的设备,就会给设备指定一个预设的配置。
|
||||
|
||||
接着,“分配”键值对被拿来应用想要的配置。例如,你可以给设备分配一个新名称、将其关联到文件系统中的一个符号链接、或者限制为只能由特定的所有者或组访问。这是从我的工作站摘出的一条规则:
|
||||
|
||||
```
|
||||
$ cat /lib/udev/rules.d/73-usb-net-by-mac.rules
|
||||
# Use MAC based names for network interfaces which are directly or indirectly
|
||||
# on USB and have an universally administered (stable) MAC address (second bit
|
||||
# is 0). Don't do this when ifnames is disabled via kernel command line or
|
||||
# customizing/disabling 99-default.link (or previously 80-net-setup-link.rules).
|
||||
|
||||
IMPORT{cmdline}="net.ifnames"
|
||||
ENV{net.ifnames}=="0", GOTO="usb_net_by_mac_end"
|
||||
|
||||
ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", NAME=="", \
|
||||
ATTR{address}=="?[014589cd]:*", \
|
||||
TEST!="/etc/udev/rules.d/80-net-setup-link.rules", \
|
||||
TEST!="/etc/systemd/network/99-default.link", \
|
||||
IMPORT{builtin}="net_id", NAME="$env{ID_NET_NAME_MAC}"
|
||||
```
|
||||
|
||||
`add` 动作告诉 udev,只要新插入的设备属于网络子系统,*并且*是一个 USB 设备,就执行操作。此外,如果我理解正确的话,只有设备的 MAC 地址由特定范围内的字符组成,并且 `80-net-setup-link.rules` 和 `99-default.link` 文件*不*存在时,规则才会生效。
|
||||
|
||||
假定所有的条件都满足,接口 ID 会改变以匹配设备的 MAC 地址。还记得之前的 dmesg 信息显示我的接口名称从 `wlan0` 改成了讨厌的 `wlxec086b1ef0b3` 吗?那都是这条规则的功劳。我怎么知道?因为 `ec:08:6b:1e:f0:b3` 是设备的 MAC 地址(不包括冒号)。
|
||||
|
||||
```
|
||||
$ ifconfig -a
|
||||
wlxec086b1ef0b3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
|
||||
inet 192.168.0.103 netmask 255.255.255.0 broadcast 192.168.0.255
|
||||
inet6 fe80::7484:3120:c6a3:e3d1 prefixlen 64 scopeid 0x20<link>
|
||||
ether ec:08:6b:1e:f0:b3 txqueuelen 1000 (Ethernet)
|
||||
RX packets 682098 bytes 714517869 (714.5 MB)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 472448 bytes 201773965 (201.7 MB)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
```
|
||||
|
||||
Linux 默认包含这条 udev 规则,我不需要自己写。但是为什么费力进行这样的命名呢——尤其是看到这样的接口命名这么难使用后?仔细看一下包含在规则中的注释:
|
||||
|
||||
> 对直接或间接插入在 USB 上的网络接口使用基于 MAC 的名称,并且用一个普遍提供的(稳定的)MAC 地址(第二位是 0)。当 ifnames 通过内核命令行或 `customizing/disabling 99-default.link`(或之前的 `80-net-setup-link.rules`)被禁用时,不要这样做。
|
||||
|
||||
注意,这个规则专为基于 USB 的网络接口设计的。和 PCI 网络接口卡(NIC)不同,USB 设备很可能时不时地被移除或者替换,这意味着无法保证它们的 ID 不变。某一天 ID 可能是 `wlan0`,第二天却变成了 `wlan3`。为了避免迷惑应用程序,指定绝对 ID 给设备——就像分配给我的 USB 接口的 ID。
|
||||
|
||||
### 操作 udev 的设置
|
||||
|
||||
下一个示例中,我将从 [VirtualBox][5] 虚拟机里抓取以太网接口的 MAC 地址和当前接口 ID,然后用这些信息创建一个改变接口 ID 的 udev 新规则。为什么这么做?也许我打算从命令行操作设备,需要输入那么长的名称让人十分烦恼。下面是工作原理。
|
||||
|
||||
改变接口 ID 之前,我需要关闭 [Netplan][6] 当前的网络配置,促使 Linux 使用新的配置。下面是 `/etc/netplan/` 目录下我的当前网络接口配置文件:
|
||||
|
||||
```
|
||||
$ less /etc/netplan/50-cloud-init.yaml
|
||||
# This file is generated from information provided by
|
||||
# the datasource. Changes to it will not persist across an instance.
|
||||
# To disable cloud-init's network configuration capabilities, write a file
|
||||
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
|
||||
# network: {config: disabled}
|
||||
network:
|
||||
ethernets:
|
||||
enp0s3:
|
||||
addresses: []
|
||||
dhcp4: true
|
||||
version: 2
|
||||
```
|
||||
|
||||
`50-cloud-init.yaml` 文件包含一个非常基本的接口定义,但是注释中也包含一些禁用配置的重要信息。为此,我将移动到 `/etc/cloud/cloud.cfg.d` 目录,创建一个名为 `/etc/cloud/cloud.cfg.d` 的新文件,插入 `network: {config: disabled}` 字符串。
|
||||
|
||||
尽管我只在 Ubuntu 发行版上测试了这个方法,但它应该在任何一个带有 systemd 的 Linux(几乎所有的 Linux 发行版都有 systemd)上都可以工作。不管你使用哪个,都可以很好地了解编写 udev 配置文件并对其进行测试。
|
||||
|
||||
接下来,我需要收集一些系统信息。执行 `ip` 命令,显示我的以太网接口名为 `enp0s3`,MAC 地址是 `08:00:27:1d:28:10`。
|
||||
|
||||
```
|
||||
$ ip a
|
||||
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 08:00:27:1d:28:10 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.0.115/24 brd 192.168.0.255 scope global dynamic enp0s3
|
||||
```
|
||||
|
||||
现在,我要在 `/etc/udev/rules.d` 目录创建一个名为 `peristent-net.rules` 的新文件。我将给文件一个以较小的数字开头的名称,比如 10:
|
||||
|
||||
```
|
||||
$ cat /etc/udev/rules.d/10-persistent-network.rules
|
||||
ACTION=="add", SUBSYSTEM=="net",ATTR{address}=="08:00:27:1d:28:10",NAME="eth3"
|
||||
```
|
||||
|
||||
数字越小,Linux 越早执行文件,我想要这个文件早点执行。文件被添加时,包含其中的代码就会分配名称 `eth3` 给网络设备——只要设备的地址能够匹配 `08:00:27:1d:28:10`,即我的接口的 MAC 地址 。
|
||||
|
||||
保存文件并重启计算机后,我的新接口名应该就会生效。我可能需要直接登录虚拟机,使用 `dhclient` 手动让 Linux 为这个新命名的网络请求一个 IP 地址。在执行下列命令前,可能无法打开 SSH 会话:
|
||||
|
||||
```
|
||||
$ sudo dhclient eth3
|
||||
```
|
||||
|
||||
大功告成。现在你能够促使 udev 控制计算机按照你想要的方式指向一个网卡,但更重要的是,你已经有了一些工具,可以弄清楚如何管理任何不听话的设备。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/linux-systemd-udevd
|
||||
|
||||
作者:[David Clinton][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/dbclinton
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_BUS_Apple_520.png?itok=ZJu-hBV1 (collection of hardware on blue backround)
|
||||
[2]: https://en.wikipedia.org/wiki/Udev
|
||||
[3]: https://en.wikipedia.org/wiki/Dmesg
|
||||
[4]: https://pluralsight.pxf.io/RqrJb
|
||||
[5]: https://www.virtualbox.org/
|
||||
[6]: https://netplan.io/
|
||||
107
published/20210608 Tune your MySQL queries like a pro.md
Normal file
107
published/20210608 Tune your MySQL queries like a pro.md
Normal file
@@ -0,0 +1,107 @@
|
||||
[#]: subject: (Tune your MySQL queries like a pro)
|
||||
[#]: via: (https://opensource.com/article/21/5/mysql-query-tuning)
|
||||
[#]: author: (Dave Stokes https://opensource.com/users/davidmstokes)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (unigeorge)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13684-1.html)
|
||||
|
||||
如老手一般玩转 MySQL 查询
|
||||
======
|
||||
|
||||
> 优化查询语句不过是一项简单的工程,而非什么高深的黑魔法。
|
||||
|
||||

|
||||
|
||||
许多人将数据库查询语句的调优视作哈利波特小说中某种神秘的“黑魔法”;使用错误的咒语,数据就会从宝贵的资源变成一堆糊状物。
|
||||
|
||||
实际上,对关系数据库系统的查询调优是一项简单的工程,其遵循的规则或启发式方法很容易理解。查询优化器会翻译你发送给 [MySQL][2] 实例的查询指令,然后将这些启发式方法和优化器已知的数据信息结合使用,确定获取所请求数据的最佳方式。再读一下后面这半句:_“优化器已知的数据信息_。”查询优化器需要对数据所在位置的猜测越少(即已知信息越多),它就可以越好地制定交付数据的计划。
|
||||
|
||||
为了让优化器更好地了解数据,你可以考虑使用索引和直方图。正确使用索引和直方图可以大大提高数据库查询的速度。这就像如果你按照食谱做菜,就可以得到你喜欢吃的东西;但是假如你随意在该食谱中添加材料,最终得到的东西可能就不那么尽如人意了。
|
||||
|
||||
### 基于成本的优化器
|
||||
|
||||
大多数现代关系型数据库使用<ruby>基于成本的优化器<rt>cost-based optimizer</rt></ruby>来确定如何从数据库中检索数据。该成本方案是基于尽可能减少非常耗费资源的磁盘读取过程。数据库服务器内的查询优化器代码会在得到数据时对这些数据的获取进行统计,并构建一个获取数据的历史模型。
|
||||
|
||||
但历史数据是可能会过时的。这就好像你去商店买你最喜欢的零食,然后突然发现零食涨价或者商店关门了。服务器的优化进程可能会根据旧信息做出错误的假设,进而制定出低效的查询计划。
|
||||
|
||||
查询的复杂性可能会影响优化。优化器希望提供可用的最低成本查询方式。连接五个不同的表就意味着有 5 的阶乘(即 120)种可能的连接组合。代码中内置了启发式方法,以尝试对所有可能的选项进行快捷评估。MySQL 每次看到查询时都希望生成一个新的查询计划,而其他数据库(例如 Oracle)则可以锁定查询计划。这就是向优化器提供有关数据的详细信息至关重要的原因。要想获得稳定的性能,在制定查询计划时为查询优化器提供最新信息确实很有效。
|
||||
|
||||
此外,优化器中内置的规则可能与数据的实际情况并不相符。没有更多有效信息的情况下,查询优化器会假设列中的所有数据均匀分布在所有行中。没有其他选择依据时,它会默认选择两个可能索引中较小的一个。虽然基于成本的优化器模型可以制定出很多好的决策,但最终查询计划并不是最佳方案的情况也是有可能的。
|
||||
|
||||
### 查询计划是什么?
|
||||
|
||||
<ruby>查询计划<rt>query plan</rt></ruby>是指优化器基于查询语句产生的,提供给服务器执行的计划内容。查看查询计划的方法是在查询语句前加上 `EXPLAIN` 关键字。例如,以下查询要从城市表(`city`)和相应的国家表(`country`)中获得城市名称(和所属国家名称),城市表和国家表通过国家唯一代码连接。本例中仅查询了英国的字母顺序前五名的城市:
|
||||
|
||||
```
|
||||
SELECT city.name AS 'City',
|
||||
country.name AS 'Country'
|
||||
FROM city
|
||||
JOIN country ON (city.countrycode = country.code)
|
||||
WHERE country.code = 'GBR'
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
在查询语句前加上 `EXPLAIN` 可以看到优化器生成的查询计划。跳过除输出末尾之外的所有内容,可以看到优化后的查询:
|
||||
|
||||
```
|
||||
SELECT `world`.`city`.`Name` AS `City`,
|
||||
'United Kingdom' AS `Country`
|
||||
FROM `world`.`city`
|
||||
JOIN `world`.`country`
|
||||
WHERE (`world`.`city`.`CountryCode` = 'GBR')
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
看下比较大的几个变化, `country.name as 'Country'` 改成了 `'United Kingdom' AS 'Country'`,`WHERE` 子句从在国家表中查找变成了在城市表中查找。优化器认为这两个改动会提供比原始查询更快的结果。
|
||||
|
||||
### 索引
|
||||
|
||||
在 MySQL 世界中,你会听到索引或键的概念。不过,索引是由键组成的,键是一种识别记录的方式,并且大概率是唯一的。如果将列设计为键,优化器可以搜索这些键的列表以找到所需的记录,而无需读取整个表。如果没有索引,服务器必须从第一列的第一行开始读取每一行数据。如果该列是作为唯一索引创建的,则服务器可以直接读取该行数据并忽略其余数据。索引的值(也称为基数)唯一性越强越好。请记住,我们在寻找更快获取数据的方法。
|
||||
|
||||
MySQL 默认的 InnoDB 存储引擎希望你的表有一个主键,并按照该键将你的数据存储在 B+ 树中。“不可见列”是 MySQL 最近添加的功能,除非在查询中明确指明该不可见列,否则不会返回该列数据。例如,`SELECT * FROM foo;` 就不会返回任何不可见列。这个功能提供了一种向旧表添加主键的方法,且无需为了包含该新列而重写所有查询语句。
|
||||
|
||||
更复杂的是,有多种类型的索引,例如函数索引、空间索引和复合索引。甚至在某些情况下,你还可以创建这样一个索引:该索引可以为查询提供所有请求的信息,从而无需再去访问数据表。
|
||||
|
||||
本文不会详细讲解各种索引类型,你只需将索引看作指向要查询的数据记录的快捷方式。你可以在一个或多个列或这些列的一部分上创建索引。我的医师系统就可以通过我姓氏的前三个字母和出生日期来查找我的记录。使用多列时要注意首选唯一性最强的字段,然后是第二强的字段,依此类推。“年-月-日”的索引可用于“年-月-日”、“年-月”和“年”搜索,但不适用于“日”、“月-日”或“年-日”搜索。考虑这些因素有助于你围绕如何使用数据这一出发点来设计索引。
|
||||
|
||||
### 直方图
|
||||
|
||||
直方图就是数据的分布形式。如果你将人名按其姓氏的字母顺序排序,就可以对姓氏以字母 A 到 F 开头的人放到一个“逻辑桶”中,然后将 G 到 J 开头的放到另一个中,依此类推。优化器会假定数据在列内均匀分布,但实际使用时多数情况并不是均匀的。
|
||||
|
||||
MySQL 提供两种类型的直方图:所有数据在桶中平均分配的等高型,以及单个值在单个桶中的等宽型。最多可以设置 1,024 个存储桶。数据存储桶数量的选择取决于许多因素,包括去重后的数值量、数据倾斜度以及需要的结果准确度。如果桶的数量超过某个阈值,桶机制带来的收益就会开始递减。
|
||||
|
||||
以下命令将在表 `t` 的列 `c1` 上创建 10 个桶的直方图:
|
||||
|
||||
```
|
||||
ANALYZE TABLE t UPDATE HISTOGRAM ON c1 WITH 10 BUCKETS;
|
||||
```
|
||||
|
||||
想象一下你在售卖小号、中号和大号袜子,每种尺寸的袜子都放在单独的储物箱中。如果你想找某个尺寸的袜子,就可以直接去对应尺寸的箱子里找。MySQL 自从三年前发布 MySQL 8.0 以来就有了直方图功能,但该功能却并没有像索引那样广为人知。与索引不同,使用直方图插入、更新或删除记录都不会产生额外开销。而如果更新索引,就必须更新 `ANALYZE TABLE` 命令。当数据变动不大并且频繁更改数据会降低效率时,直方图是一种很好的方法。
|
||||
|
||||
### 选择索引还是直方图?
|
||||
|
||||
对需要直接访问的且具备唯一性的数据项目使用索引。虽然修改、删除和插入操作会产生额外开销,但如果数据架构正确,索引就可以方便你快速访问。对不经常更新的数据则建议使用直方图,例如过去十几年的季度结果。
|
||||
|
||||
### 结语
|
||||
|
||||
本文源于最近在 [Open Source 101 会议][3] 上的一次报告。报告的演示文稿源自 [PHP UK Conferenc][4] 的研讨会。查询调优是一个复杂的话题,每次我就索引和直方图作报告时,我都会找到新的可改进点。但是每次报告反馈也表明很多软件界中的人并不精通索引,并且时常使用错误。我想直方图大概由于出现时间较短,还没有出现像索引这种使用错误的情况。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/5/mysql-query-tuning
|
||||
|
||||
作者:[Dave Stokes][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/davidmstokes
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-window-focus.png?itok=g0xPm2kD (young woman working on a laptop)
|
||||
[2]: https://www.mysql.com/
|
||||
[3]: https://opensource101.com/
|
||||
[4]: https://www.phpconference.co.uk/
|
||||
@@ -0,0 +1,92 @@
|
||||
[#]: subject: (5 useful ways to manage Kubernetes with kubectl)
|
||||
[#]: via: (https://opensource.com/article/21/7/kubectl)
|
||||
[#]: author: (Alan Smithee https://opensource.com/users/alansmithee)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (turbokernel)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13676-1.html)
|
||||
|
||||
用 kubectl 管理 Kubernetes 的 5 种有用方法
|
||||
======
|
||||
|
||||
> 学习 kubectl,提升你与 Kubernetes 的互动方式。
|
||||
|
||||
![Ship captain sailing the Kubernetes seas][1]
|
||||
|
||||
Kubernetes 可以帮你编排运行有大量容器的软件。Kubernetes 不仅提供工具来管理(或者说 [编排][2])运行的容器,还帮助这些容器根据需要进行扩展。有了 Kubernetes 作为你的中央<ruby>控制面板<rt>control panel</rt></ruby>(或称 <ruby>控制平面<rt>control plane</rt></ruby>),你需要一种方式来管理 Kubernetes,而这项工作的工具就是 kubectl。`kubectl` 命令让你控制、维护、分析和排查 Kubernetes 集群的故障。与许多使用 `ctl`(“控制”的缩写)后缀的工具一样,如 `systemctl` 和 `sysctl`,`kubectl` 拥有大量的功能和任务权限,所以如果你正在运行 Kubernetes,你肯定会经常使用它。它是一个拥有众多选项的命令,所以下面是 `kubectl` 中简单易用的五个常见任务。
|
||||
|
||||
### 1、列出并描述资源
|
||||
|
||||
按照设计,容器往往会成倍增加。在某些条件下,它们可以快速增加。如果你只能通过 `podman ps`或 `docker ps` 来查看正在运行的容器,这可能会让你不知所措。通过 `kubectl get` 和 `kubectl describe`,你可以列出正在运行的<ruby>吊舱<rt>pod</rt></ruby>以及它们正在处理的容器信息。更重要的是,你可以通过使用 `--namespace` 或 `name` 或 `--selector`等选项,只列出所需信息。
|
||||
|
||||
`get` 子命令不仅仅对吊舱和容器有用。它也有关于节点、命名空间、发布、服务和副本的信息。
|
||||
|
||||
### 2、创建资源
|
||||
|
||||
如果你只通过类似 OpenShift、OKD 或 Kubernetes 提供的 Web 用户界面(UI)创建过发布,但你想从 Linux 终端控制你的集群,那么可以使用 `kubectl create`。`kubectl create` 命令并不只是实例化一个新的应用发布。Kubernetes 中还有很多其他组件可以创建,比如服务、配额和 [计划任务][3]。
|
||||
|
||||
Kubernetes 中的计划任务可以创建一个临时的吊舱,用来在你选择的时间表上执行一些任务。它们并不难设置。下面是一个计划任务,让一个 BusyBox 镜像每分钟打印 “hello world”。
|
||||
|
||||
```
|
||||
$ kubectl create cronjob \
|
||||
hello-world \
|
||||
--image=busybox \
|
||||
--schedule="*/1 * * * *" -- echo "hello world"
|
||||
```
|
||||
|
||||
### 3、编辑文件
|
||||
|
||||
Kubernetes 中的对象都有相应的配置文件,但在文件系统中查找相应的文件较为麻烦。有了 `kubectl edit`,你可以把注意力放在对象上,而不是定义文件上。你可以通过 `kubectl` 找到并打开文件(通过 `KUBE_EDITOR` 环境变量,你可以设置成你喜欢的编辑器)。
|
||||
|
||||
```
|
||||
$ KUBE_EDITOR=emacs \
|
||||
kubectl edit cronjob/hello-world
|
||||
```
|
||||
|
||||
### 4、容器之间的传输文件
|
||||
|
||||
初次接触容器的人往往对无法直接访问的共享系统的概念感到困惑。他们可能会在容器引擎或 `kubectl` 中了解到 `exec` 选项,但当他们不能从容器中提取文件或将文件放入容器中时,容器仍然会显得不透明。使用 `kubectl cp` 命令,你可以把容器当做远程服务器,使主机和容器之间文件传输如 SSH 命令一样简单:
|
||||
|
||||
```
|
||||
$ kubectl cp foo my-pod:/tmp
|
||||
```
|
||||
|
||||
### 5、应用变更
|
||||
|
||||
对 Kubernetes 对象进行修改,可以通过 `kubectl apply` 命令完成。你所要做的就是将该命令指向一个配置文件:
|
||||
|
||||
```
|
||||
$ kubectl apply -f ./mypod.json
|
||||
```
|
||||
|
||||
类似于运行 Ansible 剧本或 Bash 脚本,`apply` 使得快速“导入”设置到运行中的 Kubernetes 实例很容易。例如,GitOps 工具 [ArgoCD][4] 由于 `apply` 子命令,安装起来出奇地简单:
|
||||
|
||||
```
|
||||
$ kubectl create namespace argocd
|
||||
$ kubectl apply -n argocd \
|
||||
-f https://raw.githubusercontent.com/argoproj/argo-cd/vx.y.z/manifests/install.yaml
|
||||
```
|
||||
|
||||
### 使用 kubectl
|
||||
|
||||
Kubectl 是一个强大的工具,由于它是一个终端命令,它可以写成脚本,并能实现用众多 Web UI 无法实现的功能。学习 `kubectl` 是进一步了解 Kubernetes、容器、吊舱以及围绕这些重要的云计算创新技术的一个好方法。[下载我们的 kubectl 速查表][5],以获得快速参考,其中包括命令示例,以帮助你学习,并在为你提供注意细节。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/7/kubectl
|
||||
|
||||
作者:[Alan Smithee][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[turbokernel](https://github.com/turbokernel)
|
||||
|
||||
本文由 [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/ship_captain_devops_kubernetes_steer.png?itok=LAHfIpek (Ship captain sailing the Kubernetes seas)
|
||||
[2]: https://opensource.com/article/20/11/orchestration-vs-automation
|
||||
[3]: https://opensource.com/article/20/11/kubernetes-jobs-cronjobs
|
||||
[4]: https://argoproj.github.io/argo-cd/
|
||||
[5]: https://opensource.com/downloads/kubectl-cheat-sheet
|
||||
231
published/20210725 Top 7 Linux Laptops You Can Buy in 2021.md
Normal file
231
published/20210725 Top 7 Linux Laptops You Can Buy in 2021.md
Normal file
@@ -0,0 +1,231 @@
|
||||
[#]: subject: (Top 7 Linux Laptops You Can Buy in 2021)
|
||||
[#]: via: (https://news.itsfoss.com/best-linux-laptops-2021/)
|
||||
[#]: author: (Ankush Das https://news.itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13672-1.html)
|
||||
|
||||
2021 年可以购买的 10 大 Linux 笔记本电脑
|
||||
======
|
||||
|
||||
> 想挑选一台安装有 Linux 的新笔记本电脑?这里有几个选项可以考虑。
|
||||
|
||||

|
||||
|
||||
Linux 笔记本电脑是 MacOS 和 Windows 笔记本电脑的完美替代品。
|
||||
|
||||
从技术上讲,你可以通过安装任何你能找到的 Linux 发行版,将你选择的任何笔记本电脑变成一台 Linux 机器。
|
||||
|
||||
但是,在这里,我们的重点将放在提供 Linux 开箱即用体验的笔记本电脑上,确保无论你有什么样的预算,都能获得最佳的兼容性和支持。
|
||||
|
||||
### 大众品牌的 Linux 笔记本电脑
|
||||
|
||||
对于消费者来说,选择由大众品牌制造商生产的 Linux 笔记本电脑往往是最好的选择。
|
||||
|
||||
你不必担心售后、延长保修期和服务维修等问题。
|
||||
|
||||
戴尔和联想是通常提供预装了 Linux 的笔记本电脑的厂商之一。
|
||||
|
||||
请注意,这会因国家/地区的情况而定。
|
||||
|
||||
*本文中提到的价格已转换为美元,以方便比较,不包括运费和其他额外费用。*
|
||||
|
||||
#### 1、联想 Thinkpad X1 Carbon (第 8 代/第 9 代)
|
||||
|
||||
![][1]
|
||||
|
||||
**价格**:起价为 **$1535**
|
||||
|
||||
联想的整个 Thinkpad 系列是 Linux 用户的一个热门选择。它经久耐用,提供了良好的兼容性。
|
||||
|
||||
然而,它的价格一直偏高。
|
||||
|
||||
你有三种选择,这取决于你的需求。如果你定制一台第 9 代 Thinkpad 笔记本电脑,你可以选择安装 Ubuntu 20.04 和 Fedora 33。
|
||||
|
||||
对于第 8 代机型,似乎 Fedora 33 不在考虑之列,而是提供了 Fedora 32 和 Ubuntu 20.04。
|
||||
|
||||
所有的配置都采用英特尔芯片组,第 8 代采用的是 10 代芯片组,第 9 代采用 11 代芯片组。
|
||||
|
||||
其他的大部分规格都相似,有 14 英寸显示屏(FHD、WQHD 和 UHD 可供选择)、高达 32GB 的内存、1TB 固态硬盘、指纹识别器和 Wi-Fi 6 支持。
|
||||
|
||||
- [Thinkpad X1 Carbon (第 9 代)][2]
|
||||
- [Thinkpad X1 Carbon (第 8 代)][3]
|
||||
|
||||
#### 2、戴尔 XPS 13 开发者版
|
||||
|
||||
![][4]
|
||||
|
||||
**价格**:起价为 **$1059**
|
||||
|
||||
戴尔 XPS 系列是一个令人印象深刻的、可以考虑运行 Linux 的笔记本电脑系列。
|
||||
|
||||
它是为开发者运行 Linux(Ubuntu 20.04)而定制的。
|
||||
|
||||
你可以得到一个 13.4 英寸的显示屏(有 FHD 和 UHD 可选)、第 11 代 i5/i7 处理器、高达 32GB 的内存、2TB 固态硬盘、指纹识别器,以及 Wi-Fi 6 支持。
|
||||
|
||||
- [戴尔 XPS 13 开发者版][5]
|
||||
|
||||
### 纯 Linux 制造商的笔记本电脑
|
||||
|
||||
如果你不想要主流的选择,而是想要一些独特的选择,那你可以选择支持纯 Linux 制造商,有几个是你可以考虑的。
|
||||
|
||||
#### 1、System76 Gazelle
|
||||
|
||||
![][6]
|
||||
|
||||
**价格**:起价为 **$1499**
|
||||
|
||||
System76 的笔记本电脑将内置他们的 Pop!_OS 操作系统,该系统基于 Ubuntu,但提供了**无忧的开箱即用体验**。
|
||||
|
||||
可以把 System76 视作 Linux 笔记本电脑中的苹果电脑,他们尽力为其提供的硬件优化了 Pop!_OS。
|
||||
|
||||
他们可以完全控制这些软件和硬件,所以这对终端消费者来说应该是令人兴奋的产品整合。
|
||||
|
||||
除了 144Hz 的 16.5 英寸显示屏、第 11 代 i7 处理器、高达 8TB 的 NVMe 固态硬盘支持等令人印象深刻的基本配置外,你还会有一个 RTX 3050 GPU,应该可以让你在笔记本电脑上处理各种苛刻的任务。
|
||||
|
||||
虽然 System76 还有一些其他型号的笔记本电脑,但在写这篇文章时,还没有上市。因此,请随时查看官方商店页面,订购定制的配置。
|
||||
|
||||
- [System76 Gazelle][7]
|
||||
|
||||
#### 2、Purism 笔记本电脑
|
||||
|
||||
![][8]
|
||||
|
||||
**价格**:起价为 **$1599**
|
||||
|
||||
如果你是一个有安全意识的用户,Purism 的笔记本电脑可以作为一个选择。
|
||||
|
||||
Librem 14 是他们最新的笔记本电脑之一,带有 [PureOS][9](也是由他们制造的)。
|
||||
|
||||
虽然它可能没有提供最新一代的处理器,但你应该对机上的第 10 代 i7 芯片感到满意吧。
|
||||
|
||||
它支持高达 64GB 的内存,并具有硬件封禁开关,可以禁用网络摄像头、耳机插孔、蓝牙或无线音频。
|
||||
|
||||
- [Librem 14][10]
|
||||
|
||||
#### 3、TUXEDO Aura 15
|
||||
|
||||
![][11]
|
||||
|
||||
**价格**:起价为 **$899**
|
||||
|
||||
如果你想要一台 AMD 的笔记本电脑(采用上一代处理器 Ryzen 7 4700U),TUXEDO 计算机公司的 Aura 15 是一个不错的选择。
|
||||
|
||||
主要规格包括全高清显示屏、高达 64GB 的内存、支持 Wi-Fi 6,以及一个 LTE 模块。
|
||||
|
||||
它配备了 Ubuntu 或 TUXEDO 操作系统(基于 Ubuntu Budgie),可根据你的定制要求。
|
||||
|
||||
- [TUXEDO Aura 15][12]
|
||||
|
||||
#### 4、TUXEDO Stellaris 15
|
||||
|
||||
![][13]
|
||||
|
||||
**价格**:起价为 **$2160**
|
||||
|
||||
如果你正在寻找最新和最强大的笔记本电脑,并希望用上 RTX 3080 显卡,这应该是一个非常好的选择。
|
||||
|
||||
它提供了最新的英特尔/AMD Ryzen 处理器的配置选择,并具有 165Hz 刷新率的 3K 分辨率显示屏。
|
||||
|
||||
它绝不是你会觉得在旅行时带着方便的东西,但如果你需要计算能力,你可以选择它。
|
||||
|
||||
- [TUXEDO Stellaris 15][21]
|
||||
|
||||
#### 5、Slimbook Pro X
|
||||
|
||||
![][14]
|
||||
|
||||
**价格**:起价为 **$1105**
|
||||
|
||||
Slimbook 专注于旅行方便携带的轻薄笔记本电脑型号。
|
||||
|
||||
你可以选择各种发行版,包括 Ubuntu(GNOME、KDE、MATE)、KDE Neon、Manjaro 和 Fedora。
|
||||
|
||||
你可以得到大部分的基本规格,包括支持高达 2TB 的固态硬盘、64GB 的内存、全高清 IPS 显示屏等等。
|
||||
|
||||
虽然你可以选择英特尔和 AMD Ryzen(最新一代处理器),并分别与 Nvidia 和 Vega 图形处理器相结合,但在写这篇文章时只有 Ryzen 型号有库存。
|
||||
|
||||
- [Slimbook Pro X][22]
|
||||
|
||||
#### 6、Slimbook Essential
|
||||
|
||||
![][23]
|
||||
|
||||
**价格**:起价为 **$646**
|
||||
|
||||
一个令人印象深刻的预算友好型 Linux 笔记本电脑的选择。
|
||||
|
||||
它提供了 AMD Ryzen 和英特尔的变体(最后一代)供你选择。你得到硬件规格还可以,包括高达 64GB 的内存、2TB 的 SSD 支持,但是要少一个大的屏幕和板载专用显卡。
|
||||
|
||||
- [Slimbook Essential][15]
|
||||
|
||||
#### 7、Jupiter 14 Pro
|
||||
|
||||
![][16]
|
||||
|
||||
**价格**:起价为 **$1199**
|
||||
|
||||
Juno 计算机公司的 Jupiter 14 采用了第 11 代英特尔处理器,并配备了 NVIDIA GTX 1650,价格诱人。
|
||||
|
||||
它内置了 Ubuntu 20.04 系统,没有其他系统可供选择。
|
||||
|
||||
基本配置包括 16GB 内存,与其他一些产品相比,这可能更物超所值一些。
|
||||
|
||||
你会发现在他们的网站上可以选择你的地区(英国/欧洲或美国/加拿大),请确保利用这一点。
|
||||
|
||||
- [Jupiter Pro 14][17]
|
||||
|
||||
#### 荣誉奖:PineBook Pro
|
||||
|
||||
![][18]
|
||||
|
||||
PineBook Pro 是一款基于 ARM 的笔记本电脑(采用 Manjaro ARM 版),预算低廉,对于 Linux 上的很多基本任务来说,应该可以正常工作。
|
||||
|
||||
在写这篇文章的时候,它已经没有库存了(直到进一步通知)。然而,当你看到这篇文章时,可以自己去看看一下。
|
||||
|
||||
- [Pinebook Pro][19]
|
||||
|
||||
### 总结
|
||||
|
||||
如果你不喜欢这里的选择,你可以去看看 [其他可以购买 Linux 笔记本电脑的地方][20]。根据你的预算,选择你觉得最适合你的东西。
|
||||
|
||||
毕竟,所有的东西都有 Linux 的影子。有些可以让你能够从多个发行版中选择,但大多数人都坚持使用预装的 Ubuntu。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/best-linux-laptops-2021/
|
||||
|
||||
作者:[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/07/thinkpad-x1-carbon.jpg?w=1060&ssl=1
|
||||
[2]: https://www.lenovo.com/us/en/laptops/thinkpad/thinkpad-x1/X1-Carbon-G9/p/22TP2X1X1C9
|
||||
[3]: https://www.lenovo.com/us/en/laptops/thinkpad/thinkpad-x1/X1-Carbon-Gen-8-/p/22TP2X1X1C8
|
||||
[4]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/dell-xps-13.jpg?w=1200&ssl=1
|
||||
[5]: https://www.dell.com/en-us/work/shop/dell-laptops-and-notebooks/new-xps-13-developer-edition/spd/xps-13-9310-laptop/ctox139w10p2c3000u
|
||||
[6]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/system76-gazelle.jpg?w=1200&ssl=1
|
||||
[7]: https://system76.com/laptops/gazelle
|
||||
[8]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/librem14.png?resize=780%2C780&ssl=1
|
||||
[9]: https://www.pureos.net
|
||||
[10]: https://puri.sm/products/librem-14/
|
||||
[11]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/tuxedo-aura-15.jpg?resize=780%2C780&ssl=1
|
||||
[12]: https://www.tuxedocomputers.com/en/Linux-Hardware/Linux-Notebooks/15-16-inch/TUXEDO-Aura-15-Gen1.tuxedo
|
||||
[13]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/tuxedo-stellaris.jpg?resize=780%2C780&ssl=1
|
||||
[14]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/slimbook-pro.jpg?resize=1568%2C849&ssl=1
|
||||
[15]: https://slimbook.es/en/essential-en
|
||||
[16]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/jupiter-pro.png?w=1314&ssl=1
|
||||
[17]: https://junocomputers.com/us/product/jupiter-14-pro/
|
||||
[18]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/pinebook-pro.png?w=869&ssl=1
|
||||
[19]: https://www.pine64.org/pinebook-pro/
|
||||
[20]: https://itsfoss.com/get-linux-laptops/
|
||||
[21]: https://www.tuxedocomputers.com/en/Linux-Hardware/Linux-Notebooks/15-16-inch/TUXEDO-Stellaris-15-Gen3.tuxedo
|
||||
[22]: https://slimbook.es/en/store/slimbook-pro-x
|
||||
[23]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/slimbook-essential.jpg?resize=1568%2C882&ssl=1
|
||||
@@ -3,22 +3,24 @@
|
||||
[#]: author: (Arindam https://www.debugpoint.com/author/admin1/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (imgradeone)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13665-1.html)
|
||||
|
||||
如何安装 elementary 优化工具
|
||||
======
|
||||
|
||||
> 这篇快速教程演示了如何安装 elementary / Pantheon 优化工具。
|
||||
|
||||
elementary 优化工具(elementary Tweaks Tool)是专为 [elementary OS][1] 设计的实用工具。它提供了一些用于修改 elementary 设置的选项。虽然 elementary 已经提供了绝大多数选项,但还有一小部分的 Pantheon 桌面优化是不能直接通过普通设置修改的,因此这个工具才得以诞生。这个工具与 GNOME 中的 [GNOME Tweaks][2] 有些相似。
|
||||

|
||||
|
||||
也就是说,安装这个工具其实十分简单,只是 [elementary OS 6 Odin][3] 与早期版本(例如 elementary OS 5 Juno)存在一些区别。从 elementary OS 6 Odin 开始,这个工具已经重命名为 Pantheon 优化工具(Pantheon Tweaks Tool)。下面是安装步骤。
|
||||
<ruby>elementary 优化工具<rt>elementary Tweaks Tool</rt></ruby>是专为 [elementary OS][1] 设计的实用工具。它提供了一些用于修改 elementary 设置的选项。虽然 elementary 已经提供了绝大多数选项,但还有一小部分的 Pantheon 桌面优化是不能直接通过普通设置修改的,因此这个工具才得以诞生。这个工具与 GNOME 中的 [GNOME Tweaks][2] 有些相似。
|
||||
|
||||
也就是说,安装这个工具其实十分简单,只是 [elementary OS 6 Odin][3] 与早期版本(例如 elementary OS 5 Juno)存在一些区别。从 elementary OS 6 Odin 开始,这个工具已经重命名为 <ruby>Pantheon 优化工具<rt>Pantheon Tweaks Tool</rt></ruby>。下面是安装步骤。
|
||||
|
||||
### 安装 elementary 优化工具
|
||||
|
||||
elementary OS 并没有内置用于添加 PPA 的 software-properties-common 软件包。如果您还没有安装此软件包,请使用如下命令安装。
|
||||
elementary OS 并没有内置用于添加 PPA 的 `software-properties-common` 软件包。如果你还没有安装此软件包,请使用如下命令安装:
|
||||
|
||||
```
|
||||
sudo apt install software-properties-common
|
||||
@@ -26,16 +28,16 @@ sudo apt install software-properties-common
|
||||
|
||||
#### elementary OS 6 Odin
|
||||
|
||||
该版本的优化工具已经改名,并且独立于原版开发。它的名称是 [Pantheon Tweaks][4]。您可以使用如下命令安装它。
|
||||
该版本的优化工具已经改名,并且独立于原版开发。它的名称是 [Pantheon Tweaks][4]。你可以使用如下命令安装它。
|
||||
|
||||
```
|
||||
sudo add-apt-repository -y ppa:philip.scott/pantheon-tweaks
|
||||
sudo apt install -y pantheon-tweaks
|
||||
```
|
||||
|
||||
#### elementary OS 5 Juno and below
|
||||
#### elementary OS 5 Juno 及更旧版本
|
||||
|
||||
如果您正在使用 elementary OS 5 Juno 或者更旧的版本,您可以使用同一 PPA 安装早期版本的 [elementary-tweaks][5]。在终端输入以下命令即可安装。
|
||||
如果你正在使用 elementary OS 5 Juno 或者更旧的版本,你可以使用同一 PPA 安装早期版本的 [elementary-tweaks][5]。在终端输入以下命令即可安装。
|
||||
|
||||
```
|
||||
sudo add-apt-repository -y ppa:philip.scott/elementary-tweaks
|
||||
@@ -44,19 +46,17 @@ sudo apt install -y elementary-tweaks
|
||||
|
||||
### 使用方法
|
||||
|
||||
安装完成后,您可以在 `应用程序菜单 > 系统设置 > Tweaks` 中使用此工具。
|
||||
安装完成后,你可以在 “应用程序菜单 > 系统设置 > 优化” 中使用此工具。
|
||||
|
||||
![设置中的 Tweaks(优化)选项][6]
|
||||
|
||||
在 Tweaks 窗口,您可以修改一些选项,配置您的 elementary 桌面。
|
||||
在“优化”窗口,你可以修改一些选项,配置你的 elementary 桌面。
|
||||
|
||||
![安装完成后的 elementary 优化工具 —— 选项][7]
|
||||
|
||||
顺便提示一下,这款工具仅仅是 elementary 桌面设置的前端。如果您知道准确的名称或属性,您可以直接在终端中修改配置。您在这款优化工具中获得的选项也可以在 `dconf` 编辑器中查找 `io.elementary` 路径以修改。
|
||||
顺便提示一下,这款工具仅仅是 elementary 桌面设置的前端。如果你知道准确的名称或属性,你可以直接在终端中修改配置。你在这款优化工具中获得的选项也可以在 `dconf` 编辑器中查找 `io.elementary` 路径以修改。
|
||||
|
||||
如果您在安装或使用优化工具时遇到了一些问题,您可以在评论区留言。
|
||||
|
||||
* * *
|
||||
如果你在安装或使用优化工具时遇到了一些问题,你可以在评论区留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -65,7 +65,7 @@ via: https://www.debugpoint.com/2021/07/elementary-tweaks-install/
|
||||
作者:[Arindam][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[imgradeone](https://github.com/imgradeone)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@@ -3,50 +3,50 @@
|
||||
[#]: author: (Jakub Kadlčík https://fedoramagazine.org/author/frostyx/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13673-1.html)
|
||||
|
||||
COPR 仓库中 4 个很酷的新项目(2021.07)
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
COPR 是个人软件仓库[集合][2],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
COPR 是个人软件仓库 [集合][2],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
|
||||
本文介绍了 COPR 中一些有趣的新项目。如果你第一次使用 COPR,请参阅 [COPR 用户文档][3]。
|
||||
|
||||
## [][4] Wike
|
||||
### Wike
|
||||
|
||||
[Wike][5] 是一个用于 GNOME 桌面的维基百科阅读器,在 GNOME Shell 中集成了搜索功能。它提供了对[在线百科全书][6]的无干扰访问。它的界面很简约,但它支持在多种语言之间切换文章、书签、文章目录、黑暗模式等。
|
||||
[Wike][5] 是一个用于 GNOME 桌面的维基百科阅读器,在 GNOME Shell 中集成了搜索功能。它提供了对 [在线百科全书][6] 的无干扰访问。它的界面很简约,但它支持在多种语言之间切换文章、书签、文章目录、黑暗模式等。
|
||||
|
||||
![][7]
|
||||
|
||||
### [][8] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库]][9]目前在 Fedora 33、34 和 Fedora Rawhide 提供 Wike。要安装它,请使用这些命令:
|
||||
该 [仓库][9] 目前为 Fedora 33、34 和 Fedora Rawhide 提供了 Wike。要安装它,请使用这些命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable xfgusta/wike
|
||||
sudo dnf install wike
|
||||
```
|
||||
|
||||
## [][10] DroidCam
|
||||
### DroidCam
|
||||
|
||||
我们正生活在一个混乱的时代,被隔离在家中,我们与朋友和同事的大部分互动都发生在一些视频会议平台上。如果你已经有一部手机,就不要把钱浪费在价格过高的网络摄像头上。[DroidCam][11] 让你将手机与电脑配对,并将其作为专用网络摄像头使用。通过 USB 线或通过 WiFi 进行连接。DroidCam 提供对摄像头的远程控制,并允许缩放、使用自动对焦、切换 LED 灯和其他便利功能。
|
||||
|
||||
![][12]
|
||||
|
||||
### [][13] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库][14]目前为在 Fedora 33 和 34 中提供 DroidCam。在安装之前,请更新你的系统并重新启动,或者确保你运行的是最新的内核版本,并安装了适当版本的 _kernel-headers_。
|
||||
该 [仓库][14] 目前为 Fedora 33 和 34 提供了 DroidCam。在安装之前,请更新你的系统并重新启动,或者确保你运行的是最新的内核版本,并安装了适当版本的 `kernel-headers`。
|
||||
|
||||
```
|
||||
sudo dnf update
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
Droidcam 依赖 _v4l2loopback_,必须从 [RPM Fusion 免费仓库][15]手动安装。
|
||||
Droidcam 依赖 `v4l2loopback`,必须从 [RPM Fusion 自由软件仓库][15] 手动安装。
|
||||
|
||||
```
|
||||
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
|
||||
@@ -54,16 +54,16 @@ sudo dnf install v4l2loopback
|
||||
sudo modprobe v4l2loopback
|
||||
```
|
||||
|
||||
现在安装 _droidcam_ 软件包:
|
||||
现在安装 `droidcam` 软件包:
|
||||
|
||||
```
|
||||
sudo dnf copr enable meeuw/droidcam
|
||||
sudo dnf install droidcam
|
||||
```
|
||||
|
||||
## [][16] Nyxt
|
||||
### Nyxt
|
||||
|
||||
[Nyxt][17] 是一个面向键盘、可无限扩展的网络浏览器,专为高级用户设计。它在很大程度上受到 Emacs 的启发,因此用 Common Lisp 实现和配置,提供熟悉的按键绑定([Emacs][18]、[vi][19]、[CUA][20])。
|
||||
[Nyxt][17] 是一个面向键盘、可无限扩展的 Web 浏览器,专为高级用户设计。它在很大程度上受到 Emacs 的启发,因此用 Common Lisp 实现和配置,提供熟悉的按键绑定([Emacs][18]、[vi][19]、[CUA][20])。
|
||||
|
||||
其他不能错过的杀手锏是一个内置的 REPL、[树形历史][21]、[缓冲区代替标签][22],还有[更多][17]。
|
||||
|
||||
@@ -71,33 +71,33 @@ Nyxt 与网络引擎无关,所以不用担心页面会以意外的方式呈现
|
||||
|
||||
![][23]
|
||||
|
||||
### [][24] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库][25]目前为 Fedora 33、34 和 Fedora Rawhide 提供 Nyxt。要安装它,请使用这些命令:
|
||||
该 [仓库][25] 目前为 Fedora 33、34 和 Fedora Rawhide 提供了 Nyxt。要安装它,请使用这些命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable teervo/nyxt
|
||||
sudo dnf install nyxt
|
||||
```
|
||||
|
||||
## [][26] Bottom
|
||||
### Bottom
|
||||
|
||||
[Bottom][27] 是一个具有可定制界面和多种功能的系统监控器,它从 [gtop][28]、[gotop][29] 和 [htop][30] 获得灵感。因此,它支持[进程][31]监控、[CPU][32]、[RAM][33]和[网络][34]使用监控。除了这些,它还提供了更多奇特的小部件,如[磁盘容量][35]使用情况,[温度传感器][36],和[电池][37]使用情况。
|
||||
[Bottom][27] 是一个具有可定制界面和多种功能的系统监控器,它从 [gtop][28]、[gotop][29] 和 [htop][30] 获得了灵感。因此,它支持 [进程][31] 监控、[CPU][32]、[RAM][33] 和 [网络][34] 使用监控。除了这些,它还提供了更多奇特的小部件,如 [磁盘容量][35] 使用情况,[温度传感器][36],和 [电池][37] 使用情况。
|
||||
|
||||
由于小部件的可自定义布局以及[可以只关注一个小部件并最大化它][38],Bottom 可以非常有效地利用屏幕空间。
|
||||
由于小部件的可自定义布局以及 [可以只关注一个小部件并最大化它][38],Bottom 可以非常有效地利用屏幕空间。
|
||||
|
||||
![][39]
|
||||
|
||||
### [][40] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库][41]提供为 Fedora 33、34 和 Fedora Rawhide 提供 Bottom。它也可用于 EPEL 7 和 8。要安装它,请使用这些命令:
|
||||
该 [仓库][41] 为 Fedora 33、34 和 Fedora Rawhide 提供了 Bottom。它也可用于 EPEL 7 和 8。要安装它,请使用这些命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable opuk/bottom
|
||||
sudo dnf install bottom
|
||||
```
|
||||
|
||||
使用 _btm_ 命令来运行该程序。
|
||||
使用 `btm` 命令来运行该程序。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -106,7 +106,7 @@ via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-july-2021
|
||||
作者:[Jakub Kadlčík][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (piaoshi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13669-1.html)
|
||||
|
||||
使用 Linux 终端查看你的电脑上有哪些文件
|
||||
======
|
||||
通过这个 Linux 教程学习如何使用 ls 命令在终端中列出文件。
|
||||
![List files on your computer][1]
|
||||
|
||||
要在有图形界面的计算机上列出文件,你通常可以打开一个文件管理器(Linux 上的 **Files**,MacOS 上的 **访达**,Windows 上的 **文件资源管理器**)来查看文件。
|
||||
> 通过这个 Linux 教程学习如何使用 ls 命令在终端中列出文件。
|
||||
|
||||
要在终端中列出文件,你可以使用 **ls** 命令来列出当前目录中的所有文件。而 **pwd** 命令可以告诉你当前所在的目录。
|
||||

|
||||
|
||||
要在有图形界面的计算机上列出文件,你通常可以打开一个文件管理器(Linux 上的 “文件”,MacOS 上的 “访达”,Windows 上的 “文件资源管理器”)来查看文件。
|
||||
|
||||
要在终端中列出文件,你可以使用 `ls` 命令来列出当前目录中的所有文件。而 `pwd` 命令可以告诉你当前所在的目录:
|
||||
|
||||
```
|
||||
$ pwd
|
||||
@@ -29,7 +31,7 @@ Templates
|
||||
Videos
|
||||
```
|
||||
|
||||
你可以通过 **\--all** 选项看到隐藏文件。
|
||||
你可以通过 `--all`(简写为 `-a`) 选项看到隐藏文件:
|
||||
|
||||
```
|
||||
$ pwd
|
||||
@@ -43,11 +45,11 @@ example.txt Templates
|
||||
Documents Videos
|
||||
```
|
||||
|
||||
如你所见,列出的前两项是点。单个点实际上是一个元位置,代表 _你当前所在的文件夹_ 。两个点表示你可以从当前位置返回的上级目录。也就是说,当前目录在另一个文件夹中。当你在计算机目录间移动时,你就可以利用这些元位置为自己创建快捷方式,或者增加你的路径的独特性。
|
||||
如你所见,列出的前两项是点。单个点(`.`)实际上是一个元位置,代表 _你当前所在的文件夹_ 。两个点(`..`)表示你可以从当前位置返回的上级目录。也就是说,当前目录在另一个文件夹中。当你在计算机目录间移动时,你就可以利用这些元位置为自己创建快捷方式,或者增加你的路径的独特性。
|
||||
|
||||
### 文件和文件夹以及如何区分它们
|
||||
|
||||
你可能会注意到,文件和文件夹是很难区分的。一些 Linux 发行版有一些漂亮的颜色设置,比如所有的文件夹都是蓝色的,文件是白色的,二进制文件是粉色或绿色的,等等。如果你没有看到这些颜色,你可以试试 **ls --color**。如果你有色盲症或者使用的不是彩色显示器,你可以使用 **\--classify** 选项替代:
|
||||
你可能会注意到,文件和文件夹是很难区分的。一些 Linux 发行版有一些漂亮的颜色设置,比如所有的文件夹都是蓝色的,文件是白色的,二进制文件是粉色或绿色的,等等。如果你没有看到这些颜色,你可以试试 `ls --color`。如果你有色盲症或者使用的不是彩色显示器,你可以使用 `--classify` 选项替代:
|
||||
|
||||
```
|
||||
$ pwd
|
||||
@@ -67,7 +69,7 @@ via: https://opensource.com/article/21/8/linux-list-files
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[piaoshi](https://github.com/piaoshi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
[#]: subject: (GNOME Web Canary is Now Available to Test Bleeding Edge Features)
|
||||
[#]: via: (https://news.itsfoss.com/gnome-web-canary/)
|
||||
[#]: author: (Ankush Das https://news.itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zd200572)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13683-1.html)
|
||||
|
||||
使用 GNOME Web 的 Canary 版本测试前沿功能
|
||||
======
|
||||
|
||||
> 如果你想测试高度不稳定的 GNOME Web 浏览器的前沿功能,Canary 版本就是为了这个。
|
||||
|
||||

|
||||
|
||||
Epiphany(或称 [GNOME Web][1])是一个 Linux 发行版上精简而功能强大的浏览器,你会发现它也是 elementary OS 的默认浏览器。
|
||||
|
||||
随同 GNOME 40 发布的 Epiphany 浏览器有一些 [改进和新增功能][2]。
|
||||
|
||||
而在幕后,经常有许多令人兴奋的提升和新增特性。因此,你可以选择为早期测试人员量身定制的 GNOME Web 技术预览版。
|
||||
|
||||
现在,它发布了一个新的 Canary 版本,你可以使用它来测试甚至在技术预览版中都没有的特性。
|
||||
|
||||
### GNOME Web Canary 版本
|
||||
|
||||
![][3]
|
||||
|
||||
GNOME Web 的 Canary 版本允许你测试甚至没有出现在最新 [WebKitGTK][4] 版本中的特性。
|
||||
|
||||
注意 Canary 版本应该是极其不稳定的,甚至稳定性比开发者技术预览版更差。
|
||||
|
||||
可是,使用 Canary 版本,终端用户可以在开发过程中的早期进行测试,帮助开发者发现灾难性 bug。
|
||||
|
||||
不只是终端用户的早期测试,Canary 版本还让 GNOME Web 的开发者的工作更轻松。
|
||||
|
||||
他们不再需要为了实现和测试一个新特性,来单独构建 WebKitGTK。
|
||||
|
||||
尽管开发者有一个 Flatpak SDK 可以简化开发人员的流程,但是这仍然是一项耗时的任务。
|
||||
|
||||
现在,没有了这个阻碍,开发速度也有可能提升。
|
||||
|
||||
### 怎样获得 Canary 版本?
|
||||
|
||||
首先,你需要使用以下命令添加 WebKit SDK Flatpak 远端仓库:
|
||||
|
||||
```
|
||||
flatpak --user remote-add --if-not-exists webkit https://software.igalia.com/flatpak-refs/webkit-sdk.flatpakrepo
|
||||
flatpak --user install https://nightly.gnome.org/repo/appstream/org.gnome.Epiphany.Canary.flatpakref
|
||||
```
|
||||
|
||||
完成后,你就可以使用提供的 [Flatpakref 文件][5] 安装啦!
|
||||
|
||||
测试 Canary 版本可以让更多的用户能够在此过程中帮助 GNOME Web 的开发人员。所以,这绝对是改进 GNOME Web 浏览器开发的急需补充。
|
||||
|
||||
更多技术细节,你可能需要看这位开发者发布的 [公告][6]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/gnome-web-canary/
|
||||
|
||||
作者:[Ankush Das][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/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://wiki.gnome.org/Apps/Web/
|
||||
[2]: https://news.itsfoss.com/gnome-web-new-tab/
|
||||
[3]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/Epiphany-Canary.png?w=940&ssl=1
|
||||
[4]: https://webkitgtk.org
|
||||
[5]: https://nightly.gnome.org/repo/appstream/org.gnome.Epiphany.Canary.flatpakref
|
||||
[6]: https://base-art.net/Articles/introducing-the-gnome-web-canary-flavor/
|
||||
@@ -3,14 +3,14 @@
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13681-1.html)
|
||||
|
||||
用 OneDriver GUI 工具在 Linux 中安装微软 OneDrive
|
||||
用 OneDriver GUI 工具在 Linux 中挂载微软 OneDrive
|
||||
======
|
||||
|
||||
在 Windows 上,微软提供了一个[免费云存储服务][1] OneDrive。它与 Windows 集成,你可以通过你的微软账户获得 5GB 的免费存储空间。
|
||||
在 Windows 上,微软提供了一个 [免费云存储服务][1] OneDrive。它与 Windows 集成,你可以通过你的微软账户获得 5GB 的免费存储空间。
|
||||
|
||||
这在 Windows 上很好用,但和谷歌一样,微软也没有在 Linux 桌面上提供 OneDrive 的本地客户端。
|
||||
|
||||
@@ -24,17 +24,17 @@
|
||||
|
||||
![OneDrive Linux illustration][4]
|
||||
|
||||
[OneDriver][5] 是一个免费的开源工具,允许你在 Linux 系统上挂载 OneDrive 文件。
|
||||
[OneDriver][5] 是一个自由而开源的工具,允许你在 Linux 系统上挂载 OneDrive 文件。
|
||||
|
||||
请记住,它不会像 OneDrive 在 Windows 系统上那样同步文件。它将 OneDrive 文件挂载在本地的挂载点上。你通过网络访问这些文件。
|
||||
|
||||
然而,它确实提供了一种混合方法。你在挂载的 OneDrive 中打开的文件也被下载到系统中。这意味着,你也可以离线访问打开的文件。如果你没有连接到互联网,这些文件将成为只读。
|
||||
|
||||
如果你在本地对文件做任何修改,如果你连接到互联网,它就会反映到 OneDrive 上。
|
||||
如果你在本地对文件做任何修改,并且连接到互联网,它就会反映到 OneDrive 上。
|
||||
|
||||
我注意到,在 GNOME 上的 Nautilus 文件管理器中,它会自动下载当前文件夹中的图像。在我的印象中,它们只有在我打开它们时才会被下载。
|
||||
|
||||
另一件事是,Nautilus 最初建立了缩略图缓存。OneDriver 在开始的时候可能会觉得有点慢,有点耗费资源,但最终会好起来。
|
||||
另一件事是,Nautilus 一开始会建立缩略图缓存。OneDriver 在开始的时候可能会觉得有点慢,有点耗费资源,但最终会好起来。
|
||||
|
||||
哦!你也可以挂载多个 OneDrive 账户。
|
||||
|
||||
@@ -48,7 +48,7 @@ sudo apt update
|
||||
sudo apt install onedriver
|
||||
```
|
||||
|
||||
对于 Ubuntu 21.04,你可以下载[其 PPA 中的 DEB 文件][6]来使用它。
|
||||
对于 Ubuntu 21.04,你可以下载 [其 PPA 中的 DEB 文件][6] 来使用它。
|
||||
|
||||
在 Fedora 上,你可以添加这个 COPR:
|
||||
|
||||
@@ -63,7 +63,7 @@ Arch 用户可以在 AUR 中找到它。
|
||||
|
||||
![Search for OneDriver][7]
|
||||
|
||||
首次运行时,它会给出一个奇怪的空界面。点击 “+” 号,选择一个文件夹或创建一个新的文件夹,在那里你将挂载 OneDrive。在我的例子中,我在我的家目录下创建了一个名为 One_drive 的新文件夹。
|
||||
首次运行时,它会给出一个奇怪的空界面。点击 “+” 号,选择一个文件夹或创建一个新的文件夹,OneDrive 会挂载在那里。在我的例子中,我在我的家目录下创建了一个名为 `One_drive` 的新文件夹。
|
||||
|
||||
![Click on + sign to add a mount point for OneDrive][8]
|
||||
|
||||
@@ -73,7 +73,7 @@ Arch 用户可以在 AUR 中找到它。
|
||||
|
||||
![one drive permission][10]
|
||||
|
||||
登陆后,你可以在挂载的目录中看到 OneDrive 的文件。
|
||||
登录后,你可以在挂载的目录中看到 OneDrive 的文件。
|
||||
|
||||
![OneDrive mounted in Linux][11]
|
||||
|
||||
@@ -81,9 +81,9 @@ Arch 用户可以在 AUR 中找到它。
|
||||
|
||||
![Autostart OneDriver mounting][12]
|
||||
|
||||
总的来说,OneDriver 是一个可以在 Linux 上访问 OneDrive 的不错的免费工具。它可能无法像[高级 Insync 服务][13]那样提供完整的同步设施,但对于有限的需求来说,它做得不错。
|
||||
总的来说,OneDriver 是一个可以在 Linux 上访问 OneDrive 的不错的免费工具。它可能无法像 [高级 Insync 服务][13] 那样提供完整的同步设施,但对于有限的需求来说,它做得不错。
|
||||
|
||||
如果你使用这个漂亮的工具,请分享你的使用经验。如果你喜欢这个项目,也许可以给它一个 [GitHub 上的关注][5]。
|
||||
如果你使用这个漂亮的工具,请分享你的使用经验。如果你喜欢这个项目,也许可以给它一个 [GitHub 上的星标][5]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -92,7 +92,7 @@ via: https://itsfoss.com/onedriver/
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
130
published/20210803 Set up a VPN server on your Linux PC.md
Normal file
130
published/20210803 Set up a VPN server on your Linux PC.md
Normal file
@@ -0,0 +1,130 @@
|
||||
[#]: subject: (Set up a VPN server on your Linux PC)
|
||||
[#]: via: (https://opensource.com/article/21/8/openvpn-server-linux)
|
||||
[#]: author: (D. Greg Scott https://opensource.com/users/greg-scott)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (perfiffer)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13680-1.html)
|
||||
|
||||
如何在免费 WiFi 中保护隐私(一)
|
||||
======
|
||||
|
||||
> 第一步是安装一个“虚拟专用网络”服务器。
|
||||
|
||||

|
||||
|
||||
你是否连接到了不受信任的网络,例如酒店或咖啡馆的 WiFi,而又需要通过智能手机和笔记本电脑安全浏览互联网?通过使用虚拟专用网络,你可以匿名访问不受信任的网络,就像你在专用网络上一样安全。
|
||||
|
||||
“虚拟专用网络” 是保护私人数据的绝佳工具。通过使用 “虚拟专用网络”,你可以在保持匿名的同时连接到互联网上的专用网络。
|
||||
|
||||
可选的 “虚拟专用网络” 服务有很多,[0penVPN][2] 依然是很多人在使用不受信任的网络时保护私人数据的第一选择。
|
||||
|
||||
0penVPN 在两点之间创建一个加密通道,防止第三方访问你的网络流量数据。通过设置你的 “虚拟专用网络” 服务,你可以成为你自己的 “虚拟专用网络” 服务商。许多流行的 “虚拟专用网络” 服务都使用 0penVPN,所以当你可以掌控自己的网络时,为什么还要将你的网络连接绑定到特定的提供商呢?
|
||||
|
||||
### 搭建 Linux 服务器
|
||||
|
||||
首先,在备用 PC 上安装一份 Linux。本例使用 Fedora,但是不论你使用的是什么 Linux 发行版,步骤基本是相同的。
|
||||
|
||||
从 [Fedora 项目][3] 网站下载最新的 Fedora ISO 副本。制作一个 USB 启动盘,将其插入到你的 PC 并启动,然后安装操作系统。如果你从未制作过可引导的 USB 启动盘,可以了解一下 [Fedora Media Writer][4]。如果你从未安装过 Linux,请阅读 [三步安装 Linux][5]。
|
||||
|
||||
### 设置网络
|
||||
|
||||
安装完成 Fedora 操作系统后,登录到控制台或者 SSH 会话。
|
||||
|
||||
更新到最新并重新启动:
|
||||
|
||||
```
|
||||
$ sudo dnf update -y && reboot
|
||||
```
|
||||
|
||||
重新登录并关闭防火墙:
|
||||
|
||||
```
|
||||
systemctl disable firewalld.service
|
||||
systemctl stop firewalld.service
|
||||
```
|
||||
|
||||
你可能希望在此系统上为你的内部网络添加适当的防火墙规则。如果是这样,请在关闭所有防火墙规则后完成 0penVPN 的设置和调试,然后添加本地防火墙规则。想要了解更多,请参照 [在 Linux 上设置防火墙][6]。
|
||||
|
||||
### 设置 IP 地址
|
||||
|
||||
你需要在你的本地网络设置一个静态 IP 地址。下面的命令假设在一个名为 `ens3` 的设备上有一个名为 `ens3` 的<ruby>网络管理器<rt>Network Manager</rt></ruby>连接。你的设备和连接名称可能不同,你可以通过打开 SSH 会话或从控制台输入以下命令:
|
||||
|
||||
```
|
||||
$ sudo nmcli connection show
|
||||
NAME UUID TYPE DEVICE
|
||||
ens3 39ad55bd-adde-384a-bb09-7f8e83380875 ethernet ens3
|
||||
```
|
||||
|
||||
你需要确保远程用户能够找到你的 “虚拟专用网络” 服务器。有两种方法可以做到这一点。你可以手动设置它的 IP 地址,或者将大部分工作交给你的路由器去完成。
|
||||
|
||||
#### 手动配置一个 IP 地址
|
||||
|
||||
通过以下命令来设置静态 IP 地址、前缀、网关和 DNS 解析器,用来替换掉原有的 IP 地址:
|
||||
|
||||
```
|
||||
$ sudo nmcli connection modify ens3 ipv4.addresses 10.10.10.97/24
|
||||
$ sudo nmcli connection modify ens3 ipv4.gateway 10.10.10.1
|
||||
$ sudo nmcli connection modify ens3 ipv4.dns 10.10.10.10
|
||||
$ sudo nmcli connection modify ens3 ipv4.method manual
|
||||
$ sudo nmcli connection modify ens3 connection.autoconnect yes
|
||||
```
|
||||
|
||||
设置主机名:
|
||||
|
||||
```
|
||||
$ sudo hostnamectl set-hostname OVPNserver2020
|
||||
```
|
||||
|
||||
如果你运行了一个本地的 DNS 服务,你需要设置一个 DNS 条目,将主机名指向 “虚拟专用网络” 服务器的 IP 地址。
|
||||
|
||||
重启并确保系统的网络运行正常。
|
||||
|
||||
#### 在路由器中配置 IP 地址
|
||||
|
||||
在你的网络当中应该有一台路由器。你可能已经购买了它,或者从互联网服务提供商(ISP)那里获得了一台。无论哪种方式,你的路由器可能都有一个内置的 DHCP 服务,可以为连接到网络上的每台设备分配一个 IP 地址。你的新 “虚拟专用网络” 服务器也是属于网络的一台设备,因此你可能已经注意到它会自动分配一个 IP 地址。
|
||||
|
||||
这里的潜在问题是你的路由器不能保证每台设备都能在重新连接后获取到相同的 IP 地址。路由器确实尝试保持 IP 地址一致,但这会根据当时连接的设备数量而发生变化。
|
||||
|
||||
但是,几乎所有的路由器都会有一个界面,允许你为特定设备调停和保留 IP 地址。
|
||||
|
||||
![Router IP address settings][7]
|
||||
|
||||
路由器没有统一的界面,因此请在你的路由器接口中搜索 “DHCP” 或 “Static IP address” 选项。为你的服务器分配自己的预留 IP 地址,使其在网络中保持 IP 不变。
|
||||
|
||||
### 连接到服务器
|
||||
|
||||
默认情况下,你的路由器可能内置了防火墙。这通常很好,因为你不希望网络之外的人能够强行进入你的任何计算机。但是,你必须允许发往 “虚拟专用网络” 服务器的流量通过防火墙,否则你的 “虚拟专用网络” 将无法访问,这种情况下你的 “虚拟专用网络” 服务器将形同虚设。
|
||||
|
||||
你至少需要一个来自互联网服务提供商的公共静态 IP 地址。使用其静态 IP 地址设置路由器的公共端,然后将你的 0penVPN 服务器放在专用端,在你的网络中使用专用静态 IP 地址。 0penVPN 默认使用 UDP 1194 端口。配置你的路由器,将你的公网 “虚拟专用网络” IP 地址的 UDP 1194 端口转发到 0penVPN 服务器上的 UDP 1194 端口。如果你决定使用不同的 UDP 端口,请相应地调整端口号。
|
||||
|
||||
### 准备好,我们开始下一步
|
||||
|
||||
在本文中,你在服务器上安装并配置了一个操作系统,这已经成功了一半。在下一篇文章中,你将解决安装和配置 0penVPN 本身的问题。同时,请熟悉你的路由器并确保你可以从外部访问你的服务器。但是请务必在测试后关闭端口转发,直到你的 “虚拟专用网络” 服务启动并运行。
|
||||
|
||||
本文的部分内容改编自 D. Greg Scott 的博客,并经许可重新发布。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/openvpn-server-linux
|
||||
|
||||
作者:[D. Greg Scott][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/greg-scott
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: https://openvpn.net/
|
||||
[3]: http://getfedora.org
|
||||
[4]: https://opensource.com/article/20/10/fedora-media-writer
|
||||
[5]: https://opensource.com/article/21/2/linux-installation
|
||||
[6]: https://www.redhat.com/sysadmin/secure-linux-network-firewall-cmd
|
||||
[7]: https://opensource.com/sites/default/files/uploads/reserved-ip.jpg (Router IP address settings)
|
||||
[8]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[9]: https://opensource.com/article/20/9/firewall
|
||||
[10]: https://www.dgregscott.com/how-to-build-a-vpn-in-four-easy-steps-without-spending-one-penny/
|
||||
@@ -3,20 +3,22 @@
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (piaoshi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13674-1.html)
|
||||
|
||||
使用 Linux 终端浏览你的计算机
|
||||
======
|
||||
学习在 Linux 终端中从一个目录切换到另一个目录。
|
||||
![Move around your computer][1]
|
||||
|
||||
> 学习在 Linux 终端中从一个目录切换到另一个目录。
|
||||
|
||||

|
||||
|
||||
要在图形界面中浏览你的计算机上的文件夹,你可能习惯于打开一个窗口来“进入”你的计算机,然后双击一个文件夹,再双击一个子文件夹,如此反复。你也可以使用箭头按钮或按键来回溯。
|
||||
|
||||
而要在终端中浏览你的计算机,你可以利用 **cd** 命令。你可以使用 **cd ..** 回到 _上一级_ 目录,或者使用 **cd ./另一个/文件夹的/路径** 来跳过许多文件夹进入一个特定的位置。
|
||||
而要在终端中浏览你的计算机,你可以利用 `cd` 命令。你可以使用 `cd ..` 回到 _上一级_ 目录,或者使用 `cd ./另一个/文件夹的/路径` 来跳过许多文件夹进入一个特定的位置。
|
||||
|
||||
你在互联网上已经使用的 URL 的概念,实际上直接来自 [POSIX][2]。当你浏览某个网站的一个特定页面时,比如 `http://www.example.com/tutorials/lesson2.html`,你实际上做的是进入 `/var/www/imaginarysite/tutorials/` 目录,并打开一个叫 `classic2.html` 的文件。当然,你是在网络浏览器中打开它的,浏览器会将所有那些看起来奇怪的 HTML 代码解释成漂亮的文本和图片。但这两者的思路是完全一样的。
|
||||
你在互联网上已经使用的 URL 的概念,实际上直接来自 [POSIX][2]。当你浏览某个网站的一个特定页面时,比如 `http://www.example.com/tutorials/lesson2.html`,你实际上做的是进入 `/var/www/imaginarysite/tutorials/` 目录,并打开一个叫 `classic2.html` 的文件。当然,你是在 Web 浏览器中打开它的,浏览器会将所有那些看起来奇怪的 HTML 代码解释成漂亮的文本和图片。但这两者的思路是完全一样的。
|
||||
|
||||
如果你把你的计算机看成是互联网(或者把互联网看成是计算机会更合适),那么你就能理解如何在你的文件夹和文件中遨游了。如果从你的用户文件夹(你的家目录,或简记为 `~`)开始,那么你想切换到的文件夹都是相对于这个文件夹而言的:
|
||||
|
||||
@@ -34,7 +36,7 @@ $ pwd
|
||||
|
||||
### 用 Tab 键自动补全
|
||||
|
||||
键盘上的 **Tab** 键可以自动补全你开始输入的文件夹和文件的名字。如果你要 **cd** 到 `~/Documents` 文件夹,那么你只需要输入 `cd ~/Doc`,然后按 **Tab** 键即可。你的 Shell 会自动补全 `uments`。这不仅仅是一个令人愉快的便利工具,它也是一种防止错误的方法。如果你按下 **Tab** 键而没有任何东西自动补全,那么可能你 _认为_ 存在于某个位置的文件或文件件实际上并不存在。即使有经验的 Linux 用户也会试图切换到一个当前目录下不存在的文件夹,所以你可以经常使用 **pwd** 和 **ls** 命令来确认你确实在你认为你在的目录、以及你的当前目录确实包含了你认为它包含的文件。
|
||||
键盘上的 `Tab` 键可以自动补全你开始输入的文件夹和文件的名字。如果你要 `cd` 到 `~/Documents` 文件夹,那么你只需要输入 `cd ~/Doc`,然后按 `Tab` 键即可。你的 Shell 会自动补全 `uments`。这不仅仅是一个令人愉快的便利工具,它也是一种防止错误的方法。如果你按下 `Tab` 键而没有任何东西自动补全,那么可能你 _认为_ 存在于某个位置的文件或文件件实际上并不存在。即使有经验的 Linux 用户也会试图切换到一个当前目录下不存在的文件夹,所以你可以经常使用 `pwd` 和 `ls` 命令来确认你确实在你认为你在的目录、以及你的当前目录确实包含了你认为它包含的文件。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -43,7 +45,7 @@ via: https://opensource.com/article/21/8/navigate-linux-directories
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[piaoshi](https://github.com/piaoshi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
52
published/20210804 Move files in the Linux terminal.md
Normal file
52
published/20210804 Move files in the Linux terminal.md
Normal file
@@ -0,0 +1,52 @@
|
||||
[#]: subject: (Move files in the Linux terminal)
|
||||
[#]: via: (https://opensource.com/article/21/8/move-files-linux)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13677-1.html)
|
||||
|
||||
基础:在 Linux 终端中移动文件
|
||||
======
|
||||
|
||||
> 使用 mv 命令将一个文件从一个位置移动到另一个位置。
|
||||
|
||||

|
||||
|
||||
要在有图形界面的计算机上移动一个文件,你要打开该文件当前所在的文件夹,然后打开另一个窗口导航到你想把文件移到的文件夹。最后,你把文件从一个窗口拖到另一个窗口。
|
||||
|
||||
要在终端中移动文件,你可以使用 `mv` 命令将文件从一个位置移动到另一个位置。
|
||||
|
||||
```
|
||||
$ mv example.txt ~/Documents
|
||||
|
||||
$ ls ~/Documents
|
||||
example.txt
|
||||
```
|
||||
|
||||
在这个例子中,你已经把 `example.txt` 从当前文件夹移到了主目录下的 `Documents` 文件夹中。
|
||||
|
||||
只要你知道一个文件在 _哪里_,又想把它移到 _哪里_ 去,你就可以把文件从任何地方移动到任何地方,而不管你在哪里。与在一系列窗口中浏览你电脑上的所有文件夹以找到一个文件,然后打开一个新窗口到你想让该文件去的地方,再拖动该文件相比,这可以大大节省时间。
|
||||
|
||||
默认情况下,`mv` 命令完全按照它被告知的那样做:它将一个文件从一个位置移动到另一个位置。如果在目标位置已经存在一个同名的文件,它将被覆盖。为了防止文件在没有警告的情况下被覆盖,请使用 `--interactive`(或简写 `-i`)选项。
|
||||
|
||||
```
|
||||
$ mv -i example.txt ~/Documents
|
||||
mv: overwrite '/home/tux/Documents/example.txt'?
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/move-files-linux
|
||||
|
||||
作者:[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/ch01s05.svg_.png?itok=PgKQEDZ7 (Moving files)
|
||||
102
published/20210807 How to Install Java on Fedora Linux.md
Normal file
102
published/20210807 How to Install Java on Fedora Linux.md
Normal file
@@ -0,0 +1,102 @@
|
||||
[#]: subject: "How to Install Java on Fedora Linux"
|
||||
[#]: via: "https://itsfoss.com/install-java-fedora/"
|
||||
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13694-1.html"
|
||||
|
||||
如何在 Fedora Linux 上安装 Java
|
||||
======
|
||||
|
||||

|
||||
|
||||
不管是爱它还是恨它,都很难避开 Java。
|
||||
|
||||
Java 仍然是一种非常流行的编程语言,在学校里教,在企业里用。
|
||||
|
||||
如果你想使用基于 Java 的工具或用 Java 编程,你就需要在你的系统上安装 Java。
|
||||
|
||||
这就变得很混乱,因为围绕着 Java 有很多技术术语。
|
||||
|
||||
* <ruby>Java 开发工具包<rt>Java Development Kit</rt></ruby>(JDK)用于创建 Java 程序
|
||||
* <ruby>Java 运行环境<rt>Java Runtime Environment</rt></ruby>(JRE)或 Java 虚拟机(JVM),用于运行 Java 程序。
|
||||
|
||||
除此之外,你还会遇到 [OpenJDK][1] 和 [Oracle Java SE][2]。推荐使用 OpenJDK ,因为它是开源的。如果你有专门的需求,那么你应该选择 Oracle Java SE。
|
||||
|
||||
还有一件事。即使是 OpenJDK 也有几个版本可供选择。在写这篇文章的时候,Fedora 34 有 OpenJDK 1.8、OpenJDK 11 和 OpenJDK 16 可用。
|
||||
|
||||
你可以自行决定想要哪个Java版本。
|
||||
|
||||
### 在 Fedora Linux 上安装 Java
|
||||
|
||||
首先,检查是否已经安装了 Java,以及它是哪个版本。我不是在开玩笑。Fedora 通常预装了 Java。
|
||||
|
||||
要检查它,请使用以下命令:
|
||||
|
||||
```
|
||||
java -version
|
||||
```
|
||||
|
||||
正如你在下面的截图中看到的,我的 Fedora 系统上安装了 Java 11(OpenJDK 11)。
|
||||
|
||||
![Check Java version][3]
|
||||
|
||||
假设你想安装另一个版本的 Java。你可以用下面的命令检查可用的选项:
|
||||
|
||||
```
|
||||
sudo dnf search openjdk
|
||||
```
|
||||
|
||||
这里的 `sudo` 不是必须的,但它会刷新 `sudo` 用户的元数据,这在你安装另一个版本的 Java 时会有帮助。
|
||||
|
||||
上面的命令将显示很多输出,其中有很多看起来相似的软件包。你必须专注于最初的几个词来理解不同的版本。
|
||||
|
||||
![Available Java versions in Fedora][4]
|
||||
|
||||
例如,要安装 Java 8(OpenJDK 1.8),包的名字应该是 `java-1.8.0-openjdk.x86_64` 或者 `java-1.8.0-openjdk`。用它来安装:
|
||||
|
||||
```
|
||||
sudo dnf install java-1.8.0-openjdk.x86_64
|
||||
```
|
||||
|
||||
![Install Java Fedora][5]
|
||||
|
||||
这就好了。现在你的系统上同时安装了 Java 11 和 Java 8。但你将如何使用其中一个呢?
|
||||
|
||||
#### 在 Fedora 上切换 Java 版本
|
||||
|
||||
你正在使用的 Java 版本保持不变,除非你明确改变它。使用这个命令来列出系统上安装的 Java 版本:
|
||||
|
||||
```
|
||||
sudo alternatives --config java
|
||||
```
|
||||
|
||||
你会注意到在 Java 版本前有一个数字。Java 版本前的 `+` 号表示当前正在使用的 Java 版本。
|
||||
|
||||
你可以指定这个数字来切换 Java 版本。因此,在下面的例子中,如果我输入 2,它将把系统中的 Java 版本从 Java 11 改为 Java 8。
|
||||
|
||||
![Switching between installed Java versions][6]
|
||||
|
||||
这就是你在 Fedora 上安装 Java 所需要做的一切。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-java-fedora/
|
||||
|
||||
作者:[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://openjdk.java.net/
|
||||
[2]: https://www.oracle.com/java/technologies/javase-downloads.html
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/check-java-version-fedora.png?resize=800%2C271&ssl=1
|
||||
[4]: https://itsfoss.com/wp-content/uploads/2021/08/available-java-versions-fedora-800x366.webp
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/install-java-fedora.png?resize=800%2C366&ssl=1
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/switch-java-versions-fedora.png?resize=800%2C513&ssl=1
|
||||
@@ -0,0 +1,73 @@
|
||||
[#]: subject: "It’s Time for Ubuntu to Opt for a Hybrid Rolling Release Model"
|
||||
[#]: via: "https://news.itsfoss.com/ubuntu-hybrid-release-model/"
|
||||
[#]: author: "Abhishek https://news.itsfoss.com/author/root/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "wxy"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13666-1.html"
|
||||
|
||||
是时候让 Ubuntu 选择混合滚动发布模式了
|
||||
======
|
||||
|
||||
> 在两个 LTS 版本之间有三个短期版本。Ubuntu 应该用滚动发布模式来取代它们。
|
||||
|
||||

|
||||
|
||||
即使你不是 Ubuntu 的用户,你可能也知道它的发布模式。
|
||||
|
||||
有一个 [长期支持(LTS)版本][1],每两年发布一次,并有五年的支持。在这两个 LTS 版本之间,我们可以看到三个非 LTS 版本,它们的发布时间间隔为 6 个月。
|
||||
|
||||
LTS 版本会保持内核不会变化(除非你选择 [HWE 内核][2]),它还维持了各种软件组件不变以提供稳定的生产环境。
|
||||
|
||||
介于两者之间的非 LTS 版 Ubuntu 具有 Ubuntu 的新功能、更新一些的内核、新的桌面环境以及 Ubuntu 软件库中的各种软件的新版本。
|
||||
|
||||
这些非 LTS 版本作为“试验场”,为最终在 LTS 版本中出现的功能提供测试,这已不是什么秘密。
|
||||
|
||||
这就是为什么我建议摆脱这些中间版本,在 LTS 版本之间选择 [滚动发布][3] 模式。个中原因,请听我说。
|
||||
|
||||
### 在 LTS 发布之间进行滚动开发
|
||||
|
||||
六个月一次的发布计划给 Ubuntu 开发者制定了一个紧凑的工作时间表。这是一个好的方法,它可以使他们的目标集中在一个适当的路线图上。
|
||||
|
||||
但是,这也为在每个版本中提供“更多”新功能带来了额外的压力。如果时间很短,这不可能总是做到。还记得 [Ubuntu 不得不从 21.04 版本中删除 GNOME 40][4] 吗?因为开发者没有足够的时间来完成它。
|
||||
|
||||
另外,最终用户(比如你和我)想选择留在非 LTS 版本中也是不可行的。其支持在九个月后结束,这意味着即使你没有立即升级到下一个非 LTS 的 Ubuntu 版本,最终你也不得不这样做。如果你在 6 个月内没升级,那你可能就得在 9 个月内升级。
|
||||
|
||||
我知道你会说,升级 Ubuntu 版本很简单。点击几下,良好的网速和一个潜在的备份就可以让你在新的 Ubuntu 版本上没有什么麻烦。
|
||||
|
||||
我的问题是,为什么要这么麻烦。滚动发布会更简单。让升级在 LTS 版本之间进行。
|
||||
|
||||
开发人员在新功能准备好的时候发布。用户随着系统更新不断得到升级,而不是每 6 个月或 9 个月做一次“重大升级”。
|
||||
|
||||
你看,那些选择非 LTS 版本的人是那些想要新功能的人,让他们通过滚动发布获得新功能。LTS 的发布时间表保持不变,每两年来一次。
|
||||
|
||||
### Bug 测试?像其他滚动发布的版本一样做个测试分支好了
|
||||
|
||||
当我说滚动发布时,我并不是指像 Arch Linux 那样的滚动。它应该是像 Manjaro 那样的滚动。换句话说,在测试后推出升级版,而不是直接在野外发布。
|
||||
|
||||
目前,新的 Ubuntu 版本有测试版,以便早期采用者可以测试它并向开发者提供反馈。这可以通过保留测试和稳定分支来实现,就像许多其他滚动发布的版本一样。
|
||||
|
||||
### 你对滚动发布怎么看?
|
||||
|
||||
我知道 Ubuntu 的铁杆用户期待着每一次的发布。代号、吉祥物、艺术品和墙纸,这些都是 Ubuntu 的传统的一部分。我们应该打破这种传统吗?
|
||||
|
||||
这只是我的看法,我很想听听你的看法。Ubuntu 应该选择这种混合滚动模式还是坚持目前的模式?你怎么看呢?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/ubuntu-hybrid-release-model/
|
||||
|
||||
作者:[Abhishek][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/root/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/long-term-support-lts/
|
||||
[2]: https://itsfoss.com/ubuntu-hwe-kernel/
|
||||
[3]: https://itsfoss.com/rolling-release/
|
||||
[4]: https://news.itsfoss.com/no-gnome-40-in-ubuntu-21-04/
|
||||
@@ -0,0 +1,84 @@
|
||||
[#]: subject: "Remove files and folders in the Linux terminal"
|
||||
[#]: via: "https://opensource.com/article/21/8/remove-files-linux-terminal"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "unigeorge"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13687-1.html"
|
||||
|
||||
基础:在 Linux 终端中删除文件和文件夹
|
||||
======
|
||||
|
||||
> 本教程讲述了如何在 Linux 终端中安全地删除文件和文件夹。
|
||||
|
||||

|
||||
|
||||
要想使用图形化界面删除计算机上的文件,你可能会直接将文件或文件夹拖拽到 “垃圾箱” 或 “回收站”。或者你也可以选择要删除的文件或文件夹,右键单击并选择 **删除**。
|
||||
|
||||
而在终端中删除文件或文件夹时并没有垃圾箱一说(至少默认情况下没有)。在图形化桌面上,`Trash`(即垃圾箱文件夹)是一个受保护的目录,保护机制可以防止用户不小心将该目录删除,或将其从默认位置移动从而导致找不到它。Trash 本质不过是一个被高度管理的文件夹,因此你可以创建自己的 Trash 文件夹以在终端中使用。
|
||||
|
||||
### 为终端设置一个垃圾箱
|
||||
|
||||
在家目录中创建一个名为 `Trash` 的目录:
|
||||
|
||||
```
|
||||
$ mkdir ~/Trash
|
||||
```
|
||||
|
||||
### 删除文件
|
||||
|
||||
要删除文件或文件夹时,使用 `mv` 命令将文件或文件夹移至 `Trash` 中:
|
||||
|
||||
```
|
||||
$ mv example.txt ~/Trash
|
||||
```
|
||||
|
||||
### 永久删除文件或文件夹
|
||||
|
||||
当你准备从系统中永久删除某个文件或文件夹时,可以使用 `rm` 命令清除垃圾箱文件夹中的所有数据。通过将 `rm` 命令指向星号(`*`),可以删除 `Trash` 文件夹内的所有文件和文件夹,而不会删除 `Trash` 文件夹本身。因为用户可以方便且自由地创建目录,所以即使不小心删除了 `Trash` 文件夹,你也可以再次新建一个。
|
||||
|
||||
```
|
||||
$ rm --recursive ~/Trash/*
|
||||
```
|
||||
|
||||
### 删除空目录
|
||||
|
||||
删除空目录有一个专门的命令 `rmdir`,它只能用来删除空目录,从而保护你免受递归删除错误的影响。
|
||||
|
||||
```
|
||||
$ mkdir full
|
||||
$ touch full/file.txt
|
||||
$ rmdir full
|
||||
rmdir: failed to remove 'full/': Directory not empty
|
||||
|
||||
$ mkdir empty
|
||||
$ rmdir empty
|
||||
```
|
||||
|
||||
### 更好的删除方式
|
||||
|
||||
此外还有一些并没有默认安装在终端上的 [删除文件命令][2],你可以从软件库安装它们。这些命令管理和使用的 `Trash` 文件夹与你在桌面模式使用的是同一个(而非你自己单独创建的),从而使删除文件变得更加方便。
|
||||
|
||||
```
|
||||
$ trash ~/example.txt
|
||||
$ trash --list
|
||||
example.txt
|
||||
$ trash --empty
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/remove-files-linux-terminal
|
||||
|
||||
作者:[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/ch01s10.svg_.png?itok=p07au80e (Removing files)
|
||||
[2]: https://www.redhat.com/sysadmin/recover-file-deletion-linux
|
||||
@@ -0,0 +1,104 @@
|
||||
[#]: subject: "The Wait is Over! elementary OS 6 ‘Odin’ is Finally Here With Exciting Changes"
|
||||
[#]: via: "https://news.itsfoss.com/elementary-os-6-release/"
|
||||
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "imgradeone"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13670-1.html"
|
||||
|
||||
久等了!elementary OS 6 “Odin” 正式发布,带来令人激动的新变化
|
||||
======
|
||||
|
||||
> 基于 Ubuntu 20.04 LTS,备受期待的 elementary OS 6 终于可以下载了。
|
||||
|
||||

|
||||
|
||||
[2021 年最值得期待的 Linux 发行版][1] 之一,终于来了。
|
||||
|
||||
elementary OS 6 基于 Ubuntu 20.04 LTS,它大幅改进了用户体验和安全性。
|
||||
|
||||
虽然我们已经列出了 [elementary OS 6 的新功能列表][2],但咱们还是来看看本次更新的主要亮点吧。
|
||||
|
||||
### 正式引入暗黑模式
|
||||
|
||||
![][3]
|
||||
|
||||
elementary OS 6 加入这个功能可能为时太晚,但至少他们做了极大的努力,让整个系统拥有一致的暗黑模式体验。
|
||||
|
||||
你也会注意到,预装应用和应用中心里部分适配过的应用都支持暗黑模式。
|
||||
|
||||
暗黑模式在安装 elementary OS 6 后也可以直接在欢迎页设置。
|
||||
|
||||
### 通知优化
|
||||
|
||||
![][4]
|
||||
|
||||
通知现在支持操作按钮和图标徽章,视觉更舒适,也更加易用。
|
||||
|
||||
### Flatpak 优先原则
|
||||
|
||||
![][5]
|
||||
|
||||
为了加强隐私保护和安全性,elementary OS 6 提供了开箱即用的 Flatpak 应用支持。
|
||||
|
||||
现在,不仅仅是系统应用,在应用中心,所有应用都已经打包为 Flatpak 格式。
|
||||
|
||||
### 多点触控手势
|
||||
|
||||
![][6]
|
||||
|
||||
对于触控板和触摸屏用户,elementary OS 6 带来了不错的手势交互,你完全可以借助手势来穿梭于系统中。
|
||||
|
||||
你甚至可以通过手势来忽略通知。
|
||||
|
||||
### 新应用,新更新
|
||||
|
||||
本次更新中,待办事项和固件更新正式加入预装应用。
|
||||
|
||||
同时,大部分系统应用(如邮件)也重构了 UI,以及获得了一些新功能。
|
||||
|
||||
### 其他重要改进
|
||||
|
||||
![][7]
|
||||
|
||||
如果你想了解更多关于本次更新的内容,我强烈建议你试用 elementary OS 6 来自行探索。
|
||||
|
||||
当然,如果你现在就想速览其他重要的新功能,那么我列出几个:
|
||||
|
||||
* 在安装应用中心之外的第三方应用时会有警告。
|
||||
* 在向终端粘贴需要 root 权限的命令时会有警告。
|
||||
* 更便于区分多任务视图中活动窗口的细节变化。
|
||||
* 系统设置内置了在线账户集成。
|
||||
* 辅助功能优化。
|
||||
* 全新壁纸。
|
||||
* 改进的安装器。
|
||||
|
||||
### 下载 elementary OS 6
|
||||
|
||||
你现在可以从 elementary OS 的官网获取 elementary OS 的最新版本。如需了解详情,你也可以查阅 [官方公告][8]。
|
||||
|
||||
- [下载 elementary OS 6][9]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/elementary-os-6-release/
|
||||
|
||||
作者:[Ankush Das][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://news.itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://news.itsfoss.com/linux-distros-for-2021/
|
||||
[2]: https://news.itsfoss.com/elementary-os-6-features/
|
||||
[3]: https://news.itsfoss.com/wp-content/uploads/2021/08/onboarding-dark.png
|
||||
[4]: https://news.itsfoss.com/wp-content/uploads/2021/06/notification-badge-elementary-os-6.png
|
||||
[5]: https://news.itsfoss.com/wp-content/uploads/2021/08/appcenter.png
|
||||
[6]: https://news.itsfoss.com/wp-content/uploads/2021/08/multitouch-multitasking.png
|
||||
[7]: https://news.itsfoss.com/wp-content/uploads/2021/08/elementary-os-6-terminal-paste-protection.png
|
||||
[8]: https://blog.elementary.io/elementary-os-6-odin-released/
|
||||
[9]: https://elementary.io
|
||||
@@ -0,0 +1,174 @@
|
||||
[#]: subject: "Top 11 New Features in elementary OS 6 Linux Release"
|
||||
[#]: via: "https://news.itsfoss.com/elementary-os-6-features/"
|
||||
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "wxy"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13678-1.html"
|
||||
|
||||
elementary OS 6 Linux 中的 11 个亮点
|
||||
======
|
||||
|
||||
> elementary OS 6 终于来了。让我们看一下这个主要版本中的重要亮点。
|
||||
|
||||

|
||||
|
||||
elementary OS 6 是其 5.x 系列经过几年更新后的一次重大升级。
|
||||
|
||||
虽然 5.x 系列也有许多功能更新和改进,但 [elementary OS 6][1] 的努力成果看起来令人兴奋。
|
||||
|
||||
在这里,让我们来看看 elementary OS 6 引入的所有新功能和变化。
|
||||
|
||||
### 1、暗黑风格及强调色
|
||||
|
||||
![][2]
|
||||
|
||||
[elementary OS][3] 暗黑风格的主题与现在主流的工作方式类似,是一种选择的偏好。你可以在安装 elementary OS 6 之后,在欢迎屏幕上选择它。
|
||||
|
||||
虽然增加暗黑模式听起来像是小事一桩,但他们似乎投入了大量的精力来提供一个整体一致的暗黑模式体验。
|
||||
|
||||
所有的第一方应用程序都无缝地支持暗黑风格和浅色主题。
|
||||
|
||||
elementary OS 还让应用开发者在 elementary OS 6 中遵照用户的偏好。因此,如果用户喜欢暗黑模式或浅色模式,应用程序就可以适应这种模式。
|
||||
|
||||
伴随着新的强调色的出现,还有一个自动的强调色偏好,可以从你当前的壁纸中挑选出强调的颜色。
|
||||
|
||||
### 2、改进的通知及重新设计的通知中心
|
||||
|
||||
通知现在支持图标徽章和行动按钮,这应该能提供更好的体验。
|
||||
|
||||
![][4]
|
||||
|
||||
这可以让你快速打开链接、标记一条消息已读,以及其他几种可能的操作。
|
||||
|
||||
紧急通知有了新的外观和独特的声音,以帮助你识别它们。
|
||||
|
||||
除了通知方面的改进,通知中心也进行了改造,使其看起来更好,并可以对多个通知进行清理。
|
||||
|
||||
### 3、在线账户
|
||||
|
||||
终于,在 elementary OS 6 中,你能够从系统设置中添加在线账户了。
|
||||
|
||||
一旦登录,你的数据将在支持的系统应用程序(如日历、任务)中同步。
|
||||
|
||||
它也会显示在系统托盘通知中。
|
||||
|
||||
### 4、第一方 Flatpak 应用及权限查看
|
||||
|
||||
为了提高整个平台的隐私和安全,elementary OS 6 采用了优先选择 Flatpak 的方式。
|
||||
|
||||
Elementary OS 现在有自己的应用中心 Flatpak 资源库。一些默认的应用程序以 Flatpak 包的形式出现,应用中心列出的所有应用程序也都有 Flatpak。
|
||||
|
||||
总的来说,这意味着更好的沙盒体验,你的所有应用程序将保持相互隔离,不会访问你的敏感数据。
|
||||
|
||||
![][5]
|
||||
|
||||
而且,最重要的是,elementary OS 6 增加了“门户”功能,应用程序会请求权限,以访问你的文件或启动另一个应用程序。
|
||||
|
||||
你还可以从系统设置中控制所有的权限。
|
||||
|
||||
### 5、多点触控手势
|
||||
|
||||
![][6]
|
||||
|
||||
对于笔记本电脑和触摸板用户来说,新的多点触控手势将变得非常方便。
|
||||
|
||||
从访问多任务视图到浏览工作区,你都可以用多点触摸手势来完成。
|
||||
|
||||
不仅仅局限于桌面上的某些功能,你还可以与通知互动、滑过应用程序,并可以通过新的多点触控手势获得全系统的顺滑体验。
|
||||
|
||||
你可以自定义手势或从系统设置下的手势部分了解更多信息。
|
||||
|
||||
### 6、屏幕盾牌
|
||||
|
||||
在 elementary OS 5 中,有些人注意到当你想运行一个耗时的任务或简单地观看视频时,会出现自动锁定屏幕的问题。
|
||||
|
||||
然而,这种情况在 elementary OS 6 中得到了改变,它不仅解决了这个问题,还以 “屏幕盾牌” 功能的形式带来了新的实现方式。
|
||||
|
||||
因此,在观看视频或执行耗时的任务时,你可以轻松地保持系统的清醒,而不会突然中断。
|
||||
|
||||
它利用了 GNOME 的守护程序设置,与第三方应用程序有更好的兼容性。
|
||||
|
||||
### 7、新的任务应用
|
||||
|
||||
![][7]
|
||||
|
||||
elementary OS 6 中添加了一个新的任务应用,在那里你可以管理任务、收到提醒,并在你的系统上组织任务,或与在线账户同步。
|
||||
|
||||
我可能还不会用它来取代 Planner,但它是一个很好的补充,因为它打造的很好。
|
||||
|
||||
### 8、固件更新应用程序
|
||||
|
||||
![][14]
|
||||
|
||||
你可以为支持的设备获得最新的固件更新,而无需摆弄任何其他设置。
|
||||
|
||||
只要从菜单中寻找“固件”应用程序就可以开始了。
|
||||
|
||||
### 9、更新的应用程序
|
||||
|
||||
一些应用程序已经被更新,同时引入了新的功能。
|
||||
|
||||
例如,Epiphany 浏览器被重新命名为 “Web”,现在有 Flatpak 包可用,以方便快速更新。
|
||||
|
||||
它还包括内置的跟踪保护和广告拦截。
|
||||
|
||||
其他一些值得注意的变化包括:
|
||||
|
||||
* 相机应用获得了一个新的用户界面,可以切换相机、镜像图像等等。
|
||||
* 应用中心现在不仅列出了 Flatpak 应用程序,而且还在应用程序完成安装后通知你,让你快速打开它。
|
||||
* 文件应用程序也得到了改进,其形式是一个新的侧边栏和列表视图。另外,现在需要双击才能打开一个文件,而单次点击可以在文件夹中导航。
|
||||
|
||||
其他应用程序如邮件、日历也得到了改进,以便更好地进行在线整合。
|
||||
|
||||
### 10、改进的桌面工作流程及屏幕截图工具
|
||||
|
||||
![][8]
|
||||
|
||||
多任务视图现在可以帮助你明确区分多个活动窗口。而热角视图可以让你将窗口移动到新的工作区,也可以将窗口最大化。
|
||||
|
||||
![][9]
|
||||
|
||||
屏幕截图工具可以在窗口中移动,而不仅仅是停留在窗口的中心。你还可以从预览中拖放图片,而不需要保存。
|
||||
|
||||
### 11、改进的安装程序
|
||||
|
||||
![][10]
|
||||
|
||||
你会注意到一些新的微妙的动画,而且还做了一些努力,以便在不重新调整窗口大小的情况下提供一个一致的安装程序布局。
|
||||
|
||||
这不是一次大修,但他们提到新的安装程序带有改进的磁盘检测和错误处理功能,这应该能使安装顺滑进行。
|
||||
|
||||
### 总结
|
||||
|
||||
[elementary OS 6][3] 是一个激动人心的版本,有多项改进。尽管外观和感觉并没有完全改变,但它已被全面精心雕琢。
|
||||
|
||||
我喜欢他们为提供一致和漂亮的用户体验所做的工作。另外,像全系统的 Flatpak 这样的变化应该使用户更容易和更安全。
|
||||
|
||||
你对这个版本有什么看法?你试过了吗?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/elementary-os-6-features/
|
||||
|
||||
作者:[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/elementary-os-6-release/
|
||||
[2]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/dark-style-elementary.jpg?w=1200&ssl=1
|
||||
[3]: https://elementary.io
|
||||
[4]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/06/notification-badge-elementary-os-6.png?w=724&ssl=1
|
||||
[5]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/elementary-os-6-permissions.png?resize=1568%2C1158&ssl=1
|
||||
[6]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/multitouch-multitasking.png?resize=1568%2C883&ssl=1
|
||||
[7]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/tasks.png?resize=1568%2C1188&ssl=1
|
||||
[8]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/window-context-dark.png?w=808&ssl=1
|
||||
[9]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/screenshot.png?w=660&ssl=1
|
||||
[10]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/installer-progress.png?resize=1568%2C1140&ssl=1
|
||||
[14]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/firmware.png?resize=1568%2C1158&ssl=1
|
||||
52
published/20210812 A Java developer-s guide to Quarkus.md
Normal file
52
published/20210812 A Java developer-s guide to Quarkus.md
Normal file
@@ -0,0 +1,52 @@
|
||||
[#]: subject: "A Java developer's guide to Quarkus"
|
||||
[#]: via: "https://opensource.com/article/21/8/java-quarkus-ebook"
|
||||
[#]: author: "Daniel Oh https://opensource.com/users/daniel-oh"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13690-1.html"
|
||||
|
||||
下载《Quarkus 的 Java 开发者指南》电子书
|
||||
======
|
||||
|
||||
> 一本新的展示了开发者如何继续使用 Java 框架来构建新的无服务器功能的电子书。
|
||||
|
||||

|
||||
|
||||
[无服务器][2] 架构已经成为一种高效的解决方案,无论是物理服务器、虚拟机还是云环境,都可以根据实际工作负载调整超额配置和不足配置资源(如 CPU、内存、磁盘、网络)。然而,在选择新的编程语言来开发无服务器应用时,Java 开发者有一个担忧。对于云上的无服务器部署,尤其是 [Kubernetes][3],Java 框架似乎过于沉重和缓慢。
|
||||
|
||||
作为 Java 开发者,如果可以继续使用 Java 框架来构建传统的云原生微服务以及同时构建新的无服务器功能呢?这种方法应该是令人兴奋的,因为你不必担心新的无服务器应用框架的学习曲线会很陡峭。
|
||||
|
||||
此外,如果 Java 框架不仅可以为开发者提供熟悉技术的乐趣,还可以在启动时以毫秒为单位优化 Kubernetes 中的 Java 无服务器功能,并提供微小的内存足迹,又会怎样?
|
||||
|
||||
### 什么是 Quarkus?
|
||||
|
||||
[Quarkus][4] 是一个新的 Java 框架,可以为 Java 开发者、企业架构师和 DevOps 工程师提供这些功能和好处。它旨在设计无服务器应用,并编写云原生微服务,以便在云基础设施(例如 Kubernetes)上运行。
|
||||
|
||||
Quarkus 还支持一个名为 [Funqy][5] 的可移植 Java API 扩展,供开发者编写和部署无服务器功能到异构无服务器运行时。
|
||||
|
||||
Quarkus Funqy 使开发者能够将 [CloudEvents][6] 与 Knative 环境中的无服务器函数绑定,以处理反应式流。这有利于开发者建立一个通用的消息传递格式来描述事件,提高多云和混合云平台之间的互操作性。
|
||||
|
||||
在我的新电子书 《[Java 无服务器功能指南][7]》的帮助下,开始你的 Quarkus 之旅。与他人分享你的 Quarkus 经验,让大家都能享受到用 Java 和 Quarkus 进行的无服务器开发。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/java-quarkus-ebook
|
||||
|
||||
作者:[Daniel Oh][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/daniel-oh
|
||||
[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://opensource.com/article/21/1/devapps-strategies
|
||||
[3]: https://opensource.com/article/19/6/reasons-kubernetes
|
||||
[4]: https://quarkus.io/
|
||||
[5]: https://quarkus.io/guides/funqy
|
||||
[6]: https://cloudevents.io/
|
||||
[7]: https://opensource.com/downloads/java-serverless-ebook
|
||||
@@ -0,0 +1,140 @@
|
||||
[#]: subject: "What is SteamOS? Everything Important You Need to Know About This “Gaming Distribution”"
|
||||
[#]: via: "https://itsfoss.com/steamos/"
|
||||
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "imgradeone"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13688-1.html"
|
||||
|
||||
SteamOS 是什么?关于这款“游戏发行版”你所要知道的事
|
||||
======
|
||||
|
||||

|
||||
|
||||
SteamOS 是一款基于 Linux 的操作系统,旨在提供来自 Steam 自己的游戏商店顺滑的游戏体验。
|
||||
|
||||
虽然它已经存在了许久,但有几件事你应该知道。
|
||||
|
||||
在这篇文章中,我们将回答许多 SteamOS 相关的常见问题。
|
||||
|
||||
### SteamOS 是什么?
|
||||
|
||||
SteamOS 是由游戏分发平台 Steam 开发的 Linux 发行版。它并是一款像 Debian、Linux Mint 或者 Ubuntu 那样的泛用型桌面操作系统,即便你确实可以使用桌面功能。默认情况下,SteamOS 的界面类似于游戏机,因为 SteamOS 旨在成为专为 Steam 游戏设备定制的操作系统,如 Steam Machine(已停产)和 Steam Deck。
|
||||
|
||||
![SteamOS 界面][1]
|
||||
|
||||
你确实也可以在任何 Linux 发行版和其他平台安装 Steam 客户端,但 SteamOS 更是为了提供类似游戏机的体验,方便你玩 Steam 上的游戏。
|
||||
|
||||
### SteamOS 基于哪个 Linux 发行版?
|
||||
|
||||
作为基于 Linux 的系统,SteamOS 最初基于 Debian 8 开发。随着 Valve 的全新 [Steam Deck][2] 掌机发布,SteamOS 的最新版本(SteamOS 3.0)将基于 Arch Linux 开发,因为 Arch 支持滚动更新。
|
||||
|
||||
SteamOS 的开发团队也相信,SteamOS 基于 Arch Linux 更有利于快速推送更新和优化 Steam Deck。
|
||||
|
||||
![][3]
|
||||
|
||||
### SteamOS 的系统要求
|
||||
|
||||
理想情况下,符合以下最低要求的设备都应该可以正常运行 SteamOS:
|
||||
|
||||
* Intel / AMD 的 64 位 CPU
|
||||
* 4GB 或更高的运行内存(RAM)
|
||||
* 250GB 或更大的磁盘
|
||||
* NVIDIA / Intel / AMD 的显卡
|
||||
* 用于安装介质的 USB 或者 DVD
|
||||
|
||||
(LCTT 译注:本段内容仅针对 SteamOS 2.0。)
|
||||
|
||||
### SteamOS 能否在你的电脑上正常运作?
|
||||
|
||||
SteamOS(2.0 版本)内置了支持特定硬件的驱动程序。
|
||||
|
||||
理论上 SteamOS 可以在任何电脑上运行,但目前官方并没有支持最新的硬件。
|
||||
|
||||
### SteamOS 只是又一款 Linux 发行版吗?
|
||||
|
||||
SteamOS 严格来说已经是现有的 [适合游戏的 Linux 发行版][4] 之一。但与其他发行版不同的是,SteamOS 并不是为了泛用型桌面而设计的。你确实可以安装 Linux 程序,但 SteamOS 支持的软件包极为有限。
|
||||
|
||||
总之,它并不适合替代普通 Linux 桌面系统。
|
||||
|
||||
### SteamOS 现在还在积极维护中吗?
|
||||
|
||||
**是**,但又**不是**。
|
||||
|
||||
SteamOS 基于 Debian 8 许久,目前没有任何更新。
|
||||
|
||||
如果你正期望将 SteamOS 安装到你的个人设备上,那么目前公开发布的版本(SteamOS 2.0)已经处于不再维护的状态。
|
||||
|
||||
不过,Valve 目前正在为 Steam Deck 维护 SteamOS 3.0。因此,可能不久 SteamOS 就可以用于你的桌面了。
|
||||
|
||||
### 你是否推荐使用 SteamOS 来玩电脑游戏吗?
|
||||
|
||||
**不推荐**。 在 Windows 和其它 Linux 发行版面前,SteamOS 并不是你应该选择的替代品。
|
||||
|
||||
虽然 SteamOS 主要是为游戏定制的,但在拿它玩游戏之前,你还需要了解许多注意事项。
|
||||
|
||||
### 所有游戏都可以在 SteamOS 上玩吗?
|
||||
|
||||
**不**。 SteamOS 需要依赖 Proton 兼容层才能让 Windows 平台的游戏正常运行。
|
||||
|
||||
当然,如今借助同样的底层技术,[在 Linux 里玩游戏][5] 已经成为了可能,但至少在我写这篇文章时,你并不能让 Steam 上架的所有游戏都可以在 Linux 中运行。
|
||||
|
||||
虽然大部分游戏都可以运行,但这并不意味着你游戏库里的所有游戏都能正常游玩。
|
||||
|
||||
如果你想玩 Steam 支持的游戏,以及仅限于 Linux 平台的游戏,那还是值得一试的。
|
||||
|
||||
### SteamOS 是否开源?
|
||||
|
||||
**是的**(SteamOS 2.0)。
|
||||
|
||||
SteamOS 操作系统是开源的,你可以在 [官方仓库][6] 中找到源码。
|
||||
|
||||
不过,你用来玩游戏的 Steam 客户端是专有的。
|
||||
|
||||
值得注意的是,SteamOS 3.0 目前仍处于开发阶段,因此你无法获得它的源代码和任何公开进展。
|
||||
|
||||
### SteamOS 是否免费使用?
|
||||
|
||||
目前你暂时无法找到可供公众使用的最新版 SteamOS,但它基本上是免费的。基于 Debian 的旧版 SteamOS 可在其 [官方网站][7] 上获取。
|
||||
|
||||
### 我能找到内置 SteamOS 的游戏主机吗?
|
||||
|
||||
![Steam Machine 游戏机,已经停产][8]
|
||||
|
||||
SteamOS 最初是为 Steam Machine 这款 Steam 自家的 PlayStation/Xbox 风格的游戏机定制的操作系统。2015 年 Steam Machine 发布后并没有在市场上获得成功,最终停产。
|
||||
|
||||
目前,唯一一款预装 SteamOS 的设备是备受瞩目的 Steam Deck。
|
||||
|
||||
待到 SteamOS 开放针对其它设备的下载后,你就可以看到有硬件厂商销售预装 SteamOS 的游戏设备了。
|
||||
|
||||
但,至少目前来看,你不应该相信任何不知名的制造商提供开箱即用的 SteamOS。
|
||||
|
||||
### 下一代 SteamOS 能否使 Linux 成为游戏的可行选择?
|
||||
|
||||
是的,绝对是的。
|
||||
|
||||
Linux 可能不是外界所推荐的游戏选择,但如果你乐意的话,你也可以查看 [我们所推荐的 Linux 游戏发行版][9]。最后,如果 SteamOS 下了狠心,让每款游戏都能在 Steam Deck 上运行,那么桌面 Linux 用户也将终于可以体验到所有曾经不支持的 Steam 游戏了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/steamos/
|
||||
|
||||
作者:[Ankush Das][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/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/wp-content/uploads/2021/08/steamos.jpg
|
||||
[2]: https://www.steamdeck.com/en/
|
||||
[3]: https://itsfoss.com/wp-content/uploads/2021/08/steam-deck.jpg
|
||||
[4]: https://itsfoss.com/linux-gaming-distributions/
|
||||
[5]: https://itsfoss.com/linux-gaming-guide/
|
||||
[6]: https://repo.steampowered.com/steamos/
|
||||
[7]: https://store.steampowered.com/steamos/
|
||||
[8]: https://itsfoss.com/wp-content/uploads/2021/08/valves-steam-machine.jpg
|
||||
[9]: https://news.itsfoss.com/linux-for-gaming-opinion/
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: (https://news.itsfoss.com/pdf-mix-tool-1-0-1-release/)
|
||||
[#]: author: (Omar Maarof https://news.itsfoss.com/author/omar/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lcf33)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: (https://news.itsfoss.com/kde-connect-windows/)
|
||||
[#]: author: (Ankush Das https://news.itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (imgradeone)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
[#]: subject: (Top 7 Linux Laptops You Can Buy in 2021)
|
||||
[#]: via: (https://news.itsfoss.com/best-linux-laptops-2021/)
|
||||
[#]: author: (Ankush Das https://news.itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Top 7 Linux Laptops You Can Buy in 2021
|
||||
======
|
||||
|
||||
Linux laptops are the perfect alternatives to macOS and Windows-powered laptops.
|
||||
|
||||
Technically, you can turn any laptop of your choice into a Linux machine by choosing to install any Linux distribution available.
|
||||
|
||||
But, here, our focus will be on the laptops that offer Linux out-of-the-box, ensuring the best compatibility and support no matter what kind of budget you have.
|
||||
|
||||
### Linux Laptops by Popular Brands
|
||||
|
||||
It is often the best choice for a consumer to opt for a Linux laptop built by a popular manufacturer.
|
||||
|
||||
You do not have to worry about the after-sales, warranty extensions, and service repairs.
|
||||
|
||||
Dell and Lenovo are usually the ones who provide laptops with Linux pre-installed.
|
||||
|
||||
Do note that everything is subject to availability depending on the country/region.
|
||||
|
||||
*_Pricing mentioned in this article is converted to USD for easy comparison, excluding shipping and other extras._
|
||||
|
||||
#### 1\. Lenovo Thinkpad X1 Carbon (Gen 8 / Gen 9)
|
||||
|
||||
![][1]
|
||||
|
||||
_**Pricing**: Starts at **$1535**_
|
||||
|
||||
The entire Thinkpad series by Lenovo is a popular choice among Linux users. It is built to last and offers good compatibility
|
||||
|
||||
However, it stays on the expensive side.
|
||||
|
||||
You will have three choices to go with depending on what you go for. If you are customizing a Gen 9 Thinkpad laptop, you will have Ubuntu 20.04 and Fedora 33 as your options to have installed.
|
||||
|
||||
For Gen 8 models, it seems that Fedora 33 is off the table, and it is Fedora 32 instead, along with Ubuntu 20.04.
|
||||
|
||||
All the variants are powered by Intel chipsets, 10th gen for Gen 8 and 11th gen for Gen 9.
|
||||
|
||||
Most of the other specifications remain similar with a 14-inch display (FHD, WQHD, and UHD options available), up to 32 GB RAM, 1 TB SSD, fingerprint reader, and Wi-Fi 6 support.
|
||||
|
||||
[Thinkpad X1 Carbon (Gen 9)][2]
|
||||
|
||||
[Thinkpad X1 Carbon (Gen 8)][3]
|
||||
|
||||
#### 2\. Dell XPS 13 Developers Edition
|
||||
|
||||
![][4]
|
||||
|
||||
_**Pricing**: Starts at **$1059**_
|
||||
|
||||
Dell XPS series is an impressive laptop lineup to consider running Linux.
|
||||
|
||||
It has been tailored to run Linux (Ubuntu 20.04) with developers in mind.
|
||||
|
||||
You get a 13.4-inch display (FHD and UHD options available), 11th gen i5/i7 processor, up to 32 GB RAM, 2 TB SSD, fingerprint reader, and Wi-FI 6 support.
|
||||
|
||||
[Dell XPS 13 Developer Edition][5]
|
||||
|
||||
### Laptops by Linux-only Manufacturers
|
||||
|
||||
If you do not want mainstream options but some unique choices to support Linux-only manufacturers in the process, there are a couple of them that you can consider.
|
||||
|
||||
#### 1\. System76 Gazelle
|
||||
|
||||
![][6]
|
||||
|
||||
_**Pricing**: Starts at **$1499**_
|
||||
|
||||
System76’s laptop will come baked in with their Pop!_OS operating system which is based on Ubuntu but provides a **hassle-free out-of-the-box experience**.
|
||||
|
||||
It is safe to assume that System76 is like the Apple of Linux laptops who try their best to optimize Pop!_OS for their hardware offered.
|
||||
|
||||
They have total control over the software and hardware, so that should be some exciting product integration for end consumers.
|
||||
|
||||
Along with impressive essentials like 144 Hz 16.5-inch display, i7 11th gen processor, up to 8 TB NVMe SSD support—you also get an RTX 3050 GPU which should enable you to tackle a variety of demanding tasks on your laptop.
|
||||
|
||||
While there are some other laptops by System76, it was not available at the time of writing this. So, feel free to check out the official store page and order a customized configuration.
|
||||
|
||||
System76 Gazelle
|
||||
|
||||
#### 2\. Purism Laptop
|
||||
|
||||
![][7]
|
||||
|
||||
![][8]
|
||||
|
||||
_**Pricing**: Starts at **$1599**_
|
||||
|
||||
A laptop by Purism can be an option if you are a security-conscious user.
|
||||
|
||||
Librem 14 is one of their latest laptops that comes baked in with [PureOS][9] (also built by them).
|
||||
|
||||
While it may not offer the latest generation processors, you should be fine with the i7 10th Gen chip on board.
|
||||
|
||||
It supports up to 64 GB of RAM and features hardware kill switches to disable the webcam, headphone jack, Bluetooth, or wireless audio
|
||||
|
||||
[Librem 14][10]
|
||||
|
||||
#### 3\. TUXEDO Aura 15
|
||||
|
||||
![][7]
|
||||
|
||||
![][11]
|
||||
|
||||
_**Pricing**: Starts at **$899**_
|
||||
|
||||
If you want an AMD-powered laptop (with its last-gen processor Ryzen 7 4700U), Aura 15 by TUXEDO Computers is a great pick.
|
||||
|
||||
The key specifications include a Full HD display, up to 64 GB RAM, Wi-Fi 6 support, and an LTE module.
|
||||
|
||||
It comes with either Ubuntu or TUXEDO OS (based on Ubuntu Budgie) as per your customization.
|
||||
|
||||
[TUXEDO Aura 15][12]
|
||||
|
||||
#### 4\. TUXEDO Stellaris 15
|
||||
|
||||
![][7]
|
||||
|
||||
![][13]
|
||||
|
||||
_**Pricing**: Starts at **$2160**_
|
||||
|
||||
If you are looking for the latest and greatest powerhouse with options to get RTX 3080 on board, this should be a fantastic option.
|
||||
|
||||
It offers the latest Intel/Ryzen processor with the configuration choices and features a 3K-res display with a 165 Hz refresh rate.
|
||||
|
||||
Definitely not something that you would find convenient to travel with, but if you need the computing power, you can choose to go with it.
|
||||
|
||||
TUXEDO Stellaris 15
|
||||
|
||||
#### 5\. Slimbook Pro X
|
||||
|
||||
![][14]
|
||||
|
||||
_**Pricing:** Starts at **$1105**_
|
||||
|
||||
Slimbook focuses on lighter Laptop models that you can conveniently travel with.
|
||||
|
||||
It gives you the option to choose from a variety of distributions that include Ubuntu (_GNOME, KDE, MATE_), KDE Neon, Manjaro, and Fedora.
|
||||
|
||||
You get most of the essential specifications that include up to 2 TB SSD support, 64 GB of RAM, Full HD IPS display, and more.
|
||||
|
||||
While you get options for Intel and Ryzen (last-gen processors) coupled with Nvidia and Vega graphics respectively, only Ryzen was available in stock at the time of writing this.
|
||||
|
||||
Slimbook Pro X
|
||||
|
||||
#### 6\. Slimbook Essential
|
||||
|
||||
![][1]
|
||||
|
||||
_**Pric**__**ing:** Starts at **$646**_
|
||||
|
||||
An impressive option for a budget-friendly Linux laptop.
|
||||
|
||||
It offers both Ryzen and Intel variants (last-gen) to choose from. You should get the basic specifications that include up to 64 GB RAM, 2 TB SSD support, minus a great screen and dedicated graphics onboard.
|
||||
|
||||
[Slimbook Essential][15]
|
||||
|
||||
#### 7\. Jupiter 14 Pro by Juno Computers
|
||||
|
||||
![][16]
|
||||
|
||||
_**Pricing**: Starts at **$1199**_
|
||||
|
||||
Featuring the 11th gen Intel processors, Jupiter 14 by Juno Computers is a sweet deal with NVIDIA GTX 1650 on board.
|
||||
|
||||
It comes baked in with Ubuntu 20.04 with no other options to choose from.
|
||||
|
||||
The base configuration includes 16 GB RAM, which could make the value offering slightly better compared to some others.
|
||||
|
||||
You will find the ability to choose your region on their website (UK/Europe or US/Canada), make sure to utilize that.
|
||||
|
||||
[Jupiter Pro 14][17]
|
||||
|
||||
#### Honorable Mention: **PineBook Pro**
|
||||
|
||||
![][18]
|
||||
|
||||
PineBook Pro is an ARM-based laptop (with Manjaro ARM edition) that is budget-friendly and should work fine for a lot of basic tasks on Linux.
|
||||
|
||||
It is out of stock (until further notice) at the time of writing this. However, you might want to check that for yourself when you read this.
|
||||
|
||||
[Pinebook Pro][19]
|
||||
|
||||
### Wrapping Up
|
||||
|
||||
If you do not like the choices presented here, you may check out [other places from where you can by Linux laptops][20]. Depending on your budget, pick what you feel is best for you.
|
||||
|
||||
After all, everything comes with Linux baked in. Some give you the ability to choose from multiple distros but most of them stick to Ubuntu pre-installed.
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/best-linux-laptops-2021/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://news.itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQzOSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[2]: https://www.lenovo.com/us/en/laptops/thinkpad/thinkpad-x1/X1-Carbon-G9/p/22TP2X1X1C9
|
||||
[3]: https://www.lenovo.com/us/en/laptops/thinkpad/thinkpad-x1/X1-Carbon-Gen-8-/p/22TP2X1X1C8
|
||||
[4]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQ3MiIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[5]: https://www.dell.com/en-us/work/shop/dell-laptops-and-notebooks/new-xps-13-developer-edition/spd/xps-13-9310-laptop/ctox139w10p2c3000u
|
||||
[6]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjU0MCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[7]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9Ijc4MCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[8]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/librem14.png?resize=780%2C780&ssl=1
|
||||
[9]: https://www.pureos.net
|
||||
[10]: https://puri.sm/products/librem-14/
|
||||
[11]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/tuxedo-aura-15.jpg?resize=780%2C780&ssl=1
|
||||
[12]: https://www.tuxedocomputers.com/en/Linux-Hardware/Linux-Notebooks/15-16-inch/TUXEDO-Aura-15-Gen1.tuxedo
|
||||
[13]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/07/tuxedo-stellaris.jpg?resize=780%2C780&ssl=1
|
||||
[14]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQyMyIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[15]: https://slimbook.es/en/essential-en
|
||||
[16]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQ2OCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[17]: https://junocomputers.com/us/product/jupiter-14-pro/
|
||||
[18]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQ0MSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[19]: https://www.pine64.org/pinebook-pro/
|
||||
[20]: https://itsfoss.com/get-linux-laptops/
|
||||
@@ -1,75 +0,0 @@
|
||||
[#]: subject: (GitLab’s New Open Source Tool Will Detect Malicious Code)
|
||||
[#]: via: (https://news.itsfoss.com/gitlab-open-source-tool-malicious-code/)
|
||||
[#]: author: (Ankush Das https://news.itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
GitLab’s New Open Source Tool Will Detect Malicious Code
|
||||
======
|
||||
|
||||
There are several open-source tools available for security researchers. Now, GitLab has introduced a new one to the arsenal that lets you detect malicious code in dependencies.
|
||||
|
||||
The tool is also known as “Package Hunter” and is an important addition that could help secure every type of software.
|
||||
|
||||
### What is Package Hunter?
|
||||
|
||||
Every software includes some form of dependencies, which makes it possible for a developer to quickly build an app.
|
||||
|
||||
While this facilitates the reuse of code to achieve the task, they often just “trust” the dependencies used without separate review.
|
||||
|
||||
Package Hunter comes to the rescue here and lets you easily detect malicious code in a dependency package.
|
||||
|
||||
### Enhanching Software Supply Chain Security
|
||||
|
||||
Many supply chain attacks involve a compromised dependency package.
|
||||
|
||||
Normally, the attacker injects malicious code in the dependency code available to the public or creates a separate private repository to distribute the malicious dependency that looks safe.
|
||||
|
||||
Even if you are using a package manager to get trusted packages, it can be tricked to download packages from a private repository. And, you will have no idea about it.
|
||||
|
||||
Hence, with an additional check to the supply chain which is as convenient as Package Hunter, the software supply chain security should improve.
|
||||
|
||||
And, especially, if the open-source supply chain security improves, [open source software security][1] will gradually get a boost as well.
|
||||
|
||||
### How Does it Work? How Can You Get it?
|
||||
|
||||
Package Hunter scans for malicious code and keeps an eye on unexpected behavior of the dependencies.
|
||||
|
||||
It installs the dependencies in a sandbox environment to monitor and detect any anomalies.
|
||||
|
||||
As of now, it supports testing NodeJS modules and Ruby Jems.
|
||||
|
||||
GitLab has been using the tool internally for a while. And, now, it seamlessly integrates with GitLab.
|
||||
|
||||
You can learn more about setting it up by referring to the [official documentation][2] and the [Package Hunter CLI instructions][3].
|
||||
|
||||
It is available as a free and open-source project on [GitLab][4].
|
||||
|
||||
_What do you think about GitLab’s open-source tool to help detect malicious code? Feel free to share your thoughts in the comments below._
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/gitlab-open-source-tool-malicious-code/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/open-source-software-security/
|
||||
[2]: https://gitlab.com/gitlab-org/security-products/package-hunter/-/blob/main/README.md
|
||||
[3]: https://gitlab.com/gitlab-org/security-products/package-hunter-cli/-/blob/main/README.md#gitlab-ci
|
||||
[4]: https://gitlab.com/gitlab-org/security-products/package-hunter/activity
|
||||
@@ -1,113 +0,0 @@
|
||||
[#]: subject: (4MLinux 37.0 Release Packs in Linux Kernel 5.10 LTS and New Applications)
|
||||
[#]: via: (https://news.itsfoss.com/4mlinux-37-0-release/)
|
||||
[#]: author: (Jacob Crume https://news.itsfoss.com/author/jacob/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
4MLinux 37.0 Release Packs in Linux Kernel 5.10 LTS and New Applications
|
||||
======
|
||||
|
||||
One of the most lightweight distros, [4MLinux][1], has just announced its 37th major release. This version brings a variety of improvements, of which we shall be looking at here.
|
||||
|
||||
Before that, however, I feel that it would be appropriate to find out more about it, especially since it’s such a niche distro.
|
||||
|
||||
### What Is 4MLinux?
|
||||
|
||||
Despite its somewhat unusual name, it actually is quite logical, especially when you look at the project’s goals:
|
||||
|
||||
* **M**aintenance (system rescue Live CD),
|
||||
* **M**ultimedia (full support for a huge number of image, audio and video formats),
|
||||
* **M**iniserver (DNS, FTP, HTTP, MySQL, NFS, Proxy, SMTP, SSH, and Telnet),
|
||||
* **M**ystery (meaning a collection of classic Linux games).
|
||||
|
||||
|
||||
|
||||
This is where it gets the “4M” part of the name from.
|
||||
|
||||
One interesting quirk of this distro is that it doesn’t come with a traditional package manager, instead opting for an ecosystem of extensions. The minimum requirements are also quite relaxed, requiring just 32 MB of RAM to run. The result of all this is an incredibly lightweight and fast distro, perfect for those older computers gathering dust in a cupboard.
|
||||
|
||||
### New Features
|
||||
|
||||
This release brings a variety of improvements, most of which are as follows:
|
||||
|
||||
* 4 new applications can be installed
|
||||
* [Linux 5.10 LTS][2]
|
||||
* [LibreOffice 7.1.5][3]
|
||||
* Firefox 90.0.2
|
||||
* Thunderbird 78.12
|
||||
* Other Updated applications
|
||||
|
||||
|
||||
|
||||
#### Linux 5.10 LTS
|
||||
|
||||
This release brings in Linux kernel 5.10 LTS, resulting in better hardware support and many small improvements. To be honest, I was actually quite surprised at this addition, as I thought that they may not opt for one of the latest kernels right now.
|
||||
|
||||
If you want to see what other improvements this addition brings, I would suggest reading [our coverage for Linux kernel 5.10 release][2].
|
||||
|
||||
#### New Applications
|
||||
|
||||
One area that M4Linux struggles in is application support. Due to the lack of a package manager, the list of available apps is very short, making each addition to it extremely meaningful.
|
||||
|
||||
This release brings the Dmidecode tool for reading hardware-related data from SMBIOS, FluidSynth software synthesizer, HandBrake video transcoder, and qBittorrent BitTorrent client.
|
||||
|
||||
These applications should improve the usefulness of this distribution, hopefully helping older computers stay out of landfill.
|
||||
|
||||
#### Updated Applications
|
||||
|
||||
2021 has had a plethora of large app upgrades, including the new interface in Firefox 89 and the vast improvements of LibreOffice 7.1.5. Now, all these improvements are coming to M4Linux with the new release.
|
||||
|
||||
Here’s a list of updated applications with this release:
|
||||
|
||||
* LibreOffice 7.1.5
|
||||
* Firefox 90.0.2
|
||||
* Mozilla Thunderbird 78.12.0
|
||||
* Audacious 4.1
|
||||
* VLC 3.0.16
|
||||
* MPV 0.33.0
|
||||
* AbiWord 3.0.5
|
||||
* GIMP 2.10.24
|
||||
* Gnumeric 1.12.50
|
||||
* Chromium 90.0
|
||||
* Mesa 21.0
|
||||
|
||||
|
||||
|
||||
In all, these updated applications should provide a much-improved user experience.
|
||||
|
||||
### Final Thoughts
|
||||
|
||||
M4Linux, despite being quite a niche, has made some incredible improvements with this release, especially when considering the incredibly small development team.
|
||||
|
||||
Even though it isn’t targeting the latest hardware, I can still see how this distribution might be perfect for some use cases.
|
||||
|
||||
You can read the [official announcement][4] to learn more.
|
||||
|
||||
_What do you think about M4Linux 37.0? Let me know in the comments below!_
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/4mlinux-37-0-release/
|
||||
|
||||
作者:[Jacob Crume][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://news.itsfoss.com/author/jacob/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://4mlinux.com/index.php?page=home
|
||||
[2]: https://news.itsfoss.com/kernel-5-10-release/
|
||||
[3]: https://news.itsfoss.com/libreoffice-7-1-community/
|
||||
[4]: https://4mlinux-releases.blogspot.com/2021/07/4mlinux-370-stable-released.html
|
||||
@@ -1,78 +0,0 @@
|
||||
[#]: subject: (GNOME Web Canary is Now Available to Test Bleeding Edge Features)
|
||||
[#]: via: (https://news.itsfoss.com/gnome-web-canary/)
|
||||
[#]: author: (Ankush Das https://news.itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
GNOME Web Canary is Now Available to Test Bleeding Edge Features
|
||||
======
|
||||
|
||||
Epiphany or [GNOME Web][1] is a minimal and yet capable browser for Linux distributions. You should find it as the default browser for elementary OS.
|
||||
|
||||
With GNOME 40, the Epiphany browser has had some [improvements and additions][2].
|
||||
|
||||
Behind the scenes, it regularly gets some exciting improvements and feature additions. And for that, you can opt for the Tech Preview version of GNOME Web tailored for early testers.
|
||||
|
||||
Now, a new Canary flavor has been introduced that you can use to test features that are not yet available even in the tech preview build.
|
||||
|
||||
### GNOME Web Canary Flavor
|
||||
|
||||
![][3]
|
||||
|
||||
GNOME Web’s “Canary” builds let you test features that are not even available in the latest [WebKitGTK][4] version.
|
||||
|
||||
Do note that the canary builds are supposed to be extremely unstable, even worse than the development builds available as a tech preview.
|
||||
|
||||
However, with the help of a Canary build, an end-user can test things way early in the process of development that can help find disastrous bugs.
|
||||
|
||||
Not just limited to end-user early testing, a canary build also makes things easier for a GNOME Web developer.
|
||||
|
||||
They no longer have to build WebKitGTK separately in order to implement and test a new feature.
|
||||
|
||||
Even though there was a Flatpak SDK available to ease the process for developers, it was still a time-consuming task.
|
||||
|
||||
Now, with that out of the way, the development pace can potentially improve as well.
|
||||
|
||||
### How to Get the Canary Build?
|
||||
|
||||
First, you need to add the WebKit SDK Flatpak remote using the commands below:
|
||||
|
||||
```
|
||||
flatpak --user remote-add --if-not-exists webkit https://software.igalia.com/flatpak-refs/webkit-sdk.flatpakrepo
|
||||
flatpak --user install https://nightly.gnome.org/repo/appstream/org.gnome.Epiphany.Canary.flatpakref
|
||||
```
|
||||
|
||||
Once done, you can install the Canary by using the [Flatpakref file][5] provided.
|
||||
|
||||
Testing a Canary build gives more users the ability to help GNOME Web developers in the process. So, it is definitely a much-needed addition to improve the development of the GNOME Web browser.
|
||||
|
||||
For more technical details, you might want to take a look at the [announcement post][6] by one of the developers.
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/gnome-web-canary/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://news.itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://wiki.gnome.org/Apps/Web/
|
||||
[2]: https://news.itsfoss.com/gnome-web-new-tab/
|
||||
[3]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY0MiIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[4]: https://webkitgtk.org
|
||||
[5]: https://nightly.gnome.org/repo/appstream/org.gnome.Epiphany.Canary.flatpakref
|
||||
[6]: https://base-art.net/Articles/introducing-the-gnome-web-canary-flavor/
|
||||
@@ -1,75 +0,0 @@
|
||||
[#]: subject: "It’s Time for Ubuntu to Opt for a Hybrid Rolling Release Model"
|
||||
[#]: via: "https://news.itsfoss.com/ubuntu-hybrid-release-model/"
|
||||
[#]: author: "Abhishek https://news.itsfoss.com/author/root/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
It’s Time for Ubuntu to Opt for a Hybrid Rolling Release Model
|
||||
======
|
||||
|
||||
Even if you are not an Ubuntu user, you probably are aware of its release model.
|
||||
|
||||
There is a [long term support (LTS) release][1] that comes every two year and gets supported for five years. In between the two LTS releases, we see three non-LTS releases that are released at an interval of six months.
|
||||
|
||||
The LTS version retains the same kernel (unless you opt for [HWE kernel][2]) and it also holds on to various software components to provide a stable production environment.
|
||||
|
||||
The non-LTS Ubuntu releases that come in between feature new features from Ubuntu, newer kernel, new desktop environment and newer version of various software available from Ubuntu repositories.
|
||||
|
||||
It is no secret that these non-LTS releases work as a ‘testing ground’ for the features that would eventually land in the LTS release.
|
||||
|
||||
And this is why I suggest to get rid of these intermediate releases and opt for a [rolling release][3] model between the LTS releases. Here me out, please.
|
||||
|
||||
### Go rolling in-between the LTS releases
|
||||
|
||||
The six monthly release schedule gives the Ubuntu developers a tight schedule to work on. It’s good in the way that keeps their objective in focus with a proper roadmap.
|
||||
|
||||
But it also builds additional pressure to deliver ‘more’ new features in every release. That cannot always happen if the timeframe is short. Remember how [Ubuntu had to drop GNOME 40 from 21.04][4] because the developers didn’t get enough time to work on it?
|
||||
|
||||
Also, it’s not that the end user (like you and me) gets a choice to stay with a non-LTS release. The support ends in nine months, which mean that even if you did not upgrade to the next non-LTS Ubuntu version immediately, you have to do it eventually. If it does not happen in six months, it has to in nine months.
|
||||
|
||||
I know you would say that upgrading Ubuntu version is simple. A few clicks, good internet speed and a potential backup will put you on the new Ubuntu version without much trouble.
|
||||
|
||||
And my questions is, why bother with that. A rolling release will be even simpler. Let the upgrades come between the LTS releases.
|
||||
|
||||
Developers release the new features when it is ready. Users get the upgrades with the system updates continually, instead of doing a ‘major upgrade’ every six or nine months.
|
||||
|
||||
See, the people who opt for non-LTS release are the ones who want new features. Let them get the new features through rolling releases. The LTS release schedule remains the same, coming every two years.
|
||||
|
||||
#### Bug testing? Get a testing branch like other rolling releases
|
||||
|
||||
When I say rolling, I do not mean rolling like Arch Linux. It should be rolling like Manjaro. In other words, roll out the upgrades after testing rather than just releasing them in the wild.
|
||||
|
||||
At present, the new Ubuntu versions have beta releases so that early adopters can test it and provide feedback to the developers. This can be achieved by keeping testing and stable branches, like many other rolling release distributions.
|
||||
|
||||
### Rolling release or not? What do you think?
|
||||
|
||||
I know that hardcore Ubuntu users look forward to every single release. The code name, the mascot, the artwork and the wallpapers, these are all part of Ubuntu’s legacy. Should we break with this legacy?
|
||||
|
||||
It’s just my opinion and I am interested to hear yours. Should Ubuntu opt for this hybrid rolling model or stick with the current one? What do you think?
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/ubuntu-hybrid-release-model/
|
||||
|
||||
作者:[Abhishek][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://news.itsfoss.com/author/root/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/long-term-support-lts/
|
||||
[2]: https://itsfoss.com/ubuntu-hwe-kernel/
|
||||
[3]: https://itsfoss.com/rolling-release/
|
||||
[4]: https://news.itsfoss.com/no-gnome-40-in-ubuntu-21-04/
|
||||
@@ -0,0 +1,126 @@
|
||||
[#]: subject: "Top 9 Features in the Newly Released Zorin OS 16 Linux Distribution"
|
||||
[#]: via: "https://news.itsfoss.com/zorin-os-16-features/"
|
||||
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Top 9 Features in the Newly Released Zorin OS 16 Linux Distribution
|
||||
======
|
||||
|
||||
Zorin OS 16 is a gorgeous Linux distribution. With the latest release, there are several helpful feature additions to the distribution.
|
||||
|
||||
While we have [highlighted the key updates in our release coverage][1], I shall focus on some of the best features you can find in Zorin OS 16.
|
||||
|
||||
### 1\. Jelly Mode
|
||||
|
||||
![][2]
|
||||
|
||||
Jelly Mode adds an engaging animation when you minimize or move the window on your screen.
|
||||
|
||||
It is more like a wobble effect when you move the windows and a fluid effect when you minimize or launch an app.
|
||||
|
||||
Unlike other animation improvements, this is quite a pleasing effect to enhance the user experience.
|
||||
|
||||
### 2\. Windows 11-like Layout
|
||||
|
||||
![][3]
|
||||
|
||||
Considering that Windows 11 made a lot of buzz for its launch, it only makes sense for Zorin OS to offers a familiar layout.
|
||||
|
||||
After all, it is one of the best Windows-like Linux distributions out there.
|
||||
|
||||
The Windows 11-like layout is only available in the Zorin Appearance settings for Pro users. So, get the Pro edition if you want to support the development and get access to some extra layouts.
|
||||
|
||||
### 3\. Touchpad Gestures
|
||||
|
||||
If you want to get a seamless touch experience with your laptop/touchpad, Zorin OS 16 is here to the rescue.
|
||||
|
||||
A simple three-finger pinch would help you navigate to the activity overview and dabble between active windows.
|
||||
|
||||
And a four-finger swipe up/down will let you switch between workspaces.
|
||||
|
||||
### 4\. Windows Software Detection
|
||||
|
||||
![][4]
|
||||
|
||||
Zorin OS 16 utilizes a database of popular Windows software to detect if you download a .exe file and want to install it.
|
||||
|
||||
This is incredibly useful for beginners considering that it also informs the alternative or the correct way to install the software on Linux.
|
||||
|
||||
Even if it does not have exact instructions for the Windows software you downloaded, it prompts you to install “**Windows App Support**” when trying to access the .exe file.
|
||||
|
||||
![][5]
|
||||
|
||||
### 5\. New Photos App
|
||||
|
||||
![][6]
|
||||
|
||||
The default photos or image viewer is often untouched when a distribution is updated. But, with Zorin OS 16, you get a more straightforward and clean photo management app.
|
||||
|
||||
You get essential options like cropping, adding filters, enhancing the image, and screencasting to the devices connected to your network.
|
||||
|
||||
### 6\. Flathub Apps
|
||||
|
||||
![][7]
|
||||
|
||||
You no longer need to install Flatpak applications from the terminal separately. Flathub is now included with the Software center.
|
||||
|
||||
So, you can effortlessly search for Flatpak applications right from the Software app.
|
||||
|
||||
### 7\. Taskbar and Dash Customization
|
||||
|
||||
With Zorin OS 16, you get a variety of customization options to tweak the appearance of the taskbar, panel, and dock.
|
||||
|
||||
![][8]
|
||||
|
||||
Starting from the transparency to its position, behavior, size, and more. These options should let you tweak your user experience.
|
||||
|
||||
### 8\. Taskbar Unread Icons and Progress bar
|
||||
|
||||
The taskbar is usually static for most of the Linux distributions. Here, you finally get an unread badge counter in the taskbar, and it also supports a new progress bar for tasks like file transfer.
|
||||
|
||||
The progress bar is a helpful addition, given that you do not have to open the app repeatedly to watch the progress.
|
||||
|
||||
### 9\. New Sound Recorder App
|
||||
|
||||
![][9]
|
||||
|
||||
You do not have to opt for a third-party application to record basic voice-overs, podcasts, or voice notes.
|
||||
|
||||
The built-in sound record app offers a clean and easy-to-use interface. So, it should be a breeze to use it.
|
||||
|
||||
### Wrapping Up
|
||||
|
||||
Have you tried Zorin OS 16 yet? What feature did you find the most useful? Let me know your thoughts in the comments down below.
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/zorin-os-16-features/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/zorin-os-16-release/
|
||||
[2]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjM0MyIgd2lkdGg9Ijc1MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[3]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQzOSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[4]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjM2MSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[5]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQyMiIgd2lkdGg9IjYxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[6]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUyMSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[7]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIzMCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[8]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQ4NSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[9]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQ4MCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
@@ -0,0 +1,144 @@
|
||||
[#]: subject: "Zorin OS 16 is a Visual Spectacle! You Can Download This New Linux Release Right Now"
|
||||
[#]: via: "https://news.itsfoss.com/zorin-os-16-release/"
|
||||
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Zorin OS 16 is a Visual Spectacle! You Can Download This New Linux Release Right Now
|
||||
======
|
||||
|
||||
Zorin OS 16, one of the most anticipated Linux distros, based on Ubuntu 20.04.3 LTS, has arrived.
|
||||
|
||||
With the latest release, they now offer a new “Pro” edition replacing the “Ultimate” edition that comes loaded with a few applications pre-installed and a couple of extra layouts.
|
||||
|
||||
Moreover, you get technical support for installation if you get the Zorin OS 16 Pro to support the developers.
|
||||
|
||||
The base edition is Zorin OS 16 “Core,” is free, which includes all the essentials.
|
||||
|
||||
In this article, I shall highlight the key new additions along with my initial impressions of Zorin OS 16.
|
||||
|
||||
### Zorin OS 16: What’s New?
|
||||
|
||||
Zorin OS 16 may not be as big of an upgrade compared to [elementary OS 6][1], but there are significant improvements across the board. Let us take a look at them.
|
||||
|
||||
### Refined User Interface
|
||||
|
||||
![][2]
|
||||
|
||||
The user interface remains familiar, but they have revamped the default theme and worked on the animations to present a polished look.
|
||||
|
||||
Subtle differences to the default transparency setting, theme, icons, and animations impact the overall user experience.
|
||||
|
||||
While you can notice the differences with Zorin OS 16 Core, the Pro edition takes it up a notch with the stunning new wallpapers and premium layouts available out-of-the-box.
|
||||
|
||||
### Flatpak Enabled
|
||||
|
||||
![][3]
|
||||
|
||||
Previously, Zorin OS supported snap right out of the box with its Software center. Now, with Zorin OS 16, Flathub has been enabled by default.
|
||||
|
||||
So, you can find plenty of applications available, including Flatpak packages in the Software manager.
|
||||
|
||||
You can even select a different package (if it is available) from the dropdown menu available in the top-right corner (as shown in the screenshot above).
|
||||
|
||||
### Improved Tour Screen
|
||||
|
||||
![][4]
|
||||
|
||||
They have also revamped their welcome screen to help you set up all the important things right from the start.
|
||||
|
||||
You get to configure online accounts, connect your smartphone with Zorin Connect, and get a head start on the available layouts to choose from.
|
||||
|
||||
### Windows 11-like Layout
|
||||
|
||||
![][2]
|
||||
|
||||
In my previous [Zorin OS 16 beta][5] coverage, I mentioned a potential Windows 10X-like layout was in the works.
|
||||
|
||||
Considering that Windows 10X no longer exists, the new layout is an alternative to Windows 11 experience.
|
||||
|
||||
Do note that you need to purchase the Zorin OS 16 Pro if you want to access Windows 11-like layout on your system.
|
||||
|
||||
### New Touchpad Gestures
|
||||
|
||||
For laptop or touchpad users, you can now swipe up/down with four fingers to move between workspaces and pinch using three fingers to open the activities overview.
|
||||
|
||||
### New Sound Recorder App
|
||||
|
||||
![][6]
|
||||
|
||||
A clean sound recording app to help you quickly record voice notes or podcasts without worrying about 3rd party applications.
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
Even though I don’t have a figure, I observed some noticeable performance improvements compared to my experience with Zorin OS 15.
|
||||
|
||||
For instance, switching between different layouts is an entirely seamless experience.
|
||||
|
||||
As a side note, I tested Zorin OS 16 Pro on my desktop with **i5-7400, 16 GB RAM,** and **a GTX 1050ti** graphics card.
|
||||
|
||||
I always have my doubts when it comes to Nvidia driver compatibility. But it worked like a charm.
|
||||
|
||||
The boot menu when installing Zorin OS 16 offered a different option for modern NVIDIA drivers, which is what I chose to install.
|
||||
|
||||
So, yes, **Zorin OS 16’s ISO comes with Nvidia driver support out-of-the-box.**
|
||||
|
||||
### Other Improvements
|
||||
|
||||
![][7]
|
||||
|
||||
There are several other additions to the animation, customization settings, and more with Zorin OS 16. Some of them are:
|
||||
|
||||
* Jelly mode to enable a macOS-like animation when minimizing or opening applications.
|
||||
* Improved taskbar
|
||||
* Introduction of fractional scaling
|
||||
* Active directory domain option in the installer
|
||||
* New photos app
|
||||
* Disabled telemetry and tracking in Firefox browser for better privacy
|
||||
|
||||
|
||||
|
||||
To explore more, you can check out [our Zorin OS 16 features list][8] or go through the [official announcement][9].
|
||||
|
||||
### Get Zorin OS 16
|
||||
|
||||
You can download Zorin OS 16 Core for free. If you opt for the Pro edition at **$39**, you also get access to a Pro-lite edition, which will be available to install for old computers.
|
||||
|
||||
The free lite edition and the pro lite version is not yet available and should be coming soon.
|
||||
|
||||
[Zorin OS 16 Download][10]
|
||||
|
||||
What do you think about Zorin OS 16? Share your thoughts in the comments down below.
|
||||
|
||||
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
|
||||
|
||||
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
|
||||
|
||||
I'm not interested
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/zorin-os-16-release/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/elementary-os-6-release/
|
||||
[2]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQzOSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[3]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIzMCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[4]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUzNiIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[5]: https://news.itsfoss.com/zorin-os-16-beta/
|
||||
[6]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQ4MCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[7]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQxNSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
|
||||
[8]: https://news.itsfoss.com/zorin-os-16-features/
|
||||
[9]: https://blog.zorin.com/2021/08/17/2021-08-17-zorin-os-16-is-released/
|
||||
[10]: https://zorin.com/os/download/
|
||||
@@ -92,7 +92,7 @@ via: https://twobithistory.org/2017/09/28/the-lineage-of-man.html
|
||||
|
||||
作者:[Two-Bit History][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[bestony](https://github.com/bestony)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (osu-zxf)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zxy-wyx)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
[#]: subject: "My first programming language and early adventures"
|
||||
[#]: via: "https://opensource.com/article/21/8/my-first-programming-language"
|
||||
[#]: author: "Tomasz Waraksa https://opensource.com/users/tomasz"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
My first programming language and early adventures
|
||||
======
|
||||
A student in 1988 in Poland is invited to a computer lab.
|
||||
![Old UNIX computer][1]
|
||||
|
||||
A few days ago, contributors to Opensource.com were asked to share our personal stories about how we got into programming. Many entertaining and fascinating responses were submitted. It would be interesting to quantify these data in time. Intriguing patterns emerged. The 70s generation was nostalgic about Fortran, punch cards, and dial-up access to shared mainframes. 80s kids (amongst which I qualify) shared stories of C, BASIC, or Pascal and their beloved Atari and Commodore computers. Surprisingly few stories from the 90s arrived. Almost like there's a generation gap. Maybe teenagers were running away in horror from C++, MFC, and the dreaded Hungarian notation, which was the order of the day. Then there's strange silence from the youngest generation. Maybe our young Raspberry Pi enthusiasts are [too busy making things][2].
|
||||
|
||||
Here's more about my road to programming.
|
||||
|
||||
### My first programming language
|
||||
|
||||
My first programming language was Microsoft BASIC. I learned it on the mighty MSX SpectraVideo 738 home PC. The MSX standard was a home computer architecture based on the Z80 CPU. Developed in the 80s by Microsoft, it was produced by Sony, Philips, Pioneer, Sharp, Yamaha, and many other vendors. My home country is Poland, and we were still under communist rule, and cut off from modern IT technology due to economic sanctions against us. But the winds of change came during the late 80s, and the MSX Spectravideo made it to my school.
|
||||
|
||||
![MSX Specravideo 738][3]
|
||||
|
||||
Image CC BY-SA [Hans Otten][4]
|
||||
|
||||
I was a student at the time, so I wasn't paid. I got so fascinated with programming that I would be willing to pay myself for the pleasure. Thankfully, all schools and universities were free at that time. Imagine you would start your IT career with zero debt! I started during my early high school years, in 1988 in Poland. I had been growing long hair, playing guitar, listening to Black Sabbath, and hoping to have a rock band one day—all the while missing out on computers. And I had a friend, who I'll call Mr. Briefcase. He was another student, and also a computer nerd with a reputation. He entered the room one day and asked _how are you?_ He had to listen to me for a while, because the Polish _will_ tell you how they are, if you ask. Then he said: _"Hey, I'm going to the computer lab. You can join me. There's no one there today except me."_ I jumped excitedly: _"The entire evening?"_ He answered: _"Sure thing. I'll be busy, but you can play games and stuff."_
|
||||
|
||||
When we first entered the lab, it felt like a Star Destroyer command center from [Star Wars][5]. The following hardware was available:
|
||||
|
||||
* One beautiful IBM PC clone, Spectravideo SVI-838 xPress-16 with an excellent clickety keyboard—no modern mechanical keyboard has yet been able to replicate that experience. Unfortunately, it was off-limits for newcomers like me.
|
||||
* ZX Spectrums—I was not too fond of these, since they looked like toys with their rubbery keyboards.
|
||||
* Futuristic MSX SVI-738 computers with color screens and Seikosha dot-matrix printers.
|
||||
|
||||
|
||||
|
||||
The choice was made. I played for a while but got bored very quickly. I asked Mr. Briefcase:
|
||||
|
||||
**Me**: _So what is it that you’re doing?_
|
||||
|
||||
**Briefcase**: _Programming._
|
||||
|
||||
**Me**: _How do you do that?_
|
||||
|
||||
**Briefcase**: _Here._
|
||||
|
||||
And he threw a manual at me.
|
||||
|
||||
### Hello world
|
||||
|
||||
I ran through the "hello world!" examples, and then stumbled onto a chapter about computer graphics. It turned out that our MSX had impressive graphic capabilities. After an hour of struggling with English, which was still foreign to me, there it was—my first working computer program, written in BASIC. I was thrilled, flabbergasted, and completely hooked. I could command this computing device to _do things_. Beautiful things. Utterly stupid things. Boring things. And it would do them all, without hesitation, line after line, only sometimes responding with `Syntax error!`
|
||||
|
||||
It was pure magic! The very next day, I signed up for the computer lab.
|
||||
|
||||
### Computer graphics
|
||||
|
||||
In the following months, I had a lot of fun with computer graphics. Those machines were amazingly efficient in educating young people in computing. Programming a language interpreter was the only way to interact with it. It booted, and you had to enter commands to do anything useful. If you were curious enough, you would inevitably ask—are there more commands? In the end, you got sucked into programming without even knowing it. The entry threshold was so low.
|
||||
|
||||
![Code][6]
|
||||
|
||||
Image CC0 Alan Smithee
|
||||
|
||||
For example, to draw a circle on the screen, all I had to do was:
|
||||
|
||||
* Boot the computer and wait a few seconds. Yes, it only took seconds to boot!
|
||||
* Write `10 CIRCLE 100`,`100`,`50` and press **ENTER**. Yes, we had to number the lines ourselves.
|
||||
* Write `run` and press **ENTER**.
|
||||
|
||||
|
||||
|
||||
There was a simplicity to programming in those days. Today, you have choices to make before you write a single line of code. You have to choose your development platform (web, desktop, both), your programming language, your framework, and more.
|
||||
|
||||
Of course there are always choices to make, but it feels simpler when all you need are a few resources, and when your computer has only **64kB** of memory—the usual on 8-bit machines. To give you a sense of scale—a single high-resolution desktop icon on my Pop_OS Linux box can be bigger than that. Yet within this tiny memory, it could run an operating system and an academic-grade compiler. It could run graphic programs with flawless sprite animation and collision detection. It would play percussion tracks through a programmable noise generator. I have to admit, [I know it's possible][7] but I hardly know where to begin with these kinds of activities today.
|
||||
|
||||
### Pascal and beyond
|
||||
|
||||
My MSX had a 3.5" floppy drive—an amazing thing these days. One day we received floppies with the CPM 2.2 operating system and a [Turbo Pascal 3.0 compiler][8]. This is how I tasted my first actual programming language, while avoiding further exposure to BASIC. Turbo Pascal was beautiful: expressive, concise, safe, and structured. There's an anecdotal theory about why programmers from Central and Eastern Europe have such highly valued skills. In western countries, C and C++ were the order of the day, full of fun quirks and idiosyncrasies. Over here though, we started with Pascal. It was a programming language of choice in schools and universities. The differences between these two are substantial, and the theory is that they wired our young minds in a substantially different way.
|
||||
|
||||
![Turbo Pascal][9]
|
||||
|
||||
Image [Public Domain][10]
|
||||
|
||||
Pascal was much more disciplined than C, and it was as "close to the metal" as it gets. Pascal had pointers, direct memory operations, and even `asm ... end` block for assembly code injection. Yet pointers weren't thrown in everywhere like they are in C, and buffer overflow attacks through null-terminated strings were non-existent. Strings in Pascal is just an array of characters, and only the first entry contains the explicit string length. Simple! It also had a proper module system, precompiled libraries, strict type control, and a blazing fast compiler on top of that.
|
||||
|
||||
Turbo Pascal had an enormous impact on the way I think while programming. Eventually it implemented object-oriented programming, and smoothly prepared me for complex software architectures and programming on Windows with Borland Delphi. I touched C and C++ only when I had no other choice.
|
||||
|
||||
Decades later, I've realized that all my career, I have unconsciously followed in the footsteps of [Anders Hejlsberg][11]. He and his team were creators of a highly successful line of Turbo compilers at Borland. Then they created Delphi, which was a relief for Windows programmers struggling with Visual Basic, WFC, MFC, Charles Petzold books, and Hungarian notation. After Borland, he continued at Microsoft and created [.NET][12], which I happily jumped into. Finally, he created TypeScript, which became the backbone of modern enterprise web development.
|
||||
|
||||
Nowadays, I'm busy architecting and developing large web applications for enterprises. JavaScript and TypeScript is the order of the day, with back-ends running on NodeJS, .NET, or Python and writing little utilities and scripts with Python and Bash, and struggling with complexities of cloud computing and [YAML][13]. After all these years, I still enjoy the thrill. I can't imagine a more satisfying job that keeps challenging me and never gets dull and boring.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/my-first-programming-language
|
||||
|
||||
作者:[Tomasz Waraksa][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/retro_old_unix_computer.png?itok=SYAb2xoW (Old UNIX computer)
|
||||
[2]: https://opensource.com/articles/21/3/raspberry-pi-projects
|
||||
[3]: https://opensource.com/sites/default/files/svi738.jpg (MSX Specravideo 738)
|
||||
[4]: http://msx.hansotten.com/special-msx-hardware/svi-738-xpress/
|
||||
[5]: https://opensource.com/article/21/5/open-source-star-wars
|
||||
[6]: https://opensource.com/sites/default/files/basic.jpg (Code)
|
||||
[7]: https://opensource.com/article/17/10/python-101
|
||||
[8]: https://en.wikipedia.org/wiki/Turbo_Pascal
|
||||
[9]: https://opensource.com/sites/default/files/uploads/turbo-pascal.png (Turbo Pascal)
|
||||
[10]: https://commons.wikimedia.org/wiki/File:Turbopascal_6.png
|
||||
[11]: https://en.wikipedia.org/wiki/Anders_Hejlsberg
|
||||
[12]: https://opensource.com/article/19/9/getting-started-net
|
||||
[13]: https://www.redhat.com/sysadmin/yaml-beginners
|
||||
@@ -0,0 +1,300 @@
|
||||
[#]: subject: "What was your first programming language?"
|
||||
[#]: via: "https://opensource.com/article/21/8/first-programming-language"
|
||||
[#]: author: "Jen Wike Huger https://opensource.com/users/jen-wike"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
What was your first programming language?
|
||||
======
|
||||
These 24 open source technologists share their programming origin
|
||||
stories.
|
||||
![Computer laptop in space][1]
|
||||
|
||||
We asked our contributors _What was your first programming language?_ but the question goes much deeper than that. There are stories to tell about who suggested it or what prompted you to learn it. If you were paid to do so, and what happened next. Then there's a lot it says about your age and what was going on in the world.
|
||||
|
||||
Let's hear a little bit about these 24 technologists' stories.
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *BASIC
|
||||
|
||||
*Were you paid to learn it? *Nope.
|
||||
|
||||
*Did you choose it? *Not really.
|
||||
|
||||
*Why? *It was Christmas of 1979, my parents (a school maintenance worker and a public health nurse) scrimped and saved the staggering US$1000 to buy a Tandy/Radio Shack TRS-80. It came with a ring binder that covered the complete BASIC programming language, and my Dad figured getting me to learn to write computer software would be a good way to keep me out of trouble.
|
||||
|
||||
*What happened next? *Mom and Dad would buy me and my younger brother books or subscriptions to popular magazines about "home computing," which included printed source code for a variety of games. We spent hours every weekend painstakingly typing and then debugging line by line with the accompanying checksums to find our typos. When the games got boring, we'd modify them... trivially at first just tweaking strings here and there to turn, say, a roman battle strategy game into a space battle strategy game; but later increasing the complexity of our changes and eventually starting to write terrible games of our own. Soon after that, we were sharing disks by mail and then over BBSes at 110bps.
|
||||
|
||||
Four decades later, I can collaborate on creations with the entire world and home connectivity has increased 7+ orders of magnitude, but part of me still misses those Saturday afternoons hunched over the keyboard, getting thoroughly trounced by my little brother at something truly terrible we created together. —[Jeremy Stanley][2]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *My first language was BASIC, which I learned in 7th grade.
|
||||
|
||||
*Were you paid to learn it? *Not unless you count being allowed to play Wolfenstein 3D, Minecraft, and Sim City in the computer lab at lunch as a perk for being interested enough in computer science to learn BASIC for fun.
|
||||
|
||||
*Did you choose it? *I don't think I was aware enough at the time to realize there might have been alternatives. This was what was available in the computer lab, and some older students knew enough about it to get me into it. I don't remember it even being part of the computer science class curriculum.
|
||||
|
||||
*Why? *At the time, it was just for fun. I used it exclusively to create text-based "Choose Your Own Adventure"-style games. Something about creating something artistic and fun from code and having the computer run it appealed to me. I'd used computers before, but this was the first time I made it do something for me.
|
||||
|
||||
*What happened next? *Perhaps not-so-coincidentally, I've used "Choose Your Own Adventure"-style games to teach myself every one of the programming languages I've learned the rest of my life.
|
||||
|
||||
This experience and the first exploration of computer games (both commercial and self-written) started me down a path toward getting involved in computers more deeply, always at school until my family bought our first computer when I was in 11th grade. Three years later, I translated this exploration into my first computer job as an intern for a research company that eventually hired me for my first "real" job out of college—working in their IT Support group.
|
||||
|
||||
I credit BASIC (and Sim City) with starting me down the path toward where I am now as an SRE, writing code and running clusters daily, some 30 years later. —[Chris Collins][3]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *I played with BASIC, but my first formal introduction was PL/I—learned it in my first programming course in college. —[Heidi Ellis][4]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *My first programming language was BASIC. This was in 1981. I learned it because I bought a home computer that booted into a BASIC editor, a TRS-80 Color Computer. It had a whopping 4K of RAM (not a typo) and could store programs on a cassette tape. I wanted to make the computer do things, so I learned how to instruct it using language it understood. Once you tap, for the first time, into that feeling of joy when your program runs successfully, the elation takes over, and you find yourself wanting to experience it again. Next thing you know, 40 years have passed. —[Matthew Helmke][5]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *My first programming language was BASIC. It was part of a computer science class I took in my first semester of college in 1977, so I was not paid to learn it nor did I choose it. But I always thought it was a great first step since it taught me how to think like a computer (and I had a good teacher). It didn't lead to anything right away as I went to graduate school in Economics, but years later I was an IT Project Manager. So I never was a coder, but I managed a few. —[Kevin O'Brien][6]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *BASIC
|
||||
|
||||
*Were you paid to learn it? *No.
|
||||
|
||||
*Did you choose it? *It was built into the Apple ][ computer my Mom brought home for the summer, and my choices were limited.
|
||||
|
||||
*Why? *It was either BASIC or 6502 Assembly, and BASIC seemed more attainable to sixth-grade-me.
|
||||
|
||||
*What happened next? *I went to the public library and found all the back issues of "Byte" magazine with source listings for Apple ][ programs. I spent a lot of time typing in programs that I could barely follow and learning the joys of debugging someone else's code (ok, I'm pretty sure I introduced most of the bugs). I was hooked. Several years later, senior-in-high-school me was very surprised and excited to learn that you could major in something called "computer science." The rest was history. —[Erik O'Shaughnessy][7]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *Fortran IV—tells you something about how long ago this was.
|
||||
|
||||
*Were you paid to learn it? *No, this was part of my first computer science course in college, so I guess that means I paid to learn it. This was on a mainframe, so after writing your program on paper, you bought your blank IBM punchcards, sat down at a keypunch to punch them out, then had to submit your collection of punchcards as a "job." Then the next day, you got your cards back with a printout from a line printer. If your program didn't run, you got nothing, or you might get pages and pages if you managed to create some sort of never-ending loop.
|
||||
|
||||
*What happened next? *At the tail end of college, they began using _Watfor_, a Fortran implementation from the University of Waterloo in Canada. Its advantage was that you could use it on a terminal, saving your programs on the central system, rather than the punchcards we loved so well. So you could run your program yourself and create your never-ending loops right away. Whoopee!
|
||||
|
||||
After Fortran, the next language that caught my eye was BASIC, which was a lot like Fortran, but handled strings much better. Fortran was awful with strings. This was mostly on an Amiga.
|
||||
|
||||
After switching to Linux, my next language was Perl, which oddly enough seemed like a fairly easy transition from BASIC. After Perl, came Python, a language less stiff with syntax. —[Gregory Pittman][8]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *Waterloo Fortran IV in 1974-5, my first computer science course—taken in the second year—back when I was sorta sure I wanted to major in computer science. We also learned a bit about IBM 360/370 assembler later in the year. Back in those days, the lower-year courses at UBC used keypunches, and there was a "student terminal" where you would cue up with your deck of cards and exchange a "blue ticket" for a run of your deck, then walk around behind the IBM line printer to pick up your output. If you were careless or distracted you might put your deck on top of the printer—even though there was a sign saying "don't put your card deck on top of the printer, in case it opens"—and of course if you did, the printer would that very moment run out of paper or have a jam and obligingly raise its lid, which caused your card deck to spill to the floor and become an unorganized mess.
|
||||
|
||||
In my third year, still in computer science, I took a bunch of courses—the mainstream third-year course featuring PL/I, a one-semester 360/370 Assembler course, the two honors courses on computational theory, a numerical analysis course, "the twelve languages of MTS," and a bunch of math courses.
|
||||
|
||||
In my fourth year, I was hired by the applied math institute as a research assistant. At that point, I was getting paid for writing Fortran programs for a small group of mathematicians mostly interested in solving differential equations. Also, by then, I realized that computer science wasn't for me, and I had switched to math. I did continue to take some computer science courses—optimization, more numerical analysis. Looking back, those were my first steps down the data science pathway.
|
||||
|
||||
My first post-university job was programming, mostly in Fortran and in PL/I and SPSS, a statistics language. As well, I learned how to use MPSX, an IBM linear programming utility. —[Chris Hermansen][9]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *In high school, a teacher who had zero experience with computers was asked to teach computer programming as part of an experiment: My school had not tried this before. Xerox Corp. provided the school with a Model-33 teletype and a 110-baud acoustic coupled modem, which gave us access to their XDS Sigma 7 mainframe running the CP-5 time-sharing system. BASIC was the order of the day.
|
||||
|
||||
_Were you paid to learn it?_ Do grades count?
|
||||
|
||||
*What happened next? *A few of us started "poking a stick" at the machine to see what would happen if we didn't type "BASIC" at the prompt... which lead us to discover that there were _other_ languages! And other stuff too! If I recall, there were (at least) three separate Fortran compilers—Fortran, FLAG (Fortran Load And Go—which compiled lightning-quick, or what passed for "quick" in the day), and at the opposite end EFFORT—or possibly EFORT, but pronounced "effort." S-L-O-W to compile, but it did what appeared to be, to our young eyes, amazing optimization of the code. Also, a brief foray with a "weird" keyboard with all sorts of symbols, and APL, where backspace was not used to erase anything but to overstrike operators to make other operators. —[Kevin Cole][10]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *Atari PILOT and Atari BASIC. My family bought an Atari 1200XL when I was a kid, and while I started out just using it for games and some art programs, there were two cartridges that my Dad said were "for adults" and "I wouldn't like them because they're not for kids." So obviously, I was incredibly curious. One day I decided to check them out. I was totally confused at first but then found the book that he had about them, and I typed in the sample code and thought it was really cool that I could make things happen. I never was able to write anything entirely on my own, but I took the sample code and just changed parts until I either got it to do something else or broke it and had to undo those changes. I've been meaning to try it out again and see how much I remember, but I just haven't had the time. —[JT Pennington][11]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *ELAN. It was a superb language for the time. It is important to note it was tightly coupled with the OS EUMEL so we could do parallel computing.
|
||||
|
||||
_Were you paid to learn it?_ It was an after-school activity.
|
||||
|
||||
*Did you choose it? *No.
|
||||
|
||||
*Why? *I wanted to learn piano, and my parents said I would get one if I take a typewriter course. Next door was the after-school computer club. I thought that was more interesting. Unfortunately, I still don't know how to play the piano as computers kept me busy till today.
|
||||
|
||||
*What happened next? *When I started at the university, they still had punch cards and Fortran. I was lucky as the high school teacher allowed me to use the parallel computer at the high school for programming. In between, I also tried BASIC, but that was just inferior and boring. I then looked at Pascal, which was not any better than ELAN. After C, Modula-2, and Ada, I finally found Occam and did lots of stuff in Occam on transputers. That was exciting as we could do more parallel computing. Having access to 64 of them was pretty cool. Also, plugging in various network configurations was exciting. This was decades ago. I see a difference between yesteryear's high school students and today's. While we initially had few resources (I could not afford a computer till I was in my fourth year at university), today's computers are commodities. Furthermore, the combination of computers and robotics such as FLL (FIRST Lego League) makes it possible to lower the entry barrier. However, today also students are distracted by accessibility to video games and access to very cool graphics. Ready-made products (videogames, cell phones, tablets) may limit the available "time" today's students have to learn computer science in their free time. I have to admit that if I would have been offered today's video games when I grew up, I may have had a very different outlook on computer science and may not have been labeled by my high schoolmates "nerd," but the video gamer.
|
||||
|
||||
Unfortunately, I have no time to do video games as my RTX3090 plays AI algorithms … The toy I really want for me is an A100 and a DGX which I use now remotely. I would argue that due to Google colab and accessibility via Jupyter, access to AI can be lowered to the high school level. However, this all depends on the high school teacher that introduces you to it. If you just have one that teaches you block-programming instead of, for example, Python on the lego robots or one that uses scratch instead of Google colab, then we do not leverage the potential that these students have in their early years and can leverage this superb infrastructure. —[Gregor von Laszewski][12]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *I got into Logo on an Apple, a computer language developed at MIT by Seymour Papert and others in 1967. It was a language designed for education. It's a subset of Lisp.
|
||||
|
||||
I learned it as part of a graduate education program I was involved with at the time. As part of that program, I taught geometry to a fifth-grade student using the Logo programming language. While teaching this student the computer language and the curriculum, I discovered that my own trouble and learned helplessness with mathematics came from an inability to visualize the material. After completing the graduate course, I used the Logo language to teach other students geometry and mathematics using the same curriculum and programming language. The students and I learned math and developed some beautiful graphics in the process, and we actually programmed a 'turtle' robot that drew our images on large pieces of paper on the classroom floor. My experience with programming led me to look for other ways to bring mathematics to life for students, which led me to Python and the "turtle' module. Lately, I've been teaching students how to write Python programs that feature an 'on-screen' turtle robot that can create beautiful graphics while at the same time introducing those students to the Python language and logical thinking skills. —[Donald Watkins][13]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *ZX81 BASIC.
|
||||
|
||||
I was still at school, probably aged 10 or 11, when a friend got a ZX81—so I taught myself BASIC and wrote a couple of simple programs I could try out on his machine. Christmas 1982, I got my own ZX81 and pretty soon outgrew the hardware and moved onto a ZX Spectrum in late 1993, by which time I was also programming a little in Z80 assembly.
|
||||
|
||||
A couple of years later, I also picked up an early CASIO handheld that ran BASIC. It was one of the PB series, possibly the PB-200, but I can't remember the exact model version. I managed to convince my teachers to let me use it for my O-Level math exam at the age of 16 in the UK. I did take a look at some other languages but didn't really learn any until I started on Ada at university. —[Steven Ellis][14]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *My first ever programming language was BASIC in the early eighties.
|
||||
|
||||
One of my relatives bought a C64 for their kids to get started with learning computers. They only used it for gaming, and I was also invited. But they also had a book about BASIC, and I was curious and gave it a try. I wrote some shortcode, I did not even know how to save it, but it was exciting to see that the computer does what I say to it. This means that I was not paid to learn it, and it was not my choice. It was the language available to me. Obviously, when I got my first computer a few years later, an XT compatible box, I first wrote some code in GW-BASIC, the dialect of BASIC available with DOS.
|
||||
|
||||
*What happened next? *The first time I really choose a programming language was Pascal. I asked around, checked some books, and it seemed to be a good compromise between features and difficulty. First, it was Turbo Pascal, and I coded all kinds of simple games and graphics in it. I loved Pascal, so in my university years, I even used it (well, FreePascal and Lazarus) for measurement automation and modeling how pollution spreads in groundwater. —[Peter Czanik][15]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *The language of the Casio fx-7200G ([a variant of][16]). I don't think it has its own name.
|
||||
|
||||
*Were you paid to learn it? *No.
|
||||
|
||||
*Did you choose it? *No.
|
||||
|
||||
*Why? *I got this programmable calculator (the box said "computer"...) for my 13th birthday.
|
||||
|
||||
*What happened next? *A year later, first high-school year, I studied their Pascal, even though we didn't have books for it—the main Pascal book our teacher recommended was university-level, considered by him to be a bit too hard for us—and the main text we used for theory and exercises was actually using BASIC, so I also learned some BASIC (unintentionally, at least from the teacher's POV).
|
||||
|
||||
I considered myself a latecomer—some kids in my class had computers with BASIC (commodore 64, Spectrum Sinclair, Amstrad) at home, and I already knew a bit of BASIC before high school, and along the first years, there was a semi-tension between us—me, and those who knew BASIC and didn't appreciate the advantages of Pascal.
|
||||
|
||||
Later on, I went to university (math and computer science), where students could use DOS PCs or a few Macintoshes, or terminals (text ones, X Terminals if you were lucky and one was available), mainly to connect to shared SunOS 4 machines. In my second year (in 1993), someone told me about Linux, which I could run at home. I already bought myself a newer PC (an AMD 386SX-compatible. Only after I "decommissioned" it, ~ 8 years later, I realized it was AMD and not an Intel 386, which is what I thought I was buying) before knowing about Linux, learning my 8088 PC isn't suitable for running more modern OSes, and so I tried Linux, which it took me several months to get installed with only 2MB RAM—soon after that, I upgraded to 4MB and then seldom rebooted to DOS (which I kept as a dual-boot option for several years). I still remember my astonishment and excitement at being able to run a UNIX-like OS, even with X windows (after upgrading to 4MB RAM), all at home.
|
||||
|
||||
In terms of languages, in the university, we studied/used Pascal (first intro course), C (intro to systems programming course), and then some course-specific ones—Eiffel (in the OOP course), MatLab (for a workshop), etc.
|
||||
|
||||
My first real job was in a project written on Unix (we used mainly DECstation machines with Ultrix), mainly in Lisp (Lucid Common Lisp) and C, where I studied Lisp, and from which I still have very good memories, even though I never used it later. I managed to make the project semi-work on a PC with Linux, as a personal side project, using a copy of LCL for SCO Unix, which I managed to make work on Linux with the `ibcs2` module and recompiling GNU `libc` with a cross-compiler toolchain (`GCC/as/ld` on Linux to generate COFF binaries for SCO). I was quite proud to demonstrate the application to my manager—something which normally needed a workstation costing ~ $30K, running on a $5K PC. But this never went to production. —[Yedidyah Bar David][17]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *TI-BASIC
|
||||
|
||||
*Were you paid to learn it? *No, but then, I was 10.
|
||||
|
||||
*Did you choose it? *No.
|
||||
|
||||
*Why? *It was the only language available on the TI-99/4A! Well, there was the "Extended Basic," too, but that was just an extended instruction set. You could actually write decent games in 16Kb of RAM.
|
||||
|
||||
*What happened next? *The next step was to type in programs that were shipped in print magazines and record them on audio cassette tapes. But with my brother, we took that one step further—we went live on radio to broadcast the resulting sound for others to record! With a clear recording and enough error correction, you could distribute and download programs wirelessly back in 1985. —[Thierry Carrez][18]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *GW-BASIC
|
||||
|
||||
*Did you choose it? *No.
|
||||
|
||||
_Why?_ It was standard education for beginners.
|
||||
|
||||
*What happened next? *I started in a company for computer hardware specialist. —[Hüseyin GÜÇ][19]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *BASIC, on the VIC-20.
|
||||
|
||||
*Were you paid to learn it? *Nope.
|
||||
|
||||
*Did you choose it? *Only insofar as I chose the computer.
|
||||
|
||||
*Why? *I figured that the VIC would be at least mostly compatible with the PET I had seen in school. Also, it had a decent keyboard.
|
||||
|
||||
*What happened next? *Those were the days of programming because there was no other way to do anything with it—learned a lot. —[Bob Murphy][20]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *It was the year 2004-05 if I recall. I was in school, maybe a fifth-grader, I was introduced to BASIC. Before that, I had learned a little bit of something called "Window Logo."
|
||||
|
||||
*Were you paid to learn it? *My parents paid for my school.
|
||||
|
||||
*Did you choose it? *Not at all.
|
||||
|
||||
*Why? *Part of the curriculum my school decided on.
|
||||
|
||||
*What happened next? *It definitely piqued my interest in programming, and I went on to learn C/C++ through extra-curricular courses outside of my school. My parents encouraged it and managed to pay extra fees somehow. I often ended up as the only "kid" in the entire computer institute. I was the only one learning a programming language while others mostly learned MS Office or PhotoShop etc. LOL. Well, the rest is history. —[Kedar Vijay Kulkarni][21]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *Fortran, because I'm old.
|
||||
|
||||
*Were you paid to learn it? *No, I paid to learn it by taking a computer science class.
|
||||
|
||||
*Did you choose it? *No, it was the only choice. I was lucky that we had terminals to work on instead of the punchcards that my poor husband used when he learned how to program in Fortran.
|
||||
|
||||
*Why? *I was a humanities major (English and Anthropology double major), and I was getting close to graduation and actually having to find a JOB. I figured a computer class might make that possible. As it has turned out, that particular programming class was one of the more valuable ones that I took in terms of marketable skills. It provided a good foundation for learning Python, understanding Git, and editing and writing documentation for Red Hat.
|
||||
|
||||
*What happened next? *I went home and taught myself BASIC on the TI-99 that my parents had bought (I'm not sure why they bought it, though—maybe for my little brother?). That early foundation in Fortran (of all things) made it easier to use the early PCs before Windows existed because I could figure out DOS. A humble beginning for sure. —[Ingrid Towey][22]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *In 2001, I learned Java SE 1.2 by reading the book _Goto Java_ from Addison-Wesley.
|
||||
|
||||
*Were you paid to learn it? *No, I was still in school.
|
||||
|
||||
*Did you choose it? *Yes.
|
||||
|
||||
*Why? *I wanted to create interactive websites with Java Applets.
|
||||
|
||||
*What happened next? *I went to college and got in touch with FOSS and learned ANSI C. —[Joël Krähemann][23]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *
|
||||
|
||||
I was going to write an article for this, but I already wrote that one: [You don't need a computer science degree to work with open source software (6 Aug 2020)][24].
|
||||
|
||||
Highlights from that article:
|
||||
|
||||
Our parents bought an Apple II+ clone called the Franklin ACE 1000. My brother and I taught ourselves how to program in AppleSoft BASIC. Our parents bought us books, and we devoured them. I learned every corner of BASIC by reading about something in the book, then writing a practice program. My favorite pastime was writing simulations and games.
|
||||
|
||||
I stayed with BASIC for a long time. But I began to learn other programming languages when I entered university. I was a physics student, and as part of our numerical analysis prerequisite, we had to learn Fortran. Having already learned BASIC, I thought Fortran was pretty easy to pick up. Fortran and BASIC were very similar, although Fortran was more limited in my experience.
|
||||
|
||||
My brother was a computer science major at a different university, and he introduced me to the C programming language. I immediately loved working in C! It was a straightforward programming language that gave me a ton of flexibility for writing useful programs. But I didn't have room in my degree program to take a class that didn't apply to my physics major. So, instead, I taught myself C by reading books and combing through the library reference guide. Each time I wanted to learn a new topic, I looked it up in the reference guide and wrote a practice program to exercise my new knowledge.
|
||||
|
||||
Over time, I leveraged what I'd learned to pick up other programming languages. I wrote a ton of Unix Korn shell scripts, Linux Bash scripts, and AWK scripts. I wrote small utilities in Perl, and later wrote Perl CGI and PHP pages for websites. I learned enough LISP to tweak my copy of GNU Emacs, and enough Scheme to work on a project that used GNU Guile. —[Jim Hall][25]
|
||||
|
||||
* * *
|
||||
|
||||
*What was your first programming language? *My first programming language was BASIC, Atari BASIC to be exact.
|
||||
|
||||
My family had an Atari 400 home computer in the early 1980s. I played games on it, but it also came with a cartridge for the BASIC language. It included a cassette recorder (Atari 1010). In those days, programs could be stored on standard audio cassette tapes. The Atari 400 didn't have internal storage, so I learned how to save my programs to cassette and later reload them. In addition to the usual "Hello World" programs, I wrote some that allowed for controlling sound and graphics using a joystick. I still remember the PEEK and POKE commands needed for setting and retrieving certain settings, such as a color or a sound setting.
|
||||
|
||||
_Were you paid to learn it?_ No.
|
||||
|
||||
_Did you choose it?_ Yes, it was the one language included with the Atari, so I decided to give it a try—and I did enjoy programming it.
|
||||
|
||||
*What happened next? *After a while, I guess I lost interest in Atari and computer gaming altogether. It wasn't until the mid-nineties that I became interested in computers and programming again when I attended computer science classes to earn a minor in CS. Those courses taught me languages such as C and Assembly and many general computer and networking skills. I later learned Java as part of my Master's degree. I have only done a small amount of formal coding during my career, mostly a little Java in a ColdFusion environment in the mid-2000s. In terms of coding, shell scripting has been my mainstay, mostly BASH and Windows, but I have coded for specific purposes whenever needed. I've used Job Control Language (JCL) for automating file transfers between mainframe systems. I've also used Python to feed REST API query results back to an enterprise monitoring dashboard. I still think that early experience with BASIC was valuable because I gained a respect for software and programming. —[Alan Formy-Duval][26]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/first-programming-language
|
||||
|
||||
作者:[Jen Wike Huger][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jen-wike
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_space_graphic_cosmic.png?itok=wu493YbB (Computer laptop in space)
|
||||
[2]: https://opensource.com/users/fungi
|
||||
[3]: https://opensource.com/users/clcollins
|
||||
[4]: https://opensource.com/users/heidi-jc-ellis
|
||||
[5]: https://opensource.com/users/matthew-helmke
|
||||
[6]: https://opensource.com/users/ahuka
|
||||
[7]: https://opensource.com/users/jnyjny
|
||||
[8]: https://opensource.com/users/greg-p
|
||||
[9]: https://opensource.com/users/clhermansen
|
||||
[10]: https://opensource.com/users/kjcole
|
||||
[11]: https://opensource.com/users/jtpennington
|
||||
[12]: https://opensource.com/users/laszewski
|
||||
[13]: https://opensource.com/users/don-watkins
|
||||
[14]: https://opensource.com/users/steven-ellis
|
||||
[15]: https://opensource.com/users/czanik
|
||||
[16]: https://en.wikipedia.org/wiki/Casio_fx-7000G
|
||||
[17]: https://opensource.com/users/didib
|
||||
[18]: https://opensource.com/users/thierry-carrez
|
||||
[19]: https://opensource.com/users/hguc
|
||||
[20]: https://opensource.com/users/murph
|
||||
[21]: https://opensource.com/users/kkulkarn
|
||||
[22]: https://opensource.com/users/i-towey
|
||||
[23]: https://opensource.com/users/joel2001k
|
||||
[24]: https://opensource.com/article/20/8/learn-open-source
|
||||
[25]: https://opensource.com/users/jim-hall
|
||||
[26]: https://opensource.com/users/alanfdoss
|
||||
@@ -1,157 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (YungeG)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Managing your attached hardware on Linux with systemd-udevd)
|
||||
[#]: via: (https://opensource.com/article/20/2/linux-systemd-udevd)
|
||||
[#]: author: (David Clinton https://opensource.com/users/dbclinton)
|
||||
|
||||
Managing your attached hardware on Linux with systemd-udevd
|
||||
======
|
||||
Manipulate how your Linux system handles physical devices with udev.
|
||||
![collection of hardware on blue backround][1]
|
||||
|
||||
Linux does a great job automatically recognizing, loading, and exposing attached hardware devices from countless vendors. In fact, it was this feature that, many years ago, convinced me to insist that my employer convert its entire infrastructure to Linux. The pain point was the way a certain company in Redmond couldn't load drivers for the integrated network card on our Compaq desktops while Linux did it effortlessly.
|
||||
|
||||
In the years since then, Linux's library of recognized devices has grown enormously along with the sophistication of the process. And the star of that show is [udev][2]. Udev's job is to listen for events from the Linux kernel involving changes to the state of a device. It could be a new USB device that's plugged in or pulled out, or it might be a wireless mouse going offline as it's drowned in spilled coffee.
|
||||
|
||||
Udev's job is to handle all changes of state by, for instance, assigning the names or permissions through which devices are accessed. A record of those changes can be accessed through [dmesg][3]. Since dmesg typically spits out thousands of entries, it's smart to filter the results. The example below shows how Linux identifies my WiFi interface. It shows the chipset my wireless device uses (**ath9k**), the original name it was assigned early in the process (**wlan0**), and the big, ugly permanent name it's currently using (**wlxec086b1ef0b3**):
|
||||
|
||||
|
||||
```
|
||||
$ dmesg | grep wlan
|
||||
[ 5.396874] ath9k_htc 1-3:1.0 wlxec086b1ef0b3: renamed from wlan0
|
||||
```
|
||||
|
||||
In this article, I'll discuss why anyone might want to use a name like that. Along the way, I'll explore the anatomy of udev configuration files and then show how to make changes to udev settings, including how to edit the way the system names devices. This article is based on a module from my new course, [Linux System Optimization][4].
|
||||
|
||||
### Understanding the udev configuration system
|
||||
|
||||
On systemd machines, udev operations are managed by the **systemd-udevd** daemon. You can check the status of the udev daemon the regular systemd way using **systemctl status systemd-udevd**.
|
||||
|
||||
Technically, udev works by trying to match each system event it receives against sets of rules found in either the **/lib/udev/rules.d/** or **/etc/udev/rules.d/** directories. Rules files include match keys and assignment keys. The set of available match keys includes **action**, **name**, and **subsystem**. This means that if a device with a specified name that's part of a specified subsystem is detected, then it will be assigned a preset configuration.
|
||||
|
||||
Then, the "assignment" key/value pairs are used to apply the desired configuration. You could, for instance, assign a new name to the device, associate it with a filesystem symlink, or restrict access to a particular owner or group. Here's an excerpt from such a rule from my workstation:
|
||||
|
||||
|
||||
```
|
||||
$ cat /lib/udev/rules.d/73-usb-net-by-mac.rules
|
||||
# Use MAC based names for network interfaces which are directly or indirectly
|
||||
# on USB and have an universally administered (stable) MAC address (second bit
|
||||
# is 0). Don't do this when ifnames is disabled via kernel command line or
|
||||
# customizing/disabling 99-default.link (or previously 80-net-setup-link.rules).
|
||||
|
||||
IMPORT{cmdline}="net.ifnames"
|
||||
ENV{net.ifnames}=="0", GOTO="usb_net_by_mac_end"
|
||||
|
||||
ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", NAME=="", \
|
||||
ATTR{address}=="?[014589cd]:*", \
|
||||
TEST!="/etc/udev/rules.d/80-net-setup-link.rules", \
|
||||
TEST!="/etc/systemd/network/99-default.link", \
|
||||
IMPORT{builtin}="net_id", NAME="$env{ID_NET_NAME_MAC}"
|
||||
```
|
||||
|
||||
The **add** action tells udev to fire up whenever a new device is plugged in that is part of the networking subsystem _and_ is a USB device. In addition, if I understand it correctly, the rule will apply only when the device has a MAC address consisting of characters within a certain range and, in addition, only if the **80-net-setup-link.rules** and **99-default.link** files do _not_ exist.
|
||||
|
||||
Assuming all these conditions are met, the interface ID will be changed to match the device's MAC address. Remember the previous dmesg entry showing how my interface name was changed from **wlan0** to that nasty **wlxec086b1ef0b3** name? That was a result of this rule's execution. How do I know? Because **ec:08:6b:1e:f0:b3** is the device's MAC address (minus the colons):
|
||||
|
||||
|
||||
```
|
||||
$ ifconfig -a
|
||||
wlxec086b1ef0b3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
|
||||
inet 192.168.0.103 netmask 255.255.255.0 broadcast 192.168.0.255
|
||||
inet6 fe80::7484:3120:c6a3:e3d1 prefixlen 64 scopeid 0x20<link>
|
||||
ether ec:08:6b:1e:f0:b3 txqueuelen 1000 (Ethernet)
|
||||
RX packets 682098 bytes 714517869 (714.5 MB)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 472448 bytes 201773965 (201.7 MB)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
```
|
||||
|
||||
This udev rule exists by default within Linux. I didn't have to write it myself. But why bother—especially seeing how difficult it is to work with such an interface designation? Take a second look at the comments included with the rule:
|
||||
|
||||
|
||||
```
|
||||
# Use MAC based names for network interfaces which are directly or indirectly
|
||||
# on USB and have an universally administered (stable) MAC address (second bit
|
||||
# is 0). Don't do this when ifnames is disabled via kernel command line or
|
||||
# customizing/disabling 99-default.link (or previously 80-net-setup-link.rules).
|
||||
```
|
||||
|
||||
Note how this rule is designed specifically for USB-based network interfaces. Unlike PCI network interface cards (NICs), USB devices are likely to be removed and replaced from time to time. This means that there's no guarantee that their ID won't change. They could be **wlan0** one day and **wlan3** the next. To avoid confusing the applications, assign devices absolute IDs—like the one given to my USB interface.
|
||||
|
||||
### Manipulating udev settings
|
||||
|
||||
For my next trick, I'm going to grab the MAC address and current ID for the Ethernet network interface on a [VirtualBox][5] virtual machine and then use that information to create a new udev rule that will change the interface ID. Why? Well, perhaps I'm planning to work with the device from the command line, and having to type that long name can be annoying. Here's how that will work.
|
||||
|
||||
Before I can change my ID, I'll need to disable [Netplan][6]'s current network configuration. That'll force Linux to pay attention to the new configuration. Here's my current network interface configuration file in the **/etc/netplan/** directory:
|
||||
|
||||
|
||||
```
|
||||
$ less /etc/netplan/50-cloud-init.yaml
|
||||
# This file is generated from information provided by
|
||||
# the datasource. Changes to it will not persist across an instance.
|
||||
# To disable cloud-init's network configuration capabilities, write a file
|
||||
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
|
||||
# network: {config: disabled}
|
||||
network:
|
||||
ethernets:
|
||||
enp0s3:
|
||||
addresses: []
|
||||
dhcp4: true
|
||||
version: 2
|
||||
```
|
||||
|
||||
The **50-cloud-init.yaml** file contains a very basic interface definition. But it also includes some important information about disabling the configuration in the comments. To do so, I'll move to the **/etc/cloud/cloud.cfg.d** directory and create a new file called **99-disable-network-config.cfg** and add the **network: {config: disabled}** string.
|
||||
|
||||
While I haven't tested this method on distros other than Ubuntu, it should work on any flavor of Linux with systemd (which is nearly all of them). Whatever you're using, you'll get a good look at writing udev config files and testing them.
|
||||
|
||||
Next, I need to gather some system information. Running the **ip** command reports that my Ethernet interface is called **enp0s3** and its MAC address is **08:00:27:1d:28:10**:
|
||||
|
||||
|
||||
```
|
||||
$ ip a
|
||||
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 08:00:27:1d:28:10 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.0.115/24 brd 192.168.0.255 scope global dynamic enp0s3
|
||||
```
|
||||
|
||||
Now, I'll create a new file called **peristent-net.rules** in the **/etc/udev/rules.d** directory. I'm going to give the file a name that starts with a low number, 10:
|
||||
|
||||
|
||||
```
|
||||
$ cat /etc/udev/rules.d/10-persistent-network.rules
|
||||
ACTION=="add", SUBSYSTEM=="net",ATTR{address}=="08:00:27:1d:28:10",NAME="eth3"
|
||||
```
|
||||
|
||||
The lower the number, the earlier Linux will execute the file, and I want this one to go early. The file contains code that will give the name **eth3** to a network device when it's added—as long as its address matches **08:00:27:1d:28:10**, which is my interface's MAC address.
|
||||
|
||||
Once I save the file and reboot the machine, my new interface name should be in play. I may need to log in directly to my virtual machine and use **dhclient** to manually get Linux to request an IP address on this newly named network. Opening SSH sessions might be impossible without doing that first:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo dhclient eth3`
|
||||
```
|
||||
|
||||
Done. So you're now able to force udev to make your computer refer to a NIC the way you want. But more importantly, you've got the tools to figure out how to manage _any_ misbehaving device.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/linux-systemd-udevd
|
||||
|
||||
作者:[David Clinton][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/dbclinton
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_BUS_Apple_520.png?itok=ZJu-hBV1 (collection of hardware on blue backround)
|
||||
[2]: https://en.wikipedia.org/wiki/Udev
|
||||
[3]: https://en.wikipedia.org/wiki/Dmesg
|
||||
[4]: https://pluralsight.pxf.io/RqrJb
|
||||
[5]: https://www.virtualbox.org/
|
||||
[6]: https://netplan.io/
|
||||
@@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (rakino)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (YungeG)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (chunibyo-wly)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: (https://opensource.com/article/21/4/share-files-linux-windows)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: (https://opensource.com/article/21/5/fog-computing)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Gordon-Deng)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hongsofwing)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: (https://opensource.com/article/21/6/freedos-linux-users)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( shipsw )
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
[#]: subject: (Tune your MySQL queries like a pro)
|
||||
[#]: via: (https://opensource.com/article/21/5/mysql-query-tuning)
|
||||
[#]: author: (Dave Stokes https://opensource.com/users/davidmstokes)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Tune your MySQL queries like a pro
|
||||
======
|
||||
Optimizing your queries isn't a dark art; it's just simple engineering.
|
||||
![woman on laptop sitting at the window][1]
|
||||
|
||||
Many people consider tuning database queries to be some mysterious "dark art" out of a Harry Potter novel; with the wrong incantation, your data turns from a valuable resource into a pile of mush.
|
||||
|
||||
In reality, tuning queries for a relational database system is simple engineering and follows easy-to-understand rules or heuristics. The query optimizer translates the query you send to a [MySQL][2] instance, and then it determines the best way to get the requested data using those heuristics combined with what it knows about your data. Reread the last part of that: _"what it knows about your data_." The less the query optimizer has to guess about where your data is located, the better it can create a plan to deliver your data.
|
||||
|
||||
To give the optimizer better insight about the data, you can use indexes and histograms. Used properly, they can greatly increase the speed of a database query. If you follow the recipe, you will get something you will like. But if you add your own ingredients to that recipe, you may not get what you want.
|
||||
|
||||
### Cost-based optimizer
|
||||
|
||||
Most modern relational databases use a cost-based optimizer to determine how to retrieve your data out of the database. That cost is based on reducing very expensive disk reads as much as possible. The query optimizer code inside the database server keeps statistics on getting that data as it is encountered, and it builds a historical model of what it took to get the data.
|
||||
|
||||
But historical data can be out of date. It's like going to the store to buy your favorite snack and being shocked at a sudden price increase or that the store closed. Your server's optimization process may make a bad assumption based on old information, and that will produce a poor query plan.
|
||||
|
||||
A query's complexity can work against optimization. The optimizer wants to deliver the lowest-cost query of the available options. Joining five different tables means that there are five-factorial or 120 possible combinations about which to join to what. Heuristics are built into the code to try to shortcut evaluating all the possible options. MySQL wants to generate a new query plan every time it sees a query, while other databases such as Oracle can have a query plan locked down. This is why giving detailed information on your data to the optimizer is vital. For consistent performance, it really helps to have up-to-date information for the query optimizer to use when making query plans.
|
||||
|
||||
Also, rules are built into the optimizer with assumptions that probably do not match the reality of your data. The query optimizer will assume all the data in a column is evenly distributed among all the rows unless it has other information. And it will default to the smaller of two possible indexes if it sees no alternative. While the cost-based model for an optimizer can make a lot of good decisions, you can smack into cases where you will not get an optimal query plan.
|
||||
|
||||
### A query plan?
|
||||
|
||||
A query plan is what the optimizer will generate for the server to execute from the query. The way to see the query plan is to prepend the word `EXPLAIN` to your query. For example, the following query asks for the name of a city from the city table and the name of the corresponding country table, and the two tables are linked by the country's unique code. This case is interested only in the top five cities alphabetically from the United Kingdom:
|
||||
|
||||
|
||||
```
|
||||
SELECT city.name AS 'City',
|
||||
country.name AS 'Country'
|
||||
FROM city
|
||||
JOIN country ON (city.countrycode = country.code)
|
||||
WHERE country.code = 'GBR'
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
Prepending `EXPLAIN` in front of this query will give the query plan generated by the optimizer. Skipping over all but the end of the output, it is easy to see the optimized query:
|
||||
|
||||
|
||||
```
|
||||
SELECT `world`.`city`.`Name` AS `City`,
|
||||
'United Kingdom' AS `Country`
|
||||
FROM `world`.`city`
|
||||
JOIN `world`.`country`
|
||||
WHERE (`world`.`city`.`CountryCode` = 'GBR')
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
The big changes are that `country.name as 'Country'` was changed to `'United Kingdom' AS 'Country'` and the `WHERE` clause went from looking in the country table to the city table. The optimizer determined that these two changes will provide a faster result than the original query.
|
||||
|
||||
### Indexes
|
||||
|
||||
You will hear indexes and keys used interchangeably in the MySQL-verse. However, indexes are made up of keys, and keys are a way to identify a record, hopefully uniquely. If a column is designed as a key, the optimizer can search a list of those keys to find the desired record without having to read the entire table. Without an index, the server has to start at the first row of the first column and read through every row of data. If the column was created as a unique index, then the server can go to that one row of data and ignore the rest. The more unique the value of the index (also known as its cardinality), the better. Remember, we are looking for faster ways of getting to the data.
|
||||
|
||||
The MySQL default InnoDB storage engine wants your table to have a primary key and will store your data in a B+ tree by that key. A recently added MySQL feature is invisible columns—columns that do not return data unless the column is explicitly named in the query. For example, `SELECT * FROM foo;` doesn't provide any columns that are designated as hidden. This feature provides a way to add a primary key to older tables without recoding all the queries to include that new column.
|
||||
|
||||
To make this even more complicated, there are many types of indexes, such as functional, spatial, and composite. There are even cases where you can create an index that will provide all the requested information for a query so that there is no need to access the data table.
|
||||
|
||||
Describing the various indexes is beyond the scope of this article, so just think of an index as a shortcut to the record or records you desire. You can create an index on one or more columns or part of those columns. My physician's system can look up my records by the first three letters of my last name and birthdate. Using multiple columns requires using the most unique field first, then the second most unique, and so forth. An index on year-month-day works for year-month-day, year-month, and year searches, but it doesn't work for day, month-day, or year-day searches. It helps to design your indexes around how you want to use your data.
|
||||
|
||||
### Histograms
|
||||
|
||||
A histogram is a distribution of your data. If you were alphabetizing people by their last name, you could use a "logical bucket" for the folks with last names starting with the letters A to F, then another for G to J, and so forth. The optimizer assumes that the data is evenly distributed within the column, but this is rarely the case in practical use.
|
||||
|
||||
MySQL provides two types of histograms: equal height, where all the data is divided equally among the buckets, and singleton, where a single value is in a bucket. You can have up to 1,024 buckets. The amount of buckets to choose for your data column depends on many factors, including how many distinct values you have, how skewed your data is, and how high your accuracy really needs to be. After a certain amount of buckets, there are diminishing returns.
|
||||
|
||||
This command will create a histogram of 10 buckets on column c1 of table t:
|
||||
|
||||
|
||||
```
|
||||
`ANALYZE TABLE t UPDATE HISTOGRAM ON c1 WITH 10 BUCKETS;`
|
||||
```
|
||||
|
||||
Imagine you sell small, medium, and large socks, and each size has its own bin for storage. To find the size you need, you go to the bin for that size. MySQL has had histograms since MySQL 8.0 was released three years ago, yet they are not as well-known as indexes. Unlike indexes, there is no overhead for inserting, updating, or deleting a record. To update an index, an `ANALYZE TABLE` command must be updated. This is a good approach when the data does not churn very much and frequent changes to the data will reduce the efficiency.
|
||||
|
||||
### Indexes or histograms?
|
||||
|
||||
Use indexes for unique items where you need to access the data directly. There is overhead for updates, deletes, and inserts, but you get speedy access if your data is properly architected. Use histograms for data that does not get updated frequently, such as quarterly results for the last dozen years.
|
||||
|
||||
### Parting thoughts
|
||||
|
||||
This article grew out of a recent presentation at the [Open Source 101 conference][3]. And that presentation grew out of a workshop at a [PHP UK Conference][4]. Query tuning is a complex subject, and each time I present on indexes and histograms, I find ways to refine my presentation. But each presentation also shows that many folks in the software world are not well-versed on indexes and tend to use them incorrectly. Histograms have not been around long enough (I hope) to have been misused similarly.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/5/mysql-query-tuning
|
||||
|
||||
作者:[Dave Stokes][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/davidmstokes
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-window-focus.png?itok=g0xPm2kD (young woman working on a laptop)
|
||||
[2]: https://www.mysql.com/
|
||||
[3]: https://opensource101.com/
|
||||
[4]: https://www.phpconference.co.uk/
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: (https://opensource.com/article/21/6/freedos-gw-basic)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chai-yuan)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
[#]: subject: ()
|
||||
[#]: via: (https://www.2daygeek.com/save-command-output-to-a-file-linux/)
|
||||
[#]: author: ( )
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
|
||||
======
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/save-command-output-to-a-file-linux/
|
||||
|
||||
作者:[][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
@@ -1,25 +0,0 @@
|
||||
[#]: subject: ()
|
||||
[#]: via: (https://www.2daygeek.com/recover-restore-deleted-logical-volume-linux/)
|
||||
[#]: author: ( )
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
|
||||
======
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/recover-restore-deleted-logical-volume-linux/
|
||||
|
||||
作者:[][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
@@ -1,249 +0,0 @@
|
||||
[#]: subject: (Use OpenCV on Fedora Linux ‒ part 1)
|
||||
[#]: via: (https://fedoramagazine.org/use-opencv-on-fedora-linux-part-1/)
|
||||
[#]: author: (Onuralp SEZER https://fedoramagazine.org/author/thunderbirdtr/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Use OpenCV on Fedora Linux ‒ part 1
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Cover image excerpted from Starry Night by [Vincent van Gogh][2], Public domain, via Wikimedia Commons
|
||||
|
||||
The technology world changes daily and the demands for computer vision, artificial intelligence, and machine learning are increasing. The technology that allows computers and mobile phones to see their surroundings is called [computer vision][3]. Work on re-creating a human eye started in the 50s. Since then, computer vision technology has come a long way. Computer vision has already made its way to our mobile phones via different applications. This article will introduce [OpenCV][4] on Fedora Linux.
|
||||
|
||||
### **What is OpenCV?**
|
||||
|
||||
> OpenCV (Open Source Computer Vision Library) is an open-source computer vision and machine learning software library. OpenCV was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in the commercial products. It has more than 2500 optimized algorithms, which includes a comprehensive set of both classic and state-of-the-art computer vision and machine learning algorithms. These algorithms can be used to detect and recognize faces, identify objects, classify human actions in videos and establish markers to overlay it with augmented reality and much more.
|
||||
>
|
||||
> [opencv.org – about][5]
|
||||
|
||||
### Install OpenCV on Fedora Linux
|
||||
|
||||
To get started with OpenCV, install it from the Fedora Linux repositories.
|
||||
|
||||
```
|
||||
$ sudo dnf install opencv opencv-contrib opencv-doc python3-opencv python3-matplotlib python3-numpy
|
||||
```
|
||||
|
||||
**Note:** On Fedora Silverblue or CoreOs, Python 3.9 is part of the core commit. Layer OpenCV and required tools with: _rpm-ostree install opencv opencv-doc python3-opencv python3-matplotlib python3-numpy_.
|
||||
|
||||
Next, enter the following commands in a terminal to verify that OpenCV is installed (user input shown in bold).
|
||||
|
||||
```
|
||||
$ python
|
||||
Python 3.9.6 (default, Jul 16 2021, 00:00:00)
|
||||
[GCC 11.1.1 20210531 (Red Hat 11.1.1-3)] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> import cv2 as cv
|
||||
>>> print( cv.__version__ )
|
||||
4.5.2
|
||||
>>> exit()
|
||||
```
|
||||
|
||||
The current OpenCV version should be displayed when you enter the _print_ command as shown above. This indicates that OpenCV and the Python-OpenCV libraries have been installed successfully.
|
||||
|
||||
Additionally, if you want to take notes and write code with Jupyter Notebook and learn more about data science tools, check out the earlier Fedora Magazine article: [_Jupyter and Data Science in Fedora_][6].
|
||||
|
||||
### Get started with OpenCV
|
||||
|
||||
After installation is complete, load a sample image using Python and the OpenCV libraries (press the **S** key to save a copy of the image in _png_ format and finish the program):
|
||||
|
||||
```
|
||||
$ cp /usr/share/opencv4/samples/data/starry_night.jpg .
|
||||
$ python starry_night.py
|
||||
```
|
||||
|
||||
Contents of _starry_night.py_:
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import sys
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
|
||||
if img is None:
|
||||
sys.exit("Could not read the image.")
|
||||
cv.imshow("Display window", img)
|
||||
k = cv.waitKey(0)
|
||||
if k == ord("s"):
|
||||
cv.imwrite("starry_night.png", img)
|
||||
```
|
||||
|
||||
![][7]
|
||||
|
||||
Gray-scale the image by adding the parameter **0** to the _cv.imread_ function as shown below.
|
||||
|
||||
```
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),0)
|
||||
```
|
||||
|
||||
![][8]
|
||||
|
||||
These are some alternative values that can be used for the second parameter of the _cv.imread_ function.
|
||||
|
||||
* **cv2.IMREAD_GRAYSCALE** or **0:** Load the image in grayscale mode.
|
||||
* **cv2.IMREAD_COLOR** or **1:** Load the image in color mode. Any transparency in the image will be removed. This is the default.
|
||||
* **cv2.IMREAD_UNCHANGED** or **-1:** Load the image unaltered; including alpha channel.
|
||||
|
||||
|
||||
|
||||
#### Display image attributes using OpenCV
|
||||
|
||||
Image attributes include the number of rows, columns, and channels; the type of image data; the number of pixels; etc. Suppose you wanted to access the image’s shape and its datatype. This is how you would do it:
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
|
||||
print("Image size is", img.shape)
|
||||
print("Data type of image is", img.dtype)
|
||||
|
||||
Image size is (600, 752, 3)
|
||||
Data type of image is uint8
|
||||
|
||||
print(f"Image 2D numpy array \n {img}")
|
||||
|
||||
Image 2D numpy array
|
||||
[[[0 0 0]
|
||||
[0 0 0]
|
||||
[0 0 0]
|
||||
...
|
||||
[0 0 0]
|
||||
[0 0 0]
|
||||
[0 0 0]]
|
||||
|
||||
[[0 0 0]
|
||||
[0 0 0]
|
||||
[0 0 0]
|
||||
...
|
||||
```
|
||||
|
||||
* **img.shape:** return a tuple of the number of rows, columns, and channels (if it is a color image)
|
||||
* **img.dtype:** return the datatype of the image
|
||||
|
||||
|
||||
|
||||
Next display image with Matplotlib:
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),0)
|
||||
plt.imshow(img)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][9]
|
||||
|
||||
#### What happened?
|
||||
|
||||
The image was read in as a gray-scale image, however it won’t necessarily display in gray-scale when using Matplotlib’s _imshow_ fucntion. This is because the _imshow_ function uses a different color map by default. To specify that a gray-scale color map should be used, set the second parameter of the _imshow_ function to _cmap=’gray’_ as shown below.
|
||||
|
||||
```
|
||||
plt.imshow(img,cmap='gray')
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
This problem is also going to happen when opening a picture in color mode because Matplotlib expects the image in RGB (red, green, blue) format whereas OpenCV stores images in BGR (blue, green, red) format. For correct display, you need to reverse the channels of the BGR image.
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
|
||||
fig, (ax1, ax2) = plt.subplots(1,2)
|
||||
ax1.imshow(img)
|
||||
ax1.set_title('BGR Colormap')
|
||||
ax2.imshow(img[:,:,::-1])
|
||||
ax2.set_title('Reversed BGR Colormap(RGB)')
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][11]
|
||||
|
||||
#### Splitting and merging color channels
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
|
||||
b,g,r = cv.split(img)
|
||||
|
||||
fig,ax = plt.subplots(2,2)
|
||||
|
||||
ax[0,0].imshow(r,cmap='gray')
|
||||
ax[0,0].set_title("Red Channel");
|
||||
ax[0,1].imshow(g,cmap='gray')
|
||||
ax[0,1].set_title("Green Channel");
|
||||
ax[1,0].imshow(b,cmap='gray')
|
||||
ax[1,0].set_title("Blue Channel");
|
||||
|
||||
# Merge the individual channels into a BGR image
|
||||
imgMerged = cv.merge((b,g,r))
|
||||
# Show the merged output
|
||||
ax[1,1].imshow(imgMerged[:,:,::-1])
|
||||
ax[1,1].set_title("Merged Output");
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][12]
|
||||
|
||||
* **cv2.split:** Divide a multi-channel array into several single-channel arrays.
|
||||
* **cv2.merge:** Merge several arrays to make a single multi-channel array. All the input matrices must have the same size.
|
||||
|
||||
|
||||
|
||||
**Note:** Images with more white have a higher density of color. Contrarily, images with more black have a lower density of color. In the above example the red color has the lowest density.
|
||||
|
||||
#### Converting to different color spaces
|
||||
|
||||
The _cv2.cvtColor_ function converts an input image from one color space to another. When transforming between the RGB and BGR color spaces, the order of the channels should be specified explicitly (_RGB2BGR_ or _BGR2RGB_). **Note that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the bytes are reversed).** So the first byte in a standard (24-bit) color image will be an 8-bit blue component, the second byte will be green, and the third byte will be red. The fourth, fifth, and sixth bytes would then be the second pixel (blue, then green, then red), and so on.
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
|
||||
img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
|
||||
plt.imshow(img_rgb)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][13]
|
||||
|
||||
### Further information
|
||||
|
||||
More details on OpenCV are available in the [online documentation][14].
|
||||
|
||||
Thank you.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/use-opencv-on-fedora-linux-part-1/
|
||||
|
||||
作者:[Onuralp SEZER][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/thunderbirdtr/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2021/08/starry-night-1-816x345.jpg
|
||||
[2]: https://commons.wikimedia.org/wiki/File:Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg
|
||||
[3]: https://en.wikipedia.org/wiki/Computer_vision
|
||||
[4]: https://en.wikipedia.org/wiki/OpenCV
|
||||
[5]: https://opencv.org/about/
|
||||
[6]: https://fedoramagazine.org/jupyter-and-data-science-in-fedora/
|
||||
[7]: https://fedoramagazine.org/wp-content/uploads/2021/06/image.png
|
||||
[8]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-1.png
|
||||
[9]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-2.png
|
||||
[10]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-3.png
|
||||
[11]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-4.png
|
||||
[12]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-5.png
|
||||
[13]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-7.png
|
||||
[14]: https://docs.opencv.org/4.5.2/index.html
|
||||
@@ -1,137 +0,0 @@
|
||||
[#]: subject: (Set up a VPN server on your Linux PC)
|
||||
[#]: via: (https://opensource.com/article/21/8/openvpn-server-linux)
|
||||
[#]: author: (D. Greg Scott https://opensource.com/users/greg-scott)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (perfiffer)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Set up a VPN server on your Linux PC
|
||||
======
|
||||
The first step in building a VPN is setting up a VPN server.
|
||||
![Person drinking a hot drink at the computer][1]
|
||||
|
||||
Have you been connected to an untrusted network such as a hotel or café WiFi and need to securely browse the internet from your smartphone or laptop? By using a virtual private network (VPN), you can access that untrusted network anonymously and as safely as if you were on a private network.
|
||||
|
||||
VPN is an amazing tool for safeguarding private data. By using a VPN, you can connect to a private network on the internet while maintaining anonymity.
|
||||
|
||||
There are many VPN services available, and many people have found that the preferred option for securing private data when using untrusted networks is [OpenVPN][2].
|
||||
|
||||
OpenVPN creates an encrypted tunnel between two points, preventing a third party from accessing your network traffic data. By setting up your VPN server, you become your own VPN provider. Many popular VPN services use OpenVPN, so why tie your connection to a specific provider when you can have complete control yourself?
|
||||
|
||||
### Set up a Linux server
|
||||
|
||||
First, install a copy of Linux onto a spare PC. These examples use Fedora, but the steps are mostly the same no matter what Linux distribution you use.
|
||||
|
||||
Download a copy of the most recent Fedora ISO from the [Fedora project][3] website. Make a bootable USB drive, plug it into and boot your PC, and install the operating system. If you've never made a bootable USB drive, read about [Fedora Media Writer][4]. If you've never installed Linux, read about [installing Linux in three steps][5].
|
||||
|
||||
### Set up networking
|
||||
|
||||
After installing the Fedora operating system, log into the console or SSH session.
|
||||
|
||||
Apply the latest updates and reboot:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo dnf update -y && reboot`
|
||||
```
|
||||
|
||||
Log in again and disable the firewall rules:
|
||||
|
||||
|
||||
```
|
||||
systemctl disable firewalld.service
|
||||
systemctl stop firewalld.service
|
||||
```
|
||||
|
||||
You may want to add appropriate firewall rules on this system for your internal network. If so, finish setting up and debugging OpenVPN with all firewall rules turned off, and then add your local firewall rules. For more information, read about [setting up firewalls on Linux][6].
|
||||
|
||||
### Set up IP addresses
|
||||
|
||||
You need a static IP address inside your local network. The commands below assume a Network Manager connection named `ens3` on a device named `ens3`. Your device and connection names might be different, so find them by opening an SSH session or the console and entering:
|
||||
|
||||
|
||||
```
|
||||
$ sudo nmcli connection show
|
||||
NAME UUID TYPE DEVICE
|
||||
ens3 39ad55bd-adde-384a-bb09-7f8e83380875 ethernet ens3
|
||||
```
|
||||
|
||||
You need to ensure that your remote people can find your VPN server. There are two ways to do this. You can set its IP address manually, or you can let your router do most of the work.
|
||||
|
||||
#### Configure an IP address manually
|
||||
|
||||
Set your static IP address, prefix, gateway, and DNS resolver with the following command but substituting your own IP addresses:
|
||||
|
||||
|
||||
```
|
||||
$ sudo nmcli connection modify ens3 ipv4.addresses 10.10.10.97/24
|
||||
$ sudo nmcli connection modify ens3 ipv4.gateway 10.10.10.1
|
||||
$ sudo nmcli connection modify ens3 ipv4.dns 10.10.10.10
|
||||
$ sudo nmcli connection modify ens3 ipv4.method manual
|
||||
$ sudo nmcli connection modify ens3 connection.autoconnect yes
|
||||
```
|
||||
|
||||
Set a hostname:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo hostnamectl set-hostname OVPNserver2020`
|
||||
```
|
||||
|
||||
If you run a local DNS server, you will want to set up a DNS entry with the hostname pointing to the VPN server IP Address.
|
||||
|
||||
Reboot and make sure the system has the correct networking information.
|
||||
|
||||
#### Configure an IP address in your router
|
||||
|
||||
You probably have a router on your network. You may have purchased it, or you may have gotten one from your internet service provider (ISP). Either way, your router probably has a built-in DHCP server that assigns an IP address to each device on your network. Your new server counts as a device on your network, so you may have noticed an IP address is assigned to it automatically.
|
||||
|
||||
The potential problem here is that your router doesn't guarantee that any device will ever get the same IP address after reconnecting. It does _try_ to keep the IP addresses consistent, but they can change depending on how many devices are connected at the time.
|
||||
|
||||
However, almost all routers have an interface allowing you to intercede and reserve IP addresses for specific devices.
|
||||
|
||||
![Router IP address settings][7]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][8])
|
||||
|
||||
There isn't a universal interface for routers, so search the interface of the router you own for **DHCP** or **Static IP address** options. Assign your server its own reserved IP address so that its network location remains the same no matter what.
|
||||
|
||||
### Access your server
|
||||
|
||||
By default, your router probably has a firewall built into it. This is normally good because you don't want someone outside your network to be able to brute force their way into any of your computers. However, you must allow traffic destined for your VPN server through your firewall, or else your VPN will be unreachable and, therefore, no use to you.
|
||||
|
||||
You will need at least one public static IP Address from your internet service provider. Set up the public side of your router with its static IP Address, and then put your OpenVPN server on the private side, with its own private static IP Address inside your network. OpenVPN uses UDP port 1194 by default. Configure your router to [port-forward][9] traffic for your public VPN IP Address on UDP port 1194 to UDP port 1194 on your OpenVPN server. If you decide to use a different UDP port, adjust the port number accordingly.
|
||||
|
||||
### Get ready for the next step
|
||||
|
||||
In this article, you installed and configured an operating system on your server, which is approximately half the battle. In the next article, you'll tackle installing and configuring OpenVPN itself. In the meantime, get familiar with your router and make sure you can reach your server from the outside world. But be sure to close the port forwarding after testing until your VPN is up and running.
|
||||
|
||||
* * *
|
||||
|
||||
_Parts of this article were adapted from D. Greg Scott's [blog][10] and have been republished with permission._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/openvpn-server-linux
|
||||
|
||||
作者:[D. Greg Scott][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/greg-scott
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: https://openvpn.net/
|
||||
[3]: http://getfedora.org
|
||||
[4]: https://opensource.com/article/20/10/fedora-media-writer
|
||||
[5]: https://opensource.com/article/21/2/linux-installation
|
||||
[6]: https://www.redhat.com/sysadmin/secure-linux-network-firewall-cmd
|
||||
[7]: https://opensource.com/sites/default/files/uploads/reserved-ip.jpg (Router IP address settings)
|
||||
[8]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[9]: https://opensource.com/article/20/9/firewall
|
||||
[10]: https://www.dgregscott.com/how-to-build-a-vpn-in-four-easy-steps-without-spending-one-penny/
|
||||
@@ -2,7 +2,7 @@
|
||||
[#]: via: "https://opensource.com/article/21/7/openvpn-router"
|
||||
[#]: author: "D. Greg Scott https://opensource.com/users/greg-scott"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: translator: "perfiffer"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
[#]: subject: "Configure your OpenVPN server on Linux"
|
||||
[#]: via: "https://opensource.com/article/21/7/openvpn-firewall"
|
||||
[#]: author: "D. Greg Scott https://opensource.com/users/greg-scott"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Configure your OpenVPN server on Linux
|
||||
======
|
||||
After you install OpenVPN, it's time to configure it.
|
||||
![Lock][1]
|
||||
|
||||
OpenVPN creates an encrypted tunnel between two points, preventing a third party from accessing your network traffic. By setting up your virtual private network (VPN) server, you become your own VPN provider. Many popular VPN services already use [OpenVPN][2], so why tie your connection to a specific provider when you can have complete control?
|
||||
|
||||
The [first article][3] in this series set up a server for your VPN, and the [second article][4] demonstrated how to install and configure the OpenVPN server software. This third article shows how to start OpenVPN with authentication in place.
|
||||
|
||||
To set up an OpenVPN server, you must:
|
||||
|
||||
* Create a configuration file.
|
||||
* Set the `sysctl` value `net.ipv4.ip_forward = 1` to enable routing.
|
||||
* Set up appropriate ownership for all configuration and authentication files to run the OpenVPN server daemon under a non-root account.
|
||||
* Set OpenVPN to start with the appropriate configuration file.
|
||||
* Configure your firewall.
|
||||
|
||||
|
||||
|
||||
### Configuration file
|
||||
|
||||
You must create a server config file in `/etc/openvpn/server/`. You can start from scratch if you want, and OpenVPN includes several sample configuration files to use as a starting point. Have a look in `/usr/share/doc/openvpn/sample/sample-config-files/` to see them all.
|
||||
|
||||
If you want to build a config file by hand, start with either `server.conf` or `roadwarrior-server.conf` (as appropriate), and place your config file in `/etc/openvpn/server`. Both files are extensively commented, so read the comments and decide which makes the most sense for your situation.
|
||||
|
||||
You can save time and aggravation by using my prebuilt server and client configuration file templates and `sysctl` file to turn on network routing. This configuration also includes customization to log connects and disconnects. It keeps logs on the OpenVPN server in `/etc/openvpn/server/logs`.
|
||||
|
||||
If you use my templates, you'll need to edit them to use your IP addresses and hostnames.
|
||||
|
||||
To use my prebuilt config templates, scripts, and `sysctl` to turn on IP forwarding, download my script:
|
||||
|
||||
|
||||
```
|
||||
$ curl \
|
||||
<https://www.dgregscott.com/ovpn/OVPNdownloads.sh> > \
|
||||
OVPNdownloads.sh
|
||||
```
|
||||
|
||||
Read the script to get an idea of what it does. Here's a quick overview of its actions:
|
||||
|
||||
* Creates the appropriate directories on your OpenVPN server
|
||||
* Downloads server and client config file templates from my website
|
||||
* Downloads my custom scripts and places them into the correct directory with correct permissions
|
||||
* Downloads `99-ipforward.conf` and places it into `/etc/sysctl.d` to turn on IP forwarding at the next boot
|
||||
* Sets up ownership for everything in `/etc/openvpn`
|
||||
|
||||
|
||||
|
||||
Once you're satisfied that you understand what the script does, make it executable and run it:
|
||||
|
||||
|
||||
```
|
||||
$ chmod +x OVPNdownloads.sh
|
||||
$ sudo ./OVPNdownloads.sh
|
||||
```
|
||||
|
||||
Here are the files it copies (notice the file ownership):
|
||||
|
||||
|
||||
```
|
||||
$ ls -al -R /etc/openvpn
|
||||
/etc/openvpn:
|
||||
total 12
|
||||
drwxr-xr-x. 4 openvpn openvpn 34 Apr 6 20:35 .
|
||||
drwxr-xr-x. 139 root root 8192 Apr 6 20:35 ..
|
||||
drwxr-xr-x. 2 openvpn openvpn 33 Apr 6 20:35 client
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 server
|
||||
|
||||
/etc/openvpn/client:
|
||||
total 4
|
||||
drwxr-xr-x. 2 openvpn openvpn 33 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 34 Apr 6 20:35 ..
|
||||
-rw-r--r--. 1 openvpn openvpn 1764 Apr 6 20:35 OVPNclient2020.ovpn
|
||||
|
||||
/etc/openvpn/server:
|
||||
total 4
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 34 Apr 6 20:35 ..
|
||||
drwxr-xr-x. 2 openvpn openvpn 59 Apr 6 20:35 ccd
|
||||
drwxr-xr-x. 2 openvpn openvpn 6 Apr 6 20:35 logs
|
||||
-rw-r--r--. 1 openvpn openvpn 2588 Apr 6 20:35 OVPNserver2020.conf
|
||||
|
||||
/etc/openvpn/server/ccd:
|
||||
total 8
|
||||
drwxr-xr-x. 2 openvpn openvpn 59 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 ..
|
||||
-rwxr-xr-x. 1 openvpn openvpn 917 Apr 6 20:35 client-connect.sh
|
||||
-rwxr-xr-x. 1 openvpn openvpn 990 Apr 6 20:35 client-disconnect.sh
|
||||
|
||||
/etc/openvpn/server/logs:
|
||||
total 0
|
||||
drwxr-xr-x. 2 openvpn openvpn 6 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 ..
|
||||
```
|
||||
|
||||
Here's the `99-ipforward.conf` file:
|
||||
|
||||
|
||||
```
|
||||
# Turn on IP forwarding. OpenVPN servers need to do routing
|
||||
net.ipv4.ip_forward = 1
|
||||
```
|
||||
|
||||
Edit `OVPNserver2020.conf` and `OVPNclient2020.ovpn` to include your IP addresses. Also, edit `OVPNserver2020.conf` to include your server certificate names from earlier. Later, you will rename and edit a copy of `OVPNclient2020.ovpn` for use with your client computers. The blocks that start with `***?` show you where to edit.
|
||||
|
||||
### File ownership
|
||||
|
||||
If you used the automated script from my website, file ownership is already in place. If not, you must ensure that your system has a user called `openvpn` that is a member of a group named `openvpn`. You must set the ownership of everything in `/etc/openvpn` to that user and group. It's safe to do this if you're unsure whether the user and group already exist because `useradd` will refuse to create a user with the same name as one that already exists:
|
||||
|
||||
|
||||
```
|
||||
$ sudo useradd openvpn
|
||||
$ sudo chown -R openvpn.openvpn /etc/openvpn
|
||||
```
|
||||
|
||||
### Firewall
|
||||
|
||||
If you decided not to disable the firewalld service in step 1, then your server's firewall service might not allow VPN traffic by default. Using the [`firewall-cmd` command][5], you can enable the OpenVPN service, which opens the necessary ports and routes traffic as necessary:
|
||||
|
||||
|
||||
```
|
||||
$ sudo firewall-cmd --add-service openvpn --permanent
|
||||
$ sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
No need to get lost in a maze of iptables!
|
||||
|
||||
### Start your server
|
||||
|
||||
You can now start your OpenVPN server. So that it starts automatically after a reboot, use the `enable` subcommand of `systemctl`:
|
||||
|
||||
|
||||
```
|
||||
`systemctl enable --now openvpn-server@OVPNserver2020.service`
|
||||
```
|
||||
|
||||
### Final steps
|
||||
|
||||
The fourth and final article in this article will demonstrate how to set up clients to connect to your OpenVPN from afar.
|
||||
|
||||
* * *
|
||||
|
||||
_This article is based on D. Greg Scott's [blog][6] and is reused with permission._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/7/openvpn-firewall
|
||||
|
||||
作者:[D. Greg Scott][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/greg-scott
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum (Lock)
|
||||
[2]: https://openvpn.net/
|
||||
[3]: https://opensource.com/article/21/7/vpn-openvpn-part-1
|
||||
[4]: https://opensource.com/article/21/7/vpn-openvpn-part-2
|
||||
[5]: https://www.redhat.com/sysadmin/secure-linux-network-firewall-cmd
|
||||
[6]: https://www.dgregscott.com/how-to-build-a-vpn-in-four-easy-steps-without-spending-one-penny/
|
||||
@@ -1,146 +0,0 @@
|
||||
[#]: subject: "Change your Linux Desktop Wallpaper Every Hour [Here’s How]"
|
||||
[#]: via: "https://www.debugpoint.com/2021/08/change-wallpaper-every-hour/"
|
||||
[#]: author: "Arindam https://www.debugpoint.com/author/admin1/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Change your Linux Desktop Wallpaper Every Hour [Here’s How]
|
||||
======
|
||||
This shell script styli.sh helps to change your Linux desktop wallpaper
|
||||
in every hour automatically and with several options.GNOMEXfceKDE
|
||||
PlasmaSway
|
||||
A nice wallpaper to start your day with, your desktop is refreshing. But it is very cumbersome to find wallpaper, then saving and eventually set as wallpaper. All these steps can be done by this script called [styli.sh][1].
|
||||
|
||||
### styli.sh – Change your Linux Desktop Wallpaper Every Hour
|
||||
|
||||
This is a shell script which you can download from GitHub. When runs, it fetches the wallpapers from popular Subreddits from Reddit and set it as your wallpaper.
|
||||
|
||||
This script works with all popular desktop environments such as GNOME, KDE Plasma, Xfce and Sway window manager.
|
||||
|
||||
It is loaded with features, and you can run the script with via crontab in every and get a fresh wallpaper in a specific interval.
|
||||
|
||||
### Download and Install, Run
|
||||
|
||||
Open a terminal and clone the GitHub repo. You need to install [feh][2] and git if not installed.
|
||||
|
||||
```
|
||||
git clone https://github.com/thevinter/styli.sh
|
||||
cd styli.sh
|
||||
```
|
||||
|
||||
To set a random wallpaper, run below as per your desktop environment.
|
||||
|
||||
![Change your Linux Desktop Wallpaper Every Hour using styli.sh][3]
|
||||
|
||||
```
|
||||
./styli.sh -g
|
||||
```
|
||||
|
||||
```
|
||||
./styli.sh -x
|
||||
```
|
||||
|
||||
```
|
||||
./styli.sh -k
|
||||
```
|
||||
|
||||
```
|
||||
./styli.sh -y
|
||||
```
|
||||
|
||||
### Change every hour
|
||||
|
||||
To change background every hour, run the following command –
|
||||
|
||||
```
|
||||
crontab -e
|
||||
```
|
||||
|
||||
And add the following to the opened file. Don’t forget to change the script path.
|
||||
|
||||
```
|
||||
@hourly script/path/styli.sh
|
||||
```
|
||||
|
||||
### Change the subreddits
|
||||
|
||||
In the source directory, there is a file called subreddits. It is filled up with some standard subreddits. If you want some more, just add the Subreddit names at the end of the file.
|
||||
|
||||
### More Config options
|
||||
|
||||
The types of wallpapers, size, can also be set. These are some unique configuration option of this script.
|
||||
|
||||
> To set a random 1920×1080 background
|
||||
> ./styli.sh
|
||||
>
|
||||
> To specify a desired width or height
|
||||
> ./styli.sh -w 1080 -h 720
|
||||
> ./styli.sh -w 2560
|
||||
> ./styli.sh -h 1440
|
||||
>
|
||||
> To set a wallpaper based on a search term
|
||||
> ./styli.sh -s island
|
||||
> ./styli.sh -s “sea sunset”
|
||||
> ./styli.sh -s sea -w 1080
|
||||
>
|
||||
> To get a random wallpaper from one of the set subreddits
|
||||
> NOTE: The width/height/search parameters DON’T work with reddit
|
||||
> ./styli.sh -l reddit
|
||||
>
|
||||
> To get a random wallpaper from a custom subreddit
|
||||
> ./styli.sh -r
|
||||
> ./styli.sh -r wallpaperdump
|
||||
>
|
||||
> To use the builtin feh –bg options
|
||||
> ./styli.sh -b
|
||||
> ./styli.sh -b bg-scale -r widescreen-wallpaper
|
||||
>
|
||||
> To add custom feh flags
|
||||
> ./styli.sh -c
|
||||
> ./styli.sh -c –no-xinerama -r widescreen-wallpaper
|
||||
>
|
||||
> To automatically set the terminal colors
|
||||
> ./styli.sh -p
|
||||
>
|
||||
> To use nitrogen instead of feh
|
||||
> ./styli.sh -n
|
||||
>
|
||||
> To update > 1 screens using nitrogen
|
||||
> ./styli.sh -n -m
|
||||
>
|
||||
> Choose a random background from a directory
|
||||
> ./styli.sh -d /path/to/dir
|
||||
|
||||
### Closing Notes
|
||||
|
||||
A unique and handy script, low on memory and can directly fetch images in an interval – like an hour. And make your desktop look [fresh and productive][4] all the time. If you do not like the wallpaper, you can simply run the script from the terminal again to cycle through.
|
||||
|
||||
[][5]
|
||||
|
||||
SEE ALSO: List of All Default Ubuntu Official Wallpapers [Gallery]
|
||||
|
||||
Do you like this script? Or do you know anything like this for wallpaper switcher? Let me know in the comment box below.
|
||||
|
||||
* * *
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.debugpoint.com/2021/08/change-wallpaper-every-hour/
|
||||
|
||||
作者:[Arindam][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.debugpoint.com/author/admin1/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/thevinter/styli.sh
|
||||
[2]: https://feh.finalrewind.org/
|
||||
[3]: https://www.debugpoint.com/blog/wp-content/uploads/2021/08/Change-your-Linux-Desktop-Wallpaper-Every-Hour-using-styli.sh_.jpg
|
||||
[4]: https://www.debugpoint.com/category/themes
|
||||
[5]: https://www.debugpoint.com/2019/09/a-list-of-all-default-ubuntu-official-wallpapers-gallery/
|
||||
@@ -1,102 +0,0 @@
|
||||
[#]: subject: "How to Install Java on Fedora Linux"
|
||||
[#]: via: "https://itsfoss.com/install-java-fedora/"
|
||||
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
How to Install Java on Fedora Linux
|
||||
======
|
||||
|
||||
Love it or hate it, it is difficult to avoid Java.
|
||||
|
||||
Java is still a very popular programming language taught in the schools and used in the enterprises.
|
||||
|
||||
If you want to use a Java-based tool or program in Java, you’ll need to have Java on your system.
|
||||
|
||||
This becomes confusing because there are so many technical terms around java.
|
||||
|
||||
* Java Development Kit (JDK) for creating Java programs
|
||||
* Java Runtime Environment (JRE) or Java Virtual Machine (JVM) for running Java programs
|
||||
|
||||
|
||||
|
||||
On top of that, you’ll come across [OpenJDK][1] and [Oracle Java SE][2]. OpenJDK is what is recommended because it is open source. If you have exclusive need then only you should go for Oracle Java SE.
|
||||
|
||||
There is one more thing here. Even OpenJDK has several versions available. At the time of writing this article, Fedora 34 has OpenJDK 1.8, OpenJDK 11 and OpenJDK 16 available.
|
||||
|
||||
It is up to you to decide which Java version you want.
|
||||
|
||||
### Installing Java on Fedora Linux
|
||||
|
||||
First thing first, check if Java is already installed and which version it is. I am not kidding. Fedora usually comes with Java preinstalled.
|
||||
|
||||
To check, use the following command:
|
||||
|
||||
```
|
||||
java -version
|
||||
```
|
||||
|
||||
As you can see in the screenshot below, I have Java 11 (OpenJDK 11) installed on my Fedora system.
|
||||
|
||||
![Check Java version][3]
|
||||
|
||||
Let’s say you want to install another version of Java. You may check the available options with the following command:
|
||||
|
||||
```
|
||||
sudo dnf search openjdk
|
||||
```
|
||||
|
||||
The sudo here is not required but it will refresh the metadata for sudo user which will eventually help when you install another version of Java.
|
||||
|
||||
The above command will show a huge output with plenty of similar looking packages. You have to focus on the initial few words to understand the different versions available.
|
||||
|
||||
![Available Java versions in Fedora][4]
|
||||
|
||||
For example, to install Java 8 (OpenJDK 1.8), the package name should be java-1.8.0-openjdk.x86_64 or java-1.8.0-openjdk. Use it to install it:
|
||||
|
||||
```
|
||||
sudo dnf install java-1.8.0-openjdk.x86_64
|
||||
```
|
||||
|
||||
![Install Java Fedora][5]
|
||||
|
||||
That’s good. Now you have both Java 11 and Java 8 installed on your system. But how will you use one of them?
|
||||
|
||||
#### Switch Java version on Fedora
|
||||
|
||||
Your Java version in use remains the same unless you explicitly change it. Use this command to list the installed Java versions on your system:
|
||||
|
||||
```
|
||||
sudo alternatives --config java
|
||||
```
|
||||
|
||||
You’ll notice a number before the Java versions. The + sign before the Java versions indicate the current Java version in use.
|
||||
|
||||
You can specify the number to switch the Java version. So, in the example below, if I enter 2, it will change the Java version on the system from Java 11 to Java 8.
|
||||
|
||||
![Switching between installed Java versions][6]
|
||||
|
||||
That’s all you need to do for installing Java on Fedora.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-java-fedora/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://openjdk.java.net/
|
||||
[2]: https://www.oracle.com/java/technologies/javase-downloads.html
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/check-java-version-fedora.png?resize=800%2C271&ssl=1
|
||||
[4]: https://itsfoss.com/wp-content/uploads/2021/08/available-java-versions-fedora-800x366.webp
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/install-java-fedora.png?resize=800%2C366&ssl=1
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/switch-java-versions-fedora.png?resize=800%2C513&ssl=1
|
||||
@@ -1,87 +0,0 @@
|
||||
[#]: subject: "Remove files and folders in the Linux terminal"
|
||||
[#]: via: "https://opensource.com/article/21/8/remove-files-linux-terminal"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Remove files and folders in the Linux terminal
|
||||
======
|
||||
Learn to safely remove files and folders in the Linux terminal.
|
||||
![Removing files][1]
|
||||
|
||||
To remove a file on a computer using a graphical interface, you usually drag a file or a folder to a "trash" or "recycle" bin. Alternately, you might be able to select the file or folder you want to remove, right-click, and select **Delete**.
|
||||
|
||||
When removing a file or folder in the terminal, there is no trash bin, at least by default. On a graphical desktop, the Trash is a protected directory so that users don't accidentally trash the Trash, or move it from its default location and lose track of it. The Trash is just a highly managed folder, so you can make your own Trash folder for use in your terminal.
|
||||
|
||||
### Setting up a trash bin for the terminal
|
||||
|
||||
Create a directory called **Trash** in your home directory:
|
||||
|
||||
|
||||
```
|
||||
`$ mkdir ~/Trash`
|
||||
```
|
||||
|
||||
### Removing a file
|
||||
|
||||
When you want to remove a file or folder, use the **mv** command to move a file or directory to your Trash:
|
||||
|
||||
|
||||
```
|
||||
`$ mv example.txt ~/Trash`
|
||||
```
|
||||
|
||||
### Deleting a file or folder permanently
|
||||
|
||||
When you're ready to remove a file or folder from your system permanently, you can use the **rm** command to erase all of the data in your Trash folder. By directing the **rm** command to an asterisk (`*`), you delete all files and folders inside the **Trash** folder without deleting the **Trash** folder itself. If you accidentally delete the **Trash** folder, however, you can just recreate it because directories are easy and free to create.
|
||||
|
||||
|
||||
```
|
||||
`$ rm --recursive ~/Trash/*`
|
||||
```
|
||||
|
||||
### Removing an empty directory
|
||||
|
||||
Deleting an empty directory has the special command **rmdir**, which only removes an empty directory, protecting you from recursive mistakes.
|
||||
|
||||
|
||||
```
|
||||
$ mkdir full
|
||||
$ touch full/file.txt
|
||||
$ rmdir full
|
||||
rmdir: failed to remove 'full/': Directory not empty
|
||||
|
||||
$ mkdir empty
|
||||
$ rmdir empty
|
||||
```
|
||||
|
||||
### Better trash
|
||||
|
||||
There are [commands for trashing files][2] that aren't included by default in your terminal, but that you can install from a software repository. They make it even easier to trash files, because they manage and use the very same Trash folder you use on your desktop.
|
||||
|
||||
|
||||
```
|
||||
$ trash ~/example.txt
|
||||
$ trash --list
|
||||
example.txt
|
||||
$ trash --empty
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/remove-files-linux-terminal
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/ch01s10.svg_.png?itok=p07au80e (Removing files)
|
||||
[2]: https://www.redhat.com/sysadmin/recover-file-deletion-linux
|
||||
@@ -0,0 +1,192 @@
|
||||
[#]: subject: "How I use Terraform and Helm to deploy the Kubernetes Dashboard"
|
||||
[#]: via: "https://opensource.com/article/21/8/terraform-deploy-helm"
|
||||
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
How I use Terraform and Helm to deploy the Kubernetes Dashboard
|
||||
======
|
||||
Terraform can deploy Helm Charts. Is it right for you?
|
||||
![Ship captain sailing the Kubernetes seas][1]
|
||||
|
||||
When I'm working on projects that require provisioning cloud infrastructure, my workflow has two disparate components: one is infrastructure orchestration, which includes Terraform to bring up the infrastructure (for instance, new EKS clusters), and the second is the provisioning component, which includes Ansible or Bash scripts to instantiate and initialize that infrastructure to accept new deployments (for instance, installing Cluster Autoscaler, kube-state-metrics, and so on.)
|
||||
|
||||
The reason for this is simple: very few tools can cross over and handle both the orchestration and the provisioning side. When I stumbled on the Helm provider for Terraform, I wanted to explore the possibility of using one tool to handle both sides: using Terraform to bring up a new EKS cluster and provision it with Prometheus, Loki, Grafana, Cluster Autoscaler, and others, all in one neat and clean deployment. But that's not happening until I figure out how to use this thing, so below is my experience using Terraform and Helm for something simple: deploying the Kubernetes Dashboard.
|
||||
|
||||
### The Helm provider
|
||||
|
||||
The Helm provider works like the other cloud providers. You can specify the path of the `KUBECONFIG` or other credentials, run `terraform init`, and the Helm provider gets initialized.
|
||||
|
||||
### Deploying the Kubernetes Dashboard
|
||||
|
||||
I'm going to use [Minikube for this test][2].
|
||||
|
||||
My `main.tf` file contains the following:
|
||||
|
||||
|
||||
```
|
||||
provider "helm" {
|
||||
kubernetes {
|
||||
config_path = "~/.kube/config"
|
||||
}
|
||||
}
|
||||
|
||||
resource "helm_release" "my-kubernetes-dashboard" {
|
||||
|
||||
name = "my-kubernetes-dashboard"
|
||||
|
||||
repository = "<https://kubernetes.github.io/dashboard/>"
|
||||
chart = "kubernetes-dashboard"
|
||||
namespace = "default"
|
||||
|
||||
set {
|
||||
name = "service.type"
|
||||
value = "LoadBalancer"
|
||||
}
|
||||
|
||||
set {
|
||||
name = "protocolHttp"
|
||||
value = "true"
|
||||
}
|
||||
|
||||
set {
|
||||
name = "service.externalPort"
|
||||
value = 80
|
||||
}
|
||||
|
||||
set {
|
||||
name = "replicaCount"
|
||||
value = 2
|
||||
}
|
||||
|
||||
set {
|
||||
name = "rbac.clusterReadOnlyRole"
|
||||
value = "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above Terraform, I'm deploying the `kubernetes-dashboard` Chart from `https://kubernetes.github.io/dashboard/` into the namespace `default`. I'm also using the `set` variable to override the Chart's defaults:
|
||||
|
||||
1. `service.type`: I'm changing this to `LoadBalancer` to review my changes locally. Remember to run `minikube tunnel` in a separate window, or this won't work.
|
||||
2. `protocolHttp`: I'm deploying the non-secure version to suppress HTTPS warnings on `localhost`.
|
||||
3. `service.externalPort`: This needs to be 80 for non-secure.
|
||||
4. `replicaCount`: I'm changing this to 2 to see if these changes even work :)
|
||||
5. `rbac.clusterReadOnlyRole`: This should be `true` for the Dashboard to have the correct permissions.
|
||||
|
||||
|
||||
|
||||
### Executing our Terraform
|
||||
|
||||
Let's start by initializing Terraform with `terraform init`:
|
||||
|
||||
|
||||
```
|
||||
Initializing the backend...
|
||||
|
||||
Initializing provider plugins...
|
||||
\- Finding latest version of hashicorp/helm...
|
||||
\- Installing hashicorp/helm v2.2.0...
|
||||
\- Installed hashicorp/helm v2.2.0 (signed by HashiCorp)
|
||||
|
||||
Terraform has created a lock file .terraform.lock.hcl to record the provider
|
||||
selections it made above. Include this file in your version control repository
|
||||
so that Terraform can guarantee to make the same selections by default when
|
||||
you run "terraform init" in the future.
|
||||
|
||||
Terraform has been successfully initialized!
|
||||
|
||||
You may now begin working with Terraform. Try running "terraform plan" to see
|
||||
any changes that are required for your infrastructure. All Terraform commands
|
||||
should now work.
|
||||
|
||||
If you ever set or change modules or backend configuration for Terraform,
|
||||
rerun this command to reinitialize your working directory. If you forget, other
|
||||
commands will detect it and remind you to do so if necessary.
|
||||
```
|
||||
|
||||
So far, so good. Terraform successfully initialized the Helm provider. And now for `terraform apply`:
|
||||
|
||||
|
||||
```
|
||||
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
|
||||
+ create
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# helm_release.my-kubernetes-dashboard will be created
|
||||
+ resource "helm_release" "my-kubernetes-dashboard" {
|
||||
+ atomic = false
|
||||
+ chart = "kubernetes-dashboard"
|
||||
+ cleanup_on_fail = false
|
||||
[...]
|
||||
+ set {
|
||||
+ name = "service.type"
|
||||
+ value = "LoadBalancer"
|
||||
}
|
||||
}
|
||||
|
||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||
|
||||
Do you want to perform these actions?
|
||||
Terraform will perform the actions described above.
|
||||
Only 'yes' will be accepted to approve.
|
||||
|
||||
Enter a value: yes
|
||||
|
||||
helm_release.my-kubernetes-dashboard: Creating...
|
||||
helm_release.my-kubernetes-dashboard: Still creating... [10s elapsed]
|
||||
helm_release.my-kubernetes-dashboard: Creation complete after 14s [id=my-kubernetes-dashboard]
|
||||
```
|
||||
|
||||
(Remember to run `minikube tunnel` in another terminal window, otherwise the `apply` won't work).
|
||||
|
||||
### Verifying our changes
|
||||
|
||||
Let's check if our pods are up using `kubectl get po` and `kubectl get svc`:
|
||||
|
||||
|
||||
```
|
||||
~ kubectl get po
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
my-kubernetes-dashboard-7bc7ccfbd9-56w56 1/1 Running 0 18m
|
||||
my-kubernetes-dashboard-7bc7ccfbd9-f6jc4 1/1 Running 0 18m
|
||||
|
||||
~ kubectl get svc
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20m
|
||||
my-kubernetes-dashboard LoadBalancer 10.104.144.125 10.104.144.125 80:32066/TCP 19m
|
||||
```
|
||||
|
||||
Our pods are deployed, and the load balancer is working. Now check the UI:
|
||||
|
||||
![Kubernetes Workloads dashboard][3]
|
||||
|
||||
Figure 2: Kubernetes Workloads dashboard
|
||||
|
||||
### Conclusion
|
||||
|
||||
You can [find the examples from this article in my Gitlab repo][4].
|
||||
|
||||
With Helm provisioning now a part of Terraform, my work life is that much easier. I do realize that the separation between Infrastructure and Provisioning served a different purpose: Infrastructure changes were usually one-off or didn't require frequent updates, maybe a few times when governance or security rules for my org changed. Provisioning changes, on the other hand, frequently occurred, sometimes with every release. So having Terraform (Infrastructure) and Helm Charts (Provisioning) in two different repos with two different tools and two different review workflows made sense. I'm not sure merging them using a single tool is the best idea, but one less tool in the toolchain is always a huge win. I think the pros and cons of this will vary from one project to another and one team to another.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/terraform-deploy-helm
|
||||
|
||||
作者:[Ayush Sharma][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/ship_captain_devops_kubernetes_steer.png?itok=LAHfIpek (Ship captain sailing the Kubernetes seas)
|
||||
[2]: https://opensource.com/article/18/10/getting-started-minikube
|
||||
[3]: https://opensource.com/sites/default/files/2021-07-12-terraform-plus-helm-a-match-made-in-heaven-hell-dashboard.png
|
||||
[4]: https://gitlab.com/ayush-sharma/example-assets/-/tree/main/kubernetes/tf_helm
|
||||
@@ -0,0 +1,109 @@
|
||||
[#]: subject: "How to get the most out of GitOps right now"
|
||||
[#]: via: "https://opensource.com/article/21/8/gitops"
|
||||
[#]: author: "Itiel Shwartz https://opensource.com/users/itielschwartz2021"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
How to get the most out of GitOps right now
|
||||
======
|
||||
GitOps is a great starting point to understand what is running in
|
||||
production, but it may need a little more augmentation to get it working
|
||||
just right for your engineering team.
|
||||
![Team checklist and to dos][1]
|
||||
|
||||
You may have encountered this brief introduction to GitOps shared by prevalent cloud software engineer, [Kelsey Hightower][2]:
|
||||
|
||||
> GitOps: versioned CI/CD on top of declarative infrastructure. Stop scripting and start shipping. <https://t.co/SgUlHgNrnY>
|
||||
>
|
||||
> — Kelsey Hightower (@kelseyhightower) [January 17, 2018][3]
|
||||
|
||||
In the world of [infrastructure as code][4], GitOps is a popular way to manage automated deployments through continuous integration/continuous development (CI/CD) and microservices architecture in general, as most of our infrastructure is essentially defined in config files today (e.g., YAML, JSON, HCL). This is not limited to Kubernetes (K8s), but it's often highly associated with K8s clusters. (I'll explain why in a second.) This basically means that changing anything in your production infrastructure is as simple as changing a line of code.
|
||||
|
||||
The reason GitOps is so closely identified with K8s is that K8s is completely configured in declarative YAML, and therefore, you can quickly achieve the benefits of using GitOps as it is really just software-defined infrastructure. When it comes to properly applying GitOps in your engineering organization, the main thing you need to pay attention to is how you enforce changes to your cluster or infrastructure.
|
||||
|
||||
When you choose the GitOps path, you can only do it through a single source of truth: your source-code management (SCM) repository (e.g., GitLab, GitHub, Bitbucket, or your own hosting solution) that enforces the version-control policy for your entire organization. This means the only way to make changes to your infrastructure is through a pull request in your repository. This is how version control is maintained at scale in large engineering organizations using GitOps.
|
||||
|
||||
### The state of real-world deployments
|
||||
|
||||
The GitOps doctrine claims to be the new and simpler way to achieve CI/CD, except that the CD part of CI/CD is a much more complex beast than GitOps practices would have you believe. With GitOps, the CD part breaks down to a very binary approach to engineering environments. You're either in staging or production, where you just flip the switch and your code is in production. In my years of experience as an engineer, I have yet to participate in a significant code change, feature rollout, or another major deployment that is that simple.
|
||||
|
||||
There is plenty more legwork encapsulated in staging or production versioning completely abstracted from the CD process with GitOps. This means that any engineering process that takes quality seriously will have a few stages between the CI and CD phases of a major deployment. These include testing, validating results, verifying that changes propagated, retesting, and often doing partial rollouts (canary and such). These are just a few examples of how CD is managed in engineering organizations.
|
||||
|
||||
#### GitOps tips for doing deployments better
|
||||
|
||||
When it comes to GitOps, there's no need to reinvent the CI/CD (and particularly the CD) wheel. If you're like most people and achieve CI/CD by duct taping your CD process with some custom scripts before and after deployment to get it over the finish line, know there are better ways to do this with GitOps facilitators. Using GitOps facilitators such as the open source, Cloud Native Computing Foundation (CNCF)-hosted [Argo CD][5] enables users to take all those custom scripts and manage them at scale in a single place. This ensures best practices when using scripts in your CI/CD process, making them canonical and repeatable every time they run.
|
||||
|
||||
What's more, since there is an agent that is continuously syncing state, it reduces human errors by enforcing the committed state.
|
||||
|
||||
### Manage chaos across repositories with GitOps
|
||||
|
||||
With complex deployment architectures such as K8s or even just plain old microservices, even small changes to the code often affect other interdependent services. Mapping these dependencies with GitOps tends to become a hellscape. Often with shared repos and files, you need to sync the state. However, what you'll also often find is that errors, misconfigurations, or even just bugs can create a [butterfly effect][6] that starts a cascade of failures that becomes extremely hard to track and understand in GitOps.
|
||||
|
||||
One common method to solve this challenge with GitOps is to create a "super repo," which is essentially a centralized monorepo that contains pointers to all the relevant dependencies, files, resources, and such. However, this quickly becomes a messy garbage bag "catchall" of a repository, where it is extremely hard to understand, track, and log changes.
|
||||
|
||||
When you have many dependencies, for this to work in GitOps, these dependencies need to be represented in Git. This requires your organization to be "Git native." This means you'll need to do a lot of duct-tape automation work to create modules and submodules to connect and correlate between your super repo and the relevant subrepos. Many times, this comes with a lot of maintenance overhead that becomes extremely difficult to maintain over time.
|
||||
|
||||
If you don't do this, you're not achieving the benefits of GitOps, and you're mostly just stuck with the downsides. You could achieve similar capabilities through a YAML file that encapsulates all the versions and dependencies, similar to a Helm umbrella chart. Without going fully Git native, you could essentially be anything else—and not GitOps.
|
||||
|
||||
While in the GitOps world, repos represent the single source of truth for environments, in practice, there are many third-party integrations in any given deployment. These integrations can be anything from your authentication and authorization (e.g., Auth0) to your database, which are, for the most part, updated externally to your repo. These changes to external resources, which could significantly impact your production and deployments, have no representation inside your single-source-of-truth repo at all. This could be a serious blind spot in your entire deployment.
|
||||
|
||||
#### GitOps tips for managing chaos better
|
||||
|
||||
When using GitOps, treat your configurations the same way you would treat your code. Don't scrimp on validation pipelines, ensure proper pull request hygiene, and maintain any other practices you apply when managing code at scale to avoid this chaos. Don't panic! If something incorrect gets pushed and you're concerned it will propagate to all servers, clusters, and repos, all you need to do is run `git revert`, and you can undo your last commit.
|
||||
|
||||
Also, similar to my recommendation regarding syncing state, using GitOps facilitators can help with managing Git practices, being Git native, and handling Kubernetes deployments (as well as being Kubernetes native).
|
||||
|
||||
Last, to avoid any disorder or complexity, ensure that your Git repository's state is as close as possible to your production environments to avoid any drift of your environments from your GitOps operation.
|
||||
|
||||
### 3 tips for using GitOps
|
||||
|
||||
Here are my tips for getting the most out of GitOps:
|
||||
|
||||
1. Make sure to build visibility into your GitOps automation early, so you're not running blind across your many repos. When it comes to making GitOps work optimally, you should work out of a single repo per application. When these start to add up, visibility can become a real pain point. Think about the dependencies and how to engineer enough visibility into the system, so if something goes wrong, you'll know how to track it down to its source and fix it.
|
||||
2. One way to do that is to plan for every kind of failure scenario. What happens when dependencies crash? When it comes to GitOps, merge conflicts are a way of life. How do you manage high-velocity deployments and promotions to production that can overwhelm a GitOps system? Think about the many potential challenges, failures, and conflicts, and have a playbook for each. Also, following up on the first point, make sure there is sufficient visibility for each to troubleshoot rapidly. And of course, don't forget the `git revert` command in the event failure happens.
|
||||
3. Use a monorepo. There, I said it. The age-old mono vs. multi-repo debate. When it comes to GitOps, there's no question which is the better choice. While a centralized monorepo has disadvantages (e.g., it can get messy, become a nightmare to understand build processes, etc.), it also can help solve a large majority of hassles with cross-repo dependencies.
|
||||
|
||||
|
||||
|
||||
As an engineer, I felt this pain directly. I realized there's a pressing need for something to correlate these dependencies and visibility challenges I felt every single day of my GitOps life.
|
||||
|
||||
I wanted a better solution for tracking and cascading failures in a complex microservices setup to a root cause or code change. Everything I had tried to date, including GitOps, provided only partial information, very little correlation, and almost no causation.
|
||||
|
||||
GitOps tools (like Argo CD) help solve many issues that arise with DIY GitOps. Using such tools can be a good thing to consider when going down the GitOps route because they:
|
||||
|
||||
* Are natively designed for Kubernetes
|
||||
* Are suitable for small teams using image-puller
|
||||
* Have strong community support (e.g., Argo CD through the CNCF, which is also easy to use with other Argo tools)
|
||||
* Provide an improved developer experience with a good user interface for applications
|
||||
* Natively integrate with Git, which helps minimize chaos and complexity
|
||||
|
||||
|
||||
|
||||
### The bottom line
|
||||
|
||||
Deployment processes, particularly with new versions, are a _complex_ engineering feat. To get these right, you need to invest effort in both the technology and design of the process. For example, what is the best way to deploy and validate my application in production?
|
||||
|
||||
GitOps is a really good starting point to understand what is running in production. Just bear in mind that it may also need a little more augmentation with additional tools and DIY automation to get it working just right for your engineering team. This way, GitOps' shine is 24K rather than fool's gold for your organization.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/gitops
|
||||
|
||||
作者:[Itiel Shwartz][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/itielschwartz2021
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf (Team checklist and to dos)
|
||||
[2]: https://twitter.com/kelseyhightower
|
||||
[3]: https://twitter.com/kelseyhightower/status/953638870888849408?ref_src=twsrc%5Etfw
|
||||
[4]: https://www.redhat.com/en/topics/automation/what-is-infrastructure-as-code-iac
|
||||
[5]: https://argoproj.github.io/argo-cd/
|
||||
[6]: https://en.wikipedia.org/wiki/Butterfly_effect
|
||||
@@ -0,0 +1,101 @@
|
||||
[#]: subject: "elementary OS 6 ODIN Released. This is What’s New."
|
||||
[#]: via: "https://www.debugpoint.com/2021/08/elementary-os-6/"
|
||||
[#]: author: "Arindam https://www.debugpoint.com/author/admin1/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
elementary OS 6 ODIN Released. This is What’s New.
|
||||
======
|
||||
The team announced the release of elementary OS 6 ODIN, and it is
|
||||
immediately available for download. We recap the release in this post.
|
||||
![elementary OS 6 ODIN Desktop][1]
|
||||
|
||||
The elementary OS 6 code named “ODIN” was a long due. This release coming after more than two years since its predecessor, [elementary OS 5.1 Hera][2]. A lot had happened in the last two years, that includes a full-fledged pandemic. Despite all the challenges, roadblocks – a brand new and much awaited release is here.
|
||||
|
||||
Let’s take a look at what’s new.
|
||||
|
||||
### elementary OS 6 Odin – What’s New
|
||||
|
||||
The team promises the following items in a nutshell in this release:
|
||||
|
||||
> Empowering you to be in control and express yourself,
|
||||
> Continuing to innovate with new features, and
|
||||
> Making elementary OS easier to get and more inclusive
|
||||
|
||||
* This release is based on Ubuntu 20.04 and Linux Kernel 5.8. If you ask me, it’s late at this moment to have a new version of a distro based on Ubuntu 20.04 whereas next LTS is due in 2022.
|
||||
* Dark theme and new ascent color is introduced in this release. With the dark theme enabled, all the default applications, windows automatically adapt to dark mode. This mode also can be set based on sunset and sunrise at your location.
|
||||
* The ascent colors applied across the system when chosen. A fair and nice list of assent colors are available.
|
||||
* The new dark theme is designed such as way that third party app developers can easily integrate their application to follow elementary OS stylesheet.
|
||||
|
||||
|
||||
|
||||
![Dark and Light theme][3]
|
||||
|
||||
* All apps in AppCenter are now Flatpak apps which runs in their separate sandbox. This is one of the best move by elementary team and all the Flatpak apps requires separate permission controls via settings.
|
||||
* If you are a touchpad/touch device fan, then you are in for a treat. Three finger swipe up gestures brings up the activities overview.
|
||||
* Three finger left and right – swap between dynamic workspaces.
|
||||
* And all the applicable apps uses two finger gestures.
|
||||
* Notifications are revamped with new look and can follow dark theme.
|
||||
* A new task application introduced to track your tasks and can sync with online accounts.
|
||||
* elementary OS 6 comes with firmware updates built in, powered by the Linux Vendor Firmware Service. Firmware updates are provided for supported devices by hardware manufacturers like Star Labs, Dell, Lenovo, HP, Intel, Logitech, Wacom, 8bitdo, and many more—now supported devices can get the latest updates for security and stability straight from System Settings → System → Firmware or by searching the Applications Menu for “Firmware.”
|
||||
* Native applications are updated and redesigned completely. Epiphany browser is renamed as Web. Mail is completely rewritten with tighter integration with online accounts.
|
||||
* Files introduces a different behavioral change. You need to single click to browse folders, but double click for files. This can not be changed via gsettings.
|
||||
* And many more updates, which you can read in the [change log][4] here.
|
||||
|
||||
|
||||
|
||||
[][5]
|
||||
|
||||
SEE ALSO: elementary OS 6 Beta Released. Download and Test Now!
|
||||
|
||||
### Minimum System Requirement for elementary OS 6
|
||||
|
||||
Here’s a system specification for this version, before you hit download.
|
||||
|
||||
* Recent Intel i3 or comparable dual-core 64-bit processor
|
||||
* 4 GB of system memory (RAM)
|
||||
* Solid state drive (SSD) with 15 GB of free space
|
||||
* Internet access
|
||||
* Built-in or wired mouse/touchpad and keyboard
|
||||
* 1024×768 minimum resolution display
|
||||
|
||||
|
||||
|
||||
### elementary OD 6 Odin – Download
|
||||
|
||||
The .iso files for the new release is available in below link. Due to rush, the servers might be busy, hence it is recommended to use torrents if possible.
|
||||
|
||||
[Download elementary OS 6 ODIN][6]
|
||||
|
||||
### How to Upgrade
|
||||
|
||||
There is no upgrade path available at the moment to upgrade to elementary 6 from elementary 5.1. Hence, you need to take backups and do a fresh installation via .iso available in above link.
|
||||
|
||||
### Closing Notes
|
||||
|
||||
There is no question that elementary OS is a one-of-a-kind Linux Distribution today. And its popularity is increasing everyday due to the awesome Pantheon desktop. It is one of the rare Linux distribution which appeals both macOS and Windows users. That said, I think the development process requires a bit faster and two years of the wait between versions is too long for IT. This release is based on Ubuntu 20.04 which is already two years old, and we have a new LTS coming up on 2022. And of course there is no upgrade path. I believe if the team work on these aspects, considering dedicated developers, donations, I think it would be one of the best Linux distro.
|
||||
|
||||
* * *
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.debugpoint.com/2021/08/elementary-os-6/
|
||||
|
||||
作者:[Arindam][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.debugpoint.com/author/admin1/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.debugpoint.com/blog/wp-content/uploads/2021/08/elementary-OS-6-ODIN-Desktop-1024x576.jpg
|
||||
[2]: https://www.debugpoint.com/2019/12/elementary-os-hera-released/
|
||||
[3]: https://www.debugpoint.com/blog/wp-content/uploads/2021/08/Dark-and-Light-theme-1024x692.png
|
||||
[4]: https://blog.elementary.io/elementary-os-6-odin-released/
|
||||
[5]: https://www.debugpoint.com/2021/05/elementary-os-6-beta/
|
||||
[6]: https://elementary.io/
|
||||
294
sources/tech/20210811 Build your own Fedora IoT Remix.md
Normal file
294
sources/tech/20210811 Build your own Fedora IoT Remix.md
Normal file
@@ -0,0 +1,294 @@
|
||||
[#]: subject: "Build your own Fedora IoT Remix"
|
||||
[#]: via: "https://fedoramagazine.org/build-your-own-fedora-iot-remix/"
|
||||
[#]: author: "Alexander Wellbrock https://fedoramagazine.org/author/w4tsn/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Build your own Fedora IoT Remix
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Background excerpted from photo by [S. Tsuchiya][2] on [Unsplash][3]
|
||||
|
||||
Fedora IoT Edition is aimed at the Internet of Things. It was introduced in the article [How to turn on an LED][4] with Fedora IoT in 2018. It is based on [RPM-OSTree][5] as a core technology to gain some nifty properties and features which will be covered in a moment.
|
||||
|
||||
RPM-OSTree is a high-level tool built on [libostree][6] which is a set of tools establishing a “git-like” model for committing and exchanging filesystem trees, deployment of said trees, bootloader configuration and layered RPM package management. Such a system benefits from the following properties:
|
||||
|
||||
* Transactional upgrade and rollback
|
||||
* Read-only filesystem areas
|
||||
* Potentially small updates through deltas
|
||||
* Branching, including rebase and multiple deployments
|
||||
* Reproducible filesystem
|
||||
* Specification of filesystem through version-controlled code
|
||||
|
||||
|
||||
|
||||
Exchange of filesystem trees and corresponding commits is done through OSTree repositories or remotes. When using one of the Fedora Editions based on RPM-OSTree there are remotes from which the system downloads commits and applies them, rather than downloading and installing separate RPMs.
|
||||
|
||||
A [Remix][7] in the Fedora ecosystem is an altered, opinionated version of the OS. It covers the needs of a specific niche. This article will dive into the world of building your own filesystem commits based on Fedora IoT Edition. You will become acquainted to the tools, terminology, design and processes of such a system. If you follow the directions in this guide you will end up with your own Fedora IoT Remix.
|
||||
|
||||
### Preparations
|
||||
|
||||
You will need some packages to get started. On non-ostree systems install the packages _ostree_ and _rpm-ostree_. Both are available in the Fedora Linux package repositories. Additionally install _git_ to access the Fedora IoT ostree spec sources.
|
||||
|
||||
```
|
||||
sudo dnf install ostree rpm-ostree git
|
||||
```
|
||||
|
||||
Assuming you have a spare, empty folder laying around to work with, start there by creating some files and folders that will be needed along the way.
|
||||
|
||||
```
|
||||
mkdir .cache .build-repo .deploy-repo .tmp custom
|
||||
```
|
||||
|
||||
The _.cache_ directory is used by all build commands around rpm-ostree. The folders _build_ and _deploy_ store separate repositories to keep the build environment separate from the actual remix. The _.tmp_ directory is used to combine the git-managed upstream sources (from Fedora IoT, for example) with modifications kept in the _custom_ directory.
|
||||
|
||||
As you build your own OSTree as derivative from Fedora IoT you will need the sources. Clone them into the folder _.fedora-iot-spec_. They contain several configuration files specifying how the ostree filesystem for Fedora IoT is built, what packages to include, etc.
|
||||
|
||||
```
|
||||
git clone -b "f34" https://pagure.io/fedora-iot/ostree.git .fedora-iot-spec
|
||||
```
|
||||
|
||||
#### OSTree repositories
|
||||
|
||||
Create repositories to build and store an OSTree filesystem and its contents . A place to store commits and manage their metadata. Wait, what? What is an OSTree commit anyway? Glad you ask! With _rpm-ostree_ you build so-called _libostree commits_. The terminology is roughly based on git. They essentially work in similar ways. Those commits store diffs from one state of the filesystem to the next. If you change a binary blob inside the tree, the commit contains this change. You can deploy this specific version of the filesystem at any time.
|
||||
|
||||
Use the _ostree init_ command to create two _ostree repositories_.
|
||||
|
||||
```
|
||||
ostree --repo=".build-repo" init --mode=bare-user
|
||||
ostree --repo=".deploy-repo" init --mode=archive
|
||||
```
|
||||
|
||||
The main difference between the repositories is their mode. Create the build repository in “bare-user” mode and the “production” repository in “archive” mode. The _bare*_ mode is well suited for build environments. The “user” portion additionally allows non-root operation and storing extended attributes. Create the other repository in _archive_ mode. It stores objects compressed; making them easy to move around. If all that doesn’t mean a thing to you, don’t worry. The specifics don’t matter for your primary goal here – to build your own Remix.
|
||||
|
||||
Let me share just a little anecdote on this: When I was working on building ostree-based systems on GitLab CI/CD pipelines and we had to move the repositories around different jobs, we once tried to move them uncompressed in _bare-user_ mode via caches. We learned that, while this works with _archive_ repos, it does not with _bare*_ repos. Important filesystem attributes will get corrupted on the way.
|
||||
|
||||
#### Custom flavor
|
||||
|
||||
What’s a Remix without any customization? Not much! Create some configuration files as adjustment for your own OS. Assuming you want to deploy the Remix on a system with a hardware watchdog (a [Raspberry Pi][8], for example) start with a watchdog configuration file:
|
||||
|
||||
```
|
||||
./custom/watchdog.conf
|
||||
watchdog-device = /dev/watchdog
|
||||
max-load-1 = 24
|
||||
max-load-15 = 9
|
||||
realtime = yes
|
||||
priority = 1
|
||||
watchdog-timeout = 15 # Broadcom BCM2835 limitation
|
||||
```
|
||||
|
||||
The _postprocess-script_ is an arbitrary shell script executed inside the target filesystem tree as part of the build process. It allows for last-minute customization of the filesystem in a restricted and (by default) network-less environment. It’s a good place to ensure the correct file permissions are set for the custom watchdog configuration file.
|
||||
|
||||
```
|
||||
./custom/treecompose-post.sh
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Prepare watchdog
|
||||
chown root:root /etc/watchdog.conf
|
||||
chmod 0644 /etc/watchdog.conf
|
||||
```
|
||||
|
||||
#### Plant a Treefile
|
||||
|
||||
Fedora IoT is pretty minimal and keeps its main focus on security and best-practices. The rest is up to you and your use-case. As a consequence, the watchdog package is not provided from the get-go. In RPM-OSTree the spec file is called [Treefile][9] and encoded in [JSON][10]. In the _Treefile_ you specify what packages to install, files and folders to exclude from packages, _configuration files_ to add to the _filesystem tree_ and _systemd units_ to enable by default.
|
||||
|
||||
```
|
||||
./custom/treefile.json
|
||||
{
|
||||
"ref": "OSTreeBeard/stable/x86_64",
|
||||
"ex-jigdo-spec": "fedora-iot.spec",
|
||||
"include": "fedora-iot-base.json",
|
||||
"boot-location": "modules",
|
||||
"packages": [
|
||||
"watchdog"
|
||||
],
|
||||
"remove-files": [
|
||||
"etc/watchdog.conf"
|
||||
],
|
||||
"add-files": [
|
||||
["watchdog.conf", "/etc/watchdog.conf"]
|
||||
],
|
||||
"units": [
|
||||
"watchdog.service"
|
||||
],
|
||||
"postprocess-script": "treecompose-post.merged.sh"
|
||||
}
|
||||
```
|
||||
|
||||
The _ref_ is basically the branch name within the repository. Use it to refer to this specific spec in _rpm-ostree_ operations. With _ex-jigdo-spec_ and _include_ you link this _Treefile_ to the configuration of the _Fedora IoT sources_. Additionally specify the _Fedora Updates repo_ in the _repos_ section. It is not part of the sources so you will have to add that yourself. More on that in a moment.
|
||||
|
||||
With _packages_ you instruct _rpm-ostree_ to install the _watchdog_ package. Exclude the _watchdog.conf_ file and replace it with the one from the _custom_ directory by using _remove-files_ and _add-files_. Now just enable the _watchdog.service_ and you are good to go.
|
||||
|
||||
All available treefile options are available in the [official RPM-OSTree documentation][11].
|
||||
|
||||
#### Add another RPM repository
|
||||
|
||||
In it’s initial configuration the OSTree only uses the initial Fedora 34 package repository. Add the Fedora 34 Updates repository as well. To do so, add the following file to your _custom_ directory.
|
||||
|
||||
```
|
||||
./custom/fedora-34-updates.repo
|
||||
[fedora-34-updates]
|
||||
name=Fedora 34 - $basearch - Updates
|
||||
#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever/Everything/$basearch/
|
||||
metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f34&arch=$basearch
|
||||
enabled=1
|
||||
repo_gpgcheck=0
|
||||
type=rpm
|
||||
gpgcheck=1
|
||||
#metadata_expire=7d
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-34-$basearch
|
||||
skip_if_unavailable=False
|
||||
```
|
||||
|
||||
Now tell rpm-ostree in the spec for your Remix to include this repository. Use the _treefile_‘s _repos_ section.
|
||||
|
||||
```
|
||||
./custom/treefile.json
|
||||
{
|
||||
...
|
||||
"repos": [
|
||||
"fedora-34",
|
||||
"fedora-34-updates"
|
||||
],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Build your own Fedora IoT Remix
|
||||
|
||||
You have all that need to build your first ostree based filesystem. By now you setup a certain project structure, downloaded the Fedora IoT upstream specs, and added some customization and initialized the ostree repositories. All you need to do now is throw everything together and create a nicely flavored Fedora IoT Remix salsa.
|
||||
|
||||
```
|
||||
cp ./.fedora-iot-spec/* .tmp/
|
||||
cp ./custom/* .tmp/
|
||||
```
|
||||
|
||||
Combine the _postprocessing-scripts_ of the _Fedora IoT upstream sources_ and your _custom_ directory.
|
||||
|
||||
```
|
||||
cat "./.fedora-iot-spec/treecompose-post.sh" "./custom/treecompose-post.sh" > ".tmp/treecompose-post.merged.sh"
|
||||
chmod +x ".tmp/treecompose-post.merged.sh"
|
||||
```
|
||||
|
||||
Remember that you specified _treecompose-post.merged.sh_ as your post-processing script earlier in _treefile.json_? That’s where this file comes from.
|
||||
|
||||
Note that all the files – systemd units, scripts, configurations – mentioned in _ostree.json_ are now available in _.tmp_. This folder is the build context that all the references are relative to.
|
||||
|
||||
You are only one command away from kicking off your first build of a customized Fedora IoT. Now, kick-of the build with _rpm-ostree compose tree_ command. Now grab a cup of coffee, enjoy and wait for the build to finish. That may take between 5 to 10 minutes depending on your host hardware. See you later!
|
||||
|
||||
```
|
||||
sudo rpm-ostree compose tree --unified-core --cachedir=".cache" --repo=".build-repo" --write-commitid-to="$COMMIT_FILE" ".tmp/treefile.json"
|
||||
```
|
||||
|
||||
#### Prepare for deployment
|
||||
|
||||
Oh, erm, you are back already? Ehem. Good! – The _.build-repo_ now stores a complete filesystem tree of around 700 to 800 MB of compressed data. The last thing to do before you consider putting this on the network and deploying it on your device(s) (at least for now) is to add a _commit_ with an arbitrary _commit subject_ and _metadata_ and to pull the result over to the _deploy-repo_.
|
||||
|
||||
```
|
||||
sudo ostree --repo=".deploy-repo" pull-local ".build-repo" "OSTreeBeard/stable/x86_64"
|
||||
```
|
||||
|
||||
The _deploy-repo_ can now be placed on any file-serving webserver and then used as a new _ostree remote_ … theoretically. I won’t go through the topic of security for ostree remotes just yet. As an initial advise though: Always sign OSTree commits with GPG to ensure the authenticity of your updates. Apart from that it’s only a matter of adding the remote configuration on your target and using _rpm-ostree rebase_ to switch over to this Remix.
|
||||
|
||||
As a final thing before you leave to do outside stuff (like with fresh air, sun, ice-cream or whatever), take a look around the newly built filesystem to ensure that everything is in place.
|
||||
|
||||
#### Explore the filesystem
|
||||
|
||||
Use _ostree refs_ to list available refs in the repo or on your system.
|
||||
|
||||
```
|
||||
$ ostree --repo=".deploy-repo" refs
|
||||
OSTreeBeard/stable/x86_64
|
||||
```
|
||||
|
||||
Take a look at the commits of a ref with _ostree log_.
|
||||
|
||||
```
|
||||
$ ostree --repo=".deploy-repo" log OSTreeBeard/stable/x86_64
|
||||
commit 849c0648969c8c2e793e5d0a2f7393e92be69216e026975f437bdc2466c599e9
|
||||
ContentChecksum: bcaa54cc9d8ffd5ddfc86ed915212784afd3c71582c892da873147333e441b26
|
||||
Date: 2021-07-27 06:45:36 +0000
|
||||
Version: 34
|
||||
(no subject)
|
||||
```
|
||||
|
||||
List the ostree filesystem contents with _ostree ls_.
|
||||
|
||||
```
|
||||
$ ostree --repo=".build-repo" ls OSTreeBeard/stable/x86_64
|
||||
d00755 0 0 0 /
|
||||
l00777 0 0 0 /bin -> usr/bin
|
||||
l00777 0 0 0 /home -> var/home
|
||||
l00777 0 0 0 /lib -> usr/lib
|
||||
l00777 0 0 0 /lib64 -> usr/lib64
|
||||
l00777 0 0 0 /media -> run/media
|
||||
l00777 0 0 0 /mnt -> var/mnt
|
||||
l00777 0 0 0 /opt -> var/opt
|
||||
l00777 0 0 0 /ostree -> sysroot/ostree
|
||||
l00777 0 0 0 /root -> var/roothome
|
||||
l00777 0 0 0 /sbin -> usr/sbin
|
||||
l00777 0 0 0 /srv -> var/srv
|
||||
l00777 0 0 0 /tmp -> sysroot/tmp
|
||||
d00755 0 0 0 /boot
|
||||
d00755 0 0 0 /dev
|
||||
d00755 0 0 0 /proc
|
||||
d00755 0 0 0 /run
|
||||
d00755 0 0 0 /sys
|
||||
d00755 0 0 0 /sysroot
|
||||
d00755 0 0 0 /usr
|
||||
d00755 0 0 0 /var
|
||||
$ ostree --repo=".build-repo" ls OSTreeBeard/stable/x86_64 /usr/etc/watchdog.conf
|
||||
-00644 0 0 208 /usr/etc/watchdog.conf
|
||||
```
|
||||
|
||||
Take note that the _watchdog.conf_ file is located under _/usr/etc/watchdog.conf_. On booted deployment this is located at _/etc/watchdog.conf_ as usual.
|
||||
|
||||
### Where to go from here?
|
||||
|
||||
You took a brave step in building a customized Fedora IoT on your local machine. First I introduced you the concepts and vocabulary so you could understand where you were at and where you wanted to go. You then ensured all the tools were in place. You looked at the ostree repository modes and mechanics before analyzing a typical _ostree configuration_. To spice it up and make it a bit more interesting you made an additional service and configuration ready to role out on your device(s). To do that you added the Fedora Updates RPM repository and then kicked off the build process. Last but not least, you packaged the result up in a format ready to be placed somewhere on the network.
|
||||
|
||||
There are a lot more topics to cover. I could explain how to configure an NGINX to serve ostree remotes effectively. Or how to ensure the security and authenticity of the filesystem and updates through GPG signatures. Also, how one manually alters the filesystem and what tooling is available for building the filesystem. There is also more to be explained about how to test the Remix and how to build flashable images and installation media.
|
||||
|
||||
Let me know in the comments what you think and what you care about. Tell me what you’d like to read next. If you already built Fedora IoT, I’m happy to read your stories too.
|
||||
|
||||
### References
|
||||
|
||||
* [Fedora IoT documentation][12]
|
||||
* [libostree documentation][13]
|
||||
* [rpm-ostree documentation][5]
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/build-your-own-fedora-iot-remix/
|
||||
|
||||
作者:[Alexander Wellbrock][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/w4tsn/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2021/08/rpi-816x345.jpg
|
||||
[2]: https://unsplash.com/@s_tsuchiya?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/s/photos/raspberry-pi?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://fedoramagazine.org/turnon-led-fedora-iot/
|
||||
[5]: https://coreos.github.io/rpm-ostree/
|
||||
[6]: https://ostreedev.github.io/ostree/
|
||||
[7]: https://fedoraproject.org/wiki/Remix
|
||||
[8]: https://en.wikipedia.org/wiki/Raspberry_Pi
|
||||
[9]: https://rpm-ostree.readthedocs.io/en/stable/manual/treefile/
|
||||
[10]: https://en.wikipedia.org/wiki/JSON
|
||||
[11]: https://coreos.github.io/rpm-ostree/treefile/
|
||||
[12]: https://docs.fedoraproject.org/en-US/iot/
|
||||
[13]: https://ostreedev.github.io/ostree/introduction/
|
||||
@@ -0,0 +1,198 @@
|
||||
[#]: subject: "Monitor your Linux system in your terminal with procps-ng"
|
||||
[#]: via: "https://opensource.com/article/21/8/linux-procps-ng"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Monitor your Linux system in your terminal with procps-ng
|
||||
======
|
||||
How to find the process ID (PID) of a program. The most common Linux
|
||||
tools for this are provided by the procps-ng package, including the ps
|
||||
and pstree, pidof, and pgrep commands.
|
||||
![System monitor][1]
|
||||
|
||||
A process, in [POSIX][2] terminology, is an ongoing event being managed by an operating system’s kernel. A process is spawned when you launch an application, although there are many other processes running in the background of your computer, including programs to keep your system time accurate, to monitor for new filesystems, to index files, and so on.
|
||||
|
||||
Most operating systems have a system activity monitor of some kind so you can learn what processes are running at any give moment. Linux has a few for you to choose from, including GNOME System Monitor and KSysGuard. Both are useful applications on the desktop, but Linux also provides the ability to monitor your system in your terminal. Regardless of which you choose, it’s a common task for those who take an active role in managing their computer is to examine a specific process.
|
||||
|
||||
In this article, I demonstrate how to find the process ID (PID) of a program. The most common tools for this are provided by the [procps-ng][3] package, including the `ps` and `pstree`, `pidof`, and `pgrep` commands.
|
||||
|
||||
### Find the PID of a running program
|
||||
|
||||
Sometimes you want to get the process ID (PID) of a specific application you know you have running. The `pidof` and `pgrep` commands find processes by command name.
|
||||
|
||||
The `pidof` command returns the PIDs of a command, searching for the exact command by name:
|
||||
|
||||
|
||||
```
|
||||
$ pidof bash
|
||||
1776 5736
|
||||
```
|
||||
|
||||
The `pgrep` command allows for regular expressions (regex):
|
||||
|
||||
|
||||
```
|
||||
$ pgrep .sh
|
||||
1605
|
||||
1679
|
||||
1688
|
||||
1776
|
||||
2333
|
||||
5736
|
||||
$ pgrep bash
|
||||
5736
|
||||
```
|
||||
|
||||
### Find a PID by file
|
||||
|
||||
You can find the PID of the process using a specific file with the `fuser` command.
|
||||
|
||||
|
||||
```
|
||||
$ fuser --user ~/example.txt
|
||||
/home/tux/example.txt: 3234(tux)
|
||||
```
|
||||
|
||||
### Get a process name by PID
|
||||
|
||||
If you have the PID _number_ of a process but not the command that spawned it, you can do a "reverse lookup" with `ps`:
|
||||
|
||||
|
||||
```
|
||||
$ ps 3234
|
||||
PID TTY STAT TIME COMMAND
|
||||
5736 pts/1 Ss 0:00 emacs
|
||||
```
|
||||
|
||||
### List all processes
|
||||
|
||||
The `ps` command lists processes. You can list every process on your system with the `-e` option:
|
||||
|
||||
|
||||
```
|
||||
$ ps -e | less
|
||||
PID TTY TIME CMD
|
||||
1 ? 00:00:03 systemd
|
||||
2 ? 00:00:00 kthreadd
|
||||
3 ? 00:00:00 rcu_gp
|
||||
4 ? 00:00:00 rcu_par_gp
|
||||
6 ? 00:00:00 kworker/0:0H-events_highpri
|
||||
[...]
|
||||
5648 ? 00:00:00 gnome-control-c
|
||||
5656 ? 00:00:00 gnome-terminal-
|
||||
5736 pts/1 00:00:00 bash
|
||||
5791 pts/1 00:00:00 ps
|
||||
5792 pts/1 00:00:00 less
|
||||
(END)
|
||||
```
|
||||
|
||||
### List just your processes
|
||||
|
||||
The output of `ps -e` can be overwhelming, so use `-U` to see the processes of just one user:
|
||||
|
||||
|
||||
```
|
||||
$ ps -U tux | less
|
||||
PID TTY TIME CMD
|
||||
3545 ? 00:00:00 systemd
|
||||
3548 ? 00:00:00 (sd-pam)
|
||||
3566 ? 00:00:18 pulseaudio
|
||||
3570 ? 00:00:00 gnome-keyring-d
|
||||
3583 ? 00:00:00 dbus-daemon
|
||||
3589 tty2 00:00:00 gdm-wayland-ses
|
||||
3592 tty2 00:00:00 gnome-session-b
|
||||
3613 ? 00:00:00 gvfsd
|
||||
3618 ? 00:00:00 gvfsd-fuse
|
||||
3665 tty2 00:01:03 gnome-shell
|
||||
[...]
|
||||
```
|
||||
|
||||
That produces 200 fewer (give or take a hundred, depending on the system you're running it on) processes to sort through.
|
||||
|
||||
You can view the same output in a different format with the `pstree` command:
|
||||
|
||||
|
||||
```
|
||||
$ pstree -U tux -u --show-pids
|
||||
[...]
|
||||
├─gvfsd-metadata(3921)─┬─{gvfsd-metadata}(3923)
|
||||
│ └─{gvfsd-metadata}(3924)
|
||||
├─ibus-portal(3836)─┬─{ibus-portal}(3840)
|
||||
│ └─{ibus-portal}(3842)
|
||||
├─obexd(5214)
|
||||
├─pulseaudio(3566)─┬─{pulseaudio}(3640)
|
||||
│ ├─{pulseaudio}(3649)
|
||||
│ └─{pulseaudio}(5258)
|
||||
├─tracker-store(4150)─┬─{tracker-store}(4153)
|
||||
│ ├─{tracker-store}(4154)
|
||||
│ ├─{tracker-store}(4157)
|
||||
│ └─{tracker-store}(4178)
|
||||
└─xdg-permission-(3847)─┬─{xdg-permission-}(3848)
|
||||
└─{xdg-permission-}(3850)
|
||||
```
|
||||
|
||||
### List just your processes with context
|
||||
|
||||
You can see extra context for all of the processes you own with the `-u` option.
|
||||
|
||||
|
||||
```
|
||||
$ ps -U tux -u
|
||||
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||
tux 3545 0.0 0.0 89656 9708 ? Ss 13:59 0:00 /usr/lib/systemd/systemd --user
|
||||
tux 3548 0.0 0.0 171416 5288 ? S 13:59 0:00 (sd-pam)
|
||||
tux 3566 0.9 0.1 1722212 17352 ? S<sl 13:59 0:29 /usr/bin/pulseaudio [...]
|
||||
tux 3570 0.0 0.0 664736 8036 ? SLl 13:59 0:00 /usr/bin/gnome-keyring-daemon [...]
|
||||
[...]
|
||||
tux 5736 0.0 0.0 235628 6036 pts/1 Ss 14:18 0:00 bash
|
||||
tux 6227 0.0 0.4 2816872 74512 tty2 Sl+14:30 0:00 /opt/firefox/firefox-bin [...]
|
||||
tux 6660 0.0 0.0 268524 3996 pts/1 R+ 14:50 0:00 ps -U tux -u
|
||||
tux 6661 0.0 0.0 219468 2460 pts/1 S+ 14:50 0:00 less
|
||||
```
|
||||
|
||||
### Troubleshoot with PIDs
|
||||
|
||||
If you’re having trouble with a specific application, or you’re just curious about what else on your system an application uses, you can see a memory map of the running process with `pmap`:
|
||||
|
||||
|
||||
```
|
||||
$ pmap 1776
|
||||
5736: bash
|
||||
000055f9060ec000 1056K r-x-- bash
|
||||
000055f9063f3000 16K r---- bash
|
||||
000055f906400000 40K rw--- [ anon ]
|
||||
00007faf0fa67000 9040K r--s- passwd
|
||||
00007faf1033b000 40K r-x-- libnss_sss.so.2
|
||||
00007faf10345000 2044K ----- libnss_sss.so.2
|
||||
00007faf10545000 4K rw--- libnss_sss.so.2
|
||||
00007faf10546000 212692K r---- locale-archive
|
||||
00007faf1d4fb000 1776K r-x-- libc-2.28.so
|
||||
00007faf1d6b7000 2044K ----- libc-2.28.so
|
||||
00007faf1d8ba000 8K rw--- libc-2.28.so
|
||||
[...]
|
||||
```
|
||||
|
||||
### Process IDs
|
||||
|
||||
The **procps-ng** package has all the commands you need to investigate and monitor what your system is using at any moment. Whether you’re just curious about how all the disparate parts of a Linux system fit together, or whether you’re investigating an error, or you’re looking to optimize how your computer is performing, learning these commands gives you a significant advantage for understanding your OS.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/linux-procps-ng
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/system-monitor-splash.png?itok=0UqsjuBQ (System monitor)
|
||||
[2]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[3]: https://gitlab.com/procps-ng
|
||||
@@ -0,0 +1,75 @@
|
||||
[#]: subject: "My top 5 tips for setting up Terraform"
|
||||
[#]: via: "https://opensource.com/article/21/8/terraform-tips"
|
||||
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
My top 5 tips for setting up Terraform
|
||||
======
|
||||
These are the lessons I've learned after five years with Terraform.
|
||||
![Puzzle pieces coming together to form a computer screen][1]
|
||||
|
||||
Working with Terraform for over five years has taught me some key lessons. Five practices have been critical to having a logical and usable Terraform setup regardless of the size of the team or the nature of the project.
|
||||
|
||||
### 1\. Know your target audience.
|
||||
|
||||
This one might seem obvious, but I've seen it go wrong several times. When organizing Terraform code, either standardizing the directory structure or defining naming conventions, it's vital to consider the intended audience. Will your team be using these Terraform scripts and modules? Are you handing the work over to another team? Will new people be joining your team sooner or later? Are you working on this project solo? Will you be using this setup in six months or a year, or will it be assigned to someone else?
|
||||
|
||||
Questions like these affect several decisions. Ideally, you should have [Remote State][2] and [State Locking][3] in place regardless of the team size now or in the future. Remote State will ensure your laptop is not the only place your Terraform works, and State Locking will ensure that only one person at a time is changing the infrastructure.
|
||||
|
||||
The naming convention should make sense to the eventual owners of the project, not just the team that is writing the code. If the project is for another team, make sure they have a say in the naming convention. If non-technical stakeholders or internal security/GCR teams review the code, make sure they check the naming convention. In addition to resource names, you should leverage resource tags to highlight any data classification/privacy requirements (high, medium, low) for more careful examination by reviewers.
|
||||
|
||||
### 2\. Reuse. Reuse. Reuse.
|
||||
|
||||
The [Terraform Registry][4] provides a library of ready-to-use modules for the most common use-cases. I've written about the extensive parameterization available in the VPC module and security groups. Simply calling modules with different parameters is enough to handle most, if not all, potential use cases. Reuse these shared modules as much as possible to avoid endless typing, testing, checking, fixing, and refactoring.
|
||||
|
||||
I've also found that separating modules and resources based on the frequency of use or change is beneficial. For example, infrastructure scaffolding used only once belongs together, such as setting up the VPC, security groups, routing tables, VPC endpoints, and so on. But things like private hosted zone entries, autoscaling groups, target groups, load balancers, etc., might change with every deployment, so separating these from the one-time scaffolding will make code reviews easier and debugging faster.
|
||||
|
||||
### 3\. Be explicit rather than implicit.
|
||||
|
||||
There are common patterns to Terraform code that I have seen lead to incorrect assumptions baked into the design. Teams can assume that the Terraform version used to write the code today will never change, or the external modules won't change, or the providers they are using won't change. These lead to invisible issues a few weeks down the road when these external dependencies inevitably get updated.
|
||||
|
||||
Ensure you explicitly define versions everywhere possible: In the main Terraform block, in the provider block, in the module block, etc. Defining versions ensures that your dependent libraries stay frozen so that you can explicitly update dependencies when required after thorough discussions, reviews, and testing.
|
||||
|
||||
### 4\. Automate everywhere. Your laptop. Your shared VM. Your CI/CD.
|
||||
|
||||
Leveraging automation at every stage of the deployment process can avoid future problems before they even arise.
|
||||
|
||||
Use [Git pre-commit hooks][5] to run `terraform fmt` and `terraform validate` before you commit your code. Pre-commit hooks ensure that code is, at a bare minimum, adequately formatted and syntactically correct. Check-in this pre-commit file to the repo, and everyone on your team can benefit from the same automation. This small but vital quality control at the first step of the process can achieve substantial time savings as your project progresses.
|
||||
|
||||
All modern deployment tools have CI processes. You can use these to run SAST and unit testing tools when pushing your code to origin. I've written on my blog about how [Checkov can test Terraform code for security and compliance and create custom checks][6] for organization-specific conventions. Add these unit testing tools to your CI pipeline to improve code quality and robustness.
|
||||
|
||||
### 5\. Have an awesome README.md.
|
||||
|
||||
We all like to think that Terraform code is self-documenting. Sure it is, but only if your future team already knows your company's naming conventions and guidelines and secret handshakes and inside jokes and whatever else your repo contains besides valid Terraform code. Getting into the habit of having a good `README.md` can be a huge time saver, and it keeps your team honest by holding them accountable for everything explicitly committed to in the README.
|
||||
|
||||
At a minimum, your README should contain the steps to initialize the right Terraform environment on your workstations (Linux, Windows, Mac, and so on), including the Terraform version to install. It should specify the required dependencies (Checkov, TerraGrunt, and others) with versions and any handy Linux aliases your team uses (some people like to define `tff` as a short-hand for `terraform fmt`). Most importantly, the branching and PR review strategy and process, naming conventions, and resource tagging standards should be specified.
|
||||
|
||||
The README should pass a simple test: if a new member joins your team tomorrow, is the README enough to teach them what to do and how to do it correctly? If not, you may find yourself hosting never-ending standards and process meetings repeatedly for the next few months.
|
||||
|
||||
### Wrap up
|
||||
|
||||
After many years of working with Terraform, these are my five best bits of wisdom to pass along. Feel free to share your own best practices below.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/terraform-tips
|
||||
|
||||
作者:[Ayush Sharma][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
|
||||
[2]: https://www.terraform.io/docs/language/state/index.html
|
||||
[3]: https://www.terraform.io/docs/language/state/locking.html
|
||||
[4]: https://registry.terraform.io/
|
||||
[5]: https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6
|
||||
[6]: https://notes.ayushsharma.in/2021/07/cloud-infrastructure-sast-terraform-checkov
|
||||
@@ -0,0 +1,129 @@
|
||||
[#]: subject: "A guide to the Linux terminal for beginners"
|
||||
[#]: via: "https://opensource.com/article/21/8/linux-terminal"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
A guide to the Linux terminal for beginners
|
||||
======
|
||||
Learn the differences between Linux terminal commands, arguments, and
|
||||
options, and how to use them to control your computer.
|
||||
![Terminal command prompt on orange background][1]
|
||||
|
||||
There's a café a few streets away from where I live, and I go there every Sunday for a regularly scheduled game of D&D. They have a menu, and the first few times I ordered, I looked over the menu for several minutes to see what my choices were. Being a creature of habit, I eventually stopped referring to the menu because I knew exactly what they have for sale, and I know exactly what I want. Ordering food for the table is now as easy as saying "the usual" and waiting for the cups of coffee and bowls of chips and scones to be delivered (usually inconveniently at just the moment we've rolled for initiative, but that's hardly the staff's fault or problem).
|
||||
|
||||
Similar to a restaurant menu, graphical interfaces for computers offer users a choice of actions. There are icons and windows and buttons, and you hunt for the one you're looking for, click on items, drag other items, and manipulate graphical representations until a task is complete. After a while, though, this can become cumbersome and, worse yet, inefficient. You know exactly what needs to be done, so wouldn't it be nice to just tell the computer exactly what you want to happen, rather than going through the physical and mental motions of hunting for components and repeating a mouse-based dance routine?
|
||||
|
||||
### What is the Linux terminal?
|
||||
|
||||
The Linux terminal is a text-based interface used to control a Linux computer. It's just one of the many tools provided to Linux users for accomplishing any given task, but it's widely considered the most efficient method available. Outside of writing code, it's certainly the most direct method possible. It's so popular, in fact, that Apple changed its foundation to Unix and has gained the [Bash and Z shell][2], and Microsoft developed [PowerShell][3], its very own open source command line.
|
||||
|
||||
### What is a Linux command?
|
||||
|
||||
A **command** is a special keyword you can use in a terminal to tell your computer to perform an action. Most commands are tiny little applications that get installed with the rest of your operating system. You may not realize they're on your computer because they're generally kept in relatively obscure directories like `/bin`, `/sbin`, `/usr/bin`, and `/usr/sbin`, but your terminal knows where to find them (thanks to something called the [PATH][4]). Other commands are built into your terminal. You don't have to worry about whether a command was installed or comes built-in because your terminal knows the commands either way. Better yet, on most Linux distributions, when your terminal can't find a command, it searches the internet for a package to provide that command and then offers to install and run it for you!
|
||||
|
||||
Here's a simple command:
|
||||
|
||||
|
||||
```
|
||||
`$ ls`
|
||||
```
|
||||
|
||||
The `ls` command is short for "list," and it lists the contents of your current directory. Open a terminal and try it out. Then open a file manager window (_Files_ on Linux, _Finder_ on macOS, _Windows Explorer_ on Windows) and compare. It's two different views of the same data.
|
||||
|
||||
### What is an argument in a Linux command?
|
||||
|
||||
An **argument** is any part of a command that isn't the command. For instance, to list the contents of a specific directory, you can provide the name of that directory as an argument:
|
||||
|
||||
|
||||
```
|
||||
`$ ls Documents`
|
||||
```
|
||||
|
||||
In this example, `ls` is the command and `Documents` is the argument. This would render a list of your `Documents` directory's contents.
|
||||
|
||||
### What are options in Linux?
|
||||
|
||||
Command **options**, also called **flags** or **switches**, are part of command arguments. A command argument is anything that follows a command, and an option is usually (but not always) demarcated by a dash or double dashes. For instance:
|
||||
|
||||
|
||||
```
|
||||
`$ ls --classify Documents`
|
||||
```
|
||||
|
||||
In this example, `--classify` is an option. It also has a short version because terminal users tend to prefer the efficiency of less typing:
|
||||
|
||||
|
||||
```
|
||||
`$ ls -F Documents`
|
||||
```
|
||||
|
||||
Short options can usually be combined. Here's an `ls` command combining the `-l` option with the `--human-readable`, `--classify`, and `--ignore-backups` options:
|
||||
|
||||
|
||||
```
|
||||
`$ ls -lhFB`
|
||||
```
|
||||
|
||||
Some options can take arguments themselves. For instance, the `--format` option for `ls` lets you change how information is presented. By default, the contents of directories are provided to you in columns, but if you need them to be listed in a comma-delimited list, you can set `format` to `comma`:
|
||||
|
||||
|
||||
```
|
||||
$ ls --format=comma Documents
|
||||
alluvial, android-info.txt, arduinoIntro, dmschema,
|
||||
headers.snippet, twine, workshop.odt
|
||||
```
|
||||
|
||||
The equal sign (`=`) is optional, so this works just as well:
|
||||
|
||||
|
||||
```
|
||||
$ ls --format comma Documents
|
||||
alluvial, android-info.txt, arduinoIntro, dmschema,
|
||||
headers.snippet, twine, workshop.odt
|
||||
```
|
||||
|
||||
### Learning to use the Linux terminal
|
||||
|
||||
Learning how to use a terminal can increase efficiency and productivity—and can also make computing a lot of fun. There are few times when I run a carefully crafted command and don't sit back marveling at what I've managed to make happen with just a few words typed into an otherwise blank screen. A terminal is many things—programming, poetry, puzzle, and pragmatism—but no matter how you see it, it's a lasting innovation that's worth learning.
|
||||
|
||||
* [Use the Linux terminal to see what files are on your computer][5]
|
||||
* [How to open and close directories in the Linux terminal][6]
|
||||
* [Navigating in the Linux terminal][7]
|
||||
* [Move a file in the Linux terminal][8]
|
||||
* [Rename a file in the Linux terminal][9]
|
||||
* [Copy files and folders in the Linux terminal][10]
|
||||
* [Remove files and folders in the Linux Terminal][11]
|
||||
|
||||
|
||||
|
||||
After reading and practicing the lessons in these articles, download our free ebook, [Sysadmin's guide to Bash scripting][12] for even more fun in the terminal.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/linux-terminal
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/terminal_command_linux_desktop_code.jpg?itok=p5sQ6ODE (Terminal command prompt on orange background)
|
||||
[2]: https://opensource.com/business/16/3/top-linux-shells
|
||||
[3]: https://opensource.com/article/18/2/powershell-people
|
||||
[4]: https://opensource.com/article/17/6/set-path-linux
|
||||
[5]: https://opensource.com/article/21/7/linux-terminal-basics-see-what-files-are-your-computer
|
||||
[6]: https://opensource.com/article/21/7/linux-terminal-basics-opening-and-closing-directories
|
||||
[7]: https://opensource.com/article/21/7/terminal-basics-moving-around-your-computer
|
||||
[8]: https://opensource.com/article/21/7/terminal-basics-moving-files-linux-terminal
|
||||
[9]: https://opensource.com/article/21/7/terminal-basics-rename-file-linux-terminal
|
||||
[10]: https://opensource.com/article/21/7/terminal-basics-copying-files-linux-terminal
|
||||
[11]: https://opensource.com/article/21/7/terminal-basics-removing-files-and-folders-linux-terminal
|
||||
[12]: https://opensource.com/downloads/bash-scripting-ebook
|
||||
@@ -0,0 +1,246 @@
|
||||
[#]: subject: "Automatically create multiple applications in Argo CD"
|
||||
[#]: via: "https://opensource.com/article/21/7/automating-argo-cd"
|
||||
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Automatically create multiple applications in Argo CD
|
||||
======
|
||||
In this tutorial, I will show you how to automatically create multiple
|
||||
applications in Argo CD using Argo CD.
|
||||
![gears and lightbulb to represent innovation][1]
|
||||
|
||||
In a previous article, I demonstrated how [Argo CD makes pull-based GitOps deployments simple][2]. In this tutorial, I’ll show you how to automatically create multiple applications in Argo CD using Argo CD itself.
|
||||
|
||||
Since Argo CD’s job is to listen to a repo and apply the Manifest files it finds to the cluster, you can use this approach to configure Argo CD internals as well. In my previous example, I used the GUI to create a sample Nginx application with three replicas. This time, I use the same approach as before, but I create an application from the GUI to deploy three separate applications: `app-1`, `app-2`, and `app-3`.
|
||||
|
||||
### Configuring our child applications
|
||||
|
||||
First, start by creating the Manifest files for your three applications. In my `example-assets` [repository][3], I have [created three applications][4] under `argocd/my-apps`. All three applications are Nginx with three replicas. Be sure to create each application in its own folder.
|
||||
|
||||
Create a [YAML file][5] to define the first application and save it as `my-apps/app-1/app.yml`:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-app-1
|
||||
labels:
|
||||
app: nginx-app-1
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-app-1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-app-1
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
Create another one for your second application and save it as `my-apps/app-2/app.yml`:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-app-2
|
||||
labels:
|
||||
app: nginx-app-2
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-app-2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-app-2
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
Create a third for your final app and save it as `my-apps/app-3/app.yml`:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-app-3
|
||||
labels:
|
||||
app: nginx-app-3
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-app-3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-app-3
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
Now that your Manifest files are ready, you must create Argo CD Applications pointing to those Manifests.
|
||||
|
||||
Argo CD can be configured in three different ways: using the GUI, using the CLI, or using Kubernetes Manifest files. In this article, I use the third method.
|
||||
|
||||
Create the following Manifest files in a new folder `argocd/argo-apps`. This is `argocd-apps/app-1.yml`:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app-1
|
||||
namespace: argocd
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
destination:
|
||||
namespace: argocd
|
||||
server: <https://kubernetes.default.svc>
|
||||
project: default
|
||||
source:
|
||||
path: argocd/my-apps/app-1
|
||||
repoURL: <https://gitlab.com/ayush-sharma/example-assets.git>
|
||||
targetRevision: HEAD
|
||||
```
|
||||
|
||||
This is `argocd-apps/app-2.yml`:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app-2
|
||||
namespace: argocd
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
destination:
|
||||
namespace: argocd
|
||||
server: <https://kubernetes.default.svc>
|
||||
project: default
|
||||
source:
|
||||
path: argocd/my-apps/app-2
|
||||
repoURL: <https://gitlab.com/ayush-sharma/example-assets.git>
|
||||
targetRevision: HEAD
|
||||
```
|
||||
|
||||
And this is `argocd-apps/app-3.yml`:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app-3
|
||||
namespace: argocd
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
destination:
|
||||
namespace: argocd
|
||||
server: <https://kubernetes.default.svc>
|
||||
project: default
|
||||
source:
|
||||
path: argocd/my-apps/app-3
|
||||
repoURL: <https://gitlab.com/ayush-sharma/example-assets.git>
|
||||
targetRevision: HEAD
|
||||
```
|
||||
|
||||
As you can see, you are creating a Kubernetes object called `Application` in the `argocd` namespace. This object contains the source Git repository and destination server details. Your Applications are pointing to the Nginx manifest files you created earlier.
|
||||
|
||||
### Configuring our main application
|
||||
|
||||
Now you need some way to tell Argo CD how to find your three Nginx applications. Do this by creating yet another Application. This pattern is called the `App of Apps` pattern, where one Application contains the instructions to deploy multiple child Applications.
|
||||
|
||||
Create a new Application from the GUI called `my-apps` with the following configuration:
|
||||
|
||||
|
||||
```
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-apps
|
||||
spec:
|
||||
destination:
|
||||
namespace: default
|
||||
server: '<https://kubernetes.default.svc>'
|
||||
source:
|
||||
path: argocd/argocd-apps
|
||||
repoURL: '<https://gitlab.com/ayush-sharma/example-assets.git>'
|
||||
targetRevision: HEAD
|
||||
project: default
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
Once it has been created, `my-apps` begins syncing in the GUI:
|
||||
|
||||
![Automating ArgoCD with ArgoCD! - Main app.][6]
|
||||
|
||||
Figure 1: Automating ArgoCD with ArgoCD! - Main app.
|
||||
|
||||
After the sync is complete, your three Nginx applications appear in the GUI as well:
|
||||
|
||||
![Automating ArgoCD with ArgoCD! - Dashboard.][7]
|
||||
|
||||
Figure 2: Automating ArgoCD with ArgoCD! - Dashboard.
|
||||
|
||||
Since you didn't enable `AutoSync`, manually sync `app-1`, `app-2`, and `app-3`. Once synced, your Nginx replicas are deployed for all three apps.
|
||||
|
||||
![Automating ArgoCD with ArgoCD! - Deployment.][8]
|
||||
|
||||
Figure 3: Automating ArgoCD with ArgoCD! - Deployment.
|
||||
|
||||
### Conclusion
|
||||
|
||||
Mastering the `App of Apps` pattern is critical to leveraging the full power of Argo CD. This method allows you to manage groups of applications cleanly. For example, deploying Prometheus, Grafana, Loki, and other vital services could be managed by a DevOps Application, while deploying frontend code could be managed by a Frontend Application. Configuring different sync options and repo locations for each gives you precise control over different application groups.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/7/automating-argo-cd
|
||||
|
||||
作者:[Ayush Sharma][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/innovation_lightbulb_gears_devops_ansible.png?itok=TSbmp3_M (gears and lightbulb to represent innovation)
|
||||
[2]: https://opensource.com/article/21/8/argo-cd
|
||||
[3]: https://gitlab.com/ayush-sharma/example-assets
|
||||
[4]: https://gitlab.com/ayush-sharma/example-assets/-/tree/main/argocd/my-apps
|
||||
[5]: https://www.redhat.com/sysadmin/yaml-beginners
|
||||
[6]: https://opensource.com/sites/default/files/1automating-argocd-with-argocd-main-app_0.png
|
||||
[7]: https://opensource.com/sites/default/files/2automating-argocd-with-argocd-dashboard.png
|
||||
[8]: https://opensource.com/sites/default/files/3automating-argocd-with-argocd-deployment.png
|
||||
@@ -0,0 +1,708 @@
|
||||
[#]: 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: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Code memory safety and efficiency by example
|
||||
======
|
||||
Learn more about memory safety and efficiency
|
||||
![Code going into a computer.][1]
|
||||
|
||||
C is a high-level language with close-to-the-metal features that make it seem, at times, more like a portable assembly language than a sibling of Java or Python. Among these features is memory management, which covers an executing program's safe and efficient use of memory. This article goes into the details of memory safety and efficiency through code examples in C and a code segment from the assembly language that a modern C compiler generates.
|
||||
|
||||
Although the code examples are in C, the guidelines for safe and efficient memory management are the same for C++. The two languages differ in various details (e.g., C++ has object-oriented features and generics that C lacks), but these languages share the very same challenges with respect to memory management.
|
||||
|
||||
### Overview of memory for an executing program
|
||||
|
||||
For an executing program (aka _process_), memory is partitioned into three areas: The **stack**, the **heap**, and the **static area**. Here's an overview of each, with full code examples to follow.
|
||||
|
||||
As a backup for general-purpose CPU registers, the _stack_ provides scratchpad storage for the local variables within a code block, such as a function or a loop body. Arguments passed to a function count as local variables in this context. Consider a short example:
|
||||
|
||||
|
||||
```
|
||||
void some_func(int a, int b) {
|
||||
int n;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Storage for the arguments passed in parameters **a** and **b** and the local variable **n** would come from the stack unless the compiler could find general-purpose registers instead. The compiler favors such registers for scratchpad because CPU access to these registers is fast (one clock tick). However, these registers are few (roughly sixteen) on the standard architectures for desktop, laptop, and handheld machines.
|
||||
|
||||
At the implementation level, which only an assembly-language programmer would see, the stack is organized as a LIFO (Last In, First Out) list with **push** (insert) and **pop** (remove) operations. The **top** pointer can act as a base address for offsets; in this way, stack locations other than **top** become accessible. For example, the expression **top+16** points to a location sixteen bytes above the stack's **top**, and the expression **top-16** points to sixteen bytes below the **top**. Accordingly, stack locations that implement scratchpad storage are accessible through the **top** pointer. On a standard ARM or Intel architecture, the stack grows from high to low memory addresses; hence, to decrement **top** is to grow the stack for a process.
|
||||
|
||||
To use the stack is to use memory effortlessly and efficiently. The compiler, rather than the programmer, writes the code that manages the stack by allocating and deallocating the required scratchpad storage; the programmer declares function arguments and local variables, leaving the implementation to the compiler. Moreover, the very same stack storage can be reused across consecutive function calls and code blocks such as loops. Well-designed modular code makes stack storage the first memory option for scratchpad, with an optimizing compiler using, whenever possible, general-purpose registers instead of the stack.
|
||||
|
||||
The **heap** provides storage allocated explicitly through programmer code, although the syntax for heap allocation differs across languages. In C, a successful call to the library function **malloc** (or variants such as **calloc**) allocates a specified number of bytes. (In languages such as C++ and Java, the **new** operator serves the same purpose.) Programming languages differ dramatically on how heap-allocated storage is deallocated:
|
||||
|
||||
* In languages such as Java, Go, Lisp, and Python, the programmer does not explicitly deallocate dynamically allocated heap storage.
|
||||
|
||||
|
||||
|
||||
For example, this Java statement allocates heap storage for a string and stores the address of this heap storage in the variable **greeting**:
|
||||
|
||||
|
||||
```
|
||||
`String greeting = new String("Hello, world!");`
|
||||
```
|
||||
|
||||
Java has a garbage collector, a runtime utility that automatically deallocates heap storage that is no longer accessible to the process that allocated the storage. Java heap deallocation is thus automatic through a garbage collector. In the example above, the garbage collector would deallocate the heap storage for the string after the variable **greeting** went out of scope.
|
||||
|
||||
* The Rust compiler writes the heap-deallocation code. This is Rust's pioneering effort to automate heap-deallocation without relying on a garbage collector, which entails runtime complexity and overhead. Hats off to the Rust effort!
|
||||
* In C (and C++), heap deallocation is a programmer task. The programmer who allocates heap storage through a call to **malloc** is then responsible for deallocating this same storage with a matching call to the library function **free**. (In C++, the **new** operator allocates heap storage, whereas the **delete** and **delete[]** operators free such storage.) Here's a C example:
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
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 avoids the cost and complexity of a garbage collector, but only by burdening the programmer with the task of heap deallocation.
|
||||
|
||||
The **static area** of memory provides storage for executable code such as C functions, string literals such as "Hello, world!", and global variables:
|
||||
|
||||
|
||||
```
|
||||
int n; /* global variable */
|
||||
int main() { /* function */
|
||||
char* msg = "No comment"; /* string literal */
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
This area is static in that its size remains fixed from the start until the end of process execution. Because the static area amounts to a fixed-sized memory footprint for a process, the rule of thumb is to keep this area as small as possible by avoiding, for example, global arrays.
|
||||
|
||||
Code examples in the following sections flesh out this overview.
|
||||
|
||||
### Stack storage
|
||||
|
||||
Imagine a program that has various tasks to perform consecutively, including processing numeric data downloaded every few minutes over a network and stored in a local file. The **stack** program below simplifies the processing (odd integer values are made even) to keep the focus on the benefits of stack storage.
|
||||
|
||||
|
||||
```
|
||||
#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][2](infile, "r");
|
||||
if (NULL == infile) return;
|
||||
FILE* output = [fopen][2](outfile, "w");
|
||||
if (NULL == output) {
|
||||
[fclose][3](input);
|
||||
return;
|
||||
}
|
||||
|
||||
[fread][4](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][3](input); /* close input file */
|
||||
|
||||
[fwrite][5](nums, n, sizeof(int), output);
|
||||
[fclose][3](output);
|
||||
}
|
||||
|
||||
int main() {
|
||||
process_data(Infile, Outfile, IntCount);
|
||||
|
||||
/** now perform other tasks **/
|
||||
other_task1(); /* automatically released stack storage available */
|
||||
other_task2(); /* ditto */
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The **main** function at the bottom first calls the **process_data** function, which creates a stack-based array of a size given by argument **n** (128,000 in the current example). Accordingly, the array holds 128,000 x **sizeof(int)** bytes, which comes to 512,000 bytes on standard devices because an **int** is four bytes on these devices. Data then are read into the array (using library function **fread**), processed in a loop, and saved to the local file **outgoing.dat** (using library function **fwrite**).
|
||||
|
||||
When the **process_data** function returns to its caller **main**, the roughly 500MB of stack scratchpad for the **process_data** function become available for other functions in the **stack** program to use as scratchpad. In this example, **main** next calls the stub functions **other_task1** and **other_task2**. The three functions are called consecutively from **main**, which means that all three can use the same stack storage for scratchpad. Because the compiler rather than the programmer writes the stack-management code, this approach is both efficient and easy on the programmer.
|
||||
|
||||
In C, any variable defined inside a block (e.g., a function's or a loop's body) has an **auto** storage class by default, which means that the variable is stack-based. The storage class **register** is now outdated because C compilers are aggressive, on their own, in trying to use CPU registers whenever possible. Only a variable defined inside a block may be **register**, which the compiler changes to **auto** if no CPU register is available.Stack-based programming may be the preferred way to go, but this style does have its challenges. The **badStack** program below illustrates.
|
||||
|
||||
|
||||
```
|
||||
#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][6]("%i ", ptr[i]);
|
||||
[puts][7]("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The flow of control in the **badStack** program is straightforward. Function **main** calls function **get_array** with an argument of 128, which the called function then uses to create a local array of this size. The **get_array** function initializes the array and returns to **main** the array's identifier **arr**, which is a pointer constant that holds the address of the array's first **int** element.
|
||||
|
||||
The local array **arr** is accessible within the **get_array** function, of course, but this array cannot be legitimately accessed once **get_array** returns. Nonetheless, function **main** tries to print the stack-based array by using the stack address **arr**, which function **get_array** returns. Modern compilers warn about the mistake. For example, here's the warning from the GNU compiler:
|
||||
|
||||
|
||||
```
|
||||
badStack.c: In function 'get_array':
|
||||
badStack.c:9:10: warning: function returns address of local variable [-Wreturn-local-addr]
|
||||
8 | return arr; /** ERROR **/
|
||||
```
|
||||
|
||||
The general rule is that stack-based storage should be accessed only within the code block that contains the local variables implemented with stack storage (in this case, the array pointer **arr** and the loop counter **i**). Accordingly, a function should never return a pointer to stack-based storage.
|
||||
|
||||
### Heap storage
|
||||
|
||||
Several code examples highlight the fine points of using heap storage in C. In the first example, heap storage is allocated, used, and then freed in line with best practice. The second example nests heap storage inside other heap storage, which complicates the deallocation operation.
|
||||
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int* get_heap_array(unsigned n) {
|
||||
int* heap_nums = [malloc][8](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][9](stderr, "%s\n", "malloc(...) failed...");
|
||||
else {
|
||||
for (i = 0; i < n; i++) [printf][6]("%i\n", heap_nums[i]);
|
||||
[free][10](heap_nums); /* free the heap storage */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The **heap** program above has two functions: **main** calls **get_heap_array** with an argument (currently 100) that specifies how many **int** elements the array should have. Because the heap allocation could fail, **main** checks whether **get_heap_array** has returned **NULL**, which signals failure. If the allocation succeeds, **main** prints the **int** values in the array—and immediately thereafter deallocates, with a call to library function **free**, the heap-allocated storage. This is best practice.
|
||||
|
||||
The **get_heap_array** function opens with this statement, which merits a closer look:
|
||||
|
||||
|
||||
```
|
||||
`int* heap_nums = malloc(sizeof(int) * n); /* heap allocation */`
|
||||
```
|
||||
|
||||
The **malloc** library function and its variants deal with bytes; hence, the argument to **malloc** is the number of bytes required for **n** elements of type **int**. (The **sizeof(int)** is four bytes on a standard modern device.) The **malloc** function returns either the address of the first among the allocated bytes or, in case of failure, **NULL**.
|
||||
|
||||
In a successful call to **malloc**, the returned address is 64-bits in size on a modern desktop machine. On handhelds and earlier desktop machines, the address might be 32-bits in size or, depending on age, even smaller. The elements in the heap-allocated array are of type **int**, a four-byte signed integer. The address of these heap-allocated **int**s is stored in the local variable **heap_nums**, which is stack-based. Here's a depiction:
|
||||
|
||||
|
||||
```
|
||||
heap-based
|
||||
stack-based /
|
||||
\ +----+----+ +----+
|
||||
heap-nums--->|int1|int2|...|intN|
|
||||
+----+----+ +----+
|
||||
```
|
||||
|
||||
Once the **get_heap_array** function returns, stack storage for pointer variable **heap_nums** is reclaimed automatically—but the heap storage for the dynamic **int** array persists, which is why the **get_heap_array** function returns (a copy of) this address to **main**, which now is responsible, after printing the array's integers, for explicitly deallocating the heap storage with a call to the library function **free**:
|
||||
|
||||
|
||||
```
|
||||
`free(heap_nums); /* free the heap storage */`
|
||||
```
|
||||
|
||||
The **malloc** function does not initialize heap-allocated storage, which therefore contains random values. By contrast, the **calloc **variant initializes the allocated storage to zeros. Both functions return **NULL** to signal failure.
|
||||
|
||||
In the **heap** example, **main** returns immediately after calling **free**, and the executing program terminates, which allows the system to reclaim any allocated heap storage. Nonetheless, the programmer should develop the habit of explicitly freeing heap storage as soon as it is no longer needed.
|
||||
|
||||
### Nested heap allocation
|
||||
|
||||
The next code example is trickier. C has various library functions that return a pointer to heap storage. Here's a familiar scenario:
|
||||
|
||||
1\. The C program invokes a library function that returns a pointer to heap-based storage, typically an aggregate such as an array or a structure:
|
||||
|
||||
|
||||
```
|
||||
`SomeStructure* ptr = lib_function(); /* returns pointer to heap storage */`
|
||||
```
|
||||
|
||||
2\. The program then uses the allocated storage.
|
||||
|
||||
3\. For cleanup, the issue is whether a simple call to **free** will clean up all of the heap-allocated storage that the library function allocates. For example, the **SomeStructure** instance may have fields that, in turn, point to heap-allocated storage. A particularly troublesome case would be a dynamically allocated array of structures, each of which has a field pointing to more dynamically allocated storage.The following code example illustrates the problem and focuses on designing a library that safely provides heap-allocated storage to clients.
|
||||
|
||||
|
||||
```
|
||||
#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][8](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][8](sizeof(float) * n);
|
||||
if (NULL == heap_struct->heap_nums) { /* failure? */
|
||||
[free][10](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][10](heap_struct->heap_nums); /* first free encapsulated aggregate */
|
||||
[free][10](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][6]("%12f\n", hs->heap_nums[i]);
|
||||
|
||||
free_all(hs); /* free dynamically allocated storage */
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The **nestedHeap** example above centers on a structure **HeapStruct** with a pointer field named **heap_nums**:
|
||||
|
||||
|
||||
```
|
||||
typedef struct {
|
||||
unsigned id;
|
||||
unsigned len;
|
||||
float* heap_nums; /** pointer **/
|
||||
} HeapStruct;
|
||||
```
|
||||
|
||||
The function **get_heap_struct** tries to allocate heap storage for a **HeapStruct** instance, which entails allocating heap storage for a specified number of **float** variables to which the field **heap_nums** points. The result of a successful call to **get_heap_struct** can be depicted as follows, with **hs** as the pointer to the heap-allocated structure:
|
||||
|
||||
|
||||
```
|
||||
hs-->HeapStruct instance
|
||||
id
|
||||
len
|
||||
heap_nums-->N contiguous float elements
|
||||
```
|
||||
|
||||
In the **get_heap_struct** function, the first heap allocation is straightforward:
|
||||
|
||||
|
||||
```
|
||||
HeapStruct* heap_struct = [malloc][8](sizeof(HeapStruct));
|
||||
if (NULL == heap_struct) /* failure? */
|
||||
return NULL; /* if so, return NULL */
|
||||
```
|
||||
|
||||
The **sizeof(HeapStruct)** includes the bytes (four on a 32-bit machine, eight on a 64-bit machine) for the **heap_nums** field, which is a pointer to the **float** elements in a dynamically allocated array. At issue, then, is whether the **malloc** delivers the bytes for this structure or **NULL** to signal failure; if **NULL**, the **get_heap_struct** function returns **NULL** to notify the caller that the heap allocation failed.
|
||||
|
||||
The second attempted heap allocation is more complicated because, at this step, heap storage for the **HeapStruct** has been allocated:
|
||||
|
||||
|
||||
```
|
||||
heap_struct->heap_nums = [malloc][8](sizeof(float) * n);
|
||||
if (NULL == heap_struct->heap_nums) { /* failure? */
|
||||
[free][10](heap_struct); /* if so, first free the HeapStruct */
|
||||
return NULL; /* and then return NULL */
|
||||
}
|
||||
```
|
||||
|
||||
The argument **n** sent to the **get_heap_struct** function indicates how many **float** elements should be in the dynamically allocated **heap_nums** array. If the required **float** elements can be allocated, then the function sets the structure's **id** and **len** fields before returning the heap address of the **HeapStruct**. If the attempted allocation fails, however, two steps are necessary to meet best practice:
|
||||
|
||||
1\. The storage for the **HeapStruct** must be freed to avoid memory leakage. Without the dynamic **heap_nums** array, the **HeapStruct** is presumably of no use to the client function that calls **get_heap_struct**; hence, the bytes for the **HeapStruct** instance should be explicitly deallocated so that the system can reclaim these bytes for future heap allocations.
|
||||
|
||||
2\. **NULL** is returned to signal failure.
|
||||
|
||||
If the call to the **get_heap_struct** function succeeds, then freeing the heap storage is also tricky because it involves two **free** operations in the proper order. Accordingly, the program includes a **free_all** function instead of requiring the programmer to figure out the appropriate two-step deallocation. For review, here's the **free_all** function:
|
||||
|
||||
|
||||
```
|
||||
void free_all(HeapStruct* heap_struct) {
|
||||
if (NULL == heap_struct) /* NULL pointer? */
|
||||
return; /* if so, do nothing */
|
||||
|
||||
[free][10](heap_struct->heap_nums); /* first free encapsulated aggregate */
|
||||
[free][10](heap_struct); /* then free containing structure */
|
||||
}
|
||||
```
|
||||
|
||||
After checking that the argument **heap_struct** is not **NULL**, the function first frees the **heap_nums** array, which requires that the **heap_struct** pointer is still valid. It would be an error to release the **heap_struct** first. Once the **heap_nums** have been deallocated, the **heap_struct** can be freed as well. If **heap_struct** were freed, but **heap_nums** were not, then the **float** elements in the array would be leakage: still allocated bytes but with no possibility of access—hence, of deallocation. The leakage would persist until the **nestedHeap** program exited and the system reclaimed the leaked bytes.
|
||||
|
||||
A few cautionary notes on the **free** library function are in order. Recall the sample calls above:
|
||||
|
||||
|
||||
```
|
||||
[free][10](heap_struct->heap_nums); /* first free encapsulated aggregate */
|
||||
[free][10](heap_struct); /* then free containing structure */
|
||||
```
|
||||
|
||||
These calls free the allocated storage—but they do _not_ set their arguments to **NULL**. (The **free** function gets a copy of an address as an argument; hence, changing the copy to **NULL** would leave the original unchanged.) For example, after a successful call to **free**, the pointer **heap_struct** still holds a heap address of some heap-allocated bytes, but using this address now would be an error because the call to **free** gives the system the right to reclaim and then reuse the allocated bytes.
|
||||
|
||||
Calling **free** with a **NULL** argument is pointless but harmless. Calling **free** repeatedly on a non-**NULL** address is an error with indeterminate results:
|
||||
|
||||
|
||||
```
|
||||
[free][10](heap_struct); /* 1st call: ok */
|
||||
[free][10](heap_struct); /* 2nd call: ERROR */
|
||||
```
|
||||
|
||||
### Memory leakage and heap fragmentation
|
||||
|
||||
The phrase "memory leakage" refers to dynamically allocated heap storage that is no longer accessible. Here's a code segment for review:
|
||||
|
||||
|
||||
```
|
||||
float* nums = [malloc][8](sizeof(float) * 10); /* 10 floats */
|
||||
nums[0] = 3.14f; /* and so on */
|
||||
nums = [malloc][8](sizeof(float) * 25); /* 25 new floats */
|
||||
```
|
||||
|
||||
Assume that the first **malloc** succeeds. The second **malloc** resets the **nums** pointer, either to **NULL** (allocation failure) or to the address of the first **float** among newly allocated twenty-five. Heap storage for the initial ten **float** elements remains allocated but is now inaccessible because the **nums** pointer either points elsewhere or is **NULL**. The result is forty bytes (**sizeof(float) * 10**) of leakage.
|
||||
|
||||
Before the second call to **malloc**, the initially allocated storage should be freed:
|
||||
|
||||
|
||||
```
|
||||
float* nums = [malloc][8](sizeof(float) * 10); /* 10 floats */
|
||||
nums[0] = 3.14f; /* and so on */
|
||||
[free][10](nums); /** good **/
|
||||
nums = [malloc][8](sizeof(float) * 25); /* no leakage */
|
||||
```
|
||||
|
||||
Even without leakage, the heap can fragment over time, which then requires system defragmentation. For example, suppose that the two biggest heap chunks are currently of sizes 200MB and 100MB. However, the two chunks are not contiguous, and process **P** needs to allocate 250MB of contiguous heap storage. Before the allocation can be made, the system must _defragment_ the heap to provide 250MB contiguous bytes for **P**. Defragmentation is complicated and, therefore, time-consuming.
|
||||
|
||||
Memory leakage promotes fragmentation by creating allocated but inaccessible heap chunks. Freeing no-longer-needed heap storage is, therefore, one way that a programmer can help to reduce the need for defragmentation.
|
||||
|
||||
### Tools to diagnose memory leakage
|
||||
|
||||
Various tools are available for profiling memory efficiency and safety. My favorite is [valgrind][11]. To illustrate how the tool works for memory leaks, here's the **leaky** program:
|
||||
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int* get_ints(unsigned n) {
|
||||
int* ptr = [malloc][8](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][6]("%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;
|
||||
}
|
||||
```
|
||||
|
||||
The function **main** calls **get_ints**, which tries to **malloc** thirty-two 4-byte **int**s from the heap and then initializes the dynamic array if the **malloc** succeeds. On success, the **main** function then calls **print_ints**. There is no call to **free** to match the call to **malloc**; hence, memory leaks.
|
||||
|
||||
With the **valgrind** toolbox installed, the command below checks the **leaky** program for memory leaks (**%** is the command-line prompt):
|
||||
|
||||
|
||||
```
|
||||
`% valgrind --leak-check=full ./leaky`
|
||||
```
|
||||
|
||||
Below is most of the output. The number on the left, 207683, is the process identifier of the executing **leaky** program. The report provides details of where the leak occurs, in this case, from the call to **malloc** within the **get_ints** function that **main** calls.
|
||||
|
||||
|
||||
```
|
||||
==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
|
||||
```
|
||||
|
||||
If function **main** is revised to include a call to **free** right after the one to **print_ints**, then **valgrind** gives the **leaky** program a clean bill of health:
|
||||
|
||||
|
||||
```
|
||||
`==218462== All heap blocks were freed -- no leaks are possible`
|
||||
```
|
||||
|
||||
### Static area storage
|
||||
|
||||
In orthodox C, a function must be defined outside all blocks. This rules out having one function defined inside the body of another, a feature that some C compilers support. My examples stick with functions defined outside all blocks. Such a function is either **static** or **extern**, with **extern** as the default.
|
||||
|
||||
C functions and variables with either **static** or **extern** as their storage class reside in what I've been calling the **static area** of memory because this area has a fixed size during program execution. The syntax for these two storage classes is complicated enough to merit a review. After the review, a full code example brings the syntactic details back to life. Functions or variables defined outside all blocks default to **extern**; hence, the storage class **static** must be explicit for both functions and variables:
|
||||
|
||||
|
||||
```
|
||||
/** 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 */
|
||||
```
|
||||
|
||||
The difference between **extern** and **static** comes down to scope: an **extern** function or variable may be visible across files. By contrast, a **static** function is visible only in the file that contains the function's _definition_, and a **static** variable is visible only in the file (or a block therein) that has the variable's _definition_:
|
||||
|
||||
|
||||
```
|
||||
static int n1; /* scope is the file */
|
||||
void func() {
|
||||
static int n2; /* scope is func's body */
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
If a **static** variable such as **n1** above is defined outside all blocks, the variable's scope is the file in which the variable is defined. Wherever a **static** variable may be defined, storage for the variable is in the static area of memory.
|
||||
|
||||
An **extern** function or variable is defined outside all blocks in a given file, but the function or variable so defined then may be declared in some other file. The typical practice is to _declare_ such a function or variable in a header file, which is included wherever needed. Some short examples clarify these tricky points.
|
||||
|
||||
Suppose that the **extern** function **foo** is _defined_ in **file1.c**, with or without the keyword **extern**:
|
||||
|
||||
|
||||
```
|
||||
/** file1.c **/
|
||||
int foo(int n) { return n * 2; } /* definition has a body {...} */
|
||||
```
|
||||
|
||||
This function must be _declared_ with an explicit **extern** in any other file (or block therein) for the function to be visible. Here's the declaration that makes the **extern** function **foo** visible in file **file2.c**:
|
||||
|
||||
|
||||
```
|
||||
/** file2.c: make function foo visible here **/
|
||||
extern int foo(int); /* declaration (no body) */
|
||||
```
|
||||
|
||||
Recall that a function declaration does not have a body enclosed in curly braces, whereas a function definition does have such a body.
|
||||
|
||||
For review, header files typically contain function and variable declarations. Source-code files that require the declarations then **#include** the relevant header file(s). The **staticProg** program in the next section illustrates this approach.
|
||||
|
||||
The rules get trickier (sorry!) with **extern** variables. Any **extern** object—function or variable—must be _defined_ outside all blocks. Also, a variable defined outside all blocks defaults to **extern**:
|
||||
|
||||
|
||||
```
|
||||
/** outside all blocks **/
|
||||
int n; /* defaults to extern */
|
||||
```
|
||||
|
||||
However, the **extern** can be explicit in the variable's _definition_ only if the variable is initialized explicitly there:
|
||||
|
||||
|
||||
```
|
||||
/** 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 */
|
||||
```
|
||||
|
||||
For a variable defined as **extern** in **file1.c** to be visible in another file such as **file2.c**, the variable must be _declared_ as explicitly **extern** in **file2.c** and not initialized, which would turn the declaration into a definition:
|
||||
|
||||
|
||||
```
|
||||
/** file2.c **/
|
||||
extern int n1; /* declaration of n1 defined in file1.c */
|
||||
```
|
||||
|
||||
To avoid confusion with **extern** variables, the rule of thumb is to use **extern** explicitly in a _declaration_ (required) but not in a _definition_ (optional and tricky). For functions, the **extern** is optional in a definition but needed for a declaration. The **staticProg** example in the next section brings these points together in a full program.
|
||||
|
||||
### The staticProg example
|
||||
|
||||
The **staticProg** program consists of three files: two C source files (**static1.c** and **static2.c**) together with a header file (**static.h**) that contains two declarations:
|
||||
|
||||
|
||||
```
|
||||
/** header file static.h **/
|
||||
#define NumCount 100 /* macro */
|
||||
extern int global_nums[NumCount]; /* array declaration */
|
||||
extern void fill_array(); /* function declaration */
|
||||
```
|
||||
|
||||
The **extern** in the two declarations, one for an array and the other for a function, underscores that the objects are _defined_ elsewhere ("externally"): the array **global_nums** is defined in file **static1.c** (without an explicit **extern**) and the function **fill_array** is defined in file **static2.c** (also without an explicit **extern**). Each source file includes the header file **static.h**.The **static1.c** file defines the two arrays that reside in the static area of memory, **global_nums** and **more_nums**. The second array has a **static** storage class, which restricts its scope to the file (**static1.c**) in which the array is defined. As noted, **global_nums** as **extern** can be made visible in multiple files.
|
||||
|
||||
|
||||
```
|
||||
/** 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][6]("%4i\t%4i\n", global_nums[i], more_nums[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The **static2.c** file below defines the **fill_array** function, which **main** (in the **static1.c** file) invokes; the **fill_array** function populates the **extern** array named **global_nums**, which is defined in file **static1.c**. The sole point of having two files is to underscore that an **extern** variable or function can be visible across files.
|
||||
|
||||
|
||||
```
|
||||
/** static2.c **/
|
||||
#include "static.h" /** declarations **/
|
||||
|
||||
void fill_array() { /** definition **/
|
||||
unsigned i;
|
||||
for (i = 0; i < NumCount; i++) global_nums[i] = i + 2;
|
||||
}
|
||||
```
|
||||
|
||||
The **staticProg** program can be compiled as follows:
|
||||
|
||||
|
||||
```
|
||||
`% gcc -o staticProg static1.c static2.c`
|
||||
```
|
||||
|
||||
### More details from assembly language
|
||||
|
||||
A modern C compiler can handle any mix of C and assembly language. When compiling a C source file, the compiler first translates the C code into assembly language. Here's the command to save the assembly language generated from the **static1.c** file above:
|
||||
|
||||
|
||||
```
|
||||
`% gcc -S static1.c`
|
||||
```
|
||||
|
||||
The resulting file is **static1.s**. Here's a segment from the top, with added line numbers for readability:
|
||||
|
||||
|
||||
```
|
||||
.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
|
||||
...
|
||||
```
|
||||
|
||||
The assembly-language directives such as **.file** (line 1) begin with a period. As the name suggests, a directive guides the assembler as it translates assembly language into machine code. The **.rodata** directive (line 6) indicates that read-only objects follow, including the string constant **"%4i\t%4i\n"** (line 8), which function **main** (line 12) uses to format output. The function **main** (line 12), introduced as a label (the colon at the end makes it so), is likewise read-only.
|
||||
|
||||
In assembly language, labels are addresses. The label **main:** (line 12) marks the address at which the code for the **main** function begins, and the label **.LC0**: (line 7) marks the address at which the format string begins.
|
||||
|
||||
The definitions of the **global_nums** (line 3) and **more_nums** (line 4) arrays include two numbers: 400 is the total number of bytes in each array, and 32 is the number of bits in each of the 100 **int** elements per array. (The **.comm** directive in line 5 stands for **common name**, which can be ignored.)
|
||||
|
||||
The array definitions differ in that **more_nums** is marked as **.local** (line 4), which means that its scope is restricted to the containing file **static1.s**. By contrast, the **global_nums** array can be made visible across multiple files, including the translations of the **static1.c** and **static2.c** files.
|
||||
|
||||
Finally, the **.text** directive occurs twice (lines 2 and 9) in the assembly code segment. The term "text" suggests "read-only" but also covers read/write variables such as the elements in the two arrays. Although the assembly language shown is for an Intel architecture, Arm6 assembly would be quite similar. For both architectures, variables in the **.text** area (in this case, elements in the two arrays) are initialized automatically to zeros.
|
||||
|
||||
### Wrapping up
|
||||
|
||||
For memory-efficient and memory-safe programming in C, the guidelines are easy to state but may be hard to follow, especially when calls to poorly designed libraries are in play. The guidelines are:
|
||||
|
||||
* Use stack storage whenever possible, thereby encouraging the compiler to optimize with general-purpose registers for scratchpad. Stack storage represents efficient memory use and promotes clean, modular code. Never return a pointer to stack-based storage.
|
||||
* Use heap storage carefully. The challenge in C (and C++) is to ensure that dynamically allocated storage is deallocated ASAP. Good programming habits and tools (such as **valgrind**) help to meet the challenge. Favor libraries that provide their own deallocation function(s), such as the **free_all** function in the **nestedHeap** code example.
|
||||
* Use static storage judiciously, as this storage impacts the memory footprint of a process from start to finish. In particular, try to avoid **extern** and **static** arrays.
|
||||
|
||||
|
||||
|
||||
The C code examples are available at my website (<https://condor.depaul.edu/mkalin>).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/memory-programming-c
|
||||
|
||||
作者:[Marty Kalin][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/
|
||||
@@ -0,0 +1,304 @@
|
||||
[#]: subject: "Use dnf updateinfo to read update changelogs"
|
||||
[#]: via: "https://fedoramagazine.org/use-dnf-updateinfo-to-read-update-changelogs/"
|
||||
[#]: author: "Mateus Rodrigues Costa https://fedoramagazine.org/author/mateusrodcosta/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Use dnf updateinfo to read update changelogs
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Cover image background excerpted from photo by [Fotis Fotopoulos][2] on [Unsplash][3]
|
||||
|
||||
This article will explore how to check the changelogs for the Fedora Linux operating system using the command line and _dnf updateinfo_. Instead of showing the commands running on a real Fedora Linux install, this article will demo running the dnf commands in [toolbox][4].
|
||||
|
||||
### Introduction
|
||||
|
||||
If you have used any type of computer recently (be it a desktop, laptop or even a smartphone), you most likely have had to deal with software updates. You might have an opinion about them. They might be a “necessary evil”, something that always breaks your setup and makes you waste hours fixing the new problems that appeared, or you might even like them.
|
||||
|
||||
No matter your opinion, there are reasons to update your software: mainly bug fixes, especially security-related bug fixes. After all, you most likely don’t want someone getting your private data by exploiting a bug that happens because of a interaction between the code of your web browser and the code that renders text on your screen.
|
||||
|
||||
If you manage your software updates in a manual or semi-manual fashion (in comparison to letting the operating system auto-update your software), one feature you should be aware of is “changelogs”.
|
||||
|
||||
A changelog is, as the name hints, a big list of changes between two releases of the same software. The changelog content can vary a lot. It may depend on the team, the type of software, its importance, and the number of changes. It can range from a very simple “several small bugs were fixed in this release”-type message, to a list of links to the bugs fixed on a issue tracker with a small description, to a big and detailed list of changes or elaborate blog posts.
|
||||
|
||||
Now, how do you check the changelogs for the updates?
|
||||
|
||||
If you use Fedora Workstation the easy way to see the changelog with a GUI is with Gnome Software. Select the name of the package or name of the software on the updates page and the changelog is displayed. You could also try your favorite GUI package manager, which will most likely show it to you as well. But how does one do the same thing via CLI?
|
||||
|
||||
### How to use dnf updateinfo
|
||||
|
||||
Start by creating a Fedora 34 toolbox called _updateinfo-demo_:
|
||||
|
||||
```
|
||||
toolbox create --distro fedora --release f34 updateinfo-demo
|
||||
```
|
||||
|
||||
Now, enter the toolbox:
|
||||
|
||||
```
|
||||
toolbox enter updateinfo-demo
|
||||
```
|
||||
|
||||
The commands from here on can also be used on a normal Fedora install.
|
||||
|
||||
First, check the updates available:
|
||||
|
||||
```
|
||||
$ dnf check-update
|
||||
audit-libs.x86_64 3.0.3-1.fc34 updates
|
||||
ca-certificates.noarch 2021.2.50-1.0.fc34 updates
|
||||
coreutils.x86_64 8.32-30.fc34 updates
|
||||
coreutils-common.x86_64 8.32-30.fc34 updates
|
||||
curl.x86_64 7.76.1-7.fc34 updates
|
||||
dnf.noarch 4.8.0-1.fc34 updates
|
||||
dnf-data.noarch 4.8.0-1.fc34 updates
|
||||
expat.x86_64 2.4.1-1.fc34 updates
|
||||
file-libs.x86_64 5.39-6.fc34 updates
|
||||
glibc.x86_64 2.33-20.fc34 updates
|
||||
glibc-common.x86_64 2.33-20.fc34 updates
|
||||
glibc-minimal-langpack.x86_64 2.33-20.fc34 updates
|
||||
krb5-libs.x86_64 1.19.1-14.fc34 updates
|
||||
libcomps.x86_64 0.1.17-1.fc34 updates
|
||||
libcurl.x86_64 7.76.1-7.fc34 updates
|
||||
libdnf.x86_64 0.63.1-1.fc34 updates
|
||||
libeconf.x86_64 0.4.0-1.fc34 updates
|
||||
libedit.x86_64 3.1-38.20210714cvs.fc34 updates
|
||||
libgcrypt.x86_64 1.9.3-3.fc34 updates
|
||||
libidn2.x86_64 2.3.2-1.fc34 updates
|
||||
libmodulemd.x86_64 2.13.0-1.fc34 updates
|
||||
librepo.x86_64 1.14.1-1.fc34 updates
|
||||
libsss_idmap.x86_64 2.5.2-1.fc34 updates
|
||||
libsss_nss_idmap.x86_64 2.5.2-1.fc34 updates
|
||||
libuser.x86_64 0.63-4.fc34 updates
|
||||
libxcrypt.x86_64 4.4.23-1.fc34 updates
|
||||
nano.x86_64 5.8-3.fc34 updates
|
||||
nano-default-editor.noarch 5.8-3.fc34 updates
|
||||
nettle.x86_64 3.7.3-1.fc34 updates
|
||||
openldap.x86_64 2.4.57-5.fc34 updates
|
||||
pam.x86_64 1.5.1-6.fc34 updates
|
||||
python-setuptools-wheel.noarch 53.0.0-2.fc34 updates
|
||||
python-unversioned-command.noarch 3.9.6-2.fc34 updates
|
||||
python3.x86_64 3.9.6-2.fc34 updates
|
||||
python3-dnf.noarch 4.8.0-1.fc34 updates
|
||||
python3-hawkey.x86_64 0.63.1-1.fc34 updates
|
||||
python3-libcomps.x86_64 0.1.17-1.fc34 updates
|
||||
python3-libdnf.x86_64 0.63.1-1.fc34 updates
|
||||
python3-libs.x86_64 3.9.6-2.fc34 updates
|
||||
python3-setuptools.noarch 53.0.0-2.fc34 updates
|
||||
sssd-client.x86_64 2.5.2-1.fc34 updates
|
||||
systemd.x86_64 248.6-1.fc34 updates
|
||||
systemd-libs.x86_64 248.6-1.fc34 updates
|
||||
systemd-networkd.x86_64 248.6-1.fc34 updates
|
||||
systemd-pam.x86_64 248.6-1.fc34 updates
|
||||
systemd-rpm-macros.noarch 248.6-1.fc34 updates
|
||||
vim-minimal.x86_64 2:8.2.3182-1.fc34 updates
|
||||
xkeyboard-config.noarch 2.33-1.fc34 updates
|
||||
yum.noarch 4.8.0-1.fc34 updates
|
||||
```
|
||||
|
||||
OK, so run your first _dnf updateinfo_ command:
|
||||
|
||||
```
|
||||
$ dnf updateinfo
|
||||
Updates Information Summary: available
|
||||
5 Security notice(s)
|
||||
4 Moderate Security notice(s)
|
||||
1 Low Security notice(s)
|
||||
11 Bugfix notice(s)
|
||||
8 Enhancement notice(s)
|
||||
3 other notice(s)
|
||||
```
|
||||
|
||||
This is the summary of updates. As you can see there are security updates, bugfix updates, enhancement updates and some which are not specified.
|
||||
|
||||
Look at the list of updates and which types they belong to:
|
||||
|
||||
```
|
||||
$ dnf updateinfo list
|
||||
FEDORA-2021-e4866762d8 enhancement audit-libs-3.0.3-1.fc34.x86_64
|
||||
FEDORA-2021-1f32e18471 bugfix ca-certificates-2021.2.50-1.0.fc34.noarch
|
||||
FEDORA-2021-b09e010a46 bugfix coreutils-8.32-30.fc34.x86_64
|
||||
FEDORA-2021-b09e010a46 bugfix coreutils-common-8.32-30.fc34.x86_64
|
||||
FEDORA-2021-83fdddca0f Moderate/Sec. curl-7.76.1-7.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix dnf-4.8.0-1.fc34.noarch
|
||||
FEDORA-2021-3b74285c43 bugfix dnf-data-4.8.0-1.fc34.noarch
|
||||
FEDORA-2021-523ee0a81e enhancement expat-2.4.1-1.fc34.x86_64
|
||||
FEDORA-2021-07625b9c81 unknown file-libs-5.39-6.fc34.x86_64
|
||||
FEDORA-2021-e14e86e40e Moderate/Sec. glibc-2.33-20.fc34.x86_64
|
||||
FEDORA-2021-e14e86e40e Moderate/Sec. glibc-common-2.33-20.fc34.x86_64
|
||||
FEDORA-2021-e14e86e40e Moderate/Sec. glibc-minimal-langpack-2.33-20.fc34.x86_64
|
||||
FEDORA-2021-8b25e4642f Low/Sec. krb5-libs-1.19.1-14.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix libcomps-0.1.17-1.fc34.x86_64
|
||||
FEDORA-2021-83fdddca0f Moderate/Sec. libcurl-7.76.1-7.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix libdnf-0.63.1-1.fc34.x86_64
|
||||
FEDORA-2021-ca22b882a5 enhancement libeconf-0.4.0-1.fc34.x86_64
|
||||
FEDORA-2021-f9c139edd8 bugfix libedit-3.1-38.20210714cvs.fc34.x86_64
|
||||
FEDORA-2021-31fdc84207 Moderate/Sec. libgcrypt-1.9.3-3.fc34.x86_64
|
||||
FEDORA-2021-bc56cf7c1f enhancement libidn2-2.3.2-1.fc34.x86_64
|
||||
FEDORA-2021-da2ec14d7f bugfix libmodulemd-2.13.0-1.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix librepo-1.14.1-1.fc34.x86_64
|
||||
FEDORA-2021-1db6330a22 unknown libsss_idmap-2.5.2-1.fc34.x86_64
|
||||
FEDORA-2021-1db6330a22 unknown libsss_nss_idmap-2.5.2-1.fc34.x86_64
|
||||
FEDORA-2021-8226c82fe9 bugfix libuser-0.63-4.fc34.x86_64
|
||||
FEDORA-2021-e6916d6758 bugfix libxcrypt-4.4.22-2.fc34.x86_64
|
||||
FEDORA-2021-fed4036fd9 bugfix libxcrypt-4.4.23-1.fc34.x86_64
|
||||
FEDORA-2021-3122d2b8d2 unknown nano-5.8-3.fc34.x86_64
|
||||
FEDORA-2021-3122d2b8d2 unknown nano-default-editor-5.8-3.fc34.noarch
|
||||
FEDORA-2021-d1fc0b9d32 Moderate/Sec. nettle-3.7.3-1.fc34.x86_64
|
||||
FEDORA-2021-97949d7a4e bugfix openldap-2.4.57-5.fc34.x86_64
|
||||
FEDORA-2021-e6916d6758 bugfix pam-1.5.1-6.fc34.x86_64
|
||||
FEDORA-2021-07931f7f08 bugfix python-setuptools-wheel-53.0.0-2.fc34.noarch
|
||||
FEDORA-2021-2056ce89d9 enhancement python-unversioned-command-3.9.6-1.fc34.noarch
|
||||
FEDORA-2021-d613e00b72 enhancement python-unversioned-command-3.9.6-2.fc34.noarch
|
||||
FEDORA-2021-2056ce89d9 enhancement python3-3.9.6-1.fc34.x86_64
|
||||
FEDORA-2021-d613e00b72 enhancement python3-3.9.6-2.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix python3-dnf-4.8.0-1.fc34.noarch
|
||||
FEDORA-2021-3b74285c43 bugfix python3-hawkey-0.63.1-1.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix python3-libcomps-0.1.17-1.fc34.x86_64
|
||||
FEDORA-2021-3b74285c43 bugfix python3-libdnf-0.63.1-1.fc34.x86_64
|
||||
FEDORA-2021-2056ce89d9 enhancement python3-libs-3.9.6-1.fc34.x86_64
|
||||
FEDORA-2021-d613e00b72 enhancement python3-libs-3.9.6-2.fc34.x86_64
|
||||
FEDORA-2021-07931f7f08 bugfix python3-setuptools-53.0.0-2.fc34.noarch
|
||||
FEDORA-2021-1db6330a22 unknown sssd-client-2.5.2-1.fc34.x86_64
|
||||
FEDORA-2021-3141f0eff1 bugfix systemd-248.6-1.fc34.x86_64
|
||||
FEDORA-2021-3141f0eff1 bugfix systemd-libs-248.6-1.fc34.x86_64
|
||||
FEDORA-2021-3141f0eff1 bugfix systemd-networkd-248.6-1.fc34.x86_64
|
||||
FEDORA-2021-3141f0eff1 bugfix systemd-pam-248.6-1.fc34.x86_64
|
||||
FEDORA-2021-3141f0eff1 bugfix systemd-rpm-macros-248.6-1.fc34.noarch
|
||||
FEDORA-2021-b8b1f6e54f enhancement vim-minimal-2:8.2.3182-1.fc34.x86_64
|
||||
FEDORA-2021-67645ae09f enhancement xkeyboard-config-2.33-1.fc34.noarch
|
||||
FEDORA-2021-3b74285c43 bugfix yum-4.8.0-1.fc34.noarch
|
||||
```
|
||||
|
||||
The output is in three columns. These show the ID for an update, the type of the update, and the package to which it refers.
|
||||
|
||||
If you want to see the Bodhi page for a specific update, just add the id to the end of this URL:
|
||||
<https://bodhi.fedoraproject.org/updates/>.
|
||||
|
||||
For example, <https://bodhi.fedoraproject.org/updates/FEDORA-2021-3141f0eff1> for _systemd-248.6-1.fc34.x86_64_ or <https://bodhi.fedoraproject.org/updates/FEDORA-2021-b09e010a46> for _coreutils-8.32-30.fc34.x86_64_.
|
||||
|
||||
The next command will list the actual changelog.
|
||||
|
||||
```
|
||||
dnf updateinfo info
|
||||
```
|
||||
|
||||
The output from this command is quite long. So only a few interesting excerpts are provided below.
|
||||
|
||||
Start with a small one:
|
||||
|
||||
```
|
||||
===============================================================================
|
||||
ca-certificates-2021.2.50-1.0.fc34
|
||||
===============================================================================
|
||||
Update ID: FEDORA-2021-1f32e18471
|
||||
Type: bugfix
|
||||
Updated: 2021-06-18 22:08:02
|
||||
Description: Update the ca-certificates list to the lastest upstream list.
|
||||
Severity: Low
|
||||
```
|
||||
|
||||
Notice how this info has the update ID, type, updated time, description and severity. Very simple and easy to understand.
|
||||
|
||||
Now look at the _systemd_ update which, in addition to the previous items, has some bugs associated with it in Red Hat Bugzilla, a more elaborate description, and a different severity.
|
||||
|
||||
```
|
||||
===============================================================================
|
||||
systemd-248.6-1.fc34
|
||||
===============================================================================
|
||||
Update ID: FEDORA-2021-3141f0eff1
|
||||
Type: bugfix
|
||||
Updated: 2021-07-24 22:00:30
|
||||
Bugs: 1963428 - if keyfile >= 1024*4096-1 service "systemd-cryptsetup@<partition name>" can't start
|
||||
: 1965815 - 50-udev-default.rules references group "sgx" which does not exist
|
||||
: 1975564 - systemd-cryptenroll SIGABRT when adding recovery key - buffer overflow
|
||||
: 1984651 - systemd[1]: Assertion 'a <= b' failed at src/libsystemd/sd-event/sd-event.c:2903, function sleep_between(). Aborting.
|
||||
Description: - Create 'sgx' group (and also use soft-static uids for input and render, see https://pagure.io/setup/c/df3194a7295c2ca3cfa923981b046f4bd2754825 and https://pagure.io/packaging-committee/issue/1078 (#1965815)
|
||||
: - Various bugfixes (#1963428, #1975564)
|
||||
: - Fix for a regression introduced in the previous release with sd-event abort (#1984651)
|
||||
:
|
||||
: No need to log out or reboot.
|
||||
Severity: Moderate
|
||||
```
|
||||
|
||||
Next look at a _curl_ update. This has a security update with several [CVE][5]s associated with it. Each CVE has its respective Red Hat Bugzilla bug.
|
||||
|
||||
```
|
||||
===============================================================================
|
||||
curl-7.76.1-7.fc34
|
||||
===============================================================================
|
||||
Update ID: FEDORA-2021-83fdddca0f
|
||||
Type: security
|
||||
Updated: 2021-07-22 22:03:07
|
||||
Bugs: 1984325 - CVE-2021-22922 curl: wrong content via metalink is not being discarded [fedora-all]
|
||||
: 1984326 - CVE-2021-22923 curl: Metalink download sends credentials [fedora-all]
|
||||
: 1984327 - CVE-2021-22924 curl: bad connection reuse due to flawed path name checks [fedora-all]
|
||||
: 1984328 - CVE-2021-22925 curl: Incorrect fix for CVE-2021-22898 TELNET stack contents disclosure [fedora-all]
|
||||
Description: - fix TELNET stack contents disclosure again (CVE-2021-22925)
|
||||
: - fix bad connection reuse due to flawed path name checks (CVE-2021-22924)
|
||||
: - disable metalink support to fix the following vulnerabilities
|
||||
: CVE-2021-22923 - metalink download sends credentials
|
||||
: CVE-2021-22922 - wrong content via metalink not discarded
|
||||
Severity: Moderate
|
||||
```
|
||||
|
||||
This item shows a simple enhancement update.
|
||||
|
||||
```
|
||||
===============================================================================
|
||||
python3-docs-3.9.6-1.fc34 python3.9-3.9.6-1.fc34
|
||||
===============================================================================
|
||||
Update ID: FEDORA-2021-2056ce89d9
|
||||
Type: enhancement
|
||||
Updated: 2021-07-08 22:00:53
|
||||
Description: Update of Python 3.9 and python3-docs to latest release 3.9.6
|
||||
Severity: None
|
||||
```
|
||||
|
||||
Finally an “unknown” type update.
|
||||
|
||||
```
|
||||
===============================================================================
|
||||
file-5.39-6.fc34
|
||||
===============================================================================
|
||||
Update ID: FEDORA-2021-07625b9c81
|
||||
Type: unknown
|
||||
Updated: 2021-06-11 22:16:57
|
||||
Bugs: 1963895 - Wrong detection of python bytecode mimetypes
|
||||
Description: do not classify python bytecode files as text (#1963895)
|
||||
Severity: None
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
So, in what situation does dnf updateinfo become handy?
|
||||
|
||||
Well, you could use it if you prefer managing updates fully via the CLI, or if you are unable to successfully use the GUI tools at a specific moment.
|
||||
|
||||
In which case is checking the changelog useful?
|
||||
|
||||
Say you manage the updates yourself, sometimes you might not consider it ideal to stop what you are doing to update your system. Instead of simply installing the updates, you check the changelogs. This allows you to figure out whether you should prioritize your updates (maybe there’s a important security fix?) or whether to postpone a bit longer (no important fix, “I will do it later when I’m not doing anything important”).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/use-dnf-updateinfo-to-read-update-changelogs/
|
||||
|
||||
作者:[Mateus Rodrigues Costa][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/mateusrodcosta/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2021/08/dnf-updateinfo-816x345.jpg
|
||||
[2]: https://unsplash.com/@ffstop?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://fedoramagazine.org/a-quick-introduction-to-toolbox-on-fedora/
|
||||
[5]: https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures
|
||||
@@ -0,0 +1,168 @@
|
||||
[#]: subject: "Parse command-line arguments with argparse in Python"
|
||||
[#]: via: "https://opensource.com/article/21/8/python-argparse"
|
||||
[#]: author: "Moshe Zadka https://opensource.com/users/moshez"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: " "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Parse command-line arguments with argparse in Python
|
||||
======
|
||||
Use the argparse module to enable options in your Python applications.
|
||||
![Python options][1]
|
||||
|
||||
There are several third-party libraries for command-line argument parsing, but the standard library module `argparse` is no slouch either.
|
||||
|
||||
Without adding any more dependencies, you can write a nifty command-line tool with useful argument parsing.
|
||||
|
||||
### Argument parsing in Python
|
||||
|
||||
When parsing command-line arguments with `argparse`, the first step is to configure an `ArgumentParser` object. This is often done at the global module scope since merely _configuring_ the parser has no side effects.
|
||||
|
||||
|
||||
```
|
||||
import argparse
|
||||
|
||||
PARSER = argparse.ArgumentParser()
|
||||
```
|
||||
|
||||
The most important method on `ArgumentParser` is `.add_argument()`. It has a few variants. By default, it adds an argument that expects a value.
|
||||
|
||||
|
||||
```
|
||||
`PARSER.add_argument("--value")`
|
||||
```
|
||||
|
||||
To see it in action, call the method `.parse_args()`:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.parse_args(["--value", "some-value"])`[/code] [code]`Namespace(value='some-value')`
|
||||
```
|
||||
|
||||
It's also possible to use the syntax with `=`:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.parse_args(["--value=some-value"])`[/code] [code]`Namespace(value='some-value')`
|
||||
```
|
||||
|
||||
You can also specify a short "alias" for a shorter command line when typed into the prompt:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.add_argument("--thing", "-t")`
|
||||
```
|
||||
|
||||
It's possible to pass either the short option:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.parse_args("-t some-thing".split())`[/code] [code]`Namespace(value=None, thing='some-thing')`
|
||||
```
|
||||
|
||||
or the long one:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.parse_args("--thing some-thing".split())`[/code] [code]`Namespace(value=None, thing='some-thing')`
|
||||
```
|
||||
|
||||
### Types
|
||||
|
||||
There are more types of arguments available. The two most popular ones, after the default, are boolean and counting. The booleans come with a variant that defaults to true, and one that defaults to false.
|
||||
|
||||
|
||||
```
|
||||
PARSER.add_argument("--active", action="store_true")
|
||||
PARSER.add_argument("--no-dry-run", action="store_false", dest="dry_run")
|
||||
PARSER.add_argument("--verbose", "-v", action="count")
|
||||
```
|
||||
|
||||
This means that `active` is `False` unless `--active` is passed, and `dry_run` is `True` unless `--no-dry-run` is passed. Short options without value can be juxtaposed.
|
||||
|
||||
Passing all the arguments results in a non-default state:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.parse_args("--active --no-dry-run -vvvv".split())`[/code] [code]`Namespace(value=None, thing=None, active=True, dry_run=False, verbose=4)`
|
||||
```
|
||||
|
||||
The default is somewhat less exciting:
|
||||
|
||||
|
||||
```
|
||||
`PARSER.parse_args("".split())`[/code] [code]`Namespace(value=None, thing=None, active=False, dry_run=True, verbose=None)`
|
||||
```
|
||||
|
||||
### Subcommands
|
||||
|
||||
Though classic Unix commands "did one thing, and did it well," the modern tendency is to do "several closely related actions."
|
||||
|
||||
The examples of `git`, `podman`, and `kubectl` can show how popular the paradigm is. The `argparse` library supports that too:
|
||||
|
||||
|
||||
```
|
||||
MULTI_PARSER = argparse.ArgumentParser()
|
||||
subparsers = MULTI_PARSER.add_subparsers()
|
||||
get = subparsers.add_parser("get")
|
||||
get.add_argument("--name")
|
||||
get.set_defaults(command="get")
|
||||
search = subparsers.add_parser("search")
|
||||
search.add_argument("--query")
|
||||
search.set_defaults(command="search")
|
||||
|
||||
[/code] [code]`MULTI_PARSER.parse_args("get --name awesome-name".split())`[/code] [code]`Namespace(name='awesome-name', command='get')`[/code] [code]`MULTI_PARSER.parse_args("search --query name~awesome".split())`[/code] [code]`Namespace(query='name~awesome', command='search')`
|
||||
```
|
||||
|
||||
### Anatomy of a program
|
||||
|
||||
One way to use `argparse` is to structure the program as follows:
|
||||
|
||||
|
||||
```
|
||||
## my_package/__main__.py
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from my_package import toplevel
|
||||
|
||||
parsed_arguments = toplevel.PARSER.parse_args(sys.argv[1:])
|
||||
toplevel.main(parsed_arguments)
|
||||
|
||||
[/code] [code]
|
||||
|
||||
## my_package/toplevel.py
|
||||
|
||||
PARSER = argparse.ArgumentParser()
|
||||
## .add_argument, etc.
|
||||
|
||||
def main(parsed_args):
|
||||
|
||||
...
|
||||
|
||||
# do stuff with parsed_args
|
||||
```
|
||||
|
||||
In this case, running the command is done with `python -m my_package`. Alternatively, you can use the [`console_scripts`][2] entry points in the package's setup.
|
||||
|
||||
### Summary
|
||||
|
||||
The `argparse` module is a powerful command-line argument parser. There are many more features that have not been covered here. The limit is your imagination.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/python-argparse
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/bitmap_0.png?itok=PBXU-cn0 (Python options)
|
||||
[2]: https://python-packaging.readthedocs.io/en/latest/command-line-scripts.html#the-console-scripts-entry-point
|
||||
72
sources/tech/20210817 4 alternatives to cron in Linux.md
Normal file
72
sources/tech/20210817 4 alternatives to cron in Linux.md
Normal file
@@ -0,0 +1,72 @@
|
||||
[#]: subject: "4 alternatives to cron in Linux"
|
||||
[#]: via: "https://opensource.com/article/21/7/alternatives-cron-linux"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "unigeorge"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
4 alternatives to cron in Linux
|
||||
======
|
||||
There are a few other open source projects out there that can be used
|
||||
either in conjunction with cron or instead of cron.
|
||||
![Alarm clocks with different time][1]
|
||||
|
||||
The [Linux `cron` system][2] is a time-tested and proven technology. However, it's not always the right tool for system automation. There are a few other open source projects out there that can be used either in conjunction with `cron` or instead of `cron`.
|
||||
|
||||
### Linux at command
|
||||
|
||||
`Cron` is intended for long-term repetition. You schedule a job, and it runs at a regular interval from now until the computer is decommissioned. Sometimes you just want to schedule a one-off command to run at a time you happen not to be at your computer. For that, you can use the `at` command.
|
||||
|
||||
The syntax of `at` is far simpler and more flexible than the `cron` syntax, and it has both an interactive and non-interactive method for scheduling (so you could use `at` to create an `at` job if you really wanted to.)
|
||||
|
||||
|
||||
```
|
||||
`$ echo "rsync -av /home/tux/ me@myserver:/home/tux/" | at 1:30 AM`
|
||||
```
|
||||
|
||||
It feels natural, it's easy to use, and you don't have to clean up old jobs because they're entirely forgotten once they've been run.
|
||||
|
||||
Read more about the [at command][3] to get started.
|
||||
|
||||
### Systemd
|
||||
|
||||
In addition to managing processes on your computer, `systemd` can also help you schedule them. Like traditional `cron` jobs, `systemd` timers can trigger events, such as shell scripts and commands, at specified time intervals. This can be once a day on a specific day of the month (and then, perhaps only if it's a Monday, for example), or every 15 minutes during business hours from 09:00 to 17:00.
|
||||
|
||||
Timers can also do some things that `cron` jobs can't.
|
||||
|
||||
For example, a timer can trigger a script or program to run a specific amount of time _after_ an event, such as boot, startup, completion of a previous task, or even the prior completion of the service unit called by the timer itself!
|
||||
|
||||
If your system runs `systemd`, then you're technically using `systemd` timers already. Default timers perform menial tasks like rotating log files, updating the mlocate database, manage the DNF database, and so on. Creating your own is easy, as demonstrated by David Both in his article [Use systemd timers instead of cronjobs][4].
|
||||
|
||||
### Anacron
|
||||
|
||||
`Cron` specializes in running a command at a specific time. This works well for a server that's never hibernating or powered down. Still, it's pretty common for laptops and desktop workstations to either intentionally or absent-mindedly turn the computer off from time to time. When the computer's not on, `cron` doesn't run, so important jobs (such as backing up data) get skipped.
|
||||
|
||||
The `anacron` system is designed to ensure that jobs are run periodically rather than on a schedule. This means you can leave a computer off for several days and still count on `anacron` to run essential tasks when you boot it up again. `Anacron` works in tandem with `cron`, so it's not strictly an alternative to it, but it's a meaningful alternative way of scheduling tasks. Many a sysadmin has configured a `cron` job to backup data late at night on a remote worker's computer, only to discover that the job's only been run once in the past six months. `Anacron` ensures that important jobs happen _sometime_ when they can rather than _never_ when they were scheduled.
|
||||
|
||||
Read more about [using anacron for a better crontab][5].
|
||||
|
||||
### Automation
|
||||
|
||||
Computers and technology are meant to make lives better and work easier. Linux provides its users with lots of helpful features to ensure important operating system tasks get done. Take a look at what's available, and start using these features for your own tasks.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/7/alternatives-cron-linux
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[unigeorge](https://github.com/unigeorge)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/clocks_time.png?itok=_ID09GDk (Alarm clocks with different time)
|
||||
[2]: https://opensource.com/article/21/7/cron-linux
|
||||
[3]: https://opensource.com/article/21/7/intro-command
|
||||
[4]: https://opensource.com/article/20/7/systemd-timers
|
||||
[5]: https://opensource.com/article/21/2/linux-automation
|
||||
@@ -0,0 +1,87 @@
|
||||
[#]: subject: "Automatically Synchronize Subtitle With Video Using SubSync"
|
||||
[#]: via: "https://itsfoss.com/subsync/"
|
||||
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Automatically Synchronize Subtitle With Video Using SubSync
|
||||
======
|
||||
|
||||
Let me share a scenario. You are trying to watch a movie or video and you need subtitles. You download the subtitle only to find that the subtitle is not properly synchronized. There are no other good subtitles available. What to do now?
|
||||
|
||||
You can [synchronize subtitles in VLC by pressing G or H keys][1]. It adds a delay to the subtitles. This could work if the subtitle is out of synch by the same time interval throughout the video. But if that’s not the case, SubSync could be of great help here.
|
||||
|
||||
### SubSync: Subtitle Speech Synchronizer
|
||||
|
||||
[SubSync][2] is a nifty open source utility available for Linux, macOS and Windows.
|
||||
|
||||
It synchronizes the subtitle by listening to the audio track and that’s how it works the magic. It will work even if the audio track and the subtitle are in different languages. If necessary, it could also be translated but I did not test this feature.
|
||||
|
||||
I made a simple test by using a subtitle which was not in synch with the video I was playing. To my surprise, it worked pretty smooth and I got perfectly synched subtitles.
|
||||
|
||||
Using SubSync is simple. You start the application and it asks to add the subtitle file and the video file.
|
||||
|
||||
![User interface for SubSync][3]
|
||||
|
||||
You’ll have to specif the language of the subtitle and the video on the interface. It may download additional assets based on the language in use.
|
||||
|
||||
![SubSync may download additional packages for language support][4]
|
||||
|
||||
Please keep in mind that it takes some time to synchronize the subtitles, depending on the length of the video and subtitle. You may grab your cup of tea/coffee or beer while you wait for the process to complete.
|
||||
|
||||
You can see the synchronization status in progress and even save it before it gets completed.
|
||||
|
||||
![SubSync synchronization in progress][5]
|
||||
|
||||
Once the synchronization completes, you hit the save button and either save the changes to the original file or save it as a new subtitle file.
|
||||
|
||||
![Synchronization completed][6]
|
||||
|
||||
I cannot say that it will work in all the cases but it worked for the sample test I ran.
|
||||
|
||||
### Installing SubSync
|
||||
|
||||
SubSync is a cross-platform application and you can get the installer files for Windows and macOS from its [download page][7].
|
||||
|
||||
For Linux users, SubSync is available as a Snap package. If your distribution has Snap support enabled, use the following command to install SubSync:
|
||||
|
||||
```
|
||||
sudo snap install subsync
|
||||
```
|
||||
|
||||
Please keep in mind that it will take some time to download SubSync snap package. So have a good internet connection or plenty of patience.
|
||||
|
||||
### In the end
|
||||
|
||||
Personally, I am addicted to subtitles. Even if I am watching movies in English on Netflix, I keep the subtitles on. It helps understand each dialogue clearly, specially if there is a strong accent. Without subtitles I could never understand a [word from Mickey O’Neil (played by Brad Pitt) in the movie Snatch][8]. Dags!!
|
||||
|
||||
Using SubSync is a lot easier than [using Subtitle Editor][9] for synchronizing subtitles. After [Penguin Subtitle Player][10], this is another great tool for someone like me who searches the entire internet for rare or recommended (mystery) movies from different countries.
|
||||
|
||||
If you are a ‘subtitle user’, I have a feeling you would like this tool. If you do use it, please share your experience with it in the comment section.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/subsync/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/how-to-synchronize-subtitles-with-movie-quick-tip/
|
||||
[2]: https://subsync.online/
|
||||
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/subsync-interface.png?resize=593%2C280&ssl=1
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/subsync-subtitle-synchronize.png?resize=522%2C189&ssl=1
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/08/subsync-subtitle-synchronize-1.png?resize=424%2C278&ssl=1
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/subsync-subtitle-synchronize-2.png?resize=424%2C207&ssl=1
|
||||
[7]: https://subsync.online/en/download.html
|
||||
[8]: https://www.youtube.com/watch?v=tGDO-9hfaiI
|
||||
[9]: https://itsfoss.com/subtitld/
|
||||
[10]: https://itsfoss.com/penguin-subtitle-player/
|
||||
@@ -0,0 +1,122 @@
|
||||
[#]: subject: "7 New Features in the Newly Released Debian 11 ‘Bullseye’ Linux Distro"
|
||||
[#]: via: "https://news.itsfoss.com/debian-11-feature/"
|
||||
[#]: author: "Abhishek https://news.itsfoss.com/author/root/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "wxy"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
新发布的 Debian 11 “Bullseye” Linux 发行版的 7 大亮点
|
||||
======
|
||||
|
||||
> 这个最新发布的通用操作系统已经来到。
|
||||
|
||||

|
||||
|
||||
期待已久的代号为 “Bullseye” 的 Debian 11 版本在经过两年的开发后终于来了。该版本将在未来五年内得到支持,就像任何其他的 Debian 稳定版版本一样。
|
||||
|
||||
感到兴奋吗?让我们来看看 Debian 11 的新内容。
|
||||
|
||||
### 1、新主题
|
||||
|
||||
Debian 11 带有一个新的 “Homeworld” 主题。它的灵感来自 [包豪斯运动][1],这是一种 20 世纪初诞生于德国的艺术风格,其特点是对建筑和设计的独特处理。
|
||||
|
||||
![Debian 11 的默认壁纸][2]
|
||||
|
||||
在 Debian 11 中,无论是在登录界面、安装程序还是 Grub 菜单上,你都会看到这个主题。
|
||||
|
||||
![Grub 屏幕][3]
|
||||
|
||||
![安装程序][4]
|
||||
|
||||
![登录屏幕][10]
|
||||
|
||||
### 2、较新版本的桌面环境
|
||||
|
||||
Debian 11 包含了它所提供的桌面变体的较新版本:
|
||||
|
||||
* GNOME 3.38
|
||||
* KDE Plasma 5.20
|
||||
* LXDE 11
|
||||
* LXQt 0.16
|
||||
* MATE 1.24
|
||||
* Xfce 4.16
|
||||
|
||||
如果你使用 Fedora 或 Arch/Manjaro 等先锐发行版,你可能会觉得很奇怪。但就是这样。Debian 更倾向于稳定,因此桌面环境的版本不是最新的。当然,它们与之前的 Debian 稳定版相比,还是比较新的。
|
||||
|
||||
### 3、软件包更新
|
||||
|
||||
Debian 已经更新了它的软件包库。Debian 11 包括了多达 11294 个新软件包,软件包总数多达 59551 个。42821 个软件包有了新的版本。删除了 9519 个软件包。
|
||||
|
||||
也就是说你应该会看到像 LibreOffice、Emacs、GIMP 以及各种服务器和编程相关工具等流行应用程序的新版本。
|
||||
|
||||
### 4、Linux 内核 5.10 LTS
|
||||
|
||||
Debian 11 带有 [Linux 5.10 内核,这是一个长期支持(LTS)版本][5]。Debian 10 Buster 在发布时使用的是 Linux 4.19 内核。
|
||||
|
||||
一个新的内核显然意味着对硬件有更好的支持,特别是较新的硬件以及性能的改进。
|
||||
|
||||
### 5、打印机和扫描器的改进
|
||||
|
||||
Debian 11 带来了新的软件包 ipp-usb。它使用了许多现代打印机所支持的供应商中立的 IPP-over-USB 协议。这意味着许多较新的打印机将被 Debian 11 所支持,而不需要驱动程序。
|
||||
|
||||
同样地,SANE 无驱动后端可以让你轻松使用扫描仪。
|
||||
|
||||
### 6、支持 exFAT
|
||||
|
||||
你不再需要使用 exfat-fuse 包来挂载 exFAT 文件系统。借助 Linux 5.10 内核,Debian 11 已经支持 exFAT 文件系统,并且默认使用它来挂载 exFAT 文件系统。
|
||||
|
||||
### 7、仍然支持 32 位
|
||||
|
||||
这算是一个功能吗?考虑到现在只有 [少数几个 Linux 发行版支持 32 位架构][6],我觉得是。
|
||||
|
||||
除了 32 位和 64 位 PC,Debian 11 还支持 64 位 ARM(arm64)、ARM EABI(armel)、ARMv7(EABI hard-float ABI,armhf)、小端 MIPS(mipsel)、64 位小端 MIPS(mips64el)、64 位小端 PowerPC(ppc64el)和 IBM System z(s390x)。
|
||||
|
||||
现在你知道为什么它被称为“通用操作系统”了吧。 🙂
|
||||
|
||||
### 其他变化
|
||||
|
||||
在这个版本中还有一些变化:
|
||||
|
||||
* Systemd 默认使用控制组 v2(cgroupv2)。
|
||||
* 针对中文、日文、韩文和其他许多语言的新 Fcitx 5 输入法。
|
||||
* Systemd 日记日志默认为持久性的。
|
||||
* 一个新的打开命令,可以用某个应用程序(GUI 或 CLI)从命令行自动打开文件。
|
||||
* 本地系统账户的密码散列现在默认使用 yescrypt 而不是 SHA-512 来提高安全性。
|
||||
|
||||
更多信息可以在 [官方发布说明][7] 中找到。
|
||||
|
||||
### 获取 Debian 11
|
||||
|
||||
Debian 11 可以从其网站下载。只要前往该网站并从那里获得 ISO。
|
||||
|
||||
- [下载 Debian][8]
|
||||
|
||||
如果你已经在使用 Debian 10,你可以 [通过改变你的源列表轻松升级到 Debian 11][9] 。
|
||||
|
||||
享受最新和最棒的通用操作系统吧。🙂
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://news.itsfoss.com/debian-11-feature/
|
||||
|
||||
作者:[Abhishek][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/root/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://mymodernmet.com/what-is-bauhaus-art-movement/
|
||||
[2]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/homeworld_desktop.png?resize=1568%2C882&ssl=1
|
||||
[3]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/homeworld_grub.png?w=640&ssl=1
|
||||
[4]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/homeworld_installer.png?w=800&ssl=1
|
||||
[5]: https://news.itsfoss.com/kernel-5-10-release/
|
||||
[6]: https://itsfoss.com/32-bit-linux-distributions/
|
||||
[7]: https://www.debian.org/releases/bullseye/amd64/release-notes/ch-whats-new.en.html
|
||||
[8]: https://www.debian.org/
|
||||
[9]: https://www.debian.org/releases/bullseye/amd64/release-notes/ch-upgrading.en.html
|
||||
[10]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/08/homeworld_login.png?resize=1568%2C882&ssl=1
|
||||
@@ -1,95 +0,0 @@
|
||||
[#]: subject: (5 useful ways to manage Kubernetes with kubectl)
|
||||
[#]: via: (https://opensource.com/article/21/7/kubectl)
|
||||
[#]: author: (Alan Smithee https://opensource.com/users/alansmithee)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
用 kubectl 管理 Kubernetes 的 5 种有用方法
|
||||
======
|
||||
学习kubectl,提升你与 Kubernetes 的互动方式。
|
||||
![Ship captain sailing the Kubernetes seas][1]
|
||||
|
||||
Kubernetes 是帮助你以有组织的方式运行大量容器的软件。除了提供工具来管理(或[编排][2])运行的容器,Kubernetes 还帮助这些容器根据需要进行扩展。有了 Kubernetes 作为你的中央控制面板(或称 _control plane_),你需要一种方法来管理 Kubernetes,而这项工作的工具就是 kubectl。`kubectl` 命令让你控制、维护、分析和排除 Kubernetes 集群的故障。与许多使用 `ctl`(“控制”的缩写)后缀的工具一样,如 systemctl 和 sysctl,kubectl 拥有大量的功能和任务权限,所以如果你正在运行 Kubernetes,你最终会经常使用它。它是一个有很多选项的大命令,所以下面是 kubectl 使之变得简单的五个常见任务。
|
||||
|
||||
### 1\. 列出并描述资源
|
||||
|
||||
按照设计,容器往往会成倍增加。在某些条件下,它们可以快速增加。如果你只能通过 `podman ps`或 `docker ps` 来查看正在运行的容器,这可能会让你不知所措。通过 `kubectl get` 和 `kubectl describe`,你可以获得关于哪些 pod 正在运行以及它们正在处理的容器的信息。更重要的是,你可以通过使用 `--namespace` 或 `name` 或 `--selector`等选项,只获得你需要的信息。
|
||||
|
||||
`get` 子命令不仅仅对 pod 和容器有用。它有关于节点、命名空间、部署、服务和复制的信息。
|
||||
|
||||
### 2\. 创建资源
|
||||
|
||||
如果你只通过类似 OpenShift、OKD 或 Kubernetes 提供的 Web 用户界面(UI)创建过部署,但你想从 Linux 终端控制你的集群,那么可以使用 `kubectl create`。`kubectl create` 命令并不只是实例化一个新的应用部署。Kubernetes 中还有很多其他组件可以创建,比如服务、配额和 [CronJob][3]。
|
||||
|
||||
Kubernetes 中的 CronJob 可以创建一个临时的 pod,用来在你选择的时间表上执行一些任务。它们并不难设置。下面是一个 CronJob,让一个 BusyBox 镜像每分钟响应 “hello world”。
|
||||
|
||||
|
||||
```
|
||||
$ kubectl create cronjob \
|
||||
hello-world \
|
||||
\--image=busybox \
|
||||
\--schedule="*/1 * * * *" -- echo "hello world"
|
||||
```
|
||||
|
||||
### 3\. 编辑文件
|
||||
|
||||
你可能了解 Kubernetes 中的对象都有相应的配置文件,但在文件系统中查找相应的文件可能很麻烦。有了 `kubectl edit`,你可以把注意力放在对象上,而不是定义它们的文件上。你可以让 `kubectl` 为你找到并打开文件(它遵循 `KUBE_EDITOR` 环境变量,所以你可以把编辑器设置成你喜欢的)。
|
||||
|
||||
|
||||
```
|
||||
$ KUBE_EDITOR=emacs \
|
||||
kubectl edit cronjob/hello-world
|
||||
```
|
||||
|
||||
### 4\. 容器之间的交换文件
|
||||
|
||||
初次接触容器的人往往对他们直接无法访问的共享系统的概念感到困惑。他们可能会在容器引擎或 kubectl 中了解到 `exec` 选项,但当他们不能从容器中获取文件或将文件放入容器中时,容器仍然会显得不透明。使用 `kubectl cp` 命令,你可以把容器当做远程服务器,使复制文件到容器或从容器复制文件不比 SSH 命令更复杂:
|
||||
|
||||
|
||||
```
|
||||
`$ kubectl cp foo my-pod:/tmp`
|
||||
```
|
||||
|
||||
### 5\. 应用更改
|
||||
|
||||
对 Kubernetes 对象进行修改,可以在任何时候通过 `kubectl apply` 命令完成。你所要做的就是将该命令指向一个配置文件:
|
||||
|
||||
|
||||
```
|
||||
`$ kubectl apply -f ./mypod.json`
|
||||
```
|
||||
|
||||
类似于运行 Ansible playbook 或 Bash 脚本,`apply` 使得快速“导入”设置到运行中的 Kubernetes 实例很容易。例如,GitOps 工具 [ArgoCD][4] 由于 `apply` 子命令,安装起来出奇地简单:
|
||||
|
||||
|
||||
```
|
||||
$ kubectl create namespace argocd
|
||||
$ kubectl apply -n argocd \
|
||||
-f <https://raw.githubusercontent.com/argoproj/argo-cd/vx.y.z/manifests/install.yaml>
|
||||
```
|
||||
|
||||
### 使用 kubectl
|
||||
|
||||
Kubectl 是一个强大的工具,由于它是一个终端命令,它可以写成脚本,并以许多 Web UI 无法实现的方式使用。学习 kubectl 是进一步了解 Kubernetes、容器、pod 以及围绕这些重要的云计算创新的所有技术的一个好方法。[下载我们的 kubectl 速查表][5],以获得快速参考,其中包括命令示例,以帮助你学习,并在你成为专家后提醒你注意细节。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/7/kubectl
|
||||
|
||||
作者:[Alan Smithee][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/ship_captain_devops_kubernetes_steer.png?itok=LAHfIpek (Ship captain sailing the Kubernetes seas)
|
||||
[2]: https://opensource.com/article/20/11/orchestration-vs-automation
|
||||
[3]: https://opensource.com/article/20/11/kubernetes-jobs-cronjobs
|
||||
[4]: https://argoproj.github.io/argo-cd/
|
||||
[5]: https://opensource.com/downloads/kubectl-cheat-sheet
|
||||
249
translated/tech/20210802 Use OpenCV on Fedora Linux - part 1.md
Normal file
249
translated/tech/20210802 Use OpenCV on Fedora Linux - part 1.md
Normal file
@@ -0,0 +1,249 @@
|
||||
[#]: subject: (Use OpenCV on Fedora Linux ‒ part 1)
|
||||
[#]: via: (https://fedoramagazine.org/use-opencv-on-fedora-linux-part-1/)
|
||||
[#]: author: (Onuralp SEZER https://fedoramagazine.org/author/thunderbirdtr/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
在 Fedora Linux 上使用 OpenCV ‒ 第一部分
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
封面图片选自[文森特-凡高][2]的《星空》,公共领域,通过维基共享资源发布
|
||||
|
||||
技术世界每天都在变化,对计算机视觉、人工智能和机器学习的需求也在增加。让计算机和手机能够看到周围环境的技术被称为[计算机视觉][3]。重新创造人眼的工作始于 50 年代。从那时起,计算机视觉技术有了长足的发展。计算机视觉已经通过不同的应用进入了我们的手机。这篇文章将介绍 Fedora Linux 上的[OpenCV][4]。
|
||||
|
||||
### **什么是 OpenCV?**
|
||||
|
||||
> OpenCV (开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。OpenCV 的建立是为了给计算机视觉应用提供一个通用的基础设施,并加速机器感知在商业产品中的应用。它有超过 2500 种优化算法,其中包括一套全面的经典和最先进的计算机视觉和机器学习算法。这些算法可用于检测和识别人脸,识别物体,对视频中的人类行为进行分类,并建立标记,将其与增强现实叠加等等。
|
||||
>
|
||||
> [opencv.org – about][5]
|
||||
|
||||
### 在 Fedora Linux 上安装 OpenCV
|
||||
|
||||
要开始使用 OpenCV,请从 Fedora Linux 仓库中安装它。
|
||||
|
||||
```
|
||||
$ sudo dnf install opencv opencv-contrib opencv-doc python3-opencv python3-matplotlib python3-numpy
|
||||
```
|
||||
|
||||
**注意:**在 Fedora Silverblue 或 CoreOs 上,Python 3.9 是核心提交的一部分。用以下方法安装 OpenCV 和所需工具:_rpm-ostree install opencv opencv-doc python3-opencv python3-matplotlib python3-numpy_。
|
||||
|
||||
接下来,在终端输入以下命令,以验证 OpenCV 是否已经安装(用户输入的内容以粗体显示)。
|
||||
|
||||
```
|
||||
$ python
|
||||
Python 3.9.6 (default, Jul 16 2021, 00:00:00)
|
||||
[GCC 11.1.1 20210531 (Red Hat 11.1.1-3)] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> import cv2 as cv
|
||||
>>> print( cv.__version__ )
|
||||
4.5.2
|
||||
>>> exit()
|
||||
```
|
||||
|
||||
当你输入 _print_ 命令时,应该显示当前的 OpenCV 版本,如上图所示。这表明 OpenCV 和 Python-OpenCV 库已经成功安装。
|
||||
|
||||
此外,如果你想用 Jupyter Notebook 做笔记和写代码,并了解更多关于数据科学工具的信息,请查看早期的 Fedora Magazine 文章:[_Fedora 中的 Jupyter 和数据科学_][6]。
|
||||
|
||||
### 开始使用 OpenCV
|
||||
|
||||
安装完成后,使用 Python 和 OpenCV 库加载一个样本图像(按 **S** 键以 _png_ 格式保存图像的副本并完成程序):
|
||||
|
||||
```
|
||||
$ cp /usr/share/opencv4/samples/data/starry_night.jpg .
|
||||
$ python starry_night.py
|
||||
```
|
||||
|
||||
_starry_night.py_ 的内容:
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import sys
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
|
||||
if img is None:
|
||||
sys.exit("Could not read the image.")
|
||||
cv.imshow("Display window", img)
|
||||
k = cv.waitKey(0)
|
||||
if k == ord("s"):
|
||||
cv.imwrite("starry_night.png", img)
|
||||
```
|
||||
|
||||
![][7]
|
||||
|
||||
通过在 _cv.imread_ 函数中添加参数 **0**,对图像进行灰度处理,如下所示。
|
||||
|
||||
```
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),0)
|
||||
```
|
||||
|
||||
![][8]
|
||||
|
||||
这些是一些可以用于 _cv.imread_ 函数的第二个参数的替代值。
|
||||
|
||||
* **cv2.IMREAD_GRAYSCALE** 或 **0:** 以灰度模式加载图像。
|
||||
* **cv2.IMREAD_COLOR** 或 **1:** 以彩色模式载入图像。图像中的任何透明度将被移除。这是默认的。
|
||||
* **cv2.IMREAD_UNCHANGED** 或 **-1:**载入未经修改的图像。包括 alpha 通道。
|
||||
|
||||
|
||||
|
||||
#### 使用 OpenCV 显示图像属性
|
||||
|
||||
图像属性包括行、列和通道的数量、图像数据的类型、像素的数量等等。假设你想访问图像的形状和它的数据类型。你可以这样做:
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
|
||||
print("Image size is", img.shape)
|
||||
print("Data type of image is", img.dtype)
|
||||
|
||||
Image size is (600, 752, 3)
|
||||
Data type of image is uint8
|
||||
|
||||
print(f"Image 2D numpy array \n {img}")
|
||||
|
||||
Image 2D numpy array
|
||||
[[[0 0 0]
|
||||
[0 0 0]
|
||||
[0 0 0]
|
||||
...
|
||||
[0 0 0]
|
||||
[0 0 0]
|
||||
[0 0 0]]
|
||||
|
||||
[[0 0 0]
|
||||
[0 0 0]
|
||||
[0 0 0]
|
||||
...
|
||||
```
|
||||
|
||||
* **img.shape:** 返回一个行数、列数和通道数的元组(如果是彩色图像)。
|
||||
* **img.dtype:** 返回图像的数据类型。
|
||||
|
||||
|
||||
|
||||
接下来用 Matplotlib 显示图像:
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),0)
|
||||
plt.imshow(img)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][9]
|
||||
|
||||
#### 发生了什么?
|
||||
|
||||
该图像是作为灰度图像读入的,但是当使用 Matplotlib 的 _imshow_ 函数时,它不一定会以灰度显示。这是因为 _imshow_ 函数默认使用不同的颜色映射。要指定使用灰度颜色映射,请将 _imshow_ 函数的第二个参数设置为 _cmap='gray'_,如下所示。
|
||||
|
||||
```
|
||||
plt.imshow(img,cmap='gray')
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
这个问题在以彩色模式打开图片时也会发生,因为 Matplotlib 期望图片为 RGB(红、绿、蓝)格式,而 OpenCV 则以 BGR(蓝、绿、红)格式存储图片。为了正确显示,你需要将 BGR 图像的通道反转。
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
|
||||
fig, (ax1, ax2) = plt.subplots(1,2)
|
||||
ax1.imshow(img)
|
||||
ax1.set_title('BGR Colormap')
|
||||
ax2.imshow(img[:,:,::-1])
|
||||
ax2.set_title('Reversed BGR Colormap(RGB)')
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][11]
|
||||
|
||||
#### 分割和合并颜色通道
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
|
||||
b,g,r = cv.split(img)
|
||||
|
||||
fig,ax = plt.subplots(2,2)
|
||||
|
||||
ax[0,0].imshow(r,cmap='gray')
|
||||
ax[0,0].set_title("Red Channel");
|
||||
ax[0,1].imshow(g,cmap='gray')
|
||||
ax[0,1].set_title("Green Channel");
|
||||
ax[1,0].imshow(b,cmap='gray')
|
||||
ax[1,0].set_title("Blue Channel");
|
||||
|
||||
# Merge the individual channels into a BGR image
|
||||
imgMerged = cv.merge((b,g,r))
|
||||
# Show the merged output
|
||||
ax[1,1].imshow(imgMerged[:,:,::-1])
|
||||
ax[1,1].set_title("Merged Output");
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][12]
|
||||
|
||||
* **cv2.split:**将一个多通道数组分割成几个单通道数组。
|
||||
* **cv2.merge:** 将几个数组合并成一个多通道数组。所有的输入矩阵必须具有相同的大小。
|
||||
|
||||
|
||||
|
||||
**注意:**白色较多的图像具有较高的颜色密度。相反,黑色较多的图像,其颜色密度较低。在上面的例子中,红色的密度是最低的。
|
||||
|
||||
#### 转换到不同的色彩空间
|
||||
|
||||
_cv2.cvtColor_ 函数将一个输入图像从一个颜色空间转换到另一个颜色空间。在 RGB 和 BGR 色彩空间之间转换时,应明确指定通道的顺序(_RGB2BGR_ 或 _BGR2RGB_)。**注意,OpenCV 中的默认颜色格式通常被称为 RGB,但它实际上是 BGR(字节是相反的)。**因此,标准(24 位)彩色图像的第一个字节将是一个 8 位蓝色分量,第二个字节是绿色,第三个字节是红色。然后第四、第五和第六个字节将是第二个像素(蓝色,然后是绿色,然后是红色),以此类推。
|
||||
|
||||
```
|
||||
import cv2 as cv
|
||||
import matplotlib.pyplot as plt
|
||||
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
|
||||
img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
|
||||
plt.imshow(img_rgb)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![][13]
|
||||
|
||||
### 更多信息
|
||||
|
||||
关于 OpenCV 的更多细节可以在[在线文档][14]中找到。
|
||||
|
||||
谢谢。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/use-opencv-on-fedora-linux-part-1/
|
||||
|
||||
作者:[Onuralp SEZER][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/thunderbirdtr/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2021/08/starry-night-1-816x345.jpg
|
||||
[2]: https://commons.wikimedia.org/wiki/File:Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg
|
||||
[3]: https://en.wikipedia.org/wiki/Computer_vision
|
||||
[4]: https://en.wikipedia.org/wiki/OpenCV
|
||||
[5]: https://opencv.org/about/
|
||||
[6]: https://fedoramagazine.org/jupyter-and-data-science-in-fedora/
|
||||
[7]: https://fedoramagazine.org/wp-content/uploads/2021/06/image.png
|
||||
[8]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-1.png
|
||||
[9]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-2.png
|
||||
[10]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-3.png
|
||||
[11]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-4.png
|
||||
[12]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-5.png
|
||||
[13]: https://fedoramagazine.org/wp-content/uploads/2021/06/image-7.png
|
||||
[14]: https://docs.opencv.org/4.5.2/index.html
|
||||
@@ -1,52 +0,0 @@
|
||||
[#]: subject: (Move files in the Linux terminal)
|
||||
[#]: via: (https://opensource.com/article/21/8/move-files-linux)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
在 Linux 终端中移动文件
|
||||
======
|
||||
使用 mv 命令将一个文件从一个位置移动到另一个位置。
|
||||
![Moving files][1]
|
||||
|
||||
要在有图形界面的计算机上移动一个文件,你要打开该文件当前所在的文件夹,然后打开另一个窗口到你想把文件移到的文件夹。最后,你把文件从一个窗口拖到另一个窗口。
|
||||
|
||||
要在终端中移动文件,你可以使用 **mv** 命令将文件从一个位置移动到另一个位置。
|
||||
|
||||
|
||||
```
|
||||
$ mv example.txt ~/Documents
|
||||
|
||||
$ ls ~/Documents
|
||||
example.txt
|
||||
```
|
||||
|
||||
在这个例子中,你已经把 **example.txt** 从当前文件夹移到了 **Documents** 文件夹中。
|
||||
|
||||
只要你知道一个文件在__哪里__,又想把它移到_哪里_去,你就可以把文件从任何地方移动到任何地方,而不管你在哪里。与在一系列窗口中浏览你电脑上的所有文件夹以找到一个文件,然后打开一个新窗口到你想让该文件去的地方,再拖动该文件相比,这可以大大节省时间。
|
||||
|
||||
默认情况下,**mv** 命令完全按照它被告知的那样做:它将一个文件从一个位置移动到另一个位置。如果在目标位置已经存在一个同名的文件,它将被覆盖。为了防止文件在没有警告的情况下被覆盖,请使用 **\--interactive**(或简写 **-i**)选项。
|
||||
|
||||
|
||||
```
|
||||
$ mv -i example.txt ~/Documents
|
||||
mv: overwrite '/home/tux/Documents/example.txt'?
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/move-files-linux
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/ch01s05.svg_.png?itok=PgKQEDZ7 (Moving files)
|
||||
@@ -0,0 +1,173 @@
|
||||
[#]: subject: "Configure your OpenVPN server on Linux"
|
||||
[#]: via: "https://opensource.com/article/21/7/openvpn-firewall"
|
||||
[#]: author: "D. Greg Scott https://opensource.com/users/greg-scott"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
在 Linux 上配置你的 OpenVPN 服务器
|
||||
======
|
||||
在你安装了 OpenVPN 之后,是时候配置它了。
|
||||
![Lock][1]
|
||||
|
||||
OpenVPN 在两点之间建立一个加密的隧道,防止第三方访问你的网络流量。通过设置你的虚拟私人网络(VPN)服务器,你就成为你自己的 VPN 供应商。许多流行的 VPN 服务已经使用 [OpenVPN][2],所以当你可以完全控制时,为什么要把你的连接绑定到一个特定的供应商?
|
||||
|
||||
本系列中的[第一篇][3]设置了一个 VPN 服务器,[第二篇][4]演示了如何安装和配置 OpenVPN 服务器软件。这第三篇文章展示了如何在认证到位的情况下启动 OpenVPN。
|
||||
|
||||
要设置一个 OpenVPN 服务器,你必须:
|
||||
|
||||
* 创建一个配置文件。
|
||||
* 设置 `sysctl` 值 `net.ipv4.ip_forward = 1` 以启用路由。
|
||||
* 为所有的配置和认证文件设置适当的所有权,以便在一个非 root 账户下运行 OpenVPN 服务器守护程序。
|
||||
* 设置 OpenVPN 以适当的配置文件启动。
|
||||
* 配置你的防火墙。
|
||||
|
||||
|
||||
|
||||
### 配置文件
|
||||
|
||||
你必须在 `/etc/openvpn/server/` 中创建一个服务器配置文件。如果你想的话,你可以从头开始,OpenVPN 包括了几个样本配置文件,可以作为开始。看看 `/usr/share/doc/openvpn/sample/sample-config-files/` 就知道了。
|
||||
|
||||
如果你想手工建立一个配置文件,从 `server.conf` 或 `roadwarrior-server.conf` 开始(视情况而定),并将你的配置文件放在 `/etc/openvpn/server` 中。这两个文件都有大量的注释,所以请阅读注释并决定哪一个适用你的情况。
|
||||
|
||||
你可以通过使用我预先建立的服务器和客户端配置文件模板和 `sysctl` 文件来打开网络路由,从而节省时间和麻烦。这个配置还包括自定义记录连接和断开的情况。它在 OpenVPN 服务器的 `/etc/openvpn/server/logs` 中保存日志。
|
||||
|
||||
如果你使用我的模板,你将需要编辑它们以使用你的 IP 地址和主机名。
|
||||
|
||||
要使用我的预建配置模板、脚本和 `sysctl` 来打开 IP 转发,请下载我的脚本:
|
||||
|
||||
|
||||
```
|
||||
$ curl \
|
||||
<https://www.dgregscott.com/ovpn/OVPNdownloads.sh> > \
|
||||
OVPNdownloads.sh
|
||||
```
|
||||
|
||||
阅读该脚本,了解它的工作内容。下面是它的行为概述:
|
||||
|
||||
* 在你的 OpenVPN 服务器上创建适当的目录
|
||||
* 从我的网站下载服务器和客户端的配置文件模板
|
||||
* 下载我的自定义脚本,并以正确的权限把它们放到正确的目录中。
|
||||
* 下载 `99-ipforward.conf` 并把它放到 `/etc/sysctl.d` 中,以便在下次启动时打开 IP 转发功能。
|
||||
* 为 `/etc/openvpn` 中的所有内容设置了所有权
|
||||
|
||||
|
||||
|
||||
当你确定你理解了这个脚本的作用,就使它可执行并运行它:
|
||||
|
||||
|
||||
```
|
||||
$ chmod +x OVPNdownloads.sh
|
||||
$ sudo ./OVPNdownloads.sh
|
||||
```
|
||||
|
||||
下面是它复制的文件(注意文件的所有权):
|
||||
|
||||
|
||||
```
|
||||
$ ls -al -R /etc/openvpn
|
||||
/etc/openvpn:
|
||||
total 12
|
||||
drwxr-xr-x. 4 openvpn openvpn 34 Apr 6 20:35 .
|
||||
drwxr-xr-x. 139 root root 8192 Apr 6 20:35 ..
|
||||
drwxr-xr-x. 2 openvpn openvpn 33 Apr 6 20:35 client
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 server
|
||||
|
||||
/etc/openvpn/client:
|
||||
total 4
|
||||
drwxr-xr-x. 2 openvpn openvpn 33 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 34 Apr 6 20:35 ..
|
||||
-rw-r--r--. 1 openvpn openvpn 1764 Apr 6 20:35 OVPNclient2020.ovpn
|
||||
|
||||
/etc/openvpn/server:
|
||||
total 4
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 34 Apr 6 20:35 ..
|
||||
drwxr-xr-x. 2 openvpn openvpn 59 Apr 6 20:35 ccd
|
||||
drwxr-xr-x. 2 openvpn openvpn 6 Apr 6 20:35 logs
|
||||
-rw-r--r--. 1 openvpn openvpn 2588 Apr 6 20:35 OVPNserver2020.conf
|
||||
|
||||
/etc/openvpn/server/ccd:
|
||||
total 8
|
||||
drwxr-xr-x. 2 openvpn openvpn 59 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 ..
|
||||
-rwxr-xr-x. 1 openvpn openvpn 917 Apr 6 20:35 client-connect.sh
|
||||
-rwxr-xr-x. 1 openvpn openvpn 990 Apr 6 20:35 client-disconnect.sh
|
||||
|
||||
/etc/openvpn/server/logs:
|
||||
total 0
|
||||
drwxr-xr-x. 2 openvpn openvpn 6 Apr 6 20:35 .
|
||||
drwxr-xr-x. 4 openvpn openvpn 56 Apr 6 20:35 ..
|
||||
```
|
||||
|
||||
下面是 `99-ipforward.conf` 文件:
|
||||
|
||||
|
||||
```
|
||||
# Turn on IP forwarding. OpenVPN servers need to do routing
|
||||
net.ipv4.ip_forward = 1
|
||||
```
|
||||
|
||||
编辑 `OVPNserver2020.conf` 和 `OVPNclient2020.ovpn` 以包括你的 IP 地址。同时,编辑 `OVPNserver2020.conf` 以包括你先前的服务器证书名称。稍后,你将重新命名和编辑 `OVPNclient2020.ovpn` 的副本,以便在你的客户电脑上使用。以 `***?` 开头的块显示了你要编辑的地方。
|
||||
|
||||
### 文件所有权
|
||||
|
||||
如果你使用了我网站上的自动脚本,文件所有权就已经到位了。如果没有,你必须确保你的系统有一个叫 `openvpn` 的用户,并且是 `openvpn` 组的成员。你必须将 `/etc/openvpn` 中的所有内容的所有权设置为该用户和组。如果你不确定该用户和组是否已经存在,这样做是安全的,因为 `useradd` 会拒绝创建一个与已经存在的用户同名的用户:
|
||||
|
||||
|
||||
```
|
||||
$ sudo useradd openvpn
|
||||
$ sudo chown -R openvpn.openvpn /etc/openvpn
|
||||
```
|
||||
|
||||
### 防火墙
|
||||
|
||||
如果你在步骤 1 中决定不禁用 firewalld 服务,那么你的服务器的防火墙服务可能默认不允许 VPN 流量。使用 [`firewall-cmd` 命令][5],你可以启用 OpenVPN 服务,它可以打开必要的端口并根据需要路由流量:
|
||||
|
||||
|
||||
```
|
||||
$ sudo firewall-cmd --add-service openvpn --permanent
|
||||
$ sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
没有必要在 iptables 的迷宫中迷失方向!
|
||||
|
||||
### 启动你的服务器
|
||||
|
||||
现在你可以启动你的 OpenVPN 服务器了。为了让它在重启后自动启动,使用 `systemctl` 的 `enable` 子命令:
|
||||
|
||||
|
||||
```
|
||||
`systemctl enable --now openvpn-server@OVPNserver2020.service`
|
||||
```
|
||||
|
||||
### 最后的步骤
|
||||
|
||||
本文的第四篇也是最后一篇文章将演示如何设置客户端,以便从远处连接到你的 OpenVPN。
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
_本文基于 D.Greg Scott 的[博客][6],经许可后重新使用。_
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/7/openvpn-firewall
|
||||
|
||||
作者:[D. Greg Scott][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/greg-scott
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum (Lock)
|
||||
[2]: https://openvpn.net/
|
||||
[3]: https://opensource.com/article/21/7/vpn-openvpn-part-1
|
||||
[4]: https://opensource.com/article/21/7/vpn-openvpn-part-2
|
||||
[5]: https://www.redhat.com/sysadmin/secure-linux-network-firewall-cmd
|
||||
[6]: https://www.dgregscott.com/how-to-build-a-vpn-in-four-easy-steps-without-spending-one-penny/
|
||||
@@ -0,0 +1,140 @@
|
||||
[#]: subject: "Change your Linux Desktop Wallpaper Every Hour [Here’s How]"
|
||||
[#]: via: "https://www.debugpoint.com/2021/08/change-wallpaper-every-hour/"
|
||||
[#]: author: "Arindam https://www.debugpoint.com/author/admin1/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
如何每小时改变你的 Linux 桌面墙纸
|
||||
======
|
||||
这个 shell 脚本 styli.sh 可以帮助你每小时自动改变你的 Linux 桌面壁纸,并且有几个选项。
|
||||
|
||||
用一张漂亮的壁纸来开始你的一天,你的桌面让人耳目一新。但寻找墙纸,然后保存,最终设置为墙纸,是非常麻烦的。所有这些步骤都可以通过这个叫做 [styl.sh][1] 的脚本完成。
|
||||
|
||||
### styli.sh - 每小时改变你的 Linux 桌面壁纸
|
||||
|
||||
这是一个 shell 脚本,你可以从 GitHub 上下载。当运行时,它从 Reddit 的热门 Subreddits 中获取壁纸并将其设置为你的壁纸。
|
||||
|
||||
该脚本适用于所有流行的桌面环境,如 GNOME、KDE Plasma、Xfce 和 Sway 窗口管理器。
|
||||
|
||||
它有很多功能,你可以通过 crontab 来运行这个脚本,并在特定的时间间隔内得到一张新的墙纸。
|
||||
|
||||
### 下载并安装、运行
|
||||
|
||||
打开一个终端,并克隆 GitHub 仓库。如果没有安装的话,你需要安装 [feh][2] 和 git。
|
||||
|
||||
```
|
||||
git clone https://github.com/thevinter/styli.sh
|
||||
cd styli.sh
|
||||
```
|
||||
|
||||
要设置随机墙纸,根据你的桌面环境运行以下内容。
|
||||
|
||||
![Change your Linux Desktop Wallpaper Every Hour using styli.sh][3]
|
||||
|
||||
```
|
||||
./styli.sh -g
|
||||
```
|
||||
|
||||
```
|
||||
./styli.sh -x
|
||||
```
|
||||
|
||||
```
|
||||
./styli.sh -k
|
||||
```
|
||||
|
||||
```
|
||||
./styli.sh -y
|
||||
```
|
||||
|
||||
### 每小时改变一次
|
||||
|
||||
要每小时改变背景,请运行以下命令:
|
||||
|
||||
```
|
||||
crontab -e
|
||||
```
|
||||
|
||||
并在打开的文件中加入以下内容。不要忘记改变脚本路径。
|
||||
|
||||
```
|
||||
@hourly script/path/styli.sh
|
||||
```
|
||||
|
||||
### 改变 subreddits
|
||||
|
||||
在源目录中,有一个名为 subreddits 的文件。它填满了一些标准的 subreddits。如果你想要更多一些,只需在文件末尾添加 subreddit 名称。
|
||||
|
||||
### 更多配置选项
|
||||
|
||||
壁纸的类型,大小,也可以设置。以下是这个脚本的一些独特的配置选项。
|
||||
|
||||
> 设置一个随机的 1920×1080 背景
|
||||
> ./styli.sh
|
||||
>
|
||||
> 指定一个所需的宽度或高度
|
||||
> ./styli.sh -w 1080 -h 720
|
||||
> ./styli.sh -w 2560
|
||||
> ./styli.sh -h 1440
|
||||
>
|
||||
> 根据搜索词设置墙纸
|
||||
> ./styli.sh -s island
|
||||
> ./styli.sh -s “sea sunset”
|
||||
> ./styli.sh -s sea -w 1080
|
||||
>
|
||||
> 从设定的一个 subreddits 中获得一个随机壁纸
|
||||
> 注意:宽度/高度/搜索参数对 reddit 不起作用。
|
||||
> ./styli.sh -l reddit
|
||||
>
|
||||
> 从一个自定义的 subreddit 获得随机墙纸
|
||||
> ./styli.sh -r
|
||||
> ./styli.sh -r wallpaperdump
|
||||
>
|
||||
> 使用内置的 feh -bg 选项
|
||||
> ./styli.sh -b
|
||||
> ./styli.sh -b bg-scale -r widescreen-wallpaper
|
||||
>
|
||||
> 添加自定义的 feh 标志
|
||||
> ./styli.sh -c
|
||||
> ./styli.sh -c –no-xinerama -r widescreen-wallpaper
|
||||
>
|
||||
> 自动设置终端的颜色
|
||||
> ./styli.sh -p
|
||||
>
|
||||
> 使用 nitrogen 而不是 feh
|
||||
> ./styli.sh -n
|
||||
>
|
||||
> 使用 nitrogen 更新 > 1 个屏幕
|
||||
> ./styli.sh -n -m
|
||||
>
|
||||
> 从一个目录中选择一个随机的背景
|
||||
> ./styli.sh -d /path/to/dir
|
||||
|
||||
### 最后说明
|
||||
|
||||
一个独特且方便的脚本,内存占用小,可以直接在一个时间间隔内比如一个小时获取图片。让你的桌面看起来[新鲜且高效][4]。如果你不喜欢这些壁纸,你可以简单地从终端再次运行脚本来循环使用。
|
||||
|
||||
你喜欢这个脚本吗?或者你知道有什么像这样的壁纸切换器吗?请在下面的评论栏里告诉我。
|
||||
|
||||
* * *
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.debugpoint.com/2021/08/change-wallpaper-every-hour/
|
||||
|
||||
作者:[Arindam][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.debugpoint.com/author/admin1/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/thevinter/styli.sh
|
||||
[2]: https://feh.finalrewind.org/
|
||||
[3]: https://www.debugpoint.com/blog/wp-content/uploads/2021/08/Change-your-Linux-Desktop-Wallpaper-Every-Hour-using-styli.sh_.jpg
|
||||
[4]: https://www.debugpoint.com/category/themes
|
||||
126
translated/tech/20210813 Install Linux with LVM.md
Normal file
126
translated/tech/20210813 Install Linux with LVM.md
Normal file
@@ -0,0 +1,126 @@
|
||||
[#]: subject: "Install Linux with LVM"
|
||||
[#]: via: "https://opensource.com/article/21/8/install-linux-mint-lvm"
|
||||
[#]: author: "Kenneth Aaron https://opensource.com/users/flyingrhino"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
用 LVM 安装 Linux
|
||||
======
|
||||
一个关于让 Linux Mint 20.2 与逻辑卷管理器(LVM)一起工作的教程。
|
||||
![Linux keys on the keyboard for a desktop computer][1]
|
||||
|
||||
几周前,[Linux Mint][2] 的人员发布了他们的开源操作系统的 20.2 版本。Live ISO 中内置的安装程序非常好,只需要点击几下就可以安装操作系统。如果你想定制你的分区,你甚至有一个内置的分区器。
|
||||
|
||||
安装程序主要集中在简单的安装上:定义你的分区并安装到这些分区。对于那些想要更灵活的设置的人来说,[逻辑卷管理器][3] (LVM)是个不错的选择,你可以通过设置卷组并在其中定义你的逻辑卷。
|
||||
|
||||
LVM 是一个硬盘管理系统,允许你在多个物理驱动器上创建存储空间。换句话说,你可以把几个小驱动器“拴”在一起,这样你的操作系统就会把它们当作一个驱动器。除此之外,它还有实时调整大小、文件系统快照和更多的优点。这篇文章并不是关于 LVM 的教程(网上已经有很多[这方面不错的信息][4]了)。 相反,我的目标是保持这个页面的主题,只关注让 Linux Mint 20.2 与 LVM 一起工作。
|
||||
|
||||
作为一个桌面操作系统,安装程序很简单,在 LVM 上安装 LM 20.2 略微复杂一些,但不会太复杂。如果你在安装程序中选择了 LVM,你会得到一个由 Linux Mint 开发者定义的设置,而且你在安装时无法控制各个卷。
|
||||
|
||||
然而,有一个解决方案:在 Live ISO 中,该方案只需要在终端中的几个命令来设置 LVM,然后你继续使用常规安装程序来完成工作。
|
||||
|
||||
我安装了 Linux Mint 20.2 和 [XFCE 桌面][5],但其他 LM 桌面的过程也类似。
|
||||
|
||||
### 分区驱动器
|
||||
|
||||
在 Linux Mint live ISO 中,你可以通过终端和 GUI 工具访问 Linux 命令行工具。如果你需要做任何分区工作,你可以使用命令行 `fdisk` 或 `parted` 命令,或者 GUI 应用 `gparted`。我想让这些说明简单到任何人都能遵循,所以我会在可能的情况下使用 GUI 工具,在必要时使用命令行工具。
|
||||
|
||||
首先,为安装创建几个分区。
|
||||
|
||||
使用 `gparted` (从菜单中启动),完成以下工作:
|
||||
|
||||
首先,创建一个 512MB 的分区,类型为 **FAT32**(这是用来确保系统可启动)。512MB 对大多数人来说是多余的,你可以用 256MB 甚至更少,但在今天的大磁盘中,即使分配 512MB 也不是什么大问题。
|
||||
|
||||
![Creating a boot partition][6]
|
||||
|
||||
CC BY-SA Seth Kenlon
|
||||
|
||||
接下来,在磁盘的其余部分创建一个 `lvm2 pv` 类型的分区(这是你的 LVM 的位置)。
|
||||
|
||||
![Partition layout][7]
|
||||
|
||||
CC BY-SA Seth Kenlon
|
||||
|
||||
现在打开一个终端窗口,并将你的权限提升到 root:
|
||||
|
||||
|
||||
```
|
||||
$ sudo -s
|
||||
# whoami
|
||||
root
|
||||
```
|
||||
|
||||
接下来,你必须找到你之前创建的 LVM 成员(大分区)。使用下列命令之一: `lsblk -f` 或 `pvs` 或 `pvscan`。
|
||||
|
||||
|
||||
```
|
||||
# pvs
|
||||
PV VG Fmt [...]
|
||||
/dev/sda2 lvm2 [...]
|
||||
```
|
||||
|
||||
在我的例子中,该分区位于 `/dev/sda2`,但你应该用你的输出中得到的内容来替换它。
|
||||
|
||||
现在你知道了你的分区有哪些设备,你可以在那里创建一个 LVM 卷组:
|
||||
|
||||
|
||||
```
|
||||
`# vgcreate vg /dev/sda2`
|
||||
```
|
||||
|
||||
你可以使用 `vgs` 或 `vgscan` 看到你创建的卷组的细节。
|
||||
|
||||
创建你想在安装时使用的逻辑卷。为了简单,我分别创建了根分区(`/`)和 `swap` 分区,但是你可以根据需要创建更多的分区(例如,为 `/home` 创建一个单独的分区)。
|
||||
|
||||
|
||||
```
|
||||
# lvcreate -L 80G -n root vg
|
||||
# lvcreate -L 16G -n swap vg
|
||||
```
|
||||
|
||||
我的例子中的分区大小是任意的,是基于我可用的。使用对你的硬盘有意义的分区大小。
|
||||
|
||||
你可以用 `lvs` 或 `lvdisplay` 查看逻辑卷。
|
||||
|
||||
终端到这就结束了。
|
||||
|
||||
### 安装 Linux
|
||||
|
||||
现在从桌面上的图标启动安装程序:
|
||||
|
||||
* 进入 **Installation type**,选择 **Something else**。
|
||||
* 编辑 512Mb 的分区并将其改为 `EFI`。
|
||||
* 编辑根 LV,将其改为 `ext4`(或一个你选择的文件系统)。选择将其挂载为根目录,并选择将其格式化。
|
||||
* 编辑交换分区并将其设置为`swap`。
|
||||
* 继续正常的安装过程。Linux Mint 安装程序会将文件放在正确的位置并为你创建挂载点。
|
||||
|
||||
|
||||
|
||||
|
||||
完成了。在你的 Linux Mint 安装中享受 LVM 的强大。
|
||||
|
||||
如果你需要调整分区大小或在系统上做任何高级工作,你会感谢选择 LVM。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/install-linux-mint-lvm
|
||||
|
||||
作者:[Kenneth Aaron][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/flyingrhino
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_keyboard_desktop.png?itok=I2nGw78_ (Linux keys on the keyboard for a desktop computer)
|
||||
[2]: https://linuxmint.com/
|
||||
[3]: https://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux)
|
||||
[4]: https://opensource.com/business/16/9/linux-users-guide-lvm
|
||||
[5]: https://opensource.com/article/19/12/xfce-linux-desktop
|
||||
[6]: https://opensource.com/sites/default/files/boot-part.png (Creating a boot partition)
|
||||
[7]: https://opensource.com/sites/default/files/part-layout.png (Partition layout)
|
||||
@@ -0,0 +1,226 @@
|
||||
[#]: subject: "Parse command options in Java with commons-cli"
|
||||
[#]: via: "https://opensource.com/article/21/8/java-commons-cli"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "unigeorge"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
使用 commons-cli 解析 Java 中的命令行选项
|
||||
======
|
||||
让用户学会用命令行选项调整你的 Java 应用程序运行方式。
|
||||
![Learning and studying technology is the key to success][1]
|
||||
|
||||
通常向终端中输入命令时,无论是启动 GUI 应用程序还是仅启动终端应用程序,都可以使用
|
||||
<ruby>
|
||||
[命令行选项][2]<rp>(</rp><rt>options or switches or flags</rt><rp>)</rp>
|
||||
</ruby>
|
||||
(**以下简称选项**)来修改应用程序的运行方式。这是 [POSIX 规范][3] 设定的标准,因此能够检测和解析选项对 Java 程序员而言是很有用的技能。
|
||||
|
||||
Java 中有若干种解析选项的方法,其中我最喜欢用的是 [Apache Commons CLI][4] 库,简称 **commons-cli**。
|
||||
|
||||
### 安装 commons-cli
|
||||
|
||||
如果你使用类似 [Maven][5] 之类的项目管理系统以及集成开发环境(Integrated Development Environment,简称IDE),可以在项目属性(比如 `pom.xml` 配置文件或者 Eclipse 和 NetBeans 的配置选项卡)中安装 Apache Commons CLI 库。
|
||||
|
||||
而如果你采用手动方式管理库,则可以从 Apache 网站下载 [该库的最新版本][6]。下载到本地的是几个捆绑在一起的 JAR 文件,你只需要其中的一个文件 `commons-cli-X.Y.jar`(其中 X 和 Y 代指最新版本号)。把这个 JAR 文件或手动或使用 IDE 添加到项目,就可以在代码中使用了。
|
||||
|
||||
### 将库导入至 Java 代码
|
||||
|
||||
在使用 **commons-cli** 库之前,必须首先导入它。对于本次选项解析的简单示例而言,可以先在 `Main.java` 文件中简单写入以下标准代码:
|
||||
|
||||
```
|
||||
package com.opensource.myoptparser;
|
||||
|
||||
import org.apache.commons.cli.*;
|
||||
|
||||
public class Main {
|
||||
public static void main([String][7][] args) {
|
||||
// code
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
至此在 Java 中解析选项的准备工作已经做好了。
|
||||
|
||||
### 在 Java 中定义布尔选项
|
||||
|
||||
要实现解析选项,首先要定义应用程序可接收的有效选项。使用 `Option`(注意是单数)类来创建选项对象,使用 `Options`(注意是复数)类来追踪项目中创建的所有选项。
|
||||
|
||||
首先为选项创建一个组,按照惯例命名为 `options`:
|
||||
|
||||
```
|
||||
//code
|
||||
Options options = new Options();
|
||||
```
|
||||
|
||||
接下来,通过列出短选项(即选项名简写)、长选项(即全写)、默认布尔值(译注:设置是否需要选项参数,指定为 false 时此选项不带参,即为布尔选项)和帮助信息来定义选项,然后设置该选项是否为必需项(译注:下方创建 `alpha` 对象的代码中未手动设置此项),最后将该选项添加到包含所有选项的 `options` 组对象中。在下面几行代码中,我只创建了一个选项,命名为 `alpha`:
|
||||
|
||||
```
|
||||
//define options
|
||||
[Option][8] alpha = new [Option][8]("a", "alpha", false, "Activate feature alpha");
|
||||
options.addOption(alpha);
|
||||
```
|
||||
|
||||
### 在 Java 中定义带参选项
|
||||
|
||||
有时用户需要通过选项提供 **true** 或 **false** 以外的信息,比如给出配置文件、输入文件或诸如日期、颜色这样的设置项值。这种情况可以使用 `builder` 方法,根据选项名简写为其创建属性(例如,`-c` 是短选项,`--config` 是长选项)。完成定义后,再将定义好的选项添加到 `options` 组中:
|
||||
|
||||
```
|
||||
[Option][8] config = [Option][8].builder("c").longOpt("config")
|
||||
.argName("config")
|
||||
.hasArg()
|
||||
.required(true)
|
||||
.desc("set config file").build();
|
||||
options.addOption(config);
|
||||
```
|
||||
|
||||
`builder`函数可以用来设置短选项、长选项、是否为必需项(本段代码中必需项设置为 **true**,也就意味着用户启动程序时必须提供此选项,否则应用程序无法运行)、帮助信息等。
|
||||
|
||||
### 使用 Java 解析选项
|
||||
|
||||
定义并添加所有可能用到的选项后,需要对用户提供的参数进行迭代处理,检测是否有参数同预设的有效短选项列表中的内容相匹配。为此要创建 **CommandLine** 命令行本身的一个实例,其中包含用户提供的所有参数(包含有效选项和无效选项)。为了处理这些参数,还要创建一个 **CommandLineParser** 对象,我在代码中将其命名为 `parser`。最后,还可以创建一个 **HelpFormatter** 对象(我将其命名为 `helper`),当参数中缺少某些必需项或者用户使用 `--help` 或 `-h` 选项时,此对象可以自动向用户提供一些有用的信息。
|
||||
|
||||
```
|
||||
// define parser
|
||||
CommandLine cmd;
|
||||
CommandLineParser parser = new BasicParser();
|
||||
HelpFormatter helper = new HelpFormatter();
|
||||
```
|
||||
|
||||
最后,添加一些条件判断来分析用户提供的选项,我们假设这些选项已经作为命令行输入被获取并存储在 `cmd` 变量中。这个示例应用程序有两种不同类型的选项,但对这两种类型都可以使用 `.hasOption` 方法加上短选项名称来检测选项是否存在。检测到一个存在的选项后,就可以对数据做进一步操作了。
|
||||
|
||||
```
|
||||
try {
|
||||
cmd = parser.parse(options, args);
|
||||
if(cmd.hasOption("a")) {
|
||||
[System][9].out.println("Alpha activated");
|
||||
}
|
||||
|
||||
if (cmd.hasOption("c")) {
|
||||
[String][7] opt_config = cmd.getOptionValue("config");
|
||||
[System][9].out.println("Config set to " + opt_config);
|
||||
}
|
||||
} catch ([ParseException][10] e) {
|
||||
[System][9].out.println(e.getMessage());
|
||||
helper.printHelp("Usage:", options);
|
||||
[System][9].exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
解析过程有可能会产生错误,因为有时可能缺少某些必需项如本例中的 `-c` 或 `--config` 选项。这时程序会打印一条帮助信息,并立即结束运行。考虑到此错误(Java 术语中称为 _exception_,异常),在 main 方法的开头要添加语句声明可能的异常:
|
||||
|
||||
|
||||
```
|
||||
public static void main(String[] args) throws ParseException {
|
||||
```
|
||||
|
||||
示例程序至此就大功告成了。
|
||||
|
||||
### 测试代码
|
||||
|
||||
你可以通过调整传递给代码的默认参数来在 IDE 中测试应用程序,或者创建一个 JAR 文件并在终端运行测试。这个过程可能会因 IDE 的不同而不同。具体请参阅相应的 IDE 文档,以及我写过的关于如何创建 JAR 文件的文章,或者参考 Daniel Oh 的关于如何使用 [Maven][11] 执行同样操作的文章。
|
||||
|
||||
首先,省略必需项 `-c` 或 `--config` 选项,检测解析器的异常处理:
|
||||
|
||||
```
|
||||
$ java -jar dist/myapp.jar
|
||||
Missing required option: c
|
||||
usage: Usage:
|
||||
-a,--alpha Activate feature alpha
|
||||
-c,--config <config> Set config file
|
||||
```
|
||||
|
||||
然后提供输入选项再进行测试:
|
||||
|
||||
```
|
||||
java -jar dist/myantapp.jar --config foo -a
|
||||
Alpha activated
|
||||
Config set to foo
|
||||
```
|
||||
|
||||
### 选项解析
|
||||
|
||||
为用户提供选项功能对任何应用程序来说都是很重要的。有了 Java 和 Apache Commons,要实现这个功能并不难。
|
||||
|
||||
以下是完整的演示代码,供读者参考:
|
||||
|
||||
|
||||
```
|
||||
package com.opensource.myapp;
|
||||
|
||||
import org.apache.commons.cli.*;
|
||||
|
||||
public class Main {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
* @throws org.apache.commons.cli.ParseException
|
||||
*/
|
||||
public static void main([String][7][] args) throws [ParseException][10] {
|
||||
// define options
|
||||
Options options = new Options();
|
||||
|
||||
[Option][8] alpha = new [Option][8]("a", "alpha", false, "Activate feature alpha");
|
||||
options.addOption(alpha);
|
||||
|
||||
[Option][8] config = [Option][8].builder("c").longOpt("config")
|
||||
.argName("config")
|
||||
.hasArg()
|
||||
.required(true)
|
||||
.desc("Set config file").build();
|
||||
options.addOption(config);
|
||||
|
||||
// define parser
|
||||
CommandLine cmd;
|
||||
CommandLineParser parser = new BasicParser();
|
||||
HelpFormatter helper = new HelpFormatter();
|
||||
|
||||
try {
|
||||
cmd = parser.parse(options, args);
|
||||
if(cmd.hasOption("a")) {
|
||||
[System][9].out.println("Alpha activated");
|
||||
}
|
||||
|
||||
if (cmd.hasOption("c")) {
|
||||
[String][7] opt_config = cmd.getOptionValue("config");
|
||||
[System][9].out.println("Config set to " + opt_config);
|
||||
}
|
||||
} catch ([ParseException][10] e) {
|
||||
[System][9].out.println(e.getMessage());
|
||||
helper.printHelp("Usage:", options);
|
||||
[System][9].exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 使用 Java 和选项
|
||||
|
||||
选项使用户可以调整命令的工作方式。使用 Java 时解析选项的方法有很多,其中之一的 `commons-cli` 是一个强大而灵活的开源解决方案。记得在你的下一个 Java 项目中尝试一下哦。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/java-commons-cli
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[unigeorge](https://github.com/unigeorge)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/studying-books-java-couch-education.png?itok=C9gasCXr (Learning and studying technology is the key to success)
|
||||
[2]: https://opensource.com/article/21/8/linux-terminal#options
|
||||
[3]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[4]: https://commons.apache.org/proper/commons-cli/usage.html
|
||||
[5]: https://maven.apache.org/
|
||||
[6]: https://commons.apache.org/proper/commons-cli/download_cli.cgi
|
||||
[7]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
|
||||
[8]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+option
|
||||
[9]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
|
||||
[10]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+parseexception
|
||||
[11]: https://developers.redhat.com/blog/2021/04/08/build-even-faster-quarkus-applications-with-fast-jar
|
||||
@@ -0,0 +1,169 @@
|
||||
[#]: subject: "Schedule a task with the Linux at command"
|
||||
[#]: via: "https://opensource.com/article/21/8/linux-at-command"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "geekpi"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
用 Linux 的命令来安排一个任务
|
||||
======
|
||||
at 命令是一种在特定时间和日期安排一次性任务的终端方法。
|
||||
![Team checklist][1]
|
||||
|
||||
计算机擅长[自动化][2],但不是每个人都知道如何使自动化工作。不过,能够在特定的时间为电脑安排一个任务,然后忘记它,这确实是一种奢侈。也许你有一个文件要在特定的时间上传或下载,或者你需要处理一批还不存在但保证在某个时间存在的文件,或者需要监控的设置,或者你只是需要一个友好的提醒,在下班回家的路上拿起面包和黄油。
|
||||
|
||||
That's what the `at`command is for.
|
||||
这就是 `at` 命令的用处。
|
||||
|
||||
### 什么是 Linux at 命令?
|
||||
|
||||
`at` 命令是 Linux 终端允许你在特定时间和日期安排一次性工作的方法。它是一种自发的自动化,在终端上很容易实现。
|
||||
|
||||
### 安装 at
|
||||
|
||||
在 Linux 上,`at` 命令可能已经安装了。你可以使用 `at -V` 命令来验证它是否已经安装。只要返回一个版本,就说明你已经安装了 `at`。
|
||||
|
||||
|
||||
```
|
||||
$ at -V
|
||||
at version x.y.z
|
||||
```
|
||||
|
||||
如果你试图使用 `at`,但没有找到该命令,大多数现代的 Linux 发行版会提供缺少的 `at` 包。
|
||||
|
||||
### 用 at 交互式地安排一个作业
|
||||
|
||||
当你使用 `at` 命令和你希望任务运行的时间时,你会打开一个交互式 `at` 提示。你可以输入你想在你指定的时间运行的命令。
|
||||
|
||||
如果有帮助的话,你可以把这个过程看作是一个日历应用,就像你可能在你的手机上使用的那样。首先,你在某一天的某个时间创建一个事件,然后指定你想要发生什么。
|
||||
|
||||
例如,尝试通过创建一个未来几分钟的任务来计划给自己的备忘录。让任务变得简单,以减少失败的可能性。要退出 `at` 提示,请按键盘上的 **Ctrl+D**。
|
||||
|
||||
|
||||
```
|
||||
$ at 11:20 AM
|
||||
warning: commands will be executed using /bin/sh
|
||||
at> echo "hello world" > ~/at-test.txt
|
||||
at> <EOT>
|
||||
job 3 at Mon Jul 26 11:20:00 2021
|
||||
```
|
||||
|
||||
正如你所看到的,`at` 使用直观和自然的时间定义。你不需要知道 24 小时制的时钟,也不需要把时间翻译成 UTC 或特定的 ISO 格式。一般来说,你可以使用你自然想到的任何符号,如 _noon_、_1:30 PM_、_13:37_ 等等,来描述你希望一个任务发生的时间。
|
||||
|
||||
等待几分钟,然后在你创建的文件上运行 `cat` 或者 `tac` 命令,验证你的任务是否已经运行:
|
||||
|
||||
|
||||
```
|
||||
$ cat ~/at-test.txt
|
||||
hello world
|
||||
```
|
||||
|
||||
### 用 at 安排一个任务
|
||||
|
||||
你不必使用 `at` 交互式提示符来安排任务。你可以使用 `echo` 或 `printf` 向它传送命令。在这个例子中,我使用了 _now_ 符号,以及我希望任务从现在开始延迟多少分钟:
|
||||
|
||||
|
||||
```
|
||||
`$ echo "echo 'hello again' >> ~/at-test.txt" | at now +1 minute`
|
||||
```
|
||||
|
||||
一分钟后,验证新的命令是否已被执行:
|
||||
|
||||
|
||||
```
|
||||
$ cat ~/at-test.txt
|
||||
hello world
|
||||
hello again
|
||||
```
|
||||
|
||||
### 时间表达式
|
||||
|
||||
`at` 命令在解释时间时是非常宽容的。你可以在许多格式中选择,这取决于哪一种对你来说最方便:
|
||||
|
||||
* `YYMMDDhhmm`[.ss]
|
||||
(缩写的年、月、日、小时、分钟,也可选择秒)
|
||||
* `CCYYMMDDhhmm`[.ss]
|
||||
(完整的年、月、日、时、分,也可选择的秒)
|
||||
* `now`
|
||||
* `midnight`
|
||||
* `noon`
|
||||
* `teatime`(4 PM)
|
||||
* `AM`
|
||||
* `PM`
|
||||
|
||||
|
||||
|
||||
时间和日期可以是绝对的,也可以加一个加号(_+_),使其与 _now_ 相对。当指定相对时间时,你可以使用你可能已经使用的词语:
|
||||
|
||||
* `minutes`
|
||||
* `hours`
|
||||
* `days`
|
||||
* `weeks`
|
||||
* `months`
|
||||
* `years`
|
||||
|
||||
|
||||
|
||||
### 时间和日期语法
|
||||
|
||||
`at` 命令对日期的输入相比日期不那么宽容。时间必须放在第一位,接着是日期,尽管日期默认为当前日期,并且只有在为未来某天安排任务时才需要。
|
||||
|
||||
这些是一些有效表达式的例子:
|
||||
|
||||
|
||||
```
|
||||
$ echo "rsync -av /home/tux me@myserver:/home/tux/" | at 3:30 AM tomorrow
|
||||
$ echo "/opt/batch.sh ~/Pictures" | at 3:30 AM 08/01/2022
|
||||
$ echo "echo hello" | at now + 3 days
|
||||
```
|
||||
|
||||
### 查看你的 at 队列
|
||||
|
||||
当你接受了 `at`,并且正在安排任务,而不是在桌子上的废纸上乱写乱画,你可能想查看一下你是否有任务还在队列中。
|
||||
|
||||
|
||||
要查看你的 `at` 队列,使用 `atq` 命令:
|
||||
|
||||
|
||||
```
|
||||
$ atq
|
||||
10 Thu Jul 29 12:19:00 2021 a tux
|
||||
9 Tue Jul 27 03:30:00 2021 a tux
|
||||
7 Tue Jul 27 00:00:00 2021 a tux
|
||||
```
|
||||
|
||||
要从队列中删除一个任务,使用 `atrm` 命令和任务号。例如,要删除任务 7:
|
||||
|
||||
|
||||
```
|
||||
$ atrm 7
|
||||
$ atq
|
||||
10 Thu Jul 29 12:19:00 2021 a tux
|
||||
9 Tue Jul 27 03:30:00 2021 a tux
|
||||
```
|
||||
|
||||
要看一个计划中的任务的实际内容,你需要查看 `at` spool。只有 root 用户可以查看 `at` spool,所以你必须使用 `sudo` 来查看 spool 或 `cat` 任何任务的内容。
|
||||
|
||||
### 用 Linux at 安排任务
|
||||
|
||||
`at` 系统是一个很好的避免忘记在一天中晚些时候运行一个作业,或者在你离开时让你的计算机为你运行一个作业的方法。与 `cron` 不同的是,它不像 `cron` 那样要求任务必须从现在起一直按计划运行到永远,因此它的语法比 `cron` 简单得多。
|
||||
|
||||
等下次你有一个希望你的计算机记住并管理它的小任务,试试 `at` 命令。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/8/linux-at-command
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [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/checklist_todo_clock_time_team.png?itok=1z528Q0y (Team checklist)
|
||||
[2]: https://opensource.com/article/20/11/orchestration-vs-automation
|
||||
Reference in New Issue
Block a user