GitHub 简易入门指南

Summary: GitHub 是一个在线平台，旨在促进在一个共同项目上工作的个人之间的代码托管、版本控制和协作。通过该平台，无论何时何地，都可以对项目进行操作

[![Getting Started With GitHub](/data/attachment/album/201708/28/054321c219m21a12fd12ki.jpg)](http://www.linuxandubuntu.com/home/getting-started-with-github)

[GitHub](https://github.com/) 是一个在线平台，旨在促进在一个共同项目上工作的个人之间的代码托管、版本控制和协作。通过该平台，无论何时何地，都可以对项目进行操作（托管和审查代码，管理项目和与世界各地的其他开发者共同开发软件）。**GitHub 平台**为开源项目和私人项目都提供了项目处理功能。

关于团队项目处理的功能包括：GitHub <ruby> 流 <rt>  Flow> </rt></ruby>和 GitHub <ruby> 页 <rt>  Pages </rt></ruby>。这些功能可以让需要定期部署的团队轻松处理工作流程。另一方面，GitHub 页提供了页面用于展示开源项目、展示简历、托管博客等。

GitHub 也为个人项目提供了必要的工具，使得个人项目可以轻松地处理。它也使得个人可以更轻松地与世界分享他们的项目。

### 注册 GitHub 并启动一个项目

在 GitHub 上启动新项目时，您必须先使用您的电子邮件地址创建一个帐户。

[![github homepage](/data/attachment/album/201708/28/054322r2ped9pevvkkpjyu.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/github-homepage_orig.jpg)

然后，在验证邮箱的时候，用户将自动登录到他们的 GitHub 帐户。

#### 1、 创建仓库

之后，我们会被带到一个用于创建<ruby> 仓库 <rt>  repository </rt></ruby>的页面。仓库存储着包括修订历史记录在内的所有项目文件。仓库可以是公开的或者是私有的。公开的仓库可以被任何人查看，但是，只有项目所有者授予权限的人才可以提交修改到这个仓库。另一方面，私有仓库提供了额外的控制，可以将项目设置为对谁可见。因此，公开仓库适用于开源软件项目，而私有仓库主要适用于私有或闭源项目。

* 填写 “<ruby> 仓库名称 <rt>  Repository Name </rt></ruby>” 和 “<ruby> 简短描述 <rt>  Short Description </rt></ruby>”。
* 选中 “<ruby> 以一个 README 文件初始化 <rt>  Initialize this repository with a README </rt></ruby>”。
* 最后，点击底部的 “<ruby> 创建仓库 <rt>  Create Repository </rt></ruby>” 按钮。

[![create a github repository](/data/attachment/album/201708/28/054323d6eigiy6ffai6g0w.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/create-a-github-repository_orig.jpg)

#### 2、 添加分支

在 GitHub 中，<ruby> 分支 <rt>  branch </rt></ruby>是一种同时操作单个仓库的各种版本的方式。默认情况下，任何创建的单个仓库都会被分配一个名为 “MASTER” 的分支，它被认为是最后一个分支。在 GitHub 中，分支在被合并到<ruby> 主干 <rt>  master </rt></ruby>（最后的分支）之前，可以在对仓库进行实验和编辑中发挥作用。

为了使项目适合每一个人的需求，通常情况下，总是需要添加几个格外的分支来匹配不同的项目。在主分支上创建一个分支和复制主分支时的当前状态是一样的。

[![add a branch to github repository](/data/attachment/album/201708/28/054323bwmwtptxa8smtisu.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/add-a-branch-to-github-repository_orig.jpg)

创建分支与在不同版本中保存单个文件是类似的。它通过在特定仓库上执行的任务重命名来实现。

分支在保持错误修复和功能添加工作中同样被证明是有效。在进行必要的修改后，这些分支会被合并到主分支中。

在创建仓库后创建一个分支：

* 在这个例子中，点击仓库名称 “Hello-World” 跳转到你的新仓库。
* 点击顶部的 “Branch:Master” 按钮，会看到一个下拉菜单，菜单里有填写分支名称的空白字段。
* 输入分支名称，在这个例子中我们输入 “readme-edits“。
* 按下回车键或者点击蓝色的 “<ruby> 创建分支 <rt>  create branch </rt></ruby>” 框。

这样就成功创建了两个分支：master 和 readme-edits。

#### 3、 修改项目文件并提交

此步骤提供了关于如何更改仓库并保存修改的指导。在 GitHub 上，<ruby> 提交 <rt>  commit </rt></ruby>被定义为保存的修改的意思。每一次提交都与一个<ruby> 提交信息 <rt>  commit message </rt></ruby>相关联，该提交信息包含了保存的修改的历史记录，以及为何进行这些更改。这使得其他贡献者可以很轻松地知道你做出的更改以及更改的原因。

要对仓库进行更改和提交更改，请执行以下步骤：

* 点击仓库名称 “Hello-World”。
* 点击右上角的铅笔图标查看和编辑文件。 [![commit changes to github repository](/data/attachment/album/201708/28/054324dkbe3epvtk3hg9ve.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/commit-changes-to-github-repository_orig.jpg)
* 在编辑器中，写一些东西来确定你可以进行更改。
* 在<ruby> 提交消息 <rt>  commit message </rt></ruby>字段中做简要的总结，以解释为什么以及如何进行更改。
* 点击<ruby> 提交更改 <rt>  commit changes </rt></ruby>按钮保存更改。

请注意，这些更改仅仅影响到 readme-edits 分支，而不影响主分支。

[![commit branch to master](/data/attachment/album/201708/28/054325dkj2ngmpc0lnn2cm.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/commit-branch-to-master_orig.jpg)

#### 4、 开启一个拉取请求

<ruby> 拉取请求 <rt>  pull request </rt></ruby>是一个允许贡献者提出并请求某人审查和合并某些更改到他们的分支的功能。拉取请求还显示了几个分支的差异（diffs）。更改、添加和删减通常以红色和绿色来表示。一旦提交完成就可以开启拉取请求，即使代码还未完成。

开启一个拉取请求：

* 点击<ruby> 拉取请求 <rt>  pull requests </rt></ruby>选项卡。 [![github pull request](/data/attachment/album/201708/28/054326lka46l74acs44acz.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/github-pull-request_orig.jpg)
* 点击<ruby> 新建拉取请求 <rt>  new pull requests </rt></ruby>按钮。
* 选择 readme-edits 分支与 master 分支进行比较。 [![compare commit changes github](/data/attachment/album/201708/28/054327mctb3tz34fca18a1.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/compare-commit-changes-github_orig.jpg)
* 确定请求，并确定这是您要提交的内容。
* 点击创建拉取请求绿色按钮并输入一个标题。 [![open a pull request in github repository](/data/attachment/album/201708/28/054327n7zv93009wkqzvv2.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/open-a-pull-request-in-github-repository_orig.jpg)
* 按下回车键。

用户可以通过尝试创建并保存拉取请求来证实这些操作。

#### 5、 合并拉取请求

最后一步是将 readme-edits 分支和 master 分支合并到一起。如果 readme-edits 分支和 master 分支不会产生冲突，则会显示<ruby> merge pull request <rt>  合并拉取请求 </rt></ruby>的按钮。

[![merge the pull request github](/data/attachment/album/201708/28/054328skefh6288kb8et8h.jpg)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/merge-the-pull-request-github_orig.jpg)

当合并拉取时，有必要确保<ruby> 评论 <rt>  comment </rt></ruby>和其他字段被正确填写。合并拉取：

* 点击<ruby> merge pull request <rt>  合并拉取请求 </rt></ruby>的按钮。
* 确认合并。
* 按下紫色的删除分支按钮，删除 readme-edits 分支，因为它已经被包含在 master 分支中。（LCTT 译注：如果是合并他人提交的拉取请求，则无需也无法删除合并过来的他人的分支。）

本文提供了 GitHub 平台从注册到使用的基本操作，接下来由大家尽情探索吧。

---

via: <http://www.linuxandubuntu.com/home/getting-started-with-github>

作者：[LinuxAndUbuntu](http://www.linuxandubuntu.com) 译者：[firmianay](https://github.com/firmianay) 校对：[wxy](https://github.com/wxy)

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


在 Snap 中玩转 OpenStack

Summary: OpenStack 非常复杂，许多社区成员都在努力使 OpenStack 的部署和操作更加容易。其中大部分时间都用来改善相关工具。但是，如果我们降低一下标准，并且还能使包的体验更加简单，将会怎样呢？

![](/data/attachment/album/201708/28/060748zgz5vzfzggfogf02.png)

OpenStack 非常复杂，许多社区成员都在努力使 OpenStack 的部署和操作更加容易。其中大部分时间都用来改善相关工具，如：Ansible、Puppet、Kolla、Juju、Triple-O 和 Chef (仅举几例)。但是，如果我们降低一下标准，并且还能使包的体验更加简单，将会怎样呢？

我们正在努力通过 snap 包来实现这一点。snap 包是一种新兴的软件分发方式，这段来自 [snapcraft.io](http://snapcraft.io/) 的介绍很好的总结了它的主要优点：*snap 包可以快速安装、易于创建、安全运行而且能自动地事务化更新，因此你的应用程序总是能保持最新的状态并且永远不会被破坏。*

### 捆绑软件

单个 snap 包可以内嵌多个不同来源的软件，从而提供一个能够快速启动和运行的解决方案。当你安装 snap 包时，你会发现安装速度是很快的，这是因为单个 snap 包捆绑了所有它需要的依赖。这和安装 deb 包有些不同，因为它需要下载所有的依赖然后分别进行安装。

### Snap 包制作简单

在 Ubuntu 工作的时候，我花了很多时间为 Debian 制作 OpenStack 的安装包。这是一种很特殊技能，需要花很长时间才能理解其中的细微差别。与 snap 包相比，deb 包和 snap 包在复杂性上的差异有天壤之别。snap 包简单易行，并且相当有趣。

### Snap 包的其它特性

* 每个 snap 包都安装在其独有的只读 squashfs 文件系统中。
* 每个 snap 包都运行在一个由 AppArmor 和 seccomp 策略构建的严格沙箱环境中。
* snap 包能事务更新。新版本的 snap 包会安装到一个新的只读 squashfs 文件系统中。如果升级失败，它将回滚到旧版本。
* 当有新版本可用时，snap 包将自动更新。
* OpenStack 的 snap 包能保证与 OpenStack 的上游约束保持一致。打包的人不需要再为 OpenStack 依赖链维护单独的包。这真是太爽了!

### OpenStack snap 包介绍

现在，下面这些项目已经有了相应的 snap 包：

* `Keystone` —— 这个 snap 包为 OpenStack 提供了身份鉴证服务。
* `Glance` —— 这个 snap 包为 OpenStack 提供了镜像服务。
* `Neutron` —— 这个 snap 包专门提供了 neutron-server 过程，作为 OpenStack 部署过程的一个 snap 包。
* `Nova` —— 这个 snap 包提供 OpenStack 部署过程中的 Nova 控制器组件。
* `Nova-hypervisor` —— 这个 snap 包提供 OpenStack 部署过程中的 hypervisor 组件，并且配置使用通过 deb 包安装的 Libvirt/KVM + Open vSwitch 组合。这个 snap 包同时也包含 nava-lxd，这允许我们使用 nova-lxd 而不用 KVM。

这些 snpa 包已经能让我们部署一个简单可工作的 OpenStack 云。你可以在 [github](https://github.com/openstack?utf8=%E2%9C%93&q=snap-&type=&language=) 上找到所有这些 OpenStack snap 包的源码。有关 OpenStack snap 包更多的细节，请参考上游存储库中各自的 README。在那里，你可以找到更多有关管理 snap 包的信息，比如覆盖默认配置、重启服务、设置别名等等。

### 想要创建自己的 OpenStack snap 包吗?

查看 [snap cookie 工具](https://github.com/openstack-snaps/snap-cookiecutter/blob/master/README.rst)。我很快就会写一篇博文，告诉你如何使用 snap cookie 工具。它非常简单，并且能帮助你在任何时候创建一个新的 OpenStack snap 包。

### 测试 OpenStack snap 包

我们已经用简单的脚本初步测试了 OpenStack snap 包。这个脚本会在单个节点上安装 sanp 包，还会在安装后提供额外的配置服务。来尝试下吧：

```
git clone https://github.com/openstack-snaps/snap-test
cd snap-test
./snap-deploy

```

这样，我们就已经在 Ubuntu Xenial（16.04） 上做了所有的测试。要注意的是，这将在你的系统上安装和配置相当多的软件，因此你最好在可自由使用的机器上运行它。

### 追踪 OpenStack

现在，你可以从 snap 商店的边缘通道来安装 snap 包，比如：

```
sudo snap install --edge keystone

```

OpenStack 团队正在努力使 CI/CD 配置到位，以便让 snap 包的发布能够交叉追踪 OpenStack 的发布（比如一个追踪 Ocata，另一个追踪 Pike 等）。每个<ruby> 轨道 <rt>  track </rt></ruby>都有 4 个不同的通道。每个轨道的边缘通道将包含 OpenStack 项目对应分支最近的内容，测试、候选和稳定通道被保留用于已发布的版本。这样我们将看到如下的用法：

```
sudo snap install --channel=ocata/stable keystone
sudo snap install --channel=pike/edge keystone

```

### 其它

我们可以使用多个环境变量来简化 snap 包的制作。[这里](https://snapcraft.io/docs/reference/env) 有相关的说明。实际上，你无需深入的研究他们，但是在安装完 snap 包后，你也许会想要了解这些位置：

#### `$SNAP == /snap/<snap-name>/current`

这是 snap 包和它所有的文件挂载的位置。所有东西都是只读的。比如我当前安装的 keystone，$SNAP 就是 `/snap/keystone/91`。幸好，你不需要知道当前版本号，因为在 `/snap/keystone/` 中有一个软链接（LCTT 译注：`/snap/keystone/current/`）指向当前正在使用版本对应的文件夹。

```
$ ls /snap/keystone/current/
bin                     etc      pysqlite2-doc        usr
command-manage.wrapper  include  snap                 var
command-nginx.wrapper   lib      snap-openstack.yaml
command-uwsgi.wrapper   meta     templates

$ ls /snap/keystone/current/bin/
alembic                oslo-messaging-send-notification
convert-json           oslo-messaging-zmq-broker
jsonschema             oslo-messaging-zmq-proxy
keystone-manage        oslopolicy-checker
keystone-wsgi-admin    oslopolicy-list-redundant
keystone-wsgi-public   oslopolicy-policy-generator
lockutils-wrapper      oslopolicy-sample-generator
make_metadata.py       osprofiler
mako-render            parse_xsd2.py
mdexport.py            pbr
merge_metadata.py      pybabel
migrate                snap-openstack
migrate-repository     sqlformat
netaddr                uwsgi
oslo-config-generator

$ ls /snap/keystone/current/usr/bin/
2to3               idle     pycompile     python2.7-config
2to3-2.7           pdb      pydoc         python2-config
cautious-launcher  pdb2.7   pydoc2.7      python-config
compose            pip      pygettext     pyversions
dh_python2         pip2     pygettext2.7  run-mailcap
easy_install       pip2.7   python        see
easy_install-2.7   print    python2       smtpd.py
edit               pyclean  python2.7

$ ls /snap/keystone/current/lib/python2.7/site-packages/
...

```

#### `$SNAP_COMMON == /var/snap/<snap-name>/common`

这个目录用于存放系统数据，对于 snap 包的多个修订版本这些数据是共用的。在这里，你可以覆盖默认配置文件和访问日志文件。

```
$ ls /var/snap/keystone/common/
etc  fernet-keys  lib  lock  log  run

$ sudo ls /var/snap/keystone/common/etc/
keystone  nginx  uwsgi

$ ls /var/snap/keystone/common/log/
keystone.log  nginx-access.log  nginx-error.log  uwsgi.log

```

### 严格限制

每个 snap 包都是在一个由 seccomp 和 AppArmor 策略构建的严格限制的环境中运行的。更多关于 snap 约束的细节可以在 [这里](https://snapcraft.io/docs/reference/confinement) 查看。

### snap 包即将到来的新特性和更新

我正在期待 snap 包一些即将到来的新特性和更新（LCTT 译注：此文发表于 7 月 6 日）：

* 我们正在致力于实现 libvirt AppArmor 策略，这样 nova-hypervisor 的 snap 包就能够访问 qcow2 的<ruby> 支持文件 <rt>  backing files </rt></ruby>。
	+ 现在，作为一种变通方法，你可以将 virt-aa-helper 放在 complain 模式下：`sudo aa-complain /usr/lib/libvirt/virt-aa-helper`。
* 我们还在为 snapd 开发额外的接口策略，以便为部署的实例启用网络连接。
	+ 现在你可以在 devmode 模式下安装 nova-hypervisor snap 包，它会禁用安全限制：`snap install -devmode -edge nova-hypervisor`。
* 自动连接 nova-hypervisor 的接口。我们正在努力实现在安装时自动定义 nova-hypervisor 接口。
	+ 定义 AppArmor 和 seccomp 策略的接口可以允许 snap 包访问系统的资源。
	+ 现在，你可以手动连接需要接口，在 nova-hypervisor snap 包的 README 中有相关的描述。
* 命令自动定义别名。我们正在努力实现 snap 包在安装时为命令自动定义别名。
	+ 这使得我们可以使用传统的命令名。安装 snap 包后，你将可以使用 `nova-manage db sync` 而无需再用 `nova.manage db sync`。
	+ 现在，你可以在安装 snap 包后手动设置别名，比如：`snap alias nova.manage nova-manage`。如想获取更多细节请查看 snap 包的 README 。
* 守护进程自动定义别名。当前 snappy 仅支持为命令（非守护进程）定义别名。一旦针对守护进程的别名可用了，我们将设置它们在安装的时候自动配置。
	+ 这使得我们可以使用额外的单元文件名。我们可以使用 `systemctl restart nova-compute` 而无需再用 `systemctl restart snap.nova.nova-compute`。
* snap 包资产跟踪。这使得我们可以追踪用来构建 snap 包的版本以便在将来构建时重复使用。

如果你想多聊一些关于 snap 包的内容，你可以在 freenode 的 #openstack-snaps 这样的 IRC 上找到我们。我们欢迎你的反馈和贡献！感谢并祝你玩得开心！Corey

---

作者简介：

Corey Bryant 是 Ubuntu 的核心开发者和 Canonical 公司 OpenStack 工程团队的软件工程师，他主要专注于为 Ubuntu 提供 OpenStack 的安装包以及为 Juju 进行 OpenStack 的魅力开发。他对开源软件充满热情，喜欢与来自世界各地的人一起工作。

译者简介：

>
> snapcraft.io 的钉子户，对 Ubuntu Core、Snaps 和 Snapcraft 有着浓厚的兴趣，并致力于将这些还在快速发展的新技术通过翻译或原创的方式介绍到中文世界。有兴趣的小伙伴也可以关注译者个人的公众号： `Snapcraft`，最近会在上面连载几篇有关 Core snap 发布策略、交付流程和验证流程的文章，欢迎围观 :）
>
>
>

---

via: <https://insights.ubuntu.com/2017/07/06/openstack-in-a-snap/>

作者：[Corey Bryant](https://insights.ubuntu.com/author/corey-bryant/) 译者：[Snapcrafter](https://github.com/Snapcrafter) 校对：[wxy](https://github.com/wxy)

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


公钥加密之外

Summary: 关于应用密码学最令人扼腕也最引人入胜的一件事就是我们在现实中实际使用的密码学是多么的少。这并不是指密码学在业界没有被广泛的应用————事实上它的应用很广泛。我想指出的是，迄今为止密码学研究人员开发了如此多实用的技术，但工业界平常使用的却少之又少。实际上，除了少数个别情况，我们现今使用的绝大部分密码学技术是在 21 世纪初（注1） 就已经存在的技术。

关于应用密码学最令人扼腕也最引人入胜的一件事就是*我们在现实中实际使用的密码学是多么的少*。这并不是指密码学在业界没有被广泛的应用————事实上它的应用很广泛。我想指出的是，迄今为止密码学研究人员开发了如此多实用的技术，但工业界平常使用的却少之又少。实际上，除了少数个别情况，我们现今使用的绝大部分密码学技术是在 21 世纪初 （注1） 就已经存在的技术。

![](/data/attachment/album/201708/28/110440n9c88r9cchni9e6r.jpg)

大多数人并不在意这点，但作为一个工作在研究与应用交汇领域的密码学家，这让我感到不开心。我不能完全解决这个问题，我*能*做的，就是谈论一部分这些新的技术。在这个夏天里，这就是我想要做的：谈论。具体来说，在接下来的几个星期里，我将会写一系列讲述这些没有被看到广泛使用的前沿密码学技术的文章。

今天我要从一个非常简单的问题开始：在公钥加密之外还有什么（可用的加密技术）？具体地说，我将讨论几个过去 20 年里开发出的技术，它们可以让我们走出传统的公钥加密的概念的局限。

这是一篇专业的技术文章，但是不会有太困难的数学内容。对于涉及方案的实际定义，我会提供一些原论文的链接，以及一些背景知识的参考资料。在这里，我们的关注点是解释这些方案在做什么————以及它们在现实中可以怎样被应用。

### 基于身份的加密

在 20 世纪 80 年代中期，一位名叫<ruby> 阿迪·萨莫尔 <rt>  Adi Shamir </rt></ruby>的密码学家提出了一个 [全新的想法](https://discovery.csc.ncsu.edu/Courses/csc774-S08/reading-assignments/shamir84.pdf) 。这个想法，简单来说，就是*摒弃公钥*。

为了理解 萨莫尔 的想法从何而来，我们最好先了解一些关于公钥加密的东西。在公钥加密的发明之前，所有的加密技术都牵涉到密钥。处理这样的密钥是相当累赘的工作。在你可以安全地通信之前，你需要和你的伙伴交换密钥。这一过程非常的困难，而且当通信规模增大时不能很好地运作。

公钥加密（由 [Diffie-Hellman](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) 和萨莫尔的 [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) 密码系统发展而来的）通过极大地简化密钥分配的过程给密码学带来了革命性的改变。比起分享密钥，用户现在只要将他们的*公共*密钥发送给其他使用者。有了公钥，公钥的接收者可以加密给你的信息（或者验证你的数字签名），但是又不能用该公钥来进行解密（或者产生数字签名）。这一部分要通过你自己保存的私有密钥来完成。

尽管公钥的使用改进了密码学应用的许多方面，它也带来了一系列新的挑战。从实践中的情况来看，拥有公钥往往只是成功的一半————人们通常还需要安全地分发这些公钥。

举一个例子，想象一下我想要给你发送一封 PGP 加密的电子邮件。在我可以这么做之前，我需要获得一份你的公钥的拷贝。我要怎么获得呢？显然我们可以亲自会面，然后当面交换这个密钥————但（由于面基的麻烦）没有人会愿意这样做。通过电子的方式获得你的公钥会更理想。在现实中，这意味着要么（1）我们必须通过电子邮件交换公钥， 要么（2）我必须通过某个第三方基础设施，比如一个 [网站](https://keybase.io/) 或者 [密钥服务器](https://pgp.mit.edu/) ，来获得你的密钥。现在我们面临这样的问题：如果电子邮件或密钥服务器是*不值得信赖的*（或者简单的来说允许任何人以 [你的名义](https://motherboard.vice.com/en_us/article/bmvdwd/wave-of-spoofed-encryption-keys-shows-weakness-in-pgp) [上传密钥](https://motherboard.vice.com/en_us/article/bmvdwd/wave-of-spoofed-encryption-keys-shows-weakness-in-pgp) ），我就可能会意外下载到恶意用户的密钥。当我给“你”发送一条消息的时候，也许我实际上正在将消息加密发送给 Mallory.

![](/data/attachment/album/201708/28/110610nvaqqf8h9h7ajvna.jpg)

*Mallory*

解决这个问题——关于交换公钥和验证它们的来源的问题——激励了*大量的*实践密码工程，包括整个 [web PKI](https://en.wikipedia.org/wiki/Certificate_authority) （网络公钥基础设施）。在大部分情况下，这些系统非常奏效。但是萨莫尔并不满意。如果，他这样问道，我们能做得更好吗？更具体地说，他这样思考：*我们是否可以用一些更好的技术去替换那些麻烦的公钥？*

萨莫尔的想法非常令人激动。他提出的是一个新的公钥加密形式，在这个方案中用户的“公钥”可以就是他们的*身份*。这个身份可以是一个名字（比如 “Matt Green”）或者某些诸如电子邮箱地址这样更准确的信息。事实上，“身份”是什么并不重要。重要的是这个公钥可以是一个任意的字符串————而*不是*一大串诸如“ 7cN5K4pspQy3ExZV43F6pQ6nEKiQVg6sBkYPg1FG56Not ”这样无意义的字符组合。

当然，使用任意字符串作为公钥会造成一个严重的问题。有意义的身份听起来很棒————但我们无法拥有它们。如果我的公钥是 “Matt Green” ，我要怎么得到的对应的私钥？如果*我*能获得那个私钥，又有谁来阻止*其他的某些 Matt Green* 获得同样的私钥，进而读取我的消息。进而考虑一下这个，谁来阻止任意的某个*不是*名为 Matt Green 的人来获得它。啊，我们现在陷入了 [Zooko 三难困境](https://en.wikipedia.org/wiki/Zooko%27s_triangle) 。

萨莫尔的想法因此要求稍微更多一点的手段。相比期望身份可以全世界范围使用，他提出了一个名为“<ruby> 密钥生成机构 <rt>  key generation authority </rt></ruby>”的特殊服务器，负责产生私钥。在设立初期，这个机构会产生一个<ruby> 最高公共密钥 <rt>  master public key </rt></ruby>（MPK），这个公钥将会向全世界公布。如果你想要加密一条消息给“Matt Green”（或者验证我的签名），你可以用我的身份和我们达成一致使用的权威机构的唯一 MPK 来加密。要*解密*这则消息（或者制作签名），我需要访问同一个密钥机构，然后请求一份我的密钥的拷贝。密钥机构将会基于一个秘密保存的<ruby> 最高私有密钥 <rt>  master secret key </rt></ruby>（MSK）来计算我的密钥。

加上上述所有的算法和参与者，整个系统看起来是这样的：

![](/data/attachment/album/201708/28/110818xrzq69zz79467glp.jpg)

*一个<ruby> 基于身份加密 <rt>  Identity-Based Encryption </rt></ruby>（IBE）系统的概览。<ruby> 密钥生成机构 <rt>  Key Generation Authority </rt></ruby>的 Setup 算法产生最高公共密钥（MPK）和最高私有密钥（MSK）。该机构可以使用 Extract 算法来根据指定的 ID 生成对应的私钥。加密器（左）仅使用身份和 MPK 来加密。消息的接受者请求对应她身份的私钥，然后用这个私钥解密。（图标由 [Eugen Belyakoff](https://thenounproject.com/eugen.belyakoff/) 制作）*

这个设计有一些重要的优点————并且胜过少数明显的缺点。在好的方面，它*完全*摆脱了任何和你发送消息的对象进行密钥交换的必要。一旦你选择了一个主密钥机构（然后下载了它的 MPK），你就可以加密给整个世界上任何一个人的消息。甚至更酷炫地，在你加密的时候，*你的通讯对象甚至还不需要联系密钥机构*。她可以在你给她发送消息*之后*再取得她的私钥。

当然，这个“特性”也同时是一个漏洞。因为密钥机构产生所有的私钥，它拥有相当大权力。一个不诚实的机构可以轻易生成你的私钥然后解密你的消息。用更得体的方式来说就是标准的 IBE 系统有效地“包含” [密钥托管机制](https://en.wikipedia.org/wiki/Key_escrow)。 （注2）

### 基于身份加密（IBE）中的“加密（E）”

所有这些想法和额外的思考都是萨莫尔在他 1984 年的论文中提出来的。其中有一个小问题：萨莫尔只能解决问题的一半。

具体地说，萨莫尔提出了一个<ruby> 基于身份签名 <rt>  identity-based signature </rt></ruby>（IBS）的方案—— 一个公共验证密钥是身份、而签名密钥由密钥机构生成的签名方案。他尽力尝试了，但仍然不能找到一个建立基于身份*加密*的解决方案。这成为了一个悬而未决的问题。 （注3）

到有人能解决萨莫尔的难题等了 16 年。令人惊讶的是，当解答出现的时候，它出现了不只一次，*而是三次*。

第一个，或许也是最负盛名的 IBE 的实现，是由<ruby> 丹·博奈 <rt>  Dan Boneh </rt></ruby>和<ruby> 马太·富兰克林Matthew Franklin</ruby>在多年以后开发的。博奈和富兰克林的发现的时机十分有意义。<ruby> 博奈富兰克林方案 <rt>  Boneh-Franklin scheme </rt></ruby> 根本上依赖于能支持有效的 “<ruby>   双线性映射  <rt>  bilinear map </rt></ruby>” （或者“<ruby> 配对 <rt>  pairing </rt></ruby>”） （注4） 的椭圆曲线。需要计算这些配对的该类 [算法](https://crypto.stanford.edu/miller/) 在萨莫尔撰写他的那篇论文是还不被人知晓，因此没有被*建设性地*使用——即被作为比起 [一种攻击](http://ieeexplore.ieee.org/document/259647/) 更有用的东西使用——直至 [2000年](https://pdfs.semanticscholar.org/845e/96c20e5a5ff3b03f4caf72c3cb817a7fa542.pdf)。

*（关于博奈富兰克林 IBE 方案的简短教学，请查看 [这个页面](https://blog.cryptographyengineering.com/boneh-franklin-ibe/)）*

第二个被称为 [Sakai-Kasahara](https://en.wikipedia.org/wiki/Sakai%E2%80%93Kasahara_scheme) 的方案的情况也大抵类似，这个方案将在与第一个大约同一时间被另外一组学者独立发现。

第三个 IBE 的实现并不如前二者有效，但却更令人吃惊得多。[这个方案](https://pdfs.semanticscholar.org/8289/821325781e2f0ce83cfbfc1b62c44be799ee.pdf) 由<ruby> 克利福德·柯克斯 <rt>  Clifford Cocks </rt></ruby>，一位英国国家通信总局的资深密码学家开发。它因为两个原因而引人注目。第一，柯克斯的 IBE 方案完全不需要用到双线性映射——都是建立在以往的 RSA 的基础上的，这意味着*原则上*这个算法这么多年来仅仅是没有被人们发现（而非在等待相应的理论基础）而已。第二，柯克斯本人近期因为一些甚至更令人惊奇的东西而闻名：在 RSA 算法被提出之前将近 5 年 [发现 RSA 加密系统](https://cryptome.org/jya/ellisdoc.htm)（LCTT 译注：即公钥加密算法）。用再一个在公钥加密领域的重要成就来结束这一成就，实在堪称令人印象深刻的创举。

自 2001 年起，许多另外的 IBE 构造涌现出来，用到了各种各样的密码学背景知识。尽管如此，博奈和富兰克林早期的实现仍然是这些算法之中最为简单和有效的。

即使你并不因为 IBE 自身而对它感兴趣，事实证明它的基本元素对密码学家来说在许许多多单纯地加密之外的领域都十分有用。事实上，如果我们把 IBE 看作是一种由单一的主公/私钥对来产生数以亿计的相关联的密钥对的方式，它将会显得意义非凡。这让 IBE 对于诸如<ruby>   选择密文攻击  <rt>  chosen ciphertext attacks </rt></ruby>， <ruby>   前向安全的公钥加密  <rt>  forward-secure public key encryption </rt></ruby> 和<ruby>   短签名方案  <rt>  short signature schemes </rt></ruby> 这样各种各样的应用来说非常有用。

### 基于特征加密

当然，如果你给密码学家以一个类似 IBE 的工具，那么首先他们要做的将是找到一种~~让事情更复杂~~改进它的方法。

最大的改进之一要归功于 [<ruby> 阿密特·萨海 <rt>  Amit Sahai </rt></ruby>和<ruby> 布伦特·沃特世 <rt>  Brent Waters </rt></ruby>](https://eprint.iacr.org/2004/086.pdf)。我们称之为<ruby> 基于特征加密 <rt>  Attribute-Based Encryption </rt></ruby>，或者 ABE。

这个想法最初并不是为了用特征来加密。相反，萨海和沃特世试图开发一种使用生物辨识特征来加密的*基于身份的*加密方案。为了理解这个问题，想象一下我决定使用某种生物辨识特征，比如你的 [虹膜扫描影像](https://en.wikipedia.org/wiki/Iris_recognition)，来作为你的“身份”来加密一则给你的密文。然后你将向权威机构请求一个对应你的虹膜的解密密钥————如果一切都匹配得上，你就可以解密信息了。

问题就在于这几乎不能奏效。

![](/data/attachment/album/201708/28/110903syooiilp00jpzy10.jpg)

*告诉我这不会给你带来噩梦*

因为生物辨识特征的读取（比如虹膜扫描或者指纹模板）本来就是易出错的。这意味着每一次的读取通常都是十分接近的，但却总是会几个对不上的比特。在标准的 IBE 系统中这是灾难性的：如果加密使用的身份和你的密钥身份有哪怕是一个比特的不同，解密都会失效。你就不走运了。

萨海和沃特世决定通过开发一种包含“阈值门”的 IBE 形式来解决这个问题。在这个背景下，一个身份的每一个字节都被表示为一个不同的“特征”。把每一个这种特征看作是你用于加密的一个元件——譬如“你的虹膜扫描的 5 号字节是 1”和“你的虹膜扫描的 23 号字节是 0”。加密的一方罗列出所有这些字节，然后将它们中的每一个都用于加密中。权威机构生成的解密密钥也嵌入了一连串相似的字节值。根据这个方案的定义，当且仅当（你的身份密钥与密文解密密钥之间）配对的特征数量超过某个预先定义的阈值时，才能顺利解密：*比如*为了能解密，2048 个字节中的（至少） 2024 个要是对应相同的。

这个想法的优美之处不在于模糊 IBE，而在于一旦你有了一个阈值门和一个“特征”的概念，你就能做更有趣的事情。[主要的观察结论](https://eprint.iacr.org/2006/309.pdf) 是阈值门可以拥有实现布尔逻辑的 AND 门和 OR 门（LCTT 译注：译者认为此处应为用 AND 门和 OR 门实现， 原文： a threshold gate can be used to implement the boolean AND and OR gates），就像这样:

![](/data/attachment/album/201708/28/110937p339jv2dse0n9302.jpg)

甚至你还可以将这些逻辑闸门*堆叠*起来，一些在另一些之上，来表示一些相当复杂的布尔表达式——这些表达式本身就用于判定在什么情况下你的密文可以被解密。举个例子，考虑一组更为现实的特征，你可以这样加密一份医学记录，使医院的儿科医生*或者*保险理算员都可以阅读它。你所需要做的只不过是保证人们可以得到正确描述*他们的*特征的密钥（就是一些任意的字符串，如同身份那样）。

![](/data/attachment/album/201708/28/111010t9shzusjus90309l.jpg)

*一个简单的“密文规定”。在这个规定中当且仅当一个密钥与一组特定的特征匹配时，密文才能被解密。在这个案例中，密钥满足该公式的条件，因此密文将被解密。其余用不到的特征在这里忽略掉。*

其他的条件判断也能实现。通过一长串特征，比如文件创建时间、文件名，甚至指示文件创建位置的 GPS 坐标， 来加密密文也是有可能的。于是你可以让权威机构分发一部分对应你的数据集的非常精确的密钥————比如说，“该密钥用于解密所有在 11 月 3 号和 12 月 12 号之间在芝加哥被加密的包含‘小儿科’或者‘肿瘤科’标记的放射科文件”。

### 函数式加密

一旦拥有一个相关的基础工具，像 IBE 和 ABE，研究人员的本能是去扩充和一般化它。为什么要止步于简单的布尔表达式？我们能不能制作嵌入了*任意的计算机程序*的<ruby> 密钥 <rt>  key </rt></ruby>（或者<ruby> 密文 <rt>  ciphertext </rt></ruby>）？答案被证明是肯定的——尽管不是非常高效。一组 [近几年的](https://eprint.iacr.org/2013/337.pdf) [研究](https://arxiv.org/abs/1210.5287) 显示可以根据各种各样的<ruby> 基于格 <rt>  lattice-based </rt></ruby>的密码假设，构建在<ruby> 任意多项式大小线路 <rt>  arbitrary polynomial-size circuits </rt></ruby>运作的 ABE。所以这一方向毫无疑问非常有发展潜力。

这一潜力启发了研究人员将所有以上的想法一般化成为单独一类被称作 <ruby>   “函数式加密”  <rt>  functional encryption </rt></ruby> 的加密方式。函数式加密更多是一种抽象的概念而没有具体所指——它不过是一种将所有这些系统看作是一个特定的类的实例的方式。它基本的想法是，用一种依赖于（1）明文，和（2）嵌入在密钥中的数据 的任意函数 F 的算法来代表解密过程。

（LCTT 译注：上面函数 F 的 （1） 原文是“the plaintext inside of a ciphertext”，但译者认为应该是密文，其下的公式同。）

这个函数大概是这样的：

```
输出 = F（密钥数据，密文数据）

```

在这一模型中，IBE 可以表达为有一个加密算法 *加密（身份，明文）*并定义了一个这样的函数 F：如果“*密钥输入 == 身份*”，则输出对应明文，否则输出空字符串的系统。相似地，ABE 可以表达为一个稍微更复杂的函数。依照这一范式，我们可以展望在将来，各类有趣的功能都可以由计算不同的函数得到，并在未来的方案中被实现。

但这些都必须要等到以后了。今天我们谈的已经足够多了。

### 所以这一切的重点是什么？

对于我来说，重点不过是证明密码学可以做到一些十分优美惊人的事。当谈及工业与“应用”密码学时，我们鲜有见到这些出现在日常应用中，但我们都可以等待着它们被广泛使用的一天的到来。

也许完美的应用就在某个地方，也许有一天我们会发现它。

*注：*

* 注 1：最初在这片博文里我写的是 “20 世纪 90 年代中期”。在文章的评论里，Tom Ristenpart 提出了异议，并且非常好地论证了很多重要的发展都是在这个时间之后发生的。所以我把时间再推进了大约 5 年，而我也在考虑怎样将这表达得更好一些。
* 注 2：我们知道有一种叫作 [“无证书加密”](http://eprint.iacr.org/2003/126.pdf) 的加密的中间形式。这个想法由 Al-Riyami 和 Paterson 提出，并且使用到标准公钥加密和 IBE 的结合。基本的思路是用一个（消息接受者生成的）传统密钥和一个 IBE 身份*共同*加密每则消息。然后接受者必须从 IBE 权威机构处获得一份私钥的拷贝来解密。这种方案的优点是两方面的：（1）IBE 密钥机构不能独自解密消息，因为它没有对应的（接受者）私钥，这就解决了“托管”问题（即权威机构完全具备解密消息的能力）；（2）发送者不必验证公钥的确属于接收者（LCTT 译注：原文为 sender,但译者认为应该是笔误，应为 recipient），因为 IBE 方面会防止伪装者解密这则消息。但不幸的是，这个系统更像是传统的公钥加密系统，而缺少 IBE 简洁的实用特性。
* 注 3：开发 IBE 的一部分挑战在于构建一个面临不同密钥持有者的“勾结”安全的系统。譬如说，想象一个非常简单的只有 2 比特的身份鉴定系统。这个系统只提供四个可能的身份：“00”，“01”，“10”，“11”。如果我分配给你对应 “01” 身份的密钥，分配给 Bob 对应 “10” 的密钥，我需要保证你们不能合谋生成对应 “00” 和 “11” 身份的密钥。一些早期提出的解决方法尝试通过用不同方式将标准公共加密密钥拼接到一起来解决这个问题（比如，为身份的每一个字节保留一个独立的公钥，然后将对应的多个私钥合并成一个分发）。但是，当仅仅只有少量用户合谋（或者他们的密钥被盗）时，这些系统就往往会出现灾难性的失败。因而基本上这个问题的解决就是真正的 IBE 与它的仿造近亲之间的区别。
* 注 4： 博奈和富兰克林方案的完整描述可以在 [这里](https://en.wikipedia.org/wiki/Boneh%E2%80%93Franklin_scheme) 看到，或者在他们的 [原版论文](https://crypto.stanford.edu/%7Edabo/papers/bfibe.pdf) 中。[这里](http://go-search.org/view?id=github.com%2Fvanadium%2Fgo.lib%2Fibe)、[这里](https://github.com/relic-toolkit/relic) 和 [这里](https://github.com/JHUISI/charm) 有一部分代码。除了指出这个方案十分高效之外，我不希望在这上面花太多的篇幅。它由 [Voltage Security](https://www.voltage.com/)（现属于惠普） 实现并占有专利。

---

via: <https://blog.cryptographyengineering.com/2017/07/02/beyond-public-key-encryption/>

作者：[Matthew Green](https://blog.cryptographyengineering.com/author/matthewdgreen/) 译者：[Janzen\_Liu](https://github.com/JanzenLiu) 校对：[wxy](https://github.com/wxy)

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


在 Linux 中分割和重组文件

Summary: csplit 是这些有趣的小命令中的一个，它永远伴你左右，一旦开始用它就离不开了。

mark一下

感觉很有用，有些系统日志文件不进行分割，出现故障后发现日志文件太大不好查看，应该可以用这个命令对日志文件进行分割吧

![](/data/attachment/album/201708/29/075907u54worafhr14m7yt.jpg)

>
> 非常有用的 `csplit` 命令可以将单个文件分割成多个文件。Carla Schroder 解释说。
>
>
>

Linux 有几个用于分割文件的工具程序。那么你为什么要分割文件呢？一个用例是将大文件分割成更小的尺寸，以便它适用于比较小的存储介质，比如 U 盘。当您遇到 FAT32（最大文件大小为 4GB），且您的文件大于此时，通过 U 盘传输文件也是一个很好的技巧。另一个用例是加速网络文件传输，因为小文件的并行传输通常更快。

我们将学习如何使用 `csplit`，`split` 和 `cat` 来重新整理文件，然后再将文件合并在一起。这些操作在任何文件类型下都有用：文本、图片、音频文件、ISO 镜像文件等。

### 使用 csplit 分割文件

`csplit` 是这些有趣的小命令中的一个，它永远伴你左右，一旦开始用它就离不开了。`csplit` 将单个文件分割成多个文件。这个示例演示了最简单的使用方法，它将文件 foo.txt 分为三个文件，以行号 17 和 33 作为分割点：

```
$ csplit foo.txt 17 33
2591
3889
2359

```

`csplit` 在当前目录下创建了三个新文件，并以字节为单位打印出新文件的大小。默认情况下，每个新文件名为 `xx_nn`：

```
$ ls
xx00
xx01
xx02

```

您可以使用 `head` 命令查看每个新文件的前十行：

```
$ head xx*

==> xx00 <==
Foo File
by Carla Schroder

Foo text

Foo subheading

More foo text

==> xx01 <==
Foo text

Foo subheading

More foo text

==> xx02 <==
Foo text

Foo subheading

More foo text

```

如果要将文件分割成包含相同行数的多个文件怎么办？可以指定行数，然后将重复次数放在在花括号中。此示例重复分割 4 次，并将剩下的转储到最后一个文件中：

```
$ csplit foo.txt 5 {4}
57
1488
249
1866
3798

```

您可以使用星号通配符来告诉 `csplit` 尽可能多地重复分割。这听起来很酷，但是如果文件不能等分，则可能会失败（LCTT 译注：低版本的 `csplit` 不支持此参数）：

```
$ csplit foo.txt 10 {*}
1545
2115
1848
1901
csplit: '10': line number out of range on repetition 4
1430

```

默认的行为是删除发生错误时的输出文件。你可以用 `-k` 选项来解决这个问题，当有错误时，它就不会删除输出文件。另一个行为是每次运行 `csplit` 时，它将覆盖之前创建的文件，所以你需要使用新的文件名来分别保存它们。使用 `--prefix= _prefix_` 来设置一个不同的文件前缀：

```
$ csplit -k --prefix=mine foo.txt 5 {*}
57
1488
249
1866
993
csplit: '5': line number out of range on repetition 9
437

$ ls
mine00
mine01
mine02
mine03
mine04
mine05

```

选项 `-n` 可用于改变对文件进行编号的数字位数（默认是 2 位）：

```
$ csplit -n 3 --prefix=mine foo.txt 5 {4}
57
1488
249
1866
1381
3798

$ ls
mine000
mine001
mine002
mine003
mine004
mine005

```

`csplit` 中的 “c” 是上下文（context）的意思。这意味着你可以根据任意匹配的方式或者巧妙的正则表达式来分割文件。下面的例子将文件分为两部分。第一个文件在包含第一次出现 “fie” 的前一行处结束，第二个文件则以包含 “fie” 的行开头。

```
$ csplit foo.txt /fie/

```

在每次出现 “fie” 时分割文件：

```
$ csplit foo.txt /fie/ {*}

```

在 “fie” 前五次出现的地方分割文件：

```
$ csplit foo.txt /fie/ {5}

```

仅当内容以包含 “fie” 的行开始时才复制，并且省略前面的所有内容：

```
$ csplit myfile %fie%

```

### 将文件分割成不同大小

`split` 与 `csplit` 类似。它将文件分割成特定的大小，当您将大文件分割成小的多媒体文件或者使用网络传送时，这就非常棒了。默认的大小为 1000 行：

```
$ split foo.mv
$ ls -hl
266K Aug 21 16:58 xaa
267K Aug 21 16:58 xab
315K Aug 21 16:58 xac
[...]

```

它们分割出来的大小相似，但你可以指定任何你想要的大小。这个例子中是 20M 字节：

```
$ split -b 20M foo.mv

```

尺寸单位缩写为 K，M，G，T，P，E，Z，Y（1024 的幂）或者 KB，MB，GB 等等（1000 的幂）。

为文件名选择你自己的前缀和后缀：

```
$ split -a 3 --numeric-suffixes=9 --additional-suffix=mine foo.mv SB
240K Aug 21 17:44 SB009mine
214K Aug 21 17:44 SB010mine
220K Aug 21 17:44 SB011mine

```

`-a` 选项控制编号的数字位置。`--numeric-suffixes` 设置编号的开始值。默认前缀为 `x`，你也可以通过在文件名后输入它来设置一个不同的前缀。

### 将分割后的文件合并

你可能想在某个时候重组你的文件。常用的 `cat` 命令就用在这里：

```
$ cat SB0* > foo2.txt

```

示例中的星号通配符将匹配到所有以 SB0 开头的文件，这可能不会得到您想要的结果。您可以使用问号通配符进行更精确的匹配，每个字符使用一个问号：

```
$ cat SB0?????? > foo2.txt

```

和往常一样，请查阅相关的手册和信息页面以获取完整的命令选项。

---

via: <https://www.linux.com/learn/intro-to-linux/2017/8/splitting-and-re-assembling-files-linux>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[firmianay](https://github.com/firmianay) 校对：[wxy](https://github.com/wxy)

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


如何恢复丢弃的 git stash 数据

Summary: 不要让 git 命令中的错误抹去你数天的工作

不要让 git 命令中的错误抹去你数天的工作

>
> 不要让 git 命令中的错误抹去你数天的工作
>
>
>

![How to recover from a git mistake](/data/attachment/album/201708/29/081540gi5br5ma5tt5urud.png "How to recover from a git mistake")

今天我的同事几乎失去了他在四天工作中所做的一切。由于不正确的 `git` 命令，他把保存在 [stash](https://www.git-scm.com/docs/git-stash) 中的更改删除了。在这悲伤的情节之后，我们试图寻找一种恢复他所做工作的方法，而且我们做到了！

首先警告一下：当你在实现一个大功能时，请将它分成小块并定期提交。长时间工作而不做提交并不是一个好主意。

现在我们已经搞定了那个错误，下面就演示一下怎样从 stash 中恢复误删的更改。

我用作示例的仓库中，只有一个源文件 “main.c”，如下所示：

![Repository with one source file](/data/attachment/album/201708/29/081540sv6z6zs8ymfcv6zb.jpg "Repository with one source file")

它只有一次提交，即 “Initial commit”：

![One commit](/data/attachment/album/201708/29/081541wn8h7p6pibez6til.jpg "One commit")

该文件的第一个版本是：

![First version of the file](/data/attachment/album/201708/29/081541hr13lr1wwyiwg1u1.jpg "First version of the file")

我将在文件中写一些代码。对于这个例子，我并不需要做什么大的改动，只需要有什么东西放进 stash 中即可，所以我们仅仅增加一行。“git diff” 的输出如下：

![git-diff output ](/data/attachment/album/201708/29/081542pl6dlerl4jl3gwl6.jpg "git-diff output ")

现在，假设我想从远程仓库中拉取一些新的更改，当时还不打算提交我自己的更改。于是，我决定先 stash 它，等拉取远程仓库中的更改后，再把我的更改恢复应用到主分支上。我执行下面的命令将我的更改移动到 stash 中：

```
git stash

```

使用命令 `git stash list` 查看 stash，在这里能看到我的更改：

![Output of changes in our stash](/data/attachment/album/201708/29/081542tpj552dj3jliggjj.jpg "Output of changes in our stash")

我的代码已经在一个安全的地方，而且主分支目前是干净的（使用命令 `git status` 检查）。现在我只需要拉取远程仓库的更改，然后把我的更改恢复应用到主分支上，而且我也应该是这么做的。

但是我错误地执行了命令：

```
git stash drop

```

它删除了 stash，而不是执行了下面的命令：

```
git stash pop

```

这条命令会在从栈中删除 stash 之前应用它。如果我再次执行命令 `git stash list`，就能看到在没有从栈中将更改恢复到主分支的之前，我就删除了它。OMG！接下来怎么办？

好消息是：`git` 并没有删除包含了我的更改的对象，它只是移除了对它的引用。为了证明这一点，我使用命令 `git fsck`，它会验证数据库中对象的连接和有效性。这是我对该仓库执行了 `git fsck` 之后的输出：

![Output after executing the git-fsck command on the repository](/data/attachment/album/201708/29/081543ntr6lfmmmmzmfraf.jpg "Output after executing the git-fsck command on the repository")

由于使用了参数 `--unreachable`，我让 `git-fsck` 显示出所有不可访问的对象。正如你看到的，它显示并没有不可访问的对象。而当我从 stash 中删除了我的更改之后，再次执行相同的指令，得到了一个不一样的输出：

![Output after dropping changes on stash](/data/attachment/album/201708/29/081543ucc9fc19uvyo1hgf.jpg "Output after dropping changes on stash")

现在有三个不可访问对象。那么哪一个才是我的更改呢？实际上，我不知道。我需要通过执行命令 `git show` 来搜索每一个对象。

![Output after executing the git-show command ](/data/attachment/album/201708/29/081543nbjmxrrk778yv0xx.jpg "Output after executing the git-show command ")

就是它！ID 号 `95ccbd927ad4cd413ee2a28014c81454f4ede82c` 对应了我的更改。现在我已经找到了丢失的更改，我可以恢复它。其中一种方法是将此 ID 取出来放进一个新的分支，或者直接提交它。如果你得到了你的更改对象的 ID 号，就可以决定以最好的方式，将更改再次恢复应用到主分支上。对于这个例子，我使用 `git stash` 将更改恢复到我的主分支上。

```
git stash apply 95ccbd927ad4cd413ee2a28014c81454f4ede82c

```

另外需要重点记住的是 `git` 会周期性地执行它的垃圾回收程序（`gc`），它执行之后，使用 `git fsck` 就不能再看到不可访问对象了。

*本文[最初发表](http://jvanz.com/recovering-missed-data-from-stash.html#recovering-missed-data-from-stash)于作者的博客，并得到了转载授权。*

（题图：opensource.com，附图：José Guilherme Vanz, [CC BY](https://creativecommons.org/licenses/by/4.0/)）

---

via: <https://opensource.com/article/17/8/recover-dropped-data-stash>

作者：[Jose Guilherme Vanz](https://opensource.com/users/jvanz) 译者：[firmianay](https://github.com/firmianay) 校对：[wxy](https://github.com/wxy)

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


六个优雅的 Linux 命令行技巧

建议还是依照原标题进行翻译（六个灵巧的），感觉现在“优雅”这个词有用滥的趋势，其含义已经偏向于“自我沉浸，自我陶醉”。

灵巧的 watch

>
> 一些非常有用的命令能让命令行的生活更满足
>
>
>

![command key keyboard](/data/attachment/album/201708/29/231508v5fzz98954s9ffd4.jpg)

使用 Linux 命令工作可以获得许多乐趣，但是如果您使用一些命令，它们可以减少您的工作或以有趣的方式显示信息时，您将获得更多的乐趣。在今天的文章中，我们将介绍六个命令，它们可能会使你用在命令行上的时间更加值当。

### watch

`watch` 命令会重复运行您给出的任何命令，并显示输出。默认情况下，它每两秒运行一次命令。命令的每次运行都将覆盖上一次运行时显示的内容，因此您始终可以看到最新的数据。

您可能会在等待某人登录时使用它。在这种情况下，您可以使用 `watch who` 命令或者 `watch -n 15 who` 命令使每 15 秒运行一次，而不是两秒一次。另外终端窗口的右上角会显示日期和时间。

```
$ watch -n 5 who
Every 5.0s: who                               stinkbug: Wed Aug 23 14:52:15 2017

shs      pts/0        2017-08-23 14:45 (192.168.0.11)
zoe      pts/1        2017-08-23 08:15 (192.168.0.19)

```

您也可以使用它来查看日志文件。如果您显示的数据没有任何变化，则只有窗口角落里的日期和时间会发生变化。

```
$ watch tail /var/log/syslog
Every 2.0s: tail /var/log/syslog              stinkbug: Wed Aug 23 15:16:37 2017

Aug 23 14:45:01 stinkbug CRON[7214]: (root) CMD (command -v debian-sa1 > /dev/nu
ll && debian-sa1 1 1)
Aug 23 14:45:17 stinkbug systemd[1]: Started Session 179 of user shs.
Aug 23 14:55:01 stinkbug CRON[7577]: (root) CMD (command -v debian-sa1 > /dev/nu
ll && debian-sa1 1 1)
Aug 23 15:05:01 stinkbug CRON[7582]: (root) CMD (command -v debian-sa1 > /dev/nu
ll && debian-sa1 1 1)
Aug 23 15:08:48 stinkbug systemd[1]: Starting Cleanup of Temporary Directories...
Aug 23 15:08:48 stinkbug systemd-tmpfiles[7584]: [/usr/lib/tmpfiles.d/var.conf:1
4] Duplicate line for path "/var/log", ignoring.
Aug 23 15:08:48 stinkbug systemd[1]: Started Cleanup of Temporary Directories.
Aug 23 15:13:41 stinkbug systemd[1]: Started Session 182 of user shs.
Aug 23 15:14:29 stinkbug systemd[1]: Started Session 183 of user shs.
Aug 23 15:15:01 stinkbug CRON[7828]: (root) CMD (command -v debian-sa1 > /dev/nu
ll && debian-sa1 1 1)

```

这里的输出和使用命令 `tail -f /var/log/syslog` 的输出相似。

### look

这个命令的名字 `look` 可能会让我们以为它和 `watch` 做类似的事情，但其实是不同的。`look` 命令用于搜索以某个特定字符串开头的单词。

```
$ look ecl
eclectic
eclectic's
eclectically
eclecticism
eclecticism's
eclectics
eclipse
eclipse's
eclipsed
eclipses
eclipsing
ecliptic
ecliptic's

```

`look` 命令通常有助于单词的拼写，它使用 `/usr/share/dict/words` 文件，除非你使用如下的命令指定了文件名：

```
$ look esac .bashrc
esac
esac
esac

```

在这种情况下，它的作用就像跟在一个 `awk` 命令后面的 `grep` ，只打印匹配行上的第一个单词。

### man -k

`man -k` 命令列出包含指定单词的手册页。它的工作基本上和 `apropos` 命令一样。

```
$ man -k logrotate
dh_installlogrotate (1) - install logrotate config files
logrotate (8)        - rotates, compresses, and mails system logs
logrotate.conf (5)   - rotates, compresses, and mails system logs

```

### help

当你完全绝望的时候，您可能会试图使用此命令，`help` 命令实际上是显示一个 shell 内置命令的列表。最令人惊讶的是它有相当多的参数变量。你可能会看到这样的东西，然后开始想知道这些内置功能可以为你做些什么：

```
$ help
GNU bash, version 4.4.7(1)-release (i686-pc-linux-gnu)
These shell commands are defined internally.  Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.

A star (*) next to a name means that the command is disabled.

 job_spec [&]                            history [-c] [-d offset] [n] or hist>
 (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
 . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
 :                                       kill [-s sigspec | -n signum | -sigs>
 [ arg... ]                              let arg [arg ...]
 [[ expression ]]                        local [option] name[=value] ...
 alias [-p] [name[=value] ... ]          logout [n]
 bg [job_spec ...]                       mapfile [-d delim] [-n count] [-O or>
 bind [-lpsvPSVX] [-m keymap] [-f file>  popd [-n] [+N | -N]
 break [n]                               printf [-v var] format [arguments]
 builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
 caller [expr]                           pwd [-LP]
 case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
 cd [-L|[-P [-e]] [-@]] [dir]            readarray [-n count] [-O origin] [-s>
 command [-pVv] command [arg ...]        readonly [-aAf] [name[=value] ...] o>
 compgen [-abcdefgjksuv] [-o option] [>  return [n]
 complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
 compopt [-o|+o option] [-DE] [name ..>  set [-abefhkmnptuvxBCHP] [-o option->
 continue [n]                            shift [n]
 coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
 declare [-aAfFgilnrtux] [-p] [name[=v>  source filename [arguments]
 dirs [-clpv] [+N] [-N]                  suspend [-f]
 disown [-h] [-ar] [jobspec ... | pid >  test [expr]
 echo [-neE] [arg ...]                   time [-p] pipeline
 enable [-a] [-dnps] [-f filename] [na>  times
 eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
 exec [-cl] [-a name] [command [argume>  true
 exit [n]                                type [-afptP] name [name ...]
 export [-fn] [name[=value] ...] or ex>  typeset [-aAfFgilnrtux] [-p] name[=v>
 false                                   ulimit [-SHabcdefiklmnpqrstuvxPT] [l>
 fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
 fg [job_spec]                           unalias [-a] name [name ...]
 for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [-n] [name ...]
 for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
 function name { COMMANDS ; } or name >  variables - Names and meanings of so>
 getopts optstring name [arg]            wait [-n] [id ...]
 hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
 help [-dms] [pattern ...]               { COMMANDS ; }

```

### stat -c

`stat` 命令用于显示文件的大小、所有者、用户组、索引节点号、权限、修改和访问时间等重要的统计信息。这是一个非常有用的命令，可以显示比 `ls -l` 更多的细节。

```
$ stat .bashrc
  File: .bashrc
  Size: 4048            Blocks: 8          IO Block: 4096   regular file
Device: 806h/2054d      Inode: 421481      Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     shs)   Gid: ( 1000/     shs)
Access: 2017-08-23 15:13:41.781809933 -0400
Modify: 2017-06-21 17:37:11.875157790 -0400
Change: 2017-06-21 17:37:11.899157791 -0400
 Birth: -

```

使用 `-c` 选项，您可以指定要查看的字段。例如，如果您只想查看一个文件或一系列文件的文件名和访问权限，则可以这样做：

```
$ stat -c '%n %a' .bashrc
.bashrc 644

```

在此命令中， `%n` 表示每个文件的名称，而 `%a` 表示访问权限。`%u` 表示数字类型的 UID，而 `%U` 表示用户名。

```
$ stat -c '%n %a' bin/*
bin/loop 700
bin/move2nohup 700
bin/nohup.out 600
bin/show_release 700

$ stat -c '%n %a %U' bin/*
bin/loop 700 shs
bin/move2nohup 700 shs
bin/nohup.out 600 root
bin/show_release 700 shs

```

### TAB

如果你没有使用过 tab 键来补全文件名，你真的错过了一个非常有用的命令行技巧。tab 键提供文件名补全功能（包括使用 `cd` 时的目录）。它在出现歧义之前尽可能多的填充文件名（多个文件以相同的字母开头。如果您有一个名为 `bigplans` 的文件，另一个名为 `bigplans2017` 的文件会发生歧义，你将听到一个声音，然后需要决定是按下回车键还是输入 `2` 之后再按下 tab 键选择第二个文件。

（题图：[Micah Elizabeth Scott](https://www.flickr.com/photos/micahdowty/4630801442/in/photolist-84d4Wb-p29iHU-dscgLx-pXKT7a-pXKT7v-azMz3V-azMz7M-4Amp2h-6iyQ51-4nf4VF-5C1gt6-6P4PwG-po6JEA-p6C5Wg-6RcRbH-7GAmbK-dCkRnT-7ETcBp-4Xbhrw-dXrN8w-dXm83Z-dXrNvQ-dXrMZC-dXrMPN-pY4GdS-azMz8X-bfNoF4-azQe61-p1iUtm-87i3vj-7enNsv-6sqvJy-dXm8aD-6smkyX-5CFfGm-dXm8dD-6sqviw-6sqvVU-dXrMVd-6smkXc-dXm7Ug-deuxUg-6smker-Hd15p-6squyf-aGtnxn-6smjRX-5YtTUN-nynqYm-ea5o3c) [(CC BY 2.0)](https://creativecommons.org/licenses/by/2.0/legalcode)）

---

via: <https://www.networkworld.com/article/3219684/linux/half-a-dozen-clever-linux-command-line-tricks.html>

作者：[Sandra Henry-Stocker](https://www.networkworld.com/author/Sandra-Henry_Stocker/) 译者：[firmianay](https://github.com/firmianay) 校对：[wxy](https://github.com/wxy)

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


通过开源书籍学习 Ruby 编程

![](/data/attachment/album/201708/29/235444vzj5tdym77o0dmc6.jpg)

### 开源的 Ruby 书籍

Ruby 是由 Yukihiro “Matz” Matsumoto 开发的一门通用目的、脚本化、结构化、灵活且完全面向对象的编程语言。它具有一个完全动态类型系统，这意味着它的大多数类型检查是在运行的时候进行，而非编译的时候。因此程序员不必过分担心是整数类型还是字符串类型。Ruby 会自动进行内存管理，它具有许多和 Python、Perl、Lisp、Ada、Eiffel 和 Smalltalk 相同的特性。

Ruby on Rails 框架对于 Ruby 的流行起到了重要作用，它是一个全栈 Web 框架，目前已被用来创建许多受欢迎的应用，包括 Basecamp、GitHub、Shopify、Airbnb、Twitch、SoundCloud、Hulu、Zendesk、Square 和 Highise 。

Ruby 具有很高的可移植性性，在 Linux、Windows、Mac OS X、Cygwin、FreeBSD、NetBSD、OpenBSD、BSD/OS、Solaris、Tru64 UNIX、HP-UX 以及其他许多系统上均可运行。目前，Ruby 在 TIOBE 编程社区排名 12 。

这篇文章有 9 本很优秀的推荐书籍，有针对包括初学者、中级程序员和高级程序员的书籍。当然，所有的书籍都是在开源许可下发布的。

这篇文章是 [OSSBlog 的系列文章开源编程书籍](https://www.ossblog.org/opensourcebooks/)的一部分。

### 《[Ruby Best Practices](https://github.com/practicingruby/rbp-book/tree/gh-pages/pdfs)》

![](/data/attachment/album/201708/29/235623al7r74zuuf0bbqur.jpg)

作者： Gregory Brown (328 页)

《Ruby Best Practices》适合那些希望像有经验的 Ruby 专家一样使用 Ruby 的程序员。本书是由 Ruby 项目 Prawn 的开发者所撰写的，它阐述了如何使用 Ruby 设计美丽的 API 和特定领域语言，以及如何利用函数式编程想法和技术，从而简化代码，提高效率。

《Ruby Best Practices》 更多的内容是关于如何使用 Ruby 来解决问题，它阐述的是你应该使用的最佳解决方案。这本书不是针对 Ruby 初学者的，所以对于编程新手也不会有太多帮助。这本书的假想读者应该对 Ruby 的相应技术有一定理解，并且拥有一些使用 Ruby 来开发软件的经验。

这本书分为两部分，前八章组成本书的核心部分，后三章附录作为补充材料。

这本书提供了大量的信息：

* 通过测试驱动代码 - 涉及了大量的测试哲学和技术。使用 mocks 和 stubs
* 通过利用 Ruby 神秘的力量来设计漂亮的 API：灵活的参数处理和代码块
* 利用动态工具包向开发者展示如何构建灵活的界面，实现单对象行为，扩展和修改已有代码，以及程序化地构建类和模块
* 文本处理和文件管理集中于正则表达式，文件、临时文件标准库以及文本处理策略实战
* 函数式编程技术优化了模块代码组织、存储、无穷目录以及更高顺序程序。
* 理解代码如何出错以及为什么会出错，阐述如何处理日志记录
* 通过利用 Ruby 的多语言能力削弱文化屏障
* 熟练的项目维护

本书为开源书籍，在 CC NC-SA 许可证下发布。

[在此下载《Ruby Best Practices》](https://github.com/practicingruby/rbp-book/tree/gh-pages/pdfs)。

### 《[I Love Ruby](https://mindaslab.github.io/I-Love-Ruby/)》

![](/data/attachment/album/201708/29/235717ubqqdkv0dkda99ip.jpg)

作者： Karthikeyan A K (246 页)

《I Love Ruby》以比传统的介绍更高的深度阐述了基本概念和技术。该方法为编写有用、正确、易维护和高效的 Ruby 代码提供了一个坚实的基础。

章节内容涵盖：

* 变量
* 字符串
* 比较和逻辑
* 循环
* 数组
* 哈希和符号
* Ranges
* 函数
* 变量作用域
* 类 & 对象
* Rdoc
* 模块和 Mixins
* 日期和时间
* 文件
* Proc、匿名 和 块
* 多线程
* 异常处理
* 正则表达式
* Gems
* 元编程

在 GNU 自由文档许可证之下，你可以复制、发布和修改本书，1.3 或任何之后版本由自由软件基金会发布。

[点此下载《I Love Ruby》](https://mindaslab.github.io/I-Love-Ruby/)。

### [Programming Ruby – The Pragmatic Programmer’s Guide](http://ruby-doc.com/docs/ProgrammingRuby/)

![](/data/attachment/album/201708/29/235744umlq3lp35f5k1du5.jpeg)

作者： David Thomas, Andrew Hunt (HTML)

《Programming Ruby – The Pragmatic Programmer’s Guide》是一本 Ruby 编程语言的教程和参考书。使用 Ruby，你将能够写出更好的代码，更加有效率，并且使编程变成更加享受的体验。

内容涵盖以下部分：

* 类、对象和变量
* 容器、块和迭代器
* 标准类型
* 更多方法
* 表达式
* 异常、捕获和抛出
* 模块
* 基本输入和输出
* 线程和进程
* 何时抓取问题
* Ruby 和它的世界、Web、Tk 和 微软 Windows
* 扩展 Ruby
* 映像、对象空间和分布式 Ruby
* 标准库
* 面向对象设计库
* 网络和 Web 库
* 嵌入式文件
* 交互式 Ruby shell

这本书的第一版在开放发布许可证 1.0 版或更新版的许可下发布。本书更新后的第二版涉及 Ruby 1.8 ，并且包括所有可用新库的描述，但是它不是在免费发行许可证下发布的。

[点此下载《Programming Ruby – The Pragmatic Programmer’s Guide》](http://ruby-doc.com/docs/ProgrammingRuby/)。

### 《[Why’s (Poignant) Guide to Ruby](http://poignant.guide/)》

![](/data/attachment/album/201708/29/235836tyqya28qfy3riyif.jpg)

作者：why the lucky stiff (176 页)

《Why’s (poignant) Guide to Ruby》是一本 Ruby 编程语言的介绍书籍。该书包含一些冷幽默，偶尔也会出现一些和主题无关的内容。本书包含的笑话在 Ruby 社区和卡通角色中都很出名。

本书的内容包括：

* 关于本书
* Kon’nichi wa, Ruby
* 一个快速（希望是无痛苦的）的 Ruby 浏览（伴随卡通角色）：Ruby 核心概念的基本介绍
* 代码浮动小叶：评估和值，哈希和列表
* 组成规则的核心部分：case/when、while/until、变量作用域、块、方法、类定义、类属性、对象、模块、IRB 中的内省、dup、self 和 rbconfig 模块
* 中心：元编程、正则表达式
* 当你打算靠近胡须时：在已存在类中发送一个新方法
* 天堂演奏

本书在 CC-SA 许可证许可下可用。

[点此下载《Why’s (poignant) Guide to Ruby》](http://poignant.guide/)。

### 《[Ruby Hacking Guide](http://ruby-hacking-guide.github.io/)》

![](/data/attachment/album/201708/29/235941o58qtddtgqovvdq5.jpg)

作者： Minero Aoki ，翻译自 Vincent Isambart 和 Clifford Escobar Caoille (HTML)

通过阅读本书可以达成下面的目标：

* 拥有关于 Ruby 结构的知识
* 掌握一般语言处理的知识
* 收获阅读源代码的技能

本书分为四个部分：

* 对象
* 动态分析
* 评估
* 外部评估

要想从本书中收获最多的东西，需要具备一定 C 语言的知识和基本的面向对象编程知识。本书在 CC-NC-SA 许可证许可下发布。

原书的官方支持网站为 [i.loveruby.net/ja/rhg/](http://i.loveruby.net/ja/rhg/)

[点此下载《Ruby Hacking Guide》](http://ruby-hacking-guide.github.io/)

### 《[The Book Of Ruby](http://www.sapphiresteel.com/ruby-programming/The-Book-Of-Ruby.html)》

![](/data/attachment/album/201708/30/000011aw0i36muw666zee3.jpg)

作者： How Collingbourne (425 页)

《The Book Of Ruby》是一本免费的 Ruby 编程高级教程。

《The Book Of Ruby》以 PDF 文件格式提供，并且每一个章节的所有例子都伴有可运行的源代码。同时，也有一个介绍来阐述如何在 Steel 或其他任何你喜欢的编辑器/IDE 中运行这些 Ruby 代码。它主要集中于 Ruby 语言的 1.8.x 版本。

本书被分成很小的块。每一个章节介绍一个主题，并且分成几个不同的子话题。每一个编程主题由一个或多个小的自包含、可运行的 Ruby 程序构成。

* 字符串、数字、类和对象 - 获取输入和输出、字符串和外部评估、数字和条件测试：if ... then、局部变量和全局变量、类和对象、实例变量、消息、方法、多态性、构造器和检属性和类变量 - 超类和子类，超类传参，访问器方法，’set‘ 访问器，属性读写器、超类的方法调用，以及类变量
* 类等级、属性和类变量 - 超类和子类，超类传参，访问器方法，’set‘ 访问器，属性读写器、超类的方法调用，以及类变量
* 字符串和 Ranges - 用户自定义字符串定界符、引号等更多
* 数组和哈希 - 展示如何创建一系列对象
* 循环和迭代器 - for 循环、代码块、while 循环、while 修改器以及 until 循环
* 条件语句 - If..Then..Else、And..Or..Not、If..Elsif、unless、if 和 unless 修改器、以及 case 语句
* 方法 - 类方法、类变量、类方法是用来干什么的、Ruby 构造器、单例方法、单例类、重载方法以及更多
* 传递参数和返回值 - 实例方法、类方法、单例方法、返回值、返回多重值、默认参数和多重参数、赋值和常量传递以及更多
* 异常处理 - 涉及 rescue、ensure、else、错误数量、retry 和 raise
* 块、Procs 和 匿名 - 阐述为什么它们对 Ruby 来说很特殊
* 符号 - 符号和字符串、符号和变量以及为什么应该使用符号
* 模块和 Mixins
* 文件和 IO - 打开和关闭文件、文件和目录、复制文件、目录询问、一个关于递归的讨论以及按大小排序
* YAML - 包括嵌套序列，保存 YAML 数据以及更多
* Marshal - 提供一个保存和加载数据的可选择方式
* 正则表达式 - 进行匹配、匹配群组以及更多
* 线程 - 向你展示如何同时运行多个任务
* 调试和测试 - 涉及交互式 Ruby shell（IRB.exe）、debugging 和 单元测试
* Ruby on Rails - 浏览一个创建博客的实践指南
* 动态编程 - 自修改程序、重运算魔法、特殊类型的运算、添加变量和方法以及更多

本书由 SapphireSteel Software 发布，SapphireSteel Software 是用于 Visual Studio 的 Ruby In Steel 集成开发环境的开发者。读者可以复制和发布本书的文本和代码（免费版）

[点此下载《The Book Of Ruby》](http://www.sapphiresteel.com/ruby-programming/The-Book-Of-Ruby.html)

### 《[The Little Book Of Ruby](http://www.sapphiresteel.com/ruby-programming/The-Book-Of-Ruby.html)》

![](/data/attachment/album/201708/30/000044ebre0hvrreb0t0rr.jpg)

作者： Huw Collingbourne (87 页)

《The Little Book of Ruby》是一本一步接一步的 Ruby 编程教程。它指导读者浏览 Ruby 的基础。另外，它分享了《The Book of Ruby》一书的内容，但是它旨在作为一个简化的教程来阐述 Ruby 的主要特性。

章节内容涵盖：

* 字符串和方法 - 包括外部评估。详细描述了 Ruby 方法的语法
* 类和对象 - 阐述如何创建一个新类型的对象
* 类等级 - 一个特殊类型的类，其为一些其他类的简化并且继承了其他一些类的特性
* 访问器、属性、类变量 - 访问器方法，属性读写器，属性创建变量，调用超类方法以及类变量探索
* 数组 - 学习如何创建一系列对象：数组包括多维数组
* 哈希 - 涉及创建哈希表，为哈希表建立索引以及哈希操作等
* 循环和迭代器 - for 循环、块、while 循环、while 修饰器以及 until 循环
* 条件语句 - If..Then..Else、And..Or..Not、If..Elsif、unless、if 和 unless 修饰器以及 case 语句
* 模块和 Mixins - 包括模块方法、模块作为名字空间模块实例方法、模块或 'mixins'、来自文件的模块和预定义模块
* 保存文件以及更多内容

本书可免费复制和发布，只需保留原始文本且注明版权信息。

[点此下载《The Little Book of Ruby》](http://www.sapphiresteel.com/ruby-programming/The-Book-Of-Ruby.html)

### 《[Kestrels, Quirky Birds, and Hopeless Egocentricity](https://leanpub.com/combinators)》

![](/data/attachment/album/201708/30/000127d60rk12krw8yrpku.jpg)

作者： Reg “raganwald” Braithwaite (123 页)

《Kestrels, Quirky Birds, and Hopeless Egocentricity》是通过收集 “Raganwald” Braithwaite 的关于组合逻辑、Method Combinators 以及 Ruby 元编程的系列文章而形成的一本方便的电子书。

本书提供了通过使用 Ruby 编程语言来应用组合逻辑的一个基本介绍。组合逻辑是一种数学表示方法，它足够强大，从而用于解决集合论问题以及计算中的问题。

在这本书中，读者会会探讨到一些标准的 Combinators，并且对于每一个 Combinators，书中都用 Ruby 编程语言写程序探讨了它的一些结果。在组合逻辑上，Combinators 之间组合并相互改变，书中的 Ruby 例子注重组合和修改 Ruby 代码。通过像 K Combinator 和 .tap 方法这样的简单例子，本书阐述了元编程的理念和递归 Combinators 。

本书在 MIT 许可证许可下发布。

[点此下载《Kestrels, Quirky Birds, and Hopeless Egocentricity》](https://leanpub.com/combinators)

### 《[Ruby Programming](https://en.wikibooks.org/wiki/Ruby_Programming)》

![](/data/attachment/album/201708/30/000157fonnnkddsy1kq2pq.jpg)

作者： Wikibooks.org (261 页)

Ruby 是一种解释性、面向对象的编程语言。

本书被分为几个部分，从而方便按顺序阅读。

* 开始 - 向读者展示如何在其中一个操作系统环境中安装并开始使用 Ruby
* Ruby 基础 - 阐述 Ruby 语法的主要特性。它涵盖了字符串、编码、写方法、类和对象以及异常等内容
* Ruby 语义参考
* 内建类
* 可用模块，涵盖一些标准库
* 中级 Ruby 涉及一些稍微高级的话题

本书在 CC-SA 3.0 本地化许可证许可下发布。

[点此下载《Ruby Programming》](https://en.wikibooks.org/wiki/Ruby_Programming)

---

无特定顺序，我将在结束前推荐一些没有在开源许可证下发布但可以免费下载的 Ruby 编程书籍。

* [Mr. Neighborly 的 Humble Little Ruby Book](http://www.humblelittlerubybook.com/) – 一个易读易学的 Ruby 完全指南。
* [Introduction to Programming with Ruby](https://launchschool.com/books/ruby) – 学习编程的基础知识，一切从零开始。
* [Object Oriented Programming with Ruby](https://launchschool.com/books/oo_ruby) – 学习编程的基础知识，一切从零开始。
* [Core Ruby Tools](https://launchschool.com/books/core_ruby_tools) – 对 Ruby 的四个核心工具 Gems、Ruby Version Managers、Bundler 和 Rake 进行了简短的概述。
* [Learn Ruby the Hard Way, 3rd Edition](https://learnrubythehardway.org/book/) – 一本适合初学者的入门书籍。
* [Learn to Program](https://pine.fm/LearnToProgram) – 来自 Chris Pine。
* [Ruby Essentials](http://www.techotopia.com/index.php/Ruby_Essentials) – 一个准确且简单易学的 Ruby 学习指南。

---

via: <https://www.ossblog.org/study-ruby-programming-with-open-source-books/>

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

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


在标准建立之前，软件所存在的问题

>
> 开源项目需要认真对待交付成果中所包含的标准
>
>
>

![The problem with software before standards](/data/attachment/album/201708/30/085019xvpgluu1vf22pl28.png "The problem with software before standards")

无论以何种标准来衡量，开源软件作为传统的专有软件的替代品而崛起，取得了不错的效果。 如今，仅 Github 中就有着数以千万计的代码仓库，其中重要项目的数量也在快速增长。在本文撰写的时候，[Apache 软件基金会](https://www.apache.org/) 开展了超过 [300 个项目](https://projects.apache.org/)， [Linux 基金会](https://www.linuxfoundation.org/) 支持的项目也超过了 60 个。与此同时，[OpenStack 基金会](https://www.linuxfoundation.org/projects/directory) 在 180 多个国家拥有超过 60,000 名成员。

这样说来，这种情景下有什么问题么？

开源软件在面对用户的众多需求时，由于缺少足够的意识，而无法独自去解决全部需求。 更糟糕的是，许多开源软件社区的成员（业务主管以及开发者）对利用最合适的工具解决这一问题并不感兴趣。

让我们开始找出那些有待解决的问题，看看这些问题在过去是如何被处理的。

问题存在于：通常许多项目都在试图解决一个大问题当中重复的一小部分，而客户希望能够在竞争产品之间做出选择，不满意的话还能够轻松选择其他产品。但是现在看来都是不可能的，在这个问题被解决之前它将会阻碍开源软件的使用。

这已经不是一个新的问题或者没有传统解决方案的问题了。在一个半世纪以来，用户期望有更多的选择和自由来变换厂商，而这一直是通过标准的制定来实现的。在现实当中，你可以对螺丝钉、灯泡、轮胎、延长线的厂商做出无数多的选择，甚至于对独特形状的红酒杯也可以专注选择。因为标准为这里的每一件物品都提供了物理规格。而在健康和安全领域，我们的幸福也依赖于成千上万的标准，这些标准是由私营行业制定的，以确保在最大化的竞争中能够有完美的结果。

随着信息与通信技术（ICT）的发展，以同样类似的方式形成了一些重要的组织机构，例如：国际电信联盟（ITU）、国际电工委员会（IEC），以及电气与电子工程师学会标准协会（IEEE-SA）。近千家财团遵循 ICT 标准来进行开发、推广以及测试。

虽然并非是所有的 ICT 标准都形成了无缝对接，但如今在我们生活的科技世界里，成千上万的基本标准履行着这一承诺，这些标准包含了计算机、移动设备、Wi-Fi 路由器以及其他一切依赖电力来运行的东西。

关键的一点，在很长的一段时间里，由于客户对拥有种类丰富的产品、避免受制于供应商，并且享受全球范围内的服务的渴望，逐渐演变出了这一体系。

现在让我们来看看开源软件是如何演进的。

好消息是伟大的软件已经被创造出来了。坏消息是对于像云计算和虚拟化网络这样的关键领域，没有任何单独的基金会在开发整个堆栈。取而代之的是，单个项目开发单独的一层或者多层，依靠需要时才建立的善意的合作，这些项目最终堆叠成栈。当这一过程运行良好时，结果是好的，但也有可能形成与传统的专有产品同样的锁定。相反，当这一过程运行不良时，坏的结果就是它会浪费开发商、社区成员的时间和努力，同时也会辜负客户的期望。

最明确的解决方法的创建标准，允许客户避免被锁定，鼓励多个解决方案通过对附加服务和功能进行有益的竞争。当然也存在着例外，但这不是开源世界正在发生的情况。

这背后的主要原因在于，开源社区的主流观点是：标准意味着限制、落后和多余。对于一个完整的堆栈中的单独一层来说，可能就是这样。但客户想要选择的自由、激烈的竞争，这就导致回到了之前的坏结果上，尽管多个厂商提供相似的集成堆栈，但却被锁定在一个技术上。

在 Yaron Haviv 于 2017 年 6 月 14 日所写的 “[除非我们协作，否则我们将被困在专有云上](https://www.enterprisetech.com/2017/06/14/well-enslaved-proprietary-clouds-unless-collaborate/)” 一文中，就有对这一问题有着很好的描述。

>
> 在今天的开源生态系统当中存在一个问题，跨项目整合并不普遍。开源项目能够进行大型合作，构建出分层的模块化的架构，比如说 Linux — 已经一次又一次的证明了它的成功。但是与 Linux 的意识形成鲜明对比的就是如今许多开源社区的日常状态。
>
>
> 举个例子：大数据生态系统，就是依赖众多共享组件或通用 API 和层的堆叠来实现的。这一过程同样缺少标准的线路协议，同时，每个处理框架（看看 Spark、Presto 和 Flink）都拥有独立的数据源 API。
>
>
> 这种合作的缺乏正在造成担忧。缺少了合作，项目就会变得不通用，结果对客户产生了负面影响。因为每个人都不得不从头开始，重新开发，这基本上就锁定了客户，减缓了项目的发展。
>
>
>

Haviv 提出了两种解决方法：

* 项目之间更紧密的合作，联合多个项目消除重叠的部分，使堆栈内的整合更加密切；
* 开发 API ，使切换更加容易。

这两种方法都能达到目的。但除非事情能有所改变，我们将只会看到第一种方法，这就是前边展望中发现的技术锁定。结果会发现工业界，无论是过去 WinTel 的世界，或者纵观苹果的历史，相互竞争的产品都是以牺牲选择来换取紧密整合的。

同样的事情似乎很有可能发生在新的开源界，如果开源项目继续忽视对标准的需求，那么竞争会存在于层内，甚至是堆栈间。如果现在能够做到的话，这样的问题可能就不会发生了。

因为如果口惠无实开发软件优先、标准在后的话，对于标准的制定就没有真正的兴趣。主要原因是，大多数的商人和开发者对标准知之甚少。不幸的是，我们能够理解这些使事情变得糟糕的原因。这些原因有几个：

* 大学几乎很少对标准进行培训；
* 过去拥有专业的标准人员的公司遣散了这些部门，现在的部署工程师接受标准组织的培训又远远不够；
* 在建立雇主标准工作方面的专业知识方面几乎没有职业价值；
* 参与标准活动的工程师可能需要以他们认为是最佳技术解决方案为代价来延长雇主的战略利益；
* 在许多公司内部，专业的标准人员与开源开发者之间鲜有交流；
* 许多软件工程师将标准视为与 FOSS 定义的“四大自由”有着直接冲突。

现在，让我们来看看在开源界正在发生什么:

* 今天大多数的软件工程师鲜有不知道开源的；
* 工程师们每天都在享受着开源工具所带来的便利；
* 许多令人激动的最前沿的工作正是在开源项目中完成的；
* 在热门的开源领域，有经验的开发者广受欢迎，并获得了大量实质性的奖励；
* 在备受好评的项目中，开发者在软件开发过程中享受到了空前的自主权；
* 事实上，几乎所有的大型 ICT 公司都参与了多个开源项目，最高级别的成员当中，通常每个公司每年的合并成本（会费加上投入的雇员）都超过了一百万美元。

如果脱离实际的话，这个比喻似乎暗示着标准是走向 ICT 历史的灰烬。但现实却有很大差别。一个被忽视的事实是，开源开发是比常人所认为的更为娇嫩的花朵。这样比喻的原因是：

* 项目的主要支持者们可以撤回（已经做过的事情），这将导致一个项目的失败；
* 社区内的个性和文化冲突会导致社区的瓦解；
* 重要项目更加紧密的整合能力有待观察；
* 有时专有权在博弈中被削弱，高资助的开源项目在某些情况下会导致失败。
* 随着时间的推移，可能个别公司认为其开源策略没能给他们带来预期的回报；
* 对关键开源项目的失败引起过多关注，会导致厂商放弃一些投资中的新项目，并说服客户谨慎选择开源方案。

奇怪的是，最积极解决这些问题的协作单位是标准组织，部分原因是，他们已经感受到了开源合作的崛起所带来的威胁。他们的回应包括更新知识产权策略以允许在此基础上各种类型的合作，开发开源工具，包含开源代码的标准，以及在其他类型的工作项目中开发开源手册。

结果就是，这些标准组织调整自己成为一个近乎中立的角色，为完整方案的开发提供平台。这些方案能够包含市场上需要的各种类型的合作产品，以及混合工作产品。随着此过程的继续，很有可能使厂商们乐意推行一些包含了标准组织在内的举措，否则他们可能会走向开源基金。

重要的是，由于这些原因，开源项目开始认真对待项目交付所包含的标准，或者与标准开发商合作，共同为完整的方案做准备。这不仅会有更多的产品选择，对客户更少的限制，而且也给客户在开源方案上更大的信心，同时也对开源产品和服务有更多的需求。

倘若这一切不发生的话，将会是一个很大的遗憾，因为这是开源所导致的巨大损失。而这取决于如今的项目所做的决定，是供给市场所需，还是甘心于未来日趋下降的影响力，而不是持续的成功。

*本文源自 ConsortiumInfo.org的 [Standards Blog](http://www.consortiuminfo.org/standardsblog/article.php?story=20170616133415179)，并已获得出版许可*

（题图：opensource.com）

---

作者简介：

Andy Updegrove - Andy helps 的 CEO，管理团队，由他们的投资者建立的成功的组织。他曾作为一名先驱，自1979年起，就为高科技公司提供商业头脑的法律顾问和策略建议。在全球舞台上，他经常作为代表，帮助推动超过 135 部全球标准的制定，宣传开源，主张联盟，其中包括一些世界上最大，最具影响力的标准制定机构。

---

via: <https://opensource.com/article/17/7/software-standards>

作者：[Andy Updegrove](https://opensource.com/users/andrewupdegrove) 译者：[softpaopao](https://github.com/softpaopao) 校对：[wxy](https://github.com/wxy)

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


听说过时间表，但是你是否知道“哈希表”

Summary: 探索哈希表（hash table）的世界并理解其底层的机制是非常有趣的，并且将会受益匪浅。所以，让我们了解它，并从头开始探索吧。

我只回复好贴

感谢！

![](/data/attachment/album/201708/30/233911yju25o44rc53x49f.jpg)

探索<ruby> 哈希表 <rt>  hash table </rt></ruby>的世界并理解其底层的机制是非常有趣的，并且将会受益匪浅。所以，让我们了解它，并从头开始探索吧。

哈希表是许多现代软件应用程序中一种常见的数据结构。它提供了类似字典的功能，使你能够在其中执行插入、删除和删除等操作。这么说吧，比如我想找出“苹果”的定义是什么，并且我知道该定义被存储在了我定义的哈希表中。我将查询我的哈希表来得到定义。它在哈希表内的记录看起来可能像：`"苹果" => "一种拥有水果之王之称的绿色水果"`。这里，“苹果”是我的关键字，而“一种拥有水果之王之称的水果”是与之关联的值。

还有一个例子可以让我们更清楚，哈希表的内容如下：

```
"面包" => "固体"
"水" => "液体"
"汤" => "液体"
"玉米片" => "固体"

```

我想知道*面包*是固体还是液体，所以我将查询哈希表来获取与之相关的值，该哈希表将返回“固体”给我。现在，我们大致了解了哈希表是如何工作的。使用哈希表需要注意的另一个重要概念是每一个关键字都是唯一的。如果到了明天，我拥有一个面包奶昔（它是液体），那么我们需要更新哈希表，把“固体”改为“液体”来反映哈希表的改变。所以，我们需要添加一条记录到字典中：关键字为“面包”，对应的值为“液体”。你能发现下面的表发生了什么变化吗？（LCTT 译注：不知道这个“面包奶昔”是一种什么食物，大约是一种面包做的奶昔，总之你就理解成作者把液体的“面包奶昔”当成一种面包吧。）

```
"面包" => "液体"
"水" => "液体"
"汤" => "液体"
"玉米片" => "固体"

```

没错，“面包”对应的值被更新为了“液体”。

**关键字是唯一的**，我的面包不能既是液体又是固体。但是，是什么使得该数据结构与其他数据结构相比如此特殊呢？为什么不使用一个[数组](https://en.wikipedia.org/wiki/Array_data_type)来代替呢？它取决于问题的本质。对于某一个特定的问题，使用数组来描述可能会更好，因此，我们需要注意的关键点就是，**我们应该选择最适合问题的数据结构**。例如，如果你需要做的只是存储一个简单的杂货列表，那么使用数组会很适合。考虑下面的两个问题，两个问题的本质完全不同。

1. 我需要一个水果的列表
2. 我需要一个水果的列表以及各种水果的价格（每千克）

正如你在下面所看到的，用数组来存储水果的列表可能是更好的选择。但是，用哈希表来存储每一种水果的价格看起来是更好的选择。

```
//示例数组
["苹果", "桔子", "梨子", "葡萄"]
//示例哈希表
{ "苹果" : 3.05,
  "桔子" : 5.5,
  "梨子" : 8.4,
  "葡萄" : 12.4
}

```

实际上，有许多的机会需要[使用](https://en.wikipedia.org/wiki/Hash_table#Uses)哈希表。

### 时间以及它对你的意义

[这里有篇对时间复杂度和空间复杂度的一个复习](https://www.hackerearth.com/practice/basic-programming/complexity-analysis/time-and-space-complexity/tutorial/)。

平均情况下，在哈希表中进行搜索、插入和删除记录的时间复杂度均为 `O(1)` 。实际上，`O(1)` 读作“大 O 1”，表示常数时间。这意味着执行每一种操作的运行时间不依赖于数据集中数据的数量。我可以保证，查找、插入和删除项目均只花费常数时间，“当且仅当”哈希表的实现方式正确时。如果实现不正确，可能需要花费很慢的 `O(n)` 时间，尤其是当所有的数据都映射到了哈希表中的同一位置/点。

### 构建一个好的哈希表

到目前为止，我们已经知道如何使用哈希表了，但是如果我们想**构建**一个哈希表呢？本质上我们需要做的就是把一个字符串（比如 “狗”）映射到一个哈希代码（一个生成的数），即映射到一个数组的索引。你可能会问，为什么不直接使用索引呢？为什么要这么麻烦呢？因为通过这种方式我们可以直接查询 “狗” 并立即得到 “狗” 所在的位置，`String name = Array["狗"] // 名字叫拉斯`。而使用索引查询名称时，可能出现的情况是我们不知道名称所在的索引。比如，`String name = Array[10] // 该名字现在叫鲍勃` - 那不是我的狗的名字。这就是把一个字符串映射到一个哈希代码的益处（对应于一个数组的索引而言）。我们可以通过使用模运算符和哈希表的大小来计算出数组的索引：`index = hash_code % table_size`。

我们需要避免的另一种情况是两个关键字映射到同一个索引，这叫做**哈希碰撞**，如果哈希函数实现的不好，这很容易发生。实际上，每一个输入比输出多的哈希函数都有可能发生碰撞。通过下面的同一个函数的两个输出来展示一个简单的碰撞：

```
int cat_idx = hashCode("猫") % table_size; //cat_idx 现在等于 1
int dog_idx = hashCode("狗") % table_size; //dog_idx 也等于 1

```

我们可以看到，现在两个数组的索引均是 1 。这样将会出现两个值相互覆盖，因为它们被写到了相同的索引中。如果我们查找 “猫” 的值，将会返回 “拉斯” ，但是这并不是我们想要的。有许多可以[解决哈希碰撞](https://en.wikipedia.org/wiki/Hash_table#Collision_resolution)的方法，但是更受欢迎的一种方法叫做**链接**。链接的想法就是对于数组的每一个索引位置都有一个链表，如果碰撞发生，值就被存到链表中。因此，在前面的例子中，我们将会得到我们需要的值，但是我们需要搜索数组中索引为 1 的位置上的链表。伴有链接的哈希实现需要 `O(1 + α)` 时间，其中 α 是装载因子，它可以表示为 n/k，其中 n 是哈希表中的记录数目，k 是哈希表中可用位置的数目。但是请记住，只有当你给出的关键字非常随机时，这一结论才正确（依赖于 [SUHA](https://en.wikipedia.org/wiki/SUHA_(computer_science)）。

这是做了一个很大的假设，因为总是有可能任何不相等的关键字都散列到同一点。这一问题的一个解决方法是去除哈希表中关键字对随机性的依赖，转而把随机性集中于关键字是如何被散列的，从而减少矛盾发生的可能性。这被称为……

### 通用散列

这个观念很简单，从<ruby> 通用散列 <rt>  universal hash </rt></ruby>家族集合随机选择一个哈希函数 h 来计算哈希代码。换句话来说，就是选择任何一个随机的哈希函数来散列关键字。通过这种方法，两个不同的关键字的散列结果相同的可能性将非常低（LCTT 译注：原文是“not be the same”，应是笔误）。我只是简单的提一下，如果不相信我那么请相信[数学](https://en.wikipedia.org/wiki/Universal_hashing#Mathematical_guarantees)。实现这一方法时需要注意的另一件事是如果选择了一个不好的通用散列家族，它会把时间和空间复杂度拖到 `O(U)`，其中 U 是散列家族的大小。而其中的挑战就是找到一个不需要太多时间来计算，也不需要太多空间来存储的哈希家族。

### 上帝哈希函数

追求完美是人的天性。我们是否能够构建一个*完美的哈希函数*，从而能够把关键字映射到整数集中，并且几乎*没有碰撞*。好消息是我们能够在一定程度上做到，但是我们的数据必须是静态的（这意味着在一定时间内没有插入/删除/更新）。一个实现完美哈希函数的方法就是使用 <ruby> 2 级哈希 <rt>  2-Level Hashing </rt></ruby>，它基本上是我们前面讨论过的两种方法的组合。它使用*通用散列*来选择使用哪个哈希函数，然后通过*链接*组合起来，但是这次不是使用链表数据结构，而是使用另一个哈希表。让我们看一看下面它是怎么实现的：

[![2-Level Hashing](/data/attachment/album/201708/30/233925d05scpy3psphz0ux.png "2-Level Hashing")](http://www.zeroequalsfalse.press/2017/02/20/hashtables/Diagram.png)

**但是这是如何工作的以及我们如何能够确保无需关心碰撞？**

它的工作方式与[生日悖论](https://en.wikipedia.org/wiki/Birthday_problem)相反。它指出，在随机选择的一堆人中，会有一些人生日相同。但是如果一年中的天数远远大于人数（平方以上），那么有极大的可能性所有人的生日都不相同。所以这二者是如何相关的？对于每一个链接哈希表，其大小均为第一级哈希表大小的平方。那就是说，如果有两个元素被散列到同一个点，那么链接哈希表的大小将为 4 。大多数时候，链接哈希表将会非常稀疏/空。

重复下面两步来确保无需担心碰撞：

* 从通用散列家族中选择一个哈希函数来计算
* 如果发生碰撞，那么继续从通用散列家族中选择另一个哈希函数来计算

字面上看就是这样（这是一个 `O(n^2)` 空间的解）。如果需要考虑空间问题，那么显然需要另一个不同的方法。但是值得庆幸的是，该过程平均只需要进行**两次**。

### 总结

只有具有一个好的哈希函数才能算得上是一个好的哈希表。在同时保证功能实现、时间和空间的提前下构建一个完美的哈希函数是一件很困难的事。我推荐你在解决问题的时候首先考虑哈希表，因为它能够为你提供巨大的性能优势，而且它能够对应用程序的可用性产生显著差异。哈希表和完美哈希函数常被用于实时编程应用中，并且在各种算法中都得到了广泛应用。你见或者不见，哈希表就在这儿。

---

via: <http://www.zeroequalsfalse.press/2017/02/20/hashtables/>

作者：[Marty Jacobs](http://www.zeroequalsfalse.press/about) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

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


如何管理开源产品的安全漏洞

Summary: 在开发开源软件时, 你需要考虑的安全漏洞也许会将你吞没。CVE ID、零日漏洞和其他漏洞似乎每天都在公布。随着这些信息洪流，你怎么能保持不掉队？

![software vulnerabilities](/data/attachment/album/201708/31/102941ewki56wetwwsadww.jpg "software vulnerabilities")

在 ELC + OpenIoT 峰会上，英特尔安全架构师 Ryan Ware 将会解释如何应对漏洞洪流，并管理你产品的安全性。

在开发开源软件时, 你需要考虑的安全漏洞也许会将你吞没。<ruby> 常见漏洞及曝光 <rt>  Common Vulnerabilities and Exposures </rt></ruby>（CVE）ID、零日漏洞和其他漏洞似乎每天都在公布。随着这些信息洪流，你怎么能保持不掉队？

英特尔安全架构师 Ryan Ware 表示：“如果你发布了基于 Linux 内核 4.4.1 的产品，该内核截止今日已经有 9 个针对该内核的 CVE。这些都会影响你的产品，尽管事实上当你配载它们时还不知道。”

在 [ELC](http://events.linuxfoundation.org/events/embedded-linux-conference) + [OpenIoT 峰会](http://events.linuxfoundation.org/events/openiot-summit)上，英特尔安全架构师 Ryan Ware 的演讲将介绍如何实施并成功管理产品的安全性的策略。在他的演讲中，Ware 讨论了最常见的开发者错误，跟上最新的漏洞的策略等等。

**Linux.com：让我们从头开始。你能否简要介绍一下常见漏洞和曝光（CVE），零日以及其他漏洞么？它们是什么，为什么重要？**

Ryan Ware：好问题。<ruby> 常见漏洞及曝光 <rt>  Common Vulnerabilities and Exposures </rt></ruby>（CVE）是按美国政府的要求由 MITR Corporation（一个非营利组织）维护的数据库。其目前由美国国土安全部资助。它是在 1999 年创建的，以包含有关所有公布的安全漏洞的信息。这些漏洞中的每一个都有自己的标识符（CVE-ID），并且可以被引用。 CVE 这个术语，已经从指整个数据库逐渐演变成代表一个单独的安全漏洞： 一个 CVE 漏洞。

出现于 CVE 数据库中的许多漏洞最初是零日漏洞。这些漏洞出于不管什么原因没有遵循更有序的如“<ruby> 责任揭秘 <rt>  Responsible Disclosure </rt></ruby>”这样的披露过程。关键在于，如果没有软件供应商能够通过某种类型的修复（通常是软件补丁）来进行响应，那么它们就成为了公开和可利用的。这些和其他未打补丁的软件漏洞至关重要，因为在修补软件之前，漏洞是可以利用的。在许多方面，发布 CVE 或者零日就像是开枪。在你比赛结束之前，你的客户很容易受到伤害。

**Linux.com：有多少漏洞？你如何确定那些与你的产品相关？**

Ryan：在探讨有多少之前，以任何形式发布软件的任何人都应该记住。即使你采取一切努力确保你发布的软件没有已知的漏洞，你的软件*也会*存在漏洞。它们只是不知道而已。例如，如果你发布了一个基于 Linux 内核 4.4.1 的产品，那么截止今日，已经有了 9 个CVE。这些都会影响你的产品，尽管事实上在你使用它们时不知道。

此时，CVE 数据库包含 80,957 个条目（截止至 2017 年 1 月 30 日），包括最早可追溯到 1999 年的所有记录，当时有 894 个已记录问题。迄今为止，一年中出现最大的数字的是 2014 年，当时记录了 7,946 个问题。也就是说，我认为过去两年该数字减少并不是因为安全漏洞的减少。这是我将在我的谈话中说到的东西。

**Linux.com：开发人员可以使用哪些策略来跟上这些信息？**

Ryan：开发人员可以通过各种方式跟上这些如洪水般涌来的漏洞信息。我最喜欢的工具之一是 [CVE Details](http://www.cvedetails.com/)。它以一种非常容易理解的方式展示了来自 MITRE 的信息。它最好的功能是创建自定义 RSS 源的能力，以便你可以跟踪你关心的组件的漏洞。那些具有更复杂的追踪需求的人可以从下载 MITR CVE 数据库（免费提供）开始，并定期更新。其他优秀工具，如 cvechecker，可以让你检查软件中已知的漏洞。

对于软件栈中的关键部分，我还推荐一个非常有用的工具：参与到上游社区中。这些是最理解你所使用的软件的人。世界上没有比他们更好的专家。与他们一起合作。

**Linux.com：你怎么知道你的产品是否解决了所有漏洞？有推荐的工具吗？**

Ryan：不幸的是，正如我上面所说，你永远无法从你的产品中移除所有的漏洞。上面提到的一些工具是关键。但是，我还没有提到一个对你发布的任何产品来说都是至关重要的部分：软件更新机制。如果你无法在当场更新产品软件，则当客户受到影响时，你无法解决安全问题。你的软件必须能够更新，更新过程越容易，你的客户将受到更好的保护。

**Linux.com：开发人员还需要知道什么才能成功管理安全漏洞？**

Ryan：有一个我反复看到的错误。开发人员总是需要牢记将攻击面最小化的想法。这是什么意思？在实践中，这意味着只包括你的产品实际需要的东西！这不仅包括确保你不将无关的软件包加入到你的产品中，而且还可以关闭不需要的功能的配置来编译项目。

这有什么帮助？想象这是 2014 年。你刚刚上班就看到 Heartbleed 的技术新闻。你知道你在产品中包含 OpenSSL，因为你需要执行一些基本的加密功能，但不使用 TLS 心跳，该问题与该漏洞相关。你愿意：

a. 花费时间与客户和合作伙伴合作，通过关键的软件更新来修复这个高度安全问题？

b. 只需要告诉你的客户和合作伙伴，你使用 “-DOPENSSL*NO*HEARTBEATS” 标志编译 OpenSSL 产品，他们不会受到损害，你就可以专注于新功能和其他生产活动。

最简单解决漏洞的方法是你不包含这个漏洞。

（题图：[Creative Commons Zero](https://www.linux.com/licenses/category/creative-commons-zero) Pixabay）

---

via: <https://www.linux.com/news/event/elcna/2017/2/how-manage-security-vulnerabilities-your-open-source-product>

作者：[AMBER ANKERHOLZ](https://www.linux.com/users/aankerholz) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


Ubuntu Linux 的不同安装类型：服务器 vs 桌面

本来就是一种商业化故意差异化。还是喜欢Debian Gnu/Linux的单一版本保持软件多样性发行版！！！尤其全镜像组件包ISO的发布。那才是方便用户的最有效保障。。。

>
> 内核是任何 Linux 机器的核心
>
>
>

![](/data/attachment/album/201708/31/110353mxfy52iyhns1zzif.jpg)

之前我已经讲了获取与安装 Ubuntu Linux，这次我将讲桌面和服务器的安装。两类安装都满足某些需求。不同的安装包是从 Ubuntu 分开下载的。你可以从 [Ubuntu.com/downloads](https://www.ubuntu.com/download) 选择你需要的。

无论安装类型如何，都有一些相似之处。

![](/data/attachment/album/201708/31/110424ak1iby9ryrwuft9m.jpg)

*可以从桌面系统图形用户界面或从服务器系统命令行添加安装包。*

两者都使用相同的内核和包管理器系统。软件包管理器系统是预编译为可在几乎任何 Ubuntu 系统运行的程序的仓库。程序分组成包，然后以安装包进行安装。安装包可以从桌面系统图形用户界面或从服务器系统命令行添加。

程序安装使用一个名为 `apt-get` 的程序。这是一个包管理器系统或程序管理器系统。最终用户只需输入命令行 `apt-get install (package-name)`，Ubuntu 就会自动获取软件包并进行安装。

软件包通常安装可以通过手册页访问的文档的命令（这本身就是一个主题）。它们可以通过输入 `man (command)` 来访问。这将打开一个描述该命令详细用法的页面。终端用户还可以 Google 任何的 Linux 命令或安装包，并找到大量关于它的信息。

例如，在安装网络连接存储套件后，可以通过命令行、GUI 或使用名为 Webmin 的程序进行管理。Webmin 安装了一个基于 Web 的管理界面，用于配置大多数 Linux 软件包，它受到了仅安装服务器版本的人群的欢迎，因为它安装为网页，不需要 GUI。它还允许远程管理服务器。

大多数（如果不是全部）基于 Linux 的软件包都有专门帮助你如何运行该软件包的视频和网页。只需在 YouTube 上搜索 “Linux Ubuntu NAS”，你就会找到一个指导你如何设置和配置此服务的视频。还有专门指导 Webmin 的设置和操作的视频。

内核是任何 Linux 安装的核心。由于内核是模块化的，它是非常小的（顾名思义）。我在一个 32MB 的小型闪存上运行 Linux 服务器。我没有打错 - 32MB 的空间！Linux 系统使用的大部分空间都是由安装的软件包使用的。

**服务器**

服务器安装 ISO 镜像是 Ubuntu 提供的最小的下载。它是针对服务器操作优化的操作系统的精简版本。此版本没有 GUI。默认情况下，它完全从命令行运行。

移除 GUI 和其他组件可简化系统并最大限度地提高性能。最初没有安装的必要软件包可以稍后通过命令行程序包管理器添加。由于没有 GUI，因此必须从命令行完成所有配置、故障排除和包管理。许多管理员将使用服务器安装来获取一个干净或最小的系统，然后只添加他们需要的某些包。这包括添加桌面 GUI 系统并制作精简桌面系统。

广播电台可以使用 Linux 服务器作为 Apache Web 服务器或数据库服务器。这些是真实需要消耗处理能力的程序，这就是为什么它们通常使用服务器形式安装以及没有 GUI 的原因。SNORT 和 Cacti 是可以在你的 Linux 服务器上运行的其他程序（这两个应用程序都在上一篇文章中介绍，可以在这里找到：[*http://tinyurl.com/yd8dyegu*](http://tinyurl.com/yd8dyegu)）。

**桌面**

桌面安装 ISO 镜像相当大，并且有多个在服务器安装 ISO 镜像上没有的软件包。此安装用于工作站或日常桌面使用。此安装类型允许自定义安装包（程序），或者可以选择默认的桌面配置。

![](/data/attachment/album/201708/31/110424hsprmgpzaemihmem.jpg)

*桌面安装 ISO 镜像相当大，并且有多个在服务器安装 ISO 镜像上没有的软件包。此安装包专为工作站或日常桌面使用设计。*

软件包通过 apt-get 包管理器系统安装，就像服务器安装一样。两者之间的区别在于，在桌面安装中，apt-get 包管理器具有不错的 GUI 前端。这允许通过点击鼠标轻松地从系统安装或删除软件包！桌面安装将设置一个 GUI 以及许多与桌面操作系统相关的软件包。

![](/data/attachment/album/201708/31/110425cs5sp1l6bdki1koo.jpg)

*通过 apt-get 包管理器系统安装软件包，就像服务器安装一样。两者之间的区别在于，在桌面安装中，apt-get 包管理器具有不错的 GUI 前端。*\*

这个系统安装后随时可用，可以很好的替代你的 Windows 或 Mac 台式机。它有很多包，包括 Office 套件和 Web 浏览器。

Linux 是一个成熟而强大的操作系统。无论哪种安装类型，它都可以配置为适合几乎所有需要。从功能强大的数据库服务器到用于网页浏览和写信给奶奶的基本台式机操作系统，天空有极限，而可用的安装包几乎是不竭的。如果你遇到一个需要计算机化解决方案的问题，Linux 可能会提供免费或低成本的软件来解决该问题。

通过提供两个安装版本，Ubuntu 做得很好，这让人们开始朝着正确的方向前进。

*Cottingham 是前无线电总工程师，现在从事流媒体工作。*

---

via: <http://www.radiomagonline.com/deep-dig/0005/linux-installation-types-server-vs-desktop/39123>

作者：[Chris Cottingham](http://www.radiomagonline.com/author/chris-cottingham) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


从这开始了解 OPNFV

Summary: NFV 是颠覆的一代，其将彻底改变网络的建设和运营。而且，OPNFV 是一个领先的开源 NFV 项目，旨在加速这项技术的采用。

GNU应该有一本SDN手册啦！！！很期待

![OPNFV](/data/attachment/album/201708/31/223444c3c5gdj6zd93k6l5.png "OPNFV")

如果电信运营商或企业今天从头开始构建网络，那么他们可能用软件定义资源的方式构建，这与 Google 或 Facebook 的基础设施类似。这是网络功能虚拟化 （NFV） 的前提。

NFV 是颠覆的一代，其将彻底改变网络的建设和运营。而且，[OPNFV](https://www.opnfv.org/) 是一个领先的开源 NFV 项目，旨在加速这项技术的采用。

你是想要知道有哪些开源项目可能会帮助你进行 NFV 转换计划的电信运营商或者相关的企业员工么？还是要将你的产品和服务推向新的 NFV 世界的技术提供商？或者，也许是一名想使用开源项目来发展你事业的工程师、网络运维或商业领袖？（例如 2013 年 Rackspace [提到](https://blog.rackspace.com/solving-the-openstack-talent-gap) 拥有 OpenStack 技能的网络工程师的平均工资比他们的同行高 13%）？如果这其中任何一个适用于你，那么 *理解 OPNFV* 一书是你的完美资源。

![OPNFV Book](/data/attachment/album/201708/31/223445hqxtv9f2vvjyjttl.jpg)

*“理解 OPNFV”一书高屋建瓴地提供了 OPNFV 的理解以及它如何帮助你和你们的组织。*

本书（由 Mirantis 、 Nick Chase 和我撰写）在 11 个易于阅读的章节和超过 144 页中介绍了从 NFV、NFV 转换、OPNFV 项目的各个方面到 VNF 入门的概述，涵盖了一系列主题。阅读本书后，你将对 OPNFV 是什么有一个高屋建瓴的理解以及它如何帮助你或你们的组织。这本书不是专门面向开发人员的，虽然有开发背景信息很有用。如果你是开发人员，希望作为贡献者参与 OPNFV 项目，那么 [wiki.opnfv.org](https://wiki.opnfv.org/) 仍然是你的最佳资源。

在本博客系列中，我们会向你展示本书的一部分内容 - 就是有些什么内容，以及你可能会学到的。

让我们从第一章开始。第 1 章，毫不奇怪，是对 NFV 的介绍。它从业务驱动因素（需要差异化服务、成本压力和敏捷需求）、NFV 是什么，以及你可从 NFV 可以获得什么好处的角度做了简要概述。

简而言之，NFV 可以在数据中心的计算节点上执行复杂的网络功能。在计算节点上执行的网络功能称为虚拟网络功能 （VNF）。因此，VNF 可以作为网络运行，NFV 还会添加机制来确定如何将它们链接在一起，以提供对网络中流量的控制。

虽然大多数人认为它用在电信，但 NFV 涵盖了广泛的使用场景，从基于应用或流量类型的按角色访问控制 （RBAC） 到用于管理网络内容的内容分发网络 （CDN） 网络（通常需要的地方），更明显的电信相关用例如演进分组核心 （EPC） 和 IP 多媒体系统（IMS）。

此外，一些主要收益包括增加收入、改善客户体验、减少运营支出 （OPEX）、减少资本支出 （CAPEX）和为新项目腾出资源。本节还提供了具体的 NFV 总体拥有成本 （TCO） 分析。这些话题的处理很简单，因为我们假设你有一些 NFV 背景。然而，如果你刚接触 NFV ，不要担心 - 介绍材料足以理解本书的其余部分。

本章总结了 NFV 要求 - 安全性、性能、互操作性、易操作性以及某些具体要求，如服务保证和服务功能链。不符合这些要求，没有 NFV 架构或技术可以真正成功。

阅读本章后，你将对为什么 NFV 非常重要、NFV是什么，以及 NFV 成功的技术要求有一个很好的概念。我们将在今后的博客文章中浏览下面的章节。

这本书已被证明是行业活动上最受欢迎的赠品，中文版正在进行之中！但是你现在可以[下载 PDF 格式的电子书](https://www.opnfv.org/resources/download-understanding-opnfv-ebook)，或者在亚马逊上下载[打印版本](https://www.amazon.com/dp/B071LQY724/ref=cm_sw_r_cp_ep_dp_pgFMzbM8YHJA9)。

（题图：[Creative Commons Zero](https://www.linux.com/licenses/category/creative-commons-zero)Pixabay）

---

via: <https://www.linux.com/blog/opnfv/2017/8/understanding-opnfv-starts-here>

作者：[AMAR KAPADIA](https://www.linux.com/users/akapadia) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


在树莓派中开启激动人心的 Perl 之旅

刚装好了kali，就不折腾了

折腾了一圈，又回到了raspberry debian。

来自河南郑州的 Chrome Mobile 40.0|Android 7.0 用户

>
> 树莓派，随心所欲。
>
>
>

![Getting started with Perl on the Raspberry Pi](/data/attachment/album/201709/01/110033jt75udbas9zva5tm.jpg "Getting started with Perl on the Raspberry Pi")

我最近在 SVPerl （硅谷 Perl 聚会）谈到在树莓派上运行 Perl 语言的时候，有人问我，“我听说树莓派应该使用 Python ，是这样吗？”。我非常乐意回答他，这是个常见误解。树莓派可以支持任何语言： Python、Perl 和其他树莓派官方软件 Raspbian Linux 初始安装的语言。

看似很厉害，其实很简单。树莓派的创造者英国的计算机科学教授 Eben Upton 曾经说过，树莓派名字中的‘派’（pi），是想为了听起来像 Python，因为他喜欢这门语言。他选择了这门语言作为孩子们的启蒙语言。但是他和他的团队做了一个通用计算机。开源软件没给树莓派任何限制。我们想运行什么就运行什么，全凭自己心意。

我在 SVPerl 和这篇文章中还想讲第二点，就是介绍我的 “PiFlash” 脚本。虽然它是用 Perl 写的，但是不需要你有多了解 Perl 就可以在 Linux 下将树莓派系统自动化烧录到 SD 卡。这样对初学者就比较友好，避免他们在烧录 SD 卡时候，偶然擦除了整个硬盘。即使是高级用户也可以从它的自动化工作中受益，包括我，这也是我开发这个工具的原因。在 Windows 和 Mac 下也有类似的工具，但是树莓派网站没有介绍类似工具给 Linux 用户。不过，现在有了。

开源软件早就有自己造轮子的传统，因为他们总是崇尚“自痒自挠”去解决问题。这种方式在 Eric S 1997 年的论文和 1999 年的书籍《[大教堂与集市](http://www.catb.org/%7Eesr/writings/cathedral-bazaar/)》中早有提及，它定义了开源软件的方法论。我也是为了满足想我这样的 Linux 用户，所以写了这个脚本。

### 下载系统镜像

想要开启树莓派之旅，你首先需要为它下载一个操作系统。我们称之为“系统镜像”文件。一旦你把它下载到你的桌面、手提电脑，或者甚至是另一个树莓派中，我就需要写入或者称之为“烧录”进你的 SD卡。详细情况可以看在线文件。手动做这件事情需要一些功底，你要把系统镜像烧录到整个 SD卡，而不是其中一块分区。系统镜像必须独自包含至少一个分区，因为树莓派引导需要一个 FAT32文件系统分区，系统引导这里开始。除了引导分区，其他分区可以是操作系统内核支持的任何分区类型。

在大部分树莓派中，我们都运行的是某些使用 Linux 内核的发行版。已经有一系列树莓派中常用的系统镜像你可以下载使用。（当然，没什么能阻止你自己造轮子）

树莓派基金会向新手推荐的是“[NOOBS](https://www.raspberrypi.org/downloads/noobs/)”系统。它代表了 “New Out of the Box System”（新鲜出炉即开即用系统），显然它好像听起来像术语 “noob"”（小白），通俗点说就是 “newbie”（菜鸟）。NOOBS 是一个基于树莓派的 Linux 系统，它会给你一个菜单可以在你的树莓派上自动下载安装几个其它的系统镜像。

[Raspbian Linux](https://www.raspberrypi.org/downloads/raspbian/) 是 Debian Linux 发行版的树莓派定制版。它是为树莓派开发的正式 Linux 发行版，并且由树莓派基金会维护。几乎所有树莓派驱动和软件都会在 Raspbian 上先试用，然后才会放到其它发行版上。其默认安装博客 Perl。

Ubuntu Linux （还有其社区版的 Ubuntu MATE）也将树莓派作为其支持 ARM （Advanced RISC Machines）处理器的平台之一。RISC（Reduced Instruction Set Computer）Ubuntu 是一个 Debian Linux 的商业化支持的开源分支，它也使用 DEB 包管理器。Perl 也在其中。它仅仅支持 32 位 ARM7 或者 64 位 ARM8 处理器的树莓派 2 和 3。ARM6 的树莓派 1 和 Zero 从未被 Ubuntu 构建过程支持。

[Fedora Linux](https://fedoraproject.org/wiki/Raspberry_Pi#Downloading_the_Fedora_ARM_image) 支持树莓派2 ，而 Fedora 25 支持 3。 Fedora 是一个隶属于红帽（Red Hat）的开源项目。Fedora 是个基础，商业版的 RHEL（Red Hat Enterprise Linux）在其上增加了商业软件包和支持，所以其软件像所有的兼容红帽的发行版一样来自 RPM（Red Hat Package Manager） 软件包。就像其它发行版一样，也包括 Perl。

[RISC OS](https://www.riscosopen.org/content/downloads/raspberry-pi) 是一个特别针对 ARM 处理器的单用户操作系统。如果你想要一个比 Linux 系统更加简洁的小型桌面（功能更少），你可以考虑一下。它同样支持 Perl。

[RaspBSD](http://www.raspbsd.org/raspberrypi.html) 是一个 FreeBSD 的树莓派发行版。它是一个基于 Unix 的系统，而不是 Linux。作为开源 Unix 的一员，它延续了 Unix 的功能，而且和 Linux 有着众多相似之处。包括有类似的开源软件带来的相似的系统环境，包括 Perl。

[OSMC](https://osmc.tv/)，即开源多媒体中心，以及 [LibreElec](https://libreelec.tv/) 电视娱乐中心，它们都基于运行 Linux 内核之上的 Kodi 娱乐中心。它是一个小巧、特化的 Linux 系统，所以不要期望它能支持 Perl。

[Microsoft Windows IoT Core](http://ms-iot.github.io/content/en-US/Downloads.htm) 是仅运行在树莓派３上的新成员。你需要微软开发者身份才能下载。而作为一个 Linux 极客，我根本不看它。我的 PiFlash 脚本还不支持它，但如果你找的是它，你可以去看看。

### PiFlash 脚本

如果你想看看[树莓派 SD 卡烧录指导](https://www.raspberrypi.org/documentation/installation/installing-images/README.md)，你可以找到在 Windows 或者 Mac 系统下需要下载的工具来完成烧录任务。但是对于 Linux 系统，只有一系列手工操作建议。我已经手工做过这个太多次，这很容易引发一个开发者的本能去自动化这个过程，这就是 PiFlash 脚本的起源。这有点难，因为 Linux 有太多方法可以配置，但是它们都是基于 Linux 内核的。

我总是觉得，手工操作潜在最大的失误恐怕就是偶然错误地擦除了某个设备，而不是擦除了 SD 卡，然后彻底清除了我本想保留在硬盘的东西。我在 SVPerl 演讲中也说了，我很惊讶地发现在听众中有犯了这种错误（而且不害怕承认）的人。因此，PiFlash 其中一个目的就是保护新手的安全，不会擦除 SD 卡之外的设备。PiFlash 脚本还会拒绝覆写包含了已经挂载的文件系统的设备。

对于有经验的用户，包括我，PiFlash 脚本还提供提供一个简便的自动化服务。下载完系统镜像之后，我不需要必须从 zip格式中解压缩或者提取出系统镜像。PiFlash 可以直接提取它，不管是哪种格式，并且直接烧录到 SD 卡中。

我把 [PiFlash 及其指导](https://github.com/ikluft/ikluft-tools/tree/master/piflash)发布在了 GitHub 上。

命令行用法如下：

```
piflash [--verbose] input-file output-device
piflash [--verbose] --SDsearch

```

`input-file` 参数是你要写入的系统镜像文件，只要是你从树莓派发行版网站下载的镜像都行。`output-device` 参数是你要写入的 SD 卡的块设备路径。

你也可以使用 `--SDsearch` 参数列出挂载在系统中 SD 卡设备名称。

可选项 `--verbose` 可以输出所有的程序状态数据，它在你需要帮助时或者递送 bug 报告和自行排错时很有用。它就是我开发时用的。

下面的例子是我使用该脚本写入仍是 zip 存档的 Raspbian 镜像到位于 `/dev/mmcblk0` 的 SD 卡：

```
piflash 2016-11-25-raspbian-jessie.img.zip /dev/mmcblk0

```

如果你已经指定了 `/dev/mmcblk0p1` （SD 卡的第一分区），它会识别到这个分区不是一个正确的位置，并拒绝写入。

在不同的 Linux 系统中怎样去识别哪个设备是 SD 卡是一个技术活。像 mmcblk0 这种在我的笔记本上是基于 PCI 的 SD卡接口。如果我使用了 USB SD 卡接口，它就是 `/dev/sdb`，这在多硬盘的系统中不好区分。然而，只有少量的 Linux 块设备支持 SD 卡。PiFlash 在这两种情况下都会检查块设备的参数。如果全部失败，它会认为可写入、可移动的，并有着正确物理扇区数量的 USB 驱动器是 SD 卡。

我想这应该能涵盖大部分情况。但是，如果你使用了我不知道的 SD 卡接口呢？我乐意看到你的来信。请在输出信息中加上 `--verbos --SDsearch` 参数，以便让我可以知道你系统目前的环境。理想情况下，如果 PiFlash 脚本可以被广泛利用，我们可以构建一个开源社区去尽可能的帮助更多的树莓派用户。

### 树莓派的 CPAN 模块

[CPAN](http://www.cpan.org/)（Comprehensive Perl Archive Network）是一个世界范围内包含各种 Perl 模块的的下载镜像。它们都是开源的。大量 CPAN 中的模块都是历久弥坚。对于成千上百的任务，你不需要重复造轮子，只要利用别人已经发布的代码就可以了。然后，你还可以提交你的新功能。

尽管树莓派是个五脏俱全的 Linux 系统，支持大部分 CPAN 模块，但是这里我想强调一下专为树莓派硬件开发的东西。一般来说它们都用在测量、控制、机器人方面的嵌入式系统中。你可以通过 GPIO （General-Purpose Input/Output）针脚将你的树莓派连接到外部电子设备。

可以使用树莓派 GPIO 针脚的模块如下：[Device::SMBus](https://metacpan.org/pod/Device::SMBus)、[Device::I2C](https://metacpan.org/pod/Device::I2C)、[Rpi::PIGPIO](https://metacpan.org/pod/RPi::PIGPIO)、[Rpi::SPI](https://metacpan.org/pod/RPi::SPI)、[Rpi::WiringPi](https://metacpan.org/pod/RPi::WiringPi)、[Device::WebIO::RaspberryPI](https://metacpan.org/pod/Device::WebIO::RaspberryPi) 和 [Device::PiGlow](https://metacpan.org/pod/Device::PiGlow)。树莓派支持的嵌入式模块如下：[UAV::Pilot::Wumpus::Server::Backend::RaspberryPiI2C](https://metacpan.org/pod/UAV::Pilot::Wumpus::Server::Backend::RaspberryPiI2C)、[RPI::DHT11](https://metacpan.org/pod/RPi::DHT11)（温度/湿度）、[RPI::HCSR04](https://metacpan.org/pod/RPi::HCSR04)（超声波）、[App::RPI::EnvUI](https://metacpan.org/pod/App::RPi::EnvUI)、[RPi::DigiPot::MCP4XXXX](https://metacpan.org/pod/RPi::DigiPot::MCP4XXXX)、[RPI::ADC::ADS](https://metacpan.org/pod/RPi::ADC::ADS)、[Device::PaPiRus](https://metacpan.org/pod/Device::PaPiRus) 和 [Device::BCM2835::Timer](https://metacpan.org/pod/Device::BCM2835::Timer)。

### 例子

这里有些我们在树莓派上可以用 Perl 做的事情的例子。

#### 例一：在 OSMC 使用 PiFlash 播放视频

本例中，你将练习如何设置并运行使用 OSMC 操作系统的树莓派。

* 到 [RaspberryPi.Org](http://raspberrypi.org/) 下载区，下载最新的 OSMC 版本。
* 将空 SD 卡插入你的 Linux 电脑或者笔记本。树莓派第一代是全尺寸的 SD 卡，除此以外都在使用 microSD，你也许需要一个通用适配器才能插入它。
* 在插入前后分别运行 `cat /proc/partitions` 命令来看看系统分给硬件的设备名称。它可能像这样 `/dev/mmcblk0` 或者 `/dev/sdb`， 用如下命令将正确的系统镜像烧录到 SD 卡：`piflash OSMC_TGT_rbp2_20170210.img.gz /dev/mmcblk0`。
* 弹出 SD 卡，将它插入树莓派中，接上 HDMI 显示器，开机。
* 当 OSMC 设置完毕，插入一个 USB 设备，在里面放点视频。出于示范目的，我将使用 `youtube-dl` 程序下载两个视频。运行 `youtube-dl OHF2xDrq8dY` （彭博关于英国高新产业，包括树莓派的介绍）还有 `youtube-dl nAvZMgXbE9c` （CNet 发表的“排名前五的树莓派项目”) 。将它们下载到 USB 中，然后卸载移除设备。
* 将 USB 设备插入到 OSMC 树莓派。点击视频选项进入到外部设备。
* 只要你能在树莓派中播放视频，那么恭喜你，你已经完成了本次练习。玩的愉快。

#### 例二：随机播放目录中的视频的脚本

这个例子将使用一个脚本在树莓派上的目录中乱序播放视频。根据视频的不同和设备的摆放位置，这可以用作信息亭显示的用途。我写这个脚本用来展示室内体验视频。

* 设置树莓派引导 Raspbian Linux。连接到 HDMI 监视器。
* 从 GitHub 上下载 [do-video 脚本](https://github.com/ikluft/ikluft-tools/tree/master/perl-on-pi)。把它放到树莓派中。
* 跟随该页面的安装指导。最主要的事情就是安装 omxplayer 包，它可以使用树莓派硬件视频加速功能平滑地播放视频。
* 在家目录的 Videos 目录下放一些视频。
* 运行 `do-video` ，这样，应该就可以播放视频了

#### 例三：读取 GPS 数据的脚本

这个例子更加深入，更有针对性。它展示了 Perl 怎么从外部设备中读取数据。在先前例子中出现的我的 GitHub上 “[Perl on Pi](https://github.com/ikluft/ikluft-tools/tree/master/perl-on-pi)” 有一个 gps-read.pl 脚本。它可以通过一系列端口从 GPS 读取 NMEA（国家海洋电子协会）的数据。页面还有教程，包括构建它所使用的 AdaFruit Industries 部分，但是你可以使用任何能输出 NMEA 数据的 GPS。

通过这些任务，我想你应该可以在树莓派上像使用其他语言一样使用 Perl了。希望你喜欢。

---

作者简介：

Ian Kluft - 上学开始，Ian 就对喜欢编程和飞行。他一直致力于 Unix 的工作。在 Linux 内核发布后的六个月他转向了 Linux。他有计算机科学硕士学位，并且拥有 CSSLP 资格证（认证规范开发流程专家），另一方面，他还是引航员和认证的飞机指令长。作为一个超过二十五年的认证的无线电爱好者，在近些年，他在一些电子设备上陆续做了实验，包括树莓派。

---

via: <https://opensource.com/article/17/3/perl-raspberry-pi>

作者：[Ian Kluft](https://opensource.com/users/ikluft) 译者：[Taylor1024](https://github.com/Taylor1024) 校对：[wxy](https://github.com/wxy)

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


OpenStack 上的 OpenShift：更好地交付应用程序

Summary: 传统的操作系统一直是关于硬件资源的展示和消耗 - 硬件提供资源，应用程序消耗它们，操作系统一直是交通警察。但传统的操作系统一直局限于单机。那么，在原生云的世界里，现在意味着这个概念扩展到包括多个操作系统实例。这就是 OpenStack 和 OpenShift 所在。

开源容器云OpenShift 构建基于Kubernetes的企业应用云平台:<br />
https://pan.baidu.com/s/1t-q0GXL4WRi8G_SvrLmkgw

![](/data/attachment/album/201709/01/114318n2qi2asy2fqypsai.jpg)

你有没有问过自己，我应该在哪里运行 OpenShift？答案是任何地方 - 它可以在裸机、虚拟机、私有云或公共云中很好地运行。但是，这里有一些为什么人们正迁移到围绕全栈和资源消耗自动化相关的私有云和公有云的原因。传统的操作系统一直是关于[硬件资源的展示和消耗](https://docs.google.com/presentation/d/139_dxpiYc5JR8yKAP8pl-FcZmOFQCuV8RyDxZqOOcVE/edit) - 硬件提供资源，应用程序消耗它们，操作系统一直是交通警察。但传统的操作系统一直局限于单机<sup> 注1</sup> 。

那么，在原生云的世界里，现在意味着这个概念扩展到包括多个操作系统实例。这就是 OpenStack 和 OpenShift 所在。在原生云世界，虚拟机、存储卷和网段都成为动态配置的构建块。我们从这些构建块构建我们的应用程序。它们通常按小时或分钟付费，并在不再需要时被取消配置。但是，你需要将它们视为应用程序的动态配置能力。 OpenStack 在动态配置能力（展示）方面非常擅长，OpenShift 在动态配置应用程序（消费）方面做的很好，但是我们如何将它们结合在一起来提供一个动态的、高度可编程的多节点操作系统呢？

要理解这个，让我们来看看如果我们在传统的环境中安装 OpenShift 会发生什么 - 想像我们想要为开发者提供动态访问来创建新的应用程序，或者想象我们想要提供业务线，使其能够访问现有应用程序的新副本以满足合同义务。每个应用程序都需要访问持久存储。持久存储不是临时的，在传统的环境中，这通过提交一张工单实现。没关系，我们可以连到 OpenShift，每次需要存储时都会提交一张工单。存储管理员可以登录企业存储阵列并根据需要删除卷，然后将其移回 OpenShift 以满足应用程序。但这将是一个非常慢的手动过程，而且你可能会遇到存储管理员辞职。

![](/data/attachment/album/201709/01/114404iu0eeenlso8sisz0.png)

在原生云的世界里，我们应该将其视为一个策略驱动的自动化流程。存储管理员变得更加战略性、设置策略、配额和服务级别（银、黄金等），但实际配置变得动态。

![](/data/attachment/album/201709/01/114405drpy1yllptg8ynl4.png)

动态过程可扩展到多个应用程序 - 这可能是开发者测试的业务线甚至新应用程序。从 10 多个应用程序到 1000 个应用程序，动态配置提供原生云体验。

![](/data/attachment/album/201709/01/114406zkzwsmsp7jx3ums6.png)

下面的演示视频展示了动态存储配置如何与 Red Hat OpenStack 平台（Cinder 卷）以及 Red Hat OpenShift 容器平台配合使用，但动态配置并不限于存储。想象一下，随着 OpenShift 的一个实例需要更多的容量、节点自动扩展的环境。想象一下，推送一个敏感的程序更改前，将网段划分为负载测试 OpenShift 的特定实例。这些是你为何需要动态配置 IT 构建块的原因。OpenStack 实际上是以 API 驱动的方式实现的。

OpenShift 和 OpenStack 一起更好地交付应用程序。OpenStack 动态提供资源，而 OpenShift 会动态地消耗它们。它们一起为你所有的容器和虚拟机需求提供灵活的原生云解决方案。

注1：高可用性集群和一些专门的操作系统在一定程度上弥合了这一差距，但在计算中通常是一个边缘情况。

---

via: <https://blog.openshift.com/openshift-on-openstack-delivering-applications-better-together/>

作者：[SCOTT MCCARTY](https://blog.openshift.com/author/smccartyredhat-com/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


使用 LibreOffice Calc 管理你的财务

Summary: 你想知道你的钱花在哪里？这个精心设计的电子表格可以一目了然地回答这个问题。

你想知道你的钱花在哪里？这个精心设计的电子表格可以一目了然地回答这个问题。

>
> 你想知道你的钱花在哪里？这个精心设计的电子表格可以一目了然地回答这个问题。
>
>
>

![Get control of your finances with LibreOffice Calc](/data/attachment/album/201709/01/134951eodh9pykzey9aloj.png "Get control of your finances with LibreOffice Calc")

如果你像大多数人一样，没有一个无底般的银行帐户。你可能需要仔细观察你的每月支出。

有很多方法可以做到这一点，但是最快最简单的方法是使用电子表格。许多人创建一个非常基本的电子表格来完成这项工作，它由两长列组成，总计位于底部。这是可行的，但这有点傻。

我将通过使用 LibreOffice Calc 创建一个更便于细查的（我认为）以及更具视觉吸引力的个人消费电子表格。

你说不用 LibreOffice？没关系。你可以使用 [Gnumeric](http://www.gnumeric.org/)、[Calligra Sheets](https://www.calligra.org/sheets/) 或 [EtherCalc](https://ethercalc.net/) 等电子表格工具使用本文中的信息。

### 首先列出你的费用

先别费心 LibreOffice 了。坐下来用笔和纸，列出你的每月日常开支。花时间，翻遍你的记录，记下所有的事情，无论它多么渺小。不要担心你花了多少钱。重点放在你把钱花在哪里。

完成之后，将你的费用分组到最有意义的标题下。例如，将你的燃气、电气和水费放在“水电费”下。你也可能想要为我们每个月都会遇到的意外费用，使用一组名为“种种”。

### 创建电子表格

启动 LibreOffice Calc 并创建一个空的电子表格。在电子表格的顶部留下三个空白行。之后我们会回来。

你把你的费用归类是有原因的：这些组将成为电子表格上的块。我们首先将最重要的花费组（例如 “家庭”）放在电子表格的顶部。

在工作表顶部第四行的第一个单元格中输入该花费组的名称。将它放大（可以是 12 号字体）、加粗使得它显眼。

在该标题下方的行中，添加以下三列：

* 花费
* 日期
* 金额

在“花费”列下的单元格中输入该组内花费的名称。

接下来，选择日期标题下的单元格。单击 **Format** 菜单，然后选择 **Number Format > Date**。对“金额”标题下的单元格重复此操作，然后选择 **Number Format > Currency**。

你会看到这样：

![A group of expenses](/data/attachment/album/201709/01/134952m97xz9x4l211jme9.png "A group of expenses")

这是一组开支的方式。不要为每个花费组创建新块, 而是复制你创建的内容并将其粘贴到第一个块旁边。我建议一行放三块, 在它们之间有一个空列。

你会看到这样：

![A row of expenses](/data/attachment/album/201709/01/134954ceeffemx28hhf1qr.png "A row of expenses")

对所有你的花费组做重复操作。

### 总计所有

查看所有个人费用是一回事，但你也可以一起查看每组费用的总额和所有费用。

我们首先总计每个费用组的金额。你可以让 LibreOffice Calc 自动做这些。高亮显示“金额”列底部的单元格，然后单击 “Formula” 工具栏上的 “Sum” 按钮。

![The Sum button](/data/attachment/album/201709/01/134954nnhnpxxebxbnxrol.png "The Sum button")

单击金额列中的第一个单元格，然后将光标拖动到列中的最后一个单元格。然后按下 Enter。

![An expense block with a total](/data/attachment/album/201709/01/134955qnznjewmqnpczmqw.png "An expense block with a total")

现在让我们用你顶部留下的两三行空白行做一些事。这就是你所有费用的总和。我建议把它放在那里，这样无论何时你打开文件时它都是可见的。

在表格左上角的其中一个单元格中，输入类似“月总计”。然后，在它旁边的单元格中，输入 `=SUM()`。这是 LibreOffice Calc 函数，它可以在电子表格中添加特定单元格的值。

不要手动输入要添加的单元格的名称，请按住键盘上的 Ctrl。然后在电子表格上单击你在每组费用中总计的单元格。

### 完成

你有一张追踪一个月花费的表。拥有单个月花费的电子表格有点浪费。为什么不用它跟踪全年的每月支出呢？

右键单击电子表格底部的选项卡，然后选择 **Move or Copy Sheet**。在弹出的窗口中，单击 **-move to end position-**，然后按下 Enter 键。一直重复到你有 12 张表 - 每月一张。以月份重命名表格，然后使用像 *Monthly Expenses 2017.ods* 这样的描述性名称保存电子表格。

现在设置完成了，你可以使用电子表格了。使用电子表格跟踪你的花费本身不会坚实你的财务基础，但它可以帮助你控制每个月的花费。

（题图： opensource.com）

---

作者简介：

Scott Nesbitt - 我是一名长期使用自由/开源软件的用户，并为了乐趣和收益写了各种软件。我不会太严肃。你可以在网上这些地方找到我：Twitter、Mastodon、GitHub。

---

via: <https://opensource.com/article/17/8/budget-libreoffice-calc>

作者：[Scott Nesbitt](https://opensource.com/users/scottnesbitt) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


为什么开源应该是云原生环境的首选

>
> 基于 Linux 击败了专有软件一样的原因，开源应该成为云原生环境的首选。
>
>
>

![Why open source should be the first choice for cloud-native environments](/data/attachment/album/201709/02/202726r0qhkxkehf6qapoo.png "Why open source should be the first choice for cloud-native environments")

让我们回溯到上世纪 90 年代，当时专有软件大行其道，而开源才刚开始进入它自己的时代。是什么导致了这种转变？更重要的是，而今天我们转到云原生环境时，我们能从中学到什么?

### 基础设施的历史经验

我将以一个高度武断的、开源的视角开始，来看看基础设施过去 30 年的历史。在上世纪 90 年代，Linux 只是大多数组织视野中一个微不足道的小光点而已——如果他们听说过它的话。你早早购入股票的那些公司们很快就发现了 Linux 的好处，它主要是作为专有的 Unix 的廉价替代品，而部署服务器的标准方式是使用专有的 Unix，或者日渐增多的使用 Microsoft Windows NT。

这种模式的专有本性为更专有的软件提供了一个肥沃的生态系统。软件被装在盒子里面放在商店出售。甚至开源软件也参与了这种装盒游戏；你可以在货架上买到 Linux，而不是用你的互联网连接免费下载。去商店和从你的软件供应商那里只是你得到软件的不同方式而已。

![Ubuntu box packaging on a Best Buy shelf](/data/attachment/album/201709/02/202729wllum8g3vmvam3us.png "Ubuntu box packaging on a Best Buy shelf")

*Ubuntu 包装盒出现在百思买的货架上*

我认为，随着 LAMP 系列（Linux、Apache、MySQL 和 PHP / Perl / Python）的崛起，情况发生了变化。LAMP 系列非常成功。它是稳定的、可伸缩的和相对用户友好的。与此同时，我开始看到对专有解决方案的不满。一旦客户在 LAMP 系列中尝过了开源的甜头，他们就会改变他们对软件的期望，包括：

* 不愿被供应商绑架，
* 关注安全，
* 希望自己来修复 bug ，以及
* 孤立开发的软件意味着创新被扼杀。

在技术方面，我们也看到了各种组织在如何使用软件上的巨大变化。忽然有一天，网站的宕机变成不可接受的了。这就对扩展性和自动化有了更多的依赖。特别是在过去的十年里，我们看到了基础设施从传统的“宠物”模式到“群牛”模式的转变，在这种模式中，服务器可以被换下和替换，而不是一直运行和被指定。公司使用大量的数据，更注重数据留存和数据到用户的处理和返回速度。

开源和开源社区，以及来自大公司的日益增多的投入，为我们改变如何使用软件提供了基础。系统管理员的岗位要求开始 要求 Linux 技能和对开源技术和理念的熟悉。通过开源类似 Chef cookbooks 和 Puppet 模块这样东西，管理员可以分享他们的模式配置。我们不再单独配置和调优 MySQL；我们创建了一个掌控基础部分的系统，我们现在可以专注于更有趣的、可以给我们雇主带来更高价值的工程作业。

开源现在无处不在，围绕它的模式也无处不在。曾经仇视这个想法的公司不仅通过协同项目与外界拥抱开源，而且进一步地，还发布了他们自己的开源软件项目并且围绕它们构建了社区。

![A "Microsoft Linux" USB stick](/data/attachment/album/201709/02/202732jhhuul1ufukzlfms.png "A \"Microsoft Linux\" USB stick")

### 转向云端

今天，我们生活在一个 DevOps 和云端的世界里。我们收获了开源运动带来的创新成果。在公司内部采用开源软件开发实践的情况下， Tim O'reilly 所称的 “[内部开源](https://opensource.com/life/16/11/create-internal-innersource-community)” 有了明显增长。我们为云平台共享部署配置。像 Terraform 这样的工具甚至允许我们编写和分享我们如何部署特定的平台。

但这些平台本身呢？

>
> “大多数人想都不想就使用了云……许多用户将钱投入到根本不属于他们的基础设施中，而对放弃他们的数据和信息毫无顾虑。" —Edward Snowden, OpenStack Summit, May 9, 2017
>
>
>

现在是时候要更多地想想本能地转移或扩展到云上的事情了。

就像 Snowden 强调的那样，现在我们正面临着对我们的用户和客户的数据的失控风险。抛开安全不谈，如果我们回顾一下我们转向开源的原因，个中原因还包括被厂商绑架的担忧、创新难以推动、甚至修复 bug 的考虑。

在把你自己和/或你的公司锁定在一个专有平台之前，考虑以下问题：

* 我使用的服务是遵循开放标准，还是被厂商绑架的？
* 如果服务供应商破产或被竞争对手收购，什么是我可以依赖的？
* 关于停机、安全等问题，供应商与其客户沟通中是否有一个明确而真诚的历史过往？
* 供应商是否响应 bug 和特性请求，即使那是来自小客户？
* 供应商是否会在我不知情的情况下使用我们的数据（或者更糟，即便我们的客户协议所不同意）？
* 供应商是否有一个计划来处理长期的，不断上升的增长成本，特别是如果最初的成本很低呢？

您可以通过这个问卷，讨论每个要点，而仍然决定使用专有的解决方案。这很好，很多公司一直都在这么做。然而，如果你像我一样，宁愿找到一个更开放的解决方案而仍然受益于云，你确实有的选择。

### 基于私有云

当您寻找私有云解决方案时，您的首选是开源，投资一个云提供商，其核心运行在开源软件上。 [OpenStack](https://www.openstack.org/) 是行业领袖，在其 7 年的历史中，有 100 多个参与组织和成千上万的贡献者（包括我）。 OpenStack 项目已经证明，结合多个基于 OpenStack 云不仅是可行的，而且相对简单。云公司之间的 API 是相似的，所以您不必局限于特定的 OpenStack 供应商。作为一个开放源码项目，您仍然可以影响该基础设施的特性、bug 请求和发展方向。

第二种选择是继续在基础层面上使用私有云，但在一个开源容器编排系统中。无论您选择 [DC/OS](https://dcos.io/)（基于[Apache Mesos](http://mesos.apache.org/)) 、[Kubernetes](https://kubernetes.io/) 或 [Docker Swarm 模式](https://docs.docker.com/engine/swarm/) ，这些平台都允许您将私有云系统提供的虚拟机作为独立的 Linux 机器，并在此之上安装您的平台。您所需要的只是 Linux 而已，不会立即被锁定在特定云的工具或平台上。可以根据具体情况来决定是否使用特定的专属后端，但如果你这样做，就应该着眼于未来。

有了这两种选择，你也可以选择完全离开云服务商。您可以部署自己的 OpenStack 云，或者将容器平台内部架构移动到您自己的数据中心。

### 做一个登月计划

最后，我想谈一谈开源项目基础设施。今年 3 月，在召开的 [南加州 Linux 展会](https://www.socallinuxexpo.org/) 上，多个开放源码项目的参与者讨论了为他们的项目运行开源基础设施。（更多的，请阅读我的 [关于该会议的总结](https://opensource.com/article/17/3/growth-open-source-project-infrastructures)）我认为这些项目正在做的这个工作是基础设施开源的最后一步。除了我们现在正在做的基本分享之外，我相信公司和组织们可以在不放弃与竞争对手相区分的“独门秘方”的情况下，进一步充分利用他们的基础设施开源。

开源了他们的基础设施的开源项目，已经证明了允许多个公司和组织向他们的基础设施提交训练有素的 bug 报告，甚至是补丁和特定论文的价值。突然之间，你可以邀请兼职的贡献者。你的客户可以通过了解你的基础设施，“深入引擎盖子之下”，从而获得信心。

想要更多的证据吗？访问 [开源基础设施](https://opensourceinfra.org/) 的网站了解开源基础设施的项目（以及他们已经发布的大量基础设施）。

可以在 8 月 26 日在费城举办的 FOSSCON 大会上 Elizabeth K. Joseph 的演讲“[基础架构开源](https://fosscon.us/node/12637)”上了解更多。

（题图：[Jason Baker](https://opensource.com/users/jason-baker). [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/). Source: [Cloud](https://pixabay.com/en/clouds-sky-cloud-dark-clouds-1473311/), [Globe](https://pixabay.com/en/globe-planet-earth-world-1015311/). Both [CC0](https://creativecommons.org/publicdomain/zero/1.0/).）

---

via: <https://opensource.com/article/17/8/open-sourcing-infrastructure>

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

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


Fedora 的 Yum 或将在一两年内退休

那麼問題來了，未來dnf的repository配置文件存在哪。<br />
會不會因爲歷史遺留問題繼續存在`/etc/yum.repos.d/`裏。

建立一个符号链接就是了。

富依赖是什么？

终于要退休了..

其实为什么不继续用yum这个命令，只要把dnf改称yum其他的继续用就行了。改个名字就是为了说明升级优化了？

![](/data/attachment/album/201709/03/114024w0kg9ajhmc04cc16.jpg)

随着 DNF 软件包管理器在最近的 Fedora 版本里面工作日益工作良好，我们可以预见到 Yum 将在之后的 Fedora 版本中谢幕。

当然，Yum 还一直广泛用在 RHEL 7 中，而在 Fedora 这边，估计在大约一年后的 Fedora 28 乃至 29 中正式退休。

在 Fedora 开发者邮件列表中有一个讨论 [Yum 退休](https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/GF6THFF5FXCNTKHVLVRRFHS46BTDPO5Y/)的新话题。看起来在 Fedora 28 或 29 的时候会移除 Yum。DNF 已经提供了与 Yum 一样的能力。Fedora 也在开发一个“富依赖”的支持，而这个功能 Yum 不支持，所以这也表明了 Yum 将在以后的 Fedora 系统中消失。

邮件列表中也提到了 Yum 和 DNF 还存在一些差异需要解决，但是看起来在 2018 年应该可以看到希望。


GNU GPL 许可证常见问题解答（二）

Summary: 本文由高级咨询师薛亮据自由软件基金会（FSF）的英文原文翻译而成，这篇常见问题解答澄清了在使用 GNU 许可证中遇到许多问题，对于企业和软件开发者在实际应用许可证和解决许可证问题时具有很强的实践指导意义。

2.49 GPL在天朝能够获得法律支持吗？

好文！感谢！

![](/data/attachment/album/201709/03/122923n2n20eonjsq2gh2o.png)

本文由高级咨询师薛亮据自由软件基金会（FSF）的[英文原文](https://www.gnu.org/licenses/gpl-faq.html)翻译而成，这篇常见问题解答澄清了在使用 GNU 许可证中遇到许多问题，对于企业和软件开发者在实际应用许可证和解决许可证问题时具有很强的实践指导意义。

1. [关于 GNU 项目、自由软件基金会（FSF）及其许可证的基本问题](/article-8761-1.html)
2. 对于 GNU 许可证的一般了解
3. 在您的程序中使用 GNU 许可证
4. 依据 GNU 许可证分发程序
5. 在编写其他程序时采用依据 GNU 许可证发布的程序
6. 将作品与依据 GNU 许可证发布的代码相结合
7. 关于违反 GNU 许可证的问题

### **2、****对于** **GNU** **许可证的一般了解**

#### 2.1 为什么 GPL 允许用户发布其修改版本？

自由软件的一个关键特点是用户可以自由合作。绝对有必要允许希望彼此帮助的用户与其他用户分享他们对错误的修复和改进。

有些人提出了 GPL 的替代方案，需要原作者批准修改版本。只要原作者持续进行维护，这种做法在实践中可能会不错，但是如果作者停止维护（或多或少会）去做别的事情，或并不打算去满足所有用户的需求，这种替代方案就会失败。除了实践上的问题之外，该方案也不允许用户之间互相帮助。

有时候对修改版本的控制，是为了防止用户制作的各种版本之间造成混淆。根据我们的经验，这种混乱不是一个大问题。在 GNU 项目之外出现了许多版本的 Emacs，但用户仍可以将它们区分开。GPL 要求版本创造者将他/她的名字标注其上，以区别于其他版本，并保护其他维护者的声誉。

#### 2.2 GPL 是否要求将修改版本的源代码公开发布？

GPL 不要求您发布修改后的版本或其中的任何一部分。您可以自由地进行修改并私人使用它们，而无需进行发布。这也适用于组织（包括企业）；组织可以制作修改版本，在内部使用它，并且绝不将修改版本发布到组织之外。

但是，*如果*您以某种方式向公众发布修改后的版本，依据 GPL 许可证，GPL 要求您保证程序的用户可以获得修改后源代码。

因此，GPL 给你以某些特定方式发布修改后的程序的授权，而不是以其他方式发布；但是，是否发布修改版本的决定取决于您。

#### 2.3 我可以在同一台电脑上安装一个遵循 GPL 许可证的程序和一个不相关的非自由程序吗？

可以。

#### 2.4 如果我知道某些人有一个遵循 GPL 许可证的程序的副本，我可以要求他们给我一个副本吗？

不可以，GPL 给人们制作和再分发程序副本的授权，倘若有人选择这样做的话。那个人也有权选择不去再分发该程序。

#### 2.5 GPL v2 中的“<ruby> 书面文件 <rp>  （ </rp> <rt>  written offer </rt> <rp>  ） </rp></ruby>对任何第三方有效”是什么意思？ 这是否意味着世界上每个人都可以获得任何遵循 GPL 许可证的程序的源代码？

如果您选择通过书面文件提供源代码，那么任何向您索求源代码的人都有权收到。

如果您对不附带源代码的二进制文件进行商业分发，GPL 要求您必须提供一份书面文件，表明将稍后分发源代码。当用户非商业性地再分发他们从您那里获取的二进制文件时，他们必须传递这份书面文件的副本。这意味着不能直接从您那里获取二进制文件的人，仍然可以收到源代码副本以及该书面文件。

我们要求书面文件对任何第三方有效的原因是，以这种方式间接收到二进制代码的人可以从您那里订购源代码。

#### 2.6 GPL v2 中规定，发布后的修改版本必须“授予…所有第三方许可”。这些第三方是谁？

第 2 节中规定，依据 GPL，您分发的修改版本必须授权给所有第三方。 “所有第三方”当然是指所有人，但这并不要求您为他们*做*任何事情。这仅仅意味着他们依据 GPL 从您那里获得了您的修改版本的许可。

#### 2.7 GPL 允许我出售程序的副本以获利吗？

是的，GPL 允许每个人这样做。[销售副本的权利](https://www.gnu.org/philosophy/selling.html)是自由软件定义的一部分。除了一种特殊情况之外，对您可以收取什么样的价格是没有限制的。（这种例外情况是：二进制版本必须附有表明将提供源代码的书面文件。）

#### 2.8 GPL 允许我从我的分发网站收取下载程序的费用吗？

允许。您可以对您分发程序副本收取任何您想收取的费用。如果您通过下载分发二进制文件，则必须提供“等同的访问权限”来让人们下载源代码，因此，下载源代码的费用可能不会超过下载二进制文件的费用。

#### 2.9 GPL 允许我要求任何接收软件的人必须向我支付费用和/或通知我吗？

不允许。实际上，这样的要求会使程序变成非自由软件。如果人们在获得程序副本时必须支付费用，或者他们必须特别通知任何人，那么这个程序就不是自由软件。请参阅[自由软件的定义](https://www.gnu.org/philosophy/free-sw.html)。

GPL 是自由软件许可证，因此允许人们使用甚至再分发软件，而不需要向任何人支付费用。

您可以向用户收取费用，[以获取您的副本](https://www.gnu.org/licenses/gpl-faq.html#DoesTheGPLAllowMoney)。当他们*从别人那里*获得副本时，您不能要求人们向您支付费用。

#### 2.10 如果我收费分发遵循 GPL 的软件，我是否还需要向公众免费提供？

不需要。不过，如果有人向您支付费用并获得副本，GPL 给予他们免费或收费向公众发布的自由。例如，有人可以向您支付费用，然后把他的副本放在一个网站上，让公众去获取。

#### 2.11 GPL 允许我根据保密协议分发副本吗？

不允许。GPL 规定，任何从您那里获取副本的人都有权再分发已修改或未修改的副本。您不得在任何更严格的基础上分发作品。

如果有人要求您签署保密协议（NDA），以获取来自 FSF 的遵循 GPL 的软件，请立即通知我们 <license-violation@fsf.org>。

如果违规行为涉及其他版权所有者的遵循 GPL 的代码，请通知该版权所有者，就像您对其他任何类型的 GPL 违规行为所做的工作一样。

#### 2.12 GPL 允许我根据保密协议分发程序的修改版或测试版吗？

不可以。GPL 规定，您的修改版本必须具备 GPL 中规定的所有自由。因此，从您那里获取您的版本副本的任何人都有权再分发该版本的副本（已修改或未修改）。您不得在更严格的基础上分发该作品的任何版本。

#### 2.13 GPL 是否允许我根据保密协议开发程序的修改版本？

可以。例如，您可以接受一份合同来开发修改版本，并同意不得发布*您的修改版本*，直到客户同意才可以发布。这是允许的，因为这种情况下不处于 GPL 协议之下的代码是依据 NDA 分发的。

您还可以依据 GPL 将您的修改版本发布给客户，但须同意不将其发布给其他任何人，除非客户同意。也同样在这种情况下，不处于 GPL 协议之下的代码是以保密协议或任何其他限制条款分发的。

GPL 将给予客户再分发您的版本的权利。在这种情况下，客户可能会选择不行使这项权利，但他确实*拥有*这项权利。

#### 2.14 为什么 GPL 要求程序的每个副本必须包含 GPL 许可证副本？

作品包含许可证副本至关重要，因此获得程序副本的每个人都可以知道他们的权利是什么。

包括一个指向许可证的 URL，而不是将许可证本身包含在内，这是一种看起来很诱人的做法。但是您不能确定该 URL 在五年或十年后仍然有效。二十年后，我们今天所知道的 URL 们可能已不复存在。

不管网络将发生什么样的变化，确保拥有该程序副本的人员能够继续看到 GPL 许可证的唯一方法是，将许可证的副本包含在该程序中。

#### 2.15 如果作品不是很长，那该怎么办？

如果整个软件包中只有很少的代码——我们使用的基准是不到 300 行，那么您可以使用一个宽松的许可证，而不是像 GNU GPL这样的 Copyleft 许可证（除非代码特别重要）。我们[建议这种情况使用 Apache License 2.0](https://www.gnu.org/licenses/license-recommendations.html#software)。

#### 2.16 我是否需要将我对遵循 GPL 的程序所做的修改声明版权？

您不需要对您的修改声明版权。不过，在大多数国家/地区，默认情况下会自动获得版权，因此，如果您不希望修改受到版权限制，您需要将修改明显地放置于公有领域。

无论您是否对您的修改声明版权，依据 GPL，您都必须将修改版本作为整体发布（参见：2.2 GPL 是否要求将修改版本的源代码公开发布？）。

#### 2.17 GPL 对于将某些代码翻译成不同的编程语言是如何规定的？

根据著作权法，翻译工作被认为是一种修改。因此，GPL 对修改版本的规定也适用于翻译版本。

#### 2.18 如果一个程序将公有领域代码与遵循 GPL 的代码相结合，我可以取出公有领域的部分，并作为公有领域代码来使用吗？

您可以这样做，如果您能弄清楚哪个部分是公有领域的部分，并将其与其他部分区分开。如果代码曾经由其开发人员放置在公有领域，那么它就是公有领域代码，无论它现在究竟在哪里。

#### 2.19 我想要因我的作品获得声誉。我想让人们知道我写了什么，如果我使用 GPL，我还能获得声誉吗？

您一定能获得这份作品的声誉。遵循 GPL 发布的程序的一部分是以您自己名义撰写的版权声明（假设您是版权所有者）。GPL 要求所有副本携带恰当的版权声明。

#### 2.20 GPL 允许我添加条款，要求在使用遵循 GPL 的软件或其输出物的研究论文中包含引用或致谢吗？

不可以，根据 GPL 的规定，这是不允许的。虽然我们认识到适当的引用是学术出版物的重要组成部分，但引用不能作为对 GPL 的附加要求。对使用 GPL 软件的研究论文要求包含引用，超出了 GPL v3 第 7（b）条中可接受的附加要求，因此将被视为对 GPL 第 7 节的额外限制。而且版权法也不允许您在[软件的输出物](https://www.gnu.org/licenses/gpl-faq.html#GPLOutput)中设置这样的要求，无论该软件是依据 GPL 还是其他许可证的条款获得许可。

#### 2.21 为了节省空间，我是否可以省略 GPL 的引言部分，或者省略如何在自己的程序上使用GPL的<ruby> 指导 <rp>  （ </rp> <rt>  instructions </rt> <rp>  ） </rp></ruby>部分吗？

引言和指导是 GNU GPL 的组成部分，不能省略。事实上，GPL 是受版权保护的，其许可证规定只能逐字复制整个 GPL。（您可以使用法律条款制作[另一个许可证](https://www.gnu.org/licenses/gpl-faq.html#ModifyGPL)，但该许可证不再是 GNU GPL。）

引言和指导部分共约 1000 字，不到 GPL 总文字数量的 1/5。除非软件包本身很小，否则引言和指导不会对软件包的大小产生大幅度的改变。在软件包很小的情况下，您可以使用一个简单的<ruby> 全权 <rp>  （ </rp> <rt>  all-permissive </rt> <rp>  ） </rp></ruby>许可证，而不是 GNU GPL。

#### 2.22 两个许可证“兼容”是指什么？

为了将两个程序（或它们的实质部分）组合成一个更大的作品，您需要有以组合方式使用这两个程序的权限。如果两个程序的许可证允许这种使用方式，则它们是兼容的。如果没有办法同时满足这两个许可证，则它们是不兼容的。

对于一些许可证，组合的方式可能会影响它们是否兼容，例如，它们可能允许将两个模块链接在一起，但不允许将其代码合并到一个模块中。

如果您只想在同一个系统中安装两个独立的程序，那么它们的许可证并不是必须兼容的，因为它们没有组合成更大的作品。

#### 2.23 许可证与 GPL 兼容是什么意思？

这意味着其他许可证和 GNU GPL 兼容；在一个更大的程序中，您可以将根据其他许可证发布的代码与根据 GNU GPL 发布的代码进行组合。

所有 GNU GPL 版本都允许进行这种组合；它们还允许分发这些组合，只要该组合在相同的 GNU GPL 版本下发布。其他许可证如果允许这样做，则其与 GPL 兼容。

与 GPL v2 相比，GPL v3 与更多的许可证兼容：它允许您与具有特定类型附加要求（GPL v3 本身不包含）的代码进行组合。GPL v3 第 7 节中有关于此问题的更多信息，包括了允许的附加要求的列表。

#### 2.24 为什么原始的 BSD 许可证与 GPL 不兼容？

因为它规定了 GPL 不包含的具体要求，即对程序广告的要求。GPL v2 第 6 节规定：

>
> *您不得对接受者行使本协议授予的权利施加进一步的限制。*
>
>
>

GPL v3 在第 10 节中提到类似的内容。广告条款正好提供了这样一个限制，因此与 GPL 不兼容。

修订的 BSD 许可证没有广告条款，从而消除了这个问题。

#### 2.25 “<ruby> 聚合 <rp>  （ </rp> <rt>  aggregate </rt> <rp>  ） </rp></ruby>”与其他类型的“修改版本”有什么区别？

“聚合”由多个单独的程序组成，分布在同一个 CD-ROM或其他媒介中。GPL 允许您创建和分发聚合，即使其他软件的许可证不是自由许可证或与 GPL 不兼容。唯一的条件是，发布“聚合”所使用的许可证不能禁止用户去行使“聚合”中每个程序对应的许可证所赋予用户的权利。

两个单独的程序还是一个程序有两个部分，区分的界限在哪里？这是一个法律问题，最终由法官决定。我们认为，适当的判断标准取决于通信机制（exec、管道、rpc、共享地址空间内的函数调用等）和通信的语义（哪些信息被互换）。

如果模块们被包含在相同的可执行文件中，则它们肯定是被组合在一个程序中。如果模块们被设计为在共享地址空间中链接在一起运行，那么几乎肯定意味着它们组合成为一个程序。

相比之下，管道、套接字和命令行参数是通常在两个独立程序之间使用的通信机制。所以当它们用于通信时，模块们通常是单独的程序。但是，如果通信的语义足够亲密，交换复杂的内部数据结构，那么也可以视为这两个部分合并成了一个更大的程序。

#### 2.26 为什么 FSF 要求为 FSF拥有版权的程序做出贡献的贡献者将版权<ruby> 分配 <rp>  （ </rp> <rt>  assign </rt> <rp>  ） </rp></ruby>给 FSF？如果我持有 GPL 程序的版权，我也应该这样做吗？如果是，怎么做？ （同1.11）

我们的律师告诉我们，为了最大限度地向法院要求违规者强制执行 GPL，我们应该让程序的版权状况尽可能简单。为了做到这一点，我们要求每个贡献者将贡献部分的版权分配给 FSF，或者放弃对贡献部分的版权要求。

我们也要求个人贡献者从雇主那里获得版权放弃声明（如果有的话），以确保雇主不会声称拥有这部分贡献的版权。

当然，如果所有的贡献者把他们的代码放在公共领域，也就没有用之来执行 GPL 许可证的版权了。所以我们鼓励人们为大规模的代码贡献分配版权，只把小规模的修改放在公共领域。

如果您想要在您的程序中执行 GPL，遵循类似的策略可能是一个好主意。如果您需要更多信息，请联系<licensing@gnu.org>。

#### 2.27 如果我使用遵循 GNU GPL 的软件，那么允许我将原始代码修改为新程序，然后在商业上分发和销售新程序吗？

您被允许在商业上出售修改程序的副本，但仅限于在 GNU GPL 的条款之下这么做。因此，例如，您必须依照 GPL 所述，使得程序用户可获取源代码，并且，用户也依照 GPL 所述，被允许再分发和修改程序。

这些要求是将遵循 GPL 的代码包含在您自己的程序中的条件。

#### 2.28 我可以将 GPL 应用于软件以外的其他作品吗？ （同1.6）

您可以将 GPL 应用于任何类型的作品，只需明确该作品的“源代码”构成即可。GPL 将“源代码”定义为作品的首选形式，以便在其中进行修改。

不过，对于手册和教科书，或更一般地，任何旨在教授某个主题的作品，我们建议使用 GFDL，而非 GPL。

#### 2.29 我想依据 GPL 授权我的代码，但我也想明确指出，它不能用于军事和/或商业用途。我可以这样做吗？

不可以，因为这两个目标相互矛盾。GNU GPL 被专门设计为防止添加进一步的限制。GPL v3 在第 7 节允许非常有限的一组附加限制，但是用户可以删除任何其他添加的限制。

#### 2.30 我可以依据 GPL 来对硬件进行许可吗？

任何可以受版权保护的<ruby> 材料 <rp>  （ </rp> <rt>  material </rt> <rp>  ） </rp></ruby>都可以依据GPL进行许可。GPL v3 也可以用于受其他类似版权法的法律保护的材料，如半导体掩模。因此，作为一个例子，您可以依据 GPL 发布物理对象的图纸或电路。

在许多情况下，版权不涵盖依照图纸制作的物理硬件。在这种情况下，无论您使用什么许可证，您对图纸的许可都不能对制造或销售物理硬件施加任何控制。当版权不涵盖利用 IC 掩膜等进行硬件制作时，GPL 能以有效的方式处理这种情况。

#### 2.31 将遵循 GPL 的二进制文件<ruby> 预链接 <rp>  （ </rp> <rt>  prelinking </rt> <rp>  ） </rp></ruby>到系统上的各种库，以优化其性能，将被视为修改吗？

不。<ruby> 预链接 <rp>  （ </rp> <rt>  prelinking </rt> <rp>  ） </rp></ruby>是编译过程的一部分；与编译过程所涉及的其他各个方面相比，预链接没有引入更多的许可证要求。如果您被允许将程序链接到各种库，那么也可以预链接到各种库。如果您分发预链接后的目标码，则需要遵循第 6 节的条款。

#### 2.32 LGPL 如何与 Java 配合使用？

详情请参阅[这篇文章](https://www.gnu.org/licenses/lgpl-java.html)。LGPL 如同被设计、被预想、被期待的那样去工作。

#### 2.33 为什么你们在 GPL v3 中发明新的术语“<ruby> 传播 <rp>  （ </rp> <rt>  propagate </rt> <rp>  ） </rp></ruby>”和“<ruby> 传递 <rp>  （ </rp> <rt>  convey </rt> <rp>  ） </rp></ruby>”？

（译者注：convey 这个词汇在一个 GPL 译本中被翻译为“转发”，此处，我们认为“转发”一词在计算机领域存在一定的歧义，因此，采用“传递”的翻译。）

GPL v2 中使用的“分发”一词来自美国版权法。多年来，我们了解到，一些司法管辖区在自己的版权法中使用了同一个词，但却给出了不同的含义。我们发明了这些新术语，无论在何处对许可证进行解释，都使我们的意图尽可能清楚。这些新术语没有使用在世界上的任何版权法中，我们直接在许可证中提供了它们的定义。

#### 2.34 在GPL v3中的“<ruby> 传递 <rp>  （ </rp> <rt>  convey </rt> <rp>  ） </rp></ruby>”与GPL v2中的“<ruby> 分发 <rp>  （ </rp> <rt>  distribute </rt> <rp>  ） </rp></ruby>”意思一样吗？

是的，差不多是一个意思。在执行 GPL v2 的过程中，我们了解到一些司法管辖区在自己的版权法中使用了“分发”这个词，但给出了不同的含义。我们发明了一个新的术语，以使我们的意图清晰，避免这些差异可能引起的任何问题。

#### 2.35 如果我只复制遵循 GPL 的程序并运行它们，而不分发或传递给其他人，许可证对我施加什么要求？

没有要求。GPL 不对此活动附加任何条件。

2.36 GPL v3将“向公众提供”作为<ruby> 传播 <rp>  （ </rp> <rt>  propagate </rt> <rp>  ） </rp></ruby>的一个例子。这是什么意思？ 是提供一种可获取的传递形式吗？

“向公众提供”的一个例子是将该软件放在公共网页或FTP服务器上。在您这样做之后，在任何人从您那里真正获取软件之前，可能会需要一段时间，但是由于这种情况可能会立即发生，您也需要能够立即履行 GPL 的义务。因此，我们将“<ruby> 传递 <rp>  （ </rp> <rt>  convey </rt> <rp>  ） </rp></ruby>”定义为包括这一活动。

#### 2.37 鉴于分发和向公众提供作为传播形式，同样也构成了 GPL v3 中的“<ruby> 传递 <rp>  （ </rp> <rt>  conveying </rt> <rp>  ） </rp></ruby>”，那么有哪些传播的例子不构成传递吗？

为自己制作软件的副本是不构成“传递”的主要传播形式。您可以依此在多台计算机上安装软件，或进行备份。

#### 2.38 GPL v3 如何让 BitTorrent 分发变得更容易？

因为 GPL v2 是在软件的点对点分发普及之前编写的，所以当您利用这种方式分享代码时，很难满足 GPL v2 的要求。在 BitTorrent 上分发 GPL v2 目标代码时，确保您合规的最佳方法是将所有相应的源代码包含在相同的<ruby> 种子文件 <rp>  （ </rp> <rt>  Torrent </rt> <rp>  ） </rp></ruby>中，但这种方式代价高昂。

GPL v3 以两种方式解决了这个问题。首先，作为该过程的一部分，下载此种子文件并将数据发送给其他人的人不需要做任何事情。因为第 9 节规定：“受保护作品的辅助传播如果仅仅是使用点对点传输来接收副本，不需要接受[本许可证]。”

第二，通过告知接收人在公共网络服务器上哪里可获取，GPL v3 的第 6（e）节旨在给予分发者（最初制作种子文件的人）一种清晰、直观的方式来提供源代码。这样可以确保每个想要获取源代码的人都可以如此获取，而且分发者几乎不用担心。

#### 2.39 什么是 <ruby> TiVo化 <rp>  （ </rp> <rt>  tivoization </rt> <rp>  ） </rp></ruby>？ GPL v3 对此如何防止？

一些设备使用可升级的自由软件，但被设计为用户不能修改该软件。有很多不同的方式可以做到这一点；例如，有时硬件校验所安装的软件，如果与预期签名不匹配，则关闭软件。制造商通过提供源代码来遵循GPL v2，但是您仍然无法自由修改您使用的软件。我们称这种做法为<ruby> TiVo 化 <rp>  （ </rp> <rt>  tivoization </rt> <rp>  ） </rp></ruby>。

当人们分发包含遵循 GPL v3 软件的“<ruby> 用户产品 <rp>  （ </rp> <rt>  User Products </rt> <rp>  ） </rp></ruby>”时，第 6 节要求他们为您提供修改该软件所需的信息。“用户产品”是该许可证特别定义的术语；“用户产品”的示例包括便携式音乐播放器、数字录像机和家庭安全系统。

#### 2.40 GPL v3 是否禁止 DRM？

不禁止，您可以使用遵循 GPL v3 发布的代码来开发您喜欢的任何类型的 DRM 技术。不过，如果您这样做，第 3 节规定，系统不会被视为一种有效的技术“保护”措施，这意味着如果有人破坏了 DRM，他也可以自由分发他的软件，不受《美国数字千禧版权法》（DMCA）和类似法律的限制。

像往常一样，GNU GPL 并不限制人们在软件中怎么做，只是阻止他们限制他人。

#### 2.41 GPL v3 是否要求投票人能够修改在投票机中运行的软件？

不要求。企业分发包含遵循 GPL v3 软件的设备，最多只需要为拥有目标代码副本的人提供软件的源代码和安装信息。使用投票机（如同任何其他信息亭一样）的选民不能拥有它，甚至不能暂时拥有，所以选民也不能拥有二进制软件。

不过，请注意，投票是一个非常特殊的情况。仅仅因为计算机中的软件是自由软件，并不意味着您可以信任计算机，并进行投票。我们认为电脑不值得信任，不能被用作投票。投票应在纸上进行。

#### 2.42 GPL v3 是否包含“专利报复条款”？

实际上，是的。第 10 节禁止传递该软件的人向其他被许可人发起专利诉讼。如果有人这样做，第 8 节解释他们将如何丧失许可证权益以及与之伴随的所有专利许可。

#### 2.43 在 GPL v3 和 AGPL v3中，当说到“尽管有本许可证的其他规定”时，是什么意思？

这仅仅意味着以下条款胜过许可证中可能与之冲突的其他任何内容。例如，如果没有该文本，有些人可能声称，您不能将遵循 GPL v3 的代码与遵循 AGPL v3 的代码结合在一起，因为 AGPL 的附加要求将被归类为 GPL v3 第 7 节下的“进一步限制”。该文本明确表示我们的预期解释是正确的，您可以进行组合。

该文本仅解决许可证不同条款之间的冲突。当两个条件之间没有冲突的时候，您必须同时满足它们。这些段落不允许您轻率地忽略许可证的其余部分，它们只是强调了一些非常有限的例外。

#### 2.44 在 AGPL v3 中，怎么才算是“通过计算机网络远程与[软件]进行交互”？

如果程序被明确设计为接受用户请求并通过网络发送响应，则它符合这些标准。属于此类程序的常见示例包括网络和邮件服务器、交互式网络应用程序和在线游戏的服务器。

如果程序没有被明确设计为通过网络与用户进行交互，而是恰好在这样做的环境中运行，那么它不属于此类。例如，仅仅因为用户通过 SSH 或远程 X 会话来运行的应用程序不需要提供源代码。

#### 2.45 GPL v3 中“<ruby> 您 <rp>  （ </rp> <rt>  you </rt> <rp>  ） </rp></ruby>”的概念如何与 Apache License 2.0 中“<ruby> 法律实体 <rp>  （ </rp> <rt>  Legal Entity </rt> <rp>  ） </rp></ruby>”的定义相比较？

它们是完全相同的。Apache License 2.0 中“法律实体”的定义在各种法律协议中是非常标准的，因此，如果法院在缺乏明确定义的情况下没有以同样的方式解释该术语，将会令人非常惊讶。我们完全期待他们在看 GPL v3 时也会如此，并考虑到谁有资格作为被许可人。

#### 2.46 在 GPL v3 中，“<ruby> 该程序 <rp>  （ </rp> <rt>  the Program </rt> <rp>  ） </rp></ruby>”是指什么？ 是每个依据 GPL v3 发布的程序？

术语“该程序”是指依据 GPL v3 进行许可的特定作品，由特定被许可人从上游许可人或分发者那里接收。“该程序”是您在 GPL v3 许可的指定情境下接受到的特定软件作品。

“该程序”并不意味着“依据 GPL v3 进行许可的所有作品”；由于一些原因，这种解释没有任何意义。针对那些想要了解更多的人，我们已经发表了对“该程序”一词的[分析](https://www.gnu.org/licenses/gplv3-the-program.html)。

#### 2.47 如果某些网络客户端软件依据 AGPL v3 发布，是否必须能够向与之交互的服务器提供源代码？

AGPL v3 需要该程序向“所有通过计算机网络进行远程交互的用户”提供源代码。至于您将程序称为“客户端”还是“服务器”，那无关紧要。您需要询问的问题是，是否存在合理的期望让一个人通过网络远程与该程序交互。

#### 2.48 对于一个运行在代理服务器上的依据 AGPL 进行许可的软件来说，如何向与该软件交互的用户提供源代码书面文件？

对于代理服务器上的软件，您可以通过向此类代理的用户传递消息的常规方法来提供源代码书面文件。例如，Web 代理可以使用登录页。当用户最初开始使用代理时，您可以将他们引导到包含源代码书面文件以及您选择提供的任何其他信息的页面。

AGPL 规定，您必须向“所有用户”提供书面文件。如果您知道某个用户已经被展示过书面文件，对于当前版本的软件，您不必再重复向该用户提供。


Linux 系统开机启动项清理

Summary: 一般情况下，常规用途的 Linux 发行版在开机启动时拉起各种相关服务进程，包括许多你可能无需使用的服务。

不错的文章，参照清理了一下服务

时间证明SYSTEMD是个好东西、GNOME也是个好东西。不过SYSTEMD还是需要具有良好的用户配置界面，二进制不是给人看滴！！！尤其在系统无法启动的时候！！！

所谓文本格式也是二进制，只是系统底层支持的好。说用文本格式比二进制方便的， 是因为那些工具方便，像 C 语言操作字符串，可不是那么方便。至于 Gnome 和 systemd 是个好东西，这个持保留意见，这两个软件部分组件比较好用。

请问一下贵站用的什么富文本编辑器啊，还支持注解

这是我们自己加的功能，其实就是一个 H5 标签。

今天刚学习完systemd，晚上就遇见文章了。哈，复习一遍systemd用法。

markdownx 可以。 你可以考虑下； 其中 h1,h2 这列东西；可以自己定义好样式；另外目录概要是 利用content 占行显示百分比; 通过 h1 或者 h2 bs4 提出索引; 挑转是根据 #div_id 跳转的，

![Linux cleanup](/data/attachment/album/201709/03/163752hjzalg5ijiduamml.png "Clean up your startup process")

一般情况下，常规用途的 Linux 发行版在开机启动时拉起各种相关服务进程，包括许多你可能无需使用的服务，例如<ruby> 蓝牙 <rt>  bluetooth </rt></ruby>、Avahi、 <ruby> 调制解调管理器 <rt>  ModemManager </rt></ruby>、ppp-dns（LCTT 译注：此处作者笔误 ppp-dns 应该为 pppd-dns) 等服务进程，这些都是什么东西？用于哪里，有何功能？

Systemd 提供了许多很好的工具用于查看系统启动情况，也可以控制在系统启动时运行什么。在这篇文章中，我将说明在 Systemd 类发行版中如何关闭一些令人讨厌的进程。

### 查看开机启动项

在过去，你能很容易通过查看 `/etc/init.d` 了解到哪些服务进程会在引导时启动。Systemd 以不同的方式展现，你可以使用如下命令罗列允许开机启动的服务进程。

```
$ systemctl list-unit-files --type=service | grep enabled
accounts-daemon.service                    enabled
anacron-resume.service                     enabled
anacron.service                            enabled
bluetooth.service                          enabled
brltty.service                             enabled
[...]

```

在此列表顶部，对我来说，蓝牙服务是冗余项，因为在该电脑上我不需要使用蓝牙功能，故无需运行此服务。下面的命令将停止该服务进程，并且使其开机不启动。

```
$ sudo systemctl stop bluetooth.service
$ sudo systemctl disable bluetooth.service

```

你可以通过下面命令确定是否操作成功。

```
$ systemctl status bluetooth.service
 bluetooth.service - Bluetooth service
  Loaded: loaded (/lib/systemd/system/bluetooth.service; disabled; vendor preset: enabled)
  Active: inactive (dead)
    Docs: man:bluetoothd(8)

```

停用的服务进程仍然能够被另外一个服务进程启动。如果你真的想在任何情况下系统启动时都不启动该进程，无需卸载该它，只需要把它掩盖起来就可以阻止该进程在任何情况下开机启动。

```
$ sudo systemctl mask bluetooth.service
 Created symlink from /etc/systemd/system/bluetooth.service to /dev/null.

```

一旦你对禁用该进程启动而没有出现负面作用感到满意，你也可以选择卸载该程序。

通过执行命令可以获得如下服务列表：

```
$ systemctl list-unit-files --type=service
UNIT FILE                                  STATE
accounts-daemon.service                    enabled
acpid.service                              disabled
alsa-restore.service                       static
alsa-utils.service                         masked

```

你不能启用或禁用静态服务，因为静态服务被其他的进程所依赖，并不意味着它们自己运行。

### 哪些服务能够禁止？

如何知道你需要哪些服务，而哪些又是可以安全地禁用的呢？它总是依赖于你的个性化需求。

这里举例了几个服务进程的作用。许多服务进程都是发行版特定的，所以你应该看看你的发行版文档（比如通过 google 或 StackOverflow）。

* **accounts-daemon.service** 是一个潜在的安全风险。它是 AccountsService 的一部分，AccountsService 允许程序获得或操作用户账户信息。我不认为有好的理由能使我允许这样的后台操作，所以我选择<ruby> 掩盖 <rt>  mask </rt></ruby>该服务进程。
* **avahi-daemon.service** 用于零配置网络发现，使电脑超容易发现网络中打印机或其他的主机，我总是禁用它，别漏掉它。
* **brltty.service** 提供布莱叶盲文设备支持，例如布莱叶盲文显示器。
* **debug-shell.service** 开放了一个巨大的安全漏洞（该服务提供了一个无密码的 root shell ，用于帮助 调试 systemd 问题），除非你正在使用该服务，否则永远不要启动服务。
* **ModemManager.service** 该服务是一个被 dbus 激活的守护进程，用于提供移动<ruby> 宽频 <rt>  broadband </rt></ruby>（2G/3G/4G）接口，如果你没有该接口，无论是内置接口，还是通过如蓝牙配对的电话，以及 USB 适配器，那么你也无需该服务。
* **pppd-dns.service** 是一个计算机发展的遗物，如果你使用拨号接入互联网的话，保留它，否则你不需要它。
* **rtkit-daemon.service** 听起来很可怕，听起来像是 rootkit。 但是你需要该服务，因为它是一个<ruby> 实时内核调度器 <rt>  real-time kernel scheduler </rt></ruby>。
* **whoopsie.service** 是 Ubuntu 错误报告服务。它用于收集 Ubuntu 系统崩溃报告，并发送报告到 <https://daisy.ubuntu.com> 。 你可以放心地禁止其启动，或者永久的卸载它。
* **wpa\_supplicant.service** 仅在你使用 Wi-Fi 连接时需要。

### 系统启动时发生了什么？

Systemd 提供了一些命令帮助调试系统开机启动问题。该命令会重演你的系统启动的所有消息。

```
$ journalctl -b

-- Logs begin at Mon 2016-05-09 06:18:11 PDT,
end at Mon 2016-05-09 10:17:01 PDT. --
May 16 06:18:11 studio systemd-journal[289]:
Runtime journal (/run/log/journal/) is currently using 8.0M.
Maximum allowed usage is set to 157.2M.
Leaving at least 235.9M free (of currently available 1.5G of space).
Enforced usage limit is thus 157.2M.
[...]

```

通过命令 `journalctl -b -1` 可以复审前一次启动，`journalctl -b -2` 可以复审倒数第 2 次启动，以此类推。

该命令会打印出大量的信息，你可能并不关注所有信息，只是关注其中问题相关部分。为此，系统提供了几个过滤器，用于帮助你锁定目标。让我们以进程号为 1 的进程为例，该进程是所有其它进程的父进程。

```
$ journalctl _PID=1

May 08 06:18:17 studio systemd[1]: Starting LSB: Raise network interfaces....
May 08 06:18:17 studio systemd[1]: Started LSB: Raise network interfaces..
May 08 06:18:17 studio systemd[1]: Reached target System Initialization.
May 08 06:18:17 studio systemd[1]: Started CUPS Scheduler.
May 08 06:18:17 studio systemd[1]: Listening on D-Bus System Message Bus Socket
May 08 06:18:17 studio systemd[1]: Listening on CUPS Scheduler.
[...]

```

这些打印消息显示了什么被启动，或者是正在尝试启动。

一个最有用的命令工具之一 `systemd-analyze blame`，用于帮助查看哪个服务进程启动耗时最长。

```
$ systemd-analyze blame
         8.708s gpu-manager.service
         8.002s NetworkManager-wait-online.service
         5.791s mysql.service
         2.975s dev-sda3.device
         1.810s alsa-restore.service
         1.806s systemd-logind.service
         1.803s irqbalance.service
         1.800s lm-sensors.service
         1.800s grub-common.service

```

这个特定的例子没有出现任何异常，但是如果存在系统启动瓶颈，则该命令将能发现它。

你也能通过如下资源了解 Systemd 如何工作：

* [理解和使用 Systemd](https://www.linux.com/learn/understanding-and-using-systemd)
* [介绍 Systemd 运行级别和服务管理命令](https://www.linux.com/learn/intro-systemd-runlevels-and-service-management-commands)
* [再次前行，另一个 Linux 初始化系统：Systemd 介绍](https://www.linux.com/learn/here-we-go-again-another-linux-init-intro-systemd)

---

via: <https://www.linux.com/learn/cleaning-your-linux-startup-process>

作者：[David Both](https://www.linux.com/users/cschroder) 译者：[penghuster](https://github.com/penghuster) 校对：[wxy](https://github.com/wxy)

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