如何在 Linux 上管理字体

# 如何在 Linux 上管理字体

我不仅写技术文档，还写小说。并且因为我对 GIMP 等工具感到满意，所以我也（LCTT 译注：此处应指使用 GIMP）为自己的书籍创作了封面（并为少数客户做了图形设计）。艺术创作取决于很多东西，包括字体。

虽然字体渲染已经在过去的几年里取得了长足进步，但它在 Linux 平台上仍是个问题。如果你在 Linux 和 macOS 平台上比较相同字体的外观，差别是显而易见的，尤其是你要盯着屏幕一整天的时候。虽然在 Linux 平台上尚未找到完美的字体渲染方案，但开源平台做的很好一件事的就是允许用户轻松地管理他们的字体。通过选择、添加、缩放和调整，你可以在 Linux 平台上相当轻松地使用字体。

此处，我将分享一些这些年来我的一些技巧，可以帮我在 Linux 上扩展“字体能力”。这些技巧将对那些在开源平台上进行艺术创作的人有特别的帮助。因为 Linux 平台上有非常多可用的桌面界面（每种界面以不同的方式处理字体），因此当桌面环境成为字体管理的中心时，我将主要聚焦在 GNOME 和 KDE 上。

话虽如此，让我们开始吧。

### 添加新字体

在相当长的一段时间里，我都是一个字体收藏家，甚至有些人会说我有些痴迷。从我使用 Linux 的早期开始，我就总是用相同的方法向我的桌面添加字体。有两种方法可以做到这一点：

* 使字体按用户可用；
* 使字体在系统范围内可用。

因为我的桌面从没有其他用户（除了我自己），我只使用了按用户可用的字体设置。然而，我会向你演示如何完成这两种设置。首先，让我们来看一下如何向用户添加新字体。你首先要做的是找到字体文件，True Type 字体（TTF）和 Open Type 字体（OTF）都可以添加。我选择手动添加字体，也就是说，我在 `~/` 目录下新建了一个名为 `~/.fonts` 的隐藏目录。该操作可由以下命令完成：

```
mkdir ~/.fonts
```

当此文件夹新建完成，我将所有 TTF 和 OTF 字体文件移动到此文件夹中。也就是说，你在此文件夹中添加的所有字体都可以在已安装的应用中使用了。但是要记住，这些字体只会对这一个用户可用。

如果你想要使这个字体集合对所有用户可用，你可以如下操作：

1. 打开一个终端窗口；
2. 切换路径到包含你所有字体的目录中；
3. 使用 `sudo cp *.ttf *.TTF /usr/share/fonts/truetype/` 和 `sudo cp *.otf *.OTF /usr/share/fonts/opentype` 命令拷贝所有字体。

当下次用户登录时，他们就将可以使用所有这些漂亮的字体。

### 图形界面字体管理

在 Linux 上你有许多方式来管理你的字体，如何完成取决于你的桌面环境。让我们以 KDE 为例。使用以 KDE 作为桌面环境的 Kubuntu 18.04，你能够找到一个预装的字体管理工具。打开此工具，你就能轻松地添加、移除、启用或禁用字体（当然也包括获得所有已安装字体的详细信息）。这个工具也能让你轻松地针对每个用户或在系统范围内添加和删除字体。假如你想要为用户添加一个特定的字体，你需要下载该字体并打开“字体管理”工具。在此工具中（图 1），点击“个人字体”并点击“+”号添加按钮。

*图 1: 在 KDE 中添加个人字体。*

导航至你的字体路径，选择它们，然后点击打开。你的字体就会被添加进了个人区域，并且立即可用（图 2）。

*图 2: 使用 KDE 字体管理添加字体*

在 GNOME 中做同样的事需要安装一个应用。打开 GNOME 软件中心或者 Ubuntu 软件中心（取决于你使用的发行版）并搜索字体管理器。选择“字体管理器”并点击安装按钮。一但安装完成，你就可以从桌面菜单中启动它，然后让我们安装个人字体。下面是如何安装：

1. 从左侧窗格选择“用户”（图 3）；
2. 点击窗口顶部的 “+” 按钮；
3. 浏览并选择已下载的字体；
4. 点击“打开”。

*图 3: 在 GNOME 中添加字体*

### 调整字体

首先你需要理解 3 个概念：

* **字体提示：** 使用数学指令调整字体轮廓显示，使其与光栅化网格对齐。
* **抗锯齿：** 一种通过使曲线和斜线锯齿状边缘光滑化，提高数字图像真实性的技术。
* **缩放因子：** 一个允许你倍增字体大小的缩放单元。也就是说如果你的字体是 12pt 并且缩放因子为 1，那么字体大小将会是 12pt。如果你的缩放因子为 2，那么字体将会是 24pt。

假设你已经安装好了你的字体，但它们看起来并不像你想的那么好。你将如何调整字体的外观？在 KDE 和 GNOME 中，你都可以做一些调整。在调整字体时需要考虑的一件事是，关于字体的口味是非常主观的。你也许会发现你只得不停地调整，直到你得到了看起来确实满意的字体（由你的需求和特殊口味决定）。让我们先看一下 KDE 下的情况吧。

打开“系统设置”工具并点击“字体”。在此节中，你不仅能切换不同字体，你也能够启用或配置抗锯齿或启用字体缩放因子（图 4）。

*图 4: 在 KDE 中配置字体*

要配置抗锯齿，在下拉菜单中选择“启用”并点击“配置”。在结果窗口中（图 5），你可以配置“排除范围”、“子像素渲染类型”和“提示类型”。

一但你做了更改，点击“应用”。重启所有正在运行的程序，然后新的设置就会生效。

要在 GNOME 中这么做，你需要安装“字体管理器”或 GNOME Tweaks。在此处，GNOME Tweaks 是更好的工具。如果你打开 GNOME Dash 菜单但没有找到 Tweaks，打开 GNOME “软件”（或 Ubuntu “软件”）并安装 GNOME Tweaks。安装完毕，打开并点击“字体”，此处你可以配置提示、抗锯齿和缩放因子（图 6）。

*图 6: 在 GNOME 中调整字体*

### 美化你的字体

以上便是使你的 Linux 字体尽可能漂亮的要旨。你可能得不到像 macOS 那样渲染的字体，但你一定可以提升字体外观。最后，你选择的字体会很大程度地影响视觉效果，因此请确保你安装的字体是干净并且完整适配的，否则你将输掉这次对抗。

通过 The Linux Foundation 和 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/5/how-manage-fonts-linux>

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

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


9 个鲜为人知的 Python 数据科学库

# 9 个鲜为人知的 Python 数据科学库

>
> 除了 pandas、scikit-learn 和 matplotlib，还要学习一些用 Python 进行数据科学的新技巧。
>
>
>

Python 是一种令人惊叹的语言。事实上，它是世界上增长最快的编程语言之一。它一次又一次地证明了它在各个行业的开发者和数据科学者中的作用。Python 及其库的整个生态系统使其成为全世界用户的恰当选择，无论是初学者还是高级用户。它成功和受欢迎的原因之一是它的一组强大的库，使它如此动态和快速。

在本文中，我们将看到 Python 库中的一些数据科学工具，而不是那些常用的工具，如 pandas、scikit-learn 和 matplotlib。虽然像 pandas、scikit-learn 这样的库是机器学习中最常想到的，但是了解这个领域的其他 Python 库也是非常有帮助的。

### Wget

提取数据，尤其是从网络中提取数据，是数据科学家的重要任务之一。[Wget](https://pypi.org/project/wget/) 是一个免费的工具，用于从网络上非交互式下载文件。它支持 HTTP、HTTPS 和 FTP 协议，以及通过 HTTP 代理进行访问。因为它是非交互式的，所以即使用户没有登录，它也可以在后台工作。所以下次你想下载一个网站或者网页上的所有图片，wget 会提供帮助。

安装：

```
$ pip install wget
```

例子：

```
import wget
url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3'

filename = wget.download(url)
100% [................................................] 3841532 / 3841532

filename
'razorback.mp3'
```

### 钟摆

对于在 Python 中处理日期时间感到沮丧的人来说， [Pendulum](https://github.com/sdispater/pendulum) 库是很有帮助的。这是一个 Python 包，可以简化日期时间操作。它是 Python 原生类的一个替代品。有关详细信息，请参阅其[文档](https://pendulum.eustace.io/docs/#installation)。

安装：

```
$ pip install pendulum
```

例子：

```
import pendulum

dt_toronto = pendulum.datetime(2012, 1, 1, tz='America/Toronto')
dt_vancouver = pendulum.datetime(2012, 1, 1, tz='America/Vancouver')

print(dt_vancouver.diff(dt_toronto).in_hours())

3
```

### 不平衡学习

当每个类别中的样本数几乎相同（即平衡）时，大多数分类算法会工作得最好。但是现实生活中的案例中充满了不平衡的数据集，这可能会影响到机器学习算法的学习和后续预测。幸运的是，[imbalanced-learn](https://github.com/scikit-learn-contrib/imbalanced-learn) 库就是为了解决这个问题而创建的。它与 [scikit-learn](http://scikit-learn.org/stable/) 兼容，并且是 [scikit-learn-contrib](https://github.com/scikit-learn-contrib) 项目的一部分。下次遇到不平衡的数据集时，可以尝试一下。

安装：

```
pip install -U imbalanced-learn
# or
conda install -c conda-forge imbalanced-learn
```

例子：

有关用法和示例，请参阅其[文档](http://imbalanced-learn.org/en/stable/api.html) 。

### FlashText

在自然语言处理（NLP）任务中清理文本数据通常需要替换句子中的关键词或从句子中提取关键词。通常，这种操作可以用正则表达式来完成，但是如果要搜索的术语数达到数千个，它们可能会变得很麻烦。

Python 的 [FlashText](https://github.com/vi3k6i5/flashtext) 模块，基于 [FlashText 算法](https://arxiv.org/abs/1711.00046)，为这种情况提供了一个合适的替代方案。FlashText 的最佳部分是运行时间与搜索项的数量无关。你可以在其 [文档](https://flashtext.readthedocs.io/en/latest/) 中读到更多关于它的信息。

安装：

```
$ pip install flashtext
```

例子：

提取关键词：

```
from flashtext import KeywordProcessor
keyword_processor = KeywordProcessor()

# keyword_processor.add_keyword(<unclean name>, <standardised name>)

keyword_processor.add_keyword('Big Apple', 'New York')
keyword_processor.add_keyword('Bay Area')
keywords_found = keyword_processor.extract_keywords('I love Big Apple and Bay Area.')

keywords_found
['New York', 'Bay Area']
```

替代关键词：

```
keyword_processor.add_keyword('New Delhi', 'NCR region')

new_sentence = keyword_processor.replace_keywords('I love Big Apple and new delhi.')

new_sentence
'I love New York and NCR region.'
```

有关更多示例，请参阅文档中的 [用法](https://flashtext.readthedocs.io/en/latest/#usage) 一节。

### 模糊处理

这个名字听起来很奇怪，但是 [FuzzyWuzzy](https://github.com/seatgeek/fuzzywuzzy) 在字符串匹配方面是一个非常有用的库。它可以很容易地实现字符串匹配率、令牌匹配率等操作。对于匹配保存在不同数据库中的记录也很方便。

安装：

```
$ pip install fuzzywuzzy
```

例子：

```
from fuzzywuzzy import fuzz
from fuzzywuzzy import process

# 简单的匹配率
fuzz.ratio("this is a test", "this is a test!")
97

# 部分的匹配率
fuzz.partial_ratio("this is a test", "this is a test!")
 100
```

更多的例子可以在 FuzzyWuzy 的 [GitHub 仓库](https://github.com/seatgeek/fuzzywuzzy)得到。

### PyFlux

时间序列分析是机器学习中最常遇到的问题之一。[PyFlux](https://github.com/RJT1990/pyflux) 是 Python 中的开源库，专门为处理时间序列问题而构建的。该库拥有一系列优秀的现代时间序列模型，包括但不限于 ARIMA、GARCH 以及 VAR 模型。简而言之，PyFlux 为时间序列建模提供了一种概率方法。这值得一试。

安装：

```
pip install pyflux
```

例子：

有关用法和示例，请参阅其 [文档](https://pyflux.readthedocs.io/en/latest/index.html)。

### IPyvolume

交流结果是数据科学的一个重要方面，可视化结果提供了显著优势。 [IPyvolume](https://github.com/maartenbreddels/ipyvolume) 是一个 Python 库，用于在 Jupyter 笔记本中可视化 3D 体积和形状（例如 3D 散点图），配置和工作量极小。然而，它目前处于 1.0 之前的阶段。一个很好的类比是这样的: IPyVolumee volshow 是 3D 阵列，Matplotlib 的 imshow 是 2D 阵列。你可以在其 [文档](https://ipyvolume.readthedocs.io/en/latest/?badge=latest) 中读到更多关于它的信息。

安装：

```
Using pip
$ pip install ipyvolume

Conda/Anaconda
$ conda install -c conda-forge ipyvolume
```

例子：

动画：

体绘制：

### Dash

[Dash](https://github.com/plotly/dash) 是一个用于构建 Web 应用程序的高效 Python 框架。它构建于 Flask、Plotty.js 和 Response.js 之上，将下拉菜单、滑块和图形等流行 UI 元素与你的 Python 分析代码联系起来，而不需要JavaScript。Dash 非常适合构建可在 Web 浏览器中呈现的数据可视化应用程序。有关详细信息，请参阅其 [用户指南](https://dash.plot.ly/) 。

安装：

```
pip install dash==0.29.0  # The core dash backend
pip install dash-html-components==0.13.2  # HTML components
pip install dash-core-components==0.36.0  # Supercharged components
pip install dash-table==3.1.3  # Interactive DataTable component (new!)
```

例子：

下面的示例显示了一个具有下拉功能的高度交互的图表。当用户在下拉列表中选择一个值时，应用程序代码将数据从 Google Finance 动态导出到 Pandas 数据框架中。

### Gym

从 [OpenAI](https://openai.com/) 而来的 [Gym](https://github.com/openai/gym) 是开发和比较强化学习算法的工具包。它与任何数值计算库兼容，如 TensorFlow 或 Theano。Gym 是一个测试问题的集合，也称为“环境”，你可以用它来制定你的强化学习算法。这些环境有一个共享的接口，允许您编写通用算法。

安装：

```
pip install gym
```

例子：

以下示例将在 [CartPole-v0](https://gym.openai.com/envs/CartPole-v0) 环境中，运行 1000 次，在每一步渲染环境。

你可以在 Gym 网站上读到 [其它的环境](https://gym.openai.com/) 。

### 结论

这些是我挑选的有用但鲜为人知的数据科学 Python 库。如果你知道另一个要添加到这个列表中，请在下面的评论中提及。

本文最初发表在 [Analytics Vidhya](https://medium.com/analytics-vidhya/python-libraries-for-data-science-other-than-pandas-and-numpy-95da30568fad) 的媒体频道上，并经许可转载。

---

via: <https://opensource.com/article/18/11/python-libraries-data-science>

作者：[Parul Pandey](https://opensource.com/users/parul-pandey) 选题：[lujun9972](https://github.com/lujun9972) 译者：[heguangzhi](https://github.com/heguangzhi) 校对：[wxy](https://github.com/wxy)

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


Emacs 系列（三）： Org 模式的补充

Summary: 当你使用 Org 模式来跟进你的 TODO 时，它有多种状态。

当你使用 Org 模式来跟进你的 TODO 时，它有多种状态。

# Emacs 系列（三）： Org 模式的补充

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

这是 [Emacs 和 Org 模式系列](https://changelog.complete.org/archives/tag/emacs2018)的第三篇。

### Todo 的跟进及关键字

当你使用 Org 模式来跟进你的 TODO 时，它有多种状态。你可以用 `C-c C-t` 来快速切换状态。我将它设为这样：

```
(setq org-todo-keywords '(
  (sequence "TODO(t!)" "NEXT(n!)" "STARTED(a!)" "WAIT(w@/!)" "OTHERS(o!)" "|" "DONE(d)" "CANCELLED(c)")
))
```

在这里，我设置了一个任务未完成的五种状态：`TODO`、`NEXT`、`STARTED`、`WAIT` 及 `OTHERS`。每一个状态都有单个字的快捷键（`t`、`n`、`a` 等）。管道符（`|`）之后的状态被认为是“完成”的状态。我有两个“完成”状态：`DONE`（已经完成）及 `CANCELLED`（还没完成，但由于其它的原因无法完成）。

`!` 的含义是记录某项更改为状态的时间。我不把这个添加到完成的状态，是因为它们已经被记录了。`@` 符号表示带理由的提示，所以当切换到 `WAIT` 时，Org 模式会问我为什么，并将这个添加到笔记中。

以下是项目状态发生变化的例子：

```
** DONE This is a test
   CLOSED: [2018-03-02 Fri 03:05]

   - State "DONE"       from "WAIT"       [2018-03-02 Fri 03:05]
   - State "WAIT"       from "TODO"       [2018-03-02 Fri 03:05] \\
     waiting for pigs to fly
   - State "TODO"       from "NEXT"       [2018-03-02 Fri 03:05]
   - State "NEXT"       from "TODO"       [2018-03-02 Fri 03:05]
```

在这里，最新的项目在最上面。

### 议程模式，日程及期限

当你处在一个待办事项时，`C-c C-s` 或 `C-c C-d` 可以为其设置相应的日程或期限。这些都是在议程模式中的功能。它们的区别在于其意图和表现。日程是你希望在某个时候完成的事情，而期限是在某个特定的时间应该完成的事情。默认情况下，议程视图将在项目的截止日期前提醒你。

在此过程中，[议程视图](https://orgmode.org/guide/Agenda-Views.html#Agenda-Views)将显示即将出现的项目，提供了一种基于纯文本或标记搜索项目的方法，甚至可以进行跨多个文件处理项目的批量操作。我在本系列的[第 2 部分](/article-10312-1.html)中介绍了为议程模式配置。

### 标签

Org 模式当然也支持标签了。你可以通过 `C-c C-q` 快速的建立标签。

你可能会想为一些常用的标签设置快捷键。就像这样:

```
  (setq org-tag-persistent-alist
        '(("@phone" . ?p)
          ("@computer" . ?c)
          ("@websurfing" . ?w)
          ("@errands" . ?e)
          ("@outdoors" . ?o)
          ("MIT" . ?m)
          ("BIGROCK" . ?b)
          ("CONTACTS" . ?C)
          ("INBOX" . ?i)
          ))
```

你还可以按文件向该列表添加标记，也可以按文件为某些内容设置标记。我就在我的 `inbox.org` 和 `email.org` 文件中设置了一个 `INBOX` 的标签。然后我可以每天从日程视图中查看所有标记为 `INBOX` 的项目，像将它们重新归档到其他文件中的这样的简单操作将让它们去掉 `INBOX` 标记。

### 重新归档

“重新归档”就是在文件中或其他地方移动。它是使用标题来完成的。`C-c C-w` 就是做这个的。我设置成这样:

```
(setq org-outline-path-complete-in-steps nil)         ; Refile in a single go
(setq org-refile-use-outline-path 'file)
```

### 归档分类

一段时间后，你的文件就会被已经完成的事情弄得乱七八糟。Org 模式有一个[归档](https://orgmode.org/guide/Archiving.html#Archiving)特性，可以将主 `.org` 文件移到其他文件中，以备将来参考。如果你在 `git` 或其他软件中 有 Org 文件，你可能希望删除这些其他文件，因为无论如何都会在历史中拥有这些文件，但是我发现它们对于析取和搜索非常方便。

我会定期检查并归档文件中的所有内容。基于 [stackoverflow 的讨论](https://stackoverflow.com/questions/6997387/how-to-archive-all-the-done-tasks-using-a-single-command)，我有以下代码：

```
(defun org-archive-done-tasks ()
  (interactive)
  (org-map-entries
   (lambda ()
     (org-archive-subtree)
     (setq org-map-continue-from (outline-previous-heading)))
   "/DONE" 'file)
  (org-map-entries
   (lambda ()
     (org-archive-subtree)
     (setq org-map-continue-from (outline-previous-heading)))
   "/CANCELLED" 'file)
)
```

这基于[一个特定的答案](https://stackoverflow.com/a/27043756) —— 你可以从评论那获得一些额外的提示。现在你可以运行 `M-x org-archive-done-tasks`，当前文件中所有标记为 `DONE` 或 `CANCELED` 的内容都将放到另一个文件中。

### 下一篇

我将通过讨论在 Org 模式中自动接受邮件以及在不同的机器上同步来对 Org 模式进行总结。

---

via: <https://changelog.complete.org/archives/9877-emacs-3-more-on-org-mode>

作者：[John Goerzen](http://changelog.complete.org/archives/author/jgoerzen) 选题：[lujun9972](https://github.com/lujun9972) 译者：[oneforalone](https://github.com/oneforalone) 校对：[wxy](https://github.com/wxy)

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


30 个 Openstack 经典面试问题和解答

# 30 个 Openstack 经典面试问题和解答

现在，大多数公司都试图将它们的 IT 基础设施和电信设施迁移到私有云， 如 OpenStack。如果你打算面试 OpenStack 管理员这个岗位，那么下面列出的这些面试问题可能会帮助你通过面试。

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

### Q:1 说一下 OpenStack 及其主要组件？

答： OpenStack 是一系列开源软件，这些软件组成了一个云供给软件，也就是 OpenStack，意即开源软件或项目栈。

下面是 OpenStack 的主要关键组件：

* **Nova** – 用于在计算级别管理虚拟机，并在计算或管理程序级别执行其他计算任务。
* **Neutron** – 为虚拟机、计算和控制节点提供网络功能。
* **Keystone** – 为所有云用户和 OpenStack 云服务提供身份认证服务。换句话说，我们可以说 Keystone 是一个提供给云用户和云服务访问权限的方法。
* **Horizon** – 用于提供图形用户界面。使用图形化管理界面可以很轻松地完成各种日常操作任务。
* **Cinder** – 用于提供块存储功能。通常来说 OpenStack 的 Cinder 中集成了 Chef 和 ScaleIO 来共同为计算和控制节点提供块存储服务。
* **Swift** – 用于提供对象存储功能。通常来说，Glance 管理的镜像是存储在对象存储空间的。像 ScaleIO 这样的外部存储也可以提供对象存储，可以很容易的集成 Glance 服务。
* **Glance** – 用于提供镜像服务。使用 Glance 的管理平台来上传和下载云镜像。
* **Heat** – 用于提供编排服务或功能。使用 Heat 管理平台可以轻松地将虚拟机作为堆栈，并且根据需要可以将虚拟机扩展或收缩。
* **Ceilometer** – 用于提供计量与监控功能。

### Q:2 什么服务通常在控制节点上运行？

答： 以下服务通常在控制节点上运行：

* 认证服务（KeyStone）
* 镜像服务（Glance）
* Nova 服务比如 Nova API、Nova Scheduler 和 Nova DB
* 块存储和对象存储服务
* Ceilometer 服务
* MariaDB / MySQL 和 RabbitMQ 服务
* 网络(Neutron)和网络代理的管理服务
* 编排服务（Heat）

### Q:3 什么服务通常在计算节点上运行？

答： 以下服务通常在计算节点运行：

* Nova 计算
* 网络服务，比如 OVS

### Q:4 计算节点上虚拟机的默认地址是什么?

答： 虚拟机存储在计算节点的 `/var/lib/nova/instances`。

### Q:5 Glance 镜像的默认地址是什么？

答： 因为 Glance 服务运行在控制节点上，所以 Glance 镜像都被存储在控制节点的 `/var/lib/glance/images` 文件夹下。

想了解更多请访问：[在 OpenStack 中如何使用命令行创建和删除虚拟机](https://www.linuxtechi.com/create-delete-virtual-machine-command-line-openstack/)

### Q:6 说一下如何使用命令行启动一个虚拟机？

答： 我们可以使用如下 OpenStack 命令来启动一个新的虚拟机：

```
# openstack server create --flavor {flavor-name} --image {Image-Name-Or-Image-ID}  --nic net-id={Network-ID} --security-group {Security_Group_ID} –key-name {Keypair-Name} <VM_Name>
```

### Q:7 如何在 OpenStack 中显示用户的网络命名空间列表？

答： 可以使用 `ip net ns` 命令来列出用户的网络命名空间。

```
~# ip netns list
qdhcp-a51635b1-d023-419a-93b5-39de47755d2d
haproxy
vrouter
```

### Q:8 如何在 OpenStack 中执行网络命名空间内的命令？

答： 假设我们想在 `qdhcp-a51635b1-d023-419a-93b5-39de47755d2d` 网络命名空间中执行 `ifconfig` 命令，我们可以执行如下命令。

命令格式 : `ip netns exec {network-space} <command>`：

```
~# ip netns exec qdhcp-a51635b1-d023-419a-93b5-39de47755d2d "ifconfig"
```

### Q:9 在 Glance 服务中如何使用命令行上传和下载镜像？

答： Glance 服务中云镜像上传可以使用如下 OpenStack 命令：

```
~# openstack image create --disk-format qcow2 --container-format bare   --public --file {Name-Cloud-Image}.qcow2     <Cloud-Image-Name>
```

下载云镜像则使用如下命令：

```
~# glance image-download --file <Cloud-Image-Name> --progress  <Image-ID>
```

### Q:10 OpenStack 如何将虚拟机从错误状态转换为活动状态？

答： 在某些情况下虚拟机可能会进入错误状态，可以使用如下命令将错误状态转换为活动状态：

```
~# nova reset-state --active {Instance_id}
```

### Q:11 如何使用命令行来获取可使用的浮动 IP 列表？

答： 可使用如下命令来显示可用浮动 IP 列表：

```
~]# openstack ip floating list | grep None | head -10
```

### Q:12 如何在特定可用区域中或在计算主机上配置虚拟机？

答： 假设我们想在 compute-02 中的可用区 NonProduction 上配置虚拟机，可以使用如下命令：

```
~]# openstack server create --flavor m1.tiny --image cirros --nic net-id=e0be93b8-728b-4d4d-a272-7d672b2560a6 --security-group NonProd_SG  --key-name linuxtec --availability-zone NonProduction:compute-02  nonprod_testvm
```

### Q:13 如何在特定计算节点上获取配置的虚拟机列表？

答： 假设我们想要获取在 compute-0-19 中配置的虚拟机列表，可以使用如下命令：

命令格式: `openstack server list –all-projects –long -c Name -c Host | grep -i {Compute-Node-Name}`：

```
~# openstack server list --all-projects --long -c Name -c Host | grep -i  compute-0-19
```

### Q:14 如何使用命令行查看 OpenStack 实例的控制台日志？

答： 使用如下命令可查看实例的控制台日志。

首先获取实例的 ID，然后使用如下命令：

```
~# openstack console log show {Instance-id}
```

### Q:15 如何获取 OpenStack 实例的控制台的 URL 地址？

答： 可以使用以下 OpenStack 命令从命令行检索实例的控制台 URL 地址：

```
~# openstack console url show {Instance-id}
```

### Q:16 如何使用命令行创建可启动的 cinder / block 存储卷？

答： 假设创建一个 8GB 可启动存储卷，可参考如下步骤：

* 使用如下命令获取镜像列表

```
~# openstack image list | grep -i cirros
| 89254d46-a54b-4bc8-8e4d-658287c7ee92 | cirros  | active |
```
* 使用 cirros 镜像创建 8GB 的可启动存储卷

```
~# cinder create --image-id 89254d46-a54b-4bc8-8e4d-658287c7ee92 --display-name cirros-bootable-vol  8
```

### Q:17 如何列出所有在你的 OpenStack 中创建的项目或用户？

答： 可以使用如下命令来检索所有项目和用户：

```
~# openstack project list --long
```

### Q:18 如何显示 OpenStack 服务端点列表？

答： OpenStack 服务端点被分为 3 类：

* 公共端点
* 内部端点
* 管理端点

使用如下 OpenStack 命令来查看各种 OpenStack 服务端点：

```
~# openstack catalog list
```

可通过以下命令来显示特定服务端点（比如说 keystone）列表：

```
~# openstack catalog show keystone
```

想了解更多请访问：[OpenStack 中的实例创建流程](https://www.linuxtechi.com/step-by-step-instance-creation-flow-in-openstack/)。

### Q:19 在控制节点上你应该按照什么步骤来重启 nova 服务？

答： 应该按照如下步骤来重启 OpenStack 控制节点的 nova 服务：

* `service nova-api restart`
* `service nova-cert restart`
* `service nova-conductor restart`
* `service nova-consoleauth restart`
* `service nova-scheduler restart`

### Q:20 假如计算节点上为数据流量配置了一些 DPDK 端口，你如何检查 DPDK 端口的状态呢？

答： 因为我们使用 openvSwitch (OVS) 来配置 DPDK 端口，因此可以使用如下命令来检查端口的状态：

```
root@compute-0-15:~# ovs-appctl bond/show | grep dpdk
active slave mac: 90:38:09:ac:7a:99(dpdk0)
slave dpdk0: enabled
slave dpdk1: enabled
root@compute-0-15:~#
root@compute-0-15:~# dpdk-devbind.py --status
```

### Q:21 如何使用命令行在 OpenStack 中向存在的安全组 SG（安全组）中添加新规则？

答： 可以使用 `neutron` 命令向 OpenStack 已存在的安全组中添加新规则：

```
~# neutron security-group-rule-create --protocol <tcp or udp>  --port-range-min <port-number> --port-range-max <port-number> --direction <ingress or egress>  --remote-ip-prefix <IP-address-or-range> Security-Group-Name
```

### Q:22 如何查看控制节点和计算节点的 OVS 桥配置？

答： 控制节点和计算节点的 OVS 桥配置可使用以下命令来查看：

```
~]# ovs-vsctl show
```

### Q:23 计算节点上的集成桥（br-int）的作用是什么？

答： 集成桥（br-int）对来自和运行在计算节点上的实例的流量执行 VLAN 标记和取消标记。

数据包从实例的 n/w 接口发出使用虚拟接口 qvo 通过 Linux 桥（qbr）。qvb 接口是用来连接 Linux 桥的，qvo 接口是用来连接集成桥的。集成桥上的 qvo 端口有一个内部 VLAN 标签，这个标签是用于当数据包到达集成桥的时候贴到数据包头部的。

### Q:24 隧道桥（br-tun）在计算节点上的作用是什么？

答： 隧道桥（br-tun）根据 OpenFlow 规则将 VLAN 标记的流量从集成网桥转换为隧道 ID。

隧道桥允许不同网络的实例彼此进行通信。隧道有利于封装在非安全网络上传输的流量，它支持两层网络，即 GRE 和 VXLAN。

### Q:25 外部 OVS 桥（br-ex）的作用是什么？

答： 顾名思义，此网桥转发来往网络的流量，以允许外部访问实例。br-ex 连接物理接口比如 eth2，这样用户网络的浮动 IP 数据从物理网络接收并路由到用户网络端口。

### Q:26 OpenStack 网络中 OpenFlow 规则的作用是什么？

答： OpenFlow 规则是一种机制，这种机制定义了一个数据包如何从源到达目的地。OpenFlow 规则存储在 flow 表中。flow 表是 OpenFlow 交换机的一部分。

当一个数据包到达交换机就会被第一个 flow 表检查，如果不匹配 flow 表中的任何入口，那这个数据包就会被丢弃或者转发到其他 flow 表中。

### Q:27 怎样查看 OpenFlow 交换机的信息（比如端口、表编号、缓存编号等）？

答： 假如我们要显示 OpenFlow 交换机的信息（br-int），需要执行如下命令：

```
root@compute-0-15# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000fe981785c443
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(patch-tun): addr:3a:c6:4f:bd:3e:3b
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 2(qvob35d2d65-f3): addr:b2:83:c4:0b:42:3a
     config:     0
     state:      0
     current:    10GB-FD COPPER
     speed: 10000 Mbps now, 0 Mbps max
 ………………………………………
```

### Q:28 如何显示交换机中的所有 flow 的入口？

答： 可以使用命令 `ovs-ofctl dump-flows` 来查看交换机的 flow 入口。

假设我们想显示 OVS 集成桥（br-int）的所有 flow 入口，可以使用如下命令：

```
[root@compute01 ~]# ovs-ofctl dump-flows br-int
```

### Q:29 什么是 Neutron 代理？如何显示所有 Neutron 代理？

答： OpenStack Neutron 服务器充当中心控制器，实际网络配置是在计算节点或者网络节点上执行的。Neutron 代理是计算节点或者网络节点上进行配置更新的软件实体。Neutron 代理通过 Neuron 服务和消息队列来和中心 Neutron 服务通信。

可通过如下命令查看 Neutron 代理列表：

```
~# openstack network agent list -c ‘Agent type’ -c Host -c Alive -c State
```

### Q:30 CPU Pinning 是什么？

答： CPU Pinning 是指为某个虚拟机保留物理核心。它也称为 CPU 隔离或处理器关联。有两个目的：

* 它确保虚拟机只能在专用核心上运行
* 它还确保公共主机进程不在这些核心上运行

我们也可以认为 Pinning 是物理核心到一个用户虚拟 CPU（vCPU）的一对一映射。

---

via: <https://www.linuxtechi.com/openstack-interview-questions-answers/>

作者：[Pradeep Kumar](http://www.linuxtechi.com/author/pradeep/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[ScarboroughCoral](https://github.com/ScarboroughCoral) 校对：[wxy](https://github.com/wxy)

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


udev 入门：管理设备事件的 Linux 子系统

Summary: 创建这样一个脚本，当指定的设备插入时触发你的计算机去做一个指定动作。

sdf j

很好的udev介绍

创建这样一个脚本，当指定的设备插入时触发你的计算机去做一个指定动作。

# udev 入门：管理设备事件的 Linux 子系统

>
> 创建这样一个脚本，当指定的设备插入时触发你的计算机去做一个指定动作。
>
>
>

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

udev 是一个为你的计算机提供设备事件的 Linux 子系统。通俗来讲就是，当你的计算机上插入了像网卡、外置硬盘（包括 U 盘）、鼠标、键盘、游戏操纵杆和手柄、DVD-ROM 驱动器等等设备时，代码能够检测到它们。这样就能写出很多可能非常有用的实用程序，而它已经很好了，普通用户就可以写出脚本去做一些事情，比如当某个硬盘驱动器插入时，执行某个任务。

这篇文章教你去如何写一个由一些 udev 事件触发的 [udev](https://linux.die.net/man/8/udev) 脚本，比如插入了一个 U 盘。当你理解了 udev 的工作原理，你就可以用它去做各种事情，比如当一个游戏手柄连接后加载一个指定的驱动程序，或者当你用于备份的驱动器连接后，自动执行备份工作。

### 一个初级的脚本

使用 udev 的最佳方式是从一个小的代码块开始。不要指望从一开始就写出完整的脚本，而是从最简单的确认 udev 触发了某些指定的事件开始。

对于你的脚本，依据你的目标，并不是在任何情况下都能保证你亲眼看到你的脚本运行结果的，因此需要在你的脚本日志中确认它成功触发了。而日志文件通常放在 `/var` 目录下，但那个目录通常是 root 用户的领地。对于测试目的，可以使用 `/tmp`，它可以被普通用户访问并且在重启动后就被清除了。

打开你喜欢的文本编辑器，然后输入下面的简单脚本：

```
#!/usr/bin/bash

echo $date > /tmp/udev.log
```

把这个脚本放在 `/usr/local/bin` 或缺省可运行路径的位置中。将它命名为 `trigger.sh`，并运行 `chmod +x` 授予可运行权限：

```
$ sudo mv trigger.sh /usr/local/bin
$ sudo chmod +x /usr/local/bin/trigger.sh
```

这个脚本没有任何和 udev 有关的事情。当它运行时，这个脚本将在文件 `/tmp/udev.log` 中放入当前的时间戳。你可以自己测试一下这个脚本：

```
$ /usr/local/bin/trigger.sh
$ cat /tmp/udev.log
Tue Oct 31 01:05:28 NZDT 2035
```

接下来让 udev 去触发这个脚本。

### 唯一设备识别

为了让你的脚本能够被一个设备事件触发，udev 必须要知道在什么情况下调用该脚本。在现实中，你可以通过它的颜色、制造商、以及插入到你的计算机这一事实来识别一个 U 盘。而你的计算机，它需要一系列不同的标准。

udev 通过序列号、制造商、以及提供商 ID 和产品 ID 号来识别设备。由于现在你的 udev 脚本还处于它的生命周期的早期阶段，因此要尽可能地宽泛、非特定和包容。换句话说就是，你希望首先去捕获尽可能多的有效 udev 事件来触发你的脚本。

使用 `udevadm monitor` 命令你可以实时利用 udev，并且可以看到当你插入不同设备时发生了什么。用 root 权限试一试。

```
$ su
# udevadm monitor
```

该监视函数输出接收到的事件：

* UDEV：在规则处理之后发出 udev 事件
* KERNEL：内核发送 uevent 事件

在 `udevadm monitor` 命令运行时，插入一个 U 盘，你将看到各种信息在你的屏幕上滚动而出。注意那一个 `ADD` 事件的事件类型。这是你所需要的识别事件类型的一个好方法。

`udevadm monitor` 命令提供了许多很好的信息，但是你可以使用 `udevadm info` 命令以更好看的格式来看到它，假如你知道你的 U 盘当前已经位于你的 `/dev` 树。如果不在这个树下，拔下它并重新插入，然后立即运行这个命令：

```
$ su -c 'dmesg | tail | fgrep -i sd*'
```

举例来说，如果那个命令返回 `sdb: sdb1`，说明内核已经给你的 U 盘分配了 `sdb` 卷标。

或者，你可以使用 `lsblk` 命令去查看所有连接到你的系统上的驱动器，包括它的大小和分区。

现在，你的驱动器已经处于你的文件系统中了，你可以使用下面的命令去查看那个设备的相关 udev 信息：

```
# udevadm info -a -n /dev/sdb | less
```

这个命令将返回许多信息。现在我们只关心信息中的第一个块。

你的任务是从 udev 的报告中找出能唯一标识那个设备的部分，然后当计算机检测到这些唯一属性时，告诉 udev 去触发你的脚本。

`udevadm info` 命令处理一个（由设备路径指定的）设备上的报告，接着“遍历”父级设备链。对于找到的大多数设备，它以一个“键值对”格式输出所有可能的属性。你可以写一个规则，从一个单个的父级设备属性上去匹配插入设备的属性。

```
looking at device '/devices/000:000/blah/blah//block/sdb':
  KERNEL=="sdb"
  SUBSYSTEM=="block"
  DRIVER==""
  ATTR{ro}=="0"
  ATTR{size}=="125722368"
  ATTR{stat}==" 2765 1537 5393"
  ATTR{range}=="16"
  ATTR{discard\_alignment}=="0"
  ATTR{removable}=="1"
  ATTR{blah}=="blah"
```

一个 udev 规则必须包含来自单个父级设备的一个属性。

父级属性是描述一个设备的最基本的东西，比如它是插入到一个物理端口的东西、或是一个容量多大的东西、或这是一个可移除的设备。

由于 `KERNEL` 卷标 `sdb` 可能会由于分配给在它之前插入的其它驱动器而发生变化，因此卷标并不是一个 udev 规则的父级属性的好选择。但是，在做概念论证时你可以使用它。一个事件的最佳候选者是 `SUBSYSTEM` 属性，它表示那个设备是一个 “block” 系统设备（也就是为什么我们要使用 `lsblk` 命令来列出设备的原因）。

在 `/etc/udev/rules.d` 目录中打开一个名为 `80-local.rules` 的文件，然后输入如下代码：

```
SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"
```

保存文件，拔下你的测试 U 盘，然后重启动系统。

等等，重启动 Linux 机器？

理论上说，你只需要运行 `udevadm control —reload` 即可，它将重新加载所有规则，但是在我们实验的现阶段，最好要排除可能影响实验结果的所有因素。udev 是非常复杂的，为了不让你躺在床上整晚都在思考为什么这个规则不能正常工作，是因为语法错误吗？还是应该重启动一下。所以，不管 POSIX 自负地告诉你过什么，你都应该去重启动一下。

当你的系统重启动完毕之后，（使用 `Ctl+Alt+F3` 或类似快捷键）切换到一个文本控制台，并插入你的 U 盘。如果你运行了一个最新的内核，当你插入 U 盘后你或许可以看到一大堆输出。如果看到一个错误信息，比如 “Could not execute /usr/local/bin/trigger.sh”，或许是因为你忘了授予这个脚本可运行的权限。否则你将看到的是，一个设备插入，它得到内核设备分配的一些东西，等等。

现在，见证奇迹的时刻到了。

```
$ cat /tmp/udev.log
Tue Oct 31 01:35:28 NZDT 2035
```

如果你在 `/tmp/udev.log` 中看到了最新的日期和时间，那么说明 udev 已经成功触发了你的脚本。

### 改进规则做一些有用的事情

现在的问题是使用的规则太通用了。插入一个鼠标、一个 U 盘、或某个人的 U 盘都将盲目地触发这个脚本。现在，我们开始专注于希望触发你的脚本的是确定的某个 U 盘。

实现上述目标的一种方式是使用提供商 ID 和产品 ID。你可以使用 `lsusb` 命令去得到这些数字。

```
$ lsusb
Bus 001 Device 002: ID 8087:0024 Slacker Corp. Hub
Bus 002 Device 002: ID 8087:0024 Slacker Corp. Hub
Bus 003 Device 005: ID 03f0:3307 TyCoon Corp.
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 hub
Bus 001 Device 003: ID 13d3:5165 SBo Networks
```

在这个例子中，`TyCoon Corp` 前面的 `03f0:3307` 就表示了提供商 ID 和产品 ID 的属性。你也可以通过 `udevadm info -a -n /dev/sdb | grep vendor` 的输出来查看这些数字，但是从 `lsusb` 的输出中可以很容易地一眼找到这些数字。

现在，可以在你的脚本中包含这些属性了。

```
SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/thumb.sh"
```

测试它（是的，为了确保不会有来自 udev 的影响因素，我们仍然建议先重新启动一下），它应该会像前面一样工作，现在，如果你插入一个不同公司制造的 U 盘（因为它们的提供商 ID 不一样）、或插入一个鼠标、或插入一个打印机，这个脚本将不会被触发。

继续添加新属性来进一步专注于你希望去触发你的脚本的那个唯一的 U 盘。使用 `udevadm info -a -n /dev/sdb` 命令，你可以找出像提供商名字、序列号、或产品名这样的东西。

为了保证思路清晰，确保每次只添加一个新属性。我们（和在网上看到的其他人）在 udev 规则中所遇到的大多数错误都是因为一次添加了太多的属性，而奇怪为什么不能正常工作了。逐个测试属性是最安全的作法，这样可以确保 udev 能够成功识别到你的设备。

### 安全

编写 udev 规则当插入一个驱动器后自动去做一些事情，将带来安全方面的担忧。在我的机器上，我甚至都没有打开自动挂载功能，而基于本文的目的，当设备插入时，脚本和规则可以运行一些命令来做一些事情。

在这里需要记住两个事情。

1. 聚焦于你的 udev 规则，当你真实地使用它们时，一旦让规则发挥作用将触发脚本。执行一个脚本去盲目地复制数据到你的计算上，或从你的计算机上复制出数据，是一个很糟糕的主意，因为有可能会遇到一个人拿着和你相同品牌的 U 盘插入到你的机器上的情况。
2. 不要在写了 udev 规则和脚本后忘记了它们的存在。我知道哪个计算上有我的 udev 规则，这些机器一般是我的个人计算机，而不是那些我带着去开会或办公室工作的计算机。一台计算机的 “社交” 程度越高，它就越不能有 udev 规则存在于它上面，因为它将潜在地导致我的数据最终可能会出现在某个人的设备、或某个人的数据中、或在我的设备上出现恶意程序。

换句话说就是，随着一个 GNU 系统提供了一个这么强大的功能，你的任务是小心地如何使用它们的强大功能。如果你滥用它或不小心谨慎地使用它，最终将让你出问题，它非常可能会导致可怕的问题。

### 现实中的 Udev

现在，你可以确认你的脚本是由 udev 触发的，那么，可以将你的关注点转到脚本功能上了。到目前为止，这个脚本是没有用的，它除了记录脚本已经运行过了这一事实外，再没有做更多的事情。

我使用 udev 去触发我的 U 盘的 [自动备份](https://gitlab.com/slackermedia/attachup) 。这个创意是，将我正在处理的文档的主副本保存在我的 U 盘上（因为我随身带着它，这样就可以随时处理它），并且在我每次将 U 盘插入到那台机器上时，这些主文档将备份回我的计算机上。换句话说就是，我的计算机是备份驱动器，而产生的数据是移动的。源代码是可用的，你可以随意查看 `attachup` 的代码，以进一步限制你的 udev 的测试示例。

虽然我使用 udev 最多的情况就是这个例子，但是 udev 能抓取很多的事件，像游戏手柄（当连接游戏手柄时，让系统去加载 xboxdrv 模块）、摄像头、麦克风（当指定的麦克风连接时用于去设置输入），所以应该意识到，它能做的事情远比这个示例要多。

我的备份系统的一个简化版本是由两个命令组成的一个过程：

```
SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", SYMLINK+="safety%n"
SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"
```

第一行使用属性去检测我的 U 盘，这在前面已经讨论过了，接着在设备树中为我的 U 盘分配一个符号链接，给它分配的符号连接是 `safety%n`。这个 `%n` 是一个 udev 宏，它是内核分配给这个设备的任意数字，比如 sdb1、sdb2、sdb3、等等。因此 `%n` 应该是 1 或 2 或 3。

这将在 dev 树中创建一个符号链接，因此它不会干涉插入一个设备的正常过程。这意味着，如果你在自动挂载设备的桌面环境中使用它，将不会出现问题。

第二行运行这个脚本。

我的备份脚本如下：

```
#!/usr/bin/bash

mount /dev/safety1 /mnt/hd
sleep 2
rsync -az /mnt/hd/ /home/seth/backups/ && umount /dev/safety1
```

这个脚本使用符号链接，这将避免出现 udev 命名导致的意外情况（例如，假设一个命名为 DISK 的 U 盘已经插入到我的计算机上，而我插入的其它 U 盘恰好名字也是 DISK，那么第二个 U 盘的卷标将被命名为 `DISK_`，这将导致我的脚本不会正常运行），它在我喜欢的挂载点 `/mnt/hd` 上挂载了 `safety1`（驱动器的第一个分区）。

一旦 `safely` 挂载之后，它将使用 [rsync](https://opensource.com/article/17/1/rsync-backup-linux) 将驱动器备份到我的备份文件夹（我真实使用的脚本用的是 `rdiff-backup`，而你可以使用任何一个你喜欢的自动备份解决方案）。

### udev 让你的设备你做主

udev 是一个非常灵活的系统，它可以让你用其它系统很少敢提供给用户的方式去定义规则和功能。学习它，使用它，去享受 POSIX 的强大吧。

本文内容来自 [Slackermedia Handbook](http://slackermedia.info/handbook/doku.php?id=backup)，它以 [GNU Free Documentation License 1.3](http://www.gnu.org/licenses/fdl-1.3.html) 许可证授权使用。

---

via: <https://opensource.com/article/18/11/udev>

作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[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/) 荣誉推出


NASA 在开放科学方面做了些什么

Summary: 在这篇文章中我们主要讨论了 NASA 的积极努力，这些努力包括他们通过开源实践来促进科学研究的积极作用。

# NASA 在开放科学方面做了些什么

最近我们刚为开设了一个新的“[科学类](https://itsfoss.com/category/science/)”的文章分类。其中发表的最新一篇文章名为：[开源是怎样影响科学的](https://itsfoss.com/open-source-impact-on-science/)。在这篇文章中我们主要讨论了 [NASA](https://www.nasa.gov/) 的积极努力，这些努力包括他们通过开源实践来促进科学研究的积极作用。

### NASA 是怎样使用开源手段促进科学研究的

NASA 将他们的整个研究库对整个公共领域开放，这是一项[壮举](https://futurism.com/free-science-nasa-just-opened-its-entire-research-library-to-the-public/)。

没错！每个人都能访问他们的整个研究库，并能从他们的研究中获益。

他们现已开放的资料可以大致分为以下三类：

* 开源 NASA
* 开放 API
* 开放数据

### 1、开源 NASA

这里有一份 [GitHub](https://github.com/) 的联合创始人之一和执行总裁 [Chris Wanstrath](http://chriswanstrath.com/) 的采访，他向我们介绍道，一切都是从很多年前开始的。

该项目名为 “[code.nasa.gov](http://code.nasa.gov)”，截至本文发表为止，NASA 已经[通过 GitHub 开源](https://github.com/open-source)了 365 个科学软件（LCTT 译注：本文原文发表于 2018/3/28，截止至本译文发布，已经有 454 个项目了）。对于一位热爱程序的开发者来说，即使一天研究一个软件，想把 NASA 的这些软件全部研究过来也要整整一年的时间。

即使你不是一位开发者，你也可以在这个门户网站浏览这个壮观的软件合集。

其中就有[阿波罗 11 号](https://www.nasa.gov/mission_pages/apollo/missions/apollo11.html)的制导计算机的源代码。阿波罗 11 号空间飞行器[首次将两名人类带上月球](https://www.space.com/16758-apollo-11-first-moon-landing.html)，分别是 [Neil Armstrong](https://www.jsc.nasa.gov/Bios/htmlbios/armstrong-na.html) 和 [Edwin Aldrin](https://www.jsc.nasa.gov/Bios/htmlbios/aldrin-b.html) 。如果你对 Edwin Aldrin 感兴趣，可以点击[这里](https://buzzaldrin.com/the-man/)了解更多。

#### NASA 开源代码促进会使用的开源代码许可

它们采用了几种[开源许可证](https://itsfoss.com/open-source-licenses-explained/)，其分类如下：

* [Apache 许可证 2.0](https://www.apache.org/licenses/LICENSE-2.0)
* [Nasa 开源许可证 3.0](https://opensource.org/licenses/NASA-1.3)
* [GPL v3](https://www.gnu.org/licenses/gpl.html)
* [MIT 许可证](https://en.wikipedia.org/wiki/MIT_License)

### 2、开放 API

开放 [API](https://en.wikipedia.org/wiki/Application_programming_interface) 在推行开放科学中起到了很大作用。与[开源促进会](https://opensource.org/)类似，对于 API，也有一个 [开放 API 促进会](https://www.openapis.org/)。下面这张示意图可以告诉你 API 是怎样将应用程序和它的开发者连接起来的。

记得点击这个[链接](https://sproutsocial.com/insights/what-is-an-api/)看看。链接内的文章使用了简单易懂的方法解读了 API ，文末总结了五大要点。

这会让你感受到专有 API 和开放 API 会有多么大的不同。

[NASA 的 Open API](https://api.nasa.gov/) 主要针对应用程序开发者，旨在显著改善数据的可访问性，也包括图片内容在内。该网站有一个实时编辑器，可供你调用[每日天文一图（APOD）](https://apod.nasa.gov/apod/astropix.html) 的 API。

#### 3、开放数据

在[我们发布的第一篇开放科学的文章](https://itsfoss.com/open-source-impact-on-science/)中，我们在“开放科学”段落下提到的三个国家 —— 法国、印度和美国的多种开放数据形式。NASA 有着类似的想法和行为。这种重要的意识形态已经被[多个国家](https://www.xbrl.org/the-standard/why/ten-countries-with-open-data/)所接受。

[NASA 的开放数据门户](https://data.nasa.gov/)致力于开放，拥有不断增长的可供大众自由使用的开放数据。将数据集纳入到这个数据集对于任何研究活动来说都是必要且重要的。NASA 还在他们的门户网站上征集各方的数据需求，以一同收录在他们的数据库中。这一举措不仅是领先的、创新的，还顺应了[数据科学](https://en.wikipedia.org/wiki/Data_science)、[AI 和深度学习](https://www.kdnuggets.com/2017/07/ai-deep-learning-explained-simply.html)的趋势。

下面的视频讲的是学者和学生们是怎样通过大量研究得出对数据科学的定义的。这个过程十分的激动人心。瑞尔森大学罗杰斯商学院的 [Murtaza Haider 教授](https://www.ryerson.ca/tedrogersschool/bm/programs/real-estate-management/murtaza-haider/)在视频结尾中提到了开源的出现对数据科学的改变，尤其让是旧有的闭源方式逐渐变得开放。而这也确实成为了现实。

现在任何人都能在 NASA 上征集数据。正如前面的视频中所说，NASA 的举措很大程度上与征集和分析优化数据有关。

你只需要免费注册即可。考虑到论坛上的公开讨论以及数据集在可能存在的每一类分析领域中的重要性，这一举措在未来会有非常积极的影响，对数据的统计分析当然也会大幅进展。在之后的文章中我们还会具体讨论这些细节，还有它们和开源模式之间的相关性。

以上就是对 NASA 开放科学模式的一些探索成就，希望您能继续关注我们接下来的相关文章！

---

via: <https://itsfoss.com/nasa-open-science/>

作者：[Avimanyu Bandyopadhyay](https://itsfoss.com/author/avimanyu/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Valoniakim](https://github.com/Valoniakim) 校对：[wxy](https://github.com/wxy)

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


一个免费、安全、跨平台的密码管理器

# 一个免费、安全、跨平台的密码管理器

在这个现代化的互联网时代，你一定在许多网站上有多个账户，它可能是个人或官方邮箱账户、社交或专业网络账户、GitHub 账户和电子商务账户等。因此，对于不同的账户，你应该设置多个不同的密码。我相信你应该已经意识到为多个账户设置相同的密码是件疯狂又危险的事情。如果攻击者设法破解了你的一个账户，那么他/她很可能尝试使用相同的密码访问你的其他账户。所以，**强烈建议为不同的账户设置不同的密码**。

不过，记住好几个密码是很困难的。你可以把它们写在纸上，但那也不是一个有效的方法，你可能会在一段时间后失去它们。这时密码管理器就派上用场了。密码管理器就像一个存储库，你可以在其中存储不同账户的所有密码，并用一个主密码将其锁定。这样，你需要记住的就只剩下主密码了。之前我们介绍过一个叫 [KeeWeb](/article-10211-1.html) 的开源密码管理器，今天，我们将介绍另外一款密码管理器 ——— Buttercup。

### 关于 Buttercup

Buttercup 是一个自由、开源、安全、跨平台的密码管理器，使用 **NodeJS** 编写。它可以帮助你将不同账户的所有登录凭证存储到加密存档中，该存档可以保存在本地系统或任何远程服务（如 DropBox、OwnCloud、NextCloud 和基于 WebDAV 的服务）中。它使用强大的 **256 位 AES 加密算法**，用主密码保存你的敏感数据。所以，除了拥有主密码的人以外，没有人可以访问你的登录信息。Buttercup 目前支持 Linux、Mac OS 和 Windows，还提供了一个浏览器扩展和移动应用程序。因此，你也可以在 Android 和 iOS 设备中的桌面应用程序和浏览器扩展程序中使用相同的存档。

### 安装 Buttercup 密码管理器

Buttercup 目前在 Linux 平台上有 .deb、.rpm 软件包、可移植的 AppImage 和 tar 归档文件等安装包。转到其 [发布页](https://github.com/buttercup/buttercup-desktop/releases/latest) 下载安装你想要的版本。

Buttercup 桌面应用程序在 [AUR](https://aur.archlinux.org/packages/buttercup-desktop/) 中也可用，你可以使用 AUR 帮助程序（如 [Yay](https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/)）在基于 Arch 的系统上安装，如下所示：

```
$ yay -S buttercup-desktop
```

如果你已经下载了方便的 AppImage 文件，使用如下命令让它执行：

```
$ chmod +x buttercup-desktop-1.11.0-x86_64.AppImage
```

然后，使用命令启动它：

```
$ ./buttercup-desktop-1.11.0-x86_64.AppImage
```

运行此命令后，会提示是否要将 Buttercup AppImage 集成到你的系统中。如果选择 “Yes”，则会将其添加到应用程序菜单并安装图标。如果不这样做，你仍然可以通过双击 AppImage 或在终端中使用上述命令启动应用程序。

### 添加存档

第一次启动时，会看到下面的欢迎界面：

我们还没有添加任何存档，所以让我们添加一个吧。单击 “New Archive File” 按钮，输入存档文件的名称，并选择它的保存位置。

你可以随意命名。我把它命名为 “mypass”，存档将以 .bcup 为扩展名保存在你选择的位置。

如果你已经创建了一个，只需单击 “Open Archive File” 来选择它。

接下来，Buttercup 将提示你为新创建的存档输入主密码，建议提供一个强级别的密码，以保护存档不会被未经授权访问。

现在我们已经创建了一个存档并使用主密码对其进行了保护。类似地，你可以创建任意数量的存档，并使用密码保护它们。

让我们继续在存档中添加账户的详细信息。

### 在存档中添加条目（登录凭证）

创建或打开存档后，你将看到下面的界面。

它就像一个保险库，我们将保存不同账户的登录凭证。如你所见，我们并没有添加任何条目。让我们添加一些。

点击右下角的 “ADD ENTRY” 按钮来添加新的条目，输入你想要保存的账户的信息。

在每个条目下面都有一个 “ADD NEW FIELD” 选项，可以用来添加其他的细节。只需点击它，然后添加要包含在条目中的字段。

添加完所有条目后，你将在 Buttercup 界面的右侧窗格中看到它们。

### 添加新的分组

你还可以将登录的详细信息分组到不同的名称下，以便于识别。例如，你可以将所有邮箱账户分组到一个名为 “my\_mails” 的名称下。默认情况下，你的登录详细信息将保存在 “General” 群组下。要创建新的群组，请点击 “NEW GROUP” 按钮并输入名称。在新的群组中创建新条目时，与上述的步骤相同，只需单击组名并开始添加条目。

### 管理和访问登录的详细信息

存储在存档中的数据可以随时编辑、移动到其他组或彻底删除。例如，如果要将用户名或密码复制到剪切板，请右击该条目，然后选择 “Copy to Clipboard”。

要进一步编辑/修改数据，只需点击所选条目下的 “Edit” 按钮。

### 在远程保存存档

默认情况下，Buttercup 会将数据保存在本地系统上。但是，你可以将它们保存在不同的远程服务（例如 Dropbox、OwnCloud、NextCloud 和基于 WebDAV 的服务）上。

要连接这些服务，请点击 “File -> Connect Cloud Sources”。

接下来，选择要连接的服务并对其授权以保存数据。

你还可以在添加存档时在 Buttercup 的欢迎界面连接这些服务。

### 导入/导出

Buttercup 允许你向其他密码管理器（例如 1Password、Lastpass 和 KeePass）导入导出数据。你也可以导出数据，在另一个系统或设备（例如 Android）中访问它们。你还可以将 Buttercup 保险库导出为 CSV 格式文件。

Buttercup 是一个简单但成熟、功能齐全的密码管理器。多年来它一直在积极开发。如果你需要密码管理器，Buttercup 可能是个不错的选择。有关更多的详细信息，请参阅项目网站和 GitHub 页面。

那就介绍到这里，希望它对你有用。更多的精彩内容即将到来，敬请关注！

谢谢！

### 资源

* [Buttercup 网站](https://buttercup.pw/)
* [Buttercup GitHub 仓库](https://github.com/buttercup/buttercup-desktop)

---

via: <https://www.ostechnix.com/buttercup-a-free-secure-and-cross-platform-password-manager/>

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

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


极客漫画：编程语言之战

Summary: 这篇漫画生动的描绘了不同时期不同编程语言的“战争”。

ItsLucas dalao（x

来自河北廊坊的 Chrome Mobile 70.0|Android 8.1 用户

勇士为了屠龙而把自己锻炼的和龙一样强大，

但这些年过去，勇士回头看，一群新人和新的野心震慑了他

没有办法

于是他成为了龙

这篇漫画生动的描绘了不同时期不同编程语言的“战争”。

# 极客漫画：编程语言之战

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

这篇漫画生动的描绘了不同时期不同编程语言的“战争”。

COBOL 是一种面向数据处理的、面向文件的、面向过程（POL）的高级编程语言，功能强大，但缺点是语法繁杂，代码冗长（看它肥的）。而 Java 当时还是个弱小的新生事物。

后来，Java 慢慢发展壮大了，内存吃的越来越多了（都和 COBOL 一样又高又肥了），当 Java 准备再去打一架的时候，COBOL 提醒他注意身后想打他们两个的三个小娃娃（Scala、Kotlin、Go）。

长江后浪推前浪。编程语言的发展很快，不停的会有功能更强的新“轮子”出现在我们眼前。而我们则需了解各个语言的优缺点，与时俱进地看待它们。

---

via: <http://turnoff.us/geek/programming-languages-battle/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者：[ItsLucas](https://github.com/ItsLucas) 点评：[ItsLucas](https://github.com/ItsLucas) 校对：[Bestony](https://github.com/bestony) 合成：[Bestony](https://github.com/bestony)

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


感谢开源和自由软件维护者的 10 种方法

Summary: 如何表达你的感激之情。

# 感谢开源和自由软件维护者的 10 种方法

>
> 如何表达你的感激之情。
>
>
>

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

每天，我使用的那些高质量的软件 —— 开发和维护这些软件的人不需要我为之付款，他们尊重我的自由，并且慷慨地付出时间和精力。

在这个感恩的季节，我鼓励那些也使用和欣赏开源和自由软件维护者工作的人表达你的感激之情。以下是十种方法：

### 容易做到的

1、发送电子邮件感谢开发人员。具体点说，告诉他们你使用他们的什么软件以及它是如何帮助了你。

2、使用你最喜爱的社交媒体平台宣传它。

3、写一篇关于你最喜欢的软件的博客文章。

### 捐款

4、如果你最喜欢的开源项目接受捐款，请汇款。

5、如果你受雇于使用开源软件的公司，看你是否可以说服管理层赞助某些项目。

6、尽你所能地捐款。社交动机能做的不可思议！

### 花费时间

7、帮助审查补丁。

8、帮助分类 bug。

9、回答 IRC、邮件列表或 [Stack Overflow](https://meta.stackoverflow.com/) 中的问题。

**10、额外的：**如果你像我一样，你在某个时候对开源社区的其他人说了一些严厉的话。承诺做得更好：用善良和开放沟通。感谢的最好方式是让开源社区成为人们能舒适沟通的地方。

---

via: <https://opensource.com/article/18/11/ways-give-thanks-open-source>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[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/) 荣誉推出


Emacs 系列（四）：使用 Org 模式自动管理邮件及同步文档

Summary: “我真的很想让它在我所有的设备上同步。”“我能在 Org 模式中转发邮件吗？”

“我真的很想让它在我所有的设备上同步。”“我能在 Org 模式中转发邮件吗？”

# Emacs 系列（四）：使用 Org 模式自动管理邮件及同步文档

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

这是 [Emacs 和 Org 模式系列](https://www.emacswiki.org/emacs/mu4e)的第四篇。

至今为止，你已经见识到了 Org 模式的强大和高效，如果你像我一样，你可能会想：

>
> “我真的很想让它在我所有的设备上同步。”
>
>
>

或者是说：

>
> “我能在 Org 模式中转发邮件吗？”
>
>
>

答案当然是肯定的，因为这就是 Emacs。

### 同步

由于 Org 模式只使用文本文件，所以使用任意工具都可以很容易地实现同步。我使用的是 git 的 `git-remote-gcrypt`。由于 `git-remote-gcrypt` 的一些限制，每台机器都倾向于推到自己的分支，并使用命令来控制。每台机器都会先合并其它所有的分支，然后再将合并后的结果推送到主干上。cron 作业可以实现将机器上的分支推送上去，而 elisp 会协调这一切 —— 确保在同步之前保存缓冲区，在同步之后从磁盘刷新缓冲区，等等。

这篇文章的代码有点多，所以我将把它链接到 github 上，而不是写在这里。

我有一个用来存放我所有的 Org 模式的文件的目录 `$HOME/org`，在 `~/org` 目录下有个 [Makefile](https://github.com/jgoerzen/public-snippets/blob/master/emacs/org-tools/Makefile) 文件来处理同步。该文件定义了以下目标：

* `push`： 添加、提交和推送到以主机命名的分支上
* `fetch`： 一个简单的 `git fetch` 操作
* `sync`： 添加、提交和拉取远程的修改，合并，并（假设合并成功）将其推送到以主机命名的分支和主干上

现在，在我的用户 crontab 中有这个：

```
*/15 * * * * make -C $HOME/org push fetch 2>&1 | logger --tag 'orgsync'
```

[与之相关的 elisp 代码](https://github.com/jgoerzen/public-snippets/blob/master/emacs/org-tools/emacs-config.org) 定义了一个快捷键（`C-c s`）来调用同步。多亏了 cronjob，只要文件被保存 —— 即使我没有在另一个机器上同步 —— 它们也会被拉取进来。

我发现这个设置非常好用。

### 用 Org 模式发邮件

在继续下去之前，首先要问自己一下：你真的需要它吗？ 我用的是带有 [mu4e](https://www.emacswiki.org/emacs/mu4e) 的 Org 模式，而且它集成的也很好；任何 Org 模式的任务都可以通过 `Message-id` 链接到电子邮件，这很理想 —— 它可以让一个人做一些事情，比如提醒他在一周内回复一条消息。

然而，Org 模式不仅仅只有提醒。它还是一个知识库、创作系统等，但是并不是我所有的邮件客户端都使用 mu4e。(注意：移动设备中有像 MobileOrg 这样的应用)。我并没有像我想的那样经常使用它，但是它有它的用途，所以我认为我也应该在这里记录它。

现在我不仅想处理纯文本电子邮件。我希望能够处理附件、HTML 邮件等。这听起来很快就有问题了 —— 但是通过使用 ripmime 和 pandoc 这样的工具，情况还不错。

第一步就是要用某些方法将获取到的邮件放入指定的文件夹下。扩展名、特殊用户等。然后我用一个 [fetchmail 配置](https://github.com/jgoerzen/public-snippets/blob/master/emacs/org-tools/fetchmailrc.orgmail) 来将它拉取下来并运行我自己的 [insorgmail](https://github.com/jgoerzen/public-snippets/blob/master/emacs/org-tools/insorgmail) 脚本。

这个脚本就是处理所有有趣的部分了。它开始用 ripmime 处理消息，用 pandoc 将 HTML 的部分转换为 Org 模式的格式。 Org 模式的层次结构是用来尽可能最好地表示 email 的结构。使用 HTML 和其他工具时，email 可能会变得相当复杂，但我发现这对于我来说是可以接受的。

### 下一篇

我最后一篇关于 Org 模式的文章将讨论如何使用它来编写文档和准备幻灯片 —— 我发现自己对 Org 模式的使用非常满意，但这需要一些调整。

---

via: <http://changelog.complete.org/archives/9898-emacs-4-automated-emails-to-org-mode-and-org-mode-syncing>

作者：[John Goerzen](http://changelog.complete.org/) 译者：[oneforalone](https://github.com/oneforalone) 校对：[wxy](https://github.com/wxy)

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


在 Linux 命令行下进行时间管理

Summary: 学习如何在命令行下用这些方法自己组织待办事项。

学习如何在命令行下用这些方法自己组织待办事项。

# 在 Linux 命令行下进行时间管理

>
> 学习如何在命令行下用这些方法自己组织待办事项。
>
>
>

关于如何在命令行下进行<ruby> 时间管理 <rt>  getting things done </rt></ruby>（GTD）有很多讨论。不知有多少文章在讲使用 ls 晦涩的选项、配合 Sed 和 Awk 的一些神奇的正则表达式，以及用 Perl 解析一大堆的文本。但这些都不是问题的重点。

本文章是关于“[如何完成](https://www.scruminc.com/getting-done/)”，在我们不需要图形桌面、网络浏览器或网络连接情况下，用命令行操作能实际完成事务的跟踪。为了达到这一点，我们将介绍四种跟踪待办事项的方式：纯文件文件、Todo.txt、TaskWarrior 和 Org 模式。

### 简单纯文本

*我喜欢用 Vim，其实你也可以用 Nano。*

最直接管理你的待办事项的方式就是用纯文本文件来编辑。只需要打开一个空文件，每一行添加一个任务。当任务完成后，删除这一行。简单有效，无论你用它做什么都没关系。不过这个方法也有两个缺点，一但你删除一行并保存了文件，它就是永远消失了。如果你想知道本周或者上周都做了哪些事情，就成了问题。使用简单文本文件很方便却也容易导致混乱。

### Todo.txt: 纯文件的升级版

*整洁，有条理，易用*

这就是我们要说的 [Todo.txt](http://todotxt.org/) 文件格式和应用程序。安装很简单，可从 GitHub [下载](https://github.com/todotxt/todo.txt-cli/releases)最新的版本解压后并执行命令 `sudo make install` 。

*也可以从 Git 克隆一个。*

Todo.txt 可以很容易的增加新任务，并能显示任务列表和已完成任务的标记：

| 命令 | 说明 |
| --- | --- |
| `todo.sh add "某任务"` | 增加 “某任务” 到你的待办列表 |
| `todo.sh ls` | 显示所有的任务 |
| `todo.sh ls due:2018-02-15` | 显示2018-02-15之前的所有任务 |
| `todo.sh do 3` | 标记任务3 为已完成任务 |

这个清单实际上仍然是纯文本，你可以用你喜欢的编辑器遵循[正确的格式](https://github.com/todotxt/todo.txt)编辑它。

该应用程序同时也内置了一个强大的帮助系统。

*你可以使用语法高亮的功能*

此外，还有许多附加组件可供选择，以及编写自己的附件组件规范。甚至有浏览器组件、移动设备应用程序和桌面应用程序支持 Todo.txt 的格式。

*GNOME的扩展组件*

Todo.txt 最大的缺点是缺少自动或内置的同步机制。大多数（不是全部）的浏览器扩展程序和移动应用程序需要用 Dropbox 实现桌面系统和应用程序直接的数据同步。如果你想内置同步机制，我们有……

### Taskwarrior: 现在我们用 Python 做事了

*花哨吗？*

[Taskwarrior](https://taskwarrior.org/) 是一个与 Todo.txt 有许多相同功能的 Python 工具。但不同的是它的数据保存在数据库里并具有内置的数据同步功能。它还可以跟踪即将要做的任务，可以提醒某个任务持续了多久，可以提醒你一些重要的事情应该马上去做。

*看起来不错*

[安装](https://taskwarrior.org/download/) Taskwarrior 可以通过通过发行版自带的包管理器，或通过 Python 命令 `pip` 安装，或者用源码编译。用法也和 Todo.txt 的命令完全一样：

| 命令 | 说明 |
| --- | --- |
| `task add "某任务"` | 增加 “某任务” 到任务清单 |
| `task list` | 列出所有任务 |
| `task list due``:today` | 列出截止今天的任务 |
| `task do 3` | 标记编号是3的任务为完成状态 |

Taskwarrior 还有漂亮的文本用户界面。

*我喜欢 Vit, 它的设计灵感来自 Vim*

不同于 Todo.txt，Taskwarrior 可以和本地或远程服务器同步信息。如果你希望运行自己的同步服务器可以使用名为 `taskd` 的非常基本的服务器，如果不使用自己的服务器也有好几个可用服务器。

Taskwarriot 还拥有一个蓬勃发展的插件和扩展生态系统，以及移动和桌面系统的应用。

*在 GNOME 下的 Taskwarrior 看起来还是很漂亮的。*

Taskwarrior 有一个唯一的缺点，你是不能直接修改待办任务的，这和其他的工具不一样。你只能把任务清单按照格式导出，然后修改导出文件后，重新再导入，这样相对于编辑器直接编辑任务还是挺麻烦的。

谁能给我们带来最大的希望呢……

### Emacs Org 模式：牛X的任务收割机

*Emacs 啥都有*

Emacs [Org 模式](https://orgmode.org/) 是目前为止最强大、最灵活的开源待办事项管理器。它支持多文件、使用纯文本、高度可定制、自动识别日期、截止日期和任务计划。相对于我们这里介绍的其他工具，它的配置也更复杂一些。但是一旦配置好，它可以比其他工具完成更多功能。如果你是熟悉或者是 [Bullet Journals](http://bulletjournal.com/) 的粉丝，Org 模式可能是在桌面程序里最像[Bullet Journals](http://bulletjournal.com/) 的了。

Emacs 能运行，Org 模式就能运行，一些移动应用程序可以和它很好交互。但是不幸的是，目前没有桌面程序或浏览器插件支持 Org 模式。尽管如此，Org 模式仍然是跟踪待办事项最好的应用程序之一，因为它确实很强大。

### 选择适合自己的工具

最后，这些程序目的是帮助你跟踪待办事项，并确保不会忘记做某个事情。这些程序的基础功能都大同小异，那一款适合你取决于多种因素。有的人需要自带同步功能，有的人需要一个移动客户端，有的人要必须支持插件。不管你选择什么，请记住程序本身不会让你更有调理，但是可以帮助你。

---

via: <https://opensource.com/article/18/2/getting-to-done-agile-linux-command-line>

作者：[Kevin Sonney](https://opensource.com/users/ksonney "Kevin Sonney") 译者：[guevaraya](https://github.com/guevaraya) 校对：[wxy](https://github.com/wxy)

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


无服务器架构的三个意义

Summary: 以及，对于无服务器（Serverless）架构，什么时候该用，什么时候不该用呢？

# 无服务器架构的三个意义

>
> 以及，对于<ruby> 无服务器 <rt>  Serverless </rt></ruby>架构，什么时候该用，什么时候不该用呢？
>
>
>

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

如果将如今互联网体验中最方便实用的那一部分去掉，那么留下来的基本就是<ruby> 客户端-服务端 <rt>  client-server </rt></ruby>模式了。这一个模式在互联网建立初期就已经在使用了，直到目前都没有太大的变化，也就是说，这个模式仍然在为我们服务。

那么，当人们谈论<ruby> 无服务器 <rt>  Serverless </rt></ruby>架构的时候，到底是指什么呢？其实，无服务器架构并不是说不使用服务器了。恰恰相反，客户端-服务端模式仍然在其中发挥着重要的作用。

无服务器架构实际上指的是能够让开发者在不需要关心服务器上架、为操作系统打补丁、创建容器镜像这些工作的情况下，就能够完成编码、部署和创建应用这一整套流程的架构。

### 无服务器架构的三个重要意义

1. 一些缺乏开发经验的人员现在要参与到开发工作中来了。无服务器架构能够让他们尽量只学习必要的工作内容，把更多的时间放在更具创造性的开发工作中。
2. 开发者不再需要重复造轮子。运行和维护服务器、为操作系统打补丁、创建容器等这一系列工作，都可以由更专业的无服务器架构提供商来完成。
3. 最现实的一点是，如果不使用无服务器架构，那么在服务器管理方面，总需要有一个作最终决策的人。当服务器发生崩溃时，或是需要在服务器上执行某些操作时，总是需要这样一个统领全局的人来作出决策。因此最佳的方案是使用无服务器架构。

### 什么时候该用或者不该用无服务器架构？

听起来无服务器架构是个好东西。但事实上，无服务器架构并不是万能的，在使用之前还需要考虑以下这些因素：

1. 成本
2. 使用范围
3. 时间
4. 控制方式

其中值得注意的是控制方式。现在已经有一些项目为开发者提供了操作和控制无服务器架构计算环境的工具了，[Apache OpenWhisk](https://opensource.com/article/18/11/developing-functions-service-apache-openwhisk) 就是其中之一。

### 为什么要将无服务器架构开源？

关于这方面的更多内容，可以观看无服务器架构方面的专家 Saron Yitbarek 在 [Command Line Heroes](https://www.redhat.com/en/command-line-heroes) 节目中的访谈。

---

via: <https://opensource.com/article/18/12/serverless-podcast-command-line-heros>

作者：[Jen Wike Huger](https://opensource.com/users/remyd) 选题：[lujun9972](https://github.com/lujun9972) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)

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


OpenSnitch：一个 Linux 上的应用程序防火墙

# OpenSnitch：一个 Linux 上的应用程序防火墙

不能因为 Linux 比 Windows 更安全，就可以在 Linux 上放松警惕。Linux 上可以使用的防火墙很多，它们可以让你的 Linux 系统更安全。今天，我们将带你了解一个这样的防火墙工具，它就是 OpenSnitch。

### OpenSnitch 是什么？

[OpenSnitch](https://www.opensnitch.io/) 是从 Little Snitch 上移植过来的。而 Little Snitch 是专门为 Mac OS 设计的一款应用程序防火墙。OpenSnitch 是由 [Simone Margaritelli](https://github.com/evilsocket) 设计，也称为 [evilsocket](https://twitter.com/evilsocket)。

OpenSnitch 所做的主要事情就是跟踪你机器上安装的应用程序所发起的互联网请求。OpenSnitch 允许你去创建规则以同意或阻止那个应用程序发起的互联网访问。当一个应用程序尝试去访问互联网而没有相应的访问规则存在时，就会出现一个对话框，这个对话框让你去选择允许还是阻止那个连接。

你也可以决定这个新规则是应用到进程上、具体的 URL 上、域名上、单个实例上，以及本次会话还是永久有效。

*OpenSnatch 规则请求*

你创建的所有规则都保存为 [JSON 文件](https://www.json.org/)，如果以后需要修改它，就可以去修改这个文件。比如说，你错误地阻止了一个应用程序。

OpenSnitch 也有一个漂亮的、一目了然的图形用户界面：

* 是什么应用程序访问 web
* 它们使用哪个 IP 地址
* 属主用户是谁
* 使用哪个端口

如果你愿意，也可以将这些信息导出到一个 CSV 文件中。

OpenSnitch 遵循 GPL v3 许可证使用。

*OpenSnitch 进程标签页*

### 在 Linux 中安装 OpenSnitch

[OpenSnitch GitHub 页面](https://github.com/evilsocket/opensnitch) 上的安装介绍是针对 Ubuntu 用户的。如果你使用的是其它发行版，你需要调整一下相关的命令。据我所知，这个应用程序仅在 [Arch User Repository](https://aur.archlinux.org/packages/opensnitch-git) 中打包了。

在你开始之前，你必须正确安装了 Go，并且已经定义好了 `$GOPATH` 环境变量。

首先，安装必需的依赖。

```
sudo apt-get install protobuf-compiler libpcap-dev libnetfilter-queue-dev python3-pip

go get github.com/golang/protobuf/protoc-gen-go

go get -u github.com/golang/dep/cmd/dep

python3 -m pip install --user grpcio-tools
```

接下来，克隆 OpenSnitch 仓库。这里可能会出现一个没有 Go 文件的信息，不用理它。如果出现 git 没有找到的信息，那么你需要首先去安装 Git。

```
go get github.com/evilsocket/opensnitch

cd $GOPATH/src/github.com/evilsocket/opensnitch
```

如果没有正确设置 `$GOPATH` 环境变量，运行上面的命令时将会出现一个 “no such folder found” 的错误信息。只需要进入到你刚才克隆仓库位置的 `evilsocket/opensnitch` 文件夹中即可。

现在，我们构建并安装它。

```
make

sudo make install
```

如果出现 “dep command could not be found” 的错误信息，在 `$PATH` 中添加 `$GOPATH/bin` 即可。

安装完成后，我们将要启动它的守护程序和图形用户界面。

```
sudo systemctl enable opensnitchd

sudo service opensnitchd start

opensnitch-ui
```

*运行在 Manjaro 上的 OpenSnitch*

### 使用体验

实话实说：我使用 OpenSnitch 的体验并不好。我开始在 Fedora 上尝试安装它。遇到了许多依赖问题。我又转到 Manjaro 上，在 Arch User Repository 上我很容易地找到了这些依赖。

不幸的是，我安装之后，不能启动图形用户界面。因此，我手动去运行最后三个步骤。一切似乎很顺利。如果我想让 Firefox 去访问 Manjaro 的网站，对话框就会弹出来询问我。

有趣的是，当我运行一个 [AUR 工具](https://itsfoss.com/best-aur-helpers/) `yay` 去更新我的系统时，弹出对话框要求了 `yay`、`pacman`、`pamac`、和 `git` 的访问规则。后来，我关闭并重启动 GUI，因为它当前是激活的。当我重启动它时，它不再要求我去创建规则了。我安装了 Falkon，而 OpenSnitch 并没有询问我去授予它任何权限。它甚至在 OpenSnitch 的 GUI 中没有列出 Falkon。我重新安装了 OpenSnitch 后，这个问题依旧存在。

然后，我转到 Ubuntu Mate 上安装 OpenSnitch，因为安装介绍就是针对 Ubuntu 所写的，进展很顺利。但是，我遇到了几个问题。我调整了一下上面介绍的安装过程以解决我遇到的问题。

安装的问题并不是我遇到的唯一问题。每次一个新的应用程序创建一个连接时弹出的对话框仅存在 10 秒钟。这么短的时间根本不够去浏览所有的可用选项。大多数情况下，这点时间只够我去永久允许一个（我信任的）应用程序访问 web。

GUI 也有一点需要去改进。由于某些原因，每次窗口都被放在顶部。而且不能通过设置来修改这个问题。如果能够从 GUI 中改变规则将是一个不错的选择。

*OpenSnitch 的 hosts 标签*

### 对 OpenSnitch 的最后意见

我很喜欢 OpenSnitch 的目标：用任何简单的方式控制离开你的计算机的信息。但是，它还很粗糙，我不能将它推荐给普通或业余用户。如果你是一个高级用户，很乐意去摆弄或挖掘这些问题，那么它可能很适合你。

这有点令人失望。我希望即将到来的 1.0 版本能够做的更好。

你以前用过 OpenSnitch 吗？如果没有，你最喜欢的防火墙应用是什么？你是如何保护你的 Linux 系统的？在下面的评论区告诉我们吧。

如果你对本文感兴趣，请花一点时间将它分享到社交媒体上吧，Hacker News 或 [Reddit](http://reddit.com/r/linuxusersgroup) 都行。

---

via: <https://itsfoss.com/opensnitch-firewall-linux/>

作者：[John Paul](https://itsfoss.com/author/john/) 选题：[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/) 荣誉推出


12 条实用的 zypper 命令范例

Summary: zypper 是 Suse Linux 系统的包和补丁管理器，你可以根据下面的 12 条附带输出示例的实用范例来学习 zypper 命令的使用。

# 12 条实用的 zypper 命令范例

`zypper` 是 Suse Linux 系统的包和补丁管理器，你可以根据下面的 12 条附带输出示例的实用范例来学习 `zypper` 命令的使用。

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

Suse Linux 使用 `zypper` 进行包管理，其是一个由 [ZYpp 包管理引擎](https://en.wikipedia.org/wiki/ZYpp)提供的包管理系统。在此篇文章中我们将分享 12 条附带输出示例的实用 `zypper` 命令，能帮助你处理日常的系统管理任务。

不带参数的 `zypper` 命令将列出所有可用的选项，这比参考详细的 man 手册要容易上手得多。

```
root@kerneltalks # zypper
  用法：
        zypper [--global-options] <command> [--command-options] [arguments]
        zypper <subcommand> [--command-options] [arguments]

  全局选项：
        --help, -h              帮助
        --version, -V           输出版本号
        --promptids             输出 zypper 用户提示符列表
        --config, -c <file>     使用指定的配置文件来替代默认的
        --userdata <string>     在历史和插件中使用的用户自定义事务 id
        --quiet, -q             忽略正常输出，只打印错误信息
        --verbose, -v           增加冗长程度
        --color
        --no-color              是否启用彩色模式，如果 tty 支持的话
        --no-abbrev, -A         表格中的文字不使用缩写
        --table-style, -s       表格样式（整型）
        --non-interactive, -n   不询问任何选项，自动使用默认答案
        --non-interactive-include-reboot-patches
                                针对带有重启标志的补丁，不使用交互模式
        --xmlout, -x            切换至 XML 输出
        --ignore-unknown, -i    忽略未知的包

        --reposd-dir, -D <dir>  使用自定义仓库文件目录
        --cache-dir, -C <dir>   为所有缓存启用可选路径
        --raw-cache-dir <dir>   启用可选 raw 元数据缓存路径
        --solv-cache-dir <dir>  启用可选 solv 文件缓存路径
        --pkg-cache-dir <dir>   启用可选包缓存路径

     仓库选项：
        --no-gpg-checks         忽略 GPG 检查失败并跳过
        --gpg-auto-import-keys  自动信任并导入新仓库的签名密钥
        --plus-repo, -p <URI>   使用附加仓库
        --plus-content <tag>    另外使用禁用的仓库来提供特定的关键词
                                尝试使用 '--plus-content debug' 选项来启用仓库
        --disable-repositories  不从仓库中读取元数据
        --no-refresh            不刷新仓库
        --no-cd                 忽略 CD/DVD 中的仓库
        --no-remote             忽略远程仓库
        --releasever            设置所有 .repo 文件中的 $releasever 变量（默认值：发行版版本）

     Target Options:
        --root, -R <dir>        在另一个根路径下进行操作
        --disable-system-resolvables
                                不读取已安装包

  命令：
        help, ?                 打印帮助
        shell, sh               允许多命令

     仓库管理：
        repos, lr               列出所有自定义仓库
        addrepo, ar             添加一个新仓库
        removerepo, rr          移除指定仓库
        renamerepo, nr          重命名指定仓库
        modifyrepo, mr          修改指定仓库
        refresh, ref            刷新所有仓库
        clean                   清除本地缓存

     服务管理：
        services, ls            列出所有自定义服务
        addservice, as          添加一个新服务
        modifyservice, ms       修改指定服务
        removeservice, rs       移除指定服务
        refresh-services, refs  刷新所有服务

     软件管理：
        install, in             安装包
        remove, rm              移除包
        verify, ve              确认包依赖的完整性
        source-install, si      安装源码包及其构建依赖
        install-new-recommends, inr
                                安装由已安装包建议一并安装的新包

     更新管理：
        update, up              更新已安装包至更新版本
        list-updates, lu        列出可用更新
        patch                   安装必要的补丁
        list-patches, lp        列出必要的补丁
        dist-upgrade, dup       进行发行版更新
        patch-check, pchk       检查补丁

     查询：
        search, se              查找符合匹配模式的包
        info, if                展示特定包的完全信息
        patch-info              展示特定补丁的完全信息
        pattern-info            展示特定模式的完全信息
        product-info            展示特定产品的完全信息
        patches, pch            列出所有可用的补丁
        packages, pa            列出所有可用的包
        patterns, pt            列出所有可用的模式
        products, pd            列出所有可用的产品
        what-provides, wp       列出提供特定功能的包

     包锁定：
        addlock, al             添加一个包锁定
        removelock, rl          移除一个包锁定
        locks, ll               列出当前的包锁定
        cleanlocks, cl          移除无用的锁定

     其他命令：
        versioncmp, vcmp        比较两个版本字符串
        targetos, tos           打印目标操作系统 ID 字符串
        licenses                打印已安装包的证书和 EULAs 报告
        download                使用命令行下载指定 rpm 包到本地目录
        source-download         下载所有已安装包的源码 rpm 包到本地目录

     子命令：
        subcommand              列出可用子命令

输入 'zypper help <command>' 来获得特定命令的帮助。
```

### 如何使用 zypper 安装包

`zypper` 通过 `in` 或 `install` 子命令来在你的系统上安装包。它的用法与 [yum 软件包安装](https://kerneltalks.com/tools/package-installation-linux-yum-apt/) 相同。你只需要提供包名作为参数，包管理器（此处是 `zypper`）就会处理所有的依赖并与你指定的包一并安装。

```
# zypper install telnet
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following NEW package is going to be installed:
  telnet

1 new package to install.
Overall download size: 51.8 KiB. Already cached: 0 B. After the operation, additional 113.3 KiB will be used.
Continue? [y/n/...? shows all options] (y): y
Retrieving package telnet-1.2-165.63.x86_64                                                                                (1/1),  51.8 KiB (113.3 KiB unpacked)
Retrieving: telnet-1.2-165.63.x86_64.rpm .........................................................................................................................[done]
Checking for file conflicts: .....................................................................................................................................[done]
(1/1) Installing: telnet-1.2-165.63.x86_64 .......................................................................................................................[done]
```

以上是我们安装 `telnet` 包时的输出，供你参考。

推荐阅读：[在 YUM 和 APT 系统中安装包](https://kerneltalks.com/tools/package-installation-linux-yum-apt/)

### 如何使用 zypper 移除包

要在 Suse Linux 中擦除或移除包，使用 `zypper` 附带 `remove` 或 `rm` 子命令。

```
root@kerneltalks # zypper rm telnet
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following package is going to be REMOVED:
  telnet

1 package to remove.
After the operation, 113.3 KiB will be freed.
Continue? [y/n/...? shows all options] (y): y
(1/1) Removing telnet-1.2-165.63.x86_64 ..........................................................................................................................[done]
```

我们在此处移除了先前安装的 telnet 包。

### 使用 zypper 检查依赖或者认证已安装包的完整性

有时可以通过强制忽略依赖关系来安装软件包。`zypper` 使你能够扫描所有已安装的软件包并检查其依赖性。如果缺少任何依赖项，它将提供你安装或重新安装它的机会，从而保持已安装软件包的完整性。

使用附带 `verify` 或 `ve` 子命令的 `zypper` 命令来检查已安装包的完整性。

```
root@kerneltalks # zypper ve
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...

Dependencies of all installed packages are satisfied.
```

在上面的输出中，你能够看到最后一行说明已安装包的所有依赖都已安装完全，并且无需更多操作。

### 如何在 Suse Linux 中使用 zypper 下载包

`zypper` 提供了一种方法使得你能够将包下载到本地目录而不去安装它。你可以在其他具有同样配置的系统上使用这个已下载的软件包。包会被下载至 `/var/cache/zypp/packages/<repo>/<arch>/` 目录。

```
root@kerneltalks # zypper download telnet
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...
Retrieving package telnet-1.2-165.63.x86_64                                                                                (1/1),  51.8 KiB (113.3 KiB unpacked)
(1/1) /var/cache/zypp/packages/SMT-http_smt-ec2_susecloud_net:SLES12-SP3-Pool/x86_64/telnet-1.2-165.63.x86_64.rpm ................................................[done]

download: Done.

# ls -lrt /var/cache/zypp/packages/SMT-http_smt-ec2_susecloud_net:SLES12-SP3-Pool/x86_64/
total 52
-rw-r--r-- 1 root root 53025 Feb 21 03:17 telnet-1.2-165.63.x86_64.rpm

```

你能看到我们使用 `zypper` 将 telnet 包下载到了本地。

推荐阅读：[在 YUM 和 APT 系统中只下载包而不安装](https://kerneltalks.com/howto/download-package-using-yum-apt/)

### 如何使用 zypper 列出可用包更新

`zypper` 允许你浏览已安装包的所有可用更新，以便你可以提前计划更新活动。使用 `list-updates` 或 `lu` 子命令来显示已安装包的所有可用更新。

```
root@kerneltalks # zypper lu
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...
S | Repository                        | Name                       | Current Version               | Available Version                  | Arch
--|-----------------------------------|----------------------------|-------------------------------|------------------------------------|-------
v | SLES12-SP3-Updates                | at-spi2-core               | 2.20.2-12.3                   | 2.20.2-14.3.1                      | x86_64
v | SLES12-SP3-Updates                | bash                       | 4.3-82.1                      | 4.3-83.5.2                         | x86_64
v | SLES12-SP3-Updates                | ca-certificates-mozilla    | 2.7-11.1                      | 2.22-12.3.1                        | noarch
v | SLE-Module-Containers12-Updates   | containerd                 | 0.2.5+gitr639_422e31c-20.2    | 0.2.9+gitr706_06b9cb351610-16.8.1  | x86_64
v | SLES12-SP3-Updates                | crash                      | 7.1.8-4.3.1                   | 7.1.8-4.6.2                        | x86_64
v | SLES12-SP3-Updates                | rsync                      | 3.1.0-12.1                    | 3.1.0-13.10.1                      | x86_64
```

输出特意被格式化以便于阅读。每一列分别代表包所属仓库名称、包名、已安装版本、可用的更新版本和架构。

### 在 Suse Linux 中列出和安装补丁

使用 `list-patches` 或 `lp` 子命令来显示你的 Suse Linux 系统需要被应用的所有可用补丁。

```
root@kerneltalks # zypper lp
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...

Repository                        | Name                                     | Category    | Severity  | Interactive | Status | Summary
----------------------------------|------------------------------------------|-------------|-----------|-------------|--------|------------------------------------------------------------------------------------
SLE-Module-Containers12-Updates   | SUSE-SLE-Module-Containers-12-2018-273   | security    | important | ---         | needed | Version update for docker, docker-runc, containerd, golang-github-docker-libnetwork
SLE-Module-Containers12-Updates   | SUSE-SLE-Module-Containers-12-2018-62    | recommended | low       | ---         | needed | Recommended update for sle2docker
SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2018-268 | recommended | low       | ---         | needed | Recommended update for python-ecdsa
SLES12-SP3-Updates                | SUSE-SLE-SERVER-12-SP3-2018-116          | security    | moderate  | ---         | needed | Security update for rsync
---- output clipped ----
SLES12-SP3-Updates                | SUSE-SLE-SERVER-12-SP3-2018-89           | security    | moderate  | ---         | needed | Security update for perl-XML-LibXML
SLES12-SP3-Updates                | SUSE-SLE-SERVER-12-SP3-2018-90           | recommended | low       | ---         | needed | Recommended update for lvm2

Found 37 applicable patches:
37 patches needed (18 security patches)
```

使用相应的表头可以很好地组织输出。你可以轻松地找出并根据情况计划你的补丁更新。我们能看到在我们的系统中，37 个可用补丁中有 18 个是安全补丁，需要被高优先级应用！

你可以通过发出 `zypper patch` 命令安装所有需要的补丁。

##### 如何使用 zypper 更新包

要使用 `zypper` 更新包，使用 `update` 或 `up` 子命令后接包名。在上述列出的更新命令中，我们知道在我们的服务器上 `rsync` 包更新可用。让我们现在来更新它吧！

```
root@kerneltalks # zypper update rsync
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following package is going to be upgraded:
  rsync

1 package to upgrade.
Overall download size: 325.2 KiB. Already cached: 0 B. After the operation, additional 64.0 B will be used.
Continue? [y/n/...? shows all options] (y): y
Retrieving package rsync-3.1.0-13.10.1.x86_64                                                                                (1/1), 325.2 KiB (625.5 KiB unpacked)
Retrieving: rsync-3.1.0-13.10.1.x86_64.rpm .......................................................................................................................[done]
Checking for file conflicts: .....................................................................................................................................[done]
(1/1) Installing: rsync-3.1.0-13.10.1.x86_64 .....................................................................................................................[done]
```

### 在 Suse Linux 上使用 zypper 查找包

如果你不确定包的全名也不要担心。你可以使用 `zypper` 附带的 `se` 或 `search` 子命令并提供查找字符串来查找包。

```
root@kerneltalks # zypper se lvm
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...

S  | Name          | Summary                      | Type
---|---------------|------------------------------|-----------
   | libLLVM       | Libraries for LLVM           | package
   | libLLVM-32bit | Libraries for LLVM           | package
   | llvm          | Low Level Virtual Machine    | package
   | llvm-devel    | Header Files for LLVM        | package
   | lvm2          | Logical Volume Manager Tools | srcpackage
i+ | lvm2          | Logical Volume Manager Tools | package
   | lvm2-devel    | Development files for LVM2   | package
```

在上述示例中我们查找了 `lvm` 字符串并得到了如上输出列表。你能在 `zypper install/remove/update` 命令中使用 `Name` 字段的名字。

### 使用 zypper 检查已安装包信息

你能够使用 `zypper` 检查已安装包的详细信息。`info` 或 `if` 子命令将列出已安装包的信息。它也可以显示未安装包的详细信息，在该情况下，`Installed` 参数将返回 `No` 值。

```
root@kerneltalks # zypper info rsync
Refreshing service 'SMT-http_smt-ec2_susecloud_net'.
Refreshing service 'cloud_update'.
Loading repository data...
Reading installed packages...

Information for package rsync:
------------------------------
Repository     : SLES12-SP3-Updates
Name           : rsync
Version        : 3.1.0-13.10.1
Arch           : x86_64
Vendor         : SUSE LLC <https://www.suse.com/>
Support Level  : Level 3
Installed Size : 625.5 KiB
Installed      : Yes
Status         : up-to-date
Source package : rsync-3.1.0-13.10.1.src
Summary        : Versatile tool for fast incremental file transfer
Description    :
    Rsync is a fast and extraordinarily versatile file  copying  tool. It can copy
    locally, to/from another host over any remote shell, or to/from a remote rsync
    daemon. It offers a large number of options that control every aspect of its
    behavior and permit very flexible specification of the set of files to be
    copied. It is famous for its delta-transfer algorithm, which reduces the amount
    of data sent over the network by sending only the differences between the
    source files and the existing files in the destination. Rsync is widely used
    for backups and mirroring and as an improved copy command for everyday use.
```

### 使用 zypper 列出仓库

使用 `zypper` 命令附带 `lr` 或 `repos` 子命令列出仓库。

```
root@kerneltalks # zypper lr
Refreshing service 'cloud_update'.
Repository priorities are without effect. All enabled repositories share the same priority.

#  | Alias                                                                                | Name                                                  | Enabled | GPG Check | Refresh
---|--------------------------------------------------------------------------------------|-------------------------------------------------------|---------|-----------|--------
 1 | SMT-http_smt-ec2_susecloud_net:SLE-Module-Adv-Systems-Management12-Debuginfo-Pool    | SLE-Module-Adv-Systems-Management12-Debuginfo-Pool    | No      | ----      | ----
 2 | SMT-http_smt-ec2_susecloud_net:SLE-Module-Adv-Systems-Management12-Debuginfo-Updates | SLE-Module-Adv-Systems-Management12-Debuginfo-Updates | No      | ----      | ----
 3 | SMT-http_smt-ec2_susecloud_net:SLE-Module-Adv-Systems-Management12-Pool              | SLE-Module-Adv-Systems-Management12-Pool              | Yes     | (r ) Yes  | No
 4 | SMT-http_smt-ec2_susecloud_net:SLE-Module-Adv-Systems-Management12-Updates           | SLE-Module-Adv-Systems-Management12-Updates           | Yes     | (r ) Yes  | Yes
 5 | SMT-http_smt-ec2_susecloud_net:SLE-Module-Containers12-Debuginfo-Pool                | SLE-Module-Containers12-Debuginfo-Pool                | No      | ----      | ----
 6 | SMT-http_smt-ec2_susecloud_net:SLE-Module-Containers12-Debuginfo-Updates             | SLE-Module-Containers12-Debuginfo-Updates             | No      | ----      | ----
```

此处你需要检查 `enabled` 列来确定哪些仓库是已被启用的而哪些没有。

### 在 Suse Linux 中使用 zypper 添加或移除仓库

要添加仓库你需要仓库或 .repo 文件的 URI，否则你会遇到如下错误。

```
root@kerneltalks # zypper addrepo -c SLES12-SP3-Updates
If only one argument is used, it must be a URI pointing to a .repo file.
```

使用 URI，你可以像如下方式添加仓库：

```
root@kerneltalks # zypper  addrepo -c http://smt-ec2.susecloud.net/repo/SUSE/Products/SLE-SDK/12-SP3/x86_64/product?credentials=SMT-http_smt-ec2_susecloud_net SLE-SDK12-SP3-Pool
Adding repository 'SLE-SDK12-SP3-Pool' ...........................................................................................................................[done]
Repository 'SLE-SDK12-SP3-Pool' successfully added

URI         : http://smt-ec2.susecloud.net/repo/SUSE/Products/SLE-SDK/12-SP3/x86_64/product?credentials=SMT-http_smt-ec2_susecloud_net
Enabled     : Yes
GPG Check   : Yes
Autorefresh : No
Priority    : 99 (default priority)

Repository priorities are without effect. All enabled repositories share the same priority.
```

在 Suse 中使用附带 `addrepo` 或 `ar` 子命令的 `zypper` 命令添加仓库，后接 URI 以及你需要提供一个别名。

要在 Suse 中移除一个仓库，使用附带 `removerepo` 或 `rr` 子命令的 `zypper` 命令。

```
root@kerneltalks # zypper removerepo nVidia-Driver-SLE12-SP3
Removing repository 'nVidia-Driver-SLE12-SP3' ....................................................................................................................[done]
Repository 'nVidia-Driver-SLE12-SP3' has been removed.
```

### 清除 zypper 本地缓存

使用 `zypper clean` 命令清除 zypper 本地缓存。

```
root@kerneltalks # zypper clean
All repositories have been cleaned up.
```

---

via: <https://kerneltalks.com/commands/12-useful-zypper-command-examples/>

作者：[KernelTalks](https://kerneltalks.com) 译者：[cycoe](https://github.com/cycoe) 校对：[wxy](https://github.com/wxy)

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


Cat 命令的源码历史

Summary: 对于 cat，这个想法和程序本身都很古老。不准确地说，我的电脑上的 cat 来自 1969 年。

# Cat 命令的源码历史

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

以前我和我的一些亲戚争论过计算机科学的学位值不值得读。当时我正在上大学，并要决定是不是该主修计算机。我姨和我表姐觉得我不应该主修计算机。她们承认知道如何编程肯定是很有用且对自己有利的一件事，但是她们认为计算机科学现在发展的如此迅速以至于我学的东西几乎马上就过时了。建议我更好是把编程作为辅业，选择一个基础原理可以受用终身的领域主修，比如经济学或物理学。

我知道我姨和我表姐说的不对，并决定主修计算机科学。（对不住啊！）平常人可能会觉得像计算机科学领域和软件工程专业每隔几年就完全和之前不一样了。其原因很容易理解。我们有了个人电脑，然后有了互联网，有了手机，之后还有了机器学习…… 科技总是在更新，支撑科技发展的原理和技能当然也在改变。当然，最惊人的是其实原理的改变竟然如此之小。我敢肯定，大多数人在知道了他们电脑里一些重要的软件的历史是多么久远时他们一定会深感震惊。当然我不是说那些刷版本号的浮夸软件 —— 我电脑上的 Firefox 浏览器副本，可能是我用的最多的软件，可能两周前就更新过。如果你看了比如 `grep` 的手册页，你就会发现它在 2010 年后就没有过更新了（至少在 MacOS 上如此）。初版 `grep` 是在 1974 年写就的，那时可以算是计算机世界的侏罗纪了。直到现在，人们（还有程序）仍然依赖 `grep` 来完成日常工作。

我姨和我表姐认为计算机技术就像一系列日渐精致的沙堡，在潮水抹净沙滩后新的沙堡完全取代旧的。但事实上，在很多领域上，我们都是不断积累能够解决问题的程序。我们可能不得不偶尔修改这些程序以避免软件无法使用，但大多数情况下我们都可以不修改。`grep` 是一个简单的程序，可以解决一个仍然存在的需求，所以它能够存活下来。 大多数应用程序编程都是在非常高的级别上完成的，它们建立在解决了旧问题的旧程序的金字塔上。 30 年或 40 年前的思路和概念，远非过时，在很多情况下它们依然在您的笔记本电脑上软件中存在着。

我想追溯这样的老程序自第一次写就以来改变了多少回很有趣。 `cat` 可能是所有 Unix 实用程序中最简单的，因此我们以它为例。Ken Thompson 于 1969 年编写了 `cat` 的原始实现。如果我告诉别人我的电脑上安装了个来自 1969 年的程序，这准确吗？我们电脑上的程序多大了？

感谢这种[这种](https://github.com/dspinellis/unix-history-repo)仓库，我们可以完整的看到 `cat` 自 1969 年后是如何发展的。我会先聚焦于可以算得上是我的 MacBook 上的 `cat` 的祖先的 `cat` 实现。随着我们从 Unix 上的第一版 `cat` 追踪到现在 MacOS 上的 `cat`，你会发现，这个程序被重写的次数比你想的还要多 —— 但是直到现在它运行的方式和五十年前多少是完全一致的。

### 研究 Unix

Ken Thompson 和 Dennis Ritchie 在 PDP 7 上开始写 Unix。那还是 1969 年，C 还没被发明出来，因此所有早期的 Unix 软件都是用 PDP 7 汇编实现的。他们使用的汇编种类是 Unix 特有的，Ken Thompson 在 DEC（PDP 7 的厂商）提供的汇编器之上加了些特性，实现了自己的汇编器。Thompson 的更改在[最初的 Unix 程序员手册](https://www.bell-labs.com/usr/dmr/www/man11.pdf)的 `as`（也就是汇编器）条目下均有所记录。

因此，[最初的](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-1-cat-pdp7-s) `cat` 也是使用 PDP 7 汇编实现的。 我添加了一些注释，试图解释每条指令的作用，但除非你理解 Thompson 在编写汇编器时加的特性，否则程序仍然很难理解。在那些特性中有两个很重要：其一是 `;` 这个字符可以在一行中用来分隔多条语句，它多出现于在使用 `sys` 指令时将系统调用的多个参数放在同一行上。其二是， Thompson 的汇编器支持使用 0 到 9 作为“临时标签”，这是在程序内可以重用的标签。因此。就如 Unix 程序员手册中所说：“对程序员的想象力和汇编程序的符号空间的要求都降低了”。在任何给定的指令内，你都可以使用 `nf` 和 `nb` 来引用下一个或最近的临时标签 `n`。 例如，如果存在标记为 `1:` 的代码块，你就可以使用指令 `jmp 1b` 从下游代码跳回该块。 （但是你不使用 `jmp 1f` 的话就没法从上面的代码跳到这里。）

初版 `cat` 最有趣的就是它包含着我们应该认识的符号。有一块指令块标记为 `getc`，还有一个标记为 `putc`，可以看到这两个符号比 C 标准还古老。第一版的 `cat` 函数实际上已经包含了这两个函数的实现。该实现做了输入缓存，这样它就不需要一次只读写一个字母。

`cat` 的第一个版本并没有持续多久。 Ken Thompson 和 Dennis Ritchie 说服贝尔实验室购买了 PDP 11，这样他们就能够继续扩展和改进 Unix。 PDP 11 的指令集和之前不一样，因此必须重写 `cat`。 我也注释了[这个第二版](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-2-cat-pdp11-s) `cat`。 它为新的指令集使用新的汇编程序助记符，并利用了 PDP 11 的各种[寻址模式](https://en.wikipedia.org/wiki/PDP-11_architecture#Addressing_modes)。（如果你对源代码中的括号和美元符号感到困惑，那是因为这些符号用于指示不同的寻址模式。）但它也使用 `;` 字符和临时标签，和 `cat` 的第一个版本一样，这意味着当把 `as` 移植到 PDP 11 上时，必须要保留这些功能。

`cat` 的第二个版本比第一个版本简单得多。 它也更有 Unix 味儿，它不只是依靠参数列表，一旦没给参数列表，它将从 `stdin` 读取数据，这也就是今天 `cat` 仍在做的事情。 你也可以在此版本的 `cat` 中以 `-` 为参数，以表示它应该从`stdin`读取。

在 1973 年，为了准备发布第四版 Unix，大部分代码都用 C 语言重写了。但是 `cat` 似乎在之后一段时间内并没有使用 C 重写。 [cat 的第一个 C 语言实现](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-3-cat-v7-c)出现在第七版 Unix 中。 这个实现非常有趣，因为它很简单。 在所有以后的实现中，这个实现和在 K＆R 的 C 语言教科书中用作教学示范的理想化 `cat` 最相似。这个程序的核心就是经典的两行：

```
while ((c = getc(fi)) != EOF)
 putchar(c);
```

当然实际代码要比这多一些，额外的代码主要是为了确保你没有在读/写同一个文件。另一个有趣的事情是，`cat` 的这一版实现只识别一个标志位 `-u`。 `-u` 标志可用于避免缓冲输入和输出，否则 `cat` 将以 512 字节为块进行输入输出。

### BSD

在第七版 Unix 之后，Unix 出现了各种衍生品和分支。 MacOS 建立于 Darwin 之上，而 Darwin 又源自<ruby> 伯克利软件分发版 <rt>  Berkeley Software Distribution </rt></ruby>（BSD），因此 BSD 是我们最感兴趣的 Unix 分支。 BSD 最初只是 Unix 中的实用程序和附加组件的集合，但它最终成为了一个完整的操作系统。直到第四版 BSD，人称 4BSD，为一大堆新标志添加了支持之前，BSD 似乎还是依赖于最初的 `cat` 实现的。`cat` 的 [4BSD 实现](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-4-cat-bsd4-c) 显然是从原始实现中衍生出来的，尽管它添加了一个新函数来实现由新标志触发的行为。已经在文件中使用的 `fflg` 变量（用于标记输入是从 `stdin` 还是文件读取的）的命名约定，被新添加的 `nflg`、`bflg`、`vflg`、`sflg`、`eflg` 和 `tflg` 沿袭了下来，这些变量记录了在调用程序时是否使用了这些新标志。这些是最后一批添加到 `cat` 的命令行标志。如今 `cat` 的手册页列出了这些标志，没有其他的标志了，至少在 Mac OS 上是如此。 4BSD 于 1980 年发布，因此这套标志已有 38 年历史。

`cat` 最后一次被完全重写是在 BSD NET/2 上，其目的是通过替换 AT&T 发布的全部 Unix 源代码来规避许可证问题。BSD Net/2 在 1991 年发布。这一版本的 `cat` 是由 Kevin Fall 重写的。 Kevin Fall 于 1988 年毕业于加州大学伯克利分校并在下一年成为<ruby> 计算机系统研究组 <rt>  Computer Systems Research Group </rt></ruby>（CSRG）的组员，Fall 和我说当时使用 AT&T 代码的 Unix 工具被列在了 CSRG 的墙上，组员需要从中选出他们想要重写的工具； Fall 选了 `cat` 以及 `mknod`。 MacOS 系统内自带的 `cat` 实现源码的最上面还有着他的名字。他的这一版 `cat`，尽管平淡无奇，在今天还是被无数人使用着。

[Fall 的原始 cat 实现](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-5-cat-net2-c) 比我们迄今为止看到的版本都要长。 除了支持 `-?` 帮助标志外，它没有增加任何新功能。 从概念上讲，它与 4BSD 的实现非常相似。 它长是因为 Fall 将实现分为 “原始” 模式和 “加工” 模式。 “原始” 模式是 `cat` 的经典实现；它一个字符一个字符的打印文件。 “加工” 模式是带有所有 4BSD 命令行选项的 `cat`。 如此区别不无道理，但这么办也扩充了实现规模，因此乍一看其源码似乎比实际上更复杂。文件末尾还有一个奇特的错误处理函数，进一步地增加了实现的长度。

### MacOS

在 2001 年，苹果发布了 MacOS X。这一发布对苹果意义重大。因为苹果用了多年的时间尝试以取代其现有的老旧操作系统（经典的 Mac OS），但是都失败了。 在 Mac OS X 之前苹果两次尝试在内部创建一个新的操作系统，但两者都无疾而终。 最后，苹果收购了史蒂夫·乔布斯的 NeXT 公司，后者开发了一个名为 NeXTSTEP 的操作系统和面向对象编程框架。 苹果将 NeXTSTEP 作为 Mac OS X 的基础。因为 NeXTSTEP 部分基于 BSD，使以 NeXTSTEP 为基础的 Mac OS X 的自然就把 BSD 系的代码直接带入苹果宇宙的中心。

因此，Mac OS X 的非常早期的第一个版本包含了从 NetBSD 项目中提取的 `cat` 的[实现](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-6-cat-macosx-c)。如今仍保持开发的 NetBSD 最初是 386BSD 的分支，而后者又直接基于 BSD Net/2。所以 Mac OS X 里面的第一个 `cat` 的实现就是 Kevin Fall 的 `cat`。唯一改变的是，Fall 的错误处理函数 `err()` 被 `err.h` 提供的 `err()` 函数取代了。 `err.h` 是 C 标准库的 BSD 扩展。

之后不久，这里的 `cat` 的 NetBSD 实现被换成了 FreeBSD 中的 `cat` 实现。 [根据维基百科](https://en.wikipedia.org/wiki/Darwin_(operating_system))，苹果在 Mac OS X 10.3（Panther）中开始使用 FreeBSD 的实现而不是 NetBSD 的实现。但根据苹果自己开源的版本，`cat` 的 Mac OS X 实现在 2007 年发布的 Mac OS X 10.5（Leopard）之前没有被替换。苹果为 Leopard 替换的的 [FreeBSD 实现](https://gist.github.com/sinclairtarget/47143ba52b9d9e360d8db3762ee0cbf5#file-7-cat-macos-10-13-c)与今天苹果计算机上的实现相同。截至 2018 年，2007 年以来的这个实现仍未被更新或修改。

所以 Mac OS 上的 `cat` 已经很老了。实际上，这一实现在 2007 年在 MacOS X 上露面两年前就被发布了。 [这个 2005 年的修改](https://github.com/freebsd/freebsd/commit/a76898b84970888a6fd015e15721f65815ea119a#diff-6e405d5ab5b47ca2a131ac7955e5a16b) 在 FreeBSD 的 Github 镜像中可见，是在苹果将其合并入 Mac OS X 前对 FreeBSD 的 `cat` 实现进行的最后一次更改。所以 Mac OS X 中的实现没有与 FreeBSD 的 `cat` 实现保持同步，它如今已经 13 岁了。对于软件修改了多少代码才能仍是算是同一软件这一话题有着旷日持久的争论。不过，在这种情况下，源文件自 2005 年以来根本没有变化。

现在 Mac OS 使用的 `cat` 实现与 Fall 1991 年为 BSD Net/2 版本编写的实现没有什么不同。最大的区别是添加了一个全新的功能来提供 Unix 域套接字支持。FreeBSD 开发人员似乎将 Fall 的 `raw_args()` 函数和 `cook_args()` 函数组合成一个名为`scanfiles()` 的函数。否则，程序的核心就仍是 Fall 的代码。

我问过 Fall 对编写了如今被数以百万计的苹果用户（直接或者间接通过依赖 `cat` 的某些程序）使用的 `cat` 实现有何感想。Fall，如今是一位顾问，也是最新版《TCP/IP 详解》的合著者，他说，当人们从了解他对 `cat` 所做的工作中收获颇丰时，他感到很惊讶。 Fall 在计算机领域有着悠久的职业生涯，曾参与许多备受瞩目的项目，但似乎很多人仍对他在 1989 年重写 `cat` 的那六个月的工作感到最为兴奋。

### 百年老程序

在宏伟的发明史中，计算机并不是一项古老的发明。我们已经习惯了百年的照片甚至是百年的视频短片。但是计算机程序不一样 —— 它们代表着高科技和新技术。至少，他们是现代的技术造出来的。随着计算行业的成熟，我们有朝一日会发现自己正在使用有着接近百年历史的程序吗？

计算机硬件可能会发生较大的变化，使得我们也许无法让现在编译的可执行文件在一个世纪后的硬件上运行。也许编程语言设计的进步让未来没有人能理解 C 语言，`cat` 将来也可能也被别的语言重写很久了。 （尽管 C 已经存在了五十年了，而且它似乎不会很快就被替换掉。）但除此之外，为什么不永远使用我们现在的 `cat`？

我认为 `cat` 的历史表明，计算机科学中的一些想法确实非常持久。事实上，对于 `cat`，这个想法和程序本身都很古老。不准确地说，我的电脑上的 `cat` 来自 1969 年。但我也可以说我的计算机上的 `cat` 来自1989 年，当时 Fall 写了他的 `cat` 实现。许多其他软件也同样古老。因此，也许我们不应该把计算机科学和软件开发视为不断破坏现状和发明新事物的领域。我们的计算机系统是由诸多历史文物构建的。有时，我们可能会花费更多时间在理解和维护这些历史文物上，而不是花在编写新代码上。

如果你喜欢本文，你可能更喜欢两周来一篇更新！在推特上关注 [@TwoBitHistory](https://twitter.com/TwoBitHistory) 或者订阅这个 [RSS 源](https://twobithistory.org/feed.xml) 以保证接受到新的文章。

---

via: <https://twobithistory.org/2018/11/12/cat.html>

作者：[Two-Bit History](https://twobithistory.org) 选题：[lujun9972](https://github.com/lujun9972) 译者：[name1e5s](https://github.com/name1e5s) 校对：[wxy](https://github.com/wxy)

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


Emacs 系列（五）：Org 模式之文档与演示稿

# Emacs 系列（五）：Org 模式之文档与演示稿

这是 [Emacs 和 Org 模式系列](https://changelog.complete.org/archives/tag/emacs2018)的第五篇。

这篇博文是由 Org 模式的源文件生成的，其有几种格式：[博客页面](https://github.com/jgoerzen/public-snippets/blob/master/emacs/emacs-org-beamer/emacs-org-beamer.org)、[演示稿](http://changelog.complete.org/archives/9900-emacs-5-documents-and-presentations-with-org-mode) 和 [PDF 文档](https://github.com/jgoerzen/public-snippets/raw/master/emacs/emacs-org-beamer/emacs-org-beamer.pdf)。

### 1 Org 模式的输出

#### 1.1 背景

Org 模式不仅仅只是一个议程生成程序，它也能输出许多不同的格式： LaTeX、PDF、Beamer、iCalendar（议程）、HTML、Markdown、ODT、普通文本、手册页和其它更多的复杂的格式，比如说网页文件。

这也不只是一些事后的想法，这是 Org 模式的设计核心部分并且集成的很好。

这一个文件可以同时是源代码、自动生成的输出、任务列表、文档和展示。

有些人将 Org 模式作为他们首选的标记格式，甚至对于 LaTeX 文档也是如此。Org 模式手册中的 [输出一节](https://orgmode.org/manual/Exporting.html#Exporting) 有更详细的介绍。

#### 1.2 开始

对于任意的 Org 模式的文档，只要按下 `C-c C-e` 键，就会弹出一个让你选择多种输出格式和选项的菜单。这些选项通常是次键选择，所以很容易设置和执行。例如：要输出一个 PDF 文档，按 `C-c C-e l p`，要输出 HMTL 格式的， 按 `C-c C-e h h`。

对于所有的输出选项，都有许多可用的设置；详情参见手册。事实上，使用 LaTeX 格式相当于同时使用 LaTeX 和 HTML 模式，在不同的模式中插入任意的前言和设置等。

#### 1.3 第三方插件

[ELPA](https://www.emacswiki.org/emacs/ELPA) 中也包含了许多额外的输出格式，详情参见 [ELPA](https://www.emacswiki.org/emacs/ELPA)。

### 2 Org 模式的 Beamer 演示

#### 2.1 关于 Beamer

[Beamer](https://en.wikipedia.org/wiki/Beamer_(LaTeX)) 是一个生成演示稿的 LaTeX 环境. 它包括了以下特性：

* 在演示稿中自动生成结构化的元素（例如 [Marburg 主题](https://hartwork.org/beamer-theme-matrix/all/beamer-albatross-Marburg-1.png))。 在演示稿中，这个特性可以为观众提供了视觉参考。
* 对组织演示稿有很大的帮助。
* 主题
* 完全支持 LaTeX

#### 2.2 Org 模式中 Beamer 的优点

在 Org 模式中用 Beamer 有很多好处，总的来说：

* Org 模式很简单而且对可视化支持的很好，同时改变结构可以快速的重组你的材料。
* 与 org-babel 绑定在一起，实时语法高亮源码和内嵌结果。
* 语法通常更容易使用。

我已经完全用 Org 模式和 beamer 替换掉使用 LibreOffice/Powerpoint/GoogleDocs。事实上，当我必须使用其中一种工具时，这是相当令人沮丧的，因为它们在可视化表示演讲稿结构方面远远比不上 Org 模式。

#### 2.3 标题层次

Org 模式的 Beamer 会将你文档中的部分（文中定义了标题的）转换成幻灯片。当然，问题是：哪些部分？这是由 H [输出设置](https://orgmode.org/manual/Export-settings.html#Export-settings)（`org-export-headline-levels`）决定的。

针对不同的人，有许多不同的方法。我比较喜欢我的演示稿这样：

```
#+OPTIONS: H:2
#+BEAMER_HEADER: \AtBeginSection{\frame{\sectionpage}}
```

这将为每个主题提供了独立部分，以突出主题的改变然后使用级别 2（两个星号）的标题来设置幻灯片。许多 Beamer 主题也有第三个间接层次，所以你可以将 H 设为 3。

#### 2.4 主题和配置

你可以在 Org 模式的文件顶部来插入几行来配置 Beamer 和 LaTeX。在本文中，例如，你可以这样定义：

```
#+TITLE:  Documents and presentations with org-mode
#+AUTHOR: John Goerzen
#+BEAMER_HEADER: \institute{The Changelog}
#+PROPERTY: comments yes
#+PROPERTY: header-args :exports both :eval never-export
#+OPTIONS: H:2
#+BEAMER_THEME: CambridgeUS
#+BEAMER_COLOR_THEME: default
```

#### 2.5 高级设置

我比教喜欢修改颜色、项目符号样式等。我的配置如下：

```
# We can't just +BEAMER_INNER_THEME: default because that picks the theme default.
# Override per https://tex.stackexchange.com/questions/11168/change-bullet-style-formatting-in-beamer
#+BEAMER_INNER_THEME: default
#+LaTeX_CLASS_OPTIONS: [aspectratio=169]
#+BEAMER_HEADER: \definecolor{links}{HTML}{0000A0}
#+BEAMER_HEADER: \hypersetup{colorlinks=,linkcolor=,urlcolor=links}
#+BEAMER_HEADER: \setbeamertemplate{itemize items}[default]
#+BEAMER_HEADER: \setbeamertemplate{enumerate items}[default]
#+BEAMER_HEADER: \setbeamertemplate{items}[default]
#+BEAMER_HEADER: \setbeamercolor*{local structure}{fg=darkred}
#+BEAMER_HEADER: \setbeamercolor{section in toc}{fg=darkred}
#+BEAMER_HEADER: \setlength{\parskip}{\smallskipamount}
```

在这里，`aspectratio=169` 将纵横比设为 16:9, 其它部分都是标准的 LaTeX/Beamer 配置。

#### 2.6 缩小 (适应屏幕)

有时你会遇到一些非常大的代码示例，你可能更倾向与将幻灯片缩小以适应它们。

只要按下 `C-c C-c p` 将 `BEAMER_opt` 属性设为 `shrink=15`\。（或者设为更大的 shrink 值）。上一张幻灯片就用到了这个。

#### 2.7 效果

这就是最终的效果：

[](https://www.flickr.com/photos/jgoerzen/26366340577/in/dateposted/)

### 3 幻灯片之间的交互

#### 3.1 交互式的 Emacs 幻灯片

使用 [org-tree-slide](https://orgmode.org/worg/org-tutorials/non-beamer-presentations.html#org-tree-slide) 这个插件的话，就可以在 Emacs 的右侧显示幻灯片了。 只要按下 `M-x`，然后输入 `org-tree-slide-mode`，回车，然后你就可以用 `C->` 和 `C-<` 在幻灯片之间切换了。

你可能会发现 `C-c C-x C-v` （即 `org-toggle-inline-images`）有助于使系统显示内嵌的图像。

#### 3.2 HTML 幻灯片

有许多方式可以将 Org 模式的演讲稿导出为 HTML，并有不同级别的 JavaScript 集成。有关详细信息，请参见 Org 模式的 wiki 中的 [非 beamer 演讲稿一节](https://orgmode.org/worg/org-tutorials/non-beamer-presentations.html)。

### 4 更多

#### 4.1 本文中的附加资源

* [orgmode.org beamer tutorial](https://orgmode.org/worg/exporters/beamer/tutorial.html)
* [LaTeX wiki](https://en.wikibooks.org/wiki/LaTeX/Presentations)
* [Generating section title slides](https://tex.stackexchange.com/questions/117658/automatically-generate-section-title-slides-in-beamer/117661)
* [Shrinking content to fit on slide](https://tex.stackexchange.com/questions/78514/content-doesnt-fit-in-one-slide)
* 很棒的资源： refcard-org-beamer
	+ 详情参见其 [Github repo](https://github.com/fniessen/refcard-org-beamer) 中的 PDF 和 .org 文件。
* 很漂亮的主题： [Theme matrix](https://hartwork.org/beamer-theme-matrix/)

#### 4.2 下一个 Emacs 系列

mu4e 邮件!

---

via: <http://changelog.complete.org/archives/9900-emacs-5-documents-and-presentations-with-org-mode>

作者：[John Goerzen](http://changelog.complete.org/archives/author/jgoerzen) 选题：[lujun9972](https://github.com/lujun9972) 译者：[oneforalone](https://github.com/oneforalone) 校对：[wxy](https://github.com/wxy)

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


降低项目失败率的三个原则

Summary: 透明和包容性的项目要求可以降低您的失败率。 以下是如何协作收集它们。

透明和包容性的项目要求可以降低您的失败率。 以下是如何协作收集它们。

# 降低项目失败率的三个原则

>
> 透明和包容性的项目要求可以降低您的失败率。 以下是如何协作收集它们。
>
>
>

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

众所周知，明确、简洁和可衡量的需求会带来更多成功的项目。一项[麦肯锡与牛津大学](http://calleam.com/WTPF/?page_id=1445)的关于大型项目的研究表明：“平均而言，大型 IT 项目超出预算 45％，时间每推移 7％，价值就比预期低 56％ 。”该研究还表明，造成这种失败的一些原因是“模糊的业务目标，不同步的利益相关者以及过度的返工。”

业务分析师经常发现自己通过持续对话来构建这些需求。为此，他们必须吸引多个利益相关方，并确保参与者提供明确的业务目标。这样可以减少返工，提高更多项目的成功率。

他们可以用开放和包容的方式做到这一点。

### 成功的框架

提高项目成功率的一个工具是[开放决策框架](https://opensource.com/open-organization/resources/open-decision-framework)。开放决策框架是一种资源，可以帮助用户在拥抱[开放原则](https://opensource.com/open-organization/resources/open-org-definition)的组织中做出更有效的决策。该框架强调三个主要原则：透明、包容、以客户为中心。

**透明**。很多时候，开发人员和产品设计人员都认为他们知道利益相关者如何使用特定工具或软件。但这些假设往往是不正确的，并导致对利益相关者实际需求的误解。开发人员和企业主讨论时实行透明势在必行。开发团队不仅需要了解一些好的情景，还需要了解利益相关方面对某些工具或流程所面临的挑战。提出诸如以下问题：“必须手动完成哪些步骤？”以及“这个工具是否按预期运行？”这提供了对问题的共同理解和讨论的基准。

**包容**。对于业务分析师来说，在收集需求时观察肢体语言和视觉暗示非常重要。如果有人双臂交叉或睁着眼睛坐着，那么这清楚地表明他们感觉没被聆听。业务分析师必须鼓励那些不被聆听的人公开交流，并给他们机会被聆听。在开始会议之前，制定基本规则，使所有人都能发表意见并分享他们的想法。聆听提供的反馈，并在收到反馈时礼貌地回复。多样化的意见和协作解决问题将为会议带来令人兴奋的想法。

**以顾客为中心**。以客户为中心的第一步是识别客户。谁从这种变化、更新或开发中受益？在项目早期，进行利益相关者映射，以帮助确定关键利益相关者，他们在项目中的角色以及他们适应大局的方式。让合适的客户参与并确保满足他们的需求将会确定更成功的要求，进行更现实（现实）的测试，并最终成功交付。

当你的需求会议透明、包容和以客户为中心时，你将收集更好的需求。当你使用[开放决策框架](https://opensource.com/open-organization/16/6/introducing-open-decision-framework)来进行会议时，参与者会感觉有更多参与与授权，他们会提供更准确和完整的需求。换一种说法：

**透明+包容+以客户为中心=更好的需求=成功的项目**

---

via: <https://opensource.com/open-organization/18/2/constructing-project-requirements>

作者：[Tracy Buckner](https://opensource.com/users/tracyb) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


数据科学家的命令行技巧

Summary: 立志掌握命令行应该在每个开发人员的学习清单上，特别是数据科学家。

立志掌握命令行应该在每个开发人员的学习清单上，特别是数据科学家。

# 数据科学家的命令行技巧

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

对于许多数据科学家来说，数据操作从始至终就是 Pandas 或 Tidyverse。从理论上讲，这样做没有任何问题。毕竟，这就是这些工具存在的原因。然而，对于像分隔符转换这样的简单任务，这些工具是大材小用了。

立志掌握命令行应该在每个开发人员的学习清单上，特别是数据科学家。学习 shell 的来龙去脉将无可否认地提高你的生产力。除此之外，命令行还是计算领域的一个重要历史课程。例如，awk —— 一种数据驱动的脚本语言。1977 年，在 [Brain Kernighan](https://en.wikipedia.org/wiki/Brian_Kernighan)（即传奇的 [K&R 书](https://en.wikipedia.org/wiki/The_C_Programming_Language)中 K）的帮助下，awk 首次出现。今天，大约五十年过去了，awk 仍然活跃在每年[新出版的书](https://www.amazon.com/Learning-AWK-Programming-cutting-edge-text-processing-ebook/dp/B07BT98HDS)里面。因此，可以安全地假设对命令行魔法的付出不会很快贬值。

### 我们将涵盖什么

* ICONV
* HEAD
* TR
* WC
* SPLIT
* SORT & UNIQ
* CUT
* PASTE
* JOIN
* GREP
* SED
* AWK

### ICONV

文件编码可能会很棘手。现在大部分文件都是 UTF-8 编码的。要了解 UTF-8 背后的一些魔力，请查看这个出色的[视频](https://www.youtube.com/watch?v=MijmeoH9LT4)。尽管如此，有时我们收到的文件不是这种编码。这可能引起对改变编码模式的一些胡乱尝试。这里，`iconv` 是一个拯救者。`iconv` 是一个简单的程序，它将获取采用一种编码的文本并输出采用另一种编码的文本。

```
# Converting -f (from) latin1 (ISO-8859-1)
# -t (to) standard UTF_8

iconv -f ISO-8859-1 -t UTF-8 < input.txt > output.txt
```

实用选项：

* `iconv -l` 列出所有已知编码
* `iconv -c` 默默丢弃无法转换的字符

### HEAD

如果你是一个 Pandas 重度用户，那么会很熟悉 `head`。通常在处理新数据时，我们想做的第一件事就是了解其内容。这就得启动 Pandas，读取数据然后调用 `df.head()` —— 要说这有点费劲。没有任何选项的 `head` 将打印出文件的前 10 行。`head` 的真正力量在于干净利落的测试操作。例如，如果我们想将文件的分隔符从逗号更改为管道。一个快速测试将是：`head mydata.csv | sed 's/,/|/g'`。

```
# Prints out first 10 lines
head filename.csv

# Print first 3 lines
head -n 3 filename.csv
```

实用选项：

* `head -n` 打印特定行数
* `head -c` 打印特定字节数

### TR

`tr` 类似于翻译。这个功能强大的实用程序是文件基础清理的主力。理想的用例是替换文件中的分隔符。

```
# Converting a tab delimited file into commas
cat tab_delimited.txt | tr "\t" "," comma_delimited.csv
```

`tr` 另一个功能是你可以用内建 `[:class:]` 变量（POSIX 字符类）发挥威力。这些包括了：

* `[:alnum:]` 所有字母和数字
* `[:alpha:]` 所有字母
* `[:blank:]` 所有水平空白
* `[:cntrl:]` 所有控制字符
* `[:digit:]` 所有数字
* `[:graph:]` 所有可打印字符，但不包括空格
* `[:lower:]` 所有小写字母
* `[:print:]` 所有可打印字符，包括空格
* `[:punct:]` 所有标点符号
* `[:space:]` 所有水平或垂直空白
* `[:upper:]` 所有大写字母
* `[:xdigit:]` 所有 16 进制数字

你可以将这些连接在一起以组成强大的程序。以下是一个基本的字数统计程序，可用于检查 README 是否被滥用。

```
cat README.md | tr "[:punct:][:space:]" "\n" | tr "[:upper:]" "[:lower:]" | grep . | sort | uniq -c | sort -nr
```

另一个使用基本正则表达式的例子：

```
# Converting all upper case letters to lower case
cat filename.csv | tr '[A-Z]' '[a-z]'
```

实用选项：

* `tr -d` 删除字符
* `tr -s` 压缩字符
* `\b` 退格
* `\f` 换页
* `\v` 垂直制表符
* `\NNN` 八进制字符

### WC

单词计数。它的价值主要来自其 `-l` 选项，它会给你提供行数。

```
# Will return number of lines in CSV
wc -l gigantic_comma.csv
```

这个工具可以方便地确认各种命令的输出。所以，如果我们在转换文件中的分隔符之后运行 `wc -l`，我们会期待总行数是一样的，如果不一致，我们就知道有地方出错了。

实用选项：

* `wc -c` 打印字节数
* `wc -m` 打印字符数
* `wc -L` 打印最长行的长度
* `wc -w` 打印单词数量

### SPLIT

文件大小的范围可以很广。对于有的任务，拆分文件或许是有好处的，所以使用 `split` 吧。`split` 的基本语法是：

```
# We will split our CSV into new_filename every 500 lines
split -l 500 filename.csv new_filename_
# filename.csv
# ls output
# new_filename_aaa
# new_filename_aab
# new_filename_aa
```

它有两个奇怪的地方是命名约定和缺少文件扩展名。后缀约定可以通过 `-d` 标志变为数字。要添加文件扩展名，你需要运行以下 `find` 命令。它将通过附加 `.csv` 扩展名来更改当前目录中所有文件的名称，所以小心了。

```
find . -type f -exec mv '{}' '{}'.csv \;
# ls output
# filename.csv.csv
# new_filename_aaa.csv
# new_filename_aab.csv
# new_filename_aac.csv
```

实用选项：

* `split -b N` 按特定字节大小分割
* `split -a N` 生成长度为 N 的后缀
* `split -x` 使用十六进制后缀

### SORT & UNIQ

上面两个命令很明显：它们的作用就是字面意思。这两者结合起来可以提供最强大的冲击 (例如，唯一单词的数量)。这是由于 `uniq` 只作用于重复的相邻行。这也是在输出前进行 `sort` 的原因。一个有趣的事情是 `sort -u` 会达到和典型的 `sort file.txt | uniq` 模式一样的结果。

`sort` 对数据科学家来说确实具有潜在的有用能力：能够根据特定列对整个 CSV 进行排序。

```
# Sorting a CSV file by the second column alphabetically
sort -t"," -k2,2 filename.csv

# Numerically
sort -t"," -k2n,2 filename.csv

# Reverse order
sort -t"," -k2nr,2 filename.csv
```

这里的 `-t` 选项将逗号指定为分隔符，通常假设分隔符是空格或制表符。此外，`-k` 选项是为了确定我们的键。这里的语法是 `-km,n`，`m` 作为开始列，`n` 作为结束列。

实用选项：

* `sort -f` 忽略大小写
* `sort -r` 反向排序
* `sort -R` 乱序
* `uniq -c` 统计出现次数
* `uniq -d` 只打印重复行

### CUT

`cut` 用于删除列。作为演示，如果我们只想删除第一和第三列。

```
cut -d, -f 1,3 filename.csv
```

要选择除了第一行外的所有行。

```
cut -d, -f 2- filename.csv
```

结合其他命令，将 `cut` 用作过滤器。

```
# Print first 10 lines of column 1 and 3, where "some_string_value" is present
head filename.csv | grep "some_string_value" | cut -d, -f 1,3
```

查出第二列中唯一值的数量。

```
cat filename.csv | cut -d, -f 2 | sort | uniq | wc -l

# Count occurences of unique values, limiting to first 10 results
cat filename.csv | cut -d, -f 2 | sort | uniq -c | head
```

### PASTE

`paste` 是一个带有趣味性功能的特定命令。如果你有两个需要合并的文件，并且它们已经排序好了，`paste` 帮你解决了接下来的步骤。

```
# names.txt
adam
john
zach

# jobs.txt
lawyer
youtuber
developer

# Join the two into a CSV
paste -d ',' names.txt jobs.txt > person_data.txt

# Output
adam,lawyer
john,youtuber
zach,developer
```

更多 SQL 式变种，见下文。

### JOIN

`join` 是一个简单的、<ruby> 准切向的 <rt>  quasi-tangential </rt></ruby> SQL。最大的区别是 `join` 将返回所有列以及只能在一个字段上匹配。默认情况下，`join` 将尝试使用第一列作为匹配键。为了获得不同结果，必须使用以下语法：

```
# Join the first file (-1) by the second column
# and the second file (-2) by the first
join -t "," -1 2 -2 1 first_file.txt second_file.txt
```

标准的 `join` 是内连接。然而，外连接通过 `-a` 选项也是可行的。另一个值得一提的技巧是 `-q` 标志，如果发现有缺失的字段，可用于替换值。

```
# Outer join, replace blanks with NULL in columns 1 and 2
# -o which fields to substitute - 0 is key, 1.1 is first column, etc...
join -t"," -1 2 -a 1 -a2 -e ' NULL' -o '0,1.1,2.2' first_file.txt second_file.txt
```

它不是最用户友好的命令，而是绝望时刻的绝望措施。

实用选项：

* `join -a` 打印不可配对的行
* `join -e` 替换丢失的输入字段
* `join -j` 相当于 `-1 FIELD -2 FIELD`

### GREP

`grep` 即 <ruby> 用正则表达式全局搜索并且打印 <rt>  Global search for a Regular Expression and Print </rt></ruby>，可能是最有名的命令，并且名副其实。`grep` 很强大，特别适合在大型代码库中查找。在数据科学的王国里，它充当其他命令的提炼机制。虽然它的标准用途也很有价值。

```
# Recursively search and list all files in directory containing 'word'

grep -lr 'word' .

# List number of files containing word

grep -lr 'word' . | wc -l

```

计算包含单词或模式的总行数。

```
grep -c 'some_value' filename.csv

# Same thing, but in all files in current directory by file name

grep -c 'some_value' *
```

对多个值使用“或”运算符： `\|`。

```
grep "first_value\|second_value" filename.csv
```

实用选项：

* `alias grep="grep --color=auto"` 使 grep 色彩丰富
* `grep -E` 使用扩展正则表达式
* `grep -w` 只匹配整个单词
* `grep -l` 打印匹配的文件名
* `grep -v` 非匹配

### 大人物们

`sed` 和 `awk` 是本文中最强大的两个命令。为简洁起见，我不打算详细讨论这两个命令。相反，我将介绍各种能证明其令人印象深刻的力量的命令。如果你想了解更多，[这儿就有一本书](https://www.amazon.com/sed-awk-Dale-Dougherty/dp/1565922255/ref=sr_1_1?ie=UTF8&qid=1524381457&sr=8-1&keywords=sed+and+awk)是关于它们的。

### SED

`sed` 本质上是一个流编辑器。它擅长替换，但也可以用于所有输出重构。

最基本的 `sed` 命令由 `s/old/new/g` 组成。它的意思是搜索 `old`，全局替换为 `new`。 如果没有 `/g`，我们的命令将在 `old` 第一次出现后终止。

为了快速了解它的功能，我们可以深入了解一个例子。 在以下情景中，你已有以下文件：

```
balance,name
$1,000,john
$2,000,jack
```

我们可能想要做的第一件事是删除美元符号。`-i` 标志表示原位。`''` 表示零长度文件扩展名，从而覆盖我们的初始文件。理想情况下，你可以单独测试，然后输出到新文件。

```
sed -i '' 's/\$//g' data.txt
# balance,name
# 1,000,john
# 2,000,jack
```

接下来，去除 `blance` 列的逗号。

```
sed -i '' 's/\([0-9]\),\([0-9]\)/\1\2/g' data.txt
# balance,name
# 1000,john
# 2000,jack
```

最后 jack 有一天决定辞职。所以，再见了，我的朋友。

```
sed -i '' '/jack/d' data.txt
# balance,name
# 1000,john
```

正如你所看到的，`sed` 有很多强大的功能，但乐趣并不止于此。

### AWK

最好的留在最后。`awk` 不仅仅是一个简单的命令：它是一个成熟的语言。在本文中涉及的所有内容中，`awk` 是目前为止最酷的。如果你感兴趣，这里有很多很棒的资源 —— 看 [这里](https://www.amazon.com/AWK-Programming-Language-Alfred-Aho/dp/020107981X/ref=sr_1_1?ie=UTF8&qid=1524388936&sr=8-1&keywords=awk)、[这里](http://www.grymoire.com/Unix/Awk.html) 和 [这里](https://www.tutorialspoint.com/awk/index.htm)。

`awk` 的常见用例包括：

* 文字处理
* 格式化文本报告
* 执行算术运算
* 执行字符串操作

`awk` 可以以最原生的形式并行 `grep`。

```
awk '/word/' filename.csv
```

或者更加神奇：将 `grep` 和 `cut` 组合起来。在这里，对于所有带我们指定单词 `word` 的行，`awk` 打印第三和第四列，用 `tab` 分隔。`-F,` 用于指定切分时的列分隔符为逗号。

```
awk -F, '/word/ { print $3 "\t" $4 }' filename.csv
```

`awk` 内置了许多精巧的变量。比如，`NF` —— 字段数，和 `NR` —— 记录数。要获取文件中的第 53 条记录：

```
awk -F, 'NR == 53' filename.csv
```

更多的花招是其基于一个或多个值进行过滤的能力。下面的第一个示例将打印第一列等于给定字符串的行的行号和列。

```
awk -F, ' $1 == "string" { print NR, $0 } ' filename.csv

# Filter based off of numerical value in second column
awk -F, ' $2 == 1000 { print NR, $0 } ' filename.csv
```

多个数值表达式：

```
# Print line number and columns where column three greater
# than 2005 and column five less than one thousand

awk -F, ' $3 >= 2005 && $5 <= 1000 { print NR, $0 } ' filename.csv
```

求出第三列的总和：

```
awk -F, '{ x+=$3 } END { print x }' filename.csv
```

在第一列等于 `something` 的那些行，求出第三列值的总和。

```
awk -F, '$1 == "something" { x+=$3 } END { print x }' filename.csv
```

获取文件的行列数：

```
awk -F, 'END { print NF, NR }' filename.csv

# Prettier version
awk -F, 'BEGIN { print "COLUMNS", "ROWS" }; END { print NF, NR }' filename.csv
```

打印出现了两次的行：

```
awk -F, '++seen[$0] == 2' filename.csv
```

删除重复的行：

```
# Consecutive lines
awk 'a !~ $0; {a=$0}']

# Nonconsecutive lines
awk '! a[$0]++' filename.csv

# More efficient
awk '!($0 in a) {a[$0];print}
```

使用内置函数 `gsub()` 替换多个值。

```
awk '{gsub(/scarlet|ruby|puce/, "red"); print}'
```

这个 `awk` 命令将组合多个 CSV 文件，忽略标题，然后在最后附加它。

```
awk 'FNR==1 && NR!=1{next;}{print}' *.csv > final_file.csv
```

需要缩小一个庞大的文件？ `awk` 可以在 `sed` 的帮助下处理它。具体来说，该命令根据行数将一个大文件分成多个较小的文件。这个一行脚本将增加一个扩展名。

```
sed '1d;$d' filename.csv | awk 'NR%NUMBER_OF_LINES==1{x="filename-"++i".csv";}{print > x}'

# Example: splitting big_data.csv into data_(n).csv every 100,000 lines
sed '1d;$d' big_data.csv | awk 'NR%100000==1{x="data_"++i".csv";}{print > x}'
```

### 结语

命令行拥有无穷无尽的力量。本文中介绍的命令足以将你从一无所知提升到英雄人物。除了涵盖的内容之外，还有许多实用程序可以考虑用于日常数据操作。[Csvkit](http://csvkit.readthedocs.io/en/1.0.3/)、[xsv](https://github.com/BurntSushi/xsv) 还有 [q](https://github.com/harelba/q) 是需要记住的三个。如果你希望更深入地了解命令行数据科学，查看[这本书](https://www.amazon.com/Data-Science-Command-Line-Time-Tested/dp/1491947853/ref=sr_1_1?ie=UTF8&qid=1524390894&sr=8-1&keywords=data+science+at+the+command+line)。它也可以[免费](https://www.datascienceatthecommandline.com/)在线获得！

---

via: <http://kadekillary.work/post/cli-4-ds/>

作者：[Kade Killary](http://kadekillary.work/authors/kadekillary) 选题：[lujun9972](https://github.com/lujun9972) 译者：[GraveAccent](https://github.com/graveaccent) 校对：[wxy](https://github.com/wxy)

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


给写作者们的 7 个命令行工具

Summary: 扔掉你的文字编辑器，然后使用这些开源工具在命令行上写作吧。

扔掉你的文字编辑器，然后使用这些开源工具在命令行上写作吧。

# 给写作者们的 7 个命令行工具

>
> 扔掉你的文字编辑器，然后使用这些开源工具在命令行上写作吧。
>
>
>

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

对于大多数人（尤其是非技术人员），写作意味着在 LibreOffice Writer 或者其他带图形界面的文字处理应用上编辑文本。但是还有许多可行的方法可以让任何人通过文本传递他们的信息，尤其是越来越多的作者选择[拥抱纯文本](https://plaintextproject.online)。

在使用图形界面写作的世界同样有命令行工具的一席之地。这些命令行工具可以帮助他们进行写作，检查他们的拼写等等 —— 无论是在写一篇文章、博客或者故事；写一个 README 文件；或者准备一份技术文档的时候。

下面是一些在任何写作情况下都有用的命令行工具。

### 编辑器

没错，你可以在命令行进行真正的写作。我知道一些写作者会使用 [Nano](https://www.nano-editor.org/)、[Vim](https://www.vim.org)、[Emacs](https://www.gnu.org/software/emacs/)、以及 [Jove](https://opensource.com/article/17/1/jove-lightweight-alternative-vim) 等编辑器在终端窗口中进行工作。而这些编辑器[并非屈指可数](https://en.wikipedia.org/wiki/List_of_text_editors#Text_user_interface)。文本编辑器的优势在于它们简单易用以及更专注于文本。非常适合用于编辑任何文本的初稿甚至完成一个漫长而复杂的写作项目。

如果你想在命令行中获得更像文字编辑器的体验，不妨了解一下 [WordGrinder](https://cowlark.com/wordgrinder/)。它是一款简单但拥有足够的编写和发布功能的文字编辑器。它支持基本的格式和样式，并且你可以将你的文字以 Markdown、ODT、LaTeX 或者 HTML 等格式导出。

### 拼写检查

每个写作者在完成他们的工作前至少要（或者说应该要）进行一次拼写检查。为什么呢？在写作的世界里有个永恒的定律，无论你检查了多少次手稿，拼写错误和错字依然会存在。

我曾经详细[介绍](https://opensource.com/article/18/2/how-check-spelling-linux-command-line-aspell)过我最喜欢的命令行拼写检查工具 [GNU Aspell](http://aspell.net/)。交互式检测文本文档的 Aspell 不仅能够高亮显示拼写错误还能在拼写错误的上方提供正确的拼写建议。Aspell 在进行拼写检查时同样能够忽略许多语法标记。

另一个够老但仍然有用的代替品是 [Ispell](https://www.cs.hmc.edu/%7Egeoff/ispell.html)。虽然它比 Aspell 稍慢一点，但它们都以相同的方式工作。当你在你的文本文件上工作时，Ispell 将提供正确的建议。Ispell 同样也对英语以外的语言提供了良好的支持。

### 文章 linter

软件开发人员使用 [linter](https://en.wikipedia.org/wiki/Lint_(software)) 来检查他们的代码是否存在错误或者 bug。同样也有用于检查文本样式或语法错误的 linter；而该命令行工具会认为这些错误是样式元素。任何写作者都可以（也应该）使用它，一个文章 linter 对于要求文档风格和样式一致的文档团队项目而言尤其有用。

[Proselint](http://proselint.com/) 是一款全能的实时检查工具。它会找出行话、大话、不正确日期和时间格式、滥用的术语[等等](http://proselint.com/checks/)。它也很容易运行并忽略文本中的标记。

[Alex](https://github.com/get-alex/alex) 是一个简单但有用的文章 linter。 对明文文本或者格式为 Markdown 或 HTML 的文档使用它。Alex 会对“性别偏好、极端主义、种族相关、宗教，或者文章中其他不平等的措辞”产生警告。如果你想要试试看 Alex，这里有一个在线 [demo](https://alexjs.com/#demo)。

### 其他工具

有时候你找不到一个单词的恰当的同义词。但你不需要去呆板的词库中抓取或者去专门的网站完善你的单词完整。仅仅需要对你想要替换的单词运行 [Aiksaurus](http://aiksaurus.sourceforge.net/)，然后它就会为你完成这个工作。但是，这个程序最大的缺点是它只支持英语。

即使是只会很少（甚至只有一项）技术技能的写作者都能接受 [Markdown](https://en.wikipedia.org/wiki/Markdown) 来快速而简单地格式化他们的作品。但是，有时候你也需要将使用 Markdown 格式的文件转换成其他格式。这就是 [Pandoc](https://pandoc.org) 的用武之地。你可以用它来将你的文档转换成 HTML、Word、LibreOffice Writer、LaTeX、EPUB 以及其他格式。你甚至可以用 Pandoc 来生成书籍和[研究论文](https://opensource.com/article/18/9/pandoc-research-paper)。

你有最喜欢的命令行写作工具吗？在社区发表评论分享它吧。

---

via: <https://opensource.com/article/18/11/command-line-tools-writers>

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

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


Bash 中使用控制运算符连接命令

Summary: 在命令行中，使用控制运算符为复合命令添加逻辑。

在命令行中，使用控制运算符为复合命令添加逻辑。

# Bash 中使用控制运算符连接命令

>
> 在命令行中，使用控制运算符为复合命令添加逻辑。
>
>
>

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

经常会使用一些简单的复合指令，比如说在一个命令行中连接几个命令。这些命令使用分号分隔，表示一个命令结束。为了在一个命令行中创建一系列简单的 shell 命令，只需要使用分号把每一条命令分隔开，就像下面这样：

```
command1 ; command2 ; command3 ; command4 ;
```

最后一个分号你可以不用添加，因为当你按下回车键时就表示一个命令的结束，但是为了和其它的保持一致，还是建议加上比较好。

所有的命令执行都没有什么问题 —— 只要没有什么意外发生。但是当出问题时到底发生了什么呢？我们可以预测，并且通过 Bash 中内置的 `&&` 和 `||` 运算符跟踪这些错误。这两个控制运算符提供了一些流控制，可以让我们改变代码执行队列的顺序。分号和换行符也被认为是 Bash 的控制运算符。

`&&` 运算符意义简单来说就是“如果 `command1` 执行成功，就接着执行 `command2`。”如果 `command1` 因为任何原因执行失败，那么 `command2` 将不执行。这个语法看下来像这样：

```
command1 && command2
```

这样写是允许的，因为每一个命令都会返回一个值（RC）给 shell 来表示这个命令在执行的过程中是否执行成功或者失败。通常，返回值是 `0` 表示成功，而一个正数值表示不同种类的错误。有一些系统管理工具仅仅返回一个 `1` 来表示所有的错误，但是也有很多工具使用其它的正数的返回值来表示各种类型错误。

我们可以很容易的使用脚本来检查 shell 变量 `$?`，可以通过命令列表中的下一个命令，或者可以直接使用系统管理工具检查。我们一起来看这些返回值。运行一个简单的命令然后立即检查它的返回值，这个返回值始终是属于最后一个运行的命令。

```
[student@studentvm1 ~]$ ll ; echo "RC = $?"
total 284
-rw-rw-r--  1 student student   130 Sep 15 16:21 ascii-program.sh
drwxrwxr-x  2 student student  4096 Nov 10 11:09 bin
<snip>
drwxr-xr-x. 2 student student  4096 Aug 18 10:21 Videos
RC = 0
[student@studentvm1 ~]$
```

这个返回值是 `0`，表示这个命令执行成功了。现在尝试使用同样的命令在一些我们没有权限的目录上。

```
[student@studentvm1 ~]$ ll /root ; echo "RC = $?"
ls: cannot open directory '/root': Permission denied
RC = 2
[student@studentvm1 ~]$
```

这个返回值的含义可以在 [ls 命令的 man 页面](http://man7.org/linux/man-pages/man1/ls.1.html) 中找到。

现在我们来试试 `&&` 这个控制运算符，因为它也可能会被用在一个命令行程序中。我们将从一个简单的示例开始：创建一个新目录，如果创建成功就在这个目录中创建一个文件。

我们需要一个目录可以创建其它的目录。首先，在你的家目录中创建一个临时的目录用来做测试。

```
[student@studentvm1 ~]$ cd ; mkdir testdir
```

在 `~/testdir` 中新建一个目录，这也应该是一个空目录，因为是你刚刚创建的，然后创建一个新的空文件在这个新目录中。下面的命令可以做这些事情。

```
[student@studentvm1 ~]$ mkdir ~/testdir/testdir2 && touch ~/testdir/testdir2/testfile1
[student@studentvm1 ~]$ ll ~/testdir/testdir2/
total 0
-rw-rw-r-- 1 student student 0 Nov 12 14:13 testfile1
[student@studentvm1 ~]$
```

我们看到一切都运行得很好，因为 `testdir` 目录是访问且可写的。然后我们改变 `testdir` 目录的权限，让用户 `student` 不再具有访问的权限。操作如下：

```
[student@studentvm1 ~]$ chmod 076 testdir ; ll | grep testdir
d---rwxrw-. 3 student student  4096 Nov 12 14:13 testdir
[student@studentvm1 ~]$
```

在长列表（`ll`）命令后面使用 `grep` 命令来列出 `testdir` 目录。你可以看到用户 `student` 不再有 `testdir` 目录的访问权限。现在我们像之前一样运行同样的命令，但是在 `testdir` 目录中创建的是一个不同的目录。

```
[student@studentvm1 ~]$ mkdir ~/testdir/testdir3 && touch ~/testdir/testdir3/testfile1
mkdir: cannot create directory ‘/home/student/testdir/testdir3’: Permission denied
[student@studentvm1 ~]$
```

尽管我们也同样得到了一个错误的消息，但 `&&` 控制运算符阻止了 `touch` 命令的运行，因为在创建 `testdir3` 目录的时候发生了错误。通过这种复合的流控制可以阻止一些错误的发生使事情变乱。但是这样看起来变得稍微复杂了一些。

`||` 控制运算符允许添加另一个命令，这个命令在初始程序语句返回值大于 0 时执行。

```
[student@studentvm1 ~]$ mkdir ~/testdir/testdir3 && touch ~/testdir/testdir3/testfile1 || echo "An error occurred while creating the directory."
mkdir: cannot create directory ‘/home/student/testdir/testdir3’: Permission denied
An error occurred while creating the directory.
[student@studentvm1 ~]$
```

当我们使用 `&&` 和 `||` 控制运算符时，使用流控制的复合命令的语法格式通常是下面这样的形式。

```
preceding commands ; command1 && command2 || command3 ; following commands
```

使用控制运算符的复合命令可以在其它命令之前或者之后，这些和控制运算符流控制有关系，但是不受控制运算符流控制的影响。如果不考虑复合命令的流控制中发生的任何事情那么所有的命令都将执行。

当程序出问题时，这些流控制运算符使得在命令中处理出错和通知我们变得更有效率。我直接在命令行中使用它们，也在脚本中使用。

你可以以 root 用户的身份来删除这个目录和它里面的内容。

```
[root@studentvm1 ~]# rm -rf /home/student/testdir
```

你是怎样使用 Bash 控制运算符的呢？在评论区中告诉我们。

---

via: <https://opensource.com/article/18/11/control-operators-bash-shell>

作者：[David Both](https://opensource.com/users/dboth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Jamskr](https://github.com/Jamskr) 校对：[wxy](https://github.com/wxy)

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


一种新的安全检测的方法

Summary: 不要只测试已有系统，强安全要求更积极主动的策略。

不要只测试已有系统，强安全要求更积极主动的策略。

# 一种新的安全检测的方法

>
> 不要只测试已有系统，强安全要求更积极主动的策略。
>
>
>

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

我们当中有多少人曾说出过下面这句话：“我希望这能起到作用！”？

毫无疑问，我们中的大多数人可能都不止一次地说过这句话。这句话不是用来激发信心的，相反它揭示了我们对自身能力和当前正在测试的功能的怀疑。不幸的是，这句话非常好地描述了我们传统的安全模型。我们的运营基于这样的假设，并希望我们实施的控制措施 —— 从 web 应用的漏扫到终端上的杀毒软件 —— 防止恶意的病毒和软件进入我们的系统，损坏或偷取我们的信息。

渗透测试通过积极地尝试侵入网络、向 web 应用注入恶意代码或者通过发送钓鱼邮件来传播病毒等等这些步骤来避免我们对假设的依赖。由于我们在不同的安全层面上来发现和渗透漏洞，手动测试无法解决漏洞被主动打开的情况。在安全实验中，我们故意在受控的情形下创造混乱，模拟事故的情形，来客观地检测我们检测、阻止这类问题的能力。

>
> “安全实验为分布式系统的安全性实验提供了一种方法，以建立对抗恶意攻击的能力的信心。”
>
>
>

在分布式系统的安全性和复杂性方面，需要反复地重申混沌工程界的一句名言，“希望不是一种有效的策略”。我们多久会主动测试一次我们设计或构建的系统，来确定我们是否已失去对它的控制？大多数组织都不会发现他们的安全控制措施失效了，直到安全事件的发生。我们相信“安全事件不是侦察措施”，而且“希望不要出事也不是一个有效的策略”应该是 IT 专业人士执行有效安全实践的口号。

行业在传统上强调预防性的安全措施和纵深防御，但我们的任务是通过侦探实验来驱动对安全工具链的新知识和见解。因为过于专注于预防机制，我们很少尝试一次以上地或者年度性地手动测试要求的安全措施，来验证这些控件是否按设计的那样执行。

随着现代分布式系统中的无状态变量的不断改变，人们很难充分理解他们的系统的行为，因为会随时变化。解决这个问题的一种途径是通过强大的系统性的设备进行检测，对于安全性检测，你可以将这个问题分成两个主要方面：**测试**，和我们称之为**实验**的部分。测试是对我们已知部分的验证和评估，简单来说，就是我们在开始找之前，要先弄清楚我们在找什么。另一方面，实验是去寻找获得我们之前并不清楚的见解和知识。虽然测试对于一个成熟的安全团队来说是一项重要实践，但以下示例会有助于进一步地阐述两者之间的差异，并对实验的附加价值提供一个更为贴切的描述。

### 示例场景：精酿啤酒

思考一个用于接收精酿啤酒订单的 web 服务或者 web 应用。

这是这家精酿啤酒运输公司的一项重要服务，这些订单来自客户的移动设备、网页，和通过为这家公司精酿啤酒提供服务的餐厅的 API。这项重要服务运行在 AWS EC2 环境上，并且公司认为它是安全的。这家公司去年成功地通过了 PCI 规则，并且每年都会请第三方进行渗透测试，所以公司认为这个系统是安全的。

这家公司有时一天两次部署来进行 DevOps 和持续交付工作，公司为其感到自豪。

在了解了混沌工程和安全实验方面的东西后，该公司的开发团队希望能确定，在一个连续不断的基础上，他们的安全系统对真实世界事件的有效性和快速恢复性怎么样。与此同时，确保他们不会把安全控件不能检测到的新问题引入到系统中。

该团队希望能小规模地通过评估端口安全和防火墙设置来让他们能够检测、阻止和警告他们 EC2 安全组上端口设置的错误配置更改。

* 该团队首先对他们正常状态下的假设进行总结。
* 在 EC2 实例里为端口安全进行一个假设。
* 为未认证的端口改变实验选择和配置 YAML 文件。
* 该配置会从已选择的目标中随机指定对象，同时端口的范围和数量也会被改变。
* 团队还会设置进行实验的时间并缩小爆破攻击的范围，来确保对业务的影响最小。
* 对于第一次测试，团队选择在他们的测试环境中运行实验并运行一个单独的测试。
* 在真实的<ruby> 游戏日 <rt>  Game Day </rt></ruby>风格里，团队在预先计划好的两个小时的窗口期内，选择<ruby> 灾难大师 <rt>  Master of Disaster </rt></ruby>来运行实验。在那段窗口期内，灾难大师会在 EC2 实例安全组中的一个实例上执行这次实验。
* 一旦游戏日结束，团队就会开始进行一个彻底的、免于指责的事后练习。它的重点在于针对稳定状态和原始假设的实验结果。问题会类似于下面这些：

### 事后验证问题

* 防火墙是否检测到未经授权的端口更改？
* 如果更改被检测到，更改是否会被阻止？
* 防火墙是否会将有用的日志信息记录到日志聚合工具中？
* SIEM 是否会对未经授权的更改发出警告？
* 如果防火墙没有检测到未经授权的更改，那么配置的管理工具是否发现了这次更改？
* 配置管理工具是否向日志聚合工具报告了完善的信息？
* SIEM 最后是否进行了关联报警？
* 如果 SIEM 发出了警报，安全运营中心是否能收到这个警报？
* 获得警报的 SOC 分析师是否能对警报采取措施，还是缺少必要的信息？
* 如果 SOC 确定警报是真实的，那么安全事件响应是否能简单地从数据中进行分类活动？

我们系统中对失败的承认和预期已经开始揭示我们对系统工作的假设。我们的使命是利用我们所学到的，并更加广泛地应用它。以此来真正主动地解决安全问题，来超越当前传统主流的被动处理问题的安全模型。

随着我们继续在这个新领域内进行探索，我们一定会发布我们的研究成果。如果您有兴趣想了解更多有关研究的信息或是想参与进来，请随时联系 Aaron Rinehart 或者 Grayson Brewer。

特别感谢 Samuel Roden 对本文提供的见解和想法。

* [看我们相关的文章：是否需要 DevSecOps 这个词？](https://opensource.com/article/18/4/devsecops)

---

via: <https://opensource.com/article/18/4/new-approach-security-instrumentation>

作者：[Aaron Rinehart](https://opensource.com/users/aaronrinehart) 选题：[lujun9972](https://github.com/lujun9972) 译者：[hopefully2333](https://github.com/hopefully2333) 校对：[wxy](https://github.com/wxy)

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