Samba 系列（九）：将 CentOS 7 桌面系统加入到 Samba4 AD 域环境中

没有必要编辑网络适配器的配置文件，7 的话完全可以用 nmcli 这种 help 的命令行工具，当然也无需重启服务。域名 .lan 估计也有问题，因为 SAMBA 强烈建议选用在互联网广泛使用的顶级域名，否则在实际使用会遇到一系列问题，比如拿不到针对该域名的数字证书。我看 .lan 并不是被广泛使用的域名。

加域只需要安装samba-winbind这个包就可以了，其他的多余。

.lan 并非有效的顶级域吧。

大佬，我按您的方法还是加入不进去。提示：Failed to join domain: failed to connect to AD: No logon servers are currently available to service the logon request.

来自广东深圳的 Internet Explorer 11.0|Windows 10 用户

这篇文章讲述了如何使用 Authconfig-gtk 工具将 CentOS 7 桌面系统加入到 Samba4 AD 域环境中，并使用域帐号登录到 CentOS 系统。

![](/data/attachment/album/201705/17/145148z2z2sccj8cp7sj68.jpg)

### 要求

1、[在 Ubuntu 系统中使用 Samba4 创建活动目录架构](/article-8065-1.html)

2、[CentOS 7.3 安装指南](/article-8048-1.html)

### 第一步：在 CentOS 系统中配置 Samba4 AD DC

1、在将 CentOS 7 加入到 Samba4 域环境之前，你得先配置 CentOS 系统的网络环境，确保在 CentOS 系统中通过 DNS 可以解析到域名。

打开网络设置，关闭有线网卡。打开下方的设置按钮，手动编辑网络设置，指定 DNS 的 IP 地址为 Samba4 AD DC 服务器的 IP 地址。

设置完成之后，应用配置，并打开有线网卡。

![](/data/attachment/album/201705/17/151749pea8111tatjfaab0.jpg)

*网络设置*

![](/data/attachment/album/201705/17/151847kzmmfcsmcfe1cycc.jpg)

*配置网络*

2、下一步，打开网络配置文件，在文件末尾添加一行域名信息。这样能确保当你仅使用主机名来查询域中的 DNS 记录时， DNS 解析器会自动把域名添加进来。

```
$ sudo vi /etc/sysconfig/network-scripts/ifcfg-eno16777736

```

添加下面一行：

```
SEARCH="your_domain_name"

```

*![](/data/attachment/album/201705/17/151948qgykbe7emeeeejb9.jpg)*

*网卡配置*

3、最后，重启网卡服务以应用更改，并验证解析器的配置文件是否正确配置。我们通过使用 ping 命令加上 DC 服务器的主机名或域名以验证 DNS 解析能否正常运行。

```
$ sudo systemctl restart network
$ cat /etc/resolv.conf
$ ping -c1 adc1
$ ping -c1 adc2
$ ping tecmint.lan

```

![](/data/attachment/album/201705/17/153310yn797h2h71029akh.jpg)

*验证网络配置是否正常*

4、同时，使用下面的命令来配置你的主机名，然后重启计算机以应用更改：

```
$ sudo hostnamectl set-hostname your_hostname
$ sudo init 6

```

使用下面的命令来验证主机名是否正确配置：

```
$ cat /etc/hostname
$ hostname

```

5、最后一步配置是使用下面的命令来保证系统时间跟 Samba4 AD DC 服务器的时间同步：

```
$ sudo yum install ntpdate
$ sudo ntpdate -ud domain.tld

```

### 第二步：安装要加入 Samba4 AD DC 所必需的软件包

6、为了将 CentOS 7 加入到活动目录域中，你需要使用下面的命令来安装相关的软件包：

```
$ sudo yum install samba samba samba-winbind krb5-workstation

```

7、最后，安装 CentOS 软件库中提供的图形化界面软件包： Authconfig-gtk 。该软件用于将 CentOS 系统集成到域环境中。

```
$ sudo yum install authconfig-gtk

```

### 第三步：将 CentOS 7 桌面系统集成到 Samba4 AD DC 域环境中

8、将 CentOS 加入到域的过程非常简单。使用有 root 权限的帐号在命令行下打开 Authconfig-gtk 程序，然后按下图所示修改相关配置即可：

```
$ sudo authconfig-gtk

```

打开身份或认证配置页面：

* 用户帐号数据库 ： 选择 Winbind
* Winbind 域 ： 你的域名
* 安全模式 ： ADS
* Winbind ADS 域 ： 你的域名.TLD
* 域控制器 ： 域控服务器的全域名
* 默认Shell ： /bin/bash
* 勾选允许离线登录

![](/data/attachment/album/201705/17/153602abqcq3zcbca7gb8s.jpg)

*域认证配置*

打开高级选项配置页面：

* 本地认证选项 ： 支持指纹识别
* 其它认证选项 ： 用户首次登录创建家目录

![](/data/attachment/album/201705/17/154238js2imzui2bg9k0zi.jpg)

*高级认证配置*

9、修改完上面的配置之后，返回到身份或认证配置页面，点击加入域按钮，在弹出的提示框点保存即可。

![](/data/attachment/album/201705/17/155141gyif2gezyoee9nie.jpg)

*身份和认证*

![](/data/attachment/album/201705/17/155212i33k3v47r3okuhuk.jpg)

*保存认证配置*

10、保存配置之后，系统将会提示你提供域管理员信息以将 CentOS 系统加入到域中。输入域管理员帐号及密码后点击 OK 按钮，加入域完成。

![](/data/attachment/album/201705/17/155243dpw45pt5w2zor2r2.jpg)

*加入 Winbind 域环境*

11、加入域后，点击应用按钮以让配置生效，选择所有的 windows 并重启机器。

![](/data/attachment/album/201705/17/155411mwicfmkxuuu9bmeo.jpg)

*应用认证配置*

12、要验证 CentOS 是否已成功加入到 Samba4 AD DC 中，你可以在安装了 [RSAT 工具](/article-8097-1.html) 的 windows 机器上，打开 AD 用户和计算机工具，点击域中的计算机。

你将会在右侧看到 CentOS 主机信息。

![](/data/attachment/album/201705/17/155526hpm72apmm1zcm1rm.jpg)

*活动目录用户和计算机*

### 第四步：使用 Samba4 AD DC 帐号登录 CentOS 桌面系统

13、选择使用其它账户，然后输入域帐号和密码进行登录，如下图所示：

```
Domain\domain_account
或
Domain_user@domain.tld

```

*![](/data/attachment/album/201705/17/155649u8yikss7f11r7c6f.jpg)*

*使用其它账户*

*![](/data/attachment/album/201705/17/155725qqrshhhho6c9hhee.jpg)*

*输入域用户名*

14、在 CentOS 系统的命令行中，你也可以使用下面的任一方式来切换到域帐号进行登录：

```
$ su - domain\domain_user
$ su - domain_user@domain.tld

```

*![](/data/attachment/album/201705/17/155752f3wkw7k8f87kr4k9.jpg)*

*使用域帐号登录*

![](/data/attachment/album/201705/17/160019veb3gwqm39b5ququ.jpg)

*使用域帐号邮箱登录*

15、要为域用户或组添加 root 权限，在命令行下使用 root 权限帐号打开 `sudoers` 配置文件，添加下面一行内容：

```
YOUR_DOMAIN\\domain_username             ALL=(ALL:ALL) ALL      #For domain users
%YOUR_DOMAIN\\your_domain\  group            ALL=(ALL:ALL) ALL  #For domain groups

```

*![](/data/attachment/album/201705/17/160103lvbzs440fbybxvy2.jpg)*

*指定用户和用户组权限*

16、使用下面的命令来查看域控制器信息：

```
$ sudo net ads info

```

*![](/data/attachment/album/201705/17/160132dcu17qvmmi7xkmtd.jpg)*

*查看域控制器信息*

17、你可以在安装了 Winbind 客户端的机器上使用下面的命令来验证 CentOS 加入到 Samba4 AD DC 后的信任关系是否正常：

```
$ sudo yum install samba-winbind-clients

```

然后，执行下面的一些命令来查看 Samba4 AD DC 的相关信息：

```
$ wbinfo -p ### Ping 域名
$ wbinfo -t ### 检查信任关系
$ wbinfo -u ### 列出域用户帐号
$ wbinfo -g ### 列出域用户组
$ wbinfo -n domain_account ### 查看域帐号的 SID 信息

```

*![](/data/attachment/album/201705/17/160159s63la9k0ljz69ll2.jpg)*

*查看 Samba4 AD DC 信息*

18、如果你想让 CentOS 系统退出域环境，使用具有管理员权限的帐号执行下面的命令，后面加上域名及域管理员帐号，如下图所示：

```
$ sudo net ads leave your_domain -U domain_admin_username

```

*![](/data/attachment/album/201705/17/160232kv0bljvl81v5khzk.jpg)*

*退出 Samba4 AD 域*

这篇文章就写到这里吧！尽管上面的这些操作步骤是将 CentOS 7 系统加入到 Samba4 AD DC 域中，其实这些步骤也同样适用于将 CentOS 7 桌面系统加入到 Microsoft Windows Server 2008 或 2012 的域中。

---

作者简介：

我是一个电脑迷，开源 Linux 系统和软件爱好者，有 4 年多的 Linux 桌面、服务器系统使用和 Base 编程经验。

---

via: <http://www.tecmint.com/join-centos-7-to-samba4-active-directory/>

作者：[Matei Cezar](http://www.tecmint.com/author/cezarmatei/) 译者：[rusking](https://github.com/rusking) 校对：[wxy](https://github.com/wxy)

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


如何安装 pandom ： 一个针对 Linux 的真随机数生成器

Summary: 本文将解释如何安装 pandom，这是一个由 ncomputers.org 维护的定时抖动真随机数生成器。

真随机？ 扯淡。

来自广东深圳的 Internet Explorer 8.0|Windows 7 用户

较新的 intel CPU 支持 RNRAND 指令集，这个伪随机方法比较实用。

![](/data/attachment/album/201705/17/204255id9jk0uijgo0g6jk.jpg)

本教程只针对 amd64/x86\_64 架构 Linux 内核版本大于等于 2.6.9 的系统。本文将解释如何安装 [pandom](http://ncomputers.org/pandom)，这是一个由 ncomputers.org 维护的定时抖动真随机数生成器。

### 简介

在现在的计算机状况下，比如说配置了固态硬盘（SSD）的个人电脑和虚拟专用服务器（VPS）的环境中，Linux 内核内置的真随机数发生器提供的吞吐量很低。

而出于各种不同的加密目的使得对真随机数的需求持续增长，从而使得这个低吞吐量问题在 Linux 实现中变得越来越严重。

在与上述相同的物理或者虚拟环境下，并假设没有其它进程以 root 身份向 `/dev/random` 进行写操作的话，64 [ubits](http://ncomputers.org/ubit)/64 bits 的 pandom 可以以 8 KiB/s 的速率生成随机数。

### 1 pandom 的安装

#### 1.1 获得 root 权限

Pandom 必须以 root 身份来安装，所以在必要的时候请运行如下命令：

```
su -

```

#### 1.2 安装编译所需的依赖

为了下载并安装 pandom，你需要 GNU `as` 汇编器、GNU `make`、GNU `tar` 和 GNU `wget` (最后两个工具通常已被安装)。随后你可以按照你的意愿卸载它们。

**基于 Arch 的系统：**

```
pacman -S binutils make

```

**基于 Debian 的系统：**

```
apt-get install binutils make

```

基于 Red Hat 的系统：

```
dnf install binutils make
yum install binutils make

```

**基于 SUSE 的系统：**

```
zypper install binutils make

```

#### 1.3 下载并析出源码

下面的命令将使用 `wget` 和 `tar` 从 ncomputers.org 下载 pandom 的源代码并将它们解压出来：

```
wget http://ncomputers.org/pandom.tar.gz
tar xf pandom.tar.gz
cd pandom/amd64-linux

```

#### 1.4 在安装前进行测试 (推荐)

这个被推荐的测试将花费大约 8 分钟的时间，它将检查内核支持情况并生成一个名为 `checkme` 的文件（在下一节中将被分析）。

```
make check

```

#### 1.5 确定系统的初始化程序

在安装 pandom 之前，你需要知道你的系统使用的是哪个初始化程序。假如下面命令的输出中包含 `running`，则意味着你的系统使用了 `systemd`，否则你的系统则可能使用了一个 `init.d` 的实现（例如 upstart、sysvinit）。

```
systemctl is-system-running
running

```

#### 1.6 安装 pandom

一旦你知道了你的系统使用何种 Linux 实现，那么你就可以相应地安装 pandom 了。

**使用基于 init.d 作为初始化程序（如： upstart、sysvinit）的系统：**

假如你的系统使用了一个 init.d 的实现（如： upstart、sysvinit），请运行下面的命令来安装 pandom：

```
make install-init.d

```

**以 systemd 作为初始化程序的系统：**

假如你的系统使用 `systemd`，则请运行以下命令来安装 pandom：

```
make install-systemd

```

### 2 checkme 文件的分析

在使用 pandom 进行加密之前，强烈建议分析一下先前在安装过程中生成的 `checkme` 文件。通过分析我们便可以知道用 pandom 生成的数是否真的随机。本节将解释如何使用 ncomputers.org 的 shell 脚本 `entropyarray` 来测试由 pandom 产生的输出的熵及序列相关性。

**注**：整个分析过程也可以在另一台电脑上完成，例如在一个笔记本电脑或台式机上。举个例子：假如你正在一个资源受到限制的 VPS 上安装 pandom 程序，或许你更倾向于将 `checkme` 复制到自己的个人电脑中，然后再进行分析。

#### 2.1 获取 root 权限

`entropyarray` 程序也必须以 root 身份来安装，所以在必要时请运行如下命令：

```
su -

```

#### 2.2 安装编译所需的依赖

为了下载并安装 `entropyarray`， 你需要 GNU g++ 编译器、GNU `make`、GNU `tar` 和 GNU `wget`。在随后你可以任意卸载这些依赖。

**基于 Arch 的系统：**

```
pacman -S gcc make

```

**基于 Debian 的系统：**

```
apt-get install g++ make

```

**基于 Red Hat 的系统：**

```
dnf install gcc-c++ make
yum install gcc-c++ make

```

**基于 SUSE 的系统：**

```
zypper install gcc-c++ make

```

#### 2.3 下载并析出源码

以下命令将使用 `wget` 和 `tar` 从 ncomputers.org 下载到 entropyarray 的源码并进行解压：

```
wget http://ncomputers.org/rearray.tar.gz
wget http://ncomputers.org/entropy.tar.gz
wget http://ncomputers.org/entropyarray.tar.gz

tar xf entropy.tar.gz
tar xf rearray.tar.gz
tar xf entropyarray.tar.gz

```

#### 2.4 安装 entropyarray

**注**：如果在编译过程中报有关 `-std=c++11` 的错误，则说明当前系统安装的 GNU g++ 版本不支持 ISO C++ 2011 标准，那么你可能需要在另一个支持该标准的系统中编译 ncomputers.org/entropy 和 ncomputers.org/rearray （例如在一个你喜爱的较新的 Linux 发行版本中来编译）。接着使用 `make install` 来安装编译好的二进制文件，再接着你可能想继续运行 `entropyarray` 程序，或者跳过运行该程序这一步骤，然而我还是建议在使用 pandom 来达到加密目地之前先分析一下 `checkme` 文件。

```
cd rearray; make install; cd ..
cd entropy; make install; cd ..
cd entropyarray; make install; cd ..

```

#### 2.5 分析 checkme 文件

**注**：64 [ubits](http://ncomputers.org/ubit) / 64 bits 的 pandom 实现所生成的结果中熵应该高于 `15.977` 且 `max` 字段低于 `70`。假如你的结果与之相差巨大，或许你应该按照下面第 5 节介绍的那样增加你的 pandom 实现的不可预测性。假如你跳过了生成 `checkme` 文件的那一步，你也可以使用其他的工具来进行测试，例如 [伪随机数序列测试](http://www.fourmilab.ch/random/)。

```
entropyarray checkme

entropyarray in /tmp/tmp.mbCopmzqsg
15.977339
min:12
med:32
max:56
15.977368
min:11
med:32
max:58
15.977489
min:11
med:32
max:59
15.977077
min:12
med:32
max:60
15.977439
min:8
med:32
max:59
15.977374
min:13
med:32
max:60
15.977312
min:12
med:32
max:67

```

#### 2.6 卸载 entropyarray (可选)

假如你打算不再使用 `entropyarray`，那么你可以按照你自己的需求卸载它：

```
cd entropyarray; make uninstall; cd ..
cd entropy; make uninstall; cd ..
cd rearray; make uninstall; cd ..

```

### 3 使用 debian 的软件仓库来进行安装

假如你想在你基于 debian 的系统中让 pandom 保持更新，则你可以使用 ncomputers.org 的 debian 软件仓库来安装或者重新安装它。

#### 3.1 获取 root 权限

以下的 debian 软件包必须以 root 身份来安装，所以在必要时请运行下面这个命令：

```
su -

```

#### 3.2 安装密钥

下面的 debian 软件包中包含 ncomputers.org debian 软件仓库的公匙密钥：

```
wget http://ncomputers.org/debian/keyring.deb
dpkg -i keyring.deb
rm keyring.deb

```

#### 3.3 安装软件源列表

下面这些 debian 软件包含有 ncomputers.org debian 软件仓库的软件源列表，这些软件源列表对应最新的 debian 发行版本(截至 2017 年)。

**注**：你也可以将下面的以 `#` 注释的行加入 `/etc/apt/sources.list` 文件中，而不是为你的 debian 发行版本安装对应的 debian 软件包。但假如这些源在将来改变了，你就需要手动更新它们。

**Wheezy：**

```
#deb http://ncomputers.org/debian wheezy main
wget http://ncomputers.org/debian/wheezy.deb
dpkg -i wheezy.deb
rm wheezy.deb

```

Jessie：

```
#deb http://ncomputers.org/debian jessie main
wget http://ncomputers.org/debian/jessie.deb
dpkg -i jessie.deb
rm jessie.deb

```

**Stretch：**

```
#deb http://ncomputers.org/debian stretch main
wget http://ncomputers.org/debian/stretch.deb
dpkg -i stretch.deb
rm stretch.deb

```

#### 3.4 升级软件源列表

一旦密钥和软件源列表安装完成，则可以使用下面的命令来更新：

```
apt-get update

```

#### 3.5 测试 pandom

测试完毕后，你可以随意卸载下面的软件包。

**注**：假如你已经在你的 Linux 中测试了 pandom ， 则你可以跳过这一步。

```
apt-get install pandom-test
pandom-test

generating checkme file, please wait around 8 minutes ...
entropyarray in /tmp/tmp.5SkiYsYG3h
15.977366
min:12
med:32
max:57
15.977367
min:13
med:32
max:57
15.977328
min:12
med:32
max:61
15.977431
min:12
med:32
max:59
15.977437
min:11
med:32
max:57
15.977298
min:11
med:32
max:59
15.977196
min:10
med:32
max:57

```

#### 3.6 安装 pandom

```
apt-get install pandom

```

### 4 管理 pandom

在 pandom 安装完成后，你可能想对它进行管理。

#### 4.1 性能测试

pandom 提供大约 8 kB/s 的随机数生成速率，但它的性能可能根据环境而有所差异。

```
dd if=/dev/random of=/dev/null bs=8 count=512

512+0 records in
512+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.451253 s, 9.1 kB/s

```

#### 4.2 熵和序列相关性检验

除了 ncomputers.org/entropyarray，还存在更多的测试，例如 [Ilja Gerhardt 的 NIST 测试套件](https://gerhardt.ch/random.php)。

```
entropyarray /dev/random 1M

```

#### 4.3 系统服务

pandom 还可以以系统服务的形式运行。

**基于 init.d 的初始化系统（如 upstart、sysvinit）：**

```
/etc/init.d/random status
/etc/init.d/random start
/etc/init.d/random stop
/etc/init.d/random restart

```

**以 systemd 作为初始化程序的系统：**

```
systemctl status random
systemctl start random
systemctl stop random
systemctl restart random

```

### 5 增强不可预测性或者性能

假如你想增加你编译的 pandom 程序的不可预测性或者性能，你可以尝试增加或删减 CPU 时间测量选项。

#### 5.1 编辑源文件

请按照自己的意愿，在源文件 `test.s` 和 `tRNG.s` 中增加或者移除 `measurement blocks` 字段。

```
#measurement block
mov $35,%rax
syscall
rdtsc
[...]

#measurement block
mov $35,%rax
syscall
rdtsc
[...]

```

#### 5.2 测试不可预测性

我们总是建议在使用个人定制的 pandom 实现来用于加密目地之前，先进行一些测试。

```
make check

```

#### 5.3 安装定制的 pandom

假如你对测试的结果很满意，你就可以使用下面的命令来安装你的 pandom 实现。

```
make install

```

更多额外信息及更新详见 <http://ncomputers.org/pandom> 。

（题图：Pixabay，CC0）

---

via: <https://www.howtoforge.com/tutorial/how-to-install-pandom-a-true-random-number-generator/>

作者：[Oliver](https://www.howtoforge.com/tutorial/how-to-install-pandom-a-true-random-number-generator/) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

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


LinuxKit：在容器中运行容器

Summary: LinuxKit 是一个灵活的、可扩展的操作系统，而为了可移植性，系统服务也是运行在容器之中。甚至，令人惊讶的是，就连 Docker 运行时环境也是运行在容器内！

![](/data/attachment/album/201705/18/102636wm4d6mwitms3tiss.png)

一些令人振奋的消息引发了我对今年 DockerCon 的兴趣，在这次会议中，无可争议的容器巨头公司 Docker 发布了一个新的操作系统：LinuxKit。

这家容器巨头宣布的是一个灵活的、可扩展的操作系统，而为了可移植性，系统服务也是运行在容器之中。甚至，令人惊讶的是，就连 Docker 运行时环境也是运行在容器内！

在本文中，我们将简要介绍一下 LinuxKit 中所承诺的内容，以及如何自己尝试一下这个不断精简、优化的容器。

### 少即是多

不可否认的是，用户一直在寻找一个可以运行他们的微服务的精简版本的 Linux 。通过容器化，你会尽可能地最小化每个应用程序，使其成为一个适合于运行在其自身容器内的独立进程。但是，由于你需要对那些驻留容器的宿主机出现的问题进行修补，因此你不断地在宿主机间移动容器。实际上，如果没有像 Kubernetes 或 Docker Swarm 这样的编排系统，容器编排几乎总是会导致停机。

不用说，这只是让你保持操作系统尽可能小的原因之一。

我曾多次在不同场合重复过的最喜爱的名言，来自荷兰的天才程序员 Wietse Zweitze，他为我们提供了重要的 Email 软件 Postfix 和 TCP Wrappers 等知名软件。

在 [Postfix 网站](http://www.postfix.org/TLS_README.html) 指出，即使你编码和 Wietse 一样小心，“每 1000 行[你]就会在 Postfix 中引入一个额外的 bug”。从我的专业的 DevSecOps 角度看，这里提到的“bug” 可以将其大致看做安全问题。

从安全的角度来看，正是由于这个原因，代码世界中“少即是多”。简单地说，使用较少的代码行有很多好处，即安全性、管理时间和性能。对于初学者来说，这意味着安全漏洞较少，更新软件包的时间更短，启动时间更快。

### 深入观察

考虑下在容器内部运行你的程序。

一个好的起点是 [Alpine Linux](https://alpinelinux.org/downloads/)，它是一个苗条、精简的操作系统，通常比那些笨重的系统更受喜欢，如 Ubuntu 或 CentOS 等。Alpine 还提供了一个 miniroot 文件系统（用于容器内），最近我看到的大小是惊人的 1.8M。事实上，这个完整的 Linux 操作系统下载后有 80M。

如果你决定使用 Alpine Linux 作为 Docker 基础镜像，那么你可以在 Docker Hub 上[找到](https://hub.docker.com/_/alpine)一个， 它将其描述为：“一个基于 Alpine Linux 的最小 Docker 镜像，具有完整的包索引，大小只有5 MB！”

据说无处不在的 “Window 开始菜单” 文件也是大致相同的大小！我没有验证过，也不会进一步评论。

讲真，希望你去了解一下这个创新的类 Unix 操作系统（如 Alpine Linux）的强大功能。

### 锁定一切

再说一点，Alpine Linux 是（并不惊人）基于 [BusyBox](https://busybox.net/)，这是一套著名的打包了 Linux 命令的集合，许多人不会意识到他们的宽带路由器、智能电视，当然还有他们家庭中的物联网设备就有它。

Alpine Linux 站点的“[关于](https://www.alpinelinux.org/about/)”页面的评论中指出：

>
> “Alpine Linux 的设计考虑到安全性。内核使用 grsecurity/PaX 的非官方移植进行了修补，所有用户态二进制文件都编译为具有堆栈保护的地址无关可执行文件（PIE）。 这些主动安全特性可以防止所有类别的零日漏洞和其它漏洞利用。”
>
>
>

换句话说，这些捆绑在 Alpine Linux 中的精简二进制文件提供的功能通过了那些行业级安全工具筛选，以缓解缓冲区溢出攻击所带来的危害。

### 多只袜子

你可能会问，为什么当我们谈及 Docker 的新操作系统时，容器的内部结构很重要？

那么，你可能已经猜到，当涉及容器时，他们的目标是精简。除非绝对必要，否则不包括任何东西。所以你可以放心地清理橱柜、花园棚子、车库和袜子抽屉了。

Docker 的确因为它们的先见而获得声望。据报道，2 月初，Docker 聘请了 Alpine Linux 的主要推动者 Nathaniel Copa，他帮助将默认的官方镜像库从 Ubuntu 切换到 Alpine。Docker Hub 从新近精简镜像节省的带宽受到了赞誉。

并且最新的情况是，这项工作将与最新的基于容器的操作系统相结合：Docker 的 LinuxKit。

要说清楚的是 LinuxKit 注定不会代替 Alpine，而是位于容器下层，并作为一个完整的操作系统出现，你可以高兴地启动你的运行时守护程序（在这种情况下，是生成你的容器的Docker 守护程序 ）。

### 原子计划

经过精心调试的宿主机绝对不是一件新事物（以前提到过嵌入式 Linux 的家用设备）。在过去几十年中一直在优化 Linux 的天才在某个时候意识到底层的操作系统才是快速生产含有大量容器主机的关键。

例如，强大的红帽长期以来一直在出售已经贡献给 [Project Atomic](http://www.projectatomic.io/) 的 [红帽 Atomic](https://www.redhat.com/en/resources/red-hat-enterprise-linux-atomic-host) 。后者继续解释：

>
> “基于 Red Hat Enterprise Linux 或 CentOS 和 Fedora 项目的成熟技术，Atomic Host 是一个轻量级的、不可变的平台，其设计目的仅在于运行容器化应用程序。”
>
>
>

将底层的、不可变的 Atomic OS 作为红帽的 OpenShift PaaS（平台即服务）产品推荐有一个很好理由：它最小化、高性能、尖端。

### 特性强大

在 Docker 关于 LinuxKit 的公告中，“少即是多”的口号是显而易见的。实现 LinuxKit 愿景的项目显然是不小的事业，它由 Docker 老将和 [Unikernel](https://en.wikipedia.org/wiki/Unikernel) 的主管 Justin Cormack 指导，并与 HPE、Intel、ARM、IBM 和 Microsoft LinuxKit 合作，可以运行在从大型机到基于物联网的冰柜之中。

LinuxKit 的可配置性、可插拔性和可扩展性将吸引许多寻求建立其服务基准的项目。通过开源项目，Docker 明智地邀请每个人全身心地投入其功能开发，随着时间的推移，它会像好的奶酪那样成熟。

### 布丁作证

按照该发布消息中所承诺的，那些急于使用新系统的人不用再等待了。如果你准备着手 LinuxKit，你可以从 GitHub 中开始：[LinuxKit](https://github.com/linuxkit/linuxkit)。

在 GitHub 页面上有关于如何启动和运行一些功能的指导。

时间允许的话我准备更加深入研究 LinuxKit。对有争议的 Kubernetes 与 Docker Swarm 编排功能对比会是有趣的尝试。此外，我还想看到内存占用、启动时间和磁盘空间使用率的基准测试。

如果该承诺可靠，则作为容器运行的可插拔系统服务是构建操作系统的迷人方式。Docker 在[博客](https://blog.docker.com/2017/04/introducing-linuxkit-container-os-toolkit)）中提到：“因为 LinuxKit 是原生容器，它有一个非常小的尺寸 - 35MB，引导时间非常小。所有系统服务都是容器，这意味着可以删除或替换所有的内容。”

我不知道你觉得怎么样，但这非常符合我的胃口。

### 呼叫警察

除了我站在 DevSecOps 角度看到的功能，我会看看其对安全的承诺。

Docker 在他们的博客上引用来自 NIST（[国家标准与技术研究所](https://www.nist.gov/)）的话：

>
> “安全性是最高目标，这与 NIST 在其《应用程序容器安全指南》草案中说明的保持一致：‘使用容器专用操作系统而不是通用操作系统来减少攻击面。当使用专用容器操作系统时，攻击面通常比通用操作系统小得多，因此攻击和危及专用容器操作系统的机会较少。’”
>
>
>

可能最重要的容器到主机和主机到容器的安全创新是将系统容器（系统服务）完全地沙箱化到自己的非特权空间中，而只给它们需要的外部访问。

通过<ruby> 内核自我保护项目 <rt>  Kernel Self Protection Project </rt></ruby>（[KSPP](https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project)）的协作来实现这一功能，我很满意 Docker 开始专注于一些非常值得的东西上。对于那些不熟悉的 KSPP 的人而言，它存在理由如下：

>
> “启动这个项目的的假设是内核 bug 的存在时间很长，内核必须设计成可以防止这些缺陷的危害。”
>
>
>

KSPP 网站进一步表态：

>
> “这些努力非常重要并还在进行，但如果我们要保护我们的十亿 Android 手机、我们的汽车、国际空间站，还有其他运行 Linux 的产品，我们必须在上游的 Linux 内核中建立积极的防御性技术。我们需要内核安全地出错，而不只是安全地运行。”
>
>
>

而且，如果 Docker 最初只是在 LinuxKit 前进了一小步，那么随着时间的推移，成熟度带来的好处可能会在容器领域中取得长足的进步。

### 终点还远

像 Docker 这样不断发展壮大的巨头无论在哪个方向上取得巨大的飞跃都将会用户和其他软件带来益处。

我鼓励所有对 Linux 感兴趣的人密切关注这个领域。

---

via: <http://www.devsecops.cc/devsecops/containers.html>

作者：[Chris Binnie](http://www.devsecops.cc/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 中使用 Asciinema 进行录制和回放终端会话

Summary: Asciinema 是一个轻量并且非常高效的终端会话录制器。使用它可以录制、回放和分享 JSON 格式的终端会话记录。最主要的优点是，它能够以通过 ASCII 文本以及 ANSI 转义码编码来录制所有的标准终端输入、输出和错误信息。

也可以用 script 记录。

生成 gif 图片不就行了．这么麻烦．

太大

![](/data/attachment/album/201705/18/115905cc2jzzn9a09ep2f9.jpg)

### 简介

Asciinema 是一个轻量并且非常高效的终端会话录制器。使用它可以录制、回放和分享 JSON 格式的终端会话记录。与一些桌面录制器，比如 Recordmydesktop、Simplescreenrecorder、Vokoscreen 或 Kazam 相比，Asciinema 最主要的优点是，它能够以通过 ASCII 文本以及 ANSI 转义码编码来录制所有的标准终端输入、输出和错误信息。

事实上，即使是很长的终端会话，录制出的 JSON 格式文件也非常小。另外，JSON 格式使得用户可以利用简单的文件转化器，将输出的 JSON 格式文件嵌入到 HTML 代码中，然后分享到公共网站或者使用 asciinema 账户分享到 Asciinema.org 。最后，如果你的终端会话中有一些错误，并且你还懂一些 ASCI 转义码语法，那么你可以使用任何编辑器来修改你的已录制终端会话。

**难易程度：**

很简单！

**标准终端：**

* **#** - 给定命令需要以 root 用户权限运行或者使用 `sudo` 命令
* **$** - 给定命令以常规权限用户运行

### 从软件库安装

通常， asciinema 可以使用你的发行版的软件库进行安装。但是，如果不可以使用系统的软件库进行安装或者你想安装最新的版本，那么，你可以像下面的“从源代码安装”部分所描述的那样，使用 Linuxbrew 包管理器来执行 Asciinema 安装。

**在 Arch Linux 上安装：**

```
# pacman -S asciinema

```

**在 Debian 上安装：**

```
# apt install asciinema

```

**在 Ubuntu 上安装：**

```
$ sudo apt install asciinema

```

**在 Fedora 上安装：**

```
$ sudo dnf install asciinema

```

### 从源代码安装

最简单并且值得推荐的方式是使用 Linuxbrew 包管理器，从源代码安装最新版本的 Asciinema 。

#### 前提条件

下面列出的前提条件是安装 Linuxbrew 和 Asciinema 需要满足的依赖关系：

* git
* gcc
* make
* ruby

在安装 Linuxbrew 之前，请确保上面的这些包都已经安装在了你的 Linux 系统中。

**在 Arch Linux 上安装 ruby：**

```
# pacman -S git gcc make ruby

```

**在 Debian 上安装 ruby：**

```
# apt install git gcc make ruby

```

**在 Ubuntu 上安装 ruby：**

```
$ sudo apt install git gcc make ruby

```

**在 Fedora 上安装 ruby：**

```
$ sudo dnf install git gcc make ruby

```

**在 CentOS 上安装 ruby：**

```
# yum install git gcc make ruby

```

#### 安装 Linuxbrew

Linuxbrew 包管理器是苹果的 MacOS 操作系统很受欢迎的 Homebrew 包管理器的一个复刻版本。还没发布多久，Homebrew 就以容易使用而著称。如果你想使用 Linuxbrew 来安装 Asciinema，那么，请运行下面命令在你的 Linux 版本上安装 Linuxbrew：

```
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install)"

```

现在，Linuxbrew 已经安装到了目录 `$HOME/.linuxbrew/` 下。剩下需要做的就是使它成为可执行 `PATH` 环境变量的一部分。

```
$ echo 'export PATH="$HOME/.linuxbrew/bin:$PATH"' >>~/.bash_profile
$ . ~/.bash_profile

```

为了确认 Linuxbrew 是否已经安装好，你可以使用 `brew` 命令来查看它的版本：

```
$ brew --version
Homebrew 1.1.7
Homebrew/homebrew-core (git revision 5229; last commit 2017-02-02)

```

#### 安装 Asciinema

安装好 Linuxbrew 以后，安装 Asciinema 就变得无比容易了：

```
$ brew install asciinema

```

检查 Asciinema 是否安装正确：

```
$ asciinema --version
asciinema 1.3.0

```

### 录制终端会话

经过一番辛苦的安装工作以后，是时候来干一些有趣的事情了。Asciinema 是一个非常容易使用的软件。事实上，目前的 1.3 版本只有很少的几个可用命令行选项，其中一个是 `--help` 。

我们首先使用 `rec` 选项来录制终端会话。下面的命令将会开始录制终端会话，之后，你将会有一个选项来丢弃已录制记录或者把它上传到 asciinema.org 网站以便将来参考。

```
$ asciinema rec

```

运行上面的命令以后，你会注意到， Asciinema 已经开始录制终端会话了，你可以按下 `CTRL+D` 快捷键或执行 `exit` 命令来停止录制。如果你使用的是 Debian/Ubuntu/Mint Linux 系统，你可以像下面这样尝试进行第一次 asciinema 录制：

```
$ su
Password:
# apt install sl
# exit
$ sl

```

一旦输入最后一个 `exit` 命令以后，将会询问你：

```
$ exit
~ Asciicast recording finished.
~ Press <Enter> to upload, <Ctrl-C> to cancel.

https://asciinema.org/a/7lw94ys68gsgr1yzdtzwijxm4

```

如果你不想上传你的私密命令行技巧到 asciinema.org 网站，那么有一个选项可以把 Asciinema 记录以 JSON 格式保存为本地文件。比如，下面的 asciinema 记录将被存为 `/tmp/my_rec.json`：

```
$ asciinema rec /tmp/my_rec.json

```

另一个非常有用的 asciinema 特性是时间微调。如果你的键盘输入速度很慢，或者你在进行多任务，输入命令和执行命令之间的时间会比较长。Asciinema 会记录你的实时按键时间，这意味着每一个停顿都将反映在最终视频的长度上。可以使用 `-w` 选项来缩短按键的时间间隔。比如，下面的命令将按键的时间间隔缩短为 0.2 秒：

```
$ asciinema rec -w 0.2

```

### 回放已录制终端会话

有两种方式可以来回放已录制会话。第一种方式是直接从 asciinema.org 网站上播放终端会话。这意味着，你之前已经把录制会话上传到了 asciinema.org 网站，并且需要提供有效链接：

```
$ asciinema play https://asciinema.org/a/7lw94ys68gsgr1yzdtzwijxm4

```

另外，你也可以使用本地存储的 JSON 文件：

```
$ asciinema play /tmp/my_rec.json

```

如果要使用 `wget` 命令来下载之前的上传记录，只需在链接的后面加上 `.json`：

```
$ wget -q -O steam_locomotive.json https://asciinema.org/a/7lw94ys68gsgr1yzdtzwijxm4.json
$ asciinema play steam_locomotive.json

```

### 将视频嵌入 HTML

最后，asciinema 还带有一个独立的 JavaScript 播放器。这意味者你可以很容易的在你的网站上分享终端会话记录。下面，使用一段简单的 `index.html` 代码来说明这个方法。首先，下载所有必要的东西：

```
$ cd /tmp/
$ mkdir steam_locomotive
$ cd steam_locomotive/
$ wget -q -O steam_locomotive.json https://asciinema.org/a/7lw94ys68gsgr1yzdtzwijxm4.json
$ wget -q https://github.com/asciinema/asciinema-player/releases/download/v2.4.0/asciinema-player.css
$ wget -q https://github.com/asciinema/asciinema-player/releases/download/v2.4.0/asciinema-player.js

```

之后，创建一个新的包含下面这些内容的 `/tmp/steam_locomotive/index.html` 文件：

```
<html>
<head>
  <link rel="stylesheet" type="text/css" href="./asciinema-player.css" />
</head>
<body>
  <asciinema-player src="./steam_locomotive.json" cols="80" rows="24"></asciinema-player>
  <script src="./asciinema-player.js"></script>
</body>
</html>

```

完成以后，打开你的网页浏览器，按下 `CTRL+O` 来打开新创建的 `/tmp/steam_locomotive/index.html` 文件。

### 结论

正如前面所说的，使用 asciinema 录制器来录制终端会话最主要的优点是它的输出文件非常小，这使得你的视频很容易分享出去。上面的例子产生了一个包含 58472 个字符的文件，它是一个只有 58 KB 大 小的 22 秒终端会话视频。如果我们查看输出的 JSON 文件，会发现甚至这个数字已经非常大了，这主要是因为一个 “蒸汽机车” 已经跑过了终端。这个长度的正常终端会话一般会产生一个更小的输出文件。

下次，当你想要在一个论坛上询问关于 Linux 配置的问题，并且很难描述你的问题的时候，只需运行下面的命令：

```
$ asciinema rec

```

然后把最后的链接贴到论坛的帖子里。

### 故障排除

#### 在 UTF-8 环境下运行 asciinema

错误信息：

```
asciinema needs a UTF-8 native locale to run. Check the output of `locale` command.

```

解决方法： 生成并导出 UTF-8 语言环境。例如：

```
$ localedef -c -f UTF-8 -i en_US en_US.UTF-8
$ export LC_ALL=en_US.UTF-8

```

---

via: <https://linuxconfig.org/record-and-replay-terminal-session-with-asciinema-on-linux>

作者：[Lubos Rendek](https://linuxconfig.org/record-and-replay-terminal-session-with-asciinema-on-linux) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


甲骨文的政策更改提高了其在 AWS 上的价格

>
> 这种改变使得在 AWS 上实施甲骨文的软件的价格翻了一番，它已经安静地生效了，而几乎没有通知用户。
>
>
>

![](/data/attachment/album/201705/18/150111lud3xvd3vuvkkwns.jpg)

之前有消息传出，甲骨文使亚马逊云上的产品价格翻了一倍。它在[如何计算 AWS 的虚拟 CPU](https://oracle-base.com/blog/2017/01/28/oracles-cloud-licensing-change-be-warned/) 上耍了一些花招。它这么做也没有任何宣扬。该公司的新定价政策于 1 月 23 日生效，直到 1 月 28 日都几乎没有被人注意到， 甲骨文的关注者 Tim Hall 偶然发现 Big Red 公司的 [甲骨文软件云计算环境许可](http://www.oracle.com/us/corporate/pricing/cloud-licensing-070579.pdf)文件并披露了出来。

乍一看，这一举动似乎并不太大，因为它仅将甲骨文的 AWS 定价与 Microsoft Azure 的价格相提并论。但是 Azure 只有市场领先的 AWS 体量的三分之一，所以如果你想在云中销售许可证，AWS 是合适的地方。虽然此举可能或可能不会影响已经在 AWS 上使用甲骨文产品的用户，但是尚不清楚新规则是否适用于已在使用产品的用户 - 它肯定会让一些考虑可能使用甲骨文的用户另寻它处。

这个举动的主要原因是显而易见的。甲骨文希望使自己的云更具吸引力 - 这让 [The Register 观察](https://www.theregister.co.uk/2017/01/30/oracle_effectively_doubles_licence_fees_to_run_in_aws/)到一点：“拉里·埃里森确实承诺过甲骨文的云将会更快更便宜”。更快和更便宜仍然有待看到。如果甲骨文的 SPARC 云计划启动，并且按照广告的形式执行，那么可能会更快，但是更便宜的可能性较小。甲骨文以对其价格的强硬态度而著称。

随着其招牌数据库和业务栈销售的下滑，并且对 Sun 公司的 74 亿美元的投资并未能按照如期那样，甲骨文将其未来赌在云计算上。但是甲骨文来晚了，迄今为止，它的努力似乎还没有结果, 一些金融预测者并没有看到甲骨文云的光明前景。他们说，云是一个拥挤的市场，而四大公司 - 亚马逊、微软、IBM 和谷歌 - 已经有了领先优势。

确实如此。但是甲骨文面临的最大的障碍是，好吧，就是甲骨文。它的声誉在它之前。

保守地说这个公司并不是因为明星客户服务而闻名。事实上，各种新闻报道将甲骨文描绘成一个恶霸和操纵者。

例如，早在 2015 年，甲骨文就因为它的云并不像预期那样快速增长而越来越沮丧，开始[激活业内人士称之为的“核特权”](http://www.businessinsider.com/oracle-is-using-the-nuclear-option-to-sell-its-cloud-software-2015-7)。它会审核客户的数据中心，如果客户不符合规定，将发出“违规通知” - 它通常只适用于大规模滥用情况，并命令客户在 30 天内退出使用其软件。

或许你能想到，大量投入在甲骨文软件平台上的大公司们绝对不能在短时间内迁移到另一个解决方案。甲骨文的违规通知将会引发灾难。

商业内幕人士 Julie Bort 解释到：“为了使违规通知消失 - 或者减少高额的违规罚款 - 甲骨文销售代表通常希望客户向合同中添加云额度”。

换句话说，甲骨文正在使用审计来扭转客户去购买它的云，而无论他们是否有需要。这种策略与最近 AWS 价格翻倍之间也可能存在联系。Hall 的文章的评论者指出，围绕价格提升的秘密背后的目的可能是触发软件审计。

使用这些策略的麻烦迟早会出来。消息一旦传播开来，你的客户就开始寻找其他选项。对 Big Red 而言或许是时候参考微软的做法，开始建立一个更好和更温和的甲骨文，将客户的需求放在第一位。

（题图：[windowsitpro](http://windowsitpro.com/)）

---

via: <http://windowsitpro.com/cloud/oracle-policy-change-raises-prices-aws>

作者：[Christine Hall](http://windowsitpro.com/author/christine-hall) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


该死，原生移动应用的开发成本太高了！

![](/data/attachment/album/201705/18/153154kw44b4yuu4wjzsco.jpg)

>
> 一个有价值的命题
>
>
>

我们遇到了一个临界点。除去少数几个特别的的用例之外，使用原生框架和原生应用开发团队构建、维护移动应用再也没有意义了。

![](/data/attachment/album/201705/19/112427dv88de7dmmvvijme.jpg)

*在美国，雇佣 [iOS，Android](http://www.indeed.com/salary)，[JavaScript](http://www.payscale.com/research/US/Skill=JavaScript/Salary) 开发人员的平均花费*

在过去的几年，原生移动应用开发的费用螺旋式上升，无法控制。对没有大量资金的新创业者来说，创建原生应用、MVP 设计架构和原型的难度大大增加。现有的公司需要抓住人才，以便在现有应用上进行迭代开发或者构建一个新的应用。要尽一切努力才能留住最好的人才，与 [世界各地的公司](http://blogs.wsj.com/cio/2016/09/30/tech-talent-war-moves-to-africa/) 拼尽全力[争个](http://www.bizjournals.com/charlotte/how-to/human-resources/2016/12/employers-offer-premium-wages-skilled-workers.html)[高](https://www.cnet.com/news/silicon-valley-talent-wars-engineers-come-get-your-250k-salary/)[下](http://www.nytimes.com/2015/08/19/technology/unicorns-hunt-for-talent-among-silicon-valleys-giants.html)。

![](/data/attachment/album/201705/19/112428c22s24203yc0szmk.png)

*2015 年初，原生方式和混合方式开发 MVP 设计架构的费用[对比](http://www.comentum.com/mobile-app-development-cost.html)*

### 这一切对于我们意味着什么？

如果你的公司很大或者有足够多的现金，旧思维是只要你在原生应用开发方面投入足够多的资金，就高枕无忧。但事实不再如此。

Facebook 是你最不会想到的在人才战中失败的公司（因为他们没有失败），它也遇到了原生应用方面金钱无法解决的问题。他们的移动应用庞大而又复杂，[他们发现编译它竟然需要 15 分钟](https://devchat.tv/react-native-radio/08-bridging-react-native-components-with-tadeu-zagallo)。这意味着哪怕是极小的用户界面改动，比如移动几个点，测试起来都要花费几个小时（甚至几天）。

除了冗长的编译时间，应用的每一个小改动在测试时都需要在两个完全不同的环境（IOS 和 Android）实施，开发团队需要使用两种语言和框架工作，这趟水更浑了。

Facebook 对这个问题的解决方案是 [React Native](https://facebook.github.io/react-native/)。

### 能不能抛弃移动应用，仅面向 Web 呢？

[一些人认为移动应用的末日已到](https://medium.com/javascript-scene/native-apps-are-doomed-ac397148a2c0#.w06yd23ej)。尽管我很欣赏、尊重 [Eric Elliott](https://medium.com/u/c359511de780) 和他的工作，但我们还是通过考察一些近期的数据，进而讨论一下某些相反的观点：

![](/data/attachment/album/201705/19/112429lin9q7dmnd029z1g.png)

*人们在移动应用上花费的[时间](http://www.smartinsights.com/mobile-marketing/mobile-marketing-analytics/mobile-marketing-statistics/attachment/percent-time-spent-on-mobile-apps-2016/)（2016年4月）*

>
> 人们使用 APP 的时间占使用手机总时长的 90%
>
>
>

目前世界上有 25 亿人在使用移动手机。[这个数字增长到 50 亿的速度会比我们想象的还要快。](http://ben-evans.com/benedictevans/2016/12/8/mobile-is-eating-the-world) 在正常情况下，丢掉 45 亿人的生意，或者抛弃有 45 亿人使用的应用程序是绝对荒唐且行不通的。

老问题是原生移动应用的开发成本对大多数公司来说太高了。然而，面向 web 的开发成本也在增加。[在美国，JavaScript 开发者的平均工资已达到 $97,000.00](http://www.indeed.com/salary?q1=javascript+developer&l1=united+states&tm=1)。

伴随着复杂性的增加以及对高质量 web 开发的需求暴涨，雇佣一个 JavaScript 开发者的平均价格直逼原生应用开发者。论证 web 开发更便宜已经没用了。

### 那混合开发呢？

混合应用是将 HTML5 应用内嵌在原生应用的容器里，并且提供实现原生平台特性所需的权限。Cordova 和 PhoneGap 就是典型的例子。

如果你想构建一个 MVP 设计架构、一个产品原型，或者不担心对原生应用的模仿的用户体验，那么混合应用会很适合你。但谨记如果你最后想把它转为原生应用，整个项目都得重写。

此领域有很多创新的东西，我最喜欢的当属 [Ionic Framework](https://ionicframework.com/)。混合开发正变得越来越好，但还不如原生开发那么流畅自然。

有很多公司，包括最严峻的初创公司，也包括大中规模的公司，混合应用在质量上的表现似乎没有满足客户的要求，给人的感觉是活糙、不够专业。

[听说应用商店里的前 100 名都不是混合应用](https://medium.com/lunabee-studio/why-hybrid-apps-are-crap-6f827a42f549#.lakqptjw6)，我没有证据支持这一观点。如果说有百分之零到百分之五是混合应用，我就不怀疑了。

>
> [我们最大的错误是在 HTML5 身上下了太多的赌注](https://techcrunch.com/2012/09/11/mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/) — 马克·扎克伯格
>
>
>

### 解决方案

如果你紧跟移动开发动向，那么你绝对听说过像 [NativeScript](https://www.nativescript.org/) 和 [React Native](https://facebook.github.io/react-native/) 这样的项目。

通过这些项目，使用由 JavaScript 写成的基本 UI 组成块，像常规 iOS 和 Android 应用那样，就可以构建出高质量的原生移动应用。

你可以仅用一位工程师，也可以用一个专业的工程师团队，通过 React Native 使用 [现有代码库](https://github.com/necolas/react-native-web) 或者 [底层技术](https://facebook.github.io/react/) 进行跨平台移动应用开发、[原生桌面开发](https://github.com/ptmt/react-native-macos)，甚至还有 web 开发。把你的应用发布到 APP Store 上、 Play Store 上，还有 Web 上。如此可以在保证不丧失原生应用性能和质量的同时，使成本仅占传统开发的一小部分。

通过 React Native 进行跨平台开发时重复使用其中 90% 的代码也不是没有的事，这个范围通常是 80% 到 90%。

如果你的团队使用 React Native, 既可以消除团队之间的分歧，也可以让 UI 和 API 的设计更一致，还可以加快开发速度。

在编译时不需要使用 React Native，在保存时应用可以实时更新，也加快了开发速度。

React Native 还可以使用 [Code Push](http://microsoft.github.io/code-push/) 和 [AppHub](https://apphub.io/) 这样的工具来远程更新你的 JavaScript 代码。这意味着你可以向用户实时推送更新、新特性，快速修复 bug，绕过打包、发布这些工作，绕过 App Store、Google Play Store 的审核，省去了耗时 2 到 7 天的过程（App Store 一直是整个过程的痛点）。混合应用的这些优势原生应用不可能比得上。

如果这个领域的创新力能像刚发行时那样保持，将来你甚至可以为 [Apple Watch](https://github.com/elliottsj/apple-watch-uikit)、[Apple TV](https://github.com/douglowder/react-native-appletv)，和 [Tizen](https://www.tizen.org/blogs/srsaul/2016/samsung-committed-bringing-react-native-tizen) 这样的平台开发应用。

>
> NativeScript 依然是个相当年轻的框架驱动，Angular 版本 2，[上个月刚刚发布测试版](http://angularjs.blogspot.com/2016/09/angular2-final.html)。但只要它保持良好的市场份额，未来就很有前途。
>
>
>

你可能还不知道世界上一些最能创新、最大的科技公司在这类技术上下了很大的赌注，特别是 [React Native](https://facebook.github.io/react-native/)。

我供职过的多家企业以及世界 500 强公司目前都在转移至 React Native。

### 在产品中特别注意使用 React Native

看下面的例子，[这是一个使用 React Native 技术的著名应用列表](https://facebook.github.io/react-native/showcase.html)。

#### Facebook

![](/data/attachment/album/201705/19/112429h8mjv93b77jhli7k.jpg)

*Facebook 公司的 React Native 应用*

Facebook 的两款应用 [Ads Manager](https://play.google.com/store/apps/details?id=com.facebook.adsmanager) 和 [Facebook Groups](https://itunes.apple.com/us/app/facebook-groups/id931735837?mt=8) 都在使用 React Native 技术，并且[将会应用到实现动态消息的框架上](https://devchat.tv/react-native-radio/40-navigation-in-react-native-with-eric-vicenti)。

Facebook 也会投入大量的资金创立和维护像 React Native 这样的开源项目，而且开源项目的开发者最近已经创建很多了不起的项目，这是很了不起的工作，像我以及全世界的业务每天都从中享受诸多好处。

#### Instagram

![](/data/attachment/album/201705/19/112429wiwamowwkn4ao49d.jpg)

*Instagram*

Instagram 应用的一部分已经使用了 React Native 技术。

#### Airbnb

![](/data/attachment/album/201705/19/112430d4ik8928t4428zjv.jpg)

*Airbnb*

Airbnb 的很多东西正用 React Native 重写。（来自 [Leland Richardson](https://medium.com/u/41a8b1601c59)）

超过 90% 的 Airbnb 旅行平台都是用 React Native 写的。（来自 [spikebrehm](https://medium.com/u/71a78c1b069b)）

#### Vogue

![](/data/attachment/album/201705/19/112430x5rwddlzxhr2zpsb.jpg)

*Vogue 是 2016 年度十佳应用之一*

Vogue 这么突出不仅仅因为它也用 React Native 写成，而是[因为它被苹果公司评为年度十佳应用之一](http://www.highsnobiety.com/2016/12/08/iphone-apps-best-of-the-year-2016/)。

![](/data/attachment/album/201705/19/112431fljrhudjigp7d9li.jpg)

#### 沃尔玛

![](/data/attachment/album/201705/19/112431fvs4euts00a44ego.jpg)

*Walmart Labs*

查看这篇 [Keerti](https://medium.com/@Keerti) 的[文章](https://medium.com/walmartlabs/react-native-at-walmartlabs-cdd140589560#.azpn97g8t)来了解沃尔玛是怎样看待 React Native 的优势的。

#### 微软

微软在 React Native 身上下的赌注很大。

它早已发布多个开源工具，包括 [Code Push](http://microsoft.github.io/code-push/)、[React Native VS Code](https://github.com/Microsoft/vscode-react-native)，以及 [React Native Windows](https://github.com/ReactWindows/react-native-windows)，旨在帮助开发者向 React Native 领域转移。

微软考虑的是那些已经使用 React Native 为 iOS 和 Android 开发应用的开发者，他们可以重用高达 90% 的代码，不用花费太多额外的时间和成本就可将应用发布到 Windows 上。

微软对 React Native 生态的贡献十分广泛，过去几年在开源界的表现很抢眼。

### 结论

移动应用界面设计和移动应用开发要进行范式转变，下一步就是 React Native 以及与其相似的技术。

#### 公司

如果你的公司正想着削减成本、加快开发速度，而又不想在应用质量和性能上妥协，这是最适合使用 React Native 的时候，它能提高你的净利润。

#### 开发者

如果你是一个开发者，想进入一个将来会快速发展的领域，我强烈推荐你把 React Native 列入你的学习清单。

如果了解 JavaScript，你会入门很快，工具我首推 [Exponent](https://medium.com/u/df61a4267d7a)，其他的就看你怎么想了。使用 Exponent 开发者可以轻松的编译、测试和发布跨 Windows 和 MacOS 两个平台的 React Native 应用。

如果已经是一位原生应用开发者，你更会受益匪浅。因为在需要时你能够胜任深入研究原生应用边缘的工作。虽然不会经常用到，但在团队需要时这可是十分宝贵的能力。

我花了很多时间来学习、指导别人 React Native。因为它让我十分激动，而且使用这个框架创作应用也是我一个平淡的小乐趣。

感谢阅读。

---

作者简介：

教授和构建 React Native 应用的软件开发专家

---

via: <https://hackernoon.com/the-cost-of-native-mobile-app-development-is-too-damn-high-4d258025033a>

作者：[Nader Dabit](https://hackernoon.com/@dabit3) 译者：[fuowang](https://github.com/fuowang) 校对：[wxy](https://github.com/wxy)

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


美联邦法院裁定：GPL 是可执行的合约

Summary: 韩国一家开发了 Hancom Office 办公软件的公司在其字处理软件中集成了开源软件 Ghostscript，但是没有遵守 Ghostscript 的 GPL 许可证而开源，也没有为该软件付费。近日，该韩国公司被美国联邦法院裁定其违约。

GPL本身也是契约精神的一部分。这样的判决确实更体现了美国法律对契约精神的尊重！！！

这种事，国内管不了

淦！早知道就把端午节给GPL了！

你如果使用了GPL的有关协议的软件，你就默认遵守其规定，不然你就是盗用别人的软件。

Hancom真是恶心！剽窃还有理。

韩国一家开发了 Hancom Office 办公软件的公司在其字处理软件中集成了开源软件 Ghostscript，但是没有遵守 Ghostscript 的 GNU GPL 许可证而开源，也没有为该软件付费。近日，该韩国公司被美国联邦法院裁定其违约。

![](/data/attachment/album/201705/19/001121wunv51nt0bou0ono.jpg)

Ghostscript 是一个开源软件，由 Artifex 公司开发，其采用了两种许可证：

* GNU GPL 许可证
* 商业付费许可证

如果要免费使用 Ghostscript，Hancom 就需要遵循该软件的开源许可证，即 GNU GPL。该许可证要求，如果你的软件中使用了采用该许可协议的软件，并公开发布的话，就需要也采用同样的 GNU GPL 许可证开源。也就是说， Hancom 需要开源其整个办公软件套件。

否则，Hancom 就需要向 Ghostscript 的开发商 Artifex 公司支付商业许可证费用。Artifex 允许商业或其它闭源软件开发商绕开严格的开源许可证 GNU GPL，只要付费就行。

但是 Hancom 从 2013 年在其软件中使用了 Ghostscript 之后，却什么都没做：既没有开源其软件，也没有向 Artifex 公司付商业许可证的费用。

在 2016 年底，交涉无果的 Artifex 公司向美国加利福尼亚北部地区法院发起了诉讼。

“在发现 Hancom 违反了 GNU GPL 许可证，侵犯了 Artifex 的 Ghostscript 的宝贵版权之后，Artifex 要求 Hancom 停止其侵权行为，并为其多年无版权使用 Ghostscript 支付合理的版权费用，”该公司陈述到，“Hancom 拒绝了该要求，Artifex 转而寻求本法院责令 Hancom 停止进一步侵权并支付其滥用 Artifex 的开源许可证的费用。”

Artifex 还提到 Hancom 在 2015 年收入了 8630 万美元。

像 GUN GPL 这样的开源许可证的可执行性长期以来一直是一个悬而未决的法律问题。美国联邦巡回法庭在 2006 年的一个判例，雅各布森诉卡泽尔案中，对开源许可证的侵犯裁定可视作对版权申明的处理。但是在本案之前，这种侵犯开源许可证是否可以依法视作侵犯合约并未裁定。

Hancom 尝试发起动议以驳回该诉讼，其认为该公司并未签署任何东西，所以该许可证并不是真正的合约。

“并不是这样”，杰奎琳·斯科特·科里法官在 4 月 25 日的议案中说。她说 GNU GPL “规定了如果用户没有获取商业许可证，即表示同意其条款。原告称被告没有获取商业许可证，并公开表明其在 GNU GPL 下使用 Ghostscript。这些指控足以为合约的存在而辩护。”

科里法官驳回了 Hancom 的动议。按照这样的做法，就树立了像 GNU GPL 这样的开源许可证可以被视作法律合约的先例，在开发商违反了开源许可证时会被起诉。这对于开源社区来说是一个重大胜利。

当然，Artifex 是否可以最终赢得这一诉讼，还要看后继的上诉和裁定。


Rowhammer：针对物理内存的攻击可以取得 Android 设备的 root 权限

Summary: 这种称之为“Rowhammer”的攻击起源于过去十多年中将更多的 DRAM（动态随机存取存储器）容量封装进越来越小的芯片中，这将导致在特定情况下存储单元电子可以从相邻两行row的一边泄漏到另一边。

“VUSec 的研究者认为，谷歌的缓解方案将会使得攻击过程更为复杂，但是它不能修复潜在的问题。” 我以为虽然这是一个利用硬件设计缺陷的漏洞，但是需要软件去触发，所以用另一种软件提供一种缓解措施，不失为一种办法。只是现在人类设计的计算机硬件还有软件如此的千疮百孔，不堪一击，还不说来自宇宙的高能射线的威胁，凭这些就像傲游星辰大海实在是有些痴心妄想。

>
> 攻击者确实可以在物理存储单元中实现位翻转来达到侵入移动设备与计算机的目的
>
>
>

![](/data/attachment/album/201705/19/083412z8b77tcuwebuthhz.jpg)

研究者们发现了一种新的在不利用任何软件漏洞情况下，利用内存芯片物理设计上的弱点来侵入 Android 设备的方式。这种攻击技术同样可以影响到其它如 ARM 和 X86 架构的设备与计算机。

这种称之为“Rowhammer”的攻击起源于过去十多年中将更多的 DRAM（动态随机存取存储器）容量封装进越来越小的芯片中，这将导致在特定情况下存储单元电子可以从相邻两<ruby> 行 <rt>  row </rt></ruby>的一边泄漏到另一边。（LCTT 译注：参见 [https://en.wikipedia.org/wiki/Row\_hammer）](https://en.wikipedia.org/wiki/Row_hammer%EF%BC%89)

例如，反复且快速的访问相同的物理储存位置，这种被称为 “<ruby> 锤击 <rt>  hammering </rt></ruby>” 的行为可以导致相邻位置的位值从 0 反转成 1，或者相反。

虽然这样的电子干扰已经被生产商知晓并且从可靠性角度研究了一段时间了，因为内存错误能够导致系统崩溃。而研究者们现在展示了在可控方式的触发下它所存在的严重安全隐患。

在 2015 年 4 月，来自谷歌 Project Zero 项目的研究者公布了两份基于内存 “Rowhammer”漏洞对于 x86-64 CPU 架构的 [提权利用](http://www.computerworld.com/article/2895898/google-researchers-hack-computers-using-dram-electrical-leaks.html)。其中一份利用可以使代码从谷歌的 Chrome 浏览器沙盒里逃逸并且直接在系统上执行，另一份可以在 Linux 机器上获取内核级权限。

此后，其他的研究者进行了更深入的调查并且展示了[通过网站中 JaveScript 脚本进行利用的方式](http://www.computerworld.com/article/2954582/security/researchers-develop-astonishing-webbased-attack-on-a-computers-dram.html)甚至能够影响运行在云环境下的[虚拟服务器](http://www.infoworld.com/article/3105889/security/flip-feng-shui-attack-on-cloud-vms-exploits-hardware-weaknesses.html)。然而，对于这项技术是否可以应用在智能手机和移动设备大量使用的 ARM 架构中还是有疑问的。

现在，一队成员来自荷兰阿姆斯特丹自由大学、奥地利格拉茨技术大学和加州大学圣塔芭芭拉分校的 VUSec 小组，已经证明了 Rowhammer 不仅仅可以应用在 ARM 架构上并且甚至比在 x86 架构上更容易。

研究者们将他们的新攻击命名为 Drammer，代表了 Rowhammer 确实存在，并且计划于周三在维也纳举办的第 23 届 ACM 计算机与通信安全大会上展示。这种攻击建立在之前就被发现与实现的 Rowhammer 技术之上。

VUSec 小组的研究者已经制造了一个适用于 Android 设备的恶意应用，当它被执行的时候利用不易察觉的内存位反转在不需要任何权限的情况下就可以获取设备根权限。

研究者们测试了来自不同制造商的 27 款 Android 设备，21 款使用 ARMv7（32-bit）指令集架构，其它 6 款使用 ARMv8（64-bit）指令集架构。他们成功的在 17 款 ARMv7 设备和 1 款 ARMv8 设备上实现了为反转，表明了这些设备是易受攻击的。

此外，Drammer 能够与其它的 Android 漏洞组合使用，例如 [Stagefright](http://www.csoonline.com/article/3045836/security/new-stagefright-exploit-puts-millions-of-android-devices-at-risk.html) 或者 [BAndroid](https://www.vusec.net/projects/bandroid/) 来实现无需用户手动下载恶意应用的远程攻击。

谷歌已经注意到了这一类型的攻击。“在研究者向谷歌漏洞奖励计划报告了这个问题之后，我们与他们进行了密切的沟通来深入理解这个问题以便我们更好的保护用户，”一位谷歌的代表在一份邮件申明中这样说到。“我们已经开发了一个缓解方案，将会包含在十一月的安全更新中。”（LCTT 译注：缓解方案，参见 <https://en.wikipedia.org/wiki/Vulnerability_management>）

VUSec 的研究者认为，谷歌的缓解方案将会使得攻击过程更为复杂，但是它不能修复潜在的问题。

事实上，从软件上去修复一个由硬件导致的问题是不现实的。硬件供应商正在研究相关问题并且有可能在将来的内存芯片中被修复，但是在现有设备的芯片中风险依然存在。

更糟的是，研究者们说，由于有许多因素会影响到攻击的成功与否并且这些因素尚未被研究透彻，因此很难去说有哪些设备会被影响到。例如，内存控制器可能会在不同的电量的情况下展现不同的行为，因此一个设备可能在满电的情况下没有风险，当它处于低电量的情况下就是有风险的。

同样的，在网络安全中有这样一句俗语：<ruby> 攻击将变本加厉，如火如荼 <rt>  Attacks always get getter, they never get worse </rt></ruby>。Rowhammer 攻击已经从理论变成了现实可能，同样的，它也可能会从现在的现实可能变成确确实实的存在。这意味着今天某个设备是不被影响的，在明天就有可能被改进后的 Rowhammer 技术证明它是存在风险的。

Drammer 在 Android 上实现是因为研究者期望研究基于 ARM 设备的影响，但是潜在的技术可以被使用在所有的架构与操作系统上。新的攻击相较于之前建立在运气与特殊特性与特定平台之上并且十分容易失效的技术已经是一个巨大的进步了。

Drammer 攻击的实现依靠于被包括图形、网络、声音等大量硬件子系统所使用的 DMA（直接存储访问）缓存。Drammer 的实现采用了所有操作系统上都有的 Android 的 ION 内存分配器、接口与方法，这给我们带来的警示是该论文的主要贡献之一。

“破天荒的，我们成功地展示了我们可以做到，在不依赖任何特定的特性情况下完全可靠的证明了 Rowhammer”， VUSec 小组中的其中一位研究者 Cristiano Giuffrida 这样说道。“攻击所利用的内存位置并非是 Android 独有的。攻击在任何的 Linux 平台上都能工作 -- 我们甚至怀疑其它操作系统也可以 -- 因为它利用的是操作系统内核内存管理中固有的特性。”

“我期待我们可以看到更多针对其它平台的攻击的变种，”阿姆斯特丹自由大学的教授兼 VUSec 系统安全研究小组的领导者 Herbert Bos 补充道。

在他们的[论文](https://vvdveen.com/publications/drammer.pdf)之外，研究者们也释出了一个 Android 应用来测试 Android 设备在当前所知的技术条件下受到 Rowhammer 攻击时是否会有风险。应用还没有传上谷歌应用商店，可以从 [VUSec Drammer 网站](https://www.vusec.net/projects/drammer/) 下载来手动安装。一个开源的 Rowhammer 模拟器同样能够帮助其他的研究者来更深入的研究这个问题。

---

via:<http://www.csoonline.com/article/3134726/security/physical-ram-attack-can-root-android-and-possibly-other-devices.html>

作者：[Lucian Constantin](http://www.csoonline.com/author/Lucian-Constantin/) 译者：[wcnnbdk1](https://github.com/wcnnbdk1) 校对：[wxy](https://github.com/wxy)

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


GraphQL 用例：使用 Golang 和 PostgreSQL 构建一个博客引擎 API

![](/data/attachment/album/201705/19/111808se294h4oy3b1bobe.jpg)

### 摘要

GraphQL 在生产环境中似乎难以使用：虽然对于建模功能来说图接口非常灵活，但是并不适用于关系型存储，不管是在实现还是性能方面。

在这篇博客中，我们会设计并实现一个简单的博客引擎 API，它支持以下功能：

* 三种类型的资源（用户、博文以及评论）支持多种功能（创建用户、创建博文、给博文添加评论、关注其它用户的博文和评论，等等。）
* 使用 PostgreSQL 作为后端数据存储（选择它因为它是一个流行的关系型数据库）。
* 使用 Golang（开发 API 的一个流行语言）实现 API。

我们会比较简单的 GraphQL 实现和纯 REST 替代方案，在一种普通场景（呈现博客文章页面）下对比它们的实现复杂性和效率。

### 介绍

GraphQL 是一种 IDL（<ruby> 接口定义语言 <rp>  （ </rp> <rt>  Interface Definition Language </rt> <rp>  ） </rp></ruby>），设计者定义数据类型和并把数据建模为一个<ruby> 图 <rp>  （ </rp> <rt>  graph </rt> <rp>  ） </rp></ruby>。每个顶点都是一种数据类型的一个实例，边代表了节点之间的关系。这种方式非常灵活，能适应任何业务领域。然而，问题是设计过程更加复杂，而且传统的数据存储不能很好地映射到图模型。阅读*附录1*了解更多关于这个问题的详细信息。

GraphQL 在 2014 年由 Facebook 的工程师团队首次提出。尽管它的优点和功能非常有趣而且引人注目，但它并没有得到大规模应用。开发者需要权衡 REST 的设计简单性、熟悉性、丰富的工具和 GraphQL 不会受限于 CRUD（LCTT 译注：Create、Read、Update、Delete） 以及网络性能（它优化了往返服务器的网络）的灵活性。

大部分关于 GraphQL 的教程和指南都跳过了从数据存储获取数据以便解决查询的问题。也就是，如何使用通用目的、流行存储方案（例如关系型数据库）为 GraphQL API 设计一个支持高效数据提取的数据库。

这篇博客介绍构建一个博客引擎 GraphQL API 的流程。它的功能相当复杂。为了和基于 REST 的方法进行比较，它的范围被限制为一个熟悉的业务领域。

这篇博客的文章结构如下：

* 第一部分我们会设计一个 GraphQL 模式并介绍所使用语言的一些功能。
* 第二部分是 PostgreSQL 数据库的设计。
* 第三部分介绍了使用 Golang 实现第一部分设计的 GraphQL 模式。
* 第四部分我们以从后端获取所需数据的角度来比较呈现博客文章页面的任务。

### 相关阅读

* 很棒的 [GraphQL 介绍文档](http://graphql.org/learn/)。
* 该项目的完整实现代码在 [github.com/topliceanu/graphql-go-example](https://github.com/topliceanu/graphql-go-example)。

### 在 GraphQL 中建模一个博客引擎

下述*列表1*包括了博客引擎 API 的全部模式。它显示了组成图的顶点的数据类型。顶点之间的关系，也就是边，被建模为指定类型的属性。

```
type User {
  id: ID
  email: String!
  post(id: ID!): Post
  posts: [Post!]!
  follower(id: ID!): User
  followers: [User!]!
  followee(id: ID!): User
  followees: [User!]!
}

type Post {
  id: ID
  user: User!
  title: String!
  body: String!
  comment(id: ID!): Comment
  comments: [Comment!]!
}

type Comment {
  id: ID
  user: User!
  post: Post!
  title: String
  body: String!
}

type Query {
  user(id: ID!): User
}

type Mutation {
  createUser(email: String!): User
  removeUser(id: ID!): Boolean
  follow(follower: ID!, followee: ID!): Boolean
  unfollow(follower: ID!, followee: ID!): Boolean
  createPost(user: ID!, title: String!, body: String!): Post
  removePost(id: ID!): Boolean
  createComment(user: ID!, post: ID!, title: String!, body: String!): Comment
  removeComment(id: ID!): Boolean
}

```

*列表1*

模式使用 GraphQL DSL 编写，它用于定义自定义数据类型，例如 `User`、`Post` 和 `Comment`。该语言也提供了一系列原始数据类型，例如 `String`、`Boolean` 和 `ID`（它是`String` 的别名，但是有顶点唯一标识符的额外语义）。

`Query` 和 `Mutation` 是语法解析器能识别并用于查询图的可选类型。从 GraphQL API 读取数据等同于遍历图。需要提供这样一个起始顶点；该角色通过 `Query` 类型来实现。在这种情况中，所有图的查询都要从一个由 id `user(id:ID!)` 指定的用户开始。对于写数据，定义了 `Mutation` 顶点。它提供了一系列操作，建模为能遍历（并返回）新创建顶点类型的参数化属性。*列表2*是这些查询的一些例子。

顶点属性能被参数化，也就是能接受参数。在图遍历场景中，如果一个博文顶点有多个评论顶点，你可以通过指定 `comment(id: ID)` 只遍历其中的一个。所有这些都取决于设计，设计者可以选择不提供到每个独立顶点的直接路径。

`!` 字符是一个类型后缀，适用于原始类型和用户定义类型，它有两种语义：

* 当被用于参数化属性的参数类型时，表示这个参数是必须的。
* 当被用于一个属性的返回类型时，表示当顶点被获取时该属性不会为空。
* 也可以把它们组合起来，例如 `[Comment!]!` 表示一个非空 Comment 顶点链表，其中 `[]`、`[Comment]` 是有效的，但 `null, [null], [Comment, null]` 就不是。

*列表2* 包括一系列用于博客 API 的 `curl` 命令，它们会使用 mutation 填充图然后查询图以便获取数据。要运行它们，按照 [topliceanu/graphql-go-example](https://github.com/graphql/graphql-js) 仓库中的指令编译并运行服务。

```
# 创建用户 1、2 和 3 的更改。更改和查询类似，在该情景中我们检索新创建用户的 id 和 email。
curl -XPOST http://vm:8080/graphql -d 'mutation {createUser(email:"user1@x.co"){id, email}}'
curl -XPOST http://vm:8080/graphql -d 'mutation {createUser(email:"user2@x.co"){id, email}}'
curl -XPOST http://vm:8080/graphql -d 'mutation {createUser(email:"user3@x.co"){id, email}}'
# 为用户添加博文的更改。为了和模式匹配我们需要检索他们的 id，否则会出现错误。
curl -XPOST http://vm:8080/graphql -d 'mutation {createPost(user:1,title:"post1",body:"body1"){id}}'
curl -XPOST http://vm:8080/graphql -d 'mutation {createPost(user:1,title:"post2",body:"body2"){id}}'
curl -XPOST http://vm:8080/graphql -d 'mutation {createPost(user:2,title:"post3",body:"body3"){id}}'
# 博文所有评论的更改。`createComment` 需要用户 id，标题和正文。看列表 1 的模式。
curl -XPOST http://vm:8080/graphql -d 'mutation {createComment(user:2,post:1,title:"comment1",body:"comment1"){id}}'
curl -XPOST http://vm:8080/graphql -d 'mutation {createComment(user:1,post:3,title:"comment2",body:"comment2"){id}}'
curl -XPOST http://vm:8080/graphql -d 'mutation {createComment(user:3,post:3,title:"comment3",body:"comment3"){id}}'
# 让用户 3 关注用户 1 和用户 2 的更改。注意 `follow` 更改只返回一个布尔值而不需要指定。
curl -XPOST http://vm:8080/graphql -d 'mutation {follow(follower:3, followee:1)}'
curl -XPOST http://vm:8080/graphql -d 'mutation {follow(follower:3, followee:2)}'

# 用户获取用户 1 所有数据的查询。
curl -XPOST http://vm:8080/graphql -d '{user(id:1)}'
# 用户获取用户 2 和用户 1 的关注者的查询。
curl -XPOST http://vm:8080/graphql -d '{user(id:2){followers{id, email}}}'
curl -XPOST http://vm:8080/graphql -d '{user(id:1){followers{id, email}}}'
# 检测用户 2 是否被用户 1 关注的查询。如果是，检索用户 1 的 email，否则返回空。
curl -XPOST http://vm:8080/graphql -d '{user(id:2){follower(id:1){email}}}'
# 返回用户 3 关注的所有用户 id 和 email 的查询。
curl -XPOST http://vm:8080/graphql -d '{user(id:3){followees{id, email}}}'
# 如果用户 3 被用户 1 关注，就获取用户 3 email 的查询。
curl -XPOST http://vm:8080/graphql -d '{user(id:1){followee(id:3){email}}}'
# 获取用户 1 的第二篇博文的查询，检索它的标题和正文。如果博文 2 不是由用户 1 创建的，就会返回空。
curl -XPOST http://vm:8080/graphql -d '{user(id:1){post(id:2){title,body}}}'
# 获取用户 1 的所有博文的所有数据的查询。
curl -XPOST http://vm:8080/graphql -d '{user(id:1){posts{id,title,body}}}'
# 获取写博文 2 用户的查询，如果博文 2 是由 用户 1 撰写；一个现实语言灵活性的例证。
curl -XPOST http://vm:8080/graphql -d '{user(id:1){post(id:2){user{id,email}}}}'

```

*列表2*

通过仔细设计 mutation 和类型属性，可以实现强大而富有表达力的查询。

### 设计 PostgreSQL 数据库

关系型数据库的设计，一如以往，由避免数据冗余的需求驱动。选择该方式有两个原因：

1. 表明实现 GraphQL API 不需要定制化的数据库技术或者学习和使用新的设计技巧。
2. 表明 GraphQL API 能在现有的数据库之上创建，更具体地说，最初设计用于 REST 后端甚至传统的呈现 HTML 站点的服务器端数据库。

阅读 *附录1* 了解关于关系型和图数据库在构建 GraphQL API 方面的区别。*列表3* 显示了用于创建新数据库的 SQL 命令。数据库模式和 GraphQL 模式相对应。为了支持 `follow/unfollow` 更改，需要添加 `followers` 关系。

```
CREATE TABLE IF NOT EXISTS users (
  id SERIAL PRIMARY KEY,
  email VARCHAR(100) NOT NULL
);
CREATE TABLE IF NOT EXISTS posts (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  title VARCHAR(200) NOT NULL,
  body TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS comments (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
  title VARCHAR(200) NOT NULL,
  body TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS followers (
  follower_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  followee_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  PRIMARY KEY(follower_id, followee_id)
);

```

*列表3*

### Golang API 实现

本项目使用的用 Go 实现的 GraphQL 语法解析器是 `github.com/graphql-go/graphql`。它包括一个查询解析器，但不包括模式解析器。这要求开发者利用库提供的结构使用 Go 构建 GraphQL 模式。这和 [nodejs 实现](https://github.com/graphql/graphql-js) 不同，后者提供了一个模式解析器并为数据获取暴露了钩子。因此 *列表1* 中的模式只是作为指导使用，需要转化为 Golang 代码。然而，这个*“限制”*提供了与抽象级别对等的机会，并且了解模式如何和用于检索数据的图遍历模型相关。*列表4* 显示了 `Comment` 顶点类型的实现：

```
var CommentType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Comment",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.NewNonNull(graphql.ID),
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                if comment, ok := p.Source.(*Comment); ok == true {
                    return comment.ID, nil
                }
                return nil, nil
            },
        },
        "title": &graphql.Field{
            Type: graphql.NewNonNull(graphql.String),
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                if comment, ok := p.Source.(*Comment); ok == true {
                    return comment.Title, nil
                }
                return nil, nil
            },
        },
        "body": &graphql.Field{
            Type: graphql.NewNonNull(graphql.ID),
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                if comment, ok := p.Source.(*Comment); ok == true {
                    return comment.Body, nil
                }
                return nil, nil
            },
        },
    },
})
func init() {
    CommentType.AddFieldConfig("user", &graphql.Field{
        Type: UserType,
        Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            if comment, ok := p.Source.(*Comment); ok == true {
                return GetUserByID(comment.UserID)
            }
            return nil, nil
        },
    })
    CommentType.AddFieldConfig("post", &graphql.Field{
        Type: PostType,
        Args: graphql.FieldConfigArgument{
            "id": &graphql.ArgumentConfig{
                Description: "Post ID",
                Type:        graphql.NewNonNull(graphql.ID),
            },
        },
        Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            i := p.Args["id"].(string)
            id, err := strconv.Atoi(i)
            if err != nil {
                return nil, err
            }
            return GetPostByID(id)
        },
    })
}

```

*列表4*

正如 *列表1* 中的模式，`Comment` 类型是静态定义的一个有三个属性的结构体：`id`、`title` 和 `body`。为了避免循环依赖，动态定义了 `user` 和 `post` 两个其它属性。

Go 并不适用于这种动态建模，它只支持一些类型检查，代码中大部分变量都是 `interface{}` 类型，在使用之前都需要进行类型断言。`CommentType` 是一个 `graphql.Object` 类型的变量，它的属性是 `graphql.Field` 类型。因此，GraphQL DSL 和 Go 中使用的数据结构并没有直接的转换。

每个字段的 `resolve` 函数暴露了 `Source` 参数，它是表示遍历时前一个节点的数据类型顶点。`Comment` 的所有属性都有作为 source 的当前 `CommentType` 顶点。检索`id`、`title` 和 `body` 是一个直接属性访问，而检索 `user` 和 `post` 要求图遍历，也需要数据库查询。由于它们非常简单，这篇文章并没有介绍这些 SQL 查询，但在*参考文献*部分列出的 github 仓库中有。

### 普通场景下和 REST 的对比

在这一部分，我们会展示一个普通的博客文章呈现场景，并比较 REST 和 GraphQL 的实现。关注重点会放在入站/出站请求数量，因为这些是造成页面呈现延迟的最主要原因。

场景：呈现一个博客文章页面。它应该包含关于作者（email）、博客文章（标题、正文）、所有评论（标题、正文）以及评论人是否关注博客文章作者的信息。*图1* 和 *图2* 显示了客户端 SPA、API 服务器以及数据库之间的交互，一个是 REST API、另一个对应是 GraphQL API。

```
+------+                  +------+                  +--------+
|client|                  |server|                  |database|
+--+---+                  +--+---+                  +----+---+
   |      GET /blogs/:id     |                           |
1\. +------------------------->  SELECT * FROM blogs...   |
   |                         +--------------------------->
   |                         <---------------------------+
   <-------------------------+                           |
   |                         |                           |
   |     GET /users/:id      |                           |
2\. +------------------------->  SELECT * FROM users...   |
   |                         +--------------------------->
   |                         <---------------------------+
   <-------------------------+                           |
   |                         |                           |
   | GET /blogs/:id/comments |                           |
3\. +-------------------------> SELECT * FROM comments... |
   |                         +--------------------------->
   |                         <---------------------------+
   <-------------------------+                           |
   |                         |                           |
   | GET /users/:id/followers|                           |
4\. +-------------------------> SELECT * FROM followers.. |
   |                         +--------------------------->
   |                         <---------------------------+
   <-------------------------+                           |
   |                         |                           |
   +                         +                           +

```

*图1*

```
+------+                  +------+                  +--------+
|client|                  |server|                  |database|
+--+---+                  +--+---+                  +----+---+
   |      GET /graphql       |                           |
1\. +------------------------->  SELECT * FROM blogs...   |
   |                         +--------------------------->
   |                         <---------------------------+
   |                         |                           |
   |                         |                           |
   |                         |                           |
2\. |                         |  SELECT * FROM users...   |
   |                         +--------------------------->
   |                         <---------------------------+
   |                         |                           |
   |                         |                           |
   |                         |                           |
3\. |                         | SELECT * FROM comments... |
   |                         +--------------------------->
   |                         <---------------------------+
   |                         |                           |
   |                         |                           |
   |                         |                           |
4\. |                         | SELECT * FROM followers.. |
   |                         +--------------------------->
   |                         <---------------------------+
   <-------------------------+                           |
   |                         |                           |
   +                         +                           +

```

*图2*

*列表5* 是一条用于获取所有呈现博文所需数据的简单 GraphQL 查询。

```
{
  user(id: 1) {
    email
    followers
    post(id: 1) {
      title
      body
      comments {
        id
        title
        user {
          id
          email
        }
      }
    }
  }
}

```

*列表5*

对于这种情况，对数据库的查询次数是故意相同的，但是到 API 服务器的 HTTP 请求已经减少到只有一个。我们认为在这种类型的应用程序中通过互联网的 HTTP 请求是最昂贵的。

为了利用 GraphQL 的优势，后端并不需要进行特别设计，从 REST 到 GraphQL 的转换可以逐步完成。这使得可以测量性能提升和优化。从这一点，API 设计者可以开始优化（潜在的合并） SQL 查询从而提高性能。缓存的机会在数据库和 API 级别都大大增加。

SQL 之上的抽象（例如 ORM 层）通常会和 `n+1` 问题相抵触。在 REST 示例的步骤 4 中，客户端可能不得不在单独的请求中为每个评论的作者请求关注状态。这是因为在 REST 中没有标准的方式来表达两个以上资源之间的关系，而 GraphQL 旨在通过使用嵌套查询来防止这类问题。这里我们通过获取用户的所有关注者来作弊。我们向客户提出了如何确定评论并关注了作者的用户的逻辑。

另一个区别是获取比客户端所需更多的数据，以免破坏 REST 资源抽象。这对于用于解析和存储不需要数据的带宽消耗和电池寿命非常重要。

### 总结

GraphQL 是 REST 的一个可用替代方案，因为：

* 尽管设计 API 更加困难，但该过程可以逐步完成。也是由于这个原因，从 REST 转换到 GraphQL 非常容易，两个流程可以没有任何问题地共存。
* 在网络请求方面更加高效，即使是类似本博客中的简单实现。它还提供了更多查询优化和结果缓存的机会。
* 在用于解析结果的带宽消耗和 CPU 周期方面它更加高效，因为它只返回呈现页面所需的数据。

REST 仍然非常有用，如果：

* 你的 API 非常简单，只有少量的资源或者资源之间关系简单。
* 在你的组织中已经在使用 REST API，而且你已经配置好了所有工具，或者你的客户希望获取 REST API。
* 你有复杂的 ACL（LCTT 译注：Access Control List） 策略。在博客例子中，可能的功能是允许用户良好地控制谁能查看他们的电子邮箱、博客、特定博客的评论、他们关注了谁，等等。优化数据获取同时检查复杂的业务规则可能会更加困难。

### 附录1：图数据库和高效数据存储

尽管将其应用领域数据想象为一个图非常直观，正如这篇博文介绍的那样，但是支持这种接口的高效数据存储问题仍然没有解决。

近年来图数据库变得越来越流行。通过将 GraphQL 查询转换为特定的图数据库查询语言从而延迟解决请求的复杂性似乎是一种可行的方案。

问题是和关系型数据库相比，图并不是一种高效的数据结构。图中一个顶点可能有到任何其它顶点的连接，访问模式比较难以预测因此提供了较少的优化机会。

例如缓存的问题，为了快速访问需要将哪些顶点保存在内存中？通用缓存算法在图遍历场景中可能没那么高效。

数据库分片问题：把数据库切分为更小、没有交叉的数据库并保存到独立的硬件。在学术上，最小切割的图划分问题已经得到了很好的理解，但可能是次优的，而且由于病态的最坏情况可能导致高度不平衡切割。

在关系型数据库中，数据被建模为记录（行或者元组）和列，表和数据库名称都只是简单的命名空间。大部分数据库都是面向行的，意味着每个记录都是一个连续的内存块，一个表中的所有记录在磁盘上一个接一个地整齐地打包（通常按照某个关键列排序）。这非常高效，因为这是物理存储最优的工作方式。HDD 最昂贵的操作是将磁头移动到磁盘上的另一个扇区，因此最小化此类访问非常重要。

很有可能如果应用程序对一条特定记录感兴趣，它需要获取整条记录，而不仅仅是记录中的其中一列。也很有可能如果应用程序对一条记录感兴趣，它也会对该记录周围的记录感兴趣，例如全表扫描。这两点使得关系型数据库相当高效。然而，也是因为这个原因，关系型数据库的最差使用场景就是总是随机访问所有数据。图数据库正是如此。

随着支持更快随机访问的 SSD 驱动器的出现，更便宜的内存使得缓存大部分图数据库成为可能，更好的优化图缓存和分区的技术，图数据库开始成为可选的存储解决方案。大部分大公司也使用它：Facebook 有 Social Graph，Google 有 Knowledge Graph。

---

via: <http://alexandrutopliceanu.ro/post/graphql-with-go-and-postgresql>

作者：[Alexandru Topliceanu](https://github.com/topliceanu) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

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


4 个拥有绝佳命令行界面的终端程序

Summary: pgcli 和 mycli 的作者为你介绍几个精心设计的 CLI 程序，以及如何解决一些可发现性问题。

超喜欢补全，这能极大的提高我的工作效率。

大大提高工作效率呢

不错不错

mycli 一执行 drop database xxxx就挂了，果然还是workbench靠谱

很强大

来自湖北武汉的 Chrome Mobile 40.0|Android 4.4 用户

看不懂

看不懂

看不懂

>
> 让我们来看几个精心设计的 CLI 程序，以及如何解决一些可发现性问题。
>
>
>

![](/data/attachment/album/201705/20/120427n325ehm22bibw3j2.jpg)

在本文中，我会指出命令行界面的<ruby> 可发现性 <rt>  discoverability </rt></ruby>缺点以及克服这些问题的几种方法。

我喜欢命令行。我第一次接触命令行是在 1997 的 DOS 6.2 上。我学习了各种命令的语法，并展示了如何在目录中列出隐藏的文件（`attrib`）。我会每次仔细检查命令中的每个字符。 当我犯了一个错误，我会从头开始重新输入命令。直到有一天，有人向我展示了如何使用向上和向下箭头按键遍历命令行历史，我被震惊了。

后来当我接触到 Linux 时，让我感到惊喜的是，上下箭头保留了它们遍历历史记录的能力。我仍然很仔细地打字，但是现在，我了解如何盲打，并且我能打的很快，每分钟可以达到 55 个单词的速度。接着有人向我展示了 tab 补完，再一次改变了我的生活。

在 GUI 应用程序中，菜单、工具提示和图标用于向用户展示功能。而命令行缺乏这种能力，但是有办法克服这个问题。在深入解决方案之前，我会来看看几个有问题的 CLI 程序：

**1、 MySQL**

首先让我们看看我们所钟爱的 MySQL REPL。我经常发现自己在输入 `SELECT * FROM` 然后按 `Tab` 的习惯。MySQL 会询问我是否想看到所有的 871 种可能性。我的数据库中绝对没有 871 张表。如果我选择 `yes`，它会显示一堆 SQL 关键字、表、函数等。（LCTT 译注：REPL —— Read-Eval-Print Loop，交互式开发环境）

![MySQL gif](/data/attachment/album/201705/20/120430kzu0iv7x0fb11bwu.gif)

**2、 Python**

我们来看另一个例子，标准的 Python REPL。我开始输入命令，然后习惯按 `Tab` 键。瞧，插入了一个 `Tab` 字符，考虑到 `Tab` 在 Python 源代码中没有特定作用，这是一个问题。

![Python gif](/data/attachment/album/201705/20/120431ri5mxao1gz5ijg0a.gif "Python gif")

### 好的用户体验

让我看下设计良好的 CLI 程序以及它们是如何克服这些可发现性问题的。

#### 自动补全： bpython

[Bpython](https://bpython-interpreter.org/) 是对 Python REPL 的一个很好的替代。当我运行 bpython 并开始输入时，建议会立即出现。我没用通过特殊的键盘绑定触发它，甚至没有按下 `Tab` 键。

![bpython gif](/data/attachment/album/201705/20/120432prrm4dr1vodyofvs.gif "bpython gif")

当我出于习惯按下 `Tab` 键时，它会用列表中的第一个建议补全。这是给 CLI 设计带来可发现性性的一个很好的例子。

bpython 的另一个方面是可以展示模块和函数的文档。当我输入一个函数的名字时，它会显示这个函数附带的签名以及文档字符串。这是一个多么令人难以置信的周到设计啊。

#### 上下文感知补全：mycli

[mycli](http://mycli.net/) 是默认的 MySQL 客户端的现代替代品。这个工具对 MySQL 来说就像 bpython 之于标准 Python REPL 一样。mycli 将在你输入时自动补全关键字、表名、列和函数。

补全建议是上下文相关的。例如，在 `SELECT * FROM` 之后，只有来自当前数据库的表才会列出，而不是所有可能的关键字。

![mycli gif](/data/attachment/album/201705/20/120433y0mqoq5xb4mfff0q.gif "mycli gif")

#### 模糊搜索和在线帮助： pgcli

如果您正在寻找 PostgreSQL 版本的 mycli，请看看 [pgcli](http://pgcli.com/)。 与 mycli 一样，它提供了上下文感知的自动补全。菜单中的项目使用模糊搜索缩小范围。模糊搜索允许用户输入整体字符串中的任意子字符串来尝试找到正确的匹配项。

![pgcli gif](/data/attachment/album/201705/20/120436qwvx5i04uhhi0aut.gif "pgcli gif")

pgcli 和 mycli 在其 CLI 中都实现了这个功能。斜杠命令的文档也作为补全菜单的一部分展示。

#### 可发现性: fish

在传统的 Unix shell（Bash、zsh 等）中，有一种搜索历史记录的方法。此搜索模式由 `Ctrl-R` 触发。当再次调用你上周运行过的命令时，例如 **ssh**或 **docker**，这是一个令人难以置信的有用的工具。 一旦你知道这个功能，你会发现自己经常会使用它。

如果这个功能是如此有用，那为什么不每次都搜索呢？这正是 [**fish** shell](https://fishshell.com/) 所做的。一旦你开始输入命令，**fish** 将开始建议与历史记录类似的命令。然后，你可以按右箭头键接受该建议。

### 命令行规矩

我已经回顾了一些解决可发现性的问题的创新方法，但也有一些基本的命令行功能应该作为每个 REPL 所实现基础功能的一部分：

* 确保 REPL 有可通过箭头键调用的历史记录。确保会话之间的历史持续存在。
* 提供在编辑器中编辑命令的方法。不管你的补全是多么棒，有时用户只需要一个编辑器来制作完美的命令来删除生产环境中所有的表。
* 使用分页器（`pager`）来管道输出。不要让用户滚动他们的终端。哦，要为分页器设置个合理的默认值。（记得添加选项来处理颜色代码。）
* 提供一种通过 `Ctrl-R` 界面或者 fish 式的自动搜索来搜索历史记录的方法。

### 总结

在第 2 节中，我将来看看 Python 中使你能够实现这些技术的特定库。同时，请查看其中一些精心设计的命令行应用程序：

* [bpython](http://bpython-interpreter.org/)或 [ptpython](http://github.com/jonathanslenders/ptpython/)：具有自动补全支持的 Python REPL。
* [http-prompt](https://github.com/eliangcs/http-prompt)：交互式 HTTP 客户端。
* [mycli](http://mycli.net/)：MySQL、MariaDB 和 Percona 的命令行界面，具有自动补全和语法高亮。
* [pgcli](http://pgcli.com/)：具有自动补全和语法高亮，是对 [psql](https://www.postgresql.org/docs/9.2/static/app-psql.html) 的替代工具。
* [wharfee](http://wharfee.com/)：用于管理 Docker 容器的 shell。

*了解更多： Amjith Ramanujam 在 5 月 20 日在波特兰俄勒冈州举办的 [PyCon US 2017](https://us.pycon.org/2017/) 上的谈话“[神奇的命令行工具](https://us.pycon.org/2017/schedule/presentation/518/)”。*

---

作者简介：

Amjith Ramanujam - Amjith Ramanujam 是 pgcli 和 mycli 的创始人。人们认为它们很酷，他表示笑纳赞誉。他喜欢用 Python、Javascript 和 C 编程。他喜欢编写简单易懂的代码，它们有时甚至会成功。

---

via: <https://opensource.com/article/17/5/4-terminal-apps>

作者：[Amjith Ramanujam](https://opensource.com/users/amjith) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


完全指南：如何在 CentOS 7 中安装、配置和安全加固 FTP 服务

Summary: FTP（文件传输协议）是一种用于通过网络在服务器和客户端之间传输文件的传统并广泛使用的标准工具，特别是在不需要身份验证的情况下（允许匿名用户连接到服务器）。我们必须明白，默认情况下 FTP 是不安全的，因为它不加密传输用户凭据和数据。

SELinux有加密功能么？好像没听说过啊。

第9出错，是按照步骤来打的，求解哪里出错了。

你得说什么错误啊？

![](/data/attachment/album/201705/21/104945ekg94rgk9hi1k2pk.jpg)

FTP（文件传输协议）是一种用于通过网络[在服务器和客户端之间传输文件](http://www.tecmint.com/scp-commands-examples/)的传统并广泛使用的标准工具，特别是在不需要身份验证的情况下（允许匿名用户连接到服务器）。我们必须明白，默认情况下 FTP 是不安全的，因为它不加密传输用户凭据和数据。

在本指南中，我们将介绍在 CentOS/RHEL7 和 Fedora 发行版中安装、配置和保护 FTP 服务器（ VSFTPD 代表 “Very Secure FTP Daemon”）的步骤。

请注意，本指南中的所有命令将以 root 身份运行，如果你不使用 root 帐户操作服务器，请使用 [sudo命令](http://www.tecmint.com/sudoers-configurations-for-setting-sudo-in-linux/) 获取 root 权限。

### 步骤 1：安装 FTP 服务器

1、 安装 vsftpd 服务器很直接，只要在终端运行下面的命令。

```
# yum install vsftpd

```

2、 安装完成后，服务先是被禁用的，因此我们需要手动启动，并设置在下次启动时自动启用：

```
# systemctl start vsftpd
# systemctl enable vsftpd

```

3、 接下来，为了允许从外部系统访问 FTP 服务，我们需要打开 FTP 守护进程监听的 21 端口：

```
# firewall-cmd --zone=public --permanent --add-port=21/tcp
# firewall-cmd --zone=public --permanent --add-service=ftp
# firewall-cmd --reload

```

### 步骤 2： 配置 FTP 服务器

4、 现在，我们会进行一些配置来设置并加密我们的 FTP 服务器，让我们先备份一下原始配置文件 `/etc/vsftpd/vsftpd.conf`：

```
# cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.orig

```

接下来，打开上面的文件，并将下面的选项设置相关的值：

```
anonymous_enable=NO             ### 禁用匿名登录
local_enable=YES        ### 允许本地用户登录
write_enable=YES        ### 允许对文件系统做改动的 FTP 命令
local_umask=022             ### 本地用户创建文件所用的 umask 值
dirmessage_enable=YES           ### 当用户首次进入一个新目录时显示一个消息
xferlog_enable=YES      ### 用于记录上传、下载细节的日志文件
connect_from_port_20=YES        ### 使用端口 20 （ftp-data）用于 PORT 风格的连接
xferlog_std_format=YES          ### 使用标准的日志格式
listen=NO               ### 不要让 vsftpd 运行在独立模式
listen_ipv6=YES             ### vsftpd 将监听 IPv6 而不是 IPv4
pam_service_name=vsftpd         ###  vsftpd 使用的 PAM 服务名
userlist_enable=YES             ### vsftpd 支持载入用户列表
tcp_wrappers=YES        ### 使用 tcp wrappers

```

5、 现在基于用户列表文件 `/etc/vsftpd.userlist` 来配置 FTP 来允许/拒绝用户的访问。

默认情况下，如果设置了 `userlist_enable=YES`，当 `userlist_deny` 选项设置为 `YES` 的时候，`userlist_file=/etc/vsftpd.userlist` 中列出的用户被拒绝登录。

然而， 更改配置为 `userlist_deny=NO`，意味着只有在 `userlist_file=/etc/vsftpd.userlist` 显式指定的用户才允许登录。

```
userlist_enable=YES                   ### vsftpd 将从 userlist_file 给出的文件中载入用户名列表
userlist_file=/etc/vsftpd.userlist    ### 存储用户名的文件
userlist_deny=NO

```

这并不是全部，当用户登录到 FTP 服务器时，它们会进入 chroot jail 中，这是仅作为 FTP 会话主目录的本地根目录。

接下来，我们将介绍如何将 FTP 用户 chroot 到 FTP 用户的家目录（本地 root）中的两种可能情况，如下所述。

6、 接下来添加下面的选项来限制 FTP 用户到它们自己的家目录。

```
chroot_local_user=YES
allow_writeable_chroot=YES

```

`chroot_local_user=YES` 意味着用户可以设置 chroot jail，默认是登录后的家目录。

同样默认的是，出于安全原因，vsftpd 不会允许 chroot jail 目录可写，然而，我们可以添加 `allow_writeable_chroot=YES` 来覆盖这个设置。

保存并关闭文件。

### 步骤 3： 用 SELinux 加密 FTP 服务器

7、现在，让我们设置下面的 SELinux 布尔值来允许 FTP 能读取用户家目录下的文件。请注意，这原本是使用以下命令完成的：

```
# setsebool -P ftp_home_dir on

```

然而，由于这个 bug 报告：<https://bugzilla.redhat.com/show_bug.cgi?id=1097775>，`ftp_home_dir` 指令默认是禁用的。

现在，我们会使用 `semanage` 命令来设置 SELinux 规则来允许 FTP 读取/写入用户的家目录。

```
# semanage boolean -m ftpd_full_access --on

```

这时，我们需要重启 vsftpd 来使目前的设置生效：

```
# systemctl restart vsftpd

```

### 步骤 4： 测试 FTP 服务器

8、 现在我们会用 [useradd 命令](http://www.tecmint.com/add-users-in-linux/)创建一个 FTP 用户来测试 FTP 服务器。

```
# useradd -m -c “Ravi Saive, CEO” -s /bin/bash ravi
# passwd ravi

```

之后，我们如下使用 [echo 命令](http://www.tecmint.com/echo-command-in-linux/)添加用户 ravi 到文件 `/etc/vsftpd.userlist` 中：

```
# echo "ravi" | tee -a /etc/vsftpd.userlist
# cat /etc/vsftpd.userlist

```

9、 现在是时候测试我们上面的设置是否可以工作了。让我们使用匿名登录测试，我们可以从下面的截图看到匿名登录没有被允许。

```
# ftp 192.168.56.10
Connected to 192.168.56.10  (192.168.56.10).
220 Welcome to TecMint.com FTP service.
Name (192.168.56.10:root) : anonymous
530 Permission denied.
Login failed.
ftp>

```

![Test Anonymous FTP Login](/data/attachment/album/201705/21/104954x8nzoi01uqvqu70s.png)

*测试 FTP 匿名登录*

10、 让我们也测试一下没有列在 `/etc/vsftpd.userlist` 中的用户是否有权限登录，下面截图是没有列入的情况：

```
# ftp 192.168.56.10
Connected to 192.168.56.10  (192.168.56.10).
220 Welcome to TecMint.com FTP service.
Name (192.168.56.10:root) : aaronkilik
530 Permission denied.
Login failed.
ftp>

```

![FTP User Login Failed](/data/attachment/album/201705/21/104955bcwaswmmv4ua8u84.png)

*FTP 用户登录失败*

11、 现在最后测试一下列在 `/etc/vsftpd.userlist` 中的用户是否在登录后真的进入了他/她的家目录：

```
# ftp 192.168.56.10
Connected to 192.168.56.10  (192.168.56.10).
220 Welcome to TecMint.com FTP service.
Name (192.168.56.10:root) : ravi
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls

```

![FTP User Login Successful](/data/attachment/album/201705/21/104956fuc9grbrw7tut7yc.png)

*用户成功登录*

警告：使用 `allow_writeable_chroot=YES` 有一定的安全隐患，特别是用户具有上传权限或 shell 访问权限时。

只有当你完全知道你正做什么时才激活此选项。重要的是要注意，这些安全性影响并不是 vsftpd 特定的，它们适用于所有提供了将本地用户置于 chroot jail 中的 FTP 守护进程。

因此，我们将在下一节中看到一种更安全的方法来设置不同的不可写本地根目录。

### 步骤 5： 配置不同的 FTP 家目录

12、 再次打开 vsftpd 配置文件，并将下面不安全的选项注释掉：

```
#allow_writeable_chroot=YES

```

接着为用户（`ravi`，你的可能不同）创建另外一个替代根目录，并将所有用户对该目录的可写权限移除：

```
# mkdir /home/ravi/ftp
# chown nobody:nobody /home/ravi/ftp
# chmod a-w /home/ravi/ftp

```

13、 接下来，在用户存储他/她的文件的本地根目录下创建一个文件夹：

```
# mkdir /home/ravi/ftp/files
# chown ravi:ravi  /home/ravi/ftp/files
# chmod 0700 /home/ravi/ftp/files/

```

接着在 vsftpd 配置文件中添加/修改这些选项：

```
user_sub_token=$USER         ### 在本地根目录下插入用户名
local_root=/home/$USER/ftp   ### 定义任何用户的本地根目录

```

保存并关闭文件。再说一次，有新的设置后，让我们重启服务：

```
# systemctl restart vsftpd

```

14、 现在最后在测试一次查看用户本地根目录就是我们在他的家目录创建的 FTP 目录。

```
# ftp 192.168.56.10
Connected to 192.168.56.10  (192.168.56.10).
220 Welcome to TecMint.com FTP service.
Name (192.168.56.10:root) : ravi
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls

```

![FTP User Home Directory Login Successful](/data/attachment/album/201705/21/104957em1lftdtyttt8pft.png)

*FTP 用户家目录登录成功*

就是这样了！在本文中，我们介绍了如何在 CentOS 7 中安装、配置以及加密的 FTP 服务器，使用下面的评论栏给我们回复，或者分享关于这个主题的任何有用信息。

**建议阅读：** [在 RHEL/CentOS 7 上安装 ProFTPD 服务器](/article-8504-1.html)

在下一篇文章中，我们还将向你介绍如何在 CentOS 7 中[保护使用 SSL/TLS](http://www.tecmint.com/secure-vsftpd-using-ssl-tls-on-centos/)连接的 FTP 服务器，再此之前，请继续关注 TecMint。

---

作者简介：

Aaron Kili 是一名 Linux 和 F.O.S.S 爱好者，即将从事 Linux 系统管理员和网页开发工作，他日前是 TecMint 技术网站的原创作者，非常喜欢使用电脑工作，坚信分享知识是一种美德。

---

via: <http://www.tecmint.com/install-ftp-server-in-centos-7/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 下当个游戏主播

真是一口老血喷在键盘上。连游戏都不能把这个程序员拉到win平台，我只能说他的人生的娱乐部分已经被Linux毁了。默哀1秒。

最好的办法的切换到windows系统当主播

在大陆不怎么适用吧

Minecraft、0 A. D.、Mindustry之类的游戏都可以在Linux上完美运行啊

![](/data/attachment/album/201705/21/162312ik2h552o3hpow2m7.jpg)

也许没有那么多铁杆的游戏玩家使用 Linux，但肯定有很多 Linux 用户喜欢玩游戏。如果你是其中之一，并希望向世界展示 Linux 游戏不再是一个笑话，那么你会喜欢下面这个关于如何捕捉并且/或者以流式播放游戏的快速教程。我在这将用一个名为 “[Open Broadcaster Software Studio](https://obsproject.com/download)” 的软件，这可能是我们所能找到最好的一种。

### 捕获设置

在顶层菜单中，我们选择 “File” → “Settings”，然后我们选择 “Output” 来设置要生成的文件的选项。这里我们可以设置想要的音频和视频的比特率、新创建的文件的目标路径和文件格式。这上面还提供了粗略的质量设置。

 [![Select output set in OBS Studio](/data/attachment/album/201705/21/162322la8g8g14mx8mx7o9.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_1.png)

如果我们将顶部的输出模式从 “Simple” 更改为 “Advanced”，我们就能够设置 CPU 负载，以控制 OBS 对系统的影响。根据所选的质量、CPU 能力和捕获的游戏，可以设置一个不会导致丢帧的 CPU 负载设置。你可能需要做一些试验才能找到最佳设置，但如果将质量设置为低，则不用太多设置。

 [![Change OBS output mode](/data/attachment/album/201705/21/162324fmbic0wo1o1tzbi0.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_2.png)

接下来，我们转到设置的 “Video” 部分，我们可以设置我们想要的输出视频分辨率。注意缩小过滤（downscaling filtering ）方式，因为它使最终的质量有所不同。

 [![Down scaling filter](/data/attachment/album/201705/21/162327drv47o8j4wwio5ow.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_3.png)

你可能还需要绑定热键以启动、暂停和停止录制。这特别有用，这样你就可以在录制时看到游戏的屏幕。为此，请在设置中选择 “Hotkeys” 部分，并在相应的框中分配所需的按键。当然，你不必每个框都填写，你只需要填写所需的。

 [![Configure Hotkeys in OBS](/data/attachment/album/201705/21/162330dz57hkxc5nppu9bp.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_4.png)

如果你对流式传输感兴趣，而不仅仅是录制，请选择 “Stream” 分类的设置，然后你可以选择支持的 30 种流媒体服务，包括 Twitch、Facebook Live 和 Youtube，然后选择服务器并输入 流密钥。

 [![Streaming settings](/data/attachment/album/201705/21/162332ii05z0802iqpnnq8.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_5.png)

### 设置源

在左下方，你会发现一个名为 “Sources” 的框。我们按下加号来添加一个新的源，它本质上就是我们录制的媒体源。在这你可以设置音频和视频源，但是图像甚至文本也是可以的。

 [![OBS Media Source](/data/attachment/album/201705/21/162336o3nss10a15tss1mi.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_6.png)

前三个是关于音频源，接下来的两个是图像，JACK 选项用于从乐器捕获的实时音频， Media Source 用于添加文件等。这里我们感兴趣的是 “Screen Capture (XSHM)”、“Video Capture Device (V4L2)” 和 “Window Capture (Xcomposite)” 选项。

屏幕捕获选项让你选择要捕获的屏幕（包括活动屏幕），以便记录所有内容。如工作区更改、窗口最小化等。对于标准批量录制来说，这是一个适合的选项，它可在发布之前进行编辑。

我们来探讨另外两个。Window Capture 将让我们选择一个活动窗口并将其放入捕获监视器。为了将我们的脸放在一个角落，视频捕获设备用于人们可以在我们说话时可以看到我们。当然，每个添加的源都提供了一组选项来供我们实现我们最后要的效果。

 [![OBS Window Capture](/data/attachment/album/201705/21/162338h5i5iqq77qiq6ia7.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_7.png)

添加的来源是可以调整大小的，也可以沿着录制帧的平面移动，因此你可以添加多个来源，并根据需要进行排列，最后通过右键单击执行基本的编辑任务。

 [![Add Multiple sources](/data/attachment/album/201705/21/162342at9wy9btb7ht7gux.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_8.png)

### 过渡

最后，如果你正在流式传输游戏会话时希望能够在游戏视图和自己（或任何其他来源）之间切换。为此，请从右下角切换为“Studio Mode”，并添加一个分配给另一个源的场景。你还可以通过取消选中 “Duplicate scene” 并检查 “Transitions” 旁边的齿轮图标上的 “Duplicate sources” 来切换。 当你想在简短评论中显示你的脸部时，这很有帮助。

 [![Studio mode](/data/attachment/album/201705/21/162343dbtl0lo6468h2t5z.png)](https://www.howtoforge.com/images/how-to-capture-and-stream-your-gaming-session-on-linux/big/pic_9.png)

这个软件有许多过渡效果，你可以按中心的 “Quick Transitions” 旁边的加号图标添加更多。当你添加它们时，还将会提示你进行设置。

### 总结

OBS Studio 是一个功能强大的免费软件，它工作稳定，使用起来相当简单直接，并且拥有越来越多的扩展其功能的[附加插件](https://obsproject.com/forum/resources/categories/obs-studio-plugins.6/)。如果你需要在 Linux 上记录并且/或者流式传输游戏会话，除了使用 OBS 之外，我无法想到其他更好的解决方案。你有其他类似工具的经验么？ 请在评论中分享也欢迎包含一个展示你技能的视频链接。:)

---

via: <https://www.howtoforge.com/tutorial/how-to-capture-and-stream-your-gaming-session-on-linux/>

作者：[Bill Toulas](https://www.howtoforge.com/tutorial/how-to-capture-and-stream-your-gaming-session-on-linux/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


5 个提升你开源项目贡献者基数的方法

![](/data/attachment/album/201705/21/171027n9suiytd8bbell9y.jpg)

许多自由和开源软件项目因解决问题而出现，人们开始为它们做贡献，是因为他们也想修复遇到的问题。当项目的最终用户发现它对他们的需求有用，该项目就开始增长。并且出于分享的目的把人们吸引到同一个项目社区。

就像任何事物都是有寿命的，增长既是开源项目成功的标志，也是开源项目成功的来源。那么项目领导者和维护者如何激励贡献者基数的增长？这里有五种方法。

### 1、 提供好的文档

人们经常低估项目[文档](https://opensource.com/tags/documentation)的重要性。它是项目贡献者的主要信息来源，它会激励他们努力。信息必须是正确和最新的。它应该包括如何构建该软件、如何提交补丁、编码风格指南等步骤。

查看经验丰富的科技作家、编辑 Bob Reselman 的 [7 个创建世界级文档的规则](https://opensource.com/business/16/1/scale-14x-interview-bob-reselman)。

开发人员文档的一个很好的例子是 [Python 开发人员指南](https://docs.python.org/devguide/)。它包括清晰简洁的步骤，涵盖 Python 开发的各个方面。

### 2、 降低进入门槛

如果你的项目有[工单或 bug 追踪工具](https://opensource.com/tags/bugs-and-issues)，请确保将初级任务标记为一个“小 bug” 或“起点”。新的贡献者可以很容易地通过解决这些问题进入项目。追踪工具也是标记非编程任务（如平面设计、图稿和文档改进）的地方。有许多项目成员不是每天都编码，但是却通过这种方式成为推动力。

Fedora 项目维护着一个这样的[易修复和入门级问题的追踪工具](https://fedoraproject.org/easyfix/)。

### 3、 为补丁提供常规反馈

确认每个补丁，即使它只有一行代码，并给作者反馈。提供反馈有助于吸引潜在的候选人，并指导他们熟悉项目。所有项目都应有一个邮件列表和[聊天功能](https://opensource.com/alternatives/slack)进行通信。问答可在这些媒介中发生。大多数项目不会在一夜之间成功，但那些繁荣的列表和沟通渠道为增长创造了环境。

### 4、 推广你的项目

始于解决问题的项目实际上可能对其他开发人员也有用。作为项目的主要贡献者，你的责任是为你的的项目建立文档并推广它。写博客文章，并在社交媒体上分享项目的进展。你可以从简要描述如何成为项目的贡献者开始，并在该描述中提供主要开发者文档的参考连接。此外，请务必提供有关路线图和未来版本的信息。

为了你的听众，看看由 Opensource.com 的社区经理 Rikki Endsley 写的[写作提示](https://opensource.com/business/15/10/what-stephen-king-can-teach-tech-writers)。

### 5、 保持友好

友好的对话语调和迅速的回复将加强人们对你的项目的兴趣。最初，这些问题只是为了寻求帮助，但在未来，新的贡献者也可能会提出想法或建议。让他们有信心他们可以成为项目的贡献者。

记住你一直在被人评头论足！人们会观察项目开发者是如何在邮件列表或聊天上交谈。这些意味着对新贡献者的欢迎和开放程度。当使用技术时，我们有时会忘记人文关怀，但这对于任何项目的生态系统都很重要。考虑一个情况，项目是很好的，但项目维护者不是很受欢迎。这样的管理员可能会驱使用户远离项目。对于有大量用户基数的项目而言，不被支持的环境可能导致分裂，一部分用户可能决定复刻项目并启动新项目。在开源世界中有这样的先例。

另外，拥有不同背景的人对于开源项目的持续增长和源源不断的点子是很重要的。

最后，项目负责人有责任维持和帮助项目成长。指导新的贡献者是项目的关键，他们将成为项目和社区未来的领导者。

阅读：由红帽的内容战略家 Nicole Engard 写的 [7 种让新的贡献者感到受欢迎的方式](https://opensource.com/life/16/5/sumana-harihareswara-maria-naggaga-oscon)。

---

作者简介：

Kushal Das - Kushal Das 是 Python 软件基金会的一名 CPython 核心开发人员和主管。他是一名长期的 FOSS 贡献者和导师，他帮助新人进入贡献世界。他目前在 Red Hat 担任 Fedora 云工程师。他的博客在 <https://kushaldas.in> 。你也可以在 Twitter @kushaldas 上找到他

---

via: <https://opensource.com/article/17/1/expand-project-contributor-base>

作者：[Kushal Das](https://opensource.com/users/kushaldas) 译者：[geekpi](https://github.com/geekpi) 校对：[Bestony](https://github.com/bestony)

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


Linux 极客的 Android：将你的 Android 设备变成 Linux 命令行界面

加个命令行就极客了？话说手机用命令行很不好用，最好买个蓝牙键盘。

还以为要介绍 Termux...

不能替代原来的Launcher，按Home键的时候会返回原来的桌面，达不到防止别人用手机的目的

看来Linux是发展趋势呀

所以可以把它设置成默认launcher，不就可以了吗？

![](/data/attachment/album/201705/22/164759ciyitpt3p9jpi39q.jpg)

不管你是一位命令行大师，还是只是不想让你的朋友和家人使用你的 Android 设备，那就看下 T-UI Launcher 这个程序。Unix/Linux 用户一定会喜欢这个。

T-UI Launcher 是一个免费的轻量级 Android 程序，具有类似 Linux 的命令行界面，它可将你的普通 Android 设备变成一个完整的命令行界面。对于喜欢使用基于文本的界面的人来说，这是一个简单、快速、智能的启动器。

#### T-UI Launcher 功能

下面是一些重要的功能：

* 第一次启动后展示快速使用指南。
* 快速且可完全定制。
* 提供自动补全菜单及快速、强大的别名系统。
* 此外，提供预测建议，并提供有用的搜索功能。

它是免费的，你可以从 Google Play 商店[下载并安装它](https://play.google.com/store/apps/details?id=ohi.andre.consolelauncher)，接着在 Android 设备中运行。

安装完成后，第一次启动时你会看到一个快速指南。阅读完成之后，你可以如下面那样使用简单的命令开始使用了。

![T-UI Commandline Help Guide](/data/attachment/album/201705/22/164806v2y3d1byd1yzz3dz.jpg)

*T-UI 命令行帮助指南*

要启动一个 app，只要输入几个字母，自动补全功能会在屏幕中展示可用的 app。接着点击你想打开的程序。

```
$ Telegram   ### 启动 telegram
$ WhatsApp   ### 启动 whatsapp
$ Chrome     ### 启动 chrome

```

![T-UI Commandline Usage](/data/attachment/album/201705/22/164807nzwzwz5oabw7ju5a.jpg)

*T-UI 命令行使用*

要浏览你的 Android 设备状态（电池电量、wifi、移动数据），输入：

```
$ status

```

![Android Phone Status](/data/attachment/album/201705/22/164807ujonxg2gcd9oh9cz.jpg)

*Android 电话状态*

其它的有用命令。

```
$ uninstall telegram                ### 卸载 telegram
$ search [google, playstore, youtube, files]    ### 搜索在线应用或本地文件
$ wifi                      ### 打开或关闭 WIFI
$ cp Downloads/* Music              ### 从 Download 文件夹复制所有文件到 Music 文件夹
$ mv Downloads/* Music              ### 从 Download 文件夹移动所有文件到 Music 文件夹

```

就是这样了！在本篇中，我们展示了一个带有类似 Linux CLI（命令界面）的简单而有用的 Android 程序，它可以将你的常规 Android 设备变成一个完整的命令行界面。尝试一下并在下面的评论栏分享你的想法。

---

作者简介：

Aaron Kili 是 Linux 和 F.O.S.S 爱好者，将来的 Linux 系统管理员和网络开发人员，目前是 TecMint 的内容创作者，他喜欢用电脑工作，并坚信分享知识。

---

via: <https://www.tecmint.com/t-ui-launcher-turns-android-device-into-linux-cli/>

作者：[Aaron Kili](https://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


8 个优秀的开源 Markdown 编辑器

Typora

还是喜欢Typora

Typora老感觉插入表格有问题，自己手动插第一行经常出问题或者插不进来，直接右键菜单插会多出一行

来自湖北武汉武汉大学的 Mobile Safari 5.0|iOS 4.3 用户

居然没有typora!!!

注意标题中的开源

来自121.195.114.9的 Chrome 57.0|GNU/Linux 用户

Typora并非开源软件

![](/data/attachment/album/201705/22/222538h6mg27etqq6e76ie.jpg)

### Markdown

首先，对 Markdown 进行一个简单的介绍。Markdown 是由 John Gruber 和 Aaron Swartz 共同创建的一种轻量级纯文本格式语法。Markdown 可以让用户“以易读、易写的纯文本格式来进行写作，然后可以将其转换为有效格式的 XHTML（或 HTML）“。Markdown 语法只包含一些非常容易记住的符号。其学习曲线平缓；你可以在炒蘑菇的同时一点点学习 Markdown 语法（大约 10 分钟）。通过使用尽可能简单的语法，错误率达到了最小化。除了拥有友好的语法，它还具有直接输出干净、有效的（X）HTML 文件的强大功能。如果你看过我的 HTML 文件，你就会知道这个功能是多么的重要。

Markdown 格式语法的主要目标是实现最大的可读性。用户能够以纯文本的形式发布一份 Markdown 格式的文件。用 Markdown 进行文本写作的一个优点是易于在计算机、智能手机和个人之间共享。几乎所有的内容管理系统都支持 Markdown 。它作为一种网络写作格式流行起来，其产生一些被许多服务采用的变种，比如 GitHub 和 Stack Exchange 。

你可以使用任何文本编辑器来写 Markdown 文件。但我建议使用一个专门为这种语法设计的编辑器。这篇文章中所讨论的软件允许你使用 Markdown 语法来写各种格式的专业文档，包括博客文章、演示文稿、报告、电子邮件以及幻灯片等。另外，所有的应用都是在开源许可证下发布的，在 Linux、OS X 和 Windows 操作系统下均可用。

### Remarkable

![](/data/attachment/album/201705/22/223204c70674n8wuz60sq7.jpg)

让我们从 Remarkable 开始。Remarkable 是一个 apt 软件包的名字，它是一个相当有特色的 Markdown 编辑器 — 它并不支持 Markdown 的全部功能特性，但该有的功能特性都有。它使用和 GitHub Markdown 类似的语法。

你可以使用 Remarkable 来写 Markdown 文档，并在实时预览窗口查看更改。你可以把你的文件导出为 PDF 格式（带有目录）和 HTML 格式文件。它有强大的配置选项，从而具有许多样式，因此，你可以把它配置成你最满意的 Markdown 编辑器。

其他一些特性：

* 语法高亮
* 支持 [GitHub 风味的 Markdown](/article-8399-1.html)
* 支持 MathJax - 通过高级格式呈现丰富文档
* 键盘快捷键

在 Debian、Ubuntu、Fedora、SUSE 和 Arch 系统上均有 Remarkable 的可用的简易安装程序。

主页： <https://remarkableapp.github.io/> 许可证： MIT 许可

### Atom

![](/data/attachment/album/201705/22/223330sq0j0fnjnmsq0znm.jpg)

毫无疑问， Atom 是一个神话般的文本编辑器。超过 50 个开源包集合在一个微小的内核上，从而构成 Atom 。伴有 Node.js 的支持，以及全套功能特性，Atom 是我最喜欢用来写代码的编辑器。Atom 的特性在[杀手级开源应用](https://www.ossblog.org/top-software/2/)的文章中有更详细介绍，它是如此的强大。但是作为一个 Markdown 编辑器，Atom 还有许多不足之处，它的默认包不支持 Markdown 的特性。例如，正如上图所展示的，它不支持等价渲染。

但是，开源拥有强大的力量，这是我强烈提倡开源的一个重要原因。Atom 上有许多包以及一些复刻，从而添加了缺失的功能特性。比如，Markdown Preview Plus 提供了 Markdown 文件的实时预览，并伴有数学公式渲染和实时重加载。另外，你也可以尝试一下 [Markdown Preview Enhanced](https://atom.io/packages/markdown-preview-enhanced)。如果你需要自动滚动特性，那么 [markdown-scroll-sync](https://atom.io/packages/markdown-scroll-sync) 可以满足你的需求。我是 [Markdown-Writer](https://atom.io/packages/markdown-writer)和 [Markdown-pdf](https://atom.io/packages/markdown-pdf)的忠实拥趸，后者支持将 Markdown 快速转换为 PDF、PNG 以及 JPEG 文件。

这个方式体现了开源的理念：允许用户通过添加扩展来提供所需的特性。这让我想起了 Woolworths 的 n 种杂拌糖果的故事。虽然需要多付出一些努力，但能收获最好的回报。

主页： <https://atom.io/> 许可证： MIT 许可

### Haroopad

![](/data/attachment/album/201705/22/223417vcjiczjrpy355p53.jpg)

Haroopad 是一个优秀的 Markdown 编辑器，是一个用于创建适宜 Web 的文档的处理器。使用 Haroopad 可以创作各种格式的文档，比如博客文章、幻灯片、演示文稿、报告和电子邮件等。Haroopad 在 Windows、Mac OS X 和 Linux 上均可用。它有 Debian/Ubuntu 的软件包，也有 Windows 和 Mac 的二进制文件。该应用程序使用 node-webkit、CodeMirror，marked，以及 Twitter 的 Bootstrap 。

Haroo 在韩语中的意思是“一天”。

它的功能列表非常可观。请看下面：

* 主题、皮肤和 UI 组件
	+ 超过 30 种不同的编辑主题 - tomorrow-night-bright 和 zenburn 是近期刚添加的
	+ 编辑器中的代码块的语法高亮
	+ Ruby、Python、PHP、Javascript、C、HTML 和 CSS 的语法高亮支持
	+ 基于 CodeMirror，这是一个在浏览器中使用 JavaScript 实现的通用文本编辑器
* 实时预览主题
	+ 基于 markdown-css 的 7 个主题
* 语法高亮
	+ 基于 hightlight.js 的 112 种语言以及 49 种样式
* 定制主题
	+ 基于 CSS （层叠样式表）的样式
* 演示模式 - 对于现场演示非常有用
* 绘图 - 流程图和序列图
* 任务列表
* 扩展 Markdown 语法，支持 TOC（目录）、 GitHub 风味 Markdown 以及数学表达式、脚注和任务列表等
* 字体大小
	+ 使用首选窗口和快捷键来设置编辑器和预览字体大小
* 嵌入富媒体内容
	+ 视频、音频、3D、文本、开放图形以及 oEmbed
	+ 支持大约 100 种主要的网络服务（YouTude、SoundCloud、Flickr 等）
	+ 支持拖放
* 显示模式
	+ 默认：编辑器｜预览器，倒置：预览器｜编辑器，仅编辑器，仅预览器（View -> Mode）
* 插入当前日期和时间
	+ 多种格式支持（Insert -> Data & Time）
* HtML 到 Markdown
	+ 拖放你在 Web 浏览器中选择好的文本
* Markdown 解析选项
* 大纲预览
* 纯粹主义者的 Vim 键位绑定
* Markdown 自动补全
* 导出为 PDF 和 HTML
* 带有样式的 HTML 复制到剪切板可用于所见即所得编辑器
* 自动保存和恢复
* 文件状态信息
* 换行符或空格缩进
* （一、二、三）列布局视图
* Markdown 语法帮助对话框
* 导入和导出设置
* 通过 MathJax 支持 LaTex 数学表达式
* 导出文件为 HTML 和 PDF
* 创建扩展来构建自己的功能
* 高效地将文件转换进博客系统：WordPress、Evernote 和 Tumblr 等
* 全屏模式－尽管该模式不能隐藏顶部菜单栏和顶部工具栏
* 国际化支持：英文、韩文、西班牙文、简体中文、德文、越南文、俄文、希腊文、葡萄牙文、日文、意大利文、印度尼西亚文土耳其文和法文

主页 <http://pad.haroopress.com/> 许可证： GNU GPL v3 许可

### StackEdit

![](/data/attachment/album/201705/22/223447jt1i4azik0w4eb8i.jpg)

StackEdit 是一个功能齐全的 Markdown 编辑器，基于 PageDown（该 Markdown 库被 Stack Overflow 和其他一些 Stack 交流网站使用）。不同于在这个列表中的其他编辑器，StackEdit 是一个基于 Web 的编辑器。在 Chrome 浏览器上即可使用 StackEdit 。

特性包括：

* 实时预览 HTML，并通过绑定滚动连接特性来将编辑器和预览的滚动条相绑定
* 支持 Markdown Extra 和 GitHub 风味 Markdown，Prettify/Highlight.js 语法高亮
* 通过 MathJax 支持 LaTex 数学表达式
* 所见即所得的控制按键
* 布局配置
* 不同风格的主题支持
* la carte 扩展
* 离线编辑
* 可以与 Google 云端硬盘（多帐户）和 Dropbox 在线同步
* 一键发布到 Blogger、Dropbox、Gist、GitHub、Google Drive、SSH 服务器、Tumblr 和 WordPress

主页： <https://stackedit.io/> 许可证： Apache 许可

### MacDown

![](/data/attachment/album/201705/22/223545ezbh49m0b9kzbi98.jpg)

MacDown 是在这个列表中唯一一个只运行在 macOS 上的全特性编辑器。具体来说，它需要在 OX S 10.8 或更高的版本上才能使用。它在内部使用 Hoedown 将 Markdown 渲染成 HTML，这使得它的特性更加强大。Heodown 是 Sundown 的一个复活复刻。它完全符合标准，无依赖，具有良好的扩展支持和 UTF-8 感知。

MacDown 基于 Mou，这是专为 Web 开发人员设计的专用解决方案。

它提供了良好的 Markdown 渲染，通过 Prism 提供的语言识别渲染实现代码块级的语法高亮，MathML 和 LaTex 渲染，GTM 任务列表，Jekyll 前端以及可选的高级自动补全。更重要的是，它占用资源很少。想在 OS X 上写 Markdown？MacDown 是我针对 Web 开发者的开源推荐。

主页： <https://macdown.uranusjr.com/> 许可证： MIT 许可

### ghostwriter

![](/data/attachment/album/201705/22/223608iunnnou2w8bbuo1c.jpg)

ghostwriter 是一个跨平台的、具有美感的、无干扰的 Markdown 编辑器。它内建了 Sundown 处理器支持，还可以自动检测 pandoc、MultiMarkdown、Discount 和 cmark 处理器。它试图成为一个朴实的编辑器。

ghostwriter 有许多很好的功能设置，包括语法高亮、全屏模式、聚焦模式、主题、通过 Hunspell 进行拼写检查、实时字数统计、实时 HTML 预览、HTML 预览自定义 CSS 样式表、图片拖放支持以及国际化支持。Hemingway 模式按钮可以禁用退格键和删除键。一个新的 “Markdown cheat sheet” HUD 窗口是一个有用的新增功能。主题支持很基本，但在 [GitHub 仓库上](https://github.com/jggouvea/ghostwriter-themes)也有一些可用的试验性主题。

ghostwriter 的功能有限。我越来越欣赏这个应用的通用性，部分原因是其简洁的界面能够让写作者完全集中在策划内容上。这一应用非常值得推荐。

ghostwirter 在 Linux 和 Windows 系统上均可用。在 Windows 系统上还有一个便携式的版本可用。

主页： <https://github.com/wereturtle/ghostwriter> 许可证： GNU GPL v3 许可

### Abricotine

![](/data/attachment/album/201705/22/223649g022sn2xaqffsdp6.jpg)

Abricotine 是一个为桌面构建的、旨在跨平台且开源的 Markdown 编辑器。它在 Linux、OS X 和 Windows 上均可用。

该应用支持 Markdown 语法以及一些 GitHub 风味的 Markdown 增强（比如表格）。它允许用户直接在文本编辑器中预览文档，而不是在侧窗栏。

该应用有一系列有用的特性，包括拼写检查、以 HTML 格式保存文件或把富文本复制粘贴到邮件客户端。你也可以在侧窗中显示文档目录，展示语法高亮代码、以及助手、锚点和隐藏字符等。它目前正处于早期的开发阶段，因此还有一些很基本的 bug 需要修复，但它值得关注。它有两个主题可用，如果有能力，你也可以添加你自己的主题。

主页： <http://abricotine.brrd.fr/> 许可证： GNU 通用公共许可证 v3 或更高许可

### ReText

![](/data/attachment/album/201705/22/223720gwxwnw99xmppkkxp.jpg)

ReText 是一个简单而强大的 Markdown 和 reStructureText 文本编辑器。用户可以控制所有输出的格式。它编辑的文件是纯文本文件，但可以导出为 PDF、HTML 和其他格式的文件。ReText 官方仅支持 Linux 系统。

特性包括：

* 全屏模式
* 实时预览
* 同步滚动（针对 Markdown）
* 支持数学公式
* 拼写检查
* 分页符
* 导出为 HTML、ODT 和 PDF 格式
* 使用其他标记语言

主页： <https://github.com/retext-project/retext> 许可证： GNU GPL v2 或更高许可

---

via: <https://www.ossblog.org/markdown-editors/>

作者：[Steve Emms](https://www.ossblog.org/author/steve/) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


人工智能正快速入侵我们生活的五个方面

Summary: 开源项目正在助推人工智能（AI）进步，而且随着技术的成熟，我们将听到更多关于 AI 如何影响我们生活的消息。你有没有考虑过 AI 是如何改变你周围的世界的？让我们来看看我们日益被我们所改变的世界，以及大胆预测一下 AI 对未来影响。

别什么都往 AI 上靠好不好

>
> 让我们来看看我们已经被人工智能包围的五个真实存在的方面。
>
>
>

![5 big ways AI is rapidly invading our lives](/data/attachment/album/201705/23/033703tnmglbu6l8dm9bl8.png "5 big ways AI is rapidly invading our lives")

开源项目[正在助推](https://www.linux.com/news/open-source-projects-are-transforming-machine-learning-and-ai)人工智能（AI）进步，而且随着技术的成熟，我们将听到更多关于 AI 如何影响我们生活的消息。你有没有考虑过 AI 是如何改变你周围的世界的？让我们来看看我们日益被我们所改变的世界，以及大胆预测一下 AI 对未来影响。

### 1. AI 影响你的购买决定

最近 [VentureBeat](https://twitter.com/venturebeat) 上的一篇文章，[“AI 将如何帮助我们解读千禧一代”](http://venturebeat.com/2017/03/16/how-ai-will-help-us-decipher-millennials/)吸引了我的注意。我承认我对人工智能没有思考太多，也没有费力尝试解读千禧一代，所以我很好奇，希望了解更多。事实证明，文章标题有点误导人，“如何卖东西给千禧一代”或许会是一个更准确的标题。

根据这篇文章，千禧一代是“一个令人垂涎的年龄阶段的人群，全世界的市场经理都在争抢他们”。通过分析网络行为 —— 无论是购物、社交媒体或其他活动 - 机器学习可以帮助预测行为模式，这将可以变成有针对性的广告。文章接着解释如何对物联网和社交媒体平台进行挖掘形成数据点。“使用机器学习挖掘社交媒体数据，可以让公司了解千禧一代如何谈论其产品，他们对一个产品类别的看法，他们对竞争对手的广告活动如何响应，还可获得很多数据，用于设计有针对性的广告，"这篇文章解释说。AI 和千禧一代成为营销的未来并不是什么很令人吃惊的事，但是 X 一代和婴儿潮一代，你们也逃不掉呢！（LCTT 译注：X 一代指出生于 20 世纪 60 年代中期至 70 年代末的美国人，婴儿潮是指二战结束后，1946 年初至 1964 年底出生的人）

>
> 人工智能根据行为变化，将包括城市人在内的整个人群设为目标群体。
>
>
>

例如， [Raconteur 上](https://twitter.com/raconteur)的一篇文章 —— “AI 将怎样改变购买者的行为”中解释说，AI 在网上零售行业最大的力量是它能够迅速适应客户行为不断变化的形势。人工智能创业公司 [Fluid AI](http://www.fluid.ai/) 首席执行官 Abhinav Aggarwal 表示，他公司的软件被一个客户用来预测顾客行为，有一次系统注意到在暴风雪期间发生了一个变化。“那些通常会忽略在一天中发送的电子邮件或应用内通知的用户现在正在打开它们，因为他们在家里没有太多的事情可做。一个小时之内，AI 系统就适应了新的情况，并在工作时间开始发送更多的促销材料。”他解释说。

AI 正在改变我们怎样花钱和为什么花钱，但是 AI 是怎样改变我们挣钱的方式的呢？

### 2. 人工智能正在改变我们如何工作

[Fast 公司](https://opensource.com/article/17/3/5-big-ways-ai-rapidly-invading-our-lives)最近的一篇文章“2017 年人工智能将如何改变我们的生活”中说道，求职者将会从人工智能中受益。作者解释说，除更新薪酬趋势之外，人工智能将被用来给求职者发送相关职位空缺信息。当你应该升职的时候，你很可能会得到一个升职的机会。

人工智能也可以被公司用来帮助新入职的员工。文章解释说：“许多新员工在刚入职的几天内会获得大量信息，其中大部分都留不下来。” 相反，机器人可能会随着时间的推移，当新员工需要相关信息时，再向他一点点“告知信息”。

[Inc.](https://twitter.com/Inc) 有一篇文章[“没有偏见的企业：人工智能将如何重塑招聘机制”](http://www.inc.com/bill-carmody/businesses-beyond-bias-how-ai-will-reshape-hiring-practices.html)，观察了人才管理解决方案提供商 [SAP SuccessFactors](https://www.successfactors.com/en_us.html) 是怎样利用人工智能作为一个工作描述“偏见检查器”，以及检查员工赔偿金的偏见。

[《Deloitte 2017 人力资本趋势报告》](https://dupress.deloitte.com/dup-us-en/focus/human-capital-trends.html?id=us:2el:3pr:dup3575:awa:cons:022817:hct17)显示，AI 正在激励组织进行重组。Fast 公司的文章[“AI 是怎样改变公司组织的方式”](https://www.fastcompany.com/3068492/how-ai-is-changing-the-way-companies-are-organized)审查了这篇报告，该报告是基于全球 10,000 多名人力资源和商业领袖的调查结果。这篇文章解释说："许多公司现在更注重文化和环境的适应性，而不是聘请最有资格的人来做某个具体任务，因为知道个人角色必须随 AI 的实施而发展。" 为了适应不断变化的技术，组织也从自上而下的结构转向多学科团队，文章说。

### 3. AI 正在改变教育

>
> AI 将使所有教育生态系统的利益相关者受益。
>
>
>

尽管教育预算正在缩减，但是教室的规模却正在增长。因此利用技术的进步有助于提高教育体系的生产率和效率，并在提高教育质量和负担能力方面发挥作用。根据 VentureBeat 上的一篇文章[“2017 年人工智能将怎样改变教育”](http://venturebeat.com/2017/02/04/how-ai-will-transform-education-in-2017/)，今年我们将看到 AI 对学生们的书面答案进行评分，机器人回答学生的问题，虚拟个人助理辅导学生等等。文章解释说：“AI 将惠及教育生态系统的所有利益相关者。学生将能够通过即时的反馈和指导学习地更好，教师将获得丰富的学习分析和对个性化教学的见解，父母将以更低的成本看到他们的孩子的更好的职业前景，学校能够规模化优质的教育，政府能够向所有人提供可负担得起的教育。"

### 4. 人工智能正在重塑医疗保健

2017 年 2 月 [CB Insights](https://twitter.com/CBinsights) 的一篇文章挑选了 106 个医疗保健领域的人工智能初创公司，它们中的很多在过去几年中提高了第一次股权融资。这篇文章说：“在 24 家成像和诊断公司中，19 家公司自 2015 年 1 月起就首次公开募股。”这份名单上有那些从事于远程病人监测，药物发现和肿瘤学方面人工智能的公司。”

3 月 16 日发表在 TechCrunch 上的一篇关于 AI 进步如何重塑医疗保健的文章解释说：“一旦对人类的 DNA 有了更好的理解，就有机会更进一步，并能根据他们特殊的生活习性为他们提供个性化的见解。这种趋势预示着‘个性化遗传学’的新纪元，人们能够通过获得关于自己身体的前所未有的信息来充分控制自己的健康。”

本文接着解释说，AI 和机器学习降低了研发新药的成本和时间。部分得益于广泛的测试，新药进入市场需要 12 年以上的时间。这篇文章说：“机器学习算法可以让计算机根据先前处理的数据来‘学习’如何做出预测，或者选择（在某些情况下，甚至是产品）需要做什么实验。类似的算法还可用于预测特定化合物对人体的副作用，这样可以加快审批速度。”这篇文章指出，2015 年旧金山的一个创业公司 [Atomwise](http://www.atomwise.com/) 一天内完成了可以减少埃博拉感染的两种新药物的分析，而不是花费数年时间。

>
> AI 正在帮助发现、诊断和治疗新疾病。
>
>
>

另外一个位于伦敦的初创公司 [BenevolentAI](https://twitter.com/benevolent_ai) 正在利用人工智能寻找科学文献中的模式。这篇文章说：“最近，这家公司找到了两种可能对 Alzheimer 起作用的化合物，引起了很多制药公司的关注。"

除了有助于研发新药，AI 正在帮助发现、诊断和治疗新疾病。TechCrunch 上的文章解释说，过去是根据显示的症状诊断疾病，但是现在 AI 正在被用于检测血液中的疾病特征，并利用对数十亿例临床病例分析进行深度学习获得经验来制定治疗计划。这篇文章说：“IBM 的 Watson 正在与纽约的 Memorial Sloan Kettering 合作，消化理解数十年来关于癌症患者和治疗方面的数据，为了向治疗疑难的癌症病例的医生提供和建议治疗方案。”

### 5. AI 正在改变我们的爱情生活

有 195 个国家的超过 5000 万活跃用户通过一个在 2012 年推出的约会应用程序 [Tinder](https://twitter.com/Tinder) 找到潜在的伴侣。在一个 [Forbes 采访播客](https://www.forbes.com/podcasts/the-forbes-interview/#5e962e5624e1)中，Tinder 的创始人兼董事长 Sean Rad spoke 与 Steven Bertoni 对人工智能是如何正在改变人们约会进行过讨论。在[关于此次采访的文章](https://www.forbes.com/sites/stevenbertoni/2017/02/14/tinders-sean-rad-on-how-technology-and-artificial-intelligence-will-change-dating/#4180fc2e5b99)中，Bertoni 引用了 Rad 说的话，他说：“可能有这样一个时刻，Tinder 可以很好的推测你会感兴趣的人，在组织约会中还可能会做很多跑腿的工作”，所以，这个 app 会向用户推荐一些附近的同伴，并更进一步，协调彼此的时间安排一次约会，而不只是向用户显示一些有可能的同伴。

>
> 我们的后代真的可能会爱上人工智能。
>
>
>

你爱上了 AI 吗？我们的后代真的可能会爱上人工智能。Raya Bidshahri 发表在 [Singularity Hub](https://twitter.com/singularityhub) 的一篇文章“AI 将如何重新定义爱情”说，几十年的后，我们可能会认为爱情不再受生物学的限制。

Bidshahri 解释说：“我们的技术符合摩尔定律，正在以惊人的速度增长 —— 智能设备正在越来越多地融入我们的生活。”，他补充道：“到 2029 年，我们将会有和人类同等智慧的 AI，而到 21 世纪 40 年代，AI 将会比人类聪明无数倍。许多人预测，有一天我们会与强大的机器合并，我们自己可能会变成人工智能。”他认为在这样一个世界上那些是不可避免的，人们将会接受与完全的非生物相爱。

这听起来有点怪异，但是相比较于未来机器人将统治世界，爱上 AI 会是一个更乐观的结果。Bidshahri 说：“对 AI 进行编程，让他们能够感受到爱，这将使我们创造出更富有同情心的 AI，这可能也是避免很多人忧虑的 AI 大灾难的关键。”

这份 AI 正在入侵我们生活各领域的清单只是涉及到了我们身边的人工智能的表面。哪些 AI 创新是让你最兴奋的，或者是让你最烦恼的？大家可以在文章评论区写下你们的感受。

---

Rikki Endsley - Rikki Endsley 是开源社区 Opensource.com 的管理员。在过去，她曾做过 Red Hat 开源和标准（OSAS）团队社区传播者；自由技术记者；USENIX 协会的社区管理员；linux 权威杂志 ADMIN 和 Ubuntu User 的合作出版者，还是杂志 Sys Admin 和 UnixReview.com 的主编。在 Twitter 上关注她：@rikkiends。

（图片来源: opensource.com）

---

via: <https://opensource.com/article/17/3/5-big-ways-ai-rapidly-invading-our-lives>

作者：[Rikki Endsley](https://opensource.com/users/rikki-endsley)  译者：[zhousiyu325](https://github.com/zhousiyu325) 校对：[jasminepeng](https://github.com/jasminepeng)

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


从蓝瘦“想哭”到 SELinux 看操作系统安全何在

SELinux 不是所有知名 Linux 发行版都安装的，比如 Ubuntu 就没有。SELinux 也出现过强制访问限制被绕过的漏洞。SELinux 太复杂，一般来说用户敢改动的地方不多。

但 ubuntu 有 AppArmor

看起来很牛

哎，看到ls -Z我就晕汤！

一切需要关闭SELinux才能使用的软件都是流氓软件！！！

审计和SELinux是独立的

但审计日志也受SELinux策略保护

大家都那么专业，我从人类使用角度来说点自己的看法：对于非专业型的小白用户，其实也应该知道点使用电脑方面的常识，而非是说真的像做一个傻瓜式使用者 满足自己使用就可以了，电脑是自己的，让电脑更好的为自己服务，不仅仅是了解如何操作电脑 更要知道电脑内部的概要远离，很多生活中我遇到的都是把电脑当成智能一样存在了，让用户了解电脑，这点linux 和unix 就比window做的好。防火墙 无论是图形还是命令 都能使用户更清楚自己的电脑都有那些东西存在 都在干些什么。

“想哭”这一程序首发有大陆，官方提供汉化。这么良心的产品你们竟然只想着破解？！

![](/data/attachment/album/201705/23/155344ez0pteesx20c02gb.jpg)

最近一周，来自网络的<ruby> “想哭”勒索病毒 <rp>  （ </rp> <rt>  Wannacry Ransomware </rt> <rp>  ） </rp></ruby>在世界各地同时上演了一部绑匪大片，台词华丽，演技出色，当仁不让地新晋世界第一网红。全球各国除了默默忙于两弹一星足不出户的朝鲜外，无不为之动容。一时间，包括“想哭”病毒在内的各种病毒的各种传闻也火爆网络，我们并不准备跟风刷屏，只是打算本着实事求是的精神，科学的探讨一下如何与它们和睦相处、谈笑风生。

### “想哭”病毒的前世今生

首先，让我们先简要回顾一下主角“想哭”病毒的前世今生。

“想哭”病毒是基于网络攻击框架二次开发的结果，它利用了 NSA（美国国家安全局）的前辈们留下的非物质文化遗产：<ruby> 永恒之蓝 <rp>  （ </rp> <rt>  ETERNAL BLUE </rt> <rp>  ） </rp></ruby> 模块，针对 Windows SMB 服务的实现漏洞植入恶意代码，再结合自己的创新：加密用户文件和显示勒索声明，一代网红勒索病毒由此诞生。从病毒本身的设计流程来看，似乎并不需要高深的编码技巧或深厚的理论根基，然而这也恰恰是这一事件中最值得我们警惕的地方：NSA 泄漏的攻击模块远不止永恒之蓝一种，借助已有攻击框架进行二次开发的难度又如此之低，所以，可以预期，一大波未知的病毒正在来袭的路上。

是不是细思极恐？所谓“知彼知己，百战不<ruby> 殆 <rp>  （ </rp> <rt>  die </rt> <rp>  ） </rp></ruby>”，要想不 die，先要充分了解对手，所以接下来我们进一步了解一下什么是病毒？病毒是如何以危险方式危害公共安全的？又是怎样进入我们的系统的？

病毒是什么，其实是老生常谈了，经常关注医疗卫生领域的朋友都知道：

>
> 病毒由一段基因与蛋白质构成，自身不能实现新陈代谢，通过适当的途径侵入宿主体内，通过宿主细胞的代谢系统实现复制传播。
>
>
>

跑题了？好吧，不要在意这些细节，我们改几个字就能用了：

>
> 病毒由一段可执行代码与数据构成，自身不能在裸机上运行，通过适当的途径侵入宿主操作系统，通过宿主系统中的存储和网络实现复制传播。
>
>
>

Wirth 教授教导我们：

>
> 算法+数据结构=程序，
>
>
> 病毒=代码+数据=算法+数据结构=程序
>
>
>

没错，病毒就是一类特殊的计算机程序，广义上称为恶意软件。与自然界病毒的最大不同之处在于，它们不是纯天然的，而是 100% 人工打造。通常它们怀着对人类的深深的恶意来到世上，行为各不相同，有的在你的屏幕上画个圈圈诅咒你，有的会窃取你设备中的隐私照片，还有的会眨眼间转走你银行卡上的购房首付款......显然，它们的目标还是很一致的：危害人类设备，破坏世界和平。

又扯远了，我们接着来看病毒是如何入侵操作系统的。病毒的入侵无外乎两个途径：主动和被动。所谓主动是针对目标系统尝试发起扫描和攻击，一般是远程发起，当发现了自己能吃定的漏洞之后，就通过各种阴险手段（其实技术实现上大多还是很优雅的）攫取系统权限，进而将恶意代码注入宿主系统中伺机作恶，对此没什么概念的小伙伴可以自行脑补一下《异形》中的人类被寄生的过程。

病毒入侵的另一种方式，我们称之为被动方式。这种方式并不需要系统存在漏洞或缺陷，需要的是用户的经验、常识或智商存在缺陷。它们通过各种伪装诱骗用户去打开或运行自己，包括形形色色让你心动的邮件、链接、不明来源的安装程序等等，一旦获得机会运行，它们会悄无声息的在你的系统中安营扎寨、留下多道后门，然后为所欲为，这类病毒又被形象地称为（特洛伊）木马。

### 如何应对各种病毒威胁

了解了病毒的来龙去脉之后，我们就可以开始讨论如何应对各种病毒层出不穷的威胁了。

对于大多数用户，良好的使用习惯是第一位的。堡垒往往从内部被攻克，再安全的操作系统，再强大的安全机制，都难以阻止用户自我毁灭的脚步。良好的使用习惯中最重要的，是安全更新，安全更新，安全更新！为什么呢？这要先谈一下操作系统漏洞的由来。

漏洞实际是软件缺陷的一种，也就是俗称的 bug，是由于软件开发人员的疏忽而导致程序没有按照预期的方式运行。软件缺陷多种多样，有些很呆，有些很萌，也并不都会对系统安全构成威胁。那些侥幸逃脱开发和测试人员的轮番围剿，随着软件的发布散落人间的软件缺陷，一旦被黑客们发现、策反，并借助自己在系统内部的有利位置，披着合法软件的外衣，做出送人头、坑队友的恶劣行径时，就成为软件系统的公敌：漏洞。越是庞大和复杂的软件越容易产生漏洞，不幸的是操作系统就是一类极其庞大而复杂的软件系统。

虽然操作系统漏洞常常难以完全避免，然而某个漏洞一旦被发现，开发厂商都会在第一时间发布安全更新对问题进行修复。以这次勒索病毒为例，针对被利用的 SMB 服务漏洞，事实上早在一个月前微软就公布了漏洞警告和补丁，提供了安全更新，那些开启自动更新并及时修复了漏洞的用户，他们可以用省下的三个比特币吃着火锅唱着歌，完全不用担心绑匪。所以请划重点：**操作系统安全更新非常重要，不论个人用户、企业用户还是系统管理员，不论服务器，桌面还是移动终端，不论 Windows，Linux 还是 MacOS，都应该尽可能及时地从操作系统厂商处获取安全更新。**

其次，杀毒软件也可以起到一定的安全增强的作用，多数杀毒软件可以借助病毒库对已有病毒的特征进行分析比对，一旦发现用户即将运行的程序中含有病毒或恶意程序，会及时提醒用户，或者自动清除。因此，杀毒软件可以在很大程度上防御已知的、以被动方式入侵系统的病毒。

那么，积极地安全更新、安装杀毒软件就可以解决所有病毒威胁了么？

很不幸，事实并非如此。安全更新和杀毒软件之于病毒威胁正如强身健体之于疾病隐患，可以大幅降低几率，却难以完全避免。为什么？这要从<ruby> 零日 <rp>  （ </rp> <rt>  0-day </rt> <rp>  ） </rp></ruby>漏洞说起。

零日漏洞，听起来就很霸气的一个名字，仿佛给人一种世界末日的感觉。它并不是指具体的某个或某类漏洞，而是指被黑客发现后立刻用来发起攻击的漏洞，这些漏洞尚未公开，用户不知道，软件厂商也不了解，**应对时间为零**。所以，这类漏洞没有检测工具，没有修复方法，传统被动升级防御、病毒特征比对的方式毫无用处，一旦被用来发起攻击，普通系统是毫无招架能力的。那么有没有可以防御零日漏洞的安全的操作系统呢？

### 安全的操作系统与 SELinux

一提到安全的操作系统，总会涌现出很多真知灼见，最脍炙人口的莫过于：

>
> “所有操作系统都有漏洞，所以没有绝对安全的操作系统；所以 Windows 也好，Linux 也好，MacOS 也好，都一样不安全。”
>
>
>

说的好有道理，我竟无言以对，因为前半句就是对本文前半部分的总结，理论正确，逻辑自洽，没什么可黑的。后半句的逻辑却似乎有点烧脑，如果它成立的话，我们不妨试着推广一下，比如：

>
> “任何物质都是有毒性的，没有什么是绝对无毒的。砒霜吃了会中毒，水喝多了也会中毒，所以砒霜和水一样不安全。”
>
>
>

**毒理学有句名言：一切谈毒性不谈剂量的行为都是耍流氓。同样，任何谈操作系统安全不谈体系架构的行为也是耍流氓。**所以面对这种耍流氓的行为，接下来我们要严肃的谈一谈操作系统的安全体系架构。

多年前，永恒之蓝的始作蛹者 NSA 为了防御自家系统，开发了一套安全框架，多年后这套框架被贡献给了 Linux 内核，这就是 SELinux。作为造成这次世界性灾难的幕后大 boss，NSA 为自己定制的 SELinux 又是怎样的一套防具呢？

SELinux 全称 Security Enhanced Linux ，是针对 Linux 的全面安全增强，相比一般的发现漏洞-修复漏洞这种被动挨打的模式，SELinux 具备主动防御能力，可以抵御包括零日漏洞在内的多种攻击。

那么 SELinux 是如何做到的呢？

访问控制是操作系统安全体系中的最核心最关键的机制，它决定了系统中什么样的资源可以被哪些用户以什么样的方式来访问，也就是说普通用户能做什么，入侵者能做什么，应用软件能做什么，恶意软件能做什么，都是访问控制系统决定的。SELinux 的核心访问机制是<ruby> 强制访问控制 <rp>  （ </rp> <rt>  Mandatory Access Control </rt> <rp>  ） </rp></ruby>，简称 MAC，SELinux 的安全特性是建立在 MAC 基础之上的。那么 MAC 何德何能，堪负如此重任？

说到 MAC 强制访问控制就不得不说它的前辈<ruby> 自主访问控制 <rp>  （ </rp> <rt>  Discretionary Access Control </rt> <rp>  ） </rp></ruby>，简称 DAC。传统的操作系统，Windows、MacOS、以及包括早期 Linux 在内的各种Unix的系统权限管理都是采用的自主访问控制，自主访问控制将用户（或用户组）简化为一个标识，系统中的资源（比如文件）都会带上用户标识和对应的访问权限信息，通过这种方式赋予不同用户不同的访问权限，操作系统通过对用户标识的比对和权限信息决定一个用户是否能访问某个资源。打个比方，你认为你家里的东西是只属于你的，在 DAC 看来，只要能进屋的人都对这个屋子里的东西拥有权限，那么你自己开门进屋睡觉也好，小偷撬门进去拿走金银细软也好，都是合法的。

在操作系统中也是如此，几乎所有操作系统中都有一个身影，叫管理员，Administrator 也好，root 也好，都是一群在系统中权力无限大，对任何资源都有完全访问权限的家伙。多数系统服务是以管理员权限运行的，如果它们存在漏洞，被劫持去做一些它们本不该做的事情的时候，DAC 是不会阻拦的，因为它无法区分某个动作是程序正常行为还是恶意行为。在它眼里，身份就是权力的象征，只要认可了你的管理员身份，你说什么都是对的，你做什么都是合法的。

那么 MAC 机制又是怎样的呢？与 DAC 中的混沌不同，MAC 是一个充满秩序的世界，一个一举一动要提出申请的世界。在 MAC 中，一切访问计划都要事先写入安全策略，没有明确的策略允许的任何访问都会被禁止。在上个例子中，作为家中的主人，你需要能够在家睡觉，也是需要明确制定计划的，你需要添加的安全策略看起来是这样的：

* 定义资源类型： 床
* 定义安全域： 休息
* 定义角色： 主人
* 访问规则： 允许 主人 休息时 使用床

如果系统对于你家中的资源访问只添加了这一条安全策略，那么你仍然可以安心的在家睡觉，小偷无论用何种方式进入你家都将寸步难行，接触任何东西的行为都会被禁止，并且一切被禁止的行为尝试都将被另一套完善的监控系统：审计日志记录在案。

明白了这个例子，回到操作系统中我们就很容易看懂 MAC 是如何防范系统带来的安全威胁的：假设我们有一个存在缓冲区溢出漏洞的文件共享服务，与多数系统服务一样使用管理员权限运行。攻击者通过精心构建一个特殊的数据包发送给服务器，使存在漏洞服务器正常的执行流程被劫持，转而执行修改管理员密码的操作。在 DAC 控制下的传统操作系统中，一旦攻击生效，那么管理员密码会被这个平时八竿子打不着的文件服务器修改，攻击者随后可以很容易的登录进入系统。而在 MAC 系统中，文件服务器的可访问的文件是严格受限的，安全策略类似于：

* 允许 系统管理员角色 运行文件服务器 该进程允许访问被共享文件。

安全策略的定义了该服务可以访问的所有资源，攻击者在攻击了文件服务器后，希望修改管理员密码，它需要访问的是 SAM 或 passwd 等的密码管理文件，由于文件服务器进程仅被策略仅允许访问需要被共享的文件，因此对密码管理文件的操作将被拒绝，攻击失效。这种情况下最坏的情形是，攻击者可能非法访问共享文件，因为它仍在安全策略允许范围内。尽管如此，一个系统级的安全漏洞对整个操作系统的影响被限制在了非常小的范围内。

通过细粒度的划分访问权限，将所有应用和服务的访问限制在最小范围内，这就是强制访问控制保护系统不受已知及未知漏洞攻击的原理。

其实 MAC 和 DAC 并不是水火不容的，在包括 SELinux 在内的多数安全框架中，它们是共同生效的，所有的资源（或者准确的说叫客体）访问请求首先要经过 DAC 权限判定，验证通过之后再进一步进行 MAC 的安全策略判定，只有同时符合自主访问控制和强制访问控制规则后才能获得访问权限。

SELinux 中，有三大类 MAC 策略模型，分别是 TE（类型增强），RBAC（角色访问控制）以及 MLS（多级别安全)，每一类模型都针对系统已有服务和应用提供了大量安全策略。一个使用了 SELinux 的典型的服务器操作系统环境，内核中会包含 10 万条以上的安全策略。

### 计算机信息系统的安全等级

了解了 SELinux 及其强制访问框架后，看到攻防两端都造诣深厚的 NSA，你可能会惊叹于矛尖盾厚的美国在信息安全领域的强大的实力。然而我国在这个陆上有东风，海上有航母，天空有北斗的时代，在信息安全这样重要的领域当然不会碌碌无为。我国很早就对信息安全领域展开了全面的研究，公安部对信息安全的各个领域提出了一些列标准，最早在 GB 17859-1999 标准中就根据需求将计算机信息系统的安全级别由低到高，划分为 1-5 共五个等级。在 GB/T 20272-2006 中更进一步对操作系统安全技术提出了具体要求。

从国标安全第三级开始要求操作系统提供强制访问控制，除了要实现 SELinux 中的各类安全模型架构外，还根据最小特权原则开创性的引入三权分立的概念，将普通操作系统中权限不受控制的管理员根据职责分解为系统管理员，安全管理员，审计管理员三个角色。

系统管理员负责“行政”体系，也就是系统中的配置管理，类似网络配置、服务启停（安全服务除外）、设备管理等等；安全管理员负责“立法”，负责安全策略制定、加载以及安全服务的开启；审计管理员的职责类似“司法”，制定违规访问的记录，安全服务的关闭。三个角色的权限之间互相制约，从而避免了恶意入侵者通过获取管理员权限对操作系统的全面控制。同时标准还对用户数据的私密性、完整性提出了严格的保护要求，要求操作系统通过安全标签保障用户数据不被非法读取和篡改。

国标安全四级除了在访问控制和数据保护上提出更为严格要求之外，还要求设计者对操作系统的安全策略模型、安全功能模块进行形式化验证，并进行隐蔽信道分析，对系统抵御攻击能力进行评估，也是目前已有操作系统能达到的最高安全等级。目前普华、凝思等国产操作系统厂商已经开发出了符合国标安全四级的安全操作系统，提供了远高于普通 SELinux 的底层安全保护。

### 结语

信息安全是全方位的，尽管病毒与恶意入侵并非只针对操作系统，单一从操作系统层面无法解决所有的安全问题，然而作为所有上层应用的最底层软件支撑，操作系统却在最终执行层面承载着一切上层软件的安全机制，脱离操作系统构建的安全体系，如同沙滩上的城堡，即使再坚固也将最终失去根基。


朝鲜 180 局的网络战部门让西方国家忧虑

just want to change people's focus, it's a typical trick of the media!

Are you 中国人?

棒子国这方面的新闻，历史证明就没有几个是真的～～～

外国人不是习惯直接用wanna吗？

*本文译自澳大利亚广播公司相关文章，不代表本站及译者、编辑的态度。*

![在夜色的映衬下，部队的军车通过平壤市区](/data/attachment/album/201705/23/204904prckpnnpyickxyrx.jpg "Military trucks through Pyongyang")

据脱北者、官方和网络安全专家的消息，朝鲜的情报机关有一个叫做 180 局的特殊部门， 这个部门已经发起过多起胆大且成功的网络战。

近几年，朝鲜被指责在美国、韩国，及其周边的几个国家对金融网络发起多起在线袭击。

网络安全研究人员称他们找到了这个月全球性感染了 150 多个国家 30 多万台计算机的[“想哭”勒索病毒和朝鲜网络战有关联的技术证据](http://www.abc.net.au/news/2017-05-16/researchers-link-wannacry-to-north-korea/8531110)。

平壤称该指控是“荒谬的”。

对朝鲜的关键指控是指朝鲜与一个叫做<ruby> 拉撒路 <rp>  （ </rp> <rt>  Lazarus </rt> <rp>  ） </rp></ruby>的黑客组织有联系，这个组织是在去年在孟加拉国中央银行网络抢劫了 8100 万美元，并在 2014 年攻击了索尼的好莱坞工作室的网络。

美国政府指责朝鲜对索尼公司的黑客袭击，同时美国政府对平壤在孟加拉国银行的盗窃行为提起公诉并要求立案。

由于没有确凿的证据、没有犯罪指控并不能够立案。朝鲜之后也否认了索尼公司和该银行的袭击与其有关。

朝鲜是世界上最封闭的国家之一，它秘密行动的一些细节很难获得。

但研究这个封闭国家的专家和流落到韩国和一些西方国家的的脱北者已经给出了或多或少的提示。

### 黑客们喜欢以雇员身份来作为掩护

金恒光，一位朝鲜前计算机教授，2004 叛逃到韩国，他仍然有着韩国内部的消息来源，他说平壤的网络战目的在于通过侦察总局（RGB）下属的一个叫做 180 局来筹集资金，这个局主要是负责海外的情报机构。

金教授称，“180 局负责入侵金融机构通过漏洞从银行账户提取资金”。

他之前也说过，他以前的一些学生已经加入了朝鲜的网络战略司令部，即朝鲜的网络部队。

>
> “黑客们到海外寻找比朝鲜更好的互联网服务的地方，以免留下痕迹，” 金教授补充说。
>
>
>

他说他们经常用贸易公司、朝鲜的海外分公司和在中国和东南亚合资企业的雇员来作为掩护。

位于华盛顿的战略与国际研究中心的一位名为 James Lewis 的朝鲜专家称，平壤首先把黑客攻击作为间谍活动的工具，然后对韩国和美国的目的进行政治干扰。

他说，“索尼公司事件之后，他们改变方法，通过用黑客来支持犯罪活动来形成国内坚挺的货币经济政策。”

“目前为止，网上毒品，假冒伪劣，走私，都是他们惯用的伎俩”。

[**VIDEO：** 你遇到过勒索病毒吗? (ABC News)](http://www.abc.net.au/news/2017-05-15/have-you-been-hit-by-ransomware/8527854)

### 韩国声称拥有“大量的证据”

美国国防部称在去年提交给国会的一个报告中显示，朝鲜将网络视为有成本效益的、不对称的、可否认的工具，它能够应付来自报复性袭击的很小风险，因为它的“网络”大部分是和因特网分离的。

>
> 报告中说，“它可能从第三方国家使用互联网基础设施。”
>
>
>

韩国政府称，他们拥有朝鲜网络战行动的大量证据。

“朝鲜进行网络战通过第三方国家来掩护网络袭击的来源，并且使用他们的信息和通讯技术设施”，韩国外交部副部长安总基在书面评论中告诉路透社。

除了孟加拉银行抢劫案，他说怀疑平壤也与菲律宾、越南和波兰的银行袭击有关。

去年六月，警察称朝鲜袭击了 160 个韩国公司和政府机构，入侵了大约 14 万台计算机，暗中在它的对手的计算机中植入恶意代码，为进行大规模网络攻击的长期计划而准备。

朝鲜也被怀疑在 2014 年对韩国核反应堆操作系统进行阶段性网络攻击，尽管朝鲜否认与其无关。

根据在一个韩国首尔的杀毒软件厂商 hauri 的高级安全研究员 Simon Choi 的说法，网络袭击是来自于朝鲜在中国的一个基地。

Choi 先生，是一位对朝鲜的黑客能力有广泛的研究的人，他称，“他们在那里行动，不管他们究竟在做什么，他们拥有中国的 IP 地址”。

[题图：脱北者说， 平壤的网络战攻击目的旨在为一个叫做“180局”的部门来筹集资金。(路透社：Damir Sagolj, file)](http://www.abc.net.au/news/2017-05-21/military-trucks-trhough-pyongyang/8545134)

---

via: <http://www.abc.net.au/news/2017-05-21/north-koreas-unit-180-cyber-warfare-cell-hacking/8545106>

作者：[www.abc.net.au](http://www.abc.net.au) 译者：[hwlog](https://github.com/hwlog) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 中删除超大的（100-200GB）文件

这个也应该要看具体文件系统吧？

感谢分享

创建一个空文件，再用mv覆盖大文件。试过删除差不多二百G日志文件，二、三秒完成，最后重启一下程序~

来自广东广州的 Chrome Mobile 37.0|Android 7.0 用户

好，windows 的删除真的sb是的，拖慢，就应该这种技术嘛

假如大文件叫做bigfile可以直接用如下命令先让其变小文件在删除啊，而且超快:

echo "" >  bigfile

rm bigfile

![](/data/attachment/album/201705/24/064946fqc1vu7oxi1bixos.jpg)

通常，要[在 Linux 终端删除一个文件](/article-8123-1.html)，我们使用 rm 命令（删除文件）、shred 命令（安全删除文件）、wipe 命令（安全擦除文件）或者 secure-deletion 工具包（一个安全文件删除工具集合）。

我们可以使用上述任意的工具来处理相对较小的文件。如果我们想要删除超大的文件/文件夹，比如大概 100-200GB，在删除文件（I/O 调度）所花费的时间以及 RAM 占用量方面，就没有你想的那么简单。

在本教程中，我们会解释如何在 Linux 中有效率并可靠地删除大文件/文件夹。

**建议阅读：** [5 个在 Linux 中清空或者删除大文件的方法](/article-8024-1.html)

我们的主要目标是使用一种不会在删除大文件时拖慢系统的技术，合理地占用 I/O。我们可以用 ionice 命令实现这个目标。

### 在 Linux 中使用 ionice 命令删除超大（200GB）文件

ionice 是一个可以对另一个程序设置或获取 I/O 调度级别和优先级的有用程序。如果没有给出参数或者只有 `-p` 参数，那么 ionice 将会查询该进程的当前的 I/O 调度级别以及优先级。

如果我们给出命令名称，如 `rm` 命令，它将使用给定的参数运行此命令。要获取或设置调度参数，请指定[进程的 PID]，如下：

```
# ionice -p PID

```

要指定名字或者调度的数字，使用（0 表示无、1 表示实时、2 表示尽力、3 表示空闲）下面的命令。

以下命令表示 `rm` 会属于空闲 I/O 级别，并且只在其他进程不使用的时候使用 I/O：

```
---- Deleting Huge Files in Linux -----
# ionice -c 3 rm /var/logs/syslog
# ionice -c 3 rm -rf /var/log/apache

```

如果系统中没有很多空闲时间，那么我们希望使用尽力调度级别，并且使用低优先级：

```
# ionice -c 2 -n 6 rm /var/logs/syslog
# ionice -c 2 -n 6 rm -rf /var/log/apache

```

注意：要使用安全的方法删除大文件，我们可以使用先前提到的 `shred`、`wipe` 以及 secure-deletion 工具包中的不同工具，而不是 `rm` 命令。

**建议阅读：**[3 个在 Linux 中永久/安全删除文件/文件夹的方法](/article-8123-1.html)

要获取更多信息，查阅 `ionice` 的手册页：

```
# man ionice

```

就是这样了！你脑海里还有其他的方法么？在评论栏中与我们分享。

---

作者简介：

Aaron Kili 是 Linux 和 F.O.S.S 爱好者，将来的 Linux 系统管理员和网络开发人员，目前是 TecMint 的内容创作者，他喜欢用电脑工作，并坚信分享知识。

---

via: <https://www.tecmint.com/delete-huge-files-in-linux/>

作者：[Aaron Kili](https://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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