使用交互式 shell 来增强你的 Python

![](/data/attachment/album/201805/19/205244xkk5ilwhk7yt5h77.jpg)

Python 编程语言已经成为 IT 中使用的最流行的语言之一。成功的一个原因是它可以用来解决各种问题。从网站开发到数据科学、机器学习到任务自动化，Python 生态系统有丰富的框架和库。本文将介绍 Fedora 软件包集合中提供的一些有用的 Python shell 来简化开发。

### Python Shell

Python Shell 让你以交互模式使用解释器。这在测试代码或尝试新库时非常有用。在 Fedora 中，你可以通过在终端会话中输入 `python3` 来调用默认的 shell。虽然 Fedora 提供了一些更高级和增强的 shell。

### IPython

IPython 为 Python shell 提供了许多有用的增强功能。例如包括 tab 补全，对象内省，系统 shell 访问和命令历史检索。许多功能也被 [Jupyter Notebook](https://ipython.org/notebook.html) 使用，因为它底层使用 IPython。

#### 安装和运行 IPython

```
dnf install ipython3
ipython3

```

使用 tab 补全会提示你可能的选择。当你使用不熟悉的库时，此功能会派上用场。

![](/data/attachment/album/201805/19/205245zpvxpnudxp7e7nie.png)

如果你需要更多信息，输入 `?` 命令来查看文档。对此的更多详细信息，你可以使用 `??` 命令。

![](/data/attachment/album/201805/19/205245l6gub53b6me75je7.png)

另一个很酷的功能是使用 `!` 字符执行系统 shell 命令的能力。然后可以在 IPython shell 中引用该命令的结果。

![](/data/attachment/album/201805/19/205245tzarh4ah1wdhvtvh.png)

IPython 完整的功能列表可在[官方文档](https://ipython.readthedocs.io/en/stable/overview.html#main-features-of-the-interactive-shell)中找到。

### bpython

bpython 并不能像 IPython 做那么多，但它却在一个简单的轻量级包中提供了一系列有用功能。除其他功能之外，bpython 提供：

* 内嵌语法高亮显示
* 在你输入时提供自动补全建议
* 可预期的参数列表
* 能够将代码发送或保存到 pastebin 服务或文件中

#### 安装和运行 bpython

```
dnf install bpython3
bpython3

```

在你输入的时候，`bpython` 为你提供了选择来自动补全你的代码。

![](/data/attachment/album/201805/19/205246tahcccaacaobv0hh.png)

当你调用函数或方法时，会自动显示需要的参数和文档字符串。

![](/data/attachment/album/201805/19/205246gafxpokpcpd3doao.png)

另一个很好的功能是可以使用功能键 `F7` 在外部编辑器（默认为 Vim）中打开当前的 `bpython` 会话。这在测试更复杂的程序时非常有用。

有关配置和功能的更多细节，请参考 bpython [文档](https://docs.bpython-interpreter.org/)。

### 总结

使用增强的 Python shell 是提高生产力的好方法。它为你提供增强的功能来编写快速原型或尝试新库。你在使用增强的 Python shell 吗？请随意在评论区留言。

图片由 [David Clode](https://unsplash.com/photos/d0CasEMHDQs?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 在 [Unsplash](https://unsplash.com/search/photos/python?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上发布

---

via: <https://fedoramagazine.org/enhance-python-interactive-shell/>

作者：[Clément Verna](https://fedoramagazine.org/author/cverna/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何使用 Ansible 打补丁以及安装应用

Summary: 使用 Ansible IT 自动化引擎节省更新的时间。

使用 Ansible IT 自动化引擎节省更新的时间。

>
> 使用 Ansible IT 自动化引擎节省更新的时间。
>
>
>

![](/data/attachment/album/201805/20/035937k1jc6t90wi80je66.jpg)

你有没有想过，如何打补丁、重启系统，然后继续工作？

如果你的回答是肯定的，那就需要了解一下 [Ansible](https://www.ansible.com/overview/how-ansible-works) 了。它是一个配置管理工具，对于一些复杂的有时候需要几个小时才能完成的系统管理任务，又或者对安全性有比较高要求的时候，使用 Ansible 能够大大简化工作流程。

以我作为系统管理员的经验，打补丁是一项最有难度的工作。每次遇到<ruby> 公共漏洞批露 <rt>  Common Vulnearbilities and Exposure </rt></ruby>（CVE）通知或者<ruby> 信息保障漏洞预警 <rt>  Information Assurance Vulnerability Alert </rt></ruby>（IAVA）时都必须要高度关注安全漏洞，否则安全部门将会严肃追究自己的责任。

使用 Ansible 可以通过运行[封装模块](https://docs.ansible.com/ansible/latest/list_of_packaging_modules.html)以缩短打补丁的时间，下面以 [yum 模块](https://docs.ansible.com/ansible/latest/yum_module.html)更新系统为例，使用 Ansible 可以执行安装、更新、删除、从其它地方安装（例如持续集成/持续开发中的 `rpmbuild`）。以下是系统更新的任务：

```
  - name: update the system
    yum:
      name: "*"
      state: latest

```

在第一行，我们给这个任务命名，这样可以清楚 Ansible 的工作内容。第二行表示使用 `yum` 模块在CentOS虚拟机中执行更新操作。第三行 `name: "*"` 表示更新所有程序。最后一行 `state: latest` 表示更新到最新的 RPM。

系统更新结束之后，需要重新启动并重新连接：

```
  - name: restart system to reboot to newest kernel
    shell: "sleep 5 && reboot"
    async: 1
    poll: 0

  - name: wait for 10 seconds
    pause:
      seconds: 10

  - name: wait for the system to reboot
    wait_for_connection:
      connect_timeout: 20
      sleep: 5
      delay: 5
      timeout: 60

  - name: install epel-release
    yum:
      name: epel-release
      state: latest

```

`shell` 模块中的命令让系统在 5 秒休眠之后重新启动，我们使用 `sleep` 来保持连接不断开，使用 `async` 设定最大等待时长以避免发生超时，`poll` 设置为 0 表示直接执行不需要等待执行结果。暂停 10 秒钟以等待虚拟机恢复，使用 `wait_for_connection` 在虚拟机恢复连接后尽快连接。随后由 `install epel-release` 任务检查 RPM 的安装情况。你可以对这个剧本执行多次来验证它的幂等性，唯一会显示造成影响的是重启操作，因为我们使用了 `shell` 模块。如果不想造成实际的影响，可以在使用 `shell` 模块的时候 `changed_when: False`。

现在我们已经知道如何对系统进行更新、重启虚拟机、重新连接、安装 RPM 包。下面我们通过 [Ansible Lightbulb](https://github.com/ansible/lightbulb/tree/master/examples/nginx-role) 来安装 NGINX:

```
  - name: Ensure nginx packages are present
    yum:
      name: nginx, python-pip, python-devel, devel
      state: present
    notify: restart-nginx-service

  - name: Ensure uwsgi package is present
    pip:
      name: uwsgi
      state: present
    notify: restart-nginx-service

  - name: Ensure latest default.conf is present
    template:
      src: templates/nginx.conf.j2
      dest: /etc/nginx/nginx.conf
      backup: yes
    notify: restart-nginx-service

  - name: Ensure latest index.html is present
    template:
      src: templates/index.html.j2
      dest: /usr/share/nginx/html/index.html

  - name: Ensure nginx service is started and enabled
    service:
      name: nginx
      state: started
      enabled: yes

  - name: Ensure proper response from localhost can be received
    uri:
      url: "http://localhost:80/"
      return_content: yes
    register: response
    until: 'nginx_test_message in response.content'
    retries: 10
    delay: 1

```

以及用来重启 nginx 服务的操作文件：

```
# 安装 nginx 的操作文件
  - name: restart-nginx-service
    service:
      name: nginx
      state: restarted

```

在这个角色里，我们使用 RPM 安装了 `nginx`、`python-pip`、`python-devel`、`devel`，用 PIP 安装了 `uwsgi`，接下来使用 `template` 模块复制 `nginx.conf` 和 `index.html` 以显示页面，并确保服务在系统启动时启动。然后就可以使用 `uri` 模块检查到页面的连接了。

这个是一个系统更新、系统重启、安装 RPM 包的剧本示例，后续可以继续安装 nginx，当然这里可以替换成任何你想要的角色和应用程序。

```
  - hosts: all
    roles:
      - centos-update
      - nginx-simple

```

这只是关于如何更新系统、重启以及后续工作的示例。简单起见，我只添加了不带[变量](https://docs.ansible.com/ansible/latest/playbooks_variables.html)的包，当你在操作大量主机的时候，你就需要修改其中的一些设置了：

* [async & poll](https://docs.ansible.com/ansible/latest/playbooks_async.html)
* [serial](https://docs.ansible.com/ansible/latest/playbooks_delegation.html#rolling-update-batch-size)
* [forks](https://docs.ansible.com/ansible/latest/intro_configuration.html#forks)

这是由于在生产环境中如果你想逐一更新每一台主机的系统，你需要花相当一段时间去等待主机重启才能够继续下去。

---

via: <https://opensource.com/article/18/3/ansible-patch-systems>

作者：[Jonathan Lozada De La Matta](https://opensource.com/users/jlozadad) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)

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


如何改善应用程序在 Linux 中的启动时间

![](/data/attachment/album/201805/20/112221y4azq4onand1q4aa.png)

大多数 Linux 发行版在默认配置下已经足够快了。但是，我们仍然可以借助一些额外的应用程序和方法让它们启动更快一点。其中一个可用的这种应用程序就是 Preload。它监视用户使用频率比较高的应用程序，并将它们添加到内存中，这样就比一般的方式加载更快一点。因为，正如你所知道的，内存的读取速度远远快于硬盘。Preload 以守护进程的方式在后台中运行，并记录用户使用较为频繁的程序的文件使用相关的统计数据。然后，它将这些二进制文件及它们的依赖项加载进内存，以改善应用程序的加载时间。简而言之，一旦安装了 Preload，你使用较为频繁的应用程序将可能加载的更快。

在这篇详细的教程中，我们将去了解如何安装和使用 Preload，以改善应用程序在 Linux 中的启动时间。

### 在 Linux 中使用 Preload 改善应用程序启动时间

Preload 可以在 [AUR](https://aur.archlinux.org/packages/preload/) 上找到。因此，你可以使用 AUR 助理程序在任何基于 Arch 的系统上去安装它，比如，Antergos、Manjaro Linux。

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

```
$ pacaur -S preload

```

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

```
$ packer -S preload

```

使用 [Trizen](https://www.ostechnix.com/trizen-lightweight-aur-package-manager-arch-based-systems/)：

```
$ trizen -S preload

```

使用 [Yay](https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/)：

```
$ yay -S preload

```

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

```
$ yaourt -S preload

```

在 Debian、Ubuntu、Linux Mint 上，Preload 可以在默认仓库中找到。因此，你可以像下面一样，使用 APT 包管理器去安装它。

```
$ sudo apt-get install preload

```

Preload 安装完成后，重新启动你的系统。从现在开始，Preload 将监视频繁使用的应用程序，并将它们的二进制文件和库添加到内存中，以使它的启动速度更快。比如，如果你经常使用 Firefox、Chrome 以及 LibreOffice，Preload 将添加这些二进制文件和库到内存中，因此，这些应用程序将启动的更快。而且更好的是，它不需要做任何配置。它是开箱即用的。但是，如果你想去对它进行微调，你可以通过编辑缺省的配置文件 `/etc/preload.conf` 来实现。

### Preload 并不一定适合每个人！

以下是 Preload 的一些缺点，它并不是对每个人都有帮助，在这个 [跟贴](https://askubuntu.com/questions/110335/drawbacks-of-using-preload-why-isnt-it-included-by-default) 中有讨论到。

1. 我使用的是一个有 8GB 内存的现代系统。因此，我的系统总体上来说很快。我每天只打开狂吃内存的应用程序（比如，Firefox、Chrome、VirtualBox、Gimp 等等）一到两次，并且它们始终处于打开状态，因此，它们的二进制文件和库被预读到内存中，并始终整天在内存中。我一般很少去关闭和打开这些应用程序，因此，内存使用纯属浪费。
2. 如果你使用的是带有 SSD 的现代系统，Preload 是绝对没用的。因为 SSD 的访问时间比起一般的硬盘来要快的多，因此，使用 Preload 是没有意义的。
3. Preload 显著影响启动时间。因为更多的应用程序要被预读到内存中，这将让你的系统启动运行时间更长。

你只有在每天都在大量的重新加载应用程序时，才能看到真正的差别。因此，Preload 最适合开发人员和测试人员，他们每天都打开和关闭应用程序好多次。

关于 Preload 更多的信息和它是如何工作的，请阅读它的作者写的完整版的 [Preload 论文](https://cs.uwaterloo.ca/%7Ebrecht/courses/702/Possible-Readings/prefetching-to-memory/preload-thesis.pdf)。

教程到此为止，希望能帮到你。后面还有更精彩的内容，请继续关注！

再见！

---

via: <https://www.ostechnix.com/how-to-improve-application-startup-time-in-linux/>

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

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


如何使用 Buildah 构建容器镜像

![](/data/attachment/album/201805/21/071923ewuygn5g3vggjf3n.png)

Project Atomic 通过他们在 Open Container Initiative（OCI）上的努力创造了一个名为 [Buildah](https://github.com/projectatomic/buildah) 的伟大工具。Buildah 能帮助创建、构建和更新，它支持 Docker 容器镜像以及 OCI 兼容镜像。

Buildah 处理构建容器镜像时无需安装完整的容器运行时或守护进程。这对建立容器的持续集成和持续交付管道尤其有用。

Buildah 使容器的文件系统可以直接供构建主机使用。这意味着构建工具在主机上可用就行，而不需要在容器镜像中可用，从而使构建更快速，镜像更小，更安全。Buildah 有 CentOS、Fedora 和 Debian 的软件包。

### 安装 Buildah

从 Fedora 26 开始 Buildah 可以使用 `dnf` 进行安装。

```
$ sudo dnf install buildah -y

```

`buildah` 的当前版本为 0.16，可以通过以下命令显示。

```
$ buildah --version

```

### 基本命令

构建容器镜像的第一步是获取基础镜像，这是通过 Dockerfile 中的 `FROM` 语句完成的。Buildah 以类似的方式处理这个。

```
$ sudo buildah from fedora

```

该命令将拉取 Fedora 的基础镜像并存储在主机上。通过执行以下操作可以检查主机上可用的镜像。

```
$ sudo buildah images
IMAGE ID IMAGE NAME CREATED AT SIZE
9110ae7f579f docker.io/library/fedora:latest Mar 7, 2018 20:51 234.7 MB

```

在拉取基础镜像后，有一个该镜像的运行容器实例，这是一个“工作容器”。

以下命令显示正在运行的容器。

```
$ sudo buildah containers
CONTAINER ID BUILDER IMAGE ID IMAGE NAME
CONTAINER NAME
6112db586ab9 * 9110ae7f579f docker.io/library/fedora:latest fedora-working-container

```

Buildah 还提供了一个非常有用的命令来停止和删除当前正在运行的所有容器。

```
$ sudo buildah rm --all

```

完整的命令列表可以使用 `--help` 选项。

```
$ buildah --help

```

### 构建一个 Apache Web 服务器容器镜像

让我们看看如何使用 Buildah 在 Fedora 基础镜像上安装 Apache Web 服务器，然后复制一个可供服务的自定义 `index.html`。

首先让我们创建自定义的 `index.html`。

```
$ echo "Hello Fedora Magazine !!!" > index.html

```

然后在正在运行的容器中安装 httpd 包。

```
$ sudo buildah from fedora
$ sudo buildah run fedora-working-container dnf install httpd -y

```

让我们将 `index.html` 复制到 `/var/www/html/`。

```
$ sudo buildah copy fedora-working-container index.html /var/www/html/index.html

```

然后配置容器入口点以启动 httpd。

```
$ sudo buildah config --entrypoint "/usr/sbin/httpd -DFOREGROUND" fedora-working-container

```

现在为了使“工作容器”可用，`commit` 命令将容器保存到镜像。

```
$ sudo buildah commit fedora-working-container hello-fedora-magazine

```

hello-fedora-magazine 镜像现在可用，并且可以推送到仓库以供使用。

```
$ sudo buildah images
IMAGE ID IMAGE NAME CREATED
AT SIZE
9110ae7f579f docker.io/library/fedora:latest
Mar 7, 2018 22:51 234.7 MB
49bd5ec5be71 docker.io/library/hello-fedora-magazine:latest
Apr 27, 2018 11:01 427.7 MB

```

通过运行以下步骤，还可以使用 Buildah 来测试此镜像。

```
$ sudo buildah from --name=hello-magazine docker.io/library/hello-fedora-magazine
$ sudo buildah run hello-magazine

```

访问 <http://localhost> 将显示 “Hello Fedora Magazine !!!”

---

via: <https://fedoramagazine.org/daemon-less-container-management-buildah/>

作者：[Ashutosh Sudhakar Bhakare](https://fedoramagazine.org/author/ashutoshbhakare/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


有用的资源，献给那些想更多了解 Linux 的人

![](/data/attachment/album/201805/21/073426vdpz8p3xdnjejlrp.png)

Linux 是最流行和多功能的操作系统之一，它可以用在智能手机，电脑甚至汽车上。自 20 世纪 90 年代以来，Linux 存在至今，并且仍然是最普遍的操作系统之一。

Linux 实际上用于运行大多数网络服务，因为与其他操作系统相比，它被认为是相当稳定的。这是[人们选择 Linux 多于 Windows 的原因](https://www.lifewire.com/windows-vs-linux-mint-2200609)之一。此外，Linux 为用户提供了隐私，根本不收集用户信息，而 Windows 10 及其 Cortana 语音控制系统总是需要更新你的个人信息。

Linux 有很多优点。然而，人们并没有听到太多关于它的消息，因为它已被 Windows 和 Mac 挤出（桌面）场。许多人开始使用 Linux 时会感到困惑，因为它与流行的操作系统有点不同。

为了帮助你，我们为那些想要了解更多关于 Linux 的人收集了 5 个有用的资源。

### 1、[Linux 纯新手](https://www.eduonix.com/courses/system-programming/linux-for-absolute-beginners)

如果你想尽可能多地学习 Linux，你应该考虑 Eduonix 为[初学者提供的 Linux 完整教程](https://www.eduonix.com/courses/system-programming/linux-for-absolute-beginners)。这个课程将向你介绍 Linux 的所有功能，并为你提供所有必要的资料，以帮助你了解更多关于 Linux 工作原理的特性。

如果你是以下情况，你应该选择本课程：

* 你想了解有关 Linux 操作系统的详细信息；
* 你想知道如何安装它；
* 你想了解 Linux 如何与硬件配合使用；
* 你想学习如何操作 Linux 命令行。

### 2、[PC World: Linux 初学者指南](https://www.pcworld.com/article/2918397/operating-systems/how-to-get-started-with-linux-a-beginners-guide.html)

为想要在一个地方学习所有有关 Linux 的人提供[免费资源](https://www.pcworld.com/article/2918397/operating-systems/how-to-get-started-with-linux-a-beginners-guide.html)。PC World 专注于计算机操作系统的各个方面，并为订阅用户提供最准确和最新的信息。在这里，你还可以了解更多关于 [Linux 的好处](https://www.popsci.com/switch-to-linux-operating-system#page-4) 和关于其操作系统的最新消息。

该资源为你提供以下信息：

* 如何安装 Linux；
* 如何使用命令行；
* 如何安装软件；
* 如何操作 Linux 桌面环境。

### 3、[Linux.com：Linux 培训](https://www.linux.com/learn/training)

很多使用计算机的人都需要学习如何操作 Linux，以防 Windows 操作系统突然崩溃。还有什么比使用官方资源来启动你的 [Linux 培训](https://www.linux.com/learn/training)更好呢？

该资源可用让你在线注册 Linux 训练，你可以从官方来源获取最新信息。“一年前，我们的 IT 部门在官方网站上为我们提供了 Linux 培训” [Assignmenthelper.com.au](https://www.assignmenthelper.com.au/) 的开发人员 Martin Gibson 说道。“我们选择了这门课，因为我们需要学习如何将我们的所有文件备份到另一个系统，为我们的客户提供最大的安全性，而且这个资源真的教会了我们所有的东西。”

所以你肯定应该使用这个资源，如果：

* 你想获得有关操作系统的第一手信息；
* 想要了解如何在你的计算机上运行 Linux 的特性；
* 想要与其他 Linux 用户联系并与他们分享你的经验。

### 4、 [Linux 基金会：视频培训](https://training.linuxfoundation.org/free-linux-training/linux-training-videos)

如果你在阅读大量资源时容易感到无聊，那么该网站绝对适合你。Linux 基金会提供了由 IT 专家、软件开发技术人员和技术顾问举办的[视频培训](https://training.linuxfoundation.org/free-linux-training/linux-training-videos)，讲座和在线研讨会。

所有培训视频分为以下类别：

* 开发人员： 使用 Linux 内核来处理 Linux 设备驱动程序、Linux 虚拟化等；
* 系统管理员：在 Linux 上开发虚拟主机，构建防火墙，分析 Linux 性能等；
* 用户：Linux 入门，介绍嵌入式 Linux 等。

### 5、 [LinuxInsider](https://www.linuxinsider.com/)

你知道吗？微软对 Linux 的效率感到惊讶，它[允许用户在微软云计算设备上运行 Linux](https://www.wired.com/2016/08/linux-took-web-now-taking-world/)。如果你想了解更多关于 Linux 操作系统的知识，[Linux Insider](https://www.linuxinsider.com/) 会向用户提供关于 Linux 操作系统的最新消息，以及最新更新和 Linux 特性的信息。

在此资源上，你将有机会：

* 参与 Linux 社区；
* 了解如何在各种设备上运行 Linux；
* 看看评论；
* 参与博客讨论并阅读科技博客。

### 总结一下

Linux 提供了很多好处，包括完全的隐私，稳定的操作甚至恶意软件保护。它绝对值得尝试，学习如何使用会帮助你更好地了解你的计算机如何工作以及它需要如何平稳运行。

### 关于作者

Lucy Benton 是一位数字营销专家，商业顾问，帮助人们将他们的梦想变为有利润的业务。现在她正在为营销和商业资源撰写。Lucy 还有自己的博客 [*Prowritingpartner.com*](https://prowritingpartner.com/)，在那里你可以查看她最近发表的文章。

---

via: <https://linuxaria.com/article/useful-resources-for-those-who-want-to-know-more-about-linux>

作者：[Lucy Benton](https://www.lifewire.com) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


一个可以更好地调试的 Perl 模块

>
> 这个简单优雅的模块可以让你包含调试或仅用于开发环境的代码，而在产品环境中隐藏它们。
>
>
>

![](/data/attachment/album/201805/21/075502mmzlyfwlllbb1ffl.jpg)

仅用于调试或开发调整时的 Perl 代码块有时会很有用。这很好，但是这样的代码块可能会对性能产生很大的影响, 尤其是在运行时才决定是否执行它。

[Curtis "Ovid" Poe](https://metacpan.org/author/OVID) 最近编写了一个可以帮助解决这个问题的模块：[Keyword::DEVELOPMENT](https://metacpan.org/pod/release/OVID/Keyword-DEVELOPMENT-0.04/lib/Keyword/DEVELOPMENT.pm)。该模块利用 `Keyword::Simple` 和 Perl 5.012 中引入的可插入关键字架构来创建了新的关键字：`DEVELOPMENT`。它使用 `PERL_KEYWORD_DEVELOPMENT` 环境变量的值来确定是否要执行一段代码。

使用它不能更容易了：

```
use Keyword::DEVELOPMENT;

sub doing_my_big_loop {
    my $self = shift;
    DEVELOPMENT {
        # insert expensive debugging code here!
    }
}

```

在编译时，`DEVELOPMENT` 块内的代码已经被优化掉了，根本就不存在。

你看到好处了么？在沙盒中将 `PERL_KEYWORD_DEVELOPMENT` 环境变量设置为 `true`，在生产环境设为 `false`，并且可以将有价值的调试工具提交到你的代码库中，在你需要的时候随时可用。

在缺乏高级配置管理的系统中，你也可以使用此模块来处理生产和开发或测试环境之间的设置差异：

```
sub connect_to_my_database {

    my $dsn = "dbi:mysql:productiondb";
    my $user = "db_user";
    my $pass = "db_pass";

    DEVELOPMENT {
        # Override some of that config information
        $dsn = "dbi:mysql:developmentdb";
    }

    my $db_handle = DBI->connect($dsn, $user, $pass);
}

```

稍后对此代码片段的增强使你能在其他地方，比如 YAML 或 INI 中读取配置信息，但我希望您能在此看到该工具。

我查看了关键字 `Keyword::DEVELOPMENT` 的源码，花了大约半小时研究，“天哪，我为什么没有想到这个？”安装 `Keyword::Simple` 后，Curtis 给我们的模块就非常简单了。这是我长期以来在自己的编码实践中所需要的一个优雅解决方案。

---

via: <https://opensource.com/article/18/4/perl-module-debugging-code>

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

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


Jupyter Notebooks 入门

>
> 通过 Jupyter 使用实时代码、方程式和可视化及文本创建交互式的共享笔记本。
>
>
>

![](/data/attachment/album/201805/21/082420s8r3azrm38op8b1n.png)

自从有了纸莎草纸以来，出版人们一直在努力以吸引读者的方式来格式化数据。尤其是在数学、科学、和编程领域，设计良好的图表、插图和方程式可以成为帮助人们理解技术信息的关键。

[Jupyter Notebook](http://jupyter.org/) 通过重新构想我们如何制作教学文本来解决这个问题。Jupyter （我在 2017 年 10 月在 [All Things Open](https://allthingsopen.org/) 上首次了解到）是一款开源应用程序，它使用户能够创建包含实时代码、方程式、可视化和文本的交互式共享笔记本。

Jupyter 从 [IPython 项目](http://ipython.org/)发展而来，它是个具有交互式 shell 和基于浏览器的笔记本，支持代码、文本和数学表达式。Jupyter 支持超过 40 种编程语言，包括 Python、R 和 Julia，其代码可以导出为 HTML、LaTeX、PDF、图像和视频，或者作为 [IPyhton](https://en.wikipedia.org/wiki/IPython) 笔记本与其他用户共享。

>
> 一个有趣的事实是：“Jupyter” 是 “Julia、Python 和 R” 的缩写。
>
>
>

根据 Jupyter 项目网站介绍，它的一些用途包括“数据清理和转换，数值模拟，统计建模，数据可视化，机器学习等等”。科学机构正在使用 Jupyter Notebooks 来解释研究结果。代码可以来自实际数据，可以调整和重新调整以可视化成不同的结果和情景。通过这种方式，Jupyter Notebooks 变成了生动的文本和报告。

### 安装并开始 Jupyter

Jupyter 软件是开源的，其授权于[修改过的 BSD 许可证](https://opensource.org/licenses/BSD-3-Clause)，它可以[安装在 Linux、MacOS 或 Windows 上](http://jupyter.org/install.html)。有很多种方法可以安装 Jupyter；我在 Linux 和 MacOS 上试过 PIP 和 [Anaconda](https://www.anaconda.com/download/#linux) 安装方式。PIP 安装要求你的计算机上已经安装了 Python；Jupyter 推荐 Python 3。

由于 Python 3 已经安装在我的电脑上，我通过在终端（在 Linux 或 Mac 上）运行以下命令来安装 Jupyter：

```
$ python3 -m pip install --upgrade pip
$ python3 -m pip install jupyter

```

在终端提示符输入以下命令立即启动应用程序：

```
$ jupyter notebook

```

很快，我的浏览器打开并显示了我在 `http://localhost:8888` 的 Jupyter Notebook 服务器。（支持的浏览器有 Google Chrome、Firefox 和 Safari）

![](/data/attachment/album/201805/21/082421dnx6fqqawddisdxq.png)

在右上角有一个标有 “New” 的下拉菜单，它使我能够根据自己的指示和代码快速创建新的笔记本。请注意，我的新笔记本默认为 Python 3，这是我目前的环境。

![](/data/attachment/album/201805/21/082421kmzvrfqtb9vvnvn6.png)

一个带有一些默认值的新笔记本，它可以被改变（包括笔记本的名字），已打开。

![](/data/attachment/album/201805/21/082421nqp66yepjym62vgx.png)

笔记本有两种不同的模式：“命令模式”和“编辑模式”。命令模式允许你添加或删除单元格。你可以通过按下 `Escape` 键进入命令模式，按 `Enter` 键或单击单元格进入编辑模式。

单元格周围的绿色高亮显示你处于编辑模式，蓝色高亮显示你处于命令模式。以下笔记本处于命令模式并准备好执行单元中的 Python 代码。注意，我已将笔记本的名称更改为 “First Notebook”。

![](/data/attachment/album/201805/21/082422vj8ane2zu85op753.png)

### 使用 Jupyter

Jupyter Notebooks 的强大之处在于除了能够输入代码之外，你还可以用 Markdown 添加叙述性和解释性文本。我想添加一个标题，所以我在代码上面添加了一个单元格，并以 Markdown 输入了一个标题。当我按下 `Ctrl+Enter` 时，我的标题转换为 HTML。（LCTT 译注：或者可以按下 Run 按钮。）

![](/data/attachment/album/201805/21/082422j434avlvey0fx7va.png)

我可以通过在命令前追加 `!` 来添加 Bash 命令或脚本的输出。

![](/data/attachment/album/201805/21/082423enzn3w8snluzl66r.png)

我也可以利用 IPython 的 [line magic 和 cell magic](http://ipython.readthedocs.io/en/stable/interactive/magics.html) 命令。你可以通过在代码单元内附加 `%` 或 `%%` 符号来列出魔术命令。例如，`%lsmagic` 将输出所有可用于 Jupyter notebooks 的魔法命令。

![](/data/attachment/album/201805/21/082423lx5f31vj9mzzf1u1.png)

这些魔术命令的例子包括 `%pwd`——它输出当前工作目录（例如 `/Users/YourName`）和 `%ls`——它列出当前工作目录中的所有文件和子目录。另一个神奇命令显示从笔记本中的 `matplotlib` 生成的图表。`%%html` 将该单元格中的任何内容呈现为 HTML，这对嵌入视频和链接很有用，还有 JavaScript 和 Bash 的单元魔术命令。

如果你需要更多关于使用 Jupyter Notebooks 和它的特性的信息，它的帮助部分是非常完整的。

人们用许多有趣的方式使用 Jupyter Notebooks；你可以在这个[展示栏目](https://github.com/jupyter/jupyter/wiki/a-gallery-of-interesting-jupyter-notebooks#mathematics)里找到一些很好的例子。你如何使用 Jupyter 笔记本？请在下面的评论中分享你的想法。

---

via: <https://opensource.com/article/18/3/getting-started-jupyter-notebooks>

作者：[Don Watkins](https://opensource.com/users/don-watkins) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


如何编译 Linux 内核

Summary: Jack 将带你在 Ubuntu 16.04 服务器上走过内核编译之旅。

文中出现128GB是个错误，原文是12GB

谢谢！

精辟

sad

Jack 将带你在 Ubuntu 16.04 服务器上走过内核编译之旅。

>
> Jack 将带你在 Ubuntu 16.04 服务器上走过内核编译之旅。
>
>
>

![](/data/attachment/album/201805/22/125626duwkeqqh5l5103t5.jpg)

曾经有一段时间，升级 Linux 内核让很多用户打心里有所畏惧。在那个时候，升级内核包含了很多步骤，也需要很多时间。现在，内核的安装可以轻易地通过像 `apt` 这样的包管理器来处理。通过添加特定的仓库，你能很轻易地安装实验版本的或者指定版本的内核（比如针对音频产品的实时内核）。

考虑一下，既然升级内核如此容易，为什么你不愿意自行编译一个呢？这里列举一些可能的原因：

* 你想要简单了解编译内核的过程
* 你需要启用或者禁用内核中特定的选项，因为它们没有出现在标准选项里
* 你想要启用标准内核中可能没有添加的硬件支持
* 你使用的发行版需要你编译内核
* 你是一个学生，而编译内核是你的任务

不管出于什么原因，懂得如何编译内核是非常有用的，而且可以被视作一个通行权。当我第一次编译一个新的 Linux 内核（那是很久以前了），然后尝试从它启动，我从中（系统马上就崩溃了，然后不断地尝试和失败）感受到一种特定的兴奋。

既然这样，让我们来实验一下编译内核的过程。我将使用 Ubuntu 16.04 Server 来进行演示。在运行了一次常规的 `sudo apt upgrade` 之后，当前安装的内核版本是 `4.4.0-121`。我想要升级内核版本到 `4.17`， 让我们小心地开始吧。

有一个警告：强烈建议你在虚拟机里实验这个过程。基于虚拟机，你总能创建一个快照，然后轻松地从任何问题中回退出来。不要在产品机器上使用这种方式升级内核，除非你知道你在做什么。

### 下载内核

我们要做的第一件事是下载内核源码。在 [Kernel.org](https://www.kernel.org/) 找到你要下载的所需内核的 URL。找到 URL 之后，使用如下命令（我以 `4.17 RC2` 内核为例） 来下载源码文件:

```
wget https://git.kernel.org/torvalds/t/linux-4.17-rc2.tar.gz

```

在下载期间，有一些事需要去考虑。

### 安装需要的环境

为了编译内核，我们首先得安装一些需要的环境。这可以通过一个命令来完成：

```
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

```

务必注意：你将需要至少 12 GB 的本地可用磁盘空间来完成内核的编译过程。因此你必须确保有足够的空间。

### 解压源码

在新下载的内核所在的文件夹下，使用该命令来解压内核：

```
tar xvzf linux-4.17-rc2.tar.gz

```

使用命令 `cd linux-4.17-rc2` 进入新生成的文件夹。

### 配置内核

在正式编译内核之前，我们首先必须配置需要包含哪些模块。实际上，有一些非常简单的方式来配置。使用一个命令，你能拷贝当前内核的配置文件，然后使用可靠的 `menuconfig` 命令来做任何必要的更改。使用如下命令来完成：

```
cp /boot/config-$(uname -r) .config

```

现在你有一个配置文件了，输入命令 `make menuconfig`。该命令将打开一个配置工具（图 1），它可以让你遍历每个可用模块，然后启用或者禁用你需要或者不需要的模块。

![menuconfig](/data/attachment/album/201805/22/125627aprvhplr8fvhkmrk.jpg "menuconfig")

*图 1: 运行中的 `make menuconfig`*

很有可能你会禁用掉内核中的一个重要部分，所以在 `menuconfig` 期间小心地一步步进行。如果你对某个选项不确定，不要去管它。或者更好的方法是使用我们拷贝的当前运行的内核的配置文件（因为我们知道它可以工作）。一旦你已经遍历了整个配置列表（它非常长），你就准备好开始编译了。

### 编译和安装

现在是时候去实际地编译内核了。第一步是使用 `make` 命令去编译。调用 `make` 命令然后回答必要的问题（图 2）。这些问题取决于你将升级的现有内核以及升级后的内核。相信我，将会有非常多的问题要回答，因此你得预留大量的时间。

![make](/data/attachment/album/201805/22/125627n1b6ttqb6ncbx16t.jpg "make")

*图 2: 回答 `make` 命令的问题*

回答了长篇累牍的问题之后，你就可以用如下的命令安装那些之前启用的模块：

```
make modules_install

```

又来了，这个命令将耗费一些时间，所以要么坐下来看着编译输出，或者去做些其他事（因为编译期间不需要你的输入）。可能的情况是，你想要去进行别的任务（除非你真的喜欢看着终端界面上飞舞而过的输出）。

现在我们使用这个命令来安装内核：

```
sudo make install

```

又一次，另一个将要耗费大量可观时间的命令。事实上，`make install` 命令将比 `make modules_install` 命令花费更多的时间。去享用午餐，配置一个路由器，将 Linux 安装在一些服务器上，或者小睡一会吧。

### 启用内核作为引导

一旦 `make install` 命令完成了，就是时候将内核启用来作为引导。使用这个命令来实现：

```
sudo update-initramfs -c -k 4.17-rc2

```

当然，你需要将上述内核版本号替换成你编译完的。当命令执行完毕后，使用如下命令来更新 grub：

```
sudo update-grub

```

现在你可以重启系统并且选择新安装的内核了。

### 恭喜!

你已经编译了一个 Linux 内核！它是一项耗费时间的活动；但是，最终你的 Linux 发行版将拥有一个定制的内核，同时你也将拥有一项被许多 Linux 管理员所倾向忽视的重要技能。

从 Linux 基金会和 edX 提供的免费 [“Introduction to Linux”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 课程来学习更多的 Linux 知识。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/4/how-compile-linux-kernel-0>

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

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


6 个 Python 的日期时间库

Summary: 在 Python 中有许多库可以很容易地测试、转换和读取日期和时间信息。

在 Python 中有许多库可以很容易地测试、转换和读取日期和时间信息。

>
> 在 Python 中有许多库可以很容易地测试、转换和读取日期和时间信息。
>
>
>

![](/data/attachment/album/201805/22/161301ewwz66h6y8hkngmk.jpg)

*这篇文章是与 [Jeff Triplett](https://opensource.com/users/jefftriplett) 一起合写的。*

曾几何时，我们中的一个人（Lacey）盯了一个多小时的 [Python 文档](https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior)中描述日期和时间格式化字符串的表格。当我试图编写从 API 中将日期时间字符串转换为 [Python datetime](https://opensource.com/article/17/5/understanding-datetime-python-primer) 对象时，我很难理解其中的特定部分，因此我决定请求帮助。

有人问道：“为什么你不使用 `dateutil` 呢？”

读者，如果你没有从这个月的 Python 专栏中获得任何东西，只是学习到有比 datetime 的 `strptime` 更容易地将 datetime 字符串转换为 datetime 对象的方法，那么我们觉得就已经成功了。

但是，除了将字符串转换为更有用的 Python 对象之外，还有许多库都有一些有用的方法和工具，可以让您更轻松地进行时间测试、将时间转换为不同的时区、以人类可读的格式传递时间信息，等等。如果这是你在 Python 中第一次接触日期和时间，请暂停并阅读 *[如何使用 Python的日期和时间](https://opensource.com/article/17/5/understanding-datetime-python-primer)* 。要理解为什么在编程中处理日期和时间是困难的，请阅读 [愚蠢的程序员相信时间](http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time)。

这篇文章将会向你介绍以下库：

* [Dateutil](https://opensource.com/#Dateutil)
* [Arrow](https://opensource.com/#Arrow)
* [Moment](https://opensource.com/#Moment)
* [Maya](https://opensource.com/#Maya)
* [Delorean](https://opensource.com/#Delorean)
* [Freezegun](https://opensource.com/#Freezegun)

随意跳过那些你已经熟悉的库，专注于那些对你而言是新的库。

### 内建的 datetime 模块

在跳转到其他库之前，让我们回顾一下如何使用 `datetime` 模块将日期字符串转换为 Python datetime 对象。

假设我们从 API 接受到一个日期字符串，并且需要它作为 Python datetime 对象存在：

```
2018-04-29T17:45:25Z

```

这个字符串包括：

* 日期是 `YYYY-MM-DD` 格式的
* 字母 `T` 表示时间即将到来
* 时间是 `HH:II:SS` 格式的
* 表示此时间的时区指示符 `Z` 采用 UTC （详细了解[日期时间字符格式](https://www.w3.org/TR/NOTE-datetime)）

要使用 `datetime` 模块将此字符串转换为 Python datetime 对象，你应该从 `strptime` 开始。 `datetime.strptime` 接受日期字符串和格式化字符并返回一个 Python datetime 对象。

我们必须手动将日期时间字符串的每个部分转换为 Python 的 `datetime.strptime` 可以理解的合适的格式化字符串。四位数年份由 `%Y` 表示，两位数月份是 `%m`，两位数的日期是 `%d`。在 24 小时制中，小时是 `%H`，分钟是 `%M`，秒是 `%S`。

为了得出这些结论，需要在[Python 文档](https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior)的表格中多加注意。

由于字符串中的 `Z` 表示此日期时间字符串采用 UTC，所以我们可以在格式中忽略此项。（现在，我们不会担心时区。）

转换的代码是这样的：

```
$ from datetime import datetime
$ datetime.strptime('2018-04-29T17:45:25Z', '%Y-%m-%dT%H:%M:%SZ')
datetime.datetime(2018, 4, 29, 17, 45, 25)

```

格式字符串很难阅读和理解。我必须手动计算原始字符串中的字母 `T` 和 “Z”的位置，以及标点符号和格式化字符串，如 `%S` 和 `%m`。有些不太了解 datetime 的人阅读我的代码可能会发现它很难理解，尽管其含义已有文档记载，但它仍然很难阅读。

让我们看看其他库是如何处理这种转换的。

### Dateutil

[dateutil 模块](https://dateutil.readthedocs.io/en/stable/)对 `datetime` 模块做了一些扩展。

继续使用上面的解析示例，使用 `dateutil` 实现相同的结果要简单得多：

```
$ from dateutil.parser import parse
$ parse('2018-04-29T17:45:25Z')
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=tzutc())

```

如果字符串包含时区，那么 `dateutil` 解析器会自动返回字符串的时区。由于我们在 UTC 时区，你可以看到返回来一个 datetime 对象。如果你想解析完全忽略时区信息并返回原生的 datetime 对象，你可以传递 `ignoretz=True` 来解析，如下所示：

```
$ from dateutil.parser import parse
$ parse('2018-04-29T17:45:25Z', ignoretz=True)
datetime.datetime(2018, 4, 29, 17, 45, 25)

```

`dateutil` 还可以解析其他人类可读的日期字符串：

```
$ parse('April 29th, 2018 at 5:45 pm')
datetime.datetime(2018, 4, 29, 17, 45)

```

`dateutil` 还提供了像 [relativedelta](https://dateutil.readthedocs.io/en/stable/relativedelta.html) 的工具，它用于计算两个日期时间之间的时间差或向日期时间添加或删除时间，[rrule](https://dateutil.readthedocs.io/en/stable/rrule.html) 创建重复日期时间，[tz](https://dateutil.readthedocs.io/en/stable/tz.html) 用于解决时区以及其他工具。

### Arrow

[Arrow](https://github.com/crsmithdev/arrow) 是另一个库，其目标是操作、格式化，以及处理对人类更友好的日期和时间。它包含 `dateutil`，根据其[文档](https://pypi.python.org/pypi/arrow-fatisar/0.5.3)，它旨在“帮助你使用更少的包导入和更少的代码来处理日期和时间”。

要返回我们的解析示例，下面介绍如何使用 Arrow 将日期字符串转换为 Arrow 的 datetime 类的实例：

```
$ import arrow
$ arrow.get('2018-04-29T17:45:25Z')
<Arrow [2018-04-29T17:45:25+00:00]>

```

你也可以在 `get()` 的第二个参数中指定格式，就像使用 `strptime` 一样，但是 Arrow 会尽力解析你给出的字符串，`get()` 返回 Arrow 的 `datetime` 类的一个实例。要使用 Arrow 来获取 Python datetime 对象，按照如下所示链式 datetime：

```
$ arrow.get('2018-04-29T17:45:25Z').datetime
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=tzutc())

```

通过 Arrow datetime 类的实例，你可以访问 Arrow 的其他有用方法。例如，它的 `humanize()` 方法将日期时间翻译成人类可读的短语，就像这样：

```
$ import arrow
$ utc = arrow.utcnow()
$ utc.humanize()
'seconds ago'

```

在 Arrow 的[文档](https://arrow.readthedocs.io/en/latest/)中阅读更多关于其有用方法的信息。

### Moment

[Moment](https://github.com/zachwill/moment) 的作者认为它是“内部测试版”，但即使它处于早期阶段，它也是非常受欢迎的，我们想来讨论它。

Moment 的方法将字符转换为其他更有用的东西很简单，类似于我们之前提到的库：

```
$ import moment
$ moment.date('2018-04-29T17:45:25Z')
<Moment(2018-04-29T17:45:25)>

```

就像其他库一样，它最初返回它自己的 datetime 类的实例，要返回 Python datetime 对象，添加额外的 `date()` 调用即可。

```
$ moment.date('2018-04-29T17:45:25Z').date
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=<StaticTzInfo 'Z'>)

```

这将 Moment datetime 类转换为 Python datetime 对象。

Moment 还提供了使用人类可读的语言创建新日期的方法。例如创建一个明天的日期：

```
$ moment.date("tomorrow")
<Moment(2018-04-06T11:24:42)>

```

它的 `add()` 和 `subtract()` 命令使用关键字参数来简化日期的操作。为了获得后天，Moment 会使用下面的代码：

```
$ moment.date("tomorrow").add(days=1)
<Moment(2018-04-07T11:26:48)>

```

### Maya

[Maya](https://github.com/kennethreitz/maya) 包含了 Python 中其他流行处理日期时间的库，包括 Humanize、 pytz 和 pendulum 等等。这个项目旨在让人们更容易处理日期。

Maya 的 README 包含几个有用的实例。以下是如何使用 Maya 来重新处理以前的解析示例：

```
$ import maya
$ maya.parse('2018-04-29T17:45:25Z').datetime()
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=<UTC>)

```

注意我们必须在 `maya.parse()` 之后调用 `datetime()`。如果我们跳过这一步，Maya 将会返回一个 MayaDT 类的示例：`<MayaDT epoch=1525023925.0>`。

由于 Maya 与 datetime 库中很多有用的方法重叠，因此它可以使用 MayaDT 类的实例执行诸如使用 `slang_time()` 方法将时间偏移量转换为纯文本语言，并将日期时间间隔保存在单个类的实例中。以下是如何使用 Maya 将日期时间表示为人类可读的短语：

```
$ import maya
$ maya.parse('2018-04-29T17:45:25Z').slang_time()
'23 days from now

```

显然，`slang_time()` 的输出将根据距离 datetime 对象相对较近或较远的距离而变化。

### Delorean

[Delorean](https://github.com/myusuf3/delorean)，以 《返回未来》 电影中的时间旅行汽车命名，它对于操纵日期时间特别有用，包括将日期时间转换为其他时区并添加或减去时间。

Delorean 需要有效的 Python datetime 对象才能工作，所以如果你需要使用时间字符串，最好将其与上述库中的一个配合使用。例如，将 Maya 与 Delorean 一起使用：

```
$ import maya
$ d_t = maya.parse('2018-04-29T17:45:25Z').datetime()

```

现在，你有了一个 datetime 对象 d\_t，你可以使用 Delorean 来做一些事情，例如将日期时间转换为美国东部时区：

```
$ from delorean import Delorean
$ d = Delorean(d_t)
$ d
Delorean(datetime=datetime.datetime(2018, 4, 29, 17, 45, 25), timezone='UTC')
$ d.shift('US/Eastern')
Delorean(datetime=datetime.datetime(2018, 4, 29, 13, 45, 25), timezone='US/Eastern')

```

看到小时是怎样从 17 变成 13 了吗？

你也可以使用自然语言方法来操作 datetime 对象。获取 2018 年 4 月 29 日之后的下个星期五（我们现在使用的）：

```
$ d.next_friday()
Delorean(datetime=datetime.datetime(2018, 5, 4, 13, 45, 25), timezone='US/Eastern')

```

在 Delorean 的[文档](https://delorean.readthedocs.io/en/latest/)中阅读更多关于其的用法。

### Freezegun

[Freezegun](https://github.com/spulec/freezegun) 是一个可以帮助你在 Python 代码中测试特定日期的库。使用 `@freeze_time` 装饰器，你可以为测试用例设置特定的日期和时间，并且所有对 `datetime.datetime.now()`、 `datetime.datetime.utcnow()` 等的调用都将返回你指定的日期和时间。例如：

```
from freezegun import freeze_time
import datetime

@freeze_time("2017-04-14")
def test():
    assert datetime.datetime.now() == datetime.datetime(2017, 4, 14)

```

要跨时区进行测试，你可以将 `tz_offset` 参数传递给装饰器。`freeze_time` 装饰器也接受更简单的口语化日期，例如 `@freeze_time('April 4, 2017')`。

---

上面提到的每个库都提供了一组不同的特性和功能，也许很难决定哪一个最适合你的需要。[Maya 的作者](https://github.com/kennethreitz/maya), Kenneth Reitz 说到：“所有这些项目相辅相成，它们都是我们的朋友”。

这些库共享一些功能，但不是全部。有些擅长时间操作，有些擅长解析，但它们都有共同的目标，即让你对日期和时间的工作更轻松。下次你发现自己对 Python 的内置 datetime 模块感到沮丧，我们希望你可以选择其中的一个库进行试验。

---

via: <https://opensource.com/article/18/4/python-datetime-libraries>

作者: [Lacey Williams Hensche](https://opensource.com/users/laceynwilliams) 选题: [lujun9972](https://github.com/lujun9972) 译者: [MjSeven](https://github.com/MjSeven) 校对: [wxy](https://github.com/wxy)

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


Bootiso ：让你安全地创建 USB 启动设备

![](/data/attachment/album/201805/22/163121prqrm82zr67vroom.png)

你好，新兵！你们有些人经常使用 `dd` 命令做各种各样的事，比如创建 USB 启动盘或者克隆硬盘分区。不过请牢记，`dd` 是一个危险且有毁灭性的命令。如果你是个 Linux 的新手，最好避免使用 `dd` 命令。如果你不知道你在做什么，你可能会在几分钟里把硬盘擦掉。从原理上说，`dd` 只是从 `if` 读取然后写到 `of` 上。它才不管往哪里写呢。它根本不关心那里是否有分区表、引导区、家目录或是其他重要的东西。你叫它做什么它就做什么。可以使用像 [Etcher](https://www.ostechnix.com/etcher-beauitiful-app-create-bootable-sd-cards-usb-drives/) 这样的用户友好的应用来代替它。这样你就可以在创建 USB 引导设备之前知道你将要格式化的是哪块盘。

今天，我发现了另一个可以安全创建 USB 引导设备的工具 Bootiso 。它实际上是一个 BASH 脚本，但真的很智能！它有很多额外的功能来帮我们安全创建 USB 引导盘。如果你想确保你的目标是 USB 设备（而不是内部驱动器），或者如果你想检测 USB 设备，你可以使用 Bootiso。下面是使用此脚本的显著优点:

* 如果只有一个 USB 驱动器，Bootiso 会自动选择它。
* 如果有一个以上的 USB 驱动器存在，它可以让你从列表中选择其中一个。
* 万一你错误地选择一个内部硬盘驱动器，它将退出而不做任何事情。
* 它检查选定的 ISO 是否具有正确的 MIME 类型。如果 MIME 类型不正确，它将退出。
* 它判定所选的项目不是分区，如果判定失败则退出。
* 它将在擦除和对 USB 驱动器分区之前提示用户确认。
* 列出可用的 USB 驱动器。
* 安装 syslinux 引导系统 (可选)。
* 自由且开源。

### 使用 Bootiso 安全地创建 USB 驱动器

安装 Bootiso 非常简单。用这个命令下载最新版本：

```
$ curl -L https://rawgit.com/jsamr/bootiso/latest/bootiso -O

```

把下载的文件加到 `$PATH` 目录中，比如 `/usr/local/bin/`。

```
$ sudo cp bootiso /usr/local/bin/

```

最后，添加运行权限：

```
$ sudo chmod +x /usr/local/bin/bootiso

```

搞定！现在就可以创建 USB 引导设备了。首先，让我们用命令看看现在有哪些 USB 驱动器：

```
$ bootiso -l

```

输出：

```
Listing USB drives available in your system:
NAME HOTPLUG SIZE STATE TYPE
sdb 1 7.5G running disk

```

如你所见，我只有一个 USB 驱动器。让我们继续通过命令用 ISO 文件创建 USB 启动盘：

```
$ bootiso bionic-desktop-amd64.iso

```

这个命令会提示你输入 `sudo` 密码。输入密码并回车来安装缺失的组件（如果有的话），然后创建 USB 启动盘。

输出：

```
[...]
Listing USB drives available in your system:
NAME HOTPLUG SIZE STATE TYPE
sdb 1 7.5G running disk
Autoselecting `sdb' (only USB device candidate)
The selected device `/dev/sdb' is connected through USB.
Created ISO mount point at `/tmp/iso.c5m'
`bootiso' is about to wipe out the content of device `/dev/sdb'.
Are you sure you want to proceed? (y/n)>y
Erasing contents of /dev/sdb...
Creating FAT32 partition on `/dev/sdb1'...
Created USB device mount point at `/tmp/usb.QgV'
Copying files from ISO to USB device with `rsync'
Synchronizing writes on device `/dev/sdb'
`bootiso' took 303 seconds to write ISO to USB device with `rsync' method.
ISO succesfully unmounted.
USB device succesfully unmounted.
USB device succesfully ejected.
You can safely remove it !

```

如果你的 ISO 文件 MIME 类型不对，你会得到下列错误信息：

```
Provided file `bionic-desktop-amd64.iso' doesn't seem to be an iso file (wrong mime type: `application/octet-stream').
Exiting bootiso...

```

当然，你也能像下面那样使用 `–no-mime-check` 选项来跳过 MIME 类型检查。

```
$ bootiso --no-mime-check bionic-desktop-amd64.iso

```

就像我前面提到的，如果系统里只有 1 个 USB 设备 Bootiso 将自动选中它。所以我们不需要告诉它 USB 设备路径。如果你连接了多个设备，你可以像下面这样使用 `-d` 来指明 USB 设备。

```
$ bootiso -d /dev/sdb bionic-desktop-amd64.iso

```

用你自己的设备路径来换掉 `/dev/sdb`。

在多个设备情况下，如果你没有使用 `-d` 来指明要使用的设备，Bootiso 会提示你选择可用的 USB 设备。

Bootiso 在擦除和改写 USB 盘分区前会要求用户确认。使用 `-y` 或 `–assume-yes` 选项可以跳过这一步。

```
$ bootiso -y bionic-desktop-amd64.iso

```

您也可以把自动选择 USB 设备与 `-y` 选项连用，如下所示。

```
$ bootiso -y -a bionic-desktop-amd64.iso

```

或者，

```
$ bootiso?--assume-yes?--autoselect bionic-desktop-amd64.iso

```

请记住，当你只连接一个 USB 驱动器时，它才会起作用。

Bootiso 会默认创建一个 FAT 32 分区，挂载后用 `rsync` 程序把 ISO 的内容拷贝到 USB 盘里。 如果你愿意也可以使用 `dd` 代替 `rsync` 。

```
$ bootiso --dd -d /dev/sdb bionic-desktop-amd64.iso

```

如果你想增加 USB 引导的成功概率，请使用 `-b` 或 `–bootloader` 选项。

```
$ bootiso -b bionic-desktop-amd64.iso

```

上面这条命令会安装 `syslinux` 引导程序（安全模式）。注意，此时 `–dd` 选项不可用。

在创建引导设备后，Bootiso 会自动弹出 USB 设备。如果不想自动弹出，请使用 `-J` 或 `–no-eject` 选项。

```
$ bootiso -J bionic-desktop-amd64.iso

```

现在，USB 设备依然连接中。你可以使用 `umount` 命令随时卸载它。

需要完整帮助信息，请输入：

```
$ bootiso -h

```

好，今天就到这里。希望这个脚本对你有帮助。好货不断，不要走开哦！

---

via: <https://www.ostechnix.com/bootiso-lets-you-safely-create-bootable-usb-drive/>

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

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


为什么建设一个社区值得额外的努力

>
> 建立 NethServer 社区是有风险的。但是我们从这些激情的人们所带来的力量当中学习到了很多。
>
>
>

![](/data/attachment/album/201805/22/171454x5jfnf8rggfsrgzo.png)

当我们在 2003 年推出 [Nethesis](http://www.nethesis.it/) 时，我们还只是系统集成商。我们只使用已有的开源项目。我们的业务模式非常明确：为这些项目增加多种形式的价值：实践知识、针对意大利市场的文档、额外模块、专业支持和培训课程。我们还通过向上游贡献代码并参与其社区来回馈上游项目。

那时时代不同。我们不能太张扬地使用“开源”这个词。人们将它与诸如“书呆子”，“没有价值”以及最糟糕的“免费”这些词联系起来。这些不太适合生意。

在 2010 年的一个星期六，Nethesis 的工作人员，他们手中拿着馅饼和浓咖啡，正在讨论如何推进事情发展（嘿，我们喜欢在创新的同时吃喝东西！）。尽管势头对我们不利，但我们决定不改变方向。事实上，我们决定加大力度 —— 去做开源和开放的工作方式，这是一个成功运营企业的模式。

多年来，我们已经证明了该模型的潜力。有一件事是我们成功的关键：社区。

在这个由三部分组成的系列文章中，我将解释社区在开放组织的存在中扮演的重要角色。我将探讨为什么一个组织希望建立一个社区，并讨论如何建立一个社区 —— 因为我确实认为这是如今产生新创新的最佳方式。

### 这个疯狂的想法

与 Nethesis 伙伴一起，我们决定构建自己的开源项目：我们自己的操作系统，它建立在 CentOS 之上（因为我们不想重新发明轮子）。我们假设我们拥有实现它的经验、实践知识和人力。我们感到很勇敢。

我们非常希望构建一个名为 [NethServer](http://www.nethserver.org/) 的操作系统，其使命是：通过开源使系统管理员的生活更轻松。我们知道我们可以为服务器创建一个 Linux 发行版，与当前已有的相比，它更容易使用、更易于部署，并且更易于理解。

不过，最重要的是，我们决定创建一个真正的，100％ 开放的项目，其主要规则有三条：

* 完全免费下载
* 开发公开
* 社区驱动

最后一个很重要。我们是一家公司。我们能够自己开发它。如果我们在内部完成这项工作，我们将会更有效（并且做出更快的决定）。与其他任何意大利公司一样，这将非常简单。

但是我们已经如此深入到开源文化中，所以我们选择了不同的路径。

我们确实希望有尽可能多的人围绕着我们、围绕着产品、围绕着公司周围。我们希望对工作有尽可能多的视角。我们意识到：独自一人，你可以走得快 —— 但是如果你想走很远，你需要一起走。

所以我们决定建立一个社区。

### 下一步是什么？

我们意识到创建社区有很多好处。例如，如果使用产品的人真正参与到项目中，他们将提供反馈和测试用例、编写文档、发现 bug，与其他产品进行比较，建议功能并为开发做出贡献。所有这些都会产生创新，吸引贡献者和客户，并扩展你产品的用户群。

但是很快就出现了这样一个问题：我们如何建立一个社区？我们不知道如何实现这一点。我们参加了很多社区，但我们从未建立过一个社区。

我们擅长编码 —— 而不是人。我们是一家公司，是一个有非常具体优先事项的组织。那么我们如何建立一个社区，并在公司和社区之间建立良好的关系呢？

我们做了你必须做的第一件事：学习。我们从专家、博客和许多书中学到了知识。我们进行了实验。我们失败了多次，从结果中收集数据，并再次进行测试。

最终我们学到了社区管理的黄金法则：**没有社区管理的黄金法则。**

人们太复杂了，社区无法用一条规则来“统治他们”。

然而，我可以说的一件事是，社区和公司之间的健康关系总是一个给予和接受的过程。在我的下一篇文章中，我将讨论你的组织如果想要一个蓬勃发展和创新的社区，应该期望提供什么。

---

via: <https://opensource.com/open-organization/18/1/why-build-community-1>

作者：[Alessio Fattorini](https://opensource.com/users/alefattorini) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


HeRM's ：一个命令行食谱管理器

Summary: 今天，我介绍 HeRM's，这是一个基于 Haskell 的命令行食谱管理器，能为你的美食食谱做笔记。

![配图](/data/attachment/album/201805/23/084210xvz2ld7a3we3w7wj.jpg)

烹饪让爱变得可见，不是吗？确实！烹饪也许是你的热情或爱好或职业，我相信你会维护一份烹饪日记。保持写烹饪日记是改善烹饪习惯的一种方法。有很多方法可以记录食谱。你可以维护一份小日记/笔记或将配方的笔记存储在智能手机中，或将它们保存在计算机中文档中。这有很多选择。今天，我介绍 **HeRM's**，这是一个基于 Haskell 的命令行食谱管理器，能为你的美食食谱做笔记。使用 Herm's，你可以添加、查看、编辑和删除食物配方，甚至可以制作购物清单。这些全部来自你的终端！它是免费的，是使用 Haskell 语言编写的开源程序。源代码在 GitHub 中免费提供，因此你可以复刻它，添加更多功能或改进它。

### HeRM's - 一个命令食谱管理器

#### 安装 HeRM's

由于它是使用 Haskell 编写的，因此我们需要首先安装 Cabal。 Cabal 是一个用于下载和编译用 Haskell 语言编写的软件的命令行程序。Cabal 存在于大多数 Linux 发行版的核心软件库中，因此你可以使用发行版的默认软件包管理器来安装它。

例如，你可以使用以下命令在 Arch Linux 及其变体（如 Antergos、Manjaro Linux）中安装 cabal：

```
sudo pacman -S cabal-install

```

在 Debian、Ubuntu 上：

```
sudo apt-get install cabal-install

```

安装 Cabal 后，确保你已经添加了 `PATH`。为此，请编辑你的 `~/.bashrc`：

```
vi ~/.bashrc

```

添加下面这行：

```
PATH=$PATH:~/.cabal/bin

```

按 `:wq` 保存并退出文件。然后，运行以下命令更新所做的更改。

```
source ~/.bashrc

```

安装 cabal 后，运行以下命令安装 `herms`：

```
cabal install herms

```

喝一杯咖啡！这将需要一段时间。几分钟后，你会看到一个输出，如下所示。

```
[...]
Linking dist/build/herms/herms ...
Installing executable(s) in /home/sk/.cabal/bin
Installed herms-1.8.1.2

```

恭喜！ Herms 已经安装完成。

#### 添加食谱

让我们添加一个食谱，例如 Dosa。对于那些想知道的，Dosa 是一种受欢迎的南印度食物，配以 sambar（LCTT 译注：扁豆和酸豆炖菜，像咖喱汤） 和**酸辣酱**。这是一种健康的，可以说是最美味的食物。它不含添加的糖或饱和脂肪。制作一个也很容易。有几种不同的 Dosas，在我们家中最常见的是 Plain Dosa。

要添加食谱，请输入：

```
herms add

```

你会看到一个如下所示的屏幕。开始输入食谱的详细信息。

![](/data/attachment/album/201805/23/084213ws2tqr4qyqqty2yt.png)

要变换字段，请使用以下键盘快捷键：

* `Tab` / `Shift+Tab` - 下一个/前一个字段
* `Ctrl + <箭头键>` - 导航字段
* `[Meta 或者 Alt] + <h-j-k-l>` - 导航字段
* `Esc` - 保存或取消。

添加完配方的详细信息后，按下 `ESC` 键并点击 `Y` 保存。同样，你可以根据需要添加尽可能多的食谱。

要列出添加的食谱，输入：

```
herms list

```

![](/data/attachment/album/201805/23/084215eywc49bd6nyssb22.png)

要查看上面列出的任何食谱的详细信息，请使用下面的相应编号。

```
herms view 1

```

![](/data/attachment/album/201805/23/084216tlmkgmkpgk5blvwl.png)

要编辑任何食谱，使用：

```
herms edit 1

```

完成更改后，按下 `ESC` 键。系统会询问你是否要保存。你只需选择适当的选项。

![](/data/attachment/album/201805/23/084218eic6r18kutkkykz2.png)

要删除食谱，命令是：

```
herms remove 1

```

要为指定食谱生成购物清单，运行：

```
herms shopping 1

```

![](/data/attachment/album/201805/23/084221b1nz2hzn3jjvkgeo.png)

要获得帮助，运行：

```
herms -h

```

当你下次听到你的同事、朋友或其他地方谈到好的食谱时，只需打开 Herm's，并快速记下，并将它们分享给你的配偶。她会很高兴！

今天就是这些。还有更好的东西。敬请关注！

干杯！！

---

via: <https://www.ostechnix.com/herms-commandline-food-recipes-manager/>

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

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


程序员的学习之路

*2016 年 10 月，当我从微软离职时，我已经在微软工作了近 21 年，在业界也快 35 年了。我花了一些时间反思我这些年来学到的东西，这些文字是那篇帖子稍加修改后得到。请见谅，文章有一点长。*

![](/data/attachment/album/201805/23/110510l6r65l555zlgc3ld.jpg)

要成为一名专业的程序员，你需要知道的事情多得令人吃惊：语言的细节、API、算法、数据结构、系统和工具。这些东西一直在随着时间变化——新的语言和编程环境不断出现，似乎总有一些“每个人”都在使用的热门的新工具或新语言。紧跟潮流，保持专业，这很重要。木匠需要知道如何为工作选择合适的锤子和钉子，并且要有能力笔直精准地钉入钉子。

与此同时，我也发现有一些理论和方法有着广泛的应用场景，它们能使用几十年。底层设备的性能和容量在这几十年来增长了几个数量级，但系统设计的思考方式还是互相有关联的，这些思考方式比具体的实现更根本。理解这些重复出现的主题对分析与设计我们所负责的系统大有帮助。

### 谦卑和自我

这不仅仅局限于编程，但在编程这个持续发展的领域，一个人需要在谦卑和自我中保持平衡。总有新的东西需要学习，并且总有人能帮助你学习——如果你愿意学习的话。一个人即需要保持谦卑，认识到自己不懂并承认它，也要保持自我，相信自己能掌握一个新的领域，并且能运用你已经掌握的知识。我见过的最大的挑战就是一些人在某个领域深入专研了很长时间，“忘记”了自己擅长学习新的东西。最好的学习来自放手去做，建造一些东西，即便只是一个原型或者 hack。我知道的最好的程序员对技术有广泛的认识，但同时他们对某个技术深入研究，成为了专家。而深入的学习来自努力解决真正困难的问题。

### 端到端观点

1981 年，Jerry Saltzer、 Dave Reed 和 Dave Clark 在做因特网和分布式系统的早期工作，他们提出了<ruby> 端到端 <rt>  end to end </rt></ruby>观点，并作出了[经典的阐述](http://web.mit.edu/Saltzer/www/publications/endtoend/endtoend.pdf)。网络上的文章有许多误传，所以更应该阅读论文本身。论文的作者很谦虚，没有声称这是他们自己的创造——从他们的角度看，这只是一个常见的工程策略，不只在通讯领域中，在其他领域中也有运用。他们只是将其写下来并收集了一些例子。下面是文章的一个小片段：

>
> 当我们设计系统的一个功能时，仅依靠端点的知识和端点的参与，就能正确地完整地实现这个功能。在一些情况下，系统的内部模块局部实现这个功能，可能会对性能有重要的提升。
>
>
>

该论文称这是一个“观点”，虽然在维基百科和其他地方它已经被上升成“原则”。实际上，还是把它看作一个观点比较好，正如作者们所说，系统设计者面临的最难的问题之一就是如何在系统组件之间划分责任，这会引发不断的讨论：怎样在划分功能时权衡利弊，怎样隔离复杂性，怎样设计一个灵活的高性能系统来满足不断变化的需求。没有简单的原则可以直接遵循。

互联网上的大部分讨论集中在通信系统上，但端到端观点的适用范围其实更广泛。分布式系统中的“<ruby> 最终一致性 <rt>  eventual consistency </rt></ruby>”就是一个例子。一个满足“最终一致性”的系统，可以让系统中的元素暂时进入不一致的状态，从而简化系统，优化性能，因为有一个更大的端到端过程来解决不一致的状态。我喜欢横向拓展的订购系统的例子（例如亚马逊），它不要求每个请求都通过中央库存的控制点。缺少中央控制点可能允许两个终端出售相同的最后一本书，所以系统需要用某种方法来解决这个问题，如通知客户该书会延期交货。不论怎样设计，想购买的最后一本书在订单完成前都有可能被仓库中的叉车运出厍（LCTT 译注：比如被其他人下单购买）。一旦你意识到你需要一个端到端的解决方案，并实现了这个方案，那系统内部的设计就可以被优化以利用这个解决方案。

事实上，这种设计上的灵活性可以优化系统的性能，或者提供其他的系统功能，从而使得端到端的方法变得如此强大。端到端的思考往往允许内部进行灵活的操作，使整个系统更加健壮，并且能适应每个组件特性的变化。这些都让端到端的方法变得健壮，并能适应变化。

端到端方法意味着，添加会牺牲整体性能灵活性的抽象层和功能时要非常小心（也可能是其他的灵活性，但性能，特别是延迟，往往是特殊的）。如果你展示出底层的原始性能（LCTT 译注：performance，也可能指操作，下同），端到端的方法可以根据这个性能（操作）来优化，实现特定的需求。如果你破坏了底层性能（操作），即使你实现了重要的有附加价值的功能，你也牺牲了设计灵活性。

如果系统足够庞大而且足够复杂，需要把整个开发团队分配给系统内部的组件，那么端到端观点可以和团队组织相结合。这些团队自然要扩展这些组件的功能，他们通常从牺牲设计上的灵活性开始，尝试在组件上实现端到端的功能。

应用端到端方法面临的挑战之一是确定端点在哪里。 俗话说，“大跳蚤上有小跳蚤，小跳蚤上有更少的跳蚤……等等”。

### 关注复杂性

编程是一门精确的艺术，每一行代码都要确保程序的正确执行。但这是带有误导的。编程的复杂性不在于各个部分的整合，也不在于各个部分之间如何相互交互。最健壮的程序会将复杂性隔离开，让最重要的部分变的简单直接，通过简单的方式与其他部分交互。虽然隐藏复杂性和信息隐藏、数据抽象等其他设计方法一样，但我仍然觉得，如果你真的要定位出系统的复杂所在，并将其隔离开，那你需要对设计特别敏锐。

在我的[文章](https://medium.com/@terrycrowley/model-view-controller-and-loose-coupling-6370f76e9cde#.o4gnupqzq)中反复提到的例子是早期的终端编辑器 VI 和 Emacs 中使用的屏幕重绘算法。早期的视频终端实现了控制序列，来控制绘制字符核心操作，也实现了附加的显示功能，来优化重新绘制屏幕，如向上向下滚动当前行，或者插入新行，或在当前行中移动字符。这些命令都具有不同的开销，并且这些开销在不同制造商的设备中也是不同的。（参见[TERMCAP](https://en.wikipedia.org/wiki/Termcap) 以获取代码和更完整的历史记录的链接。）像文本编辑器这样的全屏应用程序希望尽快更新屏幕，因此需要优化使用这些控制序列来从一个状态到另一个状态屏幕转换。

这些程序在设计上隐藏了底层的复杂性。系统中修改文本缓冲区的部分（功能上大多数创新都在这里）完全忽略了这些改变如何被转换成屏幕更新命令。这是可以接受的，因为针对*任何*内容的改变计算最佳命令所消耗的性能代价，远不及被终端本身实际执行这些更新命令的性能代价。在确定如何隐藏复杂性，以及隐藏哪些复杂性时，性能分析扮演着重要的角色，这一点在系统设计中非常常见。屏幕的更新与底层文本缓冲区的更改是异步的，并且可以独立于缓冲区的实际历史变化顺序。缓冲区是*怎样*改变的并不重要，重要的是改变了*什么*。异步耦合，在组件交互时消除组件对历史路径依赖的组合，以及用自然的交互方式以有效地将组件组合在一起是隐藏耦合复杂度的常见特征。

隐藏复杂性的成功不是由隐藏复杂性的组件决定的，而是由使用该模块的使用者决定的。这就是为什么组件的提供者至少要为组件的某些端到端过程负责。他们需要清晰的知道系统的其他部分如何与组件相互作用，复杂性是如何泄漏出来的（以及是否泄漏出来）。这常常表现为“这个组件很难使用”这样的反馈——这通常意味着它不能有效地隐藏内部复杂性，或者没有选择一个隐藏复杂性的功能边界。

### 分层与组件化

系统设计人员的一个基本工作是确定如何将系统分解成组件和层；决定自己要开发什么，以及从别的地方获取什么。开源项目在决定自己开发组件还是购买服务时，大多会选择自己开发，但组件之间交互的过程是一样的。在大规模工程中，理解这些决策将如何随着时间的推移而发挥作用是非常重要的。从根本上说，变化是程序员所做的一切的基础，所以这些设计决定不仅要在当下评估，还要随着产品的不断发展而在未来几年得到评估。

以下是关于系统分解的一些事情，它们最终会占用大量的时间，因此往往需要更长的时间来学习和欣赏。

* **层泄漏。**层（或抽象）[基本上是泄漏的](https://medium.com/@terrycrowley/leaky-by-design-7b423142ece0#.x67udeg0a)。这些泄漏会立即产生后果，也会随着时间的推移而产生两方面的后果。其中一方面就是该抽象层的特性渗透到了系统的其他部分，渗透的程度比你意识到得更深入。这些渗透可能是关于具体的性能特征的假设，以及抽象层的文档中没有明确的指出的行为发生的顺序。这意味着假如内部组件的行为发生变化，你的系统会比想象中更加脆弱。第二方面是你比表面上看起来更依赖组件内部的行为，所以如果你考虑改变这个抽象层，后果和挑战可能超出你的想象。
* **层具有太多功能。**您所采用的组件具有比实际需要更多的功能，这几乎是一个真理。在某些情况下，你决定采用这个组件是因为你想在将来使用那些尚未用到的功能。有时，你采用组件是想“上快车”，利用组件完成正在进行的工作。在功能强大的抽象层上开发会带来一些后果。
	1. 组件往往会根据你并不需要的功能作出取舍。
	2. 为了实现那些你并不没有用到的功能，组件引入了复杂性和约束，这些约束将阻碍该组件的未来的演变。
	3. 层泄漏的范围更大。一些泄漏是由于真正的“抽象泄漏”，另一些是由于明显的，逐渐增加的对组件全部功能的依赖（但这些依赖通常都没有处理好）。Office 软件太大了，我们发现，对于我们建立的任何抽象层，我们最终都在系统的某个部分完全运用了它的功能。虽然这看起来是积极的（我们完全地利用了这个组件），但并不是所用的使用都有同样的价值。所以，我们最终要付出巨大的代价才能从一个抽象层往另一个抽象层迁移，这种“长尾”没什么价值，并且对使用场景认识不足。
	4. 附加的功能会增加复杂性，并增加功能滥用的可能。如果将验证 XML 的 API 指定为 XML 树的一部分，那这个 API 可以选择动态下载 XML 的模式定义。这在我们的基本文件解析代码中被错误地执行，导致 w3c.org 服务器上的大量性能下降以及（无意）分布式拒绝服务攻击。（这些被通俗地称为“地雷”API）。
* **抽象层被更换。**需求在进化，系统在进化，组件被放弃。您最终需要更换该抽象层或组件。不管是对外部组件的依赖还是对内部组件的依赖都是如此。这意味着上述问题将变得重要起来。
* **自己构建还是购买的决定将会改变。**这是上面几方面的必然结果。这并不意味着自己构建还是购买的决定在当时是错误的。一开始时往往没有合适的组件，一段时间之后才有合适的组件出现。或者，也可能你使用了一个组件，但最终发现它不符合您不断变化的要求，而且你的要求非常窄、很好理解，或者对你的价值体系来说是非常重要的，以至于拥有自己的模块是有意义的。这意味着你像关心自己构造的模块一样，关心购买的模块，关心它们是怎样泄漏并深入你的系统中的。
* **抽象层会变臃肿。**一旦你定义了一个抽象层，它就开始增加功能。层是对使用模式优化的自然分界点。臃肿的层的困难在于，它往往会降低您利用底层的不断创新的能力。从某种意义上说，这就是操作系统公司憎恨构建在其核心功能之上的臃肿的层的原因——采用创新的速度放缓了。避免这种情况的一种比较规矩的方法是禁止在适配器层中进行任何额外的状态存储。微软基础类在 Win32 上采用这个一般方法。在短期内，将功能集成到现有层（最终会导致上述所有问题）而不是重构和重新推导是不可避免的。理解这一点的系统设计人员寻找分解和简化组件的方法，而不是在其中增加越来越多的功能。

### 爱因斯坦宇宙

几十年来，我一直在设计异步分布式系统，但是在微软内部的一次演讲中，SQL 架构师 Pat Helland 的一句话震惊了我。 “我们生活在爱因斯坦的宇宙中，没有同时性这种东西。”在构建分布式系统时（基本上我们构建的都是分布式系统），你无法隐藏系统的分布式特性。这是物理的。我一直感到远程过程调用在根本上错误的，这是一个原因，尤其是那些“透明的”远程过程调用，它们就是想隐藏分布式的交互本质。你需要拥抱系统的分布式特性，因为这些意义几乎总是需要通过系统设计和用户体验来完成。

拥抱分布式系统的本质则要遵循以下几个方面：

* 一开始就要思考设计对用户体验的影响，而不是试图在处理错误，取消请求和报告状态上打补丁。
* 使用异步技术来耦合组件。同步耦合是*不可能*的。如果某些行为看起来是同步的，是因为某些内部层尝试隐藏异步，这样做会遮蔽（但绝对不隐藏）系统运行时的基本行为特征。
* 认识到并且明确设计了交互状态机，这些状态表示长期的可靠的内部系统状态（而不是由深度调用堆栈中的变量值编码的临时，短暂和不可发现的状态）。
* 认识到失败是在所难免的。要保证能检测出分布式系统中的失败，唯一的办法就是直接看你的等待时间是否“太长”。这自然意味着[取消的等级最高](https://medium.com/@terrycrowley/how-to-think-about-cancellation-3516fc342ae#.3pfjc5b54)。系统的某一层（可能直接通向用户）需要决定等待时间是否过长，并取消操作。取消只是为了重建局部状态，回收局部的资源——没有办法在系统内广泛使用取消机制。有时用一种低成本，不可靠的方法广泛使用取消机制对优化性能可能有用。
* 认识到取消不是回滚，因为它只是回收本地资源和状态。如果回滚是必要的，它必须实现成一个端到端的功能。
* 承认永远不会真正知道分布式组件的状态。只要你发现一个状态，它可能就已经改变了。当你发送一个操作时，请求可能在传输过程中丢失，也可能被处理了但是返回的响应丢失了，或者请求需要一定的时间来处理，这样远程状态最终会在未来的某个任意的时间转换。这需要像幂等操作这样的方法，并且要能够稳健有效地重新发现远程状态，而不是期望可靠地跟踪分布式组件的状态。“[最终一致性](http://queue.acm.org/detail.cfm?id=2462076)”的概念简洁地捕捉了这其中大多数想法。

我喜欢说你应该“陶醉在异步”。与其试图隐藏异步，不如接受异步，为异步而设计。当你看到像幂等性或不变性这样的技术时，你就认识到它们是拥抱宇宙本质的方法，而不仅仅是工具箱中的一个设计工具。

### 性能

我确信 Don Knuth 会对人们怎样误解他的名言“过早的优化是一切罪恶的根源”而感到震惊。事实上，性能，及性能的持续超过 60 年的指数增长（或超过 10 年，取决于您是否愿意将晶体管，真空管和机电继电器的发展算入其中），为所有行业内的惊人创新和影响经济的“软件吃掉全世界”的变化打下了基础。

要认识到这种指数变化的一个关键是，虽然系统的所有组件正在经历指数级变化，但这些指数是不同的。硬盘容量的增长速度与内存容量的增长速度不同，与 CPU 的增长速度不同，与内存 CPU 之间的延迟的性能改善速度也不用。即使性能发展的趋势是由相同的基础技术驱动的，增长的指数也会有分歧。[延迟的改进跟不上带宽改善](http://www.ll.mit.edu/HPEC/agendas/proc04/invited/patterson_keynote.pdf)。指数变化在近距离或者短期内看起来是线性的，但随着时间的推移可能是压倒性的。系统不同组件的性能的增长不同，会出现压倒性的变化，并迫使对设计决策定期进行重新评估。

这样做的结果是，几年后，一度有意义的设计决策就不再有意义了。或者在某些情况下，二十年前有意义的方法又开始变成一个好的决策。现代内存映射的特点看起来更像是早期分时的进程切换，而不像分页那样。 （这样做有时会让我这样的老人说“这就是我们在 1975 年时用的方法”——忽略了这种方法在 40 年都没有意义，但现在又重新成为好的方法，因为两个组件之间的关系——可能是闪存和 NAND 而不是磁盘和核心内存——已经变得像以前一样了）。

当这些指数超越人自身的限制时，重要的转变就发生了。你能从 2 的 16 次方个字符（一个人可以在几个小时打这么多字）过渡到 2 的 32 次方个字符（远超出了一个人打字的范围）。你可以捕捉比人眼能感知的分辨率更高的数字图像。或者你可以将整个音乐专辑存在小巧的磁盘上，放在口袋里。或者你可以将数字化视频录制存储在硬盘上。再通过实时流式传输的能力，可以在一个地方集中存储一次，不需要在数千个本地硬盘上重复记录。

但有的东西仍然是根本的限制条件，那就是空间的三维和光速。我们又回到了爱因斯坦的宇宙。内存的分级结构将始终存在——它是物理定律的基础。稳定的存储和 IO、内存、计算和通信也都将一直存在。这些模块的相对容量，延迟和带宽将会改变，但是系统始终要考虑这些元素如何组合在一起，以及它们之间的平衡和折衷。Jim Gary 是这方面的大师。

空间和光速的根本限制造成的另一个后果是，性能分析主要是关于三件事：<ruby> 局部化 <rt>  locality </rt></ruby>、<ruby> 局部化 <rt>  locality </rt></ruby>、<ruby> 局部化 <rt>  locality </rt></ruby>。无论是将数据打包在磁盘上，管理处理器缓存的层次结构，还是将数据合并到通信数据包中，数据如何打包在一起，如何在一段时间内从局部获取数据，数据如何在组件之间传输数据是性能的基础。把重点放在减少管理数据的代码上，增加空间和时间上的局部性，是消除噪声的好办法。

Jon Devaan 曾经说过：“设计数据，而不是设计代码”。这也通常意味着当查看系统结构时，我不太关心代码如何交互——我想看看数据如何交互和流动。如果有人试图通过描述代码结构来解释一个系统，而不理解数据流的速率和数量，他们就不了解这个系统。

内存的层级结构也意味着缓存将会一直存在——即使某些系统层正在试图隐藏它。缓存是根本的，但也是危险的。缓存试图利用代码的运行时行为，来改变系统中不同组件之间的交互模式。它们需要对运行时行为进行建模，即使模型填充缓存并使缓存失效，并测试缓存命中。如果模型由于行为改变而变差或变得不佳，缓存将无法按预期运行。一个简单的指导方针是，缓存必须被检测——由于应用程序行为的改变，事物不断变化的性质和组件之间性能的平衡，缓存的行为将随着时间的推移而退化。每一个老程序员都有缓存变糟的经历。

我很幸运，我的早期职业生涯是在互联网的发源地之一 BBN 度过的。 我们很自然地将将异步组件之间的通信视为系统连接的自然方式。流量控制和队列理论是通信系统的基础，更是任何异步系统运行的方式。流量控制本质上是资源管理（管理通道的容量），但资源管理是更根本的关注点。流量控制本质上也应该由端到端的应用负责，所以用端到端的方式思考异步系统是自然的。[缓冲区膨胀](https://en.wikipedia.org/wiki/Bufferbloat)的故事在这种情况下值得研究，因为它展示了当对端到端行为的动态性以及技术“改进”（路由器中更大的缓冲区）缺乏理解时，在整个网络基础设施中导致的长久的问题。

我发现“<ruby> 光速 <rt>  light speed </rt></ruby>”的概念在分析任何系统时都非常有用。光速分析并不是从当前的性能开始分析，而是问“这个设计理论上能达到的最佳性能是多少？”真正传递的信息是什么，以什么样的速度变化？组件之间的底层延迟和带宽是多少？光速分析迫使设计师深入思考他们的方法能否达到性能目标，或者否需要重新考虑设计的基本方法。它也迫使人们更深入地了解性能在哪里损耗，以及损耗是由固有的，还是由于一些不当行为产生的。从构建的角度来看，它迫使系统设计人员了解其构建的模块的真实性能特征，而不是关注其他功能特性。

我的职业生涯大多花费在构建图形应用程序上。用户坐在系统的一端，定义关键的常量和约束。人类的视觉和神经系统没有经历过指数性的变化。它们固有地受到限制，这意味着系统设计者可以利用（必须利用）这些限制，例如，通过虚拟化（限制底层数据模型需要映射到视图数据结构中的数量），或者通过将屏幕更新的速率限制到人类视觉系统的感知限制。

### 复杂性的本质

我的整个职业生涯都在与复杂性做斗争。为什么系统和应用变得复杂呢？为什么在一个应用领域内进行开发并没有随着时间变得简单，而基础设施却没有变得更复杂，反而变得更强大了？事实上，管理复杂性的一个关键方法就是“走开”然后重新开始。通常新的工具或语言迫使我们从头开始，这意味着开发人员将工具的优点与从新开始的优点结合起来。从新开始是重要的。这并不是说新工具，新平台，或新语言可能不好，但我保证它们不能解决复杂性增长的问题。控制复杂性的最简单的方法就是用更少的程序员，建立一个更小的系统。

当然，很多情况下“走开”并不是一个选择——Office 软件建立在有巨大的价值的复杂的资源上。通过 OneNote， Office 从 Word 的复杂性上“走开”，从而在另一个维度上进行创新。Sway 是另一个例子， Office 决定从限制中跳出来，利用关键的环境变化，抓住机会从底层上采取全新的设计方案。我们有 Word、Excel、PowerPoint 这些应用，它们的数据结构非常有价值，我们并不能完全放弃这些数据结构，它们成为了开发中持续的显著的限制条件。

我受到 Fred Brook 讨论软件开发中的意外和本质的文章[《没有银弹》](http://worrydream.com/refs/Brooks-NoSilverBullet.pdf)的影响，他希望用两个趋势来尽可能地推动程序员的生产力：一是在选择自己开发还是购买时，更多地关注购买——这预示了开源社区和云架构的改变；二是从单纯的构建方法转型到更“有机”或者“生态”的增量开发方法。现代的读者可以认为是向敏捷开发和持续开发的转型。但那篇文章可是写于 1986 年！

我很欣赏 Stuart Kauffman 的在复杂性的基本性上的研究工作。Kauffman 从一个简单的布尔网络模型（“[NK 模型](https://en.wikipedia.org/wiki/NK_model)”）开始建立起来，然后探索这个基本的数学结构在相互作用的分子，基因网络，生态系统，经济系统，计算机系统（以有限的方式）等系统中的应用，来理解紧急有序行为的数学基础及其与混沌行为的关系。在一个高度连接的系统中，你固有地有一个相互冲突的约束系统，使得它（在数学上）很难向前发展（这被看作是在崎岖景观上的优化问题）。控制这种复杂性的基本方法是将系统分成独立元素并限制元素之间的相互连接（实质上减少 NK 模型中的“N”和“K”）。当然对那些使用复杂隐藏，信息隐藏和数据抽象，并且使用松散异步耦合来限制组件之间的交互的技术的系统设计者来说，这是很自然的。

我们一直面临的一个挑战是，我们想到的许多拓展系统的方法，都跨越了所有的方面。实时共同编辑是 Office 应用程序最近的一个非常具体的（也是最复杂的）例子。

我们的数据模型的复杂性往往等同于“能力”。设计用户体验的固有挑战是我们需要将有限的一组手势，映射到底层数据模型状态空间的转换。增加状态空间的维度不可避免地在用户手势中产生模糊性。这是“[纯数学](https://medium.com/@terrycrowley/the-math-of-easy-to-use-14645f819201#.untmk9eq7)”，这意味着确保系统保持“易于使用”的最基本的方式常常是约束底层的数据模型。

### 管理

我从高中开始担任一些领导角色（学生会主席！），对承担更多的责任感到理所当然。同时，我一直为自己在每个管理阶段都坚持担任全职程序员而感到自豪。但 Office 软件的开发副总裁最终还是让我从事管理，离开了日常的编程工作。当我在去年离开那份工作时，我很享受重返编程——这是一个出奇地充满创造力的充实的活动（当修完“最后”的 bug 时，也许也会有一点令人沮丧）。

尽管在我加入微软前已经做了十多年的“主管”，但是到了 1996 年我加入微软才真正了解到管理。微软强调“工程领导是技术领导”。这与我的观点一致，帮助我接受并承担更大的管理责任。

主管的工作是设计项目并透明地推进项目。透明并不简单，它不是自动的，也不仅仅是有好的意愿就行。透明需要被设计进系统中去。透明工作的最好方式是能够记录每个工程师每天活动的产出，以此来追踪项目进度（完成任务，发现 bug 并修复，完成一个情景）。留意主观上的红/绿/黄，点赞或踩的仪表板。

我过去说我的工作是设计反馈回路。独立工程师，经理，行政人员，每一个项目的参与者都能通过分析记录的项目数据，推进项目，产出结果，了解自己在整个项目中扮演的角色。最终，透明化最终成为增强能力的一个很好的工具——管理者可以将更多的局部控制权给予那些最接近问题的人，因为他们对所取得的进展有信心。这样的话，合作自然就会出现。

关键需要确定目标框架（包括关键资源的约束，如发布的时间表）。如果决策需要在管理链上下不断流动，那说明管理层对目标和约束的框架不好。

当我在 Beyond Software 工作时，我真正理解了一个项目拥有一个唯一领导的重要性。原来的项目经理离职了（后来从 FrontPage 团队雇佣了我）。我们四个主管在是否接任这个岗位上都有所犹豫，这不仅仅由于我们都不知道要在这家公司坚持多久。我们都技术高超，并且相处融洽，所以我们决定以同级的身份一起来领导这个项目。然而这槽糕透了。有一个显而易见的问题，我们没有相应的战略用来在原有的组织之间分配资源——这应当是管理者的首要职责之一！当你知道你是唯一的负责人时，你会有很深的责任感，但在这个例子中，这种责任感缺失了。我们没有真正的领导来负责统一目标和界定约束。

我有清晰地记得，我第一次充分认识到*倾听*对一个领导者的重要性。那时我刚刚担任了 Word、OneNote、Publisher 和 Text Services 团队的开发经理。关于我们如何组织文本服务团队，我们有一个很大的争议，我走到了每个关键参与者身边，听他们想说的话，然后整合起来，写下了我所听到的一切。当我向其中一位主要参与者展示我写下的东西时，他的反应是“哇，你真的听了我想说的话”！作为一名管理人员，我所经历的所有最大的问题（例如，跨平台和转型持续工程）涉及到仔细倾听所有的参与者。倾听是一个积极的过程，它包括：尝试以别人的角度去理解，然后写出我学到的东西，并对其进行测试，以验证我的理解。当一个关键的艰难决定需要发生的时候，在最终决定前，每个人都知道他们的想法都已经被听到并理解（不论他们是否同意最后的决定）。

在 FrontPage 团队担任开发经理的工作，让我理解了在只有部分信息的情况下做决定的“操作困境”。你等待的时间越长，你就会有更多的信息做出决定。但是等待的时间越长，实际执行的灵活性就越低。在某个时候，你仅需要做出决定。

设计一个组织涉及类似的两难情形。您希望增加资源领域，以便可以在更大的一组资源上应用一致的优先级划分框架。但资源领域越大，越难获得作出决定所需要的所有信息。组织设计就是要平衡这两个因素。软件复杂化，因为软件的特点可以在任意维度切入设计。Office 软件部门已经使用[共享团队](https://medium.com/@terrycrowley/breaking-conways-law-a0fdf8500413#.gqaqf1c5k)来解决这两个问题（优先次序和资源），让跨领域的团队能与需要产品的团队分享工作（增加资源）。

随着管理阶梯的提升，你会懂一个小秘密：你和你的新同事不会因为你现在承担更多的责任，就突然变得更聪明。这强调了整个组织比顶层领导者更聪明。赋予每个级别在一致框架下拥有自己的决定是实现这一目标的关键方法。听取并使自己对组织负责，阐明和解释决策背后的原因是另一个关键策略。令人惊讶的是，害怕做出一个愚蠢的决定可能是一个有用的激励因素，以确保你清楚地阐明你的推理，并确保你听取所有的信息。

### 结语

我离开大学寻找第一份工作时，面试官在最后一轮面试时问我对做“系统”和做“应用”哪一个更感兴趣。我当时并没有真正理解这个问题。在软件技术栈的每一个层面都会有趣的难题，我很高兴深入研究这些问题。保持学习。

---

via: <https://hackernoon.com/education-of-a-programmer-aaecf2d35312>

作者：[Terry Crowley](https://hackernoon.com/@terrycrowley) 译者：[explosic4](https://github.com/explosic4) 校对：[wxy](https://github.com/wxy)

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


开始 Vagrant 之旅

Summary: 用管理虚拟机和容器的工具 Vagrant 清理你的开发环境和依赖。

用管理虚拟机和容器的工具 Vagrant 清理你的开发环境和依赖。

>
> 用管理虚拟机和容器的工具 Vagrant 清理你的开发环境和依赖。
>
>
>

![](/data/attachment/album/201805/23/114315cw6iy7ak7yikb9w9.jpg)

如果你和我一样，你可能在某一个地方有一个“沙盒”，你可以在那里进行你正在做的任何项目。随着时间的推移，沙盒会变得杂乱无章，充斥着各种想法、工具链元素、你不使用的代码模块，以及其他你不需要的东西。当你完成某件事情时，这会使你的部署变得复杂，因为你可能不确定项目的实际依赖关系 —— 随着时间推移你在沙盒中已经有了一些工具，但是你忘了必须安装它。你需要一个干净的环境，将所有的依赖关系放在一个地方，以便以后更方便。

或者你可能工作在 DevOps 中，你所服务的开发人员用模糊的依赖关系来编写代码，这使得测试变得更加困难。你需要一种方法来获得一个干净的盒子，将代码放入其中，并通过它运行代码，而且你希望这些环境是一次性的和可重复的。

那么选择 [Vagrant](https://vagrantup.com) 吧。由 HashiCorp 在 [MIT 许可证](https://opensource.org/licenses/MIT)下创建，Vagrant 可充当 VirtualBox、Microsoft Hyper-V 或 Docker 容器的包装器和前端，并且可以通过[许多其他供应商](https://github.com/hashicorp/vagrant/wiki/Available-Vagrant-Plugins#providers)的插件进行扩展。你可以配置 Vagrant 以提供可重复的、干净的环境，并且已安装需要的基础架构。配置脚本是可移植的，因此，如果你的仓库和 Vagrant 配置脚本位于基于云存储上，那么你只需要很少的限制就可以启动并在多台机器机器上工作。让我们来看一看。

### 安装

对于本次安装，我的环境是 Linux Mint 桌面，版本是 18.3 Cinnamon 64 位，在其他大多数 Debian 派生系统上安装非常类似。在大多数发行版中，对于基于 RPM 的系统也有类似的安装程序。Vagrant 的[安装页面](https://www.vagrantup.com/downloads.html)为 Debian、 Windows、 CentOS、 MacOS 和 Arch Linux 都提供下载，但是我在我的软件包管理器中找到了它，所以我在那进行了安装。

最简单的安装使用了 VirtualBox 作为虚拟化提供者，所以我需要安装它：

```
sudo apt-get install virtualbox vagrant

```

安装程序将会获取依赖项 —— 主要是 Ruby 的一些东西，安装它们。

### 建立一个项目

在设置你的项目之前，你需要了解一些你想要运行它的环境。你可以在 [Vagrant Boxes 仓库](https://app.vagrantup.com/boxes/search)中找到为许多虚拟化供应商提供的大量预配置的<ruby> 系统 <rt>  box </rt></ruby>。许多会预先配置一些你可能需要的核心基础设置，比如 PHP、 MySQL 和 Apache，但是对于本次测试，我将安装一个 Debian 8 64 位 “Jessie” 裸机沙盒并手动安装一些东西，这样你就可以看到具体过程了。

```
mkdir ~/myproject
cd ~/myproject
vagrant init debian/contrib-jessie64
vagrant up

```

最后一条命令将根据需要从仓库中获取或更新 VirtualBox 镜像，然后运行启动器，你的系统上会出现一个运行的系统！下次启动这个项目时，除非镜像已经在仓库中更新，否则不会花费太长时间。

要访问该沙盒，只需要输入 `vagrant ssh`，你将进入虚拟机的全功能 SSH 会话中，你将会是 `vagrant` 用户，但也是 `sudo` 组的成员，所以你可以切换到 root，并在这里做你想做的任何事情。

你会在沙盒中看到一个名为 `/vagrant` 目录，对这个目录小心点，因为它与你主机上的 `~/myproject` 文件夹保持同步。在虚拟机 `/vagrant` 下建立一个文件它会立即复制到主机上，反之亦然。注意，有些沙盒并没有安装 VirtualBox 的附加功能，所以拷贝只能在启动时才起作用。有一些用于手动同步的命令行工具，这可能是测试环境中非常有用的特性。我倾向于坚持使用那些有附加功能的沙盒，所以这个目录可以正常工作，不必考虑它。

这个方案的好处很快显现出来了： 如果你在主机上有一个代码编辑工具链，并处于某种原因不希望它出现在虚拟机上，那么这不是问题 —— 在主机上进行编辑，虚拟机会立刻更改。快速更改虚拟机，它也将其同步到主机上的“官方”副本 。

让我们关闭这个系统，这样我们就可以在这个系统里提供一些我们需要的东西：

```
vagrant halt

```

### 在虚拟机上安装额外的软件

对于这个例子，我将使用 [Apache](https://httpd.apache.org/)、 [PostgreSQL](https://postgresql.org) 和 Perl 的 [Dancer](https://perldancer.org) web 框架进行项目开发。我将修改Vagrant 配置脚本，以便我需要的东西已经安装。 为了使之稍后更容易保持更新，我将在项目根目录下创建一个脚本`~/myproject/Vagrantfile`：

```
$provision_script = <<SCRIPT
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get -y install \
  apache2 \
  postgresql-client-9.4 \
  postgresql-9.4 \
  libdbd-pg-perl \
  libapache2-mod-fastcgi \
  libdata-validate-email-perl  \
  libexception-class-perl \
  libexception-class-trycatch-perl \
  libtemplate-perl \
  libtemplate-plugin-json-escape-perl \
  libdbix-class-perl \
  libyaml-tiny-perl \
  libcrypt-saltedhash-perl \
  libdancer2-perl \
  libtemplate-plugin-gravatar-perl  \
  libtext-csv-perl \
  libstring-tokenizer-perl \
  cpanminus
cpanm -f -n \
  Dancer2::Session::Cookie \
  Dancer2::Plugin::DBIC \
  Dancer2::Plugin::Auth::Extensible::Provider::DBIC \
  Dancer2::Plugin::Locale \
  Dancer2::Plugin::Growler
sudo a2enmod rewrite fastcgi
sudo apache2ctl restart
SCRIPT

```

在 Vagrantfile 结尾附近，你会发现一行 `config.vm.provision` 变量，正如你在示例中看到的那样，你可以在此处以内联方式进行操作，只需通过取消注释以下行：

```
  # config.vm.provision "shell", inline: <<-SHELL
  #   sudo apt-get update
  #   sudo apt-get install -y apache2
  # SHELL

```

相反，将那四行替换为使用你在文件顶部定义为变量的配置脚本：

```
config.vm.provision "shell", inline: $provision_script

```

你可能还希望将转发的端口设置为从主机访问虚拟机上的 Apache。寻找包含 `forwarded_port` 的行并取消注释它。如果你愿意，也可以将端口从 8080 更改为其他内容。我通常使用端口 5000，并在我的浏览器浏览 http://localhost:5000 就可以访问我虚拟机上的 Apache 服务器。

这里有一个设置提示：如果你的仓库位于云存储上，为了在多台机器上使用 Vagrant，你可能希望将不同机器上的 `VAGRANT_HOME` 环境变量设置为不同的东西。以 VirtualBox 的工作方式，你需要分别为这些系统存储状态信息，确保你的版本控制系统忽略了用于此的目录 —— 我将 `.vagrant.d*` 添加到仓库的 `.gitignore` 文件中。不过，我确实让 Vagrantfile 成为仓库的一部分！

### 好了！

我输入 `vagrant up`，我准备开始写代码了。一旦你做了一两次，你可能会想到你可以循环利用很多的 Vagrantfile 模板文件（就像我刚刚那样），这就是 Vagrant 的优势之一。你可以更快地完成实际的编码工作，并将很少的时间花在基础设施上！

你可以使用 Vagrant 做更多事情。配置工具存在于许多工具链中，因此，无论你需要复制什么环境，它都是快速而简单的。

---

via: <https://opensource.com/article/18/4/getting-started-vagrant>

作者：[Ruth Holloway](https://opensource.com/users/druthb) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


LikeCoin，一种给开放式许可的内容创作者的加密货币

Summary: 在共创协议下授权作品和挣钱这二者不再是一种争议。

在共创协议下授权作品和挣钱这二者不再是一种争议。

>
> 在共创协议下授权作品和挣钱这二者不再是一种争议。
>
>
>

![](/data/attachment/album/201805/24/084556u7k0oguuuiu07ovh.jpg)

传统观点认为，作家、摄影师、艺术家和其他创作者在<ruby> 共创协议 <rt>  Creative Commons </rt></ruby>和其他开放许可下免费共享内容的不会得到报酬。这意味着大多数独立创作者无法通过在互联网上发布他们的作品来赚钱。而现在有了 [LikeCoin](https://like.co/)：一个新的开源项目，旨在使这个让艺术家们经常为了贡献而不得不妥协或牺牲的常识成为过去。

LikeCoin 协议旨在通过创意内容获利，以便创作者可以专注于创造出色的内容而不是出售它。

该协议同样基于去中心化技术，它可以跟踪何时使用内容，并使用 LikeCoin 这种 [以太坊 ERC-20](https://en.wikipedia.org/wiki/ERC20) 加密货币通证来奖励其创作者。它通过“<ruby> 创造性共识 <rt>  Proof of Creativity </rt></ruby>”算法进行操作，该算法一部分根据作品收到多少个“喜欢”，一部分根据有多少作品衍生自它而分配 LikeCoin。由于开放式授权的内容有更多机会被重复使用并获得 LikeCoin 令牌，因此系统鼓励内容创作者在<ruby> 共创协议 <rt>  Creative Commons </rt></ruby>许可下发布。

### 如何运作的

当通过 LikeCoin 协议上传创意片段时，内容创作者也将包括作品的元数据，包括作者信息及其 InterPlanetary 关联数据（[IPLD](https://ipld.io/)）。这些数据构成了衍生作品的家族图谱；我们称作品与其衍生品之间的关系为“内容足迹”。这种结构使得内容的继承树可以很容易地追溯到原始作品。

LikeCoin 通证会使用作品的衍生历史记录的信息来将其分发给创作者。由于所有创意作品都包含作者钱包的元数据，因此相应的 LikeCoin 份额可以通过算法计算并分发。

LikeCoin 可以通过两种方式获得奖励：要么由想要通过支付给内容创建者来表示赞赏的个人直接给予，或通过 Creators Pool 收集观众的“赞”的并根据内容的 LikeRank 分配 LikeCoin。基于在 LikeCoin 协议中的内容追踪，LikeRank 衡量作品重要性（或者我们在这个场景下定义的创造性）。一般来说，一副作品有越多的衍生作品，创意内容的创新就越多，内容就会有更高的 LikeRank。 LikeRank 是内容创新性的量化者。

### 如何参与？

LikeCoin 仍然非常新，我们期望在 2018 年晚些时候推出我们的第一个去中心化程序来奖励<ruby> 共创协议 <rt>  Creative Commons </rt></ruby>的内容，并与更大的社区无缝连接。

LikeCoin 的大部分代码都可以在 [LikeCoin GitHub](https://github.com/likecoin) 仓库中通过 [GPL 3.0 许可证](https://www.gnu.org/licenses/gpl-3.0.en.html)访问。由于它仍处于积极开发阶段，一些实验代码尚未公开，但我们会尽快完成。

我们欢迎功能请求、拉取请求、复刻和星标。请参与我们在 Github 上的开发，并加入我们在 [Telegram](https://t.me/likecoin) 的讨论组。我们同样在 [Medium](http://medium.com/likecoin)、[Facebook](http://fb.com/likecoin.foundation)、[Twitter](https://twitter.com/likecoin_fdn) 和我们的网站 [like.co](https://like.co/) 发布关于我们进展的最新消息。

---

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

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

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


Linux 局域网路由新手指南：第 2 部分

Summary: 今天我们继续学习更精彩的内容：局域网路由器。

今天我们继续学习更精彩的内容：局域网路由器。

![](/data/attachment/album/201805/24/090919jy9w2h6eyysowa3s.jpg)

上周 [我们学习了 IPv4 地址](/article-9657-1.html) 和如何使用管理员不可或缺的工具 —— `ipcalc`，今天我们继续学习更精彩的内容：局域网路由器。

VirtualBox 和 KVM 是测试路由的好工具，在本文中的所有示例都是在 KVM 中执行的。如果你喜欢使用物理硬件去做测试，那么你需要三台计算机：一台用作路由器，另外两台用于表示两个不同的网络。你也需要两台以太网交换机和相应的线缆。

我们假设这个示例是一个有线以太局域网，为了更符合真实使用场景，我们将假设有一些桥接的无线接入点，当然我并不会使用这些无线接入点做任何事情。（我也不会去尝试所有的无线路由器，以及使用一个移动宽带设备连接到以太网的局域网口进行混合组网，因为它们需要进一步的安装和设置）

### 网段

最简单的网段是两台计算机连接在同一个交换机上的相同地址空间中。这样两台计算机不需要路由器就可以相互通讯。这就是我们常说的术语 —— “广播域”，它表示所有在相同的网络中的一组主机。它们可能连接到一台单个的以太网交换机上，也可能是连接到多台交换机上。一个广播域可以包括通过以太网桥连接的两个不同的网络，通过网桥可以让两个网络像一个单个网络一样运转。无线访问点一般是桥接到有线以太网上。

一个广播域仅当在它们通过一台网络路由器连接的情况下，才可以与不同的广播域进行通讯。

### 简单的网络

以下示例的命令并不是永久生效的，重启之后你所做的改变将会消失。

一个广播域需要一台路由器才可以与其它广播域通讯。我们使用两台计算机和 `ip` 命令来解释这些。我们的两台计算机是 192.168.110.125 和 192.168.110.126，它们都插入到同一台以太网交换机上。在 VirtualBox 或 KVM 中，当你配置一个新网络的时候会自动创建一个虚拟交换机，因此，当你分配一个网络到虚拟虚拟机上时，就像是插入一个交换机一样。使用 `ip addr show` 去查看你的地址和网络接口名字。现在，这两台主机可以互 ping 成功。

现在，给其中一台主机添加一个不同网络的地址：

```
# ip addr add 192.168.120.125/24 dev ens3

```

你可以指定一个网络接口名字，在示例中它的名字是 `ens3`。这不需要去添加一个网络前缀，在本案例中，它是 `/24`，但是显式地添加它并没有什么坏处。你可以使用 `ip` 命令去检查你的配置。下面的示例输出为了清晰其见进行了删减：

```
$ ip addr show
ens3:
 inet 192.168.110.125/24 brd 192.168.110.255 scope global dynamic ens3
 valid_lft 875sec preferred_lft 875sec
 inet 192.168.120.125/24 scope global ens3
 valid_lft forever preferred_lft forever

```

主机在 192.168.120.125 上可以 ping 它自己（`ping 192.168.120.125`），这是对你的配置是否正确的一个基本校验，这个时候第二台计算机就已经不能 ping 通那个地址了。

现在我们需要做一些网络变更。添加第三台主机作为路由器。它需要两个虚拟网络接口并添加第二个虚拟网络。在现实中，你的路由器必须使用一个静态 IP 地址，但是现在，我们可以让 KVM 的 DHCP 服务器去为它分配地址，所以，你仅需要两个虚拟网络：

* 第一个网络：192.168.110.0/24
* 第二个网络：192.168.120.0/24

接下来你的路由器必须配置去转发数据包。数据包转发默认是禁用的，你可以使用 `sysctl` 命令去检查它的配置：

```
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0

```

`0` 意味着禁用，使用如下的命令去启用它：

```
# echo 1 > /proc/sys/net/ipv4/ip_forward

```

接下来配置你的另一台主机做为第二个网络的一部分，你可以通过将原来在 192.168.110.0/24 的网络中的一台主机分配到 192.168.120.0/24 虚拟网络中，然后重新启动两个 “连网的” 主机，注意不是路由器。（或者重启动主机上的网络服务；我年龄大了还有点懒，我记不住那些重启服务的奇怪命令，还不如重启主机来得干脆。）重启后各台机器的地址应该如下所示：

* 主机 1： 192.168.110.125
* 主机 2： 192.168.120.135
* 路由器： 192.168.110.126 和 192.168.120.136

现在可以去随意 ping 它们，可以从任何一台计算机上 ping 到任何一台其它计算机上。使用虚拟机和各种 Linux 发行版做这些事时，可能会产生一些意想不到的问题，因此，有时候 ping 的通，有时候 ping 不通。不成功也是一件好事，这意味着你需要动手去创建一条静态路由。首先，查看已经存在的路由表。主机 1 和主机 2 的路由表如下所示：

```
$ ip route show
default via 192.168.110.1 dev ens3 proto static metric 100
192.168.110.0/24 dev ens3 proto kernel scope link src 192.168.110.164 metric 100

$ ip route show
default via 192.168.110.1 dev ens3 proto static metric 100
default via 192.168.120.1 dev ens3 proto static metric 101
169.254.0.0/16 dev ens3 scope link metric 1000
192.168.110.0/24 dev ens3 proto kernel scope link
 src 192.168.110.126 metric 100
192.168.120.0/24 dev ens9 proto kernel scope link
 src 192.168.120.136 metric 100

```

这显示了我们使用的由 KVM 分配的缺省路由。169.\* 地址是自动链接的本地地址，我们不去管它。接下来我们看两条路由，这两条路由指向到我们的路由器。你可以有多条路由，在这个示例中我们将展示如何在主机 1 上添加一个非默认路由：

```
# ip route add 192.168.120.0/24 via 192.168.110.126 dev ens3

```

这意味着主机 1 可以通过路由器接口 192.168.110.126 去访问 192.168.110.0/24 网络。看一下它们是如何工作的？主机 1 和路由器需要连接到相同的地址空间，然后路由器转发到其它的网络。

以下的命令去删除一条路由：

```
# ip route del 192.168.120.0/24

```

在真实的案例中，你不需要像这样手动配置一台路由器，而是使用一个路由器守护程序，并通过 DHCP 做路由器通告，但是理解基本原理很重要。接下来我们将学习如何去配置一个易于使用的路由器守护程序来为你做这些事情。

通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 来学习更多 Linux 的知识。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/3/linux-lan-routing-beginners-part-2>

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

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


在 Linux 中轻松搜索和安装 Google Web 字体

Summary: Font Finder 是旧的 Typecatcher 的 Rust 实现，用于从 Google 的字体存档中轻松搜索和安装 Google Web 字体。

![](/data/attachment/album/201805/24/123748m7v2hgeh7ixhhxzj.png)

Font Finder 是旧的 [Typecatcher](https://www.ostechnix.com/install-google-web-fonts-ubuntu/) 的 Rust 实现，用于从 [Google 的字体存档](https://fonts.google.com/)中轻松搜索和安装 Google Web 字体。它可以帮助你在 Linux 桌面上安装数百种免费和开源字体。如果你正在为你的 Web 项目和应用以及其他任何地方寻找好看的字体，Font Finder 可以轻松地为你提供。它是用 Rust 编程语言编写的自由、开源的 GTK3 应用程序。与使用 Python 编写的 Typecatcher 不同，Font Finder 可以按类别过滤字体，没有 Python 运行时依赖关系，并且有更好的性能和更低的资源消耗。

在这个简短的教程中，我们将看到如何在 Linux 中安装和使用 Font Finder。

### 安装 Font Finder

由于 Fond Finder 是使用 Rust 语言编写的，因此你需要向下面描述的那样在系统中安装 Rust。

安装 Rust 后，运行以下命令安装 Font Finder：

```
$ cargo install fontfinder

```

Font Finder 也可以从 [flatpak app](https://flathub.org/apps/details/io.github.mmstick.FontFinder) 安装。首先在你的系统中安装 Flatpak，如下面的链接所述。

然后，使用命令安装 Font Finder：

```
$ flatpak install flathub io.github.mmstick.FontFinder

```

### 在 Linux 中使用 Font Finder 搜索和安装 Google Web 字体

你可以从程序启动器启动 Font Finder，也可以运行以下命令启动它。

```
$ flatpak run io.github.mmstick.FontFinder

```

这是 Font Finder 默认界面的样子。

![](/data/attachment/album/201805/24/123749uta4wx4zgt0ly9hz.png)

正如你所看到的，Font Finder 的用户界面非常简单。所有 Google Web 字体都列在左侧窗格中，相应字体的预览显示在右侧窗格中。你可以在预览框中输入任何单词以查看单词在所选字体中的外观。在左上方还有一个搜索框，可以让你快速搜索你选择的字体。

默认情况下，Font Finder 显示所有类型的字体。但是，你可以通过搜索框上方的类别下拉框中的分类显示字体。

![](/data/attachment/album/201805/24/123750jzaq1h1sp0v9siz0.png)

要安装字体，只需选择它并点击顶部的 “Install” 按钮即可。

![](/data/attachment/album/201805/24/123751n2j259zfef2j0jrz.png)

你可以在任何文本处理程序中测试新安装的字体。

![](/data/attachment/album/201805/24/123753o2z21424hg80zgu2.png)

同样，要删除字体，只需从 Font Finder 面板中选择它并单击 “Uninstall” 按钮。就这么简单！

左上角的设置按钮（齿轮按钮）提供了切换到暗色预览的选项。

![](/data/attachment/album/201805/24/123755xafcggrcarrr73gr.png)

如你所见，Font Finder 非常简单，完全可以像在主页上宣传的那样完成工作。如果你正在寻找安装 Google Web 字体的程序，Font Finder 就是这样的一个程序。

今天就是这些。希望这有帮助。还有更好的东西。敬请关注！

干杯!

---

via: <https://www.ostechnix.com/font-finder-easily-search-and-install-google-web-fonts-in-linux/>

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

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


使用树莓派构建一个婴儿监视器

Summary: 比一般的视频监控还要好，这种 DIY 型号还有婴儿房间的自动室温控制功能。

比一般的视频监控还要好，这种 DIY 型号还有婴儿房间的自动室温控制功能。

>
> 比一般的视频监控还要好，这种 DIY 型号还有婴儿房间的自动室温控制功能。
>
>
>

![](/data/attachment/album/201805/24/174758uck2cleyykckgomy.png)

香港很湿热，即便是晚上，许多人为了更舒适，在家里也使用空调。当我的大儿子还是一个小婴儿的时候，他卧室的空调还是需要手动控制的，没有温度自动调节的功能。它的控制器只有开或者关，让空调整个晚上持续运行会导致房间过冷，并且也浪费能源和钱。

我决定使用一个基于 [树莓派](https://opensource.com/tags/raspberry-pi) 的 [物联网](https://opensource.com/tags/internet-things) 解决方案去修复这个问题。后来我进一步为它添加了一个[婴儿监视器](https://opensource.com/article/17/9/gonimo)插件。在这篇文章中，我将解释我是如何做的，它的代码在 [我的 GitHub](https://github.com/jervine/rpi-temp-humid-monitor) 页面上。

### 设计空调控制器

解决我的问题的第一个部分是使用了一个 Orvibo S20 [可通过 WiFi 连接的智能插头](https://www.amazon.co.uk/marsboy-S20-Automation-Control-Smartphone/dp/B01LXKPUDK/ref=sr_1_1/258-6082934-2585109?ie=UTF8&qid=1520578769&sr=8-1&keywords=orvibo+s20)和智能手机应用程序。虽然这样可以让我通过远程来控制空调，但是它还是手动处理的，而我希望尝试让它自动化。我在 [Instructables](http://www.instructables.com/id/Raspberry-Pi-Temperature-Humidity-Network-Monitor/) 上找到了一个满足我的需求的项目：他使用树莓派从一个 [AM2302 传感器](https://www.adafruit.com/product/393) 上测量附近的温度和湿度，并将它们记录到一个 MySQL 数据库中。

使用压接头将温度/湿度传感器连接到树莓派的相应 GPIO 针脚上。幸运的是，AM2302 传感器有一个用于读取的 [开源软件](https://github.com/adafruit/Adafruit_Python_DHT)，并且同时提供了 [Python](https://opensource.com/tags/python) 示例。

与我的项目放在一起的用于 [AM2302 传感器](https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/tree/legacy/Adafruit_DHT_Driver_Python) 接口的软件已经更新了，并且我使用的原始代码现在应该已经过时了，停止维护了。这个代码是由一个小的二进制组成，用于连接到传感器以及解释读取并返回正确值的 Python 脚本。

![Raspberry Pi, sensor, and Python code](/data/attachment/album/201805/24/174759en8sz580cqsscc50.png "Raspberry Pi, sensor, and Python code")

*树莓派、传感器、以及用于构建温度/湿度监视器的 Python 代码。*

将传感器连接到树莓派，这些 Python 代码能够正确地返回温度和湿度读数。将 Python 连接到 MySQL 数据库很简单，并且也有大量的使用 python-mysql 绑定的代码示例。因为我需要持续地监视温度和湿度，所以我写软件来实现这些。

事实上，最终我用了两个解决方案，一是作为一个持续运行的进程，周期性（一般是间隔一分钟）地获取传感器数据，另一种是让 Python 脚本运行一次然后退出。我决定使用第二种方法，并使用 cron 去每分钟调用一次这个脚本。之所以选择这种方法的主要原因是，（通过循环实现的）持续的脚本偶尔会不返回读数，这将导致尝试读取传感器的进程出现堆积，最终可能会导致系统挂起而缺乏可用资源。

我也找到了可以用程序来控制我的智能插头的一个 [Perl 脚本](https://github.com/franc-carter/bauhn-wifi)。它是解决这种问题所需的一部分，因此当某些温度/湿度达到触发条件，将触发这个 Perl 脚本。在做了一些测试之后，我决定去设计一个独立的 `checking` 脚本，从 MySQL 去拉取最新的数据，然后根据返回的值去设置智能开关为开或关。将插头控制逻辑与传感器读取脚本分开，意味着它们是各自独立运行的，就算是传感器读取脚本写的有问题也没事。

配置一个打开/关闭空调的温度值是很有意义的，因此，我将这些值转移到控制脚本读取的配置文件中。我也发现，虽然传感器的值一般都很准确，但是，偶尔也会出现返回不正确读数的情况。这个传感器脚本被修改为不向 MySQL 数据库中写入与前值差异非常大的值。同样也在配置文件中写入了连续读取的温度/湿度之间允许的最大差异值，如果读取的值处于这些限制值以外，这些值写不会提交到数据库中。

虽然，做这个自动调节器似乎花费了很多努力，但是，这意味着，记录到 MySQL 数据库的数据是有效的、可用于进一步去分析识别用户使用模式的有用数据。可以用多种图形方式去展示来自 MySQL 数据库中的数据，而我决定使用 [Google Chart](https://developers.google.com/chart/) 在一个 Web 页面上显示数据。

![Temperature and humidity chart](/data/attachment/album/201805/24/174759ukjrbb3wpjwjebo2.png "Temperature and humidity chart")

*过去六小时内测量到的温度和湿度*

### 添加一个婴儿监视摄像头

树莓派开放的性能意味着我可以不断地为它增加功能 —— 并且我有大量的未使用的可用 GPIO 针脚。我的下一个创意是去添加一个摄像头模块，将它放在孩子的卧室中，配置它去监视婴儿。

我需要一个能够在黑暗环境中工作的摄像头，而 [Pi Noir](https://www.raspberrypi.org/products/pi-noir-camera-v2/) 摄像头模块是非常适合这种条件的。Pi Noir 除了没有红外过滤之外，同样也是树莓派常用的摄像头模块。这意味着它在白天时的图像可能有点偏紫色，但是它可以在黑暗中借助红外灯来显示图像。

现在我需要一个红外光源。由于树莓派非常流行，并且进入门槛很低，因此它有大量的外围配件和插件。也有适合它的各种红外光源，我注意到的其中一个是 [Bright Pi](https://www.pi-supply.com/product/bright-pi-bright-white-ir-camera-light-raspberry-pi/)。它可以从树莓派上供电，并且它很适合为树莓派的摄像头模块提供红外光和普通光。它唯一的缺点是太考验我的焊接技能了。

我的焊接技能还是不错的，但是可能花费的时间比其他人更长。我成功地连接了外壳上所有的红外 LEDs，并将它们连接到树莓派的 GPIO 针脚上。这意味着树莓派能够编程控制红外 LED 是否点亮，以及它的亮度。

通过一个 Web 流去公开捕获的视频也很有意义，因为这样我就可以从 Web 页面上查看温度和湿度的读数图表。进一步研究之后，我选择了一个使用 M-JPEG 捕获器的 [流软件](https://elinux.org/RPi-Cam-Web-Interface)。通过 Web 页面公开 JPG 源，我可以在我的智能手机上去连接摄像头查看程序，去查看摄像头的输出。

### 做最后的修饰

没有哪个树莓派项目都已经完成了还没有为它选择一个合适的外壳，并且它有各种零件。在大量搜索和比较之后，有了一个显然的 [赢家](https://smarticase.com/collections/all/products/smartipi-kit-3)：SmartPi 的乐高积木式外壳。乐高的兼容性可以让我去安装温度/湿度传感器和摄像头。下面是最终的成果图：

![](/data/attachment/album/201805/24/174800xa1eyqu3upglie7i.png)

在这以后，我对我的这个作品作了一些改变和更新：

* 我将它从树莓派 2 Model B 升级到了 [树莓派 3](https://opensource.com/article/18/3/raspberry-pi-3b-model-news)，这意味着我可以使用 USB WiFi 模块。
* 我用一个 [TP-Link HS110](https://www.tp-link.com/uk/products/details/cat-5258_HS110.html) 智能插头替换了 Orvibo S20。
* 我也将树莓派插到了一个智能插头上，这样我就可以远程重启/重置它了。
* 我从树莓派上将 MySQL 数据库移走了，它现在运行在一个 NAS 设备上的容器中。
* 我增加了一个非常 [灵活的三角夹](https://www.amazon.com/Flexpod-Flexible-Tripod-Discontinued-Manufacturer/dp/B000JC8WYA)，这样我就可以调整到最佳角度。
* 我重新编译了 USB WiFi 模块，禁用了板载 LED 指示灯，这就是升级到树莓派 3 的其中一个好处。
* 我因此为我的第二个孩子设计了另外一个监视器。
* 因为没有时间去折腾，我为我的第三个孩子购买了夜用摄像头。

想学习更多的东西吗？所有的代码都在 [我的 GitHub](https://github.com/jervine/rpi-temp-humid-monitor) 页面上。

想分享你的树莓派项目吗？[将你的故事和创意发送给我们](http://opensource.com/story)。

---

via: <https://opensource.com/article/18/3/build-baby-monitor-raspberry-pi>

作者：[Jonathan Ervine](https://opensource.com/users/jervine) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

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


You-Get：支持 80 多个网站的命令行多媒体下载器

![](/data/attachment/album/201805/25/091532ggbojrrbpzzt18xz.jpg)

你们大多数人可能用过或听说过 **Youtube-dl**，这个命令行程序可以从包括 Youtube 在内的 100+ 网站下载视频。我偶然发现了一个类似的工具，名字叫做 **You-Get**。这是一个 Python 编写的命令行下载器，可以让你从 Youtube、Facebook、Twitter 等很多热门网站下载图片，音频和视频（LCTT 译注：首先，它们得是存在的网站）。目前该下载器支持 80+ 站点，点击[这里](https://you-get.org/#supported-sites)查看所有支持的网站。

You-Get 不仅仅是一个下载器，它还可以将在线视频导流至你的视频播放器。更进一步，它还允许你在 Google 上搜索视频，只要给出搜索项，You-Get 使用 Google 搜索并下载相关度最高的视频。另外值得一提的特性是，它允许你暂停和恢复下载过程。它是一个完全自由、开源及跨平台的应用，适用于 Linux、MacOS 及 Windows。

### 安装 You-Get

确保你已经安装如下依赖项：

* Python 3
* FFmpeg (强烈推荐) 或 Libav
* (可选) RTMPDump

有多种方式安装 You-Get，其中官方推荐采用 pip 包管理器安装。如果你还没有安装 pip，可以参考如下链接：

* [如何使用 pip 管理 Python 软件包](https://www.ostechnix.com/manage-python-packages-using-pip/)

需要注意的是，你需要安装 Python 3 版本的 `pip`。

接下来，运行如下命令安装 You-Get：

```
$ pip3 install you-get

```

可以使用命令升级 You-Get 至最新版本：

```
$ pip3 install --upgrade you-get

```

### 开始使用 You-Get

使用方式与 Youtube-dl 工具基本一致。

#### 下载视频

下载视频，只需运行：

```
$ you-get https://www.youtube.com/watch?v=HXaglTFJLMc

```

输出示例：

```
site: YouTube
title: The Last of The Mohicans by Alexandro Querevalú
stream:
 - itag: 22
 container: mp4
 quality: hd720
 size: 56.9 MiB (59654303 bytes)
 # download-with: you-get --itag=22 [URL]

Downloading The Last of The Mohicans by Alexandro Querevalú.mp4 ...
 100% ( 56.9/ 56.9MB) ├███████████████████████████████████████████████████████┤[1/1] 752 kB/s

```

下载视频前，你可能希望查看视频的细节信息。You-Get 提供了 `–info` 或 `-i` 参数，使用该参数可以获得给定视频所有可用的分辨率和格式。

```
$ you-get -i https://www.youtube.com/watch?v=HXaglTFJLMc

```

或者

```
$ you-get --info https://www.youtube.com/watch?v=HXaglTFJLMc

```

输出示例如下：

```
site: YouTube
title: The Last of The Mohicans by Alexandro Querevalú
streams: # Available quality and codecs
 [ DASH ] ____________________________________
 - itag: 137
 container: mp4
 quality: 1920x1080
 size: 101.9 MiB (106816582 bytes)
 # download-with: you-get --itag=137 [URL]

- itag: 248
 container: webm
 quality: 1920x1080
 size: 90.3 MiB (94640185 bytes)
 # download-with: you-get --itag=248 [URL]

- itag: 136
 container: mp4
 quality: 1280x720
 size: 56.9 MiB (59672392 bytes)
 # download-with: you-get --itag=136 [URL]

- itag: 247
 container: webm
 quality: 1280x720
 size: 52.6 MiB (55170859 bytes)
 # download-with: you-get --itag=247 [URL]

- itag: 135
 container: mp4
 quality: 854x480
 size: 32.2 MiB (33757856 bytes)
 # download-with: you-get --itag=135 [URL]

- itag: 244
 container: webm
 quality: 854x480
 size: 28.0 MiB (29369484 bytes)
 # download-with: you-get --itag=244 [URL]

[ DEFAULT ] _________________________________
 - itag: 22
 container: mp4
 quality: hd720
 size: 56.9 MiB (59654303 bytes)
 # download-with: you-get --itag=22 [URL]

```

默认情况下，You-Get 会下载标记为 “DEFAULT” 的格式。如果你对格式或分辨率不满意，可以选择你喜欢的格式，使用格式对应的 itag 值即可。

```
$ you-get --itag=244 https://www.youtube.com/watch?v=HXaglTFJLMc

```

#### 下载音频

执行下面的命令，可以从 soundcloud 网站下载音频：

```
$ you-get 'https://soundcloud.com/uiceheidd/all-girls-are-same-999-prod-nick-mira'
Site: SoundCloud.com
Title: ALL GIRLS ARE THE SAME (PROD. NICK MIRA)
Type: MP3 (audio/mpeg)
Size: 2.58 MiB (2710046 Bytes)

Downloading ALL GIRLS ARE THE SAME (PROD. NICK MIRA).mp3 ...
 100% ( 2.6/ 2.6MB) ├███████████████████████████████████████████████████████┤[1/1] 983 kB/s

```

查看音频文件细节，使用 `-i` 参数：

```
$ you-get -i 'https://soundcloud.com/uiceheidd/all-girls-are-same-999-prod-nick-mira'

```

#### 下载图片

运行如下命令下载图片：

```
$ you-get https://pixabay.com/en/mountain-crumpled-cyanus-montanus-3393209/

```

You-Get 也可以下载网页中的全部图片：

```
$ you-get https://www.ostechnix.com/pacvim-a-cli-game-to-learn-vim-commands/

```

#### 搜索视频

你只需向 You-Get 传递一个任意的搜索项，而无需给出有效的 URL；You-Get 会使用 Google 搜索并下载与你给出搜索项最相关的视频。(LCTT 译注：Google 的机器人检测机制可能导致 503 报错导致该功能无法使用）。

```
$ you-get 'Micheal Jackson'
Google Videos search:
Best matched result:
site: YouTube
title: Michael Jackson - Beat It (Official Video)
stream:
 - itag: 43
 container: webm
 quality: medium
 size: 29.4 MiB (30792050 bytes)
 # download-with: you-get --itag=43 [URL]

Downloading Michael Jackson - Beat It (Official Video).webm ...
 100% ( 29.4/ 29.4MB) ├███████████████████████████████████████████████████████┤[1/1] 2 MB/s

```

#### 观看视频

You-Get 可以将在线视频导流至你的视频播放器或浏览器，跳过广告和评论部分。（LCTT 译注：使用 `-p` 参数需要对应的 vlc/chrominum 命令可以调用，一般适用于具有图形化界面的操作系统）。

以 VLC 视频播放器为例，使用如下命令在其中观看视频：

```
$ you-get -p vlc https://www.youtube.com/watch?v=HXaglTFJLMc

```

或者

```
$ you-get --player vlc https://www.youtube.com/watch?v=HXaglTFJLMc

```

类似地，将视频导流至以 chromium 为例的浏览器中，使用如下命令：

```
$ you-get -p chromium https://www.youtube.com/watch?v=HXaglTFJLMc

```

![](/data/attachment/album/201805/25/091535me96eftfddthcgmr.jpg)

在上述屏幕截图中，可以看到并没有广告和评论部分，只是一个包含视频的简单页面。

#### 设置下载视频的路径及文件名

默认情况下，使用视频标题作为默认文件名，下载至当前工作目录。当然，你可以按照你的喜好进行更改，使用 `–output-dir` 或 `-o` 参数可以指定路径，使用 `–output-filename` 或 `-O` 参数可以指定下载文件的文件名。

```
$ you-get -o ~/Videos -O output.mp4 https://www.youtube.com/watch?v=HXaglTFJLMc

```

#### 暂停和恢复下载

按 `CTRL+C` 可以取消下载。一个以 `.download` 为扩展名的临时文件会保存至输出路径。下次你使用相同的参数下载时，下载过程将延续上一次的过程。

当文件下载完成后，以 `.download` 为扩展名的临时文件会自动消失。如果这时你使用同样参数下载，You-Get 会跳过下载；如果你想强制重新下载，可以使用 `–force` 或 `-f` 参数。

查看命令的帮助部分可以获取更多细节，命令如下：

```
$ you-get --help

```

这次的分享到此结束，后续还会介绍更多的优秀工具，敬请期待！

感谢各位阅读！

---

via: <https://www.ostechnix.com/you-get-a-cli-downloader-to-download-media-from-80-websites/>

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

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


如何在 Ubuntu 上安装和优化 Apache

![](/data/attachment/album/201805/25/103013e2pkoalbrkk2t2rz.jpg)

这是我们的 LAMP 系列教程的开始：如何在 Ubuntu 上安装 Apache web 服务器。

这些说明适用于任何基于 Ubuntu 的发行版，包括 Ubuntu 14.04、 Ubuntu 16.04、 [Ubuntu 18.04](https://thishosting.rocks/ubuntu-18-04-new-features-release-date/)，甚至非 LTS 的 Ubuntu 发行版，例如 Ubuntu 17.10。这些说明经过测试并为 Ubuntu 16.04 编写。

Apache (又名 httpd) 是最受欢迎和使用最广泛的 web 服务器，所以这应该对每个人都有用。

### 开始安装 Apache 之前

在我们开始之前，这里有一些要求和说明：

* Apache 可能已经在你的服务器上安装了，所以开始之前首先检查一下。你可以使用 `apachectl -V` 命令来显示你正在使用的 Apache 的版本和一些其他信息。
* 你需要一个 Ubuntu 服务器。你可以从 [Vultr](https://thishosting.rocks/go/vultr/) 购买一个，它们是[最便宜的云托管服务商](https://thishosting.rocks/cheap-cloud-hosting-providers-comparison/)之一。它们的服务器价格每月 2.5 美元起。（LCTT 译注：广告 ≤\_≤ ）
* 你需要有 root 用户或具有 sudo 访问权限的用户。下面的所有命令都由 root 用户执行，所以我们不必为每个命令都添加 `sudo`。
* 如果你使用 Ubuntu，则需要[启用 SSH](https://thishosting.rocks/how-to-enable-ssh-on-ubuntu/)，如果你使用 Windows，则应该使用类似 [MobaXterm](https://mobaxterm.mobatek.net/) 的 SSH 客户端。

这就是全部要求和注释了，让我们进入安装过程。

### 在 Ubuntu 上安装 Apache

你需要做的第一件事就是更新 Ubuntu，这是在你做任何事情之前都应该做的。你可以运行：

```
apt-get update && apt-get upgrade

```

接下来，安装 Apache，运行以下命令：

```
apt-get install apache2

```

如果你愿意，你也可以安装 Apache 文档和一些 Apache 实用程序。对于我们稍后将要安装的一些模块，你将需要一些 Apache 实用程序。

```
apt-get install apache2-doc apache2-utils

```

\**就是这样。你已经成功安装了 Apache \**

你仍然需要配置它。

### 在 Ubuntu 上配置和优化 Apache

你可以在 Apache 上做各种各样的配置，但是主要的和最常见的配置将在下面做出解释。

#### 检查 Apache 是否正在运行

默认情况下，Apache 设置为在机器启动时自动启动，因此你不必手动启用它。你可以使用以下命令检查它是否正在运行以及其他相关信息：

```
systemctl status apache2

```

[![check if apache is running](/data/attachment/album/201805/25/103025dogk7qugjoqgeggd.jpg)](https://thishosting.rocks/wp-content/uploads/2018/01/apache-running.jpg)

并且你可以检查你正在使用的版本：

```
apachectl -V

```

一种更简单的检查方法时访问服务器的 IP 地址，如果你得到默认的 Apache 页面，那么一切都正常。

#### 更新你的防火墙

如果你使用防火墙（你应该使用它），则可能需要更新防火墙规则并允许访问默认端口。Ubuntu 上最常用的防火墙是 UFW，因此以下说明使用于 UFW。

要允许通过 80（http）和 443（https）端口的流量，运行以下命令：

```
ufw allow 'Apache Full'

```

#### 安装常见的 Apache 模块

一些模块经常被建议使用，所以你应该安装它们。我们将包含最常见模块的说明：

##### 使用 PageSpeed 加速你的网站

PageSpeed 模块将自动优化并加速你的 Apache 服务器。

首先，进入 [PageSpeed 下载页](https://www.modpagespeed.com/doc/download)并选择你需要的的文件。我们使用的是 64 位 Ubuntu 服务器，所以我们安装最新的稳定版本。使用 `wget` 下载它：

```
wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb

```

然后，使用以下命令安装它：

```
dpkg -i mod-pagespeed-stable_current_amd64.deb
apt-get -f install

```

重启 Apache 以使更改生效：

```
systemctl restart apache2

```

##### 使用 mod\_rewrite 模块启动重写/重定向

顾名思义，该模块用于重写（重定向）。如果你使用 WordPress 或任何其他 CMS 来处理此问题，你就需要它。要安装它，只需运行：

```
a2enmod rewrite

```

然后再次重新启动 Apache。你可能需要一些额外的配置，具体取决于你使用的 CMS，如果有的话。为你的设置 Google 一下得到它的具体说明。

##### 使用 ModSecurity 模块保护你的 Apache

顾名思义，ModSecurity 是一个用于安全性的模块，它基本上起着防火墙的作用，它可以监控你的流量。要安装它，运行以下命令：

```
apt-get install libapache2-modsecurity

```

再次重启 Apache：

```
systemctl restart apache2

```

ModSecurity 自带了一个默认的设置，但如果你想扩展它，你可以使用 [OWASP 规则集](https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project)。

##### 使用 mod\_evasive 模块抵御 DDoS 攻击

尽管 mod\_evasive 在防止攻击方面有多大用处值得商榷，但是你可以使用它来阻止和防止服务器上的 DDoS 攻击。要安装它，使用以下命令：

```
apt-get install libapache2-mod-evasive

```

默认情况下，mod\_evasive 是禁用的，要启用它，编辑以下文件：

```
nano /etc/apache2/mods-enabled/evasive.conf

```

取消注释所有行（即删除 `#`），根据你的要求进行配置。如果你不知道要编辑什么，你可以保持原样。

[![mod_evasive](/data/attachment/album/201805/25/103026p252ibido5vcjiow.jpg)](https://thishosting.rocks/wp-content/uploads/2018/01/mod_evasive.jpg)

创建一个日志文件：

```
mkdir /var/log/mod_evasive
chown -R www-data:www-data /var/log/mod_evasive

```

就是这样。现在重启 Apache 以使更改生效。

```
systemctl restart apache2

```

你可以安装和配置[附加模块](https://httpd.apache.org/docs/2.4/mod/)，但完全取决于你和你使用的软件。它们通常不是必需的。甚至我们上面包含的 4 个模块也不是必需的。如果特定应用需要模块，那么它们可能会注意到这一点。

#### 用 Apache2Buddy 脚本优化 Apache

Apache2Buddy 是一个可以自动调整 Apache 配置的脚本。你唯一需要做的就是运行下面的命令，脚本会自动完成剩下的工作：

```
curl -sL https://raw.githubusercontent.com/richardforth/apache2buddy/master/apache2buddy.pl | perl

```

如果你没有安装 `curl`，那么你可能需要安装它。使用以下命令来安装 `curl`：

```
apt-get install curl

```

#### 额外配置

用 Apache 还可以做一些额外的东西，但我们会留下它们作为另一个教程。像启用 http/2 支持，关闭（或打开） KeepAlive，调整你的 Apache 甚至更多。这些东西你现在不需要做，但是如果你在网上找到了教程，并且如果你等不及我们的教程，那就去做吧。

### 使用 Apache 创建你的第一个网站

现在我们已经完成了所有的调优工作，让我们开始创建一个实际的网站。按照我们的指示创建一个简单的 HTML 页面和一个在 Apache 上运行的虚拟主机。

你需要做的第一件事是为你的网站创建一个新的目录。运行以下命令来执行此操作：

```
mkdir -p /var/www/example.com/public_html

```

当然，将 `example.com` 替换为你所需的域名。你可以从 [Namecheap](https://thishosting.rocks/neamcheap-review-cheap-domains-cool-names) 获得一个便宜的域名。

不要忘记在下面的所有命令中替换 `example.com`。

接下来，创建一个简单的静态网页。创建 HTML 文件：

```
nano /var/www/example.com/public_html/index.html

```

粘贴这些：

```
<html>
     <head>
       <title>Simple Page</title>
     </head>
     <body>
       <p>If you're seeing this in your browser then everything works.</p>
     </body>
</html>

```

保存并关闭文件。

配置目录的权限：

```
chown -R www-data:www-data /var/www/example.com
chmod -R og-r /var/www/example.com

```

为你的网站创建一个新的虚拟主机：

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

```

粘贴以下内容：

```
<VirtualHost *:80>
     ServerAdmin admin@example.com
     ServerName example.com
     ServerAlias www.example.com

     DocumentRoot /var/www/example.com/public_html

     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

```

这是一个基础的虚拟主机。根据你的设置，你可能需要更高级的 `.conf` 文件。

在更新所有内容后保存并关闭文件。

现在，使用以下命令启用虚拟主机：

```
a2ensite example.com.conf

```

最后，重启 Apache 以使更改生效：

```
systemctl restart apache2

```

这就是全部了，你做完了。现在你可以访问 example.com 并查看你的页面。

---

via: <https://thishosting.rocks/how-to-install-optimize-apache-ubuntu/>

作者：[ThisHosting](https://thishosting.rocks) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

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


在 CentOS 6 系统上安装最新版 Python3 软件包的 3 种方法

![](/data/attachment/album/201805/26/071008ki1rmqmar1q9yhyr.png)

CentOS 克隆自 RHEL，无需付费即可使用。CentOS 是一个企业级标准的、前沿的操作系统，被超过 90% 的网络主机托管商采用，因为它提供了技术领先的服务器控制面板 cPanel/WHM。

该控制面板使得用户无需进入命令行即可通过其管理一切。

众所周知，RHEL 提供长期支持，出于稳定性考虑，不提供最新版本的软件包。

如果你想安装的最新版本软件包不在默认源中，你需要手动编译源码安装。但手动编译安装的方式有不小的风险，即如果出现新版本，无法升级手动安装的软件包；你不得不重新手动安装。

那么在这种情况下，安装最新版软件包的推荐方法和方案是什么呢？是的，可以通过为系统添加所需的第三方源来达到目的。

可供企业级 Linux 使用的第三方源有很多，但只有几个是 CentOS 社区推荐使用的，它们在很大程度上不修改基础软件包。

这几个推荐的源维护的很好，为 CentOS 提供大量补充软件包。

在本教程中，我们将向你展示，如何在 CentOS 6 操作系统上安装最新版本的 Python 3 软件包。

### 方法 1：使用 Software Collections 源 （SCL）

SCL 源目前由 CentOS SIG 维护，除了重新编译构建 Red Hat 的 Software Collections 外，还额外提供一些它们自己的软件包。

该源中包含不少程序的更高版本，可以在不改变原有旧版本程序包的情况下安装，使用时需要通过 `scl` 命令调用。

运行如下命令可以在 CentOS 上安装 SCL 源：

```
# yum install centos-release-scl

```

检查可用的 Python 3 版本：

```
# yum info rh-python35
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: ewr.edge.kernel.org
 * remi-safe: mirror.team-cymru.com
Available Packages
Name        : rh-python35
Arch        : x86_64
Version     : 2.0
Release     : 2.el6
Size        : 0.0
Repo        : installed
From repo   : centos-sclo-rh
Summary     : Package that installs rh-python35
License     : GPLv2+
Description : This is the main package for rh-python35 Software Collection.

```

运行如下命令从 `scl` 源安装可用的最新版 python 3：

```
# yum install rh-python35

```

运行如下特殊的 `scl` 命令，在当前 shell 中启用安装的软件包：

```
# scl enable rh-python35 bash

```

运行如下命令检查安装的 python3 版本：

```
# python --version
Python 3.5.1

```

运行如下命令获取系统已安装的 SCL 软件包列表：

```
# scl -l
rh-python35

```

### 方法 2：使用 EPEL 源 (Extra Packages for Enterprise Linux）

EPEL 是 Extra Packages for Enterprise Linux 的缩写，该源由 Fedora SIG （Special Interest Group）维护。

该 SIG 为企业级 Linux 创建、维护并管理了一系列高品质补充软件包，受益的企业级 Linux 发行版包括但不限于红帽企业级 Linux （RHEL）、 CentOS、 Scientific Linux （SL） 和 Oracle Linux （OL）等。

EPEL 通常基于 Fedora 对应代码提供软件包，不会与企业级 Linux 发行版中的基础软件包冲突或替换其中的软件包。

**推荐阅读：** [在 RHEL, CentOS, Oracle Linux 或 Scientific Linux 上安装启用 EPEL 源](https://www.2daygeek.com/install-enable-epel-repository-on-rhel-centos-scientific-linux-oracle-linux/)

EPEL 软件包位于 CentOS 的 Extra 源中，已经默认启用，故我们只需运行如下命令即可：

```
# yum install epel-release

```

检查可用的 python 3 版本：

```
# yum --disablerepo="*" --enablerepo="epel" info python34
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: ewr.edge.kernel.org
Available Packages
Name        : python34
Arch        : x86_64
Version     : 3.4.5
Release     : 4.el6
Size        : 50 k
Repo        : epel
Summary     : Version 3 of the Python programming language aka Python 3000
URL         : http://www.python.org/
License     : Python
Description : Python 3 is a new version of the language that is incompatible with the 2.x
            : line of releases. The language is mostly the same, but many details, especially
            : how built-in objects like dictionaries and strings work, have changed
            : considerably, and a lot of deprecated features have finally been removed.

```

运行如下命令从 EPEL 源安装可用的最新版 python 3 软件包：

```
# yum --disablerepo="*" --enablerepo="epel" install python34

```

默认情况下并不会安装 `pip` 和 `setuptools`，我们需要运行如下命令手动安装：

```
# curl -O https://bootstrap.pypa.io/get-pip.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1603k  100 1603k    0     0  2633k      0 --:--:-- --:--:-- --:--:-- 4816k

# /usr/bin/python3.4 get-pip.py
Collecting pip
  Using cached https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl
Collecting setuptools
  Downloading https://files.pythonhosted.org/packages/8c/10/79282747f9169f21c053c562a0baa21815a8c7879be97abd930dbcf862e8/setuptools-39.1.0-py2.py3-none-any.whl (566kB)
    100% |████████████████████████████████| 573kB 4.0MB/s
Collecting wheel
  Downloading https://files.pythonhosted.org/packages/1b/d2/22cde5ea9af055f81814f9f2545f5ed8a053eb749c08d186b369959189a8/wheel-0.31.0-py2.py3-none-any.whl (41kB)
    100% |████████████████████████████████| 51kB 8.0MB/s
Installing collected packages: pip, setuptools, wheel
Successfully installed pip-10.0.1 setuptools-39.1.0 wheel-0.31.0

```

运行如下命令检查已安装的 python3 版本：

```
# python3 --version
Python 3.4.5

```

### 方法 3：使用 IUS 社区源

IUS 社区是 CentOS 社区批准的第三方 RPM 源，为企业级 Linux （RHEL 和 CentOS） 5、 6 和 7 版本提供最新上游版本的 PHP、 Python、 MySQL 等软件包。

IUS 社区源依赖于 EPEL 源，故我们需要先安装 EPEL 源，然后再安装 IUS 社区源。按照下面的步骤安装启用 EPEL 源和 IUS 社区源，利用该 RPM 系统安装软件包。

**推荐阅读：** [在 RHEL 或 CentOS 上安装启用 IUS 社区源](https://www.2daygeek.com/install-enable-ius-community-repository-on-rhel-centos/)

EPEL 软件包位于 CentOS 的 Extra 源中，已经默认启用，故我们只需运行如下命令即可：

```
# yum install epel-release

```

下载 IUS 社区源安装脚本：

```
# curl 'https://setup.ius.io/' -o setup-ius.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1914  100  1914    0     0   6563      0 --:--:-- --:--:-- --:--:--  133k

```

安装启用 IUS 社区源：

```
# sh setup-ius.sh

```

检查可用的 python 3 版本：

```
# yum --enablerepo=ius info python36u
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: ewr.edge.kernel.org
 * ius: mirror.team-cymru.com
 * remi-safe: mirror.team-cymru.com
Available Packages
Name        : python36u
Arch        : x86_64
Version     : 3.6.5
Release     : 1.ius.centos6
Size        : 55 k
Repo        : ius
Summary     : Interpreter of the Python programming language
URL         : https://www.python.org/
License     : Python
Description : Python is an accessible, high-level, dynamically typed, interpreted programming
            : language, designed with an emphasis on code readability.
            : It includes an extensive standard library, and has a vast ecosystem of
            : third-party libraries.
            :
            : The python36u package provides the "python3.6" executable: the reference
            : interpreter for the Python language, version 3.
            : The majority of its standard library is provided in the python36u-libs package,
            : which should be installed automatically along with python36u.
            : The remaining parts of the Python standard library are broken out into the
            : python36u-tkinter and python36u-test packages, which may need to be installed
            : separately.
            :
            : Documentation for Python is provided in the python36u-docs package.
            :
            : Packages containing additional libraries for Python are generally named with
            : the "python36u-" prefix.

```

运行如下命令从 IUS 源安装最新可用版本的 python 3 软件包：

```
# yum --enablerepo=ius install python36u

```

运行如下命令检查已安装的 python3 版本：

```
# python3.6 --version
Python 3.6.5

```

---

via: <https://www.2daygeek.com/3-methods-to-install-latest-python3-package-on-centos-6-system/>

作者：[PRAKASH SUBRAMANIAN](https://www.2daygeek.com/author/prakash/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

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