Merge pull request #12 from LCTT/master

更新 20171217
This commit is contained in:
Chang Liu 2017-12-17 00:06:55 +08:00 committed by GitHub
commit b83dc12340
234 changed files with 24316 additions and 4563 deletions

2
.travis.yml Normal file
View File

@ -0,0 +1,2 @@
language: c
script: make -s check

45
Makefile Normal file
View File

@ -0,0 +1,45 @@
RULES := rule-source-added \
rule-translation-requested \
rule-translation-completed \
rule-translation-revised \
rule-translation-published
.PHONY: check match $(RULES)
CHANGE_FILE := /tmp/changes
check: $(CHANGE_FILE)
echo 'PR #$(TRAVIS_PULL_REQUEST) Changes:'
cat $(CHANGE_FILE)
echo
echo 'Check for rules...'
make -k $(RULES) 2>/dev/null | grep '^Rule Matched: '
$(CHANGE_FILE):
git --no-pager diff $(TRAVIS_BRANCH) FETCH_HEAD --no-renames --name-status > $@
rule-source-added:
[ $(shell grep '^A\s\+sources/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) -ge 1 ]
[ $(shell grep -v '^A\s\+sources/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 0 ]
echo 'Rule Matched: $(@)'
rule-translation-requested:
[ $(shell grep '^M\s\+sources/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 1 ]
[ $(shell cat $(CHANGE_FILE) | wc -l) = 1 ]
echo 'Rule Matched: $(@)'
rule-translation-completed:
[ $(shell grep '^D\s\+sources/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 1 ]
[ $(shell grep '^A\s\+translated/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 1 ]
[ $(shell cat $(CHANGE_FILE) | wc -l) = 2 ]
echo 'Rule Matched: $(@)'
rule-translation-revised:
[ $(shell grep '^M\s\+translated/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 1 ]
[ $(shell cat $(CHANGE_FILE) | wc -l) = 1 ]
echo 'Rule Matched: $(@)'
rule-translation-published:
[ $(shell grep '^D\s\+translated/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 1 ]
[ $(shell grep '^A\s\+published/[a-zA-Z0-9_-/ ]*\.md' $(CHANGE_FILE) | wc -l) = 1 ]
[ $(shell cat $(CHANGE_FILE) | wc -l) = 2 ]
echo 'Rule Matched: $(@)'

View File

@ -0,0 +1,179 @@
使用 groff 编写 man 手册页
===================
`groff` 是大多数 Unix 系统上所提供的流行的文本格式化工具 nroff/troff 的 GNU 版本。它一般用于编写手册页,即命令、编程接口等的在线文档。在本文中,我们将给你展示如何使用 `groff` 编写你自己的 man 手册页。
在 Unix 系统上最初有两个文本处理系统troff 和 nroff它们是由贝尔实验室为初始的 Unix 所开发的(事实上,开发 Unix 系统的部分原因就是为了支持这样的一个文本处理系统)。这个文本处理器的第一个版本被称作 roff意为 “runoff”——径流稍后出现了 troff在那时用于为特定的<ruby>排字机<rt>Typesetter</rt></ruby>生成输出。nroff 是更晚一些的版本,它成为了各种 Unix 系统的标准文本处理器。groff 是 nroff 和 troff 的 GNU 实现,用在 Linux 系统上。它包括了几个扩展功能和一些打印设备的驱动程序。
`groff` 能够生成文档、文章和书籍,很多时候它就像是其它的文本格式化系统(如 TeX的血管一样。然而`groff`(以及原来的 nroff有一个固有的功能是 TeX 及其变体所缺乏的:生成普通 ASCII 输出。其它的系统在生成打印的文档方面做得很好,而 `groff` 却能够生成可以在线浏览的普通 ASCII甚至可以在最简单的打印机上直接以普通文本打印。如果要生成在线浏览的文档以及打印的表单`groff` 也许是你所需要的(虽然也有替代品,如 Texinfo、Lametex 等等)。
`groff` 还有一个好处是它比 TeX 小很多;它所需要的支持文件和可执行程序甚至比最小化的 TeX 版本都少。
`groff` 一个特定的用途是用于格式化 Unix 的 man 手册页。如果你是一个 Unix 程序员,你肯定需要编写和生成各种 man 手册页。在本文中,我们将通过编写一个简短的 man 手册页来介绍 `groff` 的使用。
像 TeX 一样,`groff` 使用特定的文本格式化语言来描述如何处理文本。这种语言比 TeX 之类的系统更加神秘一些,但是更加简洁。此外,`groff` 在基本的格式化器之上提供了几个宏软件包;这些宏软件包是为一些特定类型的文档所定制的。举个例子, mgs 宏对于写作文章或论文很适合,而 man 宏可用于 man 手册页。
### 编写 man 手册页
`groff` 编写 man 手册页十分简单。要让你的 man 手册页看起来和其它的一样,你需要从源头上遵循几个惯例,如下所示。在这个例子中,我们将为一个虚构的命令 `coffee` 编写 man 手册页,它用于以各种方式控制你的联网咖啡机。
使用任意文本编辑器,输入如下代码,并保存为 `coffee.man`。不要输入每行的行号,它们仅用于本文中的说明。
```
.TH COFFEE 1 "23 March 94"
.SH NAME
coffee \- Control remote coffee machine
.SH SYNOPSIS
\fBcoffee\fP [ -h | -b ] [ -t \fItype\fP ]
\fIamount\fP
.SH DESCRIPTION
\fBcoffee\fP queues a request to the remote
coffee machine at the device \fB/dev/cf0\fR.
The required \fIamount\fP argument specifies
the number of cups, generally between 0 and
12 on ISO standard coffee machines.
.SS Options
.TP
\fB-h\fP
Brew hot coffee. Cold is the default.
.TP
\fB-b\fP
Burn coffee. Especially useful when executing
\fBcoffee\fP on behalf of your boss.
.TP
\fB-t \fItype\fR
Specify the type of coffee to brew, where
\fItype\fP is one of \fBcolumbian\fP,
\fBregular\fP, or \fBdecaf\fP.
.SH FILES
.TP
\fC/dev/cf0\fR
The remote coffee machine device
.SH "SEE ALSO"
milk(5), sugar(5)
.SH BUGS
May require human intervention if coffee
supply is exhausted.
```
*清单 1示例 man 手册页源文件*
不要让这些晦涩的代码吓坏了你。字符串序列 `\fB`、`\fI` 和 `\fR` 分别用来改变字体为粗体、斜体和正体(罗马字体)。`\fP` 设置字体为前一个选择的字体。
其它的 `groff` <ruby>请求<rt>request</rt></ruby>以点(`.`)开头出现在行首。第 1 行中,我们看到的 `.TH` 请求用于设置该 man 手册页的标题为 `COFFEE`、man 的部分为 `1`、以及该 man 手册页的最新版本的日期。说明man 手册的第 1 部分用于用户命令、第 2 部分用于系统调用等等。使用 `man man` 命令了解各个部分)。
在第 2 行,`.SH` 请求用于标记一个<ruby><rt>section</rt></ruby>的开始,并给该节名称为 `NAME`。注意,大部分的 Unix man 手册页依次使用 `NAME``SYNOPSIS`、`DESCRIPTION`、`FILES`、`SEE ALSO`、`NOTES`、`AUTHOR` 和 `BUGS` 等节,个别情况下也需要一些额外的可选节。这只是编写 man 手册页的惯例,并不强制所有软件都如此。
第 3 行给出命令的名称,并在一个横线(`-`)后给出简短描述。在 `NAME` 节使用这个格式以便你的 man 手册页可以加到 whatis 数据库中——它可以用于 `man -k``apropos` 命令。
第 4-6 行我们给出了 `coffee` 命令格式的大纲。注意,斜体 `\fI...\fP` 用于表示命令行的参数,可选参数用方括号扩起来。
第 7-12 行给出了该命令的摘要介绍。粗体通常用于表示程序或文件的名称。
在 13 行,使用 `.SS` 开始了一个名为 `Options` 的子节。
接着第 14-25 行是选项列表,会使用参数列表样式表示。参数列表中的每一项以 `.TP` 请求来标记;`.TP` 后的行是参数,再之后是该项的文本。例如,第 14-16 行:
```
.TP
\fB-h\P
Brew hot coffee. Cold is the default.
```
将会显示如下:
```
-h Brew hot coffee. Cold is the default.
```
第 26-29 行创建该 man 手册页的 `FILES` 节,它用于描述该命令可能使用的文件。可以使用 `.TP` 请求来表示文件列表。
第 30-31 行,给出了 `SEE ALSO` 节,它提供了其它可以参考的 man 手册页。注意,第 30 行的 `.SH` 请求中 `"SEE ALSO"` 使用括号扩起来,这是因为 `.SH` 使用第一个空格来分隔该节的标题。任何超过一个单词的标题都需要使用引号扩起来成为一个单一参数。
最后,第 32-34 行,是 `BUGS` 节。
### 格式化和安装 man 手册页
为了在你的屏幕上查看这个手册页格式化的样式,你可以使用如下命令:
```
$ groff -Tascii -man coffee.man | more
```
`-Tascii` 选项告诉 `groff` 生成普通 ASCII 输出;`-man` 告诉 `groff` 使用 man 手册页宏集合。如果一切正常,这个 man 手册页显示应该如下。
```
COFFEE(1) COFFEE(1)
NAME
coffee - Control remote coffee machine
SYNOPSIS
coffee [ -h | -b ] [ -t type ] amount
DESCRIPTION
coffee queues a request to the remote coffee machine at
the device /dev/cf0\. The required amount argument speci-
fies the number of cups, generally between 0 and 12 on ISO
standard coffee machines.
Options
-h Brew hot coffee. Cold is the default.
-b Burn coffee. Especially useful when executing cof-
fee on behalf of your boss.
-t type
Specify the type of coffee to brew, where type is
one of columbian, regular, or decaf.
FILES
/dev/cf0
The remote coffee machine device
SEE ALSO
milk(5), sugar(5)
BUGS
May require human intervention if coffee supply is
exhausted.
```
*格式化的 man 手册页*
如之前提到过的,`groff` 能够生成其它类型的输出。使用 `-Tps` 选项替代 `-Tascii` 将会生成 PostScript 输出,你可以将其保存为文件,用 GhostView 查看,或用一个 PostScript 打印机打印出来。`-Tdvi` 会生成设备无关的 .dvi 输出,类似于 TeX 的输出。
如果你希望让别人在你的系统上也可以查看这个 man 手册页,你需要安装这个 groff 源文件到其它用户的 `%MANPATH` 目录里面。标准的 man 手册页放在 `/usr/man`。第一部分的 man 手册页应该放在 `/usr/man/man1` 下,因此,使用命令:
```
$ cp coffee.man /usr/man/man1/coffee.1
```
这将安装该 man 手册页到 `/usr/man` 中供所有人使用(注意使用 `.1` 扩展名而不是 `.man`)。当接下来执行 `man coffee` 命令时,该 man 手册页会被自动重新格式化,并且可查看的文本会被保存到 `/usr/man/cat1/coffee.1.Z` 中。
如果你不能直接复制 man 手册页的源文件到 `/usr/man`(比如说你不是系统管理员),你可创建你自己的 man 手册页目录树,并将其加入到你的 `%MANPATH`。`%MANPATH` 环境变量的格式同 `%PATH` 一样,举个例子,要添加目录 `/home/mdw/man``%MANPATH` ,只需要:
```
$ export MANPATH=/home/mdw/man:$MANPATH
```
`groff` 和 man 手册页宏还有许多其它的选项和格式化命令。找到它们的最好办法是查看 `/usr/lib/groff` 中的文件; `tmac` 目录包含了宏文件,自身通常会包含其所提供的命令的文档。要让 `groff` 使用特定的宏集合,只需要使用 `-m macro` (或 `-macro` 选项。例如,要使用 mgs 宏,使用命令:
```
groff -Tascii -mgs files...
```
`groff` 的 man 手册页对这个选项描述了更多细节。
不幸的是,随同 `groff` 提供的宏集合没有完善的文档。第 7 部分的 man 手册页提供了一些,例如,`man 7 groff_mm` 会给你 mm 宏集合的信息。然而,该文档通常只覆盖了在 `groff` 实现中不同和新功能,而假设你已经了解过原来的 nroff/troff 宏集合(称作 DWBthe Documentor's Work Bench。最佳的信息来源或许是一本覆盖了那些经典宏集合细节的书。要了解更多的编写 man 手册页的信息,你可以看看 man 手册页源文件(`/usr/man` 中),并通过它们来比较源文件的输出。
这篇文章是《Running Linux》 中的一章,由 Matt Welsh 和 Lar Kaufman 著奥莱理出版ISBN 1-56592-100-3。在本书中还包括了 Linux 下使用的各种文本格式化系统的教程。这期的《Linux Journal》中的内容及《Running Linux》应该可以给你提供在 Linux 上使用各种文本工具的良好开端。
### 祝好,撰写快乐!
Matt Welsh [mdw@cs.cornell.edu][1])是康奈尔大学的一名学生和系统程序员,在机器人和视觉实验室从事于时时机器视觉研究。
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/article/1158
作者:[Matt Welsh][a]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/user/800006
[1]:mailto:mdw@cs.cornell.edu

View File

@ -0,0 +1,87 @@
# [因为这个我要点名批评 Hacker News ][14]
> “实现高速缓存会花费 30 个小时,你有额外的 30 个小时吗?
不,你没有。我实际上并不知道它会花多少时间,可能它会花五分钟,你有五分钟吗?不,你还是没有。为什么?因为我在撒谎。它会消耗远超五分钟的时间。这一切把问题简单化的假设都只不过是程序员单方面的乐观主义。”
>
> — 出自 [Owen Astrachan][1] 教授于 2004 年 2 月 23 日在 [CPS 108][2] 上的讲座
[指责开源软件总是离奇难用已经不是一个新论点了][5];这样的论点之前就被很多比我更为雄辩的人提及过,甚至是出自一些人非常推崇开源软件的人士口中。那么为什么我要在这里老调重弹呢?
在周一的 Hacker News 期刊上,一段文章把我逗乐了。文章谈到,一些人认为 [编写代码实现和一个跟 StackOverflow 一样的系统可以简单到爆][6],并自信的 [声称他们可以在 7 月 4 号的周末就写出一版和 StackOverflow 原版一模一样的程序][7],以此来证明这一切是多么容易。另一些人则插话说,[现有的][8][那些仿制产品][9] 就已经是一个很好的例证了。
秉承着自由讨论的精神,我们来假设一个场景。你在思考了一阵之后认为你可以用 ASP.NET MVC 来编写一套你自己的 StackOverflow 。我呢,在被一块儿摇晃着的怀表催眠之后,脑袋又挨了别人一顿棒槌,然后像个二哈一样一页一页的把 StackOverflow 的源码递给你,让你照原样重新拿键盘逐字逐句的在你的环境下把那些代码再敲一遍,做成你的 StackOverflow。假设你可以像我一样打字飞快一分钟能敲 100 个词 ([也就是大约每秒敲八个字母][10]),但是却可以牛叉到我无法企及的打字零错误率。从 StackOverflow 的大小共计 2.3MB 的源码来估计(包括 .CS、 .SQL、 .CSS、 .JS 和 .aspx 文件),就单单是照着源代码这么飞速敲一遍而且一气呵成中间一个字母都不错,你也要差不多用掉至少 80 个小时的时间。
或者你打算从零开始编码实现你自己的 StackOverflow虽然我知道你肯定是不会那样做的。我们假设你从设计程序到敲代码再到最终完成调试只需要区区十倍于抄袭 StackOverflow 源代码的时间。即使在这样的假设条件下,你也要耗费几周的时间昼夜不停得狂写代码。不知道你是否愿意,但是至少我可以欣然承认,如果只给我照抄 StackOverflow 源代码用时的十倍时间来让我自己写 StackOverflow我可是打死也做不到。
_好的_我知道你在听到这些假设的时候已经开始觉得泄气了。*你在想,如果不是全部实现,而只是实现 StackOverflow __大部分__ 的功能呢?这总归会容易很多了吧。*
好的,问题是什么是 “大部分” 功能?如果只去实现提问和回答问题的功能?这个部分应该很简单吧。其实不然,因为实现问和答的功能还要求你必须做出一个对问题及其答案的投票系统,来显示大家对某个答案是赞同还是反对。因为只有这样你才能保证提问者可以得到这个问题的唯一的可信答案。当然,你还不能让人们赞同或者反对他们自己给出的答案,所以你还要去实现这种禁止自投自票的机制。除此之外,你需要去确保用户在一定的时间内不能赞同或反对其他用户太多次,以此来防止有人用机器人程序作弊乱投票。你很可能还需要去实现一个垃圾评论过滤器,即使这个过滤器很基础很简陋,你也要考虑如何去设计它。而且你恐怕还需要去支持用户图标(头像)的功能。并且你将不得不寻找一个自己真正信任的并且与 Markdown 结合很好的干净的 HTML 库(当然,假设你确实想要复用 StackOverflow 的 [那个超棒的编辑器][11] )。你还需要为所有控件购买或者设计一些小图标、小部件,此外你至少需要实现一个基本的管理界面,以便那些喜欢捣鼓的用户可以调整和改动他们的个性化设置。并且你需要实现类似于 Karma 的声望累积系统,以便用户可以随着不断地使用来稳步提升他们的话语权和解锁更多的功能以及可操作性。
但是如果你实现了以上_所有_功能可以说你_就已经_把要做的都做完了。
除非……除非你还要做全文检索功能。尤其是在“边问边搜”(动态检索)的特性中,支持全文检索是必不可少的。此外,录入和显示用户的基本信息,实现对问题答案的评论功能,以及实现一个显示热点提问的页面,以及热点问题和帖子随着时间推移沉下去的这些功能,都将是不可或缺的。另外你肯定还需要去实现回答奖励系统,并支持每个用户用多个不同的 OpenID 账户去登录,然后将这些相关的登录事件通过邮件发送出去来通知用户,并添加一个标签或徽章系统,接着允许管理员通过一个不错的图形界面来配置这些标签和<ruby>徽章<rt>Badge</rt></ruby>。你需要去显示用户的 Karma 历史,以及他们的历史点赞和差评。而且整个页面还需要很流畅的展开和拉伸,因为这个系统的页面随时都可能被 Slashdot、Reddit 或是 StackOverflow 这些动作影响到。
在这之后!你会以为你基本已经大功告成了!
……为了产品的完整性在上面所述的工作都完成之后你又奋不顾身的去实现了升级功能界面语言的国际化Karma 值上限,以及让网站更专业的 CSS 设计、AJAX还有那些看起来理所当然做起来却让人吐血的功能和特性。如果你不是真的动手来尝试做一个和 StackOverflow 一模一样的系统,你肯定不会意识到在整个程序设计实施的过程中,你会踩到无数的鬼才会知道的大坑。
那么请你告诉我:如果你要做一个让人满意的类似产品出来,上述的哪一个功能是你可以省略掉的呢?哪些是“大部分”网站都具备的功能,哪些又不是呢?
正因为这些很容易被忽视的问题,开发者才会以为做一个 StackOverflow 的仿制版产品会很简单。也同样是因为这些被忽视了的因素,开源软件才一直让人用起来很痛苦。很多软件开发人员在看到 StackOverflow 的时候,他们并不能察觉到 StackOverflow 产品的全貌。他们会简单的把 Stackoverflow 的实现抽象成下面一段逻辑和代码:
```
create table QUESTION (ID identity primary key,
TITLE varchar(255), --- 为什么我知道你认为是 255
BODY text,
UPVOTES integer not null default 0,
DOWNVOTES integer not null default 0,
USER integer references USER(ID));
create table RESPONSE (ID identity primary key,
BODY text,
UPVOTES integer not null default 0,
DOWNVOTES integer not null default 0,
QUESTION integer references QUESTION(ID))
```
如果你让这些开发者去实现 StackOverflow进入他脑海中的就是上面的两个 SQL 表和一个用以呈现表格数据的 HTML 文件。他们甚至会忽略数据的格式问题,进而单纯的以为他们可以在一个周末的时间里就把 StackOverflow 做出来。一些稍微老练的开发者可能会意识到他们还要去实现登录和注销功能、评论功能、投票系统,但是仍然会自信的认为这不过也就是利用一个周末就能完成了;因为这些功能也不过意味着在后端多了几张 SQL 表和 HTML 文件。如果借助于 Django 之类的构架和工具,他们甚至可以直接拿来主义地不花一分钱就实现用户登录和评论的功能。
但这种简单的实现却_远远不能_体现出 StackOverflow 的精髓。无论你对 StackOverflow 的感觉如何,大多数使用者似乎都同意 StackOverflow 的用户体验从头到尾都很流畅。使用 StackOverflow 的过程就是在跟一个精心打磨过的产品在愉快地交互。即使我没有深入了解过 StackOverflow ,我也能猜测出这个产品的成功和它的数据库的 Schema 没有多大关系 —— 实际上在有幸研读过 StackOverflow 的源码之后我得以印证了自己的想法StackOverflow 的成功确实和它的数据库设计关系甚小。真正让它成为一个极其易用的网站的原因是它背后_大量的_精雕细琢的设计和实施。多数的开发人员在谈及仿制和克隆一款产品的难度时真的_很少会去考虑到产品背后的打磨和雕琢工作_因为他们认为_这些打磨和雕琢都是偶然的甚至是无足轻重的。_
这就是为什么用开源工具去克隆和山寨 StackOverflow 其实是很容易失败的。即使这些开源开发者只是想去实现 StackOverflow 的主要的“规范和标准特性”,而非全面的高级特性,他们也会在实现的过程中遭遇种种关键和核心的问题,让他们阴沟翻船,半途而废。拿徽章功能来说,如果你要针对普通终端用户来设计徽章, 则要么需要实现一个用户可用来个性化设置徽章的 GUI要么则取巧的设计出一个比较通用的徽章供所有的安装版本来使用。而开源设计的实际情况是开发者会有很多的抱怨和牢骚认为给徽章这种东西设计一个功能全面的 GUI 是根本不可能的。而且他们会固执地把任何标准徽章的提案踢回去,踢出第一宇宙速度,击穿地壳甩到地球的另一端。最终这些开发者还是会搞出一个类似于 Roundup 的 bug tracker 程序都在使用的流程和方案:即实现一个通用的机制,提供以 Python 或 PHP 为基础的一些系统 API 以便那些可以自如使用 Python 或 PHP 的人可以轻松的通过这些编程接口来定制化他们自己的徽章。而且老实说PHP 和 Python 可是比任何可能的 GUI 接口都要好用和强大得多,为什么还要考虑 GUI 的方案呢?(出自开源开发者的想法)
同样的,开源开发者会认为那些系统设置和管理员界面也一样可以省略掉。在他们看来,假如你是一个管理员,有 SQL 服务器的权限,那么你就理所当然的具备那些系统管理员该有的知识和技能。那么你其实可以使用 Djang-admin 或者任何类似的工具来轻松的对 StackOverflow 做很多设置和改造工作。毕竟如果你是一个 mods (懂如何 mod 的人)那么你肯定知道网站是怎么工作的,懂得如何利用专业工具去设置和改造一个网站。对啊!这不就得了! 毋庸置疑,在开源开发者重做他们自己的 StackOverflow 的时候,他们也不会把任何 StackOverflow 在接口上面的失败设计纠正过来。即使是原版 StackOverflow 里面最愚蠢最失败的那个设计(即要求用户必须拥有一个 OpenID 并知道如何使用它)在某个将来最终被 StackOverflow 删除和修正掉了, 我相信正在复制 StackOverflow 模式的那些开源克隆产品也还是会不假思索的把这个 OpenID 的功能仿制出来。这就好比是 GNOME 和 KDE 多年以来一直在做的事情,他们并没有把精力放在如何在设计之初就避免 Windows 的那些显而易见的毛病和问题,相反的却是在亦步亦趋的重复着 Windows 的设计,想办法用开源的方式做出一个比拟 Windows 功能的系统。
开发者可能不会关心一个应用的上述设计细节,但是终端用户一定会。尤其是当他们在尝试去选择要使用哪个应用的时候,这些终端用户更会重视这些接口设计是否易用。就好像一家好的软件公司希望通过确保其产品在出货之前就有一流的质量,以降低售后维护支持的成本一样,懂行的消费者也会在他们购买这些产品之前就确保产品好用,以防在使用的时候不知所措,然后无奈的打电话给售后来解决问题。开源产品就失败在这里,而且相当之失败。一般来讲,付费软件则在这方面做得好很多。
这不是说开源软件没有自己的立足之地,这个博客就运行在 Apache、[Django][12]、[PostgreSQL][13] 和 Linux 搭建的开源系统之上。但是让我来告诉你吧,配置这些堆栈可不是谁都可以做的。老版本的 PostgreSQL 需要手工配置 Vacuuming 来确保数据库的自动清理,而即使是最新版本的 Ubuntu 和 FreeBSD 也仍然要求用户去手工配置他们的第一个数据库集群。
相比之下MS SQL (微软的 SQL 数据库) 则不需要你手工配置以上的任何一样东西。至于 Apache …… 我的天Apache 简直复杂到让我根本来不及去尝试给一个新用户讲解我们如何可以通过一个一次性的安装过程就能把虚拟机、MovableType几个 Diango apps 和 WordPress 配置在一起并流畅地使用。单单是给那些技术背景还不错但并非软件开发者的用户解释清楚 Apache 的那些针对多进程和多线程的设置参数就已经够我喝一壶的了。相比之下,微软的 IIS 7 或者是使用了 OS X 服务器的那个几乎闭源的 GUI 管理器的 Apache 在配置的时候就要简单上不止一个数量级了。Django 确实是一个好的开源产品,但它也 _只是_ 一个基础构架,而并非是一个可以直接面向终端普通用户的商业产品。而开源真正的强项就 _恰恰在_ 这种基础构架的开发和创新上,这也正是驱使开发者为开源做贡献的最本真的动力。
所以我的结论是,如果下次你再看到一个你喜欢的应用程序,请好好细心地揣摩一下这款产品,揣摩一下所有的那些针对用户的体贴入微的设计细节。而不是武断的认为你可以轻轻松松的在一周之内就用开源工具做一个和这个应用一摸一样的产品出来。那些认为制作和实现一个应用程序如此简单的人,十之八九都是因为忽略了软件开发的最终产品是要交给用户去用的。
-------------------------------------------------------------------------------
via: https://bitquabit.com/post/one-which-i-call-out-hacker-news/
作者:[Benjamin Pollack][a]
译者:[hopefully2333](https://github.com/hopefully2333)[yunfengHe](https://github.com/yunfengHe)
校对:[yunfengHe](https://github.com/yunfengHe)[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://bitquabit.com/meta/about/
[1]:http://www.cs.duke.edu/~ola/
[2]:http://www.cs.duke.edu/courses/cps108/spring04/
[3]:https://bitquabit.com/categories/programming
[4]:https://bitquabit.com/categories/technology
[5]:http://blog.bitquabit.com/2009/06/30/one-which-i-say-open-source-software-sucks/
[6]:http://news.ycombinator.com/item?id=678501
[7]:http://news.ycombinator.com/item?id=678704
[8]:http://code.google.com/p/cnprog/
[9]:http://code.google.com/p/soclone/
[10]:http://en.wikipedia.org/wiki/Words_per_minute
[11]:http://github.com/derobins/wmd/tree/master
[12]:http://www.djangoproject.com/
[13]:http://www.postgresql.org/
[14]:https://bitquabit.com/post/one-which-i-call-out-hacker-news/

View File

@ -0,0 +1,331 @@
ARMv8 上的 kprobes 事件跟踪
==============
![core-dump](http://www.linaro.org/wp-content/uploads/2016/02/core-dump.png)
### 介绍
kprobes 是一种内核功能,它允许通过在执行(或模拟)断点指令之前和之后,设置调用开发者提供例程的任意断点来检测内核。可参见 kprobes 文档^注1 获取更多信息。基本的 kprobes 功能可使用 `CONFIG_KPROBEES` 来选择。在 arm64 的 v4.8 内核发行版中, kprobes 支持被添加到主线。
在这篇文章中,我们将介绍 kprobes 在 arm64 上的使用,通过在命令行中使用 debugfs 事件追踪接口来收集动态追踪事件。这个功能在一些架构(包括 arm32上可用已经有段时间现在在 arm64 上也能使用了。这个功能可以无需编写任何代码就能使用 kprobes。
### 探针类型
kprobes 子系统提供了三种不同类型的动态探针,如下所述。
#### kprobes
基本探针是 kprobes 插入的一个软件断点,用以替代你正在探测的指令,当探测点被命中时,它为最终的单步执行(或模拟)保存下原始指令。
#### kretprobes
kretprobes 是 kprobes 的一部分,它允许拦截返回函数,而不必在返回点设置一个探针(或者可能有多个探针)。对于支持的架构(包括 ARMv8只要选择 kprobes就可以选择此功能。
#### jprobes
jprobes 允许通过提供一个具有相同<ruby>调用签名<rt>call signature</rt></ruby>的中间函数来拦截对一个函数的调用这里中间函数将被首先调用。jprobes 只是一个编程接口,它不能通过 debugfs 事件追踪子系统来使用。因此,我们将不会在这里进一步讨论 jprobes。如果你想使用 jprobes请参考 kprobes 文档。
### 调用 kprobes
kprobes 提供一系列能从内核代码中调用的 API 来设置探测点和当探测点被命中时调用的注册函数。在不往内核中添加代码的情况下kprobes 也是可用的,这是通过写入特定事件追踪的 debugfs 文件来实现的,需要在文件中设置探针地址和信息,以便在探针被命中时记录到追踪日志中。后者是本文将要讨论的重点。最后 kprobes 可以通过 perl 命令来使用。
#### kprobes API
内核开发人员可以在内核中编写函数(通常在专用的调试模块中完成)来设置探测点,并且在探测指令执行前和执行后立即执行任何所需操作。这在 kprobes.txt 中有很好的解释。
#### 事件追踪
事件追踪子系统有自己的自己的文档^注2 ,对于了解一般追踪事件的背景可能值得一读。事件追踪子系统是<ruby>追踪点<rt>tracepoints</rt></ruby>和 kprobes 事件追踪的基础。事件追踪文档重点关注追踪点所以请在查阅文档时记住这一点。kprobes 与追踪点不同的是没有预定义的追踪点列表,而是采用动态创建的用于触发追踪事件信息收集的任意探测点。事件追踪子系统通过一系列 debugfs 文件来控制和监视。事件追踪(`CONFIG_EVENT_TRACING`)将在被如 kprobe 事件追踪子系统等需要时自动选择。
##### kprobes 事件
使用 kprobes 事件追踪子系统用户可以在内核任意断点处指定要报告的信息只需要指定任意现有可探测指令的地址以及格式化信息即可确定。在执行过程中遇到断点时kprobes 将所请求的信息传递给事件追踪子系统的公共部分这些部分将数据格式化并追加到追踪日志中就像追踪点的工作方式一样。kprobes 使用一个类似的但是大部分是独立的 debugfs 文件来控制和显示追踪事件信息。该功能可使用 `CONFIG_KPROBE_EVENT` 来选择。Kprobetrace 文档^ 注3 提供了如何使用 kprobes 事件追踪的基本信息,并且应当被参考用以了解以下介绍示例的详细信息。
#### kprobes 和 perf
perf 工具为 kprobes 提供了另一个命令行接口。特别地,`perf probe` 允许探测点除了由函数名加偏移量和地址指定外还可由源文件和行号指定。perf 接口实际上是使用 kprobes 的 debugfs 接口的封装器。
### Arm64 kprobes
上述所有 kprobes 的方面现在都在 arm64 上得到实现,然而实际上与其它架构上的有一些不同:
* 注册名称参数当然是依架构而特定的,并且可以在 ARM ARM 中找到。
* 目前不是所有的指令类型都可被探测。当前不可探测的指令包括 mrs/msr除了 DAIF 读取、异常生成指令、eret 和 hint除了 nop 变体)。在这些情况下,只探测一个附近的指令来代替是最简单的。这些指令在探测的黑名单里是因为在 kprobes 单步执行或者指令模拟时它们对处理器状态造成的改变是不安全的,这是由于 kprobes 构造的单步执行上下文和指令所需要的不一致,或者是由于指令不能容忍在 kprobes 中额外的处理时间和异常处理ldx/stx
* 试图识别在 ldx/stx 序列中的指令并且防止探测,但是理论上这种检查可能会失败,导致允许探测到的原子序列永远不会成功。当探测原子代码序列附近时应该小心。
* 注意由于 linux ARM64 调用约定的具体信息,为探测函数可靠地复制栈帧是不可能的,基于此不要试图用 jprobes 这样做,这一点与支持 jprobes 的大多数其它架构不同。这样的原因是被调用者没有足够的信息来确定需要的栈数量。
* 注意当探针被命中时,一个探针记录的栈指针信息将反映出使用中的特定栈指针,它是内核栈指针或者中断栈指针。
* 有一组内核函数是不能被探测的,通常因为它们作为 kprobes 处理的一部分被调用。这组函数的一部分是依架构特定的,并且也包含如异常入口代码等。
### 使用 kprobes 事件追踪
kprobes 的一个常用例子是检测函数入口和/或出口。因为只需要使用函数名来作为探针地址它安装探针特别简单。kprobes 事件追踪将查看符号名称并且确定地址。ARMv8 调用标准定义了函数参数和返回值的位置,并且这些可以作为 kprobes 事件处理的一部分被打印出来。
#### 例子: 函数入口探测
检测 USB 以太网驱动程序复位功能:
```
$ pwd
/sys/kernel/debug/tracing
$ cat > kprobe_events <<EOF
p ax88772_reset %x0
EOF
$ echo 1 > events/kprobes/enable
```
此时每次该驱动的 `ax8872_reset()` 函数被调用,追踪事件都将会被记录。这个事件将显示指向通过作为此函数的唯一参数的 `X0`(按照 ARMv8 调用标准)传入的 `usbnet` 结构的指针。插入需要以太网驱动程序的 USB 加密狗后,我们看见以下追踪信息:
```
$ cat trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:8
#
# _—=> irqs-off
# / _—-=> need-resched
# | / _—=> hardirq/softirq
# || / _=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
kworker/0:0-4 [000] d… 10972.102939: p_ax88772_reset_0:
(ax88772_reset+0x0/0x230) arg1=0xffff800064824c80
```
这里我们可以看见传入到我们的探测函数的指针参数的值。由于我们没有使用 kprobes 事件追踪的可选标签功能,我们需要的信息自动被标注为 `arg1`。注意这指向我们需要 kprobes 记录这个探针的一组值的第一个,而不是函数参数的实际位置。在这个例子中它也只是碰巧是我们探测函数的第一个参数。
#### 例子: 函数入口和返回探测
kretprobe 功能专门用于探测函数返回。在函数入口 kprobes 子系统将会被调用并且建立钩子以便在函数返回时调用,钩子将记录需求事件信息。对最常见情况,返回信息通常在 `X0` 寄存器中,这是非常有用的。在 `%x0` 中返回值也可以被称为 `$retval`。以下例子也演示了如何提供一个可读的标签来展示有趣的信息。
使用 kprobes 和 kretprobe 检测内核 `do_fork()` 函数来记录参数和结果的例子:
```
$ cd /sys/kernel/debug/tracing
$ cat > kprobe_events <<EOF
p _do_fork %x0 %x1 %x2 %x3 %x4 %x5
r _do_fork pid=%x0
EOF
$ echo 1 > events/kprobes/enable
```
此时每次对 `_do_fork()` 的调用都会产生两个记录到 trace 文件的 kprobe 事件,一个报告调用参数值,另一个报告返回值。返回值在 trace 文件中将被标记为 `pid`。这里是三次 fork 系统调用执行后的 trace 文件的内容:
```
_$ cat trace
# tracer: nop
#
# entries-in-buffer/entries-written: 6/6 #P:8
#
# _—=> irqs-off
# / _—-=> need-resched
# | / _—=> hardirq/softirq
# || / _=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
bash-1671 [001] d… 204.946007: p__do_fork_0: (_do_fork+0x0/0x3e4) arg1=0x1200011 arg2=0x0 arg3=0x0 arg4=0x0 arg5=0xffff78b690d0 arg6=0x0
bash-1671 [001] d..1 204.946391: r__do_fork_0: (SyS_clone+0x18/0x20 <- _do_fork) pid=0x724
bash-1671 [001] d… 208.845749: p__do_fork_0: (_do_fork+0x0/0x3e4) arg1=0x1200011 arg2=0x0 arg3=0x0 arg4=0x0 arg5=0xffff78b690d0 arg6=0x0
bash-1671 [001] d..1 208.846127: r__do_fork_0: (SyS_clone+0x18/0x20 <- _do_fork) pid=0x725
bash-1671 [001] d… 214.401604: p__do_fork_0: (_do_fork+0x0/0x3e4) arg1=0x1200011 arg2=0x0 arg3=0x0 arg4=0x0 arg5=0xffff78b690d0 arg6=0x0
bash-1671 [001] d..1 214.401975: r__do_fork_0: (SyS_clone+0x18/0x20 <- _do_fork) pid=0x726_
```
#### 例子: 解引用指针参数
对于指针值kprobes 事件处理子系统也允许解引用和打印所需的内存内容,适用于各种基本数据类型。为了展示所需字段,手动计算结构的偏移量是必要的。
检测 `_do_wait()` 函数:
```
$ cat > kprobe_events <<EOF
p:wait_p do_wait wo_type=+0(%x0):u32 wo_flags=+4(%x0):u32
r:wait_r do_wait $retval
EOF
$ echo 1 > events/kprobes/enable
```
注意在第一个探针中使用的参数标签是可选的,并且可用于更清晰地识别记录在追踪日志中的信息。带符号的偏移量和括号表明了寄存器参数是指向记录在追踪日志中的内存内容的指针。`:u32` 表明了内存位置包含一个无符号的 4 字节宽的数据(在这个例子中指局部定义的结构中的一个 emum 和一个 int
探针标签(冒号后)是可选的,并且将用来识别日志中的探针。对每个探针来说标签必须是独一无二的。如果没有指定,将从附近的符号名称自动生成一个有用的标签,如前面的例子所示。
也要注意 `$retval` 参数可以只是指定为 `%x0`
这里是两次 fork 系统调用执行后的 trace 文件的内容:
```
$ cat trace
# tracer: nop
#
# entries-in-buffer/entries-written: 4/4 #P:8
#
# _—=> irqs-off
# / _—-=> need-resched
# | / _—=> hardirq/softirq
# || / _=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
bash-1702 [001] d… 175.342074: wait_p: (do_wait+0x0/0x260) wo_type=0x3 wo_flags=0xe
bash-1702 [002] d..1 175.347236: wait_r: (SyS_wait4+0x74/0xe4 <- do_wait) arg1=0x757
bash-1702 [002] d… 175.347337: wait_p: (do_wait+0x0/0x260) wo_type=0x3 wo_flags=0xf
bash-1702 [002] d..1 175.347349: wait_r: (SyS_wait4+0x74/0xe4 <- do_wait) arg1=0xfffffffffffffff6
```
#### 例子: 探测任意指令地址
在前面的例子中,我们已经为函数的入口和出口插入探针,然而探测一个任意指令(除少数例外)是可能的。如果我们正在 C 函数中放置一个探针,第一步是查看代码的汇编版本以确定我们要放置探针的位置。一种方法是在 vmlinux 文件上使用 gdb,并在要放置探针的函数中展示指令。下面是一个在 `arch/arm64/kernel/modules.c``module_alloc` 函数执行此操作的示例。在这种情况下,因为 gdb 似乎更喜欢使用弱符号定义,并且它是与这个函数关联的存根代码,所以我们从 System.map 中来获取符号值:
```
$ grep module_alloc System.map
ffff2000080951c4 T module_alloc
ffff200008297770 T kasan_module_alloc
```
在这个例子中我们使用了交叉开发工具,并且在我们的主机系统上调用 gdb 来检查指令包含我们感兴趣函数。
```
$ ${CROSS_COMPILE}gdb vmlinux
(gdb) x/30i 0xffff2000080951c4
0xffff2000080951c4 <module_alloc>: sub sp, sp, #0x30
0xffff2000080951c8 <module_alloc+4>: adrp x3, 0xffff200008d70000
0xffff2000080951cc <module_alloc+8>: add x3, x3, #0x0
0xffff2000080951d0 <module_alloc+12>: mov x5, #0x713 // #1811
0xffff2000080951d4 <module_alloc+16>: mov w4, #0xc0 // #192
0xffff2000080951d8 <module_alloc+20>:
mov x2, #0xfffffffff8000000 // #-134217728
0xffff2000080951dc <module_alloc+24>: stp x29, x30, [sp,#16] 0xffff2000080951e0 <module_alloc+28>: add x29, sp, #0x10
0xffff2000080951e4 <module_alloc+32>: movk x5, #0xc8, lsl #48
0xffff2000080951e8 <module_alloc+36>: movk w4, #0x240, lsl #16
0xffff2000080951ec <module_alloc+40>: str x30, [sp] 0xffff2000080951f0 <module_alloc+44>: mov w7, #0xffffffff // #-1
0xffff2000080951f4 <module_alloc+48>: mov x6, #0x0 // #0
0xffff2000080951f8 <module_alloc+52>: add x2, x3, x2
0xffff2000080951fc <module_alloc+56>: mov x1, #0x8000 // #32768
0xffff200008095200 <module_alloc+60>: stp x19, x20, [sp,#32] 0xffff200008095204 <module_alloc+64>: mov x20, x0
0xffff200008095208 <module_alloc+68>: bl 0xffff2000082737a8 <__vmalloc_node_range>
0xffff20000809520c <module_alloc+72>: mov x19, x0
0xffff200008095210 <module_alloc+76>: cbz x0, 0xffff200008095234 <module_alloc+112>
0xffff200008095214 <module_alloc+80>: mov x1, x20
0xffff200008095218 <module_alloc+84>: bl 0xffff200008297770 <kasan_module_alloc>
0xffff20000809521c <module_alloc+88>: tbnz w0, #31, 0xffff20000809524c <module_alloc+136>
0xffff200008095220 <module_alloc+92>: mov sp, x29
0xffff200008095224 <module_alloc+96>: mov x0, x19
0xffff200008095228 <module_alloc+100>: ldp x19, x20, [sp,#16] 0xffff20000809522c <module_alloc+104>: ldp x29, x30, [sp],#32
0xffff200008095230 <module_alloc+108>: ret
0xffff200008095234 <module_alloc+112>: mov sp, x29
0xffff200008095238 <module_alloc+116>: mov x19, #0x0 // #0
```
在这种情况下,我们将在此函数中显示以下源代码行的结果:
```
p = __vmalloc_node_range(size, MODULE_ALIGN, VMALLOC_START,
VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
NUMA_NO_NODE, __builtin_return_address(0));
```
……以及在此代码行的函数调用的返回值:
```
if (p && (kasan_module_alloc(p, size) < 0)) {
```
我们可以在从调用外部函数的汇编代码中识别这些。为了展示这些值,我们将在目标系统上的 `0xffff20000809520c``0xffff20000809521c` 处放置探针。
```
$ cat > kprobe_events <<EOF
p 0xffff20000809520c %x0
p 0xffff20000809521c %x0
EOF
$ echo 1 > events/kprobes/enable
```
现在将一个以太网适配器加密狗插入到 USB 端口后,我们看到以下写入追踪日志的内容:
```
$ cat trace
# tracer: nop
#
# entries-in-buffer/entries-written: 12/12 #P:8
#
# _—=> irqs-off
# / _—-=> need-resched
# | / _—=> hardirq/softirq
# || / _=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
systemd-udevd-2082 [000] d… 77.200991: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff200001188000
systemd-udevd-2082 [000] d… 77.201059: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
systemd-udevd-2082 [000] d… 77.201115: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff200001198000
systemd-udevd-2082 [000] d… 77.201157: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
systemd-udevd-2082 [000] d… 77.227456: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff2000011a0000
systemd-udevd-2082 [000] d… 77.227522: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
systemd-udevd-2082 [000] d… 77.227579: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff2000011b0000
systemd-udevd-2082 [000] d… 77.227635: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
modprobe-2097 [002] d… 78.030643: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff2000011b8000
modprobe-2097 [002] d… 78.030761: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
modprobe-2097 [002] d… 78.031132: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff200001270000
modprobe-2097 [002] d… 78.031187: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
```
kprobes 事件系统的另一个功能是记录统计信息,这可在 `inkprobe_profile` 中找到。在以上追踪后,该文件的内容为:
```
$ cat kprobe_profile
p_0xffff20000809520c 6 0
p_0xffff20000809521c 6 0
```
这表明我们设置的两处断点每个共发生了 8 次命中,这当然与追踪日志数据是一致的。在 kprobetrace 文档中有更多 kprobe_profile 的功能描述。
也可以进一步过滤 kprobes 事件。用来控制这点的 debugfs 文件在 kprobetrace 文档中被列出,然而它们内容的详细信息大多在 trace events 文档中被描述。
### 总结
现在Linux ARMv8 对支持 kprobes 功能也和其它架构相当。有人正在做添加 uprobes 和 systemtap 支持的工作。这些功能/工具和其他已经完成的功能(如: perf、 coresight允许 Linux ARMv8 用户像在其它更老的架构上一样调试和测试性能。
* * *
参考文献
- 注1 Jim Keniston, Prasanna S. Panchamukhi, Masami Hiramatsu. “Kernel Probes (kprobes).” _GitHub_. GitHub, Inc., 15 Aug. 2016\. Web. 13 Dec. 2016.
- 注2 Tso, Theodore, Li Zefan, and Tom Zanussi. “Event Tracing.” _GitHub_. GitHub, Inc., 3 Mar. 2016\. Web. 13 Dec. 2016.
- 注3 Hiramatsu, Masami. “Kprobe-based Event Tracing.” _GitHub_. GitHub, Inc., 18 Aug. 2016\. Web. 13 Dec. 2016.
----------------
作者简介 [David Long][8] 在 Linaro Kernel - Core Development 团队中担任工程师。 在加入 Linaro 之前他在商业和国防行业工作了数年既做嵌入式实时工作又为Unix提供软件开发工具。之后在 Digital又名 Compaq公司工作了十几年负责 Unix 标准C 编译器和运行时库的工作。之后 David 又去了一系列初创公司做嵌入式 Linux 和安卓系统,嵌入式定制操作系统和 Xen 虚拟化。他拥有 MIPSAlpha 和 ARM 平台的经验(等等)。他使用过从 1979 年贝尔实验室 V6 开始的大部分Unix操作系统并且长期以来一直是 Linux 用户和倡导者。他偶尔也因使用烙铁和数字示波器调试设备驱动而知名。
--------------------------------------------------------------------------------
via: http://www.linaro.org/blog/kprobes-event-tracing-armv8/
作者:[David Long][a]
译者:[kimii](https://github.com/kimii)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linaro.org/author/david-long/
[1]:http://www.linaro.org/blog/kprobes-event-tracing-armv8/#
[2]:https://github.com/torvalds/linux/blob/master/Documentation/kprobes.txt
[3]:https://github.com/torvalds/linux/blob/master/Documentation/trace/events.txt
[4]:https://github.com/torvalds/linux/blob/master/Documentation/trace/kprobetrace.txt
[5]:https://github.com/torvalds/linux/blob/master/Documentation/kprobes.txt
[6]:https://github.com/torvalds/linux/blob/master/Documentation/trace/events.txt
[7]:https://github.com/torvalds/linux/blob/master/Documentation/trace/kprobetrace.txt
[8]:http://www.linaro.org/author/david-long/
[9]:http://www.linaro.org/blog/kprobes-event-tracing-armv8/#comments
[10]:http://www.linaro.org/blog/kprobes-event-tracing-armv8/#
[11]:http://www.linaro.org/tag/arm64/
[12]:http://www.linaro.org/tag/armv8/
[13]:http://www.linaro.org/tag/jprobes/
[14]:http://www.linaro.org/tag/kernel/
[15]:http://www.linaro.org/tag/kprobes/
[16]:http://www.linaro.org/tag/kretprobes/
[17]:http://www.linaro.org/tag/perf/
[18]:http://www.linaro.org/tag/tracing/

View File

@ -0,0 +1,340 @@
如何在 Linux 系统里用 Scrot 截屏
============================================================
最近,我们介绍过 [gnome-screenshot][17] 工具,这是一个很优秀的屏幕抓取工具。但如果你想找一个在命令行运行的更好用的截屏工具,你一定要试试 Scrot。这个工具有一些 gnome-screenshot 没有的独特功能。在这篇文章里,我们会通过简单易懂的例子来详细介绍 Scrot。
请注意一下,这篇文章里的所有例子都在 Ubuntu 16.04 LTS 上测试过,我们用的 scrot 版本是 0.8。
### 关于 Scrot
[Scrot][18] **SCR**eensh**OT** 是一个屏幕抓取工具,使用 imlib2 库来获取和保存图片。由 Tom Gilbert 用 C 语言开发完成,通过 BSD 协议授权。
### 安装 Scrot
scort 工具可能在你的 Ubuntu 系统里预装了,不过如果没有的话,你可以用下面的命令安装:
```
sudo apt-get install scrot
```
安装完成后,你可以通过下面的命令来使用:
```
scrot [options] [filename]
```
**注意**:方括号里的参数是可选的。
### Scrot 的使用和特点
在这个小节里,我们会介绍如何使用 Scrot 工具,以及它的所有功能。
如果不带任何选项执行命令,它会抓取整个屏幕。
[
![使用 Scrot](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/scrot.png)
][19]
默认情况下,抓取的截图会用带时间戳的文件名保存到当前目录下,不过你也可以在运行命令时指定截图文件名。比如:
```
scrot [image-name].png
```
### 获取程序版本
你想的话,可以用 `-v` 选项来查看 scrot 的版本。
```
scrot -v
```
这是例子:
[
![获取 scrot 版本](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/version.png)
][20]
### 抓取当前窗口
这个工具可以限制抓取当前的焦点窗口。这个功能可以通过 `-u` 选项打开。
```
scrot -u
```
例如,这是我在命令行执行上边命令时的桌面:
[
![用 scrot 截取窗口](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/desktop.png)
][21]
这是另一张用 scrot 抓取的截图:
[
![用 scrot 抓取的图片](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/active.png)
][22]
### 抓取选定窗口
这个工具还可以让你抓取任意用鼠标点击的窗口。这个功能可以用 `-s` 选项打开。
```
scrot -s
```
例如,在下面的截图里你可以看到,我有两个互相重叠的终端窗口。我在上层的窗口里执行上面的命令。
[
![选择窗口](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/select1.png)
][23]
现在假如我想抓取下层的终端窗口。这样我只要在执行命令后点击窗口就可以了 —— 在你用鼠标点击之前,命令的执行不会结束。
这是我点击了下层终端窗口后的截图:
[
![窗口截图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/select2.png)
][24]
**注意**:你可以在上面的截图里看到,下层终端窗口的整个显示区域都被抓去下来了,甚至包括了上层窗口的部分叠加内容。
### 在截屏时包含窗口边框
我们之前介绍的 `-u` 选项在截屏时不会包含窗口边框。不过,需要的话你也可以在截屏时包含窗口边框。这个功能可以通过 `-b` 选项打开(当然要和 `-u` 选项一起)。
```
scrot -ub
```
下面是示例截图:
[
![截屏时包含窗口边框](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/border-new.png)
][25]
**注意**:截屏时包含窗口边框同时也会增加一点额外的背景。
### 延时截屏
你可以在开始截屏时增加一点延时。需要在 `--delay``-d` 选项后设定一个时间值参数。
```
scrot --delay [NUM]
scrot --delay 5
```
例如:
[
![延时截屏](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/delay.png)
][26]
在这例子里scrot 会等待 5 秒再截屏。
### 截屏前倒数
这个工具也可以在你使用延时功能后显示一个倒计时。这个功能可以通过 `-c` 选项打开。
```
scrot delay [NUM] -c
scrot -d 5 -c
```
下面是示例截图:
[
![延时截屏示例](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/countdown.png)
][27]
### 图片质量
你可以使用这个工具来调整截图的图片质量,范围是 1-100 之间。较大的值意味着更大的文件大小以及更低的压缩率。默认值是 75不过最终效果根据选择的文件类型也会有一些差异。
这个功能可以通过 `--quality``-q` 选项打开,但是你必须提供一个 1 - 100 之间的数值作为参数。
```
scrot quality [NUM]
scrot quality 10
```
下面是示例截图:
[
![截屏质量](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/img-quality.jpg)
][28]
你可以看到,`-q` 选项的参数更靠近 1 让图片质量下降了很多。
### 生成缩略图
scort 工具还可以生成截屏的缩略图。这个功能可以通过 `--thumb` 选项打开。这个选项也需要一个 NUM 数值作为参数,基本上是指定原图大小的百分比。
```
scrot --thumb NUM
scrot --thumb 50
```
**注意**:加上 `--thumb` 选项也会同时保存原始截图文件。
例如,下面是我测试的原始截图:
[
![原始截图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/orig.png)
][29]
下面是保存的缩略图:
[
![截图缩略图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/thmb.png)
][30]
### 拼接多显示器截屏
如果你的电脑接了多个显示设备,你可以用 scort 抓取并拼接这些显示设备的截图。这个功能可以通过 `-m` 选项打开。
```
scrot -m
```
下面是示例截图:
[
![拼接截屏](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/multiple.png)
][31]
### 在保存截图后执行操作
使用这个工具,你可以在保存截图后执行各种操作 —— 例如,用像 gThumb 这样的图片编辑器打开截图。这个功能可以通过 `-e` 选项打开。下面是例子:
```
scrot abc.png -e 'gthumb abc.png'
```
这个命令里的 gthumb 是一个图片编辑器,上面的命令在执行后会自动打开。
下面是命令的截图:
[
![截屏后执行命令](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/exec1.png)
][32]
这个是上面命令执行后的效果:
[
![示例截图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/exec2.png)
][33]
你可以看到 scrot 抓取了屏幕截图,然后再启动了 gThumb 图片编辑器打开刚才保存的截图图片。
如果你截图时没有指定文件名,截图将会用带有时间戳的文件名保存到当前目录 —— 这是 scrot 的默认设定,我们前面已经说过。
下面是一个使用默认名字并且加上 `-e` 选项来截图的例子:
```
scrot -e 'gthumb $n'
```
[
![scrot 截屏后运行 gthumb](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/exec3.png)
][34]
有个地方要注意的是 `$n` 是一个特殊字符串,用来获取当前截图的文件名。关于特殊字符串的更多细节,请继续看下个小节。
### 特殊字符串
scrot 的 `-e`(或 `--exec`)选项和文件名参数可以使用格式说明符。有两种类型格式。第一种是以 `%` 加字母组成,用来表示日期和时间,第二种以 `$` 开头scrot 内部使用。
下面介绍几个 `--exec` 和文件名参数接受的说明符。
`$f`  让你可以使用截图的全路径(包括文件名)。
例如:
```
scrot ashu.jpg -e mv $f ~/Pictures/Scrot/ashish/
```
下面是示例截图:
[
![示例](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/f.png)
][35]
如果你没有指定文件名scrot 默认会用日期格式的文件名保存截图。这个是 scrot 的默认文件名格式:`%yy-%mm-%dd-%hhmmss_$wx$h_scrot.png`。
`$n`  提供截图文件名。下面是示例截图:
[
![scrot $n variable](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/n.png)
][36]
`$s`  获取截图的文件大小。这个功能可以像下面这样使用。
```
scrot abc.jpg -e echo $s
```
下面是示例截图:
[
![scrot $s 变量](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/s.png)
][37]
类似的,你也可以使用其他格式字符串 `$p`、`$w`、 `$h`、`$t`、`$$` 以及 `\n` 来分别获取图片像素大小、图像宽度、图像高度、图像格式、输入 `$` 字符、以及换行。你可以像上面介绍的 `$s` 格式那样使用这些字符串。
### 结论
这个应用能轻松地安装在 Ubuntu 系统上对初学者比较友好。scrot 也提供了一些高级功能,比如支持格式化字符串,方便专业用户用脚本处理。当然,如果你想用起来的话有一点轻微的学习曲线。
--------------------------------------------------------------------------------
via: https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/
作者:[Himanshu Arora][a]
译者:[zpl1025](https://github.com/zpl1025)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/
[1]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#get-the-applicationnbspversion
[2]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#capturing-current-window
[3]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#selecting-a-window
[4]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#includenbspwindow-border-in-screenshots
[5]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#delay-in-taking-screenshots
[6]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#countdown-before-screenshot
[7]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#image-quality
[8]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#generating-thumbnails
[9]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#join-multiple-displays-shots
[10]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#executing-operations-on-saved-images
[11]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#special-strings
[12]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#about-scrot
[13]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#scrot-installation
[14]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#scrot-usagefeatures
[15]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#conclusion
[16]:https://www.howtoforge.com/subscription/
[17]:https://www.howtoforge.com/tutorial/taking-screenshots-in-linux-using-gnome-screenshot/
[18]:https://en.wikipedia.org/wiki/Scrot
[19]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/scrot.png
[20]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/version.png
[21]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/desktop.png
[22]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/active.png
[23]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/select1.png
[24]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/select2.png
[25]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/border-new.png
[26]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/delay.png
[27]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/countdown.png
[28]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/img-quality.jpg
[29]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/orig.png
[30]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/thmb.png
[31]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/multiple.png
[32]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/exec1.png
[33]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/exec2.png
[34]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/exec3.png
[35]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/f.png
[36]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/n.png
[37]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/s.png

View File

@ -0,0 +1,130 @@
更多你所不知道的 Linux 命令
============================================================
![unknown Linux commands](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/outer-limits-of-linux.jpg?itok=5L5xfj2v "unknown Linux commands")
> 在这篇文章中和 Carla Schroder 一起探索 Linux 中的一些鲜为人知的强大工具。
本文是一篇关于一些有趣但鲜为人知的工具 `termsaver`、`pv` 和 `calendar` 的文章。`termsaver` 是一个终端 ASCII 屏保,`pv` 能够测量数据吞吐量并模拟输入。Debian 的 `calendar` 拥有许多不同的日历,并且你还可以制定你自己的日历。
### 终端屏保
难道只有图形桌面能够拥有有趣的屏保吗?现在,你可以通过安装 `termsaver` 来享受 ASCII 屏保,比如 matrixLCTT 译注:电影《黑客帝国》中出现的黑客屏保)、时钟、星球大战以及两个<ruby>不太安全<rt>not-safe-for-work</rt></ruby>NSFW的屏保。 NSFW 屏保还有很多。
`termsaver` 可以从 Debian/Ubuntu 的包管理器中直接下载安装,如果你使用别的不包含该软件包的发行版比如 CentOS那么你可以从 [termsaver.brunobraga.net][7] 下载,然后按照安装指导进行安装。
运行 `termsaver -h` 来查看一系列屏保:
```
randtxt displays word in random places on screen
starwars runs the asciimation Star Wars movie
urlfetcher displays url contents with typing animation
quotes4all displays recent quotes from quotes4all.net
rssfeed displays rss feed information
matrix displays a matrix movie alike screensaver
clock displays a digital clock on screen
rfc randomly displays RFC contents
jokes4all displays recent jokes from jokes4all.net (NSFW)
asciiartfarts displays ascii images from asciiartfarts.com (NSFW)
programmer displays source code in typing animation
sysmon displays a graphical system monitor
```
![Linux commands](https://www.linux.com/sites/lcom/files/styles/floated_images/public/linux-commands-fig-1.png?itok=HveXXLLK "Linux commands")
*图片 1 星球大战屏保。*
你可以通过运行命令 `termsaver [屏保名]` 来使用屏保,比如 `termsaver matrix` ,然后按 `Ctrl+c` 停止。你也可以通过运行 `termsaver [屏保名] -h` 命令来获取关于某一个特定屏保的信息。图片 1 来自 `startwars` 屏保,它运行的是古老但受人喜爱的 [Asciimation Wars][8] 。
那些不太安全NSFW的屏保通过在线获取资源的方式运行我并不喜欢它们但好消息是由于 `termsaver` 是一些 Python 脚本文件,因此,你可以很容易的利用它们连接到任何你想要的 RSS 资源。
### pv
`pv` 命令是一个非常有趣的小工具但却很实用。它的用途是监测数据复制的过程,比如,当你运行 `rsync` 命令或创建一个 `tar` 归档的时候。当你不带任何选项运行 `pv` 命令时,默认参数为:
* -p :进程
* -t :时间,到当前总运行时间
* -e :预计完成时间,这往往是不准确的,因为 `pv` 通常不知道需要移动的数据的大小
* -r :速率计数器,或吞吐量
* -b :字节计数器
一次 `rsync` 传输看起来像这样:
```
$ rsync -av /home/carla/ /media/carla/backup/ | pv
sending incremental file list
[...]
103GiB 0:02:48 [ 615MiB/s] [ <=>
```
创建一个 tar 归档,就像下面这个例子:
```
$ tar -czf - /file/path| (pv > backup.tgz)
885MiB 0:00:30 [28.6MiB/s] [ <=>
```
`pv` 能够监测进程,因此也可以监测 Web 浏览器的最大活动,令人惊讶的是,它产生了如此多的活动:
```
$ pv -d 3095
58:/home/carla/.pki/nssdb/key4.db: 0 B 0:00:33
[ 0 B/s] [<=> ]
78:/home/carla/.config/chromium/Default/Visited Links:
256KiB 0:00:33 [ 0 B/s] [<=> ]
]
85:/home/carla/.con...romium/Default/data_reduction_proxy_leveldb/LOG:
298 B 0:00:33 [ 0 B/s] [<=> ]
```
在网上,我偶然发现一个使用 `pv` 最有趣的方式:使用 `pv` 来回显输入的内容:
```
$ echo "typing random stuff to pipe through pv" | pv -qL 8
typing random stuff to pipe through pv
```
普通的 `echo` 命令会瞬间打印一整行内容。通过管道传给 `pv` 之后能够让内容像是重新输入一样的显示出来。我不知道这是否有实际的价值,但是我非常喜欢它。`-L` 选项控制回显的速度,即多少字节每秒。
`pv` 是一个非常古老且非常有趣的命令,这么多年以来,它拥有了许多的选项,包括有趣的格式化选项,多种输出选项,以及传输速度修改器。你可以通过 `man pv` 来查看所有的选项。
### /usr/bin/calendar
通过浏览 `/usr/bin` 目录以及其他命令目录和阅读 man 手册,你能够学到很多东西。在 Debian/Ubuntu 上的 `/usr/bin/calendar` 是 BSD 日历的一个变种,但它漏掉了月亮历和太阳历。它保留了多个日历包括 `calendar.computer, calendar.discordian, calendar.music` 以及 `calendar.lotr`。在我的系统上man 手册列出了 `/usr/bin/calendar` 里存在的不同日历。下面这个例子展示了指环王日历接下来的 60 天:
```
$ calendar -f /usr/share/calendar/calendar.lotr -A 60
Apr 17 An unexpected party
Apr 23 Crowning of King Ellesar
May 19 Arwen leaves Lorian to wed King Ellesar
Jun 11 Sauron attacks Osgilliath
```
这些日历是纯文本文件,因此,你可以轻松的创建你自己的日历。最简单的方式就是复制已经存在的日历文件的格式。你可以通过 `man calendar` 命令来查看创建个人日历文件的更详细的指导。
又一次很快走到了尽头。你可以花费一些时间来浏览你的文件系统,挖掘更多有趣的命令。
_你可以通过来自 Linux 基金会和 edx 的免费课程 ["Introduction to Linux"][5] 来学习更过关于 Linux 的知识_
(题图:[CC Zero][2] Pixabay
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2017/4/more-unknown-linux-commands
作者:[CARLA SCHRODER][a]
译者:[ucasFL](https://github.com/ucasFL)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://www.linux.com/licenses/category/used-permission
[2]:https://www.linux.com/licenses/category/creative-commons-zero
[3]:https://www.linux.com/files/images/linux-commands-fig-1png
[4]:https://www.linux.com/files/images/outer-limits-linuxjpg
[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
[6]:https://www.addtoany.com/share#url=https%3A%2F%2Fwww.linux.com%2Flearn%2Fintro-to-linux%2F2017%2F4%2Fmore-unknown-linux-commands&amp;amp;amp;title=More%20Unknown%20Linux%20Commands
[7]:http://termsaver.brunobraga.net/
[8]:http://www.asciimation.co.nz/

View File

@ -0,0 +1,300 @@
用户指南Linux 文件系统的链接
============================================================
> 学习如何使用链接,通过从 Linux 文件系统多个位置来访问文件,可以让日常工作变得轻松。
![linux 文件链接用户指南](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/links.png?itok=enaPOi4L "A user's guide to links in the Linux filesystem")
Image by : [Paul Lewin][8]. Modified by Opensource.com. [CC BY-SA 2.0][9]
在我为 opensource.com 写过的关于 Linux 文件系统方方面面的文章中,包括 [Linux 的 EXT4 文件系统的历史、特性以及最佳实践][10] [在 Linux 中管理设备][11][Linux 文件系统概览][12] 和 [用户指南:逻辑卷管理][13],我曾简要的提到过 Linux 文件系统一个有趣的特性,它允许用户从多个位置来访问 Linux 文件目录树中的文件来简化一些任务。
Linux 文件系统中有两种<ruby>链接<rt>link</rt></ruby><ruby>硬链接<rt>hard link</rt></ruby><ruby>软链接<rt>soft link</rt></ruby>。虽然二者差别显著,但都用来解决相似的问题。它们都提供了对单个文件的多个目录项(引用)的访问,但实现却大为不同。链接的强大功能赋予了 Linux 文件系统灵活性,因为[一切皆是文件][14]。
举个例子,我曾发现一些程序要求特定的版本库方可运行。 当用升级后的库替代旧库后,程序会崩溃,提示旧版本库缺失。通常,库名的唯一变化就是版本号。出于直觉,我仅仅给程序添加了一个新的库链接,并以旧库名称命名。我试着再次启动程序,运行良好。程序就是一个游戏,人人都明白,每个玩家都会尽力使游戏进行下去。
事实上,几乎所有的应用程序链接库都使用通用的命名规则,链接名称中包含了主版本号,链接所指向的文件的文件名中同样包含了小版本号。再比如,程序的一些必需文件为了迎合 Linux 文件系统规范,从一个目录移动到另一个目录中,系统为了向后兼容那些不能获取这些文件新位置的程序在旧的目录中存放了这些文件的链接。如果你对 `/lib64` 目录做一个长清单列表,你会发现很多这样的例子。
```
lrwxrwxrwx. 1 root root 36 Dec 8 2016 cracklib_dict.hwm -> ../../usr/share/cracklib/pw_dict.hwm
lrwxrwxrwx. 1 root root 36 Dec 8 2016 cracklib_dict.pwd -> ../../usr/share/cracklib/pw_dict.pwd
lrwxrwxrwx. 1 root root 36 Dec 8 2016 cracklib_dict.pwi -> ../../usr/share/cracklib/pw_dict.pwi
lrwxrwxrwx. 1 root root 27 Jun 9 2016 libaccountsservice.so.0 -> libaccountsservice.so.0.0.0
-rwxr-xr-x. 1 root root 288456 Jun 9 2016 libaccountsservice.so.0.0.0
lrwxrwxrwx 1 root root 15 May 17 11:47 libacl.so.1 -> libacl.so.1.1.0
-rwxr-xr-x 1 root root 36472 May 17 11:47 libacl.so.1.1.0
lrwxrwxrwx. 1 root root 15 Feb 4 2016 libaio.so.1 -> libaio.so.1.0.1
-rwxr-xr-x. 1 root root 6224 Feb 4 2016 libaio.so.1.0.0
-rwxr-xr-x. 1 root root 6224 Feb 4 2016 libaio.so.1.0.1
lrwxrwxrwx. 1 root root 30 Jan 16 16:39 libakonadi-calendar.so.4 -> libakonadi-calendar.so.4.14.26
-rwxr-xr-x. 1 root root 816160 Jan 16 16:39 libakonadi-calendar.so.4.14.26
lrwxrwxrwx. 1 root root 29 Jan 16 16:39 libakonadi-contact.so.4 -> libakonadi-contact.so.4.14.26
```
`/lib64` 目录下的一些链接
在上面展示的 `/lib64` 目录清单列表中,文件模式第一个字母 `l` (小写字母 l表示这是一个软链接又称符号链接
### 硬链接
在 [Linux 的 EXT4 文件系统的历史、特性以及最佳实践][15]一文中,我曾探讨过这样一个事实,每个文件都有一个包含该文件信息的 inode包含了该文件的位置信息。上述文章中的[图2][16]展示了一个指向 inode 的单一目录项。每个文件都至少有一个目录项指向描述该文件信息的 inode ,目录项是一个硬链接,因此每个文件至少都有一个硬链接。
如下图 1 所示,多个目录项指向了同一 inode 。这些目录项都是硬链接。我曾在三个目录项中使用波浪线 (`~`) 的缩写,这是用户目录的惯例表示,因此在该例中波浪线等同于 `/home/user` 。值得注意的是,第四个目录项是一个完全不同的目录,`/home/shared`,可能是该计算机上用户的共享文件目录。
![fig1directory_entries.png](https://opensource.com/sites/default/files/images/life/fig1directory_entries.png)
*图 1*
硬链接被限制在一个单一的文件系统中。此处的“文件系统” 是指挂载在特定挂载点上的分区或逻辑卷,此例中是 `/home`。这是因为在每个文件系统中的 inode 号都是唯一的。而在不同的文件系统中,如 `/var``/opt`,会有和 `/home` 中相同的 inode 号。
因为所有的硬链接都指向了包含文件元信息的单一 inode ,这些属性都是文件的一部分,像所属关系、权限、到该 inode 的硬链接数目,对每个硬链接来说这些特性没有什么不同的。这是一个文件所具有的一组属性。唯一能区分这些文件的是包含在 inode 信息中的文件名。链接到同一目录中的单一文件/ inode 的硬链接必须拥有不同的文件名,这是基于同一目录下不能存在重复的文件名的事实的。
文件的硬链接数目可通过 `ls -l` 来查看,如果你想查看实际节点号,可使用 `ls -li` 命令。
### 符号(软)链接
硬链接和软链接(也称为<ruby>符号链接<rt>symlink</rt></ruby>)的区别在于,硬链接直接指向属于该文件的 inode ,而软链接直接指向一个目录项,即指向一个硬链接。因为软链接指向的是一个文件的硬链接而非该文件的 inode ,所以它们并不依赖于 inode 号,这使得它们能跨越不同的文件系统、分区和逻辑卷起作用。
软链接的缺点是,一旦它所指向的硬链接被删除或重命名后,该软链接就失效了。软链接虽然还在,但所指向的硬链接已不存在。所幸的是,`ls` 命令能以红底白字的方式在其列表中高亮显示失效的软链接。
### 实验项目: 链接实验
我认为最容易理解链接用法及其差异的方法是动手搭建一个项目。这个项目应以非超级用户的身份在一个空目录下进行。我创建了 `~/temp` 目录做这个实验,你也可以这么做。这么做可为项目创建一个安全的环境且提供一个新的空目录让程序运作,如此以来这儿仅存放和程序有关的文件。
#### 初始工作
首先在你要进行实验的目录下为该项目中的任务创建一个临时目录确保当前工作目录PWD是你的主目录然后键入下列命令。
```
mkdir temp
```
使用这个命令将当前工作目录切换到 `~/temp`
```
cd temp
```
实验开始,我们需要创建一个能够链接到的文件,下列命令可完成该工作并向其填充内容。
```
du -h > main.file.txt
```
使用 `ls -l` 长列表命名确认文件正确地创建了。运行结果应类似于我的。注意文件大小只有 7 字节,但你的可能会有 12 字节的变动。
```
[dboth@david temp]$ ls -l
total 4
-rw-rw-r-- 1 dboth dboth 7 Jun 13 07:34 main.file.txt
```
在列表中,文件模式串后的数字 `1` 代表存在于该文件上的硬链接数。现在应该是 1 ,因为我们还没有为这个测试文件建立任何硬链接。
#### 对硬链接进行实验
硬链接创建一个指向同一 inode 的新目录项,当为文件添加一个硬链接时,你会看到链接数目的增加。确保当前工作目录仍为 `~/temp`。创建一个指向 `main.file.txt` 的硬链接,然后查看该目录下文件列表。
```
[dboth@david temp]$ ln main.file.txt link1.file.txt
[dboth@david temp]$ ls -l
total 8
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 link1.file.txt
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 main.file.txt
```
目录中两个文件都有两个链接且大小相同,时间戳也一样。这就是有一个 inode 和两个硬链接(即该文件的目录项)的一个文件。再建立一个该文件的硬链接,并列出目录清单内容。你可以建立硬链接: `link1.file.txt``main.file.txt`
```
[dboth@david temp]$ ln link1.file.txt link2.file.txt ; ls -l
total 16
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link1.file.txt
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link2.file.txt
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 main.file.txt
```
注意,该目录下的每个硬链接必须使用不同的名称,因为同一目录下的两个文件不能拥有相同的文件名。试着创建一个和现存链接名称相同的硬链接。
```
[dboth@david temp]$ ln main.file.txt link2.file.txt
ln: failed to create hard link 'link2.file.txt': File exists
```
显然不行,因为 `link2.file.txt` 已经存在。目前为止我们只在同一目录下创建硬链接,接着在临时目录的父目录(你的主目录)中创建一个链接。
```
[dboth@david temp]$ ln main.file.txt ../main.file.txt ; ls -l ../main*
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
```
上面的 `ls` 命令显示 `main.file.txt` 文件确实存在于主目录中,且与该文件在 `temp` 目录中的名称一致。当然它们不是不同的文件,它们是同一文件的两个链接,指向了同一文件的目录项。为了帮助说明下一点,在 `temp` 目录中添加一个非链接文件。
```
[dboth@david temp]$ touch unlinked.file ; ls -l
total 12
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
-rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
```
使用 `ls` 命令的 `i` 选项查看 inode 的硬链接号和新创建文件的硬链接号。
```
[dboth@david temp]$ ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
```
注意上面文件模式左边的数字 `657024` ,这是三个硬链接文件所指的同一文件的 inode 号,你也可以使用 `i` 选项查看主目录中所创建的链接的节点号,和该值相同。而那个只有一个链接的 inode 号和其他的不同,在你的系统上看到的 inode 号或许不同于本文中的。
接着改变其中一个硬链接文件的大小。
```
[dboth@david temp]$ df -h > link2.file.txt ; ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
```
现在所有的硬链接文件大小都比原来大了,因为多个目录项都链接着同一文件。
下个实验在我的电脑上会出现这样的结果,是因为我的 `/tmp` 目录在一个独立的逻辑卷上。如果你有单独的逻辑卷或文件系统在不同的分区上(如果未使用逻辑卷),确定你是否能访问那个分区或逻辑卷,如果不能,你可以在电脑上挂载一个 U 盘,如果上述方式适合你,你可以进行这个实验。
试着在 `/tmp` 目录中建立一个 `~/temp` 目录下文件的链接(或你的文件系统所在的位置)。
```
[dboth@david temp]$ ln link2.file.txt /tmp/link3.file.txt
ln: failed to create hard link '/tmp/link3.file.txt' => 'link2.file.txt':
Invalid cross-device link
```
为什么会出现这个错误呢? 原因是每一个单独的可挂载文件系统都有一套自己的 inode 号。简单的通过 inode 号来跨越整个 Linux 文件系统结构引用一个文件会使系统困惑,因为相同的节点号会存在于每个已挂载的文件系统中。
有时你可能会想找到一个 inode 的所有硬链接。你可以使用 `ls -li` 命令。然后使用 `find` 命令找到所有硬链接的节点号。
```
[dboth@david temp]$ find . -inum 657024
./main.file.txt
./link1.file.txt
./link2.file.txt
```
注意 `find` 命令不能找到所属该节点的四个硬链接,因为我们在 `~/temp` 目录中查找。 `find` 命令仅在当前工作目录及其子目录中查找文件。要找到所有的硬链接,我们可以使用下列命令,指定你的主目录作为起始查找条件。
```
[dboth@david temp]$ find ~ -samefile main.file.txt
/home/dboth/temp/main.file.txt
/home/dboth/temp/link1.file.txt
/home/dboth/temp/link2.file.txt
/home/dboth/main.file.txt
```
如果你是非超级用户,没有权限,可能会看到错误信息。这个命令也使用了 `-samefile` 选项而不是指定文件的节点号。这个效果和使用 inode 号一样且更容易,如果你知道其中一个硬链接名称的话。
#### 对软链接进行实验
如你刚才看到的,不能跨越文件系统边界创建硬链接,即在逻辑卷或文件系统中从一个文件系统到另一个文件系统。软链接给出了这个问题的解决方案。虽然它们可以达到相同的目的,但它们是非常不同的,知道这些差异是很重要的。
让我们在 `~/temp` 目录中创建一个符号链接来开始我们的探索。
```
[dboth@david temp]$ ln -s link2.file.txt link3.file.txt ; ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt ->
link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
```
拥有节点号 `657024` 的那些硬链接没有变化,且硬链接的数目也没有变化。新创建的符号链接有不同的 inode 号 `658270`。 名为 `link3.file.txt` 的软链接指向了 `link2.file.txt` 文件。使用 `cat` 命令查看 `link3.file.txt` 文件的内容。符号链接的 inode 信息以字母 `l` (小写字母 l开头意味着这个文件实际是个符号链接。
上例中软链接文件 `link3.file.txt` 的大小只有 14 字节。这是文本内容 `link3.file.txt` 的大小,即该目录项的实际内容。目录项 `link3.file.txt` 并不指向一个 inode ;它指向了另一个目录项,这在跨越文件系统建立链接时很有帮助。现在试着创建一个软链接,之前在 `/tmp` 目录中尝试过的。
```
[dboth@david temp]$ ln -s /home/dboth/temp/link2.file.txt
/tmp/link3.file.txt ; ls -l /tmp/link*
lrwxrwxrwx 1 dboth dboth 31 Jun 14 21:53 /tmp/link3.file.txt ->
/home/dboth/temp/link2.file.txt
```
#### 删除链接
当你删除硬链接或硬链接所指的文件时,需要考虑一些问题。
首先,让我们删除硬链接文件 `main.file.txt`。注意指向 inode 的每个目录项就是一个硬链接。
```
[dboth@david temp]$ rm main.file.txt ; ls -li
total 8
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link2.file.txt
658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt ->
link2.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
```
`main.file.txt` 是该文件被创建时所创建的第一个硬链接。现在删除它,仍然保留着原始文件和硬盘上的数据以及所有剩余的硬链接。要删除原始文件,你必须删除它的所有硬链接。
现在删除 `link2.file.txt` 硬链接文件。
```
[dboth@david temp]$ rm link2.file.txt ; ls -li
total 8
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt
658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt ->
link2.file.txt
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
```
注意软链接的变化。删除软链接所指的硬链接会使该软链接失效。在我的系统中,断开的链接用颜色高亮显示,目标的硬链接会闪烁显示。如果需要修复这个损坏的软链接,你需要在同一目录下建立一个和旧链接相同名字的硬链接,只要不是所有硬链接都已删除就行。您还可以重新创建链接本身,链接保持相同的名称,但指向剩余的硬链接中的一个。当然如果软链接不再需要,可以使用 `rm` 命令删除它们。
`unlink` 命令在删除文件和链接时也有用。它非常简单且没有选项,就像 `rm` 命令一样。然而,它更准确地反映了删除的基本过程,因为它删除了目录项与被删除文件的链接。
### 写在最后
我用过这两种类型的链接很长一段时间后,我开始了解它们的能力和特质。我为我所教的 Linux 课程编写了一个实验室项目,以充分理解链接是如何工作的,并且我希望增进你的理解。
--------------------------------------------------------------------------------
作者简介:
戴维.布斯 - 戴维.布斯是 Linux 和开源倡导者,居住在北卡罗莱纳的罗列 。他在 IT 行业工作了四十年,为 IBM 工作了 20 多年的 OS/2。在 IBM 时,他在 1981 年编写了最初的 IBM PC 的第一个培训课程。他为 RedHat 教授过 RHCE 班,并曾在 MCI Worldcom、思科和北卡罗莱纳州工作。他已经用 Linux 和开源软件工作将近 20 年了。
---------------------------------
via: https://opensource.com/article/17/6/linking-linux-filesystem
作者:[David Both][a]
译者:[yongshouzhang](https://github.com/yongshouzhang)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/dboth
[1]:https://opensource.com/resources/what-is-linux?src=linux_resource_menu
[2]:https://opensource.com/resources/what-are-linux-containers?src=linux_resource_menu
[3]:https://developers.redhat.com/promotions/linux-cheatsheet/?intcmp=7016000000127cYAAQ
[4]:https://developers.redhat.com/cheat-sheet/advanced-linux-commands-cheatsheet?src=linux_resource_menu&intcmp=7016000000127cYAAQ
[5]:https://opensource.com/tags/linux?src=linux_resource_menu
[6]:https://opensource.com/article/17/6/linking-linux-filesystem?rate=YebHxA-zgNopDQKKOyX3_r25hGvnZms_33sYBUq-SMM
[7]:https://opensource.com/user/14106/feed
[8]:https://www.flickr.com/photos/digypho/7905320090
[9]:https://creativecommons.org/licenses/by/2.0/
[10]:https://linux.cn/article-8685-1.html
[11]:https://linux.cn/article-8099-1.html
[12]:https://linux.cn/article-8887-1.html
[13]:https://opensource.com/business/16/9/linux-users-guide-lvm
[14]:https://opensource.com/life/15/9/everything-is-a-file
[15]:https://linux.cn/article-8685-1.html
[16]:https://linux.cn/article-8685-1.html#3_19182
[17]:https://opensource.com/users/dboth
[18]:https://opensource.com/article/17/6/linking-linux-filesystem#comments

View File

@ -0,0 +1,219 @@
在红帽企业版 Linux 中将系统服务容器化(一)
====================
在 2017 年红帽峰会上,有几个人问我“我们通常用完整的虚拟机来隔离如 DNS 和 DHCP 等网络服务,那我们可以用容器来取而代之吗?”答案是可以的,下面是在当前红帽企业版 Linux 7 系统上创建一个系统容器的例子。
### 我们的目的
**创建一个可以独立于任何其它系统服务而更新的网络服务,并且可以从主机端容易地管理和更新。**
让我们来探究一下在容器中建立一个运行在 systemd 之下的 BIND 服务器。在这一部分,我们将了解到如何建立自己的容器以及管理 BIND 配置和数据文件。
在本系列的第二部分,我们将看到如何整合主机中的 systemd 和容器中的 systemd。我们将探究如何管理容器中的服务并且使它作为一种主机中的服务。
### 创建 BIND 容器
为了使 systemd 在一个容器中轻松运行,我们首先需要在主机中增加两个包:`oci-register-machine` 和 `oci-systemd-hook`。`oci-systemd-hook` 这个钩子允许我们在一个容器中运行 systemd而不需要使用特权容器或者手工配置 tmpfs 和 cgroups。`oci-register-machine` 这个钩子允许我们使用 systemd 工具如 `systemctl``machinectl` 来跟踪容器。
```
[root@rhel7-host ~]# yum install oci-register-machine oci-systemd-hook
```
回到创建我们的 BIND 容器上。[红帽企业版 Linux 7 基础镜像][6]包含了 systemd 作为其初始化系统。我们可以如我们在典型的系统中做的那样安装并激活 BIND。你可以从 [git 仓库中下载这份 Dockerfile][8]。
```
[root@rhel7-host bind]# vi Dockerfile
# Dockerfile for BIND
FROM registry.access.redhat.com/rhel7/rhel
ENV container docker
RUN yum -y install bind && \
yum clean all && \
systemctl enable named
STOPSIGNAL SIGRTMIN+3
EXPOSE 53
EXPOSE 53/udp
CMD [ "/sbin/init" ]
```
因为我们以 PID 1 来启动一个初始化系统,当我们告诉容器停止时,需要改变 docker CLI 发送的信号。从 `kill` 系统调用手册中 `man 2 kill`
> 唯一可以发送给 PID 1 进程(即 init 进程)的信号,是那些初始化系统明确安装了<ruby>信号处理器<rt>signal handler</rt></ruby>的信号。这是为了避免系统被意外破坏。
对于 systemd 信号处理器,`SIGRTMIN+3` 是对应于 `systemd start halt.target` 的信号。我们也需要为 BIND 暴露 TCP 和 UDP 端口号,因为这两种协议可能都要使用。
### 管理数据
有了一个可以工作的 BIND 服务,我们还需要一种管理配置文件和区域文件的方法。目前这些都放在容器里面,所以我们任何时候都可以进入容器去更新配置或者改变一个区域文件。从管理的角度来说,这并不是很理想。当要更新 BIND 时,我们将需要重建这个容器,所以镜像中的改变将会丢失。任何时候我们需要更新一个文件或者重启服务时,都需要进入这个容器,而这增加了步骤和时间。
相反的,我们将从这个容器中提取出配置文件和数据文件,把它们拷贝到主机上,然后在运行的时候挂载它们。用这种方式我们可以很容易地重启或者重建容器,而不会丢失所做出的更改。我们也可以使用容器外的编辑器来更改配置和区域文件。因为这个容器的数据看起来像“该系统所提供服务的特定站点数据”,让我们遵循 Linux <ruby>文件系统层次标准<rt>File System Hierarchy</rt></ruby>,并在当前主机上创建 `/srv/named` 目录来保持管理权分离。
```
[root@rhel7-host ~]# mkdir -p /srv/named/etc
[root@rhel7-host ~]# mkdir -p /srv/named/var/named
```
*提示:如果你正在迁移一个已有的配置文件,你可以跳过下面的步骤并且将它直接拷贝到 `/srv/named` 目录下。你也许仍然要用一个临时容器来检查一下分配给这个容器的 GID。*
让我们建立并运行一个临时容器来检查 BIND。在将 init 进程以 PID 1 运行时,我们不能交互地运行这个容器来获取一个 shell。我们会在容器启动后执行 shell并且使用 `rpm` 命令来检查重要文件。
```
[root@rhel7-host ~]# docker build -t named .
[root@rhel7-host ~]# docker exec -it $( docker run -d named ) /bin/bash
[root@0e77ce00405e /]# rpm -ql bind
```
对于这个例子来说,我们将需要 `/etc/named.conf``/var/named/` 目录下的任何文件。我们可以使用 `machinectl` 命令来提取它们。如果注册了一个以上的容器,我们可以在任一机器上使用 `machinectl status` 命令来查看运行的是什么。一旦有了这些配置,我们就可以终止这个临时容器了。
*如果你喜欢,资源库中也有一个[样例 `named.conf` 和针对 `example.com` 的区域文件][8]。*
```
[root@rhel7-host bind]# machinectl list
MACHINE CLASS SERVICE
8824c90294d5a36d396c8ab35167937f container docker
[root@rhel7-host ~]# machinectl copy-from 8824c90294d5a36d396c8ab35167937f /etc/named.conf /srv/named/etc/named.conf
[root@rhel7-host ~]# machinectl copy-from 8824c90294d5a36d396c8ab35167937f /var/named /srv/named/var/named
[root@rhel7-host ~]# docker stop infallible_wescoff
```
### 最终的创建
为了创建和运行最终的容器,添加卷选项以挂载:
- 将文件 `/srv/named/etc/named.conf` 映射为 `/etc/named.conf`
- 将目录 `/srv/named/var/named` 映射为 `/var/named`
因为这是我们最终的容器,我们将提供一个有意义的名字,以供我们以后引用。
```
[root@rhel7-host ~]# docker run -d -p 53:53 -p 53:53/udp -v /srv/named/etc/named.conf:/etc/named.conf:Z -v /srv/named/var/named:/var/named:Z --name named-container named
```
在最终容器运行时,我们可以更改本机配置来改变这个容器中 BIND 的行为。这个 BIND 服务器将需要在这个容器分配的任何 IP 上监听。请确保任何新文件的 GID 与来自这个容器中的其余的 BIND 文件相匹配。
```
[root@rhel7-host bind]# cp named.conf /srv/named/etc/named.conf
[root@rhel7-host ~]# cp example.com.zone /srv/named/var/named/example.com.zone
[root@rhel7-host ~]# cp example.com.rr.zone /srv/named/var/named/example.com.rr.zone
```
> 很好奇为什么我不需要在主机目录中改变 SELinux 上下文?^注1
我们将运行这个容器提供的 `rndc` 二进制文件重新加载配置。我们可以使用 `journald` 以同样的方式检查 BIND 日志。如果运行出现错误,你可以在主机中编辑该文件,并且重新加载配置。在主机中使用 `host``dig`,我们可以检查来自该容器化服务的 example.com 的响应。
```
[root@rhel7-host ~]# docker exec -it named-container rndc reload
server reload successful
[root@rhel7-host ~]# docker exec -it named-container journalctl -u named -n
-- Logs begin at Fri 2017-05-12 19:15:18 UTC, end at Fri 2017-05-12 19:29:17 UTC. --
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: 9.E.F.IP6.ARPA
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: A.E.F.IP6.ARPA
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: B.E.F.IP6.ARPA
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
May 12 19:29:17 ac1752c314a7 named[27]: reloading configuration succeeded
May 12 19:29:17 ac1752c314a7 named[27]: reloading zones succeeded
May 12 19:29:17 ac1752c314a7 named[27]: zone 1.0.10.in-addr.arpa/IN: loaded serial 2001062601
May 12 19:29:17 ac1752c314a7 named[27]: zone 1.0.10.in-addr.arpa/IN: sending notifies (serial 2001062601)
May 12 19:29:17 ac1752c314a7 named[27]: all zones loaded
May 12 19:29:17 ac1752c314a7 named[27]: running
[root@rhel7-host bind]# host www.example.com localhost
Using domain server:
Name: localhost
Address: ::1#53
Aliases:
www.example.com is an alias for server1.example.com.
server1.example.com is an alias for mail
```
> 你的区域文件没有更新吗?可能是因为你的编辑器,而不是序列号。^注2
### 终点线
我们已经达成了我们打算完成的目标,从容器中为 DNS 请求和区域文件提供服务。我们已经得到一个持久化的位置来管理更新和配置,并且更新后该配置不变。
在这个系列的第二部分,我们将看到怎样将一个容器看作为主机中的一个普通服务来运行。
---
[关注 RHEL 博客](http://redhatstackblog.wordpress.com/feed/),通过电子邮件来获得本系列第二部分和其它新文章的更新。
---
### 附加资源
- **所附带文件的 Github 仓库:** [https://github.com/nzwulfin/named-container](https://github.com/nzwulfin/named-container)
- **注1** **通过容器访问本地文件的 SELinux 上下文**
你可能已经注意到当我从容器向本地主机拷贝文件时,我没有运行 `chcon` 将主机中的文件类型改变为 `svirt_sandbox_file_t`。为什么它没有出错?将一个文件拷贝到 `/srv` 会将这个文件标记为类型 `var_t`。我 `setenforce 0` (关闭 SELinux了吗
当然没有,这将让 [Dan Walsh 大哭](https://stopdisablingselinux.com/)LCTT 译注RedHat 的 SELinux 团队负责人,倡议不要禁用 SELinux。是的`machinectl` 确实将文件标记类型设置为期望的那样,可以看一下:
启动一个容器之前:
```
[root@rhel7-host ~]# ls -Z /srv/named/etc/named.conf
-rw-r-----. unconfined_u:object_r:var_t:s0 /srv/named/etc/named.conf
```
不过,运行中我使用了一个卷选项可以使 Dan Walsh 先生高兴起来,`:Z`。`-v /srv/named/etc/named.conf:/etc/named.conf:Z` 命令的这部分做了两件事情:首先它表示这需要使用一个私有卷的 SELiunx 标记来重新标记;其次它表明以读写挂载。
启动容器之后:
```
[root@rhel7-host ~]# ls -Z /srv/named/etc/named.conf
-rw-r-----. root 25 system_u:object_r:svirt_sandbox_file_t:s0:c821,c956 /srv/named/etc/named.conf
```
- **注2** **VIM 备份行为能改变 inode**
如果你在本地主机中使用 `vim` 来编辑配置文件,而你没有看到容器中的改变,你可能不经意的创建了容器感知不到的新文件。在编辑时,有三种 `vim` 设定影响备份副本:`backup`、`writebackup` 和 `backupcopy`
我摘录了 RHEL 7 中的来自官方 VIM [backup_table][9] 中的默认配置。
```
backup writebackup
off on backup current file, deleted afterwards (default)
```
所以我们不创建残留下的 `~` 副本,而是创建备份。另外的设定是 `backupcopy``auto` 是默认的设置:
```
"yes" make a copy of the file and overwrite the original one
"no" rename the file and write a new one
"auto" one of the previous, what works best
```
这种组合设定意味着当你编辑一个文件时,除非 `vim` 有理由(请查看文档了解其逻辑),你将会得到一个包含你编辑内容的新文件,当你保存时它会重命名为原先的文件。这意味着这个文件获得了新的 inode。对于大多数情况这不是问题但是这里容器的<ruby>绑定挂载<rt>bind mount</rt></ruby>对 inode 的改变很敏感。为了解决这个问题,你需要改变 `backupcopy` 的行为。
不管是在 `vim` 会话中还是在你的 `.vimrc`中,请添加 `set backupcopy=yes`。这将确保原先的文件被清空并覆写,维持了 inode 不变并且将该改变传递到了容器中。
------------
via: http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/
作者:[Matt Micene][a]
译者:[liuxinyu123](https://github.com/liuxinyu123)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/
[1]:http://rhelblog.redhat.com/author/mmicenerht/
[2]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#repo
[3]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#sidebar_1
[4]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#sidebar_2
[5]:http://redhatstackblog.wordpress.com/feed/
[6]:https://access.redhat.com/containers
[7]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#repo
[8]:https://github.com/nzwulfin/named-container
[9]:http://vimdoc.sourceforge.net/htmldoc/editing.html#backup-table

View File

@ -0,0 +1,42 @@
vim 的酷功能:会话!
============================================================
昨天我在编写我的[vimrc][5]的时候了解到一个很酷的 vim 功能!(主要为了添加 fzf 和 ripgrep 插件)。这是一个内置功能,不需要特别的插件。
所以我画了一个漫画。
基本上你可以用下面的命令保存所有你打开的文件和当前的状态
```
:mksession ~/.vim/sessions/foo.vim
```
接着用 `:source ~/.vim/sessions/foo.vim` 或者  `vim -S ~/.vim/sessions/foo.vim` 还原会话。非常酷!
一些 vim 插件给 vim 会话添加了额外的功能:
* [https://github.com/tpope/vim-obsession][1]
* [https://github.com/mhinz/vim-startify][2]
* [https://github.com/xolox/vim-session][3]
这是漫画:
![](https://jvns.ca/images/vimsessions.png)
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2017/09/10/vim-sessions/
作者:[Julia Evans][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://jvns.ca/about
[1]:https://github.com/tpope/vim-obsession
[2]:https://github.com/mhinz/vim-startify
[3]:https://github.com/xolox/vim-session
[4]:https://jvns.ca/categories/vim
[5]:https://github.com/jvns/vimconfig/blob/master/vimrc

View File

@ -0,0 +1,75 @@
在 Linux 启动或重启时执行命令与脚本
======
有时可能会需要在重启时或者每次系统启动时运行某些命令或者脚本。我们要怎样做呢?本文中我们就对此进行讨论。 我们会用两种方法来描述如何在 CentOS/RHEL 以及 Ubuntu 系统上做到重启或者系统启动时执行命令和脚本。 两种方法都通过了测试。
### 方法 1 使用 rc.local
这种方法会利用 `/etc/` 中的 `rc.local` 文件来在启动时执行脚本与命令。我们在文件中加上一行来执行脚本,这样每次启动系统时,都会执行该脚本。
不过我们首先需要为 `/etc/rc.local` 添加执行权限,
```
$ sudo chmod +x /etc/rc.local
```
然后将要执行的脚本加入其中:
```
$ sudo vi /etc/rc.local
```
在文件最后加上:
```
sh /root/script.sh &
```
然后保存文件并退出。使用 `rc.local` 文件来执行命令也是一样的,但是一定要记得填写命令的完整路径。 想知道命令的完整路径可以运行:
```
$ which command
```
比如:
```
$ which shutter
/usr/bin/shutter
```
如果是 CentOS我们修改的是文件 `/etc/rc.d/rc.local` 而不是 `/etc/rc.local`。 不过我们也需要先为该文件添加可执行权限。
注意:- 启动时执行的脚本,请一定保证是以 `exit 0` 结尾的。
### 方法 2 使用 Crontab
该方法最简单了。我们创建一个 cron 任务,这个任务在系统启动后等待 90 秒,然后执行命令和脚本。
要创建 cron 任务,打开终端并执行
```
$ crontab -e
```
然后输入下行内容,
```
@reboot ( sleep 90 ; sh \location\script.sh )
```
这里 `\location\script.sh` 就是待执行脚本的地址。
我们的文章至此就完了。如有疑问,欢迎留言。
--------------------------------------------------------------------------------
via: http://linuxtechlab.com/executing-commands-scripts-at-reboot/
作者:[Shusain][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://linuxtechlab.com/author/shsuain/

View File

@ -0,0 +1,72 @@
Linux 上如何禁用 USB 存储
======
为了保护数据不被泄漏,我们使用软件和硬件防火墙来限制外部未经授权的访问,但是数据泄露也可能发生在内部。 为了消除这种可能性,机构会限制和监测访问互联网,同时禁用 USB 存储设备。
在本教程中,我们将讨论三种不同的方法来禁用 Linux 机器上的 USB 存储设备。所有这三种方法都在 CentOS 67 机器上通过测试。那么让我们一一讨论这三种方法,
(另请阅读: [Ultimate guide to securing SSH sessions][1]
### 方法 1 伪安装
在本方法中,我们往配置文件中添加一行 `install usb-storage /bin/true` 这会让安装 usb-storage 模块的操作实际上变成运行 `/bin/true` 这也是为什么这种方法叫做`伪安装`的原因。 具体来说就是,在文件夹 `/etc/modprobe.d` 中创建并打开一个名为 `block_usb.conf` (也可能叫其他名字)
```
$ sudo vim /etc/modprobe.d/block_usb.conf
```
然后将下行内容添加进去:
```
install usb-storage /bin/true
```
最后保存文件并退出。
### 方法 2 删除 USB 驱动
这种方法要求我们将 USB 存储的驱动程序(`usb_storage.ko`)删掉或者移走,从而达到无法再访问 USB 存储设备的目的。 执行下面命令可以将驱动从它默认的位置移走:
```
$ sudo mv /lib/modules/$(uname -r)/kernel/drivers/usb/storage/usb-storage.ko /home/user1
```
现在在默认的位置上无法再找到驱动程序了,因此当 USB 存储器连接到系统上时也就无法加载到驱动程序了,从而导致磁盘不可用。 但是这个方法有一个小问题,那就是当系统内核更新的时候,`usb-storage` 模块会再次出现在它的默认位置。
### 方法 3 - 将 USB 存储器纳入黑名单
我们也可以通过 `/etc/modprobe.d/blacklist.conf` 文件将 usb-storage 纳入黑名单。这个文件在 RHEL/CentOS 6 是现成就有的,但在 7 上可能需要自己创建。 要将 USB 存储列入黑名单,请使用 vim 打开/创建上述文件:
```
$ sudo vim /etc/modprobe.d/blacklist.conf
```
并输入以下行将 USB 纳入黑名单:
```
blacklist usb-storage
```
保存文件并退出。`usb-storage` 就在就会被系统阻止加载,但这种方法有一个很大的缺点,即任何特权用户都可以通过执行以下命令来加载 `usb-storage` 模块,
```
$ sudo modprobe usb-storage
```
这个问题使得这个方法不是那么理想,但是对于非特权用户来说,这个方法效果很好。
在更改完成后重新启动系统,以使更改生效。请尝试用这些方法来禁用 USB 存储,如果您遇到任何问题或有什么疑问,请告知我们。
--------------------------------------------------------------------------------
via: http://linuxtechlab.com/disable-usb-storage-linux/
作者:[Shusain][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject)原创编译,[Linux 中国](https://linux.cn/)荣誉推出
[a]:http://linuxtechlab.com/author/shsuain/
[1]:http://linuxtechlab.com/ultimate-guide-to-securing-ssh-sessions/

View File

@ -1,9 +1,9 @@
并发服务器(3 —— 事件驱动 并发服务器(三):事件驱动
============================================================ ============================================================
这是并发服务器系列的第三节。[第一节][26] 介绍了阻塞式编程,[第二节 —— 线程][27] 探讨了多线程,将其作为一种可行的方法来实现服务器并发编程。 这是并发服务器系列的第三节。[第一节][26] 介绍了阻塞式编程,[第二节线程][27] 探讨了多线程,将其作为一种可行的方法来实现服务器并发编程。
另一种常见的实现并发的方法叫做 _事件驱动编程_,也可以叫做 _异步_ 编程 [^注1][28]。这种方法变化万千,因此我们会从最基本的开始,使用一些基本的 APIs 而非从封装好的高级方法开始。本系列以后的文章会讲高层次抽象,还有各种混合的方法。 另一种常见的实现并发的方法叫做 _事件驱动编程_,也可以叫做 _异步_ 编程 ^注1 。这种方法变化万千,因此我们会从最基本的开始,使用一些基本的 API 而非从封装好的高级方法开始。本系列以后的文章会讲高层次抽象,还有各种混合的方法。
本系列的所有文章: 本系列的所有文章:
@ -13,13 +13,13 @@
### 阻塞式 vs. 非阻塞式 I/O ### 阻塞式 vs. 非阻塞式 I/O
要介绍这个标题,我们先讲讲阻塞和非阻塞 I/O 的区别。阻塞式 I/O 更好理解,因为这是我们使用 I/O 相关 API 时的“标准”方式。从套接字接收数据的时候,调用 `recv` 函数会发生 _阻塞_,直到它从端口上接收到了来自另一端套接字的数据。这恰恰是第一部分讲到的顺序服务器的问题。 作为本篇的介绍,我们先讲讲阻塞和非阻塞 I/O 的区别。阻塞式 I/O 更好理解,因为这是我们使用 I/O 相关 API 时的“标准”方式。从套接字接收数据的时候,调用 `recv` 函数会发生 _阻塞_,直到它从端口上接收到了来自另一端套接字的数据。这恰恰是第一部分讲到的顺序服务器的问题。
因此阻塞式 I/O 存在着固有的性能问题。第二节里我们讲过一种解决方法,就是用多线程。哪怕一个线程的 I/O 阻塞了,别的线程仍然可以使用 CPU 资源。实际上,阻塞 I/O 通常在利用资源方面非常高效,因为线程就等待着 —— 操作系统将线程变成休眠状态,只有满足了线程需要的条件才会被唤醒。 因此阻塞式 I/O 存在着固有的性能问题。第二节里我们讲过一种解决方法,就是用多线程。哪怕一个线程的 I/O 阻塞了,别的线程仍然可以使用 CPU 资源。实际上,阻塞 I/O 通常在利用资源方面非常高效,因为线程就等待着 —— 操作系统将线程变成休眠状态,只有满足了线程需要的条件才会被唤醒。
_非阻塞式_ I/O 是另一种思路。把套接字设成非阻塞模式时,调用 `recv` 时(还有 `send`,但是我们现在只考虑接收),函数返回地会很快,哪怕没有数据要接收。这时,就会返回一个特殊的错误状态 ^[注2][15] 来通知调用者,此时没有数据传进来。调用者可以去做其他的事情,或者尝试再次调用 `recv` 函数。 _非阻塞式_ I/O 是另一种思路。把套接字设成非阻塞模式时,调用 `recv` 时(还有 `send`,但是我们现在只考虑接收),函数返回的会很快,哪怕没有接收到数据。这时,就会返回一个特殊的错误状态 ^注2 来通知调用者,此时没有数据传进来。调用者可以去做其他的事情,或者尝试再次调用 `recv` 函数。
证明阻塞式和非阻塞式的 `recv` 区别的最好方式就是贴一段示例代码。这里有个监听套接字的小程序,一直在 `recv` 这里阻塞着;当 `recv` 返回了数据,程序就报告接收到了多少个字节 ^[注3][16] 示范阻塞式和非阻塞式的 `recv` 区别的最好方式就是贴一段示例代码。这里有个监听套接字的小程序,一直在 `recv` 这里阻塞着;当 `recv` 返回了数据,程序就报告接收到了多少个字节 ^注3
``` ```
int main(int argc, const char** argv) { int main(int argc, const char** argv) {
@ -70,7 +70,6 @@ socket world
^D # to end the connection> ^D # to end the connection>
``` ```
The listening program will print the following:
监听程序会输出以下内容: 监听程序会输出以下内容:
``` ```
@ -144,7 +143,6 @@ int main(int argc, const char** argv) {
这里与阻塞版本有些差异,值得注意: 这里与阻塞版本有些差异,值得注意:
1. `accept` 函数返回的 `newsocktfd` 套接字因调用了 `fcntl` 被设置成非阻塞的模式。 1. `accept` 函数返回的 `newsocktfd` 套接字因调用了 `fcntl` 被设置成非阻塞的模式。
2. 检查 `recv` 的返回状态时,我们对 `errno` 进行了检查,判断它是否被设置成表示没有可供接收的数据的状态。这时,我们仅仅是休眠了 200 毫秒然后进入到下一轮循环。 2. 检查 `recv` 的返回状态时,我们对 `errno` 进行了检查,判断它是否被设置成表示没有可供接收的数据的状态。这时,我们仅仅是休眠了 200 毫秒然后进入到下一轮循环。
同样用 `nc` 进行测试,以下是非阻塞监听器的输出: 同样用 `nc` 进行测试,以下是非阻塞监听器的输出:
@ -183,19 +181,19 @@ Peer disconnected; I'm done.
作为练习,给输出添加一个时间戳,确认调用 `recv` 得到结果之间花费的时间是比输入到 `nc` 中所用的多还是少(每一轮是 200 ms 作为练习,给输出添加一个时间戳,确认调用 `recv` 得到结果之间花费的时间是比输入到 `nc` 中所用的多还是少(每一轮是 200 ms
这里就实现了使用非阻塞的 `recv` 让监听者检查套接字变为可能,并且在没有数据的时候重新获得控制权。换句话说,这就是 _polling(轮询)_ —— 主程序周期性的查询套接字以便读取数据。 这里就实现了使用非阻塞的 `recv` 让监听者检查套接字变为可能,并且在没有数据的时候重新获得控制权。换句话说,用编程的语言说这就是 <ruby>轮询<rt>polling</rt></ruby> —— 主程序周期性的查询套接字以便读取数据。
对于顺序响应的问题,这似乎是个可行的方法。非阻塞的 `recv` 让同时与多个套接字通信变成可能,轮询这些套接字,仅当有新数据到来时才处理。就是这样,这种方式 _可以_ 用来写并发服务器;但实际上一般不这么做,因为轮询的方式很难扩展。 对于顺序响应的问题,这似乎是个可行的方法。非阻塞的 `recv` 让同时与多个套接字通信变成可能,轮询这些套接字,仅当有新数据到来时才处理。就是这样,这种方式 _可以_ 用来写并发服务器;但实际上一般不这么做,因为轮询的方式很难扩展。
首先,我在代码中引入的 200 ms 延迟对于记录非常好(监听器在我输入 `nc` 之间只打印几行 “Calling recv...”,但实际上应该有上千行)。但它也增加了多达 200 ms 的服务器响应时间,这几乎是意料不到的。实际的程序中,延迟会低得多,休眠时间越短,进程占用的 CPU 资源就越多。有些时钟周期只是浪费在等待,这并不好,尤其是在移动设备上,这些设备的电量往往有限。 首先,我在代码中引入的 200ms 延迟对于演示非常好(监听器在我输入 `nc` 之间只打印几行 “Calling recv...”,但实际上应该有上千行)。但它也增加了多达 200ms 的服务器响应时间,这无意是不必要的。实际的程序中,延迟会低得多,休眠时间越短,进程占用的 CPU 资源就越多。有些时钟周期只是浪费在等待,这并不好,尤其是在移动设备上,这些设备的电量往往有限。
但是当我们实际这样来使用多个套接字的时候,更严重的问题出现了。想像下监听器正在同时处理 1000 个 客户端。这意味着每一个循环迭代里面,它都得为 _这 1000 个套接字中的每一个_ 执行一遍非阻塞的 `recv`找到其中准备好了数据的那一个。这非常低效并且极大的限制了服务器能够并发处理的客户端数。这里有个准则每次轮询之间等待的间隔越久服务器响应性越差而等待的时间越少CPU 在无用的轮询上耗费的资源越多。 但是当我们实际这样来使用多个套接字的时候,更严重的问题出现了。想像下监听器正在同时处理 1000 个客户端。这意味着每一个循环迭代里面,它都得为 _这 1000 个套接字中的每一个_ 执行一遍非阻塞的 `recv`找到其中准备好了数据的那一个。这非常低效并且极大的限制了服务器能够并发处理的客户端数。这里有个准则每次轮询之间等待的间隔越久服务器响应性越差而等待的时间越少CPU 在无用的轮询上耗费的资源越多。
讲真所有的轮询都像是无用功。当然操作系统应该是知道哪个套接字是准备好了数据的因此没必要逐个扫描。事实上就是这样接下来就会讲一些API让我们可以更优雅地处理多个客户端。 讲真,所有的轮询都像是无用功。当然操作系统应该是知道哪个套接字是准备好了数据的,因此没必要逐个扫描。事实上,就是这样,接下来就会讲一些 API让我们可以更优雅地处理多个客户端。
### select ### select
`select` 的系统调用是轻便的POSIX标准 Unix API 中常有的部分。它是为上一节最后一部分描述的问题而设计的 —— 允许一个线程可以监视许多文件描述符 ^[注4][17] 的变化,不用在轮询中执行不必要的代码。我并不打算在这里引入一个关于 `select`理解性的教程,有很多网站和书籍讲这个,但是在涉及到问题的相关内容时,我会介绍一下它的 API然后再展示一个非常复杂的例子。 `select` 的系统调用是可移植的POSIX标准 Unix API 中常有的部分。它是为上一节最后一部分描述的问题而设计的 —— 允许一个线程可以监视许多文件描述符 ^注4 的变化,不用在轮询中执行不必要的代码。我并不打算在这里引入一个关于 `select`全面教程,有很多网站和书籍讲这个,但是在涉及到问题的相关内容时,我会介绍一下它的 API然后再展示一个非常复杂的例子。
`select` 允许 _多路 I/O_,监视多个文件描述符,查看其中任何一个的 I/O 是否可用。 `select` 允许 _多路 I/O_,监视多个文件描述符,查看其中任何一个的 I/O 是否可用。
@ -209,30 +207,25 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
`select` 的调用过程如下: `select` 的调用过程如下:
1. 在调用之前,用户先要为所有不同种类的要监视的文件描述符创建 `fd_set` 实例。如果想要同时监视读取和写入事件,`readfds` 和 `writefds` 都要被创建并且引用。 1. 在调用之前,用户先要为所有不同种类的要监视的文件描述符创建 `fd_set` 实例。如果想要同时监视读取和写入事件,`readfds` 和 `writefds` 都要被创建并且引用。
2. 用户可以使用 `FD_SET` 来设置集合中想要监视的特殊描述符。例如,如果想要监视描述符 2、7 和 10 的读取事件,在 `readfds` 这里调用三次 `FD_SET`,分别设置 2、7 和 10。 2. 用户可以使用 `FD_SET` 来设置集合中想要监视的特殊描述符。例如,如果想要监视描述符 2、7 和 10 的读取事件,在 `readfds` 这里调用三次 `FD_SET`,分别设置 2、7 和 10。
3. `select` 被调用。 3. `select` 被调用。
4. 当 `select` 返回时(现在先不管超时),就是说集合中有多少个文件描述符已经就绪了。它也修改 `readfds``writefds` 集合,来标记这些准备好的描述符。其它所有的描述符都会被清空。 4. 当 `select` 返回时(现在先不管超时),就是说集合中有多少个文件描述符已经就绪了。它也修改 `readfds``writefds` 集合,来标记这些准备好的描述符。其它所有的描述符都会被清空。
5. 这时用户需要遍历 `readfds``writefds`,找到哪个描述符就绪了(使用 `FD_ISSET`)。 5. 这时用户需要遍历 `readfds``writefds`,找到哪个描述符就绪了(使用 `FD_ISSET`)。
作为完整的例子,我在并发的服务器程序上使用 `select`,重新实现了我们之前的协议。[完整的代码在这里][18];接下来的是代码中的高亮,还有注释。警告:示例代码非常复杂,因此第一次看的时候,如果没有足够的时间,快速浏览也没有关系。 作为完整的例子,我在并发的服务器程序上使用 `select`,重新实现了我们之前的协议。[完整的代码在这里][18];接下来的是代码中的重点部分及注释。警告:示例代码非常复杂,因此第一次看的时候,如果没有足够的时间,快速浏览也没有关系。
### 使用 select 的并发服务器 ### 使用 select 的并发服务器
使用 I/O 的多发 API 诸如 `select` 会给我们服务器的设计带来一些限制;这不会马上显现出来,但这值得探讨,因为它们是理解事件驱动编程到底是什么的关键。 使用 I/O 的多发 API 诸如 `select` 会给我们服务器的设计带来一些限制;这不会马上显现出来,但这值得探讨,因为它们是理解事件驱动编程到底是什么的关键。
最重要的是,要记住这种方法本质上是单线程的 ^[注5][19]。服务器实际上在 _同一时刻只能做一件事_。因为我们想要同时处理多个客户端请求,我们需要换一种方式重构代码。 最重要的是,要记住这种方法本质上是单线程的 ^注5 。服务器实际上在 _同一时刻只能做一件事_。因为我们想要同时处理多个客户端请求,我们需要换一种方式重构代码。
首先,让我们谈谈主循环。它看起来是什么样的呢?先让我们想象一下服务器有一堆任务,它应该监视哪些东西呢?两种类型的套接字活动: 首先,让我们谈谈主循环。它看起来是什么样的呢?先让我们想象一下服务器有一堆任务,它应该监视哪些东西呢?两种类型的套接字活动:
1. 新客户端尝试连接。这些客户端应该被 `accept` 1. 新客户端尝试连接。这些客户端应该被 `accept`
2. 已连接的客户端发送数据。这个数据要用 [第一节][11] 中所讲到的协议进行传输,有可能会有一些数据要被回送给客户端。 2. 已连接的客户端发送数据。这个数据要用 [第一节][11] 中所讲到的协议进行传输,有可能会有一些数据要被回送给客户端。
尽管这两种活动在本质上有所区别,我们还是要把们放在一个循环里,因为只能有一个主循环。循环会包含 `select` 的调用。这个 `select` 的调用会监视上述的两种活动。 尽管这两种活动在本质上有所区别,我们还是要把们放在一个循环里,因为只能有一个主循环。循环会包含 `select` 的调用。这个 `select` 的调用会监视上述的两种活动。
这里是部分代码,设置了文件描述符集合,并在主循环里转到被调用的 `select` 部分。 这里是部分代码,设置了文件描述符集合,并在主循环里转到被调用的 `select` 部分。
@ -264,9 +257,7 @@ while (1) {
这里的一些要点: 这里的一些要点:
1. 由于每次调用 `select` 都会重写传递给函数的集合,调用器就得维护一个 “master” 集合,在循环迭代中,保持对所监视的所有活跃的套接字的追踪。 1. 由于每次调用 `select` 都会重写传递给函数的集合,调用器就得维护一个 “master” 集合,在循环迭代中,保持对所监视的所有活跃的套接字的追踪。
2. 注意我们所关心的,最开始的唯一那个套接字是怎么变成 `listener_sockfd` 的,这就是最开始的套接字,服务器借此来接收新客户端的连接。 2. 注意我们所关心的,最开始的唯一那个套接字是怎么变成 `listener_sockfd` 的,这就是最开始的套接字,服务器借此来接收新客户端的连接。
3. `select` 的返回值,是在作为参数传递的集合中,那些已经就绪的描述符的个数。`select` 修改这个集合,用来标记就绪的描述符。下一步是在这些描述符中进行迭代。 3. `select` 的返回值,是在作为参数传递的集合中,那些已经就绪的描述符的个数。`select` 修改这个集合,用来标记就绪的描述符。下一步是在这些描述符中进行迭代。
``` ```
@ -298,7 +289,7 @@ for (int fd = 0; fd <= fdset_max && nready > 0; fd++) {
} }
``` ```
这部分循环检查 _可读的_ 描述符。让我们跳过监听器套接字(要浏览所有内容,[看这个代码][20] 然后看看当其中一个客户端准备好了之后会发生什么。出现了这种情况后,我们调用一个叫做 `on_peer_ready_recv`_回调_ 函数,传入相应的文件描述符。这个调用意味着客户端连接到套接字上,发送某些数据,并且对套接字上 `recv` 的调用不会被阻塞 ^[注6][21]。这个回调函数返回结构体 `fd_status_t` 这部分循环检查 _可读的_ 描述符。让我们跳过监听器套接字(要浏览所有内容,[看这个代码][20] 然后看看当其中一个客户端准备好了之后会发生什么。出现了这种情况后,我们调用一个叫做 `on_peer_ready_recv`_回调_ 函数,传入相应的文件描述符。这个调用意味着客户端连接到套接字上,发送某些数据,并且对套接字上 `recv` 的调用不会被阻塞 ^注6 。这个回调函数返回结构体 `fd_status_t`
``` ```
typedef struct { typedef struct {
@ -307,7 +298,7 @@ typedef struct {
} fd_status_t; } fd_status_t;
``` ```
这个结构体告诉主循环,是否应该监视套接字的读取事件写入事件,或者两者都监视。上述代码展示了 `FD_SET``FD_CLR` 是怎么在合适的描述符集合中被调用的。对于主循环中某个准备好了写入数据的描述符,代码是类似的,除了它所调用的回调函数,这个回调函数叫做 `on_peer_ready_send` 这个结构体告诉主循环,是否应该监视套接字的读取事件写入事件,或者两者都监视。上述代码展示了 `FD_SET``FD_CLR` 是怎么在合适的描述符集合中被调用的。对于主循环中某个准备好了写入数据的描述符,代码是类似的,除了它所调用的回调函数,这个回调函数叫做 `on_peer_ready_send`
现在来花点时间看看这个回调: 现在来花点时间看看这个回调:
@ -464,37 +455,36 @@ INFO:2017-09-26 05:29:18,070:conn0 disconnecting
INFO:2017-09-26 05:29:18,070:conn2 disconnecting INFO:2017-09-26 05:29:18,070:conn2 disconnecting
``` ```
和线程的情况相似,客户端之间没有延迟,们被同时处理。而且在 `select-server` 也没有用线程!主循环 _多路_ 处理所有的客户端,通过高效使用 `select` 轮询多个套接字。回想下 [第二节中][22] 顺序的 vs 多线程的客户端处理过程的图片。对于我们的 `select-server`,三个客户端的处理流程像这样: 和线程的情况相似,客户端之间没有延迟,们被同时处理。而且在 `select-server` 也没有用线程!主循环 _多路_ 处理所有的客户端,通过高效使用 `select` 轮询多个套接字。回想下 [第二节中][22] 顺序的 vs 多线程的客户端处理过程的图片。对于我们的 `select-server`,三个客户端的处理流程像这样:
![多客户端处理流程](https://eli.thegreenplace.net/images/2017/multiplexed-flow.png) ![多客户端处理流程](https://eli.thegreenplace.net/images/2017/multiplexed-flow.png)
所有的客户端在同一个线程中同时被处理,通过乘积,做一点这个客户端的任务,然后切换到另一个,再切换到下一个,最后切换回到最开始的那个客户端。注意,这里没有什么循环调度,客户端在它们发送数据的时候被客户端处理,这实际上是受客户端左右的。 所有的客户端在同一个线程中同时被处理,通过乘积,做一点这个客户端的任务,然后切换到另一个,再切换到下一个,最后切换回到最开始的那个客户端。注意,这里没有什么循环调度,客户端在它们发送数据的时候被客户端处理,这实际上是受客户端左右的。
### 同步,异步,事件驱动,回调 ### 同步、异步、事件驱动、回调
`select-server` 示例代码为讨论什么是异步编程它和事件驱动及基于回调的编程有何联系,提供了一个良好的背景。因为这些词汇在并发服务器的(非常矛盾的)讨论中很常见。 `select-server` 示例代码为讨论什么是异步编程它和事件驱动及基于回调的编程有何联系,提供了一个良好的背景。因为这些词汇在并发服务器的(非常矛盾的)讨论中很常见。
让我们从一段 `select` 的手册页面中引用的一句开始: 让我们从一段 `select` 的手册页面中引用的一句开始:
> selectpselectFD_CLRFD_ISSETFD_SETFD_ZERO - 同步 I/O 处理 > selectpselectFD\_CLRFD\_ISSETFD\_SETFD\_ZERO - 同步 I/O 处理
因此 `select`_同步_ 处理。但我刚刚演示了大量代码的例子,使用 `select` 作为 _异步_ 处理服务器的例子。有哪些东西? 因此 `select`_同步_ 处理。但我刚刚演示了大量代码的例子,使用 `select` 作为 _异步_ 处理服务器的例子。有哪些东西?
答案是:这取决于你的观角度。同步常用作阻塞处理,并且对 `select` 的调用实际上是阻塞的。和第 1、2 节中讲到的顺序的、多线程的服务器中对 `send``recv` 是一样的。因此说 `select`_同步的_ API 是有道理的。可是,服务器的设计却可以是 _异步的_,或是 _基于回调的_,或是 _事件驱动的_,尽管其中有对 `select` 的使用。注意这里的 `on_peer_*` 函数是回调函数;它们永远不会阻塞,并且只有网络事件触发的时候才会被调用。它们可以获得部分数据,并能够在调用过程中保持稳定的状态。 答案是:这取决于你的观角度。同步常用作阻塞处理,并且对 `select` 的调用实际上是阻塞的。和第 1、2 节中讲到的顺序的、多线程的服务器中对 `send``recv` 是一样的。因此说 `select`_同步的_ API 是有道理的。可是,服务器的设计却可以是 _异步的_,或是 _基于回调的_,或是 _事件驱动的_,尽管其中有对 `select` 的使用。注意这里的 `on_peer_*` 函数是回调函数;它们永远不会阻塞,并且只有网络事件触发的时候才会被调用。它们可以获得部分数据,并能够在调用过程中保持稳定的状态。
如果你曾经做过一些 GUI 编程,这些东西对你来说应该很亲切。有个 “事件循环”,常常完全隐藏在框架里,应用的 “业务逻辑” 建立在回调上,这些回调会在各种事件触发后被调用,用户点击鼠标,选择菜单,定时器到时间,数据到达套接字,等等。曾经最常见的编程模型是客户端的 JavaScript这里面有一堆回调函数它们在浏览网页时用户的行为被触发。 如果你曾经做过一些 GUI 编程,这些东西对你来说应该很亲切。有个 “事件循环”,常常完全隐藏在框架里,应用的 “业务逻辑” 建立在回调上,这些回调会在各种事件触发后被调用,用户点击鼠标、选择菜单、定时器触发、数据到达套接字等等。曾经最常见的编程模型是客户端的 JavaScript这里面有一堆回调函数它们在浏览网页时用户的行为被触发。
### select 的局限 ### select 的局限
使用 `select` 作为第一个异步服务器的例子对于说明这个概念很有用,而且由于 `select` 是很常见可移植的 API。但是它也有一些严重的缺陷在监视的文件描述符非常大的时候就会出现。 使用 `select` 作为第一个异步服务器的例子对于说明这个概念很有用,而且由于 `select` 是很常见可移植的 API。但是它也有一些严重的缺陷在监视的文件描述符非常大的时候就会出现。
1. 有限的文件描述符的集合大小。 1. 有限的文件描述符的集合大小。
2. 糟糕的性能。 2. 糟糕的性能。
从文件描述符的大小开始。`FD_SETSIZE` 是一个编译期常数,在如今的操作系统中,它的值通常是 1024。它被硬编码在 `glibc` 的头文件里,并且不容易修改。它把 `select` 能够监视的文件描述符的数量限制在 1024 以内。曾有些分支想要写出能够处理上万个并发访问的客户端请求的服务器,这个问题很有现实意义。有一些方法,但是不可移植,也很难用。 从文件描述符的大小开始。`FD_SETSIZE` 是一个编译期常数,在如今的操作系统中,它的值通常是 1024。它被硬编码在 `glibc` 的头文件里,并且不容易修改。它把 `select` 能够监视的文件描述符的数量限制在 1024 以内。曾有些想要写出能够处理上万个并发访问的客户端请求的服务器,所以这个问题很有现实意义。有一些方法,但是不可移植,也很难用。
糟糕的性能问题就好解决的多,但是依然非常严重。注意当 `select` 返回的时候,它向调用者提供的信息是 “就绪的” 描述符的个数,还有被修改过的描述符集合。描述符集映射着描述符 就绪/未就绪”,但是并没有提供什么有效的方法去遍历所有就绪的描述符。如果只有一个描述符是就绪的,最坏的情况是调用者需要遍历 _整个集合_ 来找到那个描述符。这在监视的描述符数量比较少的时候还行,但是如果数量变的很大的时候,这种方法弊端就凸显出了 ^[注7][23] 糟糕的性能问题就好解决的多,但是依然非常严重。注意当 `select` 返回的时候,它向调用者提供的信息是 “就绪的” 描述符的个数,还有被修改过的描述符集合。描述符集映射着描述符就绪/未就绪”,但是并没有提供什么有效的方法去遍历所有就绪的描述符。如果只有一个描述符是就绪的,最坏的情况是调用者需要遍历 _整个集合_ 来找到那个描述符。这在监视的描述符数量比较少的时候还行,但是如果数量变的很大的时候,这种方法弊端就凸显出了 ^注7
由于这些原因,为了写出高性能的并发服务器, `select` 已经不怎么用了。每一个流行的操作系统有独特的不可移植的 API允许用户写出非常高效的事件循环像框架这样的高级结构还有高级语言通常在一个可移植的接口中包含这些 API。 由于这些原因,为了写出高性能的并发服务器, `select` 已经不怎么用了。每一个流行的操作系统有独特的不可移植的 API允许用户写出非常高效的事件循环像框架这样的高级结构还有高级语言通常在一个可移植的接口中包含这些 API。
@ -541,30 +531,23 @@ while (1) {
} }
``` ```
通过调用 `epoll_ctl` 来配置 `epoll`。这时,配置监听的套接字数量,也就是 `epoll` 监听的描述符的数量。然后分配一个缓冲区,把就绪的事件传给 `epoll` 以供修改。在主循环里对 `epoll_wait` 的调用是魅力所在。它阻塞着,直到某个描述符就绪了(或者超时),返回就绪的描述符数量。但这时,不盲目地迭代所有监视的集合,我们知道 `epoll_write` 会修改传给它的 `events` 缓冲区,缓冲区中有就绪的事件,从 0 到 `nready-1`,因此我们只需迭代必要的次数。 通过调用 `epoll_ctl` 来配置 `epoll`。这时,配置监听的套接字数量,也就是 `epoll` 监听的描述符的数量。然后分配一个缓冲区,把就绪的事件传给 `epoll` 以供修改。在主循环里对 `epoll_wait` 的调用是魅力所在。它阻塞着,直到某个描述符就绪了(或者超时),返回就绪的描述符数量。但这时,不盲目地迭代所有监视的集合,我们知道 `epoll_write` 会修改传给它的 `events` 缓冲区,缓冲区中有就绪的事件,从 0 到 `nready-1`,因此我们只需迭代必要的次数。
要在 `select` 里面重新遍历,有明显的差异:如果在监视着 1000 个描述符,只有两个就绪, `epoll_waits` 返回的是 `nready=2`,然后修改 `events` 缓冲区最前面的两个元素,因此我们只需要“遍历”两个描述符。用 `select` 我们就需要遍历 1000 个描述符,找出哪个是就绪的。因此,在繁忙的服务器上,有许多活跃的套接字时 `epoll``select` 更加容易扩展。 要在 `select` 里面重新遍历,有明显的差异:如果在监视着 1000 个描述符,只有两个就绪, `epoll_waits` 返回的是 `nready=2`,然后修改 `events` 缓冲区最前面的两个元素,因此我们只需要“遍历”两个描述符。用 `select` 我们就需要遍历 1000 个描述符,找出哪个是就绪的。因此,在繁忙的服务器上,有许多活跃的套接字时 `epoll``select` 更加容易扩展。
剩下的代码很直观,因为我们已经很熟悉 `select 服务器` 了。实际上,`epoll 服务器` 中的所有“业务逻辑”和 `select 服务器` 是一样的,回调构成相同的代码。 剩下的代码很直观,因为我们已经很熟悉 “select 服务器” 了。实际上“epoll 服务器” 中的所有“业务逻辑”和 “select 服务器” 是一样的,回调构成相同的代码。
这种相似是通过将事件循环抽象分离到一个库/框架中。我将会详述这些内容,因为很多优秀的程序员曾经也是这样做的。相反,下一篇文章里我们会了解 `libuv`,一个最近出现的更加受欢迎的时间循环抽象层。像 `libuv` 这样的库让我们能够写出并发的异步服务器,并且不用考虑系统调用下繁琐的细节。 这种相似是通过将事件循环抽象分离到一个库/框架中。我将会详述这些内容,因为很多优秀的程序员曾经也是这样做的。相反,下一篇文章里我们会了解 libuv一个最近出现的更加受欢迎的时间循环抽象层。像 libuv 这样的库让我们能够写出并发的异步服务器,并且不用考虑系统调用下繁琐的细节。
* * * * * *
- 注1我试着在做网络浏览和阅读这两件事的实际差别中突显自己但经常做得头疼。有很多不同的选项从“它们是一样的东西”到“一个是另一个的子集”再到“它们是完全不同的东西”。在面临这样主观的观点时最好是完全放弃这个问题专注特殊的例子和用例。
[注1][1] 我试着在两件事的实际差别中突显自己,一件是做一些网络浏览和阅读,但经常做得头疼。有很多不同的选项,从“他们是一样的东西”到“一个是另一个的子集”,再到“他们是完全不同的东西”。在面临这样主观的观点时,最好是完全放弃这个问题,专注特殊的例子和用例。 - 注2POSIX 表示这可以是 `EAGAIN`,也可以是 `EWOULDBLOCK`,可移植应用应该对这两个都进行检查。
- 注3和这个系列所有的 C 示例类似,代码中用到了某些助手工具来设置监听套接字。这些工具的完整代码在这个 [仓库][4] 的 `utils` 模块里。
[注2][2] POSIX 表示这可以是 `EAGAIN`,也可以是 `EWOULDBLOCK`,可移植应用应该对这两个都进行检查。 - 注4`select` 不是网络/套接字专用的函数,它可以监视任意的文件描述符,有可能是硬盘文件、管道、终端、套接字或者 Unix 系统中用到的任何文件描述符。这篇文章里,我们主要关注它在套接字方面的应用。
- 注5有多种方式用多线程来实现事件驱动我会把它放在稍后的文章中进行讨论。
[注3][3] 和这个系列所有的 C 示例类似,代码中用到了某些助手工具来设置监听套接字。这些工具的完整代码在这个 [仓库][4] 的 `utils` 模块里。 - 注6由于各种非实验因素_仍然_ 可以阻塞,即使是在 `select` 说它就绪了之后。因此服务器上打开的所有套接字都被设置成非阻塞模式,如果对 `recv``send` 的调用返回了 `EAGAIN` 或者 `EWOULDBLOCK`,回调函数就装作没有事件发生。阅读示例代码的注释可以了解更多细节。
- 注7注意这比该文章前面所讲的异步轮询的例子要稍好一点。轮询需要 _一直_ 发生,而 `select` 实际上会阻塞到有一个或多个套接字准备好读取/写入;`select` 会比一直询问浪费少得多的 CPU 时间。
[注4][5] `select` 不是网络/套接字专用的函数,它可以监视任意的文件描述符,有可能是硬盘文件,管道,终端,套接字或者 Unix 系统中用到的任何文件描述符。这篇文章里,我们主要关注它在套接字方面的应用。
[注5][6] 有多种方式用多线程来实现事件驱动,我会把它放在稍后的文章中进行讨论。
[注6][7] 由于各种非实验因素,它 _仍然_ 可以阻塞,即使是在 `select` 说它就绪了之后。因此服务器上打开的所有套接字都被设置成非阻塞模式,如果对 `recv``send` 的调用返回了 `EAGAIN` 或者 `EWOULDBLOCK`,回调函数就装作没有事件发生。阅读示例代码的注释可以了解更多细节。
[注7][8] 注意这比该文章前面所讲的异步 polling 例子要稍好一点。polling 需要 _一直_ 发生,而 `select` 实际上会阻塞到有一个或多个套接字准备好读取/写入;`select` 会比一直询问浪费少得多的 CPU 时间。
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -572,7 +555,7 @@ via: https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/
作者:[Eli Bendersky][a] 作者:[Eli Bendersky][a]
译者:[GitFuture](https://github.com/GitFuture) 译者:[GitFuture](https://github.com/GitFuture)
校对:[校对者ID](https://github.com/校对者ID) 校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@ -587,9 +570,9 @@ via: https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/
[8]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id9 [8]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id9
[9]:https://eli.thegreenplace.net/tag/concurrency [9]:https://eli.thegreenplace.net/tag/concurrency
[10]:https://eli.thegreenplace.net/tag/c-c [10]:https://eli.thegreenplace.net/tag/c-c
[11]:http://eli.thegreenplace.net/2017/concurrent-servers-part-1-introduction/ [11]:https://linux.cn/article-8993-1.html
[12]:http://eli.thegreenplace.net/2017/concurrent-servers-part-1-introduction/ [12]:https://linux.cn/article-8993-1.html
[13]:http://eli.thegreenplace.net/2017/concurrent-servers-part-2-threads/ [13]:https://linux.cn/article-9002-1.html
[14]:http://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/ [14]:http://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/
[15]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id11 [15]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id11
[16]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id12 [16]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id12
@ -598,10 +581,10 @@ via: https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/
[19]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id14 [19]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id14
[20]:https://github.com/eliben/code-for-blog/blob/master/2017/async-socket-server/select-server.c [20]:https://github.com/eliben/code-for-blog/blob/master/2017/async-socket-server/select-server.c
[21]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id15 [21]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id15
[22]:http://eli.thegreenplace.net/2017/concurrent-servers-part-2-threads/ [22]:https://linux.cn/article-9002-1.html
[23]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id16 [23]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id16
[24]:https://github.com/eliben/code-for-blog/blob/master/2017/async-socket-server/epoll-server.c [24]:https://github.com/eliben/code-for-blog/blob/master/2017/async-socket-server/epoll-server.c
[25]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/ [25]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/
[26]:http://eli.thegreenplace.net/2017/concurrent-servers-part-1-introduction/ [26]:https://linux.cn/article-8993-1.html
[27]:http://eli.thegreenplace.net/2017/concurrent-servers-part-2-threads/ [27]:https://linux.cn/article-9002-1.html
[28]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id10 [28]:https://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/#id10

View File

@ -1,23 +1,20 @@
translating by firmianay 检查 Linux 系统上的网络连接
Examining network connections on Linux systems
============================================================ ============================================================
### Linux systems provide a lot of useful commands for reviewing network configuration and connections. Here's a look at a few, including ifquery, ifup, ifdown and ifconfig. > Linux 系统提供了许多有用的命令来检查网络配置和连接。下面来看几个,包括 `ifquery`、`ifup`、`ifdown` 和 `ifconfig`
Linux 上有许多可用于查看网络设置和连接的命令。在今天的文章中,我们将会通过一些非常方便的命令来看看它们是如何工作的。
There are a lot of commands available on Linux for looking at network settings and connections. In today's post, we're going to run through some very handy commands and see how they work. ### ifquery 命令
### ifquery command 一个非常有用的命令是 `ifquery`。这个命令应该会显示一个网络接口列表。但是,你可能只会看到类似这样的内容 - 仅显示回环接口:
One very useful command is the **ifquery** command. This command should give you a quick list of network interfaces. However, you might only see something like this —showing only the loopback interface:
``` ```
$ ifquery --list $ ifquery --list
lo lo
``` ```
If this is the case, your **/etc/network/interfaces** file doesn't include information on network interfaces except for the loopback interface. You can add lines like the last two in the example below — assuming DHCP is used to assign addresses — if you'd like it to be more useful. 如果是这种情况,那说明你的 `/etc/network/interfaces` 不包括除了回环接口之外的网络接口信息。在下面的例子中,假设你使用 DHCP 来分配地址,且如果你希望它更有用的话,你可以添加例子最后的两行。
``` ```
# interfaces(5) file used by ifup(8) and ifdown(8) # interfaces(5) file used by ifup(8) and ifdown(8)
@ -27,15 +24,13 @@ auto eth0
iface eth0 inet dhcp iface eth0 inet dhcp
``` ```
### ifup and ifdown commands ### ifup 和 ifdown 命令
The related **ifup** and **ifdown** commands can be used to bring network connections up and shut them down as needed provided this file has the required descriptive data. Just keep in mind that "if" means "interface" in these commands just as it does in the **ifconfig** command, not "if" as in "if I only had a brain". 可以使用相关的 `ifup``ifdown` 命令来打开网络连接并根据需要将其关闭只要该文件具有所需的描述性数据即可。请记住“if” 在这里意思是<ruby>接口<rt>interface</rt></ruby>,这与 `ifconfig` 命令中的一样,而不是<ruby>如果我只有一个大脑<rt>if I only had a brain</rt></ruby> 中的 “if”。
<aside class="nativo-promo smartphone" id="" style="overflow: hidden; margin-bottom: 16px; max-width: 620px;"></aside> ### ifconfig 命令
### ifconfig command 另外,`ifconfig` 命令完全不读取 `/etc/network/interfaces`,但是仍然提供了网络接口相当多的有用信息 —— 配置数据以及可以告诉你每个接口有多忙的数据包计数。`ifconfig` 命令也可用于关闭和重新启动网络接口(例如:`ifconfig eth0 down`)。
The **ifconfig** command, on the other hand, doesn't read the /etc/network/interfaces file at all and still provides quite a bit of useful information on network interfaces -- configuration data along with packet counts that tell you how busy each interface has been. The ifconfig command can also be used to shut down and restart network interfaces (e.g., ifconfig eth0 down).
``` ```
$ ifconfig eth0 $ ifconfig eth0
@ -50,15 +45,13 @@ eth0 Link encap:Ethernet HWaddr 00:1e:4f:c8:43:fc
Interrupt:21 Memory:fe9e0000-fea00000 Interrupt:21 Memory:fe9e0000-fea00000
``` ```
The RX and TX packet counts in this output are extremely low. In addition, no errors or packet collisions have been reported. The **uptime** command will likely confirm that this system has only recently been rebooted. 输出中的 RX 和 TX 数据包计数很低。此外,没有报告错误或数据包冲突。或许可以用 `uptime` 命令确认此系统最近才重新启动。
The broadcast (Bcast) and network mask (Mask) addresses shown above indicate that the system is operating on a Class C equivalent network (the default) so local addresses will range from 192.168.0.1 to 192.168.0.254. 上面显示的广播 Bcast 和网络掩码 Mask 地址表明系统运行在 C 类等效网络(默认)上,所以本地地址范围从 `192.168.0.1``192.168.0.254`
### netstat command ### netstat 命令
The **netstat** command provides information on routing and network connections. The **netstat -rn** command displays the system's routing table. `netstat` 命令提供有关路由和网络连接的信息。`netstat -rn` 命令显示系统的路由表。192.168.0.1 是本地网关 Flags=UG)。
<aside class="nativo-promo tablet desktop" id="" style="overflow: hidden; margin-bottom: 16px; max-width: 620px;"></aside>
``` ```
$ netstat -rn $ netstat -rn
@ -69,7 +62,7 @@ Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
``` ```
That **169.254.0.0** entry in the above output is only necessary if you are using or planning to use link-local communications. You can comment out the related lines in the **/etc/network/if-up.d/avahi-autoipd** file like this if this is not the case: 上面输出中的 `169.254.0.0` 条目仅在你正在使用或计划使用本地链路通信时才有必要。如果不是这样的话,你可以在 `/etc/network/if-up.d/avahi-autoipd` 中注释掉相关的行:
``` ```
$ tail -12 /etc/network/if-up.d/avahi-autoipd $ tail -12 /etc/network/if-up.d/avahi-autoipd
@ -86,9 +79,9 @@ $ tail -12 /etc/network/if-up.d/avahi-autoipd
#fi #fi
``` ```
### netstat -a command ### netstat -a 命令
The **netstat -a** command will display  **_all_**  network connections. To limit this to listening and established connections (generally much more useful), use the **netstat -at** command instead. `netstat -a` 命令将显示“所有”网络连接。为了将其限制为显示正在监听和已建立的连接(通常更有用),请改用 `netstat -at` 命令。
``` ```
$ netstat -at $ netstat -at
@ -104,21 +97,9 @@ tcp6 0 0 ip6-localhost:ipp [::]:* LISTEN
tcp6 0 0 ip6-localhost:smtp [::]:* LISTEN tcp6 0 0 ip6-localhost:smtp [::]:* LISTEN
``` ```
### netstat -rn command ### host 命令
The **netstat -rn** command displays the system's routing table. The 192.168.0.1 address is the local gateway (Flags=UG). `host` 命令就像 `nslookup` 一样,用来查询远程系统的 IP 地址,但是还提供系统的邮箱处理地址。
```
$ netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
```
### host command
The **host** command works a lot like **nslookup** by looking up the remote system's IP address, but also provides the system's mail handler.
``` ```
$ host world.std.com $ host world.std.com
@ -126,9 +107,9 @@ world.std.com has address 192.74.137.5
world.std.com mail is handled by 10 smtp.theworld.com. world.std.com mail is handled by 10 smtp.theworld.com.
``` ```
### nslookup command ### nslookup 命令
The **nslookup** also provides information on the system (in this case, the local system) that is providing DNS lookup services. `nslookup` 还提供系统中(本例中是本地系统)提供 DNS 查询服务的信息。
``` ```
$ nslookup world.std.com $ nslookup world.std.com
@ -140,9 +121,9 @@ Name: world.std.com
Address: 192.74.137.5 Address: 192.74.137.5
``` ```
### dig command ### dig 命令
The **dig** command provides quitea lot of information on connecting to a remote system -- including the name server we are communicating with and how long the query takes to respond and is often used for troubleshooting. `dig` 命令提供了很多有关连接到远程系统的信息 - 包括与我们通信的名称服务器以及查询需要多长时间进行响应,并经常用于故障排除。
``` ```
$ dig world.std.com $ dig world.std.com
@ -167,9 +148,9 @@ world.std.com. 78146 IN A 192.74.137.5
;; MSG SIZE rcvd: 58 ;; MSG SIZE rcvd: 58
``` ```
### nmap command ### nmap 命令
The **nmap** command is most frequently used to probe remote systems, but can also be used to report on the services being offered by the local system. In the output below, we can see that ssh is available for logins, that smtp is servicing email, that a web site is active, and that an ipp print service is running. `nmap` 经常用于探查远程系统,但是同样也用于报告本地系统提供的服务。在下面的输出中,我们可以看到登录可以使用 ssh、smtp 用于电子邮箱、web 站点也是启用的,并且 ipp 打印服务正在运行。
``` ```
$ nmap localhost $ nmap localhost
@ -187,15 +168,15 @@ PORT STATE SERVICE
Nmap done: 1 IP address (1 host up) scanned in 0.09 seconds Nmap done: 1 IP address (1 host up) scanned in 0.09 seconds
``` ```
Linux systems provide a lot of useful commands for reviewing their network configuration and connections. If you run out of commands to explore, keep in mind that **apropos network** might point you toward even more. Linux 系统提供了很多有用的命令用于查看网络配置和连接。如果你都探索完了,请记住 `apropos network` 或许会让你了解更多。
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3230519/linux/examining-network-connections-on-linux-systems.html via: https://www.networkworld.com/article/3230519/linux/examining-network-connections-on-linux-systems.html
作者:[Sandra Henry-Stocker][a] 作者:[Sandra Henry-Stocker][a]
译者:[译者ID](https://github.com/译者ID) 译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID) 校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,140 @@
使用 VirtualBox 创建 Vagrant Boxes 的完全指南
======
Vagrant 是一个用来创建和管理虚拟机环境的工具,常用于建设开发环境。 它在 Docker、VirtualBox、Hyper-V、Vmware、AWS 等技术的基础上构建了一个易于使用且易于复制、重建的环境。
Vagrant Boxes 简化了软件配置部分的工作,并且完全解决了软件开发项目中经常遇到的“它能在我机器上工作”的问题,从而提高开发效率。
在本文中,我们会在 Linux 机器上学习使用 VirtualBox 来配置 Vagrant Boxes。
### 前置条件
Vagrant 是基于虚拟化环境运行的,这里我们使用 VirtualBox 来提供虚拟化环境。 关于如何安装 VirutalBox 我们在“[在 Linux 上安装 VirtualBox][1]” 中有详细描述,请阅读该文并安装 VirtualBox。
安装好 VirtualBox 后,下一步就是配置 Vagrant 了。
- 推荐阅读:[创建你的 Docker 容器][2]
### 安装
VirtualBox 准备好后,我们来安装最新的 vagrant 包。 在写本文的时刻, Vagrant 的最新版本为 2.0.0。 使用下面命令下载最新的 rpm 文件:
```
$ wget https://releases.hashicorp.com/vagrant/2.0.0/vagrant_2.0.0_x86_64.rpm
```
然后安装这个包:
```
$ sudo yum install vagrant_2.0.0_x86_64.rpm
```
如果是 Ubuntu用下面这个命令来下载最新的 vagrant 包:
```
$ wget https://releases.hashicorp.com/vagrant/2.0.0/vagrant_2.0.0_x86_64.deb
```
然后安装它,
```
$ sudo dpkg -i vagrant_2.0.0_x86_64.deb
```
安装结束后,就该进入配置环节了。
### 配置
首先,我们需要创建一个目录给 vagrant 来安装我们需要的操作系统,
```
$ mkdir /home/dan
$ cd /home/dan/vagrant
```
**注意:** 推荐在你的用户主目录下创建 vagrant否则你可能会遇到本地用户相关的权限问题。
现在执行下面命令来安装操作系统,比如 CentOS
```
$ sudo vagrant init centos/7
```
如果要安装 Ubuntu 则运行:
```
$ sudo vagrant init ubuntu/trusty64
```
![vagrant boxes][4]
这还会在存放 vagrant OS 的目录中创建一个叫做 `Vagrantfile` 的配置文件。它包含了一些关于操作系统、私有 IP 网络、转发端口、主机名等信息。 若我们需要创建一个新的操作系统, 也可以编辑这个问题。
一旦我们用 vagrant 创建/修改了操作系统,我们可以用下面命令启动它:
```
$ sudo vagrant up
```
这可能要花一些时间,因为这条命令要构建操作系统,它需要从网络上下载所需的文件。 因此根据互联网的速度, 这个过程可能会比较耗时。
![vagrant boxes][6]
这个过程完成后,你就可以使用下面这些命令来管理 vagrant 实例了。
启动 vagrant 服务器:
```
$ sudo vagrant up
```
关闭服务器:
```
$ sudo vagrant halt
```
完全删除服务器:
```
$ sudo vagrant destroy
```
使用 ssh 访问服务器:
```
$ sudo vagrant ssh
```
我们可以从 Vagrant Box 的启动过程中得到 ssh 的详细信息(参见上面的截屏)。
如果想看创建的 vagrant OS可以打开 VirtualBox然后你就能在 VirtualBox 创建的虚拟机中找到它了。 如果在 VirtualBox 中没有找到, 使用 `sudo` 权限打开 virtualbox 然后应该就能看到了。
![vagrant boxes][8]
**注意:** 在 [Vagrant 官方网站](https://app.vagrantup.com/boxes/search)上可以下载预先配置好的 Vagrant OS。
这就是本文的内容了。如有疑问请在下方留言,我们会尽快回复。
--------------------------------------------------------------------------------
via: http://linuxtechlab.com/creating-vagrant-virtual-boxes-virtualbox/
作者:[Shusain][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://linuxtechlab.com/author/shsuain/
[1]:http://linuxtechlab.com/installing-virtualbox-on-linux-centos-ubuntu/
[2]:http://linuxtechlab.com/create-first-docker-container-beginners-guide/
[3]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=721%2C87
[4]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/10/vagrant-1.png?resize=721%2C87
[5]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=980%2C414
[6]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/10/vagrant-2-e1510557565780.png?resize=980%2C414
[7]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=769%2C582
[8]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2017/10/vagrant-3.png?resize=769%2C582
[9]:https://www.facebook.com/linuxtechlab/
[10]:https://twitter.com/LinuxTechLab
[11]:https://plus.google.com/+linuxtechlab

View File

@ -0,0 +1,80 @@
面向初学者的 Linux 网络硬件:软件思维
===========================================================
![island network](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/soderskar-island.jpg?itok=wiMaF66b "island network")
> 没有路由和桥接,我们将会成为孤独的小岛,你将会在这个网络教程中学到更多知识。
[Commons Zero][3]Pixabay
上周,我们学习了本地网络硬件知识,本周,我们将学习网络互联技术和在移动网络中的一些很酷的黑客技术。
### 路由器
网络路由器就是计算机网络中的一切因为路由器连接着网络没有路由器我们就会成为孤岛。图一展示了一个简单的有线本地网络和一个无线接入点所有设备都接入到互联网上本地局域网的计算机连接到一个连接着防火墙或者路由器的以太网交换机上防火墙或者路由器连接到网络服务供应商ISP提供的电缆箱、调制调节器、卫星上行系统……好像一切都在计算中就像是一个带着不停闪烁的的小灯的盒子。当你的网络数据包离开你的局域网进入广阔的互联网它们穿过一个又一个路由器直到到达自己的目的地。
![simple LAN](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-1_7.png?itok=lsazmf3- "simple LAN")
*图一:一个简单的有线局域网和一个无线接入点。*
路由器可以是各种样式:一个只专注于路由的小巧特殊的小盒子,一个将会提供路由、防火墙、域名服务,以及 VPN 网关功能的大点的盒子,一台重新设计的台式电脑或者笔记本,一个树莓派计算机或者一个 Arduino体积臃肿矮小的像 PC Engines 这样的单板计算机,除了苛刻的用途以外,普通的商品硬件都能良好的工作运行。高端的路由器使用特殊设计的硬件每秒能够传输最大量的数据包。它们有多路数据总线,多个中央处理器和极快的存储。(可以通过了解 Juniper 和思科的路由器来感受一下高端路由器书什么样子的,而且能看看里面是什么样的构造。)
接入你的局域网的无线接入点要么作为一个以太网网桥,要么作为一个路由器。桥接器扩展了这个网络,所以在这个桥接器上的任意一端口上的主机都连接在同一个网络中。一台路由器连接的是两个不同的网络。
### 网络拓扑
有多种设置你的局域网的方式,你可以把所有主机接入到一个单独的<ruby>平面网络<rt>flat network</rt></ruby>,也可以把它们划分为不同的子网。如果你的交换机支持 VLAN 的话,你也可以把它们分配到不同的 VLAN 中。
平面网络是最简单的网络,只需把每一台设备接入到同一个交换机上即可,如果一台交换上的端口不够使用,你可以将更多的交换机连接在一起。有些交换机有特殊的上行端口,有些是没有这种特殊限制的上行端口,你可以连接其中的任意端口,你可能需要使用交叉类型的以太网线,所以你要查阅你的交换机的说明文档来设置。
平面网络是最容易管理的,你不需要路由器也不需要计算子网,但它也有一些缺点。它们的伸缩性不好,所以当网络规模变得越来越大的时候就会被广播网络所阻塞。将你的局域网进行分段将会提升安全保障, 把局域网分成可管理的不同网段将有助于管理更大的网络。图二展示了一个分成两个子网的局域网络:内部的有线和无线主机,和一个托管公开服务的主机。包含面向公共的服务器的子网称作非军事区域 DMZ你有没有注意到那些都是主要在电脑上打字的男人们的术语因为它被阻挡了所有的内部网络的访问。
![LAN](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-2_4.png?itok=LpXq7bLf "LAN")
*图二:一个分成两个子网的简单局域网。*
即使像图二那样的小型网络也可以有不同的配置方法。你可以将防火墙和路由器放置在一台单独的设备上。你可以为你的非军事区域设置一个专用的网络连接,把它完全从你的内部网络隔离,这将引导我们进入下一个主题:一切基于软件。
### 软件思维
你可能已经注意到在这个简短的系列中我们所讨论的硬件,只有网络接口、交换机,和线缆是特殊用途的硬件。
其它的都是通用的商用硬件而且都是软件来定义它的用途。Linux 是一个真实的网络操作系统,它支持大量的网络操作:网关、虚拟专用网关、以太网桥、网页、邮箱以及文件等等服务器、负载均衡、代理、服务质量、多种认证、中继、故障转移……你可以在运行着 Linux 系统的标准硬件上运行你的整个网络。你甚至可以使用 Linux 交换应用LISA和VDE2 协议来模拟以太网交换机。
有一些用于小型硬件的特殊发行版,如 DD-WRT、OpenWRT以及树莓派发行版也不要忘记 BSD 们和它们的特殊衍生用途如 pfSense 防火墙/路由器,和 FreeNAS 网络存储服务器。
你知道有些人坚持认为硬件防火墙和软件防火墙有区别?其实是没有区别的,就像说硬件计算机和软件计算机一样。
### 端口聚合和以太网绑定
聚合和绑定,也称链路聚合,是把两条以太网通道绑定在一起成为一条通道。一些交换机支持端口聚合,就是把两个交换机端口绑定在一起,成为一个是它们原来带宽之和的一条新的连接。对于一台承载很多业务的服务器来说这是一个增加通道带宽的有效的方式。
你也可以在以太网口进行同样的配置,而且绑定汇聚的驱动是内置在 Linux 内核中的,所以不需要任何其他的专门的硬件。
### 随心所欲选择你的移动宽带
我期望移动宽带能够迅速增长来替代 DSL 和有线网络。我居住在一个有 25 万人口的靠近一个城市的地方,但是在城市以外,要想接入互联网就要靠运气了,即使那里有很大的用户上网需求。我居住的小角落离城镇有 20 分钟的距离,但对于网络服务供应商来说他们几乎不会考虑到为这个地方提供网络。 我唯一的选择就是移动宽带;这里没有拨号网络、卫星网络(即使它很糟糕)或者是 DSL、电缆、光纤但却没有阻止网络供应商把那些我在这个区域从没看到过的 Xfinity 和其它高速网络服务的传单塞进我的邮箱。
我试用了 AT&T、Version 和 T-Mobile。Version 的信号覆盖范围最广,但是 Version 和 AT&T 是最昂贵的。
我居住的地方在 T-Mobile 信号覆盖的边缘,但迄今为止他们给了最大的优惠,为了能够能够有效的使用,我必须购买一个 WeBoost 信号放大器和一台中兴的移动热点设备。当然你也可以使用一部手机作为热点,但是专用的热点设备有着最强的信号。如果你正在考虑购买一台信号放大器,最好的选择就是 WeBoost因为他们的服务支持最棒而且他们会尽最大努力去帮助你。在一个小小的 APP [SignalCheck Pro][8] 的协助下设置将会精准的增强你的网络信号,他们有一个功能较少的免费的版本,但你将一点都不会后悔去花两美元使用专业版。
那个小巧的中兴热点设备能够支持 15 台主机,而且还有拥有基本的防火墙功能。 但你如果你使用像 Linksys WRT54GL这样的设备可以使用 Tomato、OpenWRT或者 DD-WRT 来替代普通的固件,这样你就能完全控制你的防护墙规则、路由配置,以及任何其它你想要设置的服务。
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2017/10/linux-networking-hardware-beginners-think-software
作者:[CARLA SCHRODER][a]
译者:[FelixYFZ](https://github.com/FelixYFZ)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://www.linux.com/licenses/category/used-permission
[2]:https://www.linux.com/licenses/category/used-permission
[3]:https://www.linux.com/licenses/category/creative-commons-zero
[4]:https://www.linux.com/files/images/fig-1png-7
[5]:https://www.linux.com/files/images/fig-2png-4
[6]:https://www.linux.com/files/images/soderskar-islandjpg
[7]:https://www.linux.com/learn/intro-to-linux/2017/10/linux-networking-hardware-beginners-lan-hardware
[8]:http://www.bluelinepc.com/signalcheck/

View File

@ -0,0 +1,84 @@
Eclipse 如何助力 IoT 发展
============================================================
> 开源组织的模块化开发方式非常适合物联网。
![How Eclipse is advancing IoT development](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_BUS_ArchitectureOfParticipation_520x292.png?itok=FA0Uuwzv "How Eclipse is advancing IoT development")
图片来源: opensource.com
[Eclipse][3] 可能不是第一个去研究物联网的开源组织。但是,远在 IoT 家喻户晓之前,该基金会在 2001 年左右就开始支持开源软件发展商业化。
九月份的 Eclipse 物联网日和 RedMonk 的 [ThingMonk 2017][4] 一块举行,着重强调了 Eclipse 在 [物联网发展][5] 中的重要作用。它现在已经包含了 28 个项目,覆盖了大部分物联网项目需求。会议过程中,我和负责 Eclipse 市场化运作的 [Ian Skerritt][6] 讨论了 Eclipse 的物联网项目以及如何拓展它。
### 物联网的最新进展?
我问 Ian 物联网同传统工业自动化,也就是前几十年通过传感器和相应工具来实现工厂互联的方式有什么不同。 Ian 指出很多工厂是还没有互联的。
另外,他说 “SCADA [<ruby>监控和数据分析<rt>supervisory control and data analysis</rt></ruby>] 系统以及工厂底层技术都是非常私有的、独立性的。我们很难去改变它,也很难去适配它们 …… 现在,如果你想运行一套生产系统,你需要设计成百上千的单元。生产线想要的是满足用户需求,使制造过程更灵活,从而可以不断产出。” 这也就是物联网会带给制造业的一个很大的帮助。
### Eclipse 物联网方面的研究
Ian 对于 Eclipse 在物联网的研究是这样描述的:“满足任何物联网解决方案的核心基础技术” ,通过使用开源技术,“每个人都可以使用,从而可以获得更好的适配性。” 他说Eclipse 将物联网视为包括三层互联的软件栈。从更高的层面上看,这些软件栈(按照大家常见的说法)将物联网描述为跨越三个层面的网络。特定的实现方式可能含有更多的层,但是它们一般都可以映射到这个三层模型的功能上:
* 一种可以装载设备(例如设备、终端、微控制器、传感器)用软件的堆栈。
* 将不同的传感器采集到的数据信息聚合起来并传输到网上的一类网关。这一层也可能会针对传感器数据检测做出实时反应。
* 物联网平台后端的一个软件栈。这个后端云存储数据并能根据采集的数据比如历史趋势、预测分析提供服务。
这三个软件栈在 Eclipse 的白皮书 “[The Three Software Stacks Required for IoT Architectures][7] ”中有更详细的描述。
Ian 说在这些架构中开发一种解决方案时,“需要开发一些特殊的东西,但是很多底层的技术是可以借用的,像通信协议、网关服务。需要一种模块化的方式来满足不同的需求场合。” Eclipse 关于物联网方面的研究可以概括为:开发模块化开源组件,从而可以被用于开发大量的特定性商业服务和解决方案。
### Eclipse 的物联网项目
在众多已被应用的 Eclipse 物联网应用中, Ian 举了两个和 [MQTT][8] 有关联的突出应用一个设备与设备互联M2M的物联网协议。 Ian 把它描述成“一个专为重视电源管理工作的油气传输线监控系统的信息发布/订阅协议。MQTT 已经是众多物联网广泛应用标准中很成功的一个。” [Eclipse Mosquitto][9] 是 MQTT 的代理,[Eclipse Paho][10] 是他的客户端。
[Eclipse Kura][11] 是一个物联网网关,引用 Ian 的话“它连接了很多不同的协议间的联系”包括蓝牙、Modbus、CANbus 和 OPC 统一架构协议,以及一直在不断添加的各种协议。他说,一个优势就是,取代了你自己写你自己的协议, Kura 提供了这个功能并将你通过卫星、网络或其他设备连接到网络。”另外它也提供了防火墙配置、网络延时以及其它功能。Ian 也指出“如果网络不通时,它会存储信息直到网络恢复。”
最新的一个项目中,[Eclipse Kapua][12] 正尝试通过微服务来为物联网云平台提供不同的服务。比如它集成了通信、汇聚、管理、存储和分析功能。Ian 说“它正在不断前进,虽然还没被完全开发出来,但是 Eurotech 和 RedHat 在这个项目上非常积极。”
Ian 说 [Eclipse hawkBit][13] 一个软件更新管理的软件是一项“非常有趣的项目。从安全的角度说如果你不能更新你的设备你将会面临巨大的安全漏洞。”很多物联网安全事故都和无法更新的设备有关他说“HawkBit 可以基本负责通过物联网系统来完成扩展性更新的后端管理。”
物联网设备软件升级的难度一直被看作是难度最高的安全挑战之一。物联网设备不是一直连接的,而且数目众多,再加上首先设备的更新程序很难完全正常。正因为这个原因,关于 IoT 软件升级的项目一直是被当作重要内容往前推进。
### 为什么物联网这么适合 Eclipse
在物联网发展趋势中的一个方面就是关于构建模块来解决商业问题,而不是跨越行业和公司的大物联网平台。 Eclipse 关于物联网的研究放在一系列模块栈、提供特定和大众化需求功能的项目上,还有就是指定目标所需的可捆绑式中间件、网关和协议组件上。
--------------------------------------------------------------------------------
作者简介:
Gordon Haff - Gordon Haff 是红帽公司的云专家,经常在消费者和行业会议上讲话,并且帮助发展红帽全面云化解决方案。他是《计算机前沿:云如何如何打开众多出版社未来之门》的作者。在红帽之前, Gordon 写了成百上千的研究报告,经常被引用到公众刊物上,像纽约时报关于 IT 的议题和产品建议等……
--------------------------------------------------------------------------------
via https://opensource.com/article/17/10/eclipse-and-iot
作者:[Gordon Haff][a]
译者:[smartgrids](https://github.com/smartgrids)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/ghaff
[1]:https://opensource.com/article/17/10/eclipse-and-iot?rate=u1Wr-MCMFCF4C45IMoSPUacCatoqzhdKz7NePxHOvwg
[2]:https://opensource.com/user/21220/feed
[3]:https://www.eclipse.org/home/
[4]:http://thingmonk.com/
[5]:https://iot.eclipse.org/
[6]:https://twitter.com/ianskerrett
[7]:https://iot.eclipse.org/resources/white-papers/Eclipse%20IoT%20White%20Paper%20-%20The%20Three%20Software%20Stacks%20Required%20for%20IoT%20Architectures.pdf
[8]:http://mqtt.org/
[9]:https://projects.eclipse.org/projects/technology.mosquitto
[10]:https://projects.eclipse.org/projects/technology.paho
[11]:https://www.eclipse.org/kura/
[12]:https://www.eclipse.org/kapua/
[13]:https://eclipse.org/hawkbit/
[14]:https://opensource.com/users/ghaff
[15]:https://opensource.com/users/ghaff
[16]:https://opensource.com/article/17/10/eclipse-and-iot#comments

View File

@ -0,0 +1,135 @@
如何使用 GPG 加解密文件
=================
目标:使用 GPG 加密文件
发行版:适用于任何发行版
要求:安装了 GPG 的 Linux 或者拥有 root 权限来安装它。
难度:简单
约定:
* `#` - 需要使用 root 权限来执行指定命令,可以直接使用 root 用户来执行,也可以使用 `sudo` 命令
* `$` - 可以使用普通用户来执行指定命令
### 介绍
加密非常重要。它对于保护敏感信息来说是必不可少的。你的私人文件应该要被加密,而 GPG 提供了很好的解决方案。
### 安装 GPG
GPG 的使用非常广泛。你在几乎每个发行版的仓库中都能找到它。如果你还没有安装它,那现在就来安装一下吧。
**Debian/Ubuntu**
```
$ sudo apt install gnupg
```
**Fedora**
```
# dnf install gnupg2
```
**Arch**
```
# pacman -S gnupg
```
**Gentoo**
```
# emerge --ask app-crypt/gnupg
```
### 创建密钥
你需要一个密钥对来加解密文件。如果你为 SSH 已经生成过了密钥对那么你可以直接使用它。如果没有GPG 包含工具来生成密钥对。
```
$ gpg --full-generate-key
```
GPG 有一个命令行程序可以帮你一步一步的生成密钥。它还有一个简单得多的工具,但是这个工具不能让你设置密钥类型,密钥的长度以及过期时间,因此不推荐使用这个工具。
GPG 首先会询问你密钥的类型。没什么特别的话选择默认值就好。
下一步需要设置密钥长度。`4096` 是一个不错的选择。
之后,可以设置过期的日期。 如果希望密钥永不过期则设置为 `0`
然后,输入你的名称。
最后,输入电子邮件地址。
如果你需要的话,还能添加一个注释。
所有这些都完成后GPG 会让你校验一下这些信息。
GPG 还会问你是否需要为密钥设置密码。这一步是可选的, 但是会增加保护的程度。若需要设置密码,则 GPG 会收集你的操作信息来增加密钥的健壮性。 所有这些都完成后, GPG 会显示密钥相关的信息。
### 加密的基本方法
现在你拥有了自己的密钥,加密文件非常简单。 使用下面的命令在 `/tmp` 目录中创建一个空白文本文件。
```
$ touch /tmp/test.txt
```
然后用 GPG 来加密它。这里 `-e` 标志告诉 GPG 你想要加密文件, `-r` 标志指定接收者。
```
$ gpg -e -r "Your Name" /tmp/test.txt
```
GPG 需要知道这个文件的接收者和发送者。由于这个文件给是你的,因此无需指定发送者,而接收者就是你自己。
### 解密的基本方法
你收到加密文件后,就需要对它进行解密。 你无需指定解密用的密钥。 这个信息被编码在文件中。 GPG 会尝试用其中的密钥进行解密。
```
$ gpg -d /tmp/test.txt.gpg
```
### 发送文件
假设你需要发送文件给别人。你需要有接收者的公钥。 具体怎么获得密钥由你自己决定。 你可以让他们直接把公钥发送给你, 也可以通过密钥服务器来获取。
收到对方公钥后,导入公钥到 GPG 中。
```
$ gpg --import yourfriends.key
```
这些公钥与你自己创建的密钥一样,自带了名称和电子邮件地址的信息。 记住,为了让别人能解密你的文件,别人也需要你的公钥。 因此导出公钥并将之发送出去。
```
gpg --export -a "Your Name" > your.key
```
现在可以开始加密要发送的文件了。它跟之前的步骤差不多, 只是需要指定你自己为发送人。
```
$ gpg -e -u "Your Name" -r "Their Name" /tmp/test.txt
```
### 结语
就这样了。GPG 还有一些高级选项, 不过你在 99% 的时间内都不会用到这些高级选项。 GPG 就是这么易于使用。你也可以使用创建的密钥对来发送和接受加密邮件,其步骤跟上面演示的差不多, 不过大多数的电子邮件客户端在拥有密钥的情况下会自动帮你做这个动作。
--------------------------------------------------------------------------------
via: https://linuxconfig.org/how-to-encrypt-and-decrypt-individual-files-with-gpg
作者:[Nick Congleton][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux 中国](https://linux.cn/) 荣誉推出
[a]:https://linuxconfig.org

View File

@ -0,0 +1,43 @@
回复:块层介绍第一部分 - 块 I/O 层
============================================================
### 块层介绍第一部分:块 I/O 层
回复amarao 在[块层介绍第一部分:块 I/O 层][1] 中提的问题
先前的文章:[块层介绍第一部分:块 I/O 层][2]
![](https://static.lwn.net/images/2017/neil-blocklayer.png)
嗨,
你在这里描述的问题与块层不直接相关。这可能是一个驱动错误、可能是一个 SCSI 层错误,但绝对不是一个块层的问题。
不幸的是,报告针对 Linux 的错误是一件难事。有些开发者拒绝去看 bugzilla有些开发者喜欢它有些像我这样只能勉强地使用它。
另一种方法是发送电子邮件。为此,你需要选择正确的邮件列表,还有也许是正确的开发人员,当他们心情愉快,或者不是太忙或者不是假期时找到它们。有些人会努力回复所有,有些是完全不可预知的 - 这对我来说通常会发送一个补丁,包含一些错误报告。如果你只是有一个你自己几乎都不了解的 bug那么你的预期响应率可能会更低。很遗憾但这是是真的。
许多 bug 都会得到回应和处理,但很多 bug 都没有。
我不认为说没有人关心是公平的,但是没有人认为它如你想的那样重要是有可能的。如果你想要一个解决方案,那么你需要驱动它。一个驱动它的方法是花钱请顾问或者与经销商签订支持合同。我怀疑你的情况没有上面的可能。另一种方法是了解代码如何工作,并自己找到解决方案。很多人都这么做,但是这对你来说可能不是一种选择。另一种方法是在不同的相关论坛上不断提出问题,直到得到回复。坚持可以见效。你需要做好准备去执行任何你所要求的测试,可能包括建立一个新的内核来测试。
如果你能在最近的内核(4.12 或者更新)上复现这个 bug我建议你邮件报告给 linux-kernel@vger.kernel.org、linux-scsi@vger.kernel.org 和我neilb@suse.com注意你不必订阅这些列表来发送邮件只需要发送就行。描述你的硬件以及如何触发问题的。
包含所有进程状态是 “D” 的栈追踪。你可以用 “cat /proc/$PID/stack” 来得到它,这里的 “$PID” 是进程的 pid。
确保避免抱怨或者说这个已经坏了好几年了以及这是多么严重不足。没有人关心这个。我们关心的是 bug 以及如何修复它。因此只要报告相关的事实就行。
尝试在邮件中而不是链接到其他地方的链接中包含所有事实。有时链接是需要的,但是对于你的脚本,它只有 8 行,所以把它包含在邮件中就行(并避免像 “fuckup” 之类的描述。只需称它为“坏的”broken或者类似的。同样确保你的邮件发送的不是 HTML 格式。我们喜欢纯文本。HTML 被所有的 @vger.kernel.org 邮件列表拒绝。你或许需要配置你的邮箱程序不发送 HTML。
--------------------------------------------------------------------------------
via: https://lwn.net/Articles/737655/
作者:[neilbrown][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://lwn.net/Articles/737655/
[1]:https://lwn.net/Articles/737588/
[2]:https://lwn.net/Articles/736534/

View File

@ -0,0 +1,217 @@
怎么使用 SVG 作为一个图像占位符
============================================================
![](https://cdn-images-1.medium.com/max/1563/0*zJGl1vKLttcJGIL4.jpg)
*从图像中生成的 SVG 可以用作占位符。请继续阅读!*
我对怎么去让 web 性能更优化和图像加载的更快充满了热情。在这些感兴趣的领域中的其中一项研究就是占位符:当图像还没有被加载的时候应该去展示些什么?
在前些天,我偶然发现了使用 SVG 的一些加载技术,我将在这篇文章中谈论它。
在这篇文章中我们将涉及如下的主题:
* 不同的占位符类型的概述
* 基于 SVG 的占位符(边缘、形状和轮廓)
* 自动化处理
### 不同的占位符类型的概述
之前 [我写过一篇关于图像占位符和<ruby>延迟加载<rt>lazy-loading</rt></ruby>][28] 的文章以及 [关于它的讨论][29]。当进行一个图像的延迟加载时,一个很好的办法是提供一个东西作为占位符,因为它可能会很大程度上影响用户的感知体验。之前我提供了几个选择:
![](https://cdn-images-1.medium.com/max/1563/0*jlMM144vAhH-0bEn.png)
在图像被加载之前,有几种办法去填充图像区域:
* 在图像区域保持空白:在一个响应式设计的环境中,这种方式防止了内容的跳跃。从用户体验的角度来看,那些布局的改变是非常差的作法。但是,它是为了性能的考虑,否则,每次为了获取图像尺寸,浏览器就要被迫进行布局重新计算,以便为它留下空间。
* 占位符:在图像那里显示一个用户配置的图像。我们可以在背景上显示一个轮廓。它一直显示直到实际的图像被加载完成,它也被用于当请求失败或者当用户根本没有设置头像图像的情况下。这些图像一般都是矢量图,并且由于尺寸非常小,可以作为内联图片。
* 单一颜色:从图像中获取颜色,并将其作为占位符的背景颜色。这可能是图像的主要颜色、最具活力的颜色 … 这个想法是基于你正在加载的图像,并且它将有助于在没有图像和图像加载完成之间进行平滑过渡。
* 模糊的图像:也被称为模糊技术。你提供一个极小版本的图像,然后再去过渡到完整的图像。最初显示的图像的像素和尺寸是极小的。为去除<ruby>细节<rt>artifacts</rt></ruby>,该图像会被放大并模糊化。我在前面写的 [Medium 是怎么做的渐进加载图像][1]、[使用 WebP 去创建极小的预览图像][2]、和[渐进加载图像的更多示例][3] 中讨论过这方面的内容。
此外还有其它的更多的变种,许多聪明的人也开发了其它的创建占位符的技术。
其中一个就是用梯度图代替单一的颜色。梯度图可以创建一个更精确的最终图像的预览,它整体上非常小(提升了有效载荷)。
![](https://cdn-images-1.medium.com/max/1250/0*ecPkBAl69ayvRctn.jpg)
*使用梯度图作为背景。这是来自 Gradify 的截屏,它现在已经不在线了,代码 [在 GitHub][4]。*
另外一种技术是使用基于 SVG 的技术,它在最近的实验和研究中取得到了一些进展。
### 基于 SVG 的占位符
我们知道 SVG 是完美的矢量图像。而在大多数情况下我们是希望加载一个位图,所以,问题是怎么去矢量化一个图像。其中一些方法是使用边缘、形状和轮廓。
#### 边缘
在 [前面的文章中][30],我解释了怎么去找出一个图像的边缘并创建一个动画。我最初的目标是去尝试绘制区域,矢量化该图像,但是我并不知道该怎么去做到。我意识到使用边缘也可能是一种创新,我决定去让它们动起来,创建一个 “绘制” 的效果。
- [范例](https://codepen.io/jmperez/embed/oogqdp?default-tabs=html%2Cresult&embed-version=2&height=600&host=https%3A%2F%2Fcodepen.io&referrer=https%3A%2F%2Fmedium.freecodecamp.org%2Fmedia%2F8c5c44a4adf82b09692a34eb4daa3e2e%3FpostId%3Dbed1b810ab2c&slug-hash=oogqdp#result-box)
> [使用边缘检测绘制图像和 SVG 动画][31]
> 在以前,很少使用和支持 SVG。一段时间以后我们开始用它去作为一个某些图标的传统位图的替代品……
#### 形状
SVG 也可以用于根据图像绘制区域而不是边缘/边界。用这种方法,我们可以矢量化一个位图来创建一个占位符。
在以前,我尝试去用三角形做类似的事情。你可以在 [CSSConf][33] 和 [Render Conf][34] 上我的演讲中看到它。
- [范例](https://codepen.io/jmperez/embed/BmaWmQ?default-tabs=html%2Cresult&embed-version=2&height=600&host=https%3A%2F%2Fcodepen.io&referrer=https%3A%2F%2Fmedium.freecodecamp.org%2Fmedia%2F05d1ee44f0537f8257258124d7b94613%3FpostId%3Dbed1b810ab2c&slug-hash=BmaWmQ#result-box)
上面的 codepen 是一个由 245 个三角形组成的基于 SVG 占位符的概念验证。生成的三角形是基于 [Delaunay triangulation][35] 的,使用了 [Possans polyserver][36]。正如预期的那样,使用更多的三角形,文件尺寸就更大。
#### Primitive 和 SQIP一个基于 SVG 的 LQIP 技术
Tobias Baldauf 正在致力于另一个使用 SVG 的低质量图像占位符技术,它被称为 [SQIP][37]。在深入研究 SQIP 之前,我先简单介绍一下 [Primitive][38],它是基于 SQIP 的一个库。
Primitive 是非常吸引人的,我强烈建议你去了解一下。它讲解了一个位图怎么变成由重叠形状组成的 SVG。它尺寸比较小适合于直接内联放置到页面中。当步骤较少时在初始的 HTML 载荷中作为占位符是非常有意义的。
Primitive 基于三角形、长方形、和圆形等形状生成一个图像。在每一步中它增加一个新形状。很多步之后,图像的结果看起来非常接近原始图像。如果你输出的是 SVG它意味着输出代码的尺寸将很大。
为了理解 Primitive 是怎么工作的,我通过几个图像来跑一下它。我用 10 个形状和 100 个形状来为这个插画生成 SVG
![](https://cdn-images-1.medium.com/max/625/1*y4sr9twkh_WyZh6h0yH98Q.png)
![](https://cdn-images-1.medium.com/max/625/1*cqyhYnx83LYvhGdmg2dFDw.png)
![](https://cdn-images-1.medium.com/max/625/1*qQP5160gPKQdysh0gFnNfw.jpeg)
使用 Primitive 处理 ,使用 [10 个形状][6] 、 [100 形状][7]、 [原图][5]。
![](https://cdn-images-1.medium.com/max/625/1*PWZLlC4lrLO4CVv1GwR7qA.png)
![](https://cdn-images-1.medium.com/max/625/1*khnga22ldJKOZ2z45Srh8A.png)
![](https://cdn-images-1.medium.com/max/625/1*N-20rR7YGFXiDSqIeIyOjA.jpeg)
使用 Primitive 处理,使用 [10 形状][9] 、 [100 形状][10]、 [原图][8] 。
当在图像中使用 10 个形状时,我们基本构画出了原始图像。在图像占位符这种使用场景里,我们可以使用这种 SVG 作为潜在的占位符。实际上,使用 10 个形状的 SVG 代码已经很小了,大约是 1030 字节,当通过 SVGO 传输时,它将下降到约 640 字节。
```
<svg xmlns=”http://www.w3.org/2000/svg" width=”1024" height=”1024"><path fill=”#817c70" d=”M0 0h1024v1024H0z/><g fill-opacity=”.502"><path fill=”#03020f” d=”M178 994l580 92L40262"/><path fill=”#f2e2ba” d=”M638 894L614 6l472 440"/><path fill=”#fff8be” d=”M-62 854h300L13862"/><path fill=”#76c2d9" d=”M41062L154 53062 38"/><path fill=”#62b4cf” d=”M10862L49830l484 508"/><path fill=”#010412" d=”M4302l196 5276 356"/><path fill=”#eb7d3f” d=”M598 594l48832308 520"/><path fill=”#080a18" d=”M198 418l32 304 116448"/><path fill=”#3f201d” d=”M1086 1062l-34452 248148"/><path fill=”#ebd29f” d=”M630 658l-60372 516 320"/></g></svg>
```
正如我们预计的那样,使用 100 个形状生成的图像更大,在 SVGO之前是 8kB之后大小约为 5kB。它们在细节上已经很好了但是仍然是个很小的载荷。使用多少三角形主要取决于图像类型和细腻程度对比度、颜色数量、复杂度
还可以创建一个类似于 [cpeg-dssim][39] 的脚本,去调整所使用的形状的数量,以满足 [结构相似][40] 的阈值(或者最差情况中的最大数量)。
这些生成的 SVG 也可以用作背景图像。因为尺寸约束和矢量化,它们在展示<ruby>超大题图<rt>hero image</rt></ruby>和大型背景图像时是很好的选择。
#### SQIP
用 [Tobias 自己的话说][41]
> SQIP 尝试在这两个极端之间找到一种平衡:它使用 [Primitive][42] 去生成一个 SVG由几种简单的形状构成近似于图像中可见的主要特征使用 [SVGO][43] 优化 SVG并且为它增加高斯模糊滤镜。产生的最终的 SVG 占位符后大小仅为约 800~1000 字节,在屏幕上看起来更为平滑,并提供一个图像内容的视觉提示。
这个结果和使用一个用了模糊技术的极小占位符图像类似。(看看  [Medium][44] 和 [其它站点][45] 是怎么做的)。区别在于它们使用了一个位图图像,如 JPG 或者 WebP而这里是使用的占位符是 SVG。
如果我们使用 SQIP 而不是原始图像,我们将得到这样的效果:
![](https://cdn-images-1.medium.com/max/938/0*yUY1ZFP27vFYgj_o.png)
![](https://cdn-images-1.medium.com/max/938/0*DKoZP7DXFvUZJ34E.png)
*[第一张图像][11] 和 [第二张图像][12] 使用了 SQIP 后的输出图像。*
输出的 SVG 约 900 字节,并且通过检查代码,我们可以发现 `feGaussianBlur` 过滤被应用到该组形状上:
```
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000"><filter id="b"><feGaussianBlur stdDeviation="12" /></filter><path fill="#817c70" d="M0 0h2000v2000H0z"/><g filter="url(#b)" transform="translate(4 4) scale(7.8125)" fill-opacity=".5"><ellipse fill="#000210" rx="1" ry="1" transform="matrix(50.41098 -3.7951 11.14787 148.07886 107 194.6)"/><ellipse fill="#eee3bb" rx="1" ry="1" transform="matrix(-56.38179 17.684 -24.48514 -78.06584 205 110.1)"/><ellipse fill="#fff4bd" rx="1" ry="1" transform="matrix(35.40604 -5.49219 14.85017 95.73337 16.4 123.6)"/><ellipse fill="#79c7db" cx="21" cy="39" rx="65" ry="65"/><ellipse fill="#0c1320" cx="117" cy="38" rx="34" ry="47"/><ellipse fill="#5cb0cd" rx="1" ry="1" transform="matrix(-39.46201 77.24476 -54.56092 -27.87353 219.2 7.9)"/><path fill="#e57339" d="M271 159l-12316 43 128z"/><ellipse fill="#47332f" cx="214" cy="237" rx="242" ry="19"/></g></svg>
```
SQIP 也可以输出一个带有 Base64 编码的 SVG 内容的图像标签:
```
<img width="640" height="640" src="example.jpg” alt="Add descriptive alt text" style="background-size: cover; background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAw…<stripped base 64>…PjwvZz48L3N2Zz4=);">
```
#### 轮廓
我们刚才看了使用了边缘和原始形状的 SVG。另外一种矢量化图像的方式是 “描绘” 它们。在几天前 [Mikael Ainalem][47] 分享了一个 [codepen][48] 代码,展示了怎么去使用两色轮廓作为一个占位符。结果非常漂亮:
![](https://cdn-images-1.medium.com/max/1250/1*r6HbVnBkISCQp_UVKjOJKQ.gif)
SVG 在这种情况下是手工绘制的,但是,这种技术可以用工具快速生成并自动化处理。
* [Gatsby][13],一个用 React 支持的描绘 SVG 的静态网站生成器。它使用 [一个 potrace 算法的 JS 移植][14] 去矢量化图像。
* [Craft 3 CMS][15],它也增加了对轮廓的支持。它使用了 [一个 potrace 算法的 PHP 移植][16]。
* [image-trace-loader][17],一个使用了 potrace 算法去处理图像的 Webpack 加载器。
如果感兴趣,可以去看一下 Emil 的 webpack 加载器 (基于 potrace) 和 Mikael 的手工绘制 SVG 之间的比较。
这里我假设该输出是使用默认选项的 potrace 生成的。但是可以对它们进行优化。查看 [图像描绘加载器的选项][49][传递给 potrace 的选项][50]非常丰富。
### 总结
我们看到了从图像中生成 SVG 并使用它们作为占位符的各种不同的工具和技术。与 [WebP 是一个用于缩略图的奇妙格式][51] 一样SVG 也是一个用于占位符的有趣格式。我们可以控制细节的级别(和它们的大小),它是高可压缩的,并且很容易用 CSS 和 JS 进行处理。
#### 额外的资源
这篇文章上到了 [Hacker News 热文][52]。对此以及在该页面的评论中分享的其它资源的链接,我表示非常感谢。下面是其中一部分。
* [Geometrize][18] 是用 Haxe 写的 Primitive 的一个移植。也有[一个 JS 实现][19],你可以直接 [在你的浏览器上][20]尝试它。
* [Primitive.js][21],它也是 Primitive 在 JS 中的一个移植,[primitive.nextgen][22],它是使用 Primitive.js 和 Electron 的 Primitive 的桌面版应用的一个移植。
* 这里有两个 Twitter 帐户,里面你可以看到一些用 Primitive 和 Geometrize 生成的图像示例。访问 [@PrimitivePic][23] 和 [@Geometrizer][24]。
* [imagetracerjs][25],它是在 JavaScript 中的光栅图像描绘器和矢量化程序。这里也有为 [Java][26] 和 [Android][27] 提供的移植。
--------------------------------------------------------------------------------
via: https://medium.freecodecamp.org/using-svg-as-placeholders-more-image-loading-techniques-bed1b810ab2c
作者:[José M. Pérez][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://medium.freecodecamp.org/@jmperezperez?source=post_header_lockup
[1]:https://medium.com/@jmperezperez/how-medium-does-progressive-image-loading-fd1e4dc1ee3d
[2]:https://medium.com/@jmperezperez/using-webp-to-create-tiny-preview-images-3e9b924f28d6
[3]:https://medium.com/@jmperezperez/more-examples-of-progressive-image-loading-f258be9f440b
[4]:https://github.com/fraser-hemp/gradify
[5]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-281184-square.jpg
[6]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-281184-square-10.svg
[7]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-281184-square-100.svg
[8]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-618463-square.jpg
[9]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-618463-square-10.svg
[10]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-618463-square-100.svg
[11]:https://jmperezperez.com/assets/images/posts/svg-placeholders/pexels-photo-281184-square-sqip.svg
[12]:https://jmperezperez.com/svg-placeholders/%28/assets/images/posts/svg-placeholders/pexels-photo-618463-square-sqip.svg
[13]:https://www.gatsbyjs.org/
[14]:https://www.npmjs.com/package/potrace
[15]:https://craftcms.com/
[16]:https://github.com/nystudio107/craft3-imageoptimize/blob/master/src/lib/Potracio.php
[17]:https://github.com/EmilTholin/image-trace-loader
[18]:https://github.com/Tw1ddle/geometrize-haxe
[19]:https://github.com/Tw1ddle/geometrize-haxe-web
[20]:http://www.samcodes.co.uk/project/geometrize-haxe-web/
[21]:https://github.com/ondras/primitive.js
[22]:https://github.com/cielito-lindo-productions/primitive.nextgen
[23]:https://twitter.com/PrimitivePic
[24]:https://twitter.com/Geometrizer
[25]:https://github.com/jankovicsandras/imagetracerjs
[26]:https://github.com/jankovicsandras/imagetracerjava
[27]:https://github.com/jankovicsandras/imagetracerandroid
[28]:https://medium.com/@jmperezperez/lazy-loading-images-on-the-web-to-improve-loading-time-and-saving-bandwidth-ec988b710290
[29]:https://www.youtube.com/watch?v=szmVNOnkwoU
[30]:https://medium.com/@jmperezperez/drawing-images-using-edge-detection-and-svg-animation-16a1a3676d3
[31]:https://medium.com/@jmperezperez/drawing-images-using-edge-detection-and-svg-animation-16a1a3676d3
[32]:https://medium.com/@jmperezperez/drawing-images-using-edge-detection-and-svg-animation-16a1a3676d3
[33]:https://jmperezperez.com/cssconfau16/#/45
[34]:https://jmperezperez.com/renderconf17/#/46
[35]:https://en.wikipedia.org/wiki/Delaunay_triangulation
[36]:https://github.com/possan/polyserver
[37]:https://github.com/technopagan/sqip
[38]:https://github.com/fogleman/primitive
[39]:https://github.com/technopagan/cjpeg-dssim
[40]:https://en.wikipedia.org/wiki/Structural_similarity
[41]:https://github.com/technopagan/sqip
[42]:https://github.com/fogleman/primitive
[43]:https://github.com/svg/svgo
[44]:https://medium.com/@jmperezperez/how-medium-does-progressive-image-loading-fd1e4dc1ee3d
[45]:https://medium.com/@jmperezperez/more-examples-of-progressive-image-loading-f258be9f440b
[46]:http://www.w3.org/2000/svg
[47]:https://twitter.com/mikaelainalem
[48]:https://codepen.io/ainalem/full/aLKxjm/
[49]:https://github.com/EmilTholin/image-trace-loader#options
[50]:https://www.npmjs.com/package/potrace#parameters
[51]:https://medium.com/@jmperezperez/using-webp-to-create-tiny-preview-images-3e9b924f28d6
[52]:https://news.ycombinator.com/item?id=15696596

View File

@ -0,0 +1,57 @@
操作系统何时运行?
============================================================
请各位思考以下问题:在你阅读本文的这段时间内,计算机中的操作系统在**运行**吗?又或者仅仅是 Web 浏览器在运行?又或者它们也许均处于空闲状态,等待着你的指示?
这些问题并不复杂,但它们深入涉及到系统软件工作的本质。为了准确回答这些问题,我们需要透彻理解操作系统的行为模型,包括性能、安全和除错等方面。在该系列文章中,我们将以 Linux 为主举例来帮助你建立操作系统的行为模型OS X 和 Windows 在必要的时候也会有所涉及。对那些深度探索者,我会在适当的时候给出 Linux 内核源码的链接。
这里有一个基本认知,就是,在任意给定时刻,某个 CPU 上仅有一个任务处于活动状态。大多数情形下这个任务是某个用户程序,例如你的 Web 浏览器或音乐播放器,但它也可能是一个操作系统线程。可以确信的是,它是**一个任务**,不是两个或更多,也不是零个,对,**永远**是一个。
这听上去可能会有些问题。比如,你的音乐播放器是否会独占 CPU 而阻止其它任务运行?从而使你不能打开任务管理工具去杀死音乐播放器,甚至让鼠标点击也失效,因为操作系统没有机会去处理这些事件。你可能会愤而喊出,“它究竟在搞什么鬼?”,并引发骚乱。
此时便轮到**中断**大显身手了。中断就好比,一声巨响或一次拍肩后,神经系统通知大脑去感知外部刺激一般。计算机主板上的[芯片组][1]同样会中断 CPU 运行以传递新的外部事件,例如键盘上的某个键被按下、网络数据包的到达、一次硬盘读取的完成,等等。硬件外设、主板上的中断控制器和 CPU 本身,它们共同协作实现了中断机制。
中断对于记录我们最珍视的资源——时间——也至关重要。计算机[启动过程][2]中,操作系统内核会设置一个硬件计时器以让其产生周期性**计时中断**,例如每隔 10 毫秒触发一次。每当计时中断到来,内核便会收到通知以更新系统统计信息和盘点如下事项:当前用户程序是否已运行了足够长时间?是否有某个 TCP 定时器超时了?中断给予了内核一个处理这些问题并采取合适措施的机会。这就好像你给自己设置了整天的周期闹铃并把它们用作检查点:我是否应该去做我正在进行的工作?是否存在更紧急的事项?直到你发现 10 年时间已逝去……
这些内核对 CPU 周期性的劫持被称为<ruby>滴答<rt>tick</rt></ruby>,也就是说,是中断让你的操作系统滴答了一下。不止如此,中断也被用作处理一些软件事件,如整数溢出和页错误,其中未涉及外部硬件。**中断是进入操作系统内核最频繁也是最重要的入口**。对于学习电子工程的人而言,这些并无古怪,它们是操作系统赖以运行的机制。
说到这里,让我们再来看一些实际情形。下图示意了 Intel Core i5 系统中的一个网卡中断。图片中的部分元素设置了超链,你可以点击它们以获取更为详细的信息,例如每个设备均被链接到了对应的 Linux 驱动源码。
![](http://duartes.org/gustavo/blog/img/os/hardware-interrupt.png)
链接如下:
- network card https://github.com/torvalds/linux/blob/v3.17/drivers/net/ethernet/intel/e1000e/netdev.c
- USB keyboard https://github.com/torvalds/linux/blob/v3.16/drivers/hid/usbhid/usbkbd.c
- I/O APIC https://github.com/torvalds/linux/blob/v3.16/arch/x86/kernel/apic/io_apic.c
- HPET https://github.com/torvalds/linux/blob/v3.17/arch/x86/kernel/hpet.c
让我们来仔细研究下。首先,由于系统中存在众多中断源,如果硬件只是通知 CPU “嘿,这里发生了一些事情”然后什么也不做,则不太行得通。这会带来难以忍受的冗长等待。因此,计算机上电时,每个设备都被授予了一根**中断线**,或者称为 IRQ。这些 IRQ 然后被系统中的中断控制器映射成值介于 0 到 255 之间的**中断向量**。等到中断到达 CPU它便具备了一个完好定义的数值异于硬件的某些其它诡异行为。
相应地CPU 中还存有一个由内核维护的指针,指向一个包含 255 个函数指针的数组,其中每个函数被用来处理某个特定的中断向量。后文中,我们将继续深入探讨这个数组,它也被称作**中断描述符表**IDT
每当中断到来CPU 会用中断向量的值去索引中断描述符表并执行相应处理函数。这相当于在当前正在执行任务的上下文中发生了一个特殊函数调用从而允许操作系统以较小开销快速对外部事件作出反应。考虑下述场景Web 服务器在发送数据时CPU 却间接调用了操作系统函数,这听上去要么很炫酷要么令人惊恐。下图展示了 Vim 编辑器运行过程中一个中断到来的情形。
![](http://duartes.org/gustavo/blog/img/os/vim-interrupted.png)
此处请留意,中断的到来是如何触发 CPU 到 [Ring 0][3] 内核模式的切换而未有改变当前活跃的任务。这看上去就像Vim 编辑器直接面向操作系统内核产生了一次神奇的函数调用,但 Vim 还在那里,它的[地址空间][4]原封未动,等待着执行流返回。
这很令人振奋,不是么?不过让我们暂且告一段落吧,我需要合理控制篇幅。我知道还没有回答完这个开放式问题,甚至还实质上翻开了新的问题,但你至少知道了在你读这个句子的同时**滴答**正在发生。我们将在充实了对操作系统动态行为模型的理解之后再回来寻求问题的答案,对 Web 浏览器情形的理解也会变得清晰。如果你仍有问题,尤其是在这篇文章公诸于众后,请尽管提出。我将会在文章或后续评论中回答它们。下篇文章将于明天在 RSS 和 Twitter 上发布。
--------------------------------------------------------------------------------
via: http://duartes.org/gustavo/blog/post/when-does-your-os-run/
作者:[gustavo][a]
译者:[Cwndmiao](https://github.com/Cwndmiao)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://duartes.org/gustavo/blog/about/
[1]:http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map
[2]:http://duartes.org/gustavo/blog/post/kernel-boot-process
[3]:http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection
[4]:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory
[5]:http://feeds.feedburner.com/GustavoDuarte
[6]:http://twitter.com/food4hackers

View File

@ -1,27 +1,27 @@
介绍 MOBY 项目:推进软件容器化运动的一个新的开源项目 介绍 Moby 项目:推进软件容器化运动的一个新的开源项目
============================================================ ============================================================
![Moby Project](https://i0.wp.com/blog.docker.com/wp-content/uploads/1-2.png?resize=763%2C275&ssl=1) ![Moby Project](https://i0.wp.com/blog.docker.com/wp-content/uploads/1-2.png?resize=763%2C275&ssl=1)
自从 Docker 四年前将软件容器推向民主化以来,整个生态系统都围绕着容器化而发展,在这段压缩的时期,它经历了两个不同的增长阶段。在这每一个阶段,生产容器系统的模式已经演变适应用户群体以及项目的规模和需求和不断增长的贡献者生态系统 自从 Docker 四年前将软件容器推向大众化以来,整个生态系统都围绕着容器化而发展,在这段这么短的时期内,它经历了两个不同的增长阶段。在这每一个阶段,生产容器系统的模式已经随着项目和不断增长的容器生态系统而演变适应用户群体的规模和需求。
Moby 是一个新的开源项目,旨在推进软件容器化运动,帮助生态系统将容器作为主流。它提供了一个组件库,一个将它们组装到定制的基于容器的系统的框架,以及所有容器爱好者进行实验和交换想法的地方。 Moby 是一个新的开源项目,旨在推进软件容器化运动,帮助生态系统将容器作为主流。它提供了一个组件库,一个将它们组装到定制的基于容器的系统的框架,也是所有容器爱好者进行实验和交换想法的地方。
让我们来回顾一下我们如何走到今天。在 2013-2014 年开拓者开始使用容器并在一个单一的开源代码库Docker 和其他一些项目中进行协作,以帮助工具成熟。 让我们来回顾一下我们如何走到今天。在 2013-2014 年开拓者开始使用容器并在一个单一的开源代码库Docker 和其他一些项目中进行协作,以帮助工具成熟。
![Docker Open Source](https://i0.wp.com/blog.docker.com/wp-content/uploads/2-2.png?resize=975%2C548&ssl=1) ![Docker Open Source](https://i0.wp.com/blog.docker.com/wp-content/uploads/2-2.png?resize=975%2C548&ssl=1)
然后在 2015-2016 年云原生应用中大量采用容器用于生产环境。在这个阶段用户社区已经发展到支持成千上万个部署由数百个生态系统项目和成千上万的贡献者支持。正是在这个阶段Docker 将其产模式演变为基于开放式组件的方法。这样,它使我们能够增加创新和合作的方面。 然后在 2015-2016 年云原生应用中大量采用容器用于生产环境。在这个阶段用户社区已经发展到支持成千上万个部署由数百个生态系统项目和成千上万的贡献者支持。正是在这个阶段Docker 将其产模式演变为基于开放式组件的方法。这样,它使我们能够增加创新和合作的方面。
涌现出来的新独立的 Docker 组件项目帮助刺激了合作伙伴生态系统和用户社区的发展。在此期间,我们从 Docker 代码库中提取并快速创新组件,以便系统制造商可以在构建自己的容器系统时独立重用它们:[runc][7]、[HyperKit][8]、[VPNKit][9]、[SwarmKit][10]、[InfraKit][11]、[containerd][12] 等。 涌现出来的新独立的 Docker 组件项目帮助促进了合作伙伴生态系统和用户社区的发展。在此期间,我们从 Docker 代码库中提取并快速创新组件,以便系统制造商可以在构建自己的容器系统时独立重用它们:[runc][7]、[HyperKit][8]、[VPNKit][9]、[SwarmKit][10]、[InfraKit][11]、[containerd][12] 等。
![Docker Open Components](https://i1.wp.com/blog.docker.com/wp-content/uploads/3-2.png?resize=975%2C548&ssl=1) ![Docker Open Components](https://i1.wp.com/blog.docker.com/wp-content/uploads/3-2.png?resize=975%2C548&ssl=1)
站在容器浪潮的最前沿,我们看到 2017 年出现的一个趋势是容器将成为主流,传播到计算、服务器、数据中心、云、桌面、物联网和移动的各个领域。每个行业和垂直市场金融、医疗、政府、旅游、制造。以及每一个使用案例,现代网络应用、传统服务器应用、机器学习、工业控制系统、机器人技术。容器生态系统中许多新进入者的共同点是,它们建立专门的系统,针对特定的基础设施、行业或使用案例。 站在容器浪潮的最前沿,我们看到 2017 年出现的一个趋势是容器将成为主流,传播到计算、服务器、数据中心、云、桌面、物联网和移动的各个领域。每个行业和垂直市场金融、医疗、政府、旅游、制造。以及每一个使用案例,现代网络应用、传统服务器应用、机器学习、工业控制系统、机器人技术。容器生态系统中许多新进入者的共同点是,它们建立专门的系统,针对特定的基础设施、行业或使用案例。
作为一家公司Docker 使用开源作为我们的创新实验室而与整个生态系统合作。Docker 的成功取决于容器生态系统的成功:如果生态系统成功,我们就成功了。因此,我们一直在计划下一阶段的容器生态系统增长:什么样的产模式将帮助我们扩大容器生态系统,实现容器成为主流的承诺? 作为一家公司Docker 使用开源作为我们的创新实验室而与整个生态系统合作。Docker 的成功取决于容器生态系统的成功:如果生态系统成功,我们就成功了。因此,我们一直在计划下一阶段的容器生态系统增长:什么样的产模式将帮助我们扩大容器生态系统,实现容器成为主流的承诺?
去年,我们的客户开始在 Linux 以外的许多平台上要求有 DockerMac 和 Windows 桌面、Windows Server、云平台如亚马逊网络服务AWS、Microsoft Azure 或 Google 云平台),并且我们专门为这些平台创建了[许多 Docker 版本][13]。为了在一个相对较短的时间与更小的团队,以可扩展的方式构建和发布这些专业版本,而不必重新发明轮子,很明显,我们需要一个新的方。我们需要我们的团队不仅在组件上进行协作,而且还在组件组合上进行协作,这借用[来自汽车行业的想法][14],其中组件被重用于构建完全不同的汽车。 去年,我们的客户开始在 Linux 以外的许多平台上要求有 DockerMac 和 Windows 桌面、Windows Server、云平台如亚马逊网络服务AWS、Microsoft Azure 或 Google 云平台),并且我们专门为这些平台创建了[许多 Docker 版本][13]。为了在一个相对较短的时间和更小的团队中,以可扩展的方式构建和发布这些专业版本,而不必重新发明轮子,很明显,我们需要一个新的方。我们需要我们的团队不仅在组件上进行协作,而且还在组件组合上进行协作,这借用[来自汽车行业的想法][14],其中组件被重用于构建完全不同的汽车。
![Docker production model](https://i1.wp.com/blog.docker.com/wp-content/uploads/4-2.png?resize=975%2C548&ssl=1) ![Docker production model](https://i1.wp.com/blog.docker.com/wp-content/uploads/4-2.png?resize=975%2C548&ssl=1)
@ -29,15 +29,13 @@ Moby 是一个新的开源项目,旨在推进软件容器化运动,帮助生
![Moby Project](https://i0.wp.com/blog.docker.com/wp-content/uploads/5-2.png?resize=975%2C548&ssl=1) ![Moby Project](https://i0.wp.com/blog.docker.com/wp-content/uploads/5-2.png?resize=975%2C548&ssl=1)
为了实现这种新的合作高度,今天我们宣布推出软件容器化运动的新开源项目 Moby。它是提供了数十个组件的“乐高”,一个将它们组合成定制容器系统的框架,以及所有容器爱好者进行试验和交换意见的场所。可以把 Moby 认为是容器系统的“乐高俱乐部”。 为了实现这种新的合作高度,今天2017 年 4 月 18 日)我们宣布推出软件容器化运动的新开源项目 Moby。它是提供了数十个组件的“乐高组件”,一个将它们组合成定制容器系统的框架,以及所有容器爱好者进行试验和交换意见的场所。可以把 Moby 认为是容器系统的“乐高俱乐部”。
Moby包括 Moby 包括:
1. 容器化后端组件**库**例如底层构建器、日志记录设备、卷管理、网络、镜像管理、containerd、SwarmKit 等)
1. 容器化后端组件**库**例如低层构建器、日志记录设备、卷管理、网络、镜像管理、containerd、SwarmKit 等)
2. 将组件组合到独立容器平台中的**框架**,以及为这些组件构建、测试和部署构件的工具。 2. 将组件组合到独立容器平台中的**框架**,以及为这些组件构建、测试和部署构件的工具。
3. 一个名为 “Moby Origin” 的引用组件,它是 Docker 容器平台的开放基础,以及使用 Moby 库或其他项目的各种组件的容器系统示例。
3. 一个名为 **Moby Origin** 的引用组件,它是 Docker 容器平台的开放基础,以及使用 Moby 库或其他项目的各种组件的容器系统示例。
Moby 专为系统构建者而设计,他们想要构建自己的基于容器的系统,而不是可以使用 Docker 或其他容器平台的应用程序开发人员。Moby 的参与者可以从源自 Docker 的组件库中进行选择或者可以选择将“自己的组件”BYOC打包为容器以便在所有组件之间进行混合和匹配以创建定制的容器系统。 Moby 专为系统构建者而设计,他们想要构建自己的基于容器的系统,而不是可以使用 Docker 或其他容器平台的应用程序开发人员。Moby 的参与者可以从源自 Docker 的组件库中进行选择或者可以选择将“自己的组件”BYOC打包为容器以便在所有组件之间进行混合和匹配以创建定制的容器系统。
@ -49,9 +47,9 @@ Docker 将 Moby 作为一个开放的研发实验室来试验、开发新的组
via: https://blog.docker.com/2017/04/introducing-the-moby-project/ via: https://blog.docker.com/2017/04/introducing-the-moby-project/
作者:[Solomon Hykes ][a] 作者:[Solomon Hykes][a]
译者:[geekpi](https://github.com/geekpi) 译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID) 校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,67 @@
了解用于 Linux 和 Windows 容器的 Docker “容器主机”与“容器操作系统”
=================
让我们来探讨一下“容器主机”和“容器操作系统”之间的关系,以及它们在 Linux 和 Windows 容器之间的区别。
### 一些定义
* <ruby>容器主机<rt>Container Host</rt></ruby>:也称为<ruby>主机操作系统<rt>Host OS</rt></ruby>。主机操作系统是 Docker 客户端和 Docker 守护程序在其上运行的操作系统。在 Linux 和非 Hyper-V 容器的情况下,主机操作系统与运行中的 Docker 容器共享内核。对于 Hyper-V每个容器都有自己的 Hyper-V 内核。
* <ruby>容器操作系统<rt>Container OS</rt></ruby>:也被称为<ruby>基础操作系统<rt>Base OS</rt></ruby>。基础操作系统是指包含操作系统如 Ubuntu、CentOS 或 windowsservercore 的镜像。通常情况下你将在基础操作系统镜像之上构建自己的镜像以便可以利用该操作系统的部分功能。请注意Windows 容器需要一个基础操作系统,而 Linux 容器不需要。
* <ruby>操作系统内核<rt>Operating System Kernel</rt></ruby>:内核管理诸如内存、文件系统、网络和进程调度等底层功能。
### 如下的一些图
![Linux Containers](http://floydhilton.com/images/2017/03/2017-03-31_14_50_13-Radom%20Learnings,%20Online%20Whiteboard%20for%20Visual%20Collaboration.png)
在上面的例子中:
* 主机操作系统是 Ubuntu。
* Docker 客户端和 Docker 守护进程(一起被称为 Docker 引擎)正在主机操作系统上运行。
* 每个容器共享主机操作系统内核。
* CentOS 和 BusyBox 是 Linux 基础操作系统镜像。
* “No OS” 容器表明你不需要基础操作系统以在 Linux 中运行一个容器。你可以创建一个含有 [scratch][1] 基础镜像的 Docker 文件,然后运行直接使用内核的二进制文件。
* 查看[这篇][2]文章来比较基础 OS 的大小。
![Windows Containers - Non Hyper-V](http://floydhilton.com/images/2017/03/2017-03-31_15_04_03-Radom%20Learnings,%20Online%20Whiteboard%20for%20Visual%20Collaboration.png)
在上面的例子中:
* 主机操作系统是 Windows 10 或 Windows Server。
* 每个容器共享主机操作系统内核。
* 所有 Windows 容器都需要 [nanoserver][3] 或 [windowsservercore][4] 的基础操作系统。
![Windows Containers - Hyper-V](http://floydhilton.com/images/2017/03/2017-03-31_15_41_31-Radom%20Learnings,%20Online%20Whiteboard%20for%20Visual%20Collaboration.png)
在上面的例子中:
* 主机操作系统是 Windows 10 或 Windows Server。
* 每个容器都托管在自己的轻量级 Hyper-V 虚拟机中。
* 每个容器使用 Hyper-V 虚拟机内的内核,它在容器之间提供额外的分离层。
* 所有 Windows 容器都需要 [nanoserver][5] 或 [windowsservercore][6] 的基础操作系统。
### 几个好的链接
* [关于 Windows 容器][7]
* [深入实现 Windows 容器,包括多用户模式和“写时复制”来节省资源][8]
* [Linux 容器如何通过使用“写时复制”来节省资源][9]
--------------------------------------------------------------------------------
via: http://floydhilton.com/docker/2017/03/31/Docker-ContainerHost-vs-ContainerOS-Linux-Windows.html
作者:[Floyd Hilton][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://floydhilton.com/about/
[1]:https://hub.docker.com/_/scratch/
[2]:https://www.brianchristner.io/docker-image-base-os-size-comparison/
[3]:https://hub.docker.com/r/microsoft/nanoserver/
[4]:https://hub.docker.com/r/microsoft/windowsservercore/
[5]:https://hub.docker.com/r/microsoft/nanoserver/
[6]:https://hub.docker.com/r/microsoft/windowsservercore/
[7]:https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/
[8]:http://blog.xebia.com/deep-dive-into-windows-server-containers-and-docker-part-2-underlying-implementation-of-windows-server-containers/
[9]:https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/#the-copy-on-write-strategy

View File

@ -0,0 +1,96 @@
Linux 上的科学图像处理
============================================================
在显示你的数据和工作方面我发现了几个科学软件,但是我不会涉及太多方面。因此在这篇文章中,我将谈到一款叫 ImageJ 的热门图像处理软件。特别的,我会介绍 [Fiji][4],这是一款绑定了一系列用于科学图像处理插件的 ImageJ 软件。
Fiji 这个名字是一个循环缩略词,很像 GNU 。代表着 “Fiji Is Just ImageJ”。 ImageJ 是科学研究领域进行图像分析的实用工具 —— 例如你可以用它来辨认航拍风景图中树的种类。 ImageJ 能划分物品种类。它以插件架构制成,海量插件可供选择以提升使用灵活度。
首先是安装 ImageJ (或 Fiji。大多数的 ImageJ 发行版都可有该软件包。你愿意的话,可以以这种方式安装它,然后根据你的研究安装所需的独立插件。另一种选择是安装 Fiji 的同时获取最常用的插件。不幸的是,大多数 Linux 发行版的软件中心不会有可用的 Fiji 安装包。幸而,官网上的简单安装文件是可以使用的。这是一个 zip 文件,包含了运行 Fiji 需要的所有文件目录。第一次启动时,你只会看到一个列出了菜单项的工具栏。(图 1
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif1.png)
*图 1. 第一次打开 Fiji 有一个最小化的界面。*
如果你没有备好图片来练习使用 ImageJ Fiji 安装包包含了一些示例图片。点击“File”->“Open Samples”的下拉菜单选项图 2。这些示例包含了许多你可能有兴趣做的任务。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif2.jpg)
*图 2. 案例图片可供学习使用 ImageJ。*
如果你安装了 Fiji而不是单纯的 ImageJ ,那么大量插件也会被安装。首先要注意的是自动更新器插件。每次打开 ImageJ ,该插件将联网检验 ImageJ 和已安装插件的更新。
所有已安装的插件都在“插件”菜单项中可选。一旦你安装了很多插件列表会变得冗杂所以需要精简你选择的插件。你想手动更新的话点击“Help”->“Update Fiji” 菜单项强制检测并获取可用更新的列表(图 3
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif3.png)
*图 3. 强制手动检测可用更新。*
那么,现在,用 Fiji/ImageJ 可以做什么呢举一例统计图片中的物品数。你可以通过点击“File”->“Open Samples”->“Embryos”来载入示例。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif4.jpg)
*图 4. 用 ImageJ 算出图中的物品数。*
第一步给图片设定比例,这样你可以告诉 ImageJ 如何判别物品。首先选择在工具栏选择线条按钮。然后选择“Analyze”->“Set Scale”然后就会设置比例尺包含的像素点个数(图 5)。你可以设置“known distance ”为 100单元为“um”。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif5.png)
*图 5. 很多图片分析任务需要对图片设定一个范围。*
接下来的步骤是简化图片内的信息。点击“Image”->“Type”->“8-bit”来减少信息量到 8 比特灰度图片。要分隔独立物体点击“Process”->“Binary”->“Make Binary”以自动设置图片门限。(图 6)。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif6.png)
*图 6. 有些工具可以自动完成像门限一样的任务。*
图片内的物品计数前你需要移除像比例尺之类的人工操作。可以用矩形选择工具来选中它并点击“Edit”->“Clear”来完成这项操作。现在你可以分析图片看看这里是啥物体。
确保图中没有区域被选中点击“Analyze”->“Analyze Particles”来弹出窗口来选择最小尺寸这决定了最后的图片会展示什么图 7
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif7.png)
*图 7. 你可以通过确定最小尺寸生成一个缩减过的图片。 *
图 8 在总结窗口展示了一个概览。每个最小点也有独立的细节窗口。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif8.png)
*图 8. 包含了已知最小点总览清单的输出结果。*
当你有一个分析程序可以工作于给定图片类型,你通常需要将相同的步骤应用到一系列图片当中。这可能数以千计,你当然不会想对每张图片手动重复操作。这时候,你可以集中必要步骤到宏,这样它们可以被应用多次。点击插件->“Macros”->“Record”弹出一个新的窗口记录你随后的所有命令。所有步骤完成你可以将之保存为一个宏文件并且通过点击“Plugins”->“Macros”->“Run”来在其它图片上重复运行。
如果你有非常特定的工作步骤,你可以简单地打开宏文件并手动编辑它,因为它是一个简单的文本文件。事实上有一套完整的宏语言可供你更加充分地控制图片处理过程。
然而如果你有真的有非常多的系列图片需要处理这也将是冗长乏味的工作。这种情况下前往“Process”->“Batch”->“Macro”会弹出一个你可以设置批量处理工作的新窗口图 9
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif9.png)
*图 9. 对批量输入的图片用单一命令运行宏。*
这个窗口中你能选择应用哪个宏文件、输入图片所在的源目录和你想写入输出图片的输出目录。也可以设置输出文件格式及通过文件名筛选输入图片中需要使用的。万事具备之后点击窗口下方的的“Process”按钮开始批量操作。
若这是会重复多次的工作你可以点击窗口底部的“Save”按钮保存批量处理到一个文本文件。点击也在窗口底部的“Open”按钮重新加载相同的工作。这个功能可以使得研究中最冗余部分自动化这样你就可以在重点放在实际的科学研究中。
考虑到单单是 ImageJ 主页就有超过 500 个插件和超过 300 种宏可供使用,简短起见,我只能在这篇短文中提出最基本的话题。幸运的是,还有很多专业领域的教程可供使用,项目主页上还有关于 ImageJ 核心的非常棒的文档。如果你觉得这个工具对研究有用,你研究的专业领域也会有很多信息指引你。
--------------------------------------------------------------------------------
作者简介:
Joey Bernard 有物理学和计算机科学的相关背景。这对他在新不伦瑞克大学当计算研究顾问的日常工作大有裨益。他也教计算物理和并行程序规划。
--------------------------------
via: https://www.linuxjournal.com/content/image-processing-linux
作者:[Joey Bernard][a]
译者:[XYenChi](https://github.com/XYenChi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linuxjournal.com/users/joey-bernard
[1]:https://www.linuxjournal.com/tag/science
[2]:https://www.linuxjournal.com/tag/statistics
[3]:https://www.linuxjournal.com/users/joey-bernard
[4]:https://imagej.net/Fiji

View File

@ -0,0 +1,98 @@
用 coredumpctl 更好地记录 bug
===========
![](https://fedoramagazine.org/wp-content/uploads/2017/11/coredump.png-945x400.jpg)
一个不幸的事实是,所有的软件都有 bug一些 bug 会导致系统崩溃。当它出现的时候,它经常会在磁盘上留下一个被称为“<ruby>核心转储<rt>core dump</rt></ruby>”的数据文件。该文件包含有关系统崩溃时的相关数据,可能有助于确定发生崩溃的原因。通常开发者要求提供 “<ruby>回溯<rt>backtrace</rt></ruby>” 形式的数据,以显示导致崩溃的指令流。开发人员可以使用它来修复 bug 以改进系统。如果系统发生了崩溃,以下是如何轻松生成 <ruby>回溯<rt>backtrace</rt></ruby> 的方法。
### 从使用 coredumpctl 开始
大多数 Fedora 系统使用[自动错误报告工具ABRT][2]来自动捕获崩溃文件并记录 bug。但是如果你禁用了此服务或删除了该软件包则此方法可能会有所帮助。
如果你遇到系统崩溃,请首先确保你运行的是最新的软件。更新通常包含修复程序,这些更新通常含有已经发现的会导致严重错误和崩溃的错误的修复。当你更新后,请尝试重现导致错误的情况。
如果崩溃仍然发生,或者你已经在运行最新的软件,那么可以使用有用的 `coredumpctl` 工具。此程序可帮助查找和处理崩溃。要查看系统上所有核心转储列表,请运行以下命令:
```
coredumpctl list
```
如果你看到比预期长的列表,请不要感到惊讶。有时系统组件在后台默默地崩溃,并自行恢复。快速查找今天的转储的简单方法是使用 `-since` 选项:
```
coredumpctl list --since=today
```
“PID” 列包含用于标识转储的进程 ID。请注意这个数字因为你会之后再用到它。或者如果你不想记住它使用下面的命令将它赋值给一个变量
```
MYPID=<PID>
```
要查看关于核心转储的信息,请使用此命令(使用 `$MYPID` 变量或替换 PID 编号):
```
coredumpctl info $MYPID
```
### 安装 debuginfo 包
在核心转储中的数据以及原始代码中的指令之间调试符号转义。这个符号数据可能相当大。与大多数用户运行在 Fedora 系统上的软件包不同,符号以 “debuginfo” 软件包的形式安装。要确定你必须安装哪些 debuginfo 包,请先运行以下命令:
```
coredumpctl gdb $MYPID
```
这可能会在屏幕上显示大量信息。最后一行可能会告诉你使用 `dnf` 安装更多的 debuginfo 软件包。[用 sudo ][3]运行该命令以安装:
```
sudo dnf debuginfo-install <packages...>
```
然后再次尝试 `coredumpctl gdb $MYPID` 命令。**你可能需要重复执行此操作**,因为其他符号会在回溯中展开。
### 捕获回溯
在调试器中运行以下命令以记录信息:
```
set logging file mybacktrace.txt
set logging on
```
你可能会发现关闭分页有帮助。对于长的回溯,这可以节省时间。
```
set pagination off
```
现在运行回溯:
```
thread apply all bt full
```
现在你可以输入 `quit` 来退出调试器。`mybacktrace.txt` 包含可附加到 bug 或问题的追踪信息。或者,如果你正在与某人实时合作,则可以将文本上传到 pastebin。无论哪种方式你现在可以向开发人员提供更多的帮助来解决问题。
---------------------------------
作者简介:
Paul W. Frields
Paul W. Frields 自 1997 年以来一直是 Linux 用户和爱好者,并于 2003 年在 Fedora 发布不久后加入 Fedora。他是 Fedora 项目委员会的创始成员之一,从事文档、网站发布、宣传、工具链开发和维护软件。他于 2008 年 2 月至 2010 年 7 月加入 Red Hat担任 Fedora 项目负责人,现任红帽公司工程部经理。他目前和妻子和两个孩子住在弗吉尼亚州。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/file-better-bugs-coredumpctl/
作者:[Paul W. Frields][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://fedoramagazine.org/author/pfrields/
[1]:https://fedoramagazine.org/file-better-bugs-coredumpctl/
[2]:https://github.com/abrt/abrt
[3]:https://fedoramagazine.org/howto-use-sudo/

View File

@ -0,0 +1,92 @@
如何轻松记住 Linux 命令
=================
![](https://www.maketecheasier.com/assets/uploads/2017/10/rc-feat.jpg)
Linux 新手往往对命令行心存畏惧。部分原因是因为需要记忆大量的命令,毕竟掌握命令是高效使用命令行的前提。
不幸的是,学习这些命令并无捷径,然而在你开始学习命令之初,有些工具还是可以帮到你的。
### history
![Linux Bash History 命令](https://www.maketecheasier.com/assets/uploads/2017/10/rc-bash-history.jpg)
首先要介绍的是命令行工具 `history`,它能帮你记住那些你曾经用过的命令。包括应用最广泛的 Bash 在内的大多数 [Linux shell][1],都会创建一个历史文件来包含那些你输入过的命令。如果你用的是 Bash这个历史文件就是 `/home/<username>/.bash_history`
这个历史文件是纯文本格式的,你可以用任意的文本编辑器打开来浏览和搜索。
### apropos
确实存在一个可以帮你找到其他命令的命令。这个命令就是 `apropos`,它能帮你找出合适的命令来完成你的搜索。比如,假设你需要知道哪个命令可以列出目录的内容,你可以运行下面命令:
```shell
apropos "list directory"
```
![Linux Apropos](https://www.maketecheasier.com/assets/uploads/2017/10/rc-apropos.jpg)
这就搜索出结果了,非常直接。给 “directory” 加上复数后再试一下。
```shell
apropos "list directories"
```
这次没用了。`apropos` 所作的其实就是搜索一系列命令的描述。描述不匹配的命令不会纳入结果中。
还有其他的用法。通过 `-a` 标志,你可以以更灵活的方式来增加搜索关键字。试试这条命令:
```shell
apropos "match pattern"
```
![Linux Apropos -a Flag](https://www.maketecheasier.com/assets/uploads/2017/10/rc-apropos-a.jpg)
你会觉得应该会有一些匹配的内容出现,比如 [grep][2] 对吗? 然而实际上并没有匹配出任何结果。再说一次apropos 只会根据字面内容进行搜索。
现在让我们试着用 `-a` 标志来把单词分割开来。LCTT 译注该选项的意思是“and”即多个关键字都存在但是不需要正好是连在一起的字符串。
```shell
apropos "match" -a "pattern"
```
这一下,你可以看到很多期望的结果了。
`apropos` 是一个很棒的工具,不过你需要留意它的缺陷。
### ZSH
![Linux ZSH Autocomplete](https://www.maketecheasier.com/assets/uploads/2017/10/rc-zsh.jpg)
ZSH 其实并不是用于记忆命令的工具。它其实是一种 shell。你可以用 [ZSH][3] 来替代 Bash 作为你的命令行 shell。ZSH 包含了自动纠错机制,能在你输入命令的时候给你予提示。开启该功能后,它会提示你相近的选择。在 ZSH 中你可以像往常一样使用命令行,同时你还能享受到极度安全的网络以及其他一些非常好用的特性。充分利用 ZSH 的最简单方法就是使用 [Oh-My-ZSH][4]。
### 速记表
最后,也可能是最间的方法就是使用 [速记表][5]。
有很多在线的速记表,比如[这个][6] 可以帮助你快速查询命令。
![linux-commandline-cheatsheet](https://www.maketecheasier.com/assets/uploads/2013/10/linux-commandline-cheatsheet.gif)
为了快速查询,你可以寻找图片格式的速记表,然后将它设置为你的桌面墙纸。
这并不是记忆命令的最好方法,但是这么做可以帮你节省在线搜索遗忘命令的时间。
在学习时依赖这些方法,最终你会发现你会越来越少地使用这些工具。没有人能够记住所有的事情,因此偶尔遗忘掉某些东西或者遇到某些没有见过的东西也很正常。这也是这些工具以及因特网存在的意义。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/remember-linux-commands/
作者:[Nick Congleton][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.maketecheasier.com/author/nickcongleton/
[1]: https://www.maketecheasier.com/alternative-linux-shells/
[2]: https://www.maketecheasier.com/what-is-grep-and-uses/
[3]: https://www.maketecheasier.com/understanding-the-different-shell-in-linux-zsh-shell/
[4]: https://github.com/robbyrussell/oh-my-zsh
[5]: https://www.maketecheasier.com/premium/cheatsheet/linux-command-line/
[6]: https://www.cheatography.com/davechild/cheat-sheets/linux-command-line/

View File

@ -0,0 +1,157 @@
tmate秒级分享你的终端会话
=================
不久前,我们写过一篇关于 [teleconsole](https://www.2daygeek.com/teleconsole-share-terminal-session-instantly-to-anyone-in-seconds/) 的介绍,该工具可用于快速分享终端给任何人(任何你信任的人)。今天我们要聊一聊另一款类似的应用,名叫 `tmate`
`tmate` 有什么用?它可以让你在需要帮助时向你的朋友们求助。
### 什么是 tmate
[tmate](https://tmate.io/) 的意思是 `teammates`,它是 tmux 的一个分支,并且使用相同的配置信息(例如快捷键配置,配色方案等)。它是一个终端多路复用器,同时具有即时分享终端的能力。它允许在单个屏幕中创建并操控多个终端,同时这些终端还能与其他同事分享。
你可以分离会话,让作业在后台运行,然后在想要查看状态时重新连接会话。`tmate` 提供了一个即时配对的方案,让你可以与一个或多个队友共享一个终端。
在屏幕的地步有一个状态栏,显示了当前会话的一些诸如 ssh 命令之类的共享信息。
### tmate 是怎么工作的?
- 运行 `tmate` 时,会通过 `libssh` 在后台创建一个连接到 tmate.io (由 tmate 开发者维护的后台服务器)的 ssh 连接。
- tmate.io 服务器的 ssh 密钥通过 DH 交换进行校验。
- 客户端通过本地 ssh 密钥进行认证。
- 连接创建后,本地 tmux 服务器会生成一个 150 位(不可猜测的随机字符)会话令牌。
- 队友能通过用户提供的 SSH 会话 ID 连接到 tmate.io。
### 使用 tmate 的必备条件
由于 `tmate.io` 服务器需要通过本地 ssh 密钥来认证客户机,因此其中一个必备条件就是生成 SSH 密钥 key。
记住,每个系统都要有自己的 SSH 密钥。
```shell
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/magi/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/magi/.ssh/id_rsa.
Your public key has been saved in /home/magi/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:3ima5FuwKbWyyyNrlR/DeBucoyRfdOtlUmb5D214NC8 magi@magi-VirtualBox
The key's randomart image is:
+---[RSA 2048]----+
| |
| |
| . |
| . . = o |
| *ooS= . + o |
| . =.@*o.o.+ E .|
| =o==B++o = . |
| o.+*o+.. . |
| ..o+o=. |
+----[SHA256]-----+
```
### 如何安装 tmate
`tmate` 已经包含在某些发行版的官方仓库中,可以通过包管理器来安装。
对于 Debian/Ubuntu可以使用 [APT-GET 命令](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/)或者 [APT 命令](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/)to 来安装。
```shell
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:tmate.io/archive
$ sudo apt-get update
$ sudo apt-get install tmate
```
你也可以从官方仓库中安装 tmate。
```shell
$ sudo apt-get install tmate
```
对于 Fedora使用 [DNF 命令](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/) 来安装。
```shell
$ sudo dnf install tmate
```
对于基于 Arch Linux 的系统,使用 []()[Yaourt 命令](https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/)或 []()[Packer 命令](https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/) 来从 AUR 仓库中安装。
```shell
$ yaourt -S tmate
```
```shell
$ packer -S tmate
```
对于 openSUSE使用 [Zypper 命令](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/) 来安装。
```shell
$ sudo zypper in tmate
```
### 如何使用 tmate
成功安装后,打开终端然后输入下面命令,就会打开一个新的会话,在屏幕底部,你能看到 SSH 会话的 ID。
```shell
$ tmate
```
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-1.png)
要注意的是SSH 会话 ID 会在几秒后消失,不过不要紧,你可以通过下面命令获取到这些详细信息。
```shell
$ tmate show-messages
```
`tmate``show-messages` 命令会显示 tmate 的日志信息,其中包含了该 ssh 连接内容。
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-2.png)
现在,分享你的 SSH 会话 ID 给你的朋友或同事从而允许他们观看终端会话。除了 SSH 会话 ID 以外,你也可以分享 web URL。
另外你还可以选择分享的是只读会话还是可读写会话。
### 如何通过 SSH 连接会话
只需要在终端上运行你从朋友那得到的 SSH 终端 ID 就行了。类似下面这样。
```shell
$ ssh session: ssh 3KuRj95sEZRHkpPtc2y6jcokP@sg2.tmate.io
```
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-4.png)
### 如何通过 Web URL 连接会话
打开浏览器然后访问朋友给你的 URL 就行了。像下面这样。
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-3.png)
只需要输入 `exit` 就能退出会话了。
```
[Source System Output]
[exited]
[Remote System Output]
[server exited]
Connection to sg2.tmate.io closed by remote host。
Connection to sg2.tmate.io closed。
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds/
作者:[Magesh Maruthamuthu][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,36 @@
如何归档 GitHub 仓库
====================
如果仓库不再活跃开发或者你不想接受额外的贡献,但这并不意味着你想要删除它。现在可以在 Github 上归档仓库让它变成只读。
[![archived repository banner](https://user-images.githubusercontent.com/7321362/32558403-450458dc-c46a-11e7-96f9-af31d2206acb.png)][1]
归档一个仓库会让它对所有人只读(包括仓库拥有者)。这包括对仓库的编辑、<ruby>问题<rt>issue</rt></ruby><ruby>合并请求<rt>pull request</rt></ruby>PR、标记、里程碑、项目、维基、发布、提交、标签、分支、反馈和评论。谁都不可以在一个归档的仓库上创建新的问题、合并请求或者评论但是你仍可以 fork 仓库——以允许归档的仓库在其它地方继续开发。
要归档一个仓库,进入仓库设置页面并点在这个仓库上点击“<ruby>归档该仓库<rt>Archive this repository</rt></ruby>”。
[![archive repository button](https://user-images.githubusercontent.com/125011/32273119-0fc5571e-bef9-11e7-9909-d137268a1d6d.png)][2]
在归档你的仓库前,确保你已经更改了它的设置并考虑关闭所有的开放问题和合并请求。你还应该更新你的 README 和描述来让它让访问者了解他不再能够对之贡献。
如果你改变了主意想要解除归档你的仓库,在相同的地方点击“<ruby>解除归档该仓库<rt>Unarchive this repository</rt></ruby>”。请注意归档仓库的大多数设置是隐藏的,你需要解除归档才能改变它们。
[![archived labelled repository](https://user-images.githubusercontent.com/125011/32541128-9d67a064-c466-11e7-857e-3834054ba3c9.png)][3]
要了解更多,请查看[这份文档][4]中的归档仓库部分。归档快乐!
--------------------------------------------------------------------------------
via: https://github.com/blog/2460-archiving-repositories
作者:[MikeMcQuaid][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://github.com/MikeMcQuaid
[1]:https://user-images.githubusercontent.com/7321362/32558403-450458dc-c46a-11e7-96f9-af31d2206acb.png
[2]:https://user-images.githubusercontent.com/125011/32273119-0fc5571e-bef9-11e7-9909-d137268a1d6d.png
[3]:https://user-images.githubusercontent.com/125011/32541128-9d67a064-c466-11e7-857e-3834054ba3c9.png
[4]:https://help.github.com/articles/about-archiving-repositories/

View File

@ -0,0 +1,70 @@
Glitch可以让你立即写出有趣的小型网站
============================================================
我刚写了一篇关于 Jupyter Notebooks 的文章,它是一个有趣的交互式写 Python 代码的方式。这让我想起我最近学习了 Glitch这个我同样喜爱我构建了一个小的程序来用于[关闭转发 twitter][2]。因此有了这篇文章!
[Glitch][3] 是一个简单的构建 Javascript web 程序的方式javascript 后端、javascript 前端)。
关于 glitch 有趣的地方有:
1. 你在他们的网站输入 Javascript 代码
2. 只要输入了任何代码,它会自动用你的新代码重载你的网站。你甚至不必保存!它会自动保存。
所以这就像 Heroku但更神奇像这样的编码你输入代码代码立即在公共网络上运行对我而言感觉很**有趣**。
这有点像用 ssh 登录服务器,编辑服务器上的 PHP/HTML 代码,它立即就可用了,而这也是我所喜爱的方式。虽然现在我们有了“更好的部署实践”,而不是“编辑代码,让它立即出现在互联网上”,但我们并不是在谈论严肃的开发实践,而是在讨论编写微型程序的乐趣。
### Glitch 有很棒的示例应用程序
Glitch 似乎是学习编程的好方式!
比如,这有一个太空侵略者游戏(由 [Mary Rose Cook][4] 编写):[https://space-invaders.glitch.me/][5]。我喜欢的是我只需要点击几下。
1. 点击 “remix this”
2. 开始编辑代码使箱子变成橘色而不是黑色
3. 制作我自己太空侵略者游戏!我的在这:[http://julias-space-invaders.glitch.me/][1]。(我只做了很小的更改使其变成橘色,没什么神奇的)
他们有大量的示例程序,你可以从中启动 - 例如[机器人][6]、[游戏][7]等等。
### 实际有用的非常好的程序tweetstorms
我学习 Glitch 的方式是从这个程序开始的:[https://tweetstorms.glitch.me/][8],它会向你展示给定用户的推特云。
比如,你可以在 [https://tweetstorms.glitch.me/sarahmei][10] 看到 [@sarahmei][9] 的推特云(她发布了很多好的 tweetstorm
### 我的 Glitch 程序: 关闭转推
当我了解到 Glitch 的时候,我想关闭在 Twitter 上关注的所有人的转推(我知道可以在 Tweetdeck 中做这件事),而且手动做这件事是一件很痛苦的事 - 我一次只能设置一个人。所以我写了一个 Glitch 程序来为我做!
我喜欢我不必设置一个本地开发环境,我可以直接开始输入然后开始!
Glitch 只支持 Javascript我不是非常了解 Javascript我之前从没写过一个 Node 程序),所以代码不是很好。但是编写它很愉快 - 能够输入并立即看到我的代码运行是令人愉快的。这是我的项目:[https://turn-off-retweets.glitch.me/][11]。
### 就是这些!
使用 Glitch 感觉真的很有趣和民主。通常情况下,如果我想 fork 某人的 Web 项目,并做出更改,我不会这样做 - 我必须 fork找一个托管设置本地开发环境或者 Heroku 或其他,安装依赖项等。我认为像安装 node.js 依赖关系这样的任务在过去很有趣,就像“我正在学习新东西很酷”,但现在我觉得它们很乏味。
所以我喜欢只需点击 “remix this!” 并立即在互联网上能有我的版本。
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2017/11/13/glitch--write-small-web-projects-easily/
作者:[Julia Evans][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://jvns.ca/
[1]:http://julias-space-invaders.glitch.me/
[2]:https://turn-off-retweets.glitch.me/
[3]:https://glitch.com/
[4]:https://maryrosecook.com/
[5]:https://space-invaders.glitch.me/
[6]:https://glitch.com/handy-bots
[7]:https://glitch.com/games
[8]:https://tweetstorms.glitch.me/
[9]:https://twitter.com/sarahmei
[10]:https://tweetstorms.glitch.me/sarahmei
[11]:https://turn-off-retweets.glitch.me/

View File

@ -0,0 +1,47 @@
介绍 GitHub 上的安全警报
====================================
上个月,我们用依赖关系图让你更容易跟踪你代码依赖的的项目,它目前支持 Javascript 和 Ruby。如今超过 75 的 GitHub 项目有依赖,我们正在帮助你做更多的事情,而不只是关注那些重要的项目。在启用依赖关系图后,当我们检测到你的依赖中有漏洞时会通知你,并给出来自 Github 社区中的已知修复。
[![Security Alerts & Suggested Fix](https://user-images.githubusercontent.com/594029/32851987-76c36e4a-c9eb-11e7-98fc-feb39fddaadb.gif)][1]
### 如何开始使用安全警报
无论你的项目时私有还是公有的,安全警报都会为团队中的正确人员提供重要的漏洞信息。
**启用你的依赖图:**
公开仓库将自动启用依赖关系图和安全警报。对于私人仓库,你需要在仓库设置中添加安全警报,或者在 “Insights” 选项卡中允许访问仓库的 “依赖关系图” 部分。
**设置通知选项:**
启用依赖关系图后,管理员将默认收到安全警报。管理员还可以在依赖关系图设置中将团队或个人添加为安全警报的收件人。
**警报响应:**
当我们通知你潜在的漏洞时,我们将突出显示我们建议更新的任何依赖关系。如果存在已知的安全版本,我们将通过机器学习和公开数据选择一个,并将其包含在我们的建议中。
### 漏洞覆盖率
有 [CVE ID][2][国家漏洞数据库][3]公开披露的漏洞)的漏洞将包含在安全警报中。但是,并非所有漏洞都有 CVE ID甚至许多公开披露的漏洞也没有。随着安全数据的增长我们将继续更好地识别漏洞。如需更多帮助来管理安全问题请查看我们的 [GitHub Marketplace 中的安全合作伙伴][4]。
这是使用世界上最大的开源数据集的下一步,可以帮助你保持代码安全并做到最好。依赖关系图和安全警报目前支持 JavaScript 和 Ruby并将在 2018 年提供 Python 支持。
- [了解更多关于安全警报][5]
--------------------------------------------------------------------------------
via: https://github.com/blog/2470-introducing-security-alerts-on-github
作者:[mijuhan][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://github.com/mijuhan
[1]:https://user-images.githubusercontent.com/594029/32851987-76c36e4a-c9eb-11e7-98fc-feb39fddaadb.gif
[2]:https://cve.mitre.org/
[3]:https://nvd.nist.gov/
[4]:https://github.com/marketplace/category/security
[5]:https://help.github.com/articles/about-security-alerts-for-vulnerable-dependencies/

View File

@ -0,0 +1,59 @@
用系统日志了解你的 Linux 系统
============
本文摘自为 Linux 小白(或者非资深桌面用户)传授技巧的系列文章。该系列文章旨在为 LinuxMagazine 发布的第 30 期特别版 “[Linux 入门][2]” (基于 [openSUSE Leap][3] )提供补充说明。
本文作者是 Romeo S.,她是一名基于 PDX 的企业 Linux 专家,专注于为创新企业提供富有伸缩性的解决方案。
Linux 系统日志非常重要。后台运行的程序(通常被称为守护进程或者服务进程)处理了你 Linux 系统中的大部分任务。当这些守护进程工作时,它们将任务的详细信息记录进日志文件中,作为它们做过什么的“历史”信息。这些守护进程的工作内容涵盖从使用原子钟同步时钟到管理网络连接。所有这些都被记录进日志文件,这样当有错误发生时,你可以通过查阅特定的日志文件来看出发生了什么。
![](https://www.suse.com/communities/blog/files/2017/11/markus-spiske-153537-300x450.jpg)
*Photo by Markus Spiske on Unsplash*
在你的 Linux 计算机上有很多不同的日志。历史上,它们一般以纯文本的格式存储到 `/var/log` 目录中。现在依然有很多日志这样做,你可以很方便的使用 `less` 来查看它们。
在新装的 openSUSE Leap 42.3 以及大多数现代操作系统上,重要的日志由 `systemd` 初始化系统存储。 `systemd`这套系统负责启动守护进程,并在系统启动时让计算机做好被使用的准备。由 `systemd` 记录的日志以二进制格式存储,这使得它们消耗的空间更小,更容易被浏览,也更容易被导出成其他各种格式,不过坏处就是你必须使用特定的工具才能查看。好在这个工具已经预安装在你的系统上了:它的名字叫 `journalctl`,而且默认情况下,它会将每个守护进程的所有日志都记录到一个地方。
只需要运行 `journalctl` 命令就能查看你的 `systemd` 日志了。它会用 `less` 分页器显示各种日志。为了让你有个直观的感受, 下面是 `journalctl` 中摘录的一条日志记录:
```
Jul 06 11:53:47 aaathats3as pulseaudio[2216]: [pulseaudio] alsa-util.c: Disabling timer-based scheduling because running inside a VM.
```
这条独立的日志记录以此包含了记录的日期和时间、计算机名、记录日志的进程名、记录日志的进程 PID以及日志内容本身。
若系统中某个程序运行出问题了,则可以查看日志文件并搜索(使用 `/` 加上要搜索的关键字)程序名称。有可能导致该程序出问题的错误会记录到系统日志中。 有时,错误信息会足够详细到让你能够修复该问题。其他时候,你需要在 Web 上搜索解决方案。 Google 就很适合来搜索奇怪的 Linux 问题。不过搜索时请注意你只输入了日志的实际内容,行首的那些信息(日期、主机名、进程 ID) 对搜索来说是无意义的,会干扰搜索结果。
解决方法一般在搜索结果的前几个连接中就会有了。当然,你不能只是无脑得运行从互联网上找到的那些命令:请一定先搞清楚你要做的事情是什么,它的效果会是什么。据说,搜索系统日志中的特定条目要比直接描述该故障通用关键字要有用的多。因为程序出错有很多原因,而且同样的故障表现也可能由多种问题引发的。
比如,系统无法发声的原因有很多,可能是播放器没有插好,也可能是声音系统出故障了,还可能是缺少合适的驱动程序。如果你只是泛泛的描述故障表现,你会找到很多无关的解决方法,而你也会浪费大量的时间。而专门搜索日志文件中的实际内容,你也许会查询出其它人也有相同日志内容的结果。
你可以对比一下图 1 和图 2。
![](https://www.suse.com/communities/blog/files/2017/11/picture1-450x450.png)
图 1 搜索系统的故障表现只会显示泛泛的,不精确的结果。这种搜索通常没什么用。
![](https://www.suse.com/communities/blog/files/2017/11/picture2-450x450.png)
图 2 搜索特定的日志行会显示出精确的,有用的结果。这种搜索通常很有用。
也有一些系统不用 `journalctl` 来记录日志。在桌面系统中最常见的这类日志包括用于记录 openSUSE 包管理器的行为的 `/var/log/zypper.log` 记录系统启动时消息的 `/var/log/boot.log` ,开机时这类消息往往滚动的特别快,根本看不过来;`/var/log/ntp` 用来记录 Network Time Protocol NTP守护进程同步时间时发生的错误。 另一个存放硬件故障信息的地方是 “Kernel Ring Buffer”内核环状缓冲区你可以输入 `demesg -H` 命令来查看(这条命令也会调用 `less` 分页器来查看。“Kernel Ring Buffer” 存储在内存中,因此会在重启电脑后丢失。不过它包含了 Linux 内核中的重要事件,比如新增了硬件、加载了模块,以及奇怪的网络错误.
希望你已经准备好深入了解你的 Linux 系统了! 祝你玩的开心!
--------------------------------------------------------------------------------
via: https://www.suse.com/communities/blog/system-logs-understand-linux-system/
作者:[chabowski]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[1]:https://www.suse.com/communities/blog/author/chabowski/
[2]:http://www.linux-magazine.com/Resources/Special-Editions/30-Getting-Started-with-Linux
[3]:https://en.opensuse.org/Portal:42.3
[4]:http://www.linux-magazine.com/

View File

@ -0,0 +1,81 @@
容器技术和 K8S 的下一站
============================================================
> 想知道容器编排管理和 K8S 的最新展望么?来看看专家怎么说。
![CIO_Big Data Decisions_2](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/CIO_Big%20Data%20Decisions_2.png?itok=Y5zMHxf8 "CIO_Big Data Decisions_2")
如果你想对容器在未来的发展方向有一个整体把握,那么你一定要跟着钱走,看看钱都投在了哪里。当然了,有很多很多的钱正在投入容器的进一步发展。相关研究预计 2020 年容器技术的投入将占有 [27 亿美元][4] 的市场份额。而在 2016 年,容器相关技术投入的总额为 7.62 亿美元,只有 2020 年投入预计的三分之一。巨额投入的背后是一些显而易见的基本因素,包括容器化的迅速增长以及并行化的大趋势。随着容器被大面积推广和使用,容器编排管理也会被理所当然的推广应用起来。
来自 [The new stack][5] 的调研数据表明,容器的推广使用是编排管理被推广的主要的催化剂。根据调研参与者的反馈数据,在已经将容器技术使用到生产环境中的使用者里,有六成使用者正在将 KubernetesK8S编排管理广泛的应用在生产环境中另外百分之十九的人员则表示他们已经处于部署 K8S 的初级阶段。在容器部署初期的使用者当中,虽然只有百分之五的人员表示已经在使用 K8S ,但是百分之五十八的人员表示他们正在计划和准备使用 K8S。总而言之容器和 Kubernetes 的关系就好比是鸡和蛋一样,相辅相成紧密关联。众多专家一致认为编排管理工具对容器的[长周期管理][6] 以及其在市场中的发展有至关重要的作用。正如 [Cockroach 实验室][7] 的 Alex Robinson 所说,容器编排管理被更广泛的拓展和应用是一个总体的大趋势。毫无疑问,这是一个正在快速演变的领域,且未来潜力无穷。鉴于此,我们对 Robinson 和其他的一些容器的实际使用和推介者做了采访,来从他们作为容器技术的践行者的视角上展望一下容器编排以及 K8S 的下一步发展。
### 容器编排将被主流接受
像任何重要技术的转型一样,我们就像是处在一个高崖之上一般,在经过了初期步履蹒跚的跋涉之后将要来到一望无际的广袤平原。广大的新天地和平实真切的应用需求将会让这种新技术在主流应用中被迅速推广,尤其是在大企业环境中。正如 Alex Robinson 说的那样,容器技术的淘金阶段已经过去,早期的技术革新创新正在减速,随之而来的则是市场对容器技术的稳定性和可用性的强烈需求。这意味着未来我们将不会再见到大量的新的编排管理系统的涌现,而是会看到容器技术方面更多的安全解决方案,更丰富的管理工具,以及基于目前主流容器编排系统的更多的新特性。
### 更好的易用性
人们将在简化容器的部署方面下大功夫,因为容器部署的初期工作对很多公司和组织来说还是比较复杂的,尤其是容器的[长期管理维护][8]更是需要投入大量的精力。正如 [Codemill AB][9] 公司的 My Karlsson 所说,容器编排技术还是太复杂了,这导致很多使用者难以娴熟驾驭和充分利用容器编排的功能。很多容器技术的新用户都需要花费很多精力,走很多弯路,才能搭建小规模的或单个的以隔离方式运行的容器系统。这种现象在那些没有针对容器技术设计和优化的应用中更为明显。在简化容器编排管理方面有很多优化可以做,这些优化和改造将会使容器技术更加具有可用性。
### 在混合云以及多云技术方面会有更多侧重
随着容器和容器编排技术被越来越多的使用,更多的组织机构会选择扩展他们现有的容器技术的部署,从之前的把非重要系统部署在单一环境的使用情景逐渐过渡到更加[复杂的使用情景][10]。对很多公司来说,这意味着他们必须开始学会在 [混合云][11] 和 [多云][12] 的环境下,全局化的去管理那些容器化的应用和微服务。正如红帽 [Openshift 部门产品战略总监][14] [Brian Gracely][13] 所说,“容器和 K8S 技术的使用使得我们成功的实现了混合云以及应用的可移植性。结合 Open Service Broker API 的使用,越来越多的结合私有云和公有云资源的新应用将会涌现出来。”
据 [CloudBees][15] 公司的高级工程师 Carlos Sanchez 分析联合服务Federation将会得到极大推动使一些诸如多地区部署和多云部署等的备受期待的新特性成为可能。
**[ 想知道 CIO 们对混合云和多云的战略构想么? 请参看我们的这条相关资源, [Hybrid Cloud: The IT leader's guide][16]。 ]**
### 平台和工具的持续整合及加强
对任何一种科技来说,持续的整合和加强从来都是大势所趋;容器编排管理技术在这方面也不例外。来自 [Sumo Logic][17] 的首席分析师 Ben Newton 表示,随着容器化渐成主流,软件工程师们正在很少数的一些技术上做持续整合加固的工作,来满足他们的一些微应用的需求。容器和 K8S 将会毫无疑问的成为容器编排管理方面的主流平台,并轻松碾压其它的一些小众平台方案。因为 K8S 提供了一个相当清晰的可以摆脱各种特有云生态的途径K8S 将被大量公司使用,逐渐形成一个不依赖于某个特定云服务的<ruby>“中立云”<rt>cloud-neutral</rt></ruby>
### K8S 的下一站
来自 [Alcide][18] 的 CTO 和联合创始人 Gadi Naor 表示K8S 将会是一个有长期和远景发展的技术,虽然我们的社区正在大力推广和发展 K8SK8S 仍有很长的路要走。
专家们对[日益流行的 K8S 平台][19]也作出了以下一些预测:
**_来自 Alcide 的 Gadi Naor 表示_** “运营商会持续演进并趋于成熟,直到在 K8S 上运行的应用可以完全自治。利用 [OpenTracing][20] 和诸如 [istio][21] 技术的 service mesh 架构,在 K8S 上部署和监控微应用将会带来很多新的可能性。”
**_来自 Red Hat 的 Brian Gracely 表示_** “K8S 所支持的应用的种类越来越多。今后在 K8S 上,你不仅可以运行传统的应用程序,还可以运行原生的云应用、大数据应用以及 HPC 或者基于 GPU 运算的应用程序,这将为灵活的架构设计带来无限可能。”
**_来自 Sumo Logic 的 Ben Newton 表示_** “随着 K8S 成为一个具有统治地位的平台,我预计更多的操作机制将会被统一化,尤其是 K8S 将和第三方管理和监控平台融合起来。”
**_来自 CloudBees 的 Carlos Sanchez 表示_** “在不久的将来我们就能看到不依赖于 Docker 而使用其它运行时环境的系统,这将会有助于消除任何可能的 lock-in 情景“ [编辑提示:[CRI-O][22] 就是一个可以借鉴的例子。]“而且我期待将来会出现更多的针对企业环境的存储服务新特性,包括数据快照以及在线的磁盘容量的扩展。”
**_来自 Cockroach Labs 的 Alex Robinson 表示_** “ K8S 社区正在讨论的一个重大发展议题就是加强对[有状态程序][23]的管理。目前在 K8S 平台下,实现状态管理仍然非常困难,除非你所使用的云服务商可以提供远程固定磁盘。现阶段也有很多人在多方面试图改善这个状况,包括在 K8S 平台内部以及在外部服务商一端做出的一些改进。”
-------------------------------------------------------------------------------
via: https://enterprisersproject.com/article/2017/11/containers-and-kubernetes-whats-next
作者:[Kevin Casey][a]
译者:[yunfengHe](https://github.com/yunfengHe)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://enterprisersproject.com/user/kevin-casey
[1]:https://enterprisersproject.com/article/2017/11/kubernetes-numbers-10-compelling-stats
[2]:https://enterprisersproject.com/article/2017/11/how-enterprise-it-uses-kubernetes-tame-container-complexity
[3]:https://enterprisersproject.com/article/2017/11/5-kubernetes-success-tips-start-smart?sc_cid=70160000000h0aXAAQ
[4]:https://451research.com/images/Marketing/press_releases/Application-container-market-will-reach-2-7bn-in-2020_final_graphic.pdf
[5]:https://thenewstack.io/
[6]:https://enterprisersproject.com/article/2017/10/microservices-and-containers-6-management-tips-long-haul
[7]:https://www.cockroachlabs.com/
[8]:https://enterprisersproject.com/article/2017/10/microservices-and-containers-6-management-tips-long-haul
[9]:https://codemill.se/
[10]:https://www.redhat.com/en/challenges/integration?intcmp=701f2000000tjyaAAA
[11]:https://enterprisersproject.com/hybrid-cloud
[12]:https://enterprisersproject.com/article/2017/7/multi-cloud-vs-hybrid-cloud-whats-difference
[13]:https://enterprisersproject.com/user/brian-gracely
[14]:https://www.redhat.com/en
[15]:https://www.cloudbees.com/
[16]:https://enterprisersproject.com/hybrid-cloud?sc_cid=70160000000h0aXAAQ
[17]:https://www.sumologic.com/
[18]:http://alcide.io/
[19]:https://enterprisersproject.com/article/2017/10/how-explain-kubernetes-plain-english
[20]:http://opentracing.io/
[21]:https://istio.io/
[22]:http://cri-o.io/
[23]:https://opensource.com/article/17/2/stateful-applications
[24]:https://enterprisersproject.com/article/2017/11/containers-and-kubernetes-whats-next?rate=PBQHhF4zPRHcq2KybE1bQgMkS2bzmNzcW2RXSVItmw8
[25]:https://enterprisersproject.com/user/kevin-casey

View File

@ -0,0 +1,74 @@
Mark McIntyre与 Fedora 的那些事
===========================
![](https://fedoramagazine.org/wp-content/uploads/2017/11/mock-couch-945w-945x400.jpg)
最近我们采访了 Mark McIntyre谈了他是如何使用 Fedora 系统的。这也是 Fedora 杂志上[系列文章的一部分][2]。该系列简要介绍了 Fedora 用户,以及他们是如何用 Fedora 把事情做好的。如果你想成为采访对象,请通过[反馈表][3]与我们联系。
### Mark McIntyre 是谁?
Mark McIntyre 为极客而生,以 Linux 为乐趣。他说:“我在 13 岁开始编程,当时自学 BASIC 语言,我体会到其中的乐趣,并在乐趣的引导下,一步步成为专业的码农。” Mark 和他的侄女都是披萨饼的死忠粉。“去年秋天,我和我的侄女开始了一个任务,去尝试诺克斯维尔的许多披萨饼连锁店。点击[这里][4]可以了解我们的进展情况。”Mark 也是一名业余的摄影爱好者,并且在 Flickr 上 [发布自己的作品][5]。
![](https://fedoramagazine.org/wp-content/uploads/2017/11/31456893222_553b3cac4d_k-1024x575.jpg)
作为一名开发者Mark 有着丰富的工作背景。他用过 Visual Basic 编写应用程序,用过 LotusScript、 PL/SQLOracle、 Tcl/TK 编写代码,也用过基于 Python 的 Django 框架。他的强项是 Python。这也是目前他作为系统工程师的工作语言。“我经常使用 Python。由于我的工作变得更像是自动化工程师 Python 用得就更频繁了。”
McIntyre 自称是个书呆子,喜欢科幻电影,但他最喜欢的一部电影却不是科幻片。“尽管我是个书呆子,喜欢看《<ruby>星际迷航<rt>Star Trek</rt></ruby>》、《<ruby>星球大战<rt>Star Wars</rt></ruby>》之类的影片,但《<ruby>光荣战役<rt>Glory</rt></ruby>》或许才是我最喜欢的电影。”他还提到,电影《<ruby>冲出宁静号<rt>Serenity</rt></ruby>》是一个著名电视剧的精彩后续(指《萤火虫》)。
Mark 比较看重他人的谦逊、知识与和气。他欣赏能够设身处地为他人着想的人。“如果你决定为另一个人服务,那么你会选择自己愿意亲近的人,而不是让自己备受折磨的人。”
McIntyre 目前在 [Scripps Networks Interactive][6] 工作,这家公司是 HGTV、Food Network、Travel Channel、DIY、GAC 以及其他几个有线电视频道的母公司。“我现在是一名系统工程师负责非线性视频内容这是所有媒体要开展线上消费所需要的。”他为一些开发团队提供支持他们编写应用程序将线性视频从有线电视发布到线上平台比如亚马逊、葫芦。这些系统既包含预置系统也包含云系统。Mark 还开发了一些自动化工具,将这些应用程序主要部署到云基础结构中。
### Fedora 社区
Mark 形容 Fedora 社区是一个富有活力的社区,充满着像 Fedora 用户一样热爱生活的人。“从设计师到封包人,这个团体依然非常活跃,生机勃勃。” 他继续说道:“这使我对该操作系统抱有一种信心。”
2002 年左右Mark 开始经常使用 IRC 上的 #fedora 频道“那时候Wi-Fi 在启用适配器和配置模块功能时,有许多还是靠手工实现的。”为了让他的 Wi-Fi 能够工作,他不得不重新去编译 Fedora 内核。
McIntyre 鼓励他人参与 Fedora 社区。“这里有许多来自不同领域的机会。前端设计、测试部署、开发、应用程序打包以及新技术实现。”他建议选择一个感兴趣的领域,然后向那个团体提出疑问。“这里有许多机会去奉献自己。”
对于帮助他起步的社区成员Mark 赞道“Ben Williams 非常乐于助人。在我第一次接触 Fedora 时,他帮我搞定了一些 #fedora 支持频道中的安装补丁。” Ben 也鼓励 Mark 去做 Fedora [大使][7]。
### 什么样的硬件和软件?
McIntyre 将 Fedora Linux 系统用在他的笔记本和台式机上。在服务器上他选择了 CentOS因为它有更长的生命周期支持。他现在的台式机是自己组装的配有 Intel 酷睿 i5 处理器32GB 的内存和2TB 的硬盘。“我装了个 4K 的显示屏,有足够大的地方来同时查看所有的应用。”他目前工作用的笔记本是戴尔灵越二合一,配备 13 英寸的屏16 GB 的内存和 525 GB 的 m.2 固态硬盘。
![](https://fedoramagazine.org/wp-content/uploads/2017/11/Screenshot-from-2017-10-26-08-51-41-1024x640.png)
Mark 现在将 Fedora 26 运行在他过去几个月装配的所有机器中。当一个新版本正式发布的时候,他倾向于避开这个高峰期。“除非在它即将发行的时候,我的工作站中有个正在运行下一代测试版本,通常情况下,一旦它发展成熟,我都会试着去获取最新的版本。”他经常采取就地更新:“这种就地更新方法利用 dnf 系统升级插件,目前表现得非常好。”
为了搞摄影McIntyre 用上了 [GIMP][8]、[Darktable][9],以及其他一些照片查看包和快速编辑包。当不用 Web 电子邮件时Mark 会使用 [Geary][10],还有[GNOME Calendar][11]。Mark 选用 HexChat 作为 IRC 客户端,[HexChat][12] 与在 Fedora 服务器实例上运行的 [ZNC bouncer][13] 联机。他的部门通过 Slave 进行沟通交流。
“我从来都不是 IDE 粉,所以大多数的编辑任务都是在 [vim][14] 上完成的。”Mark 偶尔也会打开一个简单的文本编辑器,如 [gedit][15],或者 [xed][16]。他用 [GPaste][17] 做复制和粘贴工作。“对于终端的选择,我已经变成 [Tilix][18] 的忠粉。”McIntyre 通过 [Rhythmbox][19] 来管理他喜欢的播客,并用 [Epiphany][20] 实现快速网络查询。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/mark-mcintyre-fedora/
作者:[Charles Profitt][a]
译者:[zrszrszrs](https://github.com/zrszrszrs)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://fedoramagazine.org/author/cprofitt/
[1]:https://fedoramagazine.org/mark-mcintyre-fedora/
[2]:https://fedoramagazine.org/tag/how-do-you-fedora/
[3]:https://fedoramagazine.org/submit-an-idea-or-tip/
[4]:https://knox-pizza-quest.blogspot.com/
[5]:https://www.flickr.com/photos/mockgeek/
[6]:http://www.scrippsnetworksinteractive.com/
[7]:https://fedoraproject.org/wiki/Ambassadors
[8]:https://www.gimp.org/
[9]:http://www.darktable.org/
[10]:https://wiki.gnome.org/Apps/Geary
[11]:https://wiki.gnome.org/Apps/Calendar
[12]:https://hexchat.github.io/
[13]:https://wiki.znc.in/ZNC
[14]:http://www.vim.org/
[15]:https://wiki.gnome.org/Apps/Gedit
[16]:https://github.com/linuxmint/xed
[17]:https://github.com/Keruspe/GPaste
[18]:https://fedoramagazine.org/try-tilix-new-terminal-emulator-fedora/
[19]:https://wiki.gnome.org/Apps/Rhythmbox
[20]:https://wiki.gnome.org/Apps/Web

View File

@ -0,0 +1,73 @@
LibreOffice 上架 Flathub 应用商店
===============
![LibreOffice on Flathub](http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/libroffice-on-flathub-750x250.jpeg)
> LibreOffice 现在可以从集中化的 Flatpak 应用商店 [Flathub][3] 进行安装。
它的到来使任何运行现代 Linux 发行版的人都能只点击一两次即可安装 LibreOffice 的最新稳定版本,而无需搜索 PPA纠缠于 tar 包或等待发行版将其打包。
自去年 8 月份 [LibreOffice 5.2][6] 发布以来,[LibreOffice Flatpak][5] 已经可供用户下载和安装。
这里“新”的是指发行方法。<ruby>文档基金会<rt>Document Foundation</rt></ruby>选择使用 Flathub 而不是专门的服务器来发布更新。
这对于终端用户来说是一个_很好_的消息因为这意味着不需要在新安装时担心仓库但对于 Flatpak 的倡议者来说也是一个好消息LibreOffice 是开源软件里最流行的生产力套件。它对该格式和应用商店的支持肯定会受到热烈的欢迎。
在撰写本文时,你可以从 Flathub 安装 LibreOffice 5.4.2。新的稳定版本将在发布时添加。
### 在 Ubuntu 上启用 Flathub
要在 Ubuntu 上启动并运行 Flatpak首先必须安装它
```
sudo apt install flatpak gnome-software-plugin-flatpak
```
为了能够从 Flathub 安装应用程序,你需要添加 Flathub 远程服务器:
```
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
```
这就行了。只需注销并重新登录(以便 Ubuntu Software 刷新其缓存),之后你应该能够通过 Ubuntu Software 看到 Flathub 上的任何 Flatpak 程序了。
![](http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/flathub-750x495.png)
*Fedora、Arch 和 Linux Mint 18.3 用户已经安装了 Flatpak随时可以开箱即用。Mint 甚至预启用了 Flathub remote。*
在本例中,搜索 “LibreOffice” 并在结果中找到下面有 Flathub 提示的结果。请记住Ubuntu 已经调整了客户端,来将 Snap 程序显示在最上面,所以你可能需要向下滚动列表来查看它)。
### 从 Flathub 安装 LibreOffice
- [从 Flathub 安装 LibreOffice][7]
从 flatpakref 中[安装 Flatpak 程序有一个 bug][8],所以如果上面的方法不起作用,你也可以使用命令行从 Flathub 中安装 Flathub 程序。
Flathub 网站列出了安装每个程序所需的命令。切换到“命令行”选项卡来查看它们。
### Flathub 上更多的应用
如果你经常看这个网站,你就会知道我喜欢 Flathub。这是我最喜欢的一些应用Corebird、Parlatype、GNOME MPV、Peek、Audacity、GIMP 等)的家园。我无需等待就能获得这些应用程序的最新、稳定版本(加上它们需要的所有依赖)。
而且,在我 twiiter 上发布一周左右后,大多数 Flatpak 应用现在看起来有很棒 GTK 主题 - 不再需要[临时方案][9]了!
--------------------------------------------------------------------------------
via: http://www.omgubuntu.co.uk/2017/11/libreoffice-now-available-flathub-flatpak-app-store
作者:[JOEY SNEDDON][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://plus.google.com/117485690627814051450/?rel=author
[1]:https://plus.google.com/117485690627814051450/?rel=author
[2]:http://www.omgubuntu.co.uk/category/news
[3]:http://www.flathub.org/
[4]:http://www.omgubuntu.co.uk/2017/11/libreoffice-now-available-flathub-flatpak-app-store
[5]:http://www.omgubuntu.co.uk/2016/08/libreoffice-5-2-released-whats-new
[6]:http://www.omgubuntu.co.uk/2016/08/libreoffice-5-2-released-whats-new
[7]:https://flathub.org/repo/appstream/org.libreoffice.LibreOffice.flatpakref
[8]:https://bugs.launchpad.net/ubuntu/+source/gnome-software/+bug/1716409
[9]:http://www.omgubuntu.co.uk/2017/05/flatpak-theme-issue-fix

View File

@ -0,0 +1,75 @@
如何在 Linux 下安装安卓文件传输助手
===============
如果你尝试在 Ubuntu 下连接你的安卓手机,你也许可以试试 Linux 下的安卓文件传输助手。
本质上来说,这个应用是谷歌 macOS 版本的一个克隆。它是用 Qt 编写的,用户界面非常简洁,使得你能轻松在 Ubuntu 和安卓手机之间传输文件和文件夹。
现在,有可能一部分人想知道有什么是这个应用可以做,而 NautilusUbuntu 默认的文件资源管理器)不能做的,答案是没有。
当我将我的 Nexus 5X记得选择 [媒体传输协议 MTP][7] 选项)连接在 Ubuntu 上时,在 [GVfs][8]LCTT 译注: GNOME 桌面下的虚拟文件系统)的帮助下,我可以打开、浏览和管理我的手机,就像它是一个普通的 U 盘一样。
[![Nautilus MTP integration with a Nexus 5X](http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/browsing-android-mtp-nautilus.jpg)][9]
但是*一些*用户在使用默认的文件管理器时,在 MTP 的某些功能上会出现问题:比如文件夹没有正确加载,创建新文件夹后此文件夹不存在,或者无法在媒体播放器中使用自己的手机。
这就是要为 Linux 系统用户设计一个安卓文件传输助手应用的原因,将这个应用当做将 MTP 设备安装在 Linux 下的另一种选择。如果你使用 Linux 下的默认应用时一切正常,你也许并不需要尝试使用它 (除非你真的很想尝试新鲜事物)。
![Android File Transfer Linux App](http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/android-file-transfer-for-linux-750x662.jpg)
该 app 特点:
*   简洁直观的用户界面
*   支持文件拖放功能(从 Linux 系统到手机)
*   支持批量下载 (从手机到 Linux系统)
*   显示传输进程对话框
*   FUSE 模块支持
*   没有文件大小限制
*   可选命令行工具
### Ubuntu 下安装安卓手机文件助手的步骤
以上就是对这个应用的介绍,下面是如何安装它的具体步骤。
这有一个 [PPA](个人软件包集)源为 Ubuntu 14.04 LTS、16.04 LTS 和 Ubuntu 17.10 提供可用应用。
为了将这一 PPA 加入你的软件资源列表中,执行这条命令:
```
sudo add-apt-repository ppa:samoilov-lex/aftl-stable
```
接着,为了在 Ubuntu 下安装 Linux版本的安卓文件传输助手执行
```
sudo apt-get update && sudo apt install android-file-transfer
```
这样就行了。
你会在你的应用列表中发现这一应用的启动图标。
在你启动这一应用之前,要确保没有其他应用(比如 Nautilus已经挂载了你的手机。如果其它应用正在使用你的手机就会显示“无法找到 MTP 设备”。要解决这一问题,将你的手机从 Nautilus或者任何正在使用你的手机的应用上移除然后再重新启动安卓文件传输助手。
--------------------------------------------------------------------------------
via: http://www.omgubuntu.co.uk/2017/11/android-file-transfer-app-linux
作者:[JOEY SNEDDON][a]
译者:[wenwensnow](https://github.com/wenwensnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://plus.google.com/117485690627814051450/?rel=author
[1]:https://plus.google.com/117485690627814051450/?rel=author
[2]:http://www.omgubuntu.co.uk/category/app
[3]:http://www.omgubuntu.co.uk/category/download
[4]:https://github.com/whoozle/android-file-transfer-linux
[5]:http://www.omgubuntu.co.uk/2017/11/android-file-transfer-app-linux
[6]:http://android.com/filetransfer?linkid=14270770
[7]:https://en.wikipedia.org/wiki/Media_Transfer_Protocol
[8]:https://en.wikipedia.org/wiki/GVfs
[9]:http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/browsing-android-mtp-nautilus.jpg
[10]:https://launchpad.net/~samoilov-lex/+archive/ubuntu/aftl-stable

View File

@ -0,0 +1,72 @@
开源云技能认证:系统管理员的核心竞争力
=========
![os jobs](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/open-house-sysadmin.jpg?itok=i5FHc3lu "os jobs")
> [2017年开源工作报告][1](以下简称“报告”)显示,具有开源云技术认证的系统管理员往往能获得更高的薪酬。
报告调查的受访者中53% 认为系统管理员是雇主们最期望被填补的职位空缺之一,因此,技术娴熟的系统管理员更受青睐而收获高薪职位,但这一职位,并没想象中那么容易填补。
系统管理员主要负责服务器和其他电脑操作系统的安装、服务支持和维护,及时处理服务中断和预防其他问题的出现。
总的来说今年的报告指出开源领域人才需求最大的有开源云47%应用开发44%大数据43%开发运营和安全42%)。
此外报告对人事经理的调查显示58% 期望招揽更多的开源人才67% 认为开源人才的需求增长会比业内其他领域更甚。有些单位视开源人才为招聘最优选则,它们招聘的开源人才较上年增长了 2 个百分点。
同时89% 的人事经理认为很难找到颇具天赋的开源人才。
### 为什么要获取认证
报告显示,对系统管理员的需求刺激着人事经理为 53% 的组织/机构提供正规的培训和专业技术认证,而这一比例去年为 47%。
对系统管理方面感兴趣的 IT 人才考虑获取 Linux 认证已成为行业规律。随便查看几个知名的招聘网站,你就能发现:[CompTIA Linux+][3] 认证是入门级 Linux 系统管理员的最高认证;如果想胜任高级别的系统管理员职位,获取[红帽认证工程师RHCE][4]和[红帽认证系统管理员RHCSA][5]则是不可或缺的。
戴士Dice[2017 技术行业薪资调查][6]显示2016 年系统管理员的薪水为 79,538 美元,较上年下降了 0.8%;系统架构师的薪水为 125,946 美元,同比下降 4.7%。尽管如此,该调查发现“高水平专业人才仍最受欢迎,特别是那些精通支持产业转型发展所需技术的人才”。
在开源技术方面HBase一个开源的分布式数据库技术人才的薪水在戴士 2017 技术行业薪资调查中排第一。在计算机网络和数据库领域,掌握 OpenVMS 操作系统技术也能获得高薪。
### 成为出色的系统管理员
出色的系统管理员须在问题出现时马上处理,这意味着你必须时刻准备应对可能出现的状况。这个职位追求“零责备的、精益的、流程或技术上交互式改进的”思维方式和善于自我完善的人格,成为一个系统管理员意味着“你必将与开源软件如 Linux、BSD 甚至开源 Solaris 等结下不解之缘”Paul English ^译注1 在 [opensource.com][7] 上发文指出。
Paul English 认为,现在的系统管理员较以前而言,要更多地与软件打交道,而且要能够编写脚本来协助系统管理。
>译注1Paul English计算机科学学士UNIX/Linux 系统管理员PreOS Security Inc. 公司 CEO2015-2017 年于为推动系统管理员发展实践的非盈利组织——<ruby>专业系统管理员联盟<rt>League of Professional System Administrator</rt></ruby>担任董事会成员。
### 展望 2018
[Robert Half 2018 年技术人才薪资导览][8]预测 2018 年北美地区许多单位将聘用大量系统管理方面的专业人才,同时个人软实力和领导力水平作为优秀人才的考量因素,越来越受到重视。
该报告指出:“良好的聆听能力和批判性思维能力对于理解和解决用户的问题和担忧至关重要,也是 IT 从业者必须具备的重要技能,特别是从事服务台和桌面支持工作相关的技术人员。”
这与[Linux基金会][9]^译注2 提出的不同阶段的系统管理员必备技能相一致,都强调了强大的分析能力和快速处理问题的能力。
>译注2<ruby>Linux 基金会<rt>The Linux Foundation</rt></ruby>,成立于 2000 年,致力于围绕开源项目构建可持续发展的生态系统,以加速开源项目的技术开发和商业应用;它是世界上最大的开源非盈利组织,在推广、保护和推进 Linux 发展,协同开发,维护“历史上最大的共享资源”上功勋卓越。
如果想逐渐爬上系统管理员职位的金字塔上层,还应该对系统配置的结构化方法充满兴趣;且拥有解决系统安全问题的经验;用户身份验证管理的经验;与非技术人员进行非技术交流的能力;以及优化系统以满足最新的安全需求的能力。
- [下载][10]2017年开源工作报告全文以获取更多信息。
-----------------------
via: https://www.linux.com/blog/open-source-cloud-skills-and-certification-are-key-sysadmins
作者:[linux.com][a]
译者:[wangy325](https://github.com/wangy325)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/blog/open-source-cloud-skills-and-certification-are-key-sysadmins
[1]:https://www.linuxfoundation.org/blog/2017-jobs-report-highlights-demand-open-source-skills/
[2]:https://www.linux.com/licenses/category/creative-commons-zero
[3]:https://certification.comptia.org/certifications/linux?tracking=getCertified/certifications/linux.aspx
[4]:https://www.redhat.com/en/services/certification/rhce
[5]:https://www.redhat.com/en/services/certification/rhcsa
[6]:http://marketing.dice.com/pdf/Dice_TechSalarySurvey_2017.pdf?aliId=105832232
[7]:https://opensource.com/article/17/7/truth-about-sysadmins
[8]:https://www.roberthalf.com/salary-guide/technology
[9]:https://www.linux.com/learn/10-essential-skills-novice-junior-and-senior-sysadmins%20%20
[10]:http://bit.ly/2017OSSjobsreport

View File

@ -0,0 +1,134 @@
Photon 也许能成为你最喜爱的容器操作系统
============================================================
![Photon OS](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/photon-linux.jpg?itok=jUFHPR_c "Photon OS")
>Phonton OS 专注于容器,是一个非常出色的平台。 —— Jack Wallen
容器在当下的火热,并不是没有原因的。正如[之前][13]讨论的,容器可以使您轻松快捷地将新的服务与应用部署到您的网络上,而且并不耗费太多的系统资源。比起专用硬件和虚拟机,容器都是更加划算的,除此之外,他们更容易更新与重用。
更重要的是,容器喜欢 Linux反之亦然。不需要太多时间和麻烦你就可以启动一台 Linux 服务器,运行[Docker][14],然后部署容器。但是,哪种 Linux 发行版最适合部署容器呢?我们的选择很多。你可以使用标准的 Ubuntu 服务器平台(更容易安装 Docker 并部署容器)或者是更轻量级的发行版 —— 专门用于部署容器。
[Photon][15] 就是这样的一个发行版。这个特殊的版本是由 [VMware][16] 于 2005 年创建的,它包含了 Docker 的守护进程,并可与容器框架(如 Mesos 和 Kubernetes 一起使用。Photon 经过优化可与 [VMware vSphere][17] 协同工作,而且可用于裸机、[Microsoft Azure][18]、 [Google Compute Engine][19]、 [Amazon Elastic Compute Cloud][20] 或者 [VirtualBox][21] 等。
Photon 通过只安装 Docker 守护进程所必需的东西来保持它的轻量。而这样做的结果是,这个发行版的大小大约只有 300MB。但这足以让 Linux 的运行一切正常。除此之外Photon 的主要特点还有:
* 内核为性能而调整。
* 内核根据[内核自防护项目][6]KSPP进行了加固。
* 所有安装的软件包都根据加固的安全标识来构建。
* 操作系统在信任验证后启动。
* Photon 的管理进程可以管理防火墙、网络、软件包,和远程登录在 Photon 机器上的用户。
* 支持持久卷。
* [Project Lightwave][7] 整合。
* 及时的安全补丁与更新。
Photon 可以通过 [ISO 镜像][22]、[OVA][23]、[Amazon Machine Image][24]、[Google Compute Engine 镜像][25] 和 [Azure VHD][26] 安装使用。现在我将向您展示如何使用 ISO 镜像在 VirtualBox 上安装 Photon。整个安装过程大概需要五分钟在最后您将有一台随时可以部署容器的虚拟机。
### 创建虚拟机
在部署第一台容器之前,您必须先创建一台虚拟机并安装 Photon。为此打开 VirtualBox 并点击“新建”按钮。跟着创建虚拟机向导进行配置(根据您的容器将需要的用途,为 Photon 提供必要的资源)。在创建好虚拟机后,您所需要做的第一件事就是更改配置。选择新建的虚拟机(在 VirtualBox 主窗口的左侧面板中),然后单击“设置”。在弹出的窗口中,点击“网络”(在左侧的导航中)。
在“网络”窗口图1你需要在“连接”的下拉窗口中选择桥接。这可以确保您的 Photon 服务与您的网络相连。完成更改后,单击确定。
![change settings](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/photon_0.jpg?itok=Q0yhOhsZ "change setatings")
*图 1 更改 Photon 在 VirtualBox 中的网络设置。[经许可使用][1]*
从左侧的导航选择您的 Photon 虚拟机,点击启动。系统会提示您去加载 ISO 镜像。当您完成之后Photon 安装程序将会启动并提示您按回车后开始安装。安装过程基于 ncurses没有 GUI但它非常简单。
接下来图2系统会询问您是要最小化安装完整安装还是安装 OSTree 服务器。我选择了完整安装。选择您所需要的任意选项,然后按回车继续。
![installation type](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/photon_2.jpg?itok=QL1Rs-PH "Photon")
*图 2 选择您的安装类型。[经许可使用][2]*
在下一个窗口,选择您要安装 Photon 的磁盘。由于我们将其安装在虚拟机因此只有一块磁盘会被列出图3。选择“自动”按下回车。然后安装程序会让您输入并验证管理员密码。在这之后镜像开始安装在您的磁盘上并在不到 5 分钟的时间内结束。
![Photon](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/photon_1.jpg?itok=OdnMVpaA "installation type")
*图 3 选择安装 Photon 的硬盘。[经许可使用][3]*
安装完成后,重启虚拟机并使用安装时创建的用户 root 和它的密码登录。一切就绪,你准备好开始工作了。
在开始使用 Docker 之前,您需要更新一下 Photon。Photon 使用 `yum` 软件包管理器,因此在以 root 用户登录后输入命令 `yum update`。如果有任何可用更新则会询问您是否确认图4
![Updating](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/photon_3.jpg?itok=vjqrspE2 "Updating")
*图 4 更新 Photon。[经许可使用][4]*
### 用法
正如我所说的Photon 提供了部署容器甚至创建 Kubernetes 集群所需要的所有包。但是,在使用之前还要做一些事情。首先要启动 Docker 守护进程。为此,执行以下命令:
```
systemctl start docker
systemctl enable docker
```
现在我们需要创建一个标准用户,以便我们可以不用 root 去运行 `docker` 命令。为此,执行以下命令:
```
useradd -m USERNAME
passwd USERNAME
```
其中 “USERNAME” 是我们新增的用户的名称。
接下来,我们需要将这个新用户添加到 “docker” 组,执行命令:
```
usermod -a -G docker USERNAME
```
其中 “USERNAME” 是刚刚创建的用户的名称。
注销 root 用户并切换为新增的用户。现在,您已经可以不必使用 `sudo` 命令或者切换到 root 用户来使用 `docker` 命令了。从 Docker Hub 中取出一个镜像开始部署容器吧。
### 一个优秀的容器平台
在专注于容器方面Photon 毫无疑问是一个出色的平台。请注意Photon 是一个开源项目,因此没有任何付费支持。如果您对 Photon 有任何的问题,请移步 Photon 项目的 GitHub 下的 [Issues][27],那里可以供您阅读相关问题,或者提交您的问题。如果您对 Photon 感兴趣,您也可以在该项目的官方 [GitHub][28]中找到源码。
尝试一下 Photon 吧,看看它是否能够使得 Docker 容器和 Kubernetes 集群的部署更加容易。
欲了解 Linux 的更多信息,可以通过学习 Linux 基金会和 edX 的免费课程,[“Linux 入门”][29]。
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2017/11/photon-could-be-your-new-favorite-container-os
作者:[JACK WALLEN][a]
译者:[KeyLD](https://github.com/KeyLd)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/jlwallen
[1]:https://www.linux.com/licenses/category/used-permission
[2]:https://www.linux.com/licenses/category/used-permission
[3]:https://www.linux.com/licenses/category/used-permission
[4]:https://www.linux.com/licenses/category/used-permission
[5]:https://www.linux.com/licenses/category/creative-commons-zero
[6]:https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project
[7]:http://vmware.github.io/lightwave/
[8]:https://www.linux.com/files/images/photon0jpg
[9]:https://www.linux.com/files/images/photon1jpg
[10]:https://www.linux.com/files/images/photon2jpg
[11]:https://www.linux.com/files/images/photon3jpg
[12]:https://www.linux.com/files/images/photon-linuxjpg
[13]:https://www.linux.com/learn/intro-to-linux/2017/11/how-install-and-use-docker-linux
[14]:https://www.docker.com/
[15]:https://vmware.github.io/photon/
[16]:https://www.vmware.com/
[17]:https://www.vmware.com/products/vsphere.html
[18]:https://azure.microsoft.com/
[19]:https://cloud.google.com/compute/
[20]:https://aws.amazon.com/ec2/
[21]:https://www.virtualbox.org/
[22]:https://github.com/vmware/photon/wiki/Downloading-Photon-OS
[23]:https://github.com/vmware/photon/wiki/Downloading-Photon-OS
[24]:https://github.com/vmware/photon/wiki/Downloading-Photon-OS
[25]:https://github.com/vmware/photon/wiki/Downloading-Photon-OS
[26]:https://github.com/vmware/photon/wiki/Downloading-Photon-OS
[27]:https://github.com/vmware/photon/issues
[28]:https://github.com/vmware/photon
[29]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@ -0,0 +1,76 @@
AWS 帮助构建 ONNX 开源 AI 平台
============================================================
![onnx-open-source-ai-platform](https://www.linuxinsider.com/article_images/story_graphics_xlarge/xl-2017-onnx-1.jpg)
AWS 最近成为了加入深度学习社区的<ruby>开放神经网络交换<rt>Open Neural Network Exchange</rt></ruby>ONNX协作的技术公司最近在<ruby>无障碍和可互操作<rt>frictionless and interoperable</rt></ruby>的环境中推出了高级人工智能。由 Facebook 和微软领头了该协作。
作为该合作的一部分AWS 开源其深度学习框架 Python 软件包 ONNX-MXNet该框架提供了跨多种语言的编程接口API包括 Python、Scala 和开源统计软件 R。
AWS 深度学习工程经理 Hagay Lupesko 和软件开发人员 Roshani Nagmote 上周在一篇帖子中写道ONNX 格式将帮助开发人员构建和训练其它框架的模型,包括 PyTorch、Microsoft Cognitive Toolkit 或 Caffe2。它可以让开发人员将这些模型导入 MXNet并运行它们进行推理。
### 对开发者的帮助
今年夏天Facebook 和微软推出了 ONNX以支持共享模式的互操作性来促进 AI 的发展。微软提交了其 Cognitive Toolkit、Caffe2 和 PyTorch 来支持 ONNX。
微软表示Cognitive Toolkit 和其他框架使开发人员更容易构建和运行计算图以表达神经网络。
[ONNX 代码和文档][4]的初始版本已经放到了 Github。
AWS 和微软上个月宣布了在 Apache MXNet 上的一个新 Gluon 接口计划,该计划允许开发人员构建和训练深度学习模型。
[Tractica][5] 的研究总监 Aditya Kaul 观察到“Gluon 是他们试图与 Google 的 Tensorflow 竞争的合作伙伴关系的延伸”。
他告诉 LinuxInsider“谷歌在这点上的疏忽是非常明显的但也说明了他们在市场上的主导地位。”
Kaul 说:“甚至 Tensorflow 也是开源的,所以开源在这里并不是什么大事,但这归结到底是其他生态系统联手与谷歌竞争。”
根据 AWS 的说法本月早些时候Apache MXNet 社区推出了 MXNet 的 0.12 版本,它扩展了 Gluon 的功能,以便进行新的尖端研究。它的新功能之一是变分 dropout它允许开发人员使用 dropout 技术来缓解递归神经网络中的过拟合。
AWS 指出:卷积 RNN、LSTM 网络和门控循环单元GRU允许使用基于时间的序列和空间维度对数据集进行建模。
### 框架中立方式
[Tirias Research][6] 的首席分析师 Paul Teich 说:“这看起来像是一个提供推理的好方法,而不管是什么框架生成的模型。”
他告诉 LinuxInsider“这基本上是一种框架中立的推理方式。”
Teich 指出,像 AWS、微软等云提供商在客户的压力下可以在一个网络上进行训练同时提供另一个网络以推进人工智能。
他说:“我认为这是这些供应商检查互操作性的一种基本方式。”
Tractica 的 Kaul 指出:“框架互操作性是一件好事,这会帮助开发人员确保他们建立在 MXNet 或 Caffe 或 CNTK 上的模型可以互操作。”
至于这种互操作性如何适用于现实世界Teich 指出,诸如自然语言翻译或语音识别等技术将要求将 Alexa 的语音识别技术打包并交付给另一个开发人员的嵌入式环境。
### 感谢开源
[ThinkStrategies][7] 的总经理 Jeff Kaplan 表示:“尽管存在竞争差异,但这些公司都认识到他们在开源运动所带来的软件开发进步方面所取得的巨大成功。”
他告诉 LinuxInsider“开放式神经网络交换ONNX致力于在人工智能方面产生类似的优势和创新。”
越来越多的大型科技公司已经宣布使用开源技术来加快 AI 协作开发的计划,以便创建更加统一的开发和研究平台。
ATT 几周前宣布了与 TechMahindra 和 Linux 基金会合作[推出 Acumos 项目][8]的计划。该平台旨在开拓电信、媒体和技术方面的合作。
--------------------------------------------------------------------------------
via: https://www.linuxinsider.com/story/AWS-to-Help-Build-ONNX-Open-Source-AI-Platform-84971.html
作者:[David Jones][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linuxinsider.com/story/AWS-to-Help-Build-ONNX-Open-Source-AI-Platform-84971.html#searchbyline
[1]:https://www.linuxinsider.com/story/AWS-to-Help-Build-ONNX-Open-Source-AI-Platform-84971.html#
[2]:https://www.linuxinsider.com/perl/mailit/?id=84971
[3]:https://www.linuxinsider.com/story/AWS-to-Help-Build-ONNX-Open-Source-AI-Platform-84971.html
[4]:https://github.com/onnx/onnx
[5]:https://www.tractica.com/
[6]:http://www.tiriasresearch.com/
[7]:http://www.thinkstrategies.com/
[8]:https://www.linuxinsider.com/story/84926.html
[9]:https://www.linuxinsider.com/story/AWS-to-Help-Build-ONNX-Open-Source-AI-Platform-84971.html

View File

@ -0,0 +1,149 @@
如何判断 Linux 服务器是否被入侵?
=========================
本指南中所谓的服务器被入侵或者说被黑了的意思,是指未经授权的人或程序为了自己的目的登录到服务器上去并使用其计算资源,通常会产生不好的影响。
免责声明:若你的服务器被类似 NSA 这样的国家机关或者某个犯罪集团入侵,那么你并不会注意到有任何问题,这些技术也无法发觉他们的存在。
然而,大多数被攻破的服务器都是被类似自动攻击程序这样的程序或者类似“脚本小子”这样的廉价攻击者,以及蠢蛋罪犯所入侵的。
这类攻击者会在访问服务器的同时滥用服务器资源,并且不怎么会采取措施来隐藏他们正在做的事情。
### 被入侵服务器的症状
当服务器被没有经验攻击者或者自动攻击程序入侵了的话,他们往往会消耗 100% 的资源。他们可能消耗 CPU 资源来进行数字货币的采矿或者发送垃圾邮件,也可能消耗带宽来发动 DoS 攻击。
因此出现问题的第一个表现就是服务器 “变慢了”。这可能表现在网站的页面打开的很慢,或者电子邮件要花很长时间才能发送出去。
那么你应该查看那些东西呢?
#### 检查 1 - 当前都有谁在登录?
你首先要查看当前都有谁登录在服务器上。发现攻击者登录到服务器上进行操作并不复杂。
其对应的命令是 `w`。运行 `w` 会输出如下结果:
```
08:32:55 up 98 days, 5:43, 2 users, load average: 0.05, 0.03, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 113.174.161.1 08:26 0.00s 0.03s 0.02s ssh root@coopeaa12
root pts/1 78.31.109.1 08:26 0.00s 0.01s 0.00s w
```
第一个 IP 是英国 IP而第二个 IP 是越南 IP。这个不是个好兆头。
停下来做个深呼吸, 不要恐慌之下只是干掉他们的 SSH 连接。除非你能够防止他们再次进入服务器,否则他们会很快进来并踢掉你,以防你再次回去。
请参阅本文最后的“被入侵之后怎么办”这一章节来看找到了被入侵的证据后应该怎么办。
`whois` 命令可以接一个 IP 地址然后告诉你该 IP 所注册的组织的所有信息,当然就包括所在国家的信息。
#### 检查 2 - 谁曾经登录过?
Linux 服务器会记录下哪些用户,从哪个 IP在什么时候登录的以及登录了多长时间这些信息。使用 `last` 命令可以查看这些信息。
输出类似这样:
```
root pts/1 78.31.109.1 Thu Nov 30 08:26 still logged in
root pts/0 113.174.161.1 Thu Nov 30 08:26 still logged in
root pts/1 78.31.109.1 Thu Nov 30 08:24 - 08:26 (00:01)
root pts/0 113.174.161.1 Wed Nov 29 12:34 - 12:52 (00:18)
root pts/0 14.176.196.1 Mon Nov 27 13:32 - 13:53 (00:21)
```
这里可以看到英国 IP 和越南 IP 交替出现,而且最上面两个 IP 现在还处于登录状态。如果你看到任何未经授权的 IP那么请参阅最后章节。
登录后的历史记录会记录到二进制的 `/var/log/wtmp` 文件中LCTT 译注:这里作者应该写错了,根据实际情况修改),因此很容易被删除。通常攻击者会直接把这个文件删掉,以掩盖他们的攻击行为。 因此, 若你运行了 `last` 命令却只看得见你的当前登录,那么这就是个不妙的信号。
如果没有登录历史的话,请一定小心,继续留意入侵的其他线索。
#### 检查 3 - 回顾命令历史
这个层次的攻击者通常不会注意掩盖命令的历史记录,因此运行 `history` 命令会显示出他们曾经做过的所有事情。
一定留意有没有用 `wget``curl` 命令来下载类似垃圾邮件机器人或者挖矿程序之类的非常规软件。
命令历史存储在 `~/.bash_history` 文件中,因此有些攻击者会删除该文件以掩盖他们的所作所为。跟登录历史一样,若你运行 `history` 命令却没有输出任何东西那就表示历史文件被删掉了。这也是个不妙的信号你需要很小心地检查一下服务器了。LCTT 译注,如果没有命令历史,也有可能是你的配置错误。)
#### 检查 4 - 哪些进程在消耗 CPU
你常遇到的这类攻击者通常不怎么会去掩盖他们做的事情。他们会运行一些特别消耗 CPU 的进程。这就很容易发现这些进程了。只需要运行 `top` 然后看最前的那几个进程就行了。
这也能显示出那些未登录进来的攻击者。比如,可能有人在用未受保护的邮件脚本来发送垃圾邮件。
如果你最上面的进程对不了解,那么你可以 Google 一下进程名称,或者通过 `losf``strace` 来看看它做的事情是什么。
使用这些工具,第一步从 `top` 中拷贝出进程的 PID然后运行
```
strace -p PID
```
这会显示出该进程调用的所有系统调用。它产生的内容会很多,但这些信息能告诉你这个进程在做什么。
```
lsof -p PID
```
这个程序会列出该进程打开的文件。通过查看它访问的文件可以很好的理解它在做的事情。
#### 检查 5 - 检查所有的系统进程
消耗 CPU 不严重的未授权进程可能不会在 `top` 中显露出来,不过它依然可以通过 `ps` 列出来。命令 `ps auxf` 就能显示足够清晰的信息了。
你需要检查一下每个不认识的进程。经常运行 `ps` (这是个好习惯)能帮助你发现奇怪的进程。
#### 检查 6 - 检查进程的网络使用情况
`iftop` 的功能类似 `top`,它会排列显示收发网络数据的进程以及它们的源地址和目的地址。类似 DoS 攻击或垃圾机器人这样的进程很容易显示在列表的最顶端。
#### 检查 7 - 哪些进程在监听网络连接?
通常攻击者会安装一个后门程序专门监听网络端口接受指令。该进程等待期间是不会消耗 CPU 和带宽的,因此也就不容易通过 `top` 之类的命令发现。
`lsof``netstat` 命令都会列出所有的联网进程。我通常会让它们带上下面这些参数:
```
lsof -i
```
```
netstat -plunt
```
你需要留意那些处于 `LISTEN``ESTABLISHED` 状态的进程这些进程要么正在等待连接LISTEN要么已经连接ESTABLISHED。如果遇到不认识的进程使用 `strace``lsof` 来看看它们在做什么东西。
### 被入侵之后该怎么办呢?
首先,不要紧张,尤其当攻击者正处于登录状态时更不能紧张。**你需要在攻击者警觉到你已经发现他之前夺回机器的控制权。**如果他发现你已经发觉到他了,那么他可能会锁死你不让你登陆服务器,然后开始毁尸灭迹。
如果你技术不太好那么就直接关机吧。你可以在服务器上运行 `shutdown -h now` 或者 `systemctl poweroff` 这两条命令之一。也可以登录主机提供商的控制面板中关闭服务器。关机后,你就可以开始配置防火墙或者咨询一下供应商的意见。
如果你对自己颇有自信,而你的主机提供商也有提供上游防火墙,那么你只需要以此创建并启用下面两条规则就行了:
1. 只允许从你的 IP 地址登录 SSH。
2. 封禁除此之外的任何东西,不仅仅是 SSH还包括任何端口上的任何协议。
这样会立即关闭攻击者的 SSH 会话,而只留下你可以访问服务器。
如果你无法访问上游防火墙,那么你就需要在服务器本身创建并启用这些防火墙策略,然后在防火墙规则起效后使用 `kill` 命令关闭攻击者的 SSH 会话。LCTT 译注:本地防火墙规则 有可能不会阻止已经建立的 SSH 会话,所以保险起见,你需要手工杀死该会话。)
最后还有一种方法,如果支持的话,就是通过诸如串行控制台之类的带外连接登录服务器,然后通过 `systemctl stop network.service` 停止网络功能。这会关闭所有服务器上的网络连接,这样你就可以慢慢的配置那些防火墙规则了。
重夺服务器的控制权后,也不要以为就万事大吉了。
不要试着修复这台服务器,然后接着用。你永远不知道攻击者做过什么,因此你也永远无法保证这台服务器还是安全的。
最好的方法就是拷贝出所有的数据然后重装系统。LCTT 译注:你的程序这时已经不可信了,但是数据一般来说没问题。)
--------------------------------------------------------------------------------
via: https://bash-prompt.net/guides/server-hacked/
作者:[Elliot Cooper][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://bash-prompt.net

View File

@ -0,0 +1,41 @@
有人试图挽救 Ubuntu Unity ,将其做为官方分支
============================================================
> Ubuntu Unity Remix 将支持九个月。
![](http://i1-news.softpedia-static.com/images/news2/someone-tries-to-bring-back-ubuntu-s-unity-from-the-dead-as-an-unofficial-spin-518778-2.jpg)
Canonical 在七年之后突然决定抛弃它的 Unity 用户界面影响了许多 Ubuntu 用户,现在看起来有人试图把它从死亡中带回来,成为官方<ruby>分支<rt>spin</rt></ruby>
长期 [Ubuntu][1] 成员 Dale Beaudoin 上周在官方的 Ubuntu 论坛上[进行了一项调查][2]来了解社区意向,看看他们是否对随同明年的 Ubuntu 18.04 LTSBionic Beaver一起发布的 Ubuntu Unity Remix 感兴趣,它将支持 9 个月或 5 年。
有 30 人进行了投票,其中 67 的人选择了所谓的 Ubuntu Unity Remix 的 LTS长期支持版本33 的人投票支持 9 个月的支持版本。看起来这个即将到来的 Ubuntu Unity Spin [看起来会成为官方特色版本][3],而这意味着开发它的承诺。
Dale Beaudoin 表示“最近的一项民意调查显示2/3 的人支持 Ubuntu Unity 成为 LTS 发行版,我们应该按照它成为 LTS 和官方特色版的更新周期去努力。我们将尝试使用当前默认的 Ubuntu Bionic Beaver 18.04 的每日构建版本作为平台,每周或每 10 天发布一次更新的 ISO。”
### Ubuntu Unity 是否会卷土重来?
正常情况下,最后一个带有 Unity 的 Ubuntu 版本应该是 Ubuntu 17.04Zesty Zapus它将在 2018 年 1 月终止支持。当前流行操作系统的稳定版本 Ubuntu 17.10Artful Artful是今年早些时候 Canonical CEO [宣布][4]之后第一个默认使用 GNOME 桌面环境的版本Unity 将不再开发。
然而Canonical 仍然在官方软件仓库提供 Unity 桌面环境,所以如果有人想要安装它,只需点击一下即可。但坏消息是,它们支持到 2018 年 4 月发布 Ubuntu 18.04 LTSBionic Beaver之前所以 Ubuntu Unity Remix 的开发者们将不得不在独立的仓库中继续支持。
另一方面,我们不相信 Canonical 会改变主意,接受这个 Ubuntu Unity Spin 成为官方的特色版,这意味着他们不会继续开发 Unity现在只有一小部分人可以做这个开发。最有可能的是如果对 Ubuntu Unity Remix 的兴趣没有很快消失,那么,这可能会是一个由怀旧社区支持的非官方版本。
问题是,你会对 Ubuntu Unity Spin 感兴趣么,官方或者非官方?
--------------------------------------------------------------------------------
via: http://news.softpedia.com/news/someone-tries-to-bring-back-ubuntu-s-unity-from-the-dead-as-an-unofficial-spin-518778.shtml
作者:[Marius Nestor][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://news.softpedia.com/editors/browse/marius-nestor
[1]:http://linux.softpedia.com/downloadTag/Ubuntu
[2]:https://community.ubuntu.com/t/poll-unity-7-distro-9-month-spin-or-lts-for-18-04/2066
[3]:https://community.ubuntu.com/t/unity-maintenance-roadmap/2223
[4]:http://news.softpedia.com/news/canonical-to-stop-developing-unity-8-ubuntu-18-04-lts-ships-with-gnome-desktop-514604.shtml
[5]:http://news.softpedia.com/editors/browse/marius-nestor

View File

@ -0,0 +1,127 @@
Suplemon带有多光标支持的现代 CLI 文本编辑器
======
Suplemon 是一个 CLI 中的现代文本编辑器,它模拟 [Sublime Text][1] 的多光标行为和其它特性。它是轻量级的,非常易于使用,就像 Nano 一样。
使用 CLI 编辑器的好处之一是,无论你使用的 Linux 发行版是否有 GUI你都可以使用它。这种文本编辑器也很简单、快速和强大。
你可以在其[官方仓库][2]中找到有用的信息和源代码。
### 功能
这些是一些它有趣的功能:
* 多光标支持
* 撤销/重做
* 复制和粘贴,带有多行支持
* 鼠标支持
* 扩展
* 查找、查找所有、查找下一个
* 语法高亮
* 自动完成
* 自定义键盘快捷键
### 安装
首先,确保安装了最新版本的 python3 和 pip3。
然后在终端输入:
```
$ sudo pip3 install suplemon
```
### 使用
#### 在当前目录中创建一个新文件
打开一个终端并输入:
```
$ suplemon
```
你将看到如下:
![suplemon new file](https://linoxide.com/wp-content/uploads/2017/11/suplemon-new-file.png)
#### 打开一个或多个文件
打开一个终端并输入:
```
$ suplemon <filename1> <filename2> ... <filenameN>
```
例如:
```
$ suplemon example1.c example2.c
```
### 主要配置
你可以在 `~/.config/suplemon/suplemon-config.json` 找到配置文件。
编辑这个文件很简单,你只需要进入命令模式(进入 suplemon 后)并运行 `config` 命令。你可以通过运行 `config defaults` 来查看默认配置。
#### 键盘映射配置
我会展示 suplemon 的默认键映射。如果你想编辑它们,只需运行 `keymap` 命令。运行 `keymap default` 来查看默认的键盘映射文件。
| 操作 | 快捷键 |
| ---- | ---- |
| 退出| `Ctrl + Q`|
| 复制行到缓冲区|`Ctrl + C`|
| 剪切行缓冲区| `Ctrl + X`|
| 插入缓冲区| `Ctrl + V`|
| 复制行| `Ctrl + K`|
| 跳转| `Ctrl + G`。 你可以跳转到一行或一个文件(只需键入一个文件名的开头)。另外,可以输入类似于 `exam:50` 跳转到 `example.c``50` 行。|
| 用字符串或正则表达式搜索| `Ctrl + F`|
| 搜索下一个| `Ctrl + D`|
| 去除空格| `Ctrl + T`|
| 在箭头方向添加新的光标| `Alt + 方向键`|
| 跳转到上一个或下一个单词或行| `Ctrl + 左/右`|
| 恢复到单光标/取消输入提示| `Esc`|
| 向上/向下移动行| `Page Up` / `Page Down`|
| 保存文件|`Ctrl + S`|
| 用新名称保存文件|`F1`|
| 重新载入当前文件|`F2`|
| 打开文件|`Ctrl + O`|
| 关闭文件|`Ctrl + W`|
| 切换到下一个/上一个文件|`Ctrl + Page Up` / `Ctrl + Page Down`|
| 运行一个命令|`Ctrl + E`|
| 撤消|`Ctrl + Z`|
| 重做|`Ctrl + Y`|
| 触发可见的空格|`F7`|
| 切换鼠标模式|`F8`|
| 显示行号|`F9`|
| 显示全屏|`F11`|
#### 鼠标快捷键
* 将光标置于指针位置:左键单击
* 在指针位置添加一个光标:右键单击
* 垂直滚动:向上/向下滚动滚轮
### 总结
在尝试 Suplemon 一段时间后,我改变了对 CLI 文本编辑器的看法。我以前曾经尝试过 Nano是的我喜欢它的简单性但是它的现代特征的缺乏使它在日常使用中变得不实用。
这个工具有 CLI 和 GUI 世界最好的东西……简单性和功能丰富!所以我建议你试试看,并在评论中写下你的想法 :-)
--------------------------------------------------------------------------------
via: https://linoxide.com/tools/suplemon-cli-text-editor-multi-cursor/
作者:[Ivo Ursino][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://linoxide.com/author/ursinov/
[1]:https://linoxide.com/tools/install-sublime-text-editor-linux/
[2]:https://github.com/richrd/suplemon/

View File

@ -0,0 +1,193 @@
如何在 Linux shell 中找出所有包含指定文本的文件
===========
**目标:**本文提供一些关于如何搜索出指定目录或整个文件系统中那些包含指定单词或字符串的文件。
**难度:**容易
**约定:**
* `#` - 需要使用 root 权限来执行指定命令,可以直接使用 root 用户来执行也可以使用 `sudo` 命令
* `$` - 可以使用普通用户来执行指定命令
### 案例
#### 非递归搜索包含指定字符串的文件
第一个例子让我们来搜索 `/etc/` 目录下所有包含 `stretch` 字符串的文件,但不去搜索其中的子目录:
```shell
# grep -s stretch /etc/*
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"
```
`grep``-s` 选项会在发现不存在或者不能读取的文件时隐藏报错信息。结果显示除了文件名之外,还有包含请求字符串的行也被一起输出了。
#### 递归地搜索包含指定字符串的文件
上面案例中忽略了所有的子目录。所谓递归搜索就是指同时搜索所有的子目录。
下面的命令会在 `/etc/` 及其子目录中搜索包含 `stretch` 字符串的文件:
```shell
# grep -R stretch /etc/*
/etc/apt/sources.list:# deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:#deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:deb http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb-src http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb http://security.debian.org/debian-security stretch/updates main
/etc/apt/sources.list:deb-src http://security.debian.org/debian-security stretch/updates main
/etc/dictionaries-common/words:backstretch
/etc/dictionaries-common/words:backstretch's
/etc/dictionaries-common/words:backstretches
/etc/dictionaries-common/words:homestretch
/etc/dictionaries-common/words:homestretch's
/etc/dictionaries-common/words:homestretches
/etc/dictionaries-common/words:outstretch
/etc/dictionaries-common/words:outstretched
/etc/dictionaries-common/words:outstretches
/etc/dictionaries-common/words:outstretching
/etc/dictionaries-common/words:stretch
/etc/dictionaries-common/words:stretch's
/etc/dictionaries-common/words:stretched
/etc/dictionaries-common/words:stretcher
/etc/dictionaries-common/words:stretcher's
/etc/dictionaries-common/words:stretchers
/etc/dictionaries-common/words:stretches
/etc/dictionaries-common/words:stretchier
/etc/dictionaries-common/words:stretchiest
/etc/dictionaries-common/words:stretching
/etc/dictionaries-common/words:stretchy
/etc/grub.d/00_header:background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"
```
#### 搜索所有包含特定单词的文件
上面 `grep` 命令的案例中列出的是所有包含字符串 `stretch` 的文件。也就是说包含 `stretches` `stretched` 等内容的行也会被显示。 使用 `grep``-w` 选项会只显示包含特定单词的行:
```shell
# grep -Rw stretch /etc/*
/etc/apt/sources.list:# deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:#deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:deb http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb-src http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb http://security.debian.org/debian-security stretch/updates main
/etc/apt/sources.list:deb-src http://security.debian.org/debian-security stretch/updates main
/etc/dictionaries-common/words:stretch
/etc/dictionaries-common/words:stretch's
/etc/grub.d/00_header:background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"
```
#### 显示包含特定文本的文件名
上面的命令都会产生多余的输出。下一个案例则会递归地搜索 `etc` 目录中包含 `stretch` 的文件并只输出文件名:
```shell
# grep -Rl stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/words
/etc/grub.d/00_header
/etc/os-release
```
#### 大小写不敏感的搜索
默认情况下搜索是大小写敏感的,也就是说当搜索字符串 `stretch` 时只会包含大小写一致内容的文件。
通过使用 `grep``-i` 选项,`grep` 命令还会列出所有包含 `Stretch` `STRETCH` `StReTcH` 等内容的文件,也就是说进行的是大小写不敏感的搜索。
```shell
# grep -Ril stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/default.hash
/etc/dictionaries-common/words
/etc/grub.d/00_header
/etc/os-release
```
#### 搜索时包含/排除指定文件
`grep` 命令也可以只在指定文件中进行搜索。比如,我们可以只在配置文件(扩展名为`.conf`)中搜索指定的文本/字符串。 下面这个例子就会在 `/etc` 目录中搜索带字符串 `bash` 且所有扩展名为 `.conf` 的文件:
```shell
# grep -Ril bash /etc/*.conf
OR
# grep -Ril --include=\*.conf bash /etc/*
/etc/adduser.conf
```
类似的,也可以使用 `--exclude` 来排除特定的文件:
```shell
# grep -Ril --exclude=\*.conf bash /etc/*
/etc/alternatives/view
/etc/alternatives/vim
/etc/alternatives/vi
/etc/alternatives/vimdiff
/etc/alternatives/rvim
/etc/alternatives/ex
/etc/alternatives/rview
/etc/bash.bashrc
/etc/bash_completion.d/grub
/etc/cron.daily/apt-compat
/etc/cron.daily/exim4-base
/etc/dictionaries-common/default.hash
/etc/dictionaries-common/words
/etc/inputrc
/etc/passwd
/etc/passwd-
/etc/profile
/etc/shells
/etc/skel/.profile
/etc/skel/.bashrc
/etc/skel/.bash_logout
```
#### 搜索时排除指定目录
跟文件一样,`grep` 也能在搜索时排除指定目录。 使用 `--exclude-dir` 选项就行。
下面这个例子会搜索 `/etc` 目录中搜有包含字符串 `stretch` 的文件,但不包括 `/etc/grub.d` 目录下的文件:
```shell
# grep --exclude-dir=/etc/grub.d -Rwl stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/words
/etc/os-release
```
#### 显示包含搜索字符串的行号
`-n` 选项还会显示指定字符串所在行的行号:
```shell
# grep -Rni bash /etc/*.conf
/etc/adduser.conf:6:DSHELL=/bin/bash
```
#### 寻找不包含指定字符串的文件
最后这个例子使用 `-v` 来列出所有**不**包含指定字符串的文件。
例如下面命令会搜索 `/etc` 目录中不包含 `stretch` 的所有文件:
```shell
# grep -Rlv stretch /etc/*
```
--------------------------------------------------------------------------------
via: https://linuxconfig.org/how-to-find-all-files-with-a-specific-text-using-linux-shell
作者:[Lubos Rendek][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://linuxconfig.org

View File

@ -0,0 +1,48 @@
使用 DNSTrails 自动找出每个域名的拥有者
============================================================
今天,我们很高兴地宣布我们最近几周做的新功能。它是 Whois 聚合工具,现在可以在 [DNSTrails][1] 上获得。
在过去,查找一个域名的所有者会花费很多时间,因为大部分时间你都需要把域名翻译为一个 IP 地址,以便找到同一个人拥有的其他域名。
使用老的方法,在得到你想要的域名列表之前,你在一个工具和另外一个工具的一日又一日的研究和交叉比较结果中经常会花费数个小时。
感谢这个新工具和我们的智能 [WHOIS 数据库][2],现在你可以搜索任何域名,并获得组织或个人注册的域名的完整列表,并在几秒钟内获得准确的结果。
### 我如何使用 Whois 聚合功能?
第一步:打开 [DNSTrails.com][3]
第二步搜索任何域名比如godaddy.com
第三步:在得到域名的结果后,如下所见,定位下面的 Whois 信息:
![Domain name search results](https://securitytrails.com/images/a/a/1/3/f/aa13fa3616b8dc313f925bdbf1da43a54856d463-image1.png)
第四步:你会看到那里有有关域名的电话和电子邮箱地址。
第五步:点击右边的链接,你会轻松地找到用相同电话和邮箱注册的域名。
![All domain names by the same owner](https://securitytrails.com/images/1/3/4/0/3/134037822d23db4907d421046b11f3cbb872f94f-image2.png)
如果你正在调查互联网上任何个人的域名所有权,这意味着即使域名甚至没有指向注册服务商的 IP如果他们使用相同的电话和邮件地址我们仍然可以发现其他域名。
想知道一个人拥有的其他域名么?亲自试试 [DNStrails][5] 的 [WHOIS 聚合功能][4]或者[使用我们的 API 访问][6]。
--------------------------------------------------------------------------------
via: https://securitytrails.com/blog/find-every-domain-someone-owns
作者:[SECURITYTRAILS TEAM][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://securitytrails.com/blog/find-every-domain-someone-owns
[1]:https://dnstrails.com/
[2]:https://securitytrails.com/forensics
[3]:https://dnstrails.com/
[4]:http://dnstrails.com/#/domain/domain/ueland.com
[5]:https://dnstrails.com/
[6]:https://securitytrails.com/contact

View File

@ -0,0 +1,97 @@
在命令行中使用 DuckDuckGo 搜索
=============
![](http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/duckduckgo.png)
此前我们介绍了[如何在命令行中使用 Google 搜索][3]。许多读者反馈说他们平时使用 [Duck Duck Go][4],这是一个功能强大而且保密性很强的搜索引擎。
正巧,最近出现了一款能够从命令行搜索 DuckDuckGo 的工具。它叫做 ddgr我把它读作 “dodger”非常好用。
像 [Googler][7] 一样ddgr 是一个完全开源而且非官方的工具。没错,它并不属于 DuckDuckGo。所以如果你发现它返回的结果有些奇怪请先询问这个工具的开发者而不是搜索引擎的开发者。
### DuckDuckGo 命令行应用
![](http://www.omgubuntu.co.uk/wp-content/uploads/2017/11/ddgr-gif.gif)
[DuckDuckGo BangsDuckDuckGo 快捷搜索)][8] 可以帮助你轻易地在 DuckDuckGo 上找到想要的信息(甚至 _本网站 omgubuntu_ 都有快捷搜索。ddgr 非常忠实地呈现了这个功能。
和网页版不同的是,你可以更改每页返回多少结果。这比起每次查询都要看三十多条结果要方便一些。默认界面经过了精心设计,在不影响可读性的情况下尽量减少了占用空间。
`ddgr` 有许多功能和亮点,包括:
* 更改搜索结果数
* 支持 Bash 自动补全
* 使用 DuckDuckGo Bangs
* 在浏览器中打开链接
* ”手气不错“选项
* 基于时间、地区、文件类型等的筛选功能
* 极少的依赖项
你可以从 Github 的项目页面上下载支持各种系统的 `ddgr`
- [从 Github 下载 “ddgr”][9]
另外,在 Ubuntu 16.04 LTS 或更新版本中,你可以使用 PPA 安装 ddgr。这个仓库由 ddgr 的开发者维护。如果你想要保持在最新版本的话,推荐使用这种方式安装。
需要提醒的是,在本文创作时,这个 PPA 中的 ddgr _并不是_ 最新版本,而是一个稍旧的版本(缺少 -num 选项)。
使用以下命令添加 PPA
```
sudo add-apt-repository ppa:twodopeshaggy/jarun
sudo apt-get update
```
### 如何使用 ddgr 在命令行中搜索 DuckDuckGo
安装完毕后,你只需打开你的终端模拟器,并运行:
```
ddgr
```
然后输入查询内容:
```
search-term
```
你可以限制搜索结果数:
```
ddgr --num 5 search-term
```
或者自动在浏览器中打开第一条搜索结果:
```
ddgr -j search-term
```
你可以使用参数和选项来提高搜索精确度。使用以下命令来查看所有的参数:
```
ddgr -h
```
--------------------------------------------------------------------------------
via: http://www.omgubuntu.co.uk/2017/11/duck-duck-go-terminal-app
作者:[JOEY SNEDDON][a]
译者:[yixunx](https://github.com/yixunx)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://plus.google.com/117485690627814051450/?rel=author
[1]:https://plus.google.com/117485690627814051450/?rel=author
[2]:http://www.omgubuntu.co.uk/category/download
[3]:http://www.omgubuntu.co.uk/2017/08/search-google-from-the-command-line
[4]:http://duckduckgo.com/
[5]:http://www.omgubuntu.co.uk/2017/11/duck-duck-go-terminal-app
[6]:https://github.com/jarun/ddgr
[7]:https://github.com/jarun/googler
[8]:https://duckduckgo.com/bang
[9]:https://github.com/jarun/ddgr/releases/tag/v1.1

View File

@ -0,0 +1,398 @@
Translate Shell :一款在 Linux 命令行中使用谷歌翻译的工具
============================================================
我对 CLI 应用非常感兴趣,因此热衷于使用并分享 CLI 应用。 我之所以更喜欢 CLI 很大原因是因为我在大多数的时候都使用的是字符界面black screen已经习惯了使用 CLI 应用而不是 GUI 应用。
我写过很多关于 CLI 应用的文章。 最近我发现了一些谷歌的 CLI 工具,像 “Google Translator”、“Google Calendar” 和 “Google Contacts”。 这里,我想在给大家分享一下。
今天我们要介绍的是 “Google Translator” 工具。 由于我的母语是泰米尔语,我在一天内用了很多次才理解了它的意义。
谷歌翻译为其它语系的人们所广泛使用。
### 什么是 Translate Shell
[Translate Shell][2] (之前叫做 Google Translate CLI) 是一款借助谷歌翻译默认、必应翻译、Yandex.Translate 以及 Apertium 来翻译的命令行翻译器。它让你可以在终端访问这些翻译引擎。 Translate Shell 在大多数 Linux 发行版中都能使用。
### 如何安装 Translate Shell
有三种方法安装 Translate Shell。
* 下载自包含的可执行文件
* 手工安装
* 通过包管理器安装
#### 方法 1 : 下载自包含的可执行文件
下载自包含的可执行文件放到 `/usr/bin` 目录中。
```
$ wget git.io/trans
$ chmod +x ./trans
$ sudo mv trans /usr/bin/
```
#### 方法 2 : 手工安装
克隆 Translate Shell 的 GitHub 仓库然后手工编译。
```
$ git clone https://github.com/soimort/translate-shell && cd translate-shell
$ make
$ sudo make install
```
#### 方法 3 : 通过包管理器
有些发行版的官方仓库中包含了 Translate Shell可以通过包管理器来安装。
对于 Debian/Ubuntu 使用 [APT-GET 命令][3] 或者 [APT 命令][4]来安装。
```
$ sudo apt-get install translate-shell
```
对于 Fedora, 使用 [DNF 命令][5] 来安装。
```
$ sudo dnf install translate-shell
```
对于基于 Arch Linux 的系统, 使用 [Yaourt 命令][6] 或 [Packer 明快][7] 来从 AUR 仓库中安装。
```
$ yaourt -S translate-shell
or
$ packer -S translate-shell
```
### 如何使用 Translate Shell
安装好后,打开终端闭关输入下面命令。 谷歌翻译会自动探测源文本是哪种语言,并且在默认情况下将之翻译成你的 `locale` 所对应的语言。
```
$ trans [Words]
```
下面我将泰米尔语中的单词 “நன்றி” (Nanri) 翻译成英语。 这个单词的意思是感谢别人。
```
$ trans நன்றி
நன்றி
(Naṉṟi)
Thanks
Definitions of நன்றி
[ தமிழ் -> English ]
noun
gratitude
நன்றி
thanks
நன்றி
நன்றி
Thanks
```
使用下面命令也能将英语翻译成泰米尔语。
```
$ trans :ta thanks
thanks
/THaNGks/
நன்றி
(Naṉṟi)
Definitions of thanks
[ English -> தமிழ் ]
noun
நன்றி
gratitude, thanks
thanks
நன்றி
```
要将一个单词翻译到多个语种可以使用下面命令(本例中,我将单词翻译成泰米尔语以及印地语)。
```
$ trans :ta+hi thanks
thanks
/THaNGks/
நன்றி
(Naṉṟi)
Definitions of thanks
[ English -> தமிழ் ]
noun
நன்றி
gratitude, thanks
thanks
நன்றி
thanks
/THaNGks/
धन्यवाद
(dhanyavaad)
Definitions of thanks
[ English -> हिन्दी ]
noun
धन्यवाद
thanks, thank, gratitude, thankfulness, felicitation
thanks
धन्यवाद, शुक्रिया
```
使用下面命令可以将多个单词当成一个参数(句子)来进行翻译。(只需要把句子应用起来作为一个参数就行了)。
```
$ trans :ta "what is going on your life?"
what is going on your life?
உங்கள் வாழ்க்கையில் என்ன நடக்கிறது?
(Uṅkaḷ vāḻkkaiyil eṉṉa naṭakkiṟatu?)
Translations of what is going on your life?
[ English -> தமிழ் ]
what is going on your life?
உங்கள் வாழ்க்கையில் என்ன நடக்கிறது?
```
下面命令单独地翻译各个单词。
```
$ trans :ta curios happy
curios
ஆர்வம்
(Ārvam)
Translations of curios
[ Română -> தமிழ் ]
curios
ஆர்வம், அறிவாளிகள், ஆர்வமுள்ள, அறிய, ஆர்வமாக
happy
/ˈhapē/
சந்தோஷமாக
(Cantōṣamāka)
Definitions of happy
[ English -> தமிழ் ]
மகிழ்ச்சியான
happy, convivial, debonair, gay
திருப்தி உடைய
happy
adjective
இன்பமான
happy
happy
சந்தோஷமாக, மகிழ்ச்சி, இனிய, சந்தோஷமா
```
简洁模式默认情况下Translate Shell 尽可能多的显示翻译信息。如果你希望只显示简要信息,只需要加上 `-b`选项。
```
$ trans -b :ta thanks
நன்றி
```
字典模式:加上 `-d` 可以把 Translate Shell 当成字典来用。
```
$ trans -d :en thanks
thanks
/THaNGks/
Synonyms
noun
- gratitude, appreciation, acknowledgment, recognition, credit
exclamation
- thank you, many thanks, thanks very much, thanks a lot, thank you kindly, much obliged, much appreciated, bless you, thanks a million
Examples
- In short, thanks for everything that makes this city great this Thanksgiving.
- many thanks
- There were no thanks in the letter from him, just complaints and accusations.
- It is a joyful celebration in which Bolivians give thanks for their freedom as a nation.
- festivals were held to give thanks for the harvest
- The collection, as usual, received a great response and thanks is extended to all who subscribed.
- It would be easy to dwell on the animals that Tasmania has lost, but I prefer to give thanks for what remains.
- thanks for being so helpful
- It came back on about half an hour earlier than predicted, so I suppose I can give thanks for that.
- Many thanks for the reply but as much as I tried to follow your advice, it's been a bad week.
- To them and to those who have supported the office I extend my grateful thanks .
- We can give thanks and words of appreciation to others for their kind deeds done to us.
- Adam, thanks for taking time out of your very busy schedule to be with us tonight.
- a letter of thanks
- Thank you very much for wanting to go on reading, and thanks for your understanding.
- Gerry has received a letter of thanks from the charity for his part in helping to raise this much needed cash.
- So thanks for your reply to that guy who seemed to have a chip on his shoulder about it.
- Suzanne, thanks for being so supportive with your comments on my blog.
- She has never once acknowledged my thanks , or existence for that matter.
- My grateful thanks go to the funders who made it possible for me to travel.
- festivals were held to give thanks for the harvest
- All you secretaries who made it this far into the article… thanks for your patience.
- So, even though I don't think the photos are that good, thanks for the compliments!
- And thanks for warning us that your secret service requires a motorcade of more than 35 cars.
- Many thanks for your advice, which as you can see, I have passed on to our readers.
- Tom Ryan was given a bottle of wine as a thanks for his active involvement in the twinning project.
- Mr Hill insists he has received no recent complaints and has even been sent a letter of thanks from the forum.
- Hundreds turned out to pay tribute to a beloved former headteacher at a memorial service to give thanks for her life.
- Again, thanks for a well written and much deserved tribute to our good friend George.
- I appreciate your doing so, and thanks also for the compliments about the photos!
See also
Thanks!, thank, many thanks, thanks to, thanks to you, special thanks, give thanks, thousand thanks, Many thanks!, render thanks, heartfelt thanks, thanks to this
```
使用下面格式可以使用 Translate Shell 来翻译文件。
```
$ trans :ta file:///home/magi/gtrans.txt
உங்கள் வாழ்க்கையில் என்ன நடக்கிறது?
```
下面命令可以让 Translate Shell 进入交互模式。 在进入交互模式之前你需要明确指定源语言和目标语言。本例中,我将英文单词翻译成泰米尔语。
```
$ trans -shell en:ta thanks
Translate Shell
(:q to quit)
thanks
/THaNGks/
நன்றி
(Naṉṟi)
Definitions of thanks
[ English -> தமிழ் ]
noun
நன்றி
gratitude, thanks
thanks
நன்றி
```
想知道语言代码,可以执行下面命令。
```
$ trans -R
```
或者
```
$ trans -T
┌───────────────────────┬───────────────────────┬───────────────────────┐
│ Afrikaans - af │ Hindi - hi │ Punjabi - pa │
│ Albanian - sq │ Hmong - hmn │ Querétaro Otomi- otq │
│ Amharic - am │ Hmong Daw - mww │ Romanian - ro │
│ Arabic - ar │ Hungarian - hu │ Russian - ru │
│ Armenian - hy │ Icelandic - is │ Samoan - sm │
│ Azerbaijani - az │ Igbo - ig │ Scots Gaelic - gd │
│ Basque - eu │ Indonesian - id │ Serbian (Cyr...-sr-Cyrl
│ Belarusian - be │ Irish - ga │ Serbian (Latin)-sr-Latn
│ Bengali - bn │ Italian - it │ Sesotho - st │
│ Bosnian - bs │ Japanese - ja │ Shona - sn │
│ Bulgarian - bg │ Javanese - jv │ Sindhi - sd │
│ Cantonese - yue │ Kannada - kn │ Sinhala - si │
│ Catalan - ca │ Kazakh - kk │ Slovak - sk │
│ Cebuano - ceb │ Khmer - km │ Slovenian - sl │
│ Chichewa - ny │ Klingon - tlh │ Somali - so │
│ Chinese Simp...- zh-CN│ Klingon (pIqaD)tlh-Qaak Spanish - es │
│ Chinese Trad...- zh-TW│ Korean - ko │ Sundanese - su │
│ Corsican - co │ Kurdish - ku │ Swahili - sw │
│ Croatian - hr │ Kyrgyz - ky │ Swedish - sv │
│ Czech - cs │ Lao - lo │ Tahitian - ty │
│ Danish - da │ Latin - la │ Tajik - tg │
│ Dutch - nl │ Latvian - lv │ Tamil - ta │
│ English - en │ Lithuanian - lt │ Tatar - tt │
│ Esperanto - eo │ Luxembourgish - lb │ Telugu - te │
│ Estonian - et │ Macedonian - mk │ Thai - th │
│ Fijian - fj │ Malagasy - mg │ Tongan - to │
│ Filipino - tl │ Malay - ms │ Turkish - tr │
│ Finnish - fi │ Malayalam - ml │ Udmurt - udm │
│ French - fr │ Maltese - mt │ Ukrainian - uk │
│ Frisian - fy │ Maori - mi │ Urdu - ur │
│ Galician - gl │ Marathi - mr │ Uzbek - uz │
│ Georgian - ka │ Mongolian - mn │ Vietnamese - vi │
│ German - de │ Myanmar - my │ Welsh - cy │
│ Greek - el │ Nepali - ne │ Xhosa - xh │
│ Gujarati - gu │ Norwegian - no │ Yiddish - yi │
│ Haitian Creole - ht │ Pashto - ps │ Yoruba - yo │
│ Hausa - ha │ Persian - fa │ Yucatec Maya - yua │
│ Hawaiian - haw │ Polish - pl │ Zulu - zu │
│ Hebrew - he │ Portuguese - pt │ │
└───────────────────────┴───────────────────────┴───────────────────────┘
```
想了解更多选项的内容,可以查看其 man 手册。
```
$ man trans
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/translate-shell-a-tool-to-use-google-translate-from-command-line-in-linux/
作者:[Magesh Maruthamuthu][a]
译者:[lujun9972](https://github.com/lujun9972 )
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/magesh/
[2]:https://github.com/soimort/translate-shell
[3]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
[4]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
[5]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
[6]:https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/
[7]:https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/

View File

@ -0,0 +1,132 @@
如何自动唤醒和关闭 Linux
=====================
![timekeeper](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/banner.jpg?itok=zItspoSb)
> 了解如何通过配置 Linux 计算机来根据时间自动唤醒和关闭。
不要成为一个电能浪费者。如果你的电脑不需要开机就请把它们关机。出于方便和计算机宅的考虑,你可以通过配置你的 Linux 计算机实现自动唤醒和关闭。
### 宝贵的系统运行时间
有时候有些电脑需要一直处在开机状态,在不超过电脑运行时间的限制下这种情况是被允许的。有些人为他们的计算机可以长时间的正常运行而感到自豪,且现在我们有内核热补丁能够实现只有在硬件发生故障时才需要机器关机。我认为比较实际可行的是,像减少移动部件磨损一样节省电能,且在不需要机器运行的情况下将其关机。比如,你可以在规定的时间内唤醒备份服务器,执行备份,然后关闭它直到它要进行下一次备份。或者,你可以设置你的互联网网关只在特定的时间运行。任何不需要一直运行的东西都可以将其配置成在其需要工作的时候打开,待其完成工作后将其关闭。
### 系统休眠
对于不需要一直运行的电脑,使用 root 的 cron 定时任务(即 `/etc/crontab`)可以可靠地关闭电脑。这个例子创建一个 root 定时任务实现每天晚上 11 点 15 分定时关机。
```
# crontab -e -u root
# m h dom mon dow command
15 23 * * * /sbin/shutdown -h now
```
以下示例仅在周一至周五运行:
```
15 23 * * 1-5 /sbin/shutdown -h now
```
您可以为不同的日期和时间创建多个 cron 作业。 通过命令 `man 5 crontab` 可以了解所有时间和日期的字段。
一个快速、容易的方式是,使用 `/etc/crontab` 文件。但这样你必须指定用户:
```
15 23 * * 1-5 root shutdown -h now
```
### 自动唤醒
实现自动唤醒是一件很酷的事情;我大多数 SUSE SUSE Linux的同事都在纽伦堡因此因此为了跟同事能有几小时一起工作的时间我不得不需要在凌晨五点起床。我的计算机早上 5 点半自动开始工作,而我只需要将自己和咖啡拖到我的桌子上就可以开始工作了。按下电源按钮看起来好像并不是什么大事,但是在每天的那个时候每件小事都会变得很大。
唤醒 Linux 计算机可能不如关闭它可靠因此你可能需要尝试不同的办法。你可以使用远程唤醒Wake-On-LAN、RTC 唤醒或者个人电脑的 BIOS 设置预定的唤醒这些方式。这些方式可行的原因是,当你关闭电脑时,这并不是真正关闭了计算机;此时计算机处在极低功耗状态且还可以接受和响应信号。只有在你拔掉电源开关时其才彻底关闭。
### BIOS 唤醒
BIOS 唤醒是最可靠的。我的系统主板 BIOS 有一个易于使用的唤醒调度程序 (图 1)。对你来说也是一样的容易。
![wakeup](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-1_11.png?itok=8qAeqo1I)
*图 1我的系统 BIOS 有个易用的唤醒定时器。*
### 主机远程唤醒Wake-On-LAN
远程唤醒是仅次于 BIOS 唤醒的又一种可靠的唤醒方法。这需要你从第二台计算机发送信号到所要打开的计算机。可以使用 Arduino 或<ruby>树莓派<rt>Raspberry Pi</rt></ruby>发送给基于 Linux 的路由器或者任何 Linux 计算机的唤醒信号。首先,查看系统主板 BIOS 是否支持 Wake-On-LAN ,要是支持的话,必须先启动它,因为它被默认为禁用。
然后,需要一个支持 Wake-On-LAN 的网卡;无线网卡并不支持。你需要运行 `ethtool` 命令查看网卡是否支持 Wake-On-LAN
```
# ethtool eth0 | grep -i wake-on
Supports Wake-on: pumbg
Wake-on: g
```
这条命令输出的 “Supports Wake-on” 字段会告诉你你的网卡现在开启了哪些功能:
   
* d -- 禁用
* p -- 物理活动唤醒
* u -- 单播消息唤醒
* m -- 多播(组播)消息唤醒
* b -- 广播消息唤醒
* a -- ARP 唤醒
* g -- <ruby>特定数据包<rt>magic packet</rt></ruby>唤醒
* s -- 设有密码的<ruby>特定数据包<rt>magic packet</rt></ruby>唤醒
`ethtool` 命令的 man 手册并没说清楚 `p` 选项的作用;这表明任何信号都会导致唤醒。然而,在我的测试中它并没有这么做。想要实现远程唤醒主机,必须支持的功能是 `g` —— <ruby>特定数据包<rt>magic packet</rt></ruby>唤醒而且下面的“Wake-on” 行显示这个功能已经在启用了。如果它没有被启用,你可以通过 `ethtool` 命令来启用它。
```
# ethtool -s eth0 wol g
```
这条命令可能会在重启后失效,所以为了确保万无一失,你可以创建个 root 用户的定时任务cron在每次重启的时候来执行这条命令。
```
@reboot /usr/bin/ethtool -s eth0 wol g
```
另一个选择是最近的<ruby>网络管理器<rt>Network Manager</rt></ruby>版本有一个很好的小复选框来启用 Wake-On-LAN图 2
![wakeonlan](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-2_7.png?itok=XQAwmHoQ)
*图 2启用 Wake on LAN*
这里有一个可以用于设置密码的地方,但是如果你的网络接口不支持<ruby>安全开机<rt>Secure On</rt></ruby>密码,它就不起作用。
现在你需要配置第二台计算机来发送唤醒信号。你并不需要 root 权限,所以你可以为你的普通用户创建 cron 任务。你需要用到的是想要唤醒的机器的网络接口和MAC地址信息。
```
30 08 * * * /usr/bin/wakeonlan D0:50:99:82:E7:2B
```
### RTC 唤醒
通过使用实时闹钟来唤醒计算机是最不可靠的方法。对于这个方法,可以参看 [Wake Up Linux With an RTC Alarm Clock][4] ;对于现在的大多数发行版来说这种方法已经有点过时了。
下周继续了解更多关于使用 RTC 唤醒的方法。
通过 Linux 基金会和 edX 可以学习更多关于 Linux 的免费 [Linux 入门][5]教程。
(题图:[The Observatory at Delhi][7]
--------------------------------------------------------------------------------
via:https://www.linux.com/learn/intro-to-linux/2017/11/wake-and-shut-down-linux-automatically
作者:[Carla Schroder][a]
译者:[HardworkFish](https://github.com/HardworkFish)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://www.linux.com/files/images/bannerjpg
[2]:https://www.linux.com/files/images/fig-1png-11
[3]:https://www.linux.com/files/images/fig-2png-7
[4]:https://www.linux.com/learn/wake-linux-rtc-alarm-clock
[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
[6]:https://www.linux.com/licenses/category/creative-commons-attribution
[7]:http://www.columbia.edu/itc/mealac/pritchett/00routesdata/1700_1799/jaipur/delhijantarearly/delhijantarearly.html
[8]:https://www.linux.com/licenses/category/used-permission
[9]:https://www.linux.com/licenses/category/used-permission

View File

@ -0,0 +1,62 @@
Fedora 课堂会议Ansible 101
==========
![](https://fedoramagazine.org/wp-content/uploads/2017/07/fedora-classroom-945x400.jpg)
Fedora 课堂会议本周继续进行,本周的主题是 Ansible。 会议的时间安排表发布在 [wiki][3] 上。你还可以从那里找到[之前会议的资源和录像][4]。以下是会议的具体时间 [11月30日本周星期四 1600 UTC][5]。该链接可以将这个时间转换为您的时区上的时间。
### 主题: Ansible 101
正如 Ansible [文档][6] 所说Ansible 是一个 IT 自动化工具。它主要用于配置系统,部署软件和编排更高级的 IT 任务。示例包括持续交付与零停机滚动升级。
本课堂课程涵盖以下主题:
1. SSH 简介
2. 了解不同的术语
3. Ansible 简介
4. Ansible 安装和设置
5. 建立无密码连接
6. Ad-hoc 命令
7. 管理 inventory
8. Playbooks 示例
之后还将有 Ansible 102 的后续会议。该会议将涵盖复杂的 playbooksplaybooks 角色roles动态 inventory 文件,流程控制和 Ansible Galaxy 命令行工具.
### 讲师
我们有两位经验丰富的讲师进行这次会议。
[Geoffrey Marr][7]IRC 聊天室中名字叫 coremodule是 Red Hat 的一名员工和 Fedora 的贡献者,拥有 Linux 和云技术的背景。工作时,他潜心于 [Fedora QA][8] wiki 和测试页面中。业余时间, 他热衷于 RaspberryPi 项目尤其是专注于那些软件无线电Software-defined radio项目。
[Vipul Siddharth][9] 是Red Hat的实习生他也在Fedora上工作。他喜欢贡献开源借此机会传播自由开源软件。
### 加入会议
本次会议将在 [BlueJeans][10] 上进行。下面的信息可以帮你加入到会议:
* 网址: [https://bluejeans.com/3466040121][1]
* 会议 ID (桌面版): 3466040121
我们希望您可以参加,学习,并享受这个会议!如果您对会议有任何反馈意见,有什么新的想法或者想要主持一个会议, 可以随时在这篇文章发表评论或者查看[课堂 wiki 页面][11].
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/fedora-classroom-session-ansible-101/
作者:[Sachin S Kamath]
译者:[imquanquan](https://github.com/imquanquan)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[1]:https://bluejeans.com/3466040121
[2]:https://fedoramagazine.org/fedora-classroom-session-ansible-101/
[3]:https://fedoraproject.org/wiki/Classroom
[4]:https://fedoraproject.org/wiki/Classroom#Previous_Sessions
[5]:https://www.timeanddate.com/worldclock/fixedtime.html?msg=Fedora+Classroom+-+Ansible+101&iso=20171130T16&p1=%3A
[6]:http://docs.ansible.com/ansible/latest/index.html
[7]:https://fedoraproject.org/wiki/User:Coremodule
[8]:https://fedoraproject.org/wiki/QA
[9]:https://fedoraproject.org/wiki/User:Siddharthvipul1
[10]:https://www.bluejeans.com/downloads
[11]:https://fedoraproject.org/wiki/Classroom

View File

@ -0,0 +1,163 @@
如何在 Linux 系统中通过用户组来管理用户
============================================================
![groups](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/group-of-people-1645356_1920.jpg?itok=rJlAxBSV)
> 本教程可以了解如何通过用户组和访问控制表ACL来管理用户。
当你需要管理一台容纳多个用户的 Linux 机器时,比起一些基本的用户管理工具所提供的方法,有时候你需要对这些用户采取更多的用户权限管理方式。特别是当你要管理某些用户的权限时,这个想法尤为重要。比如说,你有一个目录,某个用户组中的用户可以通过读和写的权限访问这个目录,而其他用户组中的用户对这个目录只有读的权限。在 Linux 中这是完全可以实现的。但前提是你必须先了解如何通过用户组和访问控制表ACL来管理用户。
我们将从简单的用户开始逐渐深入到复杂的访问控制表ACL。你可以在你所选择的 Linux 发行版完成你所需要做的一切。本文的重点是用户组,所以不会涉及到关于用户的基础知识。
为了达到演示的目的,我将假设:
你需要用下面两个用户名新建两个用户:
* olivia
* nathan
你需要新建以下两个用户组:
* readers
* editors
olivia 属于 editors 用户组,而 nathan 属于 readers 用户组。reader 用户组对 `/DATA` 目录只有读的权限,而 editors 用户组则对 `/DATA` 目录同时有读和写的权限。当然,这是个非常小的任务,但它会给你基本的信息,你可以扩展这个任务以适应你其他更大的需求。
我将在 Ubuntu 16.04 Server 平台上进行演示。这些命令都是通用的,唯一不同的是,要是在你的发行版中不使用 `sudo` 命令,你必须切换到 root 用户来执行这些命令。
### 创建用户
我们需要做的第一件事是为我们的实验创建两个用户。可以用 `useradd` 命令来创建用户,我们不只是简单地创建一个用户,而需要同时创建用户和属于他们的家目录,然后给他们设置密码。
```
sudo useradd -m olivia
sudo useradd -m nathan
```
我们现在创建了两个用户,如果你看看 `/home` 目录,你可以发现他们的家目录(因为我们用了 `-m` 选项,可以在创建用户的同时创建他们的家目录。
之后,我们可以用以下命令给他们设置密码:
```
sudo passwd olivia
sudo passwd nathan
```
就这样,我们创建了两个用户。
### 创建用户组并添加用户
现在我们将创建 readers 和 editors 用户组,然后给它们添加用户。创建用户组的命令是:
```
addgroup readers
addgroup editors
```
LCTT 译注:当你使用 CentOS 等一些 Linux 发行版时,可能系统没有 `addgroup` 这个命令,推荐使用 `groupadd` 命令来替换 `addgroup` 命令以达到同样的效果)
![groups](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/groups_1.jpg?itok=BKwL89BB)
*图一:我们可以使用刚创建的新用户组了。*
创建用户组后,我们需要添加我们的用户到这两个用户组。我们用以下命令来将 nathan 用户添加到 readers 用户组:
```
sudo usermod -a -G readers nathan
```
用以下命令将 olivia 添加到 editors 用户组:
```
sudo usermod -a -G editors olivia
```
现在我们可以通过用户组来管理用户了。
### 给用户组授予目录的权限
假设你有个目录 `/READERS` 且允许 readers 用户组的所有成员访问这个目录。首先,我们执行以下命令来更改目录所属用户组:
```
sudo chown -R :readers /READERS
```
接下来,执行以下命令收回目录所属用户组的写入权限:
```
sudo chmod -R g-w /READERS
```
然后我们执行下面的命令来收回其他用户对这个目录的访问权限(以防止任何不在 readers 组中的用户访问这个目录里的文件):
```
sudo chmod -R o-x /READERS
```
这时候只有目录的所有者root和用户组 reader 中的用户可以访问 `/READES` 中的文件。
假设你有个目录 `/EDITORS` ,你需要给用户组 editors 里的成员这个目录的读和写的权限。为了达到这个目的,执行下面的这些命令是必要的:
```
sudo chown -R :editors /EDITORS
sudo chmod -R g+w /EDITORS
sudo chmod -R o-x /EDITORS
```
此时 editors 用户组的所有成员都可以访问和修改其中的文件。除此之外其他用户(除了 root 之外)无法访问 `/EDITORS` 中的任何文件。
使用这个方法的问题在于你一次只能操作一个组和一个目录而已。这时候访问控制表ACL就可以派得上用场了。
### 使用访问控制表ACL
现在,让我们把这个问题变得棘手一点。假设你有一个目录 `/DATA` 并且你想给 readers 用户组的成员读取权限,并同时给 editors 用户组的成员读和写的权限。为此,你必须要用到 `setfacl` 命令。`setfacl` 命令可以为文件或文件夹设置一个访问控制表ACL
这个命令的结构如下:
```
setfacl OPTION X:NAME:Y /DIRECTORY
```
其中 OPTION 是可选选项X 可以是 `u`(用户)或者是 `g` 用户组NAME 是用户或者用户组的名字,/DIRECTORY 是要用到的目录。我们将使用 `-m` 选项进行修改。因此,我们给 readers 用户组添加读取权限的命令是:
```
sudo setfacl -m g:readers:rx -R /DATA
```
现在 readers 用户组里面的每一个用户都可以读取 `/DATA` 目录里的文件了,但是他们不能修改里面的内容。
为了给 editors 用户组里面的用户读写权限,我们执行了以下命令:
```
sudo setfacl -m g:editors:rwx -R /DATA
```
上述命令将赋予 editors 用户组中的任何成员读取权限,同时保留 readers 用户组的只读权限。
### 更多的权限控制
使用访问控制表ACL你可以实现你所需的权限控制。你可以添加用户到用户组并且灵活地控制这些用户组对每个目录的权限以达到你的需求。如果想了解上述工具的更多信息可以执行下列的命令
* `man usradd`
* `man addgroup`
* `man usermod`
* `man sefacl`
* `man chown`
* `man chmod`
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2017/12/how-manage-users-groups-linux
作者:[Jack Wallen]
译者:[imquanquan](https://github.com/imquanquan)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[1]:https://www.linux.com/files/images/group-people-16453561920jpg
[2]:https://www.linux.com/files/images/groups1jpg
[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
[4]:https://www.linux.com/licenses/category/creative-commons-zero
[5]:https://www.linux.com/licenses/category/used-permission

View File

@ -0,0 +1,34 @@
Linux Journal 停止发行
============================================================
EOF
伙计们,看起来我们要到终点了。如果按照计划而且没有什么其他的话,十一月份的 Linux Journal 将是我们的最后一期。
简单的事实是,我们已经用完了钱和期权。我们从来没有一个富有的母公司或者自己深厚的资金,从开始到结束,这使得我们变成一个反常的出版商。虽然我们在很长的一段时间内运营着,但当天平不可恢复地最终向相反方向倾斜时,我们在十一月份失去了最后一点支持。
虽然我们像看到出版业的过去那样看到出版业的未来 - 广告商赞助出版物的时代,因为他们重视品牌和读者 - 我们如今的广告宁愿追逐眼球,最好是在读者的浏览器中植入跟踪标记,并随时随地展示那些广告。但是,未来不是这样,过去的已经过去了。
我们猜想,有一个希望,那就是救世主可能会会来。但除了我们的品牌、我们的档案,我们的域名、我们的用户和读者之外,还必须是愿意承担我们一部分债务的人。如果你认识任何人能够提供认真的报价,请告诉我们。不然,请观看 LinuxJournal.com并希望至少我们的遗留归档可以追溯到 Linux Journal 诞生的 1994 年 4 月,当 Linux 命中 1.0 发布时)将不会消失。这里有很多很棒的东西,还有很多我们会痛恨世界失去的历史。
我们最大的遗憾是,我们甚至没有足够的钱回馈最看重我们的人:我们的用户。为此,我们不能更深刻或真诚地道歉。我们对订阅者而言有什么:
Linux Pro Magazine 为我们的用户提供了六本免费的杂志,我们在 Linux Journal 上一直赞叹这点。在我们需要的时候,他们是我们的第一批人,我们感谢他们的恩惠。我们今天刚刚完成了我们的 2017 年归档,其中包括我们曾经发表过的每一个问题,包括第一个和最后一个。通常我们以 25 美元的价格出售,但显然用户将免费获得。订阅者请注意有关两者的详细信息的电子邮件。
我们也希望在知道我们非常非常努力地让 Linux Journal 进行下去后能有一些安慰 ,而且我们已经用最精益、小的可能运营了很长一段时间。我们是一个大多数是自愿者的组织,有些员工已经几个月没有收到工资。我们还欠钱给自由职业者。这时一个限制发行商能够维持多长时间的限制,现在这个限制已经到头了。
伙计们,这是一个伟大的运营。乡亲。对每一个为我们的诞生、我们的成功和我们多年的坚持作出贡献的人致敬。我们列了一份名单,但是列表太长了,并且漏掉有价值的人的风险很高。你知道你是谁。我们再次感谢。
--------------------------------------------------------------------------------
via: https://www.linuxjournal.com/content/linux-journal-ceases-publication
作者:[ Carlie Fairchild][a]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linuxjournal.com/users/carlie-fairchild
[1]:https://www.linuxjournal.com/taxonomy/term/29
[2]:https://www.linuxjournal.com/users/carlie-fairchild

View File

@ -0,0 +1,161 @@
在 Ubuntu 16.04 下随机化你的 WiFi MAC 地址
============================================================
> 你的设备的 MAC 地址可以在不同的 WiFi 网络中记录你的活动。这些信息能被共享后出售,用于识别特定的个体。但可以用随机生成的伪 MAC 地址来阻止这一行为。
![A captive portal screen for a hotel allowing you to log in with social media for an hour of free WiFi](https://www.paulfurley.com/img/captive-portal-our-hotel.gif)
_Image courtesy of [Cloudessa][4]_
每一个诸如 WiFi 或者以太网卡这样的网络设备,都有一个叫做 MAC 地址的唯一标识符,如:`b4:b6:76:31:8c:ff`。这就是你能上网的原因:每当你连上 WiFi路由器就会用这一地址来向你接受和发送数据并且用它来区别你和这一网络的其它设备。
这一设计的缺陷在于唯一性,不变的 MAC 地址正好可以用来追踪你。连上了星巴克的 WiFi? 好,注意到了。在伦敦的地铁上? 也记录下来。
如果你曾经在某一个 WiFi 验证页面上输入过你的真实姓名,你就已经把自己和这一 MAC 地址建立了联系。没有仔细阅读许可服务条款、你可以认为,机场的免费 WiFi 正通过出售所谓的 ‘顾客分析数据’(你的个人信息)获利。出售的对象包括酒店,餐饮业,和任何想要了解你的人。
我不想信息被记录,再出售给多家公司,所以我花了几个小时想出了一个解决方案。
### MAC 地址不一定总是不变的
幸运的是,在不断开网络的情况下,是可以随机生成一个伪 MAC 地址的。
我想随机生成我的 MAC 地址,但是有三个要求:
1. MAC 地址在不同网络中是不相同的。这意味着,我在星巴克和在伦敦地铁网络中的 MAC 地址是不相同的,这样在不同的服务提供商中就无法将我的活动系起来。
2. MAC 地址需要经常更换,这样在网络上就没人知道我就是去年在这儿经过了 75 次的那个人。
3. MAC 地址一天之内应该保持不变。当 MAC 地址更改时,大多数网络都会与你断开连接,然后必须得进入验证页面再次登陆 - 这很烦人。
### 操作<ruby>网络管理器<rt>NetworkManager</rt></ruby>
我第一次尝试用一个叫做 `macchanger` 的工具,但是失败了。因为<ruby>网络管理器<rt>NetworkManager</rt></ruby>会根据它自己的设置恢复默认的 MAC 地址。
我了解到,网络管理器 1.4.1 以上版本可以自动生成随机的 MAC 地址。如果你在使用 Ubuntu 17.04 版本,你可以根据[这一配置文件][7]实现这一目的。但这并不能完全符合我的三个要求(你必须在<ruby>随机<rt>random</rt></ruby><ruby>稳定<rt>stable</rt></ruby>这两个选项之中选择一个,但没有一天之内保持不变这一选项)
因为我使用的是 Ubuntu 16.04,网络管理器版本为 1.2,不能直接使用高版本这一新功能。可能网络管理器有一些随机化方法支持,但我没能成功。所以我编了一个脚本来实现这一目标。
幸运的是,网络管理器 1.2 允许模拟 MAC 地址。你在已连接的网络中可以看见 ‘编辑连接’ 这一选项:
![Screenshot of NetworkManager's edit connection dialog, showing a text entry for a cloned mac address](https:/www.paulfurley.com/img/network-manager-cloned-mac-address.png)
网络管理器也支持钩子处理 —— 任何位于 `/etc/NetworkManager/dispatcher.d/pre-up.d/` 的脚本在建立网络连接之前都会被执行。
### 分配随机生成的伪 MAC 地址
我想根据网络 ID 和日期来生成新的随机 MAC 地址。 我们可以使用网络管理器的命令行工具 nmcli 来显示所有可用网络:
```
> nmcli connection
NAME UUID TYPE DEVICE
Gladstone Guest 618545ca-d81a-11e7-a2a4-271245e11a45 802-11-wireless wlp1s0
DoESDinky 6e47c080-d81a-11e7-9921-87bc56777256 802-11-wireless --
PublicWiFi 79282c10-d81a-11e7-87cb-6341829c2a54 802-11-wireless --
virgintrainswifi 7d0c57de-d81a-11e7-9bae-5be89b161d22 802-11-wireless --
```
因为每个网络都有一个唯一标识符UUID为了实现我的计划我将 UUID 和日期拼接在一起,然后使用 MD5 生成 hash 值:
```
# eg 618545ca-d81a-11e7-a2a4-271245e11a45-2017-12-03
> echo -n "${UUID}-$(date +%F)" | md5sum
53594de990e92f9b914a723208f22b3f -
```
生成的结果可以代替 MAC 地址的最后八个字节。
值得注意的是,最开始的字节 `02` 代表这个地址是[自行指定][8]的。实际上,真实 MAC 地址的前三个字节是由制造商决定的,例如 `b4:b6:76` 就代表 Intel。
有可能某些路由器会拒绝自己指定的 MAC 地址,但是我还没有遇到过这种情况。
每次连接到一个网络,这一脚本都会用 `nmcli` 来指定一个随机生成的伪 MAC 地址:
![A terminal window show a number of nmcli command line calls](https://www.paulfurley.com/imgterminal-window-nmcli-commands.png)
最后,我查看了 `ifconfig` 的输出结果,我发现 MAC 地址 `HWaddr` 已经变成了随机生成的地址(模拟 Intel 的),而不是我真实的 MAC 地址。
```
> ifconfig
wlp1s0 Link encap:Ethernet HWaddr b4:b6:76:45:64:4d
inet addr:192.168.0.86 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::648c:aff2:9a9d:764/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12107812 errors:0 dropped:2 overruns:0 frame:0
TX packets:18332141 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:11627977017 (11.6 GB) TX bytes:20700627733 (20.7 GB)
```
### 脚本
完整的脚本也可以[在 Github 上查看][9]。
```
#!/bin/sh
# /etc/NetworkManager/dispatcher.d/pre-up.d/randomize-mac-addresses
# Configure every saved WiFi connection in NetworkManager with a spoofed MAC
# address, seeded from the UUID of the connection and the date eg:
# 'c31bbcc4-d6ad-11e7-9a5a-e7e1491a7e20-2017-11-20'
# This makes your MAC impossible(?) to track across WiFi providers, and
# for one provider to track across days.
# For craptive portals that authenticate based on MAC, you might want to
# automate logging in :)
# Note that NetworkManager >= 1.4.1 (Ubuntu 17.04+) can do something similar
# automatically.
export PATH=$PATH:/usr/bin:/bin
LOG_FILE=/var/log/randomize-mac-addresses
echo "$(date): $*" > ${LOG_FILE}
WIFI_UUIDS=$(nmcli --fields type,uuid connection show |grep 802-11-wireless |cut '-d ' -f3)
for UUID in ${WIFI_UUIDS}
do
UUID_DAILY_HASH=$(echo "${UUID}-$(date +F)" | md5sum)
RANDOM_MAC="02:$(echo -n ${UUID_DAILY_HASH} | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4:\5/')"
CMD="nmcli connection modify ${UUID} wifi.cloned-mac-address ${RANDOM_MAC}"
echo "$CMD" >> ${LOG_FILE}
$CMD &
done
wait
```
_更新[使用自己指定的 MAC 地址][5]可以避免和真正的 intel 地址冲突。感谢 [@_fink][6]_
---------------------------------------------------------------------------------
via: https://www.paulfurley.com/randomize-your-wifi-mac-address-on-ubuntu-1604-xenial/
作者:[Paul M Furley][a]
译者:[wenwensnow](https://github.com/wenwensnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.paulfurley.com/
[1]:https://gist.github.com/paulfurley/46e0547ce5c5ea7eabeaef50dbacef3f/raw/5f02fc8f6ff7fca5bca6ee4913c63bf6de15abcarandomize-mac-addresses
[2]:https://gist.github.com/paulfurley/46e0547ce5c5ea7eabeaef50dbacef3f#file-randomize-mac-addresses
[3]:https://github.com/
[4]:http://cloudessa.com/products/cloudessa-aaa-and-captive-portal-cloud-service/
[5]:https://gist.github.com/paulfurley/46e0547ce5c5ea7eabeaef50dbacef3f/revisions#diff-824d510864d58c07df01102a8f53faef
[6]:https://twitter.com/fink_/status/937305600005943296
[7]:https://gist.github.com/paulfurley/978d4e2e0cceb41d67d017a668106c53/
[8]:https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
[9]:https://gist.github.com/paulfurley/46e0547ce5c5ea7eabeaef50dbacef3f

View File

@ -0,0 +1,122 @@
Docker使用多阶段构建镜像
============================================================
多阶段构建是 Docker 17.05 及更高版本提供的新功能。这对致力于优化 Dockerfile 的人来说,使得 Dockerfile 易于阅读和维护。
> 致谢: 特别感谢 [Alex Ellis][1] 授权使用他的关于 Docker 多阶段构建的博客文章 [Builder pattern vs. Multi-stage builds in Docker][2] 作为以下示例的基础。
### 在多阶段构建之前
关于构建镜像最具挑战性的事情之一是保持镜像体积小巧。 Dockerfile 中的每条指令都会在镜像中增加一层,并且在移动到下一层之前,需要记住清除不需要的构件。要编写一个非常高效的 Dockerfile你通常需要使用 shell 技巧和其它方式来尽可能地减少层数,并确保每一层都具有上一层所需的构件,而其它任何东西都不需要。
实际上最常见的是,有一个 Dockerfile 用于开发(其中包含构建应用程序所需的所有内容),而另一个裁剪过的用于生产环境,它只包含您的应用程序以及运行它所需的内容。这被称为“构建器模式”。但是维护两个 Dockerfile 并不理想。
下面分别是一个 `Dockerfile.build` 和遵循上面的构建器模式的 `Dockerfile` 的例子:
`Dockerfile.build`
```
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN go get -d -v golang.org/x/net/html \
&& CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
```
注意这个例子还使用 Bash 的 `&&` 运算符人为地将两个 `RUN` 命令压缩在一起,以避免在镜像中创建额外的层。这很容易失败,难以维护。例如,插入另一个命令时,很容易忘记继续使用 `\` 字符。
`Dockerfile`
```
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]
```
`build.sh`
```
#!/bin/sh
echo Building alexellis2/href-counter:build
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
-t alexellis2/href-counter:build . -f Dockerfile.build
docker create --name extract alexellis2/href-counter:build
docker cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker rm -f extract
echo Building alexellis2/href-counter:latest
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app
```
当您运行 `build.sh` 脚本时,它会构建第一个镜像,从中创建一个容器,以便将该构件复制出来,然后构建第二个镜像。 这两个镜像会占用您的系统的空间,而你仍然会一个 `app` 构件存放在你的本地磁盘上。
多阶段构建大大简化了这种情况!
### 使用多阶段构建
在多阶段构建中,您需要在 Dockerfile 中多次使用 `FROM` 声明。每次 `FROM` 指令可以使用不同的基础镜像,并且每次 `FROM` 指令都会开始新阶段的构建。您可以选择将构件从一个阶段复制到另一个阶段,在最终镜像中,不会留下您不需要的所有内容。为了演示这是如何工作的,让我们调整前一节中的 Dockerfile 以使用多阶段构建。
`Dockerfile`
```
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
```
您只需要单一个 Dockerfile。 不需要另外的构建脚本。只需运行 `docker build` 即可。
```
$ docker build -t alexellis2/href-counter:latest .
```
最终的结果是和以前体积一样小的生产镜像,复杂性显著降低。您不需要创建任何中间镜像,也不需要将任何构件提取到本地系统。
它是如何工作的呢?第二条 `FROM` 指令以 `alpine:latest` 镜像作为基础开始新的建造阶段。`COPY --from=0` 这一行将刚才前一个阶段产生的构件复制到这个新阶段。Go SDK 和任何中间构件都被留在那里,而不会保存到最终的镜像中。
### 命名您的构建阶段
默认情况下,这些阶段没有命名,您可以通过它们的整数来引用它们,从第一个 `FROM` 指令的 0 开始。但是,你可以通过在 `FROM` 指令中使用 `as <NAME>` 来为阶段命名。以下示例通过命名阶段并在 `COPY` 指令中使用名称来改进前一个示例。这意味着,即使您的 `Dockerfile` 中的指令稍后重新排序,`COPY` 也不会出问题。
```
FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
```
--------------------------------------------------------------------------------
via: https://docs.docker.com/engine/userguide/eng-image/multistage-build/
作者:[docker][a]
译者:[iron0x](https://github.com/iron0x)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://docs.docker.com/engine/userguide/eng-image/multistage-build/
[1]:https://twitter.com/alexellisuk
[2]:http://blog.alexellis.io/mutli-stage-docker-builds/

View File

@ -0,0 +1,298 @@
2017 年 30 款最好的支持 Linux 的 Steam 游戏
============================================================
说到游戏,人们一般都会推荐使用 Windows 系统。Windows 能提供更好的显卡支持和硬件兼容性,所以对于游戏爱好者来说的确是个更好的选择。但你是否想过[在 Linux 系统上玩游戏][9]?这的确是可以的,也许你以前还曾经考虑过。但在几年之前, [Steam for Linux][10] 上可玩的游戏并不是很吸引人。
但现在情况完全不一样了。Steam 商店里现在有许多支持 Linux 平台的游戏(包括很多主流大作)。我们在本文中将介绍 Steam 上最好的一些 Linux 游戏。
在进入正题之前,先介绍一个省钱小窍门。如果你是个狂热的游戏爱好者,在游戏上花费很多时间和金钱的话,我建议你订阅 [<ruby>Humble 每月包<rt>Humble Monthly</rt></ruby>][11]。这是个每月收费的订阅服务,每月只用 12 美元就能获得价值 100 美元的游戏。
这个游戏包中可能有些游戏不支持 Linux但除了 Steam 游戏之外,它还会让 [Humble Bundle 网站][12]上所有的游戏和书籍都打九折,所以这依然是个不错的优惠。
更棒的是,你在 Humble Bundle 上所有的消费都会捐出一部分给慈善机构。所以你在享受游戏的同时还在帮助改变世界。
### Steam 上最好的 Linux 游戏
以下排名无先后顺序。
额外提示:虽然在 Steam 上有很多支持 Linux 的游戏,但你在 Linux 上玩游戏时依然可能会遇到各种问题。你可以阅读我们之前的文章:[每个 Linux 游戏玩家都会遇到的烦人问题][14]
可以点击以下链接跳转到你喜欢的游戏类型:
* [动作类游戏][3]
* [角色扮演类游戏][4]
* [赛车/运动/模拟类游戏][5]
* [冒险类游戏][6]
* [独立游戏][7]
* [策略类游戏][8]
### Steam 上最佳 Linux 动作类游戏
#### 1、 《<ruby>反恐精英:全球攻势<rt>Counter-Strike: Global Offensive</rt></ruby>》(多人)
《CS:GO》毫无疑问是 Steam 上支持 Linux 的最好的 FPS 游戏之一。我觉得这款游戏无需介绍,但如果你没有听说过它,我要告诉你这将会是你玩过的最好玩的多人 FPS 游戏之一。《CS:GO》还是电子竞技中的一个主流项目。想要提升等级的话你需要在天梯上和其他玩家同台竞技。但你也可以选择更加轻松的休闲模式。
我本想写《彩虹六号:围攻行动》,但它目前还不支持 Linux 或 Steam OS。
- [购买《CS: GO》][15]
#### 2、 《<ruby>求生之路 2<rt>Left 4 Dead 2</rt></ruby>》(多人/单机)
这是最受欢迎的僵尸主题多人 FPS 游戏之一。在 Steam 优惠时,价格可以低至 1.3 美元。这是个有趣的游戏,能让你体会到你在僵尸游戏中期待的战栗和刺激。游戏中的环境包括了沼泽、城市、墓地等等,让游戏既有趣又吓人。游戏中的枪械并不是非常先进,但作为一个老游戏来说,它已经提供了足够真实的体验。
- [购买《求生之路 2》][16]
#### 3、 《<ruby>无主之地 2<rt>Borderlands 2</rt></ruby>》(单机/协作)
《无主之地 2》是个很有意思的 FPS 游戏。它和你以前玩过的游戏完全不同。画风看上去有些诡异和卡通化,如果你正在寻找一个第一视角的射击游戏,我可以保证,游戏体验可一点也不逊色!
如果你在寻找一个好玩而且有很多 DLC 的 Linux 游戏,《无主之地 2》绝对是个不错的选择。
- [购买《无主之地 2》][17]
#### 4、 《<ruby>叛乱<rt>Insurgency</rt></ruby>》(多人)
《叛乱》是 Steam 上又一款支持 Linux 的优秀的 FPS 游戏。它剑走偏锋,从屏幕上去掉了 HUD 和弹药数量指示。如同许多评论者所说,这是款注重武器和团队战术的纯粹的射击游戏。这也许不是最好的 FPS 游戏,但如果你想玩和《三角洲部队》类似的多人游戏的话,这绝对是最好的游戏之一。
- [购买《叛乱》][18]
#### 5、 《<ruby>生化奇兵:无限<rt>Bioshock: Infinite</rt></ruby>》(单机)
《生化奇兵:无限》毫无疑问将会作为 PC 平台最好的单机 FPS 游戏之一而载入史册。你可以利用很多强大的能力来杀死你的敌人。同时你的敌人也各个身怀绝技。游戏的剧情也非常丰富。你不容错过!
- [购买《生化奇兵:无限》][19]
#### 6、 《<ruby>杀手(年度版)<rt>HITMAN - Game of the Year Edition</rt></ruby>》(单机)
《杀手》系列无疑是 PC 游戏爱好者们的最爱之一。本系列的最新作开始按章节发布,让很多玩家觉得不满。但现在 Square Enix 撤出了开发而最新的年度版带着新的内容重返舞台。在游戏中发挥你的想象力暗杀你的目标吧杀手47
- [购买(杀手(年度版))][20]
#### 7、 《<ruby>传送门 2<rt>Portal 2</rt></ruby>
《传送门 2》完美地结合了动作与冒险。这是款解谜类游戏你可以与其他玩家协作并开发有趣的谜题。协作模式提供了和单机模式截然不同的游戏内容。
- [购买《传送门2》][21]
#### 8、 《<ruby>杀出重围:人类分裂<rt>Deux Ex: Mankind Divided</rt></ruby>
如果你在寻找隐蔽类的射击游戏,《杀出重围》是个填充你的 Steam 游戏库的完美选择。这是个非常华丽的游戏,有着最先进的武器和超乎寻常的战斗机制。
- [购买《杀出重围:人类分裂》][22]
#### 9、 《<ruby>地铁 2033 重置版<rt>Metro 2033 Redux</rt></ruby>》 / 《<ruby>地铁:最后曙光 重置版<rt>Metro Last Light Redux</rt></ruby>
《地铁 2033 重置版》和《地铁:最后曙光 重置版》是经典的《地铁 2033》和《地铁最后曙光》的最终版本。故事发生在世界末日之后。你需要消灭所有的变种人来保证人类的生存。剩下的就交给你自己去探索了
- [购买《地铁 2033 重置版》][23]
- [购买《地铁:最后曙光 重置版》][24]
#### 10、 《<ruby>坦能堡<rt>Tannenberg</rt></ruby>》(多人)
《坦能堡》是个全新的游戏 - 在本文发表一个月前刚刚发售。游戏背景是第一次世界大战的东线战场1914-1918。这款游戏只有多人模式。如果你想要在游戏中体验第一次世界大战不要错过这款游戏
- [购买《坦能堡》][25]
### Steam 上最佳 Linux 角色扮演类游戏
#### 11、 《<ruby>中土世界:暗影魔多<rt>Shadow of Mordor</rt></ruby>
《中土世界:暗影魔多》 是 Steam 上支持 Linux 的最好的开放式角色扮演类游戏之一。你将扮演一个游侠(塔里昂),和光明领主(凯勒布理鹏)并肩作战击败索隆的军队(并最终和他直接交手)。战斗机制非常出色。这是款不得不玩的游戏!
- [购买《中土世界:暗影魔多》][26]
#### 12、 《<ruby>神界:原罪加强版<rt>Divinity: Original Sin Enhanced Edition</rt></ruby>
《神界:原罪》是一款极其优秀的角色扮演类独立游戏。它非常独特而又引人入胜。这或许是评分最高的带有冒险和策略元素的角色扮演游戏。加强版添加了新的游戏模式,并且完全重做了配音、手柄支持、协作任务等等。
- [购买《神界:原罪加强版》][27]
#### 13、 《<ruby>废土 2导演剪辑版<rt>Wasteland 2: Directors Cut</rt></ruby>
《废土 2》是一款出色的 CRPG 游戏。如果《辐射 4》被移植成 CRPG 游戏,大概就是这种感觉。导演剪辑版完全重做了画面,并且增加了一百多名新人物。
- [购买《废土 2》][28]
#### 14、 《<ruby>阴暗森林<rt>Darkwood</rt></ruby>
一个充满恐怖的俯视角角色扮演类游戏。你将探索世界、搜集材料、制作武器来生存下去。
- [购买《阴暗森林》][29]
### 最佳赛车 / 运动 / 模拟类游戏
#### 15、 《<ruby>火箭联盟<rt>Rocket League</rt></ruby>
《火箭联盟》是一款充满刺激的足球游戏。游戏中你将驾驶用火箭助推的战斗赛车。你不仅是要驾车把球带进对方球门,你甚至还可以让你的对手化为灰烬!
这是款超棒的体育动作类游戏,每个游戏爱好者都值得拥有!
- [购买《火箭联盟》][30]
#### 16、 《<ruby>公路救赎<rt>Road Redemption</rt></ruby>
想念《暴力摩托》了?作为它精神上的续作,《公路救赎》可以缓解你的饥渴。当然,这并不是真正的《暴力摩托 2》但它一样有趣。如果你喜欢《暴力摩托》你也会喜欢这款游戏。
- [购买《公路救赎》][31]
#### 17、 《<ruby>尘埃拉力赛<rt>Dirt Rally</rt></ruby>
《尘埃拉力赛》是为想要体验公路和越野赛车的玩家准备的。画面非常有魄力,驾驶手感也近乎完美。
- [购买《尘埃拉力赛》][32]
#### 18、 《F1 2017》
《F1 2017》是另一款令人印象深刻的赛车游戏。由《尘埃拉力赛》的开发者 Codemasters & Feral Interactive 制作。游戏中包含了所有标志性的 F1 赛车,值得你去体验。
- [购买《F1 2017》][33]
#### 19、 《<ruby>超级房车赛:汽车运动<rt>GRID Autosport</rt></ruby>
《超级房车赛》是最被低估的赛车游戏之一。《超级房车赛:汽车运动》是《超级房车赛》的续作。这款游戏的可玩性令人惊艳。游戏中的赛车也比前作更好。推荐所有的 PC 游戏玩家尝试这款赛车游戏。游戏还支持多人模式,你可以和你的朋友组队参赛。
- [购买《超级房车赛:汽车运动》][34]
### 最好的冒险游戏
#### 20、 《<ruby>方舟:生存进化<rt>ARK: Survival Evolved</rt></ruby>
《方舟:生存进化》是一款不错的生存游戏,里面有着激动人心的冒险。你发现自己身处一个未知孤岛(方舟岛),为了生存下去并逃离这个孤岛,你必须去驯服恐龙、与其他玩家合作、猎杀其他人来抢夺资源、以及制作物品。
- [购买《方舟:生存进化》][35]
#### 21、 《<ruby>这是我的战争<rt>This War of Mine</rt></ruby>
一款独特的战争游戏。你不是扮演士兵,而是要作为一个平民来面对战争带来的艰难。你需要在身经百战的敌人手下逃生,并帮助其他的幸存者。
- [购买《这是我的战争》][36]
#### 22、 《<ruby>疯狂的麦克斯<rt>Mad Max</rt></ruby>
生存和暴力概括了《疯狂的麦克斯》的全部内容。游戏中有性能强大的汽车,开放性的世界,各种武器,以及徒手肉搏。你要不断地探索世界,并注意升级你的汽车来防患于未然。在做决定之前,你要仔细思考并设计好策略。
- [购买《疯狂的麦克斯》][37]
### 最佳独立游戏
#### 23、 《<ruby>泰拉瑞亚<rt>Terraria</rt></ruby>
这是款在 Steam 上广受好评的 2D 游戏。你在旅途中需要去挖掘、战斗、探索、建造。游戏地图是自动生成的,而不是固定不变的。也许你刚刚遇到的东西,你的朋友过一会儿才会遇到。你还将体验到富有新意的 2D 动作场景。
- [购买《泰拉瑞亚》][38]
#### 24、 《<ruby>王国与城堡<rt>Kingdoms and Castles</rt></ruby>
在《王国与城堡》中,你将建造你自己的王国。在管理你的王国的过程中,你需要收税、保护森林、规划城市,并且发展国防来防止别人入侵你的王国。
这是款比较新的游戏,但在独立游戏中已经相对获得了比较高的人气。
- [购买《王国与城堡》][39]
### Steam 上最佳 Linux 策略类游戏
#### 25、 《<ruby>文明 5<rt>Sid Meiers Civilization V</rt></ruby>
《文明 5》是 PC 上评价最高的策略游戏之一。如果你想的话,你可以去玩《文明 6》。但是依然有许多玩家喜欢《文明 5》觉得它更有独创性游戏细节也更富有创造力。
- [购买《文明 5》][40]
#### 26、 《<ruby>全面战争:战锤<rt>Total War: Warhammer</rt></ruby>
《全面战争:战锤》是 PC 平台上一款非常出色的回合制策略游戏。可惜的是,新作《战锤 2》依然不支持 Linux。但如果你喜欢使用飞龙和魔法来建造与毁灭帝国的话2016 年的《战锤》依然是个不错的选择。
- [购买《全面战争:战锤》][41]
#### 27、 《<ruby>轰炸小队<rt>Bomber Crew</rt></ruby>
想要一款充满乐趣的策略游戏?《轰炸小队》就是为你准备的。你需要选择合适的队员并且让你的队伍稳定运转来取得最终的胜利。
- [购买《轰炸小队》][42]
#### 28、 《<ruby>奇迹时代 3<rt>Age of Wonders III</rt></ruby>
非常流行的策略游戏,包含帝国建造、角色扮演、以及战争元素。这是款精致的回合制策略游戏,请一定要试试!
- [购买《奇迹时代 3》][43]
#### 29、 《<ruby>城市:天际线<rt>Cities: Skylines</rt></ruby>
一款非常简洁的策略游戏。你要从零开始建造一座城市,并且管理它的全部运作。你将体验建造和管理城市带来的愉悦与困难。我不觉得每个玩家都会喜欢这款游戏——它的用户群体非常明确。
- [购买《城市:天际线》][44]
#### 30、 《<ruby>幽浮 2<rt>XCOM 2</rt></ruby>
《幽浮 2》是 PC 上最好的回合制策略游戏之一。我在想如果《幽浮 2》能够被制作成 FPS 游戏的话该有多棒。不过它现在已经是一款好评如潮的杰作了。如果你有多余的预算能花在这款游戏上,建议你购买“<ruby>天选之战<rt>War of the Chosen</rt></ruby>“ DLC。
- [购买《幽浮 2》][45]
### 总结
我们从所有支持 Linux 的游戏中挑选了大部分的主流大作以及一些评价很高的新作。
你觉得我们遗漏了你最喜欢的支持 Linux 的 Steam 游戏么?另外,你还希望哪些 Steam 游戏开始支持 Linux 平台?
请在下面的回复中告诉我们你的想法。
--------------------------------------------------------------------------------
via: https://itsfoss.com/best-linux-games-steam/
作者:[Ankush Das][a]
译者:[yixunx](https://github.com/yixunx)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://itsfoss.com/author/ankush/
[1]:https://itsfoss.com/author/ankush/
[2]:https://itsfoss.com/best-linux-games-steam/#comments
[3]:https://itsfoss.com/best-linux-games-steam/#action
[4]:https://itsfoss.com/best-linux-games-steam/#rpg
[5]:https://itsfoss.com/best-linux-games-steam/#racing
[6]:https://itsfoss.com/best-linux-games-steam/#adv
[7]:https://itsfoss.com/best-linux-games-steam/#indie
[8]:https://itsfoss.com/best-linux-games-steam/#strategy
[9]:https://linux.cn/article-7316-1.html
[10]:https://itsfoss.com/install-steam-ubuntu-linux/
[11]:https://www.humblebundle.com/?partner=itsfoss
[12]:https://www.humblebundle.com/store?partner=itsfoss
[13]:https://www.humblebundle.com/monthly?partner=itsfoss
[14]:https://itsfoss.com/linux-gaming-problems/
[15]:http://store.steampowered.com/app/730/CounterStrike_Global_Offensive/
[16]:http://store.steampowered.com/app/550/Left_4_Dead_2/
[17]:http://store.steampowered.com/app/49520/?snr=1_5_9__205
[18]:http://store.steampowered.com/app/222880/?snr=1_5_9__205
[19]:http://store.steampowered.com/agecheck/app/8870/
[20]:http://store.steampowered.com/app/236870/?snr=1_5_9__205
[21]:http://store.steampowered.com/app/620/?snr=1_5_9__205
[22]:http://store.steampowered.com/app/337000/?snr=1_5_9__205
[23]:http://store.steampowered.com/app/286690/?snr=1_5_9__205
[24]:http://store.steampowered.com/app/287390/?snr=1_5_9__205
[25]:http://store.steampowered.com/app/633460/?snr=1_5_9__205
[26]:http://store.steampowered.com/app/241930/?snr=1_5_9__205
[27]:http://store.steampowered.com/app/373420/?snr=1_5_9__205
[28]:http://store.steampowered.com/app/240760/?snr=1_5_9__205
[29]:http://store.steampowered.com/app/274520/?snr=1_5_9__205
[30]:http://store.steampowered.com/app/252950/?snr=1_5_9__205
[31]:http://store.steampowered.com/app/300380/?snr=1_5_9__205
[32]:http://store.steampowered.com/app/310560/?snr=1_5_9__205
[33]:http://store.steampowered.com/app/515220/?snr=1_5_9__205
[34]:http://store.steampowered.com/app/255220/?snr=1_5_9__205
[35]:http://store.steampowered.com/app/346110/?snr=1_5_9__205
[36]:http://store.steampowered.com/app/282070/?snr=1_5_9__205
[37]:http://store.steampowered.com/app/234140/?snr=1_5_9__205
[38]:http://store.steampowered.com/app/105600/?snr=1_5_9__205
[39]:http://store.steampowered.com/app/569480/?snr=1_5_9__205
[40]:http://store.steampowered.com/app/8930/?snr=1_5_9__205
[41]:http://store.steampowered.com/app/364360/?snr=1_5_9__205
[42]:http://store.steampowered.com/app/537800/?snr=1_5_9__205
[43]:http://store.steampowered.com/app/226840/?snr=1_5_9__205
[44]:http://store.steampowered.com/app/255710/?snr=1_5_9__205
[45]:http://store.steampowered.com/app/268500/?snr=1_5_9__205
[46]:https://www.facebook.com/share.php?u=https%3A%2F%2Fitsfoss.com%2Fbest-linux-games-steam%2F%3Futm_source%3Dfacebook%26utm_medium%3Dsocial%26utm_campaign%3DSocialWarfare
[47]:https://twitter.com/share?original_referer=/&text=30+Best+Linux+Games+On+Steam+You+Should+Play+in+2017&url=https://itsfoss.com/best-linux-games-steam/%3Futm_source%3Dtwitter%26utm_medium%3Dsocial%26utm_campaign%3DSocialWarfare&via=ankushdas9
[48]:https://plus.google.com/share?url=https%3A%2F%2Fitsfoss.com%2Fbest-linux-games-steam%2F%3Futm_source%3DgooglePlus%26utm_medium%3Dsocial%26utm_campaign%3DSocialWarfare
[49]:https://www.linkedin.com/cws/share?url=https%3A%2F%2Fitsfoss.com%2Fbest-linux-games-steam%2F%3Futm_source%3DlinkedIn%26utm_medium%3Dsocial%26utm_campaign%3DSocialWarfare
[50]:https://www.reddit.com/submit?url=https://itsfoss.com/best-linux-games-steam/&title=30+Best+Linux+Games+On+Steam+You+Should+Play+in+2017

Some files were not shown because too many files have changed in this diff Show More