分类 技术 下的文章

你最钟爱哪一个开源密码管理器?

Bitwarden 和 Proton Pass 是两个杰出的开源密码管理器。

Bitwarden 已经成为一个可靠的选择,运行稳定已经超过六年了,而 Proton Pass 则是较新的参与者。

你应该选哪一个呢?是选择已被大众信任的密码管理器还是选择由以隐私为导向的 Proton 新开发的产品?

我一直使用 Bitwarden 和带高级特性的 Proton Pass。主要使用的是 Bitwarden,但自 Proton Pass 推出后我也在试用它。

在这里,我会分享我对两者的使用体验,以及在选择密码管理器时需要了解的一些注意事项。

应用场景和应用程序的可用性

选用密码管理器时,应用程序的可用情况和你的使用场景起着重要角色。

你需要提些问题给自己:

  • 我在哪些地方(如桌面、移动设备或网页浏览器)需要密码管理器?
  • 它有提供哪些额外功能?
  • 是否坚持使用一个服务满足多种功能需求?

我会在文章的后半部分详细阐述这些功能特性。但首先,你需要确定你想在哪里使用密码管理器,以及是否希望单独保持密码管理器服务。

Proton Pass

在编写本文时,Proton Pass 仅以 浏览器扩展 形式存在,同时提供给 移动平台 使用。

你可以为 Mozilla Firefox、Google Chrome、Brave、Edge 及其它基于 Chrome 的浏览器获取扩展。你也可以选择在你的 安卓或 iOS 设备上安装它。

✅ 如果你不需要桌面应用的密码管理器,同时希望继续使用 Proton 提供的全部服务,那么 Proton Pass 是一个适合的选择。

Bitwarden

反之,Bitwarden 可以作为 桌面应用,支持在 Windows、 macOS、Linux 上运行。

此外,你可以为 Google Chrome、Firefox、Vivaldi, Opera、Edge、Tor 和 DuckDuckGo for Mac 获取相应的扩展。

对于移动平台来说,Bitwarden 支持 iPhone、Apple Watch 和安卓手机。你也可以从 F-Droid 安装到安卓设备上。

还不仅限于这些,你可以将 Bitwarden 作为一款 网页应用,或通过 命令行接口 来使用。

✅ 如果你需要一个能够在多个平台上无缝使用的密码管理器,那么 Bitwarden 就是你完美的选择。

用户体验

Bitwarden

Bitwarden 的用户体验简洁且低调。

以下是浏览器插件的界面样式:

虽然用户界面随着年份的推移有所改进建,但始终忠于其核心理念,也就是 注重简洁而不是华丽的 UI。

它不会打扰你的操作,始终提供熟悉的用户体验。

你可以在预设的 “dark”、“light”、“solarized dark” 和 “nord” 主题间自由切换。

无论你正在使用桌面应用、移动应用还是浏览器扩展,它都能给你带来同样的便利。

Proton Pass

Proton Pass 在其布局方面 颇具特色 ,每次你访问该扩展时,它都会给出一个详细的凭证概览。

有些用户可能更倾向于 现代化的 UI 处理方式,这完全看你的个人喜好。

我个人更倾向于 Bitwarden 的传统设计方式。

价格

你可以免费开始使用这两种服务。

Bitwarden 和 Proton Pass 在其免费计划中都不限制存储的登录凭证数量和可使用设备的数量。

如果你需要包括紧急访问、家庭共享、安全存储、二次验证、电子邮箱别名隐藏等特性,你需要升级为高级版。

Bitwarden 的年费仅为 10 美元,而其家庭计划(包含六个账户)的年费为 40 美元。这个价格对大多数人来说是极其实惠的。

相比之下,Proton Pass 的价格较高,其 Plus 计划的年费为 47.88 欧元。

不过,如果你使用了所有其他 Proton 的服务,并选择了 Proton 的无限制订阅,你就可以获得包括 Proton Pass、Mail、VPN、Drive 和 Calendar 在内的高级特性。

功能

这两个密码管理器功能都十分完善,因此每一种都能提供人们所需要的核心特性。

它们共同拥有的特性包括:

  • 密码生成器
  • 安全笔记
  • 自动填充
  • 卡片信息和登录凭证
  • 便于随时获取凭证的手机应用

接下来,让我来突出一下根据我个人的使用经验,每一种服务各自独特的优点:

Bitwarden

Bitwarden 的一项关键功能是其 “ 发送 Send ” 功能,它允许你发送一个文件(最大 500 MB)或一段文本/便笺给任何人,这都是通过一个安全连接实现的,并且在整个过程中都实现了端到端的加密。这项功能可以在 桌面应用、扩展插件和网页保险库 中使用。

你可以通过添加一段只有接收者知道的密码短语来保护这个链接。还有更多的自定义选项,例如设定链接的过期时间,或在文件被下载后销毁链接。

我不认为这是一种安全发送文件的方法,更多的是适合发送私人文件(如电子邮件附件)和文本文件。

接下来,Bitwarden 提供了一个 家庭计划,允许你与 其他五个账户 共享一个订阅。Proton Pass 并没有此类服务。

我想着重强调的另一个功能是:紧急访问。

因为密码管理器储存了你所有的登录信息,它就是一个包含 所有你的访问密钥 的地方。你可以设置紧急访问功能,以方便你信任的朋友或者家庭成员在你不幸出现紧急状况后访问你的密码。

当然,在授权用户访问你的账户之前,你可以设定一个期限以确认或拒绝这个访问请求。如果你没有采取任何行动,那么这个访问权限将会授予你的信任用户。

? 紧急联系人选项只能在 网络保险库 中访问。

值得注意的是: 这两种服务的密码生成器都包含历史记录,但 Bitwarden 保留历史时间更长,而 Proton Pass 只保留一天的历史记录。

其他功能差异包括:

  • 导出为 .CSV 文件
  • 调整自动填充行为
  • 访问网络保险库
  • 桌面应用
  • 记录身份信息

对于所有列出的功能,在我使用 Bitwarden 的过程中,我都没有遇到任何重大的问题。

我唯一注意到的问题:有时在我的安卓手机上,自动填充功能并没有在键盘应用中作为建议显示。当然,这取决于各个智能手机制造商提供的定制安卓体验,因此不一定是 Bitwarden 特有的问题。

Proton Pass

如果我们从“功能数量”上进行比较,Bitwarden 会占据优势。

但是,作为一个以隐私为重点的工具,Proton Pass 实现了密码管理器所有你需要的重要功能,甚至超越了这些。

得益于对 SimpleLogin 的专业研究,Proton Pass 支持生成电子邮件别名。

如果你不太了解:SimpleLogin 是最受欢迎的 工具之一,用于保护你的电子邮件地址。

所以,当 Proton Pass 集成了这个功能后,用户可以 便捷地创建电子邮件别名,并同时保存登录信息。你在 Proton Pass 上注册的电子邮件将会是实际的电子邮件地址。

我希望他们提供一个设定新的目标电子邮件地址的选项,这将使 Proton Pass 的额外费用更具价值。

此外,如果你是一位使用了部分或所有 Proton 服务的用户,使用 Proton Pass 将会是一种良好的用户体验。因为你无需为其他平台切换或注册。

使用 Proton Pass 还可以获得基本的 导入/导出,控制某些安全措施,修改密码管理器行为 的功能。

因此,对于 Proton 用户而言,Proton Pass 可以是一种一站式的解决方案。

是的,我暂时没有注意到任何关于其移动应用的问题,Proton Pass 到目前为止很好。

你应该选择哪个?

考虑到它们的共性,这主要取决于你个人的使用体验、预算(如果选择付费),以及功能集。

对于我个人的使用,我暂时没有看到 Proton Pass 替换 Bitwarden 的需要。

然而,如果我决定购买 Proton 的无限制订阅,或是更加投入到 Proton 的各项服务中去,我可能会放弃 Bitwarden。

? 你怎么认为呢?你认为 Proton Pass 值得额外付费吗,或者对于 Proton 的捆绑订阅你有什么看法?Bitwarden 是你的最爱吗?欢迎在下方评论分享你的想法。

(题图:MJ/a2f5d428-b853-4312-837c-9d66371dd5dc)


via: https://itsfoss.com/bitwarden-vs-proton-pass/

作者:Ankush Das 选题:lujun9972 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

本篇文章作为终端基础教程系列的一部分,介绍如何在 Linux 命令行中,利用绝对路径和相对路径实现目录切换。

Linux 的 cd 命令让你可以轻松切换文件夹(即目录)。只需提供你要切换到的文件夹路径即可。

cd path_to_directory

然而对于 Linux 新人来说,可能会在路径的指定上有所困扰。

首先,让我们解决这个问题。

理解 Linux 中的路径

在 Linux 文件系统中,路径是用来追踪文件位置的信息。所有的路径都从根目录开始,然后向下延伸。

你可以通过下面的方式查看当前所在的位置:

pwd

结果可能是类似于 /home/username 的输出。注意,这里的 username 将会是你自己的用户名。

你可以注意到,路径是由 / 符号和目录名组成的。比如路径 /home/abhishek/scripts, 表示 scripts 是在文件夹 abhishek 之内,而文件夹 abhishek 在 home 文件夹之内。要注意,第一个 '/' 是指根目录(即文件系统的开始处),后面的 '/' 则作为目录的分隔符。

Path in Linux

?️ 在终端中键入 ls /,然后按回车。你将会看到根目录下的所有内容,试试看!

接下来,让我们学习两种常见的路径指定方式:绝对路径和相对路径。

绝对路径:这种路径从根开始,然后一直扩展到你需要的位置。如果一个路径是以 / 开头,那就说明它是一个绝对路径。

相对路径:这是相对于你文件系统中当前位置的路径。如果我当前位置在 /home/abhishek,并且我需要去 /home/abhishek/Documents, 我只需要简单地切换到 Documents,而不需要指定整个绝对路径 /home/abhishek/Documents。

在我演示这两种路径的区别之前,有必要先熟悉两个特殊的目录标识:

  • . (单点)表示当前目录。
  • .. (双点)表示上一级目录,也就是当前目录的母目录。

这里有一张图形化的表示。

Absolute path vs relative path

利用 cd 命令变更目录

在你已对路径概念有所了解之后,我们来了解如何切换目录。

?️ 如果你仅键入 cd 并按回车键,无论当前位置在哪,系统都会将你带回主目录。试一试吧。

敲入以下命令,你就能看到主目录里的所有文件夹:

ls

这是我看到的情况:

abhishek@ituxedo:~$ ls
Desktop    Downloads  Pictures  Templates  VirtualBoxVMs
Documents  Music      Public    Videos

你的情况可能与此类似,但未必完全一样。

假如你希望跳转到 Documents 文件夹。由于它就在当前目录下,这里使用相对路径会比较方便:

cd Documents
? 注意,大部分 Linux 发行版预设的终端模拟器会在提示符本身显示出当前所在的位置。因此你不必频繁使用 pwd 指令来确认自己的位置。

Most Linux terminal prompts show the current location

假如你希望切换到位于主目录里的 Templates 文件夹。

你可以使用相对路径 ../Templates(.. 会让你返回到上层目录,即 /home/username,然后你就可以进入 Templates 文件夹了)。

但这次我们尝试使用绝对路径。请把下面的 abhishek 替换成你的用户名。

cd /home/abhishek/Templates

此刻你已经在 Templates 文件夹里了。如何前往 Downloads 文件夹呢?这次我们再使用相对路径:

cd ../Downloads

下面的图片会回顾一下你刚才学到的所有或有关目录切换的范例。

cd command example

? 别忘了你还可以使用终端的 tab 键自动补全功能。只需要键入命令或者文件夹名称的前几个字母,然后敲击 tab 键,系统就会尝试自动地补全命令或文件夹名称,或者给你显示出所有可能的选项。

故障解决

在 Linux 终端操作切换目录的过程中,你可能会遇到一些常见的错误。

文件或目录不存在

如果在你尝试切换目录时,出现类似下面的错误信息:

bash: cd: directory\_name: No such file or directory

那么你可能在路径或目录名称上犯了误解。这里有几点你需要注意的:

  • 请确定你输入的目录名中没有拼写错误。
  • Linux 系统对大小写敏感,因此,Downloads 和 downloads 会被识别为不同的目录。
  • 你可能未正确指定路径。可能你所在的位置与你预期的不同?或者你遗漏了绝对路径中的开头的 / 字符?

Common examples of "no such file or directory" error

非目录错误

如果你看到像下面这样的错误提示:

bash: cd: filename: Not a directory

这表示你尝试使用 cd 命令对一个文件进行操作,而不是一个目录(文件夹)。很明显,你不能像进入文件夹那样“进入”一个文件,因此会出现这样的错误。

Not a directory error with the cd command

参数过多

这是 Linux 新手常犯的另一个错误:

bash: cd: too many arguments

cd 命令只接受一个参数。也就是说,你只能对命令指定一个目录。

如果你指定了超过一个的参数,或者在路径中误加了空格,你就会看到这个错误。

Too many arguments error in Linux terminal

?? 如果你输入 cd -,它将会把你带到前一个目录。当你在两个相隔较远的地方切换时非常方便,可以避免再次输入长路径。

特殊目录符号

在结束这个教程之前,我想快速告诉你关于特殊符号 ~。在 Linux 中,~ 是用户主目录的捷径。

如果用户 abhi 运行它,~ 就会代表 /home/abhi,如果用户 prakash 运行,~ 就意味着 /home/prakash。

总结一下你在这个基础教程系列中学到的所有特殊目录标识:

符号描述
.当前目录
..上级目录
~主目录
-前一个目录

测试你的知识

下面是一些简单的练习,用来测试你刚刚学到的关于路径和 cd 命令的知识。

移动到你的主目录,并使用这个命令创建一个嵌套的目录结构:

mkdir -p sample/dir1/dir2/dir3

然后,一步步来试试这个:

  • 使用绝对路径或相对路径进入 dir3
  • 使用相对路径移动到 dir1
  • 使用你能想象到的最短路径进入 dir2
  • 使用绝对路径切换到 sample 目录
  • 返回你的主目录
? 想知道你是否全都做对了吗?欢迎分享你的答案。

现在你知道如何切换目录,是不是应该学习一下如何创建它们呢?

我强烈推荐你阅读这篇文章,了解一些关于终端和命令的小技巧。

如果你想了解 Linux 命令行的基础知识,记得关注我们的 Linux 终端基础系列教程的更多章节。


via: https://itsfoss.com/change-directories/

作者:Abhishek Prakash 选题:lkxed 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这篇文章将探索 Btrfs 中的透明文件系统压缩,以及它如何帮助节省存储空间。这篇文章是《Btrfs 详解》系列文章中的一篇。从 Fedora Linux 33 开始,Btrfs 就是 Fedora Workstation 和 Fedora Silverblue 的默认文件系统。

如果你错过了,这里是本系列的上一篇文章:Btrfs 详解:快照。

简介

很多人都经历过存储空间用完的情况。也许你想从互联网下载一个大文件,或者你需要快速从你的手机中复制些照片,然后操作突然失败。虽然存储空间成本正在稳步降低,但越来越多的设备要么制造时就是固定数量的存储容量,要么最终用户难以扩展其存储容量。

但当你的存储空间不足时你可以做什么呢?也许你会求助于云存储,或者你可以随身携带一些外部存储设备。

在这篇文章里我会研究该问题的另一种解决方案:透明的文件系统压缩,这是 Btrfs 的一个特性。理想情况下,这将解决你的存储问题,同时几乎不需要对你的系统进行修改!让我们来看看是如何做到的。

透明压缩的解释

首先,让我们来探寻 透明 压缩是什么意思。你可以通过像 gzip、xz 或者 bzip2 这些压缩算法去压缩文件。这通常是显式操作:你利用一个压缩工具并且让它操作你的文件。虽然根据文件的内容,节约了空间,这有一个主要的缺点:当你想读取文件或者修改的时候,你得先解压缩。

这不仅是一个乏味的过程,而且也暂时打破了你之前节省的空间。再者,你最终解压了你不想访问的那部分文件内容。明显有比这更好的方法!

相反,透明压缩发生在文件系统级别。在这里,压缩的文件对用户看起来像常规的未压缩文件一样。但是,它们是被压缩后存储在硬盘上的。这之所以可行,是因为操作系统仅仅选择性地访问那部分文件,并且确保在向磁盘写入更新时再次压缩它们。

这里的压缩是透明的在于它不被用户感知,除了在文件访问时可能的 CPU 负载小量增加。因此,你可以应用在已有的系统而不是进行硬件修改或者求助于云存储。

压缩算法对比

Btrfs 提供了多个压缩算法的选择。出于技术原因它不能选用任意的压缩算法。它现在支持:

  • zstd
  • lzo
  • zlib

好消息是,由于透明压缩的工作原理,你不需要安装这些程序供 Btrfs 使用。在下面的文章里,你会看到如何去运行一个简单的性能测试来对比压缩算法。但是,为了运行性能测试,你必须安装必要的可执行文件。事后不需要留着它们,所以你将使用 Podman 容器来确保不会在系统中留下任何痕迹。

注意 :因为 Btrfs 使用的压缩依赖于内核对这些压缩算法的(重新)实现,用户空间版本的算法得出的结果应该认为是粗略估计。

因为一次次敲重复的命令是枯燥的工作,我已经在 Gitlab 上准备了一个可以运行的 Bash 脚本 (https://gitlab.com/hartang/btrfs-compression-test)。这会用上面提到的每个算法在不同的压缩级别运行一次简单的压缩和解压缩。

首先,下载脚本:

$ curl -LO https://gitlab.com/hartang/btrfs-compression-test/-/raw/main/btrfs_compression_test.sh

下一步,启动一个 Fedora Linux 容器去挂载你当前的工作目录,以便你可以和主机交换文件同时在那里运行脚本:

$ podman run --rm -it --security-opt label=disable -v "$PWD:$PWD" \
    -w "$PWD" registry.fedoraproject.org/fedora:37

最后运行脚本:

$ chmod +x ./btrfs_compression_test.sh
$ ./btrfs_compression_test.sh

在我机器上的输出是这样:

[INFO] Using file 'glibc-2.36.tar' as compression target
[INFO] Target file 'glibc-2.36.tar' not found, downloading now...
################################################################### 100.0%
[ OK ] Download successful!
[INFO] Copying 'glibc-2.36.tar' to '/tmp/tmp.vNBWYg1Vol/' for benchmark...
[INFO] Installing required utilities
[INFO] Testing compression for 'zlib'

    Level | Time (compress) | Compression Ratio | Time (decompress)
-------+-----------------+-------------------+-------------------
        1 |         0.322 s |          18.324 % |           0.659 s
        2 |         0.342 s |          17.738 % |           0.635 s
        3 |         0.473 s |          17.181 % |           0.647 s
        4 |         0.505 s |          16.101 % |           0.607 s
        5 |         0.640 s |          15.270 % |           0.590 s
        6 |         0.958 s |          14.858 % |           0.577 s
        7 |         1.198 s |          14.716 % |           0.561 s
        8 |         2.577 s |          14.619 % |           0.571 s
        9 |         3.114 s |          14.605 % |           0.570 s

[INFO] Testing compression for 'zstd'

    Level | Time (compress) | Compression Ratio | Time (decompress)
-------+-----------------+-------------------+-------------------
        1 |         0.492 s |          14.831 % |           0.313 s
        2 |         0.607 s |          14.008 % |           0.341 s
        3 |         0.709 s |          13.195 % |           0.318 s
        4 |         0.683 s |          13.108 % |           0.306 s
        5 |         1.300 s |          11.825 % |           0.292 s
        6 |         1.824 s |          11.298 % |           0.286 s
        7 |         2.215 s |          11.052 % |           0.284 s
        8 |         2.834 s |          10.619 % |           0.294 s
        9 |         3.079 s |          10.408 % |           0.272 s
       10 |         4.355 s |          10.254 % |           0.282 s
       11 |         6.161 s |          10.167 % |           0.283 s
       12 |         6.670 s |          10.165 % |           0.304 s
       13 |        12.471 s |          10.183 % |           0.279 s
       14 |        15.619 s |          10.075 % |           0.267 s
       15 |        21.387 s |           9.989 % |           0.270 s

[INFO] Testing compression for 'lzo'

    Level | Time (compress) | Compression Ratio | Time (decompress)
-------+-----------------+-------------------+-------------------
        1 |         0.447 s |          25.677 % |           0.438 s
        2 |         0.448 s |          25.582 % |           0.438 s
        3 |         0.444 s |          25.582 % |           0.441 s
        4 |         0.444 s |          25.582 % |           0.444 s
        5 |         0.445 s |          25.582 % |           0.453 s
        6 |         0.438 s |          25.582 % |           0.444 s
        7 |         8.990 s |          18.666 % |           0.410 s
        8 |        34.233 s |          18.463 % |           0.405 s
        9 |        41.328 s |          18.450 % |           0.426 s

[INFO] Cleaning up...
[ OK ] Benchmark complete!

重要的是在根据脚本得出的数据做决定之前注意这些事情:

  • 不是所有的文件压缩效果都一样好。像图片或电影这种已经压缩过的现代多媒体格式不会压缩得更小。
  • 脚本中压缩和解压缩各进行一次。重复运行会产生稍微不同的输出。因此,时间应该被理解为是估计,而不是准确的测量。

鉴于输出的数据,我决定在我的系统上使用压缩级别 3 的 zstd 压缩算法。依据你的需求,你可能想使用更高的压缩级别(比如,如果你存储设备相当的慢)。要估算可达到的读/写速度,可以将源存档大小(约 260MB)除以(解)压缩时间。

压缩测试默认是对 GNU libc 2.36 源码进行的。如果你想看看对指定文件的效果,你可以通过第一个参数传递文件路径给脚本。记住文件一定要可以在容器内访问才行。

如果你想要测试其他东西或者执行更加详细的测试,可以阅读脚本的源码,根据需要修改它。

配置 Btrfs 压缩

Btrfs 里的透明文件系统压缩可以通过几种方式配置:

  • 作为挂载文件系统的挂载选项(可用于相同 Btrfs 文件系统的所有子卷)
  • 通过 Btrfs 文件属性
  • 在 btrfs filesystem defrag 时(不是永久的,不在这里介绍)
  • 通过 chattr 文件属性接口(不在这里介绍)

我只会介绍其中前两个。

在挂载时开启压缩

有一个 Btrfs 挂载选项可以开启文件压缩:

$ sudo mount -o compress=<ALGORITHM>:<LEVEL> ...

例如,去挂载一个文件系统,并使用等级 3 的 ztsd 算法去压缩,你可以写成:

$ sudo mount -o compress=zstd:3 ...

设置压缩等级是可选的。重要的是注意到 compress 挂载选项应用到整个 Btrfs 文件系统和它所有的子卷。此外,这是目前唯一支持的指定压缩等级的方式。

为了对文件系统的根应用压缩,必须在 /etc/fstab 上指定。例如,Fedora Linux 安装器,默认启用级别 1 的 zstd 压缩,在 /etc/fstab 里是这样:

$ cat /etc/fstab
[ ... ]
UUID=47b03671-39f1-43a7-b0a7-db733bfb47ff  /  btrfs   subvol=root,compress=zstd:1,[ ... ] 0 0

启用单个文件压缩

另外一种方式指定压缩的方法是通过 Btrfs 文件系统属性。使用下面的命令去查看文件、目录或子卷的压缩设置:

$ btrfs property get <PATH> compression

类似的,你可以像这样配置压缩:

$ sudo btrfs property set <PATH> compression <VALUE>

例如,对在 /etc 下所有文件启用 zlib 压缩:

$ sudo btrfs property set /etc compression zlib

你可以通过 man btrfs-property 得到支持值的列表。记住这个接口不允许指定压缩级别。除此之外,如果设置了一个压缩属性,它会覆盖挂载时的其他压缩配置。

压缩已有文件

在这时,如果你对现有文件系统采用压缩,然后通过 df 或类似命令检查空间利用率,你会发现什么都没变。这是因为 Btrfs 自身不会 “重新压缩” 所有已有的文件。压缩只会发生在往磁盘写新数据的时候。有一些方式去执行显式的重压缩:

  1. 等待,什么都不做:只要文件被修改并被写回磁盘,Btrfs 根据配置压缩新写入的文件内容。如果我们等待足够长,越来越多的文件被重写,在某个时间点就会被压缩。
  2. 移动文件到另一个文件系统然后移动回来:取决于你想压缩哪些文件,这可能是相当乏味的选项。
  3. 执行一次 Btrfs 碎片整理。

最后一个选项可能是最方便的,但是它会对已经包含快照的 Btrfs 文件系统提出警告:它会破坏快照间的共享范围。换句话来说,两个快照间所有的共享内容,或者一个快照和它的父子卷,在碎片整理操作后将保存多份。

因此,如果你在你的文件系统里已经有很多快照,你不应该对整个文件系统运行碎片整理。这也没有必要,因为如果你想的话,Btrfs 可以对特定的目录或者单个文件进行碎片整理。

你可以使用以下命令去执行一次碎片整理:

$ sudo btrfs filesystem defragment -r /path/to/defragment

例如,你想像这样去整理你主目录的碎片:

$ sudo btrfs filesystem defragment -r "$HOME"

如果有疑问,最好从碎片整理单个大文件开始,并在监视文件系统上的可用空间的同时继续处理越来越大的目录。

测量文件系统压缩

有时,你可能会想,文件系统压缩为你节省了多少空间。但如何判断呢?首先,要知道一个 Btrfs 文件系统是否在挂载时启用了压缩,你可以使用以下命令:

$ findmnt -vno OPTIONS /path/to/mountpoint | grep compress

如果你得到了结果,那么给定挂载点的文件系统就使用了压缩!下一步,compsize 命令会告诉你你的文件需要多少空间:

$ sudo compsize -x /path/to/examine

在我的主目录,结果是这样:

$ sudo compsize -x "$HOME"
Processed 942853 files, 550658 regular extents (799985 refs), 462779 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL       81%       74G          91G         111G
none       100%       67G          67G          77G
zstd        28%      6.6G          23G          33G

每一行告诉你应用到文件的压缩 “类型” 。* TOTAL 是下面所有行的总计。

另一方面,这些列告诉你我们的文件需要多少空间:

  • Disk Usage 是实际分配在硬盘上的空间,
  • Uncompressed 是如果没有压缩,文件所需要的空间,
  • Referenced 是所有未压缩文件加起来的总大小。

Referenced 可以与数据 Uncompressed 不同,比如一个文件之前被重复了,或者有快照共享内容。在上面的例子,你可以看到在我的硬盘上总计 91 GB 的未压缩文件仅占据了 74 GB 的存储。取决于在目录里存储的文件类型和应用的压缩等级,这些数字可以有很大差异。

文件压缩的其它注意事项

Btrfs 使用启发式算法去探测压缩文件。这是因为压缩文件通常效果不好,所以没有必要浪费 CPU 周期去尝试进一步的压缩。为了这个目的,Btrfs 在写入压缩数据到磁盘之前测量压缩率。如果文件的第一部分压缩效果不好,文件被标记为不可压缩并且不会有后续的压缩。

如果出于某些原因,你想 Btrfs 压缩所有写入的数据,你可以通过 compress-force 选项挂载一个 Btrfs 文件系统,像这样:

$ sudo mount -o compress-force=zstd:3 ...

当像这样配置,Btrfs 会用等级 3 的 zstd 算法压缩所有写入磁盘的数据。

一个重要的注意事项是挂载一个有很多数据并开启压缩的 Btrfs 文件系统会比没开启压缩耗时更长。这是有技术上的原因的,而且这是一个不会影响文件系统操作的正常行为。

总结

本文详细介绍了 Btrfs 中的透明文件系统压缩。这是一种内置的、相对廉价的方法,可以在不需要修改的情况下从现有硬件中获得一些额外的存储空间。

本系列文章的下一篇将讨论:

  • Qgroups - 限制文件系统大小
  • RAID - 替换 mdadm 配置

(LCTT 译注:后继文章尚未发布,一旦发布我们会尽快翻译。)

如果你想了解与 Btrfs 相关的其他主题,请查看 Btrfs 维基 [1] 和文档 [2] 。如果你还没有阅读本系列的前三篇文章,请不要忘记去看看!如果你觉得本文缺少某些内容,请在下面的评论中让我知道。我们下篇文章见!

参考资料

  1. https://btrfs.wiki.kernel.org/index.php/Main_Page ↩︎
  2. https://btrfs.readthedocs.io/en/latest/Introduction.html ↩︎

(题图:MJ/1a45064c-8da5-4b60-87f2-9886d6a3299e)


via: https://fedoramagazine.org/working-with-btrfs-compression/

作者:Andreas Hartmann 选题:lujun9972 译者:A2ureStone 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你有要说明的地方吗?请将它们添加到你的 Bash 脚本中。

在 Bash 脚本中添加注释是保持代码整洁且易于理解的最有效方法之一。

你可能会问为什么。

假设你的脚本包含一个复杂的正则表达式或多个复杂的代码块,在这种情况下,你可以添加注释,以便其他开发人员或你可以了解该代码块的含义。

注释掉部分代码也有助于调试脚本。

在本教程中,我将引导你了解在 Bash 脚本中添加注释的三种方法:

  • 单行注释
  • 行内评论
  • 多行注释

那么让我们从第一个开始。

Bash 中的单行注释

要添加单行注释,你必须将哈希符号(#)放在行的开头并编写注释。

这是一个简单的例子:

#!/bin/bash
# This is a comment
echo "Hello, World!"

执行时,注释将被忽略,当我执行上面的命令时,它看起来像这样:

? # 注释规则的唯一例外是脚本开头的 #!/bin/bash 行。它称为 释伴,用于指定运行脚本时要使用的解释器。有不同的 Shell,语法也可能不同。因此,一个好的做法是指定脚本是为哪个 Shell 编写的。例如,如果是 ksh,则可以使用 #!/bin/ksh.

Bash 脚本中的内联注释

或者,你可以将注释放在代码块内以记录该特定行的用途。

? # 之后的任何内容在该行结束之前都不会执行,因此请确保在代码末尾添加注释。

这是一个简单的例子:

#!/bin/bash
echo "Hello, World!" #Prints hello world

Bash 中的多行注释

? Bash 中没有内置的多行注释功能。但是,有一些解决方法可以实现多行注释效果。

顾名思义,Bash 脚本中的多行注释允许你在多行中编写注释,或者通过将它们放在多行注释部分来阻止执行代码块:

  1. 在每行的开头使用 #
  2. 冒号表示法(使用冒号后跟单引号)
  3. 现场文档(使用 << 后跟分隔符)

那么让我们从第一个开始。

1、对块注释的每一行使用 #

如果你的目的是解释脚本的一部分,我建议使用此方法。毕竟,# 才是真正的注释功能。

这也是许多开发人员使用的方法。

假设你必须在一开始就解释脚本的用途、作者信息或许可信息。你可以这样写:

#!/bin/bash

######################################
## This script is used for scanning ##
## local network                    ##
## Licensed under GPL 2.0           ##
######################################

这个 Bash 脚本的其它部分……

当你想说明 Bash 脚本的行为方式时这不错。如果你正在调试 Bash 脚本并希望隐藏部分脚本,则在所需代码的每一行开头添加 # 并在调试后将其删除是一项耗时的任务。

接下来的两节将帮助你做到这一点。

2、冒号表示法

要使用冒号表示法,请在 : ' 和结束的 ' 之间编写块注释,如下所示:

#!/bin/bash

: '
This is how you can use colon notation
And this line too will be ignored
'
echo "GOODBYE"

当你执行上面的脚本时,它应该只打印 GOODBYE。

3、现场文档

到目前为止,这是在 Bash 中编写多行注释的最流行的方法,你可以使用 << 后跟分隔符(一组用于指定注释开始和结束的字符)。

(LCTT 译注:在编程领域,“here document” 是一个常见的术语,特指在脚本语言(如 Perl、Bash)中,能够直接在代码内部嵌入并处理一个数据块或文本串的技术。尽管传统上我们将它翻译为“嵌入式文档” 或不翻译,但这个译法似乎并不能完全地体现出原文的感觉和含义。为了让这个概念变得更为直观和易理解,我们建议将 “here document” 翻译为 “现场文档”。“现场”相比于“嵌入式”,更好的传达了文档就在代码的当前位置,或代码“现场”的含义。这样的译法也与原文 “here document” 中 “here”(这里)的含义更为契合。我们希望这个译法能够在未来得到更广泛的使用和认可,让编程的世界因语言的精准而变得更美好。PS., 该译法和解释得到了 ChatGPT 的建议和生成。)

使用方法如下:

#!/bin/bash

<<DELIMITER
Comment line 1
Comment line 2
DELIMITER

echo "Hello, World!"

还困惑吗? 这是一个简单的例子:

#!/bin/bash

<<COMMENT
This is a multi-line comment using a here document.
You can add as many lines as you want between <<COMMENT and the terminating keyword.
This block won't be executed by the shell.
COMMENT

echo "Hello, World!"

在上面的示例中,我使用了 COMMENT 作为分隔符,但你可以使用任何内容,但要确保它从注释中脱颖而出,否则会造成混乱。

当我执行上面的脚本时,它给出了以下输出:

正如你所看到的,它忽略了从 <<COMMENT 到 COMMENT 的所有内容。

我希望本指南对你有所帮助。

(题图:MJ/7c2a3ef4-5256-405e-b757-23e0ba1f0bc5)


via: https://itsfoss.com/bash-comments/

作者:Sagar Sharma 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

作为一位 Linux 管理员,你需要跟踪所有用户的活动。当服务器发生故障时,你可以分析和查看用户活动,以便寻找问题的根源。监控 Linux 用户有多种方式。本指南将专门讨论 GNU 记账工具,这是一项用于监视 Linux 用户活动的实用工具。

什么是记账工具?

记账工具可以提供诸如 Linux 系统中的连接、已执行的程序以及系统资源的使用等有底系统使用信息。这些记账工具可以通过 psacct 或 acct 软件包安装。

psacct 和 acct 实际上是相同的。在基于 RPM 的系统中,它以 psacct 的形式存在;而在基于 DEB 的系统中,它作为 acct 提供。

你可能想知道 psacct 或 acct 工具的作用。通常,用户在命令行的历史记录会保存在他们的 $HOME 目录下的 .bash_history 文件中。有些用户可能会尝试编辑、修改或删除这些历史记录。

然而,即使他们完全 清除了命令行历史,记账工具依然能够获取用户活动信息。这是因为,所有进程记账文件都由 root 用户拥有,而普通用户则无法进行编辑。

Linux 中如何安装 psacct 或 acct

psacct/acct 被打包在多种流行的 Linux 发行版本中。

如果要在 Alpine Linux 中安装 psacct,请运行以下命令:

$ sudo apk add psacct

如果在 Arch Linux 及其变体版本(如 EndeavourOS 和 Manjaro Linux)中安装 acct,请运行以下命令:

$ sudo pacman -S acct

在 Fedora、RHEL 及其衍生版本(如 CentOS、AlmaLinux 和 Rocky Linux)中安装 psacct,请运行以下命令:

$ sudo dnf install psacct

在 RHEL 6 以及更早版本中,你应当使用 yum 命令而非 dnf 来安装 psacct。

$ sudo yum install psacct

在 Debian、Ubuntu 以及 Linux Mint 中,通过如下命令来安装 acct:

$ sudo apt install acct

若在 openSUSE 中安装 acct,则运行:

$ sudo zypper install acct

启动 psacct/acct 服务

要启用并开启 psacct 服务,请执行以下命令:

$ sudo systemctl enable psacct

接着启动 psacct 服务:

$ sudo systemctl start psacct

如果你需要检查 psacct 服务是否已加载和激活,可以运行:

$ sudo systemctl status psacct

在基于 DEB 的系统中,安装完成之后,acct 服务会自动启动。

如果你想验证 acct 服务是否已经启动,可以执行以下命令:

$ sudo systemctl status acct
● acct.service - Kernel process accounting
     Loaded: loaded (/lib/systemd/system/acct.service; enabled; vendor preset: enabled)
     Active: active (exited) since Thu 2022-10-13 16:06:35 IST; 28s ago
       Docs: man:accton(8)
    Process: 3241 ExecStart=/usr/sbin/accton /var/log/account/pacct (code=exited, status=0/SUCCESS)
   Main PID: 3241 (code=exited, status=0/SUCCESS)
        CPU: 879us

Oct 13 16:06:35 ubuntu2204 systemd[1]: Starting Kernel process accounting...
Oct 13 16:06:35 ubuntu2204 accton[3241]: Turning on process accounting, file set to '/var/log/account/pacct'.
Oct 13 16:06:35 ubuntu2204 systemd[1]: Finished Kernel process accounting.

利用 psacct 或 acct 来监测 Linux 中的用户活动

psacct(进程记账)软件包包含以下用来监测用户和进程活动的工具:

  • ac - 提供用户登录时间的统计信息。
  • lastcomm - 展示先前执行过的命令的信息。
  • accton - 开启或关闭进程记账。
  • dump-acct - 把 accton 的输出文件转化为易读的格式。
  • dump-utmp - 以易读的方式打印 utmp 文件。
  • sa - 汇总信息,关于先前执行的命令。

现在就让我们一起了解如何通过每个工具来监控 Linux 用户的活动。

1、使用 ac 命令

ac 工具可以为你提供以小时为单位的连接时间报告,这样你就能知道用户或一组用户连接到系统的时长。

1.1、展示所有用户的总连接时间
$ ac

上述命令会显示所有用户的总连接时间(单位为小时)。

total       52.91

展示所有用户的总连接时间

1.2、按日期排序显示所有用户的总连接时间

你可以通过使用 -d 参数,按日期排序显示所有用户的连接时间,操作如下:

$ ac -d

示例输出:

May 11    total        4.29
May 13    total        3.23
May 14    total        7.66
May 15    total        8.97
May 16    total        0.52
May 20    total        4.09
May 24    total        1.32
Jun  9    total       15.18
Jun 10    total        2.97
Jun 22    total        2.61
Jul 19    total        1.95
Today    total        0.29

按日期排序显示所有用户的总时间

1.3、获取各个用户的总连接时间

使用 -p 参数,你可以查看每位用户各自在系统中总的连接时长。

$ ac -p

示例输出:

ostechnix                           52.85
root                                 0.51
total       53.36

获取各个用户的总连接时间

1.4、显示指定用户的总连接时间

你还可以显示特定用户的总登录时间。

$ ac ostechnix

示例输出:

total       52.95
1.5、显示特定用户各日期的总连接时间

要按日期查看某个用户的登录时间,可以运行:

$ ac -d ostechnix

示例输出:

May 11    total        4.29
May 13    total        3.23
May 14    total        7.66
May 15    total        8.97
May 16    total        0.01
May 20    total        4.09
May 24    total        1.32
Jun  9    total       15.18
Jun 10    total        2.97
Jun 22    total        2.61
Jul 19    total        1.95
Today    total        0.68

显示某个用户各日期的总连接时间

如需更多详情,可参考手册页面。

$ man ac

2、lastcomm 命令使用示例

lastcomm 工具用于列出过去执行过的命令,它会按执行的最近程度将命令列在前面。

2.1、展示过去执行的命令
$ lastcomm

示例输出:

systemd-hostnam  S     root     __         0.06 secs Thu Oct 13 17:21
systemd-localed  S     root     __         0.06 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
awk                    ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
uname                  ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
sed                    ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
grep                   ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
grep                   ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
bash              F    ostechni pts/1      0.00 secs Thu Oct 13 17:22
[...]
2.2、打印特定用户先前执行的命令

上述命令显示的是所有用户的命令。要显示特定用户以前执行的命令,可以使用下面的命令:

$ lastcomm ostechnix

示例输出:

less                   ostechni pts/1      0.00 secs Thu Oct 13 17:26
lastcomm               ostechni pts/1      0.00 secs Thu Oct 13 17:26
lastcomm               ostechni pts/1      0.00 secs Thu Oct 13 17:26
lastcomm               ostechni pts/1      0.00 secs Thu Oct 13 17:26
gdbus                X ostechni __         0.00 secs Thu Oct 13 17:24
lastcomm               ostechni pts/1      0.00 secs Thu Oct 13 17:24
ac                     ostechni pts/1      0.00 secs Thu Oct 13 17:24
update-notifier   F    ostechni __         0.00 secs Thu Oct 13 17:23
apport-checkrep        ostechni __         0.06 secs Thu Oct 13 17:23
apport-checkrep        ostechni __         0.05 secs Thu Oct 13 17:23
systemctl              ostechni __         0.00 secs Thu Oct 13 17:23
apt-check              ostechni __         0.81 secs Thu Oct 13 17:23
dpkg                   ostechni __         0.00 secs Thu Oct 13 17:23
ischroot               ostechni __         0.00 secs Thu Oct 13 17:23
dpkg                   ostechni __         0.00 secs Thu Oct 13 17:23
[...]
2.3、打印特定命令的执行次数

你还可以查看特定命令被执行的次数。

$ lastcomm apt

示例输出:

apt              S     root     pts/2      0.70 secs Thu Oct 13 16:06
apt               F    root     pts/2      0.00 secs Thu Oct 13 16:06
apt               F    root     pts/2      0.00 secs Thu Oct 13 16:06

如上述输出所示,root 用户执行了 apt 命令三次。

更详细的信息,可参考手册页:

$ man lastcomm

3、sa 命令示例

sa 实用程序将总结关于先前执行的命令的信息。

3.1、打印所有命令的总结
$ sa

示例输出:

1522    1598.63re       0.23cp         0avio     32712k
    139     570.90re       0.05cp         0avio     36877k   ***other*
     38     163.63re       0.05cp         0avio    111445k   gdbus
      3       0.05re       0.04cp         0avio     12015k   apt-check
     27     264.27re       0.02cp         0avio         0k   kworker/dying*
      2      51.87re       0.01cp         0avio   5310464k   Docker Desktop
      5       0.03re       0.01cp         0avio       785k   snap-confine
      8      59.48re       0.01cp         0avio     85838k   gmain
      5     103.94re       0.01cp         0avio    112720k   dconf worker
     24       3.38re       0.00cp         0avio      2937k   systemd-udevd*
      7       0.01re       0.00cp         0avio     36208k   5
      3       1.51re       0.00cp         0avio      3672k   systemd-timedat
      2       0.00re       0.00cp         0avio     10236k   apport-checkrep
      2       0.01re       0.00cp         0avio   4316160k   ThreadPoolForeg*
      2       0.00re       0.00cp         0avio      8550k   package-data-do
      3       0.79re       0.00cp         0avio      2156k   dbus-daemon
     12       0.00re       0.00cp         0avio     39631k   ffmpeg
[...]
3.2、查看进程数量和 CPU 分钟数

要打印基于每个用户的进程数量和 CPU 分钟数,运行带 -m 标志的 sa 命令:

$ sa -m

示例输出:

1525    1598.63re       0.23cp         0avio     32651k
root                                  561     647.23re       0.09cp         0avio      3847k
ostechnix                             825     780.79re       0.08cp         0avio     47788k
gdm                                   117      13.43re       0.06cp         0avio     63715k
colord                                  2      52.01re       0.00cp         0avio     89720k
geoclue                                 1       1.01re       0.00cp         0avio     70608k
jellyfin                               12       0.00re       0.00cp         0avio     39631k
man                                     1       0.00re       0.00cp         0avio      3124k
kernoops                                4     104.12re       0.00cp         0avio      3270k
sshd                                    1       0.05re       0.00cp         0avio      3856k
whoopsie                                1       0.00re       0.00cp         0avio      8552k
3.3、打印用户 ID 和命令名称

对于账户文件中的每个命令,使用 -u 标志打印用户 ID 和命令名称。

$ sa -u

示例输出:

root       0.00 cpu      693k mem      0 io accton          
root       0.00 cpu     3668k mem      0 io systemd-tty-ask 
root       0.00 cpu     3260k mem      0 io systemctl       
root       0.01 cpu     3764k mem      0 io deb-systemd-inv 
root       0.00 cpu      722k mem      0 io acct.postinst   
root       0.00 cpu      704k mem      0 io rm              
root       0.00 cpu      939k mem      0 io cp              
root       0.00 cpu      704k mem      0 io rm              
root       0.00 cpu      951k mem      0 io find            
root       0.00 cpu      911k mem      0 io gzip            
root       0.00 cpu      722k mem      0 io sh              
root       0.00 cpu      748k mem      0 io install-info    
root       0.00 cpu      911k mem      0 io gzip            
[...]

如需更多详细信息,请参考手册页:

$ man sa

4、dump-acct 和 dump-utmp 命令

dump-acct 实用工具将 accton 格式的输出文件显示为人类可读的格式。

$ dump-acct /var/account/pacct

dump-utmp 将 utmp 文件显示为人类可读的格式。

$ dump-utmp /var/run/utmp

如需了解更多详情,请参考手册页:

$ man dump-acct
$ man dump-utmp

5、accton 命令

accton 命令将允许你开启或关闭记账。

要开启进程记账,请运行:

$ accton on

要关闭它,运行:

$ accton off

如需了解更多详情,请参考手册页:

$ man accton

总结

每个 Linux 管理员都应该知道 GNU 记账实用程序,以便注意所有用户的行为。在故障排除时,这些实用程序会非常有帮助。

资源

(题图:MJ/da3f7e79-2a53-4121-a2ed-d63a22c3d3f4)


via: https://ostechnix.com/monitor-user-activity-linux/

作者:sk 选题:lkxed 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

缺少了 GNOME 中的最小化按钮选项?下面教你如何轻松找回它。

与 Ubuntu 不同,Fedora 和 Arch Linux 等发行版为你提供了原生的 GNOME,但可能让你烦恼的一件事是应用窗口上缺少最小化和最大化按钮。

No minimize or maximize button in application windows, only close button

GNOME 希望你使用应用切换器(Alt+Tab)或使用活动区(Super 键)在正在运行的应用之间切换,而不是最小化它。

好消息是,如果你不喜欢的话,你不必这样。

让我分享一下如何使用 GUI 和命令行选项恢复 GNOME 中的最小化和最大化按钮。

方法 1:使用 GNOME 优化工具启用最小化和最大化按钮

GNOME 优化 Tweaks 工具允许你自定义 GNOME 的各个方面。启用最小化窗口按钮就是其中之一。

首先使用发行版的包管理器安装 GNOME 优化工具。

运行应用并从左侧边栏进入 Windows 标题栏。你将在此处看到添加最小化和最大化按钮的选项,

你可以选择其中一个或两者。如果你不再需要它,你可以在 GNOME 调整工具中以相同的方式禁用按钮。

? 如果需要,你还可以选择将这些控制按钮放在左侧。该选项位于标题栏按钮选项的末尾。

方法 2:使用命令行启用最小化和最大化按钮

gsettings 命令可以选择更改按钮布局并添加最小化和最大化按钮。

gsettings set org.gnome.desktop.wm.preferences button-layout ":minimize,maximize,close"

正如你所猜测的,如果你想要禁用任何按钮,你可以运行相同的命令,但从命令中省略不需要的按钮。

? 你还可以通过将冒号放在命令的右侧来将 Windows 控制按钮移动到左侧:

gsettings set org.gnome.desktop.wm.preferences button-layout "close,minimize,maximize:"

受到 macOS 的启发并不总是一件好事

显然,这种“无最小化按钮”的设计灵感来自苹果的 macOS。我记得大约 10 年前,macOS 曾经将窗口控件放在左侧。因此 Ubuntu Unity 也尝试默认将控件保留在左侧。

苹果很奇怪。他们大多数时候都有很好的设计,但有时他们会优先考虑设计而不是使用体验。“Magic Mouse” 就是一个例子。

“Magic Mouse 深受用户喜爱”。你确定?

— Stuart (@stuwieface) 2021 年 4 月 20 日

我不明白为什么 GNOME 开发者需要从各种设计中获得灵感,尤其是那些糟糕的设计。

但那只是我的个人意见。我很高兴有一个快速简单的解决方案可以恢复 GNOME 中的最小化和最大化按钮。

(题图:MJ/f8ce0441-3d9b-498c-8e23-e48f7a90d040)


via: https://itsfoss.com/gnome-minimize-button/

作者:Abhishek Prakash 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出