8 个构建容器应用的最佳实践

# 8 个构建容器应用的最佳实践

<img src="content_image/album_201610_25_092800e8u2dct6c9i6v9mw.jpg" alt="" title="">

容器是未来在共有云和私有云进行应用开发的主要趋势，但是容器到底是什么，为什么它们成为了一种广受欢迎的部署机制，而且你需要怎样来修改你的应用来为容器化的环境优化它？

### 什么是容器？

容器技术的历史始于 2000 年的 SELinux 和 2005 年的 Solaris zones。今天，容器是由包括 SELinux、Linux 命名空间和控制组（cgroup）等几项内核特性构成，提供了用户进程、网络空间和文件系统空间的隔离。

### 为什么它们如此流行？

最近容器技术大规模的应用在很大程度上是由于旨在使容器更加易于使用的标准的发展，例如 Docker 镜像格式和分布模型，这个标准使用<ruby> 不可变镜像 <rp>  （ </rp> <rt>  immutable image </rt> <rp>  ） </rp></ruby>，这正是容器运行时环境的起点，不可变镜像可以保证开发团队发布的镜像就是经过测试的，和部署到生产环境中的镜像是同样的镜像。

容器所提供的轻量级隔离为一个应用组件提供了一个更好的抽象。在容器中运行的组件将不会干扰其它可能直接运行在虚拟机上的应用。它们可以避免对系统资源的争夺，而且除非它们共享一个持久卷，否则不会阻止对同一个文件的写请求。容器使得日志和指标采集的实践得以标准化，而且它们可以在物理机和虚拟机上支持更大的用户密度，所有的这些优点将导致更低的部署成本。

### 我们应该如何构建一个基于容器的应用呢？

将应用改为运行在容器中并不是什么很高的要求。主要的 Linux 发行版都有提供了基础镜像，任何可以在虚拟机上运行的程序都可以在上面运行。但是容器化应用的趋势是遵循如下最佳实践：

#### 1. 实例是一次性的

你的应用的任何实例都不需要小心地保持运行。如果你的一个运行了许多容器的系统崩溃了，你还能够转移到其它可用的系统去创建新的容器。

#### 2. 重试而不是崩溃

当你的应用的一个服务依赖于另一个服务的时候，在另一个服务不可用的时候它应该不会崩溃。例如，你的 API 服务正在启动而且监测到数据库不能连接。你应该设计它使得其不断重试连接，而不是运行失败和拒绝启动。当数据库连接断开的时候 API 可以返回 503 状态码，告诉客户端服务现在不可用。应用应该已经遵守了这个实践，但是如果你正在一个一次性实例的容器环境中工作，那么对这个实践的需要会更加明显。

#### 3. 持久性数据是特殊的

容器是基于共享镜像启动，它使用了写时复制（COW）文件系统。如果容器的进程选择写入文件，那么这些写的内容只有在直到容器存在时才存在。当容器被删除的时候，写时复制文件系统中的那一层会被删除。提供给容器一个挂载的文件系统目录，使之在容器存活之外也能持久保存，这需要另外的配置，而且会额外消耗物理存储。明确的抽象定义了什么存储是持久的，催生出了实例是一次性的观点。拥有一个抽象层也使得容器编制引擎可以处理挂载和卸载持久卷的复杂请求，以便这些持久卷可以用于容器。

#### 4. 使用 stdout 而不是日志文件

现在你或许会思考，如果持久的数据是特殊的，那么我用日志文件来做什么事情？容器运行时环境和编制引擎项目所采用的方法是进程应该[写入 stdout/stderr](https://docs.docker.com/engine/reference/commandline/logs/)，而且具有归档和维护[容器日志](http://kubernetes.io/docs/getting-started-guides/logging/)的基础设施。

#### 5. 敏感信息（以及其它配置信息）也是特殊的

你绝不应该将敏感信息例如密码、密钥和证书硬编码到你的镜像中。通常在你的应用与开发服务、测试服务，或者生产服务相交互时，这些敏感信息通常都是不同的。大多数开发者并没有访问生产环境的敏感信息的权限，所以如果敏感信息被打包到镜像中，那么必须创建一个新的镜像层来覆盖这个开发服务的敏感信息。基于这一点来看，你再也不能使用与你们开发团队所创建的和质量测试所测试的相同的镜像了，而且也失去了不可修改的镜像的好处。相反的，这些值应该被存储在环境变量中文件中，它们会在容器启动时导入。

#### 6. 不要假设服务的协同定位

在一个编排好的容器环境中，你会希望让编排器将你的容器发送到任何最适合的节点。最适合意味着很多事情：它应该基于那个节点现在拥有最多的空间、容器所需的服务质量、容器是否需要持久卷，等等。这可能意味这你的前端、API 和数据库容器最终都会放在不同的节点。尽管给每个节点强制分配一个 API 容器是可以做到的（参考 Kubernetes 的 [DaemonSets](http://kubernetes.io/docs/admin/daemons/)），但这种方式应该留给执行监控节点自身这类任务的容器。

#### 7. 冗余/高可用计划

即使你没有那么多负载需要高可用性的配置，你也不应该以单路方式编写服务，否则会阻止它运行多份拷贝。这将会允许你运用滚动式部署，使得将负载从一个节点移动到另外一个节点非常容易，或者将服务从一个版本更新到下一个版本而不需要下线。

#### 8. 实现就绪检查和灵活性检查

应用在响应请求之前会有一定的启动时间是一件很正常的事情，例如，一个 API 服务器需要填充内存数据缓存。容器编排引擎需要一种方法来检测你的容器是否准备好服务用户请求。为一个新的容器提供就绪检查可以允许我们进行滚动式部署，使得旧容器可以继续运行直到不再需要它，这可以防止服务宕机。类似的，一个存活检查也是一种容器编排引擎持续检查容器是否在健康可用状态的方法。决定容器健康或者说“存活”应该由容器应用的创建者说了算。一个不再存活的容器将会被结束，而且一个新的容器会被创建来替代它。

### 想查找更多资料？

我将会出席十月份的格雷丝霍普计算机女性峰会（Grace Hopper Celebration of Women in Computing），你可以在这里来看一下关于我的访谈：[应用的容器化：是什么，为什么，和如何实现](https://www.eiseverywhere.com/ehome/index.php?eventid=153076&tabid=351462&cid=1350690&sessionid=11443135&sessionchoice=1&)。今年不去 GHC 吗？那你可以在 [OpenShift](https://www.openshift.org/) 和 [Kubernetes](http://kubernetes.io/) 的项目站点来了解关于容器、编排和应用的相关内容。

---

via: <https://opensource.com/life/16/9/8-best-practices-building-containerized-applications>

作者：[Jessica Forrester](https://opensource.com/users/jwforres) 译者：[LinuxBars](https://github.com/LinuxBars) 校对：[wxy](https://github.com/wxy)

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


Mozilla 做出不再信任沃通 CA 的决定，沃通回应打一折

Summary: 从 Firefox 51 （预计将在 2017 年 1 月 23 日发布）起移除之前预置的 4 个沃通根证书

这条新闻的传播路径：

solidot--cnbeta---一些其他媒体---***---linuxcn。

自从360私有化，动作挺大啊，先是干掉了云盘，然后是整死了沃通，有把刷子。不过mozilla这么折腾没有用，360有倒填时间大法（举例：当前时间2016-10-26，但是他写成10月21日以前签的整数，mozilla就不会取消信任）。对付流氓，你还真没招儿。

错了，它可以倒填，但是它不能在 CT 上作假。

全部手动设置为不信任！

ca沃通是个流氓，大家都知道的

# Mozilla 做出不再信任沃通 CA 的决定，沃通回应打一折

<img src="content_image/album_201610_25_212540qyrfcajxc30pvlza.jpg" alt="" title="">

Mozilla 对沃通（WoSign）的处罚终于落定。

前一段时间，Mozilla 就沃通 CA 违规的问题，于 8 月 24 日发起了针对沃通 CA 的调查，并发布了一个[问题列表](https://wiki.mozilla.org/CA:WoSign_Issues)。之后在 10 月 5 日， Mozilla、奇虎 360 、StartCom 和沃通在伦敦举行了闭门商谈，讨论下一步行动。

10 月 20 日，Mozilla 公布了对沃通 CA 的[最终处理意见](https://bugzilla.mozilla.org/show_bug.cgi?id=1311824)：

* 它不再信任在 10 月 21 日之后签发的沃通 CA 证书
* 从 Firefox 51 （[预计](https://wiki.mozilla.org/RapidRelease/Calendar)将在 2017 年 1 月 23 日发布）起，移除之前预置的 4 个沃通根证书：
	1. CN=CA 沃通根证书, OU=null, O=WoSign CA Limited, C=CN
	2. CN=Certification Authority of WoSign, OU=null, O=WoSign CA Limited, C=CN
	3. CN=Certification Authority of WoSign G2, OU=null, O=WoSign CA Limited, C=CN
	4. CN=CA WoSign ECC Root, OU=null, O=WoSign CA Limited, C=CN

但是从这 4 个根证书签发的所有代码签名证书、客户端证书、签名平台（WoSignDoc）均不受任何影响。10 月 21 日（包括 21 日）之前签发的所有 SSL 证书也都不受任何影响，都能正常被 Mozilla 的火狐浏览器信任。

预计 Mozilla 的这一决定也有可能被其它主流浏览器所接纳。

此外，Mozilla 提出了六点操作要求：

1. 提供实施整改计划列表，确保将来不会违例 Mozilla 的 CA 证书策略和 CA/Browser 论坛的基准要求。
2. 实施整改，并更新其 CP/CPS 来完整描述其改进过程。CP/CPS 必须明确申明禁止倒填超过一天前的证书。
3. 对所做的整改，提供来自 Mozilla 所认可的 WebTrust 鉴证机构的面向公众的认证。该审计可能需要作为年度 WebTrust CA 审计的一部分。
4. 提供审计认证，对全部业务进行审计，确认合规 CA/Browser 论坛的基准要求。该审计可能需要作为年度 WebTrust CA 审计的一部分。
5. 提供审计认证，对 CA 的签发基础设施可以顺利完成执行完整的安全审计。
6. 所有签发的证书 100% 嵌入证书透明度（CT）信息，嵌入的 SCT 至少有一条来自谷歌，一条来自谷歌之外。

2017 年 6 月 1 日后，在满足 Mozilla 提出的上述 6 点操作要求后，沃通 CA 可以重新走正常申请 Mozilla 根认证流程，重新申请新的根证书预置。

沃通对此[表示遗憾](http://www.wosign.com/News/announcement_about_Mozilla_Action_20161024.htm)， 并宣布：

> 1. 将更新数字证书商店Buy网站，从10月22日起，所有从沃通4个根证书下签发的所有收费SSL证书全部**一折**销售；免费SSL证书继续停止开放；
> 2. 将增加一个产品选项，用户可以选购从新的沃通（WoSign）中级根证书下签发的支持所有浏览器（包括火狐浏览器）的SSL证书，在过渡期**八折**优惠。此中级根证书将由全球信任的其他CA根证书签发，支持所有浏览器和所有新老终端设备。此项产品升级计划一个月内完成并为广大用户提供证书服务；
> 3. 将积极按照Mozilla提出的6点要求进行操作，争取在2017年6月1日之后，尽快完成新根证书在各个浏览器系统的预置工作；
> 4. 已经并继续对所有系统进行全面的安全审计并加固升级改造，同时完善各种内控管理制度，组建国际标准研究团队和内审团队，确保所有系统100%符合国际标准，所有业务操作严格按照国际标准要求操作，加强员工严格按照标准操作的执行力度，违者将受到严厉惩处。
>

（题图来自：[deviantart.net](http://img13.deviantart.net/ee6d/i/2015/132/b/f/iris___broken_bridge_by_laitma-d8t2uxi.png)）


Summary: serverless 是一个概念，它允许你提供代码或可执行程序给某个服务，由服务来为你执行它们，而你无需自己管理服务器。这就是所谓的执行即服务（execution-as-a-service），它带来了很多机会，同时也遇到了它独有的挑战。

# 通过 AWS 的 Lambda 和 API Gateway 走向 Serverless

近来，在计算领域出现了很多关于 serverless 的讨论。serverless 是一个概念，它允许你提供代码或可执行程序给某个服务，由服务来为你执行它们，而你无需自己管理服务器。这就是所谓的<ruby> 执行即服务 <rp>  （ </rp> <rt>  execution-as-a-service </rt> <rp>  ） </rp></ruby>，它带来了很多机会，同时也遇到了它独有的挑战。

### 简短回忆下计算领域的发展

早期，出现了……好吧，这有点复杂。很早的时候，出现了机械计算机，后来又有了埃尼阿克 ENIAC（Electronic Numerical Integrator And Computer，很早的电子计算机)，但是都没有规模生产。直到大型机出现后，计算领域才快速发展。

<img src="content_image/album_201610_26_110123oyk1iy212ld4iyuu.jpg" alt="" title="">

* 上世纪 50 年代 - 大型机
* 上世纪 60 年代 - 微型机
* 1994 - 机架服务器
* 2001 - 刀片服务器
* 本世纪初 - 虚拟服务器
* 2006 - 服务器云化
* 2013 - 容器化
* 2014 - serverless（计算资源服务化）

>
> 这些日期是大概的发布或者流行日期，无需和我争论时间的准确性。
>
>
>

计算领域的演进趋势是执行的功能单元越来越小。每一次演进通常都意味着运维负担的减小和运维灵活性的增加。

### 发展前景

喔，Serverless！但是，serverless 能给我们带来什么好处? 我们将面临什么挑战呢?

**未执行代码时无需付费。**我认为，这是个巨大的卖点。当无人访问你的站点或用你的 API 时，你无需付钱。没有持续支出的基础设施成本，仅仅支付你需要的部分。换句话说，这履行了云计算的承诺：“仅仅支付你真正用的资源”。

**无需维护服务器，也无需考虑服务器安全。**服务器的维护和安全将由你的服务提供商来处理（当然，你也可以架设自己的 serverless 主机，只是这似乎是在向错误的方向前进）。由于你的执行时间也是受限的，安全补丁也被简化了，因为完全不需要重启。这些都应该由你的服务提供商无缝地处理。

**无限的可扩展性。**这是又一个大的好处。假设你又开发了一个 Pokemon Go, 与其频繁地把站点下线维护升级，不如用 serverless 来不断地扩展。当然，这也是个双刃剑，大量的账单也会随之而来。如果你的业务的利润强依赖于站点上线率的话，serverless 确实能帮上忙。

**强制的微服务架构。**这也有两面性，一方面，微服务似乎是一种好的构建灵活可扩展的、容错的架构的方式。另一方面，如果你的业务没有按照这种方式设计，你将很难在已有的架构中引入 serverless。

### 但是现在你被限制在**他们的**平台上

**受限的环境。**你只能用服务提供商提供的环境，你想在 Rust 中用 serverless？你可能不会太幸运。

**受限的预装包。**你只有提供商预装的包。但是你或许能够提供你自己的包。

**受限的执行时间。**你的 Function 只可以运行这么长时间。如果你必须处理 1TB 的文件，你可能需要有一个解决办法或者用其他方案。

**强制的微服务架构。**参考上面的描述。

**受限的监视和诊断能力。**例如，你的代码**在**干什么? 在 serverless 中，基本不可能在调试器中设置断点和跟踪流程。你仍然可以像往常一样记录日志并发出统计度量，但是这带来的帮助很有限，无法定位在 serverless 环境中发生的难点问题。

### 竞争领域

自从 2014 年出现 AWS Lambda 以后，serverless 的提供商已经增加了一些。下面是一些主流的服务提供商:

* AWS Lambda - 起步最早的
* OpenWhisk - 在 IBM 的 Bluemix 云上可用
* Google Cloud Functions
* Azure Functions

这些平台都有它们的相对优势和劣势（例如，Azure 支持 C#，或者紧密集成在其他提供商的平台上）。这里面最大的玩家是 AWS。

### 通过 AWS 的 Lambda 和 API Gateway 构建你的第一个 API

我们来试一试 serverless。我们将用 AWS Lambda 和 API Gateway 来构建一个能返回 [Jimmy](http://blog.ryankelly.us/2016/07/11/jimmy.html) 所说的“Guru Meditations”的 API。

所有代码在 [GitHub](https://github.com/f0rk/meditations) 上可以找到。

API文档：

```
POST /
{
    "status": "success",
    "meditation": "did u mention banana cognac shower"
}

```

### 怎样组织工程文件

文件结构树:

```
.
├── LICENSE
├── README.md
├── server
│   ├── __init__.py
│   ├── meditate.py
│   └── swagger.json
├── setup.py
├── tests
│   └── test_server
│       └── test_meditate.py
└── tools
    ├── deploy.py
    ├── serve.py
    ├── serve.sh
    ├── setup.sh
    └── zip.sh

```

AWS 中的信息（想了解这里究竟在做什么的详细信息，可查看源码 `tools/deploy.py`）。

* **API。**实际构建的对象。它在 AWS 中表示为一个单独的对象。
* **执行角色。**在 AWS 中，每个 Function 作为一个单独的角色执行。在这里就是 meditations。
* **角色策略。**每个 Function 作为一个角色执行，每个角色需要权限来干活。我们的 Lambda Function 不干太多活，故我们只添加一些日志记录权限。
* **Lambda Function。**运行我们的代码的地方。
* **Swagger。** Swagger 是 API 的规范。API Gateway 支持解析 swagger 的定义来为 API 配置大部分资源。
* **部署。**API Gateway 提供部署的概念。我们只需要为我们的 API 用一个就行（例如，所有的都用生产或者 yolo等)，但是得知道它们是存在的，并且对于真正的产品级服务，你可能想用开发和暂存环境。
* **监控。**在我们的业务崩溃的情况下（或者因为使用产生大量账单时），我们想以云告警查看方式为这些错误和费用添加一些监控。注意你应该修改 `tools/deploy.py` 来正确地设置你的 email。

### 代码

Lambda Function 将从一个硬编码列表中随机选择一个并返回 guru meditations，非常简单：

```
import logging
import random

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def handler(event, context):

    logger.info(u"received request with id '{}'".format(context.aws_request_id))

    meditations = [
    "off to a regex/",
    "the count of machines abides",
    "you wouldn't fax a bat",
    "HAZARDOUS CHEMICALS + RKELLY",
    "your solution requires a blood eagle",
    "testing is broken because I'm lazy",
    "did u mention banana cognac shower",
    ]

    meditation = random.choice(meditations)

    return {
        "status": "success",
        "meditation": meditation,
    }

```

### deploy.py 脚本

这个脚本相当长，我没法贴在这里。它基本只是遍历上述“AWS 中的信息”下的项目，确保每项都存在。

### 我们来部署这个脚本

只需运行 `./tools/deploy.py`。

基本完成了。不过似乎在权限申请上有些问题，由于 API Gateway 没有权限去执行你的 Function，所以你的 Lambda Function 将不能执行，报错应该是“Execution failed due to configuration error: Invalid permissions on Lambda function”。我不知道怎么用 botocore 添加权限。你可以通过 AWS console 来解决这个问题，找到你的 API, 进到 `/POST` 端点，进到“integration request”，点击“Lambda Function”旁边的编辑图标，修改它，然后保存。此时将弹出一个窗口提示“You are about to give API Gateway permission to invoke your Lambda function”， 点击“OK”。

当你完成后，记录下 `./tools/deploy.py` 打印出的 URL，像下面这样调用它，然后查看你的新 API 的行为：

```
$ curl -X POST https://a1b2c3d4.execute-api.us-east-1.amazonaws.com/prod/
{"status": "success", "meditation": "the count of machines abides"}

```

### 本地运行

不幸的是，AWS Lambda 没有好的方法能在本地运行你的代码。在这个例子里，我们将用一个简单的 flask 服务器来在本地托管合适的端点，并调用 handler 函数。

```
from __future__ import absolute_import

from flask import Flask, jsonify

from server.meditate import handler

app = Flask(__name__)

@app.route("/", methods=["POST"])
def index():

    class FakeContext(object):
        aws_request_id = "XXX"

    return jsonify(**handler(None, FakeContext()))

app.run(host="0.0.0.0")

```

你可以在仓库中用 `./tools/serve.sh` 运行它，像这样调用：

```
$ curl -X POST http://localhost:5000/
{
    "meditation": "your solution requires a blood eagle",
    "status": "success"
}

```

### 测试

你总是应该测试你的代码。我们的测试方法是导入并运行我们的 handler 函数。这是最基本的 python 测试方法：

```
from __future__ import absolute_import

import unittest

from server.meditate import handler

class SubmitTestCase(unittest.TestCase):

    def test_submit(self):

        class FakeContext(object):

            aws_request_id = "XXX"

        response = handler(None, FakeContext())

        self.assertEquals(response["status"], "success")
        self.assertTrue("meditation" in response)

```

你可以在仓库里通过 nose2 运行这个测试代码。

### 更多前景

* **和 AWS 服务的无缝集成。**通过 boto，你可以完美地轻易连接到任何其他的 AWS 服务。你可以轻易地让你的执行角色用 IAM 访问这些服务。你可以从 S3 取文件或放文件到 S3，连接到 Dynamo DB，调用其他 Lambda Function，等等。
* **访问数据库。**你也可以轻易地访问远程数据库。在你的 Lambda handler 模块的最上面连接数据库，并在handler 函数中执行查询。你很可能必须从它的安装位置上传相关的包内容才能使它正常工作。可能你也需要静态编译某些库。
* **调用其他 webservices。**API Gateway 也是一种把 webservices 的输出从一个格式转换成另一个格式的方法。你可以充分利用这个特点通过不同的 webservices 来代理调用，或者当业务变更时提供后向兼容能力。

---

via: <http://blog.ryankelly.us/2016/08/07/going-serverless-with-aws-lambda-and-api-gateway.html>

作者：[Ryan Kelly](https://github.com/f0rk/blog.ryankelly.us/) 译者：[messon007](https://github.com/messon007) 校对：[wxy](https://github.com/wxy)

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


开发者的实用 Vim 插件（一）

括号补全插件很好用！

delimitMate跟auto-pairs比较有什么优点，谁给普及一下？

pathgone.vim应该不推荐了吧？选择vundle吧？

我用vimplug

不错,正在捣鼓vim

# 开发者的实用 Vim 插件（一）

作为 Vi 的升级版，[Vim](http://www.vim.org/) 毫无争议是 Linux 中最受欢迎的命令行编辑器之一。除了是一个多功能编辑器外，世界各地的软件开发者将 Vim 当做 IDE（<ruby> 集成开发环境 <rp>  （ </rp> <rt>  Integrated Development Environment </rt> <rp>  ） </rp></ruby>）来使用。

事实上，因为 Vim 可以通过插件来扩展其自身功能才使得它如此功能强大。不用说，肯定有那么几个 Vim 插件是旨在提高用户的编程体验的。

特别是对于刚刚使用 Vim 或者使用 Vim 做开发的的软件开发者来说，我们将在本教程中讨论一些非常有用的 Vim 插件，具体请看例示。

请注意：本教程中列举的所有例示、命令和说明都是在 Ubuntu 16.04 环境下进行测试的，并且，我们使用的 Vim 版本是 7.4。

### 插件安装设置

这是为新用户准备的，假设他们不知道如何安装 Vim 插件。所以，首先，就是给出一些完成安装设置的步骤。

* 在你的家目录下创建 `.vim` 目录，并在其中创建子目录 `autoload` 和 `bundle`。
* 然后，在 `autoload` 放置 [pathogen.vim](http://www.vim.org/scripts/script.php?script_id=2332) 文件，这个文件可以从[此处](https://raw.githubusercontent.com/tpope/vim-pathogen/master/autoload/pathogen.vim) 下载。
* 最后，在你的家目录创建 `.vimrc` 文件，并添加以下内容。

```
call pathogen#infect()

```

至此，你已完成了 Vim 插件安装的准备工作。

注意：我们已经讨论了使用 Pathogen 管理 Vim 插件。当然还有其他的插件管理工具——欲了解，请访问[此处](http://vi.stackexchange.com/questions/388/what-is-the-difference-between-the-vim-plugin-managers)。

现在已经全部设置完毕，就让我们来讨论两个好用的 Vim 插件吧。

### Vim 标签侧边栏（Tagbar）插件

首先就是标签侧边栏（Tagbar）插件。该插件能够让你浏览源文件包含的标签，从而提供该源文件的结构简览。[其官网的插件说明](http://majutsushi.github.io/tagbar/)是这样说的：“它通过创建侧边栏，然后以一定顺序展示从当前文件以 ctags 提取的标签来完成这一功能。这意味着，比如，C++ 中的方法将展示在其自身所定义在的类里边。”

听起来很酷，不是吗？让我们来看看该怎么安装它。

标签侧边栏（Tagbar）的安装过程是相当容易的——你只需要运行下列命令：

```
cd ~/.vim/bundle/

git clone git://github.com/majutsushi/tagbar

```

安装完之后就可以使用了，你可以在 Vim 中打开一个 .cpp 文件来测试它：进入[命令模式](http://www.tldp.org/LDP/intro-linux/html/sect_06_02.html)，然后运行 `:TagbarOpen` 命令。以下是运行 `:TagbarOpen` 命令之后出现侧边栏（右侧） 的效果图。

[](https://www.howtoforge.com/images/vim-editor-plugins-for-software-developers/big/vimplugins-tagbar-example.png)

使用 `:TagbarClose` 可以关闭侧边栏。值得一提的是，可以使用 `:TagbarOpen fj` 命令打开侧边栏来打开它的跳转（shift control）功能。也就是说，你可以很方便的浏览当前文件包含的标签——在对应的标签上按下 Enter 键，然后在左侧的源代码窗口跳转到对应的位置。

假如你想要反复地开关侧边栏，你可以使用 `:TagbarToggle` 命令，而不用交替的使用 `:TagbarOpen` 和 `:TagbarClose` 命令。

如果你觉得输入这些命令很费时间，你可以为 `:TagbarToggle` 命令创建快捷键。比如，添加以下内容到 `.vimrc` 文件中：

```
nmap <F8> :TagbarToggle<CR>

```

这样，你就可以用 F8 来切换标签侧边栏（Tagbar）了。

更进一步，有时候你可能会注意到某个标签前边有一个 `+`、`-` 或者 `#` 符号。比如，以下截图（取自该插件的官网）展示了一些前边有 `+` 号的标签。

这些符号基本是用来表明一个特定标签的可见性信息。特别是 `+` 表示该类是 public 的，而 `-` 表示一个 private 类。`#` 则是表示一个 protected 类。

以下是使用标签侧边栏（Tagbar）的一些注意事项：

* 该插件的官网早就有说明：“标签侧边栏（Tagbar）并非是管理标签（tags）文件而设计，它只是在内存中动态创建所需的标签，而非创建任何文件。标签（tags）文件的管理有其他插件提供支持。”
* 低于 7.0.167 版本的 Vim 和标签侧边栏（Tagbar）插件存在着一个兼容性问题。根据官网：“如果你受到此问题的影响，请使用代替版：[下载 zip 压缩包](https://github.com/majutsushi/tagbar/zipball/70fix)。这对应到 2.2 版本，但由于大量的依赖变更，它可能不会再升级。”
* 如果你在加载该插件时遇到这样的错误：未找到 ctags！（Tagbar: Exuberant ctags not found!）。你可以从 [此处](http://ctags.sourceforge.net/)下载并安装 ctags 来修复错误。
* 获取更多信息请访问 [这里](https://github.com/majutsushi/tagbar)。

### Vim 界定符自动补齐（delimitMate）插件

下一个要介绍的插件就是界定符自动补齐（delimitMate）。该插件在 Vim 插入模式下提供引号、圆括号和方括号等界定符自动补齐功能。

[该插件官网](https://github.com/Raimondi/delimitMate)说：“它同时也提供一些相关的特性让你在输入模式下变得更加便捷，比如语法纠错（在注释区或者其他的可配置区不会自动插入结束界定符）、回车和空格填充（默认关闭）等。”

安装步骤与之前介绍的相似：

```
cd ~/.vim/bundle/

git clone git://github.com/Raimondi/delimitMate.git

```

一旦你成功安装这个插件（即上述命令执行成功），你就不需要进行任何配置了——当 Vim 启动时会自动加载这个插件。

至此，在你使用 Vim 的任何时候，只要你输入一个双引号、单引号、单号、圆括号、方括号，它们都会自动补齐。

你可以自己配置界定符自动补齐（delimitMate）。比如，你可以添加需要自动补齐的符号列表，阻止自动加载该插件，对指定类型文件关闭该插件等。想了解如何配置这些（或者其他更多的配置），请阅读该插件的详细文档——运行 `:help delimitMate` 即可。

上述命令会将你的 Vim 窗口水平分割成两个，上边一个包含我们所说的文档。

### 结论

本文之中提到的两个插件，Tagbar 需要花费较多时间来适应——你应该会同样这个说法。但只要正确设置好它（这意味着你像是有了快捷键一样方便），就容易使用了。至于 delimitMate，不需要任何要求就可以上手。

本教程就是向你展示 Vim 如何高效能的想法。除了本文中提及的，仍然还有许多开发者可用的插件，我们将在下一个部分进行讨论。假如你正在使用一个关于开发的 Vim 插件，并希望广为人知，请在下方留下评论。

我们将在本教程的第二部分讲到 [语法高亮插件：Syntastic](https://www.howtoforge.com/tutorial/vim-editor-plugins-for-software-developers-2-syntastic/)。

---

via: <https://www.howtoforge.com/tutorial/vim-editor-plugins-for-software-developers/>

作者：[Ansh](https://www.howtoforge.com/tutorial/vim-editor-plugins-for-software-developers/) 译者：[GHLandy](https://github.com/GHLandy) 校对：[wxy](https://github.com/wxy)

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


NitroShare：内网多操作系统间快捷文件共享工具

Summary: 网络的最重要用途之一就是实现文件共享的目的。现在，虽然有多种方式可以让在同一网络中的 Linux 和 Windows 以及 MacOS X 用户之间共享文件，但这篇文章，我们只打算介绍 NitroShare。这是一款跨平台、开源以及易于使用的应用软件，可以在本地网络（内网）中共享文件。

看看如何

能代替smb？

网站上不去啊~

android不支持啊？

# NitroShare：内网多操作系统间快捷文件共享工具

网络的最重要用途之一就是实现文件共享的目的。现在，虽然有多种方式可以让在同一网络中的 Linux 和 Windows 以及 MacOS X 用户之间共享文件，但这篇文章，我们只打算介绍 NitroShare。这是一款跨平台、[开源](https://github.com/nitroshare/nitroshare-desktop)以及易于使用的应用软件，可以在本地网络（内网）中共享文件。

NitroShare 大大简化了本地网络的文件共享操作，一旦安装上，它就会与操作系统无缝集成。Ubuntu 系统中，从应用程序显示面板中可以简单的打开，在 Windows 系统中，在系统托盘中可以找到它。

此外，在装有 NitroShare 的机器上，它会自动检测在同一网段的其它安装了它的设备，用户只需选择好需要传输到的设备，就可以直接向其传输文件。

NitroShare 的特性如下：

* 跨平台，即可以运行于 Linux， Windows 和 MacOS X 系统
* 设置容易，无需配置
* 易于使用
* 支持在本地网络上自动发现运行着 Nitroshare 设备的能力
* 安全性上支持可选的 TLS (<ruby> 传输层安全协议 <rp>  （ </rp> <rt>  Transport Layer Security </rt> <rp>  ） </rp></ruby>) 编码传输方式
* 支持网络高速传输功能
* 支持文件和目录（Windows 上的文件夹）传输
* 支持对发送文件、连接设备等这些的桌面通知功能

最新版本的 NitroShare 是使用 Qt5 开发的，它做了一些重大的改进，例如：

* 用户界面焕然一新
* 简化设备发现过程
* 移除不同版本传输文件大小的限制
* 为了使用方便，已经去除配置向导

### Linux 系统中安装 Nitroshare

NitroShare 可运行于各种各样的现代 Linux 发行版和桌面环境。

#### Debian Sid 和 Ubuntu 16.04+

NitroShare 已经包含在 Debian 和 Ubuntu 的软件源仓库中，所以可以很容易的就安装上，使用如下命令：

```
$ sudo apt-get install nitroshare

```

但安装的版本可能已经过期了。要安装最新的版本的话，可按照如下的命令添加最新的 PPA。

```
$ sudo apt-add-repository ppa:george-edison55/nitroshare
$ sudo apt-get update
$ sudo apt-get install nitroshare

```

#### Fedora 24-23

最近，NitroShare 已经包含在 Fedora 源仓库中了，可以按如下命令安装：

```
$ sudo dnf install nitroshare

```

#### Arch Linux

在 Arch Linux 系统中，NitroShare 包在 AUR 上已经可用了，可以用如下命令来构建/安装：

```
# wget https://aur.archlinux.org/cgit/aur.git/snapshot/nitroshare.tar.gz
# tar xf nitroshare.tar.gz
# cd nitroshare
# makepkg -sri

```

### Linux 中使用 NitroShare

注意：如我前面所述，在本地网络中，您想要共享文件的其它机器设备都需要安装上 NitroShare 并运行起来。

在成功安装后，在系统 dash 面板里或系统菜单里搜索 NitroShare，然后启动。NitroShare 非常容易使用，你可从该应用或托盘图标上找到“发送文件”、“发送目录”、“查看传输”等选项。

选择文件后，点击“打开”继续选择目标设备，如下图所示。如果在本地网络有设备正的运行 NitroShare 的话，选择相应的设备然后点击“确定”。

如果需要，在 NitroShare 的配置 -- 通用标签页里，您可以增加设备的名字，设置默认文件下载位置，在高级设置里您能设置端口、缓存、超时时间等等。

主页：<https://nitroshare.net/index.html>

这就是所要介绍的，如果您有关于 Nitroshare 的任何问题，可以在下面的评论区给我们分享。您也可以给我们提供一些建议，告诉一些可能我们不知道的很不错的跨平台文件共享应用程序。

---

via: <http://www.tecmint.com/nitroshare-share-files-between-linux-ubuntu-windows/>

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

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


解决 Linux 内核代码审查人员短缺问题

Summary: 操作系统安全是现在最重要的事情，而 Linux 则是一个主要被讨论的部分。首先要解决的问题之一就是：我们如何确定提交到上游的补丁已经进行了代码审核？

# 解决 Linux 内核代码审查人员短缺问题

操作系统安全是[现在最重要的事情](http://www.infoworld.com/article/3124432/linux/is-the-linux-kernel-a-security-problem.html)，而 Linux 则是一个主要被讨论的部分。首先要解决的问题之一就是：我们如何确定提交到上游的补丁已经进行了代码审核？

Wolfram Sang 从 2008 年开始成为一名 Linux 内核开发者，他经常在各地召开的 Linux 峰会上发表讲话，比如在 [2016 年柏林 Linux 峰会](https://linuxconcontainerconeurope2016.sched.org/event/7oA4/kernel-development-i-still-think-we-have-a-scaling-problem-wolfram-sang-consultant)，他提出了如何提高内核开发实践的想法。

让我们来看看他的观点。

<img src="content_image/album_201610_27_111637qgg4i0ygd3btztgt.png" alt="" title="">

**在 2013 年的时候，你曾在爱丁堡（Edinburgh）提醒 ELCE 委员会，如果不作出改变，那么子系统的潜在问题和其他争议问题将会逐渐扩大。他们做出改变了吗？你所提及的那些事件发生了吗？**

是的，在某些程度上来说。当然了，Linux 内核是一个很多部分组成的项目，所以给以 Linux 各个子系统更多关注应该放在一个更重要的位置。然而，有太多的子系统“只是拼图中的一块”，所以通常来说，这些子系统的潜在问题还未被解决。

**你曾指出代码审核人数是一个大问题。为何你觉得 Linux 内核开发社区没有足够的代码审核人员呢？**

理由之一就是，大多数开发者实际上只是编写代码，而读代码并不多。这本是没有什么错，但却说明了并非每个人都是代码审核人员，所以我们真的应该鼓励每个人都进行代码审核。

我所看到另一件事就是，但我们要请人员加入我们的社区时，最重要的考核就是补丁贡献数量。我个人认为这是很正常的，并且在初期总贡献量少的时候是非常好的做法。但是随着越来越多的人员，特别是公司的加入，我们就碰到源码审核的问题。但是别误解了，有着数量可观的贡献是很棒的。但目前需要指出的是，参与社区有着更多内涵，比方说如何为下一步发展负责。有些部分在改善，但是还不够。

**你认为更多的代码审核人员培训或者审核激励措施是否会有帮助？**

我最主要的观点就是要指出，现今仍存在问题。是的，目前为止我们做到很好，但不意味着全都做的很好。我们也有类似扩张方面的问题。让人们了解事实，是希望能够让一些团体对此感兴趣并参与其中。尽管，我并不认为我们需要特殊的训练。我所熟悉的一些代码审核人员都非常棒或者很有天赋，只是这类人太少或者他们的空闲时间太少。

首先就是需要有这种内在动力，至于其它的，边做边学就非常好了。这又是我想要指出的优势之一：审核补丁能够使你成为更出色的代码开发者。

**依你之见，是否有那么一个受欢迎的大项目在扩张这方面做的很好，可以供我们借鉴？**

我还真不知道有这么一个项目，如果有的话随时借鉴。

我很专注于 Linux 内核，所以可能会存在一些偏见。然而在我看来，Linux 内核项目在规模大小、贡献数量和多样性方面真的很特别。所以当我想要找另一个项目来寻找灵感以便改善工作流是很正常的想法，目前我们的扩张问题真的比较特别。而且我发现，看看其他子系统在内核中做了什么是一个很有的方法。

**你曾说安全问题是我们每个人都该想到的事情，那用户应该做些什么来避免或者改善安全问题的危险？**

在今年（2016年）柏林 Linux 峰会我的谈话是针对开发层面的。安全隐患可能来自于没有正确审核的补丁中。我并不想要用户亲自解决这种问题，我更希望这些安全问题永远不会出现。当然这是不可能的，但这仍然是我处理问题所首选的方法。

**我很好奇这个庞大社区如何改善这些问题。是否有你希望用户定期以文件形式提交的某些类型的错误报告？需要定期检查的区域却因为某些原因没有注意到的？**

我们并不缺少错误报告。我所担心的是：由于代码审核人员的短缺造成补丁不完整，从而导致更多的错误报告。所以，到时候不仅需要处理大量的贡献，还需要处理更多错误或者进行版本回退。

**你是否还有什么事情希望我们读者知道，以了解你所在的努力？**

Linux 内核的特殊性，常常让我牢记着，在底层它就是代码而已。

---

via: <https://opensource.com/business/16/10/linux-kernel-review>

作者：[Deb Nicholson](https://opensource.com/users/eximious) 译者：[GHLandy](https://github.com/GHLandy) 校对：[wxy](https://github.com/wxy)

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


ORWL：能够删除被篡改数据的微型开源计算机

只想要一个折叠屏

# ORWL：能够删除被篡改数据的微型开源计算机

在当今这个信息时代，安全是最重要的。恐怕没有人会希望自己的重要数据落入到坏人的手里。但是即便是无安全防护的硬件同样面临不少威胁，而大多数时候人们还只是对软件采取安全防护措施。ORWL 就是来改变这件事的。

### [ORWL 是什么？](http://www.design-shift.com/orwl/)

ORWL 宣称是社区里“造得最安全的家用电脑”。 它是一台小型的飞碟形计算机，在设计上全面考虑了物理安全性。物理安全很重要，因为一旦有人获得了从物理上访问你的计算机的途径，那么就 Game Over 了，这是信息安全专业人员中的一个老生常谈。

ORWL 的基本规格包括英特尔 Skylake M3 处理器、USB-C 和微型 HDMI 接口、8GB 内存、120G 固态硬盘、蓝牙、Wifi 和 NFC 技术。目前它支持的操作系统有 Ubuntu 16.04、Qubes OS，以及 Windows 10 等，开箱即用。你只需要有一个显示器，键盘和鼠标就可以开始使用它了。

### ORWL 是开源的

ORWL 是**完全**开源的。这意味着，如果有人想设计一台自己的计算机或者对 ORWL 作出改进的话，原理图和设计文件、软件、固件、所有东西都是可以获取的。

### ORWL 是如何工作的？

ORWL 使用自加密固态硬盘（SSD）。一个安全微控制器集成到其主板上来产生和存储加密密匙。一旦核实了系统的完整性和已验证用户，它就使用密匙来解密固态硬盘（SSD）。无论对 ORWL 进行任何类型的篡改，密匙都会立即删除固态硬盘（SSD）上的无用数据

为了完成身份验证，ORWL 有一个使用和智能卡类似技术的密匙卡。它使用 NFC 技术来验证用户，同时使用蓝牙来检测用户是否在当前使用范围内。如果用户不在附近（不在使用范围内），ORWL 将会自动锁定。

整个 ORWL 系统被包裹在一个到处伴有压力开关的活动翻盖网格里。安全微控制器持续监控专用惯性测量部件，活动翻盖网格，内部温度和电源输入电压，以用于检测篡改。这将防止访问内部组件，比如试图破坏翻盖将会触发安全微控制器从而删除加密密匙。此外，出于安全考虑，动态随机存储器（DRAM）也焊有外壳。

这并不是全部安全防护措施，ORWL 还有更多详细的措施来确保设备绝对的物理安全性，包括冷启动防护，直接存储器访问（DMA）攻击防御等。

更多信息可以在 [ORWL 引导页](https://www.orwl.org/)找到。这儿是一个关于它如何工作的快速视频。

### ORWL 是信息安全的最终答案吗？

令人沮丧的是，ORWL 并不是信息安全的最终答案。ORWL 只能为计算机提供物理安全，尽管这很强大并且看起来<ruby> 极酷 <rp>  （ </rp> <rt>  totally ninja </rt> <rp>  ） </rp></ruby>，但是还有许多来自其他方面的攻击会损坏你的系统。然而，ORWL 确实从整体上提高了计算机的安全性。

你认为 ORWL 怎么样？通过评论让我们知道你的想法。

---

via: <https://itsfoss.com/orwl-physically-secure-computer/>

作者：[Munif Tanjim](https://itsfoss.com/author/munif/) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


构建你的数据科学作品集：机器学习项目

Summary: 数据科学公司在决定雇佣时越来越关注你在数据科学方面的作品集。这其中的一个原因是，这样的作品集是判断某人的实际技能的最好的方法。好消息是构建这样的作品集完全要看你自己。只要你在这方面付出了努力，你一定可以取得让这些公司钦佩的作品集。

这篇文章翻译的真不容易，感谢组长……

很赞！！！

# 构建你的数据科学作品集：机器学习项目

>
> 这是[这个系列](https://www.dataquest.io/blog/data-science-portfolio-project/)发布的第三篇关于如何构建数据<ruby> 科学作品集 <rp>  （ </rp> <rt>  Data Science Portfolio </rt> <rp>  ） </rp></ruby>的文章。如果你喜欢这个系列并且想继续关注，你可以在订阅页面的底部找到[链接](https://www.dataquest.io/blog/data-science-portfolio-machine-learning/#email-signup)。
>
>
>

数据科学公司在决定雇佣时越来越关注你在数据科学方面的<ruby> 作品集 <rp>  （ </rp> <rt>  Portfolio </rt> <rp>  ） </rp></ruby>。这其中的一个原因是，这样的作品集是判断某人的实际技能的最好的方法。好消息是构建这样的作品集完全要看你自己。只要你在这方面付出了努力，你一定可以取得让这些公司钦佩的作品集。

构建高质量的作品集的第一步就是知道需要什么技能。公司想要在数据科学方面拥有的、他们希望你能够运用的主要技能有：

* 沟通能力
* 协作能力
* 技术能力
* 数据推理能力
* 动机和主动性

任何好的作品集都由多个项目表现出来，其中每个都能够表现出以上一到两点。这是本系列的第三篇，本系列我们主要讲包括如何打造面面俱到的数据科学作品集。在这一篇中，我们主要涵盖了如何构建组成你的作品集的第二个项目，以及如何创建一个端对端的机器学习项目。在最后，我们将拥有一个展示你的数据推理能力和技术能力的项目。如果你想看一下的话，[这里](https://github.com/dataquestio/loan-prediction)有一个完整的例子。

### 一个端到端的项目

作为一个数据科学家，有时候你会拿到一个数据集并被问如何[用它来讲故事](https://www.dataquest.io/blog/data-science-portfolio-project/)。在这个时候，沟通就是非常重要的，你需要用它来完成这个事情。像我们在前一篇文章中用过的，类似 Jupyter notebook 这样的工具，将对你非常有帮助。在这里你能找到一些可以用的报告或者总结文档。

不管怎样，有时候你会被要求创建一个具有操作价值的项目。具有操作价值的项目将直接影响到公司的日常业务，它会使用不止一次，经常是许多人使用。这个任务可能像这样 “创建一个算法来预测周转率”或者“创建一个模型来自动对我们的文章打标签”。在这种情况下，技术能力比讲故事更重要。你必须能够得到一个数据集，并且理解它，然后创建脚本处理该数据。这个脚本要运行的很快，占用系统资源很小。通常它可能要运行很多次，脚本的可使用性也很重要，并不仅仅是一个演示版。可使用性是指整合进操作流程，并且甚至是是面向用户的。

端对端项目的主要组成部分:

* 理解背景
* 浏览数据并找出细微差别
* 创建结构化项目，那样比较容易整合进操作流程
* 运行速度快、占用系统资源小的高性能代码
* 写好安装和使用文档以便其他人用

为了有效的创建这种类型的项目，我们可能需要处理多个文件。强烈推荐使用 [Atom](https://atom.io/) 这样的文本编辑器或者 [PyCharm](https://www.jetbrains.com/pycharm/) 这样的 IDE。这些工具允许你在文件间跳转，编辑不同类型的文件，例如 markdown 文件，Python 文件，和 csv 文件等等。结构化你的项目还利于版本控制，并上传一个类似 [Github](https://github.com/) 这样的协作开发工具上也很有用。

*Github 上的这个项目*

在这一节中我们将使用 [Pandas](http://pandas.pydata.org/) 和 [scikit-learn](http://scikit-learn.org/) 这样的库，我们还将大量用到 Pandas [DataFrames](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html)，它使得 python 读取和处理表格数据更加方便。

### 找到好的数据集

为一个端到端的作品集项目的找到好的数据集很难。在内存和性能的限制下，数据集需要尽量的大。它还需要是实际有用的。例如，[这个数据集](https://collegescorecard.ed.gov/data/)，它包含有美国院校的录取标准、毕业率以及毕业以后的收入，是个很好的可以讲故事的数据集。但是，不管你如何看待这个数据，很显然它不适合创建端到端的项目。比如，你能告诉人们他们去了这些大学以后的未来收入，但是这个快速检索却并不足够呈现出你的技术能力。你还能找出院校的招生标准和更高的收入相关，但是这更像是常理而不是你的技术结论。

这里还有内存和性能约束的问题，比如你有几千兆的数据，而且当你需要找到一些差异时，就需要对数据集一遍遍运行算法。

一个好的可操作的数据集可以让你构建一系列脚本来转换数据、动态地回答问题。一个很好的例子是股票价格数据集，当股市关闭时，就会给算法提供新的数据。这可以让你预测明天的股价，甚至预测收益。这不是讲故事，它带来的是真金白银。

一些找到数据集的好地方：

* [/r/datasets](https://reddit.com/r/datasets) – 有上百的有趣数据的 subreddit（Reddit 是国外一个社交新闻站点，subreddit 指该论坛下的各不同版块）。
* [Google Public Datasets](https://cloud.google.com/bigquery/public-data/#usa-names) – 通过 Google BigQuery 使用的公开数据集。
* [Awesome datasets](https://github.com/caesar0301/awesome-public-datasets) – 一个数据集列表，放在 Github 上。

当你查看这些数据集时，想一下人们想要在这些数据集中得到什么答案，哪怕这些问题只想过一次（“房价是如何与标准普尔 500 指数关联的?”），或者更进一步（“你能预测股市吗?”）。这里的关键是更进一步地找出问题，并且用相同的代码在不同输入（不同的数据）上运行多次。

对于本文的目标，我们来看一下 <ruby> 房利美 <rp>  （ </rp> <rt>  Fannie Mae </rt> <rp>  ） </rp></ruby>[贷款数据](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html)。房利美是一家在美国的政府赞助的企业抵押贷款公司，它从其他银行购买按揭贷款，然后捆绑这些贷款为贷款证券来转卖它们。这使得贷款机构可以提供更多的抵押贷款，在市场上创造更多的流动性。这在理论上会带来更多的住房和更好的贷款期限。从借款人的角度来说，它们大体上差不多，话虽这样说。

房利美发布了两种类型的数据 – 它获得的贷款的数据，和贷款偿还情况的数据。在理想的情况下，有人向贷款人借钱，然后还款直到还清。不管怎样，有些人多次不还，从而丧失了抵押品赎回权。抵押品赎回权是指没钱还了被银行把房子给收走了。房利美会追踪谁没还钱，并且哪个贷款需要收回抵押的房屋（取消赎回权）。每个季度会发布此数据，发布的是滞后一年的数据。当前可用是 2015 年第一季度数据。

“贷款数据”是由房利美发布的贷款发放的数据，它包含借款人的信息、信用评分，和他们的家庭贷款信息。“执行数据”，贷款发放后的每一个季度公布，包含借贷人的还款信息和是否丧失抵押品赎回权的状态，一个“贷款数据”的“执行数据”可能有十几行。可以这样理解，“贷款数据”告诉你房利美所控制的贷款，“执行数据”包含该贷款一系列的状态更新。其中一个状态更新可以告诉我们一笔贷款在某个季度被取消赎回权了。

*一个没有及时还贷的房子就这样的被卖了*

### 选择一个角度

这里有几个我们可以去分析房利美数据集的方向。我们可以：

* 预测房屋的销售价格。
* 预测借款人还款历史。
* 在获得贷款时为每一笔贷款打分。

最重要的事情是坚持单一的角度。同时关注太多的事情很难做出效果。选择一个有着足够细节的角度也很重要。下面的角度就没有太多细节：

* 找出哪些银行将贷款出售给房利美的多数被取消赎回权。
* 计算贷款人的信用评分趋势。
* 找到哪些类型的家庭没有偿还贷款的能力。
* 找到贷款金额和抵押品价格之间的关系。

上面的想法非常有趣，如果我们关注于讲故事，那是一个不错的角度，但是不是很适合一个操作性项目。

在房利美数据集中，我们将仅使用申请贷款时有的那些信息来预测贷款是否将来会被取消赎回权。实际上, 我们将为每一笔贷款建立“分数”来告诉房利美买还是不买。这将给我们打下良好的基础，并将组成这个漂亮的作品集的一部分。

### 理解数据

我们来简单看一下原始数据文件。下面是 2012 年 1 季度前几行的贷款数据：

```
100000853384|R|OTHER|4.625|280000|360|02/2012|04/2012|31|31|1|23|801|N|C|SF|1|I|CA|945||FRM|
100003735682|R|SUNTRUST MORTGAGE INC.|3.99|466000|360|01/2012|03/2012|80|80|2|30|794|N|P|SF|1|P|MD|208||FRM|788
100006367485|C|PHH MORTGAGE CORPORATION|4|229000|360|02/2012|04/2012|67|67|2|36|802|N|R|SF|1|P|CA|959||FRM|794

```

下面是 2012 年 1 季度的前几行执行数据：

```
100000853384|03/01/2012|OTHER|4.625||0|360|359|03/2042|41860|0|N||||||||||||||||
100000853384|04/01/2012||4.625||1|359|358|03/2042|41860|0|N||||||||||||||||
100000853384|05/01/2012||4.625||2|358|357|03/2042|41860|0|N||||||||||||||||

```

在开始编码之前，花些时间真正理解数据是值得的。这对于操作性项目优为重要，因为我们没有交互式探索数据，将很难察觉到细微的差别，除非我们在前期发现他们。在这种情况下，第一个步骤是阅读房利美站点的资料：

* [概述](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html)
* [有用的术语表](https://loanperformancedata.fanniemae.com/lppub-docs/lppub_glossary.pdf)
* [常见问答](https://loanperformancedata.fanniemae.com/lppub-docs/lppub_faq.pdf)
* [贷款和执行文件中的列](https://loanperformancedata.fanniemae.com/lppub-docs/lppub_file_layout.pdf)
* [贷款数据文件样本](https://loanperformancedata.fanniemae.com/lppub-docs/acquisition-sample-file.txt)
* [执行数据文件样本](https://loanperformancedata.fanniemae.com/lppub-docs/performance-sample-file.txt)

在看完这些文件后后，我们了解到一些能帮助我们的关键点：

* 从 2000 年到现在，每季度都有一个贷款和执行文件，因数据是滞后一年的，所以到目前为止最新数据是 2015 年的。
* 这些文件是文本格式的，采用管道符号`|`进行分割。
* 这些文件是没有表头的，但我们有个文件列明了各列的名称。
* 所有一起，文件包含 2200 万个贷款的数据。
* 由于执行数据的文件包含过去几年获得的贷款的信息，在早些年获得的贷款将有更多的执行数据（即在 2014 获得的贷款没有多少历史执行数据）。

这些小小的信息将会为我们节省很多时间，因为这样我们就知道如何构造我们的项目和利用这些数据了。

### 构造项目

在我们开始下载和探索数据之前，先想一想将如何构造项目是很重要的。当建立端到端项目时，我们的主要目标是：

* 创建一个可行解决方案
* 有一个快速运行且占用最小资源的解决方案
* 容易可扩展
* 写容易理解的代码
* 写尽量少的代码

为了实现这些目标，需要对我们的项目进行良好的构造。一个结构良好的项目遵循几个原则：

* 分离数据文件和代码文件
* 从原始数据中分离生成的数据。
* 有一个 `README.md` 文件帮助人们安装和使用该项目。
* 有一个 `requirements.txt` 文件列明项目运行所需的所有包。
* 有一个单独的 `settings.py` 文件列明其它文件中使用的所有的设置
	+ 例如，如果从多个 `Python` 脚本读取同一个文件，让它们全部 `import` 设置并从一个集中的地方获得文件名是有用的。
* 有一个 `.gitignore` 文件，防止大的或密码文件被提交。
* 分解任务中每一步可以单独执行的步骤到单独的文件中。
	+ 例如，我们将有一个文件用于读取数据，一个用于创建特征，一个用于做出预测。
* 保存中间结果，例如，一个脚本可以输出下一个脚本可读取的文件。
	+ 这使我们无需重新计算就可以在数据处理流程中进行更改。

我们的文件结构大体如下：

```
loan-prediction
├── data
├── processed
├── .gitignore
├── README.md
├── requirements.txt
├── settings.py

```

### 创建初始文件

首先，我们需要创建一个 `loan-prediction` 文件夹，在此文件夹下面，再创建一个 `data` 文件夹和一个 `processed` 文件夹。`data` 文件夹存放原始数据，`processed` 文件夹存放所有的中间计算结果。

其次，创建 `.gitignore` 文件，`.gitignore` 文件将保证某些文件被 git 忽略而不会被推送至 GitHub。关于这个文件的一个好的例子是由 OSX 在每一个文件夹都会创建的 `.DS_Store` 文件，`.gitignore` 文件一个很好的范本在[这里](https://github.com/github/gitignore/blob/master/Python.gitignore)。我们还想忽略数据文件，因为它们实在是太大了，同时房利美的条文禁止我们重新分发该数据文件，所以我们应该在我们的文件后面添加以下 2 行：

```
data
processed

```

[这里](https://github.com/dataquestio/loan-prediction/blob/master/.gitignore)是该项目的一个关于 .gitignore 文件的例子。

再次，我们需要创建 `README.md` 文件，它将帮助人们理解该项目。后缀 .md 表示这个文件采用 markdown 格式。Markdown 使你能够写纯文本文件，同时还可以添加你想要的神奇的格式。[这里](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)是关于 markdown 的导引。如果你上传一个叫 `README.md` 的文件至 Github，Github 会自动处理该 markdown，同时展示给浏览该项目的人。例子在[这里](https://github.com/dataquestio/loan-prediction)。

至此，我们仅需在 `README.md` 文件中添加简单的描述：

```
Loan Prediction
-----------------------

Predict whether or not loans acquired by Fannie Mae will go into foreclosure.  Fannie Mae acquires loans from other lenders as a way of inducing them to lend more.  Fannie Mae releases data on the loans it has acquired and their performance afterwards [here](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html).

```

现在，我们可以创建 `requirements.txt` 文件了。这会帮助其它人可以很方便地安装我们的项目。我们还不知道我们将会具体用到哪些库，但是以下几个库是需要的：

```
pandas
matplotlib
scikit-learn
numpy
ipython
scipy

```

以上几个是在 python 数据分析任务中最常用到的库。可以认为我们将会用到大部分这些库。[这里](https://github.com/dataquestio/loan-prediction/blob/master/requirements.txt)是该项目 `requirements.txt` 文件的一个例子。

创建 `requirements.txt` 文件之后，你应该安装这些包了。我们将会使用 python3。如果你没有安装 python，你应该考虑使用 [Anaconda](https://www.continuum.io/downloads)，它是一个 python 安装程序，同时安装了上面列出的所有包。

最后，我们可以建立一个空白的 `settings.py` 文件，因为我们的项目还没有任何设置。

### 获取数据

一旦我们有了项目的基本架构，我们就可以去获得原始数据。

房利美对获取数据有一些限制，所以你需要去注册一个账户。在创建完账户之后，你可以找到[在这里](https://loanperformancedata.fanniemae.com/lppub/index.html)的下载页面，你可以按照你所需要的下载或多或少的贷款数据文件。文件格式是 zip，在解压后当然是非常大的。

为了达到我们这个文章的目的，我们将要下载从 2012 年 1 季度到 2015 年 1 季度的所有数据。接着我们需要解压所有的文件。解压过后，删掉原来的 .zip 格式的文件。最后，loan-prediction 文件夹看起来应该像下面的一样：

```
loan-prediction
├── data
│   ├── Acquisition_2012Q1.txt
│   ├── Acquisition_2012Q2.txt
│   ├── Performance_2012Q1.txt
│   ├── Performance_2012Q2.txt
│   └── ...
├── processed
├── .gitignore
├── README.md
├── requirements.txt
├── settings.py

```

在下载完数据后，你可以在 shell 命令行中使用 `head` 和 `tail` 命令去查看文件中的行数据，你看到任何的不需要的数据列了吗？在做这件事的同时查阅[列名称的 pdf 文件](https://loanperformancedata.fanniemae.com/lppub-docs/lppub_file_layout.pdf)可能有帮助。

### 读入数据

有两个问题让我们的数据难以现在就使用：

* 贷款数据和执行数据被分割在多个文件中
* 每个文件都缺少列名标题

在我们开始使用数据之前，我们需要首先明白我们要在哪里去存一个贷款数据的文件，同时到哪里去存储一个执行数据的文件。每个文件仅仅需要包括我们关注的那些数据列，同时拥有正确的列名标题。这里有一个小问题是执行数据非常大，因此我们需要尝试去修剪一些数据列。

第一步是向 `settings.py` 文件中增加一些变量，这个文件中同时也包括了我们原始数据的存放路径和处理出的数据存放路径。我们同时也将添加其他一些可能在接下来会用到的设置数据：

```
DATA_DIR = "data"
PROCESSED_DIR = "processed"
MINIMUM_TRACKING_QUARTERS = 4
TARGET = "foreclosure_status"
NON_PREDICTORS = [TARGET, "id"]
CV_FOLDS = 3

```

把路径设置在 `settings.py` 中使它们放在一个集中的地方，同时使其修改更加的容易。当在多个文件中用到相同的变量时，你想改变它的话，把他们放在一个地方比分散放在每一个文件时更加容易。[这里的](https://github.com/dataquestio/loan-prediction/blob/master/settings.py)是一个这个工程的示例 `settings.py` 文件

第二步是创建一个文件名为 `assemble.py`，它将所有的数据分为 2 个文件。当我们运行 `Python assemble.py`，我们在处理数据文件的目录会获得 2 个数据文件。

接下来我们开始写 `assemble.py` 文件中的代码。首先我们需要为每个文件定义相应的列名标题，因此我们需要查看[列名称的 pdf 文件](https://loanperformancedata.fanniemae.com/lppub-docs/lppub_file_layout.pdf)，同时创建在每一个贷款数据和执行数据的文件的数据列的列表：

```
HEADERS = {
    "Acquisition": [
        "id",
        "channel",
        "seller",
        "interest_rate",
        "balance",
        "loan_term",
        "origination_date",
        "first_payment_date",
        "ltv",
        "cltv",
        "borrower_count",
        "dti",
        "borrower_credit_score",
        "first_time_homebuyer",
        "loan_purpose",
        "property_type",
        "unit_count",
        "occupancy_status",
        "property_state",
        "zip",
        "insurance_percentage",
        "product_type",
        "co_borrower_credit_score"
    ],
    "Performance": [
        "id",
        "reporting_period",
        "servicer_name",
        "interest_rate",
        "balance",
        "loan_age",
        "months_to_maturity",
        "maturity_date",
        "msa",
        "delinquency_status",
        "modification_flag",
        "zero_balance_code",
        "zero_balance_date",
        "last_paid_installment_date",
        "foreclosure_date",
        "disposition_date",
        "foreclosure_costs",
        "property_repair_costs",
        "recovery_costs",
        "misc_costs",
        "tax_costs",
        "sale_proceeds",
        "credit_enhancement_proceeds",
        "repurchase_proceeds",
        "other_foreclosure_proceeds",
        "non_interest_bearing_balance",
        "principal_forgiveness_balance"
    ]
}

```

接下来一步是定义我们想要保留的数据列。因为我们要预测一个贷款是否会被撤回，我们可以丢弃执行数据中的许多列。我们将需要保留贷款数据中的所有数据列，因为我们需要尽量多的了解贷款发放时的信息（毕竟我们是在预测贷款发放时这笔贷款将来是否会被撤回）。丢弃数据列将会使我们节省下内存和硬盘空间，同时也会加速我们的代码。

```
SELECT = {
    "Acquisition": HEADERS["Acquisition"],
    "Performance": [
        "id",
        "foreclosure_date"
    ]
}

```

下一步，我们将编写一个函数来连接数据集。下面的代码将：

* 引用一些需要的库，包括 `settings`。
* 定义一个函数 `concatenate`，目的是：
	+ 获取到所有 `data` 目录中的文件名。
	+ 遍历每个文件。
		- 如果文件不是正确的格式 (不是以我们需要的格式作为开头)，我们将忽略它。
		- 通过使用 Pandas 的 [read\_csv](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) 函数及正确的设置把文件读入一个 [DataFrame](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html)。
			* 设置分隔符为`｜`，以便所有的字段能被正确读出。
			* 数据没有标题行，因此设置 `header` 为 `None` 来进行标示。
			* 从 `HEADERS` 字典中设置正确的标题名称 – 这将会是我们的 DataFrame 中的数据列名称。
			* 仅选择我们加在 `SELECT` 中的 DataFrame 的列。
* 把所有的 DataFrame 共同连接在一起。
* 把已经连接好的 DataFrame 写回一个文件。

```
import os
import settings
import pandas as pd

def concatenate(prefix="Acquisition"):
    files = os.listdir(settings.DATA_DIR)
    full = []
    for f in files:
        if not f.startswith(prefix):
            continue

        data = pd.read_csv(os.path.join(settings.DATA_DIR, f), sep="|", header=None, names=HEADERS[prefix], index_col=False)
        data = data[SELECT[prefix]]
        full.append(data)

    full = pd.concat(full, axis=0)

    full.to_csv(os.path.join(settings.PROCESSED_DIR, "{}.txt".format(prefix)), sep="|", header=SELECT[prefix], index=False)

```

我们可以通过调用上面的函数，通过传递的参数 `Acquisition` 和 `Performance` 两次以将所有的贷款和执行文件连接在一起。下面的代码将：

* 仅在命令行中运行 `python assemble.py` 时执行。
* 将所有的数据连接在一起，并且产生 2 个文件：
	+ `processed/Acquisition.txt`
	+ `processed/Performance.txt`

```
if __name__ == "__main__":
    concatenate("Acquisition")
    concatenate("Performance")

```

我们现在拥有了一个漂亮的，划分过的 `assemble.py` 文件，它很容易执行，也容易建立。通过像这样把问题分解为一块一块的，我们构建工程就会变的容易许多。不用一个可以做所有工作的凌乱脚本，我们定义的数据将会在多个脚本间传递，同时使脚本间完全的彼此隔离。当你正在一个大的项目中工作时，这样做是一个好的想法，因为这样可以更加容易修改其中的某一部分而不会引起其他项目中不关联部分产生预料之外的结果。

一旦我们完成 `assemble.py` 脚本文件，我们可以运行 `python assemble.py` 命令。你可以[在这里](https://github.com/dataquestio/loan-prediction/blob/master/assemble.py)查看完整的 `assemble.py` 文件。

这将会在 `processed` 目录下产生 2 个文件：

```
loan-prediction
├── data
│   ├── Acquisition_2012Q1.txt
│   ├── Acquisition_2012Q2.txt
│   ├── Performance_2012Q1.txt
│   ├── Performance_2012Q2.txt
│   └── ...
├── processed
│   ├── Acquisition.txt
│   ├── Performance.txt
├── .gitignore
├── assemble.py
├── README.md
├── requirements.txt
├── settings.py

```

### 计算来自执行数据的值

接下来我们会计算来自 `processed/Performance.txt` 中的值。我们要做的就是推测这些资产是否被取消赎回权。如果能够计算出来，我们只要看一下关联到贷款的执行数据的参数 `foreclosure_date` 就可以了。如果这个参数的值是 `None`，那么这些资产肯定没有收回。为了避免我们的样例中只有少量的执行数据，我们会为每个贷款计算出执行数据文件中的行数。这样我们就能够从我们的训练数据中筛选出贷款数据，排除了一些执行数据。

下面是我认为贷款数据和执行数据的关系：

在上面的表格中，贷款数据中的每一行数据都关联到执行数据中的多行数据。在执行数据中，在取消赎回权的时候 `foreclosure_date` 就会出现在该季度，而之前它是空的。一些贷款还没有被取消赎回权，所以与执行数据中的贷款数据有关的行在 `foreclosure_date` 列都是空格。

我们需要计算 `foreclosure_status` 的值，它的值是布尔类型，可以表示一个特殊的贷款数据 `id` 是否被取消赎回权过，还有一个参数 `performance_count` ，它记录了执行数据中每个贷款 `id` 出现的行数。

计算这些行数有多种不同的方法：

* 我们能够读取所有的执行数据，然后我们用 Pandas 的 [groupby](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html) 方法在 DataFrame 中计算出与每个贷款 `id` 有关的行的行数，然后就可以查看贷款 `id` 的 `foreclosure_date` 值是否为 `None` 。
	+ 这种方法的优点是从语法上来说容易执行。
	+ 它的缺点需要读取所有的 129236094 行数据，这样就会占用大量内存，并且运行起来极慢。
* 我们可以读取所有的执行数据，然后在贷款 DataFrame 上使用 [apply](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html) 去计算每个贷款 `id`　出现的次数。
	+ 这种方法的优点是容易理解。
	+ 缺点是需要读取所有的 129236094 行数据。这样会占用大量内存，并且运行起来极慢。
* 我们可以在迭代访问执行数据中的每一行数据，而且会建立一个单独的计数字典。
	+ 这种方法的优点是数据不需要被加载到内存中，所以运行起来会很快且不需要占用内存。
	+ 缺点是这样的话理解和执行上可能有点耗费时间，我们需要对每一行数据进行语法分析。

加载所有的数据会非常耗费内存，所以我们采用第三种方法。我们要做的就是迭代执行数据中的每一行数据，然后为每一个贷款 `id` 在字典中保留一个计数。在这个字典中，我们会计算出贷款 `id` 在执行数据中出现的次数，而且看看 `foreclosure_date` 是否是 `None` 。我们可以查看 `foreclosure_status` 和 `performance_count` 的值 。

我们会新建一个 `annotate.py` 文件，文件中的代码可以计算这些值。我们会使用下面的代码：

* 导入需要的库
* 定义一个函数 `count_performance_rows` 。
	+ 打开 `processed/Performance.txt` 文件。这不是在内存中读取文件而是打开了一个文件标识符，这个标识符可以用来以行为单位读取文件。
	+ 迭代文件的每一行数据。
	+ 使用分隔符`|`分开每行的不同数据。
	+ 检查 `loan_id` 是否在计数字典中。
		- 如果不存在，把它加进去。
	+ `loan_id` 的 `performance_count` 参数自增 1 次，因为我们这次迭代也包含其中。
	+ 如果 `date` 不是 `None ，我们就会知道贷款被取消赎回权了，然后为`foreclosure\_status` 设置合适的值。

```
import os
import settings
import pandas as pd

def count_performance_rows():
    counts = {}
    with open(os.path.join(settings.PROCESSED_DIR, "Performance.txt"), 'r') as f:
        for i, line in enumerate(f):
            if i == 0:
                # Skip header row
                continue
            loan_id, date = line.split("|")
            loan_id = int(loan_id)
            if loan_id not in counts:
                counts[loan_id] = {
                    "foreclosure_status": False,
                    "performance_count": 0
                }
            counts[loan_id]["performance_count"] += 1
            if len(date.strip()) > 0:
                counts[loan_id]["foreclosure_status"] = True
    return counts

```

### 获取值

只要我们创建了计数字典，我们就可以使用一个函数通过一个 `loan_id` 和一个 `key` 从字典中提取到需要的参数的值：

```
def get_performance_summary_value(loan_id, key, counts):
    value = counts.get(loan_id, {
        "foreclosure_status": False,
        "performance_count": 0
    })
    return value[key]

```

上面的函数会从 `counts` 字典中返回合适的值，我们也能够为贷款数据中的每一行赋一个 `foreclosure_status` 值和一个 `performance_count` 值。如果键不存在，字典的 [get](https://docs.python.org/3/library/stdtypes.html#dict.get) 方法会返回一个默认值，所以在字典中不存在键的时候我们就可以得到一个可知的默认值。

### 转换数据

我们已经在 `annotate.py` 中添加了一些功能，现在我们来看一看数据文件。我们需要将贷款到的数据转换到训练数据集来进行机器学习算法的训练。这涉及到以下几件事情:

* 转换所有列为数字。
* 填充缺失值。
* 为每一行分配 `performance_count` 和 `foreclosure_status`。
* 移除出现执行数据很少的行（`performance_count` 计数低）。

我们有几个列是文本类型的，看起来对于机器学习算法来说并不是很有用。然而，它们实际上是分类变量，其中有很多不同的类别代码，例如 `R`，`S` 等等. 我们可以把这些类别标签转换为数值：

通过这种方法转换的列我们可以应用到机器学习算法中。

还有一些包含日期的列 (`first_payment_date` 和 `origination_date`）。我们可以将这些日期放到两个列中：

在下面的代码中，我们将转换贷款数据。我们将定义一个函数如下：

* 在 `acquisition` 中创建 `foreclosure_status` 列，并从 `counts` 字典中得到值。
* 在 `acquisition` 中创建 `performance_count` 列，并从 `counts` 字典中得到值。
* 将下面的列从字符串转换为整数：
	+ `channel`
	+ `seller`
	+ `first_time_homebuyer`
	+ `loan_purpose`
	+ `property_type`
	+ `occupancy_status`
	+ `property_state`
	+ `product_type`
* 将 `first_payment_date` 和 `origination_date` 分别转换为两列：
	+ 通过斜杠分离列。
	+ 将第一部分分离成 `month` 列。
	+ 将第二部分分离成 `year` 列。
	+ 删除该列。
	+ 最后，我们得到 `first_payment_month`、`first_payment_year`、`rigination_month` 和 `origination_year`。
* 所有缺失值填充为 `-1`。

```
def annotate(acquisition, counts):
    acquisition["foreclosure_status"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "foreclosure_status", counts))
    acquisition["performance_count"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "performance_count", counts))
    for column in [
        "channel",
        "seller",
        "first_time_homebuyer",
        "loan_purpose",
        "property_type",
        "occupancy_status",
        "property_state",
        "product_type"
    ]:
        acquisition[column] = acquisition[column].astype('category').cat.codes

    for start in ["first_payment", "origination"]:
        column = "{}_date".format(start)
        acquisition["{}_year".format(start)] = pd.to_numeric(acquisition[column].str.split('/').str.get(1))
        acquisition["{}_month".format(start)] = pd.to_numeric(acquisition[column].str.split('/').str.get(0))
        del acquisition[column]

    acquisition = acquisition.fillna(-1)
    acquisition = acquisition[acquisition["performance_count"] > settings.MINIMUM_TRACKING_QUARTERS]
    return acquisition

```

### 聚合到一起

我们差不多准备就绪了，我们只需要再在 `annotate.py` 添加一点点代码。在下面代码中，我们将：

* 定义一个函数来读取贷款的数据。
* 定义一个函数来写入处理过的数据到 `processed/train.csv`。
* 如果该文件在命令行以 `python annotate.py` 的方式运行：
	+ 读取贷款数据。
	+ 计算执行数据的计数，并将其赋予 `counts`。
	+ 转换 `acquisition` DataFrame。
	+ 将`acquisition` DataFrame 写入到 `train.csv`。

```
def read():
    acquisition = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "Acquisition.txt"), sep="|")
    return acquisition

def write(acquisition):
    acquisition.to_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"), index=False)

if __name__ == "__main__":
    acquisition = read()
    counts = count_performance_rows()
    acquisition = annotate(acquisition, counts)
    write(acquisition)

```

修改完成以后，确保运行 `python annotate.py` 来生成 `train.csv` 文件。 你可以在[这里](https://github.com/dataquestio/loan-prediction/blob/master/annotate.py)找到完整的 `annotate.py` 文件。

现在文件夹看起来应该像这样：

```
loan-prediction
├── data
│   ├── Acquisition_2012Q1.txt
│   ├── Acquisition_2012Q2.txt
│   ├── Performance_2012Q1.txt
│   ├── Performance_2012Q2.txt
│   └── ...
├── processed
│   ├── Acquisition.txt
│   ├── Performance.txt
│   ├── train.csv
├── .gitignore
├── annotate.py
├── assemble.py
├── README.md
├── requirements.txt
├── settings.py

```

### 找到误差标准

我们已经完成了训练数据表的生成，现在我们需要最后一步，生成预测。我们需要找到误差的标准，以及该如何评估我们的数据。在这种情况下，因为有很多的贷款没有被取消赎回权，所以根本不可能做到精确的计算。

我们需要读取训练数据，并且计算 `foreclosure_status` 列的计数，我们将得到如下信息：

```
import pandas as pd
import settings

train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"))
train["foreclosure_status"].value_counts()

```

```
False    4635982
True        1585
Name: foreclosure_status, dtype: int64

```

因为只有很少的贷款被取消赎回权，只需要检查正确预测的标签的百分比就意味着我们可以创建一个机器学习模型，来为每一行预测 `False`，并能取得很高的精确度。相反，我们想要使用一个度量来考虑分类的不平衡，确保我们可以准确预测。我们要避免太多的误报率（预测贷款被取消赎回权，但是实际没有），也要避免太多的漏报率（预测贷款没有别取消赎回权，但是实际被取消了）。对于这两个来说，漏报率对于房利美来说成本更高，因为他们买的贷款可能是他们无法收回投资的贷款。

所以我们将定义一个漏报率，就是模型预测没有取消赎回权但是实际上取消了，这个数除以总的取消赎回权数。这是“缺失的”实际取消赎回权百分比的模型。下面看这个图表：

通过上面的图表，有 1 个贷款预测不会取消赎回权，但是实际上取消了。如果我们将这个数除以实际取消赎回权的总数 2，我们将得到漏报率 50%。 我们将使用这个误差标准，因此我们可以评估一下模型的行为。

### 设置机器学习分类器

我们使用交叉验证预测。通过交叉验证法，我们将数据分为3组。按照下面的方法来做：

* 用组 1 和组 2 训练模型，然后用该模型来预测组 3
* 用组 1 和组 3 训练模型，然后用该模型来预测组 2
* 用组 2 和组 3 训练模型，然后用该模型来预测组 1

将它们分割到不同的组，这意味着我们永远不会用相同的数据来为其预测训练模型。这样就避免了过拟合。如果过拟合，我们将错误地拉低了漏报率，这使得我们难以改进算法或者应用到现实生活中。

[Scikit-learn](http://scikit-learn.org/) 有一个叫做 [cross*val*predict](http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.cross_val_predict.html) ，它可以帮助我们理解交叉算法.

我们还需要一种算法来帮我们预测。我们还需要一个分类器来做[二元分类](https://en.wikipedia.org/wiki/Binary_classification)。目标变量 `foreclosure_status` 只有两个值， `True` 和 `False`。

这里我们用 [逻辑回归算法](https://en.wikipedia.org/wiki/Logistic_regression)，因为它能很好的进行二元分类，并且运行很快，占用内存很小。我们来说一下它是如何工作的：不使用像随机森林一样多树结构，也不像支持向量机一样做复杂的转换，逻辑回归算法涉及更少的步骤和更少的矩阵。

我们可以使用 scikit-learn 实现的[逻辑回归分类器](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)算法。我们唯一需要注意的是每个类的权重。如果我们使用等权重的类，算法将会预测每行都为 `false`，因为它总是试图最小化误差。不管怎样，我们重视有多少贷款要被取消赎回权而不是有多少不能被取消。因此，我们给[逻辑回归](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)类的 `class_weight` 关键字传递 `balanced` 参数，让算法可以为不同 counts 的每个类考虑不同的取消赎回权的权重。这将使我们的算法不会为每一行都预测 `false`，而是两个类的误差水平一致。

### 做出预测

既然完成了前期准备，我们可以开始准备做出预测了。我将创建一个名为 `predict.py` 的新文件，它会使用我们在最后一步创建的 `train.csv` 文件。下面的代码：

* 导入所需的库
* 创建一个名为 `cross_validate` 的函数：
	+ 使用正确的关键词参数创建逻辑回归分类器
	+ 创建用于训练模型的数据列的列表，移除 `id` 和 `foreclosure_status` 列
	+ 交叉验证 `train` DataFrame
	+ 返回预测结果

```
import os
import settings
import pandas as pd
from sklearn import cross_validation
from sklearn.linear_model import LogisticRegression
from sklearn import metrics

def cross_validate(train):
    clf = LogisticRegression(random_state=1, class_weight="balanced")

    predictors = train.columns.tolist()
    predictors = [p for p in predictors if p not in settings.NON_PREDICTORS]

    predictions = cross_validation.cross_val_predict(clf, train[predictors], train[settings.TARGET], cv=settings.CV_FOLDS)
    return predictions

```

### 预测误差

现在，我们仅仅需要写一些函数来计算误差。下面的代码：

* 创建函数 `compute_error`：
	+ 使用 scikit-learn 计算一个简单的精确分数（与实际 `foreclosure_status` 值匹配的预测百分比）
* 创建函数 `compute_false_negatives`：
	+ 为了方便，将目标和预测结果合并到一个 DataFrame
	+ 查找漏报率
		- 找到原本应被预测模型取消赎回权，但实际没有取消的贷款数目
		- 除以没被取消赎回权的贷款总数目

```
def compute_error(target, predictions):
    return metrics.accuracy_score(target, predictions)

def compute_false_negatives(target, predictions):
    df = pd.DataFrame({"target": target, "predictions": predictions})
    return df[(df["target"] == 1) & (df["predictions"] == 0)].shape[0] / (df[(df["target"] == 1)].shape[0] + 1)

def compute_false_positives(target, predictions):
    df = pd.DataFrame({"target": target, "predictions": predictions})
    return df[(df["target"] == 0) & (df["predictions"] == 1)].shape[0] / (df[(df["target"] == 0)].shape[0] + 1)

```

### 聚合到一起

现在，我们可以把函数都放在 `predict.py`。下面的代码：

* 读取数据集
* 计算交叉验证预测
* 计算上面的 3 个误差
* 打印误差

```
def read():
    train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"))
    return train

if __name__ == "__main__":
    train = read()
    predictions = cross_validate(train)
    error = compute_error(train[settings.TARGET], predictions)
    fn = compute_false_negatives(train[settings.TARGET], predictions)
    fp = compute_false_positives(train[settings.TARGET], predictions)
    print("Accuracy Score: {}".format(error))
    print("False Negatives: {}".format(fn))
    print("False Positives: {}".format(fp))

```

一旦你添加完代码，你可以运行 `python predict.py` 来产生预测结果。运行结果向我们展示漏报率为 `.26`，这意味着我们没能预测 `26%` 的取消贷款。这是一个好的开始，但仍有很多改善的地方！

你可以在[这里](https://github.com/dataquestio/loan-prediction/blob/master/predict.py)找到完整的 `predict.py` 文件。

你的文件树现在看起来像下面这样：

```
loan-prediction
├── data
│   ├── Acquisition_2012Q1.txt
│   ├── Acquisition_2012Q2.txt
│   ├── Performance_2012Q1.txt
│   ├── Performance_2012Q2.txt
│   └── ...
├── processed
│   ├── Acquisition.txt
│   ├── Performance.txt
│   ├── train.csv
├── .gitignore
├── annotate.py
├── assemble.py
├── predict.py
├── README.md
├── requirements.txt
├── settings.py

```

### 撰写 README

既然我们完成了端到端的项目，那么我们可以撰写 `README.md` 文件了，这样其他人便可以知道我们做的事，以及如何复制它。一个项目典型的 `README.md` 应该包括这些部分：

* 一个高水准的项目概览，并介绍项目目的
* 任何必需的数据和材料的下载地址
* 安装命令
	+ 如何安装要求依赖
* 使用命令
	+ 如何运行项目
	+ 每一步之后会看到的结果
* 如何为这个项目作贡献
	+ 扩展项目的下一步计划

[这里](https://github.com/dataquestio/loan-prediction/blob/master/README.md) 是这个项目的一个 `README.md` 样例。

### 下一步

恭喜你完成了端到端的机器学习项目！你可以在[这里](https://github.com/dataquestio/loan-prediction)找到一个完整的示例项目。一旦你完成了项目，把它上传到 [Github](https://www.github.com/) 是一个不错的主意，这样其他人也可以看到你的文件夹的部分项目。

这里仍有一些留待探索数据的角度。总的来说，我们可以把它们分割为 3 类： 扩展这个项目并使它更加精确，发现其他可以预测的列，并探索数据。这是其中一些想法：

* 在 `annotate.py` 中生成更多的特性
* 切换 `predict.py` 中的算法
* 尝试使用比我们发表在这里的更多的房利美数据
* 添加对未来数据进行预测的方法。如果我们添加更多数据，我们所写的代码仍然可以起作用，这样我们可以添加更多过去和未来的数据。
* 尝试看看是否你能预测一个银行原本是否应该发放贷款（相对地，房利美是否应该获得贷款）
	+ 移除 `train` 中银行在发放贷款时间的不知道的任何列
		- 当房利美购买贷款时，一些列是已知的，但之前是不知道的
	+ 做出预测
* 探索是否你可以预测除了 `foreclosure_status` 的其他列
	+ 你可以预测在销售时资产值是多少？
* 探索探索执行数据更新之间的细微差别
	+ 你能否预测借款人会逾期还款多少次?
	+ 你能否标出的典型贷款周期?
* 将数据按州或邮政编码标出
	+ 你看到一些有趣的模式了吗?

如果你建立了任何有趣的东西,请在评论中让我们知道!

如果你喜欢这篇文章，或许你也会喜欢阅读“构建你的数据科学作品集”系列的其他文章：

* [用数据讲故事](https://www.dataquest.io/blog/data-science-portfolio-project/)
* [如何搭建一个数据科学博客](https://www.dataquest.io/blog/how-to-setup-a-data-science-blog/)
* [构建一个可以帮你找到工作的数据科学作品集的关键](https://www.dataquest.io/blog/build-a-data-science-portfolio/)
* [找到数据科学用的数据集的 17 个地方](https://www.dataquest.io/blog/free-datasets-for-projects)

---

via: <https://www.dataquest.io/blog/data-science-portfolio-machine-learning/>

作者：[Vik Paruchuri](https://www.dataquest.io/blog) 译者：[kokialoves](https://github.com/kokialoves), [zky001](https://github.com/zky001), [vim-kakali](https://github.com/vim-kakali), [cposture](https://github.com/cposture), [ideas4u](https://github.com/ideas4u) 校对：[wxy](https://github.com/wxy)

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


开发者的实用 Vim 插件（二）

这个插件确实不错，很及时的发现编写错误。只是在低配置的机器上，这个插件太重，影响vim的编辑速度。

顶上的图片很漂亮啊，从哪里弄的？

专业搜图小能手就是我——秘籍一：请善用搜索引擎。

非常不错的插件。~\(≧▽≦)/~

# 开发者的实用 Vim 插件（二）

毫无疑问，Vim 是一个开箱即用并能够胜任编程任务的编辑器，但实际上是该编辑器中的插件帮你实现这些方便的功能。在 [开发者的实用 Vim 插件（一）](/article-7901-1.html)，我们已经讨论两个编程相关的 Vim 插件——标签侧边栏（Tagbar）和定界符自动补齐（delimitMate）。作为相同系列，我们在本文讨论另一个非常有用、专门为软件开发正定制的插件——语法高亮插件。

请注意：本教程中列举的所有例示、命令和说明都是在 Ubuntu 16.04 环境下进行测试的，并且，我们使用的 Vim 版本是 7.4。

### 语法高亮（Syntastic）插件

假如你的软件开发工作涉及到 C/C++ 语言，毫无疑问的说，遇到编译错误也是你每天工作中的一部分。很多时候，编译错误是由源代码之中的语法不正确造成的，因为开发者在浏览源码的时候很少能够一眼就看出所有这些错误。

那么 Vim 中是否存在一种插件可以让你不经编译源码就可以显示出语法错误呢？当然是有这样一种插件的，其名字就是 Syntastic。

“Syntastic 是 Vim 用来检验语法的插件，通过外部语法校验器校验文件并将错误呈现给用户。该过程可以在需要时进行，或者在文件保存的时候自动进行。”该插件 [官方文档](https://github.com/scrooloose/syntastic) 如是说。“如果检测到语法错误就会提示用户，因为不用编译代码或者执行脚本就可以知道语法错误，用户也就乐享与此了。”

安装过程和第一部分提到的方法类似，你只需要运行下列命令即可：

```
cd ~/.vim/bundle/

git clone https://github.com/scrooloose/syntastic.git

```

一旦你成功安装这个插件（即上述命令执行成功），你就不需要进行任何配置了——当 Vim 启动时会自动加载这个插件。

现在，打开一个源码文件并用 `:w` Vim 命令保存即可使用这个插件了。等待片刻之后，如果在源码中有语法错误的好，就会高亮显示出来。比如，看看一下截图你就会明白该插件是如何高亮显示语法错误的：

在每行之前的 `>>` 表示该行中有语法错误。了解确切的错误或者想知道是什么东西错了，将光标移到该行——错误描述就会展示在 Vim 窗口的最底下。

这样，不用进行编译你就能够修复大多数语法相关的错误。

再往下，如果你运行 `:Errors` 命令，就会展现当前源文件中所有语法相关错误的描述。比如，我运行 `:Errors` 命令就是下图的效果：

请记住，`:Errors` 展现的语法错误是不会自动更新的，这意味着在你修复错误之后，你需要重新运行 `:Errors` 命令，编辑器底部的错误描述才会消除。

值得一提的是，还有 [许多配置选项](https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt) 能够使得 Syntastic 插件使用起来更加友好。比如，你可以在你的 `.vimrc` 中添加下列内容，然后 `:Errors` 就可以在修复错误之后自动更新它的底部描述。

```
let g:syntastic_always_populate_loc_list = 1

```

添加以下内容，以确保在你打开文件时 Syntastic 插件自动高亮显示错误。

```
let g:syntastic_check_on_open = 1

```

类似的，你也可以在保存或打开文件时让光标跳转到检测到的第一个问题处，将下列行放到你的 `.vimrc` 文件之中：

```
let g:syntastic_auto_jump = 1

```

这个值也可以指定为其它两个值： 2 和 3，其官方文档的解释如下：

“如果设置为 2 的话，光标就会跳到检测到的第一个问题，当然，只有这个问题是一个错误的时候才跳转；设置为 3 的话，如果存在错误，则会跳到第一个错误。所有检测到的问题都会有警告，但光标不会跳转。”

以下信息可能对你有帮助：

“使用 `:SyntasticCheck` 来手动检测错误。使用 `:Errors` 打开错误位置列表并使用 `:lclose` 来关闭。使用 `:SyntasticReset` 可以清除掉错误列表，使用 `:SyntasticToggleMode` 来切换激活（在写到 buffer 时检测）和被动（即手动检测）检测错误。”

注意：Syntastic 并不局限于 C/C++ 所写的代码，它同时也支持很多的编程语言——点击 [此处](https://github.com/scrooloose/syntastic) 了解更多相关信息。

### 结论

毫无疑问的，Syntastic 是一个非常有用的 Vim 插件，因为在出现语法相关错误时候，它至少能够让免去频繁编译的麻烦，而且不用说，同时也节约了你不少的时间。

正如你所看到的一样，配置好几个主要选项之后，Syntastic 变得非常好用了。为了帮助你了解这些设置，官方文档中包含了一份“推荐设置”——跟着文档进行设置即可。加入你遇到一些错误、有些疑问或者问题，你也可以查询一下 FAQ。

---

via: <https://www.howtoforge.com/tutorial/vim-editor-plugins-for-software-developers-2-syntastic/>

作者：[Ansh](https://www.howtoforge.com/tutorial/vim-editor-plugins-for-software-developers-2-syntastic/) 译者：[GHLandy](https://github.com/GHLandy) 校对：[wxy](https://github.com/wxy)

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


7 个 Linux 新手容易犯的错误

这些都不算什么，最可怕的还是墨守陈规，不敢尝试linux。此情况下，说什么都是0。

错误0：买了个双显卡的笔记本

错误-1：啊！这是DOS！

错误-2：这评论一排windows10用户。

错误

最尴尬的是，这样的linux文章，发表评论的都是windows用户～～～

其实最难的是迈出第一步，我帮很多朋友安装的了双系统，其中不乏程序猿，最终的结果是10个能有一个坚持下来就不错，大多数的理由都是没有QQ，没有LOL，Linux成了摆设，Linux的优势大家都知道，但是我实在是很难说服他们继续使用，真是太尴尬了。。。

错误－3，我看到公司里一堆在虚拟机里装ubuntu的

如果是纯技术宅的话，Linux 是不二的选择。只是大多数人都有其它的需求，所以 Linux 可能不是很适合那些人。

也许这是公司的电脑呢 233

已经用纯linux两年了

只在虚拟机里跑，算不算伪爱？

玩游戏的时候才想进win...

想试一试双系统

Charmony [Internet Explorer 10.0|Windows 7]

伪爱

不要尝试了，双系统没意思

我觉得在虚拟机中过渡比较好  纯属猎奇使用linux桌面不会长久  长期使用linux桌面肯定要打造一个满足日常或工作 并且相对稳定高效的系统  这个过程会很折腾   在1个虚拟机尝试安装配置所需软件  并做好文档记录   然后在另1台虚拟机中把经过验证可用的软件安装上 平时就在这台虚拟机中使用  除了必要的安全更新  避免频繁升级系统  这个想法源于git  多个虚拟机好比feature、develop、release和master分支  过程有些繁琐  但是一个有效过渡到linux桌面的方法

# 7 个 Linux 新手容易犯的错误

<img src="content_image/album_201610_30_131514eae5ql6xcfcvvlqy.jpg" alt="" title="">

换操作系统对每个人来说都是一件大事——尤其是许多用户根本不清楚操作系统是什么。

然而，从 Windows 切换到 Linux 特别地困难。这两个操作系统有着不同的前提和优先级，以及不同的处理方式。结果导致 Linux 新手容易混淆，因为他们在 Windows 上面得到经验不再适用。

例如，这里有 7 个 Windows “难民”开始使用 Linux 的时候会犯的错误（没有先后顺序）：

### 7. 选择错误的 Linux 发行版

Linux 有几百个不同的版本，或者按他们的称呼叫做<ruby> 发行版 <rp>  （ </rp> <rt>  distribution </rt> <rp>  ） </rp></ruby>。其中许多是专门针对不同的版本或用户的。选择了错误的版本，你与 Linux 的第一次亲密体验将很快变成一个噩梦。

如果你是在朋友的帮助下切换的话，确认他们的建议是适合你，而不是他们。有大量的文章可以帮助到你，你只需要关注前 20 名左右的或者列在 [Distrowatch](http://distrowatch.com/) 的即可，就不太可能会搞错。

更好的做法是，在你安装某个发行版之前先试试它的 [Live DVD](https://en.wikipedia.org/wiki/Live_CD)。Live DVD 是在外设上运行发行版的，这样可以允许你在不对硬盘做任何改动的情况下对其进行测试。事实上，除非你知道怎么让硬盘在 Linux 下可访问，否则你是不会看到你的硬盘的。

### 6. 期待什么都是一样的

由于经验有限，许多 Windows 用户不知道新的操作系统意味着新的程序和新的处理方式。事实上你的 Windows 程序是无法在 Linux 上运行的，除非你用 [WINE](https://en.wikipedia.org/wiki/Wine_%28software%29) 或者 Windows 虚拟机。而且你还不能用 MS Office 或者 PhotoShop —— 你必须要学会使用 LibreOffice 和 Krita。经过这些年，这些应用可能会有和 Windows 上的应用类似的功能，但它们的功能可能具有不同的名称，并且会从不同的菜单或工具栏获得。

就连很多想当然的都不一样了。Windows 用户会特别容易因为他们有多个桌面环境可以选择而大吃一惊——至少有一个主要的和很多次要的桌面环境。

### 5. 安装软件的时候不知所措

在 Windows 上，新软件是作为一个完全独立的程序来安装的。通常它囊括了其它所需的依赖库。

有两种叫做 [Flatpak](http://flatpak.org/) 和 [Snap](http://snapcraft.io/) 的软件包服务目前正在 Linux 上引进类似的安装系统，但是它们对于移动设备和嵌入式设备来说太大了。更多情况下，Linux 依赖于包管理系统，它会根据已安装的包来判断软件的依赖包是否是必需的，从而提供其它所需的依赖包。

笔记本和工作站上的包管理本质上相当于手机或平板电脑上的 Google Play：它速度很快，并且不需要用于安装的物理介质。不仅如此，它还可以节省 20%-35% 的硬盘空间，因为依赖包不会重复安装。

### 4. 假想软件会自动更新好

Linux 用户认为控制权很重要。Linux 提供更新服务，不过默认需要用户手动运行。例如，大多数发行版会让你知道有可用的软件更新，但是你需要选择安装这些更新。

如果你选择更新的话，你甚至可以单独决定每一个更新。例如，你可能不想更新到新的内核，因为你安装了一些东西需要使用当前的内核。又或者你想要安装所有的安全性更新，但不想把发行版更新到一个新的版本。一切都由你来选择。

### 3. 忘记密码

许多 Windows 用户因为登录不方便而忘记密码。又或者为了方便起见，经常运行一个管理账户。

在 Linux 上这两种做法都不容易。许多发行版使用 [sudo](https://en.wikipedia.org/wiki/Sudo) 来避免以 root 登录，特别是那些基于 Ubuntu 的发行版，而其它发行版大多数是安装为禁止 root 运行图形界面。但是，如果你在 Linux 上成功绕开了这些限制，请注意你的大部分 Linux 安全性优势都会无效（其实在 Windows 上也不推荐这样做）。

对了，你是不是在安装程序上看到一个自动登录的选项？那是在不常用的情景下使用的，例如不包含隐私信息的虚拟机。

### 2. 担心没有碎片整理和杀毒软件

Linux 偶尔需要进行碎片整理，不过只有在恢复分区或者分区差不多满了的时候。并且由于固态硬盘越来越火，碎片整理正在变成过去时，尽管固态硬盘确实需要在任何操作系统上定期运行 [trim](https://en.wikipedia.org/wiki/Trim_%28computing%29)。

同样地，只有当你安装的 Linux 经常传输文件给 Windows 机器的时候，杀毒软件才是一个主要问题。很少有 Linux 病毒或恶意软件存在，并且日常使用非 root 用户、使用强密码、经常备份当前文件就已经足够阻止病毒了。

### 1. 认为自己没有软件可用

Windows 上的软件是收费的，大多数类别由一家公司独占——例如，办公套装 MS Office 以及图形和设计的 Adobe。这些条件鼓励用户坚持使用相同的应用程序，尽管它们错漏百出。

在 Linux 上，故事情节不一样了。只有少数高端程序是收费的，而且几乎每一类软件都有两三个替代品，所有这些可用的软件都可以在 10 分钟或者更短的时间内下载好。如果一个替代品不合你口味，你可以删掉它然后毫不费力就可以再装一个其它的。在 Linux 上，你几乎总会有选择。

### 过渡期

可能没有那么多建议可以让 Windows 用户充分准备好切换到 Linux。即使说新用户应该保持开放的心态也是没什么用的，因为他们的期望总是太高，以至于许多用户都没有意识到自己有如此高的期望。

Linux 新手可以做的最好的事情就是调整心态，并且花一点时间来适应它们。过渡期会需要一些功夫，不过，从长远来看，你的多次尝试终会得到回报。

---

via: <http://www.datamation.com/open-source/7-mistakes-new-linux-users-make.html>

作者：[Bruce Byfield](http://www.datamation.com/author/Bruce-Byfield-6030.html) 译者：[OneNewLife](https://github.com/OneNewLife) 校对：[wxy](https://github.com/wxy)

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


科学音频处理（三）：如何使用 Octave 的高级数学技术处理音频文件

Summary: 我们的数字音频处理技术第三部分涵盖了信号调制内容，将解释如何进行调幅（Amplitude Modulation）、颤音效果（Tremolo Effect）和频率变化（Frequency Variation）。

dsfs

# 科学音频处理（三）：如何使用 Octave 的高级数学技术处理音频文件

我们的数字音频处理技术第三部分涵盖了信号调制内容，将解释如何进行<ruby> 调幅 <rp>  （ </rp> <rt>  Amplitude Modulation </rt> <rp>  ） </rp></ruby>、<ruby> 颤音效果 <rp>  （ </rp> <rt>  Tremolo Effect </rt> <rp>  ） </rp></ruby>和<ruby> 频率变化 <rp>  （ </rp> <rt>  Frequency Variation </rt> <rp>  ） </rp></ruby>。

### 调制

#### 调幅

正如它的名字暗示的那样， 影响正弦信号的振幅变化依据传递的信息而不断改变。正弦波因为承载着大量的信息被称作<ruby> 载波 <rp>  （ </rp> <rt>  carrier </rt> <rp>  ） </rp></ruby>。这种调制技术被用于许多的商业广播和市民信息传输波段（AM）。

#### 为何要使用调幅技术？

**调制发射**

假设信道是免费资源，有天线就可以发射和接收信号。这要求有效的电磁信号发射天线，它的大小和要被发射的信号的波长应该是同一数量级。很多信号，包括音频成分，通常在 100 赫兹或更低。对于这些信号，如果直接发射，我们就需要建立长达 300 公里的天线。如果通过信号调制将信息加载到 100MHz 的高频载波中，那么天线仅仅需要 1 米（横向长度）。

**集中调制与多通道**

假设多个信号占用一个通道，调制可以将不同的信号不同频域位置，以便接收者选择该特定信号。使用集中调制（“复用”）的应用有遥感探测数据、立体声调频收音机和长途电话等。

**克服设备限制的调制**

信号处理设备，比如过滤器、放大器，以及可以用它们简单组成的设备，它们的性能依赖于信号在频域中的境况以及高频率和低频信号的关系。调制可以用于传递信号到频域中的更容易满足设计需求的位置。调制也可以将“宽带信号“（高频和低频的比例很大的信号）转换成”窄带“信号。

**音频特效**

许多音频特效由于引人注目和处理信号的便捷性使用了调幅技术。我们可以说出很多，比如颤音、合唱、镶边等等。这种实用性就是我们关注它的原因。

### 颤音效果

颤音效果是调幅最简单的应用，为实现这样的效果，我们会用周期信号改变（乘）音频信号，使用正弦或其他。

```
>> tremolo='tremolo.ogg';
>> fs=44100;
>> t=0:1/fs:10;
>> wo=2*pi*440*t;
>> wa=2*pi*1.2*t;
>> audiowrite(tremolo, cos(wa).*cos(wo),fs);

```

这将创造一个正弦形状的信号，它的效果就像‘颤音’。

### 在真实音频文件中的颤音

现在我们将展示真实世界中的颤音效果。首先，我们使用之前记录过男性发声 ‘A’ 的音频文件。这个信号图就像下面这样：

```
>> [y,fs]=audioread('A.ogg');
>> plot(y);

```

现在我们将创建一个完整的正弦信号，使用如下的参数：

* 增幅 = 1
* 频率= 1.5Hz
* 相位 = 0

```
>> t=0:1/fs:4.99999999;
>> t=t(:);
>> w=2*pi*1.5*t;
>> q=cos(w);
>> plot(q);

```

注意： 当我们创建一组时间值时，默认情况下，它是以列的格式呈现，如, 1x220500 的值。为了乘以这样的值，必须将其变成行的形式（220500x1）。这就是 `t=t(:)` 命令的作用。

我们将创建第二份 ogg 音频格式的文件，它包含了如下的调制信号：

```
>> tremolo='tremolo.ogg';
>> audiowrite(tremolo, q.*y,fs);

```

### 频率变化

我们可以改变频率实现一些有趣的音效，比如原音变形，电影音效，多人比赛。

#### 正弦频率调制的影响

这是正弦调制频率变化的演示代码，根据方程：

```
Y=Ac*Cos(wo*Cos(wo/k))

```

这里：

* Ac = 增幅
* wo = 基频
* k = 标量除数

```
>> fm='fm.ogg';
>> fs=44100;
>> t=0:1/fs:10;
>> w=2*pi*442*t;
>> audiowrite(fm, cos(cos(w/1500).*w), fs);
>> [y,fs]=audioread('fm.ogg');
>> figure (); plot (y);

```

信号图：

你可以使用几乎任何类型的周期函数频率调制。本例中，我们仅仅用了一个正弦函数。请大胆的改变函数频率，用复合函数，甚至改变函数的类型。

---

via: <https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/>

作者：[David Duarte](https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/) 译者：[theArcticOcean](https://github.com/theArcticOcean) 校对：[wxy](https://github.com/wxy)

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


Linux 桌面份额连续四个月超过 2%

Summary: 我们之前报道过，今年六月份时 Linux 桌面的市场份额首次突破了 2%，并于次月达到了历史最高点 2.33%。

不管怎么样,linux有增长就好

大快人心

我新电脑用的ubuntu,放弃了下片啊

win10是有史以来最糟糕的体验，不停的更新升级稳定性却一点都不在。希望Linux的应用能追赶的快点

呵呵

Ubuntu14.04 Server版配gnome3.9的桌面用户发来贺电

不管怎么样,linux有增长就好

一个台式机，一个笔记本加公司一台电脑，我一个人贡献个3个。

国内软件是硬伤，可以deepin做的比较好点，可是还是有些软件没有啊。比如ps，AUTOcad等特别专业的软件，几乎都必须有windows和mac

在公司为了和同事统一环境 ，用的windows, 回家用我的linux desktop

国内实用性软件还是太少呀

试试

太不容易了～ 虽然我在虚拟机跑！

看着好心酸的数据， 2%...

有我的贡献 哈哈

这是国际上的数据吧，国内的远低于这个值的，关键就是应用，你看看linux应用程序，哪个不是国外（国外开源项目）的？

good

哥一个人虚拟机跑了6个，物理硬盘装了双linux，不说了，信仰啊！

心酸...

我笔记本是双系统，xubuntu + Windows ，只有工作才会用windows

# Linux 桌面份额连续四个月超过 2%

[据 Net Market Share 的数据](https://www.netmarketshare.com/report.aspx?qprid=11&qpaf=&qpcustom=Linux&qpcustomb=0)，全球的 Linux 桌面用户的份额已经连续四个月超过了 2% 。

<img src="content_image/album_201610_30_191917wke674bb417nz4n4.jpg" alt="" title="">

我们之前报道过，今年六月份时 Linux 桌面的市场份额[首次突破了 2%](/article-7538-1.html)，并于次月达到了历史最高点 2.33%。

那些将 Linux 作为主要桌面的用户们为这个份额做出了贡献。显然，从 这个图表的趋势来看，使用 Linux 作为桌面的用户越来越多了。

不过，不同的分析公司由于采样范围和分析方法的不同，其报告的数据、图表会有些不同，但是从总体的趋势来看，都是呈现向上增长的。

Net Market Share 的报告是基于全球 4 万个网站的访客得出的，4 万个网站也是一个比较大的数量了，当然，与整个互联网相比还是较小。

事实上，我们并不能真正摸清 Linux 具体的市场份额，因为有太多的发行版、内核版本和浏览器了，而且有些专门在隐私保护方面做了不少的工作，因此这部分我们的采集不到的。


Summary: ，我们将介绍单元测试的布尔断言方法 assertTrue 和 assertFalse 与身份断言 assertIs 之间的区别。

# Python 单元测试：assertTrue 是真值，assertFalse 是假值

在这篇文章中，我们将介绍单元测试的布尔断言方法 `assertTrue` 和 `assertFalse` 与身份断言 `assertIs` 之间的区别。

<img src="content_image/album_201610_30_215451lzjhnhy8qquumq8n.jpg" alt="" title="">

### 定义

下面是目前[单元测试模块文档](https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertTrue)中关于 `assertTrue` 和 `assertFalse` 的说明，代码进行了高亮：

>
> `assertTrue(expr, msg=None)`
>
>
> `assertFalse(expr, msg=None)`
>
>
>
> >
> > 测试该*表达式*是真值（或假值）。
> >
> >
> > 注：这等价于
> >
> >
> > `bool(expr) is True`
> >
> >
> > 而不等价于
> >
> >
> > `expr is True`
> >
> >
> > （后一种情况请使用 `assertIs(expr, True)`）。
> >
> >
> >
>
>
>

[Mozilla 开发者网络中定义 `真值`](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) 如下：

>
> 在一个布尔值的上下文环境中能变成“真”的值
>
>
>

在 Python 中等价于：

```
bool(expr) is True

```

这个和 `assertTrue` 的测试目的完全匹配。

因此该文档中已经指出 `assertTrue` 返回真值，`assertFalse` 返回假值。这些断言方法从接受到的值构造出一个布尔值，然后判断它。同样文档中也建议我们根本不应该使用 `assertTrue` 和 `assertFalse`。

### 在实践中怎么理解？

我们使用一个非常简单的例子 - 一个名称为 `always_true` 的函数，它返回 `True`。我们为它写一些测试用例，然后改变代码，看看测试用例的表现。

作为开始，我们先写两个测试用例。一个是“宽松的”：使用 `assertTrue` 来测试真值。另外一个是“严格的”：使用文档中建议的 `assertIs` 函数。

```
import unittest
from func import always_true

class TestAlwaysTrue(unittest.TestCase):
    def test_assertTrue(self):
        """
        always_true returns a truthy value
        """
        result = always_true()

        self.assertTrue(result)

    def test_assertIs(self):
        """
        always_true returns True
        """
        result = always_true()

        self.assertIs(result, True)

```

下面是 `func.py` 中的非常简单的函数代码：

```
def always_true():
    """
    I'm always True.

    Returns:
        bool: True
    """
    return True

```

当你运行时，所有测试都通过了：

```
always_true returns True ... ok
always_true returns a truthy value ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.004s

OK

```

开心ing~

现在，某个人将 `always_true` 函数改变成下面这样：

```
def always_true():
    """
    I'm always True.

    Returns:
        bool: True
    """
    return 'True'

```

它现在是用返回字符串 `"True"` 来替代之前反馈的 `True` （布尔值）。（当然，那个“某人”并没有更新文档 - 后面我们会增加难度。）

这次结果并不如开心了：

```
always_true returns True ... FAIL
always_true returns a truthy value ... ok

======================================================================
FAIL: always_true returns True
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/assertttt/test.py", line 22, in test_is_true
    self.assertIs(result, True)
AssertionError: 'True' is not True

----------------------------------------------------------------------
Ran 2 tests in 0.004s

FAILED (failures=1)

```

只有一个测试用例失败了！这意味着 `assertTrue` 给了我们一个<ruby> 误判 <rp>  （ </rp> <rt>  false-positive </rt> <rp>  ） </rp></ruby>。在它不应该通过测试时，它通过了。很幸运的是我们第二个测试是使用 `assertIs` 来写的。

因此，跟手册上了解到的信息一样，为了保证 `always_true` 的功能和更严格测试的结果保持一致，应该使用 `assertIs` 而不是 `assertTrue`。

### 使用断言的辅助方法

使用 `assertIs` 来测试返回 `True` 和 `False` 来冗长了。因此，如果你有个项目需要经常检查是否是返回了 `True` 或者 `False`，那们你可以自己编写一些断言的辅助方法。

这好像并没有节省大量的代码，但是我个人觉得提高了代码的可读性。

```
def assertIsTrue(self, value):
    self.assertIs(value, True)

def assertIsFalse(self, value):
    self.assertIs(value, False)

```

### 总结

一般来说，我的建议是让测试越严格越好。如果你想测试 `True` 或者 `False`，听从[文档](https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertTrue)的建议，使用 `assertIs`。除非不得已，否则不要使用 `assertTrue` 和 `assertFalse`。

如果你面对的是一个可以返回多种类型的函数，例如，有时候返回布尔值，有时候返回整形，那么考虑重构它。这是代码的异味。在 Python 中，抛出一个异常比使用 `False` 表示错误更好。

此外，如果你确实想使用断言来判断函数的返回值是否是真，可能还存在第二个代码异味 - 代码是正确封装了吗？如果 `assertTrue` 和 `assertFalse` 是根据正确的 `if` 语句来执行，那么值得检查下你是否把所有你想要的东西都封装在合适的位置。也许这些 `if` 语句应该封装在测试的函数中。

测试开心！

---

via: <http://jamescooke.info/python-unittest-asserttrue-is-truthy-assertfalse-is-falsy.html>

作者：[James Cooke](http://jamescooke.info/pages/hello-my-name-is-james.html) 译者：[chunyang-wen](https://github.com/chunyang-wen) 校对：[wxy](https://github.com/wxy)

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


在维基激动人心的四年

Summary: 我对维基的爱从我第 10 次考试（像在美国的 10 年级学生的年级考试）之后看到的英文维基文章孟加拉解放战争开始

我居然看完了……

# 在维基激动人心的四年

我自认为自己是个奥迪亚的维基人。我通过写文章和纠正文章错误给很多维基项目贡献了<ruby>   奥迪亚  <rp>  （ </rp> <rt>  Odia </rt> <rp>  ） </rp></ruby>知识（这是在印度的[奥里萨邦](https://en.wikipedia.org/wiki/Odisha)的主要语言），比如维基百科和维基文库，我也为用印地语和英语写的维基文章做贡献。

我对维基的爱从我第 10 次考试（像在美国的 10 年级学生的年级考试）之后看到的英文维基文章[孟加拉解放战争](https://en.wikipedia.org/wiki/Bangladesh_Liberation_War)开始。一不小心我打开了印度维基文章的链接，并且开始阅读它。在文章左边有用奥迪亚语写的东西，所以我点击了一下, 打开了一篇在奥迪亚维基上的 [ଭାରତ/Bhārat](https://or.wikipedia.org/s/d2) 文章。发现了用母语写的维基让我很激动！

一个邀请读者参加 2014 年 4 月 1 日召开的第二届布巴内斯瓦尔研讨会的旗帜广告引起了我的好奇。我过去从来没有为维基做过贡献，只用它做过研究，我并不熟悉开源和社区贡献流程。再加上，当时我只有 15 岁。我注册了，在研讨会上有很多语言爱好者，他们全比我大。尽管我害怕，我父亲还是鼓励我去参与。他起了非常重要的作用—他不是一个维基媒体人，和我不一样，但是他的鼓励给了我改变奥迪亚维基的动力和参加社区活动的勇气。

我觉得关于奥迪亚语言和文学的知识很多需要改进，有很多错误的观念和知识缺口，所以，我帮助组织关于奥迪亚维基的活动和和研讨会，我完成了如下列表：

* 在奥迪亚维基发起 3 次主要的 edit-a-thons ：2015 年妇女节、2016年妇女节、abd [Nabakalebara edit-a-thon 2015](https://or.wikipedia.org/s/toq)
* 在全印度发起了征集[檀车节](https://commons.wikimedia.org/wiki/Commons:The_Rathyatra_Challenge)图片的比赛
* 在谷歌的两大事件（[谷歌I/O大会扩展](http://cis-india.org/openness/blog-old/odia-wikipedia-meets-google-developer-group)和谷歌开发节）中代表奥迪亚维基
* 在2015 [Perception](http://perception.cetb.in/events/odia-wikipedia-event/) 和第一次 [Open Access India](https://opencon2015kolkata.sched.org/speaker/sailesh.patnaik007) 会议

我在维基项目当编辑直到去年（ 2015 年 1 月）为止，当我出席[孟加拉语维基百科的十周年会议](https://meta.wikimedia.org/wiki/Bengali_Wikipedia_10th_Anniversary_Celebration_Kolkata)和[毗瑟挐](https://www.facebook.com/vishnu.vardhan.50746?fref=ts)活动时，[互联网和社会中心](http://cis-india.org/)主任，邀请我参加[培训师培训计划](https://meta.wikimedia.org/wiki/CIS-A2K/Events/Train_the_Trainer_Program/2015)。我的开始超越奥迪亚维基，为[GLAM](https://en.wikipedia.org/wiki/Wikipedia:GLAM)的活动举办聚会和培训新的维基人。这些经验告诉我作为一个贡献者该如何为社区工作。

[Ravi](https://www.facebook.com/ravidreams?fref=ts)，在当时印度维基的总监，在我的旅程也发挥了重要作用。他非常相信我，让我参与到了 [Wiki Loves Food](https://commons.wikimedia.org/wiki/Commons:Wiki_Loves_Food)，维基共享中的公共摄影比赛，组织方是 [2016 印度维基会议](https://meta.wikimedia.org/wiki/WikiConference_India_2016)。在 2015 的 Loves Food 活动期间，我的团队在维基共享中加入了 10000+ 采用 CC BY-SA 协议的图片。Ravi 进一步坚定了我的信心，和我分享了很多关于维基媒体运动的信息，以及他自己在 [奥迪亚维基百科 13 周年](https://or.wikipedia.org/s/sml)的经历。

不到一年后，在 2015 年十二月，我成为了网络与社会中心的[获取知识计划](https://meta.wikimedia.org/wiki/CIS-A2K)的项目助理（ CIS-A2K 运动）。我自豪的时刻之一是在印度普里的研讨会，我们给奥迪亚维基媒体社区带来了 20 个新的维基人。现在，我在一个名为 [WikiTungi](https://or.wikipedia.org/s/xgx) 普里的非正式聚会上指导着维基人。我和这个小组一起工作，把奥迪亚 Wikiquotes 变成一个真实的计划项目。在奥迪亚维基我也致力于缩小性别差距。[八个女编辑](https://or.wikipedia.org/s/ysg)也正帮助组织聚会和研讨会，参加 [Women's History month edit-a-thon](https://or.wikipedia.org/s/ynj)。

在我四年短暂而令人激动的旅行之中，我也参与到 [维基百科的教育项目](https://outreach.wikimedia.org/wiki/Education)，[通讯团队](https://outreach.wikimedia.org/wiki/Talk:Education/News#Call_for_volunteers)，两个全球的 edit-a-thons： [Art and Feminsim](https://en.wikipedia.org/wiki/User_talk:Saileshpat#Barnstar_for_Art_.26_Feminism_Challenge) 和 [Menu Challenge](https://opensource.com/life/15/11/tasty-translations-the-open-source-way)。我期待着更多的到来！

我还要感谢 [Sameer](https://www.facebook.com/samirsharbaty?fref=ts) 和 [Anna](https://www.facebook.com/anna.koval.737?fref=ts)（都是之前维基百科教育计划的成员）。

---

via: <https://opensource.com/life/16/4/my-open-source-story-sailesh-patnaik>

作者：[Sailesh Patnaik](https://opensource.com/users/saileshpat) 译者：[hkurj](https://github.com/hkurj) 校对：[wxy](https://github.com/wxy)

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


如何在后台运行 Linux 命令并且将进程脱离终端

Summary:
当一个进程与终端关联在一起时，可能会出现两种问题：
- 你的控制终端充满了很多输出数据或者错误及诊断信息；
- 如果发生终端关闭的情况，进程连同它的子进程都将会终止。

记得以前在vps上使用nohup+aria2c下载bt种子，nohup还会把程序打印的内容保存到文本文件。如此一来，就可以通过本地浏览器直接查看输出了，很方便。

当然，如果你觉得该文本文件的内容太多，拖慢浏览器速度，可以写个php，只读取尾部50行这样的功能，如此一来，简直比迅雷离线下载还给力。

牛逼，还有这种操作

牛逼，还有这种操作

# 如何在后台运行 Linux 命令并且将进程脱离终端

在本指南中，我们将会阐明一个在 [Linux 系统中进程管理](http://www.tecmint.com/monitor-linux-processes-and-set-process-limits-per-user/)的简单但是重要的概念，那就是如何从它的控制终端完全脱离一个进程。

当一个进程与终端关联在一起时，可能会出现两种问题：

1. 你的控制终端充满了很多输出数据或者错误及诊断信息
2. 如果发生终端关闭的情况，进程连同它的子进程都将会终止

为了解决上面两个问题，你需要从一个控制终端完全脱离一个进程。在我们实际上解决这个问题之前，让我们先简要的介绍一下，如何在后台运行一个进程。

### 如何在后台开始一个 Linux 进程或者命令行

如果一个进程已经运行，例如下面的 [tar 命令行的例子](/article-7802-1.html)，简单的按下 `Ctrl+Z` 就可以停止它（LCTT 译注：这里说的“停止”，不是终止，而是“暂停”的意思），然后输入命令 `bg` 就可以继续以一个任务在后台运行了。

你可以通过输入 `jobs` 查看所有的后台任务。但是，标准输入（STDIN）、标准输出（STDOUT）和标准错误（STDERR）依旧掺杂到控制台中。

```
$ tar -czf home.tar.gz .
$ bg
$ jobs
```

*在后台运行 Linux 命令*

你也可以直接使用符号 `&` 在后台运行一个进程：

```
$ tar -czf home.tar.gz . &
$ jobs
```

*在后台开始一个 Linux 进程*

看一下下面的这个例子，虽然 [tar 命令](/article-7802-1.html)是作为一个后台任务开始的，但是错误信息依旧发送到终端，这表示，进程依旧和控制终端关联在一起。

```
$ tar -czf home.tar.gz . &
$ jobs
```

*运行在后台的 Linux 进程信息*

### 退出控制台之后，保持 Linux 进程的运行

我们将使用 `disown` 命令，它在一个进程已经运行并且被放在后台之后使用，它的作用是从 shell 的活动任务列表中移走一个 shell 任务，因此，对于该任务，你将再也不能使用 `fg` 、 `bg` 命令了。

而且，当你关闭控制控制终端，这个任务将不会挂起（暂停）或者向任何一个子任务发送 SIGHUP 信号。

让我们看一下先下面的这个使用 bash 中内置命令 `disown` 的例子。

```
$ sudo rsync Templates/* /var/www/html/files/ &
$ jobs
$ disown  -h  %1
$ jobs
```

*关闭终端之后，保持 Linux 进程运行*

你也可以使用 `nohup` 命令，这个命令也可以在用户退出 shell 之后保证进程在后台继续运行。

```
$ nohup tar -czf iso.tar.gz Templates/* &
$ jobs
```

*关闭 shell 之后把 Linux 进程置于后台*

### 从控制终端脱离一个 Linux 进程

因此，为了彻底从控制终端脱离一个程序，对于图形用户界面 (GUI) 的程序例如 firefox 来说，使用下面的命令行格式会更有效：

```
$ firefox </dev/null &>/dev/null &
```

在 Linux 上，/dev/null 是一个特殊的文件设备，它会忽略所有的写在它上面的数据，上述命令，输入来源和输出发送目标都是 /dev/null。

作为结束陈述，运行一个连接到控制终端的进程，作为用户你将会在你的终端上看到这个进程数据的许多行的输出，也包含错误信息。同样，当你关闭一个控制终端，你的进程和子进程都将会终止。

重要的是，对于这个主题任何的问题或者观点，通过下面的评论联系我们。

---

via: <http://www.tecmint.com/run-linux-command-process-in-background-detach-process/>

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

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


一个老奶奶的唠叨：当年我玩 Linux 时……

Summary: 在很久以前，那时还没有 Linux 系统。真的没有！之前也从未存在过。不像现在，Linux 系统随处可见。有各种流派的 Unix 系统、有苹果的操作系统、有微软的 Windows 操作系统。

我一看这人就很脸熟<br />
以前看过Carla Schroder写过的技术博文，写得很好很有水平。

这个图很棒，稀饭@！~

我在Linux.cn翻译的第一篇文章，感谢wxy的校对。

翻译的不错~

話說國內有大媽用Linux嗎？據說幾乎沒有一個國內證券公司的股票軟件能在跑在Linux上...

大妈我不知道，我知道有位老爷子——说起来老爷子好久没冒泡了，不知道老人家怎么样了。

我觉得苹果公司的iOS很无聊

我觉得苹果公司的iOS很无聊

在国内，首先得：

各种炒股软件 for Linux

各种IM for Linux

迅雷 for Linux

......<此处省略一万条>

# 一个老奶奶的唠叨：当年我玩 Linux 时……

在很久以前，那时还没有 Linux 系统。真的没有！之前也从未存在过。不像现在，Linux 系统随处可见。那时有各种流派的 Unix 系统、有苹果的操作系统、有微软的 Windows 操作系统。

比如说 Windows，它的很多东西都改变了，但是依然保持不变的东西的更多。尽管它已经增加了 20GB 以上的鬼知道是什么的东西，但是 Windows 还是大体保持不变（除了不能在 DOS 的提示下实际做些什么了）。嘿，谁还记得 Gorilla.bas 那个出现在 DOS 系统里的炸香蕉的游戏吗？多么美好的时光啊！不过互联网却不会忘记，你可以在 Kongregate.com 这个网站玩这个游戏的 Flash版本。

苹果系统也改变了，从一个鼓励你 hack 的友善系统变成了一个漂亮而密实的、根本不让你打开的小盒子，而且还限制了你使用的硬件接口。1998 年：软盘没了。2012 年：光驱没了。而 12 英寸的 MacBook 只有一个单一的 USB Type-C 接口，提供了电源、蓝牙、无线网卡、外部存储、视频输出和其它的一些配件的接口。而你要是想一次连接多个外设就不得不背着一堆转接器，这真是太令人抓狂了！然后就轮到耳机插孔了，没错，这唯一一个苹果世界里留着的非专有的标准硬件接口了，也注定要消失了。（LCTT 译注：还好，虽然最新的 IPhone 7 上没有耳机插孔了，但是新发布的 Macbook 上还有）

还有一大堆其它的操作系统，比如：Amiga、BeOS、OS/2 ，如果你愿意的话，你能找到几十个操作系统。我建议你去找找看，太容易找到了。Amiga、 BeOS 和 OS/2 这些系统都值得关注，因为它们有强大的功能，比如 32 位的多任务和高级图形处理能力。但是市场的影响击败了强大的系统性能，因此技术上并不出众的 Apple 和 Windows 操作系统统治了市场的主导地位，而那些曾经的系统也逐渐销声匿迹了。

然后 Linux 系统出现了，世界也因此改变了。

### 第一款电脑

我曾经使用过的第一款电脑是 Apple IIc ，大概在 1994年左右，而那个时候 Linux 系统刚出来 3 年。这是我从一个朋友那里借来的，用起来各方面都还不错，但是很不方便。所以我自己花了将近 500 美元买了一台二手的 Tandy 牌的电脑。这对于卖电脑的人来说是一件很伤心的事，因为新电脑要花费双倍的价钱。那个时候，电脑贬值的速度非常快。这个电脑当时看起来强劲得像是个怪物：一个英特尔 386SX 的 CPU，4MB的内存，一个 107MB 的硬盘，14 英寸的彩色 CRT 显示器，运行 MS-DOS 5 和 Windows 3.1 系统。

我曾无数次的拆开那个可怜的怪物，并且多次重新安装 Windows 和 DOS 系统。因为 Windows 桌面用的比较少，所以我的大部分工作都是在 DOS 下完成的。我喜欢玩血腥暴力的视频游戏，包括 Doom、Duke Nukem、Quake 和 Heretic。啊！那些美好的，让人心动的 8 位图像！

那个时候硬件的发展一直落后于软件，因此我经常升级硬件。现在我们能买到满足我们需求的任何配置的电脑。我已经好多年都没有再更新我的任何电脑硬件了。

### 《<ruby> 比特杂志 <rp>  （ </rp> <rt>  Computer bits </rt> <rp>  ） </rp></ruby>》

回到那些曾经辉煌的年代，电脑商店布满大街小巷，找到本地的一家网络服务提供商（ISP）也不用走遍整个街区。ISP 那个时候真的非比寻常，它们不是那种冷冰冰的令人讨论的超级大公司，而是像美国电信运营商和有线电视公司这样的好朋友。他们都非常友好，并且提供各种各样的像 BBS、文件下载、MUD （多玩家在线游戏）等的额外服务。

我花了很多的时间在电脑商店购买配件，但是很多时候我一个女人家去那里会让店里的员工感到吃惊，我真的很无语了，这怎么就会让一些人看不惯了。我现成已经是一位 58 岁的老家伙了，但是他们还是一样的看不惯我。我希望我这个女电脑迷在我死之前能被他们所接受。

那些商店的书架上摆满了《<ruby> 比特杂志 <rp>  （ </rp> <rt>  Computer bits </rt> <rp>  ） </rp></ruby>》。有关《比特杂志》的[历史刊物](https://web.archive.org/web/20020122193349/http://computerbits.com/)可以在<ruby> 互联网档案库 <rp>  （ </rp> <rt>  Internet Archive </rt> <rp>  ） </rp></ruby>中查到。《比特杂志》是当地一家免费报纸，有很多关于计算机方面的优秀的文章和大量的广告。可惜当时的广告没有网络版，因此大家不能再看到那些很有价值的关于计算机方面的详细信息了。你知道现在的广告商们有多么的抓狂吗？他们埋怨那些安装广告过滤器的人，致使科技新闻变成了伪装的广告。他们应该学习一下过去的广告模式，那时候的广告里有很多有价值的信息，大家都喜欢阅读。我从《比特杂志》和其它的电脑杂志的广告中学到了所有关于计算机硬件的知识。《<ruby> 电脑购买者杂志 <rp>  （ </rp> <rt>  Computer Shopper </rt> <rp>  ） </rp></ruby>》更是非常好的学习资料，其中有上百页的广告和很多高质量的文章。

《比特杂志》的出版人 Paul Harwood 开启了我的写作生涯。我的第一篇计算机专业性质的文章就是在《比特杂志》发表的。 Paul，仿佛你一直都在我的身旁，谢谢你。

在互联网档案库中，关于《比特杂志》的分类广告信息已经几乎查询不到了。分类广告模式曾经给出版商带来巨大的收入。免费的分类广告网站 Craigslist 在这个领域独占鳌头，同时也扼杀了像《比特杂志》这种以传统的报纸和出版为主的杂志行业。

其中有一些让我最难以忘怀的记忆就是一个 12 岁左右的吊儿郎当的小屁孩，他脸上挂满了对我这种光鲜亮丽的女人所做工作的不屑和不理解的表情，他在我钟爱的电脑店里走动，递给我一本《比特杂志》，当成给初学者的一本好书。我翻开杂志，指着其中一篇我写的关于 Linux 系统的文章给他看，他说“哦，我明白了”。他尴尬的脸变成了那种正常生理上都不可能呈现的颜色，然后很仓促地夹着尾巴溜走了。(不是的，我亲爱的、诚实的读者们，他不是真的只有 12 岁，而应该是 20 来岁。他现在应该比以前更成熟懂事一些了吧！）

### 发现 Linux

我第一次了解到 Linux 系统是在《比特杂志》上，大概在 1997 年左右。我一开始用的一些 Linux操作系统版本是 Red Hat 5 和 Mandrake Linux（曼德拉草）。 Mandrake 真是太棒了，它是第一款易安装型的 Linux 系统，并且还附带图形界面和声卡驱动，因此我马上就可以玩 Tux Racer 游戏了。不像那时候大多数的 Linux 迷们，因为我之前没接触过 Unix系统，所以我学习起来比较难。但是一切都还顺利吧，因为我学到的东西都很有用。相对于我在 Windows 中的体验，我在 Windows 中学习的大部分东西都是徒劳，最终只能放弃返回到 DOS 下。

玩转电脑真是充满了太多的乐趣，后来我转行成为计算机自由顾问，去帮助一些小型公司的 IT 部门把数据迁移到 Linux 服务器上，这让 Windows 系统或多或少的失去一些用武之地。通常情况下我们都是在背地里偷偷地做这些工作的，因为那段时期微软把 Linux 称为毒瘤，诬蔑 Linux 系统是一种共产主义，用来削弱和吞噬我们身体里的珍贵血液的阴谋。

### Linux 赢了

我持续做了很多年的顾问工作，也做其它一些相关的工作，比如：电脑硬件修理和升级、布线、系统和网络管理，还有运行包括 Apple、Windows、Linux 系统在内的混合网络。Apple 和 Windows 系统故意不兼容对方，因此这两个系统真的是最头疼，也最难整合到同一网络中。但是在 Linux 系统和其它开源软件中最有趣的一件事是总有一些人能够处理这些厂商之间的兼容性问题。

现在已经大不同了。在系统间的互操作方面一直存在一些兼容性问题，而且也没有桌面 Linux 系统的 1 级 OEM 厂商。我觉得这是因为微软和苹果公司在零售行业在大力垄断造成的。也许他们这样做反而帮了我们帮大忙，因为我们可以从 ZaReason 和 System76 这样独立的 Linux 系统开发商得到更好的服务和更高性能的系统。他们对 Linux 系统都很专业，也特别欢迎我们这样的用户。

Linux 除了在零售行业的桌面版系统占有一席之地以外，从嵌入式系统到超级计算机以及分布式计算系统等各个方面都占据着主要地位。开源技术掌握着软件行业的发展方向，所有的软件行业的前沿技术，比如容器、集群以及人工智能的发展都离不开开源技术的支持。从我的第一台老式的 386SX 电脑到现在，Linux 和开源技术都取得了巨大的进步。

如果没有 Linux 系统和开源，这一切都不可能发生。

（题图来自：[wallpapersafari](http://cdn.wallpapersafari.com/32/70/uLMive.jpg) ，高清）

---

via: <https://opensource.com/life/16/7/my-linux-story-carla-schroder>

作者：[Carla Schroder](https://opensource.com/users/carlaschroder) 译者：[rusking](https://github.com/rusking) 校对：[wxy](https://github.com/wxy)

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


谷歌也不信任沃通的证书了，StartCom CA 一并受到同等处罚

Summary: 从 Chrome 56 开始，不再信任沃通及被其收购的 StartCom 于 2016 年 10 月 21 日之后所颁发的证书，直到最终完全移除对这两个 CA 的信任！

出来混迟早是要还的

站长只发个新闻，也不对新闻评论下（评论下此新闻对国内的吃瓜群众有何影响，或者有何可能的影响。。）<br />
呵呵

这篇新闻是我写的。我下面评论了啊。其实一句话，尽快更换保平安。

愈演愈烈。

最后半句是错别字吧？  抑或=>亦或

为什么不稍微科普点？

可以趁1折买一个证书玩玩。

貌似国内好沃通的免费证书0.0

听西贝的喷友说是沃通很流氓，其背后是360

没错，本站有整个事件的相关线索，你可以跟着文章内的链接看看。

囧

整个事件其实我们连续报道了多篇了。不过这个事情还真没法再明白说了——明白的人自然明白其危害，不明白的人其实也根本不会意识到其危害。

吓得我赶紧用搜索引擎来验证我几十年来的用法。

这下彻底完了。360这钱白瞎了，只能说，以他们的一向行事风格，致此后果并不意外。

呵呵，

所以贵站的办站宗旨是什么呢？

是为了传播linux相关内容给精通系统、安全、网络各方面知识点的小伙伴？

是为了传播linux相关内容给linux感兴趣的初级小伙伴？

360倒闭了都活该拍手称快弹冠相庆，只是可惜了咱中国为数不多的CA机构

沒怎麼關注，幾個月前早就幹掉這個證書了，加上Chrome跟Firefox老早就封殺了，至少對一般用戶來說沒什麼影響。這貨走CNZZ老路罷了，忽悠不了誰。

哪里还有免费的证书可以申请么, 或者相当便宜的也可以

let's encrypt

这文章跟此站宗旨有毛线冲突。。。

不是很懂你们吃瓜群众。

像我，在此站和freebuf抛出沃通证书问题的时候就把自己个人博客上的startcom证书给换成了let's encrypt了

关于证书问题，从CNZZ到现在的沃通，懂的自然会懂，不懂也没关系，正常上网并没有什么影响。

你想了解证书的危害可以翻翻freebuf等网站的历史文章，很详细也很方便，善用搜索引擎，自己动手丰衣足食。

别整天等着别人喂食，那和咸鱼有何区别？#滑稽

# 谷歌也不信任沃通的证书了，StartCom CA 一并受到同等处罚

继 Mozilla 做出对<ruby> 沃通 <rp>  （ </rp> <rt>  WoSign </rt> <rp>  ） </rp></ruby>的[处罚决定](/article-7898-1.html)之后，谷歌也跟随了这一做法，从 Chrome 56 开始，不再信任沃通及被其收购的 StartCom 于 2016 年 10 月 21 日之后所颁发的证书。

此前， 苹果已经率先于 [9 月 30 日](https://support.apple.com/en-us/HT204132)将沃通的根证书[从证书存储库中移除](/article-7846-1.html)了。虽然沃通及其被其秘密收购的 StartCom 均存在不同程度的 CA 违规问题，但是苹果和 Mozilla 在最近的操作中都只对沃通采取了处罚，而谷歌的处置则更进一步，也同时对 StartCom 进行了同等处罚。

<img src="content_image/album_201611_01_232735zu1qnbnnffbvf8mn.jpg" alt="" title="">

谷歌在其[通告](https://security.googleblog.com/2016/10/distrusting-wosign-and-startcom.html)中说：

>
> 谷歌已经查明了沃通和 StartCom 这两个 CA 没有维持对其作为 CA 的高标准预期，因此根据我们的[根证书策略](https://www.chromium.org/Home/chromium-security/root-ca-policy#TOC-Removal-of-Trust)，谷歌 Chrome 将不再信任它们。这个观点类似于苹果和 Mozilla 的根证书计划发出的最近公告。
>
>
>

在 2016 年 8 月 17 日，谷歌接到了 GitHub 安全团队的通告，称沃通在没有得到他们授权的情况下签发了一个 GitHub 的证书。这促使 GitHub 安全团队和 Mozilla 合作对沃通进行了调查，发现了[沃通的若干违规签发证书的问题](https://wiki.mozilla.org/CA:WoSign_Issues)。该调查表明沃通有意地规避了浏览器限制（即对 SHA-1 签名证书的失效计划）和对 CA 的要求。更进一步的，还发现了另外一家 CA 公司 StartCom 也被沃通秘密收购，这违反了对 CA 公司被收购需要披露信息的要求。而且，沃通公司还替换了原 StartCom 的基础设施、人员、政策和签发系统。面对这种情况，沃通和 StartCom 管理层还尝试误导社区这两个公司之间的收购事实和关系。

谷歌于 10 月 31 日发布了 Chrome 56 的 Dev 渠道版本。谷歌决定从该版本的 Chrome 开始，不再信任沃通和 StartCom 于 2016 年 10 月 21 日之后签发的证书。在这个日期之前签发的证书依旧信任，但是之后，除非他们遵循 [Chrome 的证书透明策略](https://www.chromium.org/Home/chromium-security/root-ca-policy/CTPolicyMay2016edition.pdf?attredirects=0)，将只能对其已有客户的域名签发。按照计划，Chrome 56 将于 2017 年 1 月正式发布稳定版，因此在此之前，**使用这两个 CA 所签发证书的网站应该尽快迁移到其它被 Chrome 信任的 CA 所签发的证书下**。

沃通和 StartCom 的客户会发现他们的证书在 Chrome 56 中不再有效。并且，更严厉的是，谷歌还说：

>
> 在接下来的 Chrome 版本中，还会进一步减少对这两个 CA 签发的证书的支持，直到最终完全移除对这两个 CA 的信任！
>
>
>

并且称：

>
> 沃通和 StartCom 的任何试图规避处罚的做法都将导致这两个 CA 被马上全部移除！
>
>
>

沃通的证书在国内使用比较多，而 StartCom 的 StartSSL 证书则在全球范围内有广泛的使用，尤其是它的免费证书有很多个人网站在使用。鉴于 Chrome 在浏览器市场上已经占据了[一半左右的份额](/article-7534-1.html)，因此其带来的影响将是毁灭性的。

目前，主流浏览器里面，Mozilla 的 Firefox 、苹果的 Safari 和谷歌的 Chrome 都已经做出了相应的反应，但是我们目前还没见到微软对此的跟进和表态。似乎微软在 CA 策略方面一向比较散漫，因此，IE 和 Edge 浏览器的反应或许还需要一段时间，抑或不会采取措施。


如何在 Ubuntu 命令行下管理浏览器书签

Summary: 如果你已经厌倦了这些内置在浏览器中的主流工具，你或许想要寻找一个替代品。这里介绍 Buku：一个命令行下的书签管理器。它不仅可以管理你的书签，还可以给它们加密，将它们保存在一个数据库中等等。

# 如何在 Ubuntu 命令行下管理浏览器书签

浏览器书签虽然不常被提及，但是作为互联网浏览的一部分。没有好的书签功能，网站链接可能会丢失，下次再不能访问。这就是为什么一个好的书签管理器很重要。

所有的现代浏览器都提供了一些形式的管理工具，虽然它们严格上来讲功能较少。如果你已经厌倦了这些内置在浏览器中的主流工具，你或许想要寻找一个替代品。这里介绍 **Buku**：一个命令行下的书签管理器。它不仅可以管理你的书签，还可以给它们加密，将它们保存在一个数据库中等等。下面是如何安装它。

### 安装

Buku 不是非常流行。因此，用户需要自己编译它。然而，在 Ubuntu 上安装实际上很简单。打开终端并且使用 apt 安装`git` 和 `python3`，这两个工具在构建中很关键。

```
sudo apt python3-cryptography python3-bs4

```

装完所需的工具后，就可以拉取源码了。

```
git clone https://github.com/jarun/Buku/.
cd Buku

```

最后要安装它，只需要运行 `make` 命令。在这之后就可以在终端中输入 `buku`来运行 Buku 了。

```
sudo make install

```

**注意**：虽然这份指导针对的是 Ubuntu，但是 Buku 可以在任何 Linux 发行版中用相似的方法安装。

### 导入书签

要将书签直接导入 Buku 中，首先从浏览器中将书签导出成一个 html 文件。接着，输入下面的命令：

```
buku -i bookmarks.html

```

最后，导入的书签会添加到 Buku 的数据库中。

### 导出书签

导出书签和导入一样简单。要导出所有的书签，使用下面的命令：

```
buku -e bookmarks.html

```

它会和其他书签管理器一样，将数据库中所有的书签导出成一个 html 文件。之后就可以用它做你任何要做的事情了！

### 打开书签

要打开一个书签，首先要搜索。这需要用 `-s` 选项。运行下面的命令来搜索：

```
buku -s searchterm

```

接着一旦找到匹配的结果，输入旁边的数字，书签将会在默认的浏览器中打开了。

### 加密

不像其他的书签管理器，Buku 可以加密你的数据。这对拥有“敏感”书签的用户而言很有用的功能。要加密数据库，使用 `-l` 标志来创建一个密码。

```
buku -l

```

数据库加锁后，没有输入密码将不能打开书签。要解密它，使用 `-k` 选项。

```
buku -k

```

### 其他功能

这个书签管理器有许多不同的功能。要了解其他的功能，使用 `--help` 选项。当使用这个选项后，所有的选项以及每个功能详细内容都会列出来。这个非常有用，由于用户经常忘记东西，并且有时可以打开一个备忘单也不错。

```
buku --help

```

### 总结

即使这个工具不是浏览器的一部分，它的功能比任何现在管理器提供的功能多。尽管事实是它在命令行中运行，但是也有很好的竞争力。书签对大部分人来言并不重要，但是哪些不喜欢现有选择以及喜欢 Linux 命令行的应该看一下 Buku。

---

via: <https://www.maketecheasier.com/manage-browser-bookmarks-ubuntu-command-line/>

作者：[Derrik Diener](https://www.maketecheasier.com/author/derrikdiener/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


苹果新的文件系统 APFS 比 HFS+ 强在哪里？

额，和btrfs比起来谁好一些？

这个要测评一下才知道啊。兄弟要不你买两台测试机来造福人类

鉴于hfs+是史上最垃圾fs，我对这个东西不作任何期待

不用比較，蘋果的東西都是辣雞

等你换了windows 10再去评价好了，还在用windows 7还有脸评价Mac。

你还是安心用的Linux好了，喷子

# 苹果新的文件系统 APFS 比 HFS+ 强在哪里？

如果你一直关注苹果最新版的 macOS 的消息，你可能已经注意到苹果文件系统 APFS。这是不太让人感冒的话题之一。然而，它是支撑了操作系统用户体验的核心结构。APFS 将在 2017 年之前完成，不过你现在可以在 Sierra（最新版的 macOS） 上面体验一番开发者预览版。

### 特色与改进

先快速科普一下，**文件系统**是操作系统用于存储和检索数据的基本结构，不同的文件系统采用不同的方式来实现这个任务。随着计算机变得越来越快，新生代的文件系统已经从计算机速度的提升中获益，以提供新功能和适应现代存储需求。

HFS+，作为今天新一代 Mac 的附带文件系统，已经 18 岁了。它的祖先 HFS 比 Tom Cruise 的兄弟情影片“壮志凌云”还要老。它有点像一辆老丰田。它仍然可以工作（也许惊人的好），但是它不再得到人们的嘉奖。

APFS 不完全是 HFS+ 的升级版，因为相对现在而言，它是一个大幅度的飞跃。虽然这对苹果用户来说是一个重大的升级，但似乎这看起来更像是苹果赶上了其它系统，而不是超越了它们。然而，更新还进展得非常慢。

### 克隆和数据完整性

APFS 使用称为写时复制（copy-on-write）的方案来生成重复文件的即时克隆。在 HFS+ 下，当用户复制文件的时候，每一个比特（二进制中的“位”）都会被复制。而 APFS 则通过操作元数据并分配磁盘空间来创建克隆。但是，在修改复制的文件之前都不会复制任何比特。当克隆体与原始副本分离的时候，那些改动（并且只有那些改动）才会被保存。

写时复制还提高了数据的完整性。在其它系统下，如果你卸载卷导致覆写操作挂起的话，你可能会发现你的文件系统有一部分与其它部分不同步。写时复制则通过将改动写入到可用的磁盘空间而不是覆盖旧文件来避免这个问题。直到写入操作成功完成前，旧文件都是正式版本。只有当新文件被成功复制时，旧文件才会被清除。

### 系统快照

快照是写时复制架构给你带来的一个主要的升级。快照是文件系统在某个时间点的一个只读的可装载映像。随着文件系统发生改动，只有改动的比特会被更改。这可以让备份更简单，更可靠。考虑到时间机器（一个苹果出品的备份工具）已经成为硬链接的痛点，这可能是一个重大的升级。

### 输入/输出的服务质量（QoS）

你可能已经在你的路由器说明书看到了服务质量（QoS）这个名词。QoS 优先分配带宽使用以避免降低优先任务的速度。在你的路由器上，它采用用户定义的规则来为指定任务提供最大的带宽。据报道，苹果的 QoS 会优先考虑用户操作，例如活跃窗口。而诸如时间机器备份这些后台任务将会被降级。所以，这意味着更少的闲暇时光了？

### 本地加密

在后斯诺登时代，加密成为众所关注的了。越来越多的苹果产品正在强调其系统安全性。内置强大的加密机制并不让人感到意外。包括 APFS 在内，苹果正在采用更加细致入微的加密方案，要么不加密，要么就将加密进行到底。用户可以使用单个密钥来为所有数据加密，或者使用多个加密密钥分别锁定单个文件和文件夹。当然，你也可以不加密，只要你对坏蛋无所忌惮。

### 固态硬盘和闪存优化

闪存优化已经被列为 APFS 的一个亮点功能，不过它的实现并没有那么振奋人心。苹果选择将一些典型的固态硬盘芯片的处理功能迁移到操作系统，而没有深度系统集成的优势。这更像是让文件系统感知固态硬盘，而不是为它们做优化。

### 动态分区调整

APFS 驱动器的逻辑分区可以动态调整自身大小。用户只需指定所需分区的数量，然后文件系统会在运行时进行磁盘分配。每个分区只占用其用于存储文件的磁盘空间。剩余的磁盘空间会由任何分区获取。这种设计很整洁，不过比起其它文件系统，这更像是元文件夹。

### 结论

这是否重要？对于开发者和高级用户来说真是棒极了。对于一般的 Mac 用户应该没有太多的外部差异。虽然升级是重大的举措，但仍然存在一些缺失的部分。本地压缩显然还没有，对用户数据进行的校验也没有。当然，2017 年还没到，一切皆有可能，让我们拭目以待。

---

编译自: <https://www.maketecheasier.com/apple-file-system-better-than-hfs/>

作者：[Alexander Fox](https://www.maketecheasier.com/author/alexfox-2-2-2/) 译者：[OneNewLife](https://github.com/OneNewLife) 校对：[wxy](https://github.com/wxy)

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


捐赠 Let's Encrypt，共建安全的互联网

Summary: 随着 Mozilla、苹果和谷歌对沃通和 StartCom 这两家 CA 公司处罚落定，很多使用这两家 CA 所签发证书的网站纷纷寻求新的证书签发商。有一个非盈利组织可以为大家提供了免费、可靠和安全的 SSL 证书服务，这就是 Let's Encrypt 项目。现在，它需要您的帮助

支持！ let's encrypt.

# 捐赠 Let's Encrypt，共建安全的互联网

最近关于[沃通和 StartCom 这两家 CA 公司的消息](/article-7898-1.html)让人们再次关注到了网络隐私和安全的问题。随着 [Mozilla](/article-7814-1.html)、[苹果](/article-7846-1.html)和[谷歌](/article-7922-1.html)对这两家 CA 公司处罚落定，很多使用这两家 CA 所签发证书的网站纷纷寻求新的证书签发商。这里面固然有不少可信赖的 CA 公司可以提供服务，不过，有另外一个非盈利组织却为大家提供了免费、可靠和安全的 SSL 证书服务，这就是 [Let's Encrypt](/article-6565-1.html) 项目。

[Let's Encrypt](https://letsencrypt.org/) 项目是由<ruby> 互联网安全研究小组 <rt>  ISRG，Internet Security Research Group </rt></ruby>主导并开发的一个新型<ruby> 数字证书认证机构 <rt>  CA，Certificate Authority </rt></ruby>。该项目旨在开发一个自由且开放的自动化 CA 套件，并向公众提供相关的证书免费签发服务以降低安全通讯的财务、技术和教育成本。

**网站的完全加密是非常有必要的，这样每个人都可以随意在网上畅游而不用担心他们的活动被监视、拦截和修改。**

Let’s Encrypt 的做法与一般的 CA 服务商不同。他们为那些需要加密的网站提供了免费、易用的获取和管理证书的服务，而且在全球的每一个国家都可以使用。这些服务可以帮助人们或组织战胜来自经济、技术和培训方面的障碍，在互联网上安全地通讯。

仅仅在 Let’s Encrypt 运营了 10 个月之后，加密的页面数量就有了快速提升！这里面，Let’s Encrypt 项目居功甚伟，采用加密 Let’s Encrypt 的页面 90% 都是之前从未进行过加密的。

然而，互联网上还有超过一半的页面仍然没有加密。所以 Let’s Encrypt 还任重而道远，为了达成让互联网全都变成加密的这一目标，他们需要你的帮助！因此 Let’s Encrypt 在众筹网站 [generosity.com](https://www.generosity.com/community-fundraising/make-a-more-secure-web-with-let-s-encrypt) 上发起了众筹，募集更多的运营资金，以期做的更好！

如果您能捐助他们，您就为建立一个更安全的互联网埋下了一块基石。您所捐赠的每一块钱，都可以帮助 Let’s Encrypt 为所有用户创建一个尊重隐私的互联网体验。

他们划定了几个从 $25 到 $42000 不等的捐赠级别，并且为了感谢您的支持，会提供给您一些有趣的礼品以示谢意：

第一个级别 $25，您将收到一声感谢！

第二个级别 $50，您将收到一些精美的贴纸，可以贴在你的保险杠、水杯或者其它的什么地方。

第三个级别是 $100，他们叫这个“To Encryption and Beyond!”，礼品是这些漂亮的、合身的 T恤。

如果您捐赠了 $250，您将同时收到 T 恤和贴纸。

更高额度的捐赠就不在这里一一列出了，富有爱心的土豪可以移步[这个众筹网站](https://www.generosity.com/community-fundraising/make-a-more-secure-web-with-let-s-encrypt)去看看。

如果您暂时手头比较紧张，你还有其它的几种方式支持：

* 分享这篇文章或其中的视频到你常用的社交媒体中。
* 转发这个的捐赠计划。
* 参与他们的社区论坛。
* 帮助他们找到 bug 以便可以修复它。

关于 Let's Encrypt 的更多信息，您可以访问其官网： <https://letsencrypt.org/> ；如何使用他们的服务，你可以参考[这篇文章](/article-6565-1.html)。


俄罗斯总统普京要把微软赶出俄国

Summary: 一个资深的美国情报来源告诉 NBC News，普京总统将停止使用微软产品当做优先要处理的工作，他认为这个软件巨头会直接参与到美国政府发起的间谍活动当中。

其实自主研发的感觉只要你用的不是自己的内核，而是linux，我感觉其实也不安全。说不定有后门没有被发现而已，其实什么都不安全

来自江苏南京的 Internet Explorer 11.0|Windows 7 用户

它不会和美国政府或其它的政府合作在其软件中注入后门，这点我相信是真的，因为它根本就全身后门，哪还需要专门注入？

这个是偏激了。

当一个软件上升到一定规模时，无论开源还是闭源，漏洞都是不可避免的。

即便是对于显示一句的 “Hello, world!"，也需要在底层硬件没有问题的情况下才能按预期执行。这还不说运行的平台，像当年任天堂的 GBA 上，要想在屏幕上显示这句话，并不是只写几句就能搞定。

软件可以有漏洞，但明知有漏洞却不及时打补丁就是耍流氓！！！

普京牛X啊

不要因为个人情感因素，说一些信口雌黄的话。要知道在俄罗斯，除了微软，苹果，谷歌这些都是目标。另外就安卓这块来说，虽然谷歌市场份额大，但是安全方面，还是很糟糕。再多说一句，即便俄罗斯要强推 Linux，尚未看到其推荐哪些著名的 Linux 发行版。

因为根本不可能推荐啊，主流发行版哪个是俄罗斯的？倒时候他们自己改一个出来给政府用呀

政府统一用libreoffice就好了

你太理想主义了

厉害了，普京。

当一个开源公司强大后，也会变质，如ubuntu有商业公司的影子，作为使用，我们只能不断的将目前使用的系统、软件更改为使用人数少的系统和软件

更改一下：作为使用者

windows只是个玩具吧

好样的，中国政府为什么还在推广臃肿的windows？学生或者政府招聘考试仍然考windows，中国真的造不出芯片吗？联发科不是中国的吗？

用linux内核又怎样，linux内核是开源的，如果这样都看不出内核中有没有后门，那程序员不如s了算了

MTK是台湾的2333我们一厢情愿

WangYueScream [Baidu Spark 8.6|Windows 7]

scd

# 俄罗斯总统普京要把微软赶出俄国

俄罗斯已经计划通过支持本国的公司和软件来停止使用国外软件，但是最近有消息称普京总统计划加速这一进程，尽可能的快的停止使用微软的产品。

<img src="content_image/album_201611_02_235432okw0nwzsskwtnwkj.jpg" alt="" title="">

在普京看来，有很好的理由这样做：微软的软件可以被用来对它国做网络攻击，美国可以利用这些产品，比如 Windows 和 Office 来潜入到俄罗斯的系统当中。

[NBC News](http://www.nbcnews.com/nightly-news/video/exclusive-putin-targeting-microsoft-in-effort-to-nationalize-internet-798636099746?) 宣称他们从美国国土安全局得到的一份文件显示，去年俄罗斯黑客采用注入到微软 Office 文档中的木马软件中断了乌克兰电网的运行，所以普京总统担心美国利用类似的攻击来对俄罗斯发起攻击。

普京总统现在正在推行在政府和国企中停止使用外国软件，而采用可控的本国解决方案来免除间谍事件的困扰。

### 普京总统“专门”针对了微软

一个资深的美国情报来源告诉 [NBC News](http://www.nbcnews.com/nightly-news/video/exclusive-putin-targeting-microsoft-in-effort-to-nationalize-internet-798636099746?)，普京总统将停止使用微软产品当做优先要处理的工作，他认为这个软件巨头会直接参与到美国政府发起的间谍活动当中。

该内线人员说：“不仅仅是因为他们是 IT 领域最重要的美国公司，而且他们也是俄罗斯人普遍认为的美国情报机构的合作伙伴。”

微软已经解释了它不会参与任何间谍活动，并且明确说明了它不会和美国政府或其它的政府合作在其软件中注入后门。

微软的公共事务总经理 Dominic Carr 说：“我们不会秘密监视任何人，我们不会和任何政府合作监视其它政府，绝不会。”

不过，要摆脱微软的软件并不能一夜之间完成，特别是俄罗斯有着数以百万计的系统运行着 Windows 和 Office，但是该国的法律会强制政府机构和企业采用本地开发的软件来替代那些由外国公司所开发的软件。


如何在 Ubuntu 上使用 Grafana 监控 Docker

# 如何在 Ubuntu 上使用 Grafana 监控 Docker

Grafana 是一个有着丰富指标的开源控制面板。在可视化大规模测量数据的时候是非常有用的。根据不同的指标数据，它提供了一个强大、优雅的来创建、分享和浏览数据的方式。

它提供了丰富多样、灵活的图形选项。此外，针对<ruby> 数据源 <rp>  （ </rp> <rt>  Data Source </rt> <rp>  ） </rp></ruby>，它支持许多不同的存储后端。每个数据源都有针对特定数据源的特性和功能所定制的查询编辑器。Grafana 提供了对下述数据源的正式支持：Graphite、InfluxDB、OpenTSDB、 Prometheus、Elasticsearch 和 Cloudwatch。

每个数据源的查询语言和能力显然是不同的，你可以将来自多个数据源的数据混合到一个单一的仪表盘上，但每个<ruby> 面板 <rp>  （ </rp> <rt>  Panel </rt> <rp>  ） </rp></ruby>被绑定到属于一个特定<ruby> 组织 <rp>  （ </rp> <rt>  Organization </rt> <rp>  ） </rp></ruby>的特定数据源上。它支持验证登录和基于角色的访问控制方案。它是作为一个独立软件部署，使用 Go 和 JavaScript 编写的。

在这篇文章，我将讲解如何在 Ubuntu 16.04 上安装 Grafana 并使用这个软件配置 Docker 监控。

### 先决条件

* 安装好 Docker 的服务器

### 安装 Grafana

我们可以在 Docker 中构建我们的 Grafana。 有一个官方提供的 Grafana Docker 镜像。请运行下述命令来构建Grafana 容器。

```
root@ubuntu:~# docker run -i -p 3000:3000 grafana/grafana

Unable to find image 'grafana/grafana:latest' locally
latest: Pulling from grafana/grafana
5c90d4a2d1a8: Pull complete
b1a9a0b6158e: Pull complete
acb23b0d58de: Pull complete
Digest: sha256:34ca2f9c7986cb2d115eea373083f7150a2b9b753210546d14477e2276074ae1
Status: Downloaded newer image for grafana/grafana:latest
t=2016-07-27T15:20:19+0000 lvl=info msg="Starting Grafana" logger=main version=3.1.0 commit=v3.1.0 compiled=2016-07-12T06:42:28+0000
t=2016-07-27T15:20:19+0000 lvl=info msg="Config loaded from" logger=settings file=/usr/share/grafana/conf/defaults.ini
t=2016-07-27T15:20:19+0000 lvl=info msg="Config loaded from" logger=settings file=/etc/grafana/grafana.ini
t=2016-07-27T15:20:19+0000 lvl=info msg="Config overriden from command line" logger=settings arg="default.paths.data=/var/lib/grafana"
t=2016-07-27T15:20:19+0000 lvl=info msg="Config overriden from command line" logger=settings arg="default.paths.logs=/var/log/grafana"
t=2016-07-27T15:20:19+0000 lvl=info msg="Config overriden from command line" logger=settings arg="default.paths.plugins=/var/lib/grafana/plugins"
t=2016-07-27T15:20:19+0000 lvl=info msg="Path Home" logger=settings path=/usr/share/grafana
t=2016-07-27T15:20:19+0000 lvl=info msg="Path Data" logger=settings path=/var/lib/grafana
t=2016-07-27T15:20:19+0000 lvl=info msg="Path Logs" logger=settings path=/var/log/grafana
t=2016-07-27T15:20:19+0000 lvl=info msg="Path Plugins" logger=settings path=/var/lib/grafana/plugins
t=2016-07-27T15:20:19+0000 lvl=info msg="Initializing DB" logger=sqlstore dbtype=sqlite3

t=2016-07-27T15:20:20+0000 lvl=info msg="Executing migration" logger=migrator id="create playlist table v2"
t=2016-07-27T15:20:20+0000 lvl=info msg="Executing migration" logger=migrator id="create playlist item table v2"
t=2016-07-27T15:20:20+0000 lvl=info msg="Executing migration" logger=migrator id="drop preferences table v2"
t=2016-07-27T15:20:20+0000 lvl=info msg="Executing migration" logger=migrator id="drop preferences table v3"
t=2016-07-27T15:20:20+0000 lvl=info msg="Executing migration" logger=migrator id="create preferences table v3"
t=2016-07-27T15:20:20+0000 lvl=info msg="Created default admin user: [admin]"
t=2016-07-27T15:20:20+0000 lvl=info msg="Starting plugin search" logger=plugins
t=2016-07-27T15:20:20+0000 lvl=info msg="Server Listening" logger=server address=0.0.0.0:3000 protocol=http subUrl=

```

我们可以通过运行此命令确认 Grafana 容器的工作状态 `docker ps -a` 或通过这个URL访问 `http://Docker IP:3000`。

所有的 Grafana 配置设置都使用环境变量定义，在使用容器技术时这个是非常有用的。Grafana 配置文件路径为 `/etc/grafana/grafana.ini`。

### 理解配置项

Grafana 可以在它的 ini 配置文件中指定几个配置选项，或可以使用前面提到的环境变量来指定。

#### 配置文件位置

通常配置文件路径：

* 默认配置文件路径 : `$WORKING_DIR/conf/defaults.ini`
* 自定义配置文件路径 : `$WORKING_DIR/conf/custom.ini`

PS：当你使用 deb、rpm 或 docker 镜像安装 Grafana 时，你的配置文件在 `/etc/grafana/grafana.ini`。

#### 理解配置变量

现在我们看一些配置文件中的变量：

* `instance_name`：这是 Grafana 服务器实例的名字。默认值从 `${HOSTNAME}` 获取，其值是环境变量`HOSTNAME`，如果该变量为空或不存在，Grafana 将会尝试使用系统调用来获取机器名。
* `[paths]`：这些路径通常都是在 init.d 脚本或 systemd service 文件中通过命令行指定。
	+ `data`：这个是 Grafana 存储 sqlite3 数据库（如果使用）、基于文件的会话（如果使用），和其他数据的路径。
	+ `logs`：这个是 Grafana 存储日志的路径。
* `[server]`
	+ `http_addr`：应用监听的 IP 地址，如果为空，则监听所有的接口。
	+ `http_port`：应用监听的端口，默认是 3000，你可以使用下面的命令将你的 80 端口重定向到 3000 端口：`$iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000`
	+ `root_url` : 这个 URL 用于从浏览器访问 Grafana 。
	+ `cert_file` : 证书文件的路径（如果协议是 HTTPS）。
	+ `cert_key` : 证书密钥文件的路径（如果协议是 HTTPS）。
* `[database]`：Grafana 使用数据库来存储用户和仪表盘以及其他信息，默认配置为使用内嵌在 Grafana 主二进制文件中的 SQLite3。
	+ `type`：你可以根据你的需求选择 MySQL、Postgres、SQLite3。
	+ `path`：仅用于选择 SQLite3 数据库时，这个是数据库所存储的路径。
	+ `host`：仅适用 MySQL 或者 Postgres。它包括 IP 地址或主机名以及端口。例如，Grafana 和 MySQL 运行在同一台主机上设置如： `host = 127.0.0.1:3306`。
	+ `name`：Grafana 数据库的名称，把它设置为 Grafana 或其它名称。
	+ `user`：数据库用户（不适用于 SQLite3）。
	+ `password`：数据库用户密码（不适用于 SQLite3）。
	+ `ssl_mode`：对于 Postgres，使用 `disable`，`require`，或 `verify-full` 等值。对于 MySQL，使用 `true`，`false`，或 `skip-verify`。
	+ `ca_cert_path`：（只适用于 MySQL）CA 证书文件路径，在多数 Linux 系统中，证书可以在 `/etc/ssl/certs` 找到。
	+ `client_key_path`：（只适用于 MySQL）客户端密钥的路径，只在服务端需要用户端验证时使用。
	+ `client_cert_path`：（只适用于 MySQL）客户端证书的路径，只在服务端需要用户端验证时使用。
	+ `server_cert_name`：（只适用于 MySQL）MySQL 服务端使用的证书的通用名称字段。如果 `ssl_mode` 设置为 `skip-verify` 时可以不设置。
* `[security]`
	+ `admin_user`：这个是 Grafana 默认的管理员用户的用户名，默认设置为 admin。
	+ `admin_password`：这个是 Grafana 默认的管理员用户的密码，在第一次运行时设置，默认为 admin。
	+ `login_remember_days`：保持登录/记住我的持续天数。
	+ `secret_key`：用于保持登录/记住我的 cookies 的签名。

### 设置监控的重要组件

我们可以使用下面的组件来创建我们的 Docker 监控系统。

* `cAdvisor`：它被称为 Container Advisor。它给用户提供了一个资源利用和性能特征的解读。它会收集、聚合、处理、导出运行中的容器的信息。你可以通过[这个文档](https://github.com/google/cadvisor)了解更多。
* `InfluxDB`：这是一个包含了时间序列、度量和分析数据库。我们使用这个数据源来设置我们的监控。cAdvisor 只展示实时信息，并不保存这些度量信息。Influx Db 帮助保存 cAdvisor 提供的监控数据，以展示非某一时段的数据。
* `Grafana Dashboard`：它可以帮助我们在视觉上整合所有的信息。这个强大的仪表盘使我们能够针对 InfluxDB 数据存储进行查询并将他们放在一个布局合理好看的图表中。

### Docker 监控的安装

我们需要一步一步的在我们的 Docker 系统中安装以下每一个组件：

#### 安装 InfluxDB

我们可以使用这个命令来拉取 InfluxDB 镜像，并部署了 influxDB 容器。

```
root@ubuntu:~# docker run -d -p 8083:8083 -p 8086:8086 --expose 8090 --expose 8099 -e PRE_CREATE_DB=cadvisor --name influxsrv tutum/influxdb:0.8.8
Unable to find image 'tutum/influxdb:0.8.8' locally
0.8.8: Pulling from tutum/influxdb
a3ed95caeb02: Already exists
23efb549476f: Already exists
aa2f8df21433: Already exists
ef072d3c9b41: Already exists
c9f371853f28: Already exists
a248b0871c3c: Already exists
749db6d368d0: Already exists
7d7c7d923e63: Pull complete
e47cc7808961: Pull complete
1743b6eeb23f: Pull complete
Digest: sha256:8494b31289b4dbc1d5b444e344ab1dda3e18b07f80517c3f9aae7d18133c0c42
Status: Downloaded newer image for tutum/influxdb:0.8.8
d3b6f7789e0d1d01fa4e0aacdb636c221421107d1df96808ecbe8e241ceb1823

    -p 8083:8083 : user interface, log in with username-admin, pass-admin
    -p 8086:8086 : interaction with other application
    --name influxsrv : container have name influxsrv, use to cAdvisor link it.

```

你可以测试 InfluxDB 是否安装好，通过访问这个 URL `http://你的 IP 地址:8083`，用户名和密码都是 ”root“。

我们可以在这个界面上创建我们所需的数据库。

#### 安装 cAdvisor

我们的下一个步骤是安装 cAdvisor 容器，并将其链接到 InfluxDB 容器。你可以使用此命令来创建它。

```
root@ubuntu:~# docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080 --detach=true --link influxsrv:influxsrv --name=cadvisor google/cadvisor:latest -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
Unable to find image 'google/cadvisor:latest' locally
latest: Pulling from google/cadvisor
09d0220f4043: Pull complete
151807d34af9: Pull complete
14cd28dce332: Pull complete
Digest: sha256:8364c7ab7f56a087b757a304f9376c3527c8c60c848f82b66dd728980222bd2f
Status: Downloaded newer image for google/cadvisor:latest
3bfdf7fdc83872485acb06666a686719983a1172ac49895cd2a260deb1cdde29
root@ubuntu:~#

    --publish=8080:8080 : user interface
    --link=influxsrv:influxsrv: link to container influxsrv
    -storage_driver=influxdb: set the storage driver as InfluxDB
    Specify what InfluxDB instance to push data to:
    -storage_driver_host=influxsrv:8086: The ip:port of the database. Default is ‘localhost:8086’
    -storage_driver_db=cadvisor: database name. Uses db ‘cadvisor’ by default

```

你可以通过访问这个地址来测试安装 cAdvisor 是否正常 `http://你的 IP 地址:8080`。 这将为你的 Docker 主机和容器提供统计信息。

#### 安装 Grafana 控制面板

最后，我们需要安装 Grafana 仪表板并连接到 InfluxDB，你可以执行下面的命令来设置它。

```
root@ubuntu:~# docker run -d -p 3000:3000 -e INFLUXDB_HOST=localhost -e INFLUXDB_PORT=8086 -e INFLUXDB_NAME=cadvisor -e INFLUXDB_USER=root -e INFLUXDB_PASS=root --link influxsrv:influxsrv --name grafana grafana/grafana
f3b7598529202b110e4e6b998dca6b6e60e8608d75dcfe0d2b09ae408f43684a

```

现在我们可以登录 Grafana 来配置数据源. 访问 `http://你的 IP 地址:3000` 或 `http://你的 IP 地址`（如果你在前面做了端口映射的话）:

* 用户名 - admin
* 密码 - admin

一旦我们安装好了 Grafana，我们可以连接 InfluxDB。登录到仪表盘并且点击面板左上方角落的 Grafana 图标（那个火球）。点击<ruby> 数据源 <rp>  （ </rp> <rt>  Data Sources </rt> <rp>  ） </rp></ruby>来配置。

现在你可以添加新的<ruby> 图形 <rp>  （ </rp> <rt>  Graph </rt> <rp>  ） </rp></ruby>到我们默认的数据源 InfluxDB。

我们可以通过在<ruby> 测量 <rp>  （ </rp> <rt>  Metric </rt> <rp>  ） </rp></ruby>页面编辑和调整我们的查询以调整我们的图形。

关于 Docker 监控，你可用[从此了解](https://github.com/vegasbrianc/docker-monitoring)更多信息。 感谢你的阅读。我希望你可以留下有价值的建议和评论。希望你有个美好的一天。

---

via: <http://linoxide.com/linux-how-to/monitor-docker-containers-grafana-ubuntu/>

作者：[Saheetha Shameer](http://linoxide.com/author/saheethas/) 译者：[Bestony](https://github.com/bestony) 校对：[wxy](https://github.com/wxy)

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


Summary: 桌面录制工具可以帮做我们快速高效的制作教学视频和在线示范。

linuxmint！！！编辑用的系统还蛮多啊！

感觉simplescreenrecorder还不错

再推荐一个gome shell的录频扩展 easy screen cast  (arch用户可在aur中搜索安装)

simplescreenrecorder是不错

桌面录制工具可以帮做我们快速高效的制作教学视频和在线示范。

# 两款免费的 Linux 桌面录制工具：SimpleScreenRecorder 和 Kazam

>
> 桌面录制工具可以帮做我们快速高效的制作教学视频和在线示范。
>
>
>

一图胜千言，但一段视频演示则可以让你不用大费口舌。我是一个“视觉学习者”，亲眼目睹一件事情的发生对我的学习大有裨益。我也曾观察发现，如果学生实际看到应用程序的设置流程或者代码的编写过程，他们就能从中受益良多。所以，录屏工具是制作教学视频的绝佳工具。在本文中我将介绍一下两款开源桌面录制工具： [SimpleScreenRecorder](http://www.maartenbaert.be/simplescreenrecorder/) 和 [Kazam](https://launchpad.net/kazam)。

### SimpleScreenRecorder

使用 SimpleScreenRecorder 能够轻松录制桌面动作，它拥有直观的用户界面以及多样的编码方式，如 MP4、OGG、[Matroska](https://www.matroska.org/technical/whatis/index.html) 或 [WebM](https://www.webmproject.org/) 格式。 SimpleScreenRecorder 遵从 GPL 协议发行，运行在 Linux 上。

在安装运行 SimpleScreenRecorder 后，你可以轻松选择录制整个桌面、指定窗口或者一个自定义的区域。我比较偏爱最后这种方式，因为这样我可以使我的学生把注意力集中在我想让他们注意的地方。你还可以在设置中选择是否隐藏光标、调整录制帧率（默认帧率为 30fps）、视频压缩比例或者调整音频后端（如 ALSA、JACK 或 PusleAudio）。

由于 SimpleScreenRecorder 使用了 libav/ffmpeg 库进行编码，故而支持多种文件格式和视频编码方式。可以使用不同的配置文件（编码更快的配置文件意味着更大的体积），包括 YouTube 和 1000kbps – 3000kbps 的 LiveStream。

配置完毕后，单击“开始录制”按钮或者使用自定义的快捷键就可以轻松开始录制屏幕啦~

你还能在设置中开启提示音功能，它会开始录制和录制结束时给你声音的提示。屏幕录制完成后，你可以对视频文件进行编辑或者直接上传到 YouTube、Vimeo 等视频网站上。

SimpleScreenRecorder 的[官方网站](http://www.maartenbaert.be/simplescreenrecorder/)上还有大量说明文档，其中包括设置、录制、上传等方面的帮助手册和针对多种Linux发行版的安装说明。

### Kazam

Kazam 桌面录制工具同样是遵循 GPL 协议的软件。同时和 SimpleScreenRecorder 一样，Kazam 易于上手，界面直观。安装运行 Kazam 之后，你可以设置选择录制整个桌面、指定窗口或是一个自定义的区域。(LCTT 译注：关于自定义区域录制一部分的内容与 SimpleScreenRecorder 介绍中的内容基本相似，略过) ，你还可以选择记录鼠标的移动轨迹。我最中意 Kazam 的一点是延时录制的功能，这在制作视频教程的时候必不可少。

在“文件|设置”菜单下可以轻松对 Kazam 进行个性化设置，比如可以选择扬声器或是麦克风中的音源、关闭倒计时提示等等。

在设置页的第二个选项卡中可以进行视频录制设置。Kazam 默认录制帧率为 15fps，编码格式为 H264（MP4）。其它可供选择的格式有 VP8(WEBM)、HUFFYUV、Lossless JPEG 以及 RAW AVI。录制好的文件会以附加一个预设的前缀来命名，并自动保存在默认目录下，你可以随时修改这些设置。

设置屏幕截图同样很简单。你可以选择 Nikon D80 或 Canon 7D 的快门音效，也可以干脆关掉他们。截图文件是自动存放的。除非你关闭这一功能。

录制好的视频将会存储在你选定的目录下，随时可以上传到你喜欢的视频分享网站或是教程网站上。

是时候利用 Linux 和录屏工具让你的课堂焕然一新了！如果你还有其他的屏幕录制工具或是使用技巧，记得在评论里与我交流哦~

### 赠品：Kap

前面提到两款软件都是 Linux 下的屏幕录制软件，这里还有一款是 Mac 下的开源录屏软件推荐给大家： [Kap](https://getkap.co/)。它是使用 Web 技术（Node.js）构建的，以 MIT 协议开源在 [GitHub](https://github.com/wulkano/kap) 上。

你可以[直接下载 dmg 镜像](https://getkap.co/download)安装（300M），也可以使用 `brew` 从 Homebrew Cask 安装：

```
$ brew update
$ brew cask install kap
```

如果你使用 Mac，不妨一试，也欢迎你对这个项目提交贡献。

---

via: <https://opensource.com/education/16/10/simplescreenrecorder-and-kazam>

作者：[Don Watkins](https://opensource.com/users/don-watkins) 译者：[HaohongWANG](https://github.com/HaohongWANG) 校对：[wxy](https://github.com/wxy)

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