如何在 FreeBSD 上设置 PF 防火墙来保护 Web 服务器

![](/data/attachment/album/201809/15/223918yw8s808787d6707q.jpg)

我是从 Linux 迁移过来的 FreeBSD 新用户，Linux 中使用的是 netfilter 防火墙框架（LCTT 译注：netfilter 是由 Rusty Russell 提出的 Linux 2.4 内核防火墙框架）。那么在 FreeBSD 上，我该如何设置 PF 防火墙，来保护只有一个公共 IP 地址和端口的 web 服务器呢？

PF 是<ruby> 包过滤器 <rt>  packet filter </rt></ruby>的简称。它是为 OpenBSD 开发的，但是已经被移植到了 FreeBSD 以及其它操作系统上。PF 是一个包状态过滤引擎。在这篇教程中，我将向你展示如何在 FreeBSD 10.x 以及 11.x 中设置 PF 防火墙，从而来保护 web 服务器。

### 第一步：开启 PF 防火墙

你需要把下面这几行内容添加到文件 `/etc/rc.conf` 文件中：

```
# echo 'pf_enable="YES"' >> /etc/rc.conf
# echo 'pf_rules="/usr/local/etc/pf.conf"' >> /etc/rc.conf
# echo 'pflog_enable="YES"' >> /etc/rc.conf
# echo 'pflog_logfile="/var/log/pflog"' >> /etc/rc.conf
```

在这里：

1. `pf_enable="YES"` - 开启 PF 服务
2. `pf_rules="/usr/local/etc/pf.conf"` - 从文件 `/usr/local/etc/pf.conf` 中读取 PF 规则
3. `pflog_enable="YES"` - 为 PF 服务打开日志支持
4. `pflog_logfile="/var/log/pflog"` - 存储日志的文件，即日志存于文件 `/var/log/pflog` 中

### 第二步：在 `/usr/local/etc/pf.conf` 文件中创建防火墙规则

输入下面这个命令打开文件（超级用户模式下）：

```
# vi /usr/local/etc/pf.conf
```

在文件中添加下面这些 PF 规则集：

```
# vim: set ft=pf
# /usr/local/etc/pf.conf

## 设置公共端口 ##
ext_if="vtnet0"

## 设置服务器公共 IP 地址 ##
ext_if_ip="172.xxx.yyy.zzz"

## 设置并删除下面这些公共端口上的 IP 范围 ##
martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
          10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
          0.0.0.0/8, 240.0.0.0/4 }"

## 设置 http(80)/https (443) 端口 ##
webports = "{http, https}"

## 启用下面这些服务 ##
int_tcp_services = "{domain, ntp, smtp, www, https, ftp, ssh}"
int_udp_services = "{domain, ntp}"

## 跳过回环端口 - 跳过端口上的所有 PF 处理 ##
set skip on lo

## 设置 PF 应该统计的端口信息，如发送/接收字节数，通过/禁止的包的数目 ##
set loginterface $ext_if

## 设置默认策略 ##
block return in log all
block out all

# 基于 IP 分片的错误处理来防御攻击
scrub in all

# 删除所有不可达路由地址
block drop in quick on $ext_if from $martians to any
block drop out quick on $ext_if from any to $martians

## 禁止欺骗包
antispoof quick for $ext_if

# 打开 SSH 端口，SSH 服务仅从 VPN IP 139.xx.yy.zz 监听 22 号端口
# 出于安全原因，我不允许/接收 SSH 流量
pass in quick on $ext_if inet proto tcp from 139.xxx.yyy.zzz to $ext_if_ip port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.xxx.yyy.zzz"
## 使用下面这些规则来为所有来自任何 IP 地址的用户开启 SSH 服务 #
## pass in inet proto tcp to $ext_if port ssh
### [ OR ] ###
## pass in inet proto tcp to $ext_if port 22

# Allow Ping-Pong stuff. Be a good sysadmin
pass inet proto icmp icmp-type echoreq

# All access to our Nginx/Apache/Lighttpd Webserver ports
pass proto tcp from any to $ext_if port $webports

# 允许重要的发送流量
pass out quick on $ext_if proto tcp to any port $int_tcp_services
pass out quick on $ext_if proto udp to any port $int_udp_services

# 在下面添加自定义规则
```

保存并关闭文件。欢迎来参考我的[规则集](https://github.com/nixcraft/pf.conf/blob/master/pf.conf)。如果要检查语法错误，可以运行：

```
# service pf check
```

或

```
/etc/rc.d/pf check
```

或

```
# pfctl -n -f /usr/local/etc/pf.conf
```

### 第三步：开始运行 PF 防火墙

命令如下。请小心，如果是基于 SSH 的会话，你可能会和服务器断开连接。

#### 开启 PF 防火墙：

```
# service pf start
```

#### 停用 PF 防火墙：

```
# service pf stop
```

#### 检查语法错误：

```
# service pf check
```

#### 重启服务：

```
# service pf restart
```

#### 查看 PF 状态：

```
# service pf status
```

示例输出：

```
Status: Enabled for 0 days 00:02:18           Debug: Urgent

Interface Stats for vtnet0            IPv4             IPv6
  Bytes In                           19463                0
  Bytes Out                          18541                0
  Packets In
    Passed                             244                0
    Blocked                              3                0
  Packets Out
    Passed                             136                0
    Blocked                             12                0

State Table                          Total             Rate
  current entries                        1
  searches                             395            2.9/s
  inserts                                4            0.0/s
  removals                               3            0.0/s
Counters
  match                                 19            0.1/s
  bad-offset                             0            0.0/s
  fragment                               0            0.0/s
  short                                  0            0.0/s
  normalize                              0            0.0/s
  memory                                 0            0.0/s
  bad-timestamp                          0            0.0/s
  congestion                             0            0.0/s
  ip-option                              0            0.0/s
  proto-cksum                            0            0.0/s
  state-mismatch                         0            0.0/s
  state-insert                           0            0.0/s
  state-limit                            0            0.0/s
  src-limit                              0            0.0/s
  synproxy                               0            0.0/s
  map-failed                             0            0.0/s
```

#### 开启/关闭/重启 pflog 服务的命令

输入下面这些命令：

```
# service pflog start
# service pflog stop
# service pflog restart
```

### 第四步：`pfctl` 命令的简单介绍

你需要使用 `pfctl` 命令来查看 PF 规则集和参数配置，包括来自<ruby> 包过滤器 <rt>  packet filter </rt></ruby>的状态信息。让我们来看一下所有常见命令：

#### 显示 PF 规则信息

```
# pfctl -s rules
```

示例输出：

```
block return in log all
block drop out all
block drop in quick on ! vtnet0 inet from 172.xxx.yyy.zzz/24 to any
block drop in quick inet from 172.xxx.yyy.zzz/24 to any
pass in quick on vtnet0 inet proto tcp from 139.aaa.ccc.ddd to 172.xxx.yyy.zzz/24 port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.aaa.ccc.ddd"
pass inet proto icmp all icmp-type echoreq keep state
pass out quick on vtnet0 proto tcp from any to any port = domain flags S/SA keep state
pass out quick on vtnet0 proto tcp from any to any port = ntp flags S/SA keep state
pass out quick on vtnet0 proto tcp from any to any port = smtp flags S/SA keep state
pass out quick on vtnet0 proto tcp from any to any port = http flags S/SA keep state
pass out quick on vtnet0 proto tcp from any to any port = https flags S/SA keep state
pass out quick on vtnet0 proto tcp from any to any port = ftp flags S/SA keep state
pass out quick on vtnet0 proto tcp from any to any port = ssh flags S/SA keep state
pass out quick on vtnet0 proto udp from any to any port = domain keep state
pass out quick on vtnet0 proto udp from any to any port = ntp keep state
```

#### 显示每条规则的详细内容

```
# pfctl -v -s rules
```

在每条规则的详细输出中添加规则编号：

```
# pfctl -vvsr show
```

#### 显示状态信息

```
# pfctl -s state
# pfctl -s state | more
# pfctl -s state | grep 'something'
```

#### 如何在命令行中禁止 PF 服务

```
# pfctl -d
```

#### 如何在命令行中启用 PF 服务

```
# pfctl -e
```

#### 如何在命令行中刷新 PF 规则/NAT/路由表

```
# pfctl -F all
```

示例输出：

```
rules cleared
nat cleared
0 tables deleted.
2 states cleared
source tracking entries cleared
pf: statistics cleared
pf: interface flags reset
```

#### 如何在命令行中仅刷新 PF 规则

```
# pfctl -F rules
```

#### 如何在命令行中仅刷新队列

```
# pfctl -F queue
```

#### 如何在命令行中刷新统计信息（它不是任何规则的一部分）

```
# pfctl -F info
```

#### 如何在命令行中清除所有计数器

```
# pfctl -z clear
```

### 第五步：查看 PF 日志

PF 日志是二进制格式的。使用下面这一命令来查看：

```
# tcpdump -n -e -ttt -r /var/log/pflog
```

示例输出：

```
Aug 29 15:41:11.757829 rule 0/(match) block in on vio0: 86.47.225.151.55806 > 45.FOO.BAR.IP.23: S 757158343:757158343(0) win 52206 [tos 0x28]
Aug 29 15:41:44.193309 rule 0/(match) block in on vio0: 5.196.83.88.25461 > 45.FOO.BAR.IP.26941: S 2224505792:2224505792(0) ack 4252565505 win 17520 (DF) [tos 0x24]
Aug 29 15:41:54.628027 rule 0/(match) block in on vio0: 45.55.13.94.50217 > 45.FOO.BAR.IP.465: S 3941123632:3941123632(0) win 65535
Aug 29 15:42:11.126427 rule 0/(match) block in on vio0: 87.250.224.127.59862 > 45.FOO.BAR.IP.80: S 248176545:248176545(0) win 28200 <mss 1410,sackOK,timestamp 1044055305 0,nop,wscale 8> (DF)
Aug 29 15:43:04.953537 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7475: S 1164335542:1164335542(0) win 1024
Aug 29 15:43:05.122156 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7475: R 1164335543:1164335543(0) win 1200
Aug 29 15:43:37.302410 rule 0/(match) block in on vio0: 94.130.12.27.18080 > 45.FOO.BAR.IP.64857: S 683904905:683904905(0) ack 4000841729 win 16384 <mss 1460>
Aug 29 15:44:46.574863 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7677: S 3451987887:3451987887(0) win 1024
Aug 29 15:44:46.819754 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7677: R 3451987888:3451987888(0) win 1200
Aug 29 15:45:21.194752 rule 0/(match) block in on vio0: 185.40.4.130.55910 > 45.FOO.BAR.IP.80: S 3106068642:3106068642(0) win 1024
Aug 29 15:45:32.999219 rule 0/(match) block in on vio0: 185.40.4.130.55910 > 45.FOO.BAR.IP.808: S 322591763:322591763(0) win 1024
Aug 29 15:46:30.157884 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6511: S 2412580953:2412580953(0) win 1024 [tos 0x28]
Aug 29 15:46:30.252023 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6511: R 2412580954:2412580954(0) win 1200 [tos 0x28]
Aug 29 15:49:44.337015 rule 0/(match) block in on vio0: 189.219.226.213.22640 > 45.FOO.BAR.IP.23: S 14807:14807(0) win 14600 [tos 0x28]
Aug 29 15:49:55.161572 rule 0/(match) block in on vio0: 5.196.83.88.25461 > 45.FOO.BAR.IP.40321: S 1297217585:1297217585(0) ack 1051525121 win 17520 (DF) [tos 0x24]
Aug 29 15:49:59.735391 rule 0/(match) block in on vio0: 36.7.147.209.2545 > 45.FOO.BAR.IP.3389: SWE 3577047469:3577047469(0) win 8192 <mss 1460,nop,wscale 8,nop,nop,sackOK> (DF) [tos 0x2 (E)]
Aug 29 15:50:00.703229 rule 0/(match) block in on vio0: 36.7.147.209.2546 > 45.FOO.BAR.IP.3389: SWE 1539382950:1539382950(0) win 8192 <mss 1460,nop,wscale 8,nop,nop,sackOK> (DF) [tos 0x2 (E)]
Aug 29 15:51:33.880334 rule 0/(match) block in on vio0: 45.55.22.21.53510 > 45.FOO.BAR.IP.2362: udp 14
Aug 29 15:51:34.006656 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6491: S 151489102:151489102(0) win 1024 [tos 0x28]
Aug 29 15:51:34.274654 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6491: R 151489103:151489103(0) win 1200 [tos 0x28]
Aug 29 15:51:36.393019 rule 0/(match) block in on vio0: 60.191.38.78.4249 > 45.FOO.BAR.IP.8000: S 3746478095:3746478095(0) win 29200 (DF)
Aug 29 15:51:57.213051 rule 0/(match) block in on vio0: 24.137.245.138.7343 > 45.FOO.BAR.IP.5358: S 14134:14134(0) win 14600
Aug 29 15:52:37.852219 rule 0/(match) block in on vio0: 122.226.185.125.51128 > 45.FOO.BAR.IP.23: S 1715745381:1715745381(0) win 5840 <mss 1420,sackOK,timestamp 13511417 0,nop,wscale 2> (DF)
Aug 29 15:53:31.309325 rule 0/(match) block in on vio0: 189.218.148.69.377 > 45.FOO.BAR.IP5358: S 65340:65340(0) win 14600 [tos 0x28]
Aug 29 15:53:31.809570 rule 0/(match) block in on vio0: 13.93.104.140.53184 > 45.FOO.BAR.IP.1433: S 39854048:39854048(0) win 1024
Aug 29 15:53:32.138231 rule 0/(match) block in on vio0: 13.93.104.140.53184 > 45.FOO.BAR.IP.1433: R 39854049:39854049(0) win 1200
Aug 29 15:53:41.459088 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6028: S 168338703:168338703(0) win 1024
Aug 29 15:53:41.789732 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6028: R 168338704:168338704(0) win 1200
Aug 29 15:54:34.993594 rule 0/(match) block in on vio0: 212.47.234.50.5102 > 45.FOO.BAR.IP.5060: udp 408 (DF) [tos 0x28]
Aug 29 15:54:57.987449 rule 0/(match) block in on vio0: 51.15.69.145.5100 > 45.FOO.BAR.IP.5060: udp 406 (DF) [tos 0x28]
Aug 29 15:55:07.001743 rule 0/(match) block in on vio0: 190.83.174.214.58863 > 45.FOO.BAR.IP.23: S 757158343:757158343(0) win 27420
Aug 29 15:55:51.269549 rule 0/(match) block in on vio0: 142.217.201.69.26112 > 45.FOO.BAR.IP.22: S 757158343:757158343(0) win 22840 <mss 1460>
Aug 29 15:58:41.346028 rule 0/(match) block in on vio0: 169.1.29.111.29765 > 45.FOO.BAR.IP.23: S 757158343:757158343(0) win 28509
Aug 29 15:59:11.575927 rule 0/(match) block in on vio0: 187.160.235.162.32427 > 45.FOO.BAR.IP.5358: S 22445:22445(0) win 14600 [tos 0x28]
Aug 29 15:59:37.826598 rule 0/(match) block in on vio0: 94.74.81.97.54656 > 45.FOO.BAR.IP.3128: S 2720157526:2720157526(0) win 1024 [tos 0x28]stateful
Aug 29 15:59:37.991171 rule 0/(match) block in on vio0: 94.74.81.97.54656 > 45.FOO.BAR.IP.3128: R 2720157527:2720157527(0) win 1200 [tos 0x28]
Aug 29 16:01:36.990050 rule 0/(match) block in on vio0: 182.18.8.28.23299 > 45.FOO.BAR.IP.445: S 1510146048:1510146048(0) win 16384
```

如果要查看实时日志，可以运行：

```
# tcpdump -n -e -ttt -i pflog0
```

如果你想了解更多信息，可以访问 [PF FAQ](https://www.openbsd.org/faq/pf/) 和 [FreeBSD HANDBOOK](https://www.freebsd.org/doc/handbook/firewalls.html) 以及下面这些 man 页面：

```
# man tcpdump
# man pfctl
# man pf
```

### 关于作者

我是 nixCraft 的创立者，一个经验丰富的系统管理员，同时也是一位 Linux 操作系统/Unix shell 脚本培训师。我在不同的行业与全球客户工作过，包括 IT、教育、国防和空间研究、以及非营利组织。你可以在 [Twitter](https://twitter.com/nixcraft)、[Facebook](https://facebook.com/nixcraft) 或 [Google+](https://plus.google.com/+CybercitiBiz) 上面关注我。

---

via: <https://www.cyberciti.biz/faq/how-to-set-up-a-firewall-with-pf-on-freebsd-to-protect-a-web-server/>

作者：[Vivek Gite](https://www.cyberciti.biz) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


15 个可以节省你时间的命令别名

Summary: 在你安装的 Linux 发行版中默认就包含了一些别名。

在你安装的 Linux 发行版中默认就包含了一些别名。

>
> 在你安装的 Linux 发行版中默认就包含了一些别名。
>
>
>

![](/data/attachment/album/201809/15/231004r0e3uicruclm3eiu.jpg)

Linux 命令行别名非常适合帮助你提高工作效率。更好的是，在你安装的 Linux 发行版中默认就包含了一些别名。

这是 Fedora 27 中的命令别名的示例：

![](/data/attachment/album/201809/15/231019j77bgriggxpipii0.png)

这个 `alias` 命令列出了已有的别名。设置别名也十分简单：

```
alias new_name="command"
```

这里有 15 个命令行别名，可以节省你的时间：

1、安装任何应用实用 / 应用程序：

```
alias install="sudo yum install -y"
```

在这里，根据每个用户的偏好，`sudo` 和 `-y` 是可选的：

![install alias.png](/data/attachment/album/201809/15/231028vyb0lrit7yiz5247.png "install alias.png")

2、更新系统：

```
alias update="sudo yum update -y"
```

3、升级系统：

```
alias upgrade="sudo yum upgrade -y"
```

4、切换 root 用户：

```
alias root="sudo su -"
```

5、切换到 “user” 用户, 其中 `user` 设置为你的用户名：

```
alias user="su user"
```

6、显示列出所有可用端口、状态还有 IP：

```
alias myip="ip -br -c a"
```

7、`ssh` 到你的服务器 `myserver`：

```
alias myserver="ssh user@my_server_ip”
```

8、列出系统中所有进程：

```
alias process="ps -aux"
```

9、检查系统的服务状态：

```
alias sstatus="sudo systemctl status"
```

10、重启系统服务：

```
alias srestart="sudo systemctl restart"
```

11、按名称杀死进程：

```
alias kill="sudo pkill"
```

![kill process alias.png](/data/attachment/album/201809/15/231043ykhpeknro9kr7kn1.png "kill process alias.png")

12、显示系统系统总使用内存和空闲内存 ：

```
alias mem="free -h"
```

13、显示系统 CPU 框架结构、CPU 数量、线程数等：

```
alias cpu="lscpu"
```

14、显示系统总磁盘大小：

```
alias disk="df -h"
```

15、显示当前系统 Linux 发行版本（适用于 CentOS、Fedora 和 Red Hat)：

```
alias os="cat /etc/redhat-release"
```

![system_details alias.png](/data/attachment/album/201809/15/231052uh0vvui5bhy78bw7.png "system_details alias.png")

---

via: <https://opensource.com/article/18/8/time-saving-command-line-aliases>

作者：[Aarchit Modi](https://opensource.com/users/architmodi) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MZqk](https://github.com/MZqk) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 上检查一个软件包的详细信息

![](/data/attachment/album/201809/16/130119o69ayamb9p5yierr.jpg)

我们可以就这个已经被广泛讨论的话题写出大量的文章，大多数情况下，因为各种各样的原因，我们都愿意让<ruby> 包管理器 <rt>  package manager </rt></ruby>来帮我们做这些事情。

每个 Linux 发行版都有自己的包管理器，并且每个都有各自有不同的特性，这些特性包括允许用户执行安装新软件包，删除无用的软件包，更新现存的软件包，搜索某些具体的软件包，以及更新整个系统到其最新的状态之类的操作。

习惯于命令行的用户大多数时间都会使用基于命令行方式的包管理器。对于 Linux 而言，这些基于命令行的包管理器有 `yum`、`dnf`、`rpm`、`apt`、`apt-get`、`dpkg`、`pacman` 和 `zypper`。

**推荐阅读**

* [Linux 命令行包管理器列表及其用法](https://www.2daygeek.com/list-of-command-line-package-manager-for-linux/)
* [一个图形化的 Linux 包管理器前端工具](https://www.2daygeek.com/list-of-graphical-frontend-tool-for-linux-package-manager/)
* [如何搜索知道一个软件包是否存在于你的 Linux 发行版](https://www.2daygeek.com/how-to-search-if-a-package-is-available-on-your-linux-distribution-or-not/)
* [如何使用 dnf/yum 配置包管理器在 Linux 上来添加、启用和禁用软件仓库](https://www.2daygeek.com/how-to-add-enable-disable-a-repository-dnf-yum-config-manager-on-linux/)

作为一个系统管理员你应该清楚地知道：安装包来自何方，具体来自哪个软件仓库，包的具体版本，包的大小，版本，包的源代码 URL，包的许可证信息，等等。

这篇短文将用尽可能简单的方式帮你从随包自带的总结和描述中了解该包的用法。按你所使用的 Linux 发行版的不同，运行下面相应的命令，你能得到你所使用的发行版下的包的详细信息。

### YUM 命令：在 RHEL 和 CentOS 系统上获得包的信息

[YUM](https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/) 英文直译是“<ruby> 黄狗更新器–修改版 <rt>  Yellowdog Updater, Modified </rt></ruby>”，它是一个开源的基于命令行的包管理器前端实用工具。它被广泛应用在基于 RPM 的系统上，例如：RHEL 和 CentOS。

Yum 是用于在官方发行版仓库以及其他第三方发行版仓库下获取、安装、删除、查询 RPM 包的主要工具。

（LCTT 译注：用 `yum info` 获取 python 包的信息）

```
# yum info python
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: epel.mirror.constant.com
Installed Packages
Name        : python
Arch        : x86_64
Version     : 2.6.6
Release     : 66.el6_8
Size        : 78 k
Repo        : installed
From repo   : updates
Summary     : An interpreted, interactive, object-oriented programming language
URL         : http://www.python.org/
License     : Python
Description : Python is an interpreted, interactive, object-oriented programming
            : language often compared to Tcl, Perl, Scheme or Java. Python includes
            : modules, classes, exceptions, very high level dynamic data types and
            : dynamic typing. Python supports interfaces to many system calls and
            : libraries, as well as to various windowing systems (X11, Motif, Tk,
            : Mac and MFC).
            :
            : Programmers can write new built-in modules for Python in C or C++.
            : Python can be used as an extension language for applications that need
            : a programmable interface.
            :
            : Note that documentation for Python is provided in the python-docs
            : package.
            :
            : This package provides the "python" executable; most of the actual
            : implementation is within the "python-libs" package.

```

### YUMDB 命令：查看 RHEL 和 CentOS 系统上的包信息

`yumdb info` 这个命令提供与 `yum info` 相类似的的信息，不过它还额外提供了诸如包校验值、包类型、用户信息（由何人安装）。从 yum 3.2.26 版本后，`yum` 开始在 rpm 数据库外储存额外的信息了（此处如显示 `user` 表明该包由用户安装，而 `dep` 说明该包是被作为被依赖的包而被安装的）。

（LCTT 译注：用 `yumdb info` 来获取 python 包的信息）

```
# yumdb info python
Loaded plugins: fastestmirror
python-2.6.6-66.el6_8.x86_64
     changed_by = 4294967295
     checksum_data = 53c75a1756e5b4f6564c5229a37948c9b4561e0bf58076bd7dab7aff85a417f2
     checksum_type = sha256
     command_line = update -y
     from_repo = updates
     from_repo_revision = 1488370672
     from_repo_timestamp = 1488371100
     installed_by = 4294967295
     reason = dep
     releasever = 6
```

### RPM 命令：在 RHEL/CentOS/Fedora 系统上查看包的信息

[RPM](https://www.2daygeek.com/rpm-command-examples/) 英文直译为“<ruby> 红帽包管理器 <rt>  Red Hat Package Manager </rt></ruby>”，这是一个在 RedHat 以及其变种发行版（如RHEL、CentOS、Fedora、openSUSE、Megeia）下的功能强大的命令行包管理工具。它能让你轻松的安装、升级、删除、查询以及校验你的系统或服务器上的软件。RPM 文件以 `.rpm` 结尾。RPM 包由它所依赖的软件库以及其他依赖构成，它不会与系统上已经安装的包冲突。

（LCTT 译注：用 `rpm -qi` 查询 nano 包的具体信息）

```
# rpm -qi nano
Name        : nano                         Relocations: (not relocatable)
Version     : 2.0.9                             Vendor: CentOS
Release     : 7.el6                         Build Date: Fri 12 Nov 2010 02:18:36 AM EST
Install Date: Fri 03 Mar 2017 08:57:47 AM EST      Build Host: c5b2.bsys.dev.centos.org
Group       : Applications/Editors          Source RPM: nano-2.0.9-7.el6.src.rpm
Size        : 1588347                          License: GPLv3+
Signature   : RSA/8, Sun 03 Jul 2011 12:46:50 AM EDT, Key ID 0946fca2c105b9de
Packager    : CentOS BuildSystem
URL         : http://www.nano-editor.org
Summary     : A small text editor
Description :
GNU nano is a small and friendly text editor.
```

### DNF 命令：在 Fedora 系统上查看包信息

[DNF](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/) 指“<ruby> 时髦版的 Yum <rt>  Dandified yum </rt></ruby>”，我们也可以认为 DNF 是下一代的 yum 包管理器（Yum 的一个分支），它在后台使用了 hawkey/libsolv 库。Aleš Kozumplík 在Fedora 18 上开始开发 DNF，在 Fedora 22 上正式最后发布。 `dnf` 命令用来在 Fedora 22 及以后的系统上安装、更新、搜索以及删除包。它能自动的解决包安装过程中的包依赖问题。

（LCTT 译注： 用 `dnf info` 查看 tilix 包信息）

```
$ dnf info tilix
Last metadata expiration check: 27 days, 10:00:23 ago on Wed 04 Oct 2017 06:43:27 AM IST.
Installed Packages
Name         : tilix
Version      : 1.6.4
Release      : 1.fc26
Arch         : x86_64
Size         : 3.6 M
Source       : tilix-1.6.4-1.fc26.src.rpm
Repo         : @System
From repo    : @commandline
Summary      : Tiling terminal emulator
URL          : https://github.com/gnunn1/tilix
License      : MPLv2.0 and GPLv3+ and CC-BY-SA
Description  : Tilix is a tiling terminal emulator with the following features:
             :
             :  - Layout terminals in any fashion by splitting them horizontally or vertically
             :  - Terminals can be re-arranged using drag and drop both within and between
             :    windows
             :  - Terminals can be detached into a new window via drag and drop
             :  - Input can be synchronized between terminals so commands typed in one
             :    terminal are replicated to the others
             :  - The grouping of terminals can be saved and loaded from disk
             :  - Terminals support custom titles
             :  - Color schemes are stored in files and custom color schemes can be created by
             :    simply creating a new file
             :  - Transparent background
             :  - Supports notifications when processes are completed out of view
             :
             : The application was written using GTK 3 and an effort was made to conform to
             : GNOME Human Interface Guidelines (HIG).
```

### Zypper 命令：在 openSUSE 系统上查看包信息

[zypper](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/) 是一个使用 libzypp 库的命令行包管理器。`zypper` 提供诸如软件仓库访问，安装依赖解决，软件包安装等等功能。

（LCTT 译注： 用 `zypper info` 查询 nano 包的信息）

```
$ zypper info nano

Loading repository data...
Reading installed packages...

Information for package nano:
-----------------------------
Repository     : Main Repository (OSS)
Name           : nano
Version        : 2.4.2-5.3
Arch           : x86_64
Vendor         : openSUSE
Installed Size : 1017.8 KiB
Installed      : No
Status         : not installed
Source package : nano-2.4.2-5.3.src
Summary        : Pico editor clone with enhancements
Description    :
    GNU nano is a small and friendly text editor. It aims to emulate
    the Pico text editor while also offering a few enhancements.
```

### Pacman 命令：在 ArchLinux 及 Manjaro 系统上查看包信息

[Pacman](https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/) 意即<ruby> 包管理器 <rt>  package manager </rt></ruby>实用工具。`pacman` 是一个用于安装、构建、删除、管理 Arch Linux 上包的命令行工具。它后端使用 libalpm（Arch Linux package Manager（ALPM）库）来完成所有功能。

（LCTT 译注： 用 `pacman -Qi` 来查询 bash 包信息）

```
$ pacman -Qi bash
Name            : bash
Version         : 4.4.012-2
Description     : The GNU Bourne Again shell
Architecture    : x86_64
URL             : http://www.gnu.org/software/bash/bash.html
Licenses        : GPL
Groups          : base
Provides        : sh
Depends On      : readline>=7.0  glibc  ncurses
Optional Deps   : bash-completion: for tab completion
Required By     : autoconf  automake  bison  bzip2  ca-certificates-utils  db
                  dhcpcd  diffutils  e2fsprogs  fakeroot  figlet  findutils
                  flex  freetype2  gawk  gdbm  gettext  gmp  grub  gzip  icu
                  iptables  keyutils  libgpg-error  libksba  libpcap  libpng
                  libtool  lvm2  m4  man-db  mkinitcpio  nano  neofetch  nspr
                  nss  openresolv  os-prober  pacman  pcre  pcre2  shadow
                  systemd  texinfo  vte-common  which  xdg-user-dirs  xdg-utils
                  xfsprogs  xorg-mkfontdir  xorg-xpr  xz
Optional For    : None
Conflicts With  : None
Replaces        : None
Installed Size  : 7.13 MiB
Packager        : Jan Alexander Steffens (heftig)
Build Date      : Tue 14 Feb 2017 01:16:51 PM UTC
Install Date    : Thu 24 Aug 2017 06:08:12 AM UTC
Install Reason  : Explicitly installed
Install Script  : No
Validated By    : Signature
```

### apt-cache 命令：在 Debian/Ubuntu/Mint 系统上查看包信息

[apt-cache](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/) 命令能显示 apt 内部数据库中的大量信息。这些信息是从 `sources.list` 中的不同的软件源中搜集而来，因此从某种意义上这些信息也可以被认为是某种缓存。这些信息搜集工作是在运行 `apt update` 命令时执行的。

（LCTT 译注：用管理员权限查询 apache2 包的信息）

```
$ sudo apt-cache show apache2
Package: apache2
Priority: optional
Section: web
Installed-Size: 473
Maintainer: Ubuntu Developers
Original-Maintainer: Debian Apache Maintainers
Architecture: amd64
Version: 2.4.12-2ubuntu2
Replaces: apache2.2-common
Provides: httpd, httpd-cgi
Depends: lsb-base, procps, perl, mime-support, apache2-bin (= 2.4.12-2ubuntu2), apache2-utils (>= 2.4), apache2-data (= 2.4.12-2ubuntu2)
Pre-Depends: dpkg (>= 1.17.14)
Recommends: ssl-cert
Suggests: www-browser, apache2-doc, apache2-suexec-pristine | apache2-suexec-custom, ufw
Conflicts: apache2.2-common (<< 2.3~)
Filename: pool/main/a/apache2/apache2_2.4.12-2ubuntu2_amd64.deb
Size: 91348
MD5sum: ab0ee0b0d1c6b3d19bd87aa2a9537125
SHA1: 350c9a1a954906088ed032aebb77de3d5bb24004
SHA256: 03f515f7ebc3b67b050b06e82ebca34b5e83e34a528868498fce020bf1dbbe34
Description-en: Apache HTTP Server
 The Apache HTTP Server Project's goal is to build a secure, efficient and
 extensible HTTP server as standards-compliant open source software. The
 result has long been the number one web server on the Internet.
 .
 Installing this package results in a full installation, including the
 configuration files, init scripts and support scripts.
Description-md5: d02426bc360345e5acd45367716dc35c
Homepage: http://httpd.apache.org/
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Origin: Ubuntu
Supported: 9m
Task: lamp-server, mythbuntu-frontend, mythbuntu-desktop, mythbuntu-backend-slave, mythbuntu-backend-master, mythbuntu-backend-master
```

### APT 命令：查看 Debian/Ubuntu/Mint 系统上的包信息

[APT](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/) 意为<ruby> 高级打包工具 <rt>  Advanced Packaging Tool </rt></ruby>，就像 DNF 将如何替代 YUM 一样，APT 是 apt-get 的替代物。它功能丰富的命令行工具包括了如下所有命令的功能如 `apt-cache`、`apt-search`、`dpkg`、`apt-cdrom`、`apt-config`、`apt-key` 等等，我们可以方便的通过 `apt` 来安装 `.dpkg` 包，但是我们却不能通过 `apt-get` 来完成这一点，还有一些其他的类似的功能也不能用 `apt-get` 来完成，所以 `apt-get` 因为没有解决上述功能缺乏的原因而被 `apt` 所取代。

（LCTT 译注： 用 `apt show` 查看 nano 包信息）

```
$ apt show nano
Package: nano
Version: 2.8.6-3
Priority: standard
Section: editors
Origin: Ubuntu
Maintainer: Ubuntu Developers
Original-Maintainer: Jordi Mallach
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 766 kB
Depends: libc6 (>= 2.14), libncursesw5 (>= 6), libtinfo5 (>= 6)
Suggests: spell
Conflicts: pico
Breaks: nano-tiny (<< 2.8.6-2)
Replaces: nano-tiny (<< 2.8.6-2), pico
Homepage: https://www.nano-editor.org/
Task: standard, ubuntu-touch-core, ubuntu-touch
Supported: 9m
Download-Size: 222 kB
APT-Manual-Installed: yes
APT-Sources: http://in.archive.ubuntu.com/ubuntu artful/main amd64 Packages
Description: small, friendly text editor inspired by Pico
 GNU nano is an easy-to-use text editor originally designed as a replacement
 for Pico, the ncurses-based editor from the non-free mailer package Pine
 (itself now available under the Apache License as Alpine).
 .
 However, GNU nano also implements many features missing in pico, including:
  - undo/redo
  - line numbering
  - syntax coloring
  - soft-wrapping of overlong lines
  - selecting text by holding Shift
  - interactive search and replace (with regular expression support)
  - a go-to line (and column) command
  - support for multiple file buffers
  - auto-indentation
  - tab completion of filenames and search terms
  - toggling features while running
  - and full internationalization support
```

### dpkg 命令：查看Debian/Ubuntu/Mint系统上的包信息

[dpkg](https://www.2daygeek.com/dpkg-command-to-manage-packages-on-debian-ubuntu-linux-mint-systems/) 意指 <ruby> Debian 包管理器 <rt>  Debian package manager </rt></ruby>。`dpkg` 是用于 Debian 系统上安装、构建、移除以及管理 Debian 包的命令行工具。`dpkg` 使用 `aptitude`（因为它更为主流及用户友好）作为前端工具来完成所有的功能。其他的工具如`dpkg-deb` 和 `dpkg-query` 使用 `dpkg` 做为前端来实现功能。尽管系统管理员还是时不时会在必要时使用 `dpkg` 来完成一些软件安装的任务，他大多数情况下还是会因为 `apt`、`apt-get` 以及 `aptitude` 的健壮性而使用后者。

（LCTT 译注： 用 `dpkg -s` 查看 python 包的信息）

```
$ dpkg -s python
Package: python
Status: install ok installed
Priority: optional
Section: python
Installed-Size: 626
Maintainer: Ubuntu Developers
Architecture: amd64
Multi-Arch: allowed
Source: python-defaults
Version: 2.7.14-2ubuntu1
Replaces: python-dev (<< 2.6.5-2)
Provides: python-ctypes, python-email, python-importlib, python-profiler, python-wsgiref
Depends: python2.7 (>= 2.7.14-1~), libpython-stdlib (= 2.7.14-2ubuntu1)
Pre-Depends: python-minimal (= 2.7.14-2ubuntu1)
Suggests: python-doc (= 2.7.14-2ubuntu1), python-tk (>= 2.7.14-1~)
Breaks: update-manager-core (<< 0.200.5-2)
Conflicts: python-central (<< 0.5.5)
Description: interactive high-level object-oriented language (default version)
 Python, the high-level, interactive object oriented language,
 includes an extensive class library with lots of goodies for
 network programming, system administration, sounds and graphics.
 .
 This package is a dependency package, which depends on Debian's default
 Python version (currently v2.7).
Homepage: http://www.python.org/
Original-Maintainer: Matthias Klose
```

我们也可使用 `dpkg` 的 `-p` 选项，这个选项提供和 `dpkg -s` 相类似的信息，但是它还提供了包的校验值和包类型。

（LCTT 译注： 用 `dpkg -p` 查看 python3 包的信息）

```
$ dpkg -p python3
Package: python3
Priority: important
Section: python
Installed-Size: 67
Origin: Ubuntu
Maintainer: Ubuntu Developers
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Architecture: amd64
Multi-Arch: allowed
Source: python3-defaults
Version: 3.6.3-0ubuntu2
Replaces: python3-minimal (<< 3.1.2-2)
Provides: python3-profiler
Depends: python3.6 (>= 3.6.3-1~), libpython3-stdlib (= 3.6.3-0ubuntu2), dh-python
Pre-Depends: python3-minimal (= 3.6.3-0ubuntu2)
Suggests: python3-doc (>= 3.6.3-0ubuntu2), python3-tk (>= 3.6.3-1~), python3-venv (>= 3.6.3-0ubuntu2)
Filename: pool/main/p/python3-defaults/python3_3.6.3-0ubuntu2_amd64.deb
Size: 8712
MD5sum: a8bae494c6e5d1896287675faf40d373
Description: interactive high-level object-oriented language (default python3 version)
Original-Maintainer: Matthias Klose
SHA1: 2daec885cea7d4dc83c284301c3bebf42b23e095
SHA256: 865e509c91d2504a16c4b573dbe27e260c36fceec2add3fa43a30c1751d7e9bb
Homepage: http://www.python.org/
Task: minimal, ubuntu-core, ubuntu-core
Description-md5: 950ebd8122c0a7340f0a740c295b9eab
Supported: 9m
```

### aptitude 命令：查看 Debian/Ubuntu/Mint 系统上的包信息

`aptitude` 是 Debian GNU/Linux 包管理系统的文本界面。它允许用户查看已安装的包的列表，以及完成诸如安装、升级、删除包之类的包管理任务。这些管理行为也能从图形接口来执行。

（LCTT 译注： 用 `aptitude show` 查看 htop 包信息）

```
$ aptitude show htop
Package: htop
Version: 2.0.2-1
State: installed
Automatically installed: no
Priority: optional
Section: universe/utils
Maintainer: Ubuntu Developers
Architecture: amd64
Uncompressed Size: 216 k
Depends: libc6 (>= 2.15), libncursesw5 (>= 6), libtinfo5 (>= 6)
Suggests: lsof, strace
Conflicts: htop:i386
Description: interactive processes viewer
 Htop is an ncursed-based process viewer similar to top, but it allows one to scroll the list vertically and horizontally to see all processes and their full command lines.

 Tasks related to processes (killing, renicing) can be done without entering their PIDs.
Homepage: http://hisham.hm/htop/
```

---

via: <https://www.2daygeek.com/how-to-view-detailed-information-about-a-package-in-linux/>

作者：[Prakash Subramanian](https://www.2daygeek.com/author/prakash/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[DavidChenLiang](https://github.com/davidchenliang) 校对：[wxy](https://github.com/wxy)

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


如何从 Linux 的文件管理器中加密文件

![](/data/attachment/album/201809/16/220457r2jw0aj9jd9jddcy.jpg)

Linux 桌面版和服务器版具有卓越的安全性。然而这并不意味着你可以放松警惕。你应该一直认为你的数据总是很快就会被破坏。也就是说，你可能需要使用各种加密工具。比如 GnuPG，它可以让你加密和解密文件等更多功能。GnuPG 的一个问题是一些用户不想在命令行输入那么复杂的命令。如果是这样的话，你可以转向桌面文件管理器。许多 Linux 桌面版包含了简易的加密和解密文件的功能，如果这种功能没有内置，那么也是很容易添加的。

我将引导你完成从三个流行的 Linux 文件管理器中对文件进行加密和解密过程：

* Nautilus （即 GNOME Files）
* Dolphin
* Thunar

### 安装 GnuPG

在我们讨论如何处理这个问题之前，我们必须确保你的系统包含了必要的基本组件 —— [GnuPG](https://www.gnupg.org/)。大多数发行版本都包含 GnuPG。 在某些偶然情况下，你使用的是没有自带 GnuPG 的发行版，以下是安装方法：

* 基于 Ubuntu 的发行版： `sudo apt install gnupg`
* 基于 Fedora 的发行版： `sudo yum install gnupg`
* openSUSE： `sudo zypper in gnupg`
* 基于 Arch 的发行版：`sudo pacman -S gnupg`

无论你是刚刚安装了 GnuPG，还是默认安装的，你都必须创建一个 GPG 密钥才能使用。每个桌面版都使用不同的 GUI 工具完成这个工作（或者甚至根本没有包含一个完成这个任务的 GUI 工具），所以让我们从命令行中创建这个密钥。打开终端窗口并输入以下指令：

```
gpg --gen-key
```

然后，你将被要求回答以下问题。除非你有充分的理由，否则你可以接受默认值：

* 你想要哪种密钥？
* 你想要多长的密钥？
* 密钥有效期？

一旦你回答了这些问题，输入 `y` 来表示答案是正确的。接下来你需要提供以下信息：

* 真实姓名。
* Email 地址。
* 备注。

完成上述操作后，然后在提示的时候输入 `O` （即 ok）。然后，你将被要求为新密钥输入一个密码。一旦系统收集到了足够的熵（你需要在桌面上做一些工作才能做到这一点，LCTT 译注：比如随便敲击键盘），你的密钥就会被创建，然后你就可以开始工作了。

让我们看看如何从文件管理器中加密/解密文件：

### Nautilus

让我们从默认的 GNOME 文件管理器开始，因为它是最简单的。Nautilus 不需要额外安装什么或额外的工作就可以从精心设计的界面内加密/解密文件。一旦你创建完 gpg 密钥后，就可以打开文件管理器，导航到包含要加密的文件的目录，右键单击要加密的文件，然后从菜单中选择 “Encrypt” （图1）。

![nautilus](/data/attachment/album/201809/16/220458gqzol9lqcrfyqrqu.jpg "nautilus")

*图1：从 Nautilus 中加密文件。*

你将被要求选择一个收件人（或者收件人列表 —— 图2）。注意：收件人将是那些你已经导入了公钥的用户。选择所需的密钥，然后从签名信息下拉列表中选择你的密钥（电子邮件地址）。

![nautilus](/data/attachment/album/201809/16/220459vo4ao0dtt0a34faw.jpg "nautilus")

*图2：选择收件人和签名者。*

注意：你还可以选择仅使用密码来加密文件。如果文件将保留在你的本地机器上，这一点非常重要（稍后将详细介绍）。一旦你设置好加密后，单击 “OK” 并（在提示时）输入 gpg 密钥的密码。文件将被加密（现在文件名以 .gpg 结尾）并保存在工作目录中。现在你可以将加密后的文件发送给在加密过程中已选择的收件人。

比如说（有你的公钥的）某人已经给你发送了一个加密文件。保存该文件，打开文件管理器，导航到该文件所在的目录，右击这个加密文件，选择 “Open With Decrypt File”，给文件一个新名称（不带 .gpg 的扩展名），然后单击“Save”。当提示时，输入你的 gpg 密钥的密码，该文件就会被解密并准备使用。

### Dolphin

在 KDE 前端，必须安装一个软件包才能使用 Dolphin 文件管理器进行加密/解密。 登录到你的 KDE 桌面，打开终端窗口，然后输入以下命令（我正在使用 Neon 进行演示。如果你的发行版不是基于 Ubuntu 的，则必须相应地更改命令）：

```
sudo apt install kgpg
```

安装完毕后，注销并重新登录 KDE 桌面。 你可以打开 Dolphin 并右键单击要加密的文件。 由于这是你第一次使用 kgpg，因此你必须完成快速设置向导（不言自明）。当完成该向导后，你可以返回该文件，右键单击它（图3），然后选择 Encrypt File。

![Dolphin](/data/attachment/album/201809/16/220459p1smpygksl1pf2k4.jpg "Dolphin")

*图3：在 Dolphin 中加密文件。*

系统将提示你选择用于加密的密钥（图4）。 进行选择并单击 “OK”。 该文件将被加密，而且你已准备好将其发送给收件人。

注意：使用 KDE 的 Dolphin 文件管理器市，你无法仅使用密码加密。

![Dolphin](/data/attachment/album/201809/16/220500drs1lkck4egy966g.jpg "Dolphin")

*图4：选择要加密的收件人。*

如果你收到来自有你的公钥的用户的加密文件（或者你有一个自己加密的文件），请打开 Dolphin，导航到相关文件，双击该文件，为该文件指定一个新名称 ，键入加密密码并单击 “OK”。 你现在可以读取到新解密的文件。 如果你使用自己的密钥加密了该文件，则不会提示你键入密码（因为它已经被存储了）。

### Thunar

Thunar 文件管理器有点棘手。 没有任何额外的软件包可供安装；相反，你需要为了加密创建新的自定义操作。完成此操作后，你将能够在文件管理器中执行此操作。

要创建自定义操作，请打开 Thunar 文件管理器，然后单击 “Edit > Configure Custom Actions”。 在所得到的窗口中，单击 “+” 按钮（图5）并为加密操作输入以下内容：

* 名称：加密
* 描述：文件加密
* 命令：`gnome-terminal -x gpg --encrypt --recipient ％f`

单击 “OK” 以保存此操作。

![Thunar](/data/attachment/album/201809/16/220500lcjtz62ljgbz6ltj.jpg "Thunar")

*图5：在Thunar中创建自定义操作。*

注意：如果 gnome-terminal 不是你的默认终端，请替换该命令以打开你的默认终端。

你还可以创建仅使用密码（而非密钥）加密的操作。 为此，该操作的详细动作将会是以下内容：

* 名称：加密密码
* 说明：仅使用密码加密
* 命令：`gnome-terminal -x gpg -c ％f`

你不需要为解密过程创建一个自定义操作，因为 Thunar 已经知道如何处理一个加密文件。 要解密文件，只需（在 Thunar 中）右键单击它，选择 “Open With Decrypt File”，为解密文件命名，然后（在提示时）键入加密密码。 Viola，你的加密文件已被解密并可以使用。

### 一个警告

请注意：如果你使用自己的密钥加密自己的文件，则无需输入加密密码来解密它们（因为你的公钥已存储）。 但是，如果你收到（拥有你的公钥的）其他人的文件，则需要输入你的密码。 如果你想要存储自己的加密文件，而不是使用密钥来加密它们，请使用仅使用密码加密。 Nautilus 和Thunar（但不是 KDE）可以做到这一点。 通过选择密码加密（通过密钥加密），当你解密文件时，它将始终提示你输入密码。

### 其他文件管理器

还有很多其它的文件管理器，它们中的一些可以使用加密，有些则不能。 你很有可能正在使用这三种工具中的一种，因此不仅可以将加密 / 解密添加到上下文菜单，而且是非常容易。 尝试一下，看看它是否会使加密和解密的过程变得更容易。

从 Linux 基金会和 edX 免费提供的[“Linux 介绍”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux)课程了解更多关于 Linux 的信息。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/3/how-encrypt-files-within-file-manager>

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

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


8 个用于有效地管理进程的 Linux 命令

Summary: 通过这些关键的命令来全程管理你的应用。

通过这些关键的命令来全程管理你的应用。

>
> 通过这些关键的命令来全程管理你的应用。
>
>
>

![](/data/attachment/album/201809/16/225342dggc8idpid9mpp85.png)

一般来说，应用程序进程的生命周期有三种主要状态：启动、运行和停止。如果我们想成为称职的管理员，每个状态都可以而且应该得到认真的管理。这八个命令可用于管理进程的整个生命周期。

### 启动进程

启动进程的最简单方法是在命令行中键入其名称，然后按回车键。如果要启动 Nginx web 服务器，请键入 `nginx` 。也许您只是想看看其版本。

```
alan@workstation:~$ nginx

alan@workstation:~$ nginx -v
nginx version: nginx/1.14.0
```

### 查看您的可执行路径

以上启动进程的演示是假设可执行文件位于您的可执行路径中。理解这个路径是可靠地启动和管理进程的关键。管理员通常会为他们想要的目的定制这条路径。您可以使用 `echo $PATH` 查看您的可执行路径。

```
alan@workstation:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
```

#### WHICH

使用 `which` 命令查看可执行文件的完整路径。

```
alan@workstation:~$ which nginx
/opt/nginx/bin/nginx
```

我将使用流行的 web 服务器软件 Nginx 作为我的例子。假设安装了 Nginx。如果执行 `which nginx` 的命令什么也不返回，那么是找不到 Nginx 了，因为它只搜索您指定的可执行路径。有三种方法可以补救一个进程不能简单地通过名字启动的情况。首先是键入完整路径 —— 虽然，我不情愿输入全部路径，您会吗？

```
alan@workstation:~$ /home/alan/web/prod/nginx/sbin/nginx -v
nginx version: nginx/1.14.0
```

第二个解决方案是将应用程序安装在可执行文件路径中的目录中。然而，这有时可能是办不到的，特别是如果您没有 root 权限。

第三个解决方案是更新您的可执行路径环境变量，包括要使用的特定应用程序的安装目录。这个解决方案是与 shell 相关的。例如，Bash 用户需要在他们的 `.bashrc` 文件中编辑 `PATH=` 行。

```
PATH="$HOME/web/prod/nginx/sbin:$PATH"
```

现在，重复您的 `echo` 和 `which` 命令或者尝试检查版本。容易多了！

```
alan@workstation:~$ echo $PATH
/home/alan/web/prod/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

alan@workstation:~$ which nginx
/home/alan/web/prod/nginx/sbin/nginx

alan@workstation:~$ nginx -v
nginx version: nginx/1.14.0
```

### 保持进程运行

#### NOHUP

注销或关闭终端时，进程可能不会继续运行。这种特殊情况可以通过在要使用 `nohup` 命令放在要运行的命令前面让进程持续运行。此外，附加一个`&` 符号将会把进程发送到后台，并允许您继续使用终端。例如，假设您想运行 `myprogram.sh` 。

```
nohup myprogram.sh &
```

`nohup` 会返回运行进程的 PID。接下来我会更多地谈论 PID。

### 管理正在运行的进程

每个进程都有一个唯一的进程标识号 (PID) 。这个数字是我们用来管理每个进程的。我们还可以使用进程名称，我将在下面演示。有几个命令可以检查正在运行的进程的状态。让我们快速看看这些命令。

#### PS

最常见的是 `ps` 命令。`ps` 的默认输出是当前终端中运行的进程的简单列表。如下所示，第一列包含 PID。

```
alan@workstation:~$ ps
PID TTY          TIME CMD
23989 pts/0    00:00:00 bash
24148 pts/0    00:00:00 ps
```

我想看看我之前启动的 Nginx 进程。为此，我告诉 `ps` 给我展示每一个正在运行的进程（`-e`）和完整的列表（`-f`）。

```
alan@workstation:~$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Aug18 ?        00:00:10 /sbin/init splash
root         2     0  0 Aug18 ?        00:00:00 [kthreadd]
root         4     2  0 Aug18 ?        00:00:00 [kworker/0:0H]
root         6     2  0 Aug18 ?        00:00:00 [mm_percpu_wq]
root         7     2  0 Aug18 ?        00:00:00 [ksoftirqd/0]
root         8     2  0 Aug18 ?        00:00:20 [rcu_sched]
root         9     2  0 Aug18 ?        00:00:00 [rcu_bh]
root        10     2  0 Aug18 ?        00:00:00 [migration/0]
root        11     2  0 Aug18 ?        00:00:00 [watchdog/0]
root        12     2  0 Aug18 ?        00:00:00 [cpuhp/0]
root        13     2  0 Aug18 ?        00:00:00 [cpuhp/1]
root        14     2  0 Aug18 ?        00:00:00 [watchdog/1]
root        15     2  0 Aug18 ?        00:00:00 [migration/1]
root        16     2  0 Aug18 ?        00:00:00 [ksoftirqd/1]
alan     20506 20496  0 10:39 pts/0    00:00:00 bash
alan     20520  1454  0 10:39 ?        00:00:00 nginx: master process nginx
alan     20521 20520  0 10:39 ?        00:00:00 nginx: worker process
alan     20526 20506  0 10:39 pts/0    00:00:00 man ps
alan     20536 20526  0 10:39 pts/0    00:00:00 pager
alan     20564 20496  0 10:40 pts/1    00:00:00 bash
```

您可以在上面 `ps` 命令的输出中看到 Nginx 进程。这个命令显示了将近 300 行，但是我在这个例子中缩短了它。可以想象，试图处理 300 行过程信息有点混乱。我们可以将这个输出输送到 `grep`，过滤一下仅显示 nginx。

```
alan@workstation:~$ ps -ef |grep nginx
alan     20520  1454  0 10:39 ?        00:00:00 nginx: master process nginx
alan     20521 20520  0 10:39 ?        00:00:00 nginx: worker process
```

确实更好了。我们可以很快看到，Nginx 有 20520 和 20521 的 PID。

#### PGREP

`pgrep` 命令更加简化单独调用 `grep` 遇到的问题。

```
alan@workstation:~$ pgrep nginx
20520
20521
```

假设您在一个托管环境中，多个用户正在运行几个不同的 Nginx 实例。您可以使用 `-u` 选项将其他人排除在输出之外。

```
alan@workstation:~$ pgrep -u alan nginx
20520
20521
```

#### PIDOF

另一个好用的是 `pidof`。此命令将检查特定二进制文件的 PID，即使另一个同名进程正在运行。为了建立一个例子，我将我的 Nginx 复制到第二个目录，并以相应的路径前缀启动。在现实生活中，这个实例可能位于不同的位置，例如由不同用户拥有的目录。如果我运行两个 Nginx 实例，则`pidof` 输出显示它们的所有进程。

```
alan@workstation:~$ ps -ef |grep nginx
alan     20881  1454  0 11:18 ?        00:00:00 nginx: master process ./nginx -p /home/alan/web/prod/nginxsec
alan     20882 20881  0 11:18 ?        00:00:00 nginx: worker process
alan     20895  1454  0 11:19 ?        00:00:00 nginx: master process nginx
alan     20896 20895  0 11:19 ?        00:00:00 nginx: worker process
```

使用 `grep` 或 `pgrep` 将显示 PID 数字，但我们可能无法辨别哪个实例是哪个。

```
alan@workstation:~$ pgrep nginx
20881
20882
20895
20896
```

`pidof` 命令可用于确定每个特定 Nginx 实例的 PID。

```
alan@workstation:~$ pidof /home/alan/web/prod/nginxsec/sbin/nginx
20882 20881

alan@workstation:~$ pidof /home/alan/web/prod/nginx/sbin/nginx
20896 20895
```

#### TOP

`top` 命令已经有很久的历史了，对于查看运行进程的细节和快速识别内存消耗等问题是非常有用的。其默认视图如下所示。

```
top - 11:56:28 up 1 day, 13:37,  1 user,  load average: 0.09, 0.04, 0.03
Tasks: 292 total,   3 running, 225 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16387132 total, 10854648 free,  1859036 used,  3673448 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 14176540 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
17270 alan      20   0 3930764 247288  98992 R   0.7  1.5   5:58.22 gnome-shell
20496 alan      20   0  816144  45416  29844 S   0.5  0.3   0:22.16 gnome-terminal-
21110 alan      20   0   41940   3988   3188 R   0.1  0.0   0:00.17 top
    1 root      20   0  225564   9416   6768 S   0.0  0.1   0:10.72 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kthreadd
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H
    6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 mm_percpu_wq
    7 root      20   0       0      0      0 S   0.0  0.0   0:00.08 ksoftirqd/0
```

可以通过键入字母 `s` 和您喜欢的更新秒数来更改更新间隔。为了更容易监控我们的示例 Nginx 进程，我们可以使用 `-p` 选项并传递 PID 来调用 `top`。这个输出要干净得多。

```
alan@workstation:~$ top -p20881 -p20882 -p20895 -p20896

Tasks:   4 total,   0 running,   4 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.8 us,  1.3 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16387132 total, 10856008 free,  1857648 used,  3673476 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 14177928 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
20881 alan      20   0   12016    348      0 S   0.0  0.0   0:00.00 nginx
20882 alan      20   0   12460   1644    932 S   0.0  0.0   0:00.00 nginx
20895 alan      20   0   12016    352      0 S   0.0  0.0   0:00.00 nginx
20896 alan      20   0   12460   1628    912 S   0.0  0.0   0:00.00 nginx
```

在管理进程，特别是终止进程时，正确确定 PID 是非常重要。此外，如果以这种方式使用 `top`，每当这些进程中的一个停止或一个新进程开始时，`top` 都需要被告知有新的进程。

### 终止进程

#### KILL

有趣的是，没有 `stop` 命令。在 Linux 中，有 `kill` 命令。`kill` 用于向进程发送信号。最常用的信号是“终止”（`SIGTERM`）或“杀死”（`SIGKILL`）。然而，还有更多。下面是一些例子。完整的列表可以用 `kill -L` 显示。

```
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM

```

注意第 9 号信号是 `SIGKILL`，通常，我们会发出比如 `kill -9 20896` 这样的命令。默认信号是 15，这是 `SIGTERM`。请记住，许多应用程序都有自己的停止方法。Nginx 使用 `-s` 选项传递信号，如 `stop` 或 `reload`。通常，我更喜欢使用应用程序的特定方法来停止操作。然而，我将演示用 `kill` 命令来停止 Nginx 进程 20896，然后用 `pgrep` 确认它已经停止。PID 20896 就不再出现。

```
alan@workstation:~$ kill -9 20896

alan@workstation:~$ pgrep nginx
20881
20882
20895
22123
```

#### PKILL

命令 `pkill` 类似于 `pgrep`，因为它可以按名称搜索。这意味着在使用 `pkill` 时必须非常小心。在我的 Nginx 示例中，如果我只想杀死一个 Nginx 实例，我可能不会选择使用它。我可以将 Nginx 选项 `-s stop` 传递给特定的实例来消除它，或者我需要使用 `grep` 来过滤整个 `ps` 输出。

```
/home/alan/web/prod/nginx/sbin/nginx -s stop
/home/alan/web/prod/nginxsec/sbin/nginx -s stop
```

如果我想使用 `pkill`，我可以包括 `-f` 选项，让 `pkill` 过滤整个命令行参数。这当然也适用于 `pgrep`。所以，在执行 `pkill -f` 之前，首先我可以用 `pgrep -a` 确认一下。

```
alan@workstation:~$ pgrep -a nginx
20881 nginx: master process ./nginx -p /home/alan/web/prod/nginxsec
20882 nginx: worker process
20895 nginx: master process nginx
20896 nginx: worker process
```

我也可以用 `pgrep -f` 缩小我的结果。`pkill` 使用相同参数会停止该进程。

```
alan@workstation:~$ pgrep -f nginxsec
20881

alan@workstation:~$ pkill -f nginxsec
```

`pgrep`（尤其是 `pkill`）要记住的关键点是，您必须始终确保搜索结果准确性，这样您就不会无意中影响到错误的进程。

大多数这些命令都有许多命令行选项，所以我总是建议阅读每一个命令的 [man 手册页](https://www.kernel.org/doc/man-pages/)。虽然大多数这些命令都存在于 Linux、Solaris 和 BSD 等平台上，但也有一些不同之处。在命令行工作或编写脚本时，始终测试并随时准备根据需要进行更正。

---

via: <https://opensource.com/article/18/9/linux-commands-process-management>

作者：[Alan Formy-Duval](https://opensource.com/users/alanfdoss) 选题：[lujun9972](https://github.com/lujun9972) 译者：[heguangzhi](https://github.com/heguangzhi) 校对：[wxy](https://github.com/wxy)

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


i3 窗口管理器入门

>
> 本篇文章会介绍如何在 Fedora 系统中，安装、配置、使用 i3 瓦片式桌面管理器。
>
>
>

![](/data/attachment/album/201809/17/172829oj2v3k3qjqx5czuv.png)

在我的文章 [i3 桌面让 Linux 更好的 5 个理由](https://opensource.com/article/18/8/i3-tiling-window-manager)，我分享了选择 [i3 桌面管理器](https://i3wm.org) 作为一种 Linux 桌面替代方案的最主要五个理由。

在本篇文章中，我将向大家展示，如何在 Fedora 28 上安装与简单配置 i3。

### 1、 安装

首先进入 Fedora 系统中，打开一个终端。使用 `dnf` 来安装需要的软件包，如下：

```
[ricardo@f28i3 ~]$ sudo dnf install -y i3 i3-ipc i3status i3lock dmenu terminator --exclude=rxvt-unicode
Last metadata expiration check: 1:36:15 ago on Wed 08 Aug 2018 12:04:31 PM EDT.
Dependencies resolved.
================================================================================================
 Package                     Arch         Version                           Repository     Size
================================================================================================
Installing:
 dmenu                       x86_64       4.8-1.fc28                        fedora         33 k
 i3                          x86_64       4.15-1.fc28                       fedora        323 k
 i3-ipc                      noarch       0.1.4-12.fc28                     fedora         14 k
 i3lock                      x86_64       2.9.1-2.fc28                      fedora         33 k
 i3status                    x86_64       2.12-1.fc28                       updates        62 k
 terminator                  noarch       1.91-4.fc28                       fedora        570 k
Installing dependencies:
 dzen2                       x86_64       0.8.5-21.20100104svn.fc28         fedora         60 k

... Skipping dependencies/install messages

Complete!
[ricardo@f28i3 ~]$
```

注意：在这个命令中，我排除了 `rxvt-unicode` 这个包，因为我更喜欢 `terminator` 作为我的终端模拟器。

据用户目前的系统状态，在命令执行过程中可能会安装很多依赖。等待所有的依赖安装完成，之后重启你的电脑。

### 2、 首次登录与初始化

在你的机器重启之后，你便可以第一次体验 i3 了。在 GNOME 显示管理器（GDM）屏幕，选择你的用户名，之后先别着急输密码，点击下方的密码输入框下方的小齿轮，之后选择 i3 而不是 GNOME，像下方这样：

![](/data/attachment/album/201809/17/172830wvnzm44jgm2k4dmd.png)

输入你的密码，并点击 “Sign In”。在你第一次登入之后，会先看到 i3 的配置界面：

![](/data/attachment/album/201809/17/172830r4mmeuhue9306gxp.png)

点击回车键就会在 `$HOME/.config/i3` 生成一个配置文件，之后你可以通过这个配置文件来定制化 i3 的一些行为。

在下一屏，你需要选择你的 `Mod` 键。这一步很关键，因为 `Mod` 键通常都会作为 i3 命令快捷键的发起键。按回车会选择 `Win` 键作为默认的 `Mod` 键。如果你的键盘没有 `Win` 键，用 `Alt` 键做替代，用方向键键选择后按回车键确认。

![](/data/attachment/album/201809/17/172831fse22srnxlj2slnl.png)

现在你就登录到了 i3 的系统中。由于 i3 是一个极简的窗口管理器，你会看到一个黑屏窗口，以及屏幕底端显示的状态栏：

![](/data/attachment/album/201809/17/172831vs0q4jlplbhj2szh.png)

接下来，让我们看看 i3 的如何实际使用。

### 3、 基本的快捷键

现在你已经登录到了 i3 会话中，你需要几个基本的快捷键来应对基本的操作。

大多数的 i3 快捷键都会用到之前配置的 `Mod` 键。在下面的例子中，当我提到 `Mod` 键，请根据情况使用你定义的做替换。通常使用 `Win` 键或者 `Alt` 键。

首先，要打开一个终端，可以使用 `Mod+ENTER`。重复打开几个终端，观察 i3 是如何自动将它们在桌面中排列。默认情况下， i3 会在水平的方向分割屏幕；使用 `Mod + v` 来垂直分割，再按 `Mod + h` 会恢复水平分割模式。

![](/data/attachment/album/201809/17/172832x0835at51paxyhaf.png)

当需要启动其他的应用，按 `Mod + d` 来打开 `dmenu`，一个简单的文字应用菜单。默认情况下，`dmenu` 会呈现出所有在你 `$PATH` 中设置的应用。使用方向键来选择你想启动的应用，同时你可以键入应用的名称，来缩小选择的范围，之后按回车键来启动选择的应用。

![](/data/attachment/album/201809/17/172832bzg63610gszxgdz0.png)

如果你的应用没有提供退出的方法，你可以使用 i3 来关闭对应的窗口，通过按 `Mod + Shift +q`。注意，你可能会丢失未保存的工作内容。

最后，当你想关闭会话并退出 i3，按 `Mod + Shift +e`。之后会在窗口的上方提示你是否退出。点击 “Yes, exit i3” 退出，或选择 “X” 来取消。

![](/data/attachment/album/201809/17/172832q7t3979wnt95btj7.png)

这些就是 i3 中最基本的快捷键，如果想了解更多，请查阅官方[文档](https://i3wm.org/docs/userguide.html#_default_keybindings)。

### 4、 替换 GDM

使用 i3 窗口管理器会降低你操作系统的内存占用；然而，Fedora 依然会使用 GDM 作为登录屏。GDM 会载入几个与 GNOME 相关的库从而占用内存。

如果你想进一步的降低你的内存占用，你可以使用一些更轻量级的显示管理器来替换 GDM，比如 lightdm ：

```
[ricardo@f28i3 ~]$ sudo dnf install -y lightdm
[ricardo@f28i3 ~]$ sudo systemctl disable gdm
Removed /etc/systemd/system/display-manager.service.
[ricardo@f28i3 ~]$ sudo systemctl enable lightdm
Created symlink /etc/systemd/system/display-manager.service -> /usr/lib/systemd/system/lightdm.service.
[ricardo@f28i3 ~]$
```

之后重启你的机器来使用 Lightdm 的登录界面。

现在你可以继续登录并使用 i3了。

![](/data/attachment/album/201809/17/172834eflulxtu1v4lass8.png)

---

via: <https://opensource.com/article/18/8/getting-started-i3-window-manager>

作者：[Ricardo Gerardi](https://opensource.com/users/rgerardi) 选题：[lujun9972](https://github.com/lujun9972) 译者：[sd886393](https://github.com/sd886393) 校对：[wxy](https://github.com/wxy)

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


Linus Torvalds 宣布无限期休假，开始自我反省……

![](/data/attachment/album/201809/17/211434uq48ceo8idrk8skz.jpg)

>
> Linux 内核之父 Linus Torvalds 为其无理咆哮而道歉，并决定离开 Linux 内核项目休息一段时间，学习一下如何与人相处之道。
>
>
>

前一段时间， Linus Torvalds 因为[其个人的苏格兰休假计划](https://www.theregister.co.uk/2018/09/07/maintainers_summit_scotland/)而要将今年的 Linux 内核维护者峰会召开地点从原定的加拿大改到苏格兰。在会议上 Torvalds 招致了社区成员的强烈反对，以至于本次会议也由讨论技术问题，变成了抨击 Torvalds 本人的问题。一些维护者指责他“根本不懂得如何相处”，而由于此次议程变动，也使得很多本应该讨论的技术问题没能付诸讨论。

在昨天的邮件列表当中，Torvalds 在[邮件](https://lkml.org/lkml/2018/9/16/167)中承认其对其他 Linux 内核开发者和贡献者们的“轻率的攻击”是“不专业的，也是不必要的，而且很多回应属于人身攻击。从努力维护好内核更新的角度，他们提出的观点是合情合理的。……我知道这是不对的，我真的感到很抱歉。”

“我也许需要‘照照镜子’了。” Torvalds 表示，“一方面，我终于意识到，我希望不出席每年一度的 Linux 内核维护者峰会的想法是不妥当的，另一方面，我意识到自己一直忽视了社群中的一些相当深思熟虑的观点。”

“我误会了其他人，并且几年来都没有意识到我对形势的判断，导致了社群内的不专业的环境的危害有多么巨大。”

“我需要改变一些我的行为”，他补充说，“我要向那些因为我个人行为而受到伤害，甚至可能完全脱离了内核开发的人道歉。”这不是 Torvalds 第一次为其出言不逊而道歉，之前甚至因为他的无礼而导致一位著名的女性 Linux 内核核心开发人员 Sarah Sharp 的退出，不过这次看起来 Torvalds 是真正开始反省自己，并以一个技术人员的思路寻求“技术”解决方案以解决这个问题。

而上一次 Torvalds 感觉到 Linux 内核开发中的“痛点”，决定自己出手解决这个“技术”问题的后果就是 Git 的产生。

Linus Torvalds 是 Linux 内核的创始人，并从 1991 年开始就一直从事于 Linux 内核的开发和管理。他表示他会从 Linux 内核的开发当中休息一段时间——就像当年为了创建 Git 一样休息一段时间，做做“自我反省”，开发一些像 Git 一样的小工具来解决他的问题。

“我需要休息一段时间，以找到一些解决我在工具和工作流方面的问题的办法”，他接着说，“这不是我要‘撒手不干’了，我不觉得我不想继续维护 Linux 内核了。恰恰相反，我非常想继续做这个我已经做了快三十年的项目。”

“没错，我可能只是要开发一些‘工具’，比如邮件过滤器，这样我下次在邮件里写了脏话，就不会发出去了。因为我是一个工具信徒，我觉得一些问题完全可以通过简单的自动化流程而解决。”

那么，让我们拭目以待，看看 Torvalds 休息的这段时间，内核社区会怎么样，而他又会给我们带来什么变化或惊喜。


在 OpenDev 大会上学习 CI/CD

Summary: 未来的开发工作需要非常精通 CI/CD 流程。

未来的开发工作需要非常精通 CI/CD 流程。

>
> 未来的开发工作需要非常精通 CI/CD 流程。
>
>
>

![在OpenDev上，掌握CI/CD](/data/attachment/album/201809/17/231756smmq0up0b0m88s90.png)

在 2017 年启动后，OpenDev 大会现在已是一个年度活动。在去年 9 月的首届活动上，会议的重点是边缘计算。今年的活动，于 5 月 22 - 23 日举行，会议的重点是持续集成和持续发布 (CI/CD)，并与 OpenStack 峰会一起在温哥华举行。

基于我在 OpenStack 项目的 CI/CD 系统的技术背景和我近期进入容器下的 CI/CD 方面的经验，我被邀请加入 OpenDev CI/CD 计划委员会。今天我经常借助很多开源技术，例如 [Jenkins](https://jenkins.io/)、[GitLab](https://about.gitlab.com/)、[Spinnaker](https://www.spinnaker.io/) 和 [Artifactory](https://jfrog.com/artifactory/) 来讨论 CI/CD 流程。

这次活动对我来说是很激动人心的，因为我们将在这个活动中融合两个开源基础设施理念。首先，我们将讨论可以被任何组织使用的 CI/CD 工具。为此目的，在 [讲演](http://2018.opendevconf.com/schedule/) 中，我们将听到关于开源 CI/CD 工具的使用讲演，一场来自 Boris Renski 的关于 Spinnaker 的讲演，和一场来自 Jim Blair 的关于 [Zuul](https://zuul-ci.org/) 的讲演。同时，讲演会涉及关于开源技术的偏好的高级别话题，特别是那种跨社区的和本身就是开源项目的。从Fatih Degirmenci 和 Daniel Farrel 那里，我们将听到关于在不同社区分享持续发布实践经历，接着 Benjamin Mako Hill 会为我们带来一场关于为什么自由软件需要自由工具的分享。

在分享 CI/CD 相对新颖的特性后，接下来的活动是对话、研讨会和协作讨论的混合组合。当从人们所提交的讲座和研讨会中进行选择，并提出协作讨论主题时，我们希望确保有一个多样灵活的日程表，这样任何参与者都能在 CI/CD 活动进程中发现有趣的东西。

这些讲座会是标准的会议风格，选择涵盖关键主题，如制定 CI/CD 流程，在实践 DevOps 时提升安全性，以及更具体的解决方案，如基于容器关于 Kubernetes 的 [Aptomi](http://aptomi.io/) 和在 ETSI NFV 环境下 CI/CD。这些会话的大部分将会是作为给新接触 CI/CD 或这些特定技术的参与者关于这些话题和理念的简介。

交互式的研讨会会持续相对比较长的时间，参与者将会在思想上得到特定的体验。这些研讨会包括 “[在持续集成任务中的异常检测](https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21692/anomaly-detection-in-continuous-integration-jobs)”、“[如何安装 Zuul 和配置第一个任务](https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21693/how-to-install-zuul-and-configure-your-first-jobs)”，和“[Spinnake 101：快速可靠的软件发布](https://www.openstack.org/summit/vancouver-2018/summit-schedule/events/21699/spinnaker-101-releasing-software-with-velocity-and-confidence)”。（注意这些研讨会空间是有限的，所以设立了一个 RSVP 系统。你们将会在会议的链接里找到一个 RSVP 的按钮。)

可能最让我最兴奋的是协作讨论，这些协作讨论占据了一半以上的活动安排。协作讨论的主题由计划委员会选取。计划委员会根据我们在社区里所看到来选取对应的主题。这是“鱼缸”风格式的会议，通常是几个人聚在一个房间里围绕着 CI/CD 讨论某一个主题。

这次会议风格的理念是来自于开发者峰会，最初是由 Ubuntu 社区提出，接着 OpenStack 社区也在活动上采纳。这些协作讨论的主题包含不同的会议，这些会议是关于 CI/CD 基础，可以鼓励跨社区协作的提升举措，在组织里推行 CI/CD 文化，和为什么开源 CI/CD 工具如此重要。采用共享文档来做会议笔记，以确保尽可能的在会议的过程中分享知识。在讨论过程中，提出行动项目也是很常见的，因此社区成员可以推动和所涉及的主题相关的倡议。

活动将以联合总结会议结束。联合总结会议将总结来自协同讨论的关键点和为即将在这个领域工作的参与者指出可选的职业范围。

可以在 [OpenStack 峰会注册页](https://www.eventbrite.com/e/openstack-summit-may-2018-vancouver-tickets-40845826968?aff=VancouverSummit2018) 上注册参加活动。或者可以在温哥华唯一指定售票的会议中心购买活动的入场券，价格是 $199。更多关于票和全部的活动安排见官网 [OpenDev 网站](http://2018.opendevconf.com/)。

我希望你们能够加入我们，并在温哥华渡过令人激动的两天，并且在这两天的活动中学习，协作和在 CI/CD 取得进展。

---

via: <https://opensource.com/article/18/5/opendev>

作者：[Elizabeth K.Joseph](https://opensource.com/users/pleia2) 选题：[lujun9972](https://github.com/lujun9972) 译者：[jamelouis](https://github.com/jamelouis) 校对：[wxy](https://github.com/wxy)

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


在 VirtualBox 中安装 Android 系统

Summary: 你可以在该虚拟机里测试应用程序，也可以使用 Android 的内部功能。

我下载了两个安卓系统，都是安装完以后直接进入terminal，<br />
请问怎么样进入GUI 图形界面呢？

Android x86, Virtual Box 6.0, 安装完毕了以后，设置 -> 显示 -> 显卡控制器 -> VBoxVGA，并且勾选3D加速，否则不显示GUI

重启一次，开机选择第二项回车，进入debug模式

回车输入：mount -o remount,rw /mnt

输入：vi /mnt/grub/menu.lst回车，

按i，进入编辑模式，在第一个启动项，quiet后面加入nomodeset（就第一个AndroidX86 ** RC1下面那行，quiet后面  root前面）

按esc键取消编辑模式，输入：wq回车保存并退出，重启系统即可。（:wq）

重启之后就顺利的进入系统了，

我这vbox6.1，VBoxVGA和3D加速不能共存，只设置VBoxVGA之后可以进入GUI

我安装完后重启一直显示 在检测，无进展，尝试您的教程步骤多次，问题依旧，请教

mac环境，利用virtualbox安装Android x86，只有consle命令界面，如何进入GUI呀？安装有问题？

你可以在该虚拟机里测试应用程序，也可以使用 Android 的内部功能。

![](/data/attachment/album/201809/18/001443wijtrv00r8sr90b0.png)

如果你正在开发 Android 应用，也许会遇到小麻烦。诚然，ios 移动开发有 macOS 系统平台为其提供友好便利性， Android 开发仅有支持少部分 Android 系统（其中还包括可穿戴设备系统）的 Android Studio 工具。

毋庸置疑，所有的二进制工具、SDK 工具、开发框架工具以及调试器都会产生大量日志和其他各种文件，使得你的文件系统很混乱。一个有效的解决方法就是在 VirtualBox 中安装 Android 系统，这样还解决了 Android 开发中最为棘手问题之一 —— 设备模拟器。你可以在该虚拟机里测试应用程序，也可以使用 Android 的内部功能。因此，让我们迫不及待的开始吧！

### 准备工作

首先，你需要在你的系统上安装 VirtualBox，可从[这里](https://www.virtualbox.org/wiki/Downloads)下载 Windows 版本、macOS 版本或者各种 Linux 版本的 VitualBox。然后，你需要一个能在 x86 平台运行的 Android 镜像，因为 VirtualBox 为虚拟机提供运行 x86 或者 x86\_64（即 AMD64）平台的功能。

虽然大部分 Android 设备都在 ARM 上运行，但我们依然可以从 [Android on x86 项目](http://www.android-x86.org/) 中获得帮助。这些优秀的开发者已经将 Android 移植到 x86 平台上运行（包括实体机和虚拟机），我们可以下载最新版本的 Android 7.1。你也可以用之前更为稳定的版本，本文写作时最新稳定版是 Android 6.0。

### 创建 VM 虚拟机

打开 VirtualBox，单击左上角的 “新建” 按钮，在弹出的窗口中选择 “类型：Linux” ，然后根据下载的 ISO 镜像来确定版本，x86 对应 “32-bit”，x86\_64 对应 “64-bit”，此处选择 “Linux 2.6 / 3.x / 4.x (64-bit)”。

RAM 大小设置为 2 GB 到你系统能提供的最大内存之间。如果你想模拟真实的使用环境你可以设置 6 GB RAM 和 32 GB ROM。

![](/data/attachment/album/201809/18/001450x9gxkkq8wxv8zn0w.png)

![](/data/attachment/album/201809/18/001451iew2wdqwygaraawr.png)

创建完成后，你还需要做一些设置，添加更多的处理器核心，提高开机显示内存。在 VM 上打开设置选项，“设置 -> 系统 -> 处理器”，如果硬件条件允许，可以多分配一些处理器。

![](/data/attachment/album/201809/18/001451cv7grgl1l6go8x3r.png)

在 “设置 -> 显示 -> 显存大小” 中，你可以分配一大块内存并开启 3D 加速功能。

![](/data/attachment/album/201809/18/001452ajgwj8l1wpk9zklp.png)

现在我们可以启动 VM 虚拟机了。

### 安装 Android

首次启动 VM 虚拟机，VirtualBox 会提示你需要提供启动媒介，选择之前下载好的Android 镜像。

![](/data/attachment/album/201809/18/001453iw4wi4bz0ncewinv.png)

下一步，如果想长时间使用 Android，选择 “Installation” 选项，你也可以选择 Live 模式体验 Android 环境。

![](/data/attachment/album/201809/18/001454nurscj3j1jpom1j1.png)

按回车键。

#### 分区

分区是通过文本界面操作，并没有友好的 GUI 界面，所以每个操作都需要小心对待。例如，在第一屏中还没有创建分区并且只检测到原始（虚拟）硬盘时显示如下。

![](/data/attachment/album/201809/18/001454zsvpvmy7y7yvg3a2.png)

红色字母 `C` 和 `D` 表明 `C` 开头选项可以创建或者修改分区，`D` 开头选项可以检测设备。你可以选择 `D` 开头选项，然后它就会检测硬盘，也可不进行这步操作，因为在启动的时候它会自动检测。

我们选择 `C` 开头选项，在虚拟盘中创建分区。官方不推荐使用 GPT 格式，所以我们选择 “No” 并按回车键。

![](/data/attachment/album/201809/18/001454r5brfh9xd9h8upcz.png)

现在你被引导到 fdisk 工具页面。

![](/data/attachment/album/201809/18/001455pzexeffexudox2em.png)

为了简洁起见，我们就只创建一个较大的分区，使用方向键来选择 “New” ，然后选择 “Primary”，按回车键以确认。

![](/data/attachment/album/201809/18/001455t8h2gbl288qnhotb.png)

分区大小系统已经为你计算好了，按回车键确认。

![](/data/attachment/album/201809/18/001456njebitt9lrxxxxij.png)

这个分区就是 Android 系统所在的分区，所以需要它是可启动的。选择 “Bootable”，然后按回车键（上方表格中 “Flags” 标志下面会出现 “boot” 标志），进一步，选择 “Write” 选项，保存刚才的操作记录并写入分区表。

![](/data/attachment/album/201809/18/001456jbad46nw0et4ijoz.png)

现在你可以选择退出分区工具，然后继续安装过程。

![](/data/attachment/album/201809/18/001457n1qfnovnqqma4qyn.png)

#### 文件系统格式化为 EXT4 并安装 Android

在“Choose Partition”分区页面上会出现一个刚刚我们创建的分区，选择它并点击“OK”进入。

![](/data/attachment/album/201809/18/001458f0xhpn6xjt6op8x9.png)

在下一个菜单中选择 Ext4 作为实际的文件系统，在下一页中选择 “Yes” 然后格式化开始。会提示是否安装 GRUB 引导工具以及是否允许在目录 `/system` 进行读写，都选择 “Yes” 。现在，安装进程开始。

安装完成后，当系统提示可以重启的时候你可以安全地重启系统。在重启之前，你可以先关机，然后在 VitualBox 的 “设置 -> 存储” 中检查 Android iso 镜像是否还连接在虚拟机上，如果在，将它移除。

![](/data/attachment/album/201809/18/001459kzhm95fc9w8zm565.png)

移除安装媒介并保存修改，再去启动 VM 虚拟机。

#### 运行 Android

在 GRUB 引导界面，有调试模式和普通模式的选项。我们选择默认选项，如下图所示。

![](/data/attachment/album/201809/18/001459nunzjb27iep92r29.png)

如果一切正常，你将会看到如下界面：

![](/data/attachment/album/201809/18/001500ylqz8x71if3518kq.png)

如今的 Android 系统使用触摸交互而不是鼠标。不过 Android-x86 平台提供了鼠标操作支持，但开始时可能需要方向键来辅助操作。

![](/data/attachment/album/201809/18/001501js4t737j05u55ju7.png)

移动到”let’s go“按钮并按下回车键。选择 “Set up as new” 选项，回车确认。

![](/data/attachment/album/201809/18/001502n2ynnyt47ppnc9t2.png)

在提示用谷歌账户登陆之前，系统检查更新并检测设备信息。你可以跳过这一步，直接去设置日期和时间、用户名等。

还有一些其他的选项，和让你设置一个新的 Android 设备类似。选择 “I Agree” 选项同意有关更新、服务等的相应的选项，当然谷歌的服务条款是不得不同意的。

![](/data/attachment/album/201809/18/001503v3hhz48qnhdq0b0w.png)

在这之后，因为它是个虚拟机，所以可能需要添加额外的 email 账户来设置 “On-body detection”，大部分的选项对我们来说都没有多大作用，因此可以选择 ”All Set“。

接下来，它会提示你选择主屏应用，这个根据个人需求选择。现在我们进入了一个虚拟的 Android 系统。

![](/data/attachment/album/201809/18/001505trff6lmnqldjiook.png)

如果你需要在 VM 做一些交互测试，有个可触摸屏幕会提供很大的方便，因为那样才更接近真实使用环境。

希望这篇教程会给你带来帮助。

---

via: <https://linuxhint.com/install_android_virtualbox/>

作者：[Ranvir Singh](https://linuxhint.com/author/sranvir155/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[jrglinux](https://github.com/jrglinux) 校对：[wxy](https://github.com/wxy)

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


5 个在 Fedora 上管理待办事项的程序

Summary: 有效管理待办事项（to-do）可以为你的工作效率创造奇迹。

有效管理待办事项（to-do）可以为你的工作效率创造奇迹。

![](/data/attachment/album/201809/18/204131mhz93n92dz0e3wp7.jpg)

有效管理待办事项（to-do）可以为你的工作效率创造奇迹。有些人更喜欢在文本中保存待办事项，甚至只使用记事本和笔。对于需要更多待办事项功能的用户，他们通常会使用应用程序。在本文中，我们将重点介绍 4 个图形程序和一个基于终端的工具来管理待办事项。

### GNOME To Do

[GNOME To Do](https://wiki.gnome.org/Apps/Todo/) 是专为 GNOME 桌面（Fedora Workstation 的默认桌面）设计的个人任务管理器。GNOME To Do 与其他程序进行比较，它有一系列简洁的功能。

GNOME To Do 提供列表形式的任务组织方式，并能为该列表指定颜色。此外，可以为各个任务分配截止日期和优先级，以及每项任务的注释。此外，GNOME To Do 还支持扩展，能添加更多功能，包括支持 [todo.txt](http://todotxt.org/) 以及与 [todoist](https://en.todoist.com/) 等在线服务同步。

![](/data/attachment/album/201809/18/204133l8y8pzyp88yo8nws.png)

使用软件中心或者在终端中使用下面的命令安装 GNOME To Do：

```
sudo dnf install gnome-todo
```

### Getting things GNOME!

在 GNOME To Do 出现之前，在 GNOME 上追踪任务的首选程序是 [Getting things GNOME!](https://wiki.gnome.org/Apps/GTG) 这个老式的 GNOME 程序采用多窗口布局，能让你同时显示多个任务的细节。GTG 没有任务列表，它能在任务中添加子任务，甚至在子任务中添加子任务。GTG 同样能添加截止日期和开始日期。也可以通过插件同步其他程序和服务。

![](/data/attachment/album/201809/18/204135rzojjy8j4tu5j8uj.png)

在软件中心或者在终端中使用下面的命令安装 Getting Things GNOME：

```
sudo dnf install gtg
```

### Go For It!

[Go For It!](http://manuel-kehl.de/projects/go-for-it/) 是一个超级简单的任务管理程序。它能简单地创建一个任务列表，并在完成后标记它们。它不能将任务分组，也不能创建子任务。Go For It! 默认将任务存储为 todo.txt 格式，这能更方便地同步到在线服务或者其他程序中。额外地，Go For It! 包含了一个简单定时器来追踪你在当前任务花费了多少时间。

![](/data/attachment/album/201809/18/204137ej5n6b5l8llz4545.png)

Go For It! 能在 Flathub 应用仓库中找到。要安装它，只需[启用 Flathub 作为软件源](https://fedoramagazine.org/install-flathub-apps-fedora/)，接着在软件中心中安装。

### Agenda

如果你在寻找一款非常简单的待办应用，非 [Agenda](https://github.com/dahenson/agenda) 莫属。创建任务，标记完成，接着从列表中删除它们。Agenda 会在你删除它们之前一直显示所有任务（完成的或者进行中）。

![](/data/attachment/album/201809/18/204139yzf55l1zdndi19w9.png)

Agenda 能从 Flathub 应用仓库下载。要安装它，只需[启用 Flathub 作为软件源](https://fedoramagazine.org/install-flathub-apps-fedora/)，接着在软件中心中安装。

### Taskwarrior

[Taskwarrior](https://taskwarrior.org/) 是一个灵活的命令行任务管理程序。它高度可定制化，但同样“开箱即用”。使用简单的命令，你可以创建任务，标记完成，并列出当前进行中的任务。另外，任务可以被标记、添加到项目、搜索和过滤。此外，你可以设置循环任务，并设置任务截止日期。

[之前在 Fedora Magazine 上的文章](/article-9644-1.html) 对 Taskwarrior 的入门做了很好的概述。

![](/data/attachment/album/201809/18/204140qiizzk31b6iyai3w.png)

在终端中使用这个命令安装 Taskwarrior：

```
sudo dnf install task
```

---

via: <https://fedoramagazine.org/5-tools-to-manage-your-to-do-list-on-fedora/>

作者：[Ryan Lerch](https://fedoramagazine.org/introducing-flatpak/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


使用 PySimpleGUI 轻松为程序和脚本增加 GUI

Summary: 五分钟创建定制 GUI。

五分钟创建定制 GUI。

>
> 五分钟创建定制 GUI。
>
>
>

![](/data/attachment/album/201809/18/233529t20dq1juyy8hh2ym.jpg)

对于 `.exe` 类型的程序文件，我们可以通过双击鼠标左键打开；但对于 `.py` 类型的 Python 程序，几乎不会有人尝试同样的操作。对于一个（非程序员类型的）典型用户，他们双击打开 `.exe` 文件时预期弹出一个可以交互的窗体。基于 Tkinter，可以通过<ruby> 标准 Python 安装 <rt>  standard Python installations </rt></ruby>的方式提供 GUI，但很多程序都不太可能这样做。

如果打开 Python 程序并进入 GUI 界面变得如此容易，以至于真正的初学者也可以掌握，会怎样呢？会有人感兴趣并使用吗？这个问题不好回答，因为直到今天创建自定义 GUI 布局仍不是件容易的事情。

在为程序或脚本增加 GUI 这件事上，似乎存在能力的“错配”。（缺乏这方面能力的）真正的初学者被迫只能使用命令行方式，而很多（具备这方面能力的）高级程序员却不愿意花时间创建一个 Tkinter GUI。

### GUI 框架

Python 的 GUI 框架并不少，其中 Tkinter，wxPython，Qt 和 Kivy 是几种比较主流的框架。此外，还有不少在上述框架基础上封装的简化框架，例如 EasyGUI，PyGUI 和 Pyforms 等。

但问题在于，对于初学者（这里是指编程经验不超过 6 个月的用户）而言，即使是最简单的主流框架，他们也无从下手；他们也可以选择封装过的（简化）框架，但仍难以甚至无法创建自定义 GUI <ruby> 布局 <rt>  layout </rt></ruby>。即便学会了某种（简化）框架，也需要编写连篇累牍的代码。

[PySimpleGUI](https://github.com/MikeTheWatchGuy/PySimpleGUI) 尝试解决上述 GUI 难题，它提供了一种简单明了、易于理解、方便自定义的 GUI 接口。如果使用 PySimpleGUI，很多复杂的 GUI 也仅需不到 20 行代码。

### 秘诀

PySimpleGUI 极为适合初学者的秘诀在于，它已经包含了绝大多数原本需要用户编写的代码。PySimpleGUI 会处理按钮<ruby> 回调 <rt>  callback </rt></ruby>，无需用户编写代码。对于初学者，在几周内掌握函数的概念已经不容易了，要求其理解回调函数似乎有些强人所难。

在大部分 GUI 框架中，布局 GUI <ruby> 小部件 <rt>  widgets </rt></ruby>通常需要写一些代码，每个小部件至少 1-2 行。PySimpleGUI 使用了 “auto-packer” 技术，可以自动创建布局。因而，布局 GUI 窗口不再需要 pack 或 grid 系统。

（LCTT 译注：这里提到的 pack 和 grid 都是 Tkinter 的布局管理器，另外一种叫做 place 。）

最后，PySimpleGUI 框架编写中有效地利用了 Python 语言特性，降低用户代码量并简化 GUI 数据返回的方式。在<ruby> 窗体 <rt>  form </rt></ruby>布局中创建小部件时，小部件会被部署到对应的布局中，无需额外的代码。

### GUI 是什么？

绝大多数 GUI 只完成一件事情：收集用户数据并返回。在程序员看来，可以归纳为如下的函数调用：

```
button, values = GUI_Display(gui_layout)
```

绝大多数 GUI 支持的用户行为包括鼠标点击（例如，“确认”，“取消”，“保存”，“是”和“否”等）和内容输入。GUI 本质上可以归结为一行代码。

这也正是 PySimpleGUI （的简单 GUI 模式）的工作原理。当执行命令显示 GUI 后，除非点击鼠标关闭窗体，否则不会执行任何代码。

当然还有更复杂的 GUI，其中鼠标点击后窗口并不关闭；例如，机器人的远程控制界面，聊天窗口等。这类复杂的窗体也可以用 PySimpleGUI 创建。

### 快速创建 GUI

PySimpleGUI 什么时候有用呢？显然，是你需要 GUI 的时候。仅需不超过 5 分钟，就可以让你创建并尝试 GUI。最便捷的 GUI 创建方式就是从 [PySimpleGUI 经典实例](https://pysimplegui.readthedocs.io/en/latest/cookbook/)中拷贝一份代码。具体操作流程如下：

* 找到一个与你需求最接近的 GUI
* 从经典实例中拷贝代码
* 粘贴到 IDE 中并运行

下面我们看一下书中的第一个<ruby> 经典实例 <rt>  recipe </rt></ruby>：

```
import PySimpleGUI as sg

# Very basic form.  Return values as a list
form = sg.FlexForm('Simple data entry form')  # begin with a blank form

layout = [
          [sg.Text('Please enter your Name, Address, Phone')],
          [sg.Text('Name', size=(15, 1)), sg.InputText('name')],
          [sg.Text('Address', size=(15, 1)), sg.InputText('address')],
          [sg.Text('Phone', size=(15, 1)), sg.InputText('phone')],
          [sg.Submit(), sg.Cancel()]
         ]

button, values = form.LayoutAndRead(layout)

print(button, values[0], values[1], values[2])
```

运行后会打开一个大小适中的窗体。

![](/data/attachment/album/201809/18/233532aoqjbq77akjmq0qz.jpg)

如果你只是想收集一些字符串类型的值，拷贝上述经典实例中的代码，稍作修改即可满足你的需求。

你甚至可以只用 5 行代码创建一个自定义 GUI 布局。

```
import PySimpleGUI as sg

form = sg.FlexForm('My first GUI')

layout = [ [sg.Text('Enter your name'), sg.InputText()],
           [sg.OK()] ]

button, (name,) = form.LayoutAndRead(layout)
```

![](/data/attachment/album/201809/18/233534j2t8pmv4tp28vg24.jpg)

### 5 分钟内创建一个自定义 GUI

在简单布局的基础上，通过修改经典实例中的代码，5 分钟内即可使用 PySimpleGUI 创建自定义布局。

在 PySimpleGUI 中，<ruby> 小部件 <rt>  widgets </rt></ruby>被称为<ruby> 元素 <rt>  elements </rt></ruby>。元素的名称与编码中使用的名称保持一致。

（LCTT 译注：Tkinter 中使用小部件这个词）

#### 核心元素

```
Text
InputText
Multiline
InputCombo
Listbox
Radio
Checkbox
Spin
Output
SimpleButton
RealtimeButton
ReadFormButton
ProgressBar
Image
Slider
Column
```

#### 元素简写

PySimpleGUI 还包含两种元素简写方式。一种是元素类型名称简写，例如 `T` 用作 `Text` 的简写；另一种是元素参数被配置了默认值，你可以无需指定所有参数，例如 `Submit` 按钮默认的文本就是 “Submit”。

```
T = Text
Txt = Text
In = InputText
Input = IntputText
Combo = InputCombo
DropDown = InputCombo
Drop = InputCombo
```

（LCTT 译注：第一种简写就是 Python 类的别名，第二种简写是在返回元素对象的 Python 函数定义时指定了参数的默认值）

#### 按钮简写

一些通用按钮具有简写实现，包括：

```
FolderBrowse
FileBrowse
FileSaveAs
Save
Submit
OK
Ok （LCTT 译注：这里 `k` 是小写）
Cancel
Quit
Exit
Yes
No
```

此外，还有通用按钮功能对应的简写：

```
SimpleButton
ReadFormButton
RealtimeButton
```

（LCTT 译注：其实就是返回 `Button` 类实例的函数）

上面就是 PySimpleGUI 支持的全部元素。如果不在上述列表之中，就不会在你的窗口布局中生效。

（LCTT 译注：上述都是 PySimpleGUI 的类名、类别名或返回实例的函数，自然只能使用列表内的。）

#### GUI 设计模式

对于 GUI 程序，创建并展示窗口的调用大同小异，差异在于元素的布局。

设计模式代码与上面的例子基本一致，只是移除了布局：

```
import PySimpleGUI as sg

form = sg.FlexForm('Simple data entry form')
# Define your form here (it's a list of lists)
button, values = form.LayoutAndRead(layout)
```

（LCTT 译注：这段代码无法运行，只是为了说明每个程序都会用到的设计模式。）

对于绝大多数 GUI，编码流程如下：

* 创建窗体对象
* 以“列表的列表”的形式定义 GUI
* 展示 GUI 并获取元素的值

上述流程与 PySimpleGUI 设计模式部分的代码一一对应。

#### GUI 布局

要创建自定义 GUI，首先要将窗体分割成多个行，因为窗体是一行一行定义的。然后，在每一行中从左到右依次放置元素。

我们得到的就是一个“列表的列表”，类似如下：

```
layout = [  [Text('Row 1')],
            [Text('Row 2'), Checkbox('Checkbox 1', OK()), Checkbox('Checkbox 2'), OK()] ]
```

上述布局对应的效果如下：

![](/data/attachment/album/201809/18/233536ttaaph7comr8chpu.jpg)

### 展示 GUI

当你完成布局、拷贝完用于创建和展示窗体的代码后，下一步就是展示窗体并收集用户数据。

下面这行代码用于展示窗体并返回收集的数据：

```
button, values = form.LayoutAndRead(layout)
```

窗体返回的结果由两部分组成：一部分是被点击按钮的名称，另一部分是一个列表，包含所有用户输入窗体的值。

在这个例子中，窗体显示后用户直接点击 “OK” 按钮，返回的结果如下：

```
button == 'OK'
values == [False, False]
```

Checkbox 类型元素返回 `True` 或 `False` 类型的值。由于默认处于未选中状态，两个元素的值都是 `False`。

### 显示元素的值

一旦从 GUI 获取返回值，检查返回变量中的值是个不错的想法。与其使用 `print` 语句进行打印，我们不妨坚持使用 GUI 并在一个窗口中输出这些值。

（LCTT 译注：考虑使用的是 Python 3 版本，`print` 应该是函数而不是语句。）

在 PySimpleGUI 中，有多种消息框可供选取。传递给消息框（函数）的数据会被显示在消息框中；函数可以接受任意数目的参数，你可以轻松的将所有要查看的变量展示出来。

在 PySimpleGUI 中，最常用的消息框是 `MsgBox`。要展示上面例子中的数据，只需编写一行代码：

```
MsgBox('The GUI returned:', button, values)
```

### 整合

好了，你已经了解了基础知识，让我们创建一个包含尽可能多 PySimpleGUI 元素的窗体吧！此外，为了更好的感观效果，我们将采用绿色/棕褐色的配色方案。

```
import PySimpleGUI as sg

sg.ChangeLookAndFeel('GreenTan')

form = sg.FlexForm('Everything bagel', default_element_size=(40, 1))

column1 = [[sg.Text('Column 1', background_color='#d3dfda', justification='center', size=(10,1))],
           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],
           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')],
           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]]
layout = [
    [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))],
    [sg.Text('Here is some text.... and a place to enter text')],
    [sg.InputText('This is my text')],
    [sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)],
    [sg.Radio('My first Radio!     ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")],
    [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)),
     sg.Multiline(default_text='A second multi-line', size=(35, 3))],
    [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 3)),
     sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)],
    [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),
     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25),
     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75),
     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10),
     sg.Column(column1, background_color='#d3dfda')],
    [sg.Text('_'  * 80)],
    [sg.Text('Choose A Folder', size=(35, 1))],
    [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
     sg.InputText('Default Folder'), sg.FolderBrowse()],
    [sg.Submit(), sg.Cancel()]
     ]

button, values = form.LayoutAndRead(layout)
sg.MsgBox(button, values)
```

看上面要写不少代码，但如果你试着直接使用 Tkinter 框架实现同样的 GUI，你很快就会发现 PySimpleGUI 版本的代码是多么的简洁。

![](/data/attachment/album/201809/18/233550usb2xhujlcoigi5t.jpg)

代码的最后一行打开了一个消息框，效果如下：

![](/data/attachment/album/201809/18/233554rzo338oktfjs6nlc.jpg)

消息框函数中的每一个参数的内容都会被打印到单独的行中。本例的消息框中包含两行，其中第二行非常长而且包含列表嵌套。

建议花一点时间将上述结果与 GUI 中的元素一一比对，这样可以更好的理解这些结果是如何产生的。

### 为你的程序或脚本添加 GUI

如果你有一个命令行方式使用的脚本，添加 GUI 不一定意味着完全放弃该脚本。一种简单的方案如下：如果脚本不需要命令行参数，那么可以直接使用 GUI 调用该脚本；反之，就按原来的方式运行脚本。

仅需类似如下的逻辑：

```
if len(sys.argv) == 1:
        # collect arguments from GUI
else:
    # collect arguements from sys.argv
```

创建并运行 GUI 最便捷的方式就是从 [PySimpleGUI 经典实例](https://pysimplegui.readthedocs.io/en/latest/cookbook/)中拷贝一份代码并修改。

快来试试吧！给你一直疲于手动执行的脚本增加一些趣味。只需 5-10 分钟即可玩转示例脚本。你可能发现一个几乎满足你需求的经典实例；如果找不到，也很容易自己编写一个。即使你真的玩不转，也只是浪费了 5-10 分钟而已。

### 资源

#### 安装方式

支持 Tkinter 的系统就支持 PySimpleGUI，甚至包括<ruby> 树莓派 <rt>  Raspberry Pi </rt></ruby>，但你需要使用 Python 3。

```
pip install PySimpleGUI
```

#### 文档

* [手册](https://pysimplegui.readthedocs.io/en/latest/)
* [经典实例](https://pysimplegui.readthedocs.io/en/latest/cookbook/)
* [GitHub repository](https://github.com/MikeTheWatchGuy/PySimpleGUI)

---

via: <https://opensource.com/article/18/8/pysimplegui>

作者：[Mike Barnett](https://opensource.com/users/pysimplegui) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

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


使用 NetworkManager 随机化你的 MAC 地址

![](/data/attachment/album/201809/19/081148cn996dvan14mnl46.png)

今时今日，无论在家里的沙发上，还是在外面的咖啡厅，只要打开笔记本电脑，连上 Wi-Fi，就能通过网络与外界保持联系。但现在的 Wi-Fi 热点们大都能够通过[每张网卡对应的唯一 MAC 地址](https://en.wikipedia.org/wiki/MAC_address)来追踪你的设备。下面就来看一下如何避免被追踪。

现在很多人已经开始注重个人隐私这个问题。个人隐私问题并不仅仅指防止他人能够访问到你电脑上的私有内容（这又是另一个问题了），而更多的是指<ruby> 可追踪性 <rt>  legibility </rt></ruby>，也就是是否能够被轻易地统计和追踪到。大家都应该[对此更加重视](https://www.ribbonfarm.com/2010/07/26/a-big-little-idea-called-legibility/)。同时，这方面的底线是，服务提供者在得到了用户的授权后才能对用户进行追踪，例如机场的计时 Wi-Fi 只有在用户授权后才能够使用。

因为固定的 MAC 地址能被轻易地追踪到，所以应该定时进行更换，随机的 MAC 地址是一个好的选择。由于 MAC 地址一般只在局域网内使用，因此随机的 MAC 地址也不大会产生[冲突](https://serverfault.com/questions/462178/duplicate-mac-address-on-the-same-lan-possible)。

### 配置 NetworkManager

要将随机的 MAC 地址默认地用于所有的 Wi-Fi 连接，需要创建 `/etc/NetworkManager/conf.d/00-macrandomize.conf` 这个文件：

```
[device]
wifi.scan-rand-mac-address=yes

[connection]
wifi.cloned-mac-address=stable
ethernet.cloned-mac-address=stable
connection.stable-id=${CONNECTION}/${BOOT}
```

然后重启 NetworkManager ：

```
systemctl restart NetworkManager
```

以上配置文件中，将 `cloned-mac-address` 的值设置为 `stable` 就可以在每次 NetworkManager 激活连接的时候都生成相同的 MAC 地址，但连接时使用不同的 MAC 地址。如果要在每次激活连接时也获得随机的 MAC 地址，需要将 `cloned-mac-address` 的值设置为 `random`。

设置为 `stable` 可以从 DHCP 获取相同的 IP 地址，也可以让 Wi-Fi 的<ruby> <a href="https://en.wikipedia.org/wiki/Captive_portal">  强制主页 </a> <rt>  captive portal </rt></ruby>根据 MAC 地址记住你的登录状态。如果设置为 `random` ，在每次连接的时候都需要重新认证（或者点击“我同意”），在使用机场 Wi-Fi 的时候会需要到这种 `random` 模式。可以在这篇 NetworkManager 的[博客文章](https://blogs.gnome.org/thaller/2016/08/26/mac-address-spoofing-in-networkmanager-1-4-0/)中参阅到有关使用 `nmcli` 从终端配置特定连接的详细说明。

使用 `ip link` 命令可以查看当前的 MAC 地址，MAC 地址将会显示在 `ether` 一词的后面。

```
$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp2s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 52:54:00:5f:d5:4e brd ff:ff:ff:ff:ff:ff
3: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
    link/ether 52:54:00:03:23:59 brd ff:ff:ff:ff:ff:ff
```

### 什么时候不能随机化 MAC 地址

当然，在某些情况下确实需要能被追踪到。例如在家用网络中，可能需要将路由器配置为对电脑分配一致的 IP 地址以进行端口转发；再例如公司的雇主可能需要根据 MAC 地址来提供 Wi-Fi 服务，这时候就需要进行追踪。要更改特定的 Wi-Fi 连接，请使用 `nmcli` 查看 NetworkManager 连接并显示当前设置：

```
$ nmcli c | grep wifi
Amtrak_WiFi    5f4b9f75-9e41-47f8-8bac-25dae779cd87 wifi --
StaplesHotspot de57940c-32c2-468b-8f96-0a3b9a9b0a5e wifi --
MyHome         e8c79829-1848-4563-8e44-466e14a3223d wifi wlp1s0
...
$ nmcli c show 5f4b9f75-9e41-47f8-8bac-25dae779cd87 | grep cloned
802-11-wireless.cloned-mac-address:     --
$ nmcli c show e8c79829-1848-4563-8e44-466e14a3223d | grep cloned
802-11-wireless.cloned-mac-address:     stable
```

这个例子在 Amtrak 使用完全随机 MAC 地址（使用默认配置）和 MyHome 的永久 MAC 地址（使用 `stable` 配置）。永久 MAC 地址是在硬件生产的时候分配到网络接口上的，网络管理员能够根据永久 MAC 地址来查看[设备的制造商 ID](https://www.wireshark.org/tools/oui-lookup.html)。

更改配置并重新连接活动的接口：

```
$ nmcli c modify 5f4b9f75-9e41-47f8-8bac-25dae779cd87 802-11-wireless.cloned-mac-address random
$ nmcli c modify e8c79829-1848-4563-8e44-466e14a3223d 802-11-wireless.cloned-mac-address permanent
$ nmcli c down e8c79829-1848-4563-8e44-466e14a3223d
$ nmcli c up e8c79829-1848-4563-8e44-466e14a3223d
$ ip link
...
```

你还可以安装 NetworkManager-tui ，就可以通过可视化界面菜单来编辑连接。

### 总结

当你走在路上时，你要[留意周围的环境](https://www.isba.org/committees/governmentlawyers/newsletter/2013/06/becomingmoreawareafewtipsonkeepingy)，并[警惕可能的危险](http://www.selectinternational.com/safety-blog/aware-of-surroundings-can-reduce-safety-incidents)。同样，在使用公共互联网资源时也要注意你自己的可追踪性。

---

via: <https://fedoramagazine.org/randomize-mac-address-nm/>

作者：[sheogorath](https://fedoramagazine.org/author/sheogorath/),[Stuart D Gathman](https://fedoramagazine.org/author/sdgathman/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)

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


Trash-Cli：Linux 上的命令行回收站工具

Summary: 如果有人在寻找一个命令行回收站工具，那么这儿有一个不错的选择。

如果有人在寻找一个命令行回收站工具，那么这儿有一个不错的选择。

![](/data/attachment/album/201809/19/082815fwwwcsw5600z7zkw.jpg)

相信每个人都对<ruby> 回收站 <rt>  trashcan </rt></ruby>很熟悉，因为无论是对 Linux 用户，还是 Windows 用户，或者 Mac 用户来说，它都很常见。当你删除一个文件或目录的时候，该文件或目录会被移动到回收站中。

需要注意的是，当把文件移动到回收站以后，文件系统空间并没有被释放，除非把回收站清空。

如果不想永久删除文件的话（清空回收站），可以利用回收站临时存储被删除了的文件，从而在必要的时候能够帮助我们恢复删除了的文件。

但是，如果在命令行使用 `rm` 命令进行删除操作，那么你是不可能在回收站中找到任何被删除了的文件或目录的。所以，在执行 `rm` 命令前请一定要三思。如果你犯了错误（执行了 `rm` 命令），那么文件就被永久删除了，无法再恢复回来，因为存储在磁盘上的元数据已经不在了。

根据 [freedesktop.org 规范](https://freedesktop.org/wiki/Specifications/trash-spec/)，<ruby> 垃圾 <rt>  trash </rt></ruby>是由桌面管理器比如 GNOME、KDE 和 XFCE 等提供的一个特性。当通过文件管理器删除一个文件或目录的时候，该文件或目录将会成为<ruby> 垃圾 <rt>  trash </rt></ruby>，然后被移动到回收站中，回收站对应的目录是 `$HOME/.local/share/Trash` 。

回收站目录包含两个子目录：`files` 和 `info` 。`files` 目录存储实际被删除了的文件和目录，`info` 目录包含被删除了的文件和目录的信息，比如文件路径、删除日期和时间，每个文件单独存储。

你可能会问，既然已经有了<ruby> 图形用户界面 <rt>  GUI </rt></ruby>的回收站，为什么还需要命令行工具呢？因为对于大多数使用 \*NIX 系统的家伙（包括我）来说，即使使用的是基于图形用户界面的系统，也更喜欢使用命令行而不是图形用户界面。所以，如果有人在寻找一个命令行回收站工具，那么这儿有一个不错的选择。

### Trash-Cli 是什么

[trash-cli](https://github.com/andreafrancia/trash-cli) 是一个命令行回收站工具，并且符合 FreeDesktop.org 的<ruby> 垃圾 <rt>  trash </rt></ruby>规范。它能够存储每一个垃圾文件的名字、原始路径、删除日期和权限。

### 如何在 Linux 上安装 Trash-Cli

绝大多数的 Linux 发行版官方仓库都提供了 Trash-Cli 的安装包，所以你可以运行下面这些命令来安装。

对于 Debian/Ubuntu 用户，使用 [apt-get](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/) 或 [apt](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/) 命令来安装 Trash-Cli：

```
$ sudo apt install trash-cli
```

对于 RHEL/CentOS 用户，使用 [yum](https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/) 命令来安装 Trash-Cli：

```
$ sudo yum install trash-cli
```

对于 Fedora 用户，使用 [dnf](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/) 命令来安装 Trash-Cli：

```
$ sudo dnf install trash-cli
```

对于 Arch Linux 用户，使用 [pacman](https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/) 命令来安装 Trash-Cli：

```
$ sudo pacman -S trash-cli
```

对于 openSUSE 用户，使用 [zypper](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/) 命令来安装 Trash-Cli：

```
$ sudo zypper in trash-cli
```

如果你的发行版中没有提供 Trash-Cli 的安装包，那么你也可以使用 `pip` 来安装。为了能够安装 python 包，你的系统中应该会有 `pip` 包管理器。

```
$ sudo pip install trash-cli
Collecting trash-cli
 Downloading trash-cli-0.17.1.14.tar.gz
Installing collected packages: trash-cli
 Running setup.py bdist_wheel for trash-cli ... done
Successfully installed trash-cli-0.17.1.14
```

### 如何使用 Trash-Cli

Trash-Cli 的使用不难，因为它提供了一个很简单的语法。Trash-Cli 提供了下面这些命令：

* `trash-put`： 删除文件和目录（仅放入回收站中）
* `trash-list` ：列出被删除了的文件和目录
* `trash-restore`：从回收站中恢复文件或目录 trash.
* `trash-rm`：删除回收站中的文件
* `trash-empty`：清空回收站

下面，让我们通过一些例子来试验一下。

1) 删除文件和目录：在这个例子中，我们通过运行下面这个命令，将 `2g.txt` 这一文件和 `magi` 这一文件夹移动到回收站中。

```
$ trash-put 2g.txt magi
```

和你在文件管理器中看到的一样。

2) 列出被删除了的文件和目录：为了查看被删除了的文件和目录，你需要运行下面这个命令。之后，你可以在输出中看到被删除文件和目录的详细信息，比如名字、删除日期和时间，以及文件路径。

```
$ trash-list
2017-10-01 01:40:50 /home/magi/magi/2g.txt
2017-10-01 01:40:50 /home/magi/magi/magi
```

3) 从回收站中恢复文件或目录：任何时候，你都可以通过运行下面这个命令来恢复文件和目录。它将会询问你来选择你想要恢复的文件或目录。在这个例子中，我打算恢复 `2g.txt` 文件，所以我的选择是 `0` 。

```
$ trash-restore
 0 2017-10-01 01:40:50 /home/magi/magi/2g.txt
 1 2017-10-01 01:40:50 /home/magi/magi/magi
What file to restore [0..1]: 0
```

4) 从回收站中删除文件：如果你想删除回收站中的特定文件，那么可以运行下面这个命令。在这个例子中，我将删除 `magi` 目录。

```
$ trash-rm magi
```

5)清空回收站：如果你想删除回收站中的所有文件和目录，可以运行下面这个命令。

```
$ trash-empty
```

6)删除超过 X 天的垃圾文件：或者，你可以通过运行下面这个命令来删除回收站中超过 X 天的文件。在这个例子中，我将删除回收站中超过 `10` 天的项目。

```
$ trash-empty 10
```

Trash-Cli 可以工作的很好，但是如果你想尝试它的一些替代品，那么你也可以试一试 [gvfs-trash](http://manpages.ubuntu.com/manpages/trusty/man1/gvfs-trash.1.html) 和 [autotrash](https://github.com/bneijt/autotrash) 。

---

via: <https://www.2daygeek.com/trash-cli-command-line-trashcan-linux-system/>

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

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


Cloud Commander：一个有控制台和编辑器的 Web 文件管理器

Summary: Cloud Commander 是一个基于 web 的文件管理程序，它允许你通过任何计算机、移动端或平板电脑的浏览器查看、访问或管理系统文件或文件夹。

![](/data/attachment/album/201809/19/090158z46u3y69ib4o233y.png)

**Cloud Commander** 是一个基于 web 的文件管理程序，它允许你通过任何计算机、移动端或平板电脑的浏览器查看、访问或管理系统文件或文件夹。它有两个简单而又经典的面板，并且会像你设备的显示尺寸一样自动转换大小。它也拥有两款内置的叫做 **Dword** 和 **Edward** 的文本编辑器，它们支持语法高亮，并带有一个支持系统命令行的控制台。因此，您可以随时随地编辑文件。Cloud Commander 服务器是一款在 Linux、Windows、Mac OS X 运行的跨平台应用，而且该应用客户端可以在任何一款浏览器上运行。它是用 **JavaScript/Node.Js** 写的，并使用 **MIT** 许可证。

在这个简易教程中，让我们看一看如何在 Ubuntu 18.04 LTS 服务器上安装 Cloud Commander。

### 前提条件

像我之前提到的，是用 Node.js 写的。所以为了安装 Cloud Commander，我们需要首先安装 Node.js。要执行安装，参考下面的指南。

* [如何在 Linux 上安装 Node.js](https://www.ostechnix.com/install-node-js-linux/)

### 安装 Cloud Commander

在安装 Node.js 之后，运行下列命令安装 Cloud Commander:

```
$ npm i cloudcmd -g
```

祝贺！Cloud Commander 已经安装好了。让我们往下继续看看 Cloud Commander 的基本使用。

### 开始使用 Cloud Commander

运行以下命令启动 Cloud Commander：

```
$ cloudcmd
```

**输出示例：**

```
url: http://localhost:8000
```

现在，打开你的浏览器并转到链接：`http://localhost:8000` 或 `http://IP-address:8000`。

从现在开始，您可以直接在本地系统或远程系统或移动设备，平板电脑等Web浏览器中创建，删除，查看，管理文件或文件夹。

![](/data/attachment/album/201809/19/090159fn9z2r9ecp912hc7.jpg)

如你所见上面的截图，Clouder Commander 有两个面板，十个热键 （`F1` 到 `F10`），还有控制台。

每个热键执行的都是一个任务。

* `F1` – 帮助
* `F2` – 重命名文件/文件夹
* `F3` – 查看文件/文件夹
* `F4` – 编辑文件
* `F5` – 复制文件/文件夹
* `F6` – 移动文件/文件夹
* `F7` – 创建新目录
* `F8` – 删除文件/文件夹
* `F9` – 打开菜单
* `F10` – 打开设置

#### Cloud Commmander 控制台

点击控制台图标。这即将打开系统默认的命令行界面。

![](/data/attachment/album/201809/19/090201djpv00js8soe3jsf.jpg)

在此控制台中，您可以执行各种管理任务，例如安装软件包、删除软件包、更新系统等。您甚至可以关闭或重新引导系统。 因此，Cloud Commander 不仅仅是一个文件管理器，还具有远程管理工具的功能。

#### 创建文件/文件夹

要创建新的文件或文件夹就右键单击任意空位置并找到 “New - >File or Directory”。

![](/data/attachment/album/201809/19/090205ru6oaujaz4u5zjva.png)

#### 查看文件

你可以查看图片，查看音视频文件。

![](/data/attachment/album/201809/19/090207ox4xcwx8c62wy42j.jpg)

#### 上传文件

另一个很酷的特性是我们可以从任何系统或设备简单地上传一个文件到 Cloud Commander 系统。

要上传文件，右键单击 Cloud Commander 面板的任意空白处，并且单击“Upload”选项。

![](/data/attachment/album/201809/19/090208j3ez9jei3ka35fg3.png)

选择你想要上传的文件。

另外，你也可以上传来自像 Google 云盘、Dropbox、Amazon 云盘、Facebook、Twitter、Gmail、GitHub、Picasa、Instagram 还有很多的云服务上的文件。

要从云端上传文件, 右键单击面板的任意空白处，并且右键单击面板任意空白处并选择“Upload from Cloud”。

![](/data/attachment/album/201809/19/090210bqcuqkhduuc1fjqu.png)

选择任意一个你选择的网络服务，例如谷歌云盘。点击“Connect to Google drive”按钮。

![](/data/attachment/album/201809/19/090211f7vgcdk728k8ev3s.jpg)

下一步，用 Cloud Commander 验证你的谷歌云端硬盘，从谷歌云端硬盘选择文件并点击“Upload”。

![](/data/attachment/album/201809/19/090213b3pbsujhr6pbhrh3.jpg)

#### 更新 Cloud Commander

要更新到最新的可用版本，执行下面的命令：

```
$ npm update cloudcmd -g
```

#### 总结

据我测试，它运行很好。在我的 Ubuntu 服务器测试期间，我没有遇到任何问题。此外，Cloud Commander 不仅是基于 Web 的文件管理器，还可以充当执行大多数 Linux 管理任务的远程管理工具。 您可以创建文件/文件夹、重命名、删除、编辑和查看它们。此外，您可以像在终端中在本地系统中那样安装、更新、升级和删除任何软件包。当然，您甚至可以从 Cloud Commander 控制台本身关闭或重启系统。 还有什么需要的吗？ 尝试一下，你会发现它很有用。

目前为止就这样吧。 我将很快在这里发表另一篇有趣的文章。 在此之前，请继续关注我们。

祝贺！

---

via: <https://www.ostechnix.com/cloud-commander-a-web-file-manager-with-console-and-editor/>

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

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


如何使用 Apache 构建 URL 缩短服务

Summary: 用 Apache HTTP 服务器的 mod_rewrite 功能创建你自己的短链接。

>
> 用 Apache HTTP 服务器的 mod\_rewrite 功能创建你自己的短链接。
>
>
>

![](/data/attachment/album/201809/19/223103exq5ziz5baxbuix1.png)

很久以前，人们开始在 Twitter 上分享链接。140 个字符的限制意味着 URL 可能消耗一条推文的大部分（或全部），因此人们使用 URL 缩短服务。最终，Twitter 加入了一个内置的 URL 缩短服务（[t.co](http://t.co)）。

字符数现在不重要了，但还有其他原因要缩短链接。首先，缩短服务可以提供分析功能 —— 你可以看到你分享的链接的受欢迎程度。它还简化了制作易于记忆的 URL。例如，[bit.ly/INtravel](http://bit.ly/INtravel) 比<https://www.in.gov/ai/appfiles/dhs-countyMap/dhsCountyMap.html>更容易记住。如果你想预先共享一个链接，但还不知道最终地址，这时 URL 缩短服务可以派上用场。。

与任何技术一样，URL 缩短服务并非都是正面的。通过屏蔽最终地址，缩短的链接可用于指向恶意或冒犯性内容。但是，如果你仔细上网，URL 缩短服务是一个有用的工具。

我们之前在网站上[发布过缩短服务的文章](https://opensource.com/article/17/3/url-link-shortener)，但也许你想要运行一些由简单的文本文件支持的缩短服务。在本文中，我们将展示如何使用 Apache HTTP 服务器的 mod\_rewrite 功能来设置自己的 URL 缩短服务。如果你不熟悉 Apache HTTP 服务器，请查看 David Both 关于[安装和配置](https://opensource.com/article/18/2/how-configure-apache-web-server)它的文章。

### 创建一个 VirtualHost

在本教程中，我假设你购买了一个很酷的域名，你将它专门用于 URL 缩短服务。例如，我的网站是 [funnelfiasco.com](http://funnelfiasco.com)，所以我买了 [funnelfias.co](http://funnelfias.co) 用于我的 URL 缩短服务（好吧，它不是很短，但它可以满足我的虚荣心）。如果你不将缩短服务作为单独的域运行，请跳到下一部分。

第一步是设置将用于 URL 缩短服务的 VirtualHost。有关 VirtualHost 的更多信息，请参阅 [David Both 的文章](https://opensource.com/article/18/3/configuring-multiple-web-sites-apache)。这步只需要几行：

```
    <VirtualHost *:80>
        ServerName funnelfias.co
    </VirtualHost>
```

### 创建重写规则

此服务使用 HTTPD 的重写引擎来重写 URL。如果你在上面的部分中创建了 VirtualHost，则下面的配置跳到你的 VirtualHost 部分。否则跳到服务器的 VirtualHost 或主 HTTPD 配置。

```
    RewriteEngine on
    RewriteMap shortlinks txt:/data/web/shortlink/links.txt
    RewriteRule ^/(.+)$ ${shortlinks:$1} [R=temp,L]
```

第一行只是启用重写引擎。第二行在文本文件构建短链接的映射。上面的路径只是一个例子。你需要使用系统上使用有效路径（确保它可由运行 HTTPD 的用户帐户读取）。最后一行重写 URL。在此例中，它接受任何字符并在重写映射中查找它们。你可能希望重写时使用特定的字符串。例如，如果你希望所有缩短的链接都是 “slX”（其中 X 是数字），则将上面的 `(.+)` 替换为 `(sl\d+)`。

我在这里使用了临时重定向（HTTP 302）。这能让我稍后更新目标 URL。如果希望短链接始终指向同一目标，则可以使用永久重定向（HTTP 301）。用 `permanent` 替换第三行的 `temp`。

### 构建你的映射

编辑配置文件 `RewriteMap` 行中的指定文件。格式是空格分隔的键值存储。在每一行上放一个链接：

```
    osdc https://opensource.com/users/bcotton
    twitter https://twitter.com/funnelfiasco
    swody1 https://www.spc.noaa.gov/products/outlook/day1otlk.html
```

### 重启 HTTPD

最后一步是重启 HTTPD 进程。这是通过 `systemctl restart httpd` 或类似命令完成的（命令和守护进程名称可能因发行版而不同）。你的链接缩短服务现已启动并运行。当你准备编辑映射时，无需重新启动 Web 服务器。你所要做的就是保存文件，Web 服务器将获取到差异。

### 未来的工作

此示例为你提供了基本的 URL 缩短服务。如果你想将开发自己的管理接口作为学习项目，它可以作为一个很好的起点。或者你可以使用它分享容易记住的链接到那些容易忘记的 URL。

---

via: <https://opensource.com/article/18/7/apache-url-shortener>

作者：[Ben Cotton](https://opensource.com/users/bcotton) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


我从编程面试中学到的

Summary: 聊聊白板编程面试

![](/data/attachment/album/201809/19/232639udzlfvfqy6v66fvt.jpeg)

在 2017 年，我参加了 ‘计算机行业中的女性’ 的[Grace Hopper 庆祝活动](https://anitab.org/event/2017-grace-hopper-celebration-women-computing/)。这个活动是这类科技活动中最大的一个。共有 17,000 名女性IT工作者参加。

这个会议有个大型的配套招聘会，会上有招聘公司来面试会议参加者。有些人甚至现场拿到 offer。我在现场晃荡了一下，注意到一些应聘者看上去非常紧张忧虑。我还隐隐听到应聘者之间的谈话，其中一些人谈到在面试中做的并不好。

我走近我听到谈话的那群人并和她们聊了起来并给了一些面试上的小建议。我想我的建议还是比较偏基本的，如“（在面试时）一开始给出个能工作的解决方案也还说的过去”之类的，但是当她们听到我的一些其他的建议时还是颇为吃惊。

为了能更多的帮到像她们一样的小白面试者，我收集了一些过去对我有用的小点子，这些小点子我已经发表在了 [prodcast episode](https://thewomenintechshow.com/2017/12/18/programming-interviews/) 上。它们也是这篇文章的主题。

为了实习生职位和全职工作，我做过很多次的面试。当我还在大学主修计算机科学时，学校每个秋季学期都有招聘会，第一轮招聘会在校园里举行。(我在第一和最后一轮都搞砸过。)不过，每次面试后，我都会反思哪些方面我能做的更好，我还会和朋友们做模拟面试，这样我就能从他们那儿得到更多的面试反馈。

不管我们怎么样找工作: 工作中介、网络，或者学校招聘，他们的招聘流程中都会涉及到技术面试：

近年来，我注意到了一些新的不同的面试形式出现了：

* 与招聘方的一位工程师结对编程
* 网络在线测试及在线编码
* 白板编程（LCTT 译注： 这种形式应该不新了）

我将重点谈谈白板面试，这种形式我经历的最多。我有过很多次面试，有些挺不错的，有些被我搞砸了。

#### 我做错的地方

首先，我想回顾一下我做的不好的地方。知错能改，善莫大焉。

当面试者提出一个要我解决的问题时， 我立即马上立刻开始在白板上写代码，什么都不问。

这里我犯了两个错误：

#### 没有澄清对解决问题有关键作用的信息

比如，我们是否只用处理数字或者字符串？我们要支持多种数据类型吗？如果你在开始解题前不去问这些问题的话，你的面试官会有一种不好的印象：这个人在我们公司的话，他不会在开始项目工作之前不问清楚到底要做什么。而这恰恰是在工作场合很重要的一个工作习惯。公司可不像学校，你在开始工作前可不会得到写有所有详细步骤的作业说明。你得靠自己找到这些步骤并自己定义他们。

#### 只会默默思考，不去记录想法或和面试官沟通

在面试中，很多时候我也会傻傻站在那思考，什么都不写。我和一个朋友模拟面试的时候，他告诉我因为他曾经和我一起工作过所以他知道我在思考，但是如果他是个陌生的面试官的话，他会觉得我正站在那冥思苦想，毫无头绪。不要急匆匆的直奔解题而去是很重要的。花点时间多想想各种解题的可能性。有时候面试官会乐意和你一起探索解题的步骤。不管怎样，这就是在一家公司开工作会议的的普遍方式，大家各抒己见，一起讨论如何解决问题。

### 想到一个解题方法

在你开始写代码之前，如果你能总结一下要使用到的算法就太棒了。不要上来就写代码并认为你的代码肯定能解决问题。

这是对我管用的步骤：

1. 头脑风暴
2. 写代码
3. 处理错误路径
4. 测试

#### 1、 头脑风暴

对我来说，我会首先通过一些例子来视觉化我要解决的问题。比如说如果这个问题和数据结构中的树有关，我就会从树底层的空节点开始思考，如何处理一个节点的情况呢？两个节点呢？三个节点呢？这能帮助你从具体例子里抽象出你的解决方案。

在白板上先写下你的算法要做的事情列表。这样做，你往往能在开始写代码前就发现 bug 和缺陷（不过你可得掌握好时间）。我犯过的一个错误是我花了过多的时间在澄清问题和头脑风暴上，最后几乎没有留下时间给我写代码。你的面试官可能没有机会看你在白板上写下代码，这可太糟了。你可以带块手表，或者房间有钟的话，你也可以抬头看看时间。有些时候面试者会提醒你你已经得到了所有的信息（这时你就不要再问别的了），“我想我们已经把所有需要的信息都澄清了，让我们写代码实现吧”。

#### 2、 开始写代码，一气呵成

如果你还没有得到问题的完美解决方法，从最原始的解法开始总是可以的。当你在向面试官解释最显而易见的解法时，你要想想怎么去完善它，并指明这种做法是最原始的，未加优化的。（请熟悉算法中的 `O()` 的概念，这对面试非常有用。）在向面试者提交前请仔细检查你的解决方案两三遍。面试者有时会给你些提示， “还有更好的方法吗？”，这句话的意思是面试官提示你有更优化的解决方案。

#### 3、 错误处理

当你在编码时，对你想做错误处理的代码行做个注释。当面试者说，“很好，这里你想到了错误处理。你想怎么处理呢？抛出异常还是返回错误码？”，这将给你个机会去引出关于代码质量的一番讨论。当然，这种地方提出几个就够了。有时，面试者为了节省编码的时间，会告诉你可以假设外界输入的参数都已经通过了校验。不管怎样，你都要展现你对错误处理和编码质量的重要性的认识。

#### 4、 测试

在编码完成后，用你在前面头脑风暴中写的用例来在你脑子里“跑”一下你的代码，确定万无一失。例如你可以说，“让我用前面写下的树的例子来跑一下我的代码，如果是一个节点是什么结果，如果是两个节点是什么结果……”

在你结束之后，面试者有时会问你你将会怎么测试你的代码，你会涉及什么样的测试用例。我建议你用下面不同的分类来组织你的错误用例：

一些分类可以为：

1. 性能
2. 错误用例
3. 期望的正常用例

对于性能测试，要考虑极端数量下的情况。例如，如果问题是关于列表的，你可以说你将会使用一个非常大的列表以及的非常小的列表来测试。如果和数字有关，你将会测试系统中的最大整数和最小整数。我建议读一些有关软件测试的书来得到更多的知识。在这个领域我最喜欢的书是 《[我们在微软如何测试软件](https://www.amazon.com/How-We-Test-Software-Microsoft/dp/0735624259)》。

对于错误用例，想一下什么是期望的错误情况并一一写下。

对于正向期望用例，想想用户需求是什么？你的解决方案要解决什么问题？这些都可以成为正向期望用例。

### “你还有什么要问我的吗？”

面试最后总是会留几分钟给你问问题。我建议你在面试前写下你想问的问题。千万别说，“我没什么问题了”，就算你觉得面试砸了或者你对这间公司不怎么感兴趣，你总有些东西可以问问。你甚至可以问面试者他最喜欢自己的工作什么，最讨厌自己的工作什么。或者你可以问问面试官的工作具体是什么，在用什么技术和实践。不要因为觉得自己在面试中做的不好而心灰意冷，不想问什么问题。

### 申请一份工作

关于找工作和申请工作，有人曾经告诉我，你应该去找你真正有激情工作的地方。去找一家你喜欢的公司，或者你喜欢使用的产品，看看你能不能去那儿工作。

我个人并不推荐你用上述的方法去找工作。你会排除很多很好的公司，特别是你是在找实习工作或者入门级的职位时。

你也可以集中在其他的一些目标上。如：我想从这个工作里得到哪方面的更多经验？这个工作是关于云计算？Web 开发？或是人工智能？当在招聘会上与招聘公司沟通时，看看他们的工作单位有没有在这些领域的。你可能会在一家并非在你的想去公司列表上的公司（或非盈利机构）里找到你想找的职位。

#### 换组

在这家公司里的第一个组里呆了一年半以后，我觉得是时候去探索一下不同的东西了。我找到了一个我喜欢的组并进行了 4 轮面试。结果我搞砸了。

我什么都没有准备，甚至都没在白板上练练手。我当时的逻辑是，如果我都已经在一家公司干了快 2 年了，我还需要练什么？我完全错了，我在接下去的白板面试中跌跌撞撞。我的板书写得太小，而且因为没有从最左上角开始写代码，我的代码大大超出了一个白板的空间，这些都导致了白板面试失败。

我在面试前也没有刷过数据结构和算法题。如果我做了的话，我将会在面试中更有信心。就算你已经在一家公司担任了软件工程师，在你去另外一个组面试前，我强烈建议你在一块白板上演练一下如何写代码。

对于换项目组这件事，如果你是在公司内部换组的话，事先能同那个组的人非正式聊聊会很有帮助。对于这一点，我发现几乎每个人都很乐于和你一起吃个午饭。人一般都会在中午有空，约不到人或者别人正好有会议冲突的风险会很低。这是一种非正式的途径来了解你想去的组正在干什么，以及这个组成员个性是怎么样的。相信我，你能从一次午餐中得到很多信息，这可会对你的正式面试帮助不小。

非常重要的一点是，你在面试一个特定的组时，就算你在面试中做的很好，因为文化不契合的原因，你也很可能拿不到 offer。这也是为什么我一开始就想去见见组里不同的人的原因（有时这也不太可能），我希望你不要被一次拒绝所击倒，请保持开放的心态，选择新的机会，并多多练习。

以上内容选自 《[The Women in Tech Show: Technical Interviews with Prominent Women in Tech](https://thewomenintechshow.com/)》的 “[编程面试](https://thewomenintechshow.com/2017/12/18/programming-interviews/)”章节，

---

作者简介：

微软研究院 Software Engineer II， [www.thewomenintechshow.com](http://www.thewomenintechshow.com) 站长，所有观点都只代表本人意见。

---

via: <https://medium.freecodecamp.org/what-i-learned-from-programming-interviews-29ba49c9b851>

作者：[Edaena Salinas](https://medium.freecodecamp.org/@edaenas) 译者：[DavidChenLiang](https://github.com/DavidChenLiang) 校对：[wxy](https://github.com/wxy)

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


初学者指南：ZFS 是什么，为什么要使用 ZFS？

原来如此 解惑了

![ZFS filesystem](/data/attachment/album/201809/20/231709ns0cc5l3pii2i3ph.png)

今天，我们来谈论一下 ZFS，一个先进的文件系统。我们将讨论 ZFS 从何而来，它是什么，以及为什么它在科技界和企业界如此受欢迎。

虽然我是一个美国人，但我更喜欢读成 ZedFS 而不是 ZeeFS，因为前者听起来更酷一些。你可以根据你的个人喜好来发音。

>
> 注意：在这篇文章中，你将会看到 ZFS 被提到很多次。当我在谈论特性和安装的时候，我所指的是 OpenZFS 。自从<ruby> 甲骨文 <rt>  Oracle </rt></ruby>公司放弃 OpenSolaris 项目之后，ZFS（由甲骨文公司开发）和 OpenZFS 已经走向了不同的发展道路。
>
>
>

### ZFS 的历史

<ruby> Z 文件系统 <rt>  Z File System </rt></ruby>（ZFS）是由 [Matthew Ahrens 和 Jeff Bonwick](https://wiki.gentoo.org/wiki/ZFS) 在 2001 年开发的。ZFS 是作为[<ruby> 太阳微系统 <rt>  Sun MicroSystem </rt></ruby>](http://en.wikipedia.org/wiki/Sun_Microsystems) 公司的 [OpenSolaris](http://en.wikipedia.org/wiki/Opensolaris) 的下一代文件系统而设计的。在 2008 年，ZFS 被移植到了 FreeBSD 。同一年，一个移植 [ZFS 到 Linux](https://zfsonlinux.org/) 的项目也启动了。然而，由于 ZFS 是<ruby>   通用开发和发布许可证  <rt>  Common Development and Distribution License </rt></ruby>（CDDL）许可的，它和 [GNU 通用公共许可证](https://en.wikipedia.org/wiki/GNU_General_Public_License) 不兼容，因此不能将它迁移到 Linux 内核中。为了解决这个问题，绝大多数 Linux 发行版提供了一些方法来安装 ZFS　。

在甲骨文公司收购太阳微系统公司之后不久，OpenSolaris 就闭源了，这使得 ZFS 的之后的开发也变成闭源的了。许多 ZFS 开发者对这件事情非常不满。[三分之二的 ZFS 核心开发者](https://wiki.gentoo.org/wiki/ZFS)，包括 Ahrens 和 Bonwick，因为这个决定而离开了甲骨文公司。他们加入了其它公司，并于 2013 年 9 月创立了 [OpenZFS](http://www.open-zfs.org/wiki/Main_Page) 这一项目。该项目引领着 ZFS 的开源开发。

让我们回到上面提到的许可证问题上。既然 OpenZFS 项目已经和 Oracle 公司分离开了，有人可能好奇他们为什么不使用和 GPL 兼容的许可证，这样就可以把它加入到 Linux 内核中了。根据 [OpenZFS 官网](http://www.open-zfs.org/wiki/FAQ#Do_you_plan_to_release_OpenZFS_under_a_license_other_than_the_CDDL.3F) 的介绍，更改许可证需要联系所有为当前 OpenZFS 实现贡献过代码的人（包括初始的公共 ZFS 代码以及 OpenSolaris 代码），并得到他们的许可才行。这几乎是不可能的（因为一些贡献者可能已经去世了或者很难找到），因此他们决定保留原来的许可证。

### ZFS 是什么，它有什么特性？

正如前面所说过的，ZFS 是一个先进的文件系统。因此，它有一些有趣的[特性](https://wiki.archlinux.org/index.php/ZFS)。比如：

* 存储池
* 写时拷贝
* 快照
* 数据完整性验证和自动修复
* RAID-Z
* 最大单个文件大小为 16 EB（1 EB = 1024 PB）
* 最大 256 千万亿（256\*10 15 ）的 ZB（1 ZB = 1024 EB）的存储

让我们来深入了解一下其中一些特性。

#### 存储池

与大多数文件系统不同，ZFS 结合了文件系统和卷管理器的特性。这意味着，它与其他文件系统不同，ZFS 可以创建跨越一系列硬盘或池的文件系统。不仅如此，你还可以通过添加硬盘来增大池的存储容量。ZFS 可以进行[分区和格式化](https://www.howtogeek.com/175159/an-introduction-to-the-z-file-system-zfs-for-linux/)。

![Pooled storage in ZFS](/data/attachment/album/201809/20/231710te5zjh04sahk0zep.png)

*ZFS 存储池*

#### 写时拷贝

<ruby>   写时拷贝  <rt>  Copy-on-write </rt></ruby>是另一个有趣并且很酷的特性。在大多数文件系统上，当数据被重写时，它将永久丢失。而在 ZFS 中，新数据会写到不同的块。写完成之后，更新文件系统元数据信息，使之指向新的数据块（LCTT 译注：更新之后，原数据块成为磁盘上的垃圾，需要有对应的垃圾回收机制）。这确保了如果在写新数据的时候系统崩溃（或者发生其它事，比如突然断电），那么原数据将会保存下来。这也意味着，在系统发生崩溃之后，不需要运行 [fsck](https://en.wikipedia.org/wiki/Fsck) 来检查和修复文件系统。

#### 快照

写时拷贝使得 ZFS 有了另一个特性：<ruby> 快照 <rt>  snapshots </rt></ruby>。ZFS 使用快照来跟踪文件系统中的更改。[快照](https://www.freebsd.org/doc/handbook/zfs-term.html)包含文件系统的原始版本（文件系统的一个只读版本），实时文件系统则包含了自从快照创建之后的任何更改。没有使用额外的空间。因为新数据将会写到实时文件系统新分配的块上。如果一个文件被删除了，那么它在快照中的索引也会被删除。所以，快照主要是用来跟踪文件的更改，而不是文件的增加和创建。

快照可以挂载成只读的，以用来恢复一个文件的过去版本。实时文件系统也可以回滚到之前的快照。回滚之后，自从快照创建之后的所有更改将会丢失。

#### 数据完整性验证和自动修复

当向 ZFS 写入新数据时，会创建该数据的校验和。在读取数据的时候，使用校验和进行验证。如果前后校验和不匹配，那么就说明检测到了错误，然后，ZFS 会尝试自动修正错误。

#### RAID-Z

ZFS 不需要任何额外软件或硬件就可以处理 RAID（磁盘阵列）。毫不奇怪，因为 ZFS 有自己的 RAID 实现：RAID-Z 。RAID-Z 是 RAID-5 的一个变种，不过它克服了 RAID-5 的写漏洞：意外重启之后，数据和校验信息会变得不同步（LCTT 译注：RAID-5 的条带在正写入数据时，如果这时候电源中断，那么奇偶校验数据将跟该部分数据不同步，因此前边的写无效；RAID-Z 用了 “可变宽的 RAID 条带” 技术，因此所有的写都是全条带写入）。为了使用[基本级别的 RAID-Z](https://wiki.archlinux.org/index.php/ZFS/Virtual_disks#Creating_and_Destroying_Zpools)（RAID-Z1），你需要至少三块磁盘，其中两块用来存储数据，另外一块用来存储[奇偶校验信息](https://www.pcmag.com/encyclopedia/term/60364/raid-parity)。而 RAID-Z2 需要至少两块磁盘存储数据以及两块磁盘存储校验信息。RAID-Z3 需要至少两块磁盘存储数据以及三块磁盘存储校验信息。另外，只能向 RAID-Z 池中加入偶数倍的磁盘，而不能是奇数倍的。

#### 巨大的存储潜力

创建 ZFS 的时候，它是作为[最后一个文件系统](https://web.archive.org/web/20060428092023/http://www.sun.com/2004-0914/feature/)而设计的 。那时候，大多数文件系统都是 64 位的，ZFS 的创建者决定直接跳到 128 位，等到将来再来证明这是对的。这意味着 ZFS 的容量大小是 32 位或 64 位文件系统的 1600 亿亿倍。事实上，Jeff Bonwick（其中一个创建者）说：“完全填满一个 128 位的存储池所需要的[能量](https://blogs.oracle.com/bonwick/128-bit-storage:-are-you-high)，从字面上讲，比煮沸海洋需要的还多。”

### 如何安装 ZFS？

如果你想立刻使用 ZFS（开箱即用），那么你需要安装 [FreeBSD](https://www.freebsd.org/) 或一个[使用 illumos 内核的操作系统](https://wiki.illumos.org/display/illumos/Distributions)。[illumos](https://wiki.illumos.org/display/illumos/illumos+Home) 是 OpenSolaris 内核的一个克隆版本。

事实上，支持 [ZFS 是一些有经验的 Linux 用户选择 BSD 的主要原因](https://itsfoss.com/why-use-bsd/)。

如果你想在 Linux 上尝试 ZFS，那么只能在存储文件系统上使用。据我所知，没有任何 Linux 发行版可以在根目录上安装 ZFS，实现开箱即用。如果你对在 Linux 上尝试 ZFS 感兴趣，那么 [ZFS on Linux 项目](https://zfsonlinux.org/) 上有大量的教程可以指导你怎么做。

### 附加说明

这篇文章论述了 ZFS 的优点。现在，让我来告诉你一个关于 ZFS 很现实的问题。使用 RAID-Z [会很贵](http://louwrentius.com/the-hidden-cost-of-using-zfs-for-your-home-nas.html)，因为你需要购买大量的磁盘来增大存储空间。

你已经使用过 ZFS 了吗？你的使用经验是什么样的？请在下面的评论中告诉我们。

如果你觉得这篇文章有趣，请花一分钟的时间把它分享到社交媒体、极客新闻或 [Reddit](http://reddit.com/r/linuxusersgroup) 。

---

via: <https://itsfoss.com/what-is-zfs/>

作者：[John Paul](https://itsfoss.com/author/john/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


Flash Player 的两种开源替代方案

>
> Adobe 将于 2020 年终止对 Flash 媒体播放器的支持，但仍有很多人们希望访问的 Flash 视频。这里有两个开源的替代品或许可以帮到你。
>
>
>

![](/data/attachment/album/201809/21/161024gdcpdc7v70v7w37i.png)

2017 年 7 月，Adobe 为 Flash Media Player 敲响了[丧钟](https://theblog.adobe.com/adobe-flash-update/)，宣布将在 2020 年终止对曾经无处不在的在线视频播放器的支持。但事实上，在一系列损害了其声誉的零日攻击后，Flash 的份额在过去的 8 年一直在下跌。苹果公司在 2010 年宣布它不会支持这项技术后，其未来趋于黯淡，并且在谷歌停止在 Chrome 浏览器中默认启用 Flash（支持 HTML5）后，它的消亡在 2016 年进一步加速。

即便如此，Adobe 仍然每月发布该软件的更新，截至 2018 年 8 月，它在网站的使用率从 2011 年的 28.5% 下降到[仅 4.4％](https://w3techs.com/technologies/details/cp-flash/all/all)。还有更多证据表明 Flash 的下滑：谷歌工程总监 [Parisa Tabriz 说](https://www.bleepingcomputer.com/news/security/google-chrome-flash-usage-declines-from-80-percent-in-2014-to-under-8-percent-today/)通过浏览器访问 Flash 内容的 Chrome 用户数量从 2014 年的 80％ 下降到 2018 年的 8％。

尽管如今很少有视频创作者以 Flash 格式发布，但仍有很多人们希望在未来几年内访问的 Flash 视频。鉴于官方支持的日期已经屈指可数，开源软件创建者有很好的机会涉足 Adobe Flash 媒体播放器的替代品。这其中两个应用是 Lightspark 和 GNU Gnash。它们都不是完美的替代品，但来自贡献者的帮助可以使它们成为可行的替代品。

### Lightspark

[Lightspark](http://lightspark.github.io/) 是 Linux 上的 Flash Player 替代品。虽然它仍处于 alpha 状态，但自从 Adobe 在 2017 宣布废弃 Adobe 以来，开发速度已经加快。据其网站称，Lightspark 实现了 60% 的 Flash API，可在许多流行网站包括 BBC 新闻、Google Play 音乐和亚马逊音乐上[使用](https://github.com/lightspark/lightspark/wiki/Site-Support)。

Lightspark 是用 C++/C 编写的，并在 [LGPLv3](https://github.com/lightspark/lightspark/blob/master/COPYING) 下许可。该项目列出了 41 个贡献者，并正在积极征求错误报告和其他贡献。有关更多信息，请查看其 [GitHub 仓库](https://github.com/lightspark/lightspark/wiki/Site-Support)。

### GNU Gnash

[GNU Gnash](https://www.gnu.org/software/gnash/) 是一个用于 GNU/Linux 操作系统，包括 Ubuntu、Fedora 和 Debian 的 Flash Player。它作为独立软件和插件可用于 Firefox 和 Konqueror 浏览器中。

Gnash 的主要缺点是它不支持最新版本的 Flash 文件 —— 它支持大多数 Flash SWF v7 功能，一些 v8 和 v9 功能，不支持 v10 文件。它处于测试阶段，由于它在 [GNU GPLv3 或更高版本](http://www.gnu.org/licenses/gpl-3.0.html)下许可，因此你可以帮助实现它的现代化。访问其[项目页面](http://savannah.gnu.org/projects/gnash/)获取更多信息。

### 想要创建 Flash 吗？

仅因为大多数人都不会发布 Flash 视频，但这并不意味着永远不需要创建 SWF 文件。如果你发现自己需要，这两个开源工具可能会有所帮助：

* [Motion-Twin ActionScript 2 编译器](http://tech.motion-twin.com/mtasc.html)（MTASC）：一个命令行编译器，它可以在没有 Adobe Animate（Adobe 当前的视频创建软件）的情况下生成 SWF 文件。
* [Ming](http://www.libming.org/)：用 C 编写的可以生成 SWF 文件的库。它还包含一些可用于处理 Flash 的[程序](http://www.libming.org/WhatsIncluded)。

---

via: <https://opensource.com/alternatives/flash-media-player>

作者：[Opensource.com](https://opensource.com) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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