diff --git a/README.md b/README.md index fba9abe8ae..2769014a6a 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ LCTT 的组成 * 2017/11/19 wxy 在上海交大举办的 2017 中国开源年会上做了演讲:《[如何以翻译贡献参与开源社区](https://linux.cn/article-9084-1.html)》。 * 2018/01/11 提升 lujun9972 成为核心成员,并加入选题组。 * 2018/02/20 遭遇 DMCA 仓库被封。 +* 2018/05/15 提升 MjSeven 为核心成员。 核心成员 ------------------------------- @@ -92,6 +93,7 @@ LCTT 的组成 - 核心成员 @rusking, - 核心成员 @qhwdw, - 核心成员 @lujun9972 +- 核心成员 @MjSeven - 前任选题 @DeadFire, - 前任校对 @reinoir222, - 前任校对 @PurlingNayuki, diff --git a/published/20140107 Caffeinated 6.828- Exercise- Shell.md b/published/20140107 Caffeinated 6.828- Exercise- Shell.md new file mode 100644 index 0000000000..126e8c2913 --- /dev/null +++ b/published/20140107 Caffeinated 6.828- Exercise- Shell.md @@ -0,0 +1,103 @@ +Caffeinated 6.828:练习 shell +====== + +通过在 shell 中实现多项功能,该作业将使你更加熟悉 Unix 系统调用接口和 shell。你可以在支持 Unix API 的任何操作系统(一台 Linux Athena 机器、装有 Linux 或 Mac OS 的笔记本电脑等)上完成此作业。请在第一次上课前将你的 shell 提交到[网站][1]。 + +如果你在练习中遇到困难或不理解某些内容时,你不要羞于给[员工邮件列表][2]发送邮件,但我们确实希望全班的人能够自行处理这级别的 C 编程。如果你对 C 不是很熟悉,可以认为这个是你对 C 熟悉程度的检查。再说一次,如果你有任何问题,鼓励你向我们寻求帮助。 + +下载 xv6 shell 的[框架][3],然后查看它。框架 shell 包含两个主要部分:解析 shell 命令并实现它们。解析器只能识别简单的 shell 命令,如下所示: + +``` +ls > y +cat < y | sort | uniq | wc > y1 +cat y1 +rm y1 +ls | sort | uniq | wc +rm y +``` + +将这些命令剪切并粘贴到 `t.sh` 中。 + +你可以按如下方式编译框架 shell 的代码: + +``` +$ gcc sh.c +``` + +它会生成一个名为 `a.out` 的文件,你可以运行它: + +``` +$ ./a.out < t.sh +``` + +执行会崩溃,因为你还没有实现其中的几个功能。在本作业的其余部分中,你将实现这些功能。 + +### 执行简单的命令 + +实现简单的命令,例如: + +``` +$ ls +``` + +解析器已经为你构建了一个 `execcmd`,所以你唯一需要编写的代码是 `runcmd` 中的 case ' '。要测试你可以运行 “ls”。你可能会发现查看 `exec` 的手册页是很有用的。输入 `man 3 exec`。 + +你不必实现引用(即将双引号之间的文本视为单个参数)。 + +### I/O 重定向 + +实现 I/O 重定向命令,这样你可以运行: + +``` +echo "6.828 is cool" > x.txt +cat < x.txt +``` + +解析器已经识别出 '>' 和 '<',并且为你构建了一个 `redircmd`,所以你的工作就是在 `runcmd` 中为这些符号填写缺少的代码。确保你的实现在上面的测试输入中正确运行。你可能会发现 `open`(`man 2 open`) 和 `close` 的 man 手册页很有用。 + +请注意,此 shell 不会像 `bash`、`tcsh`、`zsh` 或其他 UNIX shell 那样处理引号,并且你的示例文件 `x.txt` 预计包含引号。 + +### 实现管道 + +实现管道,这样你可以运行命令管道,例如: + +``` +$ ls | sort | uniq | wc +``` + +解析器已经识别出 “|”,并且为你构建了一个 `pipecmd`,所以你必须编写的唯一代码是 `runcmd` 中的 case '|'。测试你可以运行上面的管道。你可能会发现 `pipe`、`fork`、`close` 和 `dup` 的 man 手册页很有用。 + +现在你应该可以正确地使用以下命令: + +``` +$ ./a.out < t.sh +``` + +无论是否完成挑战任务,不要忘记将你的答案提交给[网站][1]。 + +### 挑战练习 + +如果你想进一步尝试,可以将所选的任何功能添加到你的 shell。你可以尝试以下建议之一: + +* 实现由 `;` 分隔的命令列表 +* 通过实现 `(` 和 `)` 来实现子 shell +* 通过支持 `&` 和 `wait` 在后台执行命令 +* 实现参数引用 + + +所有这些都需要改变解析器和 `runcmd` 函数。 + +-------------------------------------------------------------------------------- + +via: https://sipb.mit.edu/iap/6.828/lab/shell/ + +作者:[mit][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://sipb.mit.edu +[1]:https://exokernel.scripts.mit.edu/submit/ +[2]:mailto:sipb-iap-6.828@mit.edu +[3]:https://sipb.mit.edu/iap/6.828/files/sh.c diff --git a/published/20140403 Easily Install Android Studio in Ubuntu And Linux Mint.md b/published/20140403 Easily Install Android Studio in Ubuntu And Linux Mint.md new file mode 100644 index 0000000000..6ff17f74c9 --- /dev/null +++ b/published/20140403 Easily Install Android Studio in Ubuntu And Linux Mint.md @@ -0,0 +1,101 @@ +在 Ubuntu 和 Linux Mint 中轻松安装 Android Studio +====== + +[Android Studio][1] 是谷歌自己的 Android 开发 IDE,是带 ADT 插件的 Eclipse 的不错替代品。Android Studio 可以通过源代码安装,但在这篇文章中,我们将看到**如何在 Ubuntu 18.04、16.04 和相应的 Linux Mint 变体**中安装 Android Studio。 + +在继续安装 Android Studio 之前,请确保你已经[在 Ubuntu 中安装了 Java][2]。 + +![How to install Android Studio in Ubuntu][3] + +### 使用 Snap 在 Ubuntu 和其他发行版中安装 Android Studio + +自从 Ubuntu 开始专注于 Snap 软件包以来,越来越多的软件开始提供易于安装的 Snap 软件包。Android Studio 就是其中之一。Ubuntu 用户可以直接在软件中心找到 Android Studio 程序并从那里安装。 + +![Install Android Studio in Ubuntu from Software Center][4] + +如果你在软件中心安装 Android Studio 时看到错误,则可以使用[ Snap 命令][5] 安装 Android Studio。 + +``` +sudo snap install android-studio --classic +``` + +非常简单! + +### 另一种方式 1:在 Ubuntu 中使用 umake 安装 Android Studio + +你也可以使用 Ubuntu Developer Tools Center,现在称为 [Ubuntu Make][6],轻松安装 Android Studio。Ubuntu Make 提供了一个命令行工具来安装各种开发工具和 IDE 等。Ubuntu Make 在 Ubuntu 仓库中就有。 + +要安装 Ubuntu Make,请在终端中使用以下命令: + +``` +sudo apt-get install ubuntu-make +``` + +安装 Ubuntu Make 后,请使用以下命令在 Ubuntu 中安装 Android Studio: + +``` +umake android +``` + +在安装过程中它会给你的几个选项。我认为你可以处理。如果你决定卸载 Android Studio,则可以按照以下方式使用相同的 umake 工具: + +``` +umake android --remove + +``` + +### 另一种方式 2:通过非官方的 PPA 在 Ubuntu 和 Linux Mint 中安装 Android Studio + +感谢 [Paolo Ratolo][7],我们有一个 PPA,可用于 Ubuntu 16.04、14.04、Linux Mint 和其他基于 Ubuntu 的发行版中轻松安装 Android Studio。请注意,它将下载大约 650MB 的数据。请注意你的互联网连接以及数据费用(如果有的话)。 + +打开一个终端并使用以下命令: + +``` +sudo apt-add-repository ppa:paolorotolo/android-studio +sudo apt-get update +sudo apt-get install android-studio +``` + +这不容易吗?虽然从源代码安装程序很有趣,但拥有这样的 PPA 总是不错的。我们看到了如何安装 Android Studio,现在来看看如何卸载它。 + +### 卸载 Android Studio: + +如果你还没有安装 PPA Purge: + +``` +sudo apt-get install ppa-purge +``` + +现在使用 PPA Purge 来清除已安装的 PPA: + +``` +sudo apt-get remove android-studio +sudo ppa-purge ppa:paolorotolo/android-studio +``` + +就是这些了。我希望这能够帮助你**在 Ubuntu 和 Linux Mint 上安装 Android Studio**。在运行 Android Studio 之前,请确保[在 Ubuntu 中安装了Java][8]。在类似的文章中,我建议你阅读[如何安装和配置 Ubuntu SDK ][9]和[如何在 Ubuntu 中轻松安装 Microsoft Visual Studio][10]。 + +欢迎提出任何问题或建议。再见 :) + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/install-android-studio-ubuntu-linux/ + +作者:[Abhishek Prakash][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://itsfoss.com/author/abhishek/ +[1]:http://developer.android.com/sdk/installing/studio.html +[2]:https://itsfoss.com/install-java-ubuntu-1404/ +[3]:https://itsfoss.com/wp-content/uploads/2014/04/Android_Studio_Ubuntu.jpeg +[4]:https://itsfoss.com/wp-content/uploads/2014/04/install-android-studio-snap-800x469.jpg +[5]:https://itsfoss.com/install-snap-linux/ +[6]:https://wiki.ubuntu.com/ubuntu-make +[7]:https://plus.google.com/+PaoloRotolo +[8]:https://itsfoss.com/install-java-ubuntu-1404/ (How To Install Java On Ubuntu 14.04) +[9]:https://itsfoss.com/install-configure-ubuntu-sdk/ +[10]:https://itsfoss.com/install-visual-studio-code-ubuntu/ diff --git a/published/20140410 Recursion- dream within a dream.md b/published/20140410 Recursion- dream within a dream.md new file mode 100644 index 0000000000..8056001960 --- /dev/null +++ b/published/20140410 Recursion- dream within a dream.md @@ -0,0 +1,129 @@ +递归:梦中梦 +====== + +> “方其梦也,不知其梦也。梦之中又占其梦焉,觉而后知其梦也。” —— 《庄子·齐物论》 + +**递归**是很神奇的,但是在大多数的编程类书藉中对递归讲解的并不好。它们只是给你展示一个递归阶乘的实现,然后警告你递归运行的很慢,并且还有可能因为栈缓冲区溢出而崩溃。“你可以将头伸进微波炉中去烘干你的头发,但是需要警惕颅内高压并让你的头发生爆炸,或者你可以使用毛巾来擦干头发。”难怪人们不愿意使用递归。但这种建议是很糟糕的,因为在算法中,递归是一个非常强大的思想。 + +我们来看一下这个经典的递归阶乘: + +``` +#include + +int factorial(int n) +{ + int previous = 0xdeadbeef; + + if (n == 0 || n == 1) { + return 1; + } + + previous = factorial(n-1); + return n * previous; +} + +int main(int argc) +{ + int answer = factorial(5); + printf("%d\n", answer); +} +``` + +*递归阶乘 - factorial.c* + + +函数调用自身的这个观点在一开始是让人很难理解的。为了让这个过程更形象具体,下图展示的是当调用 `factorial(5)` 并且达到 `n == 1`这行代码 时,[栈上][3] 端点的情况: + +![](https://manybutfinite.com/img/stack/factorial.png) + +每次调用 `factorial` 都生成一个新的 [栈帧][4]。这些栈帧的创建和 [销毁][5] 是使得递归版本的阶乘慢于其相应的迭代版本的原因。在调用返回之前,累积的这些栈帧可能会耗尽栈空间,进而使你的程序崩溃。 + +而这些担心经常是存在于理论上的。例如,对于每个 `factorial` 的栈帧占用 16 字节(这可能取决于栈排列以及其它因素)。如果在你的电脑上运行着现代的 x86 的 Linux 内核,一般情况下你拥有 8 GB 的栈空间,因此,`factorial` 程序中的 `n` 最多可以达到 512,000 左右。这是一个 [巨大无比的结果][6],它将花费 8,971,833 比特来表示这个结果,因此,栈空间根本就不是什么问题:一个极小的整数 —— 甚至是一个 64 位的整数 —— 在我们的栈空间被耗尽之前就早已经溢出了成千上万次了。 + +过一会儿我们再去看 CPU 的使用,现在,我们先从比特和字节回退一步,把递归看作一种通用技术。我们的阶乘算法可归结为:将整数 N、N-1、 … 1 推入到一个栈,然后将它们按相反的顺序相乘。实际上我们使用了程序调用栈来实现这一点,这是它的细节:我们在堆上分配一个栈并使用它。虽然调用栈具有特殊的特性,但是它也只是又一种数据结构而已,你可以随意使用。我希望这个示意图可以让你明白这一点。 + +当你将栈调用视为一种数据结构,有些事情将变得更加清晰明了:将那些整数堆积起来,然后再将它们相乘,这并不是一个好的想法。那是一种有缺陷的实现:就像你拿螺丝刀去钉钉子一样。相对更合理的是使用一个迭代过程去计算阶乘。 + +但是,螺丝钉太多了,我们只能挑一个。有一个经典的面试题,在迷宫里有一只老鼠,你必须帮助这只老鼠找到一个奶酪。假设老鼠能够在迷宫中向左或者向右转弯。你该怎么去建模来解决这个问题? + +就像现实生活中的很多问题一样,你可以将这个老鼠找奶酪的问题简化为一个图,一个二叉树的每个结点代表在迷宫中的一个位置。然后你可以让老鼠在任何可能的地方都左转,而当它进入一个死胡同时,再回溯回去,再右转。这是一个老鼠行走的 [迷宫示例][7]: + +![](https://manybutfinite.com/img/stack/mazeGraph.png) + +每到边缘(线)都让老鼠左转或者右转来到达一个新的位置。如果向哪边转都被拦住,说明相关的边缘不存在。现在,我们来讨论一下!这个过程无论你是调用栈还是其它数据结构,它都离不开一个递归的过程。而使用调用栈是非常容易的: + + +``` +#include +#include "maze.h" + +int explore(maze_t *node) +{ + int found = 0; + + if (node == NULL) + { + return 0; + } + if (node->hasCheese){ + return 1;// found cheese + } + + found = explore(node->left) || explore(node->right); + return found; + } + + int main(int argc) + { + int found = explore(&maze); + } +``` + +*递归迷宫求解 [下载][2]* + +当我们在 `maze.c:13` 中找到奶酪时,栈的情况如下图所示。你也可以在 [GDB 输出][8] 中看到更详细的数据,它是使用 [命令][9] 采集的数据。 + +![](https://manybutfinite.com/img/stack/mazeCallStack.png) + +它展示了递归的良好表现,因为这是一个适合使用递归的问题。而且这并不奇怪:当涉及到算法时,*递归是规则,而不是例外*。它出现在如下情景中——进行搜索时、进行遍历树和其它数据结构时、进行解析时、需要排序时——它无处不在。正如众所周知的 pi 或者 e,它们在数学中像“神”一样的存在,因为它们是宇宙万物的基础,而递归也和它们一样:只是它存在于计算结构中。 + +Steven Skienna 的优秀著作 [算法设计指南][10] 的精彩之处在于,他通过 “战争故事” 作为手段来诠释工作,以此来展示解决现实世界中的问题背后的算法。这是我所知道的拓展你的算法知识的最佳资源。另一个读物是 McCarthy 的 [关于 LISP 实现的的原创论文][11]。递归在语言中既是它的名字也是它的基本原理。这篇论文既可读又有趣,在工作中能看到大师的作品是件让人兴奋的事情。 + +回到迷宫问题上。虽然它在这里很难离开递归,但是并不意味着必须通过调用栈的方式来实现。你可以使用像 `RRLL` 这样的字符串去跟踪转向,然后,依据这个字符串去决定老鼠下一步的动作。或者你可以分配一些其它的东西来记录追寻奶酪的整个状态。你仍然是实现了一个递归的过程,只是需要你实现一个自己的数据结构。 + +那样似乎更复杂一些,因为栈调用更合适。每个栈帧记录的不仅是当前节点,也记录那个节点上的计算状态(在这个案例中,我们是否只让它走左边,或者已经尝试向右)。因此,代码已经变得不重要了。然而,有时候我们因为害怕溢出和期望中的性能而放弃这种优秀的算法。那是很愚蠢的! + +正如我们所见,栈空间是非常大的,在耗尽栈空间之前往往会遇到其它的限制。一方面可以通过检查问题大小来确保它能够被安全地处理。而对 CPU 的担心是由两个广为流传的有问题的示例所导致的:哑阶乘dumb factorial和可怕的无记忆的 O( 2^n ) [Fibonacci 递归][12]。它们并不是栈递归算法的正确代表。 + +事实上栈操作是非常快的。通常,栈对数据的偏移是非常准确的,它在 [缓存][13] 中是热数据,并且是由专门的指令来操作它的。同时,使用你自己定义的在堆上分配的数据结构的相关开销是很大的。经常能看到人们写的一些比栈调用递归更复杂、性能更差的实现方法。最后,现代的 CPU 的性能都是 [非常好的][14] ,并且一般 CPU 不会是性能瓶颈所在。在考虑牺牲程序的简单性时要特别注意,就像经常考虑程序的性能及性能的[测量][15]那样。 + +下一篇文章将是探秘栈系列的最后一篇了,我们将了解尾调用、闭包、以及其它相关概念。然后,我们就该深入我们的老朋友—— Linux 内核了。感谢你的阅读! + +![](https://manybutfinite.com/img/stack/1000px-Sierpinski-build.png) + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/recursion/ + +作者:[Gustavo Duarte][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[FSSlc](https://github.com/FSSlc) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://duartes.org/gustavo/blog/about/ +[1]:https://manybutfinite.com/post/recursion/ +[2]:https://manybutfinite.com/code/x86-stack/maze.c +[3]:https://github.com/gduarte/blog/blob/master/code/x86-stack/factorial-gdb-output.txt +[4]:https://manybutfinite.com/post/journey-to-the-stack +[5]:https://manybutfinite.com/post/epilogues-canaries-buffer-overflows/ +[6]:https://gist.github.com/gduarte/9944878 +[7]:https://github.com/gduarte/blog/blob/master/code/x86-stack/maze.h +[8]:https://github.com/gduarte/blog/blob/master/code/x86-stack/maze-gdb-output.txt +[9]:https://github.com/gduarte/blog/blob/master/code/x86-stack/maze-gdb-commands.txt +[10]:http://www.amazon.com/Algorithm-Design-Manual-Steven-Skiena/dp/1848000693/ +[11]:https://github.com/papers-we-love/papers-we-love/blob/master/comp_sci_fundamentals_and_history/recursive-functions-of-symbolic-expressions-and-their-computation-by-machine-parti.pdf +[12]:http://stackoverflow.com/questions/360748/computational-complexity-of-fibonacci-sequence +[13]:https://manybutfinite.com/post/intel-cpu-caches/ +[14]:https://manybutfinite.com/post/what-your-computer-does-while-you-wait/ +[15]:https://manybutfinite.com/post/performance-is-a-science \ No newline at end of file diff --git a/published/20140510 Journey to the Stack Part I.md b/published/20140510 Journey to the Stack Part I.md new file mode 100644 index 0000000000..86a01363cc --- /dev/null +++ b/published/20140510 Journey to the Stack Part I.md @@ -0,0 +1,106 @@ +探秘“栈”之旅 +============== + +早些时候,我们探索了 [“内存中的程序之秘”][2],我们欣赏了在一台电脑中是如何运行我们的程序的。今天,我们去探索*栈的调用*,它在大多数编程语言和虚拟机中都默默地存在。在此过程中,我们将接触到一些平时很难见到的东西,像闭包closure、递归、以及缓冲溢出等等。但是,我们首先要作的事情是,描绘出栈是如何运作的。 + +栈非常重要,因为它追踪着一个程序中运行的*函数*,而函数又是一个软件的重要组成部分。事实上,程序的内部操作都是非常简单的。它大部分是由函数向栈中推入数据或者从栈中弹出数据的相互调用组成的,而在堆上为数据分配内存才能在跨函数的调用中保持数据。不论是低级的 C 软件还是像 JavaScript 和 C# 这样的基于虚拟机的语言,它们都是这样的。而对这些行为的深刻理解,对排错、性能调优以及大概了解究竟发生了什么是非常重要的。 + +当一个函数被调用时,将会创建一个栈帧stack frame去支持函数的运行。这个栈帧包含函数的*局部变量*和调用者传递给它的*参数*。这个栈帧也包含了允许被调用的函数(*callee*)安全返回给其调用者的内部事务信息。栈帧的精确内容和结构因处理器架构和函数调用规则而不同。在本文中我们以 Intel x86 架构和使用 C 风格的函数调用(`cdecl`)的栈为例。下图是一个处于栈顶部的一个单个栈帧: + +![](https://manybutfinite.com/img/stack/stackIntro.png) + +在图上的场景中,有三个 CPU 寄存器进入栈。栈指针stack pointer `esp`(LCTT 译注:扩展栈指针寄存器) 指向到栈的顶部。栈的顶部总是被最*后一个推入到栈且还没有弹出*的东西所占据,就像现实世界中堆在一起的一叠盘子或者 100 美元大钞一样。 + +保存在 `esp` 中的地址始终在变化着,因为栈中的东西不停被推入和弹出,而它总是指向栈中的最后一个推入的东西。许多 CPU 指令的一个副作用就是自动更新 `esp`,离开寄存器而使用栈是行不通的。 + +在 Intel 的架构中,绝大多数情况下,栈的增长是向着*低位内存地址*的方向。因此,这个“顶部” 在包含数据的栈中是处于低位的内存地址(在这种情况下,包含的数据是 `local_buffer`)。注意,关于从 `esp` 到 `local_buffer` 的箭头不是随意连接的。这个箭头代表着事务:它*专门*指向到由 `local_buffer` 所拥有的*第一个字节*,因为,那是一个保存在 `esp` 中的精确地址。 + +第二个寄存器跟踪的栈是 `ebp`(LCTT 译注:扩展基址指针寄存器),它包含一个基指针base pointer或者称为帧指针frame pointer。它指向到一个*当前运行*的函数的栈帧内的固定位置,并且它为参数和局部变量的访问提供一个稳定的参考点(基址)。仅当开始或者结束调用一个函数时,`ebp` 的内容才会发生变化。因此,我们可以很容易地处理在栈中的从 `ebp` 开始偏移后的每个东西。如图所示。 + +不像 `esp`, `ebp` 大多数情况下是在程序代码中通过花费很少的 CPU 来进行维护的。有时候,完成抛弃 `ebp` 有一些性能优势,可以通过 [编译标志][3] 来做到这一点。Linux 内核就是一个这样做的示例。 + +最后,`eax`(LCTT 译注:扩展的 32 位通用数据寄存器)寄存器惯例被用来转换大多数 C 数据类型返回值给调用者。 + +现在,我们来看一下在我们的栈帧中的数据。下图清晰地按字节展示了字节的内容,就像你在一个调试器中所看到的内容一样,内存是从左到右、从顶部至底部增长的,如下图所示: + +![](https://manybutfinite.com/img/stack/frameContents.png) + +局部变量 `local_buffer` 是一个字节数组,包含一个由 null 终止的 ASCII 字符串,这是 C 程序中的一个基本元素。这个字符串可以读取自任意地方,例如,从键盘输入或者来自一个文件,它只有 7 个字节的长度。因为,`local_buffer` 只能保存 8 字节,所以还剩下 1 个未使用的字节。*这个字节的内容是未知的*,因为栈不断地推入和弹出,*除了你写入的之外*,你根本不会知道内存中保存了什么。这是因为 C 编译器并不为栈帧初始化内存,所以它的内容是未知的并且是随机的 —— 除非是你自己写入。这使得一些人对此很困惑。 + +再往上走,`local1` 是一个 4 字节的整数,并且你可以看到每个字节的内容。它似乎是一个很大的数字,在8 后面跟着的都是零,在这里可能会误导你。 + +Intel 处理器是小端little endian机器,这表示在内存中的数字也是首先从小的一端开始的。因此,在一个多字节数字中,较小的部分在内存中处于最低端的地址。因为一般情况下是从左边开始显示的,这背离了我们通常的数字表示方式。我们讨论的这种从小到大的机制,使我想起《格里佛游记》:就像小人国的人们吃鸡蛋是从小头开始的一样,Intel 处理器处理它们的数字也是从字节的小端开始的。 + +因此,`local1` 事实上只保存了一个数字 8,和章鱼的腿数量一样。然而,`param1` 在第二个字节的位置有一个值 2,因此,它的数学上的值是 `2 * 256 = 512`(我们与 256 相乘是因为,每个位置值的范围都是从 0 到 255)。同时,`param2` 承载的数量是 `1 * 256 * 256 = 65536`。 + +这个栈帧的内部数据是由两个重要的部分组成:*前一个*栈帧的地址(保存的 `ebp` 值)和函数退出才会运行的指令的地址(返回地址)。它们一起确保了函数能够正常返回,从而使程序可以继续正常运行。 + +现在,我们来看一下栈帧是如何产生的,以及去建立一个它们如何共同工作的内部蓝图。首先,栈的增长是非常令人困惑的,因为它与你你预期的方式相反。例如,在栈上分配一个 8 字节,就要从 `esp` 减去 8,去,而减法是与增长不同的奇怪方式。 + +我们来看一个简单的 C 程序: + +``` +Simple Add Program - add.c + +int add(int a, int b) +{ + int result = a + b; + return result; +} + +int main(int argc) +{ + int answer; + answer = add(40, 2); +} +``` + +*简单的加法程序 - add.c* + +假设我们在 Linux 中不使用命令行参数去运行它。当你运行一个 C 程序时,实际运行的第一行代码是在 C 运行时库里,由它来调用我们的 `main` 函数。下图展示了程序运行时每一步都发生了什么。每个图链接的 GDB 输出展示了内存和寄存器的状态。你也可以看到所使用的 [GDB 命令][4],以及整个 [GDB 输出][5]。如下: + +![](https://manybutfinite.com/img/stack/mainProlog.png) + +第 2 步和第 3 步,以及下面的第 4 步,都只是函数的序言prologue,几乎所有的函数都是这样的:`ebp` 的当前值被保存到了栈的顶部,然后,将 `esp` 的内容拷贝到 `ebp`,以建立一个新的栈帧。`main` 的序言和其它函数一样,但是,不同之处在于,当程序启动时 `ebp` 被清零。 + +如果你去检查栈下方(右边)的整形变量(`argc`),你将找到更多的数据,包括指向到程序名和命令行参数(传统的 C 的 `argv`)、以及指向 Unix 环境变量以及它们真实的内容的指针。但是,在这里这些并不是重点,因此,继续向前调用 `add()`: + +![](https://manybutfinite.com/img/stack/callAdd.png) + +在 `main` 从 `esp` 减去 12 之后得到它所需的栈空间,它为 `a` 和 `b` 设置值。在内存中的值展示为十六进制,并且是小端格式,与你从调试器中看到的一样。一旦设置了参数值,`main` 将调用 `add`,并且开始运行: + +![](https://manybutfinite.com/img/stack/addProlog.png) + +现在,有一点小激动!我们进入了另一个函数序言,但这次你可以明确看到栈帧是如何从 `ebp` 到栈建立一个链表。这就是调试器和高级语言中的 `Exception` 对象如何对它们的栈进行跟踪的。当一个新帧产生时,你也可以看到更多这种典型的从 `ebp` 到 `esp` 的捕获。我们再次从 `esp` 中做减法得到更多的栈空间。 + +当 `ebp` 寄存器的值拷贝到内存时,这里也有一个稍微有些怪异的字节逆转。在这里发生的奇怪事情是,寄存器其实并没有字节顺序:因为对于内存,没有像寄存器那样的“增长的地址”。因此,惯例上调试器以对人类来说最自然的格式展示了寄存器的值:数位从最重要的到最不重要。因此,这个在小端机器中的副本的结果,与内存中常用的从左到右的标记法正好相反。我想用图去展示你将会看到的东西,因此有了下面的图。 + +在比较难懂的部分,我们增加了注释: + +![](https://manybutfinite.com/img/stack/doAdd.png) + +这是一个临时寄存器,用于帮你做加法,因此没有什么警报或者惊喜。对于加法这样的作业,栈的动作正好相反,我们留到下次再讲。 + +对于任何读到这里的人都应该有一个小礼物,因此,我做了一个大的图表展示了 [组合到一起的所有步骤][6]。 + +一旦把它们全部布置好了,看上起似乎很乏味。这些小方框给我们提供了很多帮助。事实上,在计算机科学中,这些小方框是主要的展示工具。我希望这些图片和寄存器的移动能够提供一种更直观的构想图,将栈的增长和内存的内容整合到一起。从软件的底层运作来看,我们的软件与一个简单的图灵机器差不多。 + +这就是我们栈探秘的第一部分,再讲一些内容之后,我们将看到构建在这个基础上的高级编程的概念。下周见! + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/journey-to-the-stack/ + +作者:[Gustavo Duarte][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://duartes.org/gustavo/blog/about/ +[1]:https://manybutfinite.com/post/journey-to-the-stack/ +[2]:https://linux.cn/article-9255-1.html +[3]:http://stackoverflow.com/questions/14666665/trying-to-understand-gcc-option-fomit-frame-pointer +[4]:https://github.com/gduarte/blog/blob/master/code/x86-stack/add-gdb-commands.txt +[5]:https://github.com/gduarte/blog/blob/master/code/x86-stack/add-gdb-output.txt +[6]:https://manybutfinite.com/img/stack/callSequence.png \ No newline at end of file diff --git a/published/20141106 System Calls Make the World Go Round.md b/published/20141106 System Calls Make the World Go Round.md new file mode 100644 index 0000000000..64db43f3da --- /dev/null +++ b/published/20141106 System Calls Make the World Go Round.md @@ -0,0 +1,197 @@ +系统调用,让世界转起来! +===================== + + +我其实不想将它分解开给你看,用户应用程序其实就是一个可怜的瓮中大脑brain in a vat: + +![](https://manybutfinite.com/img/os/appInVat.png) + +它与外部世界的*每个*交流都要在内核的帮助下通过**系统调用**才能完成。一个应用程序要想保存一个文件、写到终端、或者打开一个 TCP 连接,内核都要参与。应用程序是被内核高度怀疑的:认为它到处充斥着 bug,甚至是个充满邪恶想法的脑子。 + +这些系统调用是从一个应用程序到内核的函数调用。出于安全考虑,它们使用了特定的机制,实际上你只是调用了内核的 API。“系统调用system call”这个术语指的是调用由内核提供的特定功能(比如,系统调用 `open()`)或者是调用途径。你也可以简称为:**syscall**。 + +这篇文章讲解系统调用,系统调用与调用一个库有何区别,以及在操作系统/应用程序接口上的刺探工具。如果彻底了解了应用程序借助操作系统发生的哪些事情,那么就可以将一个不可能解决的问题转变成一个快速而有趣的难题。 + +那么,下图是一个运行着的应用程序,一个用户进程: + +![](https://manybutfinite.com/img/os/sandbox.png) + +它有一个私有的 [虚拟地址空间][2]—— 它自己的内存沙箱。整个系统都在它的地址空间中(即上面比喻的那个“瓮”),程序的二进制文件加上它所使用的库全部都 [被映射到内存中][3]。内核自身也映射为地址空间的一部分。 + +下面是我们程序 `pid` 的代码,它通过 [getpid(2)][4] 直接获取了其进程 id: + + +``` +#include +#include +#include + +int main() +{ + pid_t p = getpid(); + printf("%d\n", p); +} +``` + +*pid.c [download][1]* + + +在 Linux 中,一个进程并不是一出生就知道它的 PID。要想知道它的 PID,它必须去询问内核,因此,这个询问请求也是一个系统调用: + +![](https://manybutfinite.com/img/os/syscallEnter.png) + +它的第一步是开始于调用 C 库的 [getpid()][5],它是系统调用的一个*封装*。当你调用一些函数时,比如,`open(2)`、`read(2)` 之类,你是在调用这些封装。其实,对于大多数编程语言在这一块的原生方法,最终都是在 libc 中完成的。 + +封装为这些基本的操作系统 API 提供了方便,这样可以保持内核的简洁。*所有的内核代码*运行在特权模式下,有 bug 的内核代码行将会产生致命的后果。能在用户模式下做的任何事情都应该在用户模式中完成。由库来提供友好的方法和想要的参数处理,像 `printf(3)` 这样。 + +我们拿一个 web API 进行比较,内核的封装方式可以类比为构建一个尽可能简单的 HTTP 接口去提供服务,然后提供特定语言的库及辅助方法。或者也可能有一些缓存,这就是 libc 的 `getpid()` 所做的:首次调用时,它真实地去执行了一个系统调用,然后,它缓存了 PID,这样就可以避免后续调用时的系统调用开销。 + +一旦封装完成,它做的第一件事就是进入了~~超空间~~hyperspace:内核。这种转换机制因处理器架构设计不同而不同。在 Intel 处理器中,参数和 [系统调用号][6] 是 [加载到寄存器中的][7],然后,运行一个 [指令][8] 将 CPU 置于 [特权模式][9] 中,并立即将控制权转移到内核中的全局系统调用 [入口][10]。如果你对这些细节感兴趣,David Drysdale 在 LWN 上有两篇非常好的文章([其一][11],[其二][12])。 + +内核然后使用这个系统调用号作为进入 [`sys_call_table`][14] 的一个 [索引][13],它是一个函数指针到每个系统调用实现的数组。在这里,调用了 [`sys_getpid`][15]: + +![](https://manybutfinite.com/img/os/syscallExit.png) + +在 Linux 中,系统调用大多数都实现为架构无关的 C 函数,有时候这样做 [很琐碎][16],但是通过内核优秀的设计,系统调用机制被严格隔离。它们是工作在一般数据结构中的普通代码。嗯,除了*完全偏执*的参数校验以外。 + +一旦它们的工作完成,它们就会正常*返回*,然后,架构特定的代码会接手转回到用户模式,封装将在那里继续做一些后续处理工作。在我们的例子中,[getpid(2)][17] 现在缓存了由内核返回的 PID。如果内核返回了一个错误,另外的封装可以去设置全局 `errno` 变量。这些细节可以让你知道 GNU 是怎么处理的。 + +如果你想要原生的调用,glibc 提供了 [syscall(2)][18] 函数,它可以不通过封装来产生一个系统调用。你也可以通过它来做一个你自己的封装。这对一个 C 库来说,既不神奇,也不特殊。 + +这种系统调用的设计影响是很深远的。我们从一个非常有用的 [strace(1)][19] 开始,这个工具可以用来监视 Linux 进程的系统调用(在 Mac 上,参见 [dtruss(1m)][20] 和神奇的 [dtrace][21];在 Windows 中,参见 [sysinternals][22])。这是对 `pid` 程序的跟踪: + +``` +~/code/x86-os$ strace ./pid + +execve("./pid", ["./pid"], [/* 20 vars */]) = 0 +brk(0) = 0x9aa0000 +access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) +mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7767000 +access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) +open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 +fstat64(3, {st_mode=S_IFREG|0644, st_size=18056, ...}) = 0 +mmap2(NULL, 18056, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7762000 +close(3) = 0 + +[...snip...] + +getpid() = 14678 +fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 1), ...}) = 0 +mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7766000 +write(1, "14678\n", 614678 +) = 6 +exit_group(6) = ? +``` + +输出的每一行都显示了一个系统调用、它的参数,以及返回值。如果你在一个循环中将 `getpid(2)` 运行 1000 次,你就会发现始终只有一个 `getpid()` 系统调用,因为,它的 PID 已经被缓存了。我们也可以看到在格式化输出字符串之后,`printf(3)` 调用了 `write(2)`。 + +`strace` 可以开始一个新进程,也可以附加到一个已经运行的进程上。你可以通过不同程序的系统调用学到很多的东西。例如,`sshd` 守护进程一天都在干什么? + +``` +~/code/x86-os$ ps ax | grep sshd +12218 ? Ss 0:00 /usr/sbin/sshd -D + +~/code/x86-os$ sudo strace -p 12218 +Process 12218 attached - interrupt to quit +select(7, [3 4], NULL, NULL, NULL + +[ + ... nothing happens ... + No fun, it's just waiting for a connection using select(2) + If we wait long enough, we might see new keys being generated and so on, but + let's attach again, tell strace to follow forks (-f), and connect via SSH +] + +~/code/x86-os$ sudo strace -p 12218 -f + +[lots of calls happen during an SSH login, only a few shown] + +[pid 14692] read(3, "-----BEGIN RSA PRIVATE KEY-----\n"..., 1024) = 1024 +[pid 14692] open("/usr/share/ssh/blacklist.RSA-2048", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) +[pid 14692] open("/etc/ssh/blacklist.RSA-2048", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) +[pid 14692] open("/etc/ssh/ssh_host_dsa_key", O_RDONLY|O_LARGEFILE) = 3 +[pid 14692] open("/etc/protocols", O_RDONLY|O_CLOEXEC) = 4 +[pid 14692] read(4, "# Internet (IP) protocols\n#\n# Up"..., 4096) = 2933 +[pid 14692] open("/etc/hosts.allow", O_RDONLY) = 4 +[pid 14692] open("/lib/i386-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4 +[pid 14692] stat64("/etc/pam.d", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 +[pid 14692] open("/etc/pam.d/common-password", O_RDONLY|O_LARGEFILE) = 8 +[pid 14692] open("/etc/pam.d/other", O_RDONLY|O_LARGEFILE) = 4 +``` + +看懂 SSH 的调用是块难啃的骨头,但是,如果搞懂它你就学会了跟踪。能够看到应用程序打开的是哪个文件是有用的(“这个配置是从哪里来的?”)。如果你有一个出现错误的进程,你可以 `strace` 它,然后去看它通过系统调用做了什么?当一些应用程序意外退出而没有提供适当的错误信息时,你可以去检查它是否有系统调用失败。你也可以使用过滤器,查看每个调用的次数,等等: + +``` +~/code/x86-os$ strace -T -e trace=recv curl -silent www.google.com. > /dev/null + +recv(3, "HTTP/1.1 200 OK\r\nDate: Wed, 05 N"..., 16384, 0) = 4164 <0.000007> +recv(3, "fl a{color:#36c}a:visited{color:"..., 16384, 0) = 2776 <0.000005> +recv(3, "adient(top,#4d90fe,#4787ed);filt"..., 16384, 0) = 4164 <0.000007> +recv(3, "gbar.up.spd(b,d,1,!0);break;case"..., 16384, 0) = 2776 <0.000006> +recv(3, "$),a.i.G(!0)),window.gbar.up.sl("..., 16384, 0) = 1388 <0.000004> +recv(3, "margin:0;padding:5px 8px 0 6px;v"..., 16384, 0) = 1388 <0.000007> +recv(3, "){window.setTimeout(function(){v"..., 16384, 0) = 1484 <0.000006> +``` + +我鼓励你在你的操作系统中的试验这些工具。把它们用好会让你觉得自己有超能力。 + +但是,足够有用的东西,往往要让我们深入到它的设计中。我们可以看到那些用户空间中的应用程序是被严格限制在它自己的虚拟地址空间里,运行在 Ring 3(非特权模式)中。一般来说,只涉及到计算和内存访问的任务是不需要请求系统调用的。例如,像 [strlen(3)][23] 和 [memcpy(3)][24] 这样的 C 库函数并不需要内核去做什么。这些都是在应用程序内部发生的事。 + +C 库函数的 man 页面所在的节(即圆括号里的 `2` 和 `3`)也提供了线索。节 2 是用于系统调用封装,而节 3 包含了其它 C 库函数。但是,正如我们在 `printf(3)` 中所看到的,库函数最终可以产生一个或者多个系统调用。 + +如果你对此感到好奇,这里是 [Linux][25] (也有 [Filippo 的列表][26])和 [Windows][27] 的全部系统调用列表。它们各自有大约 310 和 460 个系统调用。看这些系统调用是非常有趣的,因为,它们代表了*软件*在现代的计算机上能够做什么。另外,你还可能在这里找到与进程间通讯和性能相关的“宝藏”。这是一个“不懂 Unix 的人注定最终还要重新发明一个蹩脚的 Unix ” 的地方。(LCTT 译注:原文 “Those who do not understand Unix are condemned to reinvent it,poorly。” 这句话是 [Henry Spencer][35] 的名言,反映了 Unix 的设计哲学,它的一些理念和文化是一种技术发展的必须结果,看似糟糕却无法超越。) + +与 CPU 周期相比,许多系统调用花[很长的时间][28]去执行任务,例如,从一个硬盘驱动器中读取内容。在这种情况下,调用进程在底层的工作完成之前一直*处于休眠状态*。因为,CPU 运行的非常快,一般的程序都因为 **I/O 的限制**在它的生命周期的大部分时间处于休眠状态,等待系统调用返回。相反,如果你跟踪一个计算密集型任务,你经常会看到没有任何的系统调用参与其中。在这种情况下,[top(1)][29] 将显示大量的 CPU 使用。 + +在一个系统调用中的开销可能会是一个问题。例如,固态硬盘比普通硬盘要快很多,但是,操作系统的开销可能比 I/O 操作本身的开销 [更加昂贵][30]。执行大量读写操作的程序可能就是操作系统开销的瓶颈所在。[向量化 I/O][31] 对此有一些帮助。因此要做 [文件的内存映射][32],它允许一个程序仅访问内存就可以读或写磁盘文件。类似的映射也存在于像视频卡这样的地方。最终,云计算的经济性可能导致内核消除或最小化用户模式/内核模式的切换。 + +最终,系统调用还有益于系统安全。一是,无论如何来历不明的一个二进制程序,你都可以通过观察它的系统调用来检查它的行为。这种方式可能用于去检测恶意程序。例如,我们可以记录一个未知程序的系统调用的策略,并对它的异常行为进行报警,或者对程序调用指定一个白名单,这样就可以让漏洞利用变得更加困难。在这个领域,我们有大量的研究,和许多工具,但是没有“杀手级”的解决方案。 + +这就是系统调用。很抱歉这篇文章有点长,我希望它对你有用。接下来的时间,我将写更多(短的)文章,也可以在 [RSS][33] 和 [Twitter][34] 关注我。这篇文章献给 glorious Clube Atlético Mineiro。 + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/system-calls/ + +作者:[Gustavo Duarte][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://duartes.org/gustavo/blog/about/ +[1]:https://manybutfinite.com/code/x86-os/pid.c +[2]:https://manybutfinite.com/post/anatomy-of-a-program-in-memory +[3]:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ +[4]:http://linux.die.net/man/2/getpid +[5]:https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/getpid.c;h=937b1d4e113b1cff4a5c698f83d662e130d596af;hb=4c6da7da9fb1f0f94e668e6d2966a4f50a7f0d85#l49 +[6]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/syscalls/syscall_64.tbl#L48 +[7]:https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sysdep.h;h=4a619dafebd180426bf32ab6b6cb0e5e560b718a;hb=4c6da7da9fb1f0f94e668e6d2966a4f50a7f0d85#l139 +[8]:https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sysdep.h;h=4a619dafebd180426bf32ab6b6cb0e5e560b718a;hb=4c6da7da9fb1f0f94e668e6d2966a4f50a7f0d85#l179 +[9]:https://manybutfinite.com/post/cpu-rings-privilege-and-protection +[10]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/kernel/entry_64.S#L354-L386 +[11]:http://lwn.net/Articles/604287/ +[12]:http://lwn.net/Articles/604515/ +[13]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/kernel/entry_64.S#L422 +[14]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/kernel/syscall_64.c#L25 +[15]:https://github.com/torvalds/linux/blob/v3.17/kernel/sys.c#L800-L809 +[16]:https://github.com/torvalds/linux/blob/v3.17/kernel/sys.c#L800-L859 +[17]:http://linux.die.net/man/2/getpid +[18]:http://linux.die.net/man/2/syscall +[19]:http://linux.die.net/man/1/strace +[20]:https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dtruss.1m.html +[21]:http://dtrace.org/blogs/brendan/2011/10/10/top-10-dtrace-scripts-for-mac-os-x/ +[22]:http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx +[23]:http://linux.die.net/man/3/strlen +[24]:http://linux.die.net/man/3/memcpy +[25]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/syscalls/syscall_64.tbl +[26]:https://filippo.io/linux-syscall-table/ +[27]:http://j00ru.vexillium.org/ntapi/ +[28]:https://manybutfinite.com/post/what-your-computer-does-while-you-wait/ +[29]:http://linux.die.net/man/1/top +[30]:http://danluu.com/clwb-pcommit/ +[31]:http://en.wikipedia.org/wiki/Vectored_I/O +[32]:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ +[33]:http://feeds.feedburner.com/GustavoDuarte +[34]:http://twitter.com/food4hackers +[35]:https://en.wikipedia.org/wiki/Henry_Spencer \ No newline at end of file diff --git a/translated/talk/20170119 Be a force for good in your community.md b/published/20170119 Be a force for good in your community.md similarity index 71% rename from translated/talk/20170119 Be a force for good in your community.md rename to published/20170119 Be a force for good in your community.md index 035409c4c1..3845cfd518 100644 --- a/translated/talk/20170119 Be a force for good in your community.md +++ b/published/20170119 Be a force for good in your community.md @@ -1,31 +1,29 @@ 成为你所在社区的美好力量 ============================================================ ->明白如何传递美好,了解积极意愿的力量,以及更多。 +> 明白如何传递美好,了解积极意愿的力量,以及更多。 - ![Be a force for good in your community](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/people_remote_teams_world.png?itok=wI-GW8zX "Be a force for good in your community") + ![Be a force for good in your community](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/people_remote_teams_world.png?itok=_9DCHEel) >图片来自:opensource.com -激烈的争论是开源社区和开放组织的标志特征之一。在我们最好的日子里,这些争论充满活力和建设性。他们面红耳赤的背后其实是幽默和善意。各方实事求是,共同解决问题,推动持续改进。对我们中的许多人来说,他们只是单纯的娱乐而已。 +激烈的争论是开源社区和开放组织的标志特征之一。在好的时候,这些争论充满活力和建设性。他们面红耳赤的背后其实是幽默和善意。各方实事求是,共同解决问题,推动持续改进。对我们中的许多人来说,他们只是单纯的喜欢而已。 -然而在我们最糟糕的日子里,这些争论演变成了对旧话题的反复争吵。或者我们用各种方式来传递伤害和相互攻击,或是使用卑劣的手段,而这些侵蚀着我们社区的激情、信任和生产力。 +然而在那些不好的日子里,这些争论演变成了对旧话题的反复争吵。或者我们用各种方式来传递伤害和相互攻击,或是使用卑劣的手段,而这些侵蚀着我们社区的激情、信任和生产力。 -我们茫然四顾,束手无策,因为社区的对话开始变得有毒。然而,正如 [DeLisa Alexander最近的分享][1],我们每个人都有很多方法可以成为我们社区的一种力量。 +我们茫然四顾,束手无策,因为社区的对话开始变得有毒。然而,正如 [DeLisa Alexander 最近的分享][1],我们每个人都有很多方法可以成为我们社区的一种力量。 在这个“开源文化”系列的第一篇文章中,我将分享一些策略,教你如何在这个关键时刻进行干预,引导每个人走向更积极、更有效率的方向。 ### 不要将人推开,而是将人推向前方 -最近,我和我的朋友和同事 [Mark Rumbles][2] 一起吃午饭。多年来,我们在许多支持开源文化和引领 Red Hat 的项目中合作。在这一天,马克问我是怎么坚持的,当我看到辩论变得越来越丑陋的时候,他看到我最近介入了一个邮件列表的对话。 +最近,我和我的朋友和同事 [Mark Rumbles][2] 一起吃午饭。多年来,我们在许多支持开源文化和引领 Red Hat 的项目中合作。在这一天,Mark 问我,他看到我最近介入了一个邮件列表的对话,当其中的辩论越来越过分时我是怎么坚持的。 幸运的是,这事早已尘埃落定,事实上我几乎忘记了谈话的内容。然而,它让我们开始讨论如何在一个拥有数千名成员的社区里,公开和坦率的辩论。 ->在我们的社区里,我们成为一种美好力量的最好的方法之一就是:在回应冲突时,以一种迫使每个人提升他们的行为,而不是使冲突升级的方式。 - Mark 说了一些让我印象深刻的话。他说:“你知道,作为一个社区,我们真的很擅长将人推开。但我想看到的是,我们更多的是互相扶持 _向前_ 。” -Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量的最好的方法之一就是:在回应冲突时,以一种迫使每个人提升他们的行为,而不是使冲突升级的方式。 +Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量的最好的方法之一就是:以一种迫使每个人提升他们的行为的方式回应冲突,而不是使冲突升级的方式。 ### 积极意愿假想 @@ -33,9 +31,9 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 诚然,这不是一件容易的事情。当我看到一场辩论正在变得肮脏的迹象时,我停下来问自己,史蒂芬·科维(Steven Covey)所说的人性化问题是什么: -“为什么一个理性、正直的人会做这样的事情?” +> “为什么一个理性、正直的人会做这样的事情?” -现在,如果他是你的一个“普通的观察对象”——一个有消极行为倾向的社区成员——也许你的第一个想法是,“嗯,也许这个人是个不靠谱,不理智的人” +现在,如果他是你的一个“普通的观察对象”—— 一个有消极行为倾向的社区成员——也许你的第一个想法是,“嗯,也许这个人是个不靠谱,不理智的人” 回过头来说。我并不是说你让你自欺欺人。这其实就是人性化的问题,不仅是因为它让你理解别人的立场,它还让你变得人性化。 @@ -51,7 +49,7 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 一个简单的积极意愿假想,我们可以适用于几乎所有的不良行为,其实就是那个人想要被聆听,被尊重,或被理解。我想这是相当合理的。 -通过站在这个更客观、更有同情心的角度,我们可以看到他们的行为几乎肯定 **_不_** 会帮助他们得到他们想要的东西,而社区也会因此而受到影响。如果没有我们的帮助的话。 +通过站在这个更客观、更有同情心的角度,我们可以看到他们的行为几乎肯定 **_不会_** 帮助他们得到他们想要的东西,而社区也会因此而受到影响。如果没有我们的帮助的话。 对我来说,这激发了一个愿望:帮助每个人从我们所处的这个丑陋的地方“摆脱困境”。 @@ -60,7 +58,7 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 容易想到的例子包括: * 他们担心我们错过了一些重要的东西,或者我们犯了一个错误,没有人能看到它。 -* 他们想为自己的贡献感到有价值。 +* 他们想感受到自己的贡献的价值。 * 他们精疲力竭,因为在社区里工作过度或者在他们的个人生活中发生了一些事情。 * 他们讨厌一些东西被破坏,并感到沮丧,因为没有人能看到造成的伤害或不便。 * ……诸如此类。 @@ -69,11 +67,11 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 ### 传递美好,挣脱泥潭 -什么是 an out?(类似与佛家“解脱法门”的意思)把它想象成一个逃跑的门。这是一种退出对话的方式,或者放弃不良的行为,恢复表现得像一个体面的人,而不是丢面子。是叫某人振作向上,而不是叫他走开。 +什么是 an out?(LCTT 译注:类似与佛家“解脱法门”的意思)把它想象成一个逃跑的门。这是一种退出对话的方式,或者放弃不良的行为,恢复表现得像一个体面的人,而不是丢面子。是叫某人振作向上,而不是叫他走开。 你可能经历过这样的事情,在你的生活中,当 _你_ 在一次谈话中表现不佳时,咆哮着,大喊大叫,对某事大惊小怪,而有人慷慨地给 _你_ 提供了一个台阶下。也许他们选择不去和你“抬杠”,相反,他们说了一些表明他们相信你是一个理性、正直的人,他们采用积极意愿假想,比如: -> _所以,嗯,我听到的是你真的很担心,你很沮丧,因为似乎没有人在听。或者你担心我们忽略了它的重要性。是这样对吧?_ +> 所以,嗯,我听到的是你真的很担心,你很沮丧,因为似乎没有人在听。或者你担心我们忽略了它的重要性。是这样对吧? 于是乎:即使这不是完全正确的(也许你的意图不那么高尚),在那一刻,你可能抓住了他们提供给你的台阶,并欣然接受了重新定义你的不良行为的机会。你几乎可以肯定地转向一个更富有成效的角度,甚至你自己可能都没有意识到。 @@ -85,13 +83,13 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 ### 坏行为还是坏人? -如果这个人特别激动,他们可能不会听到或者接受你给出的第一台阶。没关系。最可能的是,他们迟钝的大脑已经被史前曾经对人类生存至关重要的杏仁核接管了,他们需要更多的时间来认识到你并不是一个威胁。只是需要你保持温和的态度,坚定地对待他们,就好像他们 _曾经是_ 一个理性、正直的人,看看会发生什么。 +如果这个人特别激动,他们可能不会听到或者接受你给出的第一个台阶。没关系。最可能的是,他们迟钝的大脑已经被史前曾经对人类生存至关重要的杏仁体接管了,他们需要更多的时间来认识到你并不是一个威胁。只是需要你保持温和的态度,坚定地对待他们,就好像他们 _曾经是_ 一个理性、正直的人,看看会发生什么。 根据我的经验,这些社区干预以三种方式结束: 大多数情况下,这个人实际上 _是_ 一个理性的人,很快,他们就感激地接受了这个事实。在这个过程中,每个人都跳出了“黑与白”,“赢或输”的心态。人们开始思考创造性的选择和“双赢”的结果,每个人都将受益。 -> 为什么一个理性、正直的人会做这样的事呢? +> 为什么一个理性、正直的人会做这样的事呢? 有时候,这个人天生不是特别理性或正直的,但当他被你以如此一致的、不知疲倦的、耐心的慷慨和善良的对待的时候,他们就会羞愧地从谈话中撤退。这听起来像是,“嗯,我想我已经说了所有要说的了。谢谢你听我的意见”。或者,对于不那么开明的人来说,“嗯,我厌倦了这种谈话。让我们结束吧。”(好的,谢谢)。 @@ -99,7 +97,7 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 这就是积极意愿假想的力量。通过对愤怒和充满敌意的言辞做出回应,优雅而有尊严地回应,你就能化解一场战争,理清混乱,解决棘手的问题,而且在这个过程中很有可能会交到一个新朋友。 -我每次应用这个原则都成功吗?见鬼,不。但我从不后悔选择了积极意愿。但是我能生动的回想起,当我采用消极意愿假想时,将问题变得更糟糕的场景。 +我每次应用这个原则都成功吗?见鬼,不会。但我从不后悔选择了积极意愿。但是我能生动的回想起,当我采用消极意愿假想时,将问题变得更糟糕的场景。 现在轮到你了。我很乐意听到你提出的一些策略和原则,当你的社区里的对话变得激烈的时候,要成为一股好力量。在下面的评论中分享你的想法。 @@ -111,7 +109,7 @@ Mark 是绝对正确的。在我们的社区里,我们成为一种美好力量 ![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/headshot-square_0.jpg?itok=FS97b9YD) -丽贝卡·费尔南德斯(Rebecca Fernandez)是红帽公司(Red Hat)的首席就业品牌 + 通讯专家,是《开源组织》书籍的贡献者,也是开源决策框架的维护者。她的兴趣是开源和业务管理模型的开源方式。Twitter:@ruhbehka +丽贝卡·费尔南德斯(Rebecca Fernandez)是红帽公司(Red Hat)的首席就业品牌 + 通讯专家,是《开放组织》书籍的贡献者,也是开源决策框架的维护者。她的兴趣是开源和业务管理模型的开源方式。Twitter:@ruhbehka -------------------------------------------------------------------------------- @@ -119,7 +117,7 @@ via: https://opensource.com/open-organization/17/1/force-for-good-community 作者:[Rebecca Fernandez][a] 译者:[chao-zhi](https://github.com/chao-zhi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/tech/20170213 Getting Started with Taskwarrior.md b/published/20170213 Getting Started with Taskwarrior.md similarity index 51% rename from sources/tech/20170213 Getting Started with Taskwarrior.md rename to published/20170213 Getting Started with Taskwarrior.md index 3fccc15498..b2e276859e 100644 --- a/sources/tech/20170213 Getting Started with Taskwarrior.md +++ b/published/20170213 Getting Started with Taskwarrior.md @@ -1,64 +1,67 @@ -Getting Started with Taskwarrior -====== -Taskwarrior is a flexible [command-line task management program][1]. In their [own words][2]: +基于命令行的任务管理器 Taskwarrior +===== -Taskwarrior manages your TODO list from your command line. It is flexible, fast, efficient, unobtrusive, does its job then gets out of your way. +Taskwarrior 是一个灵活的[命令行任务管理程序][1],用他们[自己的话说][2]: -Taskwarrior is highly customizable, but can also be used "right out of the box." In this article, we'll show you the basic commands to add and complete tasks. Then we'll cover a couple more advanced commands. And finally, we'll show you some basic configuration settings to begin customizing your setup. +> Taskwarrior 在命令行里管理你的 TODO 列表。它灵活,快速,高效,不显眼,它默默做自己的事情让你避免自己管理。 -### Installing Taskwarrior +Taskwarrior 是高度可定制的,但也可以“立即使用”。在本文中,我们将向你展示添加和完成任务的基本命令,然后我们将介绍几个更高级的命令。最后,我们将向你展示一些基本的配置设置,以开始自定义你的设置。 + +### 安装 Taskwarrior + +Taskwarrior 在 Fedora 仓库中是可用的,所有安装它很容易: -Taskwarrior is available in the Fedora repositories, so installing it is simple: ``` sudo dnf install task - ``` -Once installed, run `task`. This first run will create a `~/.taskrc` file for you. +一旦完成安装,运行 `task` 命令。第一次运行将会创建一个 `~/.taskrc` 文件。 + ``` -$ **task** +$ task A configuration file could not be found in ~ Would you like a sample /home/link/.taskrc created, so Taskwarrior can proceed? (yes/no) yes [task next] No matches. - ``` -### Adding Tasks +### 添加任务 + +添加任务快速而不显眼。 -Adding tasks is fast and unobtrusive. ``` -$ **task add Plant the wheat** +$ task add Plant the wheat Created task 1. ``` -Run `task` or `task list` to show upcoming tasks. +运行 `task` 或者 `task list` 来显示即将来临的任务。 + ``` -$ **task list** +$ task list ID Age Description Urg 1 8s Plant the wheat 0 1 task - ``` -Let's add a few more tasks to round out the example. +让我们添加一些任务来完成这个示例。 + ``` -$ **task add Tend the wheat** +$ task add Tend the wheat Created task 2. -$ **task add Cut the wheat** +$ task add Cut the wheat Created task 3. -$ **task add Take the wheat to the mill to be ground into flour** +$ task add Take the wheat to the mill to be ground into flour Created task 4. -$ **task add Bake a cake** +$ task add Bake a cake Created task 5. - ``` -Run `task` again to view the list. +再次运行 `task` 来查看列表。 + ``` [task next] @@ -70,83 +73,83 @@ ID Age Description Urg 5 2s Bake a cake 0 5 tasks - ``` -### Completing Tasks +### 完成任务 + +将一个任务标记为完成, 查找其 ID 并运行: -To mark a task as complete, look up its ID and run: ``` -$ **task 1 done** +$ task 1 done Completed task 1 'Plant the wheat'. Completed 1 task. - ``` -You can also mark a task done with its description. +你也可以用它的描述来标记一个任务已完成。 + ``` -$ **task 'Tend the wheat' done** +$ task 'Tend the wheat' done Completed task 1 'Tend the wheat'. Completed 1 task. - ``` -With `add`, `list` and `done`, you're all ready to get started with Taskwarrior. +通过使用 `add`、`list` 和 `done`,你可以说已经入门了。 -### Setting Due Dates +### 设定截止日期 + +很多任务不需要一个截止日期: -Many tasks do not require a due date: ``` task add Finish the article on Taskwarrior - ``` -But sometimes, setting a due date is just the kind of motivation you need to get productive. Use the `due` modifier when adding a task to set a specific due date. +但是有时候,设定一个截止日期正是你需要提高效率的动力。在添加任务时使用 `due` 修饰符来设置特定的截止日期。 + ``` task add Finish the article on Taskwarrior due:tomorrow - ``` -`due` is highly flexible. It accepts specific dates ("2017-02-02"), or ISO-8601 ("2017-02-02T20:53:00Z"), or even relative time ("8hrs"). See the [Date & Time][3] documentation for all the examples. +`due` 非常灵活。它接受特定日期 (`2017-02-02`) 或 ISO-8601 (`2017-02-02T20:53:00Z`),甚至相对时间 (`8hrs`)。可以查看所有示例的 [Date & Time][3] 文档。 + +日期也不只有截止日期,Taskwarrior 有 `scheduled`, `wait` 和 `until` 选项。 -Dates go beyond due dates too. Taskwarrior has `scheduled`, `wait`, and `until`. ``` task add Proof the article on Taskwarrior scheduled:thurs - ``` -Once the date (Thursday in this example) passes, the task is tagged with the `READY` virtual tag. It will then show up in the `ready` report. +一旦日期(本例中的星期四)通过,该任务就会被标记为 `READY` 虚拟标记。它会显示在 `ready` 报告中。 + ``` -$ **task ready** +$ task ready ID Age S Description Urg 1 2s 1d Proof the article on Taskwarrior 5 - ``` -To remove a date, `modify` the task with a blank value: +要移除一个日期,使用空白值来 `modify` 任务: + ``` $ task 1 modify scheduled: - ``` -### Searching Tasks +### 查找任务 + +如果没有使用正则表达式搜索的能力,任务列表是不完整的,对吧? -No task list is complete without the ability to search with regular expressions, right? ``` -$ **task '/.* the wheat/' list** +$ task '/.* the wheat/' list ID Age Project Description Urg 2 42min Take the wheat to the mill to be ground into flour 0 1 42min Home Cut the wheat 1 2 tasks - ``` -### Customizing Taskwarrior +### 自定义 Taskwarrior + +记得我们在开头创建的文件 (`~/.taskrc`)吗?让我们来看看默认设置: -Remember that file we created back in the beginning (`~/.taskrc`). Let's take at the defaults: ``` # [Created by task 2.5.1 2/9/2017 16:39:14] # Taskwarrior program configuration file. @@ -178,47 +181,46 @@ data.location=~/.task #include /usr//usr/share/task/solarized-dark-256.theme #include /usr//usr/share/task/solarized-light-256.theme #include /usr//usr/share/task/no-color.theme - - ``` -The only active option right now is `data.location=~/.task`. To view active configuration settings (including the built-in defaults), run `show`. +现在唯一生效的选项是 `data.location=~/.task`。要查看活动配置设置(包括内置的默认设置),运行 `show`。 + ``` task show - ``` -To change a setting, use `config`. +要改变设置,使用 `config`。 + ``` -$ **task config displayweeknumber no** +$ task config displayweeknumber no Are you sure you want to add 'displayweeknumber' with a value of 'no'? (yes/no) yes Config file /home/link/.taskrc modified. - ``` -### Examples +### 示例 -These are just some of the things you can do with Taskwarrior. +这些只是你可以用 Taskwarrior 做的一部分事情。 + +将你的任务分配到一个项目: -Assign a project to your tasks: ``` task 'Fix leak in the roof' modify project:Home - ``` -Use `start` to mark what you were working on. This can help you remember what you were working on after the weekend: +使用 `start` 来标记你正在做的事情,这可以帮助你回忆起你周末后在做什么: + ``` task 'Fix bug #141291' start - ``` -Use relevant tags: +使用相关的标签: + ``` task add 'Clean gutters' +weekend +house ``` -Be sure to read the [complete documentation][4] to learn all the ways you can catalog and organize your tasks. +务必阅读[完整文档][4]以了解你可以编目和组织任务的所有方式。 -------------------------------------------------------------------------------- @@ -226,8 +228,8 @@ Be sure to read the [complete documentation][4] to learn all the ways you can ca via: https://fedoramagazine.org/getting-started-taskwarrior/ 作者:[Link Dupont][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/talk/20170320 Education of a Programmer.md b/published/20170320 Education of a Programmer.md similarity index 53% rename from translated/talk/20170320 Education of a Programmer.md rename to published/20170320 Education of a Programmer.md index 84762b8655..0837bd4c0c 100644 --- a/translated/talk/20170320 Education of a Programmer.md +++ b/published/20170320 Education of a Programmer.md @@ -1,122 +1,116 @@ 程序员的学习之路 ============================================================ -*2016 年 10 月,当我从微软离职时,我已经在微软工作了近 21 年,在工业界也快 35 年了。我花了一些时间反思我这些年来学到的东西,这些文字是那篇帖子稍加修改后得到。请见谅,文章有一点长。* +*2016 年 10 月,当我从微软离职时,我已经在微软工作了近 21 年,在业界也快 35 年了。我花了一些时间反思我这些年来学到的东西,这些文字是那篇帖子稍加修改后得到。请见谅,文章有一点长。* -要成为一名专业的程序员,你需要知道的事情多得令人吃惊:语言的细节,API,算法,数据结构,系统和工具。这些东西一直在随着时间变化——新的语言和编程环境不断出现,似乎总有热门的新工具或新语言是“每个人”都在使用的。紧跟潮流,保持专业,这很重要。木匠需要知道如何为工作选择合适的锤子和钉子,并且要有能力笔直精准地钉入钉子。 +要成为一名专业的程序员,你需要知道的事情多得令人吃惊:语言的细节、API、算法、数据结构、系统和工具。这些东西一直在随着时间变化——新的语言和编程环境不断出现,似乎总有一些“每个人”都在使用的热门的新工具或新语言。紧跟潮流,保持专业,这很重要。木匠需要知道如何为工作选择合适的锤子和钉子,并且要有能力笔直精准地钉入钉子。 与此同时,我也发现有一些理论和方法有着广泛的应用场景,它们能使用几十年。底层设备的性能和容量在这几十年来增长了几个数量级,但系统设计的思考方式还是互相有关联的,这些思考方式比具体的实现更根本。理解这些重复出现的主题对分析与设计我们所负责的系统大有帮助。 -谦卑和自我 +### 谦卑和自我 -这不仅仅局限于编程,但在编程这个持续发展的领域,一个人需要在谦卑和自我中保持平衡。总有新的东西需要学习,并且总有人能帮助你学习——如果你愿意学习的话。一个人即需要保持谦卑,认识到自己不懂并承认它,也要保持自我,相信自己能掌握一个新的领域,并且能运用你已经掌握的知识。我见过的最大的挑战就是一些人在某个领域深入专研了很长时间,“忘记”了自己擅长学习新的东西。最好的学习来自放手去做,建造一些东西,即便只是一个原型或者 hack。我知道的最好的程序员对技术有广泛的认识,但同时他们对某个技术深入研究,成为了专家。而深入的学习来自努力解决真正困难的问题。 +这不仅仅局限于编程,但在编程这个持续发展的领域,一个人需要在谦卑和自我中保持平衡。总有新的东西需要学习,并且总有人能帮助你学习——如果你愿意学习的话。一个人即需要保持谦卑,认识到自己不懂并承认它,也要保持自我,相信自己能掌握一个新的领域,并且能运用你已经掌握的知识。我见过的最大的挑战就是一些人在某个领域深入专研了很长时间,“忘记”了自己擅长学习新的东西。最好的学习来自放手去做,建造一些东西,即便只是一个原型或者 hack。我知道的最好的程序员对技术有广泛的认识,但同时他们对某个技术深入研究,成为了专家。而深入的学习来自努力解决真正困难的问题。 -端到端观点 +### 端到端观点 -1981 年,Jerry Saltzer, Dave Reed 和 Dave Clark 在做因特网和分布式系统的早期工作,他们提出了端到端观点,并作出了[经典的阐述][4]。网络上的文章有许多误传,所以更应该阅读论文本身。论文的作者很谦虚,没有声称这是他们自己的创造——从他们的角度看,这只是一个常见的工程策略,不只在通讯领域中,在其他领域中也有运用。他们只是将其写下来并收集了一些例子。下面是文章的一个小片段: +1981 年,Jerry Saltzer、 Dave Reed 和 Dave Clark 在做因特网和分布式系统的早期工作,他们提出了端到端end to end观点,并作出了[经典的阐述][4]。网络上的文章有许多误传,所以更应该阅读论文本身。论文的作者很谦虚,没有声称这是他们自己的创造——从他们的角度看,这只是一个常见的工程策略,不只在通讯领域中,在其他领域中也有运用。他们只是将其写下来并收集了一些例子。下面是文章的一个小片段: > 当我们设计系统的一个功能时,仅依靠端点的知识和端点的参与,就能正确地完整地实现这个功能。在一些情况下,系统的内部模块局部实现这个功能,可能会对性能有重要的提升。 -论文称这是一个“观点”,虽然在维基百科和其他地方它已经被上升成“原则”。实际上,还是把它看作一个观点比较好,正如作者们所说,系统设计者面临的最难的问题之一就是如何在系统组件之间划分责任,这会引发不断的讨论:怎样在划分功能时权衡利弊,怎样隔离复杂性,怎样设计一个灵活的高性能系统来满足不断变化的需求。没有简单的原则可以直接遵循。 +该论文称这是一个“观点”,虽然在维基百科和其他地方它已经被上升成“原则”。实际上,还是把它看作一个观点比较好,正如作者们所说,系统设计者面临的最难的问题之一就是如何在系统组件之间划分责任,这会引发不断的讨论:怎样在划分功能时权衡利弊,怎样隔离复杂性,怎样设计一个灵活的高性能系统来满足不断变化的需求。没有简单的原则可以直接遵循。 -互联网上的大部分讨论集中在通信系统上,但端到端观点的适用范围其实更广泛。分布式系统中的“最终一致性”就是一个例子。一个满足“最终一致性”的系统,可以让系统中的元素暂时进入不一致的状态,从而简化系统,优化性能,因为有一个更大的端到端过程来解决不一致的状态。我喜欢横向拓展的订购系统的例子(例如亚马逊),它不要求每个请求都通过中央库存的控制点。缺少中央控制点可能允许两个终端出售相同的最后一本书,所以系统需要用某种方法来解决这个问题,如通知客户该书会延期交货。不论怎样设计,想购买的最后一本书在订单完成前都有可能被仓库中的叉车运出厍(译者注:比如被其他人下单购买)。一旦你意识到你需要一个端到端的解决方案,并实现了这个方案,那系统内部的设计就可以被优化,并利用这个解决方案。 +互联网上的大部分讨论集中在通信系统上,但端到端观点的适用范围其实更广泛。分布式系统中的“最终一致性eventual consistency”就是一个例子。一个满足“最终一致性”的系统,可以让系统中的元素暂时进入不一致的状态,从而简化系统,优化性能,因为有一个更大的端到端过程来解决不一致的状态。我喜欢横向拓展的订购系统的例子(例如亚马逊),它不要求每个请求都通过中央库存的控制点。缺少中央控制点可能允许两个终端出售相同的最后一本书,所以系统需要用某种方法来解决这个问题,如通知客户该书会延期交货。不论怎样设计,想购买的最后一本书在订单完成前都有可能被仓库中的叉车运出厍(LCTT 译注:比如被其他人下单购买)。一旦你意识到你需要一个端到端的解决方案,并实现了这个方案,那系统内部的设计就可以被优化以利用这个解决方案。 事实上,这种设计上的灵活性可以优化系统的性能,或者提供其他的系统功能,从而使得端到端的方法变得如此强大。端到端的思考往往允许内部进行灵活的操作,使整个系统更加健壮,并且能适应每个组件特性的变化。这些都让端到端的方法变得健壮,并能适应变化。 -端到端方法意味着,添加会牺牲整体性能灵活性的抽象层和功能时要非常小心(也可能是其他的灵活性,但性能,特别是延迟,往往是特殊的)。如果你展示出底层的原始性能(performance, 也可能指操作),端到端的方法可以根据这个性能(操作)来优化,实现特定的需求。如果你破坏了底层性能(操作),即使你实现了重要的有附加价值的功能,你也牺牲了设计灵活性。 +端到端方法意味着,添加会牺牲整体性能灵活性的抽象层和功能时要非常小心(也可能是其他的灵活性,但性能,特别是延迟,往往是特殊的)。如果你展示出底层的原始性能(LCTT 译注:performance,也可能指操作,下同),端到端的方法可以根据这个性能(操作)来优化,实现特定的需求。如果你破坏了底层性能(操作),即使你实现了重要的有附加价值的功能,你也牺牲了设计灵活性。 如果系统足够庞大而且足够复杂,需要把整个开发团队分配给系统内部的组件,那么端到端观点可以和团队组织相结合。这些团队自然要扩展这些组件的功能,他们通常从牺牲设计上的灵活性开始,尝试在组件上实现端到端的功能。 应用端到端方法面临的挑战之一是确定端点在哪里。 俗话说,“大跳蚤上有小跳蚤,小跳蚤上有更少的跳蚤……等等”。 -关注复杂性 +### 关注复杂性 -编程是一门精确的艺术,每一行代码都要确保程序的正确执行。但这是带有误导的。编程的复杂性不在于各个部分的整合,也不在于各个部分之间如何相互交互。最健壮的程序将复杂性隔离开,让最重要的部分变的简单直接,通过简单的方式与其他部分交互。虽然隐藏复杂性和信息隐藏、数据抽象等其他设计方法一样,但我仍然觉得,如果你真的要定位出系统的复杂所在,并将其隔离开,那你需要对设计特别敏锐。 +编程是一门精确的艺术,每一行代码都要确保程序的正确执行。但这是带有误导的。编程的复杂性不在于各个部分的整合,也不在于各个部分之间如何相互交互。最健壮的程序会将复杂性隔离开,让最重要的部分变的简单直接,通过简单的方式与其他部分交互。虽然隐藏复杂性和信息隐藏、数据抽象等其他设计方法一样,但我仍然觉得,如果你真的要定位出系统的复杂所在,并将其隔离开,那你需要对设计特别敏锐。 -在我的[文章][5]中反复提到的例子是早期的终端编辑器 VI 和 Emacs 中使用的屏幕重绘算法。早期的视频终端实现了控制序列,来控制绘制字符核心操作,也实现了附加的显示功能,来优化重新绘制屏幕,如向上向下滚动当前行,或者插入新行,或在当前行中移动字符。这些命令都具有不同的开销,并且这些开销在不同制造商的设备中也是不同的。(参见[TERMCAP][6]以获取代码链接和更完整的历史记录。)像文本编辑器这样的全屏应用程序希望尽快更新屏幕,因此需要优化使用这些控制序列来转换屏幕从一个状态到另一个状态。 +在我的[文章][5]中反复提到的例子是早期的终端编辑器 VI 和 Emacs 中使用的屏幕重绘算法。早期的视频终端实现了控制序列,来控制绘制字符核心操作,也实现了附加的显示功能,来优化重新绘制屏幕,如向上向下滚动当前行,或者插入新行,或在当前行中移动字符。这些命令都具有不同的开销,并且这些开销在不同制造商的设备中也是不同的。(参见[TERMCAP][6] 以获取代码和更完整的历史记录的链接。)像文本编辑器这样的全屏应用程序希望尽快更新屏幕,因此需要优化使用这些控制序列来从一个状态到另一个状态屏幕转换。 -这些程序在设计上隐藏了底层的复杂性。系统中修改文本缓冲区的部分(功能上大多数创新都在这里)完全忽略了这些改变如何被转换成屏幕更新命令。这是可以接受的,因为针对*任何*内容的改变计算最佳命令所消耗的性能代价,远不及被终端本身实际执行这些更新命令的性能代价。在确定如何隐藏复杂性,以及隐藏哪些复杂性时,性能分析扮演着重要的角色,这一点在系统设计中非常常见。屏幕的更新与底层文本缓冲区的更改是异步的,并且可以独立于缓冲区的实际历史变化顺序。缓冲区*怎样*改变的并不重要,重要的是改变了*什么*。异步耦合,在组件交互时消除组件对历史路径依赖的组合,以及用自然的交互方式以有效地将组件组合在一起是隐藏耦合复杂度的常见特征。 +这些程序在设计上隐藏了底层的复杂性。系统中修改文本缓冲区的部分(功能上大多数创新都在这里)完全忽略了这些改变如何被转换成屏幕更新命令。这是可以接受的,因为针对*任何*内容的改变计算最佳命令所消耗的性能代价,远不及被终端本身实际执行这些更新命令的性能代价。在确定如何隐藏复杂性,以及隐藏哪些复杂性时,性能分析扮演着重要的角色,这一点在系统设计中非常常见。屏幕的更新与底层文本缓冲区的更改是异步的,并且可以独立于缓冲区的实际历史变化顺序。缓冲区是*怎样*改变的并不重要,重要的是改变了*什么*。异步耦合,在组件交互时消除组件对历史路径依赖的组合,以及用自然的交互方式以有效地将组件组合在一起是隐藏耦合复杂度的常见特征。 隐藏复杂性的成功不是由隐藏复杂性的组件决定的,而是由使用该模块的使用者决定的。这就是为什么组件的提供者至少要为组件的某些端到端过程负责。他们需要清晰的知道系统的其他部分如何与组件相互作用,复杂性是如何泄漏出来的(以及是否泄漏出来)。这常常表现为“这个组件很难使用”这样的反馈——这通常意味着它不能有效地隐藏内部复杂性,或者没有选择一个隐藏复杂性的功能边界。 -分层与组件化 +### 分层与组件化 -系统设计人员的一个基本工作是确定如何将系统分解成组件和层;决定自己要开发什么,以及从别的地方获取什么。开源项目在决定自己开发组件还是购买服务时,大多会选择自己开发,但组件之间交互的过程是一样的。在大规模工程中,理解这些决策将如何随着时间的推移而发挥作用是非常重要的。从根本上说,变化是程序员所做的一切的基础,所以这些设计决定不仅在当下被评估,还要随着产品的不断发展而在未来几年得到评估。 +系统设计人员的一个基本工作是确定如何将系统分解成组件和层;决定自己要开发什么,以及从别的地方获取什么。开源项目在决定自己开发组件还是购买服务时,大多会选择自己开发,但组件之间交互的过程是一样的。在大规模工程中,理解这些决策将如何随着时间的推移而发挥作用是非常重要的。从根本上说,变化是程序员所做的一切的基础,所以这些设计决定不仅要在当下评估,还要随着产品的不断发展而在未来几年得到评估。 以下是关于系统分解的一些事情,它们最终会占用大量的时间,因此往往需要更长的时间来学习和欣赏。 -* 层泄漏。层(或抽象)[基本上是泄漏的][1]。这些泄漏会立即产生后果,也会随着时间的推移而产生两方面的后果。其中一方面就是该抽象层的特性渗透到了系统的其他部分,渗透的程度比你意识到得更深入。这些渗透可能是关于具体的性能特征的假设,以及抽象层的文档中没有明确的指出的行为发生的顺序。这意味着假如内部组件的行为发生变化,你的系统会比想象中更加脆弱。第二方面是你比表面上看起来更依赖组件内部的行为,所以如果你考虑改变这个抽象层,后果和挑战可能超出你的想象。 +* **层泄漏。**层(或抽象)[基本上是泄漏的][1]。这些泄漏会立即产生后果,也会随着时间的推移而产生两方面的后果。其中一方面就是该抽象层的特性渗透到了系统的其他部分,渗透的程度比你意识到得更深入。这些渗透可能是关于具体的性能特征的假设,以及抽象层的文档中没有明确的指出的行为发生的顺序。这意味着假如内部组件的行为发生变化,你的系统会比想象中更加脆弱。第二方面是你比表面上看起来更依赖组件内部的行为,所以如果你考虑改变这个抽象层,后果和挑战可能超出你的想象。 +* **层具有太多功能。**您所采用的组件具有比实际需要更多的功能,这几乎是一个真理。在某些情况下,你决定采用这个组件是因为你想在将来使用那些尚未用到的功能。有时,你采用组件是想“上快车”,利用组件完成正在进行的工作。在功能强大的抽象层上开发会带来一些后果。 + 1. 组件往往会根据你并不需要的功能作出取舍。 + 2. 为了实现那些你并不没有用到的功能,组件引入了复杂性和约束,这些约束将阻碍该组件的未来的演变。 + 3. 层泄漏的范围更大。一些泄漏是由于真正的“抽象泄漏”,另一些是由于明显的,逐渐增加的对组件全部功能的依赖(但这些依赖通常都没有处理好)。Office 软件太大了,我们发现,对于我们建立的任何抽象层,我们最终都在系统的某个部分完全运用了它的功能。虽然这看起来是积极的(我们完全地利用了这个组件),但并不是所用的使用都有同样的价值。所以,我们最终要付出巨大的代价才能从一个抽象层往另一个抽象层迁移,这种“长尾”没什么价值,并且对使用场景认识不足。 + 4. 附加的功能会增加复杂性,并增加功能滥用的可能。如果将验证 XML 的 API 指定为 XML 树的一部分,那这个 API 可以选择动态下载 XML 的模式定义。这在我们的基本文件解析代码中被错误地执行,导致 w3c.org 服务器上的大量性能下降以及(无意)分布式拒绝服务攻击。(这些被通俗地称为“地雷”API)。 +* **抽象层被更换。**需求在进化,系统在进化,组件被放弃。您最终需要更换该抽象层或组件。不管是对外部组件的依赖还是对内部组件的依赖都是如此。这意味着上述问题将变得重要起来。 +* **自己构建还是购买的决定将会改变。**这是上面几方面的必然结果。这并不意味着自己构建还是购买的决定在当时是错误的。一开始时往往没有合适的组件,一段时间之后才有合适的组件出现。或者,也可能你使用了一个组件,但最终发现它不符合您不断变化的要求,而且你的要求非常窄、很好理解,或者对你的价值体系来说是非常重要的,以至于拥有自己的模块是有意义的。这意味着你像关心自己构造的模块一样,关心购买的模块,关心它们是怎样泄漏并深入你的系统中的。 +* **抽象层会变臃肿。**一旦你定义了一个抽象层,它就开始增加功能。层是对使用模式优化的自然分界点。臃肿的层的困难在于,它往往会降低您利用底层的不断创新的能力。从某种意义上说,这就是操作系统公司憎恨构建在其核心功能之上的臃肿的层的原因——采用创新的速度放缓了。避免这种情况的一种比较规矩的方法是禁止在适配器层中进行任何额外的状态存储。微软基础类在 Win32 上采用这个一般方法。在短期内,将功能集成到现有层(最终会导致上述所有问题)而不是重构和重新推导是不可避免的。理解这一点的系统设计人员寻找分解和简化组件的方法,而不是在其中增加越来越多的功能。 -* 层具有太多功能了。您所采用的组件具有比实际需要更多的功能,这几乎是一个真理。在某些情况下,你决定采用这个组件是因为你想在将来使用那些尚未用到的功能。有时,你采用组件是想“上快车”,利用组件完成正在进行的工作。在功能强大的抽象层上开发会带来一些后果。1) 组件往往会根据你并不需要的功能作出取舍。 2) 为了实现那些你并不没有用到的功能,组件引入了复杂性和约束,这些约束将阻碍该组件的未来的演变。3) 层泄漏的范围更大。一些泄漏是由于真正的“抽象泄漏”,另一些是由于明显的,逐渐增加的对组件全部功能的依赖(但这些依赖通常都没有处理好)。Office 太大了,我们发现,对于我们建立的任何抽象层,我们最终都在系统的某个部分完全运用了它的功能。虽然这看起来是积极的(我们完全地利用了这个组件),但并不是所用的使用都有同样的价值。所以,我们最终要付出巨大的代价才能从一个抽象层往另一个抽象层迁移,这种“长尾巴”没什么价值,并且对使用场景认识不足。4) 附加的功能会增加复杂性,并增加功能滥用的可能。如果将验证 XML 的 API 指定为 XML 树的一部分,那这个 API 可以选择动态下载 XML 的模式定义。这在我们的基本文件解析代码中被错误地执行,导致 w3c.org 服务器上的大量性能下降以及(无意)分布式拒绝服务攻击。(这些被通俗地称为“地雷”API)。 +### 爱因斯坦宇宙 -* 抽象层被更换。需求发展,系统发展,组件被放弃。您最终需要更换该抽象层或组件。不管是对外部组件的依赖还是对内部组件的依赖都是如此。这意味着上述问题将变得重要起来。 - -* 自己构建还是购买的决定将会改变。这是上面几方面的必然结果。这并不意味着自己构建还是购买的决定在当时是错误的。一开始时往往没有合适的组件,一段时间之后才有合适的组件出现。或者,也可能你使用了一个组件,但最终发现它不符合您不断变化的要求,而且你的要求非常窄,能被理解,或着对你的价值体系来说是非常重要的,以至于拥有自己的模块是有意义的。这意味着你像关心自己构造的模块一样,关心购买的模块,关心它们是怎样泄漏并深入你的系统中的。 - -* 抽象层会变臃肿。一旦你定义了一个抽象层,它就开始增加功能。层是对使用模式优化的自然分界点。臃肿的层的困难在于,它往往会降低您利用底层的不断创新的能力。从某种意义上说,这就是操作系统公司憎恨构建在其核心功能之上的臃肿的层的原因——采用创新的速度放缓了。避免这种情况的一种比较规矩的方法是禁止在适配器层中进行任何额外的状态存储。微软基础类在 Win32 上采用这个一般方法。在短期内,将功能集成到现有层(最终会导致上述所有问题)而不是重构和重新推导是不可避免的。理解这一点的系统设计人员寻找分解和简化组件的方法,而不是在其中增加越来越多的功能。 - -爱因斯坦宇宙 - -几十年来,我一直在设计异步分布式系统,但是在微软内部的一次演讲中,SQL 架构师 Pat Helland 的一句话震惊了我。 “我们生活在爱因斯坦的宇宙中,没有同时性。”在构建分布式系统时(基本上我们构建的都是分布式系统),你无法隐藏系统的分布式特性。这是物理的。我一直感到远程过程调用在根本上错误的,这是一个原因,尤其是那些“透明的”远程过程调用,它们就是想隐藏分布式的交互本质。你需要拥抱系统的分布式特性,因为这些意义几乎总是需要通过系统设计和用户体验来完成。 +几十年来,我一直在设计异步分布式系统,但是在微软内部的一次演讲中,SQL 架构师 Pat Helland 的一句话震惊了我。 “我们生活在爱因斯坦的宇宙中,没有同时性这种东西。”在构建分布式系统时(基本上我们构建的都是分布式系统),你无法隐藏系统的分布式特性。这是物理的。我一直感到远程过程调用在根本上错误的,这是一个原因,尤其是那些“透明的”远程过程调用,它们就是想隐藏分布式的交互本质。你需要拥抱系统的分布式特性,因为这些意义几乎总是需要通过系统设计和用户体验来完成。 拥抱分布式系统的本质则要遵循以下几个方面: * 一开始就要思考设计对用户体验的影响,而不是试图在处理错误,取消请求和报告状态上打补丁。 - * 使用异步技术来耦合组件。同步耦合是*不可能*的。如果某些行为看起来是同步的,是因为某些内部层尝试隐藏异步,这样做会遮蔽(但绝对不隐藏)系统运行时的基本行为特征。 - * 认识到并且明确设计了交互状态机,这些状态表示长期的可靠的内部系统状态(而不是由深度调用堆栈中的变量值编码的临时,短暂和不可发现的状态)。 - * 认识到失败是在所难免的。要保证能检测出分布式系统中的失败,唯一的办法就是直接看你的等待时间是否“太长”。这自然意味着[取消的等级最高][2]。系统的某一层(可能直接通向用户)需要决定等待时间是否过长,并取消操作。取消只是为了重建局部状态,回收局部的资源——没有办法在系统内广泛使用取消机制。有时用一种低成本,不可靠的方法广泛使用取消机制对优化性能可能有用。 - * 认识到取消不是回滚,因为它只是回收本地资源和状态。如果回滚是必要的,它必须实现成一个端到端的功能。 - * 承认永远不会真正知道分布式组件的状态。只要你发现一个状态,它可能就已经改变了。当你发送一个操作时,请求可能在传输过程中丢失,也可能被处理了但是返回的响应丢失了,或者请求需要一定的时间来处理,这样远程状态最终会在未来的某个任意的时间转换。这需要像幂等操作这样的方法,并且要能够稳健有效地重新发现远程状态,而不是期望可靠地跟踪分布式组件的状态。“[最终一致性][3]”的概念简洁地捕捉了这其中大多数想法。 我喜欢说你应该“陶醉在异步”。与其试图隐藏异步,不如接受异步,为异步而设计。当你看到像幂等性或不变性这样的技术时,你就认识到它们是拥抱宇宙本质的方法,而不仅仅是工具箱中的一个设计工具。 -性能 +### 性能 -我确信 Don Knuth 会对人们怎样误解他的名言“过早的优化是一切罪恶的根源”而感到震惊。事实上,性能,及性能持续超过60年的指数增长(或超过10年,取决于您是否愿意将晶体管,真空管和机电继电器的发展算入其中),为所有行业内的惊人创新和影响经济的“软件吃遍世界”的变化打下了基础。 +我确信 Don Knuth 会对人们怎样误解他的名言“过早的优化是一切罪恶的根源”而感到震惊。事实上,性能,及性能的持续超过 60 年的指数增长(或超过 10 年,取决于您是否愿意将晶体管,真空管和机电继电器的发展算入其中),为所有行业内的惊人创新和影响经济的“软件吃掉全世界”的变化打下了基础。 -要认识到这种指数变化的一个关键是,虽然系统的所有组件正在经历指数变化,但这些指数是不同的。硬盘容量的增长速度与内存容量的增长速度不同,与 CPU 的增长速度不同,与内存 CPU 之间的延迟的性能改善速度也不用。即使性能发展的趋势是由相同的基础技术驱动的,增长的指数也会有分歧。[延迟的改进从根本上改善了带宽][7]。指数变化在近距离或者短期内看起来是线性的,但随着时间的推移可能是压倒性的。系统不同组件的性能的增长不同,会出现压倒性的变化,并迫使对设计决策定期进行重新评估。 +要认识到这种指数变化的一个关键是,虽然系统的所有组件正在经历指数级变化,但这些指数是不同的。硬盘容量的增长速度与内存容量的增长速度不同,与 CPU 的增长速度不同,与内存 CPU 之间的延迟的性能改善速度也不用。即使性能发展的趋势是由相同的基础技术驱动的,增长的指数也会有分歧。[延迟的改进从根本上改善了带宽][7]。指数变化在近距离或者短期内看起来是线性的,但随着时间的推移可能是压倒性的。系统不同组件的性能的增长不同,会出现压倒性的变化,并迫使对设计决策定期进行重新评估。 -这样做的结果是,几年后,一度有意义的设计决定就不再有意义了。或者在某些情况下,二十年前有意义的方法又开始变成一个好的决定。现代内存映射的特点看起来更像是早期分时的进程切换,而不像分页那样。 (这样做有时会让我这样的老人说“这就是我们在 1975 年时用的方法”——忽略了这种方法在 40 年都没有意义,但现在又重新成为好的方法,因为两个组件之间的关系——可能是闪存和 NAND 而不是磁盘和核心内存——已经变得像以前一样了)。 +这样做的结果是,几年后,一度有意义的设计决策就不再有意义了。或者在某些情况下,二十年前有意义的方法又开始变成一个好的决策。现代内存映射的特点看起来更像是早期分时的进程切换,而不像分页那样。 (这样做有时会让我这样的老人说“这就是我们在 1975 年时用的方法”——忽略了这种方法在 40 年都没有意义,但现在又重新成为好的方法,因为两个组件之间的关系——可能是闪存和 NAND 而不是磁盘和核心内存——已经变得像以前一样了)。 -当这些指数超越人自身的限制时,重要的转变就发生了。你能从 2 的 16 次方个字符(一个人可以在几个小时打这么多字)过渡到 2 的 3 次方个字符(远超出了一个人打字的范围)。你可以捕捉比人眼能感知的分辨率更高的数字图像。或者你可以将整个音乐专辑存在小巧的磁盘上,放在口袋里。或者你可以将数字化视频录制存储在硬盘上。再通过实时流式传输的能力,可以在一个地方集中存储一次,不需要在数千个本地硬盘上重复记录。 +当这些指数超越人自身的限制时,重要的转变就发生了。你能从 2 的 16 次方个字符(一个人可以在几个小时打这么多字)过渡到 2 的 32 次方个字符(远超出了一个人打字的范围)。你可以捕捉比人眼能感知的分辨率更高的数字图像。或者你可以将整个音乐专辑存在小巧的磁盘上,放在口袋里。或者你可以将数字化视频录制存储在硬盘上。再通过实时流式传输的能力,可以在一个地方集中存储一次,不需要在数千个本地硬盘上重复记录。 -但有的东西仍然是根本的限制条件,那就是空间的三维和光速。我们又回到了爱因斯坦的宇宙。内存的分级结构将始终存在——它是物理定律的基础。稳定的存储和 IO,内存,计算和通信也都将一直存在。这些模块的相对容量,延迟和带宽将会改变,但是系统始终要考虑这些元素如何组合在一起,以及它们之间的平衡和折衷。Jim Gary 是这方面的大师。 +但有的东西仍然是根本的限制条件,那就是空间的三维和光速。我们又回到了爱因斯坦的宇宙。内存的分级结构将始终存在——它是物理定律的基础。稳定的存储和 IO、内存、计算和通信也都将一直存在。这些模块的相对容量,延迟和带宽将会改变,但是系统始终要考虑这些元素如何组合在一起,以及它们之间的平衡和折衷。Jim Gary 是这方面的大师。 -空间和光速的根本限制造成的另一个后果是,性能分析主要是关于三件事:局部化 (locality),局部化,局部化。无论是将数据打包在磁盘上,管理处理器缓存的层次结构,还是将数据合并到通信数据包中,数据如何打包在一起,如何在一段时间内从局部获取数据,数据如何在组件之间传输数据是性能的基础。把重点放在减少管理数据的代码上,增加空间和时间上的局部性,是消除噪声的好办法。 +空间和光速的根本限制造成的另一个后果是,性能分析主要是关于三件事:局部化locality局部化locality局部化locality。无论是将数据打包在磁盘上,管理处理器缓存的层次结构,还是将数据合并到通信数据包中,数据如何打包在一起,如何在一段时间内从局部获取数据,数据如何在组件之间传输数据是性能的基础。把重点放在减少管理数据的代码上,增加空间和时间上的局部性,是消除噪声的好办法。 Jon Devaan 曾经说过:“设计数据,而不是设计代码”。这也通常意味着当查看系统结构时,我不太关心代码如何交互——我想看看数据如何交互和流动。如果有人试图通过描述代码结构来解释一个系统,而不理解数据流的速率和数量,他们就不了解这个系统。 -内存的层级结构也意味着我缓存将会一直存在——即使某些系统层正在试图隐藏它。缓存是根本的,但也是危险的。缓存试图利用代码的运行时行为,来改变系统中不同组件之间的交互模式。它们需要对运行时行为进行建模,即使模型填充缓存并使缓存失效,并测试缓存命中。如果模型由于行为改变而变差或变得不佳,缓存将无法按预期运行。一个简单的指导方针是,缓存必须被检测——由于应用程序行为的改变,事物不断变化的性质和组件之间性能的平衡,缓存的行为将随着时间的推移而退化。每一个老程序员都有缓存变糟的经历。 +内存的层级结构也意味着缓存将会一直存在——即使某些系统层正在试图隐藏它。缓存是根本的,但也是危险的。缓存试图利用代码的运行时行为,来改变系统中不同组件之间的交互模式。它们需要对运行时行为进行建模,即使模型填充缓存并使缓存失效,并测试缓存命中。如果模型由于行为改变而变差或变得不佳,缓存将无法按预期运行。一个简单的指导方针是,缓存必须被检测——由于应用程序行为的改变,事物不断变化的性质和组件之间性能的平衡,缓存的行为将随着时间的推移而退化。每一个老程序员都有缓存变糟的经历。 我很幸运,我的早期职业生涯是在互联网的发源地之一 BBN 度过的。 我们很自然地将将异步组件之间的通信视为系统连接的自然方式。流量控制和队列理论是通信系统的基础,更是任何异步系统运行的方式。流量控制本质上是资源管理(管理通道的容量),但资源管理是更根本的关注点。流量控制本质上也应该由端到端的应用负责,所以用端到端的方式思考异步系统是自然的。[缓冲区膨胀][8]的故事在这种情况下值得研究,因为它展示了当对端到端行为的动态性以及技术“改进”(路由器中更大的缓冲区)缺乏理解时,在整个网络基础设施中导致的长久的问题。 - 我发现“光速”的概念在分析任何系统时都非常有用。光速分析并不是从当前的性能开始分析,而是问“这个设计理论上能达到的最佳性能是多少?”真正传递的信息是什么,以什么样的速度变化?组件之间的底层延迟和带宽是多少?光速分析迫使设计师深入思考他们的方法能否达到性能目标,或者否需要重新考虑设计的基本方法。它也迫使人们更深入地了解性能在哪里损耗,以及损耗是由固有的,还是由于一些不当行为产生的。从构建的角度来看,它迫使系统设计人员了解其构建的模块的真实性能特征,而不是关注其他功能特性。 +我发现“光速light speed”的概念在分析任何系统时都非常有用。光速分析并不是从当前的性能开始分析,而是问“这个设计理论上能达到的最佳性能是多少?”真正传递的信息是什么,以什么样的速度变化?组件之间的底层延迟和带宽是多少?光速分析迫使设计师深入思考他们的方法能否达到性能目标,或者否需要重新考虑设计的基本方法。它也迫使人们更深入地了解性能在哪里损耗,以及损耗是由固有的,还是由于一些不当行为产生的。从构建的角度来看,它迫使系统设计人员了解其构建的模块的真实性能特征,而不是关注其他功能特性。 我的职业生涯大多花费在构建图形应用程序上。用户坐在系统的一端,定义关键的常量和约束。人类的视觉和神经系统没有经历过指数性的变化。它们固有地受到限制,这意味着系统设计者可以利用(必须利用)这些限制,例如,通过虚拟化(限制底层数据模型需要映射到视图数据结构中的数量),或者通过将屏幕更新的速率限制到人类视觉系统的感知限制。 -复杂性的本质 +### 复杂性的本质 我的整个职业生涯都在与复杂性做斗争。为什么系统和应用变得复杂呢?为什么在一个应用领域内进行开发并没有随着时间变得简单,而基础设施却没有变得更复杂,反而变得更强大了?事实上,管理复杂性的一个关键方法就是“走开”然后重新开始。通常新的工具或语言迫使我们从头开始,这意味着开发人员将工具的优点与从新开始的优点结合起来。从新开始是重要的。这并不是说新工具,新平台,或新语言可能不好,但我保证它们不能解决复杂性增长的问题。控制复杂性的最简单的方法就是用更少的程序员,建立一个更小的系统。 -当然,很多情况下“走开”并不是一个选择——Office 建立在有巨大的价值的复杂的资源上。通过 OneNote, Office 从 Word 的复杂性上“走开”,从而在另一个维度上进行创新。Sway 是另一个例子, Office 决定从限制中跳出来,利用关键的环境变化,抓住机会从底层上采取全新的设计方案。我们有 Word,Excel,PowerPoint 这些应用,它们的数据结构非常有价值,我们并不能完全放弃这些数据结构,它们成为了开发中持续的显著的限制条件。 +当然,很多情况下“走开”并不是一个选择——Office 软件建立在有巨大的价值的复杂的资源上。通过 OneNote, Office 从 Word 的复杂性上“走开”,从而在另一个维度上进行创新。Sway 是另一个例子, Office 决定从限制中跳出来,利用关键的环境变化,抓住机会从底层上采取全新的设计方案。我们有 Word、Excel、PowerPoint 这些应用,它们的数据结构非常有价值,我们并不能完全放弃这些数据结构,它们成为了开发中持续的显著的限制条件。 -我受到 Fred Brook 讨论软件开发中的意外和本质的文章[《没有银子弹》][9]的影响,他希望用两个趋势来尽可能地推动程序员的生产力:一是在选择自己开发还是购买时,更多地关注购买——这预示了开源社区和云架构的改变;二是从单纯的构建方法转型到更“有机”或者“生态”的增量开发方法。现代的读者可以认为是向敏捷开发和持续开发的转型。但那篇文章可是写于 1986 年! +我受到 Fred Brook 讨论软件开发中的意外和本质的文章[《没有银弹》][9]的影响,他希望用两个趋势来尽可能地推动程序员的生产力:一是在选择自己开发还是购买时,更多地关注购买——这预示了开源社区和云架构的改变;二是从单纯的构建方法转型到更“有机”或者“生态”的增量开发方法。现代的读者可以认为是向敏捷开发和持续开发的转型。但那篇文章可是写于 1986 年! 我很欣赏 Stuart Kauffman 的在复杂性的基本性上的研究工作。Kauffman 从一个简单的布尔网络模型(“[NK 模型][10]”)开始建立起来,然后探索这个基本的数学结构在相互作用的分子,基因网络,生态系统,经济系统,计算机系统(以有限的方式)等系统中的应用,来理解紧急有序行为的数学基础及其与混沌行为的关系。在一个高度连接的系统中,你固有地有一个相互冲突的约束系统,使得它(在数学上)很难向前发展(这被看作是在崎岖景观上的优化问题)。控制这种复杂性的基本方法是将系统分成独立元素并限制元素之间的相互连接(实质上减少 NK 模型中的“N”和“K”)。当然对那些使用复杂隐藏,信息隐藏和数据抽象,并且使用松散异步耦合来限制组件之间的交互的技术的系统设计者来说,这是很自然的。 - 我们一直面临的一个挑战是,我们想到的许多拓展系统的方法,都跨越了所有的方面。实时共同编辑是 Office 应用程序最近的一个非常具体的(也是最复杂的)例子。 我们的数据模型的复杂性往往等同于“能力”。设计用户体验的固有挑战是我们需要将有限的一组手势,映射到底层数据模型状态空间的转换。增加状态空间的维度不可避免地在用户手势中产生模糊性。这是“[纯数学][11]”,这意味着确保系统保持“易于使用”的最基本的方式常常是约束底层的数据模型。 -管理 +### 管理 -我从高中开始着手一些领导角色(学生会主席!),对承担更多的责任感到理所当然。同时,我一直为自己在每个管理阶段都坚持担任全职程序员而感到自豪。但 Office 的开发副总裁最终还是让我从事管理,离开了日常的编程工作。当我在去年离开那份工作时,我很享受重返编程——这是一个出奇地充满创造力的充实的活动(当修完“最后”的 bug 时,也许也会有一点令人沮丧)。 +我从高中开始担任一些领导角色(学生会主席!),对承担更多的责任感到理所当然。同时,我一直为自己在每个管理阶段都坚持担任全职程序员而感到自豪。但 Office 软件的开发副总裁最终还是让我从事管理,离开了日常的编程工作。当我在去年离开那份工作时,我很享受重返编程——这是一个出奇地充满创造力的充实的活动(当修完“最后”的 bug 时,也许也会有一点令人沮丧)。 尽管在我加入微软前已经做了十多年的“主管”,但是到了 1996 年我加入微软才真正了解到管理。微软强调“工程领导是技术领导”。这与我的观点一致,帮助我接受并承担更大的管理责任。 @@ -124,21 +118,19 @@ Jon Devaan 曾经说过:“设计数据,而不是设计代码”。这也通 我过去说我的工作是设计反馈回路。独立工程师,经理,行政人员,每一个项目的参与者都能通过分析记录的项目数据,推进项目,产出结果,了解自己在整个项目中扮演的角色。最终,透明化最终成为增强能力的一个很好的工具——管理者可以将更多的局部控制权给予那些最接近问题的人,因为他们对所取得的进展有信心。这样的话,合作自然就会出现。 -Key to this is that the goal has actually been properly framed (including key resource constraints like ship schedule). Decision-making that needs to constantly flow up and down the management chain usually reflects poor framing of goals and constraints by management. - 关键需要确定目标框架(包括关键资源的约束,如发布的时间表)。如果决策需要在管理链上下不断流动,那说明管理层对目标和约束的框架不好。 -当我在 Beyond Software 工作时,我真正理解了一个项目拥有一个唯一领导的重要性。原来的项目经理离职了(后来从 FrontPage 雇佣了我)。我们四个主管在是否接任这个岗位上都有所犹豫,这不仅仅由于我们都不知道要在这家公司坚持多久。我们都技术高超,并且相处融洽,所以我们决定以同级的身份一起来领导这个项目。然而这槽糕透了。有一个显而易见的问题,我们没有相应的战略用来在原有的组织之间分配资源——这应当是管理者的首要职责之一!当你知道你是唯一的负责人时,你会有很深的责任感,但在这个例子中,这种责任感缺失了。我们没有真正的领导来负责统一目标和界定约束。 +当我在 Beyond Software 工作时,我真正理解了一个项目拥有一个唯一领导的重要性。原来的项目经理离职了(后来从 FrontPage 团队雇佣了我)。我们四个主管在是否接任这个岗位上都有所犹豫,这不仅仅由于我们都不知道要在这家公司坚持多久。我们都技术高超,并且相处融洽,所以我们决定以同级的身份一起来领导这个项目。然而这槽糕透了。有一个显而易见的问题,我们没有相应的战略用来在原有的组织之间分配资源——这应当是管理者的首要职责之一!当你知道你是唯一的负责人时,你会有很深的责任感,但在这个例子中,这种责任感缺失了。我们没有真正的领导来负责统一目标和界定约束。 -我有清晰地记得,我第一次充分认识到*倾听*对一个领导者的重要性。那时我刚刚担任了 Word,OneNote,Publisher 和 Text Services 团队的开发经理。关于我们如何组织文本服务团队,我们有一个很大的争议,我走到了每个关键参与者身边,听他们想说的话,然后整合起来,写下了我所听到的一切。当我向其中一位主要参与者展示我写下的东西时,他的反应是“哇,你真的听了我想说的话”!作为一名管理人员,我所经历的所有最大的问题(例如,跨平台和转型持续工程)涉及到仔细倾听所有的参与者。倾听是一个积极的过程,它包括:尝试以别人的角度去理解,然后写出我学到的东西,并对其进行测试,以验证我的理解。当一个关键的艰难决定需要发生的时候,在最终决定前,每个人都知道他们的想法都已经被听到并理解(不论他们是否同意最后的决定)。 +我有清晰地记得,我第一次充分认识到*倾听*对一个领导者的重要性。那时我刚刚担任了 Word、OneNote、Publisher 和 Text Services 团队的开发经理。关于我们如何组织文本服务团队,我们有一个很大的争议,我走到了每个关键参与者身边,听他们想说的话,然后整合起来,写下了我所听到的一切。当我向其中一位主要参与者展示我写下的东西时,他的反应是“哇,你真的听了我想说的话”!作为一名管理人员,我所经历的所有最大的问题(例如,跨平台和转型持续工程)涉及到仔细倾听所有的参与者。倾听是一个积极的过程,它包括:尝试以别人的角度去理解,然后写出我学到的东西,并对其进行测试,以验证我的理解。当一个关键的艰难决定需要发生的时候,在最终决定前,每个人都知道他们的想法都已经被听到并理解(不论他们是否同意最后的决定)。 -在 FrontPage 担任开发经理的工作,让我理解了在只有部分信息的情况下做决定的“操作困境”。你等待的时间越长,你就会有更多的信息做出决定。但是等待的时间越长,实际执行的灵活性就越低。在某个时候,你仅需要做出决定。 +在 FrontPage 团队担任开发经理的工作,让我理解了在只有部分信息的情况下做决定的“操作困境”。你等待的时间越长,你就会有更多的信息做出决定。但是等待的时间越长,实际执行的灵活性就越低。在某个时候,你仅需要做出决定。 -设计一个组织涉及类似的两难情形。您希望增加资源领域,以便可以在更大的一组资源上应用一致的优先级划分框架。但资源领域越大,越难获得作出决定所需要的所有信息。组织设计就是要平衡这两个因素。软件复杂化,因为软件的特点可以在任意维度切入设计。Office 已经使用[共享团队][12]来解决这两个问题(优先次序和资源),让跨领域的团队能与需要产品的团队分享工作(增加资源)。 +设计一个组织涉及类似的两难情形。您希望增加资源领域,以便可以在更大的一组资源上应用一致的优先级划分框架。但资源领域越大,越难获得作出决定所需要的所有信息。组织设计就是要平衡这两个因素。软件复杂化,因为软件的特点可以在任意维度切入设计。Office 软件部门已经使用[共享团队][12]来解决这两个问题(优先次序和资源),让跨领域的团队能与需要产品的团队分享工作(增加资源)。 随着管理阶梯的提升,你会懂一个小秘密:你和你的新同事不会因为你现在承担更多的责任,就突然变得更聪明。这强调了整个组织比顶层领导者更聪明。赋予每个级别在一致框架下拥有自己的决定是实现这一目标的关键方法。听取并使自己对组织负责,阐明和解释决策背后的原因是另一个关键策略。令人惊讶的是,害怕做出一个愚蠢的决定可能是一个有用的激励因素,以确保你清楚地阐明你的推理,并确保你听取所有的信息。 -结语 +### 结语 我离开大学寻找第一份工作时,面试官在最后一轮面试时问我对做“系统”和做“应用”哪一个更感兴趣。我当时并没有真正理解这个问题。在软件技术栈的每一个层面都会有趣的难题,我很高兴深入研究这些问题。保持学习。 @@ -146,9 +138,9 @@ Key to this is that the goal has actually been properly framed (including key re via: https://hackernoon.com/education-of-a-programmer-aaecf2d35312 -作者:[ Terry Crowley][a] +作者:[Terry Crowley][a] 译者:[explosic4](https://github.com/explosic4) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20170628 Notes on BPF and eBPF.md b/published/20170628 Notes on BPF and eBPF.md similarity index 74% rename from translated/tech/20170628 Notes on BPF and eBPF.md rename to published/20170628 Notes on BPF and eBPF.md index b7fad29ba1..f4dc3852a0 100644 --- a/translated/tech/20170628 Notes on BPF and eBPF.md +++ b/published/20170628 Notes on BPF and eBPF.md @@ -7,17 +7,16 @@ 我想在讨论的基础上去写一些笔记,因为,我觉得它超级棒! -这是 [幻灯片][9] 和一个 [pdf][10]。这个 pdf 非常好,结束的位置有一些链接,在 PDF 中你可以直接点击这个链接。 +开始前,这里有个 [幻灯片][9] 和一个 [pdf][10]。这个 pdf 非常好,结束的位置有一些链接,在 PDF 中你可以直接点击这个链接。 ### 什么是 BPF? -在 BPF 出现之前,如果你想去做包过滤,你必须拷贝所有进入用户空间的包,然后才能去过滤它们(使用 “tap”)。 +在 BPF 出现之前,如果你想去做包过滤,你必须拷贝所有的包到用户空间,然后才能去过滤它们(使用 “tap”)。 这样做存在两个问题: -1. 如果你在用户空间中过滤,意味着你将拷贝所有进入用户空间的包,拷贝数据的代价是很昂贵的。 - -2. 使用的过滤算法很低效 +1. 如果你在用户空间中过滤,意味着你将拷贝所有的包到用户空间,拷贝数据的代价是很昂贵的。 +2. 使用的过滤算法很低效。 问题 #1 的解决方法似乎很明显,就是将过滤逻辑移到内核中。(虽然具体实现的细节并没有明确,我们将在稍后讨论) @@ -35,12 +34,11 @@ ### 为什么 BPF 要工作在内核中 -这里的关键点是,包仅仅是个字节的数组。BPF 程序是运行在这些字节的数组上。它们不允许有循环(loops),但是,它们 _可以_  有聪明的办法知道 IP 包头(IPv6 和 IPv4 长度是不同的)以及基于它们的长度来找到 TCP 端口 +这里的关键点是,包仅仅是个字节的数组。BPF 程序是运行在这些字节的数组之上。它们不允许有循环(loop),但是,它们 _可以_  有聪明的办法知道 IP 包头(IPv6 和 IPv4 长度是不同的)以及基于它们的长度来找到 TCP 端口: ``` x = ip_header_length port = *(packet_start + x + port_offset) - ``` (看起来不一样,其实它们基本上都相同)。在这个论文/幻灯片上有一个非常详细的虚拟机的描述,因此,我不打算解释它。 @@ -48,13 +46,9 @@ port = *(packet_start + x + port_offset) 当你运行 `tcpdump host foo` 后,这时发生了什么?就我的理解,应该是如下的过程。 1. 转换 `host foo` 为一个高效的 DAG 规则 - 2. 转换那个 DAG 规则为 BPF 虚拟机的一个 BPF 程序(BPF 字节码) - 3. 发送 BPF 字节码到 Linux 内核,由 Linux 内核验证它 - -4. 编译这个 BPF 字节码程序为一个原生(native)代码。例如, [在 ARM 上是 JIT 代码][1] 以及为 [x86][2] 的机器码 - +4. 编译这个 BPF 字节码程序为一个原生native代码。例如,这是个[ARM 上的 JIT 代码][1] 以及 [x86][2] 的机器码 5. 当包进入时,Linux 运行原生代码去决定是否过滤这个包。对于每个需要去处理的包,它通常仅需运行 100 - 200 个 CPU 指令就可以完成,这个速度是非常快的! ### 现状:eBPF @@ -63,19 +57,15 @@ port = *(packet_start + x + port_offset) 关于 eBPF 的一些事实是: -* eBPF 程序有它们自己的字节码语言,并且从那个字节码语言编译成内核原生代码,就像 BPF 程序 - +* eBPF 程序有它们自己的字节码语言,并且从那个字节码语言编译成内核原生代码,就像 BPF 程序一样 * eBPF 运行在内核中 - -* eBPF 程序不能随心所欲的访问内核内存。而是通过内核提供的函数去取得一些受严格限制的所需要的内容的子集。 - +* eBPF 程序不能随心所欲的访问内核内存。而是通过内核提供的函数去取得一些受严格限制的所需要的内容的子集 * 它们  _可以_  与用户空间的程序通过 BPF 映射进行通讯 - * 这是 Linux 3.18 的 `bpf` 系统调用 ### kprobes 和 eBPF -你可以在 Linux 内核中挑选一个函数(任意函数),然后运行一个你写的每次函数被调用时都运行的程序。这样看起来是不是很神奇。 +你可以在 Linux 内核中挑选一个函数(任意函数),然后运行一个你写的每次该函数被调用时都运行的程序。这样看起来是不是很神奇。 例如:这里有一个 [名为 disksnoop 的 BPF 程序][12],它的功能是当你开始/完成写入一个块到磁盘时,触发它执行跟踪。下图是它的代码片断: @@ -92,45 +82,37 @@ b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start") ``` -从根本上来说,它声明一个 BPF 哈希(它的作用是当请求开始/完成时,这个程序去触发跟踪),一个名为 `trace_start` 的函数将被编译进 BPF 字节码,然后附加 `trace_start` 到内核函数 `blk_start_request` 上。 +本质上它声明一个 BPF 哈希(它的作用是当请求开始/完成时,这个程序去触发跟踪),一个名为 `trace_start` 的函数将被编译进 BPF 字节码,然后附加 `trace_start` 到内核函数 `blk_start_request` 上。 -这里使用的是 `bcc` 框架,它可以使你写的 Python 化的程序去生成 BPF 代码。你可以在 [https://github.com/iovisor/bcc][13] 找到它(那里有非常多的示例程序)。 +这里使用的是 `bcc` 框架,它可以让你写 Python 式的程序去生成 BPF 代码。你可以在 [https://github.com/iovisor/bcc][13] 找到它(那里有非常多的示例程序)。 ### uprobes 和 eBPF -因为我知道你可以附加 eBPF 程序到内核函数上,但是,我不知道你能否将 eBPF 程序附加到用户空间函数上!那会有更多令人激动的事情。这是 [在 Python 中使用一个 eBPF 程序去计数 malloc 调用的示例][14]。 +因为我知道可以附加 eBPF 程序到内核函数上,但是,我不知道能否将 eBPF 程序附加到用户空间函数上!那会有更多令人激动的事情。这是 [在 Python 中使用一个 eBPF 程序去计数 malloc 调用的示例][14]。 ### 附加 eBPF 程序时应该考虑的事情 * 带 XDP 的网卡(我之前写过关于这方面的文章) - * tc egress/ingress (在网络栈上) - * kprobes(任意内核函数) - -* uprobes(很明显,任意用户空间函数??像带符号的任意 C 程序) - +* uprobes(很明显,任意用户空间函数??像带调试符号的任意 C 程序) * probes 是为 dtrace 构建的名为 “USDT probes” 的探针(像 [这些 mysql 探针][3])。这是一个 [使用 dtrace 探针的示例程序][4] - * [JVM][5] - * 跟踪点 - * seccomp / landlock 安全相关的事情 - -* 更多的事情 +* 等等 ### 这个讨论超级棒 -在幻灯片里有很多非常好的链接,并且在  iovisor 仓库里有个 [LINKS.md][15]。现在已经很晚了,但是,很快我将写我的第一个 eBPF 程序了! +在幻灯片里有很多非常好的链接,并且在  iovisor 仓库里有个 [LINKS.md][15]。虽然现在已经很晚了,但是我马上要去写我的第一个 eBPF 程序了! -------------------------------------------------------------------------------- via: https://jvns.ca/blog/2017/06/28/notes-on-bpf---ebpf/ -作者:[Julia Evans ][a] +作者:[Julia Evans][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20170925 Advanced image viewing tricks with ImageMagick.md b/published/20170925 Advanced image viewing tricks with ImageMagick.md new file mode 100644 index 0000000000..57813c80c2 --- /dev/null +++ b/published/20170925 Advanced image viewing tricks with ImageMagick.md @@ -0,0 +1,122 @@ +ImageMagick 的一些高级图片查看技巧 +====== + +> 用这些 ImageMagick 命令行图像编辑应用的技巧更好的管理你的数码照片集。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-photo-camera-green.png?itok=qiDqmXV1) + +图片源于 [Internet Archive Book Images](https://www.flickr.com/photos/internetarchivebookimages/14759826206/in/photolist-ougY7b-owgz5y-otZ9UN-waBxfL-oeEpEf-xgRirT-oeMHfj-wPAvMd-ovZgsb-xhpXhp-x3QSRZ-oeJmKC-ovWeKt-waaNUJ-oeHPN7-wwMsfP-oeJGTK-ovZPKv-waJnTV-xDkxoc-owjyCW-oeRqJh-oew25u-oeFTm4-wLchfu-xtjJFN-oxYznR-oewBRV-owdP7k-owhW3X-oxXxRg-oevDEY-oeFjP1-w7ZB6f-x5ytS8-ow9C7j-xc6zgV-oeCpG1-oewNzY-w896SB-wwE3yA-wGNvCL-owavts-oevodT-xu9Lcr-oxZqZg-x5y4XV-w89d3n-x8h6fi-owbfiq),Opensource.com 修改,[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)协议 + +在我先前的[ImageMagick 入门:使用命令行来编辑图片][1] 文章中,我展示了如何使用 ImageMagick 的菜单栏进行图片的编辑和变换风格。在这篇续文里,我将向你展示使用这个开源的图像编辑器来查看图片的另外方法。 + +### 别样的风格 + +在深入 ImageMagick 的高级图片查看技巧之前,我想先分享另一个使用 `convert` 达到的有趣但简单的效果,在[上一篇文章][1]中我已经详细地介绍了 `convert` 命令,这个技巧涉及这个命令的 `edge` 和 `negate` 选项: + +``` +convert DSC_0027.JPG -edge 3 -negate edge3+negate.jpg +``` + +![在图片上使用 `edge` 和 `negate` 选项][3] + +*使用`edge` 和 `negate` 选项前后的图片对比* + +这些使我更喜爱编辑后的图片:海的外观,作为前景和背景的植被,特别是太阳及其在海上的反射,最后是天空。 + +### 使用 display 来查看一系列图片 + +假如你跟我一样是个命令行用户,你就知道 shell 为复杂任务提供了更多的灵活性和快捷方法。下面我将展示一个例子来佐证这个观点。ImageMagick 的 `display` 命令可以克服我在 GNOME 桌面上使用 [Shotwell][4] 图像管理器导入图片时遇到的问题。 + +Shotwell 会根据每张导入图片的 [Exif][5] 数据,创建以图片被生成或者拍摄时的日期为名称的目录结构。最终的效果是最上层的目录以年命名,接着的子目录是以月命名 (01、 02、 03 等等),然后是以每月的日期命名的子目录。我喜欢这种结构,因为当我想根据图片被创建或者拍摄时的日期来查找它们时将会非常方便。 + +但这种结构也并不是非常完美的,当我想查看最近几个月或者最近一年的所有图片时就会很麻烦。使用常规的图片查看器,我将不停地在不同层级的目录间跳转,但 ImageMagick 的 `display` 命令可以使得查看更加简单。例如,假如我想查看最近一年的图片,我便可以在命令行中键入下面的 `display` 命令: + +``` +display -resize 35% 2017/*/*/*.JPG +``` + +我可以一个月又一个月,一天又一天地遍历这一年。 + +现在假如我想查看某张图片,但我不确定我是在 2016 年的上半年还是在 2017 的上半年拍摄的,那么我便可以使用下面的命令来找到它: + +``` +display -resize 35% 201[6-7]/0[1-6]/*/*.JPG +``` + +这限制查看的图片拍摄于 2016 和 2017 年的一月到六月 + +### 使用 montage 来查看图片的缩略图 + +假如现在我要查找一张我想要编辑的图片,使用 `display` 的一个问题是它只会显示每张图片的文件名,而不显示其在目录结构中的位置,所以想要找到那张图片并不容易。另外,假如我很偶然地在从相机下载图片的过程中将这些图片从相机的内存里面清除了它们,结果使得下次拍摄照片的名称又从 `DSC_0001.jpg` 开始命名,那么当使用 `display` 来展示一整年的图片时,将会在这 12 个月的图片中花费很长的时间来查找它们。 + +这时 `montage` 命令便可以派上用场了。它可以将一系列的图片缩略图放在一张图片中,这样就会非常有用。例如可以使用下面的命令来完成上面的任务: + +``` +montage -label %d/%f -title 2017 -tile 5x -resize 10% -geometry +4+4 2017/0[1-4]/*/*.JPG 2017JanApr.jpg +``` + +从左到右,这个命令以标签开头,标签的形式是包含文件名(`%f`)和以 `/` 分割的目录(`%d`)结构,接着这个命令以目录的名称(2017)来作为标题,然后将图片排成 5 列,每个图片缩放为 10% (这个参数可以很好地匹配我的屏幕)。`geometry` 的设定将在每张图片的四周留白,最后指定那些图片要包括到这张合成图片中,以及一个合适的文件名称(`2017JanApr.jpg`)。现在图片 `2017JanApr.jpg` 便可以成为一个索引,使得我可以不时地使用它来查看这个时期的所有图片。 + +### 注意内存消耗 + +你可能会好奇为什么我在上面的合成图中只特别指定了为期 4 个月(从一月到四月)的图片。因为 `montage` 将会消耗大量内存,所以你需要多加注意。我的相机产生的图片每张大约有 2.5MB,我发现我的系统可以很轻松地处理 60 张图片。但一旦图片增加到 80 张,如果此时还有另外的程序(例如 Firefox 、Thunderbird)在后台工作,那么我的电脑将会死机,这似乎和内存使用相关,`montage`可能会占用可用 RAM 的 80% 乃至更多(你可以在此期间运行 `top` 命令来查看内存占用)。假如我关掉其他的程序,我便可以在我的系统死机前处理 80 张图片。 + +下面的命令可以让你知晓在你运行 `montage` 命令前你需要处理图片张数: + +``` +ls 2017/0[1-4/*/*.JPG > filelist; wc -l filelist +``` + +`ls` 命令生成我们搜索的文件的列表,然后通过重定向将这个列表保存在任意以名为 `filelist` 的文件中。接着带有 `-l` 选项的 `wc` 命令输出该列表文件共有多少行,换句话说,展示出了需要处理的文件个数。下面是我运行命令后的输出: + +``` +163 filelist +``` + +啊呀!从一月到四月我居然有 163 张图片,使用这些图片来创建一张合成图一定会使得我的系统死机的。我需要将这个列表减少点,可能只处理到 3 月份或者更早的图片。但如果我在 4 月 20 号到 30 号期间拍摄了很多照片,我想这便是问题的所在。下面的命令便可以帮助指出这个问题: + +``` +ls 2017/0[1-3]/*/*.JPG > filelist; ls 2017/04/0[1-9]/*.JPG >> filelist; ls 2017/04/1[0-9]/*.JPG >> filelist; wc -l filelist +``` + +上面一行中共有 4 个命令,它们以分号分隔。第一个命令特别指定从一月到三月期间拍摄的照片;第二个命令使用 `>>` 将拍摄于 4 月 1 日至 9 日的照片追加到这个列表文件中;第三个命令将拍摄于 4 月 10 日到 19 日的照片追加到列表中。最终它的显示结果为: + +``` +81 filelist +``` + +我知道假如我关掉其他的程序,处理 81 张图片是可行的。 + +使用 `montage` 来处理它们是很简单的,因为我们只需要将上面所做的处理添加到 `montage` 命令的后面即可: + +``` +montage -label %d/%f -title 2017 -tile 5x -resize 10% -geometry +4+4 2017/0[1-3]/*/*.JPG 2017/04/0[1-9]/*.JPG 2017/04/1[0-9]/*.JPG 2017Jan01Apr19.jpg +``` + +从左到右,`montage` 命令后面最后的那个文件名将会作为输出,在它之前的都是输入。这个命令将花费大约 3 分钟来运行,并生成一张大小约为 2.5MB 的图片,但我的系统只是有一点反应迟钝而已。 + +### 展示合成图片 + +当你第一次使用 `display` 查看一张巨大的合成图片时,你将看到合成图的宽度很合适,但图片的高度被压缩了,以便和屏幕相适应。不要慌,只需要左击图片,然后选择 `View > Original Size` 便会显示整个图片。再次点击图片便可以使菜单栏隐藏。 + +我希望这篇文章可以在你使用新方法查看图片时帮助你。在我的下一篇文章中,我将讨论更加复杂的图片操作技巧。 + +### 作者简介 + +Greg Pittman - Greg 肯塔基州路易斯维尔的一名退休的神经科医生,对计算机和程序设计有着长期的兴趣,最早可以追溯到 1960 年代的 Fortran IV 。当 Linux 和开源软件相继出现时,他开始学习更多的相关知识,并分享自己的心得。他是 Scribus 团队的成员。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/9/imagemagick-viewing-images + +作者:[Greg Pittman][a] +译者:[FSSlc](https://github.com/FSSlc) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/greg-p +[1]:https://linux.cn/article-8851-1.html +[3]:https://opensource.com/sites/default/files/u128651/edge3negate.jpg "Using the edge and negate options on an image." +[4]:https://wiki.gnome.org/Apps/Shotwell +[5]:https://en.wikipedia.org/wiki/Exif diff --git a/published/20171109 Testing IPv6 Networking in KVM- Part 2.md b/published/20171109 Testing IPv6 Networking in KVM- Part 2.md new file mode 100644 index 0000000000..6ab7937b49 --- /dev/null +++ b/published/20171109 Testing IPv6 Networking in KVM- Part 2.md @@ -0,0 +1,120 @@ +在 KVM 中测试 IPv6 网络:第 2 部分 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/banner_4.png?itok=yZBHylwd) + +我们又见面了,在上一篇 [在 KVM 中测试 IPv6 网络:第 1 部分][1] 中,我们学习了有关 IPv6 私有地址的内容。今天,我们将使用 KVM 创建一个网络,去测试上一星期学习的 IPv6 的内容。 + +如果你想重新温习如何使用 KVM,可以查看 [在 KVM 中创建虚拟机:第 1 部分][2] 和 [在 KVM 中创建虚拟机:第 2 部分— 网络][3]。 + +### 在 KVM 中创建网络 + +在 KVM 中你至少需要两个虚拟机。当然了,如果你愿意,也可以创建更多的虚拟机。在我的系统中有 Fedora、Ubuntu、以及 openSUSE。去创建一个新的 IPv6 网络,在主虚拟机管理窗口中打开 “Edit > Connection Details > Virtual Networks”。点击左下角的绿色十字按钮去创建一个新的网络(图 1)。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/kvm-fig-1_0.png?itok=ruqjPXxd) + +*图 1:创建一个网络* + +给新网络输入一个名字,然后,点击 “Forward” 按钮。如果你愿意,也可以不创建 IPv4 网络。当你创建一个新的 IPv4 网络时,虚拟机管理器将不让你创建重复网络,或者是使用了一个无效地址。在我的宿主机 Ubuntu 系统上,有效的地址是以绿色高亮显示的,而无效地址是使用高亮的玫瑰红色调。在我的 openSUSE 机器上没有高亮颜色。启用或不启用 DHCP,以及创建或不创建一个静态路由,然后进入下一个窗口。 + +选中 “Enable IPv6 network address space definition”,然后输入你的私有地址范围。你可以使用任何你希望的 IPv6 地址类,但是要注意,不能将你的实验网络泄漏到公网上去。我们将使用非常好用的 IPv6 唯一本地地址(ULA),并且使用在 [Simple DNS Plus][4] 上的在线地址生成器,去创建我们的网络地址。拷贝 “Combined/CID” 地址到网络框中(图 2)。 + +![network address][6] + +*图 2:拷贝 "Combined/CID" 地址到网络框中* + +虚拟机认为我的地址是无效的,因为,它显示了高亮的玫瑰红色。它做的对吗?我们使用 `ipv6calc` 去验证一下: + +``` +$ ipv6calc -qi fd7d:844d:3e17:f3ae::/64 +Address type: unicast, unique-local-unicast, iid, iid-local +Registry for address: reserved(RFC4193#3.1) +Address type has SLA: f3ae +Interface identifier: 0000:0000:0000:0000 +Interface identifier is probably manual set +``` + +`ipv6calc` 认为没有问题。如果感兴趣,你可以改变其中一个数字为无效的东西,比如字母 `g`,然后再试一次。(问 “如果…?”,试验和错误是最好的学习方法)。 + +我们继续进行,启用 DHCPv6(图 3)。你可以接受缺省值,或者输入一个你自己的设置值。 + +![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/kvm-fig-3.png?itok=F-oAAtN9) + +*图 3: 启用 DHCPv6* + +我们将跳过缺省路由定义这一步,继续进入下一屏,在那里我们将启用 “Isolated Virtual Network” 和 “Enable IPv6 internal routing/networking”。 + +### 虚拟机网络选择 + +现在,你可以配置你的虚拟机去使用新的网络。打开你的虚拟机,然后点击顶部左侧的 “i” 按钮去打开 “Show virtual hardware details” 屏幕。在 “Add Hardware” 列点击 “NIC” 按钮去打开网络选择器,然后选择你喜欢的新的 IPv6 网络。点击 “Apply”,然后重新启动。(或者使用你喜欢的方法去重新启动网络,或者更新你的 DHCP 租期。) + +### 测试 + +`ifconfig` 告诉我们它做了什么? + +``` +$ ifconfig +ens3: flags=4163 UP,BROADCAST,RUNNING,MULTICAST mtu 1500 + inet 192.168.30.207 netmask 255.255.255.0 + broadcast 192.168.30.255 + inet6 fd7d:844d:3e17:f3ae::6314 + prefixlen 128 scopeid 0x0 + inet6 fe80::4821:5ecb:e4b4:d5fc + prefixlen 64 scopeid 0x20 +``` + +这是我们新的 ULA,`fd7d:844d:3e17:f3ae::6314`,它是自动生成的本地链路地址。如果你有兴趣,可以 ping 一下,ping 网络上的其它虚拟机: + +``` +vm1 ~$ ping6 -c2 fd7d:844d:3e17:f3ae::2c9f +PING fd7d:844d:3e17:f3ae::2c9f(fd7d:844d:3e17:f3ae::2c9f) 56 data bytes +64 bytes from fd7d:844d:3e17:f3ae::2c9f: icmp_seq=1 ttl=64 time=0.635 ms +64 bytes from fd7d:844d:3e17:f3ae::2c9f: icmp_seq=2 ttl=64 time=0.365 ms + +vm2 ~$ ping6 -c2 fd7d:844d:3e17:f3ae:a:b:c:6314 +PING fd7d:844d:3e17:f3ae:a:b:c:6314(fd7d:844d:3e17:f3ae:a:b:c:6314) 56 data bytes +64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=1 ttl=64 time=0.744 ms +64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=2 ttl=64 time=0.364 ms +``` + +当你努力去理解子网时,这是一个可以让你尝试不同地址是否可以正常工作的快速易用的方法。你可以给单个接口分配多个 IP 地址,然后 ping 它们去看一下会发生什么。在一个 ULA 中,接口,或者主机是 IP 地址的最后四部分,因此,你可以在那里做任何事情,只要它们在同一个子网中即可,在那个例子中是 `f3ae`。在我的其中一个虚拟机上,我只改变了这个示例的接口 ID,以展示使用这四个部分,你可以做任何你想做的事情: + +``` +vm1 ~$ sudo /sbin/ip -6 addr add fd7d:844d:3e17:f3ae:a:b:c:6314 dev ens3 + +vm2 ~$ ping6 -c2 fd7d:844d:3e17:f3ae:a:b:c:6314 +PING fd7d:844d:3e17:f3ae:a:b:c:6314(fd7d:844d:3e17:f3ae:a:b:c:6314) 56 data bytes +64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=1 ttl=64 time=0.744 ms +64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=2 ttl=64 time=0.364 ms +``` + +现在,尝试使用不同的子网,在下面的示例中使用了 `f4ae` 代替 `f3ae`: + +``` +$ ping6 -c2 fd7d:844d:3e17:f4ae:a:b:c:6314 +PING fd7d:844d:3e17:f4ae:a:b:c:6314(fd7d:844d:3e17:f4ae:a:b:c:6314) 56 data bytes +From fd7d:844d:3e17:f3ae::1 icmp_seq=1 Destination unreachable: No route +From fd7d:844d:3e17:f3ae::1 icmp_seq=2 Destination unreachable: No route +``` + +这也是练习路由的好机会,以后,我们将专门做一期,如何在不使用 DHCP 情况下实现自动寻址。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2017/11/testing-ipv6-networking-kvm-part-2 + +作者:[CARLA SCHRODER][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/cschroder +[1]:https://linux.cn/article-9594-1.html +[2]:https://www.linux.com/learn/intro-to-linux/2017/5/creating-virtual-machines-kvm-part-1 +[3]:https://www.linux.com/learn/intro-to-linux/2017/5/creating-virtual-machines-kvm-part-2-networking +[4]:http://simpledns.com/private-ipv6.aspx +[5]:/files/images/kvm-fig-2png +[6]:https://www.linux.com/sites/lcom/files/styles/floated_images/public/kvm-fig-2.png?itok=gncdPGj- "network address" +[7]:https://www.linux.com/licenses/category/used-permission diff --git a/published/20171116 10 easy steps from proprietary to open source.md b/published/20171116 10 easy steps from proprietary to open source.md new file mode 100644 index 0000000000..b7b9b6d028 --- /dev/null +++ b/published/20171116 10 easy steps from proprietary to open source.md @@ -0,0 +1,74 @@ +从专有到开源的十个简单步骤 +====== + +> 这个共同福利并不适用于专有软件:保持隐藏的东西是不能照亮或丰富这个世界的。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open_abstract_pieces.jpg?itok=tGR1d2MU) + +“开源软件肯定不太安全,因为每个人都能看到它的源代码,而且他们能重新编译它,用他们自己写的不好的东西进行替换。”举手示意:谁之前听说过这个说法?^注1 + +当我和客户讨论的时候(是的,他们有时候会让我和客户交谈),对于这个领域^注2 的人来说种问题是很常见的。在前一篇文章中,“[许多只眼睛的审查并不一定能防止错误代码]”,我谈论的是开源软件(尤其是安全软件)并不能神奇地比专有软件更安全,但是和专有软件比起来,我每次还是比较青睐开源软件。但我听到“关于开源软件不是很安全”这种问题表明了有时候只是说“开源需要参与”是不够的,我们也需要积极的参与辩护^注3 。 + +我并不期望能够达到牛顿或者维特根斯坦的逻辑水平,但是我会尽我所能,而且我会在结尾做个总结,如果你感兴趣的话可以去快速的浏览一下。 + +### 关键因素 + +首先,我们必须明白没有任何软件是完美的^注6 。无论是专有软件还是开源软件。第二,我们应该承认确实还是存在一些很不错的专有软件的,以及第三,也存在一些糟糕的开源软件。第四,有很多非常聪明的,很有天赋的,专业的架构师、设计师和软件工程师设计开发了专有软件。 + +但也有些问题:第五,从事专有软件的人员是有限的,而且你不可能总是能够雇佣到最好的员工。即使在政府部门或者公共组织 —— 他们拥有丰富的人才资源池,但在安全应用这块,他们的人才也是有限的。第六,可以查看、测试、改进、拆解、再次改进和发布开源软件的人总是无限的,而且还包含最好的人才。第七(也是我最喜欢的一条),这群人也包含很多编写专有软件的人才。第八,许多政府或者公共组织开发的软件也都逐渐开源了。 + +第九,如果你在担心你在运行的软件的不被支持或者来源不明,好消息是:有一批组织^注7 会来检查软件代码的来源,提供支持、维护和补丁更新。他们会按照专利软件模式那样去运行开源软件,你也可以确保你从他们那里得到的软件是正确的软件:他们的技术标准就是对软件包进行签名,以便你可以验证你正在运行的开源软件不是来源不明或者是恶意的软件。 + +第十(也是这篇文章的重点),当你运行开源软件,测试它,对问题进行反馈,发现问题并且报告的时候,你就是在为共同福利commonwealth贡献知识、专业技能以及经验,这就是开源,其因为你的所做的这些而变得更好。如果你是通过个人或者提供支持开源软件的商业组织之一^注8 参与的,你已经成为了这个共同福利的一部分了。开源让软件变得越来越好,你可以看到它们的变化。没有什么是隐藏封闭的,它是完全开放的。事情会变坏吗?是的,但是我们能够及时发现问题并且修复。 + +这个共同福利并不适用于专有软件:保持隐藏的东西是不能照亮或丰富这个世界的。 + +我知道作为一个英国人在使用共同福利commonwealth这个词的时候要小心谨慎的;它和帝国连接着的,但我所表达的不是这个意思。它不是克伦威尔^注9 在对这个词所表述的意思,无论如何,他是一个有争议的历史人物。我所表达的意思是这个词有“共同”和“福利”连接,福利不是指钱而是全人类都能拥有的福利。 + +我真的很相信这点的。如果i想从这篇文章中得到一些虔诚信息的话,那应该是第十条^注10 :共同福利是我们的遗产,我们的经验,我们的知识,我们的责任。共同福利是全人类都能拥有的。我们共同拥有它而且它是一笔无法估量的财富。 + +### 便利贴 + + 1. (几乎)没有一款软件是完美无缺的。 + 2. 有很好的专有软件。 + 3. 有不好的专有软件。 + 4. 有聪明,有才能,专注的人开发专有软件。 + 5. 从事开发完善专有软件的人是有限的,即使在政府或者公共组织也是如此。 + 6. 相对来说从事开源软件的人是无限的。 + 7. …而且包括很多从事专有软件的人才。 + 8. 政府和公共组织的人经常开源它们的软件。 + 9. 有商业组织会为你的开源软件提供支持。 + 10. 贡献--即使是使用--为开源软件贡献。 + + +### 脚注 + +- 注1: 好的--你现在可以放下手了 +- 注2:这应该大写吗?有特定的领域吗?或者它是如何工作的?我不确定。 +- 注3:我有一个英国文学和神学的学位--这可能不会惊讶到我的文章的普通读者^注4 。 +- 注4: 我希望不是,因为我说的太多神学了^注5 。但是它经常充满了冗余的,无关紧要的人文科学引用。 +- 注5: Emacs,每一次。 +- 注6: 甚至是 Emacs。而且我知道有技术能够去证明一些软件的正确性。(我怀疑 Emacs 不能全部通过它们...) +- 注7: 注意这里:我被他们其中之一 [Red Hat][3] 所雇佣,去查看一下--它是一个有趣的工作地方,而且[我们经常在招聘][4]。 +- 注8: 假设他们完全遵守他们正在使用的开源软件许可证。 +- 注9: 昔日的“英格兰、苏格兰、爱尔兰的上帝守护者”--比克伦威尔。 +- 注10: 很明显,我选择 Emacs 而不是 Vi 变体。 + +这篇文章原载于 [Alice, Eve, and Bob - a security blog] 而且已经被授权重新发布。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/11/commonwealth-open-source + +作者:[Mike Bursell][a] +译者:[FelixYFZ](https://github.com/FelixYFZ) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mikecamel +[1]:https://opensource.com/article/17/10/many-eyes +[2]:https://en.wikipedia.org/wiki/Apologetics +[3]:https://www.redhat.com/ +[4]:https://www.redhat.com/en/jobs +[5]:https://aliceevebob.com/2017/10/24/the-commonwealth-of-open-source/ diff --git a/translated/tech/20171129 5 best practices for getting started with DevOps.md b/published/20171129 5 best practices for getting started with DevOps.md similarity index 70% rename from translated/tech/20171129 5 best practices for getting started with DevOps.md rename to published/20171129 5 best practices for getting started with DevOps.md index 3fa96176d5..d161d20f8c 100644 --- a/translated/tech/20171129 5 best practices for getting started with DevOps.md +++ b/published/20171129 5 best practices for getting started with DevOps.md @@ -1,55 +1,55 @@ 5 个最佳实践开始你的 DevOps 之旅 ============================================================ -### 想要实现 DevOps 但是不知道如何开始吗?试试这 5 个最佳实践吧。 - +> 想要实现 DevOps 但是不知道如何开始吗?试试这 5 个最佳实践吧。 ![5 best practices for getting started with DevOps](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/devops-gears.png?itok=rUejbLQX "5 best practices for getting started with DevOps") Image by : [Andrew Magill][8]. Modified by Opensource.com. [CC BY 4.0][9] -想要采用 DevOps 的人通常会过早的被它的歧义性给吓跑,更不要说更加深入的使用了。当一些人开始使用 DevOps 的时候都会问:“如何开始使用呢?”,”怎么才算使用了呢?“。这 5 个最佳实践是很好的路线图来指导你的 DevOps 之旅。 +想要采用 DevOps 的人通常会过早的被它的歧义性给吓跑,更不要说更加深入的使用了。当一些人开始使用 DevOps 的时候都会问:“如何开始使用呢?”,”怎么才算使用了呢?“。这 5 个最佳实践是指导你的 DevOps 之旅的很好的路线图。 -### 1\. 衡量所有的事情 +### 1、 衡量所有的事情 -除非你能量化输出结果,否则你并不能确认你的努力能否使事情变得更好。新功能能否快速的输出给客户?有更少的漏洞泄漏给他们吗?出错了能快速应对和恢复吗? +除非你能够量化输出结果,否则你并不能确认你的努力能否使事情变得更好。新功能能否快速的输出给客户?带给他们的缺陷更少吗?出错了能快速应对和恢复吗? 在你开始做任何修改之前,思考一下你切换到 DevOps 之后想要一些什么样的输出。随着你的 DevOps 之旅,将享受到服务的所有内容的丰富的实时报告,从这两个指标考虑一下: -* **上架时间** 衡量端到端,通常是面向客户的业务经验。这通常从一个功能被正式提出而开始,客户在产品中开始使用这个功能而结束。上架时间不是团队的主要指标;更加重要的是,当开发出一个有价值的新功能时,它表明了你完成业务的效率,为系统改进提供了一个机会。 +* **上架时间** 衡量端到端,通常是面向客户的业务经验。这通常从一个功能被正式提出而开始,客户在产品中开始使用这个功能而结束。上架时间不是工程团队的主要指标;更加重要的是,当开发出一个有价值的新功能时,它表明了你完成业务的效率,为系统改进提供了一个机会。 -* **时间周期** 衡量工程团队的进度。从开始开发一个新功能开始,到在产品中运行需要多久?这个指标对于你理解团队的效率是非常有用的,为团队等级的提升提供了一个机会。 +* **时间周期** 衡量工程团队的进度。从开始开发一个新功能开始,到在产品环境中运行需要多久?这个指标对于你了解团队的效率是非常有用的,为团队层面的提升提供了一个机会。 -### 2\. 放飞你的流程 +### 2、 放飞你的流程 -DevOps 的成功需要团队布置一个定期流程并且持续提升它。这不总是有效的,但是必须是一个定期(希望有效)的流程。通常它有一些敏捷开发的味道,就像 Scrum 或者 Scrumban 一样;一些时候它也像精益开发。不论你用的什么方法,挑选一个正式的流程,开始使用它,并且做好这些基础。 +DevOps 的成功需要团队布置一个定期(但愿有效)流程并且持续提升它。这不总是有效的,但是必须是一个定期的流程。通常它有一些敏捷开发的味道,就像 Scrum 或者 Scrumban 一样;一些时候它也像精益开发。不论你用的什么方法,挑选一个正式的流程,开始使用它,并且做好这些基础。 -定期检查和调整流程是 DevOps 成功的关键,抓住相关演示,团队回顾,每日会议的机会来提升你的流程。 +定期检查和调整流程是 DevOps 成功的关键,抓住相关演示、团队回顾、每日会议的机会来提升你的流程。 DevOps 的成功取决于大家一起有效的工作。团队的成员需要在一个有权改进的公共流程中工作。他们也需要定期找机会分享从这个流程中上游或下游的其他人那里学到的东西。 -随着你构建成功。好的流程规范能帮助你的团队以很快的速度体会到 DevOps 其他的好处 +随着你构建成功,好的流程规范能帮助你的团队以很快的速度体会到 DevOps 其他的好处 尽管更多面向开发的团队采用 Scrum 是常见的,但是以运营为中心的团队(或者其他中断驱动的团队)可能选用一个更短期的流程,例如 Kanban。 -### 3\. 可视化工作流程 +### 3、 可视化工作流程 + 这是很强大的,能够看到哪个人在给定的时间做哪一部分工作,可视化你的工作流程能帮助大家知道接下来应该做什么,流程中有多少工作以及流程中的瓶颈在哪里。 在你看到和衡量之前你并不能有效的限制流程中的工作。同样的,你也不能有效的排除瓶颈直到你清楚的看到它。 全部工作可视化能帮助团队中的成员了解他们在整个工作中的贡献。这样可以促进跨组织边界的关系建设,帮助您的团队更有效地协作,实现共同的成就感。 -### 4\. 持续化所有的事情 +### 4、 持续化所有的事情 -DevOps 应该是强制自动化的。然而罗马不是一日建成的。你应该注意的第一个事情应该是努力的持续集成(CI),但是不要停留到这里;紧接着的是持续交付(CD)以及最终的持续部署。 +DevOps 应该是强制自动化的。然而罗马不是一日建成的。你应该注意的第一个事情应该是努力的[持续集成(CI)][10],但是不要停留到这里;紧接着的是[持续交付(CD)][11]以及最终的持续部署。 -持续部署的过程中是个注入自动测试的好时机。这个时候新代码刚被提交,你的持续部署应该运行测试代码来测试你的代码和构建成功的加工品。这个加工品经受流程的考验被产出直到最终被客户看到。 +持续部署的过程中是个注入自动测试的好时机。这个时候新代码刚被提交,你的持续部署应该运行测试代码来测试你的代码和构建成功的加工品。这个加工品经受流程的考验被产出,直到最终被客户看到。 -另一个“持续”是不太引人注意的持续改进。一个简单的场景是每天询问你旁边的同事:“今天做些什么能使工作变得更好?”,随着时间的推移,这些日常的小改进融合到一起会引起很大的结果,你将很惊喜!但是这也会让人一直思考着如何改进。 +另一个“持续”是不太引人注意的持续改进。一个简单的场景是每天询问你旁边的同事:“今天做些什么能使工作变得更好?”,随着时间的推移,这些日常的小改进融合到一起会带来很大的结果,你将很惊喜!但是这也会让人一直思考着如何改进。 -### 5\. Gherkinize +### 5、 Gherkinize -促进组织间更有效的沟通对于成功的 DevOps 的系统思想至关重要。在程序员和业务员之间直接使用共享语言来描述新功能的需求文档对于沟通是个好办法。一个好的产品经理能在一天内学会 [Gherkin][12] 然后使用它构造出明确的英语来描述需求文档,工程师会使用 Gherkin 描述的需求文档来写功能测试,之后开发功能代码直到代码通过测试。这是一个简化的 [验收测试驱动开发][13](ATDD),这样就开始了你的 DevOps 文化和开发实践。 +促进组织间更有效的沟通对于成功的 DevOps 的系统思想至关重要。在程序员和业务员之间直接使用共享语言来描述新功能的需求文档对于沟通是个好办法。一个好的产品经理能在一天内学会 [Gherkin][12] 然后使用它以平实的英语构造出明确的描述需求文档,工程师会使用 Gherkin 描述的需求文档来写功能测试,之后开发功能代码直到代码通过测试。这是一个简化的 [验收测试驱动开发][13](ATDD),能够帮助你开始你的 DevOps 文化和开发实践。 ### 开始你旅程 @@ -60,15 +60,15 @@ DevOps 应该是强制自动化的。然而罗马不是一日建成的。你应 [![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/headshot_4.jpg?itok=jntfDCfX)][14] - Magnus Hedemark - Magnus 在IT行业已有20多年,并且一直热衷于技术。他目前是 nitedHealth Group 的 DevOps 工程师。在业余时间,Magnus 喜欢摄影和划独木舟。 + Magnus Hedemark - Magnus 在 IT 行业已有 20 多年,并且一直热衷于技术。他目前是 nitedHealth Group 的 DevOps 工程师。在业余时间,Magnus 喜欢摄影和划独木舟。 -------------------------------------------------------------------------------- via: https://opensource.com/article/17/11/5-keys-get-started-devops -作者:[Magnus Hedemark ][a] +作者:[Magnus Hedemark][a] 译者:[aiwhj](https://github.com/aiwhj) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20171213 Will DevOps steal my job-.md b/published/20171213 Will DevOps steal my job-.md similarity index 52% rename from translated/tech/20171213 Will DevOps steal my job-.md rename to published/20171213 Will DevOps steal my job-.md index 065d638bfa..53b7511dbe 100644 --- a/translated/tech/20171213 Will DevOps steal my job-.md +++ b/published/20171213 Will DevOps steal my job-.md @@ -1,4 +1,4 @@ -DevOps 将让你失业? +DevOps 会让你失业吗? ====== >你是否担心工作中自动化将代替人?可能是对的,但是这并不是件坏事。 @@ -8,19 +8,19 @@ DevOps 将让你失业? 这是一个很正常的担心:DevOps 最终会让你失业?毕竟,DevOps 意味着开发人员做运营,对吗?DevOps 是自动化的。如果我的工作都自动化了,我去做什么?实行持续分发和容器化意味着运营已经过时了吗?对于 DevOps 来说,所有的东西都是代码:基础设施是代码、测试是代码、这个和那个都是代码。如果我没有这些技能怎么办? -[DevOps][1] 是一个即将到来的变化,将颠覆这一领域,狂热的拥挤者们正在谈论,如何使用 [三种方法][2] 去改变世界 —— 即 DevOps 的三大基础 —— 去推翻一个旧的世界。它是势不可档的。那么,问题来了 —— DevOps 将会让我失业吗? +[DevOps][1] 是一个即将到来的变化,它将颠覆这一领域,狂热的拥挤者们正在谈论,如何使用 [三种方法][2] 去改变世界 —— 即 DevOps 的三大基础 —— 去推翻一个旧的世界。它是势不可档的。那么,问题来了 —— DevOps 将会让我失业吗? -### 第一个担心:再也不需要我了 +### 第一个担心:再也不需要我了 -由于开发者来管理应用程序的整个生命周期,接受 DevOps 的理念很容易。容器化可能是影响这一想法的重要因素。当容器化在各种场景下铺开之后,它们被吹嘘成开发者构建、测试、和部署他们代码的一站式解决方案。DevOps 对于运营、测试、以及 QA 团队来说,有什么作用呢? +由于开发者来管理应用程序的整个生命周期,接受 DevOps 的理念很容易。容器化可能是影响这一想法的重要因素。当容器化在各种场景下铺开之后,它们被吹嘘成开发者构建、测试和部署他们代码的一站式解决方案。DevOps 对于运营、测试、以及 QA 团队来说,有什么作用呢? -这源于对 DevOps 原则的误解。DevOps 的第一原则,或者第一方法是,_系统思考_ ,或者强调整体管理方法和了解应用程序或服务的整个生命周期。这并不意味着应用程序的开发者将学习和管理整个过程。相反,是拥有各个专业和技能的人共同合作,以确保成功。让开发者对这一过程完全负责的作法,几乎是将开发者置于使用者的对立面—— 本质上就是 “将鸡蛋放在了一个篮子里”。 +这源于对 DevOps 原则的误解。DevOps 的第一原则,或者第一方法是,系统思考Systems Thinking,或者强调整体管理方法和了解应用程序或服务的整个生命周期。这并不意味着应用程序的开发者将学习和管理整个过程。相反,是拥有各个专业和技能的人共同合作,以确保成功。让开发者对这一过程完全负责的作法,几乎是将开发者置于使用者的对立面 —— 本质上就是 “将鸡蛋放在了一个篮子里”。 在 DevOps 中有一个为你保留的专门职位。就像将一个受过传统教育的、拥有线性回归和二分查找知识的软件工程师,被用去写一些 Ansible playbooks 和 Docker 文件,这是一种浪费。而对于那些拥有高级技能,知道如何保护一个系统和优化数据库执行的系统管理员,被浪费在写一些 CSS 和设计用户流这样的工作上。写代码、做测试、和维护应用程序的高效团队一般是跨学科、跨职能的、拥有不同专业技术和背景的人组成的混编团队。 ### 第二个担心:我的工作将被自动化 -或许是,或许不是,DevOps 可能在有时候是自动化的同义词。当自动化构建、测试、部署、监视、以及提醒等事项,已经占据了整个应用程序生命周期管理的时候,还会给我们剩下什么工作呢?这种对自动化的关注可能与第二个方法有关:_放大反馈循环_。DevOps 的第二个方法是在团队和部署的应用程序之间,采用相反的方向优先处理快速反馈 —— 从监视和维护部署、测试、开发、等等,通过强调,使反馈更加重要并且可操作。虽然这第二种方式与自动化并不是特别相关,许多自动化工具团队在它们的部署流水线中使用,以促进快速提醒和快速行动,或者基于对使用者的支持业务中产生的反馈来改进。传统的做法是靠人来完成的,这就可以理解为什么自动化可能会导致未来一些人失业的焦虑了。 +或许是,或许不是,DevOps 可能在有时候是自动化的同义词。当自动化构建、测试、部署、监视,以及提醒等事项,已经占据了整个应用程序生命周期管理的时候,还会给我们剩下什么工作呢?这种对自动化的关注可能与第二个方法有关:放大反馈循环Amplify Feedback Loops。DevOps 的第二个方法是在团队和部署的应用程序之间,采用相反的方向优先处理快速反馈 —— 从监视和维护部署、测试、开发、等等,通过强调,使反馈更加重要并且可操作。虽然这第二种方式与自动化并不是特别相关,许多自动化工具团队在它们的部署流水线中使用,以促进快速提醒和快速行动,或者基于对使用者的支持业务中产生的反馈来改进。传统的做法是靠人来完成的,这就可以理解为什么自动化可能会导致未来一些人失业的焦虑了。 自动化只是一个工具,它并不能代替人。聪明的人使用它来做一些重复的工作,不去开发智力和创造性的财富,而是去按红色的 “George Jetson” 按钮是一种极大的浪费。让每天工作中的苦活自动化,意味着有更多的时间去解决真正的问题和即将到来的创新的解决方案。人类需要解决更多的 “怎么做和为什么” 问题,而计算机只能处理 “复制和粘贴”。 @@ -28,17 +28,17 @@ DevOps 将让你失业? ### 第三个担心:我没有这些技能怎么办 -"我怎么去继续做这些事情?我不懂如何自动化。现在所有的工作都是代码 —— 我不是开发人员,我不会做 DevOps 中写代码的工作“,第三个担心是一种不自信的担心。由于文化的改变,是的,团队将也会要求随之改变,一些人可能担心,他们缺乏继续做他们工作的技能。 +“我怎么去继续做这些事情?我不懂如何自动化。现在所有的工作都是代码 —— 我不是开发人员,我不会做 DevOps 中写代码的工作”,第三个担心是一种不自信的担心。由于文化的改变,是的,团队将也会要求随之改变,一些人可能担心,他们缺乏继续做他们工作的技能。 -然而,大多数人或许已经比他们所想的更接近。Dockerfile 是什么,或者像 Puppet 或 Ansible 配置管理是什么,但是环境即代码,系统管理员已经写了 shell 脚本和 Python 程序去处理他们重复的任务。学习更多的知识并使用已有的工具处理他们的更多问题 —— 编排、部署、维护即代码 —— 尤其是当从繁重的手动任务中解放出来,专注于成长时。 +然而,大多数人或许已经比他们所想的更接近。Dockerfile 是什么,或者像 Puppet 或 Ansible 配置管理是什么,这就是环境即代码,系统管理员已经写了 shell 脚本和 Python 程序去处理他们重复的任务。学习更多的知识并使用已有的工具处理他们的更多问题 —— 编排、部署、维护即代码 —— 尤其是当从繁重的手动任务中解放出来,专注于成长时。 -在 DevOps 的使用者中去回答这第三个担心,第三个方法是:_一种不断实验和学习的文化_。尝试、失败、并从错误中吸取教训而不是责怪它们的能力,是设计出更有创意的解决方案的重要因素。第三个方法是为前两个方法授权—— 允许快速检测和修复问题,并且开发人员可以自由地尝试和学习,其它的团队也是如此。从未使用过配置管理或者写过自动供给基础设施程序的运营团队也要自由尝试并学习。测试和 QA 团队也要自由实现新测试流水线,并且自动批准和发布新流程。在一个拥抱学习和成长的文化中,每个人都可以自由地获取他们需要的技术,去享受工作带来的成功和喜悦。 +在 DevOps 的使用者中去回答这第三个担心,第三个方法是:一种不断实验和学习的文化A Culture of Continual Experimentation and Learning。尝试、失败,并从错误中吸取教训而不是责怪它们的能力,是设计出更有创意的解决方案的重要因素。第三个方法是为前两个方法授权 —— 允许快速检测和修复问题,并且开发人员可以自由地尝试和学习,其它的团队也是如此。从未使用过配置管理或者写过自动供给基础设施程序的运营团队也要自由尝试并学习。测试和 QA 团队也要自由实现新测试流水线,并且自动批准和发布新流程。在一个拥抱学习和成长的文化中,每个人都可以自由地获取他们需要的技术,去享受工作带来的成功和喜悦。 ### 结束语 在一个行业中,任何可能引起混乱的实践或变化都会产生担心和不确定,DevOps 也不例外。对自己工作的担心是对成百上千的文章和演讲的合理回应,其中列举了无数的实践和技术,而这些实践和技术正致力于授权开发者对行业的各个方面承担职责。 -然而,事实上,DevOps 是 "[一个跨学科的沟通实践,致力于研究构建、进化、和运营快速变化的弹性系统][3]"。 DevOps 意味着终结 ”筒仓“,但并不专业化。它是受委托去做苦差事的自动化系统,解放你,让你去做人类更擅长做的事:思考和想像。并且,如果你愿意去学习和成长,它将不会终结你解决新的、挑战性的问题的机会。 +然而,事实上,DevOps 是 “[一个跨学科的沟通实践,致力于研究构建、进化、和运营快速变化的弹性系统][3]”。 DevOps 意味着终结 “筒仓”,但并不专业化。它是受委托去做苦差事的自动化系统,解放你,让你去做人类更擅长做的事:思考和想像。并且,如果你愿意去学习和成长,它将不会终结你解决新的、挑战性的问题的机会。 DevOps 会让你失业吗?会的,但它同时给你提供了更好的工作。 @@ -48,7 +48,7 @@ via: https://opensource.com/article/17/12/will-devops-steal-my-job 作者:[Chris Collins][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171220 Containers without Docker at Red Hat.md b/published/20171220 Containers without Docker at Red Hat.md new file mode 100644 index 0000000000..6cb741069e --- /dev/null +++ b/published/20171220 Containers without Docker at Red Hat.md @@ -0,0 +1,117 @@ +Red Hat 的去 Docker 化容器实践 +====== + +最近几年,开源项目 Docker (已更名为[Moby][1]) 在容器普及化方面建树颇多。然而,它的功能特性不断集中到一个单一、庞大的系统,该系统由具有 root 权限运行的守护进程 `dockerd` 管控,这引发了人们的焦虑。对这些焦虑的阐述,具有代表性的是 Red Hat 公司的容器团队负责人 Dan Walsh 在 [KubeCon + CloudNativecon][3] 会议中的[演讲][2]。Walsh 讲述了他的容器团队目前的工作方向,即使用一系列更小、可协同工作的组件替代 Docker。他的战斗口号是“拒绝臃肿的守护进程”,理由是与公认的 Unix 哲学相违背。 + +### Docker 模块化实践 + +就像我们在[早期文献][4]中看到的那样,容器的基础操作不复杂:你首先拉取一个容器镜像,利用该镜像创建一个容器,最后启动这个容器。除此之外,你要懂得如何构建镜像并推送至镜像仓库。大多数人在上述这些步骤中使用 Docker,但其实 Docker 并不是唯一的选择,目前的可替换选择是 `rkt`。rkt 引发了一系列标准的创建,包括运行时标准 CRI,镜像标准 OCI 及网络标准 CNI 等。遵守这些标准的后端,如 [CRI-O][5] 和 Docker,可以与 [Kubernetes][6] 为代表的管理软件协同工作。 + +这些标准促使 Red Hat 公司开发了一系列实现了部分标准的“核心应用”供 Kubernetes 使用,例如 CRI-O 运行时。但 Kubernetes 提供的功能不足以满足 Red Hat 公司的 [OpenShift][7] 项目所需。开发者可能需要构建容器并推送至镜像仓库,实现这些操作需要额外的一整套方案。 + +事实上,目前市面上已有多种构建容器的工具。来自 Sysdig 公司的 Michael Ducy 在[分会场][8]中回顾了 Docker 本身之外的 8 种镜像构建工具,而这也很可能不是全部。Ducy 将理想的构建工具定义如下:可以用可重现的方式创建最小化镜像。最小化镜像并不包含操作系统,只包含应用本身及其依赖。Ducy 认为 [Distroless][9], [Smith][10] 及 [Source-to-Image][11] 都是很好的工具,可用于构建最小化镜像。Ducy 将最小化镜像称为“微容器”。 + +可重现镜像reproducible container是指构建多次结果保持不变的镜像。为达到这个目标,Ducy 表示应该使用“宣告式”而不是“命令式”的方式。考虑到 Ducy 来自 Chef 配置管理工具领域,你应该能理解他的意思。Ducy 给出了符合标准的几个不错的实现,包括 [Ansible 容器][12]、 [Habitat][13]、 [nixos-容器][14]和 [Simth][10] 等,但你需要了解这些项目对应的编程语言。Ducy 额外指出 Habitat 构建的容器自带管理功能,如果你已经使用了 systemd、 Docker 或 Kubernetes 等外部管理工具,Habitat 的管理功能可能是冗余的。除此之外,我们还要提到从 Docker 和 [Buildah][16] 项目诞生的新项目 [BuildKit][15], 它是 Red Hat 公司 [Atomic 工程][17]的一个组件。 + +### 使用 Buildah 构建容器 + +![\[Buildah logo\]][18] + +Buildah 名称显然来自于 Walsh 风趣的 [波士顿口音][19]; 该工具的品牌宣传中充满了波士顿风格,例如 logo 使用了波士顿梗犬(如图所示)。该项目的实现思路与 Ducy 不同:为了构建容器,与其被迫使用宣告式配置管理的方案,不如构建一些简单工具,结合你最喜欢的配置管理工具使用。这样你可以如愿的使用命令行,例如使用 `cp` 命令代替 Docker 的自定义指令 `COPY` 。除此之外,你可以使用如下工具为容器提供内容:1) 配置管理工具,例如Ansible 或 Puppet;2) 操作系统相关或编程语言相关的安装工具,例如 APT 和 pip; 3) 其它系统。下面展示了基于通用 shell 命令的容器构建场景,其中只需要使用 `make` 命令即可为容器安装可执行文件。 + +``` +# 拉取基础镜像, 类似 Dockerfile 中的 FROM 命令 +buildah from redhat + +# 挂载基础镜像, 在其基础上工作 +crt=$(buildah mount) +ap foo $crt +make install DESTDIR=$crt + +# 下一步,生成快照 +buildah commit +``` + +有趣的是,基于这个思路,你可以复用主机环境中的构建工具,无需在镜像中安装这些依赖,故可以构建非常微小的镜像。通常情况下,构建容器镜像时需要在容器中安装目标应用的构建依赖。例如,从源码构建需要容器中有编译器工具链,这是因为构建并不在主机环境进行。大量的容器也包含了 `ps` 和 `bash` 这样的 Unix 命令,对微容器而言其实是多余的。开发者经常忘记或无法从构建好的容器中移除一些依赖,增加了不必要的开销和攻击面。 + +Buildah 的模块化方案能够以非 root 方式进行部分构建;但`mount` 命令仍然需要 `CAP_SYS_ADMIN`,有一个 [工单][20] 试图解决该问题。但 Buildah 与 Docker [都有][21]同样的[限制][22],即无法在容器内构建容器。对于 Docker,你需要使用“特权”模式运行容器,一些特殊的环境很难满足这个条件,例如 [GitLab 持续集成][23];即使满足该条件,配置也特别[繁琐][24]。 + +手动提交的步骤可以对创建容器快照的时间节点进行细粒度控制。Dockerfile 每一行都会创建一个新的快照;相比而言,Buildah 的提交检查点都是事先选择好的,这可以减少不必要的快照并节省磁盘空间。这也有利于隔离私钥或密码等敏感信息,避免其出现在公共镜像中。 + +Docker 构建的镜像是非标准的、仅供其自身使用;相比而言,Buildah 提供[多种输出格式][25],其中包括符合 OCI 标准的镜像。为向后兼容,Buildah 提供了一个“使用 Dockerfile 构建”的命令,即 [`buildah bud`][26], 它可以解析标准的 Dockerfile。Buildah 提供 `enter` 命令直接查看镜像内部信息,`run` 命令启动一个容器。实现这些功能仅使用了 `runc` 在内的标准工具,无需在后台运行一个“臃肿的守护进程”。 + +Ducy 对 Buildah 表示质疑,认为采用非宣告性不利于可重现性。如果允许使用 shell 命令,可能产生很多预想不到的情况;例如,一个 shell 脚本下载了任意的可执行程序,但后续无法追溯文件的来源。shell 命令的执行受环境变量影响,执行结果可能大相径庭。与基于 shell 的工具相比,Puppet 或 Chef 这样的配置管理系统在理论上更加可靠,因为它们的设计初衷就是收敛于最终配置;事实上,可以通过配置管理系统调用 shell 命令。但 Walsh 对此提出反驳,认为已有的配置管理工具可以在 Buildah 的基础上工作,用户可以选择是否使用配置管理;这样更加符合“机制与策略分离”的经典 Unix 哲学。 + +目前 Buildah 处于测试阶段,Red Hat 公司正努力将其集成到 OpenShift。我写这篇文章时已经测试过 Buildah,它缺少一些文档,但基本可以稳定运行。尽管在错误处理方面仍有待提高,但它确实是一款值得你关注的容器工具。 + +### 替换其它 Docker 命令行 + +Walsh 在其演讲中还简单介绍了 Red hat 公司 正在开发的另一个暂时叫做 [libpod][24] 的项目。项目名称来源于 Kubernetes 中的 “pod”, 在 Kubernetes 中 “pod” 用于分组主机内的容器,分享名字空间等。 + +Libpod 提供 `kpod` 命令,用于直接检查和操作容器存储。Walsh 分析了该命令发挥作用的场景,例如 `dockerd` 停止响应或 Kubernetes 集群崩溃。基本上,`kpod` 独立地再次实现了 `docker` 命令行工具。`kpod ps` 返回运行中的容器列表,`kpod images` 返回镜像列表。事实上,[命令转换速查手册][28] 中给出了每一条 Docker 命令对应的 `kpod` 命令。 + +这种模块化实现的一个好处是,当你使用 `kpod run` 运行容器时,容器直接作为当前 shell 而不是 `dockerd` 的子进程启动。理论上,可以直接使用 systemd 启动容器,这样可以消除 `dockerd` 引入的冗余。这让[由套接字激活的容器][29]成为可能,但暂时基于 Docker 实现该特性[并不容易][30],[即使借助 Kubernetes][31] 也是如此。但我在测试过程中发现,使用 `kpod` 启动的容器有一些基础功能性缺失,具体而言是网络功能(!),相关实现在[活跃开发][32]过程中。 + +我们最后提到的命令是 `push`。虽然上述命令已经足以满足本地使用容器的需求,但没有提到远程仓库,借助远程仓库开发者可以活跃地进行应用打包协作。仓库也是持续部署框架的核心组件。[skopeo][33] 项目用于填补这个空白,它是另一个 Atomic 成员项目,按其 `README` 文件描述,“包含容器镜像及镜像库的多种操作”。该项目的设计初衷是,在不用类似 `docker pull` 那样实际去下载可能体积庞大的镜像的前提下,检查容器镜像的内容。Docker [拒绝加入][34] 检查功能,建议通过一个额外的工具实现该功能,这促成了 Skopeo 项目。除了 `pull`、`push`,Skopeo 现在还可以完成很多其它操作,例如在,不产生本地副本的情况下将镜像在不同的仓库中复制和转换。由于部分功能比较基础,可供其它项目使用,目前很大一部分 Skopeo 代码位于一个叫做 [containers/image][35] 的基础库。[Pivotal][36]、 Google 的 [container-diff][37] 、`kpod push` 及 `buildah push` 都使用了该库。 + +`kpod` 与 Kubernetes 并没有紧密的联系,故未来可能会更换名称(事实上,在本文刊发过程中,已经更名为 [`podman`][38]),毕竟 Red Hat 法务部门还没有明确其名称。该团队希望实现更多 pod 级别的命令,这样可以对多个容器进行操作,有点类似于 [`docker compose`][39] 实现的功能。但在这方面,[Kompose][40] 是更好的工具,可以通过 [复合 YAML 文件][41] 在 Kubernetes 集群中运行容器。按计划,我们不会实现类似于 [`swarm`] 的 Docker 命令,这部分功能最好由 Kubernetes 本身完成。 + +目前看来,已经持续数年的 Docker 模块化努力终将硕果累累。但目前 `kpod` 处于快速迭代过程中,不太适合用于生产环境,不过那些工具的与众不同的设计理念让人很感兴趣,而且其中大部分的工具已经可以用于开发环境。目前只能通过编译源码的方式安装 libpod,但最终会提供各个发行版的二进制包。 + +> 本文[最初发表][43]于 [Linux Weekly News][44]。 + +-------------------------------------------------------------------------------- + +via: https://anarc.at/blog/2017-12-20-docker-without-docker/ + +作者:[Anarcat][a] +译者:[pinewall](https://github.com/pinewall) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://anarc.at +[1]:https://mobyproject.org/ +[2]:https://kccncna17.sched.com/event/CU8j/cri-o-hosted-by-daniel-walsh-red-hat +[3]:http://events.linuxfoundation.org/events/kubecon-and-cloudnativecon-north-america +[4]:https://lwn.net/Articles/741897/ +[5]:http://cri-o.io/ +[6]:https://kubernetes.io/ +[7]:https://www.openshift.com/ +[8]:https://kccncna17.sched.com/event/CU6B/building-better-containers-a-survey-of-container-build-tools-i-michael-ducy-chef +[9]:https://github.com/GoogleCloudPlatform/distroless +[10]:https://github.com/oracle/smith +[11]:https://github.com/openshift/source-to-image +[12]:https://www.ansible.com/ansible-container +[13]:https://www.habitat.sh/ +[14]:https://nixos.org/nixos/manual/#ch-containers +[15]:https://github.com/moby/buildkit +[16]:https://github.com/projectatomic/buildah +[17]:https://www.projectatomic.io/ +[18]:https://raw.githubusercontent.com/projectatomic/buildah/master/logos/buildah-logomark_large.png (Buildah logo) +[19]:https://en.wikipedia.org/wiki/Boston_accent +[20]:https://github.com/projectatomic/buildah/issues/171 +[21]:https://github.com/projectatomic/buildah/issues/158 +[22]:https://github.com/moby/moby/issues/27886#issuecomment-281278525 +[23]:https://about.gitlab.com/features/gitlab-ci-cd/ +[24]:https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/ +[25]:https://github.com/projectatomic/buildah/blob/master/docs/buildah-push.md +[26]:https://github.com/projectatomic/buildah/blob/master/docs/buildah-bud.md +[27]:https://github.com/projectatomic/libpod +[28]:https://github.com/projectatomic/libpod/blob/master/transfer.md#development-transfer +[29]:http://0pointer.de/blog/projects/socket-activated-containers.html +[30]:https://legacy-developer.atlassian.com/blog/2015/03/docker-systemd-socket-activation/ +[31]:https://github.com/kubernetes/kubernetes/issues/484 +[32]:https://github.com/projectatomic/libpod/issues/129 +[33]:https://github.com/projectatomic/skopeo +[34]:https://github.com/moby/moby/pull/14258 +[35]:https://github.com/containers/image +[36]:https://pivotal.io/ +[37]:https://github.com/GoogleCloudPlatform/container-diff +[38]:https://github.com/projectatomic/libpod/blob/master/docs/podman.1.md +[39]:https://docs.docker.com/compose/overview/#compose-documentation +[40]:http://kompose.io/ +[41]:https://docs.docker.com/compose/compose-file/ +[42]:https://docs.docker.com/engine/swarm/ +[43]:https://lwn.net/Articles/741841/ +[44]:http://lwn.net/ diff --git a/published/20171221 A Commandline Food Recipes Manager.md b/published/20171221 A Commandline Food Recipes Manager.md new file mode 100644 index 0000000000..b9754014d0 --- /dev/null +++ b/published/20171221 A Commandline Food Recipes Manager.md @@ -0,0 +1,155 @@ +HeRM's :一个命令行食谱管理器 +====== + +![配图](https://www.ostechnix.com/wp-content/uploads/2017/12/herms-720x340.jpg) + +烹饪让爱变得可见,不是吗?确实!烹饪也许是你的热情或爱好或职业,我相信你会维护一份烹饪日记。保持写烹饪日记是改善烹饪习惯的一种方法。有很多方法可以记录食谱。你可以维护一份小日记/笔记或将配方的笔记存储在智能手机中,或将它们保存在计算机中文档中。这有很多选择。今天,我介绍 **HeRM's**,这是一个基于 Haskell 的命令行食谱管理器,能为你的美食食谱做笔记。使用 Herm's,你可以添加、查看、编辑和删除食物配方,甚至可以制作购物清单。这些全部来自你的终端!它是免费的,是使用 Haskell 语言编写的开源程序。源代码在 GitHub 中免费提供,因此你可以复刻它,添加更多功能或改进它。 + +### HeRM's - 一个命令食谱管理器 + +#### 安装 HeRM's + +由于它是使用 Haskell 编写的,因此我们需要首先安装 Cabal。 Cabal 是一个用于下载和编译用 Haskell 语言编写的软件的命令行程序。Cabal 存在于大多数 Linux 发行版的核心软件库中,因此你可以使用发行版的默认软件包管理器来安装它。 + +例如,你可以使用以下命令在 Arch Linux 及其变体(如 Antergos、Manjaro Linux)中安装 cabal: + +``` +sudo pacman -S cabal-install +``` + +在 Debian、Ubuntu 上: + +``` +sudo apt-get install cabal-install +``` + +安装 Cabal 后,确保你已经添加了 `PATH`。为此,请编辑你的 `~/.bashrc`: + +``` +vi ~/.bashrc +``` + +添加下面这行: + +``` +PATH=$PATH:~/.cabal/bin +``` + +按 `:wq` 保存并退出文件。然后,运行以下命令更新所做的更改。 + +``` +source ~/.bashrc +``` + +安装 cabal 后,运行以下命令安装 `herms`: + +``` +cabal install herms +``` + +喝一杯咖啡!这将需要一段时间。几分钟后,你会看到一个输出,如下所示。 + +``` +[...] +Linking dist/build/herms/herms ... +Installing executable(s) in /home/sk/.cabal/bin +Installed herms-1.8.1.2 +``` + +恭喜! Herms 已经安装完成。 + +#### 添加食谱 + +让我们添加一个食谱,例如 Dosa。对于那些想知道的,Dosa 是一种受欢迎的南印度食物,配以 sambar(LCTT 译注:扁豆和酸豆炖菜,像咖喱汤) 和**酸辣酱**。这是一种健康的,可以说是最美味的食物。它不含添加的糖或饱和脂肪。制作一个也很容易。有几种不同的 Dosas,在我们家中最常见的是 Plain Dosa。 + +要添加食谱,请输入: + +``` +herms add +``` + +你会看到一个如下所示的屏幕。开始输入食谱的详细信息。 + +![][2] + +要变换字段,请使用以下键盘快捷键: + + * `Tab` / `Shift+Tab` - 下一个/前一个字段 + * `Ctrl + <箭头键>` - 导航字段 + * `[Meta 或者 Alt] + ` - 导航字段 + * `Esc` - 保存或取消。 + + +添加完配方的详细信息后,按下 `ESC` 键并点击 `Y` 保存。同样,你可以根据需要添加尽可能多的食谱。 + +要列出添加的食谱,输入: + +``` +herms list +``` + +![][3] + +要查看上面列出的任何食谱的详细信息,请使用下面的相应编号。 + +``` +herms view 1 +``` + +![][4] + +要编辑任何食谱,使用: + +``` +herms edit 1 +``` + +完成更改后,按下 `ESC` 键。系统会询问你是否要保存。你只需选择适当的选项。 + +![][5] + +要删除食谱,命令是: + +``` +herms remove 1 +``` + +要为指定食谱生成购物清单,运行: + +``` +herms shopping 1 +``` + +![][6] + +要获得帮助,运行: + +``` +herms -h +``` + +当你下次听到你的同事、朋友或其他地方谈到好的食谱时,只需打开 Herm's,并快速记下,并将它们分享给你的配偶。她会很高兴! + +今天就是这些。还有更好的东西。敬请关注! + +干杯!! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/herms-commandline-food-recipes-manager/ + +作者:[SK][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2017/12/Make-Dosa-1.png +[3]:http://www.ostechnix.com/wp-content/uploads/2017/12/herms-1-1.png +[4]:http://www.ostechnix.com/wp-content/uploads/2017/12/herms-2.png +[5]:http://www.ostechnix.com/wp-content/uploads/2017/12/herms-3.png +[6]:http://www.ostechnix.com/wp-content/uploads/2017/12/herms-4.png diff --git a/published/20171221 How to create mobile-friendly documentation.md b/published/20171221 How to create mobile-friendly documentation.md new file mode 100644 index 0000000000..66900d2e07 --- /dev/null +++ b/published/20171221 How to create mobile-friendly documentation.md @@ -0,0 +1,84 @@ +如何创建适合移动设备的文档 +===== + +> 帮助用户在智能手机或平板上快速轻松地找到他们所需的信息。 + +![配图](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/idea_innovation_mobile_phone.png?itok=RqVtvxkd) + +我并不是完全相信[移动为先][1]的理念,但是我确实发现更多的人使用智能手机和平板电脑等移动设备来获取信息。这包括在线的软件和硬件文档,但它们大部分都是冗长的,不适合小屏幕。通常情况下,它的伸缩性不太好,而且很难导航。 + +当用户使用移动设备访问文档时,他们通常需要迅速获取信息以了解如何执行任务或解决问题,他们不想通过看似无尽的页面来寻找他们需要的特定信息。幸运的是,解决这个问题并不难。以下是一些技巧,可以帮助你构建文档以满足移动阅读器的需求。 + +### 简短一点 + +这意味着简短的句子,简短的段落和简短的流程。你不是在写一部长篇小说或一段长新闻。使你的文档简洁。尽可能使用少量的语言来获得想法和信息。 + +以广播新闻报道为示范:关注关键要素,用简单直接的语言对其进行解释。不要让你的读者在屏幕上看到冗长的文字。 + +另外,直接切入重点。关注读者需要的信息。在线发布的文档不应该像以前厚厚的手册一样。不要把所有东西都放在一个页面上,把你的信息分成更小的块。接下来是怎样做到这一点: + +### 主题 + +在技术写作的世界里,主题是独立的,独立的信息块。每个主题都由你网站上的单个页面组成。读者应该能从特定的主题中获取他们需要的信息 -- 并且只是那些信息。要做到这一点,选择哪些主题要包含在文档中并决定如何组织它们: + +### DITA + +[达尔文信息类型化体系结构][2]Darwin Information Typing Architecture (DITA) 是用于编写和发布的一个 XML 模型。它[广泛采用][3]在技术写作中,特别是作为较长的文档集中。 + +我并不是建议你将文档转换为 XML(除非你真的想)。相反,考虑将 DITA 的不同类型主题的概念应用到你的文档中: + +* 一般:概述信息 +* 任务:分步骤的流程 +* 概念:背景或概念信息 +* 参考:API 参考或数据字典等专用信息 +* 术语表:定义术语 +* 故障排除:有关用户可能遇到的问题以及如何解决问题的信息 + +你会得到很多单独的页面。要连接这些页面: + +### 链接 + +许多内容管理系统、维基和发布框架都包含某种形式的导航 —— 通常是目录或[面包屑导航][4],这是一种在移动设备上逐渐消失的导航。 + +为了加强导航,在主题之间添加明确的链接。将这些链接放在每个主题末尾的标题**另请参阅**或**相关主题**。每个部分应包含两到五个链接,指向与当前主题相关的概述、概念和参考主题。 + +如果你需要指向文档集之外的信息,请确保链接在浏览器新的选项卡中打开。这将把读者送到另一个网站,同时也将读者继续留你的网站上。 + +这解决了文本问题,那么图片呢? + +### 不使用图片 + +除少数情况之外,不应该加太多图片到文档中。仔细查看文档中的每个图片,然后问自己: + +* 它有用吗? +* 它是否增强了文档? +* 如果删除它,读者会错过这张图片吗? + +如果回答否,那么移除图片。 + +另一方面,如果你绝对不能没有图片,就让它变成[响应式的][5]。这样,图片就会自动调整以适应更小的屏幕。 + +如果你仍然不确定图片是否应该出现,Opensource.com 社区版主 Ben Cotton 提供了一个关于在文档中使用屏幕截图的[极好的解释][6]。 + +### 最后的想法 + +通过少量努力,你就可以构建适合移动设备用户的文档。此外,这些更改也改进了桌面计算机和笔记本电脑用户的文档体验。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/think-mobile + +作者:[Scott Nesbitt][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/chrisshort +[1]:https://www.uxmatters.com/mt/archives/2012/03/mobile-first-what-does-it-mean.php +[2]:https://en.wikipedia.org/wiki/Darwin_Information_Typing_Architecture +[3]:http://dita.xml.org/book/list-of-organizations-using-dita +[4]:https://en.wikipedia.org/wiki/Breadcrumb_(navigation) +[5]:https://en.wikipedia.org/wiki/Responsive_web_design +[6]:https://opensource.com/business/15/9/when-does-your-documentation-need-screenshots diff --git a/published/20180101 How Exit Traps Can Make Your Bash Scripts Way More Robust And Reliable.md b/published/20180101 How Exit Traps Can Make Your Bash Scripts Way More Robust And Reliable.md new file mode 100644 index 0000000000..18cc5179bc --- /dev/null +++ b/published/20180101 How Exit Traps Can Make Your Bash Scripts Way More Robust And Reliable.md @@ -0,0 +1,164 @@ +“Exit Trap” 让你的 Bash 脚本更稳固可靠 +============================================================ + +有个简单实用的技巧可以让你的 bash 脚本更稳健 -- 确保总是执行必要的收尾工作,哪怕是在发生异常的时候。要做到这一点,秘诀就是 bash 提供的一个叫做 EXIT 的伪信号,你可以 [trap][1] 它,当脚本因为任何原因退出时,相应的命令或函数就会执行。我们来看看它是如何工作的。 + +基本的代码结构看起来像这样: + +``` +#!/bin/bash +function finish { + # 你的收尾代码 +} +trap finish EXIT +``` + +你可以把任何你觉得务必要运行的代码放在这个 `finish` 函数里。一个很好的例子是:创建一个临时目录,事后再删除它。 + +``` +#!/bin/bash +scratch=$(mktemp -d -t tmp.XXXXXXXXXX) +function finish { + rm -rf "$scratch" +} +trap finish EXIT +``` + +这样,在你的核心代码中,你就可以在这个 `$scratch` 目录里下载、生成、操作中间或临时数据了。^[注1][2] + +``` +# 下载所有版本的 linux 内核…… 为了科学研究! +for major in {1..4}; do + for minor in {0..99}; do + for patchlevel in {0..99}; do + tarball="linux-${major}-${minor}-${patchlevel}.tar.bz2" + curl -q "http://kernel.org/path/to/$tarball" -o "$scratch/$tarball" || true + if [ -f "$scratch/$tarball" ]; then + tar jxf "$scratch/$tarball" + fi + done + done +done +# 整合成单个文件 +# 复制到目标位置 +cp "$scratch/frankenstein-linux.tar.bz2" "$1" +# 脚本结束, scratch 目录自动被删除 +``` + +比较一下如果不用 `trap` ,你是怎么删除 `scratch` 目录的: + +``` +#!/bin/bash +# 别这样做! + +scratch=$(mktemp -d -t tmp.XXXXXXXXXX) + +# 在这里插入你的几十上百行代码 + +# 都搞定了,退出之前把目录删除 +rm -rf "$scratch" +``` + +这有什么问题么?很多: + +* 如果运行出错导致脚本提前退出, `scratch` 目录及里面的内容不会被删除。这会导致资料泄漏,可能引发安全问题。 +* 如果这个脚本的设计初衷就是在脚本末尾以前退出,那么你必须手动复制粘贴 `rm` 命令到每一个出口。 + +* 这也给维护带来了麻烦。如果今后在脚本某处添加了一个 `exit` ,你很可能就忘了加上删除操作 -- 从而制造潜在的安全漏洞。 + +### 无论如何,服务要在线 + +另外一个场景: 想象一下你正在运行一些自动化系统运维任务,要临时关闭一项服务,最后这项服务需要重启,而且要万无一失,即使脚本运行出错。那么你可以这样做: + +``` +function finish { + # 重启服务 + sudo /etc/init.d/something start +} +trap finish EXIT +sudo /etc/init.d/something stop +# 主要任务代码 + +# 脚本结束,执行 finish 函数重启服务 +``` + +一个具体的实例:比如 Ubuntu 服务器上运行着 MongoDB ,你要为 crond 写一个脚本来临时关闭服务并做一些日常维护工作。你应该这样写: + +``` +function finish { + # 重启服务 + sudo service mongdb start +} +trap finish EXIT +# 关闭 mongod 服务 +sudo service mongdb stop +# (如果 mongod 配置了 fork ,比如 replica set ,你可能需要执行 “sudo killall --wait /usr/bin/mongod”) +``` + +### 控制开销 + +有一种情况特别能体现 EXIT `trap` 的价值:如果你的脚本运行过程中需要初始化一下成本高昂的资源,结束时要确保把它们释放掉。比如你在 AWS (Amazon Web Services) 上工作,要在脚本中创建一个镜像。 + +(名词解释: 在亚马逊云上的运行的服务器叫“[实例][3]”。实例从亚马逊机器镜像Amazon Machine Image创建而来,通常被称为 “AMI” 或 “镜像” 。AMI 相当于某个特殊时间点的服务器快照。) + +我们可以这样创建一个自定义的 AMI : + +1. 基于一个基准 AMI 运行一个实例(例如,启动一个服务器)。 +2. 在实例中手动或运行脚本来做一些修改。 +3. 用修改后的实例创建一个镜像。 +4. 如果不再需要这个实例,可以将其删除。 + +最后一步**相当重要**。如果你的脚本没有把实例删除掉,它会一直运行并计费。(到月底你的账单让你大跌眼镜时,恐怕哭都来不及了!) + +如果把 AMI 的创建封装在脚本里,我们就可以利用 `trap` EXIT 来删除实例了。我们还可以用上 EC2 的命令行工具: + +``` +#!/bin/bash +# 定义基准 AMI 的 ID +ami=$1 +# 保存临时实例的 ID +instance='' +# 作为 IT 人,让我们看看 scratch 目录的另类用法 +scratch=$(mktemp -d -t tmp.XXXXXXXXXX) +function finish { + if [ -n "$instance" ]; then + ec2-terminate-instances "$instance" + fi + rm -rf "$scratch" +} +trap finish EXIT +# 创建实例,将输出(包含实例 ID )保存到 scratch 目录下的文件里 +ec2-run-instances "$ami" > "$scratch/run-instance" +# 提取实例 ID +instance=$(grep '^INSTANCE' "$scratch/run-instance" | cut -f 2) +``` + +脚本执行到这里,实例(EC2 服务器)已经开始运行 ^[注2][4]。接下来你可以做任何事情:在实例中安装软件,修改配置文件等,然后为最终版本创建一个镜像。实例会在脚本结束时被删除 -- 即使脚本因错误而提前退出。(请确保实例创建成功后再运行业务代码。) + +### 更多应用 + +这篇文章只讲了些皮毛。我已经使用这个 bash 技巧很多年了,现在还能不时发现一些有趣的用法。你也可以把这个方法应用到你自己的场景中,从而提升你的 bash 脚本的可靠性。 + +### 尾注 + +- 注1. `mktemp` 的选项 `-t` 在 Linux 上是可选的,在 OS X 上是必需的。带上此选项可以让你的脚本有更好的可移植性。 +- 注2. 如果只是为了获取实例 ID ,我们不用创建文件,直接写成 `instance=$(ec2-run-instances "$ami" | grep '^INSTANCE' | cut -f 2)` 就可以。但把输出写入文件可以记录更多有用信息,便于调试 ,代码可读性也更强。 + +作者简介:美国加利福尼亚旧金山的作家,软件工程师,企业家。[Powerful Python][5] 的作者,他的 [blog][6]。 + +-------------------------------------------------------------------------------- +via: http://redsymbol.net/articles/bash-exit-traps/ + +作者:[aaron maxwell][a] +译者:[Dotcra](https://github.com/Dotcra) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://redsymbol.net/ +[1]:http://www.gnu.org/software/bash/manual/bashref.html#index-trap +[2]:http://redsymbol.net/articles/bash-exit-traps/#footnote-1 +[3]:http://aws.amazon.com/ec2/ +[4]:http://redsymbol.net/articles/bash-exit-traps/#footnote-2 +[5]:https://www.amazon.com/d/0692878971 +[6]:https://powerfulpython.com/blog/ diff --git a/published/20180115 2 scientific calculators for the Linux desktop.md b/published/20180115 2 scientific calculators for the Linux desktop.md new file mode 100644 index 0000000000..9e10e16355 --- /dev/null +++ b/published/20180115 2 scientific calculators for the Linux desktop.md @@ -0,0 +1,122 @@ +两款 Linux 桌面端可用的科学计算器 +====== + +> 如果你想找个高级的桌面计算器的话,你可以看看开源软件,以及一些其它有趣的工具。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_OpenData_CityNumbers.png?itok=lC03ce76) + +每个 Linux 桌面环境都至少带有一个功能简单的桌面计算器,但大多数计算器只能进行一些简单的计算。 + +幸运的是,还是有例外的:不仅可以做得比开平方根和一些三角函数还多,而且还很简单。这里将介绍两款强大的计算器,外加一大堆额外的功能。 + +### SpeedCrunch + +[SpeedCrunch][1] 是一款高精度科学计算器,有着简明的 Qt5 图像界面,并且强烈依赖键盘。 + +![SpeedCrunch graphical interface][3] + +*SpeedCrunch 运行中* + +它支持单位,并且可用在所有函数中。 + +例如, + +``` +2 * 10^6 newton / (meter^2) +``` + +你可以得到: + +``` += 2000000 pascal +``` + +SpeedCrunch 会默认地将结果转化为国际标准单位,但还是可以用 `in` 命令转换: + +例如: + +``` +3*10^8 meter / second in kilo meter / hour +``` + +结果是: + +``` += 1080000000 kilo meter / hour +``` + +`F5` 键可以将所有结果转为科学计数法(`1.08e9 kilo meter / hour`),`F2` 键可以只将那些很大的数或很小的数转为科学计数法。更多选项可以在配置页面找到。 + +可用的函数的列表看上去非常壮观。它可以用在 Linux 、 Windows、macOS。许可证是 GPLv2,你可以在 [Bitbucket][4] 上得到它的源码。 + +### Qalculate! + +[Qalculate!][5](有感叹号)有一段长而复杂的历史。 + +这个项目给了我们一个强大的库,而这个库可以被其它程序使用(在 Plasma 桌面中,krunner 可以用它来计算),以及一个用 GTK3 搭建的图形界面。它允许你转换单位,处理物理常量,创建图像,使用复数,矩阵以及向量,选择任意精度,等等。 + +![Qalculate! Interface][7] + +*在 Qalculate! 中查看物理常量* + +在单位的使用方面,Qalculate! 会比 SppedCrunch 更加直观,而且可以识别一些常用前缀。你有听说过 exapascal 压力吗?反正我没有(太阳的中心大概在 `~26 PPa`),但 Qalculate! ,可以准确 `1 EPa` 的意思。同时,Qalculate! 可以更加灵活地处理语法错误,所以你不需要担心打括号:如果没有歧义,Qalculate! 会直接给出正确答案。 + +一段时间之后这个项目看上去被遗弃了。但在 2016 年,它又变得强大了,在一年里更新了 10 个版本。它的许可证是 GPLv2 (源码在 [GitHub][8] 上),提供Linux 、Windows 、macOS的版本。 + +### 更多计算器 + +#### ConvertAll + +好吧,这不是“计算器”,但这个程序非常好用。 + +大部分单位转换器只是一个大的基本单位列表以及一大堆基本组合,但 [ConvertAll][9] 与它们不一样。有试过把天文单位每年转换为英寸每秒吗?不管它们说不说得通,只要你想转换任何种类的单位,ConvertAll 就是你要的工具。 + +只需要在相应的输入框内输入转换前和转换后的单位:如果单位相容,你会直接得到答案。 + +主程序是在 PyQt5 上搭建的,但也有 [JavaScript 的在线版本][10]。 + +#### 带有单位包的 (wx)Maxima + +有时候(好吧,很多时候)一款桌面计算器时候不够你用的,然后你需要更多的原力。 + +[Maxima][11] 是一款计算机代数系统(LCTT 译注:进行符号运算的软件。这种系统的要件是数学表示式的符号运算),你可以用它计算导数、积分、方程、特征值和特征向量、泰勒级数、拉普拉斯变换与傅立叶变换,以及任意精度的数字计算、二维或三维图像··· ···列出这些都够我们写几页纸的了。 + +[wxMaxima][12] 是一个设计精湛的 Maxima 的图形前端,它简化了许多 Maxima 的选项,但并不会影响其它。在 Maxima 的基础上,wxMaxima 还允许你创建 “笔记本”,你可以在上面写一些笔记,保存你的图像等。其中一项 (wx)Maxima 最惊艳的功能是它可以处理尺寸单位。 + +在提示符只需要输入: + +``` +load("unit") +``` + +按 `Shift+Enter`,等几秒钟的时间,然后你就可以开始了。 + +默认地,单位包可以用基本的 MKS 单位,但如果你喜欢,例如,你可以用 `N` 为单位而不是 `kg*m/s2`,你只需要输入:`setunits(N)`。 + +Maxima 的帮助(也可以在 wxMaxima 的帮助菜单中找到)会给你更多信息。 + +你使用这些程序吗?你知道还有其它好的科学、工程用途的桌面计算器或者其它相关的计算器吗?在评论区里告诉我们吧! + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/scientific-calculators-linux + +作者:[Ricardo Berlasso][a] +译者:[zyk2290](https://github.com/zyk2290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/rgb-es +[1]:http://speedcrunch.org/index.html +[2]:/file/382511 +[3]:https://opensource.com/sites/default/files/u128651/speedcrunch.png "SpeedCrunch graphical interface" +[4]:https://bitbucket.org/heldercorreia/speedcrunch +[5]:https://qalculate.github.io/ +[6]:/file/382506 +[7]:https://opensource.com/sites/default/files/u128651/qalculate-600.png "Qalculate! Interface" +[8]:https://github.com/Qalculate +[9]:http://convertall.bellz.org/ +[10]:http://convertall.bellz.org/js/ +[11]:http://maxima.sourceforge.net/ +[12]:https://andrejv.github.io/wxmaxima/ diff --git a/published/20180116 Why building a community is worth the extra effort.md b/published/20180116 Why building a community is worth the extra effort.md new file mode 100644 index 0000000000..503712cf1a --- /dev/null +++ b/published/20180116 Why building a community is worth the extra effort.md @@ -0,0 +1,66 @@ +为什么建设一个社区值得额外的努力 +====== + +> 建立 NethServer 社区是有风险的。但是我们从这些激情的人们所带来的力量当中学习到了很多。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_brandbalance.png?itok=XSQ1OU16) + +当我们在 2003 年推出 [Nethesis][1] 时,我们还只是系统集成商。我们只使用已有的开源项目。我们的业务模式非常明确:为这些项目增加多种形式的价值:实践知识、针对意大利市场的文档、额外模块、专业支持和培训课程。我们还通过向上游贡献代码并参与其社区来回馈上游项目。 + +那时时代不同。我们不能太张扬地使用“开源”这个词。人们将它与诸如“书呆子”,“没有价值”以及最糟糕的“免费”这些词联系起来。这些不太适合生意。 + +在 2010 年的一个星期六,Nethesis 的工作人员,他们手中拿着馅饼和浓咖啡,正在讨论如何推进事情发展(嘿,我们喜欢在创新的同时吃喝东西!)。尽管势头对我们不利,但我们决定不改变方向。事实上,我们决定加大力度 —— 去做开源和开放的工作方式,这是一个成功运营企业的模式。 + +多年来,我们已经证明了该模型的潜力。有一件事是我们成功的关键:社区。 + +在这个由三部分组成的系列文章中,我将解释社区在开放组织的存在中扮演的重要角色。我将探讨为什么一个组织希望建立一个社区,并讨论如何建立一个社区 —— 因为我确实认为这是如今产生新创新的最佳方式。 + +### 这个疯狂的想法 + +与 Nethesis 伙伴一起,我们决定构建自己的开源项目:我们自己的操作系统,它建立在 CentOS 之上(因为我们不想重新发明轮子)。我们假设我们拥有实现它的经验、实践知识和人力。我们感到很勇敢。 + +我们非常希望构建一个名为 [NethServer][2] 的操作系统,其使命是:通过开源使系统管理员的生活更轻松。我们知道我们可以为服务器创建一个 Linux 发行版,与当前已有的相比,它更容易使用、更易于部署,并且更易于理解。 + +不过,最重要的是,我们决定创建一个真正的,100% 开放的项目,其主要规则有三条: + + * 完全免费下载 + * 开发公开 + * 社区驱动 + +最后一个很重要。我们是一家公司。我们能够自己开发它。如果我们在内部完成这项工作,我们将会更有效(并且做出更快的决定)。与其他任何意大利公司一样,这将非常简单。 + +但是我们已经如此深入到开源文化中,所以我们选择了不同的路径。 + +我们确实希望有尽可能多的人围绕着我们、围绕着产品、围绕着公司周围。我们希望对工作有尽可能多的视角。我们意识到:独自一人,你可以走得快 —— 但是如果你想走很远,你需要一起走。 + +所以我们决定建立一个社区。 + +### 下一步是什么? + +我们意识到创建社区有很多好处。例如,如果使用产品的人真正参与到项目中,他们将提供反馈和测试用例、编写文档、发现 bug,与其他产品进行比较,建议功能并为开发做出贡献。所有这些都会产生创新,吸引贡献者和客户,并扩展你产品的用户群。 + +但是很快就出现了这样一个问题:我们如何建立一个社区?我们不知道如何实现这一点。我们参加了很多社区,但我们从未建立过一个社区。 + +我们擅长编码 —— 而不是人。我们是一家公司,是一个有非常具体优先事项的组织。那么我们如何建立一个社区,并在公司和社区之间建立良好的关系呢? + +我们做了你必须做的第一件事:学习。我们从专家、博客和许多书中学到了知识。我们进行了实验。我们失败了多次,从结果中收集数据,并再次进行测试。 + +最终我们学到了社区管理的黄金法则:**没有社区管理的黄金法则。** + +人们太复杂了,社区无法用一条规则来“统治他们”。 + +然而,我可以说的一件事是,社区和公司之间的健康关系总是一个给予和接受的过程。在我的下一篇文章中,我将讨论你的组织如果想要一个蓬勃发展和创新的社区,应该期望提供什么。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/open-organization/18/1/why-build-community-1 + +作者:[Alessio Fattorini][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/alefattorini +[1]:http://www.nethesis.it/ +[2]:http://www.nethserver.org/ diff --git a/published/20180122 A Simple Command-line Snippet Manager.md b/published/20180122 A Simple Command-line Snippet Manager.md new file mode 100644 index 0000000000..dd18a8cb10 --- /dev/null +++ b/published/20180122 A Simple Command-line Snippet Manager.md @@ -0,0 +1,345 @@ +Pet:一个简单的命令行片段管理器 +===== + +![](https://www.ostechnix.com/wp-content/uploads/2018/01/pet-6-720x340.png) + +我们不可能记住所有的命令,对吧?是的。除了经常使用的命令之外,我们几乎不可能记住一些很少使用的长命令。这就是为什么需要一些外部工具来帮助我们在需要时找到命令。在过去,我们已经点评了两个有用的工具,名为 “Bashpast” 和 “Keep”。使用 Bashpast,我们可以轻松地为 Linux 命令添加书签,以便更轻松地重复调用。而 Keep 实用程序可以用来在终端中保留一些重要且冗长的命令,以便你可以随时使用它们。今天,我们将看到该系列中的另一个工具,以帮助你记住命令。现在让我们认识一下 “Pet”,这是一个用 Go 语言编写的简单的命令行代码管理器。 + +使用 Pet,你可以: + + * 注册/添加你重要的、冗长和复杂的命令片段。 + * 以交互方式来搜索保存的命令片段。 + * 直接运行代码片段而无须一遍又一遍地输入。 + * 轻松编辑保存的代码片段。 + * 通过 Gist 同步片段。 + * 在片段中使用变量 + * 还有很多特性即将来临。 + +### 安装 Pet 命令行接口代码管理器 + +由于它是用 Go 语言编写的,所以确保你在系统中已经安装了 Go。 + +安装 Go 后,从 [**Pet 发布页面**][3] 获取最新的二进制文件。 + +``` +wget https://github.com/knqyf263/pet/releases/download/v0.2.4/pet_0.2.4_linux_amd64.zip +``` + +对于 32 位计算机: + +``` +wget https://github.com/knqyf263/pet/releases/download/v0.2.4/pet_0.2.4_linux_386.zip +``` + +解压下载的文件: + +``` +unzip pet_0.2.4_linux_amd64.zip +``` + +对于 32 位: + +``` +unzip pet_0.2.4_linux_386.zip +``` + +将 `pet` 二进制文件复制到 PATH(即 `/usr/local/bin` 之类的)。 + +``` +sudo cp pet /usr/local/bin/ +``` + +最后,让它可以执行: + +``` +sudo chmod +x /usr/local/bin/pet +``` + +如果你使用的是基于 Arch 的系统,那么你可以使用任何 AUR 帮助工具从 AUR 安装它。 + +使用 [Pacaur][4]: + +``` +pacaur -S pet-git +``` + +使用 [Packer][5]: + +``` +packer -S pet-git +``` + +使用 [Yaourt][6]: + +``` +yaourt -S pet-git +``` + +使用 [Yay][7]: + +``` +yay -S pet-git +``` + +此外,你需要安装 [fzf][8] 或 [peco][9] 工具以启用交互式搜索。请参阅官方 GitHub 链接了解如何安装这些工具。 + +### 用法 + +运行没有任何参数的 `pet` 来查看可用命令和常规选项的列表。 + +``` +$ pet +pet - Simple command-line snippet manager. + +Usage: + pet [command] + +Available Commands: + configure Edit config file + edit Edit snippet file + exec Run the selected commands + help Help about any command + list Show all snippets + new Create a new snippet + search Search snippets + sync Sync snippets + version Print the version number + +Flags: + --config string config file (default is $HOME/.config/pet/config.toml) + --debug debug mode + -h, --help help for pet + +Use "pet [command] --help" for more information about a command. +``` + +要查看特定命令的帮助部分,运行: + +``` +$ pet [command] --help +``` + +#### 配置 Pet + +默认配置其实工作的挺好。但是,你可以更改保存片段的默认目录,选择要使用的选择器(fzf 或 peco),编辑片段的默认文本编辑器,添加 GIST id 详细信息等。 + +要配置 Pet,运行: + +``` +$ pet configure +``` + +该命令将在默认的文本编辑器中打开默认配置(例如我是 vim),根据你的要求更改或编辑特定值。 + +``` +[General] + snippetfile = "/home/sk/.config/pet/snippet.toml" + editor = "vim" + column = 40 + selectcmd = "fzf" + +[Gist] + file_name = "pet-snippet.toml" + access_token = "" + gist_id = "" + public = false +~ +``` + +#### 创建片段 + +为了创建一个新的片段,运行: + +``` +$ pet new +``` + +添加命令和描述,然后按下回车键保存它。 + +``` +Command> echo 'Hell1o, Welcome1 2to OSTechNix4' | tr -d '1-9' +Description> Remove numbers from output. +``` + +![][11] + +这是一个简单的命令,用于从 `echo` 命令输出中删除所有数字。你可以很轻松地记住它。但是,如果你很少使用它,几天后你可能会完全忘记它。当然,我们可以使用 `CTRL+R` 搜索历史记录,但 Pet 会更容易。另外,Pet 可以帮助你添加任意数量的条目。 + +另一个很酷的功能是我们可以轻松添加以前的命令。为此,在你的 `.bashrc` 或 `.zshrc` 文件中添加以下行。 + +``` +function prev() { + PREV=$(fc -lrn | head -n 1) + sh -c "pet new `printf %q "$PREV"`" +} +``` + +执行以下命令来使保存的更改生效。 + +``` +source .bashrc +``` + +或者: + +``` +source .zshrc +``` + +现在,运行任何命令,例如: + +``` +$ cat Documents/ostechnix.txt | tr '|' '\n' | sort | tr '\n' '|' | sed "s/.$/\\n/g" +``` + +要添加上述命令,你不必使用 `pet new` 命令。只需要: + +``` +$ prev +``` + +将说明添加到该命令代码片段中,然后按下回车键保存。 + +![][12] + +#### 片段列表 + +要查看保存的片段,运行: + +``` +$ pet list +``` + +![][13] + +#### 编辑片段 + +如果你想编辑代码片段的描述或命令,运行: + +``` +$ pet edit +``` + +这将在你的默认文本编辑器中打开所有保存的代码片段,你可以根据需要编辑或更改片段。 + +``` +[[snippets]] + description = "Remove numbers from output." + command = "echo 'Hell1o, Welcome1 2to OSTechNix4' | tr -d '1-9'" + output = "" + +[[snippets]] + description = "Alphabetically sort one line of text" + command = "\t prev" + output = "" +``` + +#### 在片段中使用标签 + +要将标签用于判断,使用下面的 `-t` 标志。 + +``` +$ pet new -t +Command> echo 'Hell1o, Welcome1 2to OSTechNix4' | tr -d '1-9 +Description> Remove numbers from output. +Tag> tr command examples +``` + +#### 执行片段 + +要执行一个保存的片段,运行: + +``` +$ pet exec +``` + +从列表中选择你要运行的代码段,然后按回车键来运行它: + +![][14] + +记住你需要安装 fzf 或 peco 才能使用此功能。 + +#### 寻找片段 + +如果你有很多要保存的片段,你可以使用字符串或关键词如 below.qjz 轻松搜索它们。 + +``` +$ pet search +``` + +输入搜索字词或关键字以缩小搜索结果范围。 + +![][15] + +#### 同步片段 + +首先,你需要获取访问令牌。转到此链接 并创建访问令牌(只需要 “gist” 范围)。 + +使用以下命令来配置 Pet: + +``` +$ pet configure +``` + +将令牌设置到 `[Gist]` 字段中的 `access_token`。 + +设置完成后,你可以像下面一样将片段上传到 Gist。 + +``` +$ pet sync -u +Gist ID: 2dfeeeg5f17e1170bf0c5612fb31a869 +Upload success +``` + +你也可以在其他 PC 上下载片段。为此,编辑配置文件并在 `[Gist]` 中将 `gist_id` 设置为 GIST id。 + +之后,使用以下命令下载片段: + +``` +$ pet sync +Download success +``` + +获取更多细节,参阅帮助选项: + +``` +pet -h +``` + +或者: + +``` +pet [command] -h +``` + +这就是全部了。希望这可以帮助到你。正如你所看到的,Pet 使用相当简单易用!如果你很难记住冗长的命令,Pet 实用程序肯定会有用。 + +干杯! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/pet-simple-command-line-snippet-manager/ + +作者:[SK][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/bookmark-linux-commands-easier-repeated-invocation/ +[2]:https://www.ostechnix.com/save-commands-terminal-use-demand/ +[3]:https://github.com/knqyf263/pet/releases +[4]:https://www.ostechnix.com/install-pacaur-arch-linux/ +[5]:https://www.ostechnix.com/install-packer-arch-linux-2/ +[6]:https://www.ostechnix.com/install-yaourt-arch-linux/ +[7]:https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/ +[8]:https://github.com/junegunn/fzf +[9]:https://github.com/peco/peco +[10]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[11]:http://www.ostechnix.com/wp-content/uploads/2018/01/pet-1.png +[12]:http://www.ostechnix.com/wp-content/uploads/2018/01/pet-2.png +[13]:http://www.ostechnix.com/wp-content/uploads/2018/01/pet-3.png +[14]:http://www.ostechnix.com/wp-content/uploads/2018/01/pet-4.png +[15]:http://www.ostechnix.com/wp-content/uploads/2018/01/pet-5.png diff --git a/published/20180126 How To Manage NodeJS Packages Using Npm.md b/published/20180126 How To Manage NodeJS Packages Using Npm.md new file mode 100644 index 0000000000..e9805185e9 --- /dev/null +++ b/published/20180126 How To Manage NodeJS Packages Using Npm.md @@ -0,0 +1,401 @@ +如何使用 npm 管理 NodeJS 包 +===== + +![](https://www.ostechnix.com/wp-content/uploads/2018/01/npm-720x340.png) + +前一段时间,我们发布了一个[使用 pip 管理 Python 包][3]的指南。今天,我们将讨论如何使用 npm 管理 NodeJS 包。npm 是最大的软件注册中心,包含 600,000 多个包。每天,世界各地的开发人员通过 npm 共享和下载软件包。在本指南中,我将解释使用 npm 基础知识,例如安装包(本地和全局)、安装特定版本的包、更新、删除和管理 NodeJS 包等等。 + +### 安装 npm + +用于 npm 是用 NodeJS 编写的,我们需要安装 NodeJS 才能使用 npm。要在不同的 Linux 发行版上安装 NodeJS,请参考下面的链接。 + +- [在 Linux 上安装 NodeJS](https://www.ostechnix.com/install-node-js-linux/) + +检查 node 安装的位置: + +``` +$ which node +/home/sk/.nvm/versions/node/v9.4.0/bin/node +``` + +检查它的版本: + +``` +$ node -v +v9.4.0 +``` + +进入 Node 交互式解释器: + +``` +$ node +> .help +.break Sometimes you get stuck, this gets you out +.clear Alias for .break +.editor Enter editor mode +.exit Exit the repl +.help Print this help message +.load Load JS from a file into the REPL session +.save Save all evaluated commands in this REPL session to a file +> .exit +``` + +检查 npm 安装的位置: + +``` +$ which npm +/home/sk/.nvm/versions/node/v9.4.0/bin/npm +``` + +还有版本: + +``` +$ npm -v +5.6.0 +``` + +棒极了!Node 和 npm 已安装好!正如你可能已经注意到,我已经在我的 `$HOME` 目录中安装了 NodeJS 和 NPM,这样是为了避免在全局模块时出现权限问题。这是 NodeJS 团队推荐的方法。 + +那么,让我们继续看看如何使用 npm 管理 NodeJS 模块(或包)。 + +### 安装 NodeJS 模块 + +NodeJS 模块可以安装在本地或全局(系统范围)。现在我将演示如何在本地安装包(LCTT 译注:即将包安装到一个 NodeJS 项目当中,所以下面会先创建一个空项目做演示)。 + +#### 在本地安装包 + +为了在本地管理包,我们通常使用 `package.json` 文件来管理。 + +首先,让我们创建我们的项目目录。 + +``` +$ mkdir demo +$ cd demo +``` + +在项目目录中创建一个 `package.json` 文件。为此,运行: + +``` +$ npm init +``` + +输入你的包的详细信息,例如名称、版本、作者、GitHub 页面等等,或者按下回车键接受默认值并键入 `yes` 确认。 + +``` +This utility will walk you through creating a package.json file. +It only covers the most common items, and tries to guess sensible defaults. + +See `npm help json` for definitive documentation on these fields +and exactly what they do. + +Use `npm install ` afterwards to install a package and +save it as a dependency in the package.json file. + +Press ^C at any time to quit. +package name: (demo) +version: (1.0.0) +description: demo nodejs app +entry point: (index.js) +test command: +git repository: +keywords: +author: +license: (ISC) +About to write to /home/sk/demo/package.json: + +{ + "name": "demo", + "version": "1.0.0", + "description": "demo nodejs app", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} + +Is this ok? (yes) yes +``` + +上面的命令初始化你的项目并创建了 `package.json` 文件。 + +你也可以使用命令以非交互式方式执行此操作: + +``` +npm init --y +``` + +现在让我们安装名为 [commander][2] 的包。 + +``` +$ npm install commander +``` + +示例输出: + +``` +npm notice created a lockfile as package-lock.json. You should commit this file. +npm WARN demo@1.0.0 No repository field. + ++ commander@2.13.0 +added 1 package in 2.519s +``` + +这将在项目的根目录中创建一个名为 `node_modules` 的目录(如果它不存在的话),并在其中下载包。 + +让我们检查 `pachage.json` 文件。 + +``` +$ cat package.json +{ + "name": "demo", + "version": "1.0.0", + "description": "demo nodejs app", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "commander": "^2.13.0" + } +} +``` + +你会看到添加了依赖文件,版本号前面的插入符号 ( `^` ) 表示在安装时,npm 将取出它可以找到的最高版本的包。 + +``` +$ ls node_modules/ +commander +``` + +`package.json` 文件的优点是,如果你的项目目录中有 `package.json` 文件,只需键入 `npm install`,那么 `npm` 将查看文件中列出的依赖关系并下载它们。你甚至可以与其他开发人员共享它或将其推送到你的 GitHub 仓库。因此,当他们键入 `npm install` 时,他们将获得你拥有的所有相同的包。 + +你也可能会注意到另一个名为 `package-lock.json` 的文件,该文件确保在项目安装的所有系统上都保持相同的依赖关系。 + +要在你的程序中使用已安装的包,使用实际代码在项目目录中创建一个 `index.js`(或者其他任何名称)文件,然后使用以下命令运行它: + +``` +$ node index.js +``` + +#### 在全局安装包 + +如果你想使用一个包作为命令行工具,那么最好在全局安装它。这样,无论你的当前目录是哪个目录,它都能正常工作。 + +``` +$ npm install async -g ++ async@2.6.0 +added 2 packages in 4.695s +``` + +或者 + +``` +$ npm install async --global +``` + +要安装特定版本的包,我们可以: + +``` +$ npm install async@2.6.0 --global +``` + +### 更新 NodeJS 模块 + +要更新本地包,转到 `package.json` 所在的项目目录并运行: + +``` +$ npm update +``` + +然后,运行以下命令确保所有包都更新了。 + +``` +$ npm outdated +``` + +如果没有需要更新的,那么它返回空。 + +要找出哪一个全局包需要更新,运行: + +``` +$ npm outdated -g --depth=0 +``` + +如果没有输出,意味着所有包都已更新。 + +更新单个全局包,运行: + +``` +$ npm update -g +``` + +更新所有的全局包,运行: + +``` +$ npm update -g +``` + +### 列出 NodeJS 模块 + +列出本地包,转到项目目录并运行: + +``` +$ npm list +demo@1.0.0 /home/sk/demo +└── commander@2.13.0 +``` + +如你所见,我在本地安装了 `commander` 这个包。 + +要列出全局包,从任何位置都可以运行以下命令: + +``` +$ npm list -g +``` + +示例输出: + +``` +/home/sk/.nvm/versions/node/v9.4.0/lib +├─┬ async@2.6.0 +│ └── lodash@4.17.4 +└─┬ npm@5.6.0 + ├── abbrev@1.1.1 + ├── ansi-regex@3.0.0 + ├── ansicolors@0.3.2 + ├── ansistyles@0.1.3 + ├── aproba@1.2.0 + ├── archy@1.0.0 +[...] +``` + +该命令将列出所有模块及其依赖关系。 + +要仅仅列出顶级模块,使用 `-depth=0` 选项: + +``` +$ npm list -g --depth=0 +/home/sk/.nvm/versions/node/v9.4.0/lib +├── async@2.6.0 +└── npm@5.6.0 +``` + +#### 寻找 NodeJS 模块 + +要搜索一个模块,使用 `npm search` 命令: + +``` +npm search +``` + +例如: + +``` +$ npm search request +``` + +该命令将显示包含搜索字符串 `request` 的所有模块。 + +##### 移除 NodeJS 模块 + +要删除本地包,转到项目目录并运行以下命令,这会从 `node_modules` 目录中删除包: + +``` +$ npm uninstall +``` + +要从 `package.json` 文件中的依赖关系中删除它,使用如下所示的 `save` 选项: + +``` +$ npm uninstall --save +``` + +要删除已安装的全局包,运行: + +``` +$ npm uninstall -g +``` + +### 清除 npm 缓存 + +默认情况下,npm 在安装包时,会将其副本保存在 `$HOME` 目录中名为 `.npm` 的缓存文件夹中。所以,你可以在下次安装时不必再次下载。 + +查看缓存模块: + +``` +$ ls ~/.npm +``` + +随着时间的推移,缓存文件夹会充斥着大量旧的包。所以不时清理缓存会好一些。 + +从 npm@5 开始,npm 缓存可以从 corruption 问题中自行修复,并且保证从缓存中提取的数据有效。如果你想确保一切都一致,运行: + +``` +$ npm cache verify +``` + +清除整个缓存,运行: + +``` +$ npm cache clean --force +``` + +### 查看 npm 配置 + +要查看 npm 配置,键入: + +``` +$ npm config list +``` + +或者: + +``` +$ npm config ls +``` + +示例输出: + +``` +; cli configs +metrics-registry = "https://registry.npmjs.org/" +scope = "" +user-agent = "npm/5.6.0 node/v9.4.0 linux x64" + +; node bin location = /home/sk/.nvm/versions/node/v9.4.0/bin/node +; cwd = /home/sk +; HOME = /home/sk +; "npm config ls -l" to show all defaults. +``` + +要显示当前的全局位置: + +``` +$ npm config get prefix +/home/sk/.nvm/versions/node/v9.4.0 +``` + +好吧,这就是全部了。我们刚才介绍的只是基础知识,npm 是一个广泛话题。有关更多详细信息,参阅 [**NPM Getting Started**][3] 指南。 + +希望这对你有帮助。更多好东西即将来临,敬请关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/manage-nodejs-packages-using-npm/ + +作者:[SK][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/manage-python-packages-using-pip/ +[2]:https://www.npmjs.com/package/commander +[3]:https://docs.npmjs.com/getting-started/ diff --git a/published/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md b/published/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md new file mode 100644 index 0000000000..7f3f10a6e3 --- /dev/null +++ b/published/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md @@ -0,0 +1,99 @@ +如何使用 rsync 通过 SSH 恢复部分传输的文件 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2016/02/Resume-Partially-Transferred-Files-Over-SSH-Using-Rsync.png) + +由于诸如电源故障、网络故障或用户干预等各种原因,使用 `scp` 命令通过 SSH 复制的大型文件可能会中断、取消或损坏。有一天,我将 Ubuntu 16.04 ISO 文件复制到我的远程系统。不幸的是断电了,网络连接立即断了。结果么?复制过程终止!这只是一个简单的例子。Ubuntu ISO 并不是那么大,一旦电源恢复,我就可以重新启动复制过程。但在生产环境中,当你在传输大型文件时,你可能并不希望这样做。 + +而且,你不能继续使用 `scp` 命令恢复被中止的进度。因为,如果你这样做,它只会覆盖现有的文件。这时你会怎么做?别担心!这是 `rsync` 派上用场的地方!`rsync` 可以帮助你恢复中断的复制或下载过程。对于那些好奇的人,`rsync` 是一个快速、多功能的文件复制程序,可用于复制和传输远程和本地系统中的文件或文件夹。 + +它提供了大量控制其各种行为的选项,并允许非常灵活地指定要复制的一组文件。它以增量传输算法而闻名,它通过仅发送源文件和目标中现有文件之间的差异来减少通过网络发送的数据量。 `rsync` 广泛用于备份和镜像,以及日常使用中改进的复制命令。 + +就像 `scp` 一样,`rsync` 也会通过 SSH 复制文件。如果你想通过 SSH 下载或传输大文件和文件夹,我建议您使用 `rsync`。请注意,应该在两边(远程和本地系统)都安装 `rsync` 来恢复部分传输的文件。 + +### 使用 rsync 恢复部分传输的文件 + +好吧,让我给你看一个例子。我将使用命令将 Ubuntu 16.04 ISO 从本地系统复制到远程系统: + +``` +$ scp Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +这里, + + * `sk`是我的远程系统的用户名 + * `192.168.43.2` 是远程机器的 IP 地址。 + +现在,我按下 `CTRL+C` 结束它。 + +示例输出: + +``` +sk@192.168.43.2's password: +ubuntu-16.04-desktop-amd64.iso 26% 372MB 26.2MB/s 00:39 ETA^c +``` + +![][2] + +正如你在上面的输出中看到的,当它达到 26% 时,我终止了复制过程。 + +如果我重新运行上面的命令,它只会覆盖现有的文件。换句话说,复制过程不会在我断开的地方恢复。 + +为了恢复复制过程,我们可以使用 `rsync` 命令,如下所示。 + +``` +$ rsync -P -rsh=ssh Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +示例输出: + +``` +sk@192.168.1.103's password: +sending incremental file list +ubuntu-16.04-desktop-amd64.iso +                   380.56M 26% 41.05MB/s 0:00:25 +``` + +![][4] + +看见了吗?现在,复制过程在我们之前断开的地方恢复了。你也可以像下面那样使用 `-partial` 而不是 `-P` 参数。 + +``` +$ rsync --partial -rsh=ssh Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +这里,参数 `-partial` 或 `-P` 告诉 `rsync` 命令保留部分下载的文件并恢复进度。 + +或者,我们也可以使用以下命令通过 SSH 恢复部分传输的文件。 + +``` +$ rsync -avP Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +或者, + +``` +rsync -av --partial Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +就是这样了。你现在知道如何使用 `rsync` 命令恢复取消、中断和部分下载的文件。正如你所看到的,它也不是那么难。如果两个系统都安装了 `rsync`,我们可以轻松地通过上面描述的那样恢复复制的进度。 + +如果你觉得本教程有帮助,请在你的社交、专业网络上分享,并支持我们。还有更多的好东西。敬请关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-resume-partially-downloaded-or-transferred-files-using-rsync/ + +作者:[SK][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2016/02/scp.png +[3]:/cdn-cgi/l/email-protection +[4]:http://www.ostechnix.com/wp-content/uploads/2016/02/rsync.png diff --git a/sources/tech/20180205 How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command.md b/published/20180205 How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command.md similarity index 50% rename from sources/tech/20180205 How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command.md rename to published/20180205 How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command.md index 8062d469e9..d30177c34f 100644 --- a/sources/tech/20180205 How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command.md +++ b/published/20180205 How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command.md @@ -1,24 +1,26 @@ -How to Create, Revert and Delete KVM Virtual machine snapshot with virsh command +如何使用 virsh 命令创建、还原和删除 KVM 虚拟机快照 ====== -[![KVM-VirtualMachine-Snapshot][1]![KVM-VirtualMachine-Snapshot][2]][2] -While working on the virtualization platform system administrators usually take the snapshot of virtual machine before doing any major activity like deploying the latest patch and code. +![KVM-VirtualMachine-Snapshot][2] -Virtual machine **snapshot** is a copy of virtual machine’s disk at the specific point of time. In other words we can say snapshot keeps or preserve the state and data of a virtual machine at given point of time. +在虚拟化平台上进行系统管理工作时,经常需要在开始重大操作比如部署补丁和代码前先设置一个虚拟机快照snapshot。 -### Where we can use VM snapshots ..? +虚拟机**快照**是特定时间点的虚拟机磁盘的副本。换句话说,快照保存了给定的时间点虚拟机的状态和数据。 -If you are working on **KVM** based **hypervisors** we can take virtual machines or domain snapshot using the virsh command. Snapshot becomes very helpful in a situation where you have installed or apply the latest patches on the VM but due to some reasons, application hosted in the VMs becomes unstable and application team wants to revert all the changes or patches. If you had taken the snapshot of the VM before applying patches then we can restore or revert the VM to its previous state using snapshot. +### 我们可以在哪里使用虚拟机快照? + +如果你在使用基于 **KVM** 的**虚拟机管理程序**,那么可以使用 `virsh` 命令获取虚拟机或域快照。快照在一种情况下变得非常有用,当你已经在虚拟机上安装或应用了最新的补丁,但是由于某些原因,虚拟机上的程序变得不稳定,开发团队想要还原所有的更改和补丁。如果你在应用补丁之前设置了虚拟机的快照,那么可以使用快照将虚拟机恢复到之前的状态。 + +**注意:**我们只能对磁盘格式为 **Qcow2** 的虚拟机的进行快照,并且 kvm 的 `virsh` 命令不支持 raw 磁盘格式,请使用以下命令将原始磁盘格式转换为 qcow2。 -**Note:** We can only take the snapshot of the VMs whose disk format is **Qcow2** and raw disk format is not supported by kvm virsh command, Use below command to convert the raw disk format to qcow2 ``` # qemu-img convert -f raw -O qcow2 image-name.img image-name.qcow2 - ``` -### Create KVM Virtual Machine (domain) Snapshot +### 创建 KVM 虚拟机(域)快照 + +我假设 KVM 管理程序已经在 CentOS 7 / RHEL 7 机器上配置好了,并且有虚拟机正在运行。我们可以使用下面的 `virsh` 命令列出虚拟机管理程序中的所有虚拟机, -I am assuming KVM hypervisor is already configured on CentOS 7 / RHEL 7 box and VMs are running on it. We can list the all the VMs on hypervisor using below virsh command, ``` [root@kvm-hypervisor ~]# virsh list --all  Id    Name                           State @@ -29,35 +31,33 @@ I am assuming KVM hypervisor is already configured on CentOS 7 / RHEL 7 box and  103   overcloud-compute1             running  114   webserver                      running  115   Test-MTN                       running -[root@kvm-hypervisor ~]# - ``` -Let’s suppose we want to create the snapshot of ‘ **webserver** ‘ VM, run the below command, +假设我们想创建 webserver 虚拟机的快照,运行下面的命令, -**Syntax :** +**语法:** ``` # virsh snapshot-create-as –domain {vm_name} –name {snapshot_name} –description “enter description here” ``` + ``` [root@kvm-hypervisor ~]# virsh snapshot-create-as --domain webserver --name webserver_snap --description "snap before patch on 4Feb2018" Domain snapshot webserver_snap created -[root@kvm-hypervisor ~]# - ``` -Once the snapshot is created then we can list snapshots related to the VM using below command, +创建快照后,我们可以使用下面的命令列出与虚拟机相关的快照: + ``` [root@kvm-hypervisor ~]# virsh snapshot-list webserver  Name                 Creation Time             State ------------------------------------------------------------  webserver_snap       2018-02-04 15:05:05 +0530 running [root@kvm-hypervisor ~]# - ``` -To list the detailed info of VM’s snapshot, run the beneath virsh command, +要列出虚拟机快照的详细信息,请运行下面的 `virsh` 命令: + ``` [root@kvm-hypervisor ~]# virsh snapshot-info --domain webserver --snapshotname webserver_snap Name:           webserver_snap @@ -69,58 +69,52 @@ Parent:         - Children:       0 Descendants:    0 Metadata:       yes -[root@kvm-hypervisor ~]# - ``` -We can view the size of snapshot using below qemu-img command, +我们可以使用下面的 `qemu-img` 命令查看快照的大小: + ``` [root@kvm-hypervisor ~]# qemu-img info /var/lib/libvirt/images/snaptestvm.img - ``` -[![qemu-img-command-output-kvm][1]![qemu-img-command-output-kvm][3]][3] +![qemu-img-command-output-kvm][3] -### Revert / Restore KVM virtual Machine to Snapshot +### 还原 KVM 虚拟机快照 -Let’s assume we want to revert or restore webserver VM to the snapshot that we have created in above step. Use below virsh command to restore Webserver VM to its snapshot “ **webserver_snap** ” +假设我们想要将 webserver 虚拟机还原到我们在上述步骤中创建的快照。使用下面的 `virsh` 命令将 Webserver 虚拟机恢复到其快照 webserver_snap 时。 -**Syntax :** +**语法:** ``` # virsh snapshot-revert {vm_name} {snapshot_name} ``` + ``` [root@kvm-hypervisor ~]# virsh snapshot-revert webserver webserver_snap -[root@kvm-hypervisor ~]# - ``` -### Delete KVM virtual Machine Snapshots +### 删除 KVM 虚拟机快照 + +要删除 KVM 虚拟机快照,首先使用 `virsh snapshot-list` 命令获取虚拟机的快照详细信息,然后使用 `virsh snapshot-delete` 命令删除快照。如下示例所示: -To delete KVM virtual machine snapshots, first get the VM’s snapshot details using “ **virsh snapshot-list** ” command and then use “ **virsh snapshot-delete** ” command to delete the snapshot. Example is shown below: ``` [root@kvm-hypervisor ~]# virsh snapshot-list --domain webserver  Name                 Creation Time             State ------------------------------------------------------------  webserver_snap       2018-02-04 15:05:05 +0530 running -[root@kvm-hypervisor ~]# - [root@kvm-hypervisor ~]# virsh snapshot-delete --domain webserver --snapshotname webserver_snap Domain snapshot webserver_snap deleted -[root@kvm-hypervisor ~]# - ``` -That’s all from this article, I hope you guys get an idea on how to manage KVM virtual machine snapshots using virsh command. Please do share your feedback and don’t hesitate to share it among your technical friends 🙂 +这就是本文的全部内容,我希望你们能够了解如何使用 `virsh` 命令来管理 KVM 虚拟机快照。请分享你的反馈,并不要犹豫地分享给你的技术朋友🙂 -------------------------------------------------------------------------------- via: https://www.linuxtechi.com/create-revert-delete-kvm-virtual-machine-snapshot-virsh-command/ 作者:[Pradeep Kumar][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180208 Python Global, Local and Nonlocal variables (With Examples).md b/published/20180208 Python Global, Local and Nonlocal variables (With Examples).md new file mode 100644 index 0000000000..679fb486de --- /dev/null +++ b/published/20180208 Python Global, Local and Nonlocal variables (With Examples).md @@ -0,0 +1,198 @@ +初识 Python:全局、局部和非局部变量(带示例) +====== + +### 全局变量 + +在 Python 中,在函数之外或在全局范围内声明的变量被称为全局变量。 这意味着,全局变量可以在函数内部或外部访问。 + +我们来看一个关于如何在 Python 中创建一个全局变量的示例。 + +#### 示例 1:创建全局变量 + +```python +x = "global" + +def foo(): + print("x inside :", x) + +foo() + print("x outside:", x) +``` + +当我们运行代码时,将会输出: + +``` +x inside : global +x outside: global +``` + +在上面的代码中,我们创建了 `x` 作为全局变量,并定义了一个 `foo()` 来打印全局变量 `x`。 最后,我们调用 `foo()` 来打印x的值。 + +倘若你想改变一个函数内的 `x` 的值该怎么办? + +```python +x = "global" + +def foo(): + x = x * 2 + print(x) +foo() +``` + +当我们运行代码时,将会输出: + +``` +UnboundLocalError: local variable 'x' referenced before assignment +``` + +输出显示一个错误,因为 Python 将 `x` 视为局部变量,而 `x` 没有在 `foo()` 内部定义。 + +为了运行正常,我们使用 `global` 关键字,查看 [PythonGlobal 关键字][1]以便了解更多。 + +### 局部变量 + +在函数体内或局部作用域内声明的变量称为局部变量。 + +#### 示例 2:访问作用域外的局部变量 + +```python +def foo(): + y = "local" + +foo() +print(y) +``` + +当我们运行代码时,将会输出: + +``` +NameError: name 'y' is not defined +``` + +输出显示了一个错误,因为我们试图在全局范围内访问局部变量 `y`,而局部变量只能在 `foo()` 函数内部或局部作用域内有效。 + +我们来看一个关于如何在 Python 中创建一个局部变量的例子。 + +#### 示例 3:创建一个局部变量 + +通常,我们在函数内声明一个变量来创建一个局部变量。 + +```python +def foo(): + y = "local" + print(y) + +foo() +``` + +当我们运行代码时,将会输出: + +``` +local +``` + +让我们来看看前面的问题,其中x是一个全局变量,我们想修改 `foo()` 内部的 `x`。 + +### 全局变量和局部变量 + +在这里,我们将展示如何在同一份代码中使用全局变量和局部变量。 + +#### 示例 4:在同一份代码中使用全局变量和局部变量 + +```python +x = "global" + +def foo(): + global x + y = "local" + x = x * 2 + print(x) + print(y) + +foo() +``` + +当我们运行代码时,将会输出(LCTT 译注:原文中输出结果的两个 `global` 有空格,正确的是没有空格): +``` +globalglobal +local +``` + +在上面的代码中,我们将 `x` 声明为全局变量,将 `y` 声明为 `foo()` 中的局部变量。 然后,我们使用乘法运算符 `*` 来修改全局变量 `x`,并打印 `x` 和 `y`。 + +在调用 `foo()` 之后,`x` 的值变成 `globalglobal`了(LCTT 译注:原文同样有空格,正确的是没有空格),因为我们使用 `x * 2` 打印两次 `global`。 之后,我们打印局部变量y的值,即 `local` 。 + +#### 示例 5:具有相同名称的全局变量和局部变量 + +```python +x = 5 + +def foo(): + x = 10 + print("local x:", x) + +foo() +print("global x:", x) +``` + +当我们运行代码时,将会输出: + +``` +local x: 10 +global x: 5 +``` + +在上面的代码中,我们对全局变量和局部变量使用了相同的名称 `x`。 当我们打印相同的变量时却得到了不同的结果,因为这两个作用域内都声明了变量,即 `foo()` 内部的局部作用域和 `foo()` 外面的全局作用域。 + +当我们在 `foo()` 内部打印变量时,它输出 `local x: 10`,这被称为变量的局部作用域。 + +同样,当我们在 `foo()` 外部打印变量时,它输出 `global x: 5`,这被称为变量的全局作用域。 + +### 非局部变量 + +非局部变量用于局部作用域未定义的嵌套函数。 这意味着,变量既不能在局部也不能在全局范围内。 + +我们来看一个关于如何在 Python 中创建一个非局部变量的例子。(LCTT 译者注:原文为创建全局变量,疑为笔误) + +我们使用 `nonlocal` 关键字来创建非局部变量。 + +#### 例 6:创建一个非局部变量 + +```python +def outer(): + x = "local" + + def inner(): + nonlocal x + x = "nonlocal" + print("inner:", x) + + inner() + print("outer:", x) + +outer() +``` + +当我们运行代码时,将会输出: + +``` +inner: nonlocal +outer: nonlocal +``` + +在上面的代码中有一个嵌套函数 `inner()`。 我们使用 `nonlocal` 关键字来创建非局部变量。`inner()` 函数是在另一个函数 `outer()` 的作用域中定义的。 + +注意:如果我们改变非局部变量的值,那么变化就会出现在局部变量中。 + +-------------------------------------------------------------------------------- + +via: https://www.programiz.com/python-programming/global-local-nonlocal-variables + +作者:[programiz][a] +译者:[Flowsnow](https://github.com/Flowsnow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.programiz.com/ +[1]:https://www.programiz.com/python-programming/global-keyword diff --git a/translated/talk/20180220 How slowing down made me a better leader.md b/published/20180220 How slowing down made me a better leader.md similarity index 81% rename from translated/talk/20180220 How slowing down made me a better leader.md rename to published/20180220 How slowing down made me a better leader.md index cfca276cf9..e03f969652 100644 --- a/translated/talk/20180220 How slowing down made me a better leader.md +++ b/published/20180220 How slowing down made me a better leader.md @@ -1,6 +1,8 @@ -放慢速度是如何使我变得更好的领导者 +放慢速度如何使我变成更好的领导者 ====== +> 开放式领导和耐心、倾听一样重要,它们都是关于执行的。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_leadership_brand.png?itok=YW1Syk4S) 在我职业生涯的早期,我认为我能做的最重要的事情就是行动。如果我的老板说跳,我的回答是“跳多高?” @@ -9,15 +11,15 @@ 实行开放式领导需要培养耐心和倾听技能,我需要在[最佳行动计划上进行合作,而不仅仅是最快的计划][2]。它还为我提供了一些工具,以解释 [为什么我会对某人说“不”][3] (或者,也许是“不是现在”),这样我就能以透明和自信的方式领导。 -如果你正在进行软件开发和实践 scrum 中,那么下面的观点可能会引起你的共鸣:在 sprint 计划和 sprint 演示中,耐心和倾听经理的表现和它的技能一样重要。(译注: scrum 是迭代式增量软件开发过程,通常用于敏捷软件开发。 sprint 计划和 sprint 演示是其中的两个术语。)忘掉它们,你会减少你能够产生的影响。 +如果你正在进行软件开发和实践 scrum 中,那么下面的观点可能会引起你的共鸣:在 sprint 计划和 sprint 演示中,耐心和倾听经理的表现和它的技能一样重要。(LCTT 译注: scrum 是迭代式增量软件开发过程,通常用于敏捷软件开发。 sprint 计划和 sprint 演示是其中的两个术语。)忘掉它们,你会减少你能够产生的影响。 ### 专注于耐心 -专注和耐心并不总是容易的。通常,我发现自己正坐在会议上,用行动项目填满我的笔记本时,我一般会思考:“我们可以简单地对 x 和 y 进行改进”。然后我记得事情不是那么线性的。(译者注:这句话感觉翻译得并不通顺) +专注和耐心并不总是容易的。通常,我发现自己正坐在会议上,用行动项目填满我的笔记本时,我一般会思考:“我们只要做了某事,另外一件事就会得到改善”。然后我记得事物不是那么线性发展的。 -我需要考虑可能影响情况的其他因素。暂停下来从多个人和资源中获取数据可以帮我充实策略,以确保出组织长期成功。它还帮助我确定那些短期的里程碑,这些里程碑应该会让我负责生产的业务完成交付。 +我需要考虑可能影响情况的其他因素。暂停下来从多个人和资源中获取数据可以帮我充实策略,以确保组织长期成功。它还帮助我确定那些短期的里程碑,这些里程碑应该可以让我负责生产的业务完成交付。 -这里有一个很好的例子,以前耐心不是我认为应该拥有的东西,而这又是如何影响了我的表现。当我在北卡罗来纳州工作时,我与一个在亚利桑那州的人共事。我们没有使用视频会议技术,所以当我们交谈时我没有看到她的肢体语言。然而当我负责为我领导的项目交付结果时,她是确保我获得足够支持的两个人之一。 +这里有一个很好的例子,以前耐心不是我认为应该拥有、以及影响我的表现的东西。当我在北卡罗来纳州工作时,我与一个在亚利桑那州的人共事。我们没有使用视频会议技术,所以当我们交谈时我没有看到她的肢体语言。然而当我负责为我领导的项目交付结果时,她是确保我获得足够支持的两个人之一。 无论出于何种原因,当我与她交谈时,当她要求我做某件事时,我做了。她会为我的绩效评估提供意见,所以我想确保她高兴。那时,我还不够成熟不懂得其实没必要非要讨她开心;我的重点应该放在其他绩效指标上。我本应该花更多的时间倾听并与她合作,而不是在她还在说话的时候拿起第一个“行动项目”并开始工作。 @@ -35,7 +37,7 @@ 我最终对她有一些反馈。 下次我们一起工作时,我不想在六个月后听到反馈意见。 我想早些时候和更频繁地听到反馈意见,以便我能够尽早从错误中学习。 关于这项工作的持续讨论是任何团队都应该发生的事情。 -当我成为一名管理者和领导者时,我坚持要求我的团队达到相同的标准:计划,制定计划并反思。 重复。 不要让外力造成的麻烦让你偏离你需要实施的计划。 将工作分成小的增量,以便反思和调整计划。 正如 Daniel Goleman 写道:“把注意力放在需要的地方是领导力的一个主要任务。” 不要害怕面对这个挑战。 +当我成为一名管理者和领导者时,我坚持要求我的团队达到相同的标准:计划,执行计划并反思。 重复。 不要让外力造成的麻烦让你偏离你需要实施的计划。 将工作分成小的增量,以便反思和调整计划。 正如 Daniel Goleman 写道:“把注意力放在需要的地方是领导力的一个主要任务。” 不要害怕面对这个挑战。 -------------------------------------------------------------------------------- @@ -43,7 +45,7 @@ via: [https://opensource.com/open-organization/18/2/open-leadership-patience-lis 作者:[Angela Robertson][a] 译者:[MjSeven](https://github.com/MjSeven) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180220 How to format academic papers on Linux with groff -me.md b/published/20180220 How to format academic papers on Linux with groff -me.md similarity index 61% rename from translated/tech/20180220 How to format academic papers on Linux with groff -me.md rename to published/20180220 How to format academic papers on Linux with groff -me.md index 55b2e48517..52027eccaf 100644 --- a/translated/tech/20180220 How to format academic papers on Linux with groff -me.md +++ b/published/20180220 How to format academic papers on Linux with groff -me.md @@ -1,64 +1,51 @@ -# 在 Linux 上使用 groff -me 格式化你的学术论文 +在 Linux 上使用 groff -me 格式化你的学术论文 +=========== + +> 学习用简单的宏为你的课程论文添加脚注、引用、子标题及其它格式。 ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life_paperclips.png?itok=j48op49T) -当我在 1993 年发现 Linux 时,我还是一名本科生。我很兴奋在我的宿舍里拥有 Unix 系统的强大功能,但是尽管它有很多功能,Linux 却缺乏应用程序。像 LibreOffice 和 OpenOffice 这样的文字处理程序还需要几年的时间。如果你想使用文字处理器,你可能会将你的系统引导到 MS-DOS 中,并使用 WordPerfect、shareware GalaxyWrite 或类似的程序。 +当我在 1993 年发现 Linux 时,我还是一名本科生。我很兴奋在我的宿舍里拥有 Unix 系统的强大功能,但是尽管它有很多功能,但 Linux 却缺乏应用程序。像 LibreOffice 和 OpenOffice 这样的文字处理程序还需要几年的时间才出现。如果你想使用文字处理器,你可能会将你的系统引导到 MS-DOS 中,并使用 WordPerfect、共享软件 GalaxyWrite 或类似的程序。 -`nroff` 和 `troff ` 。它们是同一系统的不同接口:`nroff` 生成纯文本输出,适用于屏幕或行式打印机,而 `troff` 产生非常优美的输出,通常用于在激光打印机上打印。 - -这就是我的方法,因为我需要为我的课程写论文,但我更喜欢呆在 Linux 中。我从我们的 “大 Unix ” 校园计算机实验室得知,Unix 系统提供了一组文本格式化的程序。它们是同一系统的不同接口:生成纯文本的输出,适合于屏幕或行打印机,或者生成非常优美的输出,通常用于在激光打印机上打印。 +这就是我的方法,因为我需要为我的课程写论文,但我更喜欢呆在 Linux 中。我从我们的 “大 Unix” 校园计算机实验室得知,Unix 系统提供了一组文本格式化的程序 `nroff` 和 `troff ` ,它们是同一系统的不同接口:`nroff` 生成纯文本输出,适用于屏幕或行式打印机,而 `troff` 产生非常优美的输出,通常用于在激光打印机上打印。 在 Linux 上,`nroff` 和 `troff` 被合并为 GNU troff,通常被称为 [groff][1]。 我很高兴看到早期的 Linux 发行版中包含了某个版本的 groff,因此我着手学习如何使用它来编写课程论文。 我学到的第一个宏集是 `-me` 宏包,一个简单易学的宏集。 -关于 `groff` ,首先要了解的是它根据一组宏处理和格式化文本。一个宏通常是一个两个字符的命令,它自己设置在一行上,并带有一个引导点。宏可能包含一个或多个选项。当 groff 在处理文档时遇到这些宏中的一个时,它会自动对文本进行格式化。 +关于 `groff` ,首先要了解的是它根据一组宏来处理和格式化文本。宏通常是个两个字符的命令,它自己设置在一行上,并带有一个引导点。宏可能包含一个或多个选项。当 `groff` 在处理文档时遇到这些宏中的一个时,它会自动对文本进行格式化。 下面,我将分享使用 `groff -me` 编写课程论文等简单文档的基础知识。 我不会深入细节进行讨论,比如如何创建嵌套列表,保存和显示,以及使用表格和数字。 ### 段落 -让我们从一个简单的例子开始,在几乎所有类型的文档中都可以看到:段落。段落可以格式化第一行的缩进或不缩进(即,与左边齐平)。 包括学术论文,杂志,期刊和书籍在内的许多印刷文档都使用了这两种类型的组合,其中文档或章节中的第一个(主要)段落与左侧的所有段落以及所有其他(常规)段落缩进。 在 `groff -me`中,您可以使用两种段落类型:前导段落(`.lp`)和常规段落(`.pp`)。 +让我们从一个简单的例子开始,在几乎所有类型的文档中都可以看到:段落。段落可以格式化为首行缩进或不缩进(即,与左边齐平)。 包括学术论文,杂志,期刊和书籍在内的许多印刷文档都使用了这两种类型的组合,其中文档或章节中的第一个(主要)段落左侧对齐,而所有其他(常规)的段落缩进。 在 `groff -me`中,您可以使用两种段落类型:前导段落(`.lp`)和常规段落(`.pp`)。 ``` .lp - This is the first paragraph. - .pp - This is a standard paragraph. - ``` ### 文本格式 -用粗体格式化文本的宏是 `.b`,斜体格式是 `.i` 。 如果您将 `.b` 或 `.i` 放在一行上,则后面的所有文本将以粗体或斜体显示。 但更有可能你只是想用粗体或斜体来表示一个或几个词。 要将一个词加粗或斜体,将该单词放在与 `.b` 或 `.i` 相同的行上作为选项。 要用**粗体**或斜体格式化多个单词,请将文字用引号引起来。 +用粗体格式化文本的宏是 `.b`,斜体格式是 `.i` 。 如果您将 `.b` 或 `.i` 放在一行上,则后面的所有文本将以粗体或斜体显示。 但更有可能你只是想用粗体或斜体来表示一个或几个词。 要将一个词加粗或斜体,将该单词放在与 `.b` 或 `.i` 相同的行上作为选项。 要用粗体或斜体格式化多个单词,请将文字用引号引起来。 ``` .pp - You can do basic formatting such as - .i italics - or - .b "bold text." - ``` -在上面的例子中,粗体文本结尾的句点也是粗体。 在大多数情况下,这不是你想要的。 只要文字是粗体字,而不是后面的句点也是粗体字。 要获得您想要的效果,您可以向 `.b` 或 `.i` 添加第二个参数,以指示要以粗体或斜体显示的文本,但是正常类型的文本。 您可以这样做,以确保尾随句点不会以粗体显示。 +在上面的例子中,粗体文本结尾的句点也是粗体。 在大多数情况下,这不是你想要的。 只要文字是粗体字,而不是后面的句点也是粗体字。 要获得您想要的效果,您可以向 `.b` 或 `.i` 添加第二个参数,以指示以粗体或斜体显示的文本后面跟着的任意文本以正常类型显示。 您可以这样做,以确保尾随句点不会以粗体显示。 ``` .pp - You can do basic formatting such as - .i italics - or - .b "bold text" . - ``` ### 列表 @@ -67,64 +54,38 @@ or ``` .pp - Bullet lists are easy to make: - .bu - Apple - .bu - Banana - .bu - Pineapple - .pp - Numbered lists are as easy as: - .np - One - .np - Two - .np - Three - .pp - Note that numbered lists will reset at the next pp or lp. - ``` ### 副标题 -如果你正在写一篇长论文,你可能想把你的内容分成几部分。使用 `groff -me`,您可以创建编号的标题 (`.sh`) 和未编号的标题 (`.uh`)。在这两种方法中,将节标题作为参数括起来。对于编号的标题,您还需要提供标题级别 `:1` 将给出一个一级标题(例如,1)。同样,`2` 和 `3` 将给出第二和第三级标题,如 2.1 或 3.1.1。 +如果你正在写一篇长论文,你可能想把你的内容分成几部分。使用 `groff -me`,您可以创建编号的标题(`.sh`) 和未编号的标题 (`.uh`)。在这两种方法中,将节标题作为参数括起来。对于编号的标题,您还需要提供标题级别 `:1` 将给出一个一级标题(例如,`1`)。同样,`2` 和 `3` 将给出第二和第三级标题,如 `2.1` 或 `3.1.1`。 ``` .uh Introduction - .pp - Provide one or two paragraphs to describe the work - and why it is important. - .sh 1 "Method and Tools" - .pp - Provide a few paragraphs to describe how you - did the research, including what equipment you used - ``` ### 智能引号和块引号 @@ -133,135 +94,88 @@ did the research, including what equipment you used ``` .pp - Christine Peterson coined the phrase \*(lqopen source.\*(rq - ``` `groff -me` 中还有一个快捷方式来创建这些引号(`.q`),我发现它更易于使用。 ``` .pp - Christine Peterson coined the phrase - .q "open source." - ``` -如果引用的是跨越几行的较长的引用,则需要使用一个块引用。为此,在引用的开头和结尾插入块引用宏( - -`.(q`)。 +如果引用的是跨越几行的较长的引用,则需要使用一个块引用。为此,在引用的开头和结尾插入块引用宏(`.(q`)。 ``` .pp - Christine Peterson recently wrote about open source: - .(q - On April 7, 1998, Tim O'Reilly held a meeting of key - leaders in the field. Announced in advance as the first - .q "Freeware Summit," - by April 14 it was referred to as the first - .q "Open Source Summit." - .)q - ``` ### 脚注 -要插入脚注,请在脚注文本前后添加脚注宏(`.(f`),并使用内联宏(`\ **`)添加脚注标记。脚注标记应出现在文本中和脚注中。 +要插入脚注,请在脚注文本前后添加脚注宏(`.(f`),并使用内联宏(`\**`)添加脚注标记。脚注标记应出现在文本中和脚注中。 ``` .pp - Christine Peterson recently wrote about open source:\** - .(f - \**Christine Peterson. - .q "How I coined the term open source." - .i "OpenSource.com." - 1 Feb 2018. - .)f - .(q - On April 7, 1998, Tim O'Reilly held a meeting of key - leaders in the field. Announced in advance as the first - .q "Freeware Summit," - by April 14 it was referred to as the first - .q "Open Source Summit." - .)q - ``` ### 封面 -大多数课程论文都需要一个包含论文标题,姓名和日期的封面。 在 `groff -me` 中创建封面需要一些组件。 我发现最简单的方法是使用居中的文本块并在标题,名称和日期之间添加额外的行。 (我倾向于在每一行之间使用两个空行)。在文章顶部,从标题页(`.tp`)宏开始,插入五个空白行(`.sp 5`),然后添加居中文本(`.(c`) 和额外的空白行(`.sp 2`)。 +大多数课程论文都需要一个包含论文标题,姓名和日期的封面。 在 `groff -me` 中创建封面需要一些组件。 我发现最简单的方法是使用居中的文本块并在标题、名字和日期之间添加额外的行。 (我倾向于在每一行之间使用两个空行)。在文章顶部,从标题页(`.tp`)宏开始,插入五个空白行(`.sp 5`),然后添加居中文本(`.(c`) 和额外的空白行(`.sp 2`)。 ``` .tp - .sp 5 - .(c - .b "Writing Class Papers with groff -me" - .)c - .sp 2 - .(c - Jim Hall - .)c - .sp 2 - .(c - February XX, 2018 - .)c - .bp - ``` 最后一个宏(`.bp`)告诉 groff 在标题页后添加一个分页符。 ### 更多内容 -这些是用 `groff-me` 写一份专业的论文非常基础的东西,包括前导和缩进段落,粗体和斜体,有序和无需列表,编号和不编号的章节标题,块引用以及脚注。 +这些是用 `groff-me` 写一份专业的论文非常基础的东西,包括前导和缩进段落,粗体和斜体,有序和无需列表,编号和不编号的章节标题,块引用以及脚注。 -我已经包含一个示例 groff 文件来演示所有这些格式。 将 `lorem-ipsum.me` 文件保存到您的系统并通过 groff 运行。 `-Tps` 选项将输出类型设置为 `PostScript` ,以便您可以将文档发送到打印机或使用 `ps2pdf` 程序将其转换为 PDF 文件。 +我已经包含一个[示例 groff 文件](https://opensource.com/sites/default/files/lorem-ipsum.me_.txt)来演示所有这些格式。 将 `lorem-ipsum.me` 文件保存到您的系统并通过 groff 运行。 `-Tps` 选项将输出类型设置为 `PostScript` ,以便您可以将文档发送到打印机或使用 `ps2pdf` 程序将其转换为 [PDF 文件](https://opensource.com/sites/default/files/lorem-ipsum.me_.pdf)。 ``` groff -Tps -me lorem-ipsum.me > lorem-ipsum.me.ps - ps2pdf lorem-ipsum.me.ps lorem-ipsum.me.pdf - ``` -如果你想使用 groff-me 的更多高级功能,请参阅 Eric Allman 所著的 “使用 `Groff-me` 来写论文”,你可以在你系统的 groff 的 `doc` 目录下找到一个名叫 `meintro.me` 的文件。这份文档非常完美的说明了如何使用 `groff-me` 宏来格式化你的论文。 +如果你想使用 `groff -me` 的更多高级功能,请参阅 Eric Allman 所著的 “使用 Groff -me 来写论文”,你可以在你系统的 groff 的 `doc` 目录下找到一个名叫 `meintro.me` 的文件。这份文档非常完美的说明了如何使用 `groff-me` 宏来格式化你的论文。 -------------------------------------------------------------------------------- @@ -269,7 +183,7 @@ via: https://opensource.com/article/18/2/how-format-academic-papers-linux-groff- 作者:[Jim Hall][a] 译者:[amwps290](https://github.com/amwps290) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180222 Linux LAN Routing for Beginners- Part 1.md b/published/20180222 Linux LAN Routing for Beginners- Part 1.md similarity index 54% rename from translated/tech/20180222 Linux LAN Routing for Beginners- Part 1.md rename to published/20180222 Linux LAN Routing for Beginners- Part 1.md index a53252ad6f..00409d9a83 100644 --- a/translated/tech/20180222 Linux LAN Routing for Beginners- Part 1.md +++ b/published/20180222 Linux LAN Routing for Beginners- Part 1.md @@ -2,13 +2,14 @@ Linux 局域网路由新手指南:第 1 部分 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/traffic_warder.jpeg?itok=hZxS_PB4) + 前面我们学习了 [IPv6 路由][1]。现在我们继续深入学习 Linux 中的 IPv4 路由的基础知识。我们从硬件概述、操作系统和 IPv4 地址的基础知识开始,下周我们将继续学习它们如何配置,以及测试路由。 ### 局域网路由器硬件 -Linux 实际上是一个网络操作系统,一直都是,从一开始它就有内置的网络功能。为将你的局域网连入因特网,构建一个局域网路由器比起构建网关路由器要简单的多。你不要太过于执念安全或者防火墙规则,对于处理 NAT 它还是比较复杂的,网络地址转换是 IPv4 的一个痛点。我们为什么不放弃 IPv4 去转到 IPv6 呢?这样将使网络管理员的工作更加简单。 +Linux 实际上是一个网络操作系统,一直都是,从一开始它就有内置的网络功能。要将你的局域网连入因特网,构建一个局域网路由器比起构建网关路由器要简单的多。你不要太过于执念安全或者防火墙规则,对于处理网络地址转换(NAT)它还是比较复杂的,NAT是 IPv4 的一个痛点。我们为什么不放弃 IPv4 去转到 IPv6 呢?这样将使网络管理员的工作更加简单。 -有点跑题了。从理论上讲,你的 Linux 路由器是一个至少有两个网络接口的小型机器。Linux Gizmos 是一个单片机的综合体:[98 个开放规格的目录,黑客友好的 SBCs][2]。你能够使用一个很老的笔记本电脑或者台式计算机。你也可以使用一个精简版计算机,像 ZaReason Zini 或者 System76 Meerkat 一样,虽然这些有点贵,差不多要 $600。但是它们又结实又可靠,并且你不用在 Windows 许可证上浪费钱。 +有点跑题了。从理论上讲,你的 Linux 路由器是一个至少有两个网络接口的小型机器。Linux Gizmos 有一个很大的单板机名单:[98 个开放规格、适于黑客的 SBC 的目录][2]。你能够使用一个很老的笔记本电脑或者台式计算机。你也可以使用一个紧凑型计算机,像 ZaReason Zini 或者 System76 Meerkat 一样,虽然这些有点贵,差不多要 $600。但是它们又结实又可靠,并且你不用在 Windows 许可证上浪费钱。 如果对路由器的要求不高,使用树莓派 3 Model B 作为路由器是一个非常好的选择。它有一个 10/100 以太网端口,板载 2.4GHz 的 802.11n 无线网卡,并且它还有四个 USB 端口,因此你可以插入多个 USB 网卡。USB 2.0 和低速板载网卡可能会让树莓派变成你的网络上的瓶颈,但是,你不能对它期望太高(毕竟它只有 $35,既没有存储也没有电源)。它支持很多种风格的 Linux,因此你可以选择使用你喜欢的版本。基于 Debian 的树莓派是我的最爱。 @@ -16,63 +17,63 @@ Linux 实际上是一个网络操作系统,一直都是,从一开始它就 你可以在你选择的硬件上安装将你喜欢的 Linux 的简化版,因为定制的路由器操作系统,比如 OpenWRT、 Tomato、DD-WRT、Smoothwall、Pfsense 等等,都有它们自己的非标准界面。我的观点是,没有必要这么麻烦,它们对你并没有什么帮助。尽量使用标准的 Linux 工具,因为你只需要学习它们一次就够了。 -Debian 的网络安装镜像大约有 300MB 大小,并且支持多种架构,包括 ARM、i386、amd64、和 armhf。Ubuntu 的服务器网络安装镜像也小于 50MB,这样你就可以控制你要安装哪些包。Fedora、Mageia、和 openSUSE 都提供精简的网络安装镜像。如果你需要创意,你可以浏览 [Distrowatch][3]。 +Debian 的网络安装镜像大约有 300MB 大小,并且支持多种架构,包括 ARM、i386、amd64 和 armhf。Ubuntu 的服务器网络安装镜像也小于 50MB,这样你就可以控制你要安装哪些包。Fedora、Mageia、和 openSUSE 都提供精简的网络安装镜像。如果你需要创意,你可以浏览 [Distrowatch][3]。 ### 路由器能做什么 -我们需要网络路由器做什么?一个路由器连接不同的网络。如果没有路由,那么每个网络都是相互隔离的,所有的悲伤和孤独都没有人与你分享,所有节点只能孤独终老。假设你有一个 192.168.1.0/24 和一个 192.168.2.0/24 网络。如果没有路由器,你的两个网络之间不能相互沟通。这些都是 C 类的私有地址,它们每个都有 254 个可用网络地址。使用 ipcalc 可以非常容易地得到它们的这些信息: +我们需要网络路由器做什么?一个路由器连接不同的网络。如果没有路由,那么每个网络都是相互隔离的,所有的悲伤和孤独都没有人与你分享,所有节点只能孤独终老。假设你有一个 192.168.1.0/24 和一个 192.168.2.0/24 网络。如果没有路由器,你的两个网络之间不能相互沟通。这些都是 C 类的私有地址,它们每个都有 254 个可用网络地址。使用 `ipcalc` 可以非常容易地得到它们的这些信息: + ``` $ ipcalc 192.168.1.0/24 -Address: 192.168.1.0 11000000.10101000.00000001. 00000000 -Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 -Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111 +Address: 192.168.1.0 11000000.10101000.00000001. 00000000 +Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 +Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111 => -Network: 192.168.1.0/24 11000000.10101000.00000001. 00000000 -HostMin: 192.168.1.1 11000000.10101000.00000001. 00000001 -HostMax: 192.168.1.254 11000000.10101000.00000001. 11111110 -Broadcast: 192.168.1.255 11000000.10101000.00000001. 11111111 -Hosts/Net: 254 Class C, Private Internet - +Network: 192.168.1.0/24 11000000.10101000.00000001. 00000000 +HostMin: 192.168.1.1 11000000.10101000.00000001. 00000001 +HostMax: 192.168.1.254 11000000.10101000.00000001. 11111110 +Broadcast: 192.168.1.255 11000000.10101000.00000001. 11111111 +Hosts/Net: 254 Class C, Private Internet ``` -我喜欢 ipcalc 的二进制输出信息,它更加可视地表示了掩码是如何工作的。前三个八位组表示了网络地址,第四个八位组是主机地址,因此,当你分配主机地址时,你将 “掩盖” 掉网络地址部分,只使用剩余的主机部分。你的两个网络有不同的网络地址,而这就是如果两个网络之间没有路由器它们就不能互相通讯的原因。 +我喜欢 `ipcalc` 的二进制输出信息,它更加可视地表示了掩码是如何工作的。前三个八位组表示了网络地址,第四个八位组是主机地址,因此,当你分配主机地址时,你将 “掩盖” 掉网络地址部分,只使用剩余的主机部分。你的两个网络有不同的网络地址,而这就是如果两个网络之间没有路由器它们就不能互相通讯的原因。 -每个八位组一共有 256 字节,但是它们并不能提供 256 个主机地址,因为第一个和最后一个值 ,也就是 0 和 255,是被保留的。0 是网络标识,而 255 是广播地址,因此,只有 254 个主机地址。ipcalc 可以帮助你很容易地计算出这些。 +每个八位组一共有 256 字节,但是它们并不能提供 256 个主机地址,因为第一个和最后一个值 ,也就是 0 和 255,是被保留的。0 是网络标识,而 255 是广播地址,因此,只有 254 个主机地址。`ipcalc` 可以帮助你很容易地计算出这些。 当然,这并不意味着你不能有一个结尾是 0 或者 255 的主机地址。假设你有一个 16 位的前缀: + ``` $ ipcalc 192.168.0.0/16 -Address: 192.168.0.0 11000000.10101000. 00000000.00000000 -Netmask: 255.255.0.0 = 16 11111111.11111111. 00000000.00000000 -Wildcard: 0.0.255.255 00000000.00000000. 11111111.11111111 +Address: 192.168.0.0 11000000.10101000. 00000000.00000000 +Netmask: 255.255.0.0 = 16 11111111.11111111. 00000000.00000000 +Wildcard: 0.0.255.255 00000000.00000000. 11111111.11111111 => -Network: 192.168.0.0/16 11000000.10101000. 00000000.00000000 -HostMin: 192.168.0.1 11000000.10101000. 00000000.00000001 -HostMax: 192.168.255.254 11000000.10101000. 11111111.11111110 -Broadcast: 192.168.255.255 11000000.10101000. 11111111.11111111 -Hosts/Net: 65534 Class C, Private Internet - +Network: 192.168.0.0/16 11000000.10101000. 00000000.00000000 +HostMin: 192.168.0.1 11000000.10101000. 00000000.00000001 +HostMax: 192.168.255.254 11000000.10101000. 11111111.11111110 +Broadcast: 192.168.255.255 11000000.10101000. 11111111.11111111 +Hosts/Net: 65534 Class C, Private Internet ``` -ipcalc 列出了你的第一个和最后一个主机地址,它们是 192.168.0.1 和 192.168.255.254。你是可以有以 0 或者 255 结尾的主机地址的,例如,192.168.1.0 和 192.168.0.255,因为它们都在最小主机地址和最大主机地址之间。 +`ipcalc` 列出了你的第一个和最后一个主机地址,它们是 192.168.0.1 和 192.168.255.254。你是可以有以 0 或者 255 结尾的主机地址的,例如,192.168.1.0 和 192.168.0.255,因为它们都在最小主机地址和最大主机地址之间。 -不论你的地址块是私有的还是公共的,这个原则同样都是适用的。不要羞于使用 ipcalc 来帮你计算地址。 +不论你的地址块是私有的还是公共的,这个原则同样都是适用的。不要羞于使用 `ipcalc` 来帮你计算地址。 ### CIDR -CIDR(无类域间路由)就是通过可变长度的子网掩码来扩展 IPv4 的。CIDR 允许对网络空间进行更精细地分割。我们使用 ipcalc 来演示一下: +CIDR(无类域间路由)就是通过可变长度的子网掩码来扩展 IPv4 的。CIDR 允许对网络空间进行更精细地分割。我们使用 `ipcalc` 来演示一下: + ``` $ ipcalc 192.168.1.0/22 -Address: 192.168.1.0 11000000.10101000.000000 01.00000000 -Netmask: 255.255.252.0 = 22 11111111.11111111.111111 00.00000000 -Wildcard: 0.0.3.255 00000000.00000000.000000 11.11111111 +Address: 192.168.1.0 11000000.10101000.000000 01.00000000 +Netmask: 255.255.252.0 = 22 11111111.11111111.111111 00.00000000 +Wildcard: 0.0.3.255 00000000.00000000.000000 11.11111111 => -Network: 192.168.0.0/22 11000000.10101000.000000 00.00000000 -HostMin: 192.168.0.1 11000000.10101000.000000 00.00000001 -HostMax: 192.168.3.254 11000000.10101000.000000 11.11111110 -Broadcast: 192.168.3.255 11000000.10101000.000000 11.11111111 -Hosts/Net: 1022 Class C, Private Internet - +Network: 192.168.0.0/22 11000000.10101000.000000 00.00000000 +HostMin: 192.168.0.1 11000000.10101000.000000 00.00000001 +HostMax: 192.168.3.254 11000000.10101000.000000 11.11111110 +Broadcast: 192.168.3.255 11000000.10101000.000000 11.11111111 +Hosts/Net: 1022 Class C, Private Internet ``` 网络掩码并不局限于整个八位组,它可以跨越第三和第四个八位组,并且子网部分的范围可以是从 0 到 3,而不是非得从 0 到 255。可用主机地址的数量并不一定是 8 的倍数,因为它是由整个八位组定义的。 @@ -81,7 +82,7 @@ Hosts/Net: 1022 Class C, Private Internet 从 [理解 IP 地址和 CIDR 图表][4]、[IPv4 私有地址空间和过滤][5]、以及 [IANA IPv4 地址空间注册][6] 开始。接下来的我们将学习如何创建和管理路由器。 -通过来自 Linux 基金会和 edX 的免费课程 ["Linux 入门" ][7]学习更多 Linux 知识。 +通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”][7]学习更多 Linux 知识。 -------------------------------------------------------------------------------- @@ -89,7 +90,7 @@ via: https://www.linux.com/learn/intro-to-linux/2018/2/linux-lan-routing-beginne 作者:[Carla Schroder][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180227 How to block local spoofed addresses using the Linux firewall.md b/published/20180227 How to block local spoofed addresses using the Linux firewall.md new file mode 100644 index 0000000000..be0e5f85ec --- /dev/null +++ b/published/20180227 How to block local spoofed addresses using the Linux firewall.md @@ -0,0 +1,69 @@ +如何使用 Linux 防火墙隔离本地欺骗地址 +====== + +> 如何使用 iptables 防火墙保护你的网络免遭黑客攻击。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_UnspokenBlockers_1110_A.png?itok=x8A9mqVA) + +即便是被入侵检测和隔离系统所保护的远程网络,黑客们也在寻找各种精巧的方法入侵。IDS/IPS 不能停止或者减少那些想要接管你的网络控制权的黑客攻击。不恰当的配置允许攻击者绕过所有部署的安全措施。 + +在这篇文章中,我将会解释安全工程师或者系统管理员该怎样避免这些攻击。 + +几乎所有的 Linux 发行版都带着一个内建的防火墙来保护运行在 Linux 主机上的进程和应用程序。大多数防火墙都按照 IDS/IPS 解决方案设计,这样的设计的主要目的是检测和避免恶意包获取网络的进入权。 + +Linux 防火墙通常有两种接口:iptables 和 ipchains 程序(LCTT 译注:在支持 systemd 的系统上,采用的是更新的接口 firewalld)。大多数人将这些接口称作 iptables 防火墙或者 ipchains 防火墙。这两个接口都被设计成包过滤器。iptables 是有状态防火墙,其基于先前的包做出决定。ipchains 不会基于先前的包做出决定,它被设计为无状态防火墙。 + +在这篇文章中,我们将会专注于内核 2.4 之后出现的 iptables 防火墙。 + +有了 iptables 防火墙,你可以创建策略或者有序的规则集,规则集可以告诉内核该如何对待特定的数据包。在内核中的是Netfilter 框架。Netfilter 既是框架也是 iptables 防火墙的项目名称。作为一个框架,Netfilter 允许 iptables 勾连被设计来操作数据包的功能。概括地说,iptables 依靠 Netfilter 框架构筑诸如过滤数据包数据的功能。 + +每个 iptables 规则都被应用到一个表中的链上。一个 iptables 链就是一个比较包中相似特征的规则集合。而表(例如 `nat` 或者 `mangle`)则描述不同的功能目录。例如, `mangle` 表用于修改包数据。因此,特定的修改包数据的规则被应用到这里;而过滤规则被应用到 `filter` 表,因为 `filter` 表过滤包数据。 + +iptables 规则有一个匹配集,以及一个诸如 `Drop` 或者 `Deny` 的目标,这可以告诉 iptables 对一个包做什么以符合规则。因此,没有目标和匹配集,iptables 就不能有效地处理包。如果一个包匹配了一条规则,目标会指向一个将要采取的特定措施。另一方面,为了让 iptables 处理,每个数据包必须匹配才能被处理。 + +现在我们已经知道 iptables 防火墙如何工作,让我们着眼于如何使用 iptables 防火墙检测并拒绝或丢弃欺骗地址吧。 + +### 打开源地址验证 + +作为一个安全工程师,在处理远程的欺骗地址的时候,我采取的第一步是在内核打开源地址验证。 + +源地址验证是一种内核层级的特性,这种特性丢弃那些伪装成来自你的网络的包。这种特性使用反向路径过滤器方法来检查收到的包的源地址是否可以通过包到达的接口可以到达。(LCTT 译注:到达的包的源地址应该可以从它到达的网络接口反向到达,只需反转源地址和目的地址就可以达到这样的效果) + +利用下面简单的脚本可以打开源地址验证而不用手工操作: + +``` +#!/bin/sh +#作者: Michael K Aboagye +#程序目标: 打开反向路径过滤 +#日期: 7/02/18 +#在屏幕上显示 “enabling source address verification” +echo -n "Enabling source address verification…" +#将值0覆盖为1来打开源地址验证 +echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter +echo "completed" +``` + +上面的脚本在执行的时候只显示了 `Enabling source address verification` 这条信息而不会换行。默认的反向路径过滤的值是 `0`,`0` 表示没有源验证。因此,第二行简单地将默认值 `0` 覆盖为 `1`。`1` 表示内核将会通过确认反向路径来验证源地址。 + +最后,你可以使用下面的命令通过选择 `DROP` 或者 `REJECT` 目标之一来丢弃或者拒绝来自远端主机的欺骗地址。但是,处于安全原因的考虑,我建议使用 `DROP` 目标。 + +像下面这样,用你自己的 IP 地址代替 `IP-address` 占位符。另外,你必须选择使用 `REJECT` 或者 `DROP` 中的一个,这两个目标不能同时使用。 + +``` +iptables -A INPUT -i internal_interface -s IP_address -j REJECT / DROP +iptables -A INPUT -i internal_interface -s 192.168.0.0/16 -j REJECT / DROP +``` + +这篇文章只提供了如何使用 iptables 防火墙来避免远端欺骗攻击的基础知识。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/block-local-spoofed-addresses-using-linux-firewall + +作者:[Michael Kwaku Aboagye][a] +译者:[leemeans](https://github.com/leemeans) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/revoks diff --git a/translated/tech/20180228 Protecting Code Integrity with PGP - Part 3- Generating PGP Subkeys.md b/published/20180228 Protecting Code Integrity with PGP - Part 3- Generating PGP Subkeys.md similarity index 60% rename from translated/tech/20180228 Protecting Code Integrity with PGP - Part 3- Generating PGP Subkeys.md rename to published/20180228 Protecting Code Integrity with PGP - Part 3- Generating PGP Subkeys.md index cd9c2c237d..35086cd037 100644 --- a/translated/tech/20180228 Protecting Code Integrity with PGP - Part 3- Generating PGP Subkeys.md +++ b/published/20180228 Protecting Code Integrity with PGP - Part 3- Generating PGP Subkeys.md @@ -1,43 +1,43 @@ -使用 PGP 保护代码完整性 - 第 3 部分:生成 PGP 子密钥 +使用 PGP 保护代码完整性(三):生成 PGP 子密钥 ====== + +> 在第三篇文章中,我们将解释如何生成用于日常工作的 PGP 子密钥。 + ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/binary.jpg?itok=h62HujOC) -在本系列教程中,我们提供了使用 PGP 的实用指南。在此之前,我们介绍了[基本工具和概念][1],并介绍了如何[生成并保护您的主 PGP 密钥][2]。在第三篇文章中,我们将解释如何生成 PGP 子密钥,以及它们在日常工作中使用。 +在本系列教程中,我们提供了使用 PGP 的实用指南。在此之前,我们介绍了[基本工具和概念][1],并介绍了如何[生成并保护您的主 PGP 密钥][2]。在第三篇文章中,我们将解释如何生成用于日常工作的 PGP 子密钥。 ### 清单 1. 生成 2048 位加密子密钥(必要) -   2. 生成 2048 位签名子密钥(必要) - -  3. 生成一个 2048 位验证子密钥(可选) - +  3. 生成一个 2048 位验证子密钥(推荐)   4. 将你的公钥上传到 PGP 密钥服务器(必要) -   5. 设置一个刷新的定时任务(必要) +### 注意事项 +现在我们已经创建了主密钥,让我们创建用于日常工作的密钥。我们创建 2048 位的密钥是因为很多专用硬件(我们稍后会讨论这个)不能处理更长的密钥,但同样也是出于实用的原因。如果我们发现自己处于一个 2048 位 RSA 密钥也不够好的世界,那将是由于计算或数学有了基本突破,因此更长的 4096 位密钥不会产生太大的差别。 -#### 注意事项 - -现在我们已经创建了主密钥,让我们创建用于日常工作的密钥。我们创建了 2048 位密钥,因为很多专用硬件(我们稍后会讨论这个)不能处理更长的密钥,但同样也是出于实用的原因。如果我们发现自己处于一个 2048 位 RSA 密钥也不够好的世界,那将是由于计算或数学的基本突破,因此更长的 4096 位密钥不会产生太大的差别。 - -##### 创建子密钥 +### 创建子密钥 要创建子密钥,请运行: + ``` $ gpg --quick-add-key [fpr] rsa2048 encr $ gpg --quick-add-key [fpr] rsa2048 sign - ``` -你也可以创建验证密钥,这能让你使用你的 PGP 密钥来使用 ssh: +用你密钥的完整指纹替换 `[fpr]`。 + +你也可以创建验证密钥,这能让你将你的 PGP 密钥用于 ssh: + ``` $ gpg --quick-add-key [fpr] rsa2048 auth - ``` -你可以使用 gpg --list-key [fpr] 来查看你的密钥信息: +你可以使用 `gpg --list-key [fpr]` 来查看你的密钥信息: + ``` pub rsa4096 2017-12-06 [C] [expires: 2019-12-06] 111122223333444455556666AAAABBBBCCCCDDDD @@ -45,55 +45,57 @@ uid [ultimate] Alice Engineer uid [ultimate] Alice Engineer sub rsa2048 2017-12-06 [E] sub rsa2048 2017-12-06 [S] - ``` -##### 上传你的公钥到密钥服务器 +### 上传你的公钥到密钥服务器 你的密钥创建已完成,因此现在需要你将其上传到一个公共密钥服务器,使其他人能更容易找到密钥。 (如果你不打算实际使用你创建的密钥,请跳过这一步,因为这只会在密钥服务器上留下垃圾数据。) + ``` $ gpg --send-key [fpr] - ``` 如果此命令不成功,你可以尝试指定一台密钥服务器以及端口,这很有可能成功: + ``` $ gpg --keyserver hkp://pgp.mit.edu:80 --send-key [fpr] - ``` 大多数密钥服务器彼此进行通信,因此你的密钥信息最终将与所有其他密钥信息同步。 -**关于隐私的注意事项:**密钥服务器是完全公开的,因此在设计上会泄露有关你的潜在敏感信息,例如你的全名、昵称以及个人或工作邮箱地址。如果你签名了其他人的钥匙或某人签名你的钥匙,那么密钥服务器还会成为你的社交网络的泄密者。一旦这些个人信息发送给密钥服务器,就不可能编辑或删除。即使你撤销签名或身份,它也不会将你的密钥记录删除,它只会将其标记为已撤消 - 这甚至会显得更突出。 +**关于隐私的注意事项:**密钥服务器是完全公开的,因此在设计上会泄露有关你的潜在敏感信息,例如你的全名、昵称以及个人或工作邮箱地址。如果你签名了其他人的钥匙或某人签名了你的钥匙,那么密钥服务器还会成为你的社交网络的泄密者。一旦这些个人信息发送给密钥服务器,就不可能被编辑或删除。即使你撤销签名或身份,它也不会将你的密钥记录删除,它只会将其标记为已撤消 —— 这甚至会显得更显眼。 也就是说,如果你参与公共项目的软件开发,以上所有信息都是公开记录,因此通过密钥服务器另外让这些信息可见,不会导致隐私的净损失。 -###### 上传你的公钥到 GitHub +### 上传你的公钥到 GitHub 如果你在开发中使用 GitHub(谁不是呢?),则应按照他们提供的说明上传密钥: +- [添加 PGP 密钥到你的 GitHub 账户](https://help.github.com/articles/adding-a-new-gpg-key-to-your-github-account/) + 要生成适合粘贴的公钥输出,只需运行: + ``` $ gpg --export --armor [fpr] - ``` -##### 设置一个刷新定时任务 +### 设置一个刷新定时任务 + +你需要定期刷新你的钥匙环,以获取其他人公钥的最新更改。你可以设置一个定时任务来做到这一点: -你需要定期刷新你的 keyring,以获取其他人公钥的最新更改。你可以设置一个定时任务来做到这一点: ``` $ crontab -e - ``` 在新行中添加以下内容: + ``` @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1 - ``` -**注意:**检查你的 gpg 或 gpg2 命令的完整路径,如果你的 gpg 是旧式的 GnuPG v.1,请使用 gpg2。 +**注意:**检查你的 `gpg` 或 `gpg2` 命令的完整路径,如果你的 `gpg` 是旧式的 GnuPG v.1,请使用 gpg2。 +通过 Linux 基金会和 edX 的免费“[Introduction to Linux](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux)” 课程了解关于 Linux 的更多信息。 -------------------------------------------------------------------------------- @@ -101,10 +103,10 @@ via: https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-p 作者:[Konstantin Ryabitsev][a] 译者:[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/) 荣誉推出 [a]:https://www.linux.com/users/mricon -[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools -[2]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key +[1]:https://linux.cn/article-9524-1.html +[2]:https://linux.cn/article-9529-1.html \ No newline at end of file diff --git a/published/20090203 How the Kernel Manages Your Memory.md b/published/201803/20090203 How the Kernel Manages Your Memory.md similarity index 100% rename from published/20090203 How the Kernel Manages Your Memory.md rename to published/201803/20090203 How the Kernel Manages Your Memory.md diff --git a/published/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md b/published/201803/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md similarity index 100% rename from published/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md rename to published/201803/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md diff --git a/published/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md b/published/201803/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md similarity index 100% rename from published/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md rename to published/201803/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md diff --git a/published/201803/20120424 How To Set Readonly File Permissions On Linux - Unix Web Server DocumentRoot.md b/published/201803/20120424 How To Set Readonly File Permissions On Linux - Unix Web Server DocumentRoot.md new file mode 100644 index 0000000000..2aad1679ba --- /dev/null +++ b/published/201803/20120424 How To Set Readonly File Permissions On Linux - Unix Web Server DocumentRoot.md @@ -0,0 +1,178 @@ +如何在 Web 服务器文档根目录上设置只读文件权限 +====== + +**Q:如何对我存放在 `/var/www/html/` 目录中的所有文件设置只读权限?** + +你可以使用 `chmod` 命令对 Linux/Unix/macOS/OS X/*BSD 操作系统上的所有文件来设置只读权限。这篇文章介绍如何在 Linux/Unix 的 web 服务器(如 Nginx、 Lighttpd、 Apache 等)上来设置只读文件权限。 + +[![Proper read-only permissions for Linux/Unix Nginx/Apache web server's directory][1]][1] + +### 如何设置文件为只读模式 + +语法为: + +``` +### 仅针对文件 ### +chmod 0444 /var/www/html/* +chmod 0444 /var/www/html/*.php +``` + +### 如何设置目录为只读模式 + +语法为: + +``` +### 仅针对目录 ### +chmod 0444 /var/www/html/ +chmod 0444 /path/to/your/dir/ +# *************************************************************************** +# 假如 web 服务器的用户/用户组是 www-data,文件拥有者是 ftp-data 用户/用户组 +# *************************************************************************** +# 设置目录所有文件为只读 +chmod -R 0444 /var/www/html/ +# 设置文件/目录拥有者为 ftp-data +chown -R ftp-data:ftp-data /var/www/html/ +# 所有目录和子目录的权限为 0445 (这样 web 服务器的用户或用户组就可以读取我们的文件) +find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 "{}" +``` + +找到所有 `/var/www/html` 下的所有文件(包括子目录),键入: + +``` +### 仅对文件有效 ### +find /var/www/html -type f -iname "*" -print0 | xargs -I {} -0 chmod 0444 {} +``` + +然而,你需要在 `/var/www/html` 目录及其子目录上设置只读和执行权限,如此才能让 web 服务器能够访问根目录,键入: + +``` +### 仅对目录有效 ### +find /var/www/html -type d -iname "*" -print0 | xargs -I {} -0 chmod 0544 {} +``` + +### 警惕写权限 + +请注意在 `/var/www/html/` 目录上的写权限会允许任何人删除文件或添加新文件。也就是说,你可能需要设置一个只读权限给 `/var/www/html/` 目录本身。 + +``` +### web根目录只读 ### +chmod 0555 /var/www/html +``` + +在某些情况下,根据你的设置要求,你可以改变文件的属主和属组来设置严格的权限。 + +``` +### 如果 /var/www/html 目录的拥有人是普通用户,你可以设置拥有人为:root:root 或 httpd:httpd (推荐) ### +chown -R root:root /var/www/html/ + +### 确保 apache 拥有 /var/www/html/ ### +chown -R apache:apache /var/www/html/ +``` + +### 关于 NFS 导出目录 + +你可以在 `/etc/exports` 文件中指定哪个目录应该拥有[只读或者读写权限 ][2]。这个文件定义各种各样的共享在 NFS 服务器和他们的权限。如: + + +``` +# 对任何人只读权限 +/var/www/html *(ro,sync) + +# 对192.168.1.10(upload.example.com)客户端读写权限访问 +/var/www/html 192.168.1.10(rw,sync) +``` + +### 关于用于 MS-Windows客户端的 Samba(CIFS)只读共享 + + +要以只读共享 `sales`,更新 `smb.conf`,如下: + +``` +[sales] +comment = Sales Data +path = /export/cifs/sales +read only = Yes +guest ok = Yes +``` + +### 关于文件系统表(fstab) + +你可以在 Unix/Linux 上的 `/etc/fstab` 文件中配置挂载某些文件为只读模式。 + +你需要有专用分区,不要设置其他系统分区为只读模式。 + +如下在 `/etc/fstab` 文件中设置 `/srv/html` 为只读模式。 + +``` +/dev/sda6 /srv/html ext4 ro 1 1 +``` + +你可以使用 `mount` 命令[重新挂载分区为只读模式][3](使用 root 用户) + +``` +# mount -o remount,ro /dev/sda6 /srv/html +``` + +或者 + +``` +# mount -o remount,ro /srv/html +``` + +上面的命令会尝试重新挂载已挂载的文件系统到 `/srv/html`上。这是改变文件系统挂载标志的常用方法,特别是让只读文件改为可写的。这种方式不会改变设备或者挂载点。让文件变得再次可写,键入: + +``` +# mount -o remount,rw /dev/sda6 /srv/html +``` + +或 + +``` +# mount -o remount,rw /srv/html +``` + +### Linux:chattr 命令 + + +你可以在 Linux 文件系统上使用 `chattr` 命令[改变文件属性为只读][4],如: + +``` +chattr +i /path/to/file.php +chattr +i /var/www/html/ + +# 查找任何在/var/www/html下的文件并设置为只读# +find /var/www/html -iname "*" -print0 | xargs -I {} -0 chattr +i {} +``` + +通过提供 `-i` 选项可删除只读属性: + +``` +chattr -i /path/to/file.php +``` + +FreeBSD、Mac OS X 和其他 BSD Unix 用户可使用[`chflags`命令][5]: + +``` +### 设置只读 ## +chflags schg /path/to/file.php + +### 删除只读 ## +chflags noschg /path/to/file.php +``` + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/howto-set-readonly-file-permission-in-linux-unix/ + +作者:[Vivek Gite][a] +译者:[yizhuoyan](https://github.com/yizhuoyan) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/media/new/faq/2012/04/linux-unix-set-read-only-file-system-permission-for-apache-nginx.jpg +[2]:https://www.cyberciti.biz//www.cyberciti.biz/faq/centos-fedora-rhel-nfs-v4-configuration/ +[3]:https://www.cyberciti.biz/faq/howto-freebsd-remount-partition/ +[4]:https://www.cyberciti.biz/tips/linux-password-trick.html +[5]:https://www.cyberciti.biz/tips/howto-write-protect-file-with-immutable-bit.html diff --git a/published/201803/20140225 How To Safely Generate A Random Number - Quarrelsome.md b/published/201803/20140225 How To Safely Generate A Random Number - Quarrelsome.md new file mode 100644 index 0000000000..000b50f159 --- /dev/null +++ b/published/201803/20140225 How To Safely Generate A Random Number - Quarrelsome.md @@ -0,0 +1,92 @@ +如何安全地生成随机数 +====== + +### 使用 urandom + +使用 [urandom][1]!使用 [urandom][2]!使用 [urandom][3]! + +使用 [urandom][4]!使用 [urandom][5]!使用 [urandom][6]! + +### 但对于密码学密钥呢? + +仍然使用 [urandom][6]。 + +### 为什么不是 SecureRandom、OpenSSL、havaged 或者 c 语言实现呢? + +这些是用户空间的 CSPRNG(伪随机数生成器)。你应该用内核的 CSPRNG,因为: + +* 内核可以访问原始设备熵。 +* 它可以确保不在应用程序之间共享相同的状态。 +* 一个好的内核 CSPRNG,像 FreeBSD 中的,也可以保证它播种之前不给你随机数据。 + +研究过去十年中的随机失败案例,你会看到一连串的用户空间的随机失败案例。[Debian 的 OpenSSH 崩溃][7]?用户空间随机!安卓的比特币钱包[重复 ECDSA 随机 k 值][8]?用户空间随机!可预测洗牌的赌博网站?用户空间随机! + +用户空间的生成器几乎总是依赖于内核的生成器。即使它们不这样做,整个系统的安全性也会确保如此。**但用户空间的 CSPRNG 不会增加防御深度;相反,它会产生两个单点故障。** + +### 手册页不是说使用 /dev/random 嘛? + +这个稍后详述,保留你的意见。你应该忽略掉手册页。不要使用 `/dev/random`。`/dev/random` 和 `/dev/urandom` 之间的区别是 Unix 设计缺陷。手册页不想承认这一点,因此它产生了一个并不存在的安全顾虑。把 `random(4)` 中的密码学上的建议当作传说,继续你的生活吧。 + +### 但是如果我需要的是真随机值,而非伪随机值呢? + +urandom 和 `/dev/random` 提供的是同一类型的随机。与流行的观念相反,`/dev/random` 不提供“真正的随机”。从密码学上来说,你通常不需要“真正的随机”。 + +urandom 和 `/dev/random` 都基于一个简单的想法。它们的设计与流密码的设计密切相关:一个小秘密被延伸到不可预测值的不确定流中。 这里的秘密是“熵”,而流是“输出”。 + +只在 Linux 上 `/dev/random` 和 urandom 仍然有意义上的不同。Linux 内核的 CSPRNG 定期进行密钥更新(通过收集更多的熵)。但是 `/dev/random` 也试图跟踪内核池中剩余的熵,并且如果它没有足够的剩余熵时,偶尔也会罢工。这种设计和我所说的一样蠢;这与基于“密钥流”中剩下多少“密钥”的 AES-CTR 设计类似。 + +如果你使用 `/dev/random` 而非 urandom,那么当 Linux 对自己的 RNG(随机数生成器)如何工作感到困惑时,你的程序将不可预测地(或者如果你是攻击者,非常可预测地)挂起。使用 `/dev/random` 会使你的程序不太稳定,但这不会让你在密码学上更安全。 + +### 这是个缺陷,对吗? + +不是,但存在一个你可能想要了解的 Linux 内核 bug,即使这并不能改变你应该使用哪一个 RNG。 + +在 Linux 上,如果你的软件在引导时立即运行,或者这个操作系统你刚刚安装好,那么你的代码可能会与 RNG 发生竞争。这很糟糕,因为如果你赢了竞争,那么你可能会在一段时间内从 urandom 获得可预测的输出。这是 Linux 中的一个 bug,如果你正在为 Linux 嵌入式设备构建平台级代码,那你需要了解它。 + +在 Linux 上,这确实是 urandom(而不是 `/dev/random`)的问题。这也是 [Linux 内核中的错误][9]。 但它也容易在用户空间中修复:在引导时,明确地为 urandom 提供种子。长期以来,大多数 Linux 发行版都是这么做的。但**不要**切换到不同的 CSPRNG。 + +### 在其它操作系统上呢? + +FreeBSD 和 OS X 消除了 urandom 和 `/dev/random` 之间的区别;这两个设备的行为是相同的。不幸的是,手册页在解释为什么这样做上干的很糟糕,并延续了 Linux 上 urandom 可怕的神话。 + +无论你使用 `/dev/random` 还是 urandom,FreeBSD 的内核加密 RNG 都不会停摆。 除非它没有被提供种子,在这种情况下,这两者都会停摆。与 Linux 不同,这种行为是有道理的。Linux 应该采用它。但是,如果你是一名应用程序开发人员,这对你几乎没有什么影响:Linux、FreeBSD、iOS,无论什么:使用 urandom 吧。 + +### 太长了,懒得看 + +直接使用 urandom 吧。 + +### 结语 + +[ruby-trunk Feature #9569][10] + +> 现在,在尝试检测 `/dev/urandom` 之前,SecureRandom.random_bytes 会尝试检测要使用的 OpenSSL。 我认为这应该反过来。在这两种情况下,你只需要将随机字节进行解压,所以 SecureRandom 可以跳过中间人(和第二个故障点),如果可用的话可以直接与 `/dev/urandom` 进行交互。 + +总结: + +> `/dev/urandom` 不适合用来直接生成会话密钥和频繁生成其他应用程序级随机数据。 +> +> GNU/Linux 上的 random(4) 手册所述...... + +感谢 Matthew Green、 Nate Lawson、 Sean Devlin、 Coda Hale 和 Alex Balducci 阅读了本文草稿。公正警告:Matthew 只是大多同意我的观点。 + +-------------------------------------------------------------------------------- + +via: https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ + +作者:[Thomas & Erin Ptacek][a] +译者:[kimii](https://github.com/kimii) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://sockpuppet.org/blog +[1]:http://blog.cr.yp.to/20140205-entropy.html +[2]:http://cr.yp.to/talks/2011.09.28/slides.pdf +[3]:http://golang.org/src/pkg/crypto/rand/rand_unix.go +[4]:http://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key +[5]:http://stackoverflow.com/a/5639631 +[6]:https://twitter.com/bramcohen/status/206146075487240194 +[7]:http://research.swtch.com/openssl +[8]:http://arstechnica.com/security/2013/08/google-confirms-critical-android-crypto-flaw-used-in-5700-bitcoin-heist/ +[9]:https://factorable.net/weakkeys12.extended.pdf +[10]:https://bugs.ruby-lang.org/issues/9569 diff --git a/published/20150615 Let-s Build A Simple Interpreter. Part 1..md b/published/201803/20150615 Let-s Build A Simple Interpreter. Part 1..md similarity index 100% rename from published/20150615 Let-s Build A Simple Interpreter. Part 1..md rename to published/201803/20150615 Let-s Build A Simple Interpreter. Part 1..md diff --git a/published/20150708 Choosing a Linux Tracer (2015).md b/published/201803/20150708 Choosing a Linux Tracer (2015).md similarity index 100% rename from published/20150708 Choosing a Linux Tracer (2015).md rename to published/201803/20150708 Choosing a Linux Tracer (2015).md diff --git a/translated/tech/20160810 How does gdb work.md b/published/201803/20160810 How does gdb work.md similarity index 57% rename from translated/tech/20160810 How does gdb work.md rename to published/201803/20160810 How does gdb work.md index e45b988d3d..58fb60873e 100644 --- a/translated/tech/20160810 How does gdb work.md +++ b/published/201803/20160810 How does gdb work.md @@ -1,9 +1,9 @@ gdb 如何工作? ============================================================ -大家好!今天,我开始进行我的 [ruby 堆栈跟踪项目][1],我意识到,我现在了解了一些关于 gdb 内部如何工作的内容。 +大家好!今天,我开始进行我的 [ruby 堆栈跟踪项目][1],我发觉我现在了解了一些关于 `gdb` 内部如何工作的内容。 -最近,我使用 gdb 来查看我的 Ruby 程序,所以,我们将对一个 Ruby 程序运行 gdb 。它实际上就是一个 Ruby 解释器。首先,我们需要打印出一个全局变量的地址:`ruby_current_thread`。 +最近,我使用 `gdb` 来查看我的 Ruby 程序,所以,我们将对一个 Ruby 程序运行 `gdb` 。它实际上就是一个 Ruby 解释器。首先,我们需要打印出一个全局变量的地址:`ruby_current_thread`。 ### 获取全局变量 @@ -13,10 +13,9 @@ gdb 如何工作? $ sudo gdb -p 2983 (gdb) p & ruby_current_thread $2 = (rb_thread_t **) 0x5598a9a8f7f0 - ``` -变量能够位于的地方有堆、栈或者程序的文本段。全局变量也是程序的一部分。某种程度上,你可以把它们想象成是在编译的时候分配的。因此,我们可以很容易的找出全局变量的地址。让我们来看看,gdb 是如何找出 `0x5598a9a87f0` 这个地址的。 +变量能够位于的地方有heapstack或者程序的文本段text。全局变量是程序的一部分。某种程度上,你可以把它们想象成是在编译的时候分配的。因此,我们可以很容易的找出全局变量的地址。让我们来看看,`gdb` 是如何找出 `0x5598a9a87f0` 这个地址的。 我们可以通过查看位于 `/proc` 目录下一个叫做 `/proc/$pid/maps` 的文件,来找到这个变量所位于的大致区域。 @@ -42,35 +41,33 @@ $4 = 0x48a7f0 ``` sudo nm /proc/2983/exe | grep ruby_current_thread 000000000048a7f0 b ruby_current_thread - ``` 我们看到了什么?能够看到 `0x48a7f0` 吗?是的,没错。所以,如果我们想找到程序中一个全局变量的地址,那么只需在符号表中查找变量的名字,然后再加上在 `/proc/whatever/maps` 中的起始地址,就得到了。 -所以现在,我们知道 gdb 做了什么。但是,gdb 实际做的事情更多,让我们跳过直接转到… +所以现在,我们知道 `gdb` 做了什么。但是,`gdb` 实际做的事情更多,让我们跳过直接转到… ### 解引用指针 ``` (gdb) p ruby_current_thread $1 = (rb_thread_t *) 0x5598ab3235b0 - ``` -我们要做的下一件事就是解引用 `ruby_current_thread` 这一指针。我们想看一下它所指向的地址。为了完成这件事,gdb 会运行大量系统调用比如: +我们要做的下一件事就是解引用 `ruby_current_thread` 这一指针。我们想看一下它所指向的地址。为了完成这件事,`gdb` 会运行大量系统调用比如: ``` ptrace(PTRACE_PEEKTEXT, 2983, 0x5598a9a8f7f0, [0x5598ab3235b0]) = 0 ``` -你是否还记得 `0x5598a9a8f7f0` 这个地址?gdb 会问:“嘿,在这个地址中的实际内容是什么?”。`2983` 是我们运行 gdb 这个进程的 ID。gdb 使用 `ptrace` 这一系统调用来完成这一件事。 +你是否还记得 `0x5598a9a8f7f0` 这个地址?`gdb` 会问:“嘿,在这个地址中的实际内容是什么?”。`2983` 是我们运行 gdb 这个进程的 ID。gdb 使用 `ptrace` 这一系统调用来完成这一件事。 -好极了!因此,我们可以解引用内存并找出内存地址中存储的内容。一些有用的 gdb 命令能够分别知道 `x/40w` 和 `x/40b` 这两个变量哪一个会在给定地址展示 40 个字/字节。 +好极了!因此,我们可以解引用内存并找出内存地址中存储的内容。有一些有用的 `gdb` 命令,比如 `x/40w 变量` 和 `x/40b 变量` 分别会显示给定地址的 40 个字/字节。 ### 描述结构 -一个内存地址中的内容可能看起来像下面这样。大量的字节! +一个内存地址中的内容可能看起来像下面这样。可以看到很多字节! ``` (gdb) x/40b ruby_current_thread @@ -79,7 +76,6 @@ ptrace(PTRACE_PEEKTEXT, 2983, 0x5598a9a8f7f0, [0x5598ab3235b0]) = 0 0x5598ab3235c0: 16 -64 -55 115 -97 127 0 0 0x5598ab3235c8: 0 0 2 0 0 0 0 0 0x5598ab3235d0: -96 -83 -39 115 -97 127 0 0 - ``` 这很有用,但也不是非常有用!如果你是一个像我一样的人类并且想知道它代表什么,那么你需要更多内容,比如像这样: @@ -92,10 +88,9 @@ $8 = {self = 94114195940880, vm = 0x5598ab322f20, stack = 0x7f9f73c9c010, passed_bmethod_me = 0x0, passed_ci = 0x0, top_self = 94114195612680, top_wrapper = 0, base_block = 0x0, root_lep = 0x0, root_svar = 8, thread_id = 140322820187904, - ``` -太好了。现在就更加有用了。gdb 是如何知道这些所有域的,比如 `stack_size` ?输入 `DWARF`。`DWARF` 是存储额外程序调试数据的一种方式,从而调试器比如 gdb 能够更好的工作。它通常存储为一部分二进制。如果我对我的 Ruby 二进制文件运行 `dwarfdump` 命令,那么我将会得到下面的输出: +太好了。现在就更加有用了。`gdb` 是如何知道这些所有域的,比如 `stack_size` ?是从 `DWARF` 得知的。`DWARF` 是存储额外程序调试数据的一种方式,从而像 `gdb` 这样的调试器能够工作的更好。它通常存储为二进制的一部分。如果我对我的 Ruby 二进制文件运行 `dwarfdump` 命令,那么我将会得到下面的输出: (我已经重新编排使得它更容易理解) @@ -128,7 +123,7 @@ DW_TAG_member ``` -所以,`ruby_current_thread` 的类型名为 `rb_thread_struct`,它的大小为 0x3e8 (或 1000 字节),它有许多成员项,`stack_size` 是其中之一,在偏移为 24 的地方,它有类型 `31\` 。`31` 是什么?不用担心,我们也可以在 DWARF 信息中查看。 +所以,`ruby_current_thread` 的类型名为 `rb_thread_struct`,它的大小为 `0x3e8` (即 1000 字节),它有许多成员项,`stack_size` 是其中之一,在偏移为 `24` 的地方,它有类型 `31` 。`31` 是什么?不用担心,我们也可以在 DWARF 信息中查看。 ``` < 1><0x00000031> DW_TAG_typedef @@ -141,67 +136,61 @@ DW_TAG_member ``` -所以,`stack_size` 具有类型 `size_t`,即 `long unsigned int`,它是 8 字节的。这意味着我们可以查看栈大小。 +所以,`stack_size` 具有类型 `size_t`,即 `long unsigned int`,它是 8 字节的。这意味着我们可以查看该栈的大小。 如果我们有了 DWARF 调试数据,该如何分解: 1. 查看 `ruby_current_thread` 所指向的内存区域 - -2. 加上 24 字节来得到 `stack_size` - +2. 加上 `24` 字节来得到 `stack_size` 3. 读 8 字节(以小端的格式,因为是在 x86 上) - 4. 得到答案! -在上面这个例子中是 131072 或 128 kb 。 +在上面这个例子中是 `131072`(即 128 kb)。 -对我来说,这使得调试信息的用途更加明显。如果我们不知道这些所有变量所表示的额外元数据,那么我们无法知道在 `0x5598ab325b0` 这一地址的字节是什么。 +对我来说,这使得调试信息的用途更加明显。如果我们不知道这些所有变量所表示的额外的元数据,那么我们无法知道存储在 `0x5598ab325b0` 这一地址的字节是什么。 -这就是为什么你可以从你的程序中单独安装一个程序的调试信息,因为 gdb 并不关心从何处获取额外的调试信息。 +这就是为什么你可以为你的程序单独安装程序的调试信息,因为 `gdb` 并不关心从何处获取这些额外的调试信息。 -### DWARF 很迷惑 +### DWARF 令人迷惑 -我最近阅读了大量的 DWARF 信息。现在,我使用 libdwarf,使用体验不是很好,这个 API 很令人迷惑,你将以一种奇怪的方式初始化所有东西,它真的很慢(需要花费 0.3 s 的时间来读取我的 Ruby 程序的所有调试信息,这真是可笑)。有人告诉我,libdw 比 elfutils 要好一些。 +我最近阅读了大量的 DWARF 知识。现在,我使用 libdwarf,使用体验不是很好,这个 API 令人迷惑,你将以一种奇怪的方式初始化所有东西,它真的很慢(需要花费 0.3 秒的时间来读取我的 Ruby 程序的所有调试信息,这真是可笑)。有人告诉我,来自 elfutils 的 libdw 要好一些。 -同样,你可以查看 `DW_AT_data_member_location` 来查看结构成员的偏移。我在 Stack Overflow 上查找如何完成这件事,并且得到[这个答案][2]。基本上,以下面这样一个检查开始: +同样,再提及一点,你可以查看 `DW_AT_data_member_location` 来查看结构成员的偏移。我在 Stack Overflow 上查找如何完成这件事,并且得到[这个答案][2]。基本上,以下面这样一个检查开始: ``` dwarf_whatform(attrs[i], &form, &error); if (form == DW_FORM_data1 || form == DW_FORM_data2 form == DW_FORM_data2 || form == DW_FORM_data4 form == DW_FORM_data8 || form == DW_FORM_udata) { - ``` 继续往前。为什么会有 800 万种不同的 `DW_FORM_data` 需要检查?发生了什么?我没有头绪。 -不管怎么说,我的印象是,DWARF 是一个庞大而复杂的标准(可能是人们用来生成 DWARF 的库不匹配),但是这是我们所拥有的,所以我们只能用它来工作。 +不管怎么说,我的印象是,DWARF 是一个庞大而复杂的标准(可能是人们用来生成 DWARF 的库稍微不兼容),但是我们有的就是这些,所以我们只能用它来工作。 -我能够编写代码并查看 DWARF 并且我的代码实际上大多数能够工作,这就很酷了,除了程序崩溃的时候。我就是这样工作的。 +我能够编写代码并查看 DWARF ,这就很酷了,并且我的代码实际上大多数能够工作。除了程序崩溃的时候。我就是这样工作的。 ### 展开栈路径 -在这篇文章的早期版本中,我说过,gdb 使用 libunwind 来展开栈路径,这样说并不总是对的。 +在这篇文章的早期版本中,我说过,`gdb` 使用 libunwind 来展开栈路径,这样说并不总是对的。 -有一位对 gdb 有深入研究的人发了大量邮件告诉我,他们花费了大量时间来尝试如何展开栈路径从而能够做得比 libunwind 更好。这意味着,如果你在程序的一个奇怪的中间位置停下来了,你所能够获取的调试信息又很少,那么你可以对栈做一些奇怪的事情,gdb 会尝试找出你位于何处。 +有一位对 `gdb` 有深入研究的人发了大量邮件告诉我,为了能够做得比 libunwind 更好,他们花费了大量时间来尝试如何展开栈路径。这意味着,如果你在程序的一个奇怪的中间位置停下来了,你所能够获取的调试信息又很少,那么你可以对栈做一些奇怪的事情,`gdb` 会尝试找出你位于何处。 ### gdb 能做的其他事 -我在这儿所描述的一些事请(查看内存,理解 DWARF 所展示的结构)并不是 gdb 能够做的全部事情。阅读 Brendan Gregg 的[昔日 gdb 例子][3],我们可以知道,gdb 也能够完成下面这些事情: +我在这儿所描述的一些事请(查看内存,理解 DWARF 所展示的结构)并不是 `gdb` 能够做的全部事情。阅读 Brendan Gregg 的[昔日 gdb 例子][3],我们可以知道,`gdb` 也能够完成下面这些事情: * 反汇编 - * 查看寄存器内容 在操作程序方面,它可以: * 设置断点,单步运行程序 - * 修改内存(这是一个危险行为) -了解 gdb 如何工作使得当我使用它的时候更加自信。我过去经常感到迷惑,因为 gdb 有点像 C,当你输入 `ruby_current_thread->cfp->iseq`,就好像是在写 C 代码。但是你并不是在写 C 代码。我很容易遇到 gdb 的限制,不知道为什么。 +了解 `gdb` 如何工作使得当我使用它的时候更加自信。我过去经常感到迷惑,因为 `gdb` 有点像 C,当你输入 `ruby_current_thread->cfp->iseq`,就好像是在写 C 代码。但是你并不是在写 C 代码。我很容易遇到 `gdb` 的限制,不知道为什么。 -知道使用 DWARF 来找出结构内容给了我一个更好的心理模型和更加正确的期望!这真是极好的! +知道使用 DWARF 来找出结构内容给了我一个更好的心智模型和更加正确的期望!这真是极好的! -------------------------------------------------------------------------------- @@ -209,7 +198,7 @@ via: https://jvns.ca/blog/2016/08/10/how-does-gdb-work/ 作者:[Julia Evans][a] 译者:[ucasFL](https://github.com/ucasFL) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201803/20170210 Evolutional Steps of Computer Systems.md b/published/201803/20170210 Evolutional Steps of Computer Systems.md new file mode 100644 index 0000000000..0b28a3588e --- /dev/null +++ b/published/201803/20170210 Evolutional Steps of Computer Systems.md @@ -0,0 +1,109 @@ +计算机系统进化论 +====== + +纵观现代计算机的历史,从与系统的交互方式方面,可以划分为数个进化阶段。而我更倾向于将之归类为以下几个阶段: + +1. 数字系统 +2. 专用应用系统 +3. 应用中心系统 +4. 信息中心系统 +5. 无应用系统 + +下面我们详细聊聊这几种分类。 + +### 数字系统 + +在我看来,[早期计算机][1],只被设计用来处理数字。它们能够加、减、乘、除。在它们中有一些能够运行像是微分和积分之类的更复杂的数学操作。 + +当然,如果你把字符映射成数字,它们也可以计算字符串。但这多少有点“数字的创造性使用”的意思,而不是直接处理各种信息。 + +### 专用应用系统 + +对于更高层级的问题,纯粹的数字系统是不够的。专用应用系统被开发用来处理单一任务。它们和数字系统十分相似,但是,它们拥有足够的复杂数字计算能力。这些系统能够完成十分明确的高层级任务,像调度问题的相关计算或者其他优化问题。 + +这类系统为单一目的而搭建,它们解决的是单一明确的问题。 + +### 应用中心系统 + +应用中心系统是第一个真正的通用系统。它们的主要使用风格很像专用应用系统,但是它们拥有以时间片模式(一个接一个)或以多任务模式(多应用同时)运行的多个应用程序。 + +上世纪 70 年代的 [早期的个人电脑][3]是第一种受人们欢迎的应用中心系统。 + +如今的现在操作系统 —— Windows 、macOS 、大多数 GNU/Linux 桌面环境 —— 一直遵循相同的法则。 + +当然,应用中心系统还可以再细分为两种子类: + +1. 紧密型应用中心系统 +2. 松散型应用中心系统 + +紧密型应用中心系统像是 [Windows 3.1][4] (拥有程序管理器和文件管理器)或者甚至 [Windows 95][5] 的最初版本都没有预定义的文件夹层次。用户启动文本处理程序(像 [ WinWord ][6])并且把文件保存在 WinWord 的程序文件夹中。在使用表格处理程序的时候,又把文件保存在表格处理工具的程序文件夹中。诸如此类。用户几乎不创建自己的文件层次结构,可能由于此举的不方便、用户单方面的懒惰,或者他们认为根本没有必要。那时,每个用户拥有几十个至多几百个文件。 + +为了访问文件中的信息,用户常常先打开一个应用程序,然后通过程序中的“文件/打开”功能来获取处理过的数据文件。 + +在 Windows 平台的 [Windows 95][5] SP2 中,“[我的文档][7]”首次被使用。有了这样一个文件层次结构的样板,应用设计者开始把 “[我的文档][7]” 作为程序的默认的保存 / 打开目录,抛弃了原来将软件产品安装目录作为默认目录的做法。这样一来,用户渐渐适应了这种模式,并且开始自己维护文件夹层次。 + +松散型应用中心系统(通过文件管理器来提取文件)应运而生。在这种系统下,当打开一个文件的时候,操作系统会自动启动与之相关的应用程序。这是一次小而精妙的用法转变。这种应用中心系统的用法模式一直是个人电脑的主要用法模式。 + +然而,这种模式有很多的缺点。例如,为了防止数据提取出现问题,需要维护一个包含给定项目的所有相关文件的严格文件夹层次结构。不幸的是,人们并不总能这样做。更进一步说,[这种模式不能很好的扩展][8]。 桌面搜索引擎和高级数据组织工具(像 [tagstore][9])可以起到一点改善作用。正如研究显示的那样,只有一少部分人正在使用那些高级文件提取工具。大多数的用户不使用替代提取工具或者辅助提取技术在文件系统中寻找文件。 + +### 信息中心系统 + +解决上述需要将所有文件都放到一个文件夹的问题的可行办法之一就是从应用中心系统转换到信息中心系统。 + +信息中心系统将项目的所有信息联合起来,放在一个地方,放在同一个应用程序里。因此,我们再也不需要计算项目预算时,打开表格处理程序;写工程报告时,打开文本处理程序;处理图片文件时,又打开另一个工具。 + +上个月的预算情况在客户会议笔记的右下方,客户会议笔记又在画板的右下方,而画板又在另一些要去完成的任务的右下方。在各个层之间没有文件或者应用程序来回切换的麻烦。 + +早期,IBM [OS/2][10]、 Microsoft [OLE][11] 和 [NeXT][12] 都做过类似的尝试。但都由于种种原因没有取得重大成功。从 [Plan 9][14] 发展而来的 [ACme][13] 是一个非常有趣的信息中心环境。它在一个应用程序中包含了[多种应用程序][15]。但是即时是它移植到了 Windows 和 GNU/Linux,也从来没有成为一个引起关注的软件。 + +信息中心系统的现代形式是高级 [个人维基][16](像 [TheBrain][17] 和 [Microsoft OneNote][18])。 + +我选择的个人工具是带 [Org 模式][19] 扩展的 [GNU/Emacs][20] 平台。在用电脑的时候,我几乎不能没有 Org 模式 。为了访问外部数据资源,我创建了一个可以将多种数据导入 Org 模式的插件 —— [Memacs][20] 。我喜欢将表格数据计算放到日程任务的右下方,然后是行内图片,内部和外部链接,等等。它是一个真正的用户不用必须操心程序或者严格的层次文件系统文件夹的信息中心系统。同时,用简单的或高级的标签也可以进行多分类。一个命令可以派生多种视图。比如,一个视图有日历,待办事项。另一个视图是租借事宜列表。等等。它对 Org 模式的用户没有限制。只有你想不到,没有它做不到。 + +进化结束了吗? 当然没有。 + +### 无应用系统 + +我能想到这样一类操作系统,我称之为无应用系统。在下一步的发展中,系统将不需要单一领域的应用程序,即使它们能和 Org 模式一样出色。计算机直接提供一个处理信息和使用功能的友好用户接口,而不通过文件和程序。甚至连传统的操作系统也不需要。 + +无应用系统也可能和 [人工智能][21] 联系起来。把它想象成 [2001 太空漫游][23] 中的 [HAL 9000][22] 和星际迷航中的 [LCARS][24] 一类的东西就可以了。 + +从基于应用的、基于供应商的软件文化到无应用系统的转化让人很难相信。 或许,缓慢但却不断发展的开源环境,可以使一个由各种各样组织和人们贡献的真正无应用环境成型。 + +信息和提取、操作信息的功能,这是系统应该具有的,同时也是我们所需要的。其他的东西仅仅是为了使我们不至于分散注意力。 + +-------------------------------------------------------------------------------- + +via: http://karl-voit.at/2017/02/10/evolution-of-systems/ + +作者:[Karl Voit][a] +译者:[lontow](https://github.com/lontow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://karl-voit.at +[1]:https://en.wikipedia.org/wiki/History_of_computing_hardware +[2]:https://en.wikipedia.org/wiki/String_%2528computer_science%2529 +[3]:https://en.wikipedia.org/wiki/Xerox_Alto +[4]:https://en.wikipedia.org/wiki/Windows_3.1x +[5]:https://en.wikipedia.org/wiki/Windows_95 +[6]:https://en.wikipedia.org/wiki/Microsoft_Word +[7]:https://en.wikipedia.org/wiki/My_Documents +[8]:http://karl-voit.at/tagstore/downloads/Voit2012b.pdf +[9]:http://karl-voit.at/tagstore/ +[10]:https://en.wikipedia.org/wiki/OS/2 +[11]:https://en.wikipedia.org/wiki/Object_Linking_and_Embedding +[12]:https://en.wikipedia.org/wiki/NeXT +[13]:https://en.wikipedia.org/wiki/Acme_%2528text_editor%2529 +[14]:https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs +[15]:https://en.wikipedia.org/wiki/List_of_Plan_9_applications +[16]:https://en.wikipedia.org/wiki/Personal_wiki +[17]:https://en.wikipedia.org/wiki/TheBrain +[18]:https://en.wikipedia.org/wiki/Microsoft_OneNote +[19]:../../../../tags/emacs +[20]:https://github.com/novoid/Memacs +[21]:https://en.wikipedia.org/wiki/Artificial_intelligence +[22]:https://en.wikipedia.org/wiki/HAL_9000 +[23]:https://en.wikipedia.org/wiki/2001:_A_Space_Odyssey +[24]:https://en.wikipedia.org/wiki/LCARS diff --git a/published/20170310 9 Lightweight Linux Applications to Speed Up Your System.md b/published/201803/20170310 9 Lightweight Linux Applications to Speed Up Your System.md similarity index 100% rename from published/20170310 9 Lightweight Linux Applications to Speed Up Your System.md rename to published/201803/20170310 9 Lightweight Linux Applications to Speed Up Your System.md diff --git a/published/20170921 How to answer questions in a helpful way.md b/published/201803/20170921 How to answer questions in a helpful way.md similarity index 100% rename from published/20170921 How to answer questions in a helpful way.md rename to published/201803/20170921 How to answer questions in a helpful way.md diff --git a/published/20171002 Bash Bypass Alias Linux-Unix Command.md b/published/201803/20171002 Bash Bypass Alias Linux-Unix Command.md similarity index 100% rename from published/20171002 Bash Bypass Alias Linux-Unix Command.md rename to published/201803/20171002 Bash Bypass Alias Linux-Unix Command.md diff --git a/published/20171002 Reset Linux Desktop To Default Settings With A Single Command.md b/published/201803/20171002 Reset Linux Desktop To Default Settings With A Single Command.md similarity index 100% rename from published/20171002 Reset Linux Desktop To Default Settings With A Single Command.md rename to published/201803/20171002 Reset Linux Desktop To Default Settings With A Single Command.md diff --git a/published/201803/20171007 How to use GNU Stow to manage programs installed from source and dotfiles.md b/published/201803/20171007 How to use GNU Stow to manage programs installed from source and dotfiles.md new file mode 100644 index 0000000000..306684f885 --- /dev/null +++ b/published/201803/20171007 How to use GNU Stow to manage programs installed from source and dotfiles.md @@ -0,0 +1,137 @@ +如何使用 GNU Stow 来管理从源代码安装的程序和点文件 +===== + +### 目的 + +使用 GNU Stow 轻松管理从源代码安装的程序和点文件(LCTT 译注:点文件dotfile,即以 `.` 开头的文件,在 *nix 下默认为隐藏文件,常用于存储程序的配置信息。) + +### 要求 + +* root 权限 + +### 难度 + +简单 + +### 约定 + +* `#` - 给定的命令要求直接以 root 用户身份或使用 `sudo` 命令以 root 权限执行 +* `$` - 给定的命令将作为普通的非特权用户来执行 + +### 介绍 + +有时候我们必须从源代码安装程序,因为它们也许不能通过标准渠道获得,或者我们可能需要特定版本的软件。 GNU Stow 是一个非常不错的符号链接工厂symlinks factory程序,它可以帮助我们保持文件的整洁,易于维护。 + +### 获得 stow + +你的 Linux 发行版本很可能包含 `stow`,例如在 Fedora,你安装它只需要: + +``` +# dnf install stow +``` + +在 Ubuntu/Debian 中,安装 `stow` 需要执行: + +``` +# apt install stow +``` + +在某些 Linux 发行版中,`stow` 在标准库中是不可用的,但是可以通过一些额外的软件源(例如 RHEL 和 CentOS7 中的EPEL )轻松获得,或者,作为最后的手段,你可以从源代码编译它。只需要很少的依赖关系。 + +### 从源代码编译 + +最新的可用 stow 版本是 `2.2.2`。源码包可以在这里下载:`https://ftp.gnu.org/gnu/stow/`。 + +一旦你下载了源码包,你就必须解压它。切换到你下载软件包的目录,然后运行: + +``` +$ tar -xvpzf stow-2.2.2.tar.gz +``` + +解压源文件后,切换到 `stow-2.2.2` 目录中,然后编译该程序,只需运行: + +``` +$ ./configure +$ make +``` + +最后,安装软件包: + +``` +# make install +``` + +默认情况下,软件包将安装在 `/usr/local/` 目录中,但是我们可以改变它,通过配置脚本的 `--prefix` 选项指定目录,或者在运行 `make install` 时添加 `prefix="/your/dir"`。 + +此时,如果所有工作都按预期工作,我们应该已经在系统上安装了 `stow`。 + +### stow 是如何工作的? + +`stow` 背后主要的概念在程序手册中有很好的解释: + +> Stow 使用的方法是将每个软件包安装到自己的目录树中,然后使用符号链接使它看起来像文件一样安装在公共的目录树中 + +为了更好地理解这个软件的运作,我们来分析一下它的关键概念: + +#### stow 文件目录 + +stow 目录是包含所有 stow 软件包的根目录,每个包都有自己的子目录。典型的 stow 目录是 `/usr/local/stow`:在其中,每个子目录代表一个软件包。 + +#### stow 软件包 + +如上所述,stow 目录包含多个“软件包”,每个软件包都位于自己单独的子目录中,通常以程序本身命名。包就是与特定软件相关的文件和目录列表,作为一个实体进行管理。 + +#### stow 目标目录 + +stow 目标目录解释起来是一个非常简单的概念。它是包文件应该安装到的目录。默认情况下,stow 目标目录被视作是调用 stow 的目录。这种行为可以通过使用 `-t` 选项( `--target` 的简写)轻松改变,这使我们可以指定一个替代目录。 + +### 一个实际的例子 + +我相信一个好的例子胜过 1000 句话,所以让我来展示 `stow` 如何工作。假设我们想编译并安装 `libx264`,首先我们克隆包含其源代码的仓库: + +``` +$ git clone git://git.videolan.org/x264.git +``` + +运行该命令几秒钟后,将创建 `x264` 目录,它将包含准备编译的源代码。我们切换到 `x264` 目录中并运行 `configure` 脚本,将 `--prefix` 指定为 `/usr/local/stow/libx264` 目录。 + +``` +$ cd x264 && ./configure --prefix=/usr/local/stow/libx264 +``` + +然后我们构建该程序并安装它: + +``` +$ make +# make install +``` + +`x264` 目录应该创建在 `stow` 目录内:它包含了所有通常直接安装在系统中的东西。 现在,我们所要做的就是调用 `stow`。 我们必须从 `stow` 目录内运行这个命令,通过使用 `-d` 选项来手动指定 `stow` 目录的路径(默认为当前目录),或者通过如前所述用 `-t` 指定目标。我们还应该提供要作为参数存储的软件包的名称。 在这里,我们从 `stow` 目录运行程序,所以我们需要输入的内容是: + +``` +# stow libx264 +``` + +libx264 软件包中包含的所有文件和目录现在已经在调用 stow 的父目录 (/usr/local) 中进行了符号链接,因此,例如在 `/usr/local/ stow/x264/bin` 中包含的 libx264 二进制文件现在符号链接在 `/usr/local/bin` 之中,`/usr/local/stow/x264/etc` 中的文件现在符号链接在 `/usr/local/etc` 之中等等。通过这种方式,系统将显示文件已正常安装,并且我们可以容易地跟踪我们编译和安装的每个程序。要反转该操作,我们只需使用 `-D` 选项: + +``` +# stow -d libx264 +``` + +完成了!符号链接不再存在:我们只是“卸载”了一个 stow 包,使我们的系统保持在一个干净且一致的状态。 在这一点上,我们应该清楚为什么 stow 还可以用于管理点文件。 通常的做法是在 git 仓库中包含用户特定的所有配置文件,以便轻松管理它们并使它们在任何地方都可用,然后使用 stow 将它们放在适当位置,如放在用户主目录中。 + +stow 还会阻止你错误地覆盖文件:如果目标文件已经存在,并且没有指向 stow 目录中的包时,它将拒绝创建符号链接。 这种情况在 stow 术语中称为冲突。 + +就是这样!有关选项的完整列表,请参阅 stow 帮助页,并且不要忘记在评论中告诉我们你对此的看法。 + +-------------------------------------------------------------------------------- + +via: https://linuxconfig.org/how-to-use-gnu-stow-to-manage-programs-installed-from-source-and-dotfiles + +作者:[Egidio Docile][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://linuxconfig.org diff --git a/published/201803/20171009 10 Free Linux Productivity Apps You Haven-t Heard Of.md b/published/201803/20171009 10 Free Linux Productivity Apps You Haven-t Heard Of.md new file mode 100644 index 0000000000..ebf7592b07 --- /dev/null +++ b/published/201803/20171009 10 Free Linux Productivity Apps You Haven-t Heard Of.md @@ -0,0 +1,101 @@ +你没听过的 10 个免费的 Linux 生产力应用程序 +===== + +![](https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-00-Featured.jpg) + +高效率的应用程序确实可以让你工作变得更轻松。如果你是一位 Linux 用户,这 10 个不太知名的 Linux 桌面应用程序可以帮助到你。事实上,Linux 用户可能已经听说过这个列表上的所有应用,但对于那些只用过主流应用的人来说,应该是不知道这些应用的。 + +### 1. Tomboy/Gnote + +![linux-productivity-apps-01-tomboy][1] + +[Tomboy][2] 是一个简单的便签应用。它不仅仅适用于 Linux,你也可以在 Unix、Windows 和 macOS 上获得它。Tomboy 很容易使用——你写一个便条,选择是否让它粘贴在你的桌面上,当你完成它时删除它。 + +### 2. MyNotex + +![linux-productivity-apps-02-mynotex][3] + +如果你想要一个更多功能的便签,但是仍喜欢一个小而简单的应用程序,而不是一个巨大的套件,请看看 [MyNotex][4]。除了简单的笔记和检索之外,它还带有一些不错的功能,例如格式化、键盘快捷键和附件等等。你也可以将其用作图片管理器。 + +### 3. Trojitá + +![linux-productivity-apps-03-trojita][5] + +尽管你可以没有桌面电子邮件客户端,但如果你想要一个的话,在几十个的桌面电子邮件客户端里,请尝试下 [Trojita][6]。这有利于生产力,因为它是一个快速而轻量级的电子邮件客户端,但它提供了一个好的电子邮件客户端所必须具备的所有功能(以及更多)。 + +### 4. Kontact + +![linux-productivity-apps-04-kontact][7] + +个人信息管理器(PIM)是一款出色的生产力工具。我的个人喜好是 [Kontact][8]。尽管它已经有几年没有更新,但它仍然是一个非常有用的 PIM 工具,用于管理电子邮件、地址簿、日历、任务、新闻源等。Kontact 是一个 KDE 原生程序,但你也可以在其他桌面上使用它。 + +### 5. Osmo + +![linux-productivity-apps-05-osmo][9] + +[Osmo][10] 是一款更先进的应用,包括日历、任务、联系人和便签功能。它还附带一些额外的功能,比如加密私有数据备份和地图上的地理位置,以及对便签、任务、联系人等的强大搜索功能。 + +### 6. Catfish + +![linux-productivity-apps-06-catfish][11] + +没有好的搜索工具就没有高生产力。[Catfish][12] 是一个必须尝试的搜索工具。它是一个 GTK+ 工具,非常快速,轻量级。Catfish 会利用 Zeitgeist 的自动完成功能,你还可以按日期和类型过滤搜索结果。 + +### 7. KOrganizer + +![linux-productivity-apps-07-korganizer][13] + +[KOrganizer][14] 是我上面提到的 Kontact 应用程序的日历和计划组件。如果你不需要完整的 PIM 应用程序,只需要日历和日程安排,则可以使用 KOrganizer。KOrganizer 提供快速的待办事项和快速事件条目,以及事件和待办事项的附件。 + +### 8. Evolution + +![linux-productivity-apps-08-evolution][15] + +如果你不是 KDE 应用程序的粉丝,但你仍然需要一个好的 PIM,那么试试 GNOME 的 [Evolution][16]。Evolution 并不是一个你从没听过的少见的应用程序,但因为它有用,所以它出现在这个列表中。也许你已经听说过 Evolution 是一个电子邮件客户端,但它远不止于此——你可以用它来管理日历、邮件、地址簿和任务。 + +### 9. Freeplane + +![linux-productivity-apps-09-freeplane][17] + +我不知道你们中的大多数是否每天都使用思维导图软件,但是如果你使用,请选择 [Freeplane][18]。这是一款免费的思维导图和知识管理软件,可用于商业或娱乐。你可以创建笔记,将其排列在云图或图表中,使用日历和提醒设置任务等。 + +### 10. Calligra Flow + +![linux-productivity-apps-10-calligra-flow][19] + +最后,如果你需要流程图和图表工具,请尝试 [Calligra Flow][20]。你可以将其视为开放源代码的 [Microsoft Visio][21] 替代品,但 Calligra Flow 不提供 Viso 提供的所有特性。不过,你可以使用它来创建网络图、组织结构图、流程图等等。 + +生产力工具不仅可以加快工作速度,还可以让你更有条理。我敢打赌,几乎没有人不使用某种形式的生产力工具。尝试这里列出的应用程序可以使你的工作效率更高,还能让你的生活至少轻松一些。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/free-linux-productivity-apps-you-havent-heard-of/ + +作者:[Ada Ivanova][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.maketecheasier.com/author/adaivanoff/ +[1]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-01-Tomboy.png (linux-productivity-apps-01-tomboy) +[2]:https://wiki.gnome.org/Apps/Tomboy +[3]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-02-MyNotex.jpg (linux-productivity-apps-02-mynotex) +[4]:https://sites.google.com/site/mynotex/ +[5]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-03-Trojita.jpg (linux-productivity-apps-03-trojita) +[6]:http://trojita.flaska.net/ +[7]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-04-Kontact.jpg (linux-productivity-apps-04-kontact) +[8]:https://userbase.kde.org/Kontact +[9]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-05-Osmo.jpg (linux-productivity-apps-05-osmo) +[10]:http://clayo.org/osmo/ +[11]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-06-Catfish.png (linux-productivity-apps-06-catfish) +[12]:http://www.twotoasts.de/index.php/catfish/ +[13]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-07-KOrganizer.jpg (linux-productivity-apps-07-korganizer) +[14]:https://userbase.kde.org/KOrganizer +[15]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-08-Evolution.jpg (linux-productivity-apps-08-evolution) +[16]:https://help.gnome.org/users/evolution/3.22/intro-main-window.html.en +[17]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-09-Freeplane.jpg (linux-productivity-apps-09-freeplane) +[18]:https://www.freeplane.org/wiki/index.php/Home +[19]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-10-Calligra-Flow.jpg (linux-productivity-apps-10-calligra-flow) +[20]:https://www.calligra.org/flow/ +[21]:https://www.maketecheasier.com/5-best-free-alternatives-to-microsoft-visio/ diff --git a/published/20171009 10 layers of Linux container security - Opensource.com.md b/published/201803/20171009 10 layers of Linux container security - Opensource.com.md similarity index 100% rename from published/20171009 10 layers of Linux container security - Opensource.com.md rename to published/201803/20171009 10 layers of Linux container security - Opensource.com.md diff --git a/published/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md b/published/201803/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md similarity index 100% rename from published/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md rename to published/201803/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md diff --git a/published/20171017 What Are the Hidden Files in my Linux Home Directory For.md b/published/201803/20171017 What Are the Hidden Files in my Linux Home Directory For.md similarity index 100% rename from published/20171017 What Are the Hidden Files in my Linux Home Directory For.md rename to published/201803/20171017 What Are the Hidden Files in my Linux Home Directory For.md diff --git a/published/20171102 What is huge pages in Linux.md b/published/201803/20171102 What is huge pages in Linux.md similarity index 100% rename from published/20171102 What is huge pages in Linux.md rename to published/201803/20171102 What is huge pages in Linux.md diff --git a/translated/tech/20171108 How to Use GNOME Shell Extensions [Complete Guide].md b/published/201803/20171108 How to Use GNOME Shell Extensions [Complete Guide].md similarity index 57% rename from translated/tech/20171108 How to Use GNOME Shell Extensions [Complete Guide].md rename to published/201803/20171108 How to Use GNOME Shell Extensions [Complete Guide].md index 8f3c10cfa7..47cb18df76 100644 --- a/translated/tech/20171108 How to Use GNOME Shell Extensions [Complete Guide].md +++ b/published/201803/20171108 How to Use GNOME Shell Extensions [Complete Guide].md @@ -1,7 +1,7 @@ -如何使用 GNOME Shell 扩展[完整指南] +如何使用 GNOME Shell 扩展 ===== -**简介:这是一份详细指南,我将会向你展示如何手动或通过浏览器轻松安装 GNOME Shell 扩展。** +> 简介:这是一份详细指南,我将会向你展示如何手动或通过浏览器轻松安装 GNOME Shell 扩展Extension。 在讨论 [如何在 Ubuntu 17.10 上安装主题][1] 一文时,我简要地提到了 GNOME Shell 扩展,它用来安装用户主题。今天,我们将详细介绍 Ubuntu 17.10 中的 GNOME Shell 扩展。 @@ -11,94 +11,103 @@ 在此之前,如果你喜欢视频,我已经在 [FOSS 的 YouTube 频道][2] 上展示了所有的这些操作。我强烈建议你订阅它来获得更多有关 Linux 的视频。 -## 什么是 GNOME Shell 扩展? +### 什么是 GNOME Shell 扩展? [GNOME Shell 扩展][3] 根本上来说是增强 GNOME 桌面功能的一小段代码。 -把它看作是你浏览器的一个附加组件。例如,你可以在浏览器中安装附加组件来禁用广告。这个附加组件是由第三方开发者开发的。虽然你的 Web 浏览器默认不提供此项功能,但安装此附加组件可增强你 Web 浏览器的功能。 +把它看作是你的浏览器的一个附加组件。例如,你可以在浏览器中安装附加组件来禁用广告。这个附加组件是由第三方开发者开发的。虽然你的 Web 浏览器默认不提供此项功能,但安装此附加组件可增强你 Web 浏览器的功能。 -同样, GNOME Shell 扩展就像那些可以安装在 GNOME 之上的第三方附加组件和插件。这些扩展程序是为执行特定任务而创建的,例如显示天气状况,网速等。大多数情况下,你可以在顶部面板中访问它们。 +同样, GNOME Shell 扩展就像那些可以安装在 GNOME 之上的第三方附加组件和插件。这些扩展程序是为执行特定任务而创建的,例如显示天气状况、网速等。大多数情况下,你可以在顶部面板中访问它们。 -![GNOME Shell 扩展 in action][5] +![GNOME Shell 扩展显示天气信息][5] -还有一些 GNOME 扩展在顶部面板上不可见,但它们仍然可以调整 GNOME 的行为。例如,鼠标中轴可以使用扩展来关闭一个应用程序。 +也有一些 GNOME 扩展在顶部面板上不可见,但它们仍然可以调整 GNOME 的行为。例如,有一个这样的扩展可以让鼠标中键来关闭应用程序。 -## 安装 GNOME Shell 扩展 +### 安装 GNOME Shell 扩展 现在你知道了什么是 GNOME Shell 扩展,那么让我们来看看如何安装它吧。有三种方式可以使用 GNOME 扩展: -* 使用来自 Ubuntu 的最小扩展集(或你的 Linux 发行版) -* 在 Web 浏览器种查找并安装扩展程序 +* 使用来自 Ubuntu (或你的 Linux 发行版)的最小扩展集 +* 在 Web 浏览器中查找并安装扩展程序 * 下载并手动安装扩展 在你学习如何使用 GNOME Shell 扩展之前,你应该安装 GNOME Tweak Tool。你可以在软件中心找到它,或者你可以使用以下命令: + ``` sudo apt install gnome-tweak-tool ``` 有时候,你需要知道你正在使用的 GNOME Shell 的版本,这有助于你确定扩展是否与系统兼容。你可以使用下面的命令来找到它: + ``` gnome-shell --version ``` -### 1. 使用 gnome-shell-extensions 包 [最简单最安全的方式] +#### 1. 使用 gnome-shell-extensions 包 [最简单最安全的方式] -Ubuntu (以及其他几个 Linux 发行版,如 Fedora )提供了一个包,这个包有最小的 GNOME 扩展。由于 Linux 发行版经过测试,所以你不必担心兼容性问题。 +Ubuntu(以及其他几个 Linux 发行版,如 Fedora )提供了一个包,这个包有最小集合的 GNOME 扩展。由于 Linux 发行版经过测试,所以你不必担心兼容性问题。 + +如果你不想费神,你只需获得这个包,你就可以安装 8-10 个 GNOME 扩展。 -如果你想要一个简单易懂的程序,你只需获得这个包,你就可以安装 8-10 个 GNOME 扩展。 ``` sudo apt install gnome-shell-extensions ``` -你将不得不重新启动系统(或者重新启动 GNOME Shell,我具体忘了是哪个)。之后,启动 GNOME Tweaks,你会发现一些扩展自动安装了,你只需切换按钮即可开始使用已安装的扩展程序。 +你将需要重新启动系统(或者重新启动 GNOME Shell,我具体忘了是哪个)。之后,启动 GNOME Tweaks,你会发现一些扩展自动安装了,你只需切换按钮即可开始使用已安装的扩展程序。 ![Change GNOME Shell theme in Ubuntu 17.1][6] -### 2. 从 Web 浏览器安装 GNOME Shell 扩展 +#### 2. 从 Web 浏览器安装 GNOME Shell 扩展 -GNOME 项目有一个专门用于扩展的网站。不是这个,你可以找到并安装它,从而管理你的扩展程序,甚至不需要 GNOME Tweaks Tool。 +GNOME 项目有一个专门用于扩展的网站,不干别的,你可以在这里找到并安装扩展,并管理它们,甚至不需要 GNOME Tweaks Tool。 -[GNOME Shell Extensions Website][3] +- [GNOME Shell Extensions Website][3] 但是为了安装 Web 浏览器扩展,你需要两件东西:浏览器附加组件和本地主机连接器。 -#### 步骤 1: 安装 浏览器附加组件 +**步骤 1: 安装 浏览器附加组件** 当你访问 GNOME Shell 扩展网站时,你会看到如下消息: -> "要使用此站点控制 GNOME Shell 扩展,你必须安装由两部分组成的 GNOME Shell 集成:浏览器扩展和本地主机消息应用。" + +> “要使用此站点控制 GNOME Shell 扩展,你必须安装由两部分组成的 GNOME Shell 集成:浏览器扩展和本地主机消息应用。” ![Installing GNOME Shell Extensions][7] -你只需在你的 Web 浏览器上点击建议的附加组件即可。你也可以从下面的链接安装它们: +你只需在你的 Web 浏览器上点击建议的附加组件链接即可。你也可以从下面的链接安装它们: -#### 步骤 2: 安装本地连接器 +- 对于 Google Chrome、Chromium 和 Vivaldi: [Chrome Web 商店][21] +- 对于 Firefox: [Mozilla Addons][22] +- 对于 Opera: [Opera Addons][23] + +**步骤 2: 安装本地连接器** 仅仅安装浏览器附加组件并没有帮助。你仍然会看到如下错误: -> "尽管 GNOME Shell 集成扩展正在运行,但未检测到本地主机连接器。请参阅文档以获取有关安装连接器的信息。" +> “尽管 GNOME Shell 集成扩展正在运行,但未检测到本地主机连接器。请参阅文档以获取有关安装连接器的信息。” ![How to install GNOME Shell Extensions][8] 这是因为你尚未安装主机连接器。要做到这一点,请使用以下命令: + ``` sudo apt install chrome-gnome-shell ``` -不要担心包名中的 'chrome' 前缀,它与 Chrome 无关,你无需再次安装 Firefox 或 Opera 的单独软件包。 +不要担心包名中的 “chrome” 前缀,它与 Chrome 无关,你无需再次安装 Firefox 或 Opera 的单独软件包。 -#### 步骤 3: 在 Web 浏览器中安装 GNOME Shell 扩展 +**步骤 3: 在 Web 浏览器中安装 GNOME Shell 扩展** 一旦你完成了这两个要求,你就可以开始了。现在,你将看不到任何错误消息。 ![GNOME Shell Extension][9] -一件好事情是它会按照 GNOME Shell 版本对扩展进行排序,但这不是强制性的。这里发生的事情是开发人员为当前的 GNOME 版本创建扩展。在一年之内,还会有两个 GNOME 发行版本。但开发人员没有时间测试或更新他/她的扩展。 +一件好的做法是按照 GNOME Shell 版本对扩展进行排序,但这不是强制性的。这是因为开发人员是为其当前的 GNOME 版本创建的扩展。而在一年之内,会发布两个或更多 GNOME 发行版本,但开发人员没有时间(在新的 GNOME 版本上)测试或更新他/她的扩展。 因此,你不知道该扩展是否与你的系统兼容。尽管扩展已经存在很长一段时间了,但是有可能在最新的 GNOME Shell 版本中,它也能正常工作。同样它也有可能不工作。 你也可以去搜索扩展程序。假设你想要安装有关天气的扩展,只要搜索它并选择一个搜索结果即可。 -当你访问扩展页面是,你会看到一个切换按钮。 +当你访问扩展页面时,你会看到一个切换按钮。 ![Installing GNOME Shell Extension ][10] @@ -106,21 +115,21 @@ sudo apt install chrome-gnome-shell ![Install GNOME Shell Extensions via web browser][11] -很明显,直接安装。安装完成后,你会看到切换按钮已打开,旁边有一个设置选项。你也可以使用设置选项配置扩展,也可以禁用扩展。 +显然,直接安装就好。安装完成后,你会看到切换按钮已打开,旁边有一个设置选项。你也可以使用设置选项配置扩展,也可以禁用扩展。 ![Configuring installed GNOME Shell Extensions][12] -你还可以在 GNOME Tweaks Tool 中配置 Web 浏览器中安装的扩展: +你也可以在 GNOME Tweaks Tool 中配置通过 Web 浏览器安装的扩展: ![GNOME Tweaks to handle GNOME Shell Extensions][13] -你可以在 GNOME 网站中 [安装的扩展部分][14] 下查看所有已安装的扩展。 +你可以在 GNOME 网站中 [已安装的扩展部分][14] 下查看所有已安装的扩展。 ![Manage your installed GNOME Shell Extensions][15] -使用 GNOME 扩展网站的一个主要优点是你可以查看是否有可用于扩展的更新,你不会在 GNOME Tweaks 或系统更新中获得它。 +使用 GNOME 扩展网站的一个主要优点是你可以查看扩展是否有可用的更新,你不会在 GNOME Tweaks 或系统更新中得到更新(和提示)。 -### 3. 手动安装 GNOME Shell 扩展 +#### 3. 手动安装 GNOME Shell 扩展 你不需要始终在线才能安装 GNOME Shell 扩展,你可以下载文件并稍后安装,这样就不必使用互联网了。 @@ -128,41 +137,41 @@ sudo apt install chrome-gnome-shell ![Download GNOME Shell Extension][16] -解压下载的文件,将该文件夹复制到 **~/.local/share/gnome-shell/extensions** 目录。到主目录下并按 Crl+H 显示隐藏的文件夹,在这里找到 .local 文件夹,你可以找到你的路径,直至扩展目录。 +解压下载的文件,将该文件夹复制到 `~/.local/share/gnome-shell/extensions` 目录。到主目录下并按 `Ctrl+H` 显示隐藏的文件夹,在这里找到 `.local` 文件夹,你可以找到你的路径,直至 `extensions` 目录。 -一旦你将文件复制到正确的目录后,进入它并打开 metadata.json 文件,寻找 uuid 的值。 +一旦你将文件复制到正确的目录后,进入它并打开 `metadata.json` 文件,寻找 `uuid` 的值。 -确保扩展文件夹名称与 metadata.json 中的 uuid 值相同。如果不相同,请将目录重命名为 uuid 的值。 +确保该扩展的文件夹名称与 `metadata.json` 中的 `uuid` 值相同。如果不相同,请将目录重命名为 `uuid` 的值。 ![Manually install GNOME Shell extension][17] -差不多了!现在重新启动 GNOME Shell。 按 Alt+F2 并输入 r 重新启动 GNOME Shell。 +差不多了!现在重新启动 GNOME Shell。 按 `Alt+F2` 并输入 `r` 重新启动 GNOME Shell。 ![Restart GNOME Shell][18] -同样重新启动 GNOME Tweaks Tool。你现在应该可以在 Tweaks Tool 中看到手动安装 GNOME 扩展,你可以在此处配置或启用新安装的扩展。 +同样重新启动 GNOME Tweaks Tool。你现在应该可以在 Tweaks Tool 中看到手动安装的 GNOME 扩展,你可以在此处配置或启用新安装的扩展。 这就是安装 GNOME Shell 扩展你需要知道的所有内容。 -## 移除 GNOME Shell 扩展 +### 移除 GNOME Shell 扩展 你可能想要删除一个已安装的 GNOME Shell 扩展,这是完全可以理解的。 如果你是通过 Web 浏览器安装的,你可以到 [GNOME 网站的以安装的扩展部分][14] 那移除它(如前面的图片所示)。 -如果你是手动安装的,可以从 ~/.local/share/gnome-shell/extensions 目录中删除扩展文件来删除它。 +如果你是手动安装的,可以从 `~/.local/share/gnome-shell/extensions` 目录中删除扩展文件来删除它。 -## 特别提示:获得 GNOME Shell 扩展更新的通知 +### 特别提示:获得 GNOME Shell 扩展更新的通知 到目前为止,你已经意识到除了访问 GNOME 扩展网站之外,无法知道更新是否可用于 GNOME Shell 扩展。 幸运的是,有一个 GNOME Shell 扩展可以通知你是否有可用于已安装扩展的更新。你可以从下面的链接中获得它: -[Extension Update Notifier][19] +- [Extension Update Notifier][19] ### 你如何管理 GNOME Shell 扩展? -我觉得很奇怪你不能通过系统更新来更新扩展,就好像 GNOME Shell 扩展不是系统的一部分。 +我觉得很奇怪不能通过系统更新来更新扩展,就好像 GNOME Shell 扩展不是系统的一部分。 如果你正在寻找一些建议,请阅读这篇文章: [关于最佳 GNOME 扩展][20]。同时,你可以分享有关 GNOME Shell 扩展的经验。你经常使用它们吗?如果是,哪些是你最喜欢的? @@ -172,7 +181,7 @@ via: [https://itsfoss.com/gnome-shell-extensions/](https://itsfoss.com/gnome-she 作者:[Abhishek Prakash][a] 译者:[MjSeven](https://github.com/MjSeven) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -196,3 +205,6 @@ via: [https://itsfoss.com/gnome-shell-extensions/](https://itsfoss.com/gnome-she [18]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/restart-gnome-shell-800x299.jpeg [19]:https://extensions.gnome.org/extension/1166/extension-update-notifier/ [20]:https://itsfoss.com/best-gnome-extensions/ +[21]:https://chrome.google.com/webstore/detail/gnome-shell-integration/gphhapmejobijbbhgpjhcjognlahblep +[22]:https://addons.mozilla.org/en/firefox/addon/gnome-shell-integration/ +[23]:https://addons.opera.com/en/extensions/details/gnome-shell-integration/ \ No newline at end of file diff --git a/published/20171109 Concurrent Servers- Part 4 - libuv.md b/published/201803/20171109 Concurrent Servers- Part 4 - libuv.md similarity index 100% rename from published/20171109 Concurrent Servers- Part 4 - libuv.md rename to published/201803/20171109 Concurrent Servers- Part 4 - libuv.md diff --git a/published/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md b/published/201803/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md similarity index 100% rename from published/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md rename to published/201803/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md diff --git a/published/20171115 How to create better documentation with a kanban board.md b/published/201803/20171115 How to create better documentation with a kanban board.md similarity index 100% rename from published/20171115 How to create better documentation with a kanban board.md rename to published/201803/20171115 How to create better documentation with a kanban board.md diff --git a/published/20171116 Record and Share Terminal Session with Showterm.md b/published/201803/20171116 Record and Share Terminal Session with Showterm.md similarity index 100% rename from published/20171116 Record and Share Terminal Session with Showterm.md rename to published/201803/20171116 Record and Share Terminal Session with Showterm.md diff --git a/translated/tech/20171117 Command line fun- Insult the user when typing wrong bash command.md b/published/201803/20171117 Command line fun- Insult the user when typing wrong bash command.md similarity index 79% rename from translated/tech/20171117 Command line fun- Insult the user when typing wrong bash command.md rename to published/201803/20171117 Command line fun- Insult the user when typing wrong bash command.md index 3f1cacfaab..77acb72719 100644 --- a/translated/tech/20171117 Command line fun- Insult the user when typing wrong bash command.md +++ b/published/201803/20171117 Command line fun- Insult the user when typing wrong bash command.md @@ -1,57 +1,75 @@ -命令行乐趣:恶搞输错 Bash 命令的用户 +命令行乐趣:嘲讽输错 Bash 命令的用户 ====== -你可以通过配置 sudo 命令去恶搞输入错误密码的用户。但是之后,shell 的恶搞提示语可能会滥用于输入错误命令的用户。 +你可以通过配置 `sudo` 命令去嘲讽输入错误密码的用户。但是现在,当用户在 shell 输错命令时,就能嘲讽他了(滥用?)。 -## 你好 bash-insulter +### 你好 bash-insulter 来自 Github 页面: -> 当用户键入错误命令,随机嘲讽。它使用了一个 bash4.x. 版本的全新内置错误处理函数,叫 command_not_found_handle。 +> 当用户键入错误命令,随机嘲讽。它使用了一个 bash4.x. 版本的全新内置错误处理函数,叫 `command_not_found_handle`。 -## 安装 +### 安装 键入下列 git 命令克隆一个仓库: -`git clone https://github.com/hkbakke/bash-insulter.git bash-insulter` + +``` +git clone https://github.com/hkbakke/bash-insulter.git bash-insulter +``` + 示例输出: + ``` Cloning into 'bash-insulter'... remote: Counting objects: 52, done. remote: Compressing objects: 100% (49/49), done. remote: Total 52 (delta 12), reused 12 (delta 2), pack-reused 0 Unpacking objects: 100% (52/52), done. - ``` -用文本编辑器,编辑你的 ~/.bashrc 或者 /etc/bash.bashrc 文件,比如说使用 vi: -`$ vi ~/.bashrc` -在其后追加这一行(具体了解请查看 [if..else..fi 声明][1] 和 [命令源码][2]): +用文本编辑器,比如说使用 `vi`,编辑你的 `~/.bashrc` 或者 `/etc/bash.bashrc` 文件: + +``` +$ vi ~/.bashrc +``` + +在其后追加这一行(具体了解请查看 [if..else..fi 声明][1] 和 [source 命令][2]): + ``` if [ -f $HOME/bash-insulter/src/bash.command-not-found ]; then source $HOME/bash-insulter/src/bash.command-not-found fi ``` -保存并关闭文件。重新登陆,如果不想退出账号也可以手动运行它: +保存并关闭文件。重新登录,如果不想退出账号也可以手动运行它: + ``` $ . $HOME/bash-insulter/src/bash.command-not-found ``` -## 如何使用它? +### 如何使用它? 尝试键入一些无效命令: + ``` $ ifconfigs $ dates ``` + 示例输出: + [![一个有趣的 bash 钩子功能,嘲讽输入了错误命令的你。][3]][3] -## 自定义 +### 自定义 + +你需要编辑 `$HOME/bash-insulter/src/bash.command-not-found`: + +``` +$ vi $HOME/bash-insulter/src/bash.command-not-found +``` -你需要编辑 $HOME/bash-insulter/src/bash.command-not-found: -`$ vi $HOME/bash-insulter/src/bash.command-not-found` 示例代码: + ``` command_not_found_handle () { local INSULTS=( @@ -104,15 +122,28 @@ command_not_found_handle () { } ``` -## sudo 嘲讽 +### 赠品:sudo 嘲讽 + +编辑 `sudoers` 文件: + +``` +$ sudo visudo +``` -编辑 sudoers 文件: -`$ sudo visudo` 追加下面这一行: -`Defaults insults` + +``` +Defaults insults +``` + 或者像下面尾行增加一句嘲讽语: -`Defaults !lecture,tty_tickets,!fqdn,insults` + +``` +Defaults !lecture,tty_tickets,!fqdn,insults +``` + 这是我的文件: + ``` Defaults env_reset Defaults mail_badpass @@ -140,19 +171,26 @@ root ALL = (ALL:ALL) ALL #includedir /etc/sudoers.d ``` -Try it out: +试一试: + ``` -$ sudo -k # clear old stuff so that we get a fresh prompt +$ sudo -k # 清除缓存,从头开始 $ sudo ls /root/ $ sudo -i ``` -样例对话: + +样例对话: + [![当输入错误密码时,你会被一个有趣的的 sudo 嘲讽语戏弄。][4]][4] -## 你好 sl +### 赠品:你好 sl + +[sl 或是 UNIX 经典捣蛋软件][5] 游戏。当你错误的把 `ls` 输入成 `sl`,将会有一辆蒸汽机车穿过你的屏幕。 + +``` +$ sl +``` -[sl 或是 UNIX 经典捣蛋软件][5] 游戏。当你错误的把 “ls” 输入成 “sl”,将会有一辆蒸汽机车穿过你的屏幕。 -`$ sl` [![Linux / UNIX 桌面乐趣: 蒸汽机车][6]][5] -------------------------------------------------------------------------------- @@ -161,7 +199,7 @@ via: https://www.cyberciti.biz/howto/insult-linux-unix-bash-user-when-typing-wro 作者:[Vivek Gite][a] 译者:[CYLeft](https://github.com/CYLeft) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171121 How to organize your passwords using pass password manager.md b/published/201803/20171121 How to organize your passwords using pass password manager.md similarity index 100% rename from published/20171121 How to organize your passwords using pass password manager.md rename to published/201803/20171121 How to organize your passwords using pass password manager.md diff --git a/published/20171201 Torrents - Everything You Need to Know.md b/published/201803/20171201 Torrents - Everything You Need to Know.md similarity index 100% rename from published/20171201 Torrents - Everything You Need to Know.md rename to published/201803/20171201 Torrents - Everything You Need to Know.md diff --git a/published/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md b/published/201803/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md similarity index 100% rename from published/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md rename to published/201803/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md diff --git a/published/20171207 Concurrent Servers- Part 5 - Redis case study.md b/published/201803/20171207 Concurrent Servers- Part 5 - Redis case study.md similarity index 100% rename from published/20171207 Concurrent Servers- Part 5 - Redis case study.md rename to published/201803/20171207 Concurrent Servers- Part 5 - Redis case study.md diff --git a/published/20171213 Creating a blog with pelican and Github pages.md b/published/201803/20171213 Creating a blog with pelican and Github pages.md similarity index 100% rename from published/20171213 Creating a blog with pelican and Github pages.md rename to published/201803/20171213 Creating a blog with pelican and Github pages.md diff --git a/published/20171214 6 open source home automation tools.md b/published/201803/20171214 6 open source home automation tools.md similarity index 100% rename from published/20171214 6 open source home automation tools.md rename to published/201803/20171214 6 open source home automation tools.md diff --git a/published/20171214 IPv6 Auto-Configuration in Linux.md b/published/201803/20171214 IPv6 Auto-Configuration in Linux.md similarity index 100% rename from published/20171214 IPv6 Auto-Configuration in Linux.md rename to published/201803/20171214 IPv6 Auto-Configuration in Linux.md diff --git a/translated/tech/20171218 What Are Containers and Why Should You Care-.md b/published/201803/20171218 What Are Containers and Why Should You Care-.md similarity index 65% rename from translated/tech/20171218 What Are Containers and Why Should You Care-.md rename to published/201803/20171218 What Are Containers and Why Should You Care-.md index 8d612dbed0..32e8af76b0 100644 --- a/translated/tech/20171218 What Are Containers and Why Should You Care-.md +++ b/published/201803/20171218 What Are Containers and Why Should You Care-.md @@ -1,44 +1,47 @@ 什么是容器?为什么我们关注它? ====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/containers-basics.jpg?itok=ZLH9VSaC) + 什么是容器?你需要它们吗?为什么?在这篇文章中,我们会回答这些基本问题。 但是,为了回答这些问题,我们要提出更多的问题。当你开始考虑怎么用容器适配你的工作时,你需要弄清楚:你在哪开发应用?你在哪测试它?你在哪使用它? -你可能在你的笔记本电脑上开发应用,你的电脑上已经装好了所需要的库文件,扩展包,开发工具,和开发框架。它在一个模拟生产环境的机器上进行测试,然后被用于生产。问题是这三种环境不一定都是一样的;他们没有同样的工具,框架,和库。你在你机器上开发的应用不一定可以在生产环境中正常工作。 +你可能在你的笔记本电脑上开发应用,你的电脑上已经装好了所需要的库文件、扩展包、开发工具和开发框架。它在一个模拟生产环境的机器上进行测试,然后被用于生产环境。问题是这三种环境不一定都是一样的;它们没有同样的工具、框架和库。你在你机器上开发的应用不一定可以在生产环境中正常工作。 -容器解决了这个问题。正如 Docker 解释的,“容器镜像是软件的一个轻量的,独立的,可执行的包,包括了执行它所需要的所有东西:代码,运行环境,系统工具,系统库,设置。” +容器解决了这个问题。正如 Docker 解释的,“容器镜像是软件的一个轻量的、独立的、可执行的包,包括了执行它所需要的所有东西:代码、运行环境、系统工具、系统库、设置。” -这代表着,一旦一个应用被封装成容器,那么它所依赖的下层环境就不再重要了。它可以在任何地方运行,甚至在混合云环境下也可以。这是容器在开发者,执行团队,甚至 CIO (信息主管)中变得如此流行的原因之一。 +这代表着,一旦一个应用被封装成容器,那么它所依赖的下层环境就不再重要了。它可以在任何地方运行,甚至在混合云环境下也可以。这是容器在开发人员,执行团队,甚至 CIO (信息主管)中变得如此流行的原因之一。 -### 容器对开发者的好处 +### 容器对开发人员的好处 -现在开发者或执行者不再需要关注他们要使用什么平台来运行应用。开发者不会再说:“这在我的系统上运行得好好的。” +现在开发人员或运维人员不再需要关注他们要使用什么平台来运行应用。开发人员不会再说:“这在我的系统上运行得好好的。” -容器的另一个重大优势时它的隔离性和安全性。因为容器将应用和运行平台隔离开了,应用以及它周边的东西都会变得安全。同时,不同的团队可以在一台设备上同时运行不同的应用——对于传统应用来说这是不可以的。 +容器的另一个重大优势是它的隔离性和安全性。因为容器将应用和运行平台隔离开了,应用以及它周边的东西都会变得安全。同时,不同的团队可以在一台设备上同时运行不同的应用——对于传统应用来说这是不可以的。 -这不是虚拟机( VM )所提供的吗?是的,也不是。虚拟机可以隔离应用,但它负载太高了。[在一份文献中][1],Canonical 比较了容器和虚拟机,结果是:“容器提供了一种新的虚拟化方法,它有着和传统虚拟机几乎相同的资源隔离水平。但容器的负载更小,它占用更少的内存,更为高效。这意味着可以实现高密度的虚拟化:一旦安装,你可以在相同的硬件上运行更多应用。”另外,虚拟机启动前需要更多的准备,而容器只需几秒就能运行,可以瞬间启动。 +这不是虚拟机( VM )所提供的吗?既是,也不是。虚拟机可以隔离应用,但它负载太高了。[在一份文献中][1],Canonical 比较了容器和虚拟机,结果是:“容器提供了一种新的虚拟化方法,它有着和传统虚拟机几乎相同的资源隔离水平。但容器的负载更小,它占用更少的内存,更为高效。这意味着可以实现高密度的虚拟化:一旦安装,你可以在相同的硬件上运行更多应用。”另外,虚拟机启动前需要更多的准备,而容器只需几秒就能运行,可以瞬间启动。 ### 容器对应用生态的好处 -现在,一个庞大的,由供应商和解决方案组成的生态系统已经允许公司大规模地运用容器,不管是用于编排,监控,记录,或者生命周期管理。 +现在,一个庞大的,由供应商和解决方案组成的生态系统已经可以让公司大规模地运用容器,不管是用于编排、监控、记录或者生命周期管理。 -为了保证容器可以运行在任何地方,容器生态系统一起成立了[开源容器倡议][2](OCI)。这是一个 Linux 基金会的项目,目标在于创建关于容器运行环境和容器镜像格式这两个容器核心部分的规范。这两个规范确保容器空间中不会有任何碎片。 +为了保证容器可以运行在任何地方,容器生态系统一起成立了[开源容器倡议][2](OCI)。这是一个 Linux 基金会的项目,目标在于创建关于容器运行环境和容器镜像格式这两个容器核心部分的规范。这两个规范确保容器领域中不会有任何不一致。 -在很长的一段时间里,容器是专门用于 Linux 内核的,但微软和 Docker 的密切合作将容器带到了微软平台上。现在你可以在 Linux,Windows,Azure,AWS,Google 计算引擎,Rackspace,以及大型计算机上使用容器。甚至 VMware 也正在发展容器,它的 [vSphere Integrated Container][3](VIC)允许 IT 专业人员在他们平台的传统工作负载上运行容器。 +在很长的一段时间里,容器是专门用于 Linux 内核的,但微软和 Docker 的密切合作将容器带到了微软平台上。现在你可以在 Linux、Windows、Azure、AWS、Google 计算引擎、Rackspace,以及大型计算机上使用容器。甚至 VMware 也正在发展容器,它的 [vSphere Integrated Container][3](VIC)允许 IT 专业人员在他们平台的传统工作负载上运行容器。 ### 容器对 CIO 的好处 -容器在开发者中因为以上的原因而变得十分流行,同时他们也给CIO提供了很大的便利。将工作负载迁移到容器中的优势正在改变着公司运行的模式。 +容器在开发人员中因为以上的原因而变得十分流行,同时他们也给 CIO 提供了很大的便利。将工作负载迁移到容器中的优势正在改变着公司运行的模式。 -传统的应用有大约十年的生命周期。新版本的发布需要多年的努力,因为应用是独立于平台的,有时需要经过几年的努力才能看到生产效果。由于这个生命周期,开发者会尽可能在应用里塞满各种功能,这会使应用变得庞大笨拙,漏洞百出。 +传统的应用有大约十年的生命周期。新版本的发布需要多年的努力,因为应用是依赖于平台的,有时几年也不能到达产品阶段。由于这个生命周期,开发人员会尽可能在应用里塞满各种功能,这会使应用变得庞大笨拙,漏洞百出。 这个过程影响了公司内部的创新文化。当人们几个月甚至几年都不能看到他们的创意被实现时,他们就不再有动力了。 -容器解决了这个问题。因为你可以将应用切分成更小的微服务。你可以在几周或几天内开发,测试和部署。新特性可以添加成为新的容器。他们可以在测试结束后以最快的速度被投入生产。公司可以更快转型,超过他们的竞争者。因为想法可以被很快转化为容器并部署,这个方式使得创意爆炸式增长。 +容器解决了这个问题。因为你可以将应用切分成更小的微服务。你可以在几周或几天内开发、测试和部署。新特性可以添加成为新的容器。他们可以在测试结束后以最快的速度被投入生产。公司可以更快转型,超过他们的竞争者。因为想法可以被很快转化为容器并部署,这个方式使得创意爆炸式增长。 ### 结论 -容器解决了许多传统工作负载所面对的问题。但是,它并不能解决所有 IT 专业人员面对的问题。它只是众多解决方案中的一个。在下一篇文章中,我们将会覆盖一些容器的基本属于,然后我们会解释如何开始构建容器。 +容器解决了许多传统工作负载所面对的问题。但是,它并不能解决所有 IT 专业人员面对的问题。它只是众多解决方案中的一个。在下一篇文章中,我们将会覆盖一些容器的基本术语,然后我们会解释如何开始构建容器。 通过 Linux 基金会和 edX 提供的免费的 ["Introduction to Linux" ][4] 课程学习更多 Linux 知识。 @@ -46,9 +49,9 @@ via: https://www.linux.com/blog/intro-to-Linux/2017/12/what-are-containers-and-why-should-you-care -作者:[wapnil Bhartiya][a] +作者:[SWAPNIL BHARTIYA][a] 译者:[lonaparte](https://github.com/lonaparte) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171218 Whats CGManager.md b/published/201803/20171218 Whats CGManager.md similarity index 100% rename from published/20171218 Whats CGManager.md rename to published/201803/20171218 Whats CGManager.md diff --git a/published/201803/20171221 Mail transfer agent (MTA) basics.md b/published/201803/20171221 Mail transfer agent (MTA) basics.md new file mode 100644 index 0000000000..dc0c2bba91 --- /dev/null +++ b/published/201803/20171221 Mail transfer agent (MTA) basics.md @@ -0,0 +1,277 @@ +邮件传输代理(MTA)基础 +====== + +### 概述 + +本教程中,你将学习: + + * 使用 `mail` 命令。 + * 创建邮件别名。 + * 配置电子邮件转发。 + * 了解常见邮件传输代理(MTA),比如,postfix、sendmail、qmail、以及 exim。 + +### 控制邮件去向 + +Linux 系统上的电子邮件是使用 MTA 投递的。你的 MTA 投递邮件到你的系统上的其他用户,并且 MTA 彼此通讯跨越系统投递到全世界。 + +Sendmail 是最古老的 Linux MTA。它最初起源于 1979 年用于阿帕网(ARPANET)的 delivermail 程序。如今它有几个替代品,在本教程中,我也会介绍它们。 + +#### 前提条件 + +为完成本系列教程的大部分内容,你需要具备 Linux 的基础知识,你需要拥有一个 Linux 系统来实践本教程中的命令。你应该熟悉 GNU 以及 UNIX 命令。有时候不同版本的程序的输出格式可能不同,因此,在你的系统中输出的结果可能与我在下面列出的稍有不同。 + +在本教程中,我使用的是 Ubuntu 14.04 LTS 和 sendmail 8.14.4 来做的演示。 + +### 邮件传输 + +邮件传输代理(比如 sendmail)在用户之间和系统之间投递邮件。大量的因特网邮件使用简单邮件传输协议(SMTP),但是本地邮件可能是通过文件或者套接字等其它可能的方式来传输的。邮件是一种存储和转发的操作,因此,在用户接收邮件或者接收系统和通讯联系可用之前,邮件一直是存储在某种文件或者数据库中。配置和确保 MTA 的安全是非常复杂的任务,它们中的大部分内容都已经超出了本教程的范围。 + +### mail 命令 + +如果你使用 SMTP 协议传输电子邮件,你或许知道你可以使用许多邮件客户端,包括 `mail`、`mutt`、`alpine`、`notmuch`、以及其它基于主机控制台或者图形界面的邮件客户端。`mail` 命令是最老的、可用于脚本中的、发送和接收以及管理收到的邮件的备用命令。 + +你可以使用 `mail` 命令交互式的向列表中的收件人发送信息,或者不使用参数去查看你收到的邮件。清单 1 展示了如何在你的系统上去发送信息到用户 steve 和 pat,同时抄送拷贝给用户 bob。当提示 `Cc:` 和 `subject:` 时,输入相应的抄送用户以及邮件主题,接着输入邮件正文,输入完成后按下 `Ctrl+D` (按下 `Ctrl` 键并保持再按下 `D` 之后全部松开)。 + +``` +ian@attic4-u14:~$ mail steve,pat +Cc: bob +Subject: Test message 1 +This is a test message + +Ian +``` + +*清单 1. 使用 `mail` 交互式发送邮件* + +如果一切顺利,你的邮件已经发出。如果在这里发生错误,你将看到错误信息。例如,如果你在接收者列表中输入一个无效的用户名,邮件将无法发送。注意在本示例中,所有的用户都在本地系统上存在,因此他们都是有效用户。 + +你也可以使用命令行以非交互式发送邮件。清单 2 展示了如何给用户 steve 和 pat 发送一封邮件。这种方式可以用在脚本中。在不同的软件包中 `mail` 命令的版本不同。对于抄送(`Cc:`)有些支持一个 `-c` 选项,但是我使用的这个版本不支持这个选项,因此,我仅将邮件发送到收件人。 + +``` +ian@attic4-u14:~$ mail -t steve,pat -s "Test message 2" <<< "Another test.\n\nIan" +``` + +*清单 2. 使用 `mail` 命令非交互式发送邮件* + +如果你使用没有选项的 `mail` 命令,你将看到一个如清单 3 中所展示的那样一个收到信息的列表。你将看到用户 steve 有我上面发送的两个信息,再加上我以前发送的一个信息和后来用户 bob 发送的信息。所有的邮件都用 'N' 标记为新邮件。 + +``` +steve@attic4-u14:~$ mail +"/var/mail/steve": 4 messages 4 new +>N 1 Ian Shields Tue Dec 12 21:03 16/704 test message + N 2 Ian Shields Tue Dec 12 21:04 18/701 Test message 1 + N 3 Ian Shields Tue Dec 12 21:23 15/661 Test message 2 + N 4 Bob C Tue Dec 12 21:45 17/653 How about lunch tomorrow? +? +``` + +*清单 3. 使用 `mail` 查看收到的邮件* + +当前选中的信息使用一个 `>` 来标识,它是清单 3 中的第一封邮件。如果你按下回车键(`Enter`),将显示下一封未读邮件的第一页。按下空格楗将显示这个邮件的下一页。当你读完这个邮件并想返回到 `?` 提示符时,按下回车键再次查看下一封邮件,依次类推。在 `?` 提示符下,你可以输入 `h` 再次去查看邮件头。你看过的邮件前面将显示一个 `R` 状态,如清单 4 所示。 + +``` +? h + R 1 Ian Shields Tue Dec 12 21:03 16/704 test message + R 2 Ian Shields Tue Dec 12 21:04 18/701 Test message 1 +>R 3 Ian Shields Tue Dec 12 21:23 15/661 Test message 2 + N 4 Bob C Tue Dec 12 21:45 17/653 How about lunch tomorrow? +? +``` + +*清单 4. 使用 `h` 去显示邮件头* + +在这个图中,Steve 已经读了三个邮件,但是没有读来自 bob 的邮件。你可以通过数字来选择单个的信息,你也可以通过输入 `d` 删除你不想要的信息,或者输入 `3d` 去删除第三个信息。如果你输入 `q` 你将退出 `mail` 命令。已读的信息将被转移到你的家目录下的 `mbox` 文件中,而未读的信息仍然保留在你的收件箱中,默认在 `/var/mail/$(id -un)`。如清单 5 所示。 + +``` +? h + R 1 Ian Shields Tue Dec 12 21:03 16/704 test message + R 2 Ian Shields Tue Dec 12 21:04 18/701 Test message 1 +>R 3 Ian Shields Tue Dec 12 21:23 15/661 Test message 2 + N 4 Bob C Tue Dec 12 21:45 17/653 How about lunch tomorrow? +? q +Saved 3 messages in /home/steve/mbox +Held 1 message in /var/mail/steve +You have mail in /var/mail/steve +``` + +*清单 5. 使用 `q` 退出 `mail`* + +如果你输入 `x` 而不是使用 `q` 去退出,你的邮箱在退出后将不保留你做的改变。因为这在 `/var` 文件系统中,你的系统管理员可能仅允许邮件在一个有限的时间范围内保留。要重新读取或者以其它方式再次处理保存在你的本地邮箱中的邮件,你可以使用 `-f` 选项去指定想要去读的文件。比如,`mail -f mbox`。 + +### 邮件别名 + +在前面的节中,看了如何在系统上给许多用户发送邮件。你可以使用一个全限定名字(比如 ian@myexampledomain.com)给其它系统上的用户发送邮件。 + +有时候你可能希望用户的所有邮件都可以发送到其它地方。比如,你有一个服务器群,你希望所有的 root 用户的邮件都发给中心的系统管理员。或者你可能希望去创建一个邮件列表,将邮件发送给一些人。为实现上述目标,你可以使用别名,别名允许你为一个给定的用户名定义一个或者多个目的地。这个目的地或者是其它用户的邮箱、文件、管道、或者是某个进一步处理的命令。你可以在 `/etc/mail/aliases` 或者 `/etc/aliases` 中创建别名来实现上述目的。根据你的系统的不同,你可以找到上述其中一个,符号链接到它们、或者其中之一。改变别名文件你需要有 root 权限。 + +别名的格式一般是: + +``` +name: addr_1, addr_2, addr_3, ... +``` + +这里 `name` 是一个要别名的本地用户名字(即别名),而 `addr_1`,`addr_2`,... 可以是一个或多个别名。别名可以是一个本地用户、一个本地文件名、另一个别名、一个命令、一个包含文件,或者一个外部地址。 + +因此,发送邮件时如何区分别名呢(addr-N)? + + * 本地用户名是你机器上系统中的一个用户名字。从技术角度来说,它可以通过调用 `getpwnam` 命令找到它。 + * 本地文件名是以 `/` 开始的完全路径和文件名。它必须是 `sendmail` 可写的。信息会追加到这个文件上。 + * 命令是以一个管道符号开始的(`|`)。信息是通过标准输入的方式发送到命令的。 + * 包含文件别名是以 `:include:` 和指定的路径和文件名开始的。在该文件中的别名被添加到该名字所代表的别名中。 + * 外部地址是一个电子邮件地址,比如 john@somewhere.com。 + +你可以在你的系统中找到一个示例文件,它是与你的 sendmail 包一起安装的,它的位置在 `/usr/share/sendmail/examples/db/aliases`。它包含一些给 `postmaster`、`MAILER-DAEMON`、`abuse` 和 `spam 的别名建议。在清单 6,我把我的 Ubuntu 14.04 LTS 系统上的一些示例文件,和人工修改的示例结合起来说明一些可能的情况。 + +``` +ian@attic4-u14:~$ cat /etc/mail/aliases +# First include some default system aliases from +# /usr/share/sendmail/examples/db/aliases + +# +# Mail aliases for sendmail +# +# You must run newaliases(1) after making changes to this file. +# + +# Required aliases +postmaster: root +MAILER-DAEMON: postmaster + +# Common aliases +abuse: postmaster +spam: postmaster + +# Other aliases + +# Send steve's mail to bob and pat instead +steve: bob,pat + +# Send pat's mail to a file in her home directory and also to her inbox. +# Finally send it to a command that will make another copy. +pat: /home/pat/accumulated-mail, + \pat, + |/home/pat/makemailcopy.sh + +# Mailing list for system administrators +sysadmins: :include: /etc/aliases-sysadmins +``` + +*清单 6. 人工修改的 /etc/mail/aliases 示例* + +注意那个 pat 既是一个别名也是一个系统中的用户。别名是以递归的方式展开的,因此,如果一个别名也是一个名字,那么它将被展开。Sendmail 并不会给同一个用户发送相同的邮件两遍,因此,如果你正好将 pat 作为 pat 的别名,那么 sendmail 在已经找到并处理完用户 pat 之后,将忽略别名 pat。为避免这种问题,你可以在别名前使用一个 `\` 做为前缀去指示它是一个不要进一步引起混淆的名字。在这种情况下,pat 的邮件除了文件和命令之外,其余的可能会被发送到他的正常的邮箱中。 + +在 `aliases` 文件中以 `#` 开始的行是注释,它会被忽略。以空白开始的行会以延续行来处理。 + +清单 7 展示了包含文件 `/etc/aliases-sysadmins`。 + +``` +ian@attic4-u14:~$ cat /etc/aliases-sysadmins + +# Mailing list for system administrators +bob,pat +``` + +*清单 7 包含文件 /etc/aliases-sysadmins* + +### newaliases 命令 + +sendmail 使用的主要配置文件会被编译成数据库文件。邮件别名也是如此。你可以使用 `newaliases` 命令去编译你的 `/etc/mail/aliases` 和任何包含文件到 `/etc/mail/aliases.db` 中。注意,`newaliases` 命令等价于 `sendmail -bi`。清单 8 展示了一个示例。 + +``` +ian@attic4-u14:~$ sudo newaliases +/etc/mail/aliases: 7 aliases, longest 62 bytes, 184 bytes total +ian@attic4-u14:~$ ls -l /etc/mail/aliases* +lrwxrwxrwx 1 root smmsp 10 Dec 8 15:48 /etc/mail/aliases -> ../aliases +-rw-r----- 1 smmta smmsp 12288 Dec 13 23:18 /etc/mail/aliases.db +``` + +*清单 8. 为邮件别名重建数据库* + +### 使用别名的示例 + +清单 9 展示了一个简单的 shell 脚本,它在我的别名示例中以一个命令的方式来使用。 + +``` +ian@attic4-u14:~$ cat ~pat/makemailcopy.sh +#!/bin/bash + +# Note: Target file ~/mail-copy must be writeable by sendmail! +cat >> ~pat/mail-copy +``` + +*清单 9. makemailcopy.sh 脚本* + +清单 10 展示了用于测试时更新的文件。 + +``` +ian@attic4-u14:~$ date +Wed Dec 13 22:54:22 EST 2017 +ian@attic4-u14:~$ mail -t sysadmins -s "sysadmin test 1" <<< "Testing mail" +ian@attic4-u14:~$ ls -lrt $(find /var/mail ~pat -type f -mmin -3 2>/dev/null ) +-rw-rw---- 1 pat mail 2046 Dec 13 22:54 /home/pat/mail-copy +-rw------- 1 pat mail 13240 Dec 13 22:54 /var/mail/pat +-rw-rw---- 1 pat mail 9442 Dec 13 22:54 /home/pat/accumulated-mail +-rw-rw---- 1 bob mail 12522 Dec 13 22:54 /var/mail/bob +``` + +*清单 10. /etc/aliases-sysadmins 包含文件* + +需要注意的几点: + + * sendmail 使用的用户和组的名字是 mail。 + * sendmail 在 `/var/mail` 保存用户邮件,它也是用户 mail 的家目录。用户 ian 的默认收件箱在 `/var/mail/ian` 中。 + * 如果你希望 sendmail 在用户目录下写入文件,这个文件必须允许 sendmail 可写入。与其让任何人都可以写入,还不如定义一个组可写入,组名称为 mail。这需要系统管理员来帮你完成。 + +### 使用一个 `.forward` 文件去转发邮件 + +别名文件是由系统管理员来管理的。个人用户可以使用它们自己的家目录下的 `.forward` 文件去转发他们自己的邮件。你可以在你的 `.forward` 文件中放任何可以出现在别名文件的右侧的东西。这个文件的内容是明文的,不需要编译。当你收到邮件时,sendmail 将检查你的家目录中的 `.forward` 文件,然后就像处理别名一样处理它。 + +### 邮件队列和 mailq 命令 + +Linux 邮件使用存储-转发的处理模式。你已经看到的已接收邮件,在你读它之前一直保存在文件 `/var/mail` 中。你发出的邮件在接收服务器连接可用之前也会被保存。你可以使用 `mailq` 命令去查看邮件队列。清单 11 展示了一个发送给外部用户 ian@attic4-c6 的一个邮件示例,以及运行 `mailq` 命令的结果。在这个案例中,当前服务器没有连接到 attic4-c6,因此邮件在与对方服务器连接可用之前一直保存在队列中。 + +``` +ian@attic4-u14:~$ mail -t ian@attic4-c6 -s "External mail" <<< "Testing external mail queues" +ian@attic4-u14:~$ mailq +MSP Queue status... +/var/spool/mqueue-client is empty + Total requests: 0 +MTA Queue status... + /var/spool/mqueue (1 request) +-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient----------- +vBE4mdE7025908* 29 Wed Dec 13 23:48 + + Total requests: 1 +``` + +*清单 11. 使用 `mailq` 命令* + +### 其它邮件传输代理 + +为解决使用 sendmail 时安全方面的问题,在上世纪九十年代开发了几个其它的邮件传输代理。Postfix 或许是最流行的一个,但是 qmail 和 exim 也大量使用。 + +Postfix 是 IBM 为代替 sendmail 而研发的。它更快、也易于管理、安全性更好一些。从外表看它非常像 sendmail,但是它的内部完全与 sendmail 不同。 + +Qmail 是一个安全、可靠、高效、简单的邮件传输代理,它由 Dan Bernstein 开发。但是,最近几年以来,它的核心包已经不再更新了。Qmail 和几个其它的包已经被吸收到 IndiMail 中了。 + +Exim 是另外一个 MTA,它由 University of Cambridge 开发。最初,它的名字是 `EXperimental Internet Mailer`。 + +所有的这些 MTA 都是为代替 sendmail 而设计的,因此,它们它们都兼容 sendmail 的一些格式。它们都能够处理别名和 `.forward` 文件。有些封装了一个 `sendmail` 命令作为一个到特定的 MTA 自有命令的前端。尽管一些选项可能会被静默忽略,但是大多数都允许使用常见的 sendmail 选项。`mailq` 命令是被直接支持的,或者使用一个类似功能的命令来代替。比如,你可以使用 `mailq` 或者 `exim -bp` 去显示 exim 邮件队列。当然,输出可以看到与 sendmail 的 `mailq` 命令的不同之外。 + +查看相关的主题,你可以找到更多的关于这些 MTA 的更多信息。 + +对 Linux 上的邮件传输代理的介绍到此结束。 + +-------------------------------------------------------------------------------- + +via: https://www.ibm.com/developerworks/library/l-lpic1-108-3/index.html + +作者:[Ian Shields][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ibm.com +[1]:http://www.lpi.org +[2]:https://www.ibm.com/developerworks/library/l-lpic1-map/ diff --git a/published/20180102 HTTP errors in WordPress.md b/published/201803/20180102 HTTP errors in WordPress.md similarity index 100% rename from published/20180102 HTTP errors in WordPress.md rename to published/201803/20180102 HTTP errors in WordPress.md diff --git a/published/201803/20180102 How To Find (Top-10) Largest Files In Linux.md b/published/201803/20180102 How To Find (Top-10) Largest Files In Linux.md new file mode 100644 index 0000000000..12726d369d --- /dev/null +++ b/published/201803/20180102 How To Find (Top-10) Largest Files In Linux.md @@ -0,0 +1,177 @@ +如何在 Linux 中查找最大的 10 个文件 +====== + +当系统的磁盘空间不足时,您可能会使用 `df`、`du` 或 `ncdu` 命令进行检查,但这些命令只会显示当前目录的文件,并不会显示整个系统范围的文件。 + +您得花费大量的时间才能用上述命令获取系统中最大的文件,因为要进入到每个目录重复运行上述命令。 + +这种方法比较麻烦,也并不恰当。 + +如果是这样,那么该如何在 Linux 中找到最大的 10 个文件呢? + +我在谷歌上搜索了很久,却没发现类似的文章,我反而看到了很多关于列出当前目录中最大的 10 个文件的文章。所以,我希望这篇文章对那些有类似需求的人有所帮助。 + +本教程中,我们将教您如何使用以下四种方法在 Linux 系统中查找最大的前 10 个文件。 + +### 方法 1 + +在 Linux 中没有特定的命令可以直接执行此操作,因此我们需要将多个命令结合使用。 + +``` +# find / -type f -print0 | xargs -0 du -h | sort -rh | head -n 10 + +1.4G /swapfile +1.1G /home/magi/ubuntu-17.04-desktop-amd64.iso +564M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA +378M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8 +377M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU +100M /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0 +93M /usr/lib/firefox/libxul.so +84M /var/lib/snapd/snaps/core_3604.snap +84M /var/lib/snapd/snaps/core_3440.snap +84M /var/lib/snapd/snaps/core_3247.snap +``` + +详解: + +- `find`:在目录结构中搜索文件的命令 +- `/`:在整个系统(从根目录开始)中查找 +- `-type`:指定文件类型 + - `f`:普通文件 +- `-print0`:在标准输出显示完整的文件名,其后跟一个空字符(null) +- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理 +- `xargs`:将标准输入转换成命令行参数的命令 +- `-0`:以空字符(null)而不是空白字符(LCTT 译者注:即空格、制表符和换行)来分割记录 +- `du -h`:以可读格式计算磁盘空间使用情况的命令 +- `sort`:对文本文件进行排序的命令 +- `-r`:反转结果 +- `-h`:用可读格式打印输出 +- `head`:输出文件开头部分的命令 +- `n -10`:打印前 10 个文件 + +### 方法 2 + +这是查找 Linux 系统中最大的前 10 个文件的另一种方法。我们依然使用多个命令共同完成这个任务。 + +``` +# find / -type f -exec du -Sh {} + | sort -rh | head -n 10 + +1.4G /swapfile +1.1G /home/magi/ubuntu-17.04-desktop-amd64.iso +564M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA +378M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8 +377M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU +100M /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0 +93M /usr/lib/firefox/libxul.so +84M /var/lib/snapd/snaps/core_3604.snap +84M /var/lib/snapd/snaps/core_3440.snap +84M /var/lib/snapd/snaps/core_3247.snap +``` + +详解: + +- `find`:在目录结构中搜索文件的命令 +- `/`:在整个系统(从根目录开始)中查找 +- `-type`:指定文件类型 + - `f`:普通文件 +- `-exec`:在所选文件上运行指定命令 +- `du`:计算文件占用的磁盘空间的命令 +- `-S`:不包含子目录的大小 +- `-h`:以可读格式打印 +- `{}`:递归地查找目录,统计每个文件占用的磁盘空间 +- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理 +- `sort`:对文本文件进行按行排序的命令 +- `-r`:反转结果 +- `-h`:用可读格式打印输出 +- `head`:输出文件开头部分的命令 +- `n -10`:打印前 10 个文件 + +### 方法 3 + +这里介绍另一种在 Linux 系统中搜索最大的前 10 个文件的方法。 + +``` +# find / -type f -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {} + +84M /var/lib/snapd/snaps/core_3247.snap +84M /var/lib/snapd/snaps/core_3440.snap +84M /var/lib/snapd/snaps/core_3604.snap +93M /usr/lib/firefox/libxul.so +100M /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0 +377M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU +378M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8 +564M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA +1.1G /home/magi/ubuntu-17.04-desktop-amd64.iso +1.4G /swapfile +``` + +详解: + +- `find`:在目录结构中搜索文件的命令 +- `/`:在整个系统(从根目录开始)中查找 +- `-type`:指定文件类型 + - `f`:普通文件 +- `-print0`:输出完整的文件名,其后跟一个空字符(null) +- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理 +- `xargs`:将标准输入转换成命令行参数的命令 +- `-0`:以空字符(null)而不是空白字符来分割记录 +- `du`:计算文件占用的磁盘空间的命令 +- `sort`:对文本文件进行按行排序的命令 +- `-n`:根据数字大小进行比较 +- `tail -10`:输出文件结尾部分的命令(最后 10 个文件) +- `cut`:从每行删除特定部分的命令 +- `-f2`:只选择特定字段值 +- `-I{}`:将初始参数中出现的每个替换字符串都替换为从标准输入读取的名称 +- `-s`:仅显示每个参数的总和 +- `-h`:用可读格式打印输出 +- `{}`:递归地查找目录,统计每个文件占用的磁盘空间 + +### 方法 4 + +还有一种在 Linux 系统中查找最大的前 10 个文件的方法。 + +``` +# find / -type f -ls | sort -k 7 -r -n | head -10 | column -t | awk '{print $7,$11}' + +1494845440 /swapfile +1085984380 /home/magi/ubuntu-17.04-desktop-amd64.iso +591003648 /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA +395770383 /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8 +394891761 /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU +103999072 /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0 +97356256 /usr/lib/firefox/libxul.so +87896064 /var/lib/snapd/snaps/core_3604.snap +87793664 /var/lib/snapd/snaps/core_3440.snap +87089152 /var/lib/snapd/snaps/core_3247.snap +``` + +详解: + +- `find`:在目录结构中搜索文件的命令 +- `/`:在整个系统(从根目录开始)中查找 +- `-type`:指定文件类型 + - `f`:普通文件 +- `-ls`:在标准输出中以 `ls -dils` 的格式列出当前文件 +- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理 +- `sort`:对文本文件进行按行排序的命令 +- `-k`:按指定列进行排序 +- `-r`:反转结果 +- `-n`:根据数字大小进行比较 +- `head`:输出文件开头部分的命令 +- `-10`:打印前 10 个文件 +- `column`:将其输入格式化为多列的命令 +- `-t`:确定输入包含的列数并创建一个表 +- `awk`:模式扫描和处理语言 +- `'{print $7,$11}'`:只打印指定的列 + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-find-search-check-print-top-10-largest-biggest-files-in-linux/ + +作者:[Magesh Maruthamuthu][a] +译者:[jessie-pang](https://github.com/jessie-pang) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/magesh/ \ No newline at end of file diff --git a/published/201803/20180104 Tlog - A Tool to Record - Play Terminal IO and Sessions.md b/published/201803/20180104 Tlog - A Tool to Record - Play Terminal IO and Sessions.md new file mode 100644 index 0000000000..a27b805aad --- /dev/null +++ b/published/201803/20180104 Tlog - A Tool to Record - Play Terminal IO and Sessions.md @@ -0,0 +1,98 @@ +Tlog:录制/播放终端 IO 和会话的工具 +====== + +Tlog 是 Linux 中终端 I/O 录制和回放软件包。它用于实现一个集中式用户会话录制。它将所有经过的消息录制为 JSON 消息。录制为 JSON 格式的主要目的是将数据传送到 ElasticSearch 之类的存储服务,可以从中搜索和查询,以及回放。同时,它们保留所有通过的数据和时序。 + +Tlog 包含三个工具,分别是 `tlog-rec`、tlog-rec-session` 和 `tlog-play`。 + + * `tlog-rec` 工具一般用于录制终端、程序或 shell 的输入或输出。 + * `tlog-rec-session` 工具用于录制整个终端会话的 I/O,包括录制的用户。 + * `tlog-play` 工具用于回放录制。 + +在本文中,我将解释如何在 CentOS 7.4 服务器上安装 Tlog。 + +### 安装 + +在安装之前,我们需要确保我们的系统满足编译和安装程序的所有软件要求。在第一步中,使用以下命令更新系统仓库和软件包。 + +``` +# yum update +``` + +我们需要安装此软件安装所需的依赖项。在安装之前,我已经使用这些命令安装了所有依赖包。 + +``` +# yum install wget gcc +# yum install systemd-devel json-c-devel libcurl-devel m4 +``` + +完成这些安装后,我们可以下载该工具的[源码包][1]并根据需要将其解压到服务器上: + +``` +# wget https://github.com/Scribery/tlog/releases/download/v3/tlog-3.tar.gz +# tar -xvf tlog-3.tar.gz +# cd tlog-3 +``` + +现在,你可以使用我们通常的配置和编译方法开始构建此工具。 + +``` +# ./configure --prefix=/usr --sysconfdir=/etc && make +# make install +# ldconfig +``` + +最后,你需要运行 `ldconfig`。它对命令行中指定目录、`/etc/ld.so.conf` 文件,以及信任的目录( `/lib` 和 `/usr/lib`)中最近的共享库创建必要的链接和缓存。 + +### Tlog 工作流程图 + +![Tlog working process][2] + +首先,用户通过 PAM 进行身份验证登录。名称服务交换器(NSS)提供的 `tlog` 信息是用户的 shell。这初始化了 tlog 部分,并从环境变量/配置文件收集关于实际 shell 的信息,并在 PTY 中启动实际的 shell。然后通过 syslog 或 sd-journal 开始录制在终端和 PTY 之间传递的所有内容。 + +### 用法 + +你可以使用 `tlog-rec` 录制一个会话并使用 `tlog-play` 回放它,以测试新安装的 tlog 是否能够正常录制和回放会话。 + +#### 录制到文件中 + +要将会话录制到文件中,请在命令行中执行 `tlog-rec`,如下所示: + +``` +tlog-rec --writer=file --file-path=tlog.log +``` + +该命令会将我们的终端会话录制到名为 `tlog.log` 的文件中,并将其保存在命令中指定的路径中。 + +#### 从文件中回放 + +你可以在录制过程中或录制后使用 `tlog-play` 命令回放录制的会话。 + +``` +tlog-play --reader=file --file-path=tlog.log +``` + +该命令从指定的路径读取先前录制的文件 `tlog.log`。 + +### 总结 + +Tlog 是一个开源软件包,可用于实现集中式用户会话录制。它主要是作为一个更大的用户会话录制解决方案的一部分使用,但它被设计为独立且可重用的。该工具可以帮助录制用户所做的一切,并将其存储在服务器的某个位置,以备将来参考。你可以从这个[文档][3]中获得关于这个软件包使用的更多细节。我希望这篇文章对你有用。请发表你的宝贵建议和意见。 + +**关于 Saheetha Shameer (作者)** + +我正在担任高级系统管理员。我是一名快速学习者,有轻微的倾向跟随行业中目前和正在出现的趋势。我的爱好包括听音乐、玩策略游戏、阅读和园艺。我对尝试各种美食也有很高的热情 :-) + +-------------------------------------------------------------------------------- + +via: https://linoxide.com/linux-how-to/tlog-tool-record-play-terminal-io-sessions/ + +作者:[Saheetha Shameer][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/saheethas/ +[1]:https://github.com/Scribery/tlog/releases/download/v3/tlog-3.tar.gz +[2]:https://linoxide.com/wp-content/uploads/2018/01/Tlog-working-process.png +[3]:https://github.com/Scribery/tlog/blob/master/README.md diff --git a/published/201803/20180105 Ansible- the Automation Framework That Thinks Like a Sysadmin.md b/published/201803/20180105 Ansible- the Automation Framework That Thinks Like a Sysadmin.md new file mode 100644 index 0000000000..4c85c4f811 --- /dev/null +++ b/published/201803/20180105 Ansible- the Automation Framework That Thinks Like a Sysadmin.md @@ -0,0 +1,180 @@ +Ansible:像系统管理员一样思考的自动化框架 +====== + +这些年来,我已经写了许多关于 DevOps 工具的文章,也培训了这方面的人员。尽管这些工具很棒,但很明显,大多数都是按照开发人员的思路设计出来的。这也没有什么问题,因为以编程的方式接近配置管理是重点。不过,直到我开始接触 Ansible,我才觉得这才是系统管理员喜欢的东西。 + +喜欢的一部分原因是 Ansible 与客户端计算机通信的方式,是通过 SSH 的。作为系统管理员,你们都非常熟悉通过 SSH 连接到计算机,所以从单词“去”的角度来看,相对于其它选择,你更容易理解 Ansible。 + +考虑到这一点,我打算写一些文章,探讨如何使用 Ansible。这是一个很好的系统,但是当我第一次接触到这个系统的时候,不知道如何开始。这并不是学习曲线陡峭。事实上,问题是在开始使用 Ansible 之前,我并没有太多的东西要学,这才是让人感到困惑的。例如,如果您不必安装客户端程序(Ansible 没有在客户端计算机上安装任何软件),那么您将如何启动? + +### 踏出第一步 + +起初 Ansible 对我来说非常困难的原因在于配置服务器/客户端的关系是非常灵活的,我不知道我该从何入手。事实是,Ansible 并不关心你如何设置 SSH 系统。它会利用你现有的任何配置。需要考虑以下几件事情: + +1. Ansible 需要通过 SSH 连接到客户端计算机。 +2. 连接后,Ansible 需要提升权限才能配置系统,安装软件包等等。 + +不幸的是,这两个考虑真的带来了一堆蠕虫。连接到远程计算机并提升权限是一件可怕的事情。当您在远程计算机上安装代理并使用 Chef 或 Puppet 处理特权升级问题时,似乎感觉就没那么可怕了。 Ansible 并非不安全,而是安全的决定权在你手中。 + +接下来,我将列出一系列潜在的配置,以及每个配置的优缺点。这不是一个详尽的清单,但是你会受到正确的启发,去思考在你自己的环境中什么是理想的配置。也需要注意,我不会提到像 Vagrant 这样的系统,因为尽管 Vagrant 在构建测试和开发的敏捷架构时非常棒,但是和一堆服务器是非常不同的,因此考虑因素是极不相似的。 + +### 一些 SSH 场景 + +#### 1)在 Ansible 配置中,root 用户以密码进入远程计算机。 + +拥有这个想法是一个非常可怕的开始。这个设置的“优点”是它消除了对特权提升的需要,并且远程服务器上不需要其他用户帐户。 但是,这种便利的成本是不值得的。 首先,大多数系统不会让你在不改变默认配置的情况下以 root 身份进行 SSH 登录。默认的配置之所以如此,坦率地说,是因为允许 root 用户远程连接是一个不好的主意。 其次,将 root 密码放在 Ansible 机器上的纯文本配置文件中是不合适的。 真的,我提到了这种可能性,因为这是可以的,但这是应该避免的。 请记住,Ansible 允许你自己配置连接,它可以让你做真正愚蠢的事情。 但是请不要这么做。 + +#### 2)使用存储在 Ansible 配置中的密码,以普通用户的身份进入远程计算机。 + +这种情况的一个优点是它不需要太多的客户端配置。 大多数用户默认情况下都可以使用 SSH,因此 Ansible 应该能够使用用户凭据并且能够正常登录。 我个人不喜欢在配置文件中以纯文本形式存储密码,但至少它不是 root 密码。 如果您使用此方法,请务必考虑远程服务器上的权限提升方式。 我知道我还没有谈到权限提升,但是如果你在配置文件中配置了一个密码,这个密码可能会被用来获得 sudo 访问权限。 因此,一旦发生泄露,您不仅已经泄露了远程用户的帐户,还可能泄露整个系统。 + +#### 3)使用具有空密码的密钥对进行身份验证,以普通用户身份进入远程计算机。 + +这消除了将密码存储在配置文件中的弊端,至少在登录的过程中消除了。 没有密码的密钥对并不理想,但这是我经常做的事情。 在我的个人内部网络中,我通常使用没有密码的密钥对来自动执行许多事情,如需要身份验证的定时任务。 这不是最安全的选择,因为私钥泄露意味着可以无限制地访问远程用户的帐户,但是相对于在配置文件中存储密码我更喜欢这种方式。 + +#### 4)使用通过密码保护的密钥对进行身份验证,以普通用户的身份通过 SSH 连接到远程计算机。 + +这是处理远程访问的一种非常安全的方式,因为它需要两种不同的身份验证因素来解密:私钥和密码。 如果你只是以交互方式运行 Ansible,这可能是理想的设置。 当你运行命令时,Ansible 会提示你输入私钥的密码,然后使用密钥对登录到远程系统。 是的,只需使用标准密码登录并且不用在配置文件中指定密码即可完成,但是如果不管怎样都要在命令行上输入密码,那为什么不在保护层添加密钥对呢? + +#### 5)使用密码保护密钥对进行 SSH 连接,但是使用 ssh-agent “解锁”私钥。 + +这并不能完美地解决无人值守、自动化的 Ansible 命令的问题,但是它确实也使安全设置变得相当方便。 ssh-agent 程序一次验证密码,然后使用该验证进行后续连接。当我使用 Ansible 时,这是我想要做的事情。如果我是完全值得信任的,我通常仍然使用没有密码的密钥对,但是这通常是因为我在我的家庭服务器上工作,是不是容易受到攻击的。 + +在配置 SSH 环境时还要记住一些其他注意事项。 也许你可以限制 Ansible 用户(通常是你的本地用户),以便它只能从一个特定的 IP 地址登录。 也许您的 Ansible 服务器可以位于不同的子网中,位于强大的防火墙之后,因此其私钥更难以远程访问。 也许 Ansible 服务器本身没有安装 SSH 服务器,所以根本没法访问。 同样,Ansible 的优势之一是它使用 SSH 协议进行通信,而且这是一个你用了多年的协议,你已经把你的系统调整到最适合你的环境了。 我不是宣传“最佳实践”的忠实粉丝,因为实际上最好的做法是考虑你的环境,并选择最适合你情况的设置。 + +### 权限提升 + +一旦您的 Ansible 服务器通过 SSH 连接到它的客户端,就需要能够提升特权。 如果你选择了上面的选项 1,那么你已经是 root 了,这是一个有争议的问题。 但是由于没有人选择选项 1(对吧?),您需要考虑客户端计算机上的普通用户如何获得访问权限。 Ansible 支持各种权限提升的系统,但在 Linux 中,最常用的选项是 `sudo` 和 `su`。 和 SSH 一样,有几种情况需要考虑,虽然肯定还有其他选择。 + +#### 1)使用 su 提升权限。 + +对于 RedHat/CentOS 用户来说,可能默认是使用 `su` 来获得系统访问权限。 默认情况下,这些系统在安装过程中配置了 root 密码,要想获得特殊访问权限,您需要输入该密码。使用 `su` 的问题在于,虽说它可以给了您完全访问远程系统,而您确实也可以完全访问远程系统。 (是的,这是讽刺。)另外,`su` 程序没有使用密钥对进行身份验证的能力,所以密码必须以交互方式输入或存储在配置文件中。 由于它实际上是 root 密码,因此将其存储在配置文件中听起来像、也确实是一个可怕的想法。 + +#### 2)使用 sudo 提升权限。 + +这就是 Debian/Ubuntu 系统的配置方式。 正常用户组中的用户可以使用 `sudo` 命令并使用 root 权限执行该命令。 随之而来的是,这仍然存在密码存储或交互式输入的问题。 由于在配置文件中存储用户的密码看起来不太可怕,我猜这是使用 `su` 的一个进步,但是如果密码被泄露,仍然可以完全访问系统。 (毕竟,输入 `sudo` 和 `su -` 都将允许用户成为 root 用户,就像拥有 root 密码一样。) + +#### 3) 使用 sudo 提升权限,并在 sudoers 文件中配置 NOPASSWD。 + +再次,在我的本地环境中,我就是这么做的。 这并不完美,因为它给予用户帐户无限制的 root 权限,并且不需要任何密码。 但是,当我这样做并且使用没有密码短语的 SSH 密钥对时,我可以让 Ansible 命令更轻松的自动化。 再次提示,虽然这很方便,但这不是一个非常安全的想法。 + +#### 4)使用 sudo 提升权限,并在特定的可执行文件上配置 NOPASSWD。 + +这个想法可能是安全性和便利性的最佳折衷。 基本上,如果你知道你打算用 Ansible 做什么,那么你可以为远程用户使用的那些应用程序提供 NOPASSWD 权限。 这可能会让人有些困惑,因为 Ansible 使用 Python 来处理很多事情,但是经过足够的尝试和错误,你应该能够弄清原理。 这是额外的工作,但确实消除了一些明显的安全漏洞。 + +### 计划实施 + +一旦你决定如何处理 Ansible 认证和权限提升,就需要设置它。 在熟悉 Ansible 之后,您可能会使用该工具来帮助“引导”新客户端,但首先手动配置客户端非常重要,以便您知道发生了什么事情。 将你熟悉的事情变得自动化比从头开始自动化要好。 + +我已经写过关于 SSH 密钥对的文章,网上有无数的设置类的文章。 来自 Ansible 服务器的简短版本看起来像这样: + +``` +# ssh-keygen +# ssh-copy-id -i .ssh/id_dsa.pub remoteuser@remote.computer.ip +# ssh remoteuser@remote.computer.ip +``` + +如果您在创建密钥对时选择不使用密码,最后一步您应该可以直接进入远程计算机,而不用输入密码或密钥串。 + +为了在 `sudo` 中设置权限提升,您需要编辑 `sudoers` 文件。 你不应该直接编辑文件,而是使用: + +``` +# sudo visudo +``` + +这将打开 `sudoers` 文件并允许您安全地进行更改(保存时会进行错误检查,所以您不会意外地因为输入错误将自己锁住)。 这个文件中有一些例子,所以你应该能够弄清楚如何分配你想要的确切的权限。 + +一旦配置完成,您应该在使用 Ansible 之前进行手动测试。 尝试 SSH 到远程客户端,然后尝试使用您选择的任何方法提升权限。 一旦你确认配置的方式可以连接,就可以安装 Ansible 了。 + +### 安装 Ansible + +由于 Ansible 程序仅安装在一台计算机上,因此开始并不是一件繁重的工作。 Red Hat/Ubuntu 系统的软件包安装有点不同,但都不是很困难。 + +在 Red Hat/CentOS 中,首先启用 EPEL 库: + +``` +sudo yum install epel-release +``` + +然后安装 Ansible: + +``` +sudo yum install ansible +``` + +在 Ubuntu 中,首先启用 Ansible PPA: + +``` +sudo apt-add-repository spa:ansible/ansible +(press ENTER to access the key and add the repo) +``` + +然后安装 Ansible: + +``` +sudo apt-get update +sudo apt-get install ansible +``` + +### Ansible 主机文件配置 + +Ansible 系统无法知道您希望它控制哪个客户端,除非您给它一个计算机列表。 该列表非常简单,看起来像这样: + +``` +# file /etc/ansible/hosts + +[webservers] +blogserver ansible_host=192.168.1.5 +wikiserver ansible_host=192.168.1.10 + +[dbservers] +mysql_1 ansible_host=192.168.1.22 +pgsql_1 ansible_host=192.168.1.23 +``` + +方括号内的部分是指定的组。 单个主机可以列在多个组中,而 Ansible 可以指向单个主机或组。 这也是配置文件,比如纯文本密码的东西将被存储,如果这是你计划的那种设置。 配置文件中的每一行配置一个主机地址,并且可以在 `ansible_host` 语句之后添加多个声明。 一些有用的选项是: + +``` +ansible_ssh_pass +ansible_become +ansible_become_method +ansible_become_user +ansible_become_pass +``` + +### Ansible 保险库Vault + +(LCTT 译注:Vault 作为 ansible 的一项新功能可将例如密码、密钥等敏感数据文件进行加密,而非明文存放) + +我也应该注意到,尽管安装程序比较复杂,而且这不是在您首次进入 Ansible 世界时可能会做的事情,但该程序确实提供了一种加密保险库中的密码的方法。 一旦您熟悉 Ansible,并且希望将其投入生产,将这些密码存储在加密的 Ansible 保险库中是非常理想的。 但是本着先学会爬再学会走的精神,我建议首先在非生产环境下使用无密码方法。 + +### 系统测试 + +最后,你应该测试你的系统,以确保客户端可以正常连接。 `ping` 测试将确保 Ansible 计算机可以 `ping` 每个主机: + +``` +ansible -m ping all +``` + +运行后,如果 `ping` 成功,您应该看到每个定义的主机显示 `ping` 的消息:`pong`。 这实际上并没有测试认证,只是测试网络连接。 试试这个来测试你的认证: + +``` +ansible -m shell -a 'uptime' webservers +``` + +您应该可以看到 webservers 组中每个主机的运行时间命令的结果。 + +在后续文章中,我计划开始深入 Ansible 管理远程计算机的功能。 我将介绍各种模块,以及如何使用 ad-hoc 模式来完成一些按键操作,这些操作在命令行上单独处理都需要很长时间。 如果您没有从上面的示例 Ansible 命令中获得预期的结果,请花些时间确保身份验证可以工作。 如果遇到困难,请查阅 [Ansible 文档][1]获取更多帮助。 + +-------------------------------------------------------------------------------- + +via: http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin + +作者:[Shawn Powers][a] +译者:[Flowsnow](https://github.com/Flowsnow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxjournal.com/users/shawn-powers +[1]:http://docs.ansible.com diff --git a/published/20180109 How to use syslog-ng to collect logs from remote Linux machines.md b/published/201803/20180109 How to use syslog-ng to collect logs from remote Linux machines.md similarity index 100% rename from published/20180109 How to use syslog-ng to collect logs from remote Linux machines.md rename to published/201803/20180109 How to use syslog-ng to collect logs from remote Linux machines.md diff --git a/published/20180110 Best Linux Screenshot and Screencasting Tools.md b/published/201803/20180110 Best Linux Screenshot and Screencasting Tools.md similarity index 100% rename from published/20180110 Best Linux Screenshot and Screencasting Tools.md rename to published/201803/20180110 Best Linux Screenshot and Screencasting Tools.md diff --git a/published/20180110 How to install-update Intel microcode firmware on Linux.md b/published/201803/20180110 How to install-update Intel microcode firmware on Linux.md similarity index 100% rename from published/20180110 How to install-update Intel microcode firmware on Linux.md rename to published/201803/20180110 How to install-update Intel microcode firmware on Linux.md diff --git a/published/201803/20180111 How to install software applications on Linux.md b/published/201803/20180111 How to install software applications on Linux.md new file mode 100644 index 0000000000..9116e438be --- /dev/null +++ b/published/201803/20180111 How to install software applications on Linux.md @@ -0,0 +1,232 @@ +如何在 Linux 上安装应用程序 +===== + +> 学习在你的 Linux 计算机上摆弄那些软件。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux-penguins.png?itok=yKOpaJM_) + +图片提供:Internet Archive Book Images。由 Opensource.com 修改。CC BY-SA 4.0 + +如何在 Linux 上安装应用程序?因为有许多操作系统,这个问题不止有一个答案。应用程序可以可以来自许多来源 —— 几乎不可能数的清,并且每个开发团队都可以以他们认为最好的方式提供软件。知道如何安装你所得到的软件是成为操作系统高级用户的一部分。 + +### 仓库 + +十多年来,Linux 已经在使用软件库来分发软件。在这种情况下,“仓库”是一个托管可安装软件包的公共服务器。Linux 发行版提供了一条命令,以及该命令的图形界面,用于从服务器获取软件并将其安装到你的计算机。这是一个非常简单的概念,它已经成为所有主流手机操作系统的模式,最近,该模式也成为了两大闭源计算机操作系统的“应用商店”。 + +![Linux repository][2] + +*不是应用程序商店* + +从软件仓库安装是在 Linux 上安装应用程序的主要方法,它应该是你寻找想要安装的任何应用程序的首选地方。 + +从软件仓库安装,通常需要一个命令,如: + +``` +$ sudo dnf install inkscape +``` + +实际使用的命令取决于你所使用的 Linux 发行版。Fedora 使用 `dnf`,OpenSUSE 使用 `zypper`,Debian 和 Ubuntu 使用 `apt`,Slackware 使用 `sbopkg`,FreeBSD 使用 `pkg_add`,而基于 lllumos 的 Openlndiana 使用 `pkg`。无论你使用什么,该命令通常要搜索你想要安装应用程序的正确名称,因为有时候你认为的软件名称不是它官方或独有的名称: + +``` +$ sudo dnf search pyqt +PyQt.x86_64 : Python bindings for Qt3 +PyQt4.x86_64 : Python bindings for Qt4 +python-qt5.x86_64 : PyQt5 is Python bindings for Qt5 +``` + +一旦你找到要安装的软件包的名称后,使用 `install` 子命令执行实际的下载和自动安装: + +``` +$ sudo dnf install python-qt5 +``` + +有关从软件仓库安装的具体信息,请参阅你的 Linux 发行版的文档。 + +图形工具通常也是如此。搜索你认为你想要的,然后安装它。 + +![](https://opensource.com/sites/default/files/u128651/apper.png) + +与底层命令一样,图形安装程序的名称取决于你正在运行的 Linux 发行版。相关的应用程序通常使用“软件(software)”或“包(package)”等关键字进行标记,因此请在你的启动项或菜单中搜索这些词汇,然后你将找到所需的内容。 由于开源全由用户来选择,所以如果你不喜欢你的发行版提供的图形用户界面(GUI),那么你可以选择安装替代品。 你知道该如何做到这一点。 + +#### 额外仓库 + +你的 Linux 发行版为其打包的软件提供了标准仓库,通常也有额外的仓库。例如,[EPEL][3] 服务于 Red Hat Enterprise Linux 和 CentOS,[RPMFusion][4] 服务于 Fedora,Ubuntu 有各种级别的支持以及个人包存档(PPA),[Packman][5] 为 OpenSUSE 提供额外的软件以及 [SlackBuilds.org][6] 为 Slackware 提供社区构建脚本。 + +默认情况下,你的 Linux 操作系统设置为只查看其官方仓库,因此如果你想使用其他软件集合,则必须自己添加额外库。你通常可以像安装软件包一样安装仓库。实际上,当你安装例如 [GNU Ring][7] 视频聊天,[Vivaldi][8] web 浏览器,谷歌浏览器等许多软件时,你的实际安装是访问他们的私有仓库,从中将最新版本的应用程序安装到你的机器上。 + +![Installing a repo][10] + +*安装仓库* + +你还可以通过编辑文本文件将仓库手动添加到你的软件包管理器的配置目录,或者运行命令来添加添加仓库。像往常一样,你使用的确切命令取决于 Linux 发行版本。例如,这是一个 `dnf` 命令,它将一个仓库添加到系统中: + +``` +$ sudo dnf config-manager --add-repo=http://example.com/pub/centos/7 +``` + +### 不使用仓库来安装应用程序 + +仓库模型非常流行,因为它提供了用户(你)和开发人员之间的链接。重要更新发布之后,系统会提示你接受更新,并且你可以从一个集中位置接受所有更新。 + +然而,有时候一个软件包还没有放到仓库中时。这些安装包有几种形式。 + +#### Linux 包 + +有时候,开发人员会以通用的 Linux 打包格式分发软件,例如 RPM、DEB 或较新但非常流行的 FlatPak 或 Snap 格式。你不是访问仓库下载的,你只是得到了这个包。 + +例如,视频编辑器 [Lightworks][11] 为 APT 用户提供了一个 `.deb` 文件,RPM 用户提供了 `.rpm` 文件。当你想要更新时,可以到网站下载最新的适合的文件。 + +这些一次性软件包可以使用从仓库进行安装时所用的一样的工具进行安装。如果双击下载的软件包,图形安装程序将启动并逐步完成安装过程。 + +或者,你可以从终端进行安装。这里的区别在于你从互联网下载的独立包文件不是来自仓库。这是一个“本地”安装,这意味着你的软件安装包不需要下载来安装。大多数软件包管理器都是透明处理的: + +``` +$ sudo dnf install ~/Downloads/lwks-14.0.0-amd64.rpm +``` + +在某些情况下,你需要采取额外的步骤才能使应用程序运行,因此请仔细阅读有关你正在安装软件的文档。 + +#### 通用安装脚本 + +一些开发人员以几种通用格式发布他们的包。常见的扩展名包括 `.run` 和 `.sh`。NVIDIA 显卡驱动程序、像 Nuke 和 Mari 这样的 Foundry visual FX 软件包以及来自 [GOG][12] 的许多非 DRM 游戏都是用这种安装程序。(LCTT 译注:DRM 是数字版权管理。) + +这种安装模式依赖于开发人员提供安装“向导”。一些安装程序是图形化的,而另一些只是在终端中运行。 + +有两种方式来运行这些类型的安装程序。 + +1、 你可以直接从终端运行安装程序: + +``` +$ sh ./game/gog_warsow_x.y.z.sh +``` + +2、 另外,你可以通过标记其为可执行文件来运行它。要标记为安装程序可执行文件,右键单击它的图标并选择其属性。 + +![Giving an installer executable permission][14] + +*给安装程序可执行权限。* + +一旦你允许其运行,双击图标就可以安装了。 + +![GOG installer][16] + +*GOG 安装程序* + +对于其余的安装程序,只需要按照屏幕上的说明进行操作。 + +#### AppImage 便携式应用程序 + +AppImage 格式对于 Linux 相对来说比较新,尽管它的概念是基于 NeXT 和 Rox 的。这个想法很简单:运行应用程序所需的一切都应该放在一个目录中,然后该目录被视为一个“应用程序”。要运行该应用程序,只需双击该图标即可运行。不需要也要不应该把应用程序安装在传统意义的地方;它从你在硬盘上的任何地方运行都行。 + +尽管它可以作为独立应用运行,但 AppImage 通常提供一些系统集成。 + +![AppImage system integration][18] + +*AppImage 系统集成* + +如果你接受此条件,则将一个本地的 `.desktop` 文件安装到你的主目录。`.desktop` 文件是 Linux 桌面的应用程序菜单和 mimetype 系统使用的一个小配置文件。实质上,只是将桌面配置文件放置在主目录的应用程序列表中“安装”应用程序,而不实际安装它。你获得了安装某些东西的所有好处,以及能够在本地运行某些东西的好处,即“便携式应用程序”。 + +#### 应用程序目录 + +有时,开发人员只是编译一个应用程序,然后将结果发布到下载中,没有安装脚本,也没有打包。通常,这意味着你下载了一个 TAR 文件,然后 [解压缩][19],然后双击可执行文件(通常是你下载软件的名称)。 + +![Twine downloaded for Linux][21] + +*下载 Twine* + +当使用这种软件方式交付时,你可以将它放在你下载的地方,当你需要它时,你可以手动启动它,或者你可以自己进行快速但是麻烦的安装。这包括两个简单的步骤: + +1. 将目录保存到一个标准位置,并在需要时手动启动它。 +2. 将目录保存到一个标准位置,并创建一个 `.desktop` 文件,将其集成到你的系统中。 + +如果你只是为自己安装应用程序,那么传统上会在你的主目录中放个 `bin` (“二进制文件binary” 的简称)目录作为本地安装的应用程序和脚本的存储位置。如果你的系统上有其他用户需要访问这些应用程序,传统上将二进制文件放置在 `/opt` 中。最后,这取决于你存储应用程序的位置。 + +下载通常以带版本名称的目录进行,如 `twine_2.13` 或者 `pcgen-v6.07.04`。由于假设你将在某个时候更新应用程序,因此将版本号删除或创建目录的符号链接是个不错的主意。这样,即使你更新应用程序本身,为应用程序创建的启动程序也可以保持不变。 + +要创建一个 `.desktop` 启动文件,打开一个文本编辑器并创建一个名为 `twine.desktop` 的文件。[桌面条目规范][22] 由 [FreeDesktop.org][23] 定义。下面是一个简单的启动器,用于一个名为 Twine 的游戏开发 IDE,安装在系统范围的 `/opt` 目录中: + +``` +[Desktop Entry] +Encoding=UTF-8 +Name=Twine +GenericName=Twine +Comment=Twine +Exec=/opt/twine/Twine +Icon=/usr/share/icons/oxygen/64x64/categories/applications-games.png +Terminal=false +Type=Application +Categories=Development;IDE; +``` + +棘手的一行是 `Exec` 行。它必须包含一个有效的命令来启动应用程序。通常,它只是你下载的东西的完整路径,但在某些情况下,它更复杂一些。例如,Java 应用程序可能需要作为 Java 自身的参数启动。 + +``` +Exec=java -jar /path/to/foo.jar +``` + +有时,一个项目包含一个可以运行的包装脚本,这样你就不必找出正确的命令: + +``` +Exec=/opt/foo/foo-launcher.sh +``` + +在这个 Twine 例子中,没有与该下载的软件捆绑的图标,因此示例 `.desktop` 文件指定了 KDE 桌面附带的通用游戏图标。你可以使用类似的解决方法,但如果你更具艺术性,可以创建自己的图标,或者可以在 Internet 上搜索一个好的图标。只要 `Icon` 行指向一个有效的 PNG 或 SVG 文件,你的应用程序就会以该图标为代表。 + +示例脚本还将应用程序类别主要设置为 Development,因此在 KDE、GNOME 和大多数其他应用程序菜单中,Twine 出现在开发类别下。 + +为了让这个例子出现在应用程序菜单中,把 `twine.desktop` 文件放这到两个地方之一: + +* 如果你将应用程序存储在你自己的家目录下,那么请将其放在 `~/.local/share/applications`。 +* 如果你将应用程序存储在 `/opt` 目录或者其他系统范围的位置,并希望它出现在所有用户的应用程序菜单中,请将它放在 `/usr/share/applications` 目录中。 + +现在,该应用程序已安装,因为它需要与系统的其他部分集成。 + +### 从源代码编译 + +最后,还有真正的通用格式安装格式:源代码。从源代码编译应用程序是学习如何构建应用程序,如何与系统交互以及如何定制应用程序的好方法。尽管如此,它绝不是一个点击按钮式过程。它需要一个构建环境,通常需要安装依赖库和头文件,有时还要进行一些调试。 + +要了解更多关于从源代码编译的内容,请阅读[我这篇文章][24]。 + +### 现在你明白了 + +有些人认为安装软件是一个神奇的过程,只有开发人员理解,或者他们认为它“激活”了应用程序,就好像二进制可执行文件在“安装”之前无效。学习许多不同的安装方法会告诉你安装实际上只是“将文件从一个地方复制到系统中适当位置”的简写。 没有什么神秘的。只要你去了解每次安装,不是期望应该如何发生,并且寻找开发者为安装过程设置了什么,那么通常很容易,即使它与你的习惯不同。 + +重要的是安装器要诚实于你。 如果你遇到未经你的同意尝试安装其他软件的安装程序(或者它可能会以混淆或误导的方式请求同意),或者尝试在没有明显原因的情况下对系统执行检查,则不要继续安装。 + +好的软件是灵活的、诚实的、开放的。 现在你知道如何在你的计算机上获得好软件了。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/how-install-apps-linux + +作者:[Seth Kenlon][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/seth +[1]:/file/382591 +[2]:https://opensource.com/sites/default/files/u128651/repo.png (Linux repository) +[3]:https://fedoraproject.org/wiki/EPEL +[4]:http://rpmfusion.org +[5]:http://packman.links2linux.org/ +[6]:http://slackbuilds.org +[7]:https://ring.cx/en/download/gnu-linux +[8]:http://vivaldi.com +[9]:/file/382566 +[10]:https://opensource.com/sites/default/files/u128651/access.png (Installing a repo) +[11]:https://www.lwks.com/ +[12]:http://gog.com +[13]:/file/382581 +[14]:https://opensource.com/sites/default/files/u128651/exec.jpg (Giving an installer executable permission) +[15]:/file/382586 +[16]:https://opensource.com/sites/default/files/u128651/gog.jpg (GOG installer) +[17]:/file/382576 +[18]:https://opensource.com/sites/default/files/u128651/appimage.png (AppImage system integration) +[19]:https://opensource.com/article/17/7/how-unzip-targz-file +[20]:/file/382596 +[21]:https://opensource.com/sites/default/files/u128651/twine.jpg (Twine downloaded for Linux) +[22]:https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html +[23]:http://freedesktop.org +[24]:https://opensource.com/article/17/10/open-source-cats diff --git a/published/20180111 The Fold Command Tutorial With Examples For Beginners.md b/published/201803/20180111 The Fold Command Tutorial With Examples For Beginners.md similarity index 100% rename from published/20180111 The Fold Command Tutorial With Examples For Beginners.md rename to published/201803/20180111 The Fold Command Tutorial With Examples For Beginners.md diff --git a/published/20180116 A Versatile Free Software for Partition Imaging and Cloning.md b/published/201803/20180116 A Versatile Free Software for Partition Imaging and Cloning.md similarity index 100% rename from published/20180116 A Versatile Free Software for Partition Imaging and Cloning.md rename to published/201803/20180116 A Versatile Free Software for Partition Imaging and Cloning.md diff --git a/published/20180116 Analyzing the Linux boot process.md b/published/201803/20180116 Analyzing the Linux boot process.md similarity index 100% rename from published/20180116 Analyzing the Linux boot process.md rename to published/201803/20180116 Analyzing the Linux boot process.md diff --git a/published/20180116 SPARTA - Network Penetration Testing GUI Toolkit.md b/published/201803/20180116 SPARTA - Network Penetration Testing GUI Toolkit.md similarity index 100% rename from published/20180116 SPARTA - Network Penetration Testing GUI Toolkit.md rename to published/201803/20180116 SPARTA - Network Penetration Testing GUI Toolkit.md diff --git a/published/20180117 How To Manage Vim Plugins Using Vundle On Linux.md b/published/201803/20180117 How To Manage Vim Plugins Using Vundle On Linux.md similarity index 100% rename from published/20180117 How To Manage Vim Plugins Using Vundle On Linux.md rename to published/201803/20180117 How To Manage Vim Plugins Using Vundle On Linux.md diff --git a/published/20180117 Linux tee Command Explained for Beginners (6 Examples).md b/published/201803/20180117 Linux tee Command Explained for Beginners (6 Examples).md similarity index 100% rename from published/20180117 Linux tee Command Explained for Beginners (6 Examples).md rename to published/201803/20180117 Linux tee Command Explained for Beginners (6 Examples).md diff --git a/published/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md b/published/201803/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md similarity index 100% rename from published/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md rename to published/201803/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md diff --git a/published/20180119 How to install Spotify application on Linux.md b/published/201803/20180119 How to install Spotify application on Linux.md similarity index 100% rename from published/20180119 How to install Spotify application on Linux.md rename to published/201803/20180119 How to install Spotify application on Linux.md diff --git a/translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md b/published/201803/20180123 Never miss a Magazine-s article, build your own RSS notification system.md similarity index 70% rename from translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md rename to published/201803/20180123 Never miss a Magazine-s article, build your own RSS notification system.md index acd94006d8..feb3acbe71 100644 --- a/translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md +++ b/published/201803/20180123 Never miss a Magazine-s article, build your own RSS notification system.md @@ -1,4 +1,4 @@ -构建你自己的 RSS 提示系统——让杂志文章一篇也不会错过 +用 Python 构建你自己的 RSS 提示系统 ====== ![](https://fedoramagazine.org/wp-content/uploads/2018/01/learn-python-rss-notifier.png-945x400.jpg) @@ -7,9 +7,9 @@ ### Fedora 和 Python —— 入门知识 -Python 3.6 在 Fedora 中是默认安装的,它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如,在我们的案例中,我们将使用 [**sqlite3**][1] 模块在数据库中去创建表、添加和读取数据。在这个案例中,我们试图去解决的是在标准库中没有的特定的问题,也有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 [PyPI][2] Python 包索引去搜索一下。在我们的示例中,我们将使用 [**feedparser**][3] 去解析 RSS 源。 +Python 3.6 在 Fedora 中是默认安装的,它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如,在我们的案例中,我们将使用 [sqlite3][1] 模块在数据库中去创建表、添加和读取数据。在这个案例中,我们试图去解决的是这样的一个特定问题,在标准库中没有包含,而有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 [PyPI][2] Python 包索引去搜索一下。在我们的示例中,我们将使用 [feedparser][3] 去解析 RSS 源。 -因为 **feedparser** 并不是标准库,我们需要将它安装到我们的系统上。幸运的是,在 Fedora 中有这个 RPM 包,因此,我们可以运行如下的命令去安装 **feedparser**: +因为 feedparser 并不是标准库,我们需要将它安装到我们的系统上。幸运的是,在 Fedora 中有这个 RPM 包,因此,我们可以运行如下的命令去安装 feedparser: ``` $ sudo dnf install python3-feedparser ``` @@ -18,11 +18,12 @@ $ sudo dnf install python3-feedparser ### 存储源数据 -我们需要存储已经发布的文章的数据,这样我们的系统就可以只提示新发布的文章。我们要保存的数据将是用来辨别一篇文章的唯一方法。因此,我们将存储文章的**标题**和**发布日期**。 +我们需要存储已经发布的文章的数据,这样我们的系统就可以只提示新发布的文章。我们要保存的数据将是用来辨别一篇文章的唯一方法。因此,我们将存储文章的标题和发布日期。 -因此,我们来使用 Python **sqlite3** 模块和一个简单的 SQL 语句来创建我们的数据库。同时也添加一些后面将要用到的模块(**feedparse**,**smtplib**,和 **email**)。 +因此,我们来使用 Python sqlite3 模块和一个简单的 SQL 语句来创建我们的数据库。同时也添加一些后面将要用到的模块(feedparse,smtplib,和 email)。 #### 创建数据库 + ``` #!/usr/bin/python3 import sqlite3 @@ -34,14 +35,14 @@ import feedparser db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite') db = db_connection.cursor() db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)') - ``` -这几行代码创建一个新的保存在一个名为 'magazine_rss.sqlite' 文件中的 sqlite 数据库,然后在数据库创建一个名为 'magazine' 的新表。这个表有两个列 —— 'title' 和 'date' —— 它们能存诸 TEXT 类型的数据,也就是说每个列的值都是文本字符。 +这几行代码创建一个名为 `magazine_rss.sqlite` 文件的新 sqlite 数据库,然后在数据库创建一个名为 `magazine` 的新表。这个表有两个列 —— `title` 和 `date` —— 它们能存诸 TEXT 类型的数据,也就是说每个列的值都是文本字符。 #### 检查数据库中的旧文章 由于我们仅希望增加新的文章到我们的数据库中,因此我们需要一个功能去检查 RSS 源中的文章在数据库中是否存在。我们将根据它来判断是否发送(有新文章的)邮件提示。Ok,现在我们来写这个功能的代码。 + ``` def article_is_not_db(article_title, article_date): """ Check if a given pair of article title and date @@ -60,13 +61,14 @@ def article_is_not_db(article_title, article_date): return False ``` -这个功能的主要部分是一个 SQL 查询,我们运行它去搜索数据库。我们使用一个 SELECT 命令去定义我们将要在哪个列上运行这个查询。我们使用 `*` 符号去选取所有列(title 和 date)。然后,我们使用查询的 WHERE 条件 `article_title` and `article_date` 去匹配标题和日期列中的值,以检索出我们需要的内容。 +这个功能的主要部分是一个 SQL 查询,我们运行它去搜索数据库。我们使用一个 `SELECT` 命令去定义我们将要在哪个列上运行这个查询。我们使用 `*` 符号去选取所有列(`title` 和 `date`)。然后,我们使用查询的 `WHERE` 条件 `article_title` 和 `article_date` 去匹配标题和日期列中的值,以检索出我们需要的内容。 最后,我们使用一个简单的返回 `True` 或者 `False` 的逻辑来表示是否在数据库中找到匹配的文章。 #### 在数据库中添加新文章 现在我们可以写一些代码去添加新文章到数据库中。 + ``` def add_article_to_db(article_title, article_date): """ Add a new article title and date to the database @@ -78,13 +80,14 @@ def add_article_to_db(article_title, article_date): db_connection.commit() ``` -这个功能很简单,我们使用了一个 SQL 查询去插入一个新行到 'magazine' 表的 article_title 和 article_date 列中。然后提交它到数据库中永久保存。 +这个功能很简单,我们使用了一个 SQL 查询去插入一个新行到 `magazine` 表的 `article_title` 和 `article_date` 列中。然后提交它到数据库中永久保存。 这些就是在数据库中所需要的东西,接下来我们看一下,如何使用 Python 实现提示系统和发送电子邮件。 ### 发送电子邮件提示 -我们来使用 Python 标准库模块 **smtplib** 来创建一个发送电子邮件的功能。我们也可以使用标准库中的 **email** 模块去格式化我们的电子邮件信息。 +我们使用 Python 标准库模块 smtplib 来创建一个发送电子邮件的功能。我们也可以使用标准库中的 email 模块去格式化我们的电子邮件信息。 + ``` def send_notification(article_title, article_url): """ Add a new article title and date to the database @@ -113,6 +116,7 @@ def send_notification(article_title, article_url): ### 读取 Fedora Magazine 的 RSS 源 我们已经有了在数据库中存储文章和发送提示电子邮件的功能,现在来创建一个解析 Fedora Magazine RSS 源并提取文章数据的功能。 + ``` def read_article_feed(): """ Get articles from RSS feed """ @@ -127,25 +131,26 @@ if __name__ == '__main__': db_connection.close() ``` -在这里我们将使用 **feedparser.parse** 功能。这个功能返回一个用字典表示的 RSS 源,对于 **feedparser** 的完整描述可以参考它的 [文档][5]。 +在这里我们将使用 `feedparser.parse` 功能。这个功能返回一个用字典表示的 RSS 源,对于 feedparser 的完整描述可以参考它的 [文档][5]。 RSS 源解析将返回最后的 10 篇文章作为 `entries`,然后我们提取以下信息:标题、链接、文章发布日期。因此,我们现在可以使用前面定义的检查文章是否在数据库中存在的功能,然后,发送提示电子邮件并将这个文章添加到数据库中。 -当运行我们的脚本时,最后的 if 语句运行我们的 `read_article_feed` 功能,然后关闭数据库连接。 +当运行我们的脚本时,最后的 `if` 语句运行我们的 `read_article_feed` 功能,然后关闭数据库连接。 ### 运行我们的脚本 -给脚本文件赋于正确运行权限。接下来,我们使用 **cron** 实用程序去每小时自动运行一次我们的脚本。**cron** 是一个作业计划程序,我们可以使用它在一个固定的时间去运行一个任务。 +给脚本文件赋于正确运行权限。接下来,我们使用 cron 实用程序去每小时自动运行一次我们的脚本。cron 是一个作业计划程序,我们可以使用它在一个固定的时间去运行一个任务。 + ``` $ chmod a+x my_rss_notifier.py $ sudo cp my_rss_notifier.py /etc/cron.hourly ``` -**为了使该教程保持简单**,我们使用了 cron.hourly 目录每小时运行一次我们的脚本,如果你想学习关于 **cron** 的更多知识以及如何配置 **crontab**,请阅读 **cron** 的 wikipedia [页面][6]。 +为了使该教程保持简单,我们使用了 `cron.hourly` 目录每小时运行一次我们的脚本,如果你想学习关于 cron 的更多知识以及如何配置 crontab,请阅读 cron 的 wikipedia [页面][6]。 ### 总结 -在本教程中,我们学习了如何使用 Python 去创建一个简单的 sqlite 数据库、解析一个 RSS 源、以及发送电子邮件。我希望通过这篇文章能够向你展示,**使用 Python 和 Fedora 构建你自己的应用程序是件多么容易的事**。 +在本教程中,我们学习了如何使用 Python 去创建一个简单的 sqlite 数据库、解析一个 RSS 源、以及发送电子邮件。我希望通过这篇文章能够向你展示,使用 Python 和 Fedora 构建你自己的应用程序是件多么容易的事。 这个脚本在 [GitHub][7] 上可以找到。 @@ -155,7 +160,7 @@ via: https://fedoramagazine.org/never-miss-magazines-article-build-rss-notificat 作者:[Clément Verna][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180124 4 cool new projects to try in COPR for January.md b/published/201803/20180124 4 cool new projects to try in COPR for January.md similarity index 73% rename from translated/tech/20180124 4 cool new projects to try in COPR for January.md rename to published/201803/20180124 4 cool new projects to try in COPR for January.md index 68b131967f..a52feb9270 100644 --- a/translated/tech/20180124 4 cool new projects to try in COPR for January.md +++ b/published/201803/20180124 4 cool new projects to try in COPR for January.md @@ -1,21 +1,22 @@ -一月 COPR 中 4 个新的很酷的项目 +COPR 仓库中 4 个很酷的新软件 ====== ![](https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg) -COPR 是一个个人软件仓库[集合][1],它们不存在于 Fedora 中。有些软件不符合标准而不容易打包。或者它可能不符合其他的 Fedora 标准,尽管它是免费和开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 支持或者由项目自己签名。但是,它是尝试新的或实验性软件的一种很好的方法。 +COPR 是一个个人软件仓库[集合][1],它们不存在于 Fedora 中。有些软件不符合标准而不容易打包。或者它可能不符合其他的 Fedora 标准,尽管它是自由和开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己签名的。但是,它是尝试新的或实验性软件的一种很好的方法。 这是 COPR 中一系列新的和有趣的项目。 ### Elisa -[Elisa][2] 是一个最小的音乐播放器。它可以让你通过专辑、艺术家或曲目浏览音乐。它会自动检测你的 ~/Music 目录中的所有可播放音乐,因此它根本不需要设置 - 它也不提供任何音乐。目前,Elisa 专注于做一个简单的音乐播放器,所以它不提供管理音乐收藏的工具。 +[Elisa][2] 是一个极小的音乐播放器。它可以让你通过专辑、艺术家或曲目浏览音乐。它会自动检测你的 `~/Music` 目录中的所有可播放音乐,因此它根本不需要设置 - 它也不提供任何音乐。目前,Elisa 专注于做一个简单的音乐播放器,所以它不提供管理音乐收藏的工具。 ![][3] #### 安装说明 仓库目前为 Fedora 26、27 和 Rawhide 提供 Elisa。要安装 Elisa,请使用以下命令: + ``` sudo dnf copr enable eclipseo/elisa sudo dnf install elisa @@ -28,6 +29,7 @@ sudo dnf install elisa #### 安装说明 仓库目前为 Fedora 25、26、27 和 Rawhide 提供必应壁纸。要安装必应壁纸,请使用以下命令: + ``` sudo dnf copr enable julekgwa/Bingwallpapers sudo dnf install bingwallpapers @@ -35,11 +37,12 @@ sudo dnf install bingwallpapers ### Polybar -[Polybar][5] 是一个创建状态栏的工具。它有很多自定义选项以及内置的功能来显示常用服务的信息,例如 [bspwm][6]、[i3][7] 的系统托盘图标、窗口标题、工作区和桌面面板等。你也可以为你的状态栏配置你自己的模块。有关使用和配置的更多信息,请参考[ Polybar 的 wiki][8]。 +[Polybar][5] 是一个创建状态栏的工具。它有很多自定义选项以及显示常用服务的信息的内置功能,例如 [bspwm][6]、[i3][7] 的系统托盘图标、窗口标题、工作区和桌面面板等。你也可以为你的状态栏配置你自己的模块。有关使用和配置的更多信息,请参考[ Polybar 的 wiki][8]。 #### 安装说明 仓库目前为 Fedora 27 提供 Polybar。要安装 Polybar,请使用以下命令: + ``` sudo dnf copr enable tomwishaupt/polybar sudo dnf install polybar @@ -59,14 +62,13 @@ sudo dnf copr enable recteurlp/netdata sudo dnf install netdata ``` - -------------------------------------------------------------------------------- via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-january/ 作者:[Dominik Turecek][a] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180125 Building a Linux-based HPC system on the Raspberry.md b/published/201803/20180125 Building a Linux-based HPC system on the Raspberry.md similarity index 64% rename from translated/tech/20180125 Building a Linux-based HPC system on the Raspberry.md rename to published/201803/20180125 Building a Linux-based HPC system on the Raspberry.md index b201690a3f..f7f8dab1fd 100644 --- a/translated/tech/20180125 Building a Linux-based HPC system on the Raspberry.md +++ b/published/201803/20180125 Building a Linux-based HPC system on the Raspberry.md @@ -1,15 +1,14 @@ 使用 Ansible 在树莓派上构建一个基于 Linux 的高性能计算系统 ============================================================ -### 使用低成本的硬件和开源软件设计一个高性能计算集群。 +> 使用低成本的硬件和开源软件设计一个高性能计算集群。 ![Building a Linux-based HPC system on the Raspberry Pi with Ansible](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82 "Building a Linux-based HPC system on the Raspberry Pi with Ansible") 图片来源:opensource.com -在我的 [Opensource.com 上前面的文章中][14],我介绍了 [OpenHPC][15] 项目,它的目标是致力于加速高性能计算(HPC)的创新。这篇文章将更深入来介绍使用 OpenHPC 的特性来构建一个小型的 HPC 系统。将它称为 _HPC 系统_  可能有点“扯虎皮拉大旗”的意思,因此,更确切的说法应该是,通过 OpenHPC 项目发布的 [方法构建集群][16] 系统。 - -这个集群由两台树莓派 3 系统作为活动计算节点,以及一台虚拟机作为主节点,结构示意如下: +在我的 [之前发表在 Opensource.com 上的文章中][14],我介绍了 [OpenHPC][15] 项目,它的目标是致力于加速高性能计算(HPC)的创新。这篇文章将更深入来介绍使用 OpenHPC 的特性来构建一个小型的 HPC 系统。将它称为 _HPC 系统_  可能有点“扯虎皮拉大旗”的意思,因此,更确切的说法应该是,它是一个基于 OpenHPC 项目发布的 [集群构建方法][16] 的系统。 +这个集群由两台树莓派 3 系统作为计算节点,以及一台虚拟机作为主节点,结构示意如下: ![Map of HPC cluster](https://opensource.com/sites/default/files/u128651/hpc_with_pi-1.png "Map of HPC cluster") @@ -17,13 +16,12 @@ 下图是真实的设备工作照: - ![HPC hardware setup](https://opensource.com/sites/default/files/u128651/hpc_with_pi-2.jpg "HPC hardware setup") -去配置一台像上图这样的 HPC 系统,我是按照 OpenHPC 集群构建方法 ——  [CentOS 7.4/aarch64 + Warewulf + Slurm 安装指南][17] (PDF) 的一些步骤来做的。这个方法包括 [Warewulf][18] 提供的使用说明;因为我的那三个系统是手动安装的,我跳过了 Warewulf 部分以及创建 [Ansible playbook][19] 的一些步骤。 +要把我的系统配置成像上图这样的 HPC 系统,我是按照 OpenHPC 的集群构建方法的 [CentOS 7.4/aarch64 + Warewulf + Slurm 安装指南][17] (PDF)的一些步骤来做的。这个方法包括了使用 [Warewulf][18] 的配置说明;因为我的那三个系统是手动安装的,我跳过了 Warewulf 部分以及创建 [Ansible 剧本][19] 的一些步骤。 +在 [Ansible][26] 剧本中设置完成我的集群之后,我就可以向资源管理器提交作业了。在我的这个案例中, [Slurm][27] 充当了资源管理器,它是集群中的一个实例,由它来决定我的作业什么时候在哪里运行。在集群上启动一个简单的作业的方式之一: -在 [Ansible][26] playbooks 中设置完成我的集群之后,我就可以向资源管理器提交作业了。在我的这个案例中, [Slurm][27] 充当了资源管理器,它是集群中的一个实例,由它来决定我的作业什么时候在哪里运行。其中一种可做的事情是,在集群上启动一个简单的作业: ``` [ohpc@centos01 ~]$ srun hostname calvin @@ -66,9 +64,9 @@ calvin Mon 11 Dec 16:42:41 UTC 2017 ``` -为示范资源管理器的基本功能、简单的和一系列的命令行工具,这个集群系统是挺合适的,但是,去配置一个类似HPC 系统去做各种工作就有点无聊了。 +为示范资源管理器的基本功能,简单的串行命令行工具就行,但是,做各种工作去配置一个类似 HPC 系统就有点无聊了。 -一个更有趣的应用是在这个集群的所有可用 CPU 上运行一个 [Open MPI][20] 并行作业。我使用了一个基于 [Game of Life][21] 的应用,它被用于一个名为“使用 Red Hat 企业版 Linux 跨多种架构运行 `Game of Life`“的 [视频][22]。除了以前实现的基于 MPI 的 `Game of Life` 之外,在我的集群中现在运行的这个版本对每个涉及的主机的单元格颜色都是不同的。下面的脚本以图形输出的方式来交互式启动应用: +一个更有趣的应用是在这个集群的所有可用 CPU 上运行一个 [Open MPI][20] 的并行作业。我使用了一个基于 [康威生命游戏][21] 的应用,它被用于一个名为“使用 Red Hat 企业版 Linux 跨多种架构运行康威生命游戏”的 [视频][22]。除了以前基于 MPI 的 `Game of Life` 版本之外,在我的集群中现在运行的这个版本对每个涉及的主机的单元格颜色都是不同的。下面的脚本以图形输出的方式来交互式启动应用: ``` $ cat life.mpi @@ -91,15 +89,13 @@ $ srun -n 8 --x11 life.mpi 为了演示,这个作业有一个图形界面,它展示了当前计算的结果: - ![](https://opensource.com/sites/default/files/u128651/hpc_with_pi-3.png) -红色单元格是由其中一个计算节点来计算的,而绿色单元格是由另外一个计算节点来计算的。我也可以让 `Game of Life` 程序为使用的每个 CPU 核心(这里的每个计算节点有四个核心)去生成不同的颜色,这样它的输出如下: - +红色单元格是由其中一个计算节点来计算的,而绿色单元格是由另外一个计算节点来计算的。我也可以让康威生命游戏程序为使用的每个 CPU 核心(这里的每个计算节点有四个核心)去生成不同的颜色,这样它的输出如下: ![](https://opensource.com/sites/default/files/u128651/hpc_with_pi-4.png) -感谢 OpenHPC 提供的软件包和安装方法,因为它们我可以去配置一个由两个计算节点和一个主节点的 HPC 式的系统。我可以在资源管理器上提交作业,然后使用 OpenHPC 提供的软件在我的树莓派的 CPU 上去启动 MPI 应用程序。 +感谢 OpenHPC 提供的软件包和安装方法,因为它们让我可以去配置一个由两个计算节点和一个主节点的 HPC 式的系统。我可以在资源管理器上提交作业,然后使用 OpenHPC 提供的软件在我的树莓派的 CPU 上去启动 MPI 应用程序。 * * * @@ -107,15 +103,15 @@ $ srun -n 8 --x11 life.mpi ### 关于作者 - [![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/gotchi-square.png?itok=PJKu7LHn)][23] Adrian Reber —— Adrian 是 Red Hat 的高级软件工程师,他早在 2010 年就开始了迁移的过程,迁移到高性能计算环境中,从那个时候起迁移了许多的程序,并因此获得了博士学位,然后加入了 Red Hat 公司并开始去迁移到容器。偶尔他仍然去迁移单个进程,并且它至今仍然对高性能计算非常感兴趣。[关于我的更多信息点这里][12] + [![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/gotchi-square.png?itok=PJKu7LHn)][23] Adrian Reber —— Adrian 是 Red Hat 的高级软件工程师,他早在 2010 年就开始了迁移处理过程到高性能计算环境,从那个时候起迁移了许多的处理过程,并因此获得了博士学位,然后加入了 Red Hat 公司并开始去迁移到容器。偶尔他仍然去迁移单个处理过程,并且它至今仍然对高性能计算非常感兴趣。[关于我的更多信息点这里][12] -------------------------------------------------------------------------------- via: https://opensource.com/article/18/1/how-build-hpc-system-raspberry-pi-and-openhpc -作者:[Adrian Reber ][a] +作者:[Adrian Reber][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180125 Keep Accurate Time on Linux with NTP.md b/published/201803/20180125 Keep Accurate Time on Linux with NTP.md similarity index 100% rename from published/20180125 Keep Accurate Time on Linux with NTP.md rename to published/201803/20180125 Keep Accurate Time on Linux with NTP.md diff --git a/translated/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md b/published/201803/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md similarity index 76% rename from translated/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md rename to published/201803/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md index 8296840a01..6825f8ccd2 100644 --- a/translated/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md +++ b/published/201803/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md @@ -1,64 +1,53 @@ 如何搭建“我的世界”服务器 ====== -我们将通过一个一步步的、新手友好的教程来向你展示如何搭建一个“我的世界”服务器。这将会是一个长期的多人游戏服务器,你可以与来自世界各地的朋友们一起玩,而不用在同一个局域网下。 + +![](https://thishosting.rocks/wp-content/uploads/2018/01/how-to-make-minecraft-server.jpg) + +我们将通过一个一步步的、新手友好的教程来向你展示如何搭建一个“我的世界(Minecraft)”服务器。这将会是一个长期的多人游戏服务器,你可以与来自世界各地的朋友们一起玩,而不用在同一个局域网下。 ### 如何搭建一个“我的世界”服务器 - 快速指南 如果你很急,想直达重点的话,这是我们的目录。我们推荐通读整篇文章。 * [学点东西][1] (可选) - * [再学点东西][2] (可选) - * [需求][3] (必读) - * [安装并运行“我的世界”服务器][4] (必读) - * [在你登出 VPS 后继续运行服务端][5] (可选) - * [让服务端随系统启动][6] (可选) - * [配置你的“我的世界”服务器][7] (必读) - * [常见问题][8] (可选) 在你开始行动之前,要先了解一些事情: -#### 为什么你不应该使用专门的“我的世界”服务器提供商 +#### 为什么你**不**应该使用专门的“我的世界”服务器提供商 既然你正在阅读这篇文章,你肯定对搭建自己的“我的世界”服务器感兴趣。不应该使用专门的“我的世界”服务器提供商的原因有很多,以下是其中一些: * 它们通常很慢。这是因为你是在和很多用户一起共享资源。这有的时候会超负荷,他们中很多都会超售。 - -* 你并不能完全控制”我的世界“服务端,或是真正的服务器。你没法按照你的意愿进行自定义。 - +* 你并不能完全控制“我的世界”服务端或真正的服务器。你没法按照你的意愿进行自定义。 * 你是受限制的。这种主机套餐或多或少都会有限制。 -当然,使用现成的提供商也是有优点的。最好的就是你不用做下面这些操作。但是那还有什么意思呢?![🙂](https://s.w.org/images/core/emoji/2.3/svg/1f642.svg) +当然,使用现成的提供商也是有优点的。最好的就是你不用做下面这些操作。但是那还有什么意思呢?! -#### 为什么不应该用你的个人电脑作为”我的世界“服务器 +#### 为什么不应该用你的个人电脑作为“我的世界”服务器 我们注意到很多教程都展示的是如何在你自己的电脑上搭建服务器。这样做有一些弊端,比如: * 你的家庭网络不够安全,无法抵挡 DDoS 攻击。游戏服务器通常容易被 DDoS 攻击,而你的家庭网络设置通常不够安全,来抵挡它们。很可能连小型攻击都无法阻挡。 - -* 你得处理端口转发。如果你试着在家庭网络中搭建”我的世界“服务器的话,你肯定会偶然发现端口转发的问题,并且处理时可能会有问题。 - +* 你得处理端口转发。如果你试着在家庭网络中搭建“我的世界”服务器的话,你肯定会偶然发现端口转发的问题,并且处理时可能会有问题。 * 你得保持你的电脑一直开着。你的电费将会突破天际,并且你会增加不必要的硬件负载。大部分服务器硬件都是企业级的,提升了稳定性和持久性,专门设计用来处理负载。 - * 你的家庭网络速度不够快。家庭网络并不是设计用来负载多人联机游戏的。即使你想搭建一个小型服务器,你也需要一个更好的网络套餐。幸运的是,数据中心有多个高速的、企业级的互联网连接,来保证他们达到(或尽量达到)100%在线。 - * 你的硬件很可能不够好。再说一次,服务器使用的都是企业级硬件,最新最快的处理器、固态硬盘,等等。你的个人电脑很可能不是的。 +* 你的个人电脑很可能是 Windows/MacOS。尽管这有所争议,但我们相信 Linux 更适合搭建游戏服务器。不用担心,搭建“我的世界”服务器不需要完全了解 Linux(尽管推荐这样)。我们会向你展示你需要了解的。 -* 你的个人电脑很可能是 Windows/MacOS。尽管这是有争议的,我们相信 Linux 更适合搭建游戏服务器。不用担心,搭建”我的世界“服务器不需要完全了解 Linux(尽管推荐这样)。我们会向你展示你需要了解的。 +我们的建议是不要使用个人电脑,即使从技术角度来说你能做到。买一个云服务器并不是很贵。下面我们会向你展示如何在云服务器上搭建“我的世界”服务端。小心地遵守以下步骤,就很简单。 -我们的建议是不要使用个人电脑,即使从技术角度来说你能做到。买一个云服务器并不是很贵。下面我们会向你展示如何在云服务器上搭建”我的世界“服务端。小心地遵守以下步骤,就很简单。 - -### 搭建一个”我的世界“服务器 - 需求 +### 搭建一个“我的世界”服务器 - 需求 这是一些需求,你在教程开始之前需要拥有并了解它们: -* 你需要一个 [Linux 云服务器][9]。我们推荐 [Vultr][10]。这家价格便宜,服务质量高,客户支持很好,并且所有的服务器硬件都很高端。检查[“我的世界”服务器需求][11]来选择你需要哪种类型的服务器(像内存和硬盘之类的资源)。我们推荐每月 20 美元的套餐。他们也支持按小时收费,所以如果你只是临时需要服务器和朋友们联机的话,你的花费会更少。注册时选择 Ubuntu 16.04 发行版。在注册时选择离你的朋友们最近的地域。这样的话你就需要保护并管理服务器。如果你不想这样的话,你可以选择[托管的服务器][],这样的话服务器提供商可能会给你搭建好一个“我的世界”服务器。 +* 你需要一个 [Linux 云服务器][9]。我们推荐 [Vultr][10]。这家价格便宜,服务质量高,客户支持很好,并且所有的服务器硬件都很高端。检查[“我的世界”服务器需求][11]来选择你需要哪种类型的服务器(像内存和硬盘之类的资源)。我们推荐每月 20 美元的套餐。他们也支持按小时收费,所以如果你只是临时需要服务器和朋友们联机的话,你的花费会更少。注册时选择 Ubuntu 16.04 发行版。在注册时选择离你的朋友们最近的地域。这样的话你就需要保护并管理服务器。如果你不想这样的话,你可以选择[托管的服务器][12],这样的话服务器提供商可能会给你搭建好一个“我的世界”服务器。 * 你需要一个 SSH 客户端来连接到你的 Linux 云服务器。新手通常建议使用 [PuTTy][13],但我们也推荐使用 [MobaXTerm][14]。也有很多 SSH 客户端,所以挑一个你喜欢的吧。 * 你需要设置你的服务器(至少做好基本的安全设置)。谷歌一下你会发现很多教程。你也可以按照 [Linode 的 安全指南][15],然后在你的 [Vultr][16] 服务器上一步步操作。 * 下面我们将会处理软件依赖,比如 Java。 @@ -67,17 +56,17 @@ ### 如何在 Ubuntu(Linux)上搭建一个“我的世界”服务器 -这篇教程是为 [Vultr][17] 上的 Ubuntu 16.04 撰写并测试可行的。但是这对 Ubuntu 14.04, [Ubuntu 18.04][18],以及其他基于 Ubuntu 的发行版,其他服务器提供商也是可行的。 +这篇教程是为 [Vultr][17] 上的 Ubuntu 16.04 撰写并测试可行的。但是这对 Ubuntu 14.04, [Ubuntu 18.04][18],以及其他基于 Ubuntu 的发行版、其他服务器提供商也是可行的。 -我们使用默认的 Vanilla 服务端。你也可以使用像 CraftBukkit 或 Spigot 这样的服务端,来支持更多的自定义和插件。虽然如果你使用过多插件的话会毁了服务端。这各有优缺点。不管怎么说,下面的教程使用默认的 Vanilla 服务端,来使事情变得简单和更新手友好。如果有兴趣的话我们可能会发表一篇 CraftBukkit 的教程。 +我们使用默认的 Vanilla 服务端。你也可以使用像 CraftBukkit 或 Spigot 这样的服务端,来支持更多的自定义和插件。虽然如果你使用过多插件的话会影响服务端。这各有优缺点。不管怎么说,下面的教程使用默认的 Vanilla 服务端,来使事情变得简单和更新手友好。如果有兴趣的话我们可能会发表一篇 CraftBukkit 的教程。 -#### 1. 登陆到你的服务器 +#### 1. 登录到你的服务器 -我们将使用 root 账户。如果你使用受限的账户的话,大部分命令都需要 ‘sudo’。做你没有权限的事情时会出现警告。 +我们将使用 root 账户。如果你使用受限的账户的话,大部分命令都需要 `sudo`。做你没有权限的事情时会出现警告。 -你可以通过 SSH 客户端来登陆你的服务器。使用你的 IP 和端口(大部分都是 22)。 +你可以通过 SSH 客户端来登录你的服务器。使用你的 IP 和端口(大部分都是 22)。 -在你登陆之后,确保你的[服务器安全][19]。 +在你登录之后,确保你的[服务器安全][19]。 #### 2. 更新 Ubuntu @@ -87,7 +76,7 @@ apt-get update && apt-get upgrade ``` -在提示时敲击“回车键” 和/或 “y”。 +在提示时敲击“回车键” 和/或 `y`。 #### 3. 安装必要的工具 @@ -113,37 +102,37 @@ mkdir /opt/minecraft cd /opt/minecraft ``` -现在你可以下载“我的世界“服务端文件了。去往[下载页面][20]获取下载链接。使用wget下载文件: +现在你可以下载“我的世界“服务端文件了。去往[下载页面][20]获取下载链接。使用 `wget` 下载文件: ``` wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar ``` -#### 5. 安装”我的世界“服务端 +#### 5. 安装“我的世界”服务端 -下载好了服务端 .jar 文件之后,你就需要先运行一下,它会生成一些文件,包括一个 eula.txt 许可文件。第一次运行的时候,它会返回一个错误并退出。这是正常的。使用下面的命令运行它: +下载好了服务端的 .jar 文件之后,你就需要先运行一下,它会生成一些文件,包括一个 `eula.txt` 许可文件。第一次运行的时候,它会返回一个错误并退出。这是正常的。使用下面的命令运行它: ``` java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui ``` -”-Xms2048M“是你的服务端能使用的最小的内存,”-Xmx3472M“是最大的。[调整][21]基于你服务器的硬件资源。如果你在 [Vultr][22] 服务器上有 4GB 内存,并且不用服务器来干其他事情的话可以就这样留着不动。 +`-Xms2048M` 是你的服务端能使用的最小的内存,`-Xmx3472M` 是最大的内存。[调整][21]基于你服务器的硬件资源。如果你在 [Vultr][22] 服务器上有 4GB 内存,并且不用服务器来干其他事情的话可以就这样留着不动。 -在这条命令结束并返回一个错误之后,将会生成一个新的 eula.txt 文件。你需要同意那个文件里的协议。你可以通过下面这条命令将”eula=true“添加到文件中: +在这条命令结束并返回一个错误之后,将会生成一个新的 `eula.txt` 文件。你需要同意那个文件里的协议。你可以通过下面这条命令将 `eula=true` 添加到文件中: ``` sed -i.orig 's/eula=false/eula=true/g' eula.txt ``` -你现在可以通过和上面一样的命令来开启服务端并进入”我的世界“服务端控制台了: +你现在可以通过和上面一样的命令来开启服务端并进入“我的世界”服务端控制台了: ``` java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui ``` -确保你在 /opt/minecraft 目录,或者其他你安装你的 MC 服务端的目录下。 +确保你在 `/opt/minecraft` 目录,或者其他你安装你的 MC 服务端的目录下。 -如果你只是测试或暂时需要的话,到这里就可以停了。如果你在登陆服务器时有问题的话,你就需要[配置你的防火墙][23]。 +如果你只是测试或暂时需要的话,到这里就可以停了。如果你在登录服务器时有问题的话,你就需要[配置你的防火墙][23]。 第一次成功启动服务端时会花费一点时间来生成。 @@ -166,7 +155,7 @@ nano /opt/minecraft/startminecraft.sh cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui ``` -如果你不熟悉 nano 的话 - 你可以使用“CTRL + X”,再敲击“Y”,然后回车。这个脚本将进入你先前创建的“我的世界”服务端并运行 Java 命令来开启服务端。你需要执行下面的命令来使脚本可执行: +如果你不熟悉 nano 的话 - 你可以使用 `CTRL + X`,再敲击 `Y`,然后回车。这个脚本将进入你先前创建的“我的世界”服务端并运行 Java 命令来开启服务端。你需要执行下面的命令来使脚本可执行: ``` chmod +x startminecraft.sh @@ -178,7 +167,7 @@ chmod +x startminecraft.sh /opt/minecraft/startminecraft.sh ``` -但是,如果/当你登出 SSH 会话的话,服务端就会关闭。要想让服务端不登陆也持续运行的话,你可以使用 screen 会话。一个 screen 会话会一直运行,直到实际的服务器被关闭或重启。 +但是,如果/当你登出 SSH 会话的话,服务端就会关闭。要想让服务端不登录也持续运行的话,你可以使用 `screen` 会话。`screen` 会话会一直运行,直到实际的服务器被关闭或重启。 使用下面的命令开启一个 screen 会话: @@ -186,23 +175,23 @@ chmod +x startminecraft.sh screen -S minecraft ``` -一旦你进入了 screen 会话(看起来就像是你新建了一个 SSH 会话),你就可以使用先前创建的 bash 脚本来启动服务端: +一旦你进入了 `screen` 会话(看起来就像是你新建了一个 SSH 会话),你就可以使用先前创建的 bash 脚本来启动服务端: ``` /opt/minecraft/startminecraft.sh ``` -要退出 screen 会话的话,你应该按 CTRL +A-D。即使你离开 screen 会话(断开的),服务端也会继续运行。你现在可以安全的登出 Ubuntu 服务器了,你创建的“我的世界”服务端将会继续运行。 +要退出 `screen` 会话的话,你应该按 `CTRL+A-D`。即使你离开 `screen` 会话(断开的),服务端也会继续运行。你现在可以安全的登出 Ubuntu 服务器了,你创建的“我的世界”服务端将会继续运行。 -但是,如果 Ubuntu 服务器重启或关闭了的话,screen 会话将不再起作用。所以**为了让我们之前做的这些在启动时自动运行**,做下面这些: +但是,如果 Ubuntu 服务器重启或关闭了的话,`screen` 会话将不再起作用。所以**为了让我们之前做的这些在启动时自动运行**,做下面这些: -打开 /etc/rc.local 文件: +打开 `/etc/rc.local` 文件: ``` nano /etc/rc.local ``` -在“exit 0”语句前添加如下内容: +在 `exit 0` 语句前添加如下内容: ``` screen -dm -S minecraft /opt/minecraft/startminecraft.sh @@ -211,7 +200,7 @@ exit 0 保存并关闭文件。 -要访问“我的世界”服务端控制台,只需运行下面的命令来重新连接 screen 会话: +要访问“我的世界”服务端控制台,只需运行下面的命令来重新连接 `screen` 会话: ``` screen -r minecraft @@ -247,7 +236,7 @@ ufw allow 25565/tcp nano /opt/minecraft/server.properties ``` -并将“white-list”行改为“true”: +并将 `white-list` 行改为 `true`: ``` white-list=true @@ -279,7 +268,7 @@ whitelist add PlayerUsername whitelist remove PlayerUsername ``` -使用 CTRL + A-D 来退出 screen(服务器控制台)。值得注意的是,这会拒绝除白名单以外的所有人连接到服务端。 +使用 `CTRL+A-D` 来退出 `screen`(服务器控制台)。值得注意的是,这会拒绝除白名单以外的所有人连接到服务端。 [![how to create a minecraft server](https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg)][26] @@ -305,7 +294,7 @@ whitelist remove PlayerUsername screen -r minecraft ``` -在这里执行[命令][28]。像下面这些命令: +并执行[命令][28]。像下面这些命令: ``` difficulty hard @@ -321,7 +310,7 @@ gamemode survival @a 如果有新版本发布的话,你需要这样做: -进入”我的世界“目录: +进入“我的世界”目录: ``` cd /opt/minecraft @@ -356,7 +345,7 @@ cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar #### 为什么你们的教程这么长,而其他的只有 2 行那么长?! -我们想让这个教程对新手来说更友好,并且尽可能详细。我们还向你展示了了如何让服务端长期运行并跟随系统启动,我们向你展示了如何配置你的服务端以及所有的东西。我是说,你当然可以用几行来启动“我的世界”服务器,但那样的话绝对很烂,从不仅一方面说。 +我们想让这个教程对新手来说更友好,并且尽可能详细。我们还向你展示了如何让服务端长期运行并跟随系统启动,我们向你展示了如何配置你的服务端以及所有的东西。我是说,你当然可以用几行来启动“我的世界”服务器,但那样的话绝对很烂,从不仅一方面说。 #### 我不知道 Linux 或者这里说的什么东西,我该如何搭建一个“我的世界”服务器呢? @@ -372,7 +361,7 @@ via: https://thishosting.rocks/how-to-make-a-minecraft-server/ 作者:[ThisHosting.Rocks][a] 译者:[heart4lor](https://github.com/heart4lor) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md b/published/201803/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md similarity index 100% rename from published/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md rename to published/201803/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md diff --git a/published/20180129 Create your own personal Cloud- Install OwnCloud.md b/published/201803/20180129 Create your own personal Cloud- Install OwnCloud.md similarity index 100% rename from published/20180129 Create your own personal Cloud- Install OwnCloud.md rename to published/201803/20180129 Create your own personal Cloud- Install OwnCloud.md diff --git a/published/20180129 How programmers learn to code.md b/published/201803/20180129 How programmers learn to code.md similarity index 100% rename from published/20180129 How programmers learn to code.md rename to published/201803/20180129 How programmers learn to code.md diff --git a/published/201803/20180129 Parsing HTML with Python.md b/published/201803/20180129 Parsing HTML with Python.md new file mode 100644 index 0000000000..9159672395 --- /dev/null +++ b/published/201803/20180129 Parsing HTML with Python.md @@ -0,0 +1,225 @@ +如何用 Python 解析 HTML +====== + +用一些简单的脚本,可以很容易地清理文档和其它大量的 HTML 文件。但是首先你需要解析它们。 +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus_html_code.png?itok=VjUmGsnl) + +图片由 Jason Baker 为 Opensource.com 所作。 + +作为 Scribus 文档团队的长期成员,我要随时了解最新的源代码更新,以便对文档进行更新和补充。 我最近在刚升级到 Fedora 27 系统的计算机上使用 Subversion 进行检出操作时,对于下载该文档所需要的时间我感到很惊讶,文档由 HTML 页面和相关图像组成。 我恐怕该项目的文档看起来比项目本身大得多,并且怀疑其中的一些内容是“僵尸”文档——不再使用的 HTML 文件以及 HTML 中无法访问到的图像。 + +我决定为自己创建一个项目来解决这个问题。 一种方法是搜索未使用的现有图像文件。 如果我可以扫描所有 HTML 文件中的图像引用,然后将该列表与实际图像文件进行比较,那么我可能会看到不匹配的文件。 + +这是一个典型的图像标签: + +``` +Edit examples +``` + +我对 `src=` 之后的第一组引号之间的部分很感兴趣。 在寻找了一些解决方案后,我找到一个名为 [BeautifulSoup][1] 的 Python 模块。 脚本的核心部分如下所示: + +``` +soup = BeautifulSoup(all_text, 'html.parser') +match = soup.findAll("img") +if len(match) > 0: + for m in match: + imagelist.append(str(m)) +``` + +我们可以使用这个 `findAll` 方法来挖出图片标签。 这是一小部分输出: + +``` +GSview - Advanced Options PanelScribus External Tools Preferences +``` + +到现在为止还挺好。我原以为下一步就可以搞定了,但是当我在脚本中尝试了一些字符串方法时,它返回了有关标记的错误而不是字符串的错误。 我将输出保存到一个文件中,并在 [KWrite][2] 中进行编辑。 KWrite 的一个好处是你可以使用正则表达式(regex)来做“查找和替换”操作,所以我可以用 `\n', all_text) +if len(match)>0: + for m in match: + imagelist.append(m) +``` + +它的一小部分输出如下所示: + +``` +images/cmcanvas.png" title="Context Menu for the document canvas" alt="Context Menu for the document canvas" />
+``` + +我决定回到 `src=` 这一块。 一种方法是等待 `s` 出现,然后看下一个字符是否是 `r`,下一个是 `c`,下一个是否 `=`。 如果是这样,那就匹配上了! 那么两个双引号之间的内容就是我所需要的。 这种方法的问题在于需要连续识别上面这样的结构。 一种查看代表一行 HTML 文本的字符串的方法是: + +``` +for c in all_text: +``` + +但是这个逻辑太乱了,以至于不能持续匹配到前面的 `c`,还有之前的字符,更之前的字符,更更之前的字符。 + +最后,我决定专注于 `=` 并使用索引方法,以便我可以轻松地引用字符串中的任何先前或将来的字符。 这里是搜索部分: + +``` + index = 3 + while index < linelength: + if (all_text[index] == '='): + if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and (all_text[index-1] == 'c'): + imagefound(all_text, imagelist, index) + index += 1 + else: + index += 1 + else: + index += 1 +``` + +我用第四个字符开始搜索(索引从 0 开始),所以我在下面没有出现索引错误,并且实际上,在每一行的第四个字符之前不会有等号。 第一个测试是看字符串中是否出现了 `=`,如果没有,我们就会前进。 如果我们确实看到一个等号,那么我们会看前三个字符是否是 `s`、`r` 和 `c`。 如果全都匹配了,就调用函数 `imagefound`: + +``` +def imagefound(all_text, imagelist, index): + end = 0 + index += 2 + newimage = '' + while end == 0: + if (all_text[index] != '"'): + newimage = newimage + all_text[index] + index += 1 + else: + newimage = newimage + '\n' + imagelist.append(newimage) + end = 1 + return +``` + +我们给函数发送当前索引,它代表着 `=`。 我们知道下一个字符将会是 `"`,所以我们跳过两个字符,并开始向名为 `newimage` 的控制字符串添加字符,直到我们发现下一个 `"`,此时我们完成了一次匹配。 我们将字符串加一个换行符(`\n`)添加到列表 `imagelist` 中并返回(`return`),请记住,在剩余的这个 HTML 字符串中可能会有更多图片标签,所以我们马上回到搜索循环中。 + +以下是我们的输出现在的样子: + +``` +images/text-frame-link.png +images/text-frame-unlink.png +images/gimpoptions1.png +images/gimpoptions3.png +images/gimpoptions2.png +images/fontpref3.png +images/font-subst.png +images/fontpref2.png +images/fontpref1.png +images/dtp-studio.png +``` + +啊,干净多了,而这只花费几秒钟的时间。 我本可以将索引前移 7 步来剪切 `images/` 部分,但我更愿意把这个部分保存下来,以确保我没有剪切掉图像文件名的第一个字母,这很容易用 KWrite 编辑成功 —— 你甚至不需要正则表达式。 做完这些并保存文件后,下一步就是运行我编写的另一个脚本 `sortlist.py`: + +``` +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# sortlist.py + +import os + +imagelist = [] +for line in open('/tmp/imagelist_parse4.txt').xreadlines(): + imagelist.append(line) + +imagelist.sort() + +outfile = open('/tmp/imagelist_parse4_sorted.txt', 'w') +outfile.writelines(imagelist) +outfile.close() +``` + +这会读取文件内容,并存储为列表,对其排序,然后另存为另一个文件。 之后,我可以做到以下几点: + +``` +ls /home/gregp/development/Scribus15x/doc/en/images/*.png > '/tmp/actual_images.txt' +``` + +然后我需要在该文件上运行 `sortlist.py`,因为 `ls` 方法的排序与 Python 不同。 我原本可以在这些文件上运行比较脚本,但我更愿意以可视方式进行操作。 最后,我成功找到了 42 个图像,这些图像没有来自文档的 HTML 引用。 + +这是我的完整解析脚本: + +``` +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# parseimg4.py + +import os + +def imagefound(all_text, imagelist, index): + end = 0 + index += 2 + newimage = '' + while end == 0: + if (all_text[index] != '"'): + newimage = newimage + all_text[index] + index += 1 + else: + newimage = newimage + '\n' + imagelist.append(newimage) + end = 1 + return + +htmlnames = [] +imagelist = [] +tempstring = '' +filenames = os.listdir('/home/gregp/development/Scribus15x/doc/en/') +for name in filenames: + if name.endswith('.html'): + htmlnames.append(name) +#print htmlnames +for htmlfile in htmlnames: + all_text = open('/home/gregp/development/Scribus15x/doc/en/' + htmlfile).read() + linelength = len(all_text) + index = 3 + while index < linelength: + if (all_text[index] == '='): + if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and +(all_text[index-1] == 'c'): + imagefound(all_text, imagelist, index) + index += 1 + else: + index += 1 + else: + index += 1 + +outfile = open('/tmp/imagelist_parse4.txt', 'w') +outfile.writelines(imagelist) +outfile.close() +imageno = len(imagelist) +print str(imageno) + " images were found and saved" +``` + +脚本名称为 `parseimg4.py`,这并不能真实反映我陆续编写的脚本数量(包括微调的和大改的以及丢弃并重新开始写的)。 请注意,我已经对这些目录和文件名进行了硬编码,但是很容易变得通用化,让用户输入这些信息。 同样,因为它们是工作脚本,所以我将输出发送到 `/tmp` 目录,所以一旦重新启动系统,它们就会消失。 + +这不是故事的结尾,因为下一个问题是:僵尸 HTML 文件怎么办? 任何未使用的文件都可能会引用图像,不能被前面的方法所找出。 我们有一个 `menu.xml` 文件作为联机手册的目录,但我还需要考虑 TOC(LCTT 译注:TOC 是 table of contents 的缩写)中列出的某些文件可能引用了不在 TOC 中的文件,是的,我确实找到了一些这样的文件。 + +最后我可以说,这是一个比图像搜索更简单的任务,而且开发的过程对我有很大的帮助。 + +### 关于作者 + + [![](https://opensource.com/sites/default/files/styles/profile_pictures/public/20150529_gregp.jpg?itok=nv02g6PV)][7] + +Greg Pittman 是 Kentucky 州 Louisville 市的一名退休的神经学家,从二十世纪六十年代的 Fortran IV 语言开始长期以来对计算机和编程有着浓厚的兴趣。 当 Linux 和开源软件出现的时候,Greg 深受启发,去学习更多知识,并实现最终贡献的承诺。 他是 Scribus 团队的成员。[更多关于我][8] + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/parsing-html-python + +作者:[Greg Pittman][a] +译者:[Flowsnow](https://github.com/Flowsnow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/greg-p +[1]:https://www.crummy.com/software/BeautifulSoup/ +[2]:https://www.kde.org/applications/utilities/kwrite/ +[7]:https://opensource.com/users/greg-p +[8]:https://opensource.com/users/greg-p diff --git a/published/20180130 Use of du - df commands (with examples).md b/published/201803/20180130 Use of du - df commands (with examples).md similarity index 100% rename from published/20180130 Use of du - df commands (with examples).md rename to published/201803/20180130 Use of du - df commands (with examples).md diff --git a/published/20180131 10 things I love about Vue.md b/published/201803/20180131 10 things I love about Vue.md similarity index 100% rename from published/20180131 10 things I love about Vue.md rename to published/201803/20180131 10 things I love about Vue.md diff --git a/published/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md b/published/201803/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md similarity index 100% rename from published/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md rename to published/201803/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md diff --git a/published/20180131 An old DOS BBS in a Docker container.md b/published/201803/20180131 An old DOS BBS in a Docker container.md similarity index 100% rename from published/20180131 An old DOS BBS in a Docker container.md rename to published/201803/20180131 An old DOS BBS in a Docker container.md diff --git a/published/20180131 How to access-view Python help when using vim.md b/published/201803/20180131 How to access-view Python help when using vim.md similarity index 100% rename from published/20180131 How to access-view Python help when using vim.md rename to published/201803/20180131 How to access-view Python help when using vim.md diff --git a/published/201803/20180201 How I coined the term open source.md b/published/201803/20180201 How I coined the term open source.md new file mode 100644 index 0000000000..2dd310ecb8 --- /dev/null +++ b/published/201803/20180201 How I coined the term open source.md @@ -0,0 +1,107 @@ +我是如何创造“开源”这个词的 +============================================================ + + +> Christine Peterson 最终公开讲述了二十年前那决定命运的一天。 + +![How I coined the term 'open source'](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/hello-name-sticker-badge-tag.png?itok=fAgbMgBb "How I coined the term 'open source'") + +图片来自: opensource.com + +2 月 3 日是术语“[开源软件][6]open source software”创立 20 周年的纪念日。由于开源软件渐受欢迎,并且为这个时代强有力的重要变革提供了动力,我们仔细反思了它的初生到崛起。 + +我是 “开源软件” 这个词的始作俑者,它是我在前瞻协会Foresight Institute担任执行董事时提出的。我不像其它人是个软件开发者,所以感谢 Linux 程序员 Todd Anderson 对这个术语的支持并将它提交小组讨论。 + +这是我对于它如何想到的,如何提出的,以及后续影响的记叙。当然,还有一些有关该术语的其它记叙,例如 Eric Raymond 和 Richard Stallman 写的,而我的,则写于 2006 年 1 月 2 日。 + +但直到今天,我才公诸于世。 + +* * * + +推行术语“开源软件”是特别为了让新手和商业人士更加理解这个领域,对它的推广被认为对于更广泛的用户社区很有必要。早期的称呼“自由软件free software”不适用并非是因为含有政治意义,而是对于新手来说会误导关注于价格。所以需要一个关注于关键的源代码,而且不会让新用户混淆概念的术语。第一个在正确时间出现并且满足这些要求的术语被迅速接受了:开源open source。 + +这个术语很长一段时间被用在“情报”(即间谍活动)活动中,但据我所知,确实在 1998 年以前软件领域从未使用过该术语。下面这个就是讲述了术语“开源软件”如何流行起来,并且变成了一项产业和一场运动名称的故事。 + +### 计算机安全会议 + +在 1997 年的晚些时候,前瞻协会Foresight Institute开始举办周会讨论计算机安全问题。这个协会是一个非盈利性智库,它专注于纳米技术和人工智能,而二者的安全性及可靠性取决于软件安全。我们确定了自由软件是一个改进软件安全可靠性且具有发展前景的方法,并将寻找推动它的方式。 对自由软件的兴趣开始在编程社区外开始增长,而且越来越清晰,一个改变世界的机会正在来临。然而,该怎么做我们并不清楚,因为我们当时正在摸索中。 + +在这些会议中,由于“容易混淆”的因素,我们讨论了采用一个新术语的必要性。观点主要如下:对于那些新接触“自由软件”的人会把 “free” 当成了价格上的 “免费” 。老资格的成员们开始解释,通常像下面所说的:“我们指的是 ‘freedom’ 中的自由,而不是‘免费啤酒’的免费。”在这一点上,关于软件方面的讨论就会变成了关于酒精饮料价格的讨论。问题不在于解释不了它的含义 —— 问题在于重要概念的术语不应该使新手们感到困惑。所以需要一个更清晰的术语。自由软件一词并没有政治上的问题;问题在于这个术语不能对新人清晰表明其概念。 + +### 开放的网景 + +1998 年 2 月 2 日,Eric Raymond 访问网景公司,并与它一起计划采用自由软件风格的许可证发布其浏览器的源代码。我们那晚在前瞻协会位于罗斯阿尔托斯Los Altos的办公室开会,商讨并完善了我们的计划。除了 Eric 和我,积极参与者还有 Brian Behlendorf、Michael Tiemann、Todd Anderson、Mark S. Miller 和 Ka-Ping Yee。但在那次会议上,这一领域仍然被描述成“自由软件”,或者用 Brian 的话说, 叫“可获得源代码的” 软件。 + +在这个镇上,Eric 把前瞻协会作为行动的大本营。他访问行程期间,他接到了网景的法律和市场部门人员的电话。当他聊完后,我要求和他们(一男一女,可能是 Mitchell Baker)通电话,以便我告诉他们一个新的术语的必要性。他们原则上立即同意了,但我们在具体术语上并未达成一致。 + +在那周的会议中,我始终专注于起一个更好的名字并提出了 “开源软件”一词。 虽然不太理想,但我觉得足够好了。我找到至少四个人征求意见:Eric Drexler、Mark Miller 以及 Todd Anderson 都喜欢它,而一个从事市场公关的朋友觉得术语 “open” 被滥用了,并且觉得我们能找到一个更好。理论上他是对的,可我想不出更好的了,所以我想试着先推广它。事后想起来,我应该直接向 Eric Raymond 提议,但在那时我并不是很了解他,所以我采取了间接的策略。 + +Todd 强烈同意需要一个新的术语,并提供协助推广它。这很有帮助,因为作为一个非编程人员,我在自由软件社区的影响力很弱。我从事的纳米技术教育是一个加分项,但不足以让我在自由软件问题上非常得到重视。而作为一个 Linux 程序员,Todd 的话更容易被倾听。 + +### 关键性会议 + +那周稍晚时候,1998 年的 2 月 5 日,一伙人在 VA Research 进行头脑风暴商量对策。与会者除了 Eric Raymond、Todd 和我之外,还有 Larry Augustin、Sam Ockman,和 Jon Hall (“maddog”)通过电话参与。 + +会议的主要议题是推广策略,特别是要联系的公司。 我几乎没说什么,但是一直在寻找机会介绍提议的术语。我觉得我直接说“你们这些技术人员应当开始使用我的新术语了。”没有什么用。大多数与会者不认识我,而且据我所知,他们可能甚至不同意现在就迫切需要一个新术语。 + +幸运的是,Todd 一直留心着。他没有主张社区应该用哪个特定的术语,而是面对社区这些固执的人间接地做了一些事。他仅仅是在其它话题中使用了那个术语 —— 把它放进对话里看看会发生什么。我很紧张,期待得到回应,但是起初什么也没有。讨论继续进行原来的话题。似乎只有他和我注意了这个术语的使用。 + +不仅如此——模因演化(LCTT 译注:人类学术语)在起作用。几分钟后,另一个人使用了这个术语,显然没有注意到,而在继续进行话题讨论。Todd 和我用眼角互觑了一下:是的,我们都注意到发生了什么。我很激动——它或许有用!但我保持了安静:我在小组中仍然地位不高。可能有些人都奇怪为什么 Eric 会邀请我。 + +临近会议尾声,可能是 Todd 或 Eric,明确提出了[术语问题][8]。Maddog 提及了一个早期的术语“可自由分发的”,和一个新的术语“合作开发的”。Eric 列出了“自由软件”、“开源软件”和“软件源”作为主要选项。Todd 提议使用“开源”,然后 Eric 支持了他。我没说太多,就让 Todd 和 Eric(轻松、非正式地)就“开源”这个名字达成了共识。显然对于大多数与会者,改名并不是在这讨论的最重要议题;那只是一个次要的相关议题。从我的会议记录中看只有大约 10% 的内容是术语的。 + +但是我很高兴。在那有许多社区的关键领导人,并且他们喜欢这新名字,或者至少没反对。这是一个好的信号。可能我帮不上什么忙; Eric Raymond 更适合宣传新的名称,而且他也这么做了。Bruce Perens 立即表示支持,帮助建立了 [Opensource.org][9] 并在新术语的宣传中发挥了重要作用。 + +为了让这个名字获得认同,Tim O'Reilly 同意在代表社区的多个项目中积极使用它,这是很必要,甚至是非常值得的。并且在官方即将发布的 Netscape Navigator(网景浏览器)代码中也使用了此术语。 到二月底, O'Reilly & Associates 还有网景公司(Netscape) 已经开始使用新术语。 + +### 名字的宣传 + +在那之后的一段时间,这条术语由 Eric Raymond 向媒体推广,由 Tim O'Reilly 向商业推广,并由二人向编程社区推广,它似乎传播的相当快。 + +1998 年 4 月 17 日,Tim O'Reilly 召集了该领域的一些重要领袖的峰会,宣布为第一次 “[自由软件峰会][10]” ,在 4 月14 日之后,它又被称作首届 “[开源峰会][11]”。 + +这几个月对于开源来说是相当激动人心的。似乎每周都有一个新公司宣布加入计划。读 Slashdot(LCTT 译注:科技资讯网站)已经成了一个必需操作,甚至对于那些像我一样只能外围地参与者亦是如此。我坚信新术语能对快速传播到商业很有帮助,能被公众广泛使用。 + +尽管在谷歌搜索一下表明“开源”比“自由软件”出现的更多,但后者仍然有大量的使用,在和偏爱它的人们沟通的时候我们应该包容。 + +### 快乐的感觉 + +当 Eric Raymond 写的有关术语更改的[早期声明][12]被发布在了开源促进会Open Source Initiative的网站上时,我被列在 VA 头脑风暴会议的名单上,但并不是作为术语的创始人。这是我自己的失误,我没告诉 Eric 细节。我的想法就是让它过去吧,我呆在幕后就好,但是 Todd 不这样认为。他认为我总有一天会为被称作“开源软件”这个名词的创造者而高兴。他向 Eric 解释了这个情况,Eric 及时更新了网站。 + +想出这个短语只是一个小贡献,但是我很感激那些把它归功于我的人。每次我听到它(现在经常听到了),它都给我些许的感动。 + +说服社区的巨大功劳要归功于 Eric Raymond 和 Tim O'Reilly,是他们让这一切成为可能。感谢他们对我的归功,并感谢 Todd Anderson 所做的一切。以上内容并非完整的开源一词的历史,让我对很多没有提及的关键人士表示歉意。那些寻求更完整讲述的人应该参考本文和网上其他地方的链接。 + +### 关于作者 + +[![photo of Christine Peterson](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/cp2016_crop2_185.jpg?itok=vUkSjFig)][13] + +Christine Peterson 撰写、举办讲座,并向媒体介绍未来强大的技术,特别是在纳米技术,人工智能和长寿方面。她是纳米科技公益组织前瞻协会的共同创始人和前任主席。前瞻协会向公众、技术团体和政策制定者提供未来强大的技术的教育以及告诉它是如何引导他们的长期影响。她服务于[机器智能][2]咨询委员会……[更多关于 Christine Peterson][3] + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/coining-term-open-source-software + +作者:[Christine Peterson][a] +译者:[fuzheng1998](https://github.com/fuzheng1998) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/christine-peterson +[1]:https://opensource.com/article/18/2/coining-term-open-source-software?rate=HFz31Mwyy6f09l9uhm5T_OFJEmUuAwpI61FY-fSo3Gc +[2]:http://intelligence.org/ +[3]:https://opensource.com/users/christine-peterson +[4]:https://opensource.com/users/christine-peterson +[5]:https://opensource.com/user/206091/feed +[6]:https://opensource.com/resources/what-open-source +[7]:https://opensource.org/osd +[8]:https://wiki2.org/en/Alternative_terms_for_free_software +[9]:https://opensource.org/ +[10]:http://www.oreilly.com/pub/pr/636 +[11]:http://www.oreilly.com/pub/pr/796 +[12]:https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Alternative_terms_for_free_software.html +[13]:https://opensource.com/users/christine-peterson +[14]:https://opensource.com/users/christine-peterson +[15]:https://opensource.com/users/christine-peterson +[16]:https://opensource.com/article/18/2/coining-term-open-source-software#comments diff --git a/translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md b/published/201803/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md similarity index 74% rename from translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md rename to published/201803/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md index 069058b917..0a940e1ccd 100644 --- a/translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md +++ b/published/201803/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md @@ -1,18 +1,18 @@ -如何检查你的 Linux PC 是否存在 Meltdown 或者 Spectre 漏洞 +如何检查你的 Linux 系统是否存在 Meltdown 或者 Spectre 漏洞 ====== ![](https://www.maketecheasier.com/assets/uploads/2018/01/lmc-feat.jpg) Meltdown 和 Specter 漏洞的最恐怖的现实之一是它们涉及非常广泛。几乎每台现代计算机都会受到一些影响。真正的问题是_你_是否受到了影响?每个系统都处于不同的脆弱状态,具体取决于已经或者还没有打补丁的软件。 -由于 Meltdown 和 Spectre 都是相当新的,并且事情正在迅速发展,所以告诉你需要注意什么或在系统上修复了什么并非易事。有一些工具可以提供帮助。它们并不完美,但它们可以帮助你找出你需要知道的东西。 +由于 Meltdown 和 Spectre 都是相当新的漏洞,并且事情正在迅速发展,所以告诉你需要注意什么或在系统上修复了什么并非易事。有一些工具可以提供帮助。它们并不完美,但它们可以帮助你找出你需要知道的东西。 ### 简单测试 顶级的 Linux 内核开发人员之一提供了一种简单的方式来检查系统在 Meltdown 和 Specter 漏洞方面的状态。它是简单的,也是最简洁的,但它不适用于每个系统。有些发行版不支持它。即使如此,也值得一试。 + ``` grep . /sys/devices/system/cpu/vulnerabilities/* - ``` ![Kernel Vulnerability Check][1] @@ -24,24 +24,24 @@ grep . /sys/devices/system/cpu/vulnerabilities/* 如果上面的方法不适合你,或者你希望看到更详细的系统报告,一位开发人员已创建了一个 shell 脚本,它将检查你的系统来查看系统收到什么漏洞影响,还有做了什么来减轻 Meltdown 和 Spectre 的影响。 要得到脚本,请确保你的系统上安装了 Git,然后将脚本仓库克隆到一个你不介意运行它的目录中。 + ``` cd ~/Downloads git clone https://github.com/speed47/spectre-meltdown-checker.git - ``` 这不是一个大型仓库,所以它应该只需要几秒钟就克隆完成。完成后,输入新创建的目录并运行提供的脚本。 + ``` cd spectre-meltdown-checker ./spectre-meltdown-checker.sh - ``` -你会在中断看到很多输出。别担心,它不是太难查看。首先,脚本检查你的硬件,然后运行三个漏洞:Specter v1、Spectre v2 和 Meltdown。每个漏洞都有自己的部分。在这之间,脚本明确地告诉你是否受到这三个漏洞的影响。 +你会在终端看到很多输出。别担心,它不是太难理解。首先,脚本检查你的硬件,然后运行三个漏洞检查:Specter v1、Spectre v2 和 Meltdown。每个漏洞都有自己的部分。在这之间,脚本明确地告诉你是否受到这三个漏洞的影响。 ![Meltdown Spectre Check Script Ubuntu][2] -每个部分为你提供潜在的可用的缓解方案,以及它们是否已被应用。这里需要你的一点常识。它给出的决定可能看起来有冲突。研究一下,看看它所说的修复是否实际上完全缓解了这个问题。 +每个部分为你提供了潜在的可用的缓解方案,以及它们是否已被应用。这里需要你的一点常识。它给出的决定可能看起来有冲突。研究一下,看看它所说的修复是否实际上完全缓解了这个问题。 ### 这意味着什么 @@ -53,7 +53,7 @@ via: https://www.maketecheasier.com/check-linux-meltdown-spectre-vulnerability/ 作者:[Nick Congleton][a] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180201 How to Run Your Own Public Time Server on Linux.md b/published/201803/20180201 How to Run Your Own Public Time Server on Linux.md similarity index 55% rename from translated/tech/20180201 How to Run Your Own Public Time Server on Linux.md rename to published/201803/20180201 How to Run Your Own Public Time Server on Linux.md index 70eae1596d..4c59cd5dda 100644 --- a/translated/tech/20180201 How to Run Your Own Public Time Server on Linux.md +++ b/published/201803/20180201 How to Run Your Own Public Time Server on Linux.md @@ -3,35 +3,36 @@ ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/eddington_a._space_time_and_gravitation._fig._9.jpg?itok=KgNqViyZ) -公共服务最重要的一点就是守时,但是很多人并没有意识到这一点。大多数公共时间服务器都是由志愿者管理,以满足不断增长的需求。学习如何运行你自己的时间服务器,为基本的公共利益做贡献。(查看 [在 Linux 上使用 NTP 保持精确时间][1] 去学习如何设置一台局域网时间服务器) +最重要的公共服务之一就是报时timekeeping,但是很多人并没有意识到这一点。大多数公共时间服务器都是由志愿者管理,以满足不断增长的需求。这里学习一下如何运行你自己的时间服务器,为基础公共利益做贡献。(查看 [在 Linux 上使用 NTP 保持精确时间][1] 去学习如何设置一台局域网时间服务器) ### 著名的时间服务器滥用事件 就像现实生活中任何一件事情一样,即便是像时间服务器这样的公益项目,也会遭受不称职的或者恶意的滥用。 -消费类网络设备的供应商因制造了大混乱而臭名昭著。我回想起的第一件事发生在 2003 年,那时,Netgear 在它们的路由器中硬编码了 University of Wisconsin-Madison 的 NTP 时间服务器地址。使得时间服务器的查询请求突然增加,随着 NetGear 卖出越来越多的路由器,这种情况越发严重。更有意思的是,路由器的程序设置是每秒钟发送一次请求,这将使服务器难堪重负。后来 Netgear 发布了升级固件,但是,升级他们的设备的用户很少,并且他们的其中一些用户的设备,到今天为止,还在不停地每秒钟查询一次 University of Wisconsin-Madison 的 NTP 服务器。Netgear 给 University of Wisconsin-Madison 捐献了一些钱,以帮助弥补他们带来的成本增加,直到这些路由器全部淘汰。类似的事件还有 D-Link、Snapchat、TP-Link 等等。 +消费类网络设备的供应商因制造了大混乱而臭名昭著。我回想起的第一件事发生在 2003 年,那时,NetGear 在它们的路由器中硬编码了威斯康星大学的 NTP 时间服务器地址。使得时间服务器的查询请求突然增加,随着 NetGear 卖出越来越多的路由器,这种情况越发严重。更有意思的是,路由器的程序设置是每秒钟发送一次请求,这将使服务器难堪重负。后来 Netgear 发布了升级固件,但是,升级他们的设备的用户很少,并且他们的其中一些用户的设备,到今天为止,还在不停地每秒钟查询一次威斯康星大学的 NTP 服务器。Netgear 给威斯康星大学捐献了一些钱,以帮助弥补他们带来的成本增加,直到这些路由器全部淘汰。类似的事件还有 D-Link、Snapchat、TP-Link 等等。 -对 NTP 协议进行反射和放大,已经成为发起 DDoS 攻击的一个选择。当攻击者使用一个伪造的源地址向目标受害者发送请求,称为反射;攻击者发送请求到多个服务器,这些服务器将回复请求,这样就使伪造的地址受到轰炸。放大是指一个很小的请求收到大量的回复信息。例如,在 Linux 上,`ntpq` 命令是一个查询你的 NTP 服务器并验证它们的系统时间是否正确的很有用的工具。一些回复,比如,对端列表,是非常大的。组合使用反射和放大,攻击者可以将 10 倍甚至更多带宽的数据量发送到被攻击者。 +对 NTP 协议进行反射和放大,已经成为发起 DDoS 攻击的一个选择。当攻击者使用一个伪造的目标受害者的源地址向时间服务器发送请求,称为反射攻击;攻击者发送请求到多个服务器,这些服务器将回复请求,这样就使伪造的源地址受到轰炸。放大攻击是指一个很小的请求收到大量的回复信息。例如,在 Linux 上,`ntpq` 命令是一个查询你的 NTP 服务器并验证它们的系统时间是否正确的很有用的工具。一些回复,比如,对端列表,是非常大的。组合使用反射和放大,攻击者可以将 10 倍甚至更多带宽的数据量发送到被攻击者。 那么,如何保护提供公益服务的公共 NTP 服务器呢?从使用 NTP 4.2.7p26 或者更新的版本开始,它们可以帮助你的 Linux 发行版不会发生前面所说的这种问题,因为它们都是在 2010 年以后发布的。这个发行版都默认禁用了最常见的滥用攻击。目前,[最新版本是 4.2.8p10][2],它发布于 2017 年。 -你可以采用的另一个措施是,在你的网络上启用入站和出站过滤器。阻塞进入你的网络的数据包,以及拦截发送到伪造地址的出站数据包。入站过滤器帮助你,而出站过滤器则帮助你和其他人。阅读 [BCP38.info][3] 了解更多信息。 +你可以采用的另一个措施是,在你的网络上启用入站和出站过滤器。阻塞宣称来自你的网络的数据包进入你的网络,以及拦截发送到伪造返回地址的出站数据包。入站过滤器可以帮助你,而出站过滤器则帮助你和其他人。阅读 [BCP38.info][3] 了解更多信息。 ### 层级为 0、1、2 的时间服务器 -NTP 有超过 30 年的历史了,它是至今还在使用的最老的因特网协议之一。它的用途是保持计算机与协调世界时间(UTC)的同步。NTP 网络是分层组织的,并且同层的设备是对等的。层次 0 包含主守时设备,比如,原子钟。层级 1 的时间服务器与层级 0 的设备同步。层级 2 的设备与层级 1 的设备同步,层级 3 的设备与层级 2 的设备同步。NTP 协议支持 16 个层级,现实中并没有使用那么多的层级。同一个层级的服务器是相互对等的。 +NTP 有超过 30 年的历史了,它是至今还在使用的最老的因特网协议之一。它的用途是保持计算机与世界标准时间(UTC)的同步。NTP 网络是分层组织的,并且同层的设备是对等的。层次Stratum 0 包含主报时设备,比如,原子钟。层级 1 的时间服务器与层级 0 的设备同步。层级 2 的设备与层级 1 的设备同步,层级 3 的设备与层级 2 的设备同步。NTP 协议支持 16 个层级,现实中并没有使用那么多的层级。同一个层级的服务器是相互对等的。 -过去很长一段时间内,我们都为客户端选择配置单一的 NTP 服务器,而现在更好的做法是使用 [NTP 服务器地址池][4],它使用往返的 DNS 信息去共享负载。池地址只是为客户端服务的,比如单一的 PC 和你的本地局域网 NTP 服务器。当你运行一台自己的公共服务器时,你不能使用这些池中的地址。 +过去很长一段时间内,我们都为客户端选择配置单一的 NTP 服务器,而现在更好的做法是使用 [NTP 服务器地址池][4],它使用轮询的 DNS 信息去共享负载。池地址只是为客户端服务的,比如单一的 PC 和你的本地局域网 NTP 服务器。当你运行一台自己的公共服务器时,你不用使用这些池地址。 ### 公共 NTP 服务器配置 -运行一台公共 NTP 服务器只有两步:设置你的服务器,然后加入到 NTP 服务器池。运行一台公共的 NTP 服务器是一种很高尚的行为,但是你得先知道如何加入到 NTP 服务器池中。加入 NTP 服务器池是一种长期责任,因为即使你加入服务器池后,运行了很短的时间马上退出,然后接下来的很多年你仍然会接收到请求。 +运行一台公共 NTP 服务器只有两步:设置你的服务器,然后申请加入到 NTP 服务器池。运行一台公共的 NTP 服务器是一种很高尚的行为,但是你得先知道这意味着什么。加入 NTP 服务器池是一种长期责任,因为即使你加入服务器池后,运行了很短的时间马上退出,然后接下来的很多年你仍然会接收到请求。 你需要一个静态的公共 IP 地址,一个至少 512Kb/s 带宽的、可靠的、持久的因特网连接。NTP 使用的是 UDP 的 123 端口。它对机器本身要求并不高,很多管理员在其它的面向公共的服务器(比如,Web 服务器)上顺带架设了 NTP 服务。 -配置一台公共的 NTP 服务器与配置一台用于局域网的 NTP 服务器是一样的,只需要几个配置。我们从阅读 [协议规则][5] 开始。遵守规则并注意你的行为;几乎每个时间服务器的维护者都是像你这样的志愿者。然后,从 [StratumTwoTimeServers][6] 中选择 2 台层级为 4-7 的上游服务器。选择的时候,选取地理位置上靠近(小于 300 英里的)你的因特网服务提供商的上游服务器,阅读他们的访问规则,然后,使用 `ping` 和 `mtr` 去找到延迟和跳数最小的服务器。 +配置一台公共的 NTP 服务器与配置一台用于局域网的 NTP 服务器是一样的,只需要几个配置。我们从阅读 [协议规则][5] 开始。遵守规则并注意你的行为;几乎每个时间服务器的维护者都是像你这样的志愿者。然后,从 [StratumTwoTimeServers][6] 中选择 4 到 7 个层级 2 的上游服务器。选择的时候,选取地理位置上靠近(小于 300 英里的)你的因特网服务提供商的上游服务器,阅读他们的访问规则,然后,使用 `ping` 和 `mtr` 去找到延迟和跳数最小的服务器。 以下的 `/etc/ntp.conf` 配置示例文件,包括了 IPv4 和 IPv6,以及基本的安全防护: + ``` # stratum 2 server list server servername_1 iburst @@ -47,10 +48,10 @@ restrict -6 default kod noquery nomodify notrap nopeer limited # Allow ntpq and ntpdc queries only from localhost restrict 127.0.0.1 restrict ::1 - ``` 启动你的 NTP 服务器,让它运行几分钟,然后测试它对远程服务器的查询: + ``` $ ntpq -p remote refid st t when poll reach delay offset jitter @@ -63,21 +64,21 @@ $ ntpq -p ``` 目前表现很好。现在从另一台 PC 上使用你的 NTP 服务器名字进行测试。以下的示例是一个正确的输出。如果有不正确的地方,你将看到一些错误信息。 + ``` -$ ntpdate -q _yourservername_ +$ ntpdate -q yourservername server 66.96.99.10, stratum 2, offset 0.017690, delay 0.12794 server 98.191.213.2, stratum 1, offset 0.014798, delay 0.22887 server 173.49.198.27, stratum 2, offset 0.020665, delay 0.15012 server 129.6.15.28, stratum 1, offset -0.018846, delay 0.20966 26 Jan 11:13:54 ntpdate[17293]: adjust time server 98.191.213.2 offset 0.014798 sec - ``` 一旦你的服务器运行的很好,你就可以向 [manage.ntppool.org][7] 申请加入池中。 -查看官方的手册 [分布式网络时间服务器(NTP)][8] 学习所有的命令、配置选项、以及高级特性,比如,管理、查询、和验证。访问以下的站点学习关于运行一台时间服务器所需要的一切东西。 +查看官方的手册 [分布式网络时间服务器(NTP)][8] 学习所有的命令、配置选项、以及高级特性,比如,管理、查询、和验证。访问以下的站点学习关于运行一台时间服务器所需要的一切东西。 -通过来自 Linux 基金会和 edX 的免费课程 ["Linux 入门" ][9] 学习更多 Linux 的知识。 +通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”][9] 学习更多 Linux 的知识。 -------------------------------------------------------------------------------- @@ -85,12 +86,12 @@ via: https://www.linux.com/learn/intro-to-linux/2018/2/how-run-your-own-public-t 作者:[CARLA SCHRODER][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[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/learn/intro-to-linux/2018/1/keep-accurate-time-linux-ntp +[1]:https://linux.cn/article-9462-1.html [2]:http://www.ntp.org/downloads.html [3]:http://www.bcp38.info/index.php/Main_Page [4]:http://www.pool.ntp.org/en/use.html diff --git a/translated/tech/20180202 How do I edit files on the command line.md b/published/201803/20180202 How do I edit files on the command line.md similarity index 50% rename from translated/tech/20180202 How do I edit files on the command line.md rename to published/201803/20180202 How do I edit files on the command line.md index e559630730..ee5c19a748 100644 --- a/translated/tech/20180202 How do I edit files on the command line.md +++ b/published/201803/20180202 How do I edit files on the command line.md @@ -1,11 +1,11 @@ -如何在命令行上编辑文件?-- 三个命令行编辑器使用教程 +快捷教程:如何在命令行上编辑文件 ====== 此次教程中,我们将向您展示三种命令行编辑文件的方式。本文一共覆盖了三种命令行编辑器,vi(或 vim)、nano 和 emacs。 -#### 在命令行上使用 Vi 或 Vim 编辑文件 +### 在命令行上使用 Vi 或 Vim 编辑文件 -您可以使用 vi 编辑文件。运行如下命令,打开文件: +您可以使用 `vi` 编辑文件。运行如下命令,打开文件: ``` vi /path/to/file @@ -13,13 +13,13 @@ vi /path/to/file 现在,您可以看见文件中的内容了(如果文件存在。请注意,如果此文件不存在,该命令会创建文件)。 -vi 最重要的命令莫过于此: +`vi` 最重要的命令莫过于此: -键入 `i` 进入 `Insert`(编辑)模式。如此,您可以编辑文本。 +键入 `i` 进入编辑Insert模式。如此,您可以编辑文本。 退出编辑模式请键入 `ESC`。 -正处于光标之下的字符,使用 `x` 键删除(您千万不要在编辑模式这样做,如果您这样做了,将不会删除光标下的字符,而是会在光标下插入 `x` 字符)。因此,当您仅仅使用 vi 打开文本(此时默认进入指令模式),此时您可以使用 `x` 键立即删除字符。在编辑模式下,您需要键入 `ESC` 退出编辑模式。 +正处于光标之下的字符,使用 `x` 键删除(您千万不要在编辑模式这样做,如果您这样做了,将不会删除光标下的字符,而是会在光标下插入 `x` 字符)。因此,当您仅仅使用 `vi` 打开文本(LCTT 译注:此时默认进入指令模式),此时您可以使用 `x` 键立即删除字符。在编辑模式下,您需要键入 `ESC` 退出编辑模式。 如果您做了修改,想要保存文件,请键入 `:x`(同样,您不能在编辑模式执行此操作。请按 `ESC` 退出编辑模式,完成此操作)。 @@ -29,19 +29,19 @@ vi 最重要的命令莫过于此: 请注意在上述所有操作中,您都可以使用方向键操控光标在文本中的位置。 -以上所有都是 vi 编辑器的内容。请注意,vim 编辑器或多或少也会支持这些操作,如果您有深层次了解 vim 的需求,请看 [这里][1]。 +以上所有都是 `vi` 编辑器的内容。请注意,`vim` 编辑器或多或少也会支持这些操作,如果您想深层次了解 `vim`,请看 [这里][1]。 -#### 使用 Nano 命令行编辑器编辑文件 +### 使用 Nano 命令行编辑器编辑文件 -接下来是 Nano 编辑器。您可以执行 'nano' 命令调用它: +接下来是 Nano 编辑器。您可以执行 `nano` 命令调用它: ``` nano ``` -这里是 nano 的用户界面: +这里是 `nano` 的用户界面: -[![Nano 命令行编辑器][2]][3] +![Nano 命令行编辑器][3] 您同样可以使用它启动文件。 @@ -55,105 +55,105 @@ nano [filename] nano test.txt ``` -[![在 nano 中打开文件][4]][5] +![在 nano 中打开文件][5] 如您所见的用户界面,大致被分成四个部分。编辑器顶部显示编辑器版本、正在编辑的文件和编辑状态。然后是实际编辑区域,在这里,您能看见文件的内容。编辑器下方高亮区展示着重要的信息,最后两行显示能执行基础任务地快捷键,切实地帮助初学者。 这里是您前期应当了解的快捷键快表。 -使用方向键浏览文本,退格键删除文本,**Ctrl+o** 保存文件修改。当您尝试保存时,nano 会征询您的确认(请参阅截图中主编辑器下方区域): +使用方向键浏览文本,退格键删除文本,`Ctrl+O` 保存文件修改。当您尝试保存时,`nano` 会征询您的确认(请参阅截图中主编辑器下方区域): -[![在 nano 中保存文件][6]][7] +![在 nano 中保存文件][7] -注意,在这个阶段,您有一个选项,可以保存不同的系统格式。键入 **Altd+d** 选择 DOS 格式,**Atl+m** 选择 Mac 格式。 +注意,在这个阶段,您有一个选项,可以保存不同的系统格式。键入 `Alt+D` 选择 DOS 格式,`Atl+M` 选择 Mac 格式。 -[![以 DOS 格式保存文件][8]][9] +![以 DOS 格式保存文件][9] 敲回车保存更改。 -[![文件已经被保存][10]][11] +![文件已经被保存][11] -继续,文本剪切使用 **Ctrl+K**,文本复制使用 **Ctrl+u**。这些快捷键同样可以用来粘贴剪切单个单词,但您需要先选择好单词,通常,您可以通过键入 **Alt+A**(光标在第一个单词下) 然后使用方向键选择完整的单词。 +继续,文本剪切使用 `Ctrl+K`,文本复制使用 `Ctrl+U`。这些快捷键同样可以用来粘贴剪切单个单词,但您需要先选择好单词,通常,您可以通过键入 `Alt+A`(光标在第一个单词下) 然后使用方向键选择完整的单词。 -现在来进行搜索操作。使用 **Ctrl+w** 可以执行一个简单的搜索,同时搜索和替换您可以使用 **Ctrl+\\**。 +现在来进行搜索操作。使用 `Ctrl+W` 可以执行一个简单的搜索,同时搜索和替换您可以使用 `Ctrl+\\`。 -[![使用 nano 在文件中搜索][12]][13] +![使用 nano 在文件中搜索][13] -这些就是 nano 的一些基础功,它能给您带来一些不错的开始,如果您是初次使用 nano 编辑器。更多内容,请阅读我们的完整内容,点击 [这里][14]。 +这些就是 `nano` 的一些基础功,它能给您带来一些不错的开始,如果您是初次使用 `nano` 编辑器。更多内容,请阅读我们的完整内容,点击 [这里][14]。 -#### 使用 Emacs 命令行编辑器编辑文件 +### 使用 Emacs 命令行编辑器编辑文件 -接下来登场的是 **Emacs**。如果系统未安装此软件,您可以使用下面的命令在您的系统中安装它: +接下来登场的是 Emacs。如果系统未安装此软件,您可以使用下面的命令在您的系统中安装它: ``` sudo apt-get install emacs ``` -和 nano 一致,您可以使用下面的方式在 emacs 中直接打开文件: +和 `nano` 一致,您可以使用下面的方式在 `emacs` 中直接打开文件: ``` emacs -nw [filename] ``` -**注意**:**-nw** 选项确保 emacs 在本窗口启动,而不是打开一个新窗口,默认情况下,它会打开一个新窗口。 +注意:`-nw` 选项确保 `emacs` 在本窗口启动,而不是打开一个新窗口,默认情况下,它会打开一个新窗口。 一个实例: + ``` emacs -nw test.txt - ``` 下面是编辑器的用户界面: -[![在 emacs 中打开文件][15]][16] +![在 emacs 中打开文件][16] -和 nano 一样,emacs 的界面同样被分割成了几个部分。第一部分是最上方的菜单区域,和您在图形界面下的应用程序一致。接下来是显示文本(您打开的文件文本)内容的主编辑区域。 +和 `nano` 一样,`emacs` 的界面同样被分割成了几个部分。第一部分是最上方的菜单区域,和您在图形界面下的应用程序一致。接下来是显示文本(您打开的文件文本)内容的主编辑区域。 -编辑区域下方坐落着另一个高亮菜单条,显示了文件名,编辑模式(如截图内的‘Text’)和状态(** 已修改,- 未修改,%% 只读状态)。最后是提供输入指令的区域,同时也能查看输出。 +编辑区域下方坐落着另一个高亮菜单条,显示了文件名,编辑模式(如截图内的 ‘Text’)和状态(`**` 为已修改,`-` 为未修改,`%%` 为只读)。最后是提供输入指令的区域,同时也能查看输出。 -现在开始基础操作,当您做了修改、想要保存时,在 **Ctrl+x** 之后键入 **Ctrl+s**。最后,在面板最后一行会向您显示一些信息:‘**Wrote ........’。这里有一个例子: +现在开始基础操作,当您做了修改、想要保存时,在 `Ctrl+x` 之后键入 `Ctrl+s`。最后,在面板最后一行会向您显示一些信息:‘Wrote ........’。这里有一个例子: -[![emascs 中保存文件][17]][18] +![emascs 中保存文件][18] -现在,如果您放弃修改并且退出时,在 **Ctrl+x** 之后键入**Ctrl+c**。编辑器将会立即询问,如下图: +现在,如果您放弃修改并且退出时,在 `Ctrl+x` 之后键入`Ctrl+c`。编辑器将会立即询问,如下图: -[![emacs 中抛弃修改][19]][20] +![emacs 中抛弃修改][20] -输入 ‘n’ 之后键入 ‘yes’,之后编辑器将会不保存而直接退出。 +输入 `n` 之后键入 `yes`,之后编辑器将会不保存而直接退出。 -请注意,Emacs 中 ‘C’ 代表 ‘Ctrl’,‘M’ 代表 ‘Alt’。比如,当你看见 C-x,这意味着 Ctrl+x。 +请注意,Emacs 中 `C` 代表 `Ctrl`,`M` 代表 `Alt`。比如,当你看见 `C-x`,这意味着按下 `Ctrl+x`。 -至于其他基本编辑器操作,以删除为例,大多数人都会,使用 Backspace/Delete 键。然而,这里的一些删除快捷键能够提高用户体验。比如,使用 **Ctrl+k** 删除一整行,**Alt+d** 删除一个单词,**Alt+k** 删除一个整句。 +至于其他基本编辑器操作,以删除为例,大多数人都会,使用 `Backspace`/`Delete` 键。然而,这里的一些删除快捷键能够提高用户体验。比如,使用 `Ctrl+k` 删除一整行,`Alt+d` 删除一个单词,`Alt+k` 删除一个整句。 -在键入 ‘ **Ctrl+k** ’ 之后键入 ‘ **u** ’ 将不会生效,输入 **Ctrl+g** 之后输入 **Crel+_** 撤销操作。使用 **Crel+s** 向前搜索,**Ctrl+r** 反向搜索。 +在键入 `Ctrl+k` 之后键入 `u` 将撤销操作,输入 `Ctrl+g` 之后输入 `Ctrl+_` 恢复撤销的操作。使用 `Ctrl+s` 向前搜索,`Ctrl+r` 反向搜索。 -[![使用 emacs 在文件中搜索][21]][22] +![使用 emacs 在文件中搜索][22] -继续,使用 Alt+Shift+% 执行替换操作。您将被询问替换单词。回复并回车。之后编辑器将会询问您是否替换。例如,下方截图展示了 emacs 询问使用者关于单词 ‘This’ 的替换操作。 +继续,使用 `Alt+Shift+%` 执行替换操作。您将被询问要替换单词。回复并回车。之后编辑器将会询问您是否替换。例如,下方截图展示了 `emacs` 询问使用者关于单词 ‘This’ 的替换操作。 -[![使用 emacs 替换单词][23]][24] +![使用 emacs 替换单词][24] -输入替换文本并回车。每一个替换操作 emacs 都会等待询问,下面是首次询问: +输入替换文本并回车。每一个替换操作 `emacs` 都会等待询问,下面是首次询问: -[![确定文本替换][25]][26] +![确定文本替换][26] -键入 'y' 之后,单词将会被替换。 +键入 `y` 之后,单词将会被替换。 -[![键入 y 确定操作][27]][28] +![键入 y 确定操作][28] -这些就是几乎所有的基础操作,您在开始使用 emacs 时需要了解掌握的。对了,我们忘记讨论如何访问顶部菜单,其实这些可以通过使用 F10 访问它们。 +这些就是几乎所有的基础操作,您在开始使用 `emacs` 时需要了解掌握的。对了,我们忘记讨论如何访问顶部菜单,其实这些可以通过使用 `F10` 访问它们。 -[![基础编辑器操作][29]][30] +![基础编辑器操作][30] -按 Esc 键三次,退出这些菜单。 +按 `Esc` 键三次,退出这些菜单。 -------------------------------------------------------------------------------- via: https://www.howtoforge.com/faq/how-to-edit-files-on-the-command-line -作者:[falko][a] +作者:[Falko Timme, Himanshu Arora][a] 译者:[CYLeft](https://github.com/CYLeft) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180202 How to Manage PGP and SSH Keys with Seahorse.md b/published/201803/20180202 How to Manage PGP and SSH Keys with Seahorse.md similarity index 100% rename from published/20180202 How to Manage PGP and SSH Keys with Seahorse.md rename to published/201803/20180202 How to Manage PGP and SSH Keys with Seahorse.md diff --git a/translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md b/published/201803/20180203 3 Ways to Extend the Power of Kubernetes.md similarity index 62% rename from translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md rename to published/201803/20180203 3 Ways to Extend the Power of Kubernetes.md index ceee299984..963c441dee 100644 --- a/translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md +++ b/published/201803/20180203 3 Ways to Extend the Power of Kubernetes.md @@ -1,19 +1,19 @@ -3种扩展 Kubernetes 能力的方式 +3 种扩展 Kubernetes 能力的方式 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/chen-goldberg-kubecon.png?itok=WR_4i31u) -Google 的工程总监 Chen Goldberg 在奥斯汀最近的[KubeCon 和 CloudNativeCon][1]上说,Kubernetes 的扩展能力是它的秘密武器。 +Google 的工程总监 Chen Goldberg 在最近的奥斯汀 [KubeCon 和 CloudNativeCon][1]上说,Kubernetes 的扩展能力是它的秘密武器。 在建立帮助工程师提高工作效率的工具的竞赛中,Goldberg 谈到他曾经领导过一个开发这样一个平台的团队。尽管平台最初有用,但它无法扩展,并且修改也很困难。 -幸运的是,Goldberg 说,Kubernetes 没有这些问题。首先,Kubernetes 是一个自我修复系统,因为它使用的控制器实现了“_协调环_”(Reconciliation Loop)。在协调环中,控制器观察系统的当前状态并将其与所需状态进行比较。一旦它确定了这两个状态之间的差异,它就会努力实现所需的状态。这使得 Kubernetes 非常适合动态环境。 +幸运的是,Goldberg 说,Kubernetes 没有这些问题。首先,Kubernetes 是一个自我修复系统,因为它使用的控制器实现了“协调环Reconciliation Loop”。在协调环中,控制器观察系统的当前状态并将其与所需状态进行比较。一旦它确定了这两个状态之间的差异,它就会努力实现所需的状态。这使得 Kubernetes 非常适合动态环境。 -### 3种扩展 Kubernetes 的方式 +### 3 种扩展 Kubernetes 的方式 -Goldberg 然后解释说,要建立控制器,你需要资源,也就是说,你需要扩展 Kubernetes。有三种方法可以做到这一点,从最灵活(但也更困难)到最简单的是:使用 Kube 聚合器,使用 API​​ 服务器构建器或创建自定义资源定义(或 CRD)。 +Goldberg 然后解释说,要建立控制器,你需要资源,也就是说,你需要扩展 Kubernetes。有三种方法可以做到这一点,从最灵活(但也更困难)到最简单的依次是:使用 Kube 聚合器、使用 API​​ 服务器构建器或创建自定义资源定义Custom Resource Definition(CRD)。 -后者允许即使使用最少的编码来扩展 Kubernetes 的功能。为了演示它是如何完成的,Goggle 软件工程师 Anthony Yeh 出席并展示了为 Kubernetes 添加一个状态集。 (状态集对象用于管理有状态应用,即需要存储应用状态的程序,跟踪例如用户身份及其个人设置。)使用 _catset_,在一个 100 行 JavaScript 的文件中实现的 CRD,Yeh 展示了如何将状态集添加到 Kubernetes 部署中。之前的扩展不是 CRD,需要 24 个文件和 3000 多行代码。 +后者甚至可以使用极少的代码来扩展 Kubernetes 的功能。为了演示它是如何完成的,Goggle 软件工程师 Anthony Yeh 上台展示了为 Kubernetes 添加一个状态集。 (状态集对象用于管理有状态应用,即需要存储应用状态的程序,跟踪例如用户身份及其个人设置。)使用 _catset_,在一个 100 行 JavaScript 的文件中实现的 CRD,Yeh 展示了如何将状态集添加到 Kubernetes 部署中。之前的扩展不是 CRD,需要 24 个文件和 3000 多行代码。 为解决 CRD 可靠性问题,Goldberg 表示,Kubernetes 已经启动了一项认证计划,允许公司在 Kubernetes 社区注册和认证其扩展。在一个月内,已有 30 多家公司报名参加该计划。 @@ -31,7 +31,7 @@ via: https://www.linux.com/blog/event/kubecon/2018/2/3-ways-extend-power-kuberne 作者:[PAUL BROWN][a] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180203 How to print filename with awk on Linux - Unix.md b/published/201803/20180203 How to print filename with awk on Linux - Unix.md similarity index 63% rename from translated/tech/20180203 How to print filename with awk on Linux - Unix.md rename to published/201803/20180203 How to print filename with awk on Linux - Unix.md index 58307d1e5c..34fc95c484 100644 --- a/translated/tech/20180203 How to print filename with awk on Linux - Unix.md +++ b/published/201803/20180203 How to print filename with awk on Linux - Unix.md @@ -1,8 +1,9 @@ -# 如何在 Linux / Unix 上使用 awk 打印文件名 +如何在 Linux / Unix 上使用 awk 打印文件名 +================= -我想在 Linux / 类Unix 系统上使用 awk 打印文件名。 如何使用 awk 的 BEGIN 特殊模式打印文件名? 我可以使用 gawk/awk 打印当前输入文件的名称吗?( LCTT 注:读者最好能有一些 awk 的背景知识,否则阅读本文的时候会有一些困惑) +Q:我想在 Linux / 类Unix 系统上使用 awk 打印文件名。 如何使用 awk 的 `BEGIN` 特殊模式打印文件名? 我可以使用 gawk/awk 打印当前输入文件的名称吗?(LCTT 译注:读者最好能有一些 awk 的背景知识,否则阅读本文的时候会有一些困惑) -在 FILENAME 变量中存放着当前输入文件的名称。 您可以使用 FILENAME 显示或打印当前输入文件名,如果在命令行中未指定文件,则FILENAME的值为“ - ”(标准输入)( LCTT 注:多次按下回车键即可看到效果)。 但是,除非由 getline 设置,否则 FILENAME 在 BEGIN 特殊模式中未定义。 +在 `FILENAME` 变量中存放着当前输入文件的名称。 您可以使用 `FILENAME` 显示或打印当前输入文件名,如果在命令行中未指定文件,则 `FILENAME` 的值为 `-` (标准输入)(LCTT 译注:多次按下回车键即可看到效果)。 但是,除非由 `getline` 设置,否则 `FILENAME` 在 `BEGIN` 特殊模式中未定义。 ### 使用 awk 打印文件名 @@ -12,43 +13,48 @@ awk '{ print FILENAME }' fileNameHere awk '{ print FILENAME }' /etc/hosts ``` -因 awk 逐行读取文件,因此,你可能看到多个文件名,为了避免这个情况,你可以使用如下的命令:( LCTT注:FNR 表示当前记录数,只在文件中有效) + +因 awk 逐行读取文件,因此,你可能看到多个文件名,为了避免这个情况,你可以使用如下的命令:(LCTT 译注:`FNR` 表示当前记录数,只在文件中有效) ``` awk 'FNR == 1{ print FILENAME } ' /etc/passwd awk 'FNR == 1{ print FILENAME } ' /etc/hosts ``` + ![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-print-filename-using-awk-on-Linux-or-Unix.jpg) ### 使用 awk 的 BEGIN 特殊规则打印文件名 -使用下面的语法:( LCTT 注:ARGV[I] 表示输入的第 i 个参数) +使用下面的语法:(LCTT 译注:`ARGV[I]` 表示输入的第 i 个参数) ``` awk 'BEGIN{print ARGV[1]}' fileNameHere awk 'BEGIN{print ARGV[1]}{ print "someting or do something on data" }END{}' fileNameHere awk 'BEGIN{print ARGV[1]}' /etc/hosts ``` + 示例输出: ``` /etc/hosts - ``` -然而,ARGV\[1\] 并不是每一次都能奏效,例如: +然而,`ARGV[1]` 并不是每一次都能奏效,例如: -`ls -l /etc/hosts | awk 'BEGIN{print ARGV[1]} { print }'` +``` +ls -l /etc/hosts | awk 'BEGIN{print ARGV[1]} { print }' +``` -你需要将它修改如下(假设 ls -l 只产生一行输出): +你需要将它修改如下(假设 `ls -l` 只产生一行输出): -`ls -l /etc/hosts | awk '{ print "File: " $9 ", Owner:" $3 ", Group: " $4 }'` +``` +ls -l /etc/hosts | awk '{ print "File: " $9 ", Owner:" $3 ", Group: " $4 }' +``` 示例输出: ``` File: /etc/hosts, Owner:root, Group: root - ``` ### 处理由通配符指定的多个文件名 @@ -59,6 +65,7 @@ File: /etc/hosts, Owner:root, Group: root awk '{ print FILENAME; nextfile } ' *.c awk 'BEGIN{ print "Starting..."} { print FILENAME; nextfile }END{ print "....DONE"} ' *.conf ``` + 示例输出: ``` @@ -101,10 +108,9 @@ xattr.conf xinetd.conf yp.conf ....DONE - ``` -nextfile 告诉 awk 停止处理当前的输入文件。 下一个输入记录读取来自下一个输入文件。 更多信息,请参见 awk/[gawk][1] 命令手册页: +`nextfile` 告诉 awk 停止处理当前的输入文件。 下一个输入记录读取来自下一个输入文件。 更多信息,请参见 awk/[gawk][1] 命令手册页: ``` man awk @@ -115,11 +121,13 @@ man gawk 作者是 nixCraft 的创立者,也是经验丰富的系统管理员和 Linux/Unix shell 脚本的培训师。 他曾与全球各行各业的客户合作,涉及 IT,教育,国防和空间研究以及非营利部门等多个行业。 您可以在 [Twitter][2],[Facebook][3] 和 [Google+][4]上关注他。 可以通过订阅我的 [RSS][5] 来获取更多的关于**系统管理,Linux/Unix ,和开源主题**的相关资料。 +------------- + via: https://www.cyberciti.biz/faq/how-to-print-filename-with-awk-on-linux-unix/ -作者:Vivek GIte[][a] +作者:[Vivek Gite][a] 译者:[amwps290](https://github.com/amwps290) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180204 How to Check if Your Computer Uses UEFI or BIOS.md b/published/201803/20180204 How to Check if Your Computer Uses UEFI or BIOS.md similarity index 100% rename from published/20180204 How to Check if Your Computer Uses UEFI or BIOS.md rename to published/201803/20180204 How to Check if Your Computer Uses UEFI or BIOS.md diff --git a/published/20180204 LKRG- Linux to Get a Loadable Kernel Module for Runtime Integrity Checking.md b/published/201803/20180204 LKRG- Linux to Get a Loadable Kernel Module for Runtime Integrity Checking.md similarity index 100% rename from published/20180204 LKRG- Linux to Get a Loadable Kernel Module for Runtime Integrity Checking.md rename to published/201803/20180204 LKRG- Linux to Get a Loadable Kernel Module for Runtime Integrity Checking.md diff --git a/translated/tech/20180204 Python Hello World and String Manipulation.md b/published/201803/20180204 Python Hello World and String Manipulation.md similarity index 52% rename from translated/tech/20180204 Python Hello World and String Manipulation.md rename to published/201803/20180204 Python Hello World and String Manipulation.md index 3c5bb2ac04..6763873658 100644 --- a/translated/tech/20180204 Python Hello World and String Manipulation.md +++ b/published/201803/20180204 Python Hello World and String Manipulation.md @@ -1,113 +1,113 @@ -Python 中的 Hello World 和字符串操作 +初识 Python:Hello World 和字符串操作 ====== ![](https://process.filestackapi.com/cache=expiry:max/resize=width:700/compress/eadkmsrBTcWSyCeA4qti) -开始之前,说一下本文中的[代码][1]和[视频][2]可以在我的 github 上找到。 +开始之前,说一下本文中的[代码][1]和[视频][2]可以在我的 GitHub 上找到。 -那么,让我们开始吧!如果你糊涂了,我建议你在单独的选项卡中打开下面的[视频][3]。 +那么,让我们开始吧!如果你糊涂了,我建议你在单独的选项卡中打开下面的视频。 -[Python 的 Hello World 和字符串操作视频][2] +- [Python 的 Hello World 和字符串操作视频][2] -#### ** 开始 (先决条件) +### 开始 (先决条件) -在你的操作系统上安装 Anaconda(Python)。你可以从[官方网站][4]下载 anaconda 并自行安装,或者你可以按照以下这些 anaconda 安装教程进行安装。 +首先在你的操作系统上安装 Anaconda (Python)。你可以从[官方网站][4]下载 anaconda 并自行安装,或者你可以按照以下这些 anaconda 安装教程进行安装。 -在 Windows 上安装 Anaconda: [链接[5] +- 在 Windows 上安装 Anaconda: [链接[5] +- 在 Mac 上安装 Anaconda: [链接][6] +- 在 Ubuntu (Linux) 上安装 Anaconda:[链接][7] -在 Mac 上安装 Anaconda: [链接][6] - -在 Ubuntu (Linux) 上安装 Anaconda:[链接][7] - -#### 打开一个 Jupyter Notebook +### 打开一个 Jupyter Notebook 打开你的终端(Mac)或命令行,并输入以下内容([请参考视频中的 1:16 处][8])来打开 Jupyter Notebook: + ``` jupyter notebook - ``` -#### 打印语句/Hello World +### 打印语句/Hello World + +在 Jupyter 的单元格中输入以下内容并按下 `shift + 回车`来执行代码。 -在 Jupyter 的单元格中输入以下内容并按下 **shift + 回车**来执行代码。 ``` # This is a one line comment print('Hello World!') - ``` -![][9] -打印输出 “Hello World!” +![](https://cdn-images-1.medium.com/max/1600/1*tRRBPYjREydsRIcKFa9NPQ.png) -#### 字符串和字符串操作 +*打印输出 “Hello World!”* + +### 字符串和字符串操作 + +字符串是 Python 类的一种特殊类型。作为对象,在类中,你可以使用 `.methodName()` 来调用字符串对象的方法。字符串类在 Python 中默认是可用的,所以你不需要 `import` 语句来使用字符串对象接口。 -字符串是 python 类的一种特殊类型。作为对象,在类中,你可以使用 .methodName() 来调用字符串对象的方法。字符串类在 python 中默认是可用的,所以你不需要 import 语句来使用字符串对象接口。 ``` # Create a variable # Variables are used to store information to be referenced # and manipulated in a computer program. firstVariable = 'Hello World' print(firstVariable) - ``` -![][9] -输出打印变量 firstVariable +![](https://cdn-images-1.medium.com/max/1600/1*f0aXyvLgXb7PCV1Xao_D8Q.png) + +*输出打印变量 firstVariable* + ``` # Explore what various string methods print(firstVariable.lower()) print(firstVariable.upper()) print(firstVariable.title()) - ``` -![][9] -使用 .lower()、.upper() 和 title() 方法输出 +![](https://cdn-images-1.medium.com/max/1600/1*8dZfNBBABBSTuXxqE9mI3g.png) + +*使用 .lower()、.upper() 和 title() 方法输出* + ``` # Use the split method to convert your string into a list print(firstVariable.split(' ')) - ``` -![][9] -使用 split 方法输出(此例中以空格分隔) +![](https://cdn-images-1.medium.com/max/1600/1*gG7KFXpkNjbYjQgZwgtGTQ.png) + +*使用 split 方法输出(此例中以空格分隔)* + ``` # You can add strings together. a = "Fizz" + "Buzz" print(a) - ``` -![][9] -字符串连接 +![](https://cdn-images-1.medium.com/max/1600/1*p7y9qCsQmXAbae7Cf9t_3w.png) -#### 查询方法的功能 +*字符串连接* + +### 查询方法的功能 对于新程序员,他们经常问你如何知道每种方法的功能。Python 提供了两种方法来实现。 - 1.(在不在 Jupyter Notebook 中都可用)使用 **help** 查询每个方法的功能。 +1、(在不在 Jupyter Notebook 中都可用)使用 `help` 查询每个方法的功能。 +![](https://cdn-images-1.medium.com/max/1600/1*3Mz8PtPFypNrptb9JqyOqA.png) +*查询每个方法的功能* -![][9] - 查询每个方法的功能 - - 2. (Jupyter Notebook exclusive) You can also look up what a method does by having a question mark after a method. - 2.(Jupyter Notebook 专用)你也可以通过在方法之后添加问号来查找方法的功能。 - +2.(Jupyter Notebook 专用)你也可以通过在方法之后添加问号来查找方法的功能。 ``` # To look up what each method does in jupyter (doesnt work outside of jupyter) firstVariable.lower? - ``` -![][9] -在 Jupyter 中查找每个方法的功能 +![](https://cdn-images-1.medium.com/max/1600/1*VrLofndKpFcsKNAsv5vz9Q.png) -#### 结束语 +*在 Jupyter 中查找每个方法的功能* -如果你对本文或在[ YouTube 视频][2]的评论部分有任何疑问,请告诉我们。文章中的代码也可以在我的 [github][1] 上找到。本系列教程的第 2 部分是[简单的数学操作][10]。 +### 结束语 + +如果你对本文或在 [YouTube 视频][2]的评论部分有任何疑问,请告诉我们。文章中的代码也可以在我的 [GitHub][1] 上找到。本系列教程的第 2 部分是[简单的数学操作][10]。 -------------------------------------------------------------------------------- @@ -115,7 +115,7 @@ via: https://www.codementor.io/mgalarny/python-hello-world-and-string-manipulati 作者:[Michael][a] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180205 A File Transfer Utility To Download Only The New Parts Of A File.md b/published/201803/20180205 A File Transfer Utility To Download Only The New Parts Of A File.md similarity index 55% rename from translated/tech/20180205 A File Transfer Utility To Download Only The New Parts Of A File.md rename to published/201803/20180205 A File Transfer Utility To Download Only The New Parts Of A File.md index 1055aeacf4..444eb923c8 100644 --- a/translated/tech/20180205 A File Transfer Utility To Download Only The New Parts Of A File.md +++ b/published/201803/20180205 A File Transfer Utility To Download Only The New Parts Of A File.md @@ -1,43 +1,41 @@ -一个仅下载文件新的部分的传输工具 +Zsync:一个仅下载文件新的部分的传输工具 ====== ![](https://www.ostechnix.com/wp-content/uploads/2018/02/Linux-1-720x340.png) -仅仅因为网费每天变得越来越便宜,你也不应该重复下载相同的东西来浪费你的流量。一个很好的例子就是下载 Ubuntu 或任何 Linux 镜像的开发版本。如你所知,Ubuntu 开发人员每隔几个月就会发布一次日常构建、alpha、beta 版 ISO 镜像以供测试。在过去,一旦发布我就会下载这些镜像,并审查每个版本。现在不用了!感谢 **Zsync** 文件传输程序。现在可以仅下载 ISO 镜像新的部分。这将为你节省大量时间和 Internet 带宽。不仅时间和带宽,它将为你节省服务端和客户端的资源。 +就算是网费每天变得越来越便宜,你也不应该重复下载相同的东西来浪费你的流量。一个很好的例子就是下载 Ubuntu 或任何 Linux 镜像的开发版本。如你所知,Ubuntu 开发人员每隔几个月就会发布一次日常构建、alpha、beta 版 ISO 镜像以供测试。在过去,一旦发布我就会下载这些镜像,并审查每个版本。现在不用了!感谢 Zsync 文件传输程序。现在可以仅下载 ISO 镜像新的部分。这将为你节省大量时间和 Internet 带宽。不仅时间和带宽,它将为你节省服务端和客户端的资源。 -Zsync 使用与 **Rsync** 相同​​的算法,但它只下载文件的新部分,你会得到一份已有文件旧版本的副本。 Rsync 主要用于在计算机之间同步数据,而 Zsync 则用于分发数据。简单地说,可以使用 Zsync 将中心的一个文件分发给数千个下载者。它在 Artistic License V2 许可证下发布,完全免费且开源。 +Zsync 使用与 Rsync 相同​​的算法,如果你会得到一份已有文件旧版本,它只下载该文件新的部分。 Rsync 主要用于在计算机之间同步数据,而 Zsync 则用于分发数据。简单地说,可以使用 Zsync 将中心的一个文件分发给数千个下载者。它在 Artistic License V2 许可证下发布,完全免费且开源。 ### 安装 Zsync Zsync 在大多数 Linux 发行版的默认仓库中有。 -在 **Arch Linux** 及其衍生版上,使用命令安装它: +在 Arch Linux 及其衍生版上,使用命令安装它: ``` $ sudo pacman -S zsync - ``` -在 **Fedora** 上: +在 Fedora 上,启用 Zsync 仓库: -启用 Zsync 仓库: ``` $ sudo dnf copr enable ngompa/zsync - ``` 并使用命令安装它: + ``` $ sudo dnf install zsync - ``` -在 **Debian、Ubuntu、Linux Mint** 上: +在 Debian、Ubuntu、Linux Mint 上: + ``` $ sudo apt-get install zsync - ``` -对于其他发行版,你可以从 [**Zsync 下载页面**][1]下载二进制文件,并手动编译安装它,如下所示。 +对于其他发行版,你可以从 [Zsync 下载页面][1]下载二进制打包文件,并手动编译安装它,如下所示。 + ``` $ wget http://zsync.moria.org.uk/download/zsync-0.6.2.tar.bz2 $ tar xjf zsync-0.6.2.tar.bz2 @@ -45,44 +43,41 @@ $ cd zsync-0.6.2/ $ configure $ make $ sudo make install - ``` ### 用法 -请注意,**只有当人们提供 zsync 下载时,zsync 才有用**。目前,Debian、Ubuntu(所有版本)的 ISO 镜像都可以用 .zsync 下载。例如,请访问以下链接。 +请注意,只有当人们提供 zsync 下载方式时,zsync 才有用。目前,Debian、Ubuntu(所有版本)的 ISO 镜像都有 .zsync 下载链接。例如,请访问以下链接。 -你可能注意到,Ubuntu 18.04 LTS 每日构建版有直接的 ISO 和 .zsync 文件。如果你下载 .ISO 文件,则必须在 ISO 更新时下载完整的 ISO 文件。但是,如果你下载的是 .zsync 文件,那么 Zsync 将在未来仅下载新的更改。你不需要每次都下载整个 ISO 映像。 +你可能注意到,Ubuntu 18.04 LTS 每日构建版有直接的 ISO 和 .zsync 文件。如果你下载 .ISO 文件,则必须在 ISO 更新时下载完整的 ISO 文件。但是,如果你下载的是 .zsync 文件,那么 Zsync 以后仅会下载新的更改。你不需要每次都下载整个 ISO 映像。 .zsync 文件包含 zsync 程序所需的元数据。该文件包含 rsync 算法的预先计算的校验和。它在服务器上生成一次,然后由任意数量的下载器使用。要使用 Zsync 客户端程序下载 .zsync 文件,你只需执行以下操作: + ``` $ zsync <.zsync-file-URL> - ``` 例如: + ``` $ zsync http://cdimage.ubuntu.com/ubuntu/daily-live/current/bionic-desktop-amd64.iso.zsync - ``` 如果你的系统中已有以前的镜像文件,那么 Zsync 将计算远程服务器中旧文件和新文件之间的差异,并仅下载新的部分。你将在终端看见计算过程一系列的点或星星。 -如果你下载的文件的旧版本存在于当前工作目录,那么 Zsync 将只下载新的部分。下载完成后,你将看到两个镜像,一个你刚下载的镜像和以 **.iso.zs-old** 为扩展名的旧镜像。 +如果你下载的文件的旧版本存在于当前工作目录,那么 Zsync 将只下载新的部分。下载完成后,你将看到两个镜像,一个你刚下载的镜像和以 .iso.zs-old 为扩展名的旧镜像。 如果没有找到相关的本地数据,Zsync 会下载整个文件。 ![](http://www.ostechnix.com/wp-content/uploads/2018/02/Zsync-1.png) -你可以随时按 **CTRL-C** 取消下载过程。 +你可以随时按 `CTRL-C` 取消下载过程。 试想一下,如果你直接下载 .ISO 文件或使用 torrent,每当你下载新镜像时,你将损失约 1.4GB 流量。因此,Zsync 不会下载整个 Alpha、beta 和日常构建映像,而只是在你的系统上下载了 ISO 文件的新部分,并在系统中有一个旧版本的拷贝。 -今天就到这里。希望对你有帮助。我将很快另外写一篇有用的指南。在此之前,请继续关注 OSTechNix! - -干杯! - +今天就到这里。希望对你有帮助。我将很快另外写一篇有用的指南。在此之前,请保持关注! +干杯! -------------------------------------------------------------------------------- @@ -90,7 +85,7 @@ via: https://www.ostechnix.com/zsync-file-transfer-utility-download-new-parts-fi 作者:[SK][a] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180205 Block ads on your network with Raspberry Pi and pi-hole.md b/published/201803/20180205 Block ads on your network with Raspberry Pi and pi-hole.md similarity index 81% rename from translated/tech/20180205 Block ads on your network with Raspberry Pi and pi-hole.md rename to published/201803/20180205 Block ads on your network with Raspberry Pi and pi-hole.md index a2dd85f4d5..41e8f0afe6 100644 --- a/translated/tech/20180205 Block ads on your network with Raspberry Pi and pi-hole.md +++ b/published/201803/20180205 Block ads on your network with Raspberry Pi and pi-hole.md @@ -1,11 +1,13 @@ -使用树莓派和 pi-hole 拦截你的网络上的广告 +在你的网络中使用树莓派和 Pi-hole 拦截广告 ====== +> 痛恨上网时看到广告?学习这篇教程来设置 Pi-hole。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/pi-hole-banner.png?itok=1TXcp3hm) 有一个闲置的树莓派?在浏览网页时讨厌广告?[Pi-hole][1] 是一个拦截广告的开源软件项目,它可以将你的家庭网络上的所有广告路由到一个不存在的地方,从而实现在你的设备上拦截广告的目的。这么好的方法只需要花几钟的时间来设置,你就可以使用它了。 -Pi-hole 拦截了超过 100,000 个提供广告的域名,它可以拦截任何设备(包括移动设备、平板电脑、以及个人电脑)上的广告,并且它是完整的拦截了广告,而不是仅将它们隐藏起来,它这样做可以提升总体的网络性能(因为广告不需要下载)。你可以在一个 web 界面上、或者也可以使用一个 API 来监视性能和统计数据。 +Pi-hole 拦截了超过 100,000 个提供广告的域名,它可以拦截任何设备(包括移动设备、平板电脑、以及个人电脑)上的广告,并且它是完整的拦截了广告,而不是仅将它们隐藏起来,这样做可以提升总体的网络性能(因为广告不需要下载)。你可以在一个 web 界面上、或者也可以使用一个 API 来监视性能和统计数据。 ### 你需要: @@ -19,7 +21,7 @@ Pi-hole 拦截了超过 100,000 个提供广告的域名,它可以拦截任何 ![](https://opensource.com/sites/default/files/u128651/power-supply.png) ![](https://opensource.com/sites/default/files/u128651/ethernet-cable.png) -你不需要使用一个最新型号的树莓派 — 一个老款足够完成这项工作,只要它的内存不小于 512MB 就可以 — 因此一个一代树莓派 Model B(rev 2)就足够,一个 Model B+、或者二代的或者三代的树莓派都可以。你可能需要一个 Pi Zero,也需要一个 USB micro 以太网适配器。你可以使用一个带 WiFi 的 Pi Zero W 而不是以太网。但是,作为你的网络基础设施的一部分,我建议你使用一个性能良好、稳定的有线连接来代替 WiFi 连接。 +你不需要使用一个最新型号的树莓派 — 一个老款足够完成这项工作,只要它的内存不小于 512MB 就可以 — 因此一个一代树莓派 Model B(rev 2)就足够,一个 Model B+、或者二代的或者三代的树莓派都可以。你可以使用 Pi Zero,但需要一个 USB micro 以太网适配器。你可以使用一个带 WiFi 的 Pi Zero W 而不是以太网。但是,作为你的网络基础设施的一部分,我建议你使用一个性能良好、稳定的有线连接来代替 WiFi 连接。 ### 准备 SD 卡 @@ -33,14 +35,14 @@ Pi-hole 拦截了超过 100,000 个提供广告的域名,它可以拦截任何 ![](https://opensource.com/sites/default/files/etcher-win-520px.png) -SD 卡准备完成之后,你可以将它插入到你的树莓派,连接上键盘、显示器、和以太网,然后为树莓派接上电源。在初始化设置之后,这个树莓派就不需要键盘或显示器了。如果你有使用”无头“树莓派工作的经验,你可以去 [启用 SSH][4] 然后去设置它 [启用远程连接][5]。 +SD 卡准备完成之后,你可以将它插入到你的树莓派,连接上键盘、显示器和以太网,然后为树莓派接上电源。在初始化设置之后,这个树莓派就不需要键盘或显示器了。如果你有使用“无末端headless”树莓派工作的经验,你可以 [启用 SSH][4] 然后去设置它 [启用远程连接][5]。 ### 安装 Pi-hole 在你的树莓派引导完成之后,用缺省用户名(`pi`)和密码(`raspberry`)登入。现在你就可以运行命令行了,可以去安装 Pi-hole 了。简单地输入下列命令并回车: + ``` curl -sSL https://install.pi-hole.net | bash - ``` 这个命令下载了 Pi-hole 安装脚本然后去运行它。你可以在你的电脑浏览器中输入 `https://install.pi-hole.net` 来查看它的内容,你将会看到这个脚本做了些什么。它为你生成了一个**管理员密码**,并和其它安装信息一起显示在你的屏幕上。 @@ -59,17 +61,17 @@ curl -sSL https://install.pi-hole.net | bash 关于这一步的更多信息,可以查看 [Pi-hole discourse][6]。 -你还需要确保你的 Pi-hole 始终保持相同的 IP 地址,因此,你需要去查看 DHCP,将你的树莓派的 IP 地址条目添加到保留地址中。 +你还需要确保你的 Pi-hole 始终保持相同的 IP 地址,因此,你需要去查看 DHCP 设置,将你的树莓派的 IP 地址条目添加到保留地址中。 ### 外部测试 现在,在命令行下输入 `sudo halt` 关闭运行的树莓派,并断开它的电源。你可以拔掉显示器连接线和键盘,然后将你的树莓派放置到一个合适的固定的地方 — 或许应该将它放在你的路由器附近。确保连接着以太网线,然后重新连接电源以启动它。 -在你的个人电脑上导航到一个网站(强烈建议访问 [Opensource.com][7] 网站),或者用你的 WiFi 中的一个设备去检查你的因特网访问是否正常(如果不能正常访问,可能是你的 DNS 配置错误)。如果在浏览器中看到了预期的结果,说明它的工作正常。现在,你浏览网站时,应该再也看不到广告了!甚至在你的 apps 中提供的广告也无法出现在你的移动设备中!祝你”冲浪“愉快! +在你的个人电脑上导航到一个网站(强烈建议访问 [Opensource.com][7] 网站),或者用你的 WiFi 中的一个设备去检查你的因特网访问是否正常(如果不能正常访问,可能是你的 DNS 配置错误)。如果在浏览器中看到了预期的结果,说明它的工作正常。现在,你浏览网站时,应该再也看不到广告了!甚至在你的 app 中提供的广告也无法出现在你的移动设备中!祝你“冲浪”愉快! 如果你想去测试一下你的广告拦截的新功能,你可以去这个 [测试页面][8] 尝试浏览一些内置广告的网站。 -现在你可以在你的电脑浏览器上输入 Pi-hole 的 IP 地址来访问它的 web 界面(比如, \- 或者 `http://pi.hole/admin` 也可能会工作)。你将看到 Pi-hole 管理面板和一些统计数据(在这时可能数字比较小)。在你输入密码(在安装时显示在屏幕上的)后,你将看到更漂亮的图形界面: +现在你可以在你的电脑浏览器上输入 Pi-hole 的 IP 地址来访问它的 web 界面(比如,`http://192.168.1.4/admin` 或者 `http://pi.hole/admin` 也可能会工作)。你将看到 Pi-hole 管理面板和一些统计数据(在这时可能数字比较小)。在你输入(在安装时显示在屏幕上的)密码后,你将看到更漂亮的图形界面: ![](https://opensource.com/sites/default/files/u128651/pi-hole-web.png) @@ -87,7 +89,7 @@ via: https://opensource.com/article/18/2/block-ads-raspberry-pi 作者:[Ben Nuttall][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180205 New Linux User- Try These 8 Great Essential Linux Apps.md b/published/201803/20180205 New Linux User- Try These 8 Great Essential Linux Apps.md similarity index 100% rename from published/20180205 New Linux User- Try These 8 Great Essential Linux Apps.md rename to published/201803/20180205 New Linux User- Try These 8 Great Essential Linux Apps.md diff --git a/published/20180207 How To Easily Correct Misspelled Bash Commands In Linux.md b/published/201803/20180207 How To Easily Correct Misspelled Bash Commands In Linux.md similarity index 100% rename from published/20180207 How To Easily Correct Misspelled Bash Commands In Linux.md rename to published/201803/20180207 How To Easily Correct Misspelled Bash Commands In Linux.md diff --git a/published/20180208 Advanced Dnsmasq Tips and Tricks.md b/published/201803/20180208 Advanced Dnsmasq Tips and Tricks.md similarity index 100% rename from published/20180208 Advanced Dnsmasq Tips and Tricks.md rename to published/201803/20180208 Advanced Dnsmasq Tips and Tricks.md diff --git a/published/20180209 Gnome without chrome-gnome-shell.md b/published/201803/20180209 Gnome without chrome-gnome-shell.md similarity index 100% rename from published/20180209 Gnome without chrome-gnome-shell.md rename to published/201803/20180209 Gnome without chrome-gnome-shell.md diff --git a/published/201803/20180209 How to setup and configure network bridge on Debian Linux.md b/published/201803/20180209 How to setup and configure network bridge on Debian Linux.md new file mode 100644 index 0000000000..1e7f4a5b9c --- /dev/null +++ b/published/201803/20180209 How to setup and configure network bridge on Debian Linux.md @@ -0,0 +1,158 @@ +如何在 Debian Linux 上设置和配置网桥 +===== + +Q:我是一个新 Debian Linux 用户,我想为 Debian Linux 上运行的虚拟化环境(KVM)设置网桥。那么我该如何在 Debian Linux 9.x 服务器上的 `/etc/network/interfaces` 中设置桥接网络呢? + +如何你想为你的虚拟机分配 IP 地址并使其可从你的局域网访问,则需要设置网络桥接器。默认情况下,虚拟机使用 KVM 创建的专用网桥。但你需要手动设置接口,避免与网络管理员发生冲突。 + +### 怎样安装 brctl + +输入以下 [apt-get 命令][1]: + +``` +$ sudo apt install bridge-utils +``` + +### 怎样在 Debian Linux 上设置网桥 + +你需要编辑 `/etc/network/interface` 文件。不过,我建议在 `/etc/network/interface.d/` 目录下放置一个全新的配置。在 Debian Linux 配置网桥的过程如下: + +#### 步骤 1 - 找出你的物理接口 + +使用 [ip 命令][2]: + +``` +$ ip -f inet a s +``` + +示例输出如下: + +``` +2: eno1: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 + inet 192.168.2.23/24 brd 192.168.2.255 scope global eno1 + valid_lft forever preferred_lft forever +``` + +`eno1` 是我的物理网卡。 + +#### 步骤 2 - 更新 /etc/network/interface 文件 + +确保只有 `lo`(loopback 在 `/etc/network/interface` 中处于活动状态)。(LCTT 译注:loopback 指本地环回接口,也称为回送地址)删除与 `eno1` 相关的任何配置。这是我使用 [cat 命令][3] 打印的配置文件: + +``` +$ cat /etc/network/interface +``` + +``` +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). +  +source /etc/network/interfaces.d/* +  +# The loopback network interface +auto lo +iface lo inet loopback +``` + +#### 步骤 3 - 在 /etc/network/interfaces.d/br0 中配置网桥(br0) + +使用文本编辑器创建一个文本文件,比如 `vi` 命令: + +``` +$ sudo vi /etc/network/interfaces.d/br0 +``` + +在其中添加配置: + +``` +## static ip config file for br0 ## +auto br0 +iface br0 inet static + address 192.168.2.23 + broadcast 192.168.2.255 + netmask 255.255.255.0 + gateway 192.168.2.254 + # If the resolvconf package is installed, you should not edit + # the resolv.conf configuration file manually. Set name server here + #dns-nameservers 192.168.2.254 + # If you have muliple interfaces such as eth0 and eth1 + # bridge_ports eth0 eth1 + bridge_ports eno1 + bridge_stp off # disable Spanning Tree Protocol + bridge_waitport 0 # no delay before a port becomes available + bridge_fd 0 # no forwarding delay +``` + +如果你想使用 DHCP 来获得 IP 地址: + +``` +## DHCP ip config file for br0 ## +auto br0 +  +# Bridge setup + iface br0 inet dhcp + bridge_ports eno1 +``` + +[在 vi/vim 中保存并关闭文件][4]。 + +#### 步骤 4 - 重新启动网络服务 + +在重新启动网络服务之前,请确保防火墙已关闭。防火墙可能会引用较老的接口,例如 `eno1`。一旦服务重新启动,你必须更新 `br0` 接口的防火墙规则。键入以下命令重新启动防火墙: + +``` +$ sudo systemctl restart network-manager +``` + +确认服务已经重新启动: + +``` +$ systemctl status network-manager +``` + +借助 [ip 命令][2]寻找新的 `br0` 接口和路由表: + +``` +$ ip a s $ ip r $ ping -c 2 cyberciti.biz +``` + +示例输出: + +![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-setup-and-configure-network-bridge-on-Debian-Linux.jpg) + +你可以使用 brctl 命令查看网桥有关信息: + +``` +$ brctl show +``` + +显示当前网桥: + +``` +$ bridge link +``` + +![](https://www.cyberciti.biz/media/new/faq/2018/02/Show-current-bridges-and-what-interfaces-they-are-connected-to-on-Linux.jpg) + +### 关于作者 + +作者是 nixCraft 的创建者,也是经验丰富的系统管理员,DevOps 工程师以及 Linux 操作系统/ Unix shell 脚本的培训师。通过订阅 [RSS/XML 流][6] 或者 [每周邮件推送][7]获得关于 SysAdmin, Linux/Unix 和开源主题的最新教程。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-configuring-bridging-in-debian-linux/ + +作者:[Vivek GIte][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz/ +[1]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[2]:https://www.cyberciti.biz/faq/linux-ip-command-examples-usage-syntax/ (See Linux/Unix ip command examples for more info) +[3]:https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/ (See Linux/Unix cat command examples for more info) +[4]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/ +[5]:https://www.cyberciti.biz/faq/linux-restart-network-interface/ +[6]:https://www.cyberciti.biz/atom/atom.xml +[7]:https://www.cyberciti.biz/subscribe-to-weekly-linux-unix-newsletter-for-sysadmin/ diff --git a/published/20180213 Getting started with the RStudio IDE.md b/published/201803/20180213 Getting started with the RStudio IDE.md similarity index 100% rename from published/20180213 Getting started with the RStudio IDE.md rename to published/201803/20180213 Getting started with the RStudio IDE.md diff --git a/published/20180213 Linux ldd Command Explained with Examples.md b/published/201803/20180213 Linux ldd Command Explained with Examples.md similarity index 100% rename from published/20180213 Linux ldd Command Explained with Examples.md rename to published/201803/20180213 Linux ldd Command Explained with Examples.md diff --git a/published/20180217 The List Of Useful Bash Keyboard Shortcuts.md b/published/201803/20180217 The List Of Useful Bash Keyboard Shortcuts.md similarity index 100% rename from published/20180217 The List Of Useful Bash Keyboard Shortcuts.md rename to published/201803/20180217 The List Of Useful Bash Keyboard Shortcuts.md diff --git a/published/20180219 How Linux became my job.md b/published/201803/20180219 How Linux became my job.md similarity index 100% rename from published/20180219 How Linux became my job.md rename to published/201803/20180219 How Linux became my job.md diff --git a/published/20180221 Create a wiki on your Linux desktop with Zim.md b/published/201803/20180221 Create a wiki on your Linux desktop with Zim.md similarity index 100% rename from published/20180221 Create a wiki on your Linux desktop with Zim.md rename to published/201803/20180221 Create a wiki on your Linux desktop with Zim.md diff --git a/published/201803/20180306 Most Useful Linux Commands You Can Run in Windows 10.md b/published/201803/20180306 Most Useful Linux Commands You Can Run in Windows 10.md new file mode 100644 index 0000000000..6fec18c739 --- /dev/null +++ b/published/201803/20180306 Most Useful Linux Commands You Can Run in Windows 10.md @@ -0,0 +1,142 @@ +可以运行在 Windows 10 中的最实用的 Linux 命令 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-commands.png?itok=91oEXdO8) + +在本系列早先的文章中,我们讨论了关于如何在 [Windows 10 上开启 WSL 之旅][1] 的内容。作为本系列的最后一篇文章,我们准备探讨一些能在 Windows 10 上广泛使用的 Linux 命令。 + +话题深入之前,请先让我们明确本教程所适用的人群。本文适用于使用 Windows 10 系统,但是又想在 Azure、AWS 或是私有云平台上学习 Linux 的初级开发者。换句话说,就是为了帮助初次接触 Linux 系统的 Windows 10 用户。 + +您的工作任务决定了您所需要的命令,而我的需求可能和您的不一样。本文旨在帮助您在 Windwos 10 上舒服的使用 Linux。不过请牢记,WSL 并不提供硬件访问的功能,比如声卡、GPU,至少官方是这么描述的。但是这可能并不能阻止 Linux 用户的折腾精神。很多用户不仅完成了硬件访问,甚至已经在 Windows 10 上安装上了 Linux 桌面程序。但是本文并不会涉及这些内容,我们可能会讨论这些,但不是现在。 + +下面是我们需要着手的任务。 + +### 如何让您的 Linux 系统保持到最新的版本 + +因为 Linux 运行在了 Windows 系统中,所以您将被剥夺 Linux 系统所提供的所有安全特性。另外,如果不及时给 Linux 系统打补丁,你的 Windows 设备将被迫暴露在外界威胁中,所以还请保持您的 Linux 为最新版本。 + +WSL 官方支持 openSUSE/SUSE Linux Enterprise 和 Ubuntu。您也可以安装其他发行版,但是我只需要它们当中的二者之一就可以完成我的所有工作,毕竟,我只需要访问一些 Linux 基础程序。 + +**更新 openSUSE Leap:** + +``` +sudo zypper up +``` + +如果您想升级系统,您可以运行下面的命令: + +``` +sudo zypper dup +``` + +**更新 Ubuntu:** + +``` +sudo apt-get update +sudo apt-get dist-upgrade +``` + +这样你就安全了,由于 Linux 系统的更新是渐进式的,所以更新系统成为了我的日常。不像 Windows 10 的更新通常需要重启系统,而 Linux 不同,一般只有 KB 或是 MB 级的更新,无需重启。 + +### 管理文件目录 + +系统更新之后,我们来看看一些或普通或不太普通的任务。 + +系统更新之外的第二重要的任务是使用 Linux 管理本地和远程文件。我承认我更青睐图形界面程序,但是终端能提供更可靠、更有价值的服务。要不你使用资源管理器移动 1 TB 的文件试试?我通常使用 `rsync` 命令来移动大量文件。如果中断任务,`rsync` 可以在上次停止的位置继续工作。 + +虽然您可能更习惯使用 `cp` 或是 `mv` 命令复制、移动文件,但是我还是喜欢灵活的 `rsync` 命令,了解 `rsync` 对远程文件传输也有帮助。使用 `rsync` 大半为了完成下面三个任务: + +**使用 rsync 复制整个目录:** + +``` +rsync -avzP /source-directory /destination directory +``` + +**使用 rsync 移动文件:** + +``` +rsync --remove-source-files -avzP /source-directory /destination-directory +``` + +在成功复制目标目录之后,此命令将删除源文件。 + +**使用 rsync 同步文件:** + +我的文件可能在多处存储。但是,我只会在主要位置中增加或是删除。如果不使用专业的软件,同步文件可能会给用户带来挑战,而 `rsync` 刚好可以简化这个过程。这个命令可以让两个目录文件内容同步。不过要注意,这是一个单向同步,即从源位置同步到目标位置。 + +``` +rsync --delete -avzP /source-directory /destination-directory +``` + +如果源目录中没有找到文件,上述命令将删除目标目录中的文件。换言之,它创建了源目录的一个镜像。 + +### 文件自动备份 + +保持文件备份是一项乏味的工作。为了保持我的设备的完全同步,我运行了一个 cron 作业在夜间保持我的所有目录同步。不过我会留一个外部驱动器,基本上每周我都会手动同步一次。由于可能删掉我不想删除的文件,所以我并没有使用 `--delete` 选项。我会根据情况手动决定是否使用这个选项。 + +**创建 cron 作业,打开 crontab:** + +``` +crontab -e +``` + +移动大文件时,我会选择在系统空闲的深夜执行该命令。此命令将在每天早上 1 点运行,您大概可以这样修改它: + +``` +# 0 1 * * * rsync -avzP /source-directory /destination-directory +``` + +这是使用 crontab 的定时作业的命令结构: + +``` +# m h dom mon dow command +``` + +在此,`m` = 分钟,`h` = 小时,`dom` = 本月的某天,`mon` = 月,`dow` = 本周的某天。 + +我们将在每天早上 1 点运行这条命令。您可以选择 `dow` 或是 `dom`(比如,每月 5 号)等。您可以在 [这里][2] 阅读更多相关内容。 + +### 管理远程服务器 + +在 Windows 系统上使用 WSL 的优势之一就是能方便管理云上的 Linux 服务器,WSL 能提供原生的 Linux 工具给您。首先,您需要使用 `ssh` 命令登录远程 Linux 服务器。 + +比如,我的服务器 ip 是 192.168.0.112;端口为 2018(不是默认的 22 端口);Linux 用户名是 swapnil,密码是 “就不告诉你”。 + +``` +ssh -p2018 swapnil@192.168.0.112 +``` + +它会向您询问用户密码,然后您就可以登录到 Linux 服务器了。现在您可以在 Linux 服务器上执行任意您想执行的所有操作了。不需使用 PuTTY 程序了。 + +使用 `rsync` ,您可以很轻易的在本地机器和远程机器之间传输文件。源目录还是目标目录取决于您是上传文件到服务器,还是下载文件到本地目录,您可以使用 `username@IP-address-of-server:/path-of-directory` 来指定目录。 + +如果我想复制一些文本内容到服务器的 home 目录,命令如下: + +``` +rsync -avzP /source-directory-on-local-machine ‘ssh -p2018’ swapnil@192.168.0.112:/home/swapnil/Documents/ +``` + +这将会复制这些文件到远程服务器中 `Documents` 目录。 + +### 总结 + +本教程主要是为了证明您可以在 Windows 10 系统上通过 WSL 完成 Linux 方面的很大一部分的任务。通常来说,它提高了生产效率。现在,Linux 的世界已经向 Windwos 10 系统张开怀抱了,尽情探索吧。如果您有任何疑问,或是想了解 WSL 涉及到的其他层面,欢迎在下方的评论区分享您的想法。 + +在 [Administering Linux on Azure (LFS205)][4] 课程中了解更多,可以在 [这里][5] 注册。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/3/most-useful-linux-commands-you-can-run-windows-10 + +作者:[SAPNIL BHARTIYA][a] +译者:[CYLeft](https://github.com/CYLeft) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/arnieswap +[1]:https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-10 +[2]:http://www.adminschoice.com/crontab-quick-reference +[3]:mailto:username@IP +[4]:https://training.linuxfoundation.org/linux-courses/system-administration-training/administering-linux-on-azure +[5]:http://bit.ly/2FpFtPg diff --git a/published/201803/20180308 Test Your BASH Skills By Playing Command Line Games.md b/published/201803/20180308 Test Your BASH Skills By Playing Command Line Games.md new file mode 100644 index 0000000000..9ed72f5616 --- /dev/null +++ b/published/201803/20180308 Test Your BASH Skills By Playing Command Line Games.md @@ -0,0 +1,127 @@ +通过玩命令行游戏来测试你的 BASH 技能 +===== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/Test-your-bash-skills-1-720x340.png) + +如果我们经常在实际场景中使用 Linux 命令,我们就会更有效的学习和记忆它们。除非你经常使用 Linux 命令,否则你可能会在一段时间内忘记它们。无论你是新手还是老手,总会有一些趣味的方法来测试你的 BASH 技能。在本教程中,我将解释如何通过玩命令行游戏来测试你的 BASH 技能。其实从技术上讲,这些并不是像 Super TuxKart、极品飞车或 CS 等真正的游戏。这些只是 Linux 命令培训课程的游戏化版本。你将需要根据游戏本身的某些指示来完成一个任务。 + +现在,我们来看看几款能帮助你实时学习和练习 Linux 命令的游戏。这些游戏不是消磨时间或者令人惊诧的,这些游戏将帮助你获得终端命令的真实体验。请继续阅读: + +### 使用 “Wargames” 来测试 BASH 技能 + +这是一个在线游戏,所以你必须联网。这些游戏可以帮助你以充满乐趣的游戏形式学习和练习 Linux 命令。Wargames 是一个 shell 游戏的集合,每款游戏有很多关卡。只有通过解决先前的关卡才能访问下一个关卡。不要担心!每个游戏都提供了有关如何进入下一关的清晰简洁说明。 + +要玩 Wargames,请点击以下链接:[Wargames][1] 。 + +![][2] + +如你所见,左边列出了许多 shell 游戏。每个 shell 游戏都有自己的 SSH 端口。所以,你必须通过本地系统配置 SSH 连接到游戏,你可以在 Wargames 网站的左上角找到关于如何使用 SSH 连接到每个游戏的信息。 + +例如,让我们来玩 Bandit 游戏吧。为此,单击 Wargames 主页上的 Bandit 链接。在左上角,你会看到 Bandit 游戏的 SSH 信息。 + +![][3] + +正如你在上面的屏幕截图中看到的,有很多关卡。要进入每个关卡,请单机左侧列中的相应链接。此外,右侧还有适合初学者的说明。如果你对如何玩此游戏有任何疑问,请阅读它们。 + +现在,让我们点击它进入关卡 0。在下一个屏幕中,你将获得该关卡的 SSH 信息。 + +![][4] + +正如你在上面的屏幕截图中看到的,你需要配置 SSH 端口 2220 连接 `bandit.labs.overthewire.org`,用户名是 `bandit0`,密码是 `bandit0`。 + +让我们连接到 Bandit 游戏关卡 0。 + +``` +$ ssh bandit0@bandit.labs.overthewire.org -p 2220 +``` + +输入密码 `bandit0`。 + +示例输出将是: + +![][5] + +登录后,输入 `ls` 命令查看内容或者进入关卡 1 页面,了解如何通过关卡 1 等等。建议的命令列表已在每个关卡提供。所以,你可以选择和使用任何合适的命令来解决每个关卡。 + +我必须承认,Wargames 是令人上瘾的,并且解决每个关卡是非常有趣的。 尽管有些关卡确实很具挑战性,你可能需要谷歌才能知道如何解决问题。 试一试,你会很喜欢它。 + +### 使用 “Terminus” 来测试 BASH 技能 + +这是另一个基于浏览器的在线 CLI 游戏,可用于改进或测试你的 Linux 命令技能。要玩这个游戏,请打开你的 web 浏览器并导航到以下 URL:[Play Terminus Game][9] + +一旦你进入游戏,你会看到有关如何玩游戏的说明。与 Wargames 不同,你不需要连接到它们的游戏服务器来玩游戏。Terminus 有一个内置的 CLI,你可以在其中找到有关如何使用它的说明。 + +你可以使用命令 `ls` 查看周围的环境,使用命令 `cd 位置` 移动到新的位置,返回使用命令 `cd ..`,与这个世界进行交互使用命令 `less 项目` 等等。要知道你当前的位置,只需输入 `pwd`。 + +![][6] + +### 使用 “clmystery” 来测试 BASH 技能 + +与上述游戏不同,你可以在本地玩这款游戏。你不需要连接任何远程系统,这是完全离线的游戏。 + +相信我,这家伙是一个有趣的游戏。按照给定的说明,你将扮演一个侦探角色来解决一个神秘案件。 + +首先,克隆仓库: + +``` +$ git clone https://github.com/veltman/clmystery.git +``` + +或者,从 [这里][7] 将其作为 zip 文件下载。解压缩并切换到下载文件的地方。最后,通过阅读 `instructions` 文件来开启宝箱。 + +``` +[sk@sk]: clmystery-master>$ ls +cheatsheet.md cheatsheet.pdf encoded hint1 hint2 hint3 hint4 hint5 hint6 hint7 hint8 instructions LICENSE.md mystery README.md solution +``` + +这里是玩这个游戏的说明: + +终端城发生了一起谋杀案,TCPD 需要你的帮助。你需要帮助它们弄清楚是谁犯罪了。 + +为了查明是谁干的,你需要到 `mystery` 子目录并从那里开始工作。你可能需要查看犯罪现场的所有线索( `crimescene` 文件)。现场的警官相当谨慎,所以他们在警官报告中写下了一切。幸运的是,警官以全部大写的 “CLUE” 一词把真正的线索标记了出来。 + +如果里遇到任何问题,请打开其中一个提示文件,例如 “hint1”,“hint2” 等。你可以使用下面的 `cat` 命令打开提示文件。 + +``` +$ cat hint1 +$ cat hint2 +``` + +要检查你的答案或找出解决方案,请在 `clmystery` 目录中打开文件 `solution`。 + +``` +$ cat solution +``` + +要了解如何使用命令行,请参阅 `cheatsheet.md` 或 `cheatsheet.pdf` (在命令行中,你可以输入 ‘nano cheatsheet.md’)。请勿使用文本编辑器查看除 `instructions`、`cheatsheet` 和 `hint` 以外的任何文件。 + +有关更多详细信息,请参阅 [clmystery GitHub][8] 页面。 + +推荐阅读: + +而这就是我现在所知道的。如果将来遇到任何问题,我会继续添加更多游戏。将此链接加入书签并不时访问。如果你知道其他类似的游戏,请在下面的评论部分告诉我,我将测试和更新本指南。 + +还有更多好东西,敬请关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/test-your-bash-skills-by-playing-command-line-games/ + +作者:[SK][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:http://overthewire.org/wargames/ +[2]:http://www.ostechnix.com/wp-content/uploads/2018/03/Wargames-1.png +[3]:http://www.ostechnix.com/wp-content/uploads/2018/03/Bandit-game.png +[4]:http://www.ostechnix.com/wp-content/uploads/2018/03/Bandit-level-0.png +[5]:http://www.ostechnix.com/wp-content/uploads/2018/03/Bandit-level-0-ssh-1.png +[6]:http://www.ostechnix.com/wp-content/uploads/2018/03/Terminus.png +[7]:https://github.com/veltman/clmystery/archive/master.zip +[8]:https://github.com/veltman/clmystery +[9]:http://web.mit.edu/mprat/Public/web/Terminus/Web/main.html diff --git a/translated/tech/20180309 How to check your network connections on Linux.md b/published/201803/20180309 How to check your network connections on Linux.md similarity index 50% rename from translated/tech/20180309 How to check your network connections on Linux.md rename to published/201803/20180309 How to check your network connections on Linux.md index 1e6923b56f..d8225dd4dc 100644 --- a/translated/tech/20180309 How to check your network connections on Linux.md +++ b/published/201803/20180309 How to check your network connections on Linux.md @@ -1,11 +1,11 @@ -如何在Linux上检查您的网络连接 +解读 ip 命令展示的网络连接信息 ====== ![](https://images.idgesg.net/images/article/2018/03/network-connections-100751906-large.jpg) -**ip**命令有很多可以告诉你网络连接配置和状态的信息,但是所有这些词和数字意味着什么? 让我们深入了解一下,看看所有显示的值都试图告诉你什么。 +`ip` 命令可以告诉你很多网络连接配置和状态的信息,但是所有这些词和数字意味着什么? 让我们深入了解一下,看看所有显示的值都试图告诉你什么。 -当您使用`ip a`(或`ip addr`)命令获取系统上所有网络接口的信息时,您将看到如下所示的内容: +当您使用 `ip a`(或 `ip addr`)命令获取系统上所有网络接口的信息时,您将看到如下所示的内容: ``` $ ip a @@ -23,46 +23,46 @@ $ ip a valid_lft forever preferred_lft forever ``` -这个系统上的两个接口 - 环回(lo)和网络(enp0s25)——显示了很多统计数据。 “lo”接口显然是环回地址。 我们可以在列表中看到环回IPv4地址(127.0.0.1)和环回IPv6( **::1**)。 正常的网络接口更有趣。 +这个系统上的两个接口 - 环回(`lo`)和网络(`enp0s25`)——显示了很多统计数据。 `lo` 接口显然是环回地址loolback。 我们可以在列表中看到环回 IPv4 地址(`127.0.0.1`)和环回 IPv6(`::1`)。 而普通的网络接口更有趣。 -### 为什么是enp0s25而不是eth0 +### 为什么是 enp0s25 而不是 eth0 -如果你想知道为什么它在这个系统上被称为**enp0s25**,而不是可能更熟悉的**eth0**,那我们可以稍微解释一下。 +如果你想知道为什么它在这个系统上被称为 `enp0s25`,而不是可能更熟悉的 `eth0`,那我们可以稍微解释一下。 -新的命名方案被称为“可预测的网络接口”。 它已经在基于systemd的Linux系统上使用了一段时间了。 接口名称取决于硬件的物理位置。 “**en**”仅仅就是“ethernet”的意思就像“eth”用于对于eth0,一样。 “**p**”是以太网卡的总线编号,“**s**”是插槽编号。 所以“enp0s25”告诉我们很多我们正在使用的硬件的信息。 +新的命名方案被称为“可预测的网络接口Predictable Network Interface”。 它已经在基于systemd 的 Linux 系统上使用了一段时间了。 接口名称取决于硬件的物理位置。 `en` 仅仅就是 “ethernet” 的意思,就像 “eth” 用于对应 `eth0`,一样。 `p` 是以太网卡的总线编号,`s` 是插槽编号。 所以 `enp0s25` 告诉我们很多我们正在使用的硬件的信息。 + +`` 这个配置串告诉我们: - 这个配置串告诉我们: ``` BROADCAST 该接口支持广播 MULTICAST 该接口支持多播 UP 网络接口已启用 LOWER_UP 网络电缆已插入,设备已连接至网络 -mtu 1500 最大传输单位(数据包大小)为1,500字节 ``` -列出的其他值也告诉了我们很多关于接口的知识,但我们需要知道“brd”和“qlen”这些词代表什么意思。 所以,这里显示的是上面展示的**ip**信息的其余部分的翻译。 +列出的其他值也告诉了我们很多关于接口的知识,但我们需要知道 `brd` 和 `qlen` 这些词代表什么意思。 所以,这里显示的是上面展示的 `ip` 信息的其余部分的翻译。 ``` -mtu 最大传输单位(数据包大小)为1,500字节 +mtu 1500 最大传输单位(数据包大小)为1,500字节 qdisc pfifo_fast 用于数据包排队 state UP 网络接口已启用 group default 接口组 qlen 1000 传输队列长度 -link/ether 00:1e:4f:c8:43:fc 接口的MAC(硬件)地址 +link/ether 00:1e:4f:c8:43:fc 接口的 MAC(硬件)地址 brd ff:ff:ff:ff:ff:ff 广播地址 -inet 192.168.0.24/24 IPv4地址 +inet 192.168.0.24/24 IPv4 地址 brd 192.168.0.255 广播地址 scope global 全局有效 dynamic enp0s25 地址是动态分配的 -valid_lft 80866sec IPv4地址的有效使用期限 -preferred_lft 80866sec IPv4地址的首选生存期 -inet6 fe80::2c8e:1de0:a862:14fd/64 IPv6地址 +valid_lft 80866sec IPv4 地址的有效使用期限 +preferred_lft 80866sec IPv4 地址的首选生存期 +inet6 fe80::2c8e:1de0:a862:14fd/64 IPv6 地址 scope link 仅在此设备上有效 -valid_lft forever IPv6地址的有效使用期限 -preferred_lft forever IPv6地址的首选生存期 +valid_lft forever IPv6 地址的有效使用期限 +preferred_lft forever IPv6 地址的首选生存期 ``` -您可能已经注意到,ifconfig命令提供的一些信息未包含在**ip a** 命令的输出中 —— 例如传输数据包的统计信息。 如果您想查看发送和接收的数据包数量以及冲突数量的列表,可以使用以下ip命令: +您可能已经注意到,`ifconfig` 命令提供的一些信息未包含在 `ip a` 命令的输出中 —— 例如传输数据包的统计信息。 如果您想查看发送和接收的数据包数量以及冲突数量的列表,可以使用以下 `ip` 命令: ``` $ ip -s link show enp0s25 @@ -74,7 +74,8 @@ $ ip -s link show enp0s25 6131373 78152 0 0 0 0 ``` -另一个**ip**命令提供有关系统路由表的信息。 +另一个 `ip` 命令提供有关系统路由表的信息。 + ``` $ ip route show default via 192.168.0.1 dev enp0s25 proto static metric 100 @@ -82,7 +83,7 @@ default via 192.168.0.1 dev enp0s25 proto static metric 100 192.168.0.0/24 dev enp0s25 proto kernel scope link src 192.168.0.24 metric 100 ``` -**ip**命令是非常通用的。 您可以从**ip**命令及其来自[Red Hat][1]的选项获得有用的备忘单。 +`ip` 命令是非常通用的。 您可以从 `ip` 命令及其来自[Red Hat][1]的选项获得有用的备忘单。 -------------------------------------------------------------------------------- @@ -90,7 +91,7 @@ via: https://www.networkworld.com/article/3262045/linux/checking-your-network-co 作者:[Sandra Henry-Stocker][a] 译者:[Flowsnow](https://github.com/Flowsnow) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201803/20180322 chkservice - A Tool For Managing Systemd Units From Linux Terminal.md b/published/201803/20180322 chkservice - A Tool For Managing Systemd Units From Linux Terminal.md new file mode 100644 index 0000000000..902d8a4e12 --- /dev/null +++ b/published/201803/20180322 chkservice - A Tool For Managing Systemd Units From Linux Terminal.md @@ -0,0 +1,113 @@ +chkservice:在 Linux 终端管理 systemd 单元的工具 +================ + +systemd 意即系统守护进程system daemon,是一个新的初始化系统和系统管理工具,它现在非常流行,大部分的 Linux 发行版开始使用这种新的初始化系统。 + +`systemctl` 是一个 systemd 的工具,它可以帮助我们管理 systemd 守护进程。 它控制系统的启动程序和服务,使用并行化方式,为启动的服务激活套接字和 D-Bus,提供守护进程的按需启动,使用 Linux 控制组跟踪进程,维护挂载和自动挂载点。 + +此外,它还提供了日志守护进程、用于控制基本系统配置的功能,如主机名、日期、地区、维护已登录用户列表和运行容器和虚拟机、系统帐户、运行时目录和设置,以及管理简单网络配置、网络时间同步、日志转发和名称解析的守护进程。 + +### 什么是 chkservice + +[chkservice][1] 是一个基于 ncurses 的在终端中管理 systemd 单元的工具。它提供了一个非常全面的 systemd 服务的视图,使得它们非常容易修改。 + +只有拥有超级管理权限才能够改变 systemd 单元的状态和 sysv 系统启动脚本。 + +### 在 Linux 安装 chkservice + +我们可以通过两种方式安装 `chkservice`,通过包安装或者手动安装。 + +对于 Debian/Ubuntu,使用 [APT-GET 命令][2] 或 [APT 命令][3] 安装 `chkservice`。 + +``` +$ sudo add-apt-repository ppa:linuxenko/chkservice +$ sudo apt-get update +$ sudo apt-get install chkservice +``` + +对于 Arch Linux 系的系统,使用 [Yaourt 命令][4] 或 [Packer 命令][5] 从 AUR 库安装 `chkservice`。 + +``` +$ yaourt -S chkservice +或 +$ packer -S chkservice +``` + +对于 Fedora,使用 [DNF 命令][6] 安装 `chkservice`。 + +``` +$ sudo dnf copr enable srakitnican/default +$ sudo dnf install chkservice +``` + +对于 Debian 系系统,使用 [DPKG 命令][7] 安装 `chkservice`。 + +``` +$ wget https://github.com/linuxenko/chkservice/releases/download/0.1/chkservice_0.1.0-amd64.deb +$ sudo dpkg -i chkservice_0.1.0-amd64.deb +``` + +对于 RPM 系的系统,使用 [DNF 命令][8] 安装 `chkservice`。 + +``` +$ sudo yum install https://github.com/linuxenko/chkservice/releases/download/0.1/chkservice_0.1.0-amd64.rpm +``` + +### 如何使用 chkservice + +只需输入以下命令即可启动 `chkservice` 工具。 输出分为四部分。 + + * **第一部分:** 这一部分显示了守护进程的状态,比如可用的 `[X]` 或者不可用的 `[ ]` 或者静态的 `[s]` 或者被掩藏的 `-m-` + * **第二部分:** 这一部分显示守护进程的状态例如开始 `>` 或者停止 `=` + * **第三部分:** 这一部分显示单元的名称 + * **第四部分:** 这一部分简短地显示了守护进程的一些信息 + +``` +$ sudo chkservice +``` + +![][10] + +要查看帮助页面,按下 `?`。 这将向您显示管理 systemd 服务的可用选项。 + +![][11] + +选择要启用或禁用的守护进程,然后点击空格键。 + +![][12] + +选择你想开始或停止的守护进程,然后按下 `s`。 + +![][13] + +选择要重新启动的守护进程,然后按下 `r`,之后,您可以在顶部看到更新的提示。 + +![][14] + +按下 `q` 退出。 + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/chkservice-a-tool-for-managing-systemd-units-from-linux-terminal/ + +作者:[Ramya Nuvvula][a] +译者:[amwps290](https://github.com/amwps290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/ramya/ +[1]:https://github.com/linuxenko/chkservice +[2]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/ +[3]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/ +[4]:https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/ +[5]:https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/ +[6]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/ +[7]:https://www.2daygeek.com/dpkg-command-to-manage-packages-on-debian-ubuntu-linux-mint-systems/ +[8]:https://www.2daygeek.com/rpm-command-examples/ +[9]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[10]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-1.png +[11]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-2.png +[12]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-3.png +[13]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-4.png +[14]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-5.png diff --git a/translated/tech/20180307 Host your own email with projectx-os and a Raspberry Pi.md b/published/20180307 Host your own email with projectx-os and a Raspberry Pi.md similarity index 66% rename from translated/tech/20180307 Host your own email with projectx-os and a Raspberry Pi.md rename to published/20180307 Host your own email with projectx-os and a Raspberry Pi.md index ef93bc51c7..5d9c3a4ba6 100644 --- a/translated/tech/20180307 Host your own email with projectx-os and a Raspberry Pi.md +++ b/published/20180307 Host your own email with projectx-os and a Raspberry Pi.md @@ -1,24 +1,24 @@ -使用一个树莓派和 projectx/os 托管你自己的电子邮件 +使用树莓派和 projectx/os 托管你自己的电子邮件 ====== +> 这个开源项目可以通过低成本的服务器设施帮助你保护你的数据隐私和所有权。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/document_free_access_cut_security.png?itok=ocvCv8G2) -现在有大量的理由,不能再将存储你的数据的任务委以他人之手,也不能在第三方公司运行你的服务;隐私、所有权、以及防范任何人拿你的数据去“赚钱”。但是对于大多数人来说,自己去运行一个服务器,是件即费时间又需要太多的专业知识的事情。不得已,我们只能妥协。抛开这些顾虑,使用某些公司的云服务,随之而来的就是广告、数据挖掘和售卖、以及其它可能的任何东西。 +现在有大量的理由,不能再将存储你的数据的任务委以他人之手,也不能在第三方公司运行你的服务;隐私、所有权,以及防范任何人拿你的数据去“赚钱”。但是对于大多数人来说,自己去运行一个服务器,是件即费时间又需要太多的专业知识的事情。不得已,我们只能妥协。抛开这些顾虑,使用某些公司的云服务,随之而来的就是广告、数据挖掘和售卖、以及其它可能的任何东西。 [projectx/os][1] 项目就是要去除这种顾虑,它可以在家里毫不费力地做服务托管,并且可以很容易地创建一个类似于 Gmail 的帐户。实现上述目标,你只需一个 $35 的树莓派 3 和一个基于 Debian 的操作系统镜像 —— 并且不需要很多的专业知识。仅需要四步就可以实现: 1. 解压缩一个 ZIP 文件到 SD 存储卡中。 - 2. 编辑 SD 上的一个文本文件以便于它连接你的 WiFi(如果你不使用有线网络的话)。 + 2. 编辑 SD 卡上的一个文本文件以便于它连接你的 WiFi(如果你不使用有线网络的话)。 3. 将这个 SD 卡插到树莓派 3 中。 - 4. 使用你的智能手机在树莓派 3 上安装 "email 服务器“ 应用并选择一个二级域。 + 4. 使用你的智能手机在树莓派 3 上安装 “email 服务器” 应用并选择一个二级域。 +服务器应用程序(比如电子邮件服务器)被分解到多个容器中,它们中的每个都只能够使用指定的方式与外界通讯,它们使用了管理粒度非常细的隔离措施以提高安全性。例如,入站 SMTP、[SpamAssassin][2](反垃圾邮件平台)、[Dovecot][3] (安全的 IMAP 服务器),以及 webmail 都使用了独立的容器,它们之间相互不能看到对方的数据,因此,单个守护进程出现问题不会波及其它的进程。 +另外,它们都是无状态容器,比如 SpamAssassin 和入站 SMTP,每次收到电子邮件之后,它们的容器都会被销毁并重建,因此,即便是有人找到了 bug 并利用了它,他们也不能访问以前的电子邮件或者接下来的电子邮件;他们只能访问他们自己挖掘出漏洞的那封电子邮件。幸运的是,大多数对外发布的、最容易受到攻击的服务都是隔离的和无状态的。 -服务器应用程序(比如电子邮件服务器)被分解到多个容器中,它们中的每个都只能够使用指定的方式与外界通讯,它们使用了管理粒度非常细的隔离措施以提高安全性。例如,入站 SMTP,[SpamAssassin][2](防垃圾邮件平台),[Dovecot][3] (安全 IMAP 服务器),并且 webmail 都使用了独立的容器,它们之间相互不能看到对方的数据,因此,单个守护进程出现问题不会波及其它的进程。 - -另外,它们都是无状态容器,比如 SpamAssassin 和入站 SMTP,每次收到电子邮件之后,它们的连接都会被拆除并重建,因此,即便是有人找到了 bug 并利用了它,他们也不能访问以前的电子邮件或者接下来的电子邮件;他们只能访问他们自己挖掘出漏洞的那封电子邮件。幸运的是,大多数对外发布的、最容易受到攻击的服务都是隔离的和无状态的。 - -所有存储的数据都使用 [dm-crypt][4] 进行加密。非公开服务,比如 Dovecot(IMAP)或者 webmail,都是在内部监听,并使用 [ZeroTier One][5] 加密整个网络,因此只有你的设备(智能手机、笔记本电脑、平板等等)才能访问它们。 +所有存储的数据都使用 [dm-crypt][4] 进行加密。非公开的服务,比如 Dovecot(IMAP)或者 webmail,都是在内部监听,并使用 [ZeroTier One][5] 所提供的私有的加密层叠网络,因此只有你的设备(智能手机、笔记本电脑、平板等等)才能访问它们。 虽然电子邮件并不是端到端加密的(除非你使用了 [PGP][6]),但是非加密的电子邮件绝不会跨越网络,并且也不会存储在磁盘上。现在明文的电子邮件只存在于双方的私有邮件服务器上,它们都在他们的家中受到很好的安全保护并且只能通过他们的客户端访问(智能手机、笔记本电脑、平板等等)。 @@ -26,9 +26,7 @@ ### 展望 -电子邮件是我使用 project/os 项目打包的第一个应用程序。想像一下,一个应用程序商店有全部的服务器软件,为易于安装和使用将它们打包到一起。想要一个博客?添加一个 WordPress 应用程序!想替换安全的 Dropbox ?添加一个 [Seafile][8] 应用程序或者一个 [Syncthing][9] 后端应用程序。 [IPFS][10] 节点? [Mastodon][11] 实例?GitLab 服务器?各种家庭自动化/物联网后端服务?这里有大量的非常好的开源服务器软件 ,它们都非常易于安装,并且可以使用它们来替换那些有专利的云服务。 - -Nolan Leake 的 [在每个家庭中都有一个云:0 系统管理员技能就可以在家里托管服务器][12] 将在三月 8 - 11日的 [Southern California Linux Expo][12] 进行。使用折扣代码 **OSDC** 去注册可以 50% 的价格得到门票。 +电子邮件是我使用 project/os 项目打包的第一个应用程序。想像一下,一个应用程序商店有全部的服务器软件,打包起来易于安装和使用。想要一个博客?添加一个 WordPress 应用程序!想替换安全的 Dropbox ?添加一个 [Seafile][8] 应用程序或者一个 [Syncthing][9] 后端应用程序。 [IPFS][10] 节点? [Mastodon][11] 实例?GitLab 服务器?各种家庭自动化/物联网后端服务?这里有大量的非常好的开源服务器软件 ,它们都非常易于安装,并且可以使用它们来替换那些有专利的云服务。 -------------------------------------------------------------------------------- @@ -36,7 +34,7 @@ via: https://opensource.com/article/18/3/host-your-own-email 作者:[Nolan Leake][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180308 How to set up a print server on a Raspberry Pi.md b/published/20180308 How to set up a print server on a Raspberry Pi.md similarity index 66% rename from translated/tech/20180308 How to set up a print server on a Raspberry Pi.md rename to published/20180308 How to set up a print server on a Raspberry Pi.md index 0b53281d7f..65b9fd5a5a 100644 --- a/translated/tech/20180308 How to set up a print server on a Raspberry Pi.md +++ b/published/20180308 How to set up a print server on a Raspberry Pi.md @@ -1,60 +1,58 @@ 如何将树莓派配置为打印服务器 ====== +> 用树莓派和 CUPS 打印服务器将你的打印机变成网络打印机。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life-raspberrypi_0.png?itok=Kczz87J2) -我喜欢在家做一些小项目,因此,今年我选择使用一个 [树莓派 3 Model B][1],这是一个像我这样的业余爱好者非常适合的东西。使用树莓派 3 Model B 的无线功能,我可以不使用线缆将树莓派连接到我的家庭网络中。这样可以很容易地将树莓派用到各种它所需要的地方。 +我喜欢在家做一些小项目,因此,今年我买了一个 [树莓派 3 Model B][1],这是一个非常适合像我这样的业余爱好者的东西。使用树莓派 3 Model B 的内置无线功能,我可以不使用线缆就将树莓派连接到我的家庭网络中。这样可以很容易地将树莓派用到各种所需要的地方。 -在家里,我和我的妻子都使用笔记本电脑,但是我们只有一台打印机:一台使用的并不频繁的 HP 彩色激光打印机。因为我们的打印机并不内置无线网卡,因此,它不能直接连接到无线网络中,一般情况下,使用我的笔记本电脑时,我并不连接打印机,因为,我做的大多数工作并不需要打印。虽然这种安排在大多数时间都没有问题,但是,有时候,我的妻子想在不 “麻烦” 我的情况下,自己去打印一些东西。 - -### 基本设置 +在家里,我和我的妻子都使用笔记本电脑,但是我们只有一台打印机:一台使用的并不频繁的 HP 彩色激光打印机。因为我们的打印机并不内置无线网卡,因此,它不能直接连接到无线网络中,我们一般把打印机连接到我的笔记本电脑上,因为通常是我在打印。虽然这种安排在大多数时间都没有问题,但是,有时候,我的妻子想在不 “麻烦” 我的情况下,自己去打印一些东西。 我觉得我们需要一个将打印机连接到无线网络的解决方案,以便于我们都能够随时随地打印。我本想买一个无线打印服务器将我的 USB 打印机连接到家里的无线网络上。后来,我决定使用我的树莓派,将它设置为打印服务器,这样就可以让家里的每个人都可以随时来打印。 -设置树莓派是非常简单的事。我下载了 [Raspbian][2] 镜像,并将它写入到我的 microSD 卡中。然后,使用它引导连接了一个 HDMI 显示器、一个 USB 键盘和一个 USB 鼠标的树莓派。之后,我们开始对它进行设置! +### 基本设置 + +设置树莓派是非常简单的事。我下载了 [Raspbian][2] 镜像,并将它写入到我的 microSD 卡中。然后,使用它来引导一个连接了 HDMI 显示器、 USB 键盘和 USB 鼠标的树莓派。之后,我们开始对它进行设置! 这个树莓派系统自动引导到一个图形桌面,然后我做了一些基本设置:设置键盘语言、连接无线网络、设置普通用户帐户(`pi`)的密码、设置管理员用户(`root`)的密码。 -我并不打算将树莓派运行在桌面环境下。我一般是通过我的普通的 Linux 计算机远程来使用它。因此,我使用树莓派的图形化管理工具,去设置将树莓派引导到控制台模式,而且不以 `pi` 用户自动登入。 +我并不打算将树莓派运行在桌面环境下。我一般是通过我的普通的 Linux 计算机远程来使用它。因此,我使用树莓派的图形化管理工具,去设置将树莓派引导到控制台模式,但不以 `pi` 用户自动登入。 重新启动树莓派之后,我需要做一些其它的系统方面的小调整,以便于我在家用网络中使用树莓派做为 “服务器”。我设置它的 DHCP 客户端为使用静态 IP 地址;默认情况下,DHCP 客户端可能任选一个可用的网络地址,这样我会不知道应该用哪个地址连接到树莓派。我的家用网络使用一个私有的 A 类地址,因此,我的路由器的 IP 地址是 `10.0.0.1`,并且我的全部可用地 IP 地址是 `10.0.0.x`。在我的案例中,低位的 IP 地址是安全的,因此,我通过在 `/etc/dhcpcd.conf` 中添加如下的行,设置它的无线网络使用 `10.0.0.11` 这个静态地址。 + ``` interface wlan0 - static ip_address=10.0.0.11/24 - static routers=10.0.0.1 - static domain_name_servers=8.8.8.8 8.8.4.4 - ``` 在我再次重启之前,我需要去确认安全 shell 守护程序(SSHD)已经正常运行(你可以在 “偏好” 中设置哪些服务在引导时启动它)。这样我就可以使用 SSH 从普通的 Linux 系统上基于网络连接到树莓派中。 ### 打印设置 -现在,我的树莓派已经在网络上正常工作了,我通过 SSH 从我的 Linux 电脑上远程连接它,接着做剩余的设置。在继续设置之前,确保你的打印机已经连接到树莓派上。 +现在,我的树莓派已经连到网络上了,我通过 SSH 从我的 Linux 电脑上远程连接它,接着做剩余的设置。在继续设置之前,确保你的打印机已经连接到树莓派上。 + +设置打印机很容易。现代的打印服务器被称为 CUPS,意即“通用 Unix 打印系统”。任何最新的 Unix 系统都可以通过 CUPS 打印服务器来打印。为了在树莓派上设置 CUPS 打印服务器。你需要通过几个命令去安装 CUPS 软件,并使用新的配置来重启打印服务器,这样就可以允许其它系统来打印了。 -设置打印机很容易。现在的打印服务器都称为 CUPS,它是标准的通用 Unix 打印系统。任何最新的 Unix 系统都可以通过 CUPS 打印服务器来打印。为了在树莓派上设置 CUPS 打印服务器。你需要通过几个命令去安装 CUPS 软件,并使用新的配置来重启打印服务器,这样就可以允许其它系统来打印了。 ``` $ sudo apt-get install cups - $ sudo cupsctl --remote-any - $ sudo /etc/init.d/cups restart - ``` -在 CUPS 中设置打印机也是非常简单的,你可以通过一个 Web 界面来完成。CUPS 监听端口是 631,因此你可以在浏览器中收藏这个地址: +在 CUPS 中设置打印机也是非常简单的,你可以通过一个 Web 界面来完成。CUPS 监听端口是 631,因此你用常用的浏览器来访问这个地址: + ``` https://10.0.0.11:631/ - ``` -你的 Web 浏览器可能会弹出警告,因为它不认可这个 Web 浏览器的 https 证书;选择 ”接受它“,然后以管理员用户登入系统,你将看到如下的标准的 CUPS 面板: +你的 Web 浏览器可能会弹出警告,因为它不认可这个 Web 浏览器的 https 证书;选择 “接受它”,然后以管理员用户登入系统,你将看到如下的标准的 CUPS 面板: + ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/cups-1-home.png?itok=t9OFJgSX) -这时候,导航到管理标签,选择 “Add Printer"。 +这时候,导航到管理标签,选择 “Add Printer”。 ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/cups-2-administration.png?itok=MlEINoYC) @@ -64,9 +62,9 @@ https://10.0.0.11:631/ ### 客户端设置 -从 Linux 中设置一台网络打印机非常简单。我的桌面环境是 GNOME,你可以从 GNOME 的设置应用程序中添加网络打印机。只需要导航到设备和打印机,然后解锁这个面板。点击 “Add" 按钮去添加打印机。 +从 Linux 中设置一台网络打印机非常简单。我的桌面环境是 GNOME,你可以从 GNOME 的“设置”应用程序中添加网络打印机。只需要导航到“设备和打印机”,然后解锁这个面板。点击 “添加” 按钮去添加打印机。 -在我的系统中,GNOME 设置为 ”自动发现网络打印机并添加它“。如果你的系统不是这样,你需要通过树莓派的 IP 地址,手动去添加打印机。 +在我的系统中,GNOME 的“设置”应用程序会自动发现网络打印机并添加它。如果你的系统不是这样,你需要通过树莓派的 IP 地址,手动去添加打印机。 ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/gnome-settings-printers.png?itok=NOQLTaLs) @@ -78,7 +76,7 @@ via: https://opensource.com/article/18/3/print-server-raspberry-pi 作者:[Jim Hall][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180312 How To Quickly Monitor Multiple Hosts In Linux.md b/published/20180312 How To Quickly Monitor Multiple Hosts In Linux.md new file mode 100644 index 0000000000..860f70553a --- /dev/null +++ b/published/20180312 How To Quickly Monitor Multiple Hosts In Linux.md @@ -0,0 +1,107 @@ +如何在 Linux 中快速监控多个主机 +===== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/rwho-1-720x340.png) + +有很多监控工具可用来监控本地和远程 Linux 系统,一个很好的例子是 [Cockpit][1]。但是,这些工具的安装和使用比较复杂,至少对于新手管理员来说是这样。新手管理员可能需要花一些时间来弄清楚如何配置这些工具来监视系统。如果你想要以快速且粗略地在局域网中一次监控多台主机,你可能需要了解一下 “rwho” 工具。只要安装了 rwho 实用程序,它将立即快速地监控本地和远程系统。你什么都不用配置!你所要做的就是在要监视的系统上安装 “rwho” 工具。 + +请不要将 rwho 视为功能丰富且完整的监控工具。这只是一个简单的工具,它只监视远程系统的“正常运行时间”(`uptime`),“负载”(`load`)和**登录的用户**。使用 “rwho” 使用程序,我们可以发现谁在哪台计算机上登录;一个被监视的计算机的列表,列出了正常运行时间(自上次重新启动以来的时间);有多少用户登录了;以及在过去的 1、5、15 分钟的平均负载。不多不少!而且,它只监视同一子网中的系统。因此,它非常适合小型和家庭办公网络。 + +### 在 Linux 中监控多台主机 + +让我来解释一下 `rwho` 是如何工作的。每个在网络上使用 `rwho` 的系统都将广播关于它自己的信息,其他计算机可以使用 `rwhod` 守护进程来访问这些信息。因此,网络上的每台计算机都必须安装 `rwho`。此外,为了分发或访问其他主机的信息,必须允许 `rwho` 端口(例如端口 `513/UDP`)通过防火墙/路由器。 + +好的,让我们来安装它。 + +我在 Ubuntu 16.04 LTS 服务器上进行了测试,`rwho` 在默认仓库中可用,所以,我们可以使用像下面这样的 APT 软件包管理器来安装它。 + +``` +$ sudo apt-get install rwho +``` + +在基于 RPM 的系统如 CentOS、 Fedora、 RHEL 上,使用以下命令来安装它: + +``` +$ sudo yum install rwho +``` + +如果你在防火墙/路由器之后,确保你已经允许使用 rwhod 513 端口。另外,使用命令验证 `rwhod` 守护进程是否正在运行: + +$ sudo systemctl status rwhod + +如果它尚未启动,运行以下命令启用并启动 `rwhod` 服务: + +``` +$ sudo systemctl enable rwhod +$ sudo systemctl start rwhod +``` + +现在是时候来监视系统了。运行以下命令以发现谁在哪台计算机上登录: + +``` +$ rwho +ostechni ostechnix:pts/5 Mar 12 17:41 +root server:pts/0 Mar 12 17:42 +``` + +正如你所看到的,目前我的局域网中有两个系统。本地系统用户是 `ostechnix` (Ubuntu 16.04 LTS),远程系统的用户是 `root` (CentOS 7)。可能你已经猜到了,`rwho` 与 `who` 命令相似,但它会监视远程系统。 + +而且,我们可以使用以下命令找到网络上所有正在运行的系统的正常运行时间: + +``` +$ ruptime +ostechnix up 2:17, 1 user, load 0.09, 0.03, 0.01 +server up 1:54, 1 user, load 0.00, 0.01, 0.05 +``` + +这里,`ruptime`(类似于 `uptime` 命令)显示了我的 Ubuntu(本地) 和 CentOS(远程)系统的总运行时间。明白了吗?棒极了!以下是我的 Ubuntu 16.04 LTS 系统的示例屏幕截图: + +![][3] + +你可以在以下位置找到有关局域网中所有其他机器的信息: + +``` +$ ls /var/spool/rwho/ +whod.ostechnix whod.server +``` + +它很小,但却非常有用,可以发现谁在哪台计算机上登录,以及正常运行时间和系统负载详情。 + +**建议阅读:** + +请注意,这种方法有一个严重的漏洞。由于有关每台计算机的信息都通过网络进行广播,因此该子网中的每个人都可能获得此信息。通常情况下可以,但另一方面,当有关网络的信息分发给非授权用户时,这可能是不必要的副作用。因此,强烈建议在受信任和受保护的局域网中使用它。 + +更多的信息,查找 man 手册页。 + +``` +$ man rwho +``` + +好了,这就是全部了。更多好东西要来了,敬请期待! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/ + +作者:[SK][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/cockpit-monitor-administer-linux-servers-via-web-browser/ +[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[3]:http://www.ostechnix.com/wp-content/uploads/2018/03/rwho.png +[4]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=reddit (Click to share on Reddit) +[5]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=twitter (Click to share on Twitter) +[6]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=facebook (Click to share on Facebook) +[7]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=google-plus-1 (Click to share on Google+) +[8]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=linkedin (Click to share on LinkedIn) +[9]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=pocket (Click to share on Pocket) +[10]:https://api.whatsapp.com/send?text=How%20To%20Quickly%20Monitor%20Multiple%20Hosts%20In%20Linux%20https%3A%2F%2Fwww.ostechnix.com%2Fhow-to-quickly-monitor-multiple-hosts-in-linux%2F (Click to share on WhatsApp) +[11]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=telegram (Click to share on Telegram) +[12]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/?share=email (Click to email this to a friend) +[13]:https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/#print (Click to print) diff --git a/published/20180314 How to measure particulate matter with a Raspberry Pi.md b/published/20180314 How to measure particulate matter with a Raspberry Pi.md new file mode 100644 index 0000000000..47046dcd26 --- /dev/null +++ b/published/20180314 How to measure particulate matter with a Raspberry Pi.md @@ -0,0 +1,171 @@ +如何使用树莓派测定颗粒物(PM 2.5) +====== + +> 使用两个简单的硬件设备和几行代码构建一个空气质量探测器。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bubblehands_fromRHT_520_0612LL.png?itok=_iQ2dO3S) + +我们在东南亚的学校定期测定空气中的颗粒物。这里的测定值非常高,尤其是在二到五月之间,干燥炎热、土地干旱等各种因素都对空气质量产生了不利的影响。我将会在这篇文章中展示如何使用树莓派来测定颗粒物。 + +### 什么是颗粒物? + +颗粒物就是粉尘或者空气中的微小颗粒。其中 PM10 和 PM2.5 之间的差别就是 PM10 指的是粒径小于 10 微米的颗粒,而 PM2.5 指的是粒径小于 2.5 微米的颗粒。在粒径小于 2.5 微米的的情况下,由于它们能被吸入肺泡中并且对呼吸系统造成影响,因此颗粒越小,对人的健康危害越大。 + +世界卫生组织的建议[颗粒物浓度][1]是: + + * 年均 PM10 不高于 20 µg/m³ + * 年均 PM2.5 不高于 10 µg/m³ + * 不允许超标时,日均 PM10 不高于 50 µg/m³ + * 不允许超标时,日均 PM2.5 不高于 25 µg/m³ + +以上数值实际上是低于大多数国家的标准的,例如欧盟对于 PM10 所允许的年均值是不高于 40 µg/m³。 + +### 什么是空气质量指数Air Quality Index(AQI)? + +空气质量指数是按照颗粒物的测定值来评价空气质量的好坏,然而由于各国之间的计算方式有所不同,这个指数并没有统一的标准。维基百科上关于[空气质量指数][2]的词条对此给出了一个概述。我们学校则以[美国环境保护协会][3]Environment Protection Agency(EPA)建立的分类法来作为依据。 + +![空气质量指数][5] + +*空气质量指数* + +### 测定颗粒物需要哪些准备? + +测定颗粒物只需要以下两种器材: + + * 树莓派(款式不限,最好带有 WiFi) + * SDS011 颗粒物传感器 + +![颗粒物传感器][7] + +*颗粒物传感器* + +如果是只带有 Micro USB 的树莓派 Zero W,那还需要一根连接到标准 USB 端口的适配线,只需要 20 美元,而传感器则自带适配串行接口的 USB 适配器。 + +### 安装过程 + +对于树莓派,只需要下载对应的 Raspbian Lite 镜像并且[写入到 Micro SD 卡][8]上就可以了(网上很多教程都有介绍如何设置 WLAN 连接,我就不细说了)。 + +如果要使用 SSH,那还需要在启动分区建立一个名为 `ssh` 的空文件。树莓派的 IP 通过路由器或者 DHCP 服务器获取,随后就可以通过 SSH 登录到树莓派了(默认密码是 raspberry): + +``` +$ ssh pi@192.168.1.5 +``` + +首先我们需要在树莓派上安装一下这些包: + +``` +$ sudo apt install git-core python-serial python-enum lighttpd +``` + +在开始之前,我们可以用 `dmesg` 来获取 USB 适配器连接的串行接口: + +``` +$ dmesg +[ 5.559802] usbcore: registered new interface driver usbserial +[ 5.559930] usbcore: registered new interface driver usbserial_generic +[ 5.560049] usbserial: USB Serial support registered for generic +[ 5.569938] usbcore: registered new interface driver ch341 +[ 5.570079] usbserial: USB Serial support registered for ch341-uart +[ 5.570217] ch341 1–1.4:1.0: ch341-uart converter detected +[ 5.575686] usb 1–1.4: ch341-uart converter now attached to ttyUSB0 +``` + +在最后一行,可以看到接口 `ttyUSB0`。然后我们需要写一个 Python 脚本来读取传感器的数据并以 JSON 格式存储,在通过一个 HTML 页面就可以把数据展示出来了。 + +### 在树莓派上读取数据 + +首先创建一个传感器实例,每 5 分钟读取一次传感器的数据,持续 30 秒,这些数值后续都可以调整。在每两次测定的间隔,我们把传感器调到睡眠模式以延长它的使用寿命(厂商认为元件的寿命大约 8000 小时)。 + +我们可以使用以下命令来下载 Python 脚本: + +``` +$ wget -O /home/pi/aqi.py https://raw.githubusercontent.com/zefanja/aqi/master/python/aqi.py +``` + +另外还需要执行以下两条命令来保证脚本正常运行: + +``` +$ sudo chown pi:pi /var/www/html/ +$ echo '[]' > /var/www/html/aqi.json +``` + +下面就可以执行脚本了: + +``` +$ chmod +x aqi.p +$ ./aqi.py +PM2.5:55.3, PM10:47.5 +PM2.5:55.5, PM10:47.7 +PM2.5:55.7, PM10:47.8 +PM2.5:53.9, PM10:47.6 +PM2.5:53.6, PM10:47.4 +PM2.5:54.2, PM10:47.3 +… +``` + +### 自动化执行脚本 + +只需要使用诸如 crontab 的服务,我们就不需要每次都手动启动脚本了。按照以下命令打开 crontab 文件: + +``` +$ crontab -e +``` + +在文件末尾添加这一行: + +``` +@reboot cd /home/pi/ && ./aqi.py +``` + +现在我们的脚本就会在树莓派每次重启后自动执行了。 + +### 展示颗粒物测定值和空气质量指数的 HTML 页面 + +我们在前面已经安装了一个轻量级的 web 服务器 `lighttpd`,所以我们需要把 HTML、JavaScript、CSS 文件放置在 `/var/www/html` 目录中,这样就能通过电脑和智能手机访问到相关数据了。执行下面的三条命令,可以下载到对应的文件: + +``` +$ wget -O /var/www/html/index.html https://raw.githubusercontent.com/zefanja/aqi/master/html/index.html +$ wget -O /var/www/html/aqi.js https://raw.githubusercontent.com/zefanja/aqi/master/html/aqi.js +$ wget -O /var/www/html/style.css https://raw.githubusercontent.com/zefanja/aqi/master/html/style.css +``` + +在 JavaScript 文件中,实现了打开 JSON 文件、提取数据、计算空气质量指数的过程,随后页面的背景颜色将会根据 EPA 的划分标准而变化。 + +你只需要用浏览器访问树莓派的地址,就可以看到当前颗粒物浓度值等数据了: [http://192.168.1.5:][9] + +这个页面比较简单而且可扩展,比如可以添加一个展示过去数小时历史数据的表格等等。 + +这是[Github上的完整源代码][10]。 + +### 总结 + +在资金相对紧张的情况下,树莓派是一种选择。除此以外,还有很多可以用来测定颗粒物的应用,包括室外固定装置、移动测定设备等等。我们学校则同时采用了这两种:固定装置在室外测定全天颗粒物浓度,而移动测定设备在室内检测空调过滤器的效果。 + +[Luftdaten.info][12] 提供了一个如何设计类似的传感器的介绍,其中的软件效果出众,而且因为它没有使用树莓派,所以硬件更是小巧。 + +对于学生来说,设计一个颗粒物传感器确实算得上是一个优秀的课外项目。 + +你又打算如何使用你的[树莓派][13]呢? + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/how-measure-particulate-matter-raspberry-pi + +作者:[Stephan Tetzel][a] +译者:[HankChow](https://github.com/HankChow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/stephan +[1]:https://en.wikipedia.org/wiki/Particulates +[2]:https://en.wikipedia.org/wiki/Air_quality_index +[3]:https://en.wikipedia.org/wiki/United_States_Environmental_Protection_Agency +[5]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/air_quality_index.png?itok=FwmGf1ZS (Air quality index) +[7]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/particulate_sensor.jpg?itok=ddH3bBwO (Particulate sensor) +[8]:https://www.raspberrypi.org/documentation/installation/installing-images/README.md +[9]:http://192.168.1.5/ +[10]:https://github.com/zefanja/aqi +[11]:https://opensource.com/article/18/3/raspberry-pi-week-giveaway +[12]:http://luftdaten.info/ +[13]:https://openschoolsolutions.org/shutdown-servers-case-power-failure%e2%80%8a-%e2%80%8aups-nut-co/ diff --git a/published/20180317 How To Edit Multiple Files Using Vim Editor.md b/published/20180317 How To Edit Multiple Files Using Vim Editor.md new file mode 100644 index 0000000000..b890cbe282 --- /dev/null +++ b/published/20180317 How To Edit Multiple Files Using Vim Editor.md @@ -0,0 +1,348 @@ +如何使用 Vim 编辑多个文件 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/Edit-Multiple-Files-Using-Vim-Editor-720x340.png) + +有时候,您可能需要修改多个文件,或要将一个文件的内容复制到另一个文件中。在图形用户界面中,您可以在任何图形文本编辑器(如 gedit)中打开文件,并使用 `CTRL + C` 和 `CTRL + V` 复制和粘贴内容。在命令行模式下,您不能使用这种编辑器。不过别担心,只要有 `vim` 编辑器就有办法。在本教程中,我们将学习使用 `vim` 编辑器同时编辑多个文件。相信我,很有意思哒。 + +### 安装 Vim + +Vim 编辑器可在大多数 Linux 发行版的官方软件仓库中找到,所以您可以用默认的软件包管理器来安装它。例如,在 Arch Linux 及其变体上,您可以使用如下命令: + +``` +$ sudo pacman -S vim +``` + +在 Debian 和 Ubuntu 上: + +``` +$ sudo apt-get install vim +``` + +在 RHEL 和 CentOS 上: + +``` +$ sudo yum install vim +``` + +在 Fedora 上: + +``` +$ sudo dnf install vim +``` + +在 openSUSE 上: + +``` +$ sudo zypper install vim +``` + +### 使用 Linux 的 Vim 编辑器同时编辑多个文件 + +现在让我们谈谈正事,我们可以用两种方法做到这一点。 + +#### 方法一 + +有两个文件,即 `file1.txt` 和 `file2.txt`,带有一堆随机单词: + +``` +$ cat file1.txt +ostechnix +open source +technology +linux +unix + +$ cat file2.txt +line1 +line2 +line3 +line4 +line5 +``` + +现在,让我们同时编辑这两个文件。请运行: + +``` +$ vim file1.txt file2.txt +``` + +Vim 将按顺序显示文件的内容。首先显示第一个文件的内容,然后显示第二个文件,依此类推。 + +![][2] + +##### 在文件中切换 + +要移至下一个文件,请键入: + +``` +:n +``` + +![][3] + +要返回到前一个文件,请键入: + +``` +:N +``` + +如果有任何未保存的更改,Vim 将不允许您移动到下一个文件。要保存当前文件中的更改,请键入: + +``` +ZZ +``` + +请注意,是两个大写字母 `ZZ`(`SHIFT + zz`)。 + +要放弃更改并移至上一个文件,请键入: + +``` +:N! +``` + +要查看当前正在编辑的文件,请键入: + +``` +:buffers +``` + +![][4] + +您将在底部看到加载文件的列表。 + +![][5] + +要切换到下一个文件,请输入 `:buffer`,后跟缓冲区编号。例如,要切换到第一个文件,请键入: + +``` +:buffer 1 +``` + +![][6] + +##### 打开其他文件进行编辑 + +目前我们正在编辑两个文件,即 `file1.txt` 和 `file2.txt`。我想打开另一个名为 `file3.txt` 的文件进行编辑。 + +您会怎么做?这很容易。只需键入 `:e`,然后输入如下所示的文件名即可: + +``` +:e file3.txt +``` + +![][7] + +现在你可以编辑 `file3.txt` 了。 + +要查看当前正在编辑的文件数量,请键入: + +``` +:buffers +``` + +![][8] + +请注意,对于使用 `:e` 打开的文件,您无法使用 `:n` 或 `:N` 进行切换。要切换到另一个文件,请输入 `:buffer`,然后输入文件缓冲区编号。 + +##### 将一个文件的内容复制到另一个文件中 + +您已经知道了如何同时打开和编辑多个文件。有时,您可能想要将一个文件的内容复制到另一个文件中。这也是可以做到的。切换到您选择的文件,例如,假设您想将 `file1.txt` 的内容复制到 `file2.txt` 中: + + +首先,请切换到 `file1.txt`: + +``` +:buffer 1 +``` + +将光标移动至在想要复制的行的前面,并键入`yy` 以抽出(复制)该行。然后,移至 `file2.txt`: + +``` +:buffer 2 +``` + +将光标移至要从 `file1.txt` 粘贴复制行的位置,然后键入 `p`。例如,您想要将复制的行粘贴到 `line2` 和 `line3` 之间,请将鼠标光标置于行前并键入 `p`。 + +输出示例: + +``` +line1 +line2 +ostechnix +line3 +line4 +line5 +``` + +![][9] + +要保存当前文件中所做的更改,请键入: + +``` +ZZ +``` + +再次提醒,是两个大写字母 ZZ(`SHIFT + z`)。 + +保存所有文件的更改并退出 vim 编辑器,键入: + +``` +:wq +``` + +同样,您可以将任何文件的任何行复制到其他文件中。 + +##### 将整个文件内容复制到另一个文件中 + +我们知道如何复制一行,那么整个文件的内容呢?也是可以的。比如说,您要将 `file1.txt` 的全部内容复制到 `file2.txt` 中。 + +先打开 `file2.txt`: + +``` +$ vim file2.txt +``` + +如果文件已经加载,您可以通过输入以下命令切换到 `file2.txt`: + +``` +:buffer 2 +``` + +将光标移动到您想要粘贴 `file1.txt` 的内容的位置。我想在 `file2.txt` 的第 5 行之后粘贴 `file1.txt` 的内容,所以我将光标移动到第 5 行。然后,键入以下命令并按回车键: + +``` +:r file1.txt +``` + +![][10] + +这里,`r` 代表 “read”。 + +现在您会看到 `file1.txt` 的内容被粘贴在 `file2.txt` 的第 5 行之后。 + +``` +line1 +line2 +line3 +line4 +line5 +ostechnix +open source +technology +linux +unix +``` + +![][11] + +要保存当前文件中的更改,请键入: + +``` +ZZ + +``` + +要保存所有文件的所有更改并退出 vim 编辑器,请输入: + +``` +:wq +``` + +#### 方法二 + +另一种同时打开多个文件的方法是使用 `-o` 或 `-O` 标志。 + +要在水平窗口中打开多个文件,请运行: + +``` +$ vim -o file1.txt file2.txt +``` + +![][12] + +要在窗口之间切换,请按 `CTRL-w w`(即按 `CTRL + w` 并再次按 `w`)。或者,您可以使用以下快捷方式在窗口之间移动: + + * `CTRL-w k` – 上面的窗口 + * `CTRL-w j` – 下面的窗口 + +要在垂直窗口中打开多个文件,请运行: + +``` +$ vim -O file1.txt file2.txt file3.txt +``` + +![][13] + +要在窗口之间切换,请按 `CTRL-w w`(即按 `CTRL + w` 并再次按 `w`)。或者,使用以下快捷方式在窗口之间移动: + + * `CTRL-w l` – 左面的窗口 + * `CTRL-w h` – 右面的窗口 + +其他的一切都与方法一的描述相同。 + +例如,要列出当前加载的文件,请运行: + +``` +:buffers +``` + +在文件之间切换: + +``` +:buffer 1 +``` + +打开其他文件,请键入: + +``` +:e file3.txt +``` + +将文件的全部内容复制到另一个文件中: + +``` +:r file1.txt + +``` + +方法二的唯一区别是,只要您使用 `ZZ` 保存对当前文件的更改,文件将自动关闭。然后,您需要依次键入 `:wq` 来关闭文件。但是,如果您按照方法一进行操作,输入 `:wq` 时,所有更改将保存在所有文件中,并且所有文件将立即关闭。 + +有关更多详细信息,请参阅手册页。 + +``` +$ man vim +``` + + +### 建议阅读 + +您现在掌握了如何在 Linux 中使用 vim 编辑器编辑多个文件。正如您所见,编辑多个文件并不难。Vim 编辑器还有更强大的功能。我们接下来会提供更多关于 Vim 编辑器的内容。 + +再见! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-edit-multiple-files-using-vim-editor/ + +作者:[SK][a] +译者:[jessie-pang](https://github.com/jessie-pang) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-1-1.png +[3]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-2.png +[4]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-5.png +[5]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-6.png +[6]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-7.png +[7]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-8.png +[8]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-10-1.png +[9]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-11.png +[10]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-12.png +[11]:http://www.ostechnix.com/wp-content/uploads/2018/03/edit-multiple-files-13.png +[12]:http://www.ostechnix.com/wp-content/uploads/2018/03/Edit-multiple-files-16.png +[13]:http://www.ostechnix.com/wp-content/uploads/2018/03/Edit-multiple-files-17.png \ No newline at end of file diff --git a/published/20180319 A Command Line Productivity Tool For Tracking Work Hours.md b/published/20180319 A Command Line Productivity Tool For Tracking Work Hours.md new file mode 100644 index 0000000000..010c434fb1 --- /dev/null +++ b/published/20180319 A Command Line Productivity Tool For Tracking Work Hours.md @@ -0,0 +1,190 @@ +moro:一个用于追踪工作时间的命令行生产力工具 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/Moro-720x340.jpg) + +保持对你的工作小时数的追踪将让你知晓在一个特定时间区间内你所完成的工作总量。在网络上有大量的基于 GUI 的生产力工具可以用来追踪工作小时数。但我却不能找到一个基于 CLI 的工具。今天我偶然发现了一个简单而奏效的叫做 Moro 的追踪工作时间数的工具。Moro 是一个芬兰词汇,意为“Hello”。通过使用 Moro,你可以找到你在完成某项特定任务时花费了多少时间。这个工具是自由开源软件,它是通过 NodeJS 编写的。 + +### Moro - 一个追踪工作时间的命令行生产力工具 + +由于 Moro 是使用 NodeJS 编写的,保证你的系统上已经安装了 NodeJS。如果你没有安装好 NodeJS,跟随下面的链接在你的 Linux 中安装 NodeJS 和 NPM。 + +- [如何在 Linux 上安装 NodeJS](https://www.ostechnix.com/install-node-js-linux/) + +NodeJS 和NPM一旦装好,运行下面的命令来安装 Moro。 + +``` +$ npm install -g moro +``` + +### 用法 + +Moro 的工作概念非常简单。它记录了你的工作开始时间,结束时间和在你的系统上的休息时间。在每天结束时,它将会告知你已经工作了多少时间。 + +当你到达办公室时,只需键入: + +``` +$ moro +``` + +示例输出: +``` +♥ Moro \o/ +√ You clocked in at: 9:20 +``` + +Moro 将会把这个时间注册为你的开始时间。 + +当你离开办公室时,再次键入: + +``` +$ moro +``` + +示例输出: + +``` +♥ Moro \o/ +√ You clocked out at: 19:22 +ℹ Today looks like this so far: +┌──────────────────┬─────────────────────────┐ +│ Today you worked │ 9 Hours and 72 Minutes │ +├──────────────────┼─────────────────────────┤ +│ Clock in │ 9:20 │ +├──────────────────┼─────────────────────────┤ +│ Clock out │ 19:22 │ +├──────────────────┼─────────────────────────┤ +│ Break duration │ 30 minutes │ +├──────────────────┼─────────────────────────┤ +│ Date │ 2018-03-19 │ +└──────────────────┴─────────────────────────┘ +ℹ Run moro --help to learn how to edit your clock in, clock out or break duration for today +``` + +Moro 将会把这个时间注册为你的结束时间。 + +现在,Moro 将会从结束时间减去开始时间,然后从总的时间减去另外的 30 分钟作为休息时间,并给你在那天总的工作时间。抱歉,我的数学计算过程解释实在糟糕。假设你在早上 10:00 来工作并在晚上 17:30 离开。所以,你总共在办公室呆了 7:30 小时(例如 17:30-10)。然后在总的时间减去休息时间(默认是 30 分钟)。因此,你的总工作时间是 7 小时。明白了?很好! + +**注意:**不要像我在写这个手册的时候一样把 “moro” 和 “more” 弄混了。 + +查看你注册的所有小时数,运行: + +``` +$ moro report --all +``` + +以防万一,如果你忘记注册开始时间或者结束时间,你一样可以在之后指定这些值。 + +例如,将上午 10 点注册为开始时间,运行: + +``` +$ moro hi 10:00 +♥ Moro \o/ +√ You clocked in at: 10:00 +⏰ Working until 18:00 will make it a full (7.5 hours) day +``` + +注册 17:30 作为结束时间: + +``` +$ moro bye 17:30 +♥ Moro \o/ +√ You clocked out at: 17:30 +ℹ Today looks like this so far: + +┌──────────────────┬───────────────────────┐ +│ Today you worked │ 7 Hours and 0 Minutes │ +├──────────────────┼───────────────────────┤ +│ Clock in │ 10:00 │ +├──────────────────┼───────────────────────┤ +│ Clock out │ 17:30 │ +├──────────────────┼───────────────────────┤ +│ Break duration │ 30 minutes │ +├──────────────────┼───────────────────────┤ +│ Date │ 2018-03-19 │ +└──────────────────┴───────────────────────┘ +ℹ Run moro --help to learn how to edit your clock in, clock out or break duration for today +``` + +你已经知道 Moro 默认将会减去 30 分钟的休息时间。如果你需要设置一个自定义的休息时间,你可以简单使用以下命令: + +``` +$ moro break 45 +``` + +现在,休息时间是 45 分钟了。 + +若要清除所有的数据: + +``` +$ moro clear --yes +♥ Moro \o/ +√ Database file deleted successfully +``` + +#### 添加笔记 + +有时候,你想要在工作时添加笔记。不必去寻找一个独立的作笔记的应用。Moro 将会帮助你添加笔记。要添加笔记,只需运行: + +``` +$ moro note mynotes +``` + +要在之后搜索所有已经注册的笔记,只需做: + +``` +$ moro search mynotes +``` + +#### 修改默认设置 + +默认的完整工作时间是 7.5 小时。这是因为开发者来自芬兰,这是官方的工作小时数。但是你也可以修改这个设置为你的国家的工作小时数。 + +举个例子,要将其设置为 7 小时,运行: + +``` +$ moro config --day 7 +``` + +同样地,默认的休息时间也可以像下面这样从 30 分钟修改: + +``` +$ moro config --break 45 +``` + +#### 备份你的数据 + +正如我已经说了的,Moro 将时间追踪信息存储在你的家目录,文件名是 `.moro-data.db`。 + +但是,你可以保存备份数据库到不同的位置。要这样做的话,像下面这样将 `.moro-data.db` 文件移到你选择的一个不同的位置并告知 Moro 使用那个数据库文件。 + +``` +$ moro config --database-path /home/sk/personal/moro-data.db +``` + +在上面的每一个命令,我都已经把默认的数据库文件分配到了 `/home/sk/personal` 目录。 + +需要帮助的话,运行: + +``` +$ moro --help +``` + +正如你所见,Moro 是非常简单而又能用于追踪你完成你的工作使用了多少时间的。对于自由职业者和任何想要在一定时间范围内完成事情的人,它将会是有用的。 + +并且,这些只是今天的内容。希望这些内容能够有所帮助。更多的好东西将会出现。请保持关注! + +干杯! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/moro-a-command-line-productivity-tool-for-tracking-work-hours/ + +作者:[SK][a] +译者:[leemeans](https://github.com/leemeans) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ diff --git a/published/20180320 Dry - An Interactive CLI Manager For Docker Containers.md b/published/20180320 Dry - An Interactive CLI Manager For Docker Containers.md new file mode 100644 index 0000000000..1855ebb265 --- /dev/null +++ b/published/20180320 Dry - An Interactive CLI Manager For Docker Containers.md @@ -0,0 +1,161 @@ +Dry:一个命令行交互式 Docker 容器管理器 +====== + +Docker 是一种所谓容器化的操作系统级的虚拟化软件。 + +基于 Linux 内核的 cgroup 和 namespace 等资源隔离特性,Docker 可以在单个 Linux 实例中运行多个独立的容器。 + +通过将应用依赖和相关库打包进容器,Docker 使得应用可以在容器中安全隔离地运行。 + +### Dry 是什么 + +[Dry][1] 是一个管理并监控 Docker 容器和镜像的命令行工具。 + +Dry 可以给出容器相关的信息,包括对应镜像、容器名称、网络、容器中运行的命令及容器状态;如果运行在 Docker Swarm 中,工具还会给出 Swarm 集群的各种状态信息。 + +Dry 可以连接至本地或远程的 Docker 守护进程。如果连接本地 Docker,Docker 主机显示为 `unix:///var/run/docker.sock`。 + +如果连接远程 Docker,Docker 主机显示为 `tcp://IP Address:Port Number` 或 `tcp://Host Name:Port Number`。 + +Dry 可以提供类似 `docker ps` 的指标输出,但输出比 `docker ps` 内容详实、富有色彩。 + +相比 Docker,Dry 还可以手动添加一个额外的名称列,用于降低记忆难度。 + +**推荐阅读:** + +- [Portainer – 用于 Docker 管理的简明 GUI][2] +- [Rancher – 适用于生产环境的完备容器管理平台][3] +- [cTop – Linux环境下容器管理与监控的命令行工具][4] + +### 如何在 Linux 中安装 Dry + +在 Linux 中,可以通过一个简单的 shell 脚本安装最新版本的 Dry 工具。Dry 不依赖外部库。对于绝大多数的 Docker 命令,Dry 提供类似样式的命令。 + +``` +$ curl -sSf https://moncho.github.io/dry/dryup.sh | sudo sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 10 100 10 0 0 35 0 --:--:-- --:--:-- --:--:-- 35 +dryup: downloading dry binary +######################################################################## 100.0% +dryup: Moving dry binary to its destination +dryup: dry binary was copied to /usr/local/bin, now you should 'sudo chmod 755 /usr/local/bin/dry' +``` + +使用如下命令将文件权限变更为 `755`: + +``` +$ sudo chmod 755 /usr/local/bin/dry +``` + +对于使用 Arch Linux 的用户,可以使用 **[Packer][5]** 或 **[Yaourt][6]** 包管理器,从 AUR 源安装该工具。 +``` +$ yaourt -S dry-bin +或者 +$ packer -S dry-bin +``` + +如果希望在 Docker 容器中运行 dry,可以运行如下命令。前提条件是已确认在操作系统中安装了 Docker。 + +**推荐阅读:** + +- [如何在 Linux 中安装 Docker][7] +- [如何在 Linux 中玩转 Docker 镜像][8] +- [如何在 Linux 中玩转 Docker 容器][9] +- [如何在 Docker 容器中安装并运行应用程序][10] + +``` +$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock moncho/dry +``` + +### 如何启动并运行 Dry + +在控制台运行 `dry` 命令即可启动该工具,其默认输出如下: + +``` +$ dry +``` + +![][12] + +### 如何使用 Dry 监控 Docker + +你可以在 dry 的界面中按下 `m` 键打开监控模式。 + +![][13] + +### 如何使用 Dry 管理容器 + +在选中的容器上单击回车键,即可管理容器。Dry 提供如下操作:查看日志,查看、杀死、删除容器,停止、启动、重启容器,查看容器状态及镜像历史记录等。 + +![][14] + +### 如何监控容器资源利用率 + +用户可以使用 `Stats+Top` 选项查看指定容器的资源利用率。 + +该操作需要在容器管理界面完成(在上一步的基础上,点击 `Stats+Top` 选项)。另外,也可以按下 `s` 打开容器资源利用率界面。 + +![][15] + +### 如何查看容器、镜像及本地卷的磁盘使用情况 + +可以使用 `F8` 键查看容器、镜像及本地卷的磁盘使用情况。 + +该界面明确地给出容器、镜像和卷的总数,哪些处于使用状态,以及整体磁盘使用情况、可回收空间大小的详细信息。 + +![][16] + +### 如何查看已下载的镜像 + +按下 `2` 键即可列出全部的已下载镜像。 + +![][17] + +### 如何查看网络列表 + +按下 `3` 键即可查看全部网络及网关。 + +![][18] + +### 如何查看全部 Docker 容器 + +按下 `F2` 键即可列出列出全部容器,包括运行中和已关闭的容器。 + +![][19] + +### Dry 快捷键 + +查看帮助页面或 [dry GitHub][1] 即可查看全部快捷键。 + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/dry-an-interactive-cli-manager-for-docker-containers/ + +作者:[Magesh Maruthamuthu][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[pinewall](https://github.com/pinewall) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/magesh/ +[1]:https://github.com/moncho/dry +[2]:https://www.2daygeek.com/portainer-a-simple-docker-management-gui/ +[3]:https://www.2daygeek.com/rancher-a-complete-container-management-platform-for-production-environment/ +[4]:https://www.2daygeek.com/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux/ +[5]:https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/ +[6]:https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/ +[7]:https://www.2daygeek.com/install-docker-on-centos-rhel-fedora-ubuntu-debian-oracle-archi-scentific-linux-mint-opensuse/ +[8]:https://www.2daygeek.com/list-search-pull-download-remove-docker-images-on-linux/ +[9]:https://www.2daygeek.com/create-run-list-start-stop-attach-delete-interactive-daemonized-docker-containers-on-linux/ +[10]:https://www.2daygeek.com/install-run-applications-inside-docker-containers/ +[11]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[12]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-1.png +[13]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-2.png +[14]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-3.png +[15]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-4.png +[16]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-5.png +[17]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-6.png +[18]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-7.png +[19]:https://www.2daygeek.com/wp-content/uploads/2018/03/dry-an-interactive-cli-manager-for-docker-containers-8.png diff --git a/published/20180321 How to use Ansible to patch systems and install applications.md b/published/20180321 How to use Ansible to patch systems and install applications.md new file mode 100644 index 0000000000..d55e1bae17 --- /dev/null +++ b/published/20180321 How to use Ansible to patch systems and install applications.md @@ -0,0 +1,146 @@ +如何使用 Ansible 打补丁以及安装应用 +====== + +> 使用 Ansible IT 自动化引擎节省更新的时间。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tools_osyearbook2016_sysadmin_cc.png?itok=Y1AHCKI4) + +你有没有想过,如何打补丁、重启系统,然后继续工作? + +如果你的回答是肯定的,那就需要了解一下 [Ansible][1] 了。它是一个配置管理工具,对于一些复杂的有时候需要几个小时才能完成的系统管理任务,又或者对安全性有比较高要求的时候,使用 Ansible 能够大大简化工作流程。 + +以我作为系统管理员的经验,打补丁是一项最有难度的工作。每次遇到公共漏洞批露Common Vulnearbilities and Exposure(CVE)通知或者信息保障漏洞预警Information Assurance Vulnerability Alert(IAVA)时都必须要高度关注安全漏洞,否则安全部门将会严肃追究自己的责任。 + +使用 Ansible 可以通过运行[封装模块][2]以缩短打补丁的时间,下面以 [yum 模块][3]更新系统为例,使用 Ansible 可以执行安装、更新、删除、从其它地方安装(例如持续集成/持续开发中的 `rpmbuild`)。以下是系统更新的任务: + +``` + - name: update the system + yum: + name: "*" + state: latest +``` + +在第一行,我们给这个任务命名,这样可以清楚 Ansible 的工作内容。第二行表示使用 `yum` 模块在CentOS虚拟机中执行更新操作。第三行 `name: "*"` 表示更新所有程序。最后一行 `state: latest` 表示更新到最新的 RPM。 + +系统更新结束之后,需要重新启动并重新连接: + +``` + - name: restart system to reboot to newest kernel + shell: "sleep 5 && reboot" + async: 1 + poll: 0 + + - name: wait for 10 seconds + pause: + seconds: 10 + + - name: wait for the system to reboot + wait_for_connection: + connect_timeout: 20 + sleep: 5 + delay: 5 + timeout: 60 + + - name: install epel-release + yum: + name: epel-release + state: latest +``` + +`shell` 模块中的命令让系统在 5 秒休眠之后重新启动,我们使用 `sleep` 来保持连接不断开,使用 `async` 设定最大等待时长以避免发生超时,`poll` 设置为 0 表示直接执行不需要等待执行结果。暂停 10 秒钟以等待虚拟机恢复,使用 `wait_for_connection` 在虚拟机恢复连接后尽快连接。随后由 `install epel-release` 任务检查 RPM 的安装情况。你可以对这个剧本执行多次来验证它的幂等性,唯一会显示造成影响的是重启操作,因为我们使用了 `shell` 模块。如果不想造成实际的影响,可以在使用 `shell` 模块的时候 `changed_when: False`。 + +现在我们已经知道如何对系统进行更新、重启虚拟机、重新连接、安装 RPM 包。下面我们通过 [Ansible Lightbulb][4] 来安装 NGINX: + +``` + - name: Ensure nginx packages are present + yum: + name: nginx, python-pip, python-devel, devel + state: present + notify: restart-nginx-service + + - name: Ensure uwsgi package is present + pip: + name: uwsgi + state: present + notify: restart-nginx-service + + - name: Ensure latest default.conf is present + template: + src: templates/nginx.conf.j2 + dest: /etc/nginx/nginx.conf + backup: yes + notify: restart-nginx-service + + - name: Ensure latest index.html is present + template: + src: templates/index.html.j2 + dest: /usr/share/nginx/html/index.html + + - name: Ensure nginx service is started and enabled + service: + name: nginx + state: started + enabled: yes + + - name: Ensure proper response from localhost can be received + uri: + url: "http://localhost:80/" + return_content: yes + register: response + until: 'nginx_test_message in response.content' + retries: 10 + delay: 1 +``` + +以及用来重启 nginx 服务的操作文件: + +``` +# 安装 nginx 的操作文件 + - name: restart-nginx-service + service: + name: nginx + state: restarted +``` + +在这个角色里,我们使用 RPM 安装了 `nginx`、`python-pip`、`python-devel`、`devel`,用 PIP 安装了 `uwsgi`,接下来使用 `template` 模块复制 `nginx.conf` 和 `index.html` 以显示页面,并确保服务在系统启动时启动。然后就可以使用 `uri` 模块检查到页面的连接了。 + +这个是一个系统更新、系统重启、安装 RPM 包的剧本示例,后续可以继续安装 nginx,当然这里可以替换成任何你想要的角色和应用程序。 + +``` + - hosts: all + roles: + - centos-update + - nginx-simple +``` + +观看演示视频了解了解这个过程。 + +[demo](https://asciinema.org/a/166437/embed?) + +这只是关于如何更新系统、重启以及后续工作的示例。简单起见,我只添加了不带[变量][5]的包,当你在操作大量主机的时候,你就需要修改其中的一些设置了: + +- [async & poll](https://docs.ansible.com/ansible/latest/playbooks_async.html) +- [serial](https://docs.ansible.com/ansible/latest/playbooks_delegation.html#rolling-update-batch-size) +- [forks](https://docs.ansible.com/ansible/latest/intro_configuration.html#forks) + +这是由于在生产环境中如果你想逐一更新每一台主机的系统,你需要花相当一段时间去等待主机重启才能够继续下去。 + +有关 Ansible 进行自动化工作的更多用法,请查阅[其它文章][6]。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/ansible-patch-systems + +作者:[Jonathan Lozada De La Matta][a] +译者:[HankChow](https://github.com/HankChow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jlozadad +[1]:https://www.ansible.com/overview/how-ansible-works +[2]:https://docs.ansible.com/ansible/latest/list_of_packaging_modules.html +[3]:https://docs.ansible.com/ansible/latest/yum_module.html +[4]:https://github.com/ansible/lightbulb/tree/master/examples/nginx-role +[5]:https://docs.ansible.com/ansible/latest/playbooks_variables.html +[6]:https://opensource.com/tags/ansible diff --git a/published/20180325 Could we run Python 2 and Python 3 code in the same VM with no code changes.md b/published/20180325 Could we run Python 2 and Python 3 code in the same VM with no code changes.md new file mode 100644 index 0000000000..58d1df78fe --- /dev/null +++ b/published/20180325 Could we run Python 2 and Python 3 code in the same VM with no code changes.md @@ -0,0 +1,117 @@ +我们可以在同一个虚拟机中运行 Python 2 和 3 代码而不需要更改代码吗? +===== + +从理论上来说,可以。Zed Shaw 说过一句著名的话,如果不行,那么 Python 3 一定不是图灵完备的。但在实践中,这是不现实的,我将通过给你们举几个例子来说明原因。 + +### 对于字典(dict)来说,这意味着什么? + +让我们来想象一台拥有 Python 6 的虚拟机,它可以读取 Python 3.6 编写的 `module3.py`。但是在这个模块中,它可以导入 Python 2.7 编写的 `module2.py`,并成功使用它,没有问题。这显然是实验代码,但假设 `module2.py` 包含以下的功能: + +``` +def update_config_from_dict(config_dict): + items = config_dict.items() + while items: + k, v = items.pop() + memcache.set(k, v) + +def config_to_dict(): + result = {} + for k, v in memcache.getall(): + result[k] = v + return result + +def update_in_place(config_dict): + for k, v in config_dict.items(): + new_value = memcache.get(k) + if new_value is None: + del config_dict[k] + elif new_value != v: + config_dict[k] = v +``` + +现在,当我们想从 `module3` 中调用这些函数时,我们遇到了一个问题:Python 3.6 中的字典类型与 Python 2.7 中的字典类型不同。在 Python 2 中,字典是无序的,它们的 `.keys()`, `.values()`, `.items()` 方法返回了正确的序列,这意味着调用 `.items()` 会在字典中创建状态的副本。在 Python 3 中,这些方法返回字典当前状态的动态视图。 + +这意味着如果 `module3` 调用 `module2.update_config_from_dict(some_dictionary)`,它将无法运行,因为 Python 3 中 `dict.items()` 返回的值不是一个列表,并且没有 `.pop()` 方法。反过来也是如此。如果 `module3` 调用 `module2.config_to_dict()`,它可能会返回一个 Python 2 的字典。现在调用 `.items()` 突然返回一个列表,所以这段代码无法正常工作(这对 Python 3 字典来说工作正常): + +``` +def main(cmdline_options): + d = module2.config_to_dict() + items = d.items() + for k, v in items: + print(f'Config from memcache: {k}={v}') + for k, v in cmdline_options: + d[k] = v + for k, v in items: + print(f'Config with cmdline overrides: {k}={v}') +``` + +最后,使用 `module2.update_in_place()` 会失败,因为 Python 3 中 `.items()` 的值现在不允许在迭代过程中改变。 + +对于字典来说,还有很多问题。Python 2 的字典在 Python 3 上使用 `isinstance(d, dict)` 应该返回 `True` 吗?如果是的话,这将是一个谎言。如果没有,代码将无法继续。 + +### Python 应该神奇地知道类型并会自动转换! + +为什么我们的 Python 6 的虚拟机无法识别 Python 3 的代码,在 Python 2 中调用 `some_dict.keys()` 时,我们还有别的意思吗?好吧,Python 不知道代码的作者在编写代码时,她所认为的 `some_dict` 应该是什么。代码中没有任何内容表明它是否是一个字典。在 Python 2 中没有类型注释,因为它们是可选的,即使在 Python 3 中,大多数代码也不会使用它们。 + +在运行时,当你调用 `some_dict.keys()` 的时候,Python 只是简单地在对象上查找一个属性,该属性恰好隐藏在 `some_dict` 名下,并试图在该属性上运行 `__call__()`。这里有一些关于方法绑定,描述符,slots 等技术问题,但这是它的核心。我们称这种行为为“鸭子类型”。 + +由于鸭子类型,Python 6 的虚拟机将无法做出编译时决定,以正确转换调用和属性查找。 + +### 好的,让我们在运行时做出这个决定 + +Python 6 的虚拟机可以标记每个属性,通过查找“来自 py2 的调用”或“来自 py3 的调用”的信息来实现这一点,并使对象发送正确的属性。这会让它变得很慢,并且使用更多的内存。这将要求我们在内存中保留两种版本的代码,并通过代理来使用它们。我们需要加倍付出努力,在用户背后同步这些对象的状态。毕竟,新字典的内存表示与 Python 2 不同。 + +如果你已经被字典问题绕晕了,那么再想想 Python 3 中的 Unicode 字符串和 Python 2 中的字节(byte)字符串的各种问题吧。 + +### 没有办法了吗?Python 3 根本就不能运行旧代码吗? + +不会。每天都会有项目移植到 Python 3。将 Python 2 代码移植到两个版本的 Python 上推荐方法是在你的代码上运行 [Python-Modernize][1]。它会捕获那些在 Python 3 上不起作用的代码,并使用 [six][2] 库将其替换,以便它在 Python 2 和 Python 3 上运行。这是 `2to3` 的一个改编版本,用于生成仅针对 Python 3 代码。`Modernize` 是首选,因为它提供了更多的增量迁移路线。所有的这些在 Python 文档中的 [Porting Python 2 Code to Python 3][3]文档中都有很好的概述。 + +但是,等一等,你不是说 Python 6 的虚拟机不能自动执行此操作吗?对。`Modernize` 查看你的代码,并试图猜测哪些是安全的。它会做出一些不必要的改变,还会错过其他必要的改变。但是,它不会帮助你处理字符串。如果你的代码没有在“来自外部的二进制数据”和“流程中的文本数据”之间保持界限,那么这种转换就不会那么轻易。 + +因此,大项目的迁移不能自动完成,并且需要人类进行测试,发现问题并修复它们。它工作吗?是的,我曾帮助[将一百万行代码迁移到 Python 3][4],并且这种切换没有造成事故。这一举措让我们重新获得了 1/3 的服务器内存,并使代码运行速度提高了 12%。那是在 Python 3.5 上,但是 Python 3.6 的速度要快得多,根据你的工作量,你甚至可以达到 [4 倍加速][5]。 + +### 亲爱的 Zed + +hi,伙计,我关注你已经超过 10 年了。我一直在观察,当你感到沮丧的时候,你对 Mongrel 没有任何信任,尽管 Rails 生态系统几乎全部都在上面运行。当你重新设计它并开始 Mongrel 2 项目时,我一直在观察。我一直在关注你使用 Fossil 这一令人惊讶的举动。随着你发布 “Rails 是一个贫民窟”的帖子,我看到你突然离开了 Ruby 社区。当你开始编写《笨方法学 Python》并且开始推荐它时,我感到非常兴奋。2013 年我在 [DjangoCon Europe][6] 见过你,我们谈了很多关于绘画,唱歌和倦怠的内容。[你的这张照片][7]是我在 Instagram 上的第一个帖子。 + +你几乎把另一个“贫民区”的行动与 [“反对 Python 3” 案例][8] 文章拉到一起。我认为你本意是好的,但是这篇文章引起了很多混淆,包括许多人觉得你认为 Python 3 不是图灵完整的。我花了好几个小时让人们相信,你是在开玩笑。但是,鉴于你对《笨方法学 Python》的重大贡献,我认为这是值得的。特别是你为 Python 3 更新了你的书。感谢你做这件事。如果我们社区中真的有人因你的帖子为由要求将你和你的书列入黑名单,而请他们出去。这是一个双输的局面,这是错误的。 + +说实话,没有一个核心 Python 开发人员认为 Python 2 到 Python 3 的转换过程会顺利而且计划得当,[包括 Guido van Rossum][9]。真的,可以看那个视频,这有点事后诸葛亮的意思了。从这个意义上说,*我们实际上是积极地相互认同的*。如果我们再做一次,它会看起来不一样。但在这一点上,[在 2020 年 1 月 1 日,Python 2 将会到达终结][10]。大多数第三方库已经支持 Python 3,甚至开始发布只支持 Python 3 的版本(参见 [Django][11] 或 [科学项目关于 Python 3 的声明][12])。 + +我们也积极地就另一件事达成一致。就像你于 Mongrel 一样,Python 核心开发人员是志愿者,他们的工作没有得到报酬。我们大多数人在这个项目上投入了大量的时间和精力,因此[我们自然而然敏感][13]于那些对他们的贡献不屑一顾和激烈的评论。特别是如果这个信息既攻击目前的事态,又要求更多的自由贡献。 + +我希望到 2018 年你会让忘记 2016 发布的帖子,有一堆好的反驳。[我特别喜欢 eevee][14](LCTT 译注:eevee 是一个为 Blender 设计的渲染器)。它特别针对“一起运行 Python 2 和 Python 3 ”的场景,这是不现实的,就像在同一个虚拟机中运行 Ruby 1.8 和 Ruby 2.x 一样,或者像 Lua 5.3 和 Lua 5.1 同时运行一样。你甚至不能用 libc.so.6 运行针对 libc.so.5 编译的 C 二进制文件。然而,我发现最令人惊讶的是,你声称 Python 核心开发者是“有目的地”创造诸如 2to3 之类的破坏工具,这些由 Guido 创建,其最大利益就是让每个人尽可能顺利,快速地迁移。我很高兴你在之后的帖子中放弃了这个说法,但是你必须意识到你会激怒那些阅读了原始版本的人。对蓄意伤害的指控最好有强有力的证据支持。 + +但看起来你仍然会这样做。[就在今天][15]你说 Python 核心开发者“忽略”尝试解决 API 的问题,特别是 `six`。正如我上面写的那样,Python 文档中的官方移植指南涵盖了 `six`。更重要的是,`six` 是由 Python 2.7 的发布管理者 Benjamin Peterson 编写。很多人学会了编程,这要归功于你,而且由于你在网上有大量的粉丝,人们会阅读这样的推文,他们会相信它的价值,这是有害的。 + +我有一个建议,让我们把 “Python 3 管理不善”的争议搁置起来。Python 2 正在死亡,这个过程会很慢,并且它是丑陋而血腥的,但它是一条单行道。争论那些没有用。相反,让我们专注于我们现在可以做什么来使 Python 3.8 比其他任何 Python 版本更好。也许你更喜欢看外面的角色,但作为这个社区的成员,你会更有影响力。请说“我们”而不是“他们”。 + + +-------------------------------------------------------------------------------- + +via: http://lukasz.langa.pl/13/could-we-run-python-2-and-python-3-code-same-vm/ + +作者:[Łukasz Langa][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://lukasz.langa.pl +[1]:https://python-modernize.readthedocs.io/ +[2]:http://pypi.python.org/pypi/six +[3]:https://docs.python.org/3/howto/pyporting.html +[4]:https://www.youtube.com/watch?v=66XoCk79kjM +[5]:https://twitter.com/llanga/status/963834977745022976 +[6]:https://www.instagram.com/p/ZVC9CwH7G1/ +[7]:https://www.instagram.com/p/ZXtdtUn7Gk/ +[8]:https://learnpythonthehardway.org/book/nopython3.html +[9]:https://www.youtube.com/watch?v=Oiw23yfqQy8 +[10]:https://mail.python.org/pipermail/python-dev/2018-March/152348.html +[11]:https://pypi.python.org/pypi/Django/2.0.3 +[12]:http://python3statement.org/ +[13]:https://www.youtube.com/watch?v=-Nk-8fSJM6I +[14]:https://eev.ee/blog/2016/11/23/a-rebuttal-for-python-3/ +[15]:https://twitter.com/zedshaw/status/977909970795745281 diff --git a/published/20180326 4 command line note-taking applications for Linux.md b/published/20180326 4 command line note-taking applications for Linux.md new file mode 100644 index 0000000000..7f706a65dc --- /dev/null +++ b/published/20180326 4 command line note-taking applications for Linux.md @@ -0,0 +1,79 @@ +4 个 Linux 下的命令行笔记程序 +=============== + +> 这些工具可以让你在 Linux 命令行下简单而有效地记录笔记和保存信息。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/note-taking.jpeg?itok=fiF5EBEb) + +当你需要保存代码段或 URL、想法或引用时,可能会启动文本编辑器或使用[桌面][1]或[基于 Web 的][2]笔记记录工具。但那些不是你唯一的选择。如果你在终端窗口中工作,则可以使用 Linux 命令行下的许多笔记记录工具之一。 + +我们来看看这四个程序。 + +### tnote + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/tnote.png?itok=M84ABZcr) + +[tnote][3] 使在终端窗口中记笔记很简单 —— 几乎太简单了。 + +tnote 是一个 Python 脚本。首次启动时,它会要求你输入密码和口令来加密存储笔记的 [SQLite 数据库][4]。完成之后,按 `A` 创建一个笔记。输入你的笔记,然后按 `CTRL-D` 保存。 + +一旦你有几个(或多个)笔记,你可以查看它们或搜索特定的笔记,单词或短语或标签。tnote 没有很多功能,但它确实实现了任务。 + +### Terminal Velocity + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/terminal_velocity.png?itok=rkWejQ7_) + +如果你使用过 Mac OS,你可能会看到一个名为 [Notational Velocity][5] 的流行开源笔记程序,这是一种记录笔记的简单有效方法。[Terminal Velocity][6] 在将 Notational Velocity 体验带入命令行方面做得很好。 + +Terminal Velocity 打开你的默认文本编辑器(由你的 `.profile` 或 `.bashrc` 文件中的 `$EDITOR` 变量设置)。输入你的笔记,然后保存。该笔记出现在 Terminal Velocity 窗口的列表中。 + +使用键盘上的箭头键滚动查看你的笔记列表。要查看或编辑笔记,请按回车键。如果你有一长串笔记,则可以在 `Find or Create` 字段中输入笔记标题的前几个字符以缩小列表的范围。在那里滚动笔记并按下回车键将其打开。 + +### pygmynote + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/pygmynote.png?itok=Z8qEC4dq) + +在本文中的四个应用中,[pygmynote][7] 可能是最不用户友好的。然而,它是最灵活的。 + +像 tnote 一样,pygmynote 将你的笔记和附件保存在 SQLite 数据库中。当你启动它时,pygmynote 看起来并不特别有用。在任何时候,输入 `help` 并按下回车键获取命令列表。 + +你可以添加、编辑、查看和搜索笔记,并在笔记中添加[标签][8]。标签使找到笔记更容易,特别是如果你有很多笔记的时候。 + +pygmynote 的灵活性在于它能够将附件添加到笔记中。这些附件可以是任何东西:图像、文本、word、PDF、电子表格或与笔记相关的任何其他内容。 + +### jrnl + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/jrnl.png?itok=Mx7QIgYj) + +[jrnl][9] 是这里的一个奇怪应用。正如你可能从它的名字中猜到的那样,jrnl 意在成为一种日记工具。但这并不意味着你不能记笔记。 jrnl 做得很好。 + +当你第一次启动 jrnl 时,它会询问你想把文件 `journal.txt` (它存储你的笔记)保存的位置以及是否需要密码保护。如果你决定添加密码,那么你在应用内的操作都需要输入密码。 + +你可以通过两种方式输入笔记:直接从命令行或使用计算机的默认编辑器。你可以将标签(例如,`@opensource.com`)添加到笔记中,并指定日期和时间戳。如果你有很多笔记的话,添加标签和日期可以帮助搜索你的笔记(jrnl 有一个相当不错的搜索功能)。 + +由于 jrnl 将你的笔记保存为纯文本文件,因此你可以使用 [ownCloud][10]、[Nextcloud][11] 或任何你喜欢的文件共享/同步服务在设备间同步它。 + +你有没有喜欢的工具或自制的命令行笔记工具?请发表评论,随时与社区分享。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/command-line-note-taking-applications + +作者:[Scott Nesbitt][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/scottnesbitt +[1]:https://opensource.com/life/16/9/4-desktop-note-taking-applications +[2]:https://opensource.com/alternatives/evernote +[3]:https://github.com/tasdikrahman/tnote +[4]:http://en.wikipedia.org/wiki/SQLite +[5]:http://notational.net/ +[6]:https://vhp.github.io/terminal_velocity/ +[7]:https://github.com/dmpop/pygmynote +[8]:https://en.wikipedia.org/wiki/Tag_(metadata) +[9]:http://jrnl.sh/ +[10]:https://owncloud.com/ +[11]:https://nextcloud.com/ diff --git a/published/20180327 Reliable IoT event logging with syslog-ng.md b/published/20180327 Reliable IoT event logging with syslog-ng.md new file mode 100644 index 0000000000..4fd6856d09 --- /dev/null +++ b/published/20180327 Reliable IoT event logging with syslog-ng.md @@ -0,0 +1,88 @@ +使用 syslog-ng 可靠地记录物联网事件 +====== + +> 用增强的日志守护进程 syslog-ng 来监控你的物联网设备。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openwires_fromRHT_520_0612LL.png?itok=PqZi55Ab) + +现在,物联网设备和嵌入式系统越来越多。对于许多连接到因特网或者一个网络的设备来说,记录事件很有必要,因为你需要知道这些设备都做了些什么事情,这样你才能够解决可能出现的问题。 + +可以考虑去使用的一个监视工具是开源的 [syslog-ng][1] 应用程序,它是一个强化的、致力于可移植的、中心化的日志收集守护程序。它可以从许多不同种类的来源、进程来收集日志,并且可以对这些日志进行处理和过滤,也可以存储或者路由它们,以便于做进一步的分析。syslog-ng 的大多数代码是用高效率的、高可移植的 C 代码写成的。它能够适用于各种场景,无论你是将它运行在一个处理能力很弱的设备上做一些简单的事情,还是运行在数据中心从成千上万的机器中收集日志的强大应用,它都能够胜任。 + +你可能注意到在这个段落中,我使用了大量的溢美词汇。为了让你更清晰地了解它,我们来复习一下,但这将花费更多的时间,也了解的更深入一些。 + +### 日志 + +首先解释一下日志。日志logging是记录一台计算机上事件的东西。在一个典型的 Linux 机器上,你可以在 `/var/log` 目录中找到这些信息。例如,如果你通过 SSH 登录到机器中,你将可以在其中一个日志文件中找到类似于如下内容的信息: + +``` +Jan 14 11:38:48 linux-0jbu sshd[7716]: Accepted publickey for root from 127.0.0.1 port 48806 ssh2 +``` + +日志的内容可能是关于你的 CPU 过热、通过 HTTP 下载了一个文档,或者你的应用程序认为重要的任何东西。 + +### syslog-ng + +正如我在上面所写的那样,syslog-ng 应用程序是一个强化的、致力于可移植性、和中心化的日志收集守护程序。守护程序的意思是,syslog-ng 是一个持续运行在后台的应用程序,在这里,它用于收集日志信息。 + +虽然现在大多数应用程序的 Linux 测试是限制在 x86_64 的机器上,但是,syslog-ng 也可以运行在大多数 BSD 和商业 UNIX 变种版本上的。从嵌入式/物联网的角度来看,这种能够运行在不同的 CPU 架构(包括 32 位和 64 位的 ARM、PowerPC、MIPS 等等)的能力甚至更为重要。(有时候,我通过阅读关于 syslog-ng 是如何使用它们的来学习新架构) + +为什么中心化的日志收集如此重要?其中一个很重要的原因是易于使用,因为它放在一个地方,不用到成百上千的机器上挨个去检查它们的日志。另一个原因是可用性 —— 即使一个设备不论是什么原因导致了它不可用,你都可以检查这个设备的日志信息。第三个原因是安全性;当你的设备被黑,检查设备日志可以发现攻击的踪迹。 + +### syslog-ng 的四种用法 + +syslog-ng 有四种主要的用法:收集、处理、过滤、和保存日志信息。 + +**收集信息:** syslog-ng 能够从各种各样的 [特定平台源][2] 上收集信息,比如 `/dev/log`,`journal`,或者 `sun-streams`。作为一个中心化的日志收集器,传统的(`rfc3164`)和最新的(`rfc5424`)系统日志协议、以及它们基于 UDP、TCP 和加密连接的各种变种,它都是支持的。你也可以从管道、套接字、文件、甚至应用程序输出来收集日志信息(或者各种文本数据)。 + +**处理日志信息:** 它的处理能力几乎是无限的。你可以用它内置的解析器来分类、规范,以及结构化日志信息。如果它没有为你提供在你的应用场景中所需要的解析器,你甚至可以用 Python 来自己写一个解析器。你也可以使用地理数据来丰富信息,或者基于信息内容来附加一些字段。日志信息可以按处理它的应用程序所要求的格式进行重新格式化。你也可以重写日志信息 —— 当然了,不是篡改日志内容 —— 比如在某些情况下,需要满足匿名要求的信息。 + +**过滤日志:** 过滤日志的用法主要有两种:丢弃不需要保存的日志信息 —— 像调试级别的信息;和路由日志信息—— 确保正确的日志到达正确的目的地。后一种用法的一个例子是,转发所有的认证相关的信息到一个安全信息与事件管理系统(SIEM)。 + +**保存信息:** 传统的做法是,将文件保存在本地或者发送到中心化日志服务器;不论是哪种方式,它们都被发送到一个[普通文件][3]。经过这些年的改进,syslog-ng 已经开始支持 SQL 数据库,并且在过去的几年里,包括 HDFS、Kafka、MongoDB、和 Elasticsearch 在内的大数据存储,都被加入到 syslog-ng 的支持中。 + +### 消息格式 + +当在你的 `/var/log` 目录中查看消息时,你将看到(如上面的 SSH 信息)大量的消息都是如下格式的内容: + +``` +日期 + 主机名 + 应用名 + 一句几乎完整的英文信息 +``` + +在这里的每个应用程序事件都是用不同的语法描述的,基于这些数据去创建一个报告是个痛苦的任务。 + +解决这种混乱信息的一个方案是使用结构化日志。在这种情况下,事件被表示为键-值对,而不是随意的日志信息。比如,一个 SSH 日志能够按应用程序名字、源 IP 地址、用户名、认证方法等等来描述。 + +你可以从一开始就对你的日志信息按合适的格式进行结构化处理。当处理传统的日志信息时,你可以在 syslog-ng 中使用不同的解析器,转换非结构化(和部分结构化)的信息为键-值对格式。一旦你的日志信息表示为键-值对,那么,报告、报警、以及简单查找信息将变得很容易。 + +### 物联网日志 + +我们从一个棘手的问题开始:哪个版本的 syslog-ng 最流行?在你回答之前,想想如下这些事实:这个项目启动于 20 年以前,Red Hat 企业版 Linux EPEL 已经有了 3.5 版,而当前版本是 3.14。当我在我的演讲中问到这个问题时,观众通常回答是他们用的 Linux 发行版中自带的那个。你们绝对想不到的是,正确答案竟然是 1.6 版最流行,这个版本已经有 15 年的历史的。这什么这个版本是最为流行的,因为它是包含在亚马逊 Kindle 阅读器中的版本,它是电子书阅读器,因为它运行在全球范围内超过 1 亿台的设备上。另外一个在消费类设备上运行 syslog-ng 的例子是 BMW i3 电动汽车。 + +Kindle 使用 syslog-ng 去收集关于用户在这台设备上都做了些什么事情等所有可能的信息。在 BMW 电动汽车上,syslog-ng 所做的事情更复杂,基于内容过滤日志信息,并且在大多数情况下,只记录最重要的日志。 + +使用 syslog-ng 的其它类别设备还有网络和存储。一些比较知名的例子有,Turris Omnia 开源 Linux 路由器和群晖 NAS 设备。在大多数案例中,syslog-ng 是在设备上作为一个日志客户端来运行,但是在有些案例中,它运行为一个有丰富 Web 界面的中心日志服务器。 + +你还可以在一些行业服务中找到 syslog-ng 的身影。它运行在来自美国国家仪器有限公司(NI)的实时 Linux 设备上,执行测量和自动化任务。它也被用于从定制开发的应用程序中收集日志。从命令行就可以做配置,但是一个漂亮的 GUI 可用于浏览日志。 + +最后,还有大量的项目,比如,汽车和飞机,syslog-ng 在它们上面既可以运行为客户端,也可以运行为服务端。在这种使用案例中,syslog-ng 一般用来收集所有的日志和测量数据,然后发送它们到处理这些日志的中心化服务器集群上,然后保存它们到支持大数据的目的地,以备进一步分析。 + +### 对物联网的整体益处 + +在物联网环境中使用 syslog-ng 有几个好处。第一,它的分发性能很高,并且是一个可靠的日志收集器。第二,它的架构也很简单,因此,系统、应用程序日志、以及测量数据可以被一起收集。第三,它使数据易于使用,因为,数据可以被解析和表示为易于使用的格式。最后,通过 syslog-ng 的高效路由和过滤功能,可以显著降低处理程序的负载水平。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/logging-iot-events-syslog-ng + +作者:[Peter Czanik][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/czanik +[1]:https://syslog-ng.com/open-source-log-management +[2]:https://syslog-ng.com/documents/html/syslog-ng-ose-latest-guides/en/syslog-ng-ose-guide-admin/html/sources.html +[3]:https://en.wikipedia.org/wiki/Flat_file_database diff --git a/published/20180328 Getting started with Jupyter Notebooks.md b/published/20180328 Getting started with Jupyter Notebooks.md new file mode 100644 index 0000000000..36e68b222d --- /dev/null +++ b/published/20180328 Getting started with Jupyter Notebooks.md @@ -0,0 +1,93 @@ +Jupyter Notebooks 入门 +===== + +> 通过 Jupyter 使用实时代码、方程式和可视化及文本创建交互式的共享笔记本。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/email_paper_envelope_document.png?itok=uPj_kouJ) + +自从有了纸莎草纸以来,出版人们一直在努力以吸引读者的方式来格式化数据。尤其是在数学、科学、和编程领域,设计良好的图表、插图和方程式可以成为帮助人们理解技术信息的关键。 + +[Jupyter Notebook][1] 通过重新构想我们如何制作教学文本来解决这个问题。Jupyter (我在 2017 年 10 月在 [All Things Open][2] 上首次了解到)是一款开源应用程序,它使用户能够创建包含实时代码、方程式、可视化和文本的交互式共享笔记本。 + +Jupyter 从 [IPython 项目][3]发展而来,它是个具有交互式 shell 和基于浏览器的笔记本,支持代码、文本和数学表达式。Jupyter 支持超过 40 种编程语言,包括 Python、R 和 Julia,其代码可以导出为 HTML、LaTeX、PDF、图像和视频,或者作为 [IPyhton][4] 笔记本与其他用户共享。 + +> 一个有趣的事实是:“Jupyter” 是 “Julia、Python 和 R” 的缩写。 + +根据 Jupyter 项目网站介绍,它的一些用途包括“数据清理和转换,数值模拟,统计建模,数据可视化,机器学习等等”。科学机构正在使用 Jupyter Notebooks 来解释研究结果。代码可以来自实际数据,可以调整和重新调整以可视化成不同的结果和情景。通过这种方式,Jupyter Notebooks 变成了生动的文本和报告。 + +### 安装并开始 Jupyter + +Jupyter 软件是开源的,其授权于[修改过的 BSD 许可证][5],它可以[安装在 Linux、MacOS 或 Windows 上][6]。有很多种方法可以安装 Jupyter;我在 Linux 和 MacOS 上试过 PIP 和 [Anaconda][7] 安装方式。PIP 安装要求你的计算机上已经安装了 Python;Jupyter 推荐 Python 3。 + +由于 Python 3 已经安装在我的电脑上,我通过在终端(在 Linux 或 Mac 上)运行以下命令来安装 Jupyter: + +``` +$ python3 -m pip install --upgrade pip +$ python3 -m pip install jupyter +``` + +在终端提示符输入以下命令立即启动应用程序: + +``` +$ jupyter notebook +``` + +很快,我的浏览器打开并显示了我在 `http://localhost:8888` 的 Jupyter Notebook 服务器。(支持的浏览器有 Google Chrome、Firefox 和 Safari) + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_1.png?itok=UyM1GuVG) + +在右上角有一个标有 “New” 的下拉菜单,它使我能够根据自己的指示和代码快速创建新的笔记本。请注意,我的新笔记本默认为 Python 3,这是我目前的环境。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_2.png?itok=alDI432q) + +一个带有一些默认值的新笔记本,它可以被改变(包括笔记本的名字),已打开。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_3.png?itok=9zjG-5JC) + +笔记本有两种不同的模式:“命令模式”和“编辑模式”。命令模式允许你添加或删除单元格。你可以通过按下 `Escape` 键进入命令模式,按 `Enter` 键或单击单元格进入编辑模式。 + +单元格周围的绿色高亮显示你处于编辑模式,蓝色高亮显示你处于命令模式。以下笔记本处于命令模式并准备好执行单元中的 Python 代码。注意,我已将笔记本的名称更改为 “First Notebook”。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_4.png?itok=-QPxcuFX) + +### 使用 Jupyter + +Jupyter Notebooks 的强大之处在于除了能够输入代码之外,你还可以用 Markdown 添加叙述性和解释性文本。我想添加一个标题,所以我在代码上面添加了一个单元格,并以 Markdown 输入了一个标题。当我按下 `Ctrl+Enter` 时,我的标题转换为 HTML。(LCTT 译注:或者可以按下 Run 按钮。) + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_5.png?itok=-sr9A8-W) + +我可以通过在命令前追加 `!` 来添加 Bash 命令或脚本的输出。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_6.png?itok=o_g38ECp) + +我也可以利用 IPython 的 [line magic 和 cell magic][8] 命令。你可以通过在代码单元内附加 `%` 或 `%%` 符号来列出魔术命令。例如,`%lsmagic` 将输出所有可用于 Jupyter notebooks 的魔法命令。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/jupyter_7.png?itok=uit0PtND) + +这些魔术命令的例子包括 `%pwd`——它输出当前工作目录(例如 `/Users/YourName`)和 `%ls`——它列出当前工作目录中的所有文件和子目录。另一个神奇命令显示从笔记本中的 `matplotlib` 生成的图表。`%%html` 将该单元格中的任何内容呈现为 HTML,这对嵌入视频和链接很有用,还有 JavaScript 和 Bash 的单元魔术命令。 + +如果你需要更多关于使用 Jupyter Notebooks 和它的特性的信息,它的帮助部分是非常完整的。 + +人们用许多有趣的方式使用 Jupyter Notebooks;你可以在这个[展示栏目][9]里找到一些很好的例子。你如何使用 Jupyter 笔记本?请在下面的评论中分享你的想法。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/getting-started-jupyter-notebooks + +作者:[Don Watkins][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/don-watkins +[1]:http://jupyter.org/ +[2]:https://allthingsopen.org/ +[3]:http://ipython.org/ +[4]:https://en.wikipedia.org/wiki/IPython +[5]:https://opensource.org/licenses/BSD-3-Clause +[6]:http://jupyter.org/install.html +[7]:https://www.anaconda.com/download/#linux +[8]:http://ipython.readthedocs.io/en/stable/interactive/magics.html +[9]:https://github.com/jupyter/jupyter/wiki/a-gallery-of-interesting-jupyter-notebooks#mathematics diff --git a/published/20180328 How To Use Instagram In Terminal.md b/published/20180328 How To Use Instagram In Terminal.md new file mode 100644 index 0000000000..cd1276a4ce --- /dev/null +++ b/published/20180328 How To Use Instagram In Terminal.md @@ -0,0 +1,68 @@ +如何在终端中使用 Instagram +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/instagram-in-terminal-720x340.png) + +Instagram 不需要介绍。它是像 Facebook 和 Twitter 之类的流行社交网络平台之一,它可以公开或私下分享照片和视频给确认过的粉丝。它是由两位企业家 **Kevin Systrom** 和 **Mike Krieger**于 2010 年发起的。2012 年,社交网络巨头 Facebook 收购了 Instagram。Android 和 iOS 设备上可以免费下载 Instagram。我们也可以通过网络浏览器在桌面系统中使用它。而且,最酷的是现在你可以在任何类 Unix 操作系统上的终端中使用 Instagram。你兴奋了吗?那么,请阅读以下内容了解如何在终端上查看你的 Instagram feed。 + +### 终端中的 Instagram + +首先,按照以下链接中的说明安装 `pip3`。 + +然后,git clone 它的脚本仓库。 + +``` +$ git clone https://github.com/billcccheng/instagram-terminal-news-feed.git +``` + +以上命令会将 instagram 脚本的内容克隆到当前工作目录中名为 `instagram-terminal-news-feed` 的目录中。cd 到该目录: + +``` +$ cd instagram-terminal-news-feed/ +``` + +然后,运行以下命令安装它: + +``` +$ pip3 install -r requirements.txt +``` + +现在,运行以下命令在 Linux 终端中启动 instagram。 + +``` +$ python3 start.py +``` + +输入你的 Instagram 用户名和密码,并直接从终端中浏览你的 Instagram feed。你的 instragram 用户名和密码将仅本地存储在名为 `credential.json` 的文件中。所以,你不必担心它。你也可以选择不保存默认保存的凭证。 + +下面是[我的 Instagram 页面][1]的一些截图。 + +![][3] + +![][4] + +![][5] + +请注意,你只能查看你的 feed。你不能关注任何人,喜欢或评论帖子。这只是一个 instagram feed 阅读器。 + +该项目可在 GitHub 上免费获得,因此你可以查看源代码,改进它,添加更多功能,修复任何 bug。 + +玩得开心!干杯!! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-use-instagram-in-terminal/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.instagram.com/ostechnix/ +[3]:http://www.ostechnix.com/wp-content/uploads/2018/03/instagram-in-terminal-1.png +[4]:http://www.ostechnix.com/wp-content/uploads/2018/03/instagram-in-terminal-2.png +[5]:http://www.ostechnix.com/wp-content/uploads/2018/03/instagram-in-terminal-3-2.png diff --git a/published/201804/20090211 Page Cache the Affair Between Memory and Files.md b/published/201804/20090211 Page Cache the Affair Between Memory and Files.md new file mode 100644 index 0000000000..726ea23041 --- /dev/null +++ b/published/201804/20090211 Page Cache the Affair Between Memory and Files.md @@ -0,0 +1,86 @@ +页面缓存、内存和文件之间的那些事 +============================================================ + + +上一篇文章中我们学习了内核怎么为一个用户进程 [管理虚拟内存][2],而没有提及文件和 I/O。这一篇文章我们将专门去讲这个重要的主题 —— 页面缓存。文件和内存之间的关系常常很不好去理解,而它们对系统性能的影响却是非常大的。 + +在面对文件时,有两个很重要的问题需要操作系统去解决。第一个是相对内存而言,慢的让人发狂的硬盘驱动器,[尤其是磁盘寻道][3]。第二个是需要将文件内容一次性地加载到物理内存中,以便程序间*共享*文件内容。如果你在 Windows 中使用 [进程浏览器][4] 去查看它的进程,你将会看到每个进程中加载了大约 ~15MB 的公共 DLL。我的 Windows 机器上现在大约运行着 100 个进程,因此,如果不共享的话,仅这些公共的 DLL 就要使用高达 ~1.5 GB 的物理内存。如果是那样的话,那就太糟糕了。同样的,几乎所有的 Linux 进程都需要 ld.so 和 libc,加上其它的公共库,它们占用的内存数量也不是一个小数目。 + +幸运的是,这两个问题都用一个办法解决了:页面缓存 —— 保存在内存中的页面大小的文件块。为了用图去说明页面缓存,我捏造出一个名为 `render` 的 Linux 程序,它打开了文件 `scene.dat`,并且一次读取 512 字节,并将文件内容存储到一个分配到堆中的块上。第一次读取的过程如下: + +![Reading and the page cache](http://static.duartes.org/img/blogPosts/readFromPageCache.png) + +1. `render` 请求 `scene.dat` 从位移 0 开始的 512 字节。 +2. 内核搜寻页面缓存中 `scene.dat` 的 4kb 块,以满足该请求。假设该数据没有缓存。 +3. 内核分配页面帧,初始化 I/O 请求,将 `scend.dat` 从位移 0 开始的 4kb 复制到分配的页面帧。 +4. 内核从页面缓存复制请求的 512 字节到用户缓冲区,系统调用 `read()` 结束。 + +读取完 12KB 的文件内容以后,`render` 程序的堆和相关的页面帧如下图所示: + +![Non-mapped file read](http://static.duartes.org/img/blogPosts/nonMappedFileRead.png) + +它看起来很简单,其实这一过程做了很多的事情。首先,虽然这个程序使用了普通的读取(`read`)调用,但是,已经有三个 4KB 的页面帧将文件 scene.dat 的一部分内容保存在了页面缓存中。虽然有时让人觉得很惊奇,但是,**普通的文件 I/O 就是这样通过页面缓存来进行的**。在 x86 架构的 Linux 中,内核将文件认为是一系列的 4KB 大小的块。如果你从文件中读取单个字节,包含这个字节的整个 4KB 块将被从磁盘中读入到页面缓存中。这是可以理解的,因为磁盘通常是持续吞吐的,并且程序一般也不会从磁盘区域仅仅读取几个字节。页面缓存知道文件中的每个 4KB 块的位置,在上图中用 `#0`、`#1` 等等来描述。Windows 使用 256KB 大小的视图view,类似于 Linux 的页面缓存中的页面page。 + +不幸的是,在一个普通的文件读取中,内核必须拷贝页面缓存中的内容到用户缓冲区中,它不仅花费 CPU 时间和影响 [CPU 缓存][6],**在复制数据时也浪费物理内存**。如前面的图示,`scene.dat` 的内存被存储了两次,并且,程序中的每个实例都用另外的时间去存储内容。我们虽然解决了从磁盘中读取文件缓慢的问题,但是在其它的方面带来了更痛苦的问题。内存映射文件是解决这种痛苦的一个方法: + +![Mapped file read](http://static.duartes.org/img/blogPosts/mappedFileRead.png) + +当你使用文件映射时,内核直接在页面缓存上映射你的程序的虚拟页面。这样可以显著提升性能:[Windows 系统编程][7] 报告指出,在相关的普通文件读取上运行时性能提升多达 30% ,在 [Unix 环境中的高级编程][8] 的报告中,文件映射在 Linux 和 Solaris 也有类似的效果。这取决于你的应用程序类型的不同,通过使用文件映射,可以节约大量的物理内存。 + +对高性能的追求是永恒不变的目标,[测量是很重要的事情][9],内存映射应该是程序员始终要使用的工具。这个 API 提供了非常好用的实现方式,它允许你在内存中按字节去访问一个文件,而不需要为了这种好处而牺牲代码可读性。在一个类 Unix 的系统中,可以使用 [mmap][11] 查看你的 [地址空间][10],在 Windows 中,可以使用 [CreateFileMapping][12],或者在高级编程语言中还有更多的可用封装。当你映射一个文件内容时,它并不是一次性将全部内容都映射到内存中,而是通过 [页面故障][13] 来按需映射的。在 [获取][15] 需要的文件内容的页面帧后,页面故障句柄 [映射你的虚拟页面][14] 到页面缓存上。如果一开始文件内容没有缓存,这还将涉及到磁盘 I/O。 + +现在出现一个突发的状况,假设我们的 `render` 程序的最后一个实例退出了。在页面缓存中保存着 `scene.dat` 内容的页面要立刻释放掉吗?人们通常会如此考虑,但是,那样做并不是个好主意。你应该想到,我们经常在一个程序中创建一个文件,退出程序,然后,在第二个程序去使用这个文件。页面缓存正好可以处理这种情况。如果考虑更多的情况,内核为什么要清除页面缓存的内容?请记住,磁盘读取的速度要慢于内存 5 个数量级,因此,命中一个页面缓存是一件有非常大收益的事情。因此,只要有足够大的物理内存,缓存就应该保持全满。并且,这一原则适用于所有的进程。如果你现在运行 `render` 一周后, `scene.dat` 的内容还在缓存中,那么应该恭喜你!这就是什么内核缓存越来越大,直至达到最大限制的原因。它并不是因为操作系统设计的太“垃圾”而浪费你的内存,其实这是一个非常好的行为,因为,释放物理内存才是一种“浪费”。(LCTT 译注:释放物理内存会导致页面缓存被清除,下次运行程序需要的相关数据,需要再次从磁盘上进行读取,会“浪费” CPU 和 I/O 资源)最好的做法是尽可能多的使用缓存。 + +由于页面缓存架构的原因,当程序调用 [write()][16] 时,字节只是被简单地拷贝到页面缓存中,并将这个页面标记为“脏”页面。磁盘 I/O 通常并**不会**立即发生,因此,你的程序并不会被阻塞在等待磁盘写入上。副作用是,如果这时候发生了电脑死机,你的写入将不会完成,因此,对于至关重要的文件,像数据库事务日志,要求必须进行 [fsync()][17](仍然还需要去担心磁盘控制器的缓存失败问题),另一方面,读取将被你的程序阻塞,直到数据可用为止。内核采取预加载的方式来缓解这个矛盾,它一般提前预读取几个页面并将它加载到页面缓存中,以备你后来的读取。在你计划进行一个顺序或者随机读取时(请查看 [madvise()][18]、[readahead()][19]、[Windows 缓存提示][20] ),你可以通过提示hint帮助内核去调整这个预加载行为。Linux 会对内存映射的文件进行 [预读取][21],但是我不确定 Windows 的行为。当然,在 Linux 中它可能会使用 [O_DIRECT][22] 跳过预读取,或者,在 Windows 中使用 [NO_BUFFERING][23] 去跳过预读,一些数据库软件就经常这么做。 + +一个文件映射可以是私有的,也可以是共享的。当然,这只是针对内存中内容的**更新**而言:在一个私有的内存映射上,更新并不会提交到磁盘或者被其它进程可见,然而,共享的内存映射,则正好相反,它的任何更新都会提交到磁盘上,并且对其它的进程可见。内核使用写时复制copy on write(CoW)机制,这是通过页面表条目page table entry(PTE)来实现这种私有的映射。在下面的例子中,`render` 和另一个被称为 `render3d` 的程序都私有映射到 `scene.dat` 上。然后 `render` 去写入映射的文件的虚拟内存区域: + +![The Copy-On-Write mechanism](http://static.duartes.org/img/blogPosts/copyOnWrite.png) + +1. 两个程序私有地映射 `scene.dat`,内核误导它们并将它们映射到页面缓存,但是使该页面表条目只读。 +2. `render` 试图写入到映射 `scene.dat` 的虚拟页面,处理器发生页面故障。 +3. 内核分配页面帧,复制 `scene.dat` 的第二块内容到其中,并映射故障的页面到新的页面帧。 +4. 继续执行。程序就当做什么都没发生。 + +上面展示的只读页面表条目并不意味着映射是只读的,它只是内核的一个用于共享物理内存的技巧,直到尽可能的最后一刻之前。你可以认为“私有”一词用的有点不太恰当,你只需要记住,这个“私有”仅用于更新的情况。这种设计的重要性在于,要想看到被映射的文件的变化,其它程序只能读取它的虚拟页面。一旦“写时复制”发生,从其它地方是看不到这种变化的。但是,内核并不能保证这种行为,因为它是在 x86 中实现的,从 API 的角度来看,这是有意义的。相比之下,一个共享的映射只是将它简单地映射到页面缓存上。更新会被所有的进程看到并被写入到磁盘上。最终,如果上面的映射是只读的,页面故障将触发一个内存段失败而不是写到一个副本。 + +动态加载库是通过文件映射融入到你的程序的地址空间中的。这没有什么可奇怪的,它通过普通的 API 为你提供与私有文件映射相同的效果。下面的示例展示了映射文件的 `render` 程序的两个实例运行的地址空间的一部分,以及物理内存,尝试将我们看到的许多概念综合到一起。 + +![Mapping virtual memory to physical memory](http://static.duartes.org/img/blogPosts/virtualToPhysicalMapping.png) + +这是内存架构系列的第三部分的结论。我希望这个系列文章对你有帮助,对理解操作系统的这些主题提供一个很好的思维模型。 + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ + +作者:[Gustavo Duarte][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://duartes.org/gustavo/blog/about/ +[1]:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ +[2]:https://linux.cn/article-9393-1.html +[3]:https://manybutfinite.com/post/what-your-computer-does-while-you-wait +[4]:http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx +[5]:http://ld.so +[6]:https://manybutfinite.com/post/intel-cpu-caches +[7]:http://www.amazon.com/Windows-Programming-Addison-Wesley-Microsoft-Technology/dp/0321256190/ +[8]:http://www.amazon.com/Programming-Environment-Addison-Wesley-Professional-Computing/dp/0321525949/ +[9]:https://manybutfinite.com/post/performance-is-a-science +[10]:https://manybutfinite.com/post/anatomy-of-a-program-in-memory +[11]:http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html +[12]:http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx +[13]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2678 +[14]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2436 +[15]:http://lxr.linux.no/linux+v2.6.28/mm/filemap.c#L1424 +[16]:http://www.kernel.org/doc/man-pages/online/pages/man2/write.2.html +[17]:http://www.kernel.org/doc/man-pages/online/pages/man2/fsync.2.html +[18]:http://www.kernel.org/doc/man-pages/online/pages/man2/madvise.2.html +[19]:http://www.kernel.org/doc/man-pages/online/pages/man2/readahead.2.html +[20]:http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx#caching_behavior +[21]:http://lxr.linux.no/linux+v2.6.28/mm/filemap.c#L1424 +[22]:http://www.kernel.org/doc/man-pages/online/pages/man2/open.2.html +[23]:http://msdn.microsoft.com/en-us/library/cc644950(VS.85).aspx \ No newline at end of file diff --git a/published/201804/20100419 10 Tools To Add Some Spice To Your UNIX-Linux Shell Scripts.md b/published/201804/20100419 10 Tools To Add Some Spice To Your UNIX-Linux Shell Scripts.md new file mode 100644 index 0000000000..022f9229bd --- /dev/null +++ b/published/201804/20100419 10 Tools To Add Some Spice To Your UNIX-Linux Shell Scripts.md @@ -0,0 +1,408 @@ +10 个增加 UNIX/Linux Shell 脚本趣味的工具 +====== + +有些误解认为 shell 脚本仅用于 CLI 环境。实际上在 KDE 或 Gnome 桌面下,你可以有效的使用各种工具编写 GUI 或者网络(socket)脚本。shell 脚本可以使用一些 GUI 组件(菜单、警告框、进度条等),你可以控制终端输出、光标位置以及各种输出效果等等。利用下面的工具,你可以构建强壮的、可交互的、对用户友好的 UNIX/Linux bash 脚本。 + +制作 GUI 应用不是一项困难的任务,但需要时间和耐心。幸运的是,UNIX 和 Linux 都带有大量编写漂亮 GUI 脚本的工具。以下工具是基于 FreeBSD 和 Linux 操作系统做的测试,而且也适用于其他类 UNIX 操作系统。 + +### 1、notify-send 命令 + +`notify-send` 命令允许你借助通知守护进程发送桌面通知给用户。这种避免打扰用户的方式,对于通知桌面用户一个事件或显示一些信息是有用的。在 Debian 或 Ubuntu 上,你需要使用 [apt 命令][1] 或 [apt-get 命令][2] 安装的包: + +```bash +sudo apt-get install libnotify-bin +``` + +CentOS/RHEL 用户使用下面的 [yum 命令][3]: + +```bash +sudo yum install libnotify +``` + +Fedora Linux 用户使用下面的 dnf 命令: + +```bash +`$ sudo dnf install libnotify` +In this example, send simple desktop notification from the command line, enter: +### 发送一些通知 ### +notify-send "rsnapshot done :)" +``` + +示例输出: + +![Fig:01: notify-send in action ][4] + +下面是另一个附加选项的代码: + +```bash +... +alert=18000 +live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g') +[ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i "BSE Sensex touched 18k"; notify_counter=1; } +... +``` + +示例输出: + +![Fig.02: notify-send with timeouts and other options][5] + +这里: + + * `-t 5000`:指定超时时间(毫秒) (5000 毫秒 = 5 秒) + * `-u low`: 设置紧急等级 (如:低、普通、紧急) + * `-i gtk-dialog-info`: 设置要显示的图标名称或者指定的图标(你可以设置路径为:`-i /path/to/your-icon.png`) + +关于更多使用 `notify-send` 功能的信息,请参考 man 手册。在命令行下输入 `man notify-send` 即可看见: + +```bash +man notify-send +``` + +### 2、tput 命令 + +`tput` 命令用于设置终端特性。通过 `tput` 你可以设置: + + * 在屏幕上移动光标。 + * 获取终端信息。 + * 设置颜色(背景和前景)。 + * 设置加粗模式。 + * 设置反转模式等等。 + +下面有一段示例代码: + +```bash +#!/bin/bash + +# clear the screen +tput clear + +# Move cursor to screen location X,Y (top left is 0,0) +tput cup 3 15 + +# Set a foreground colour using ANSI escape +tput setaf 3 +echo "XYX Corp LTD." +tput sgr0 + +tput cup 5 17 +# Set reverse video mode +tput rev +echo "M A I N - M E N U" +tput sgr0 + +tput cup 7 15 +echo "1. User Management" + +tput cup 8 15 +echo "2. Service Management" + +tput cup 9 15 +echo "3. Process Management" + +tput cup 10 15 +echo "4. Backup" + +# Set bold mode +tput bold +tput cup 12 15 +read -p "Enter your choice [1-4] " choice + +tput clear +tput sgr0 +tput rc +``` + +示例输出: + +![Fig.03: tput in action][6] + +关于 `tput` 命令的详细信息,参见手册: + +```bash +man 5 terminfo +man tput +``` + +### 3、setleds 命令 + +`setleds` 命令允许你设置键盘灯。下面是打开数字键灯的示例: + +```bash +setleds -D +num +``` + +关闭数字键灯,输入: + +```bash +setleds -D -num +``` + + * `-caps`:关闭大小写锁定灯 + * `+caps`:打开大小写锁定灯 + * `-scroll`:关闭滚动锁定灯 + * `+scroll`:打开滚动锁定灯 + +查看 `setleds` 手册可看见更多信息和选项 `man setleds`。 + +### 4、zenity 命令 + +[zenity 命令显示 GTK+ 对话框][7],并且返回用户输入。它允许你使用各种 Shell 脚本向用户展示或请求信息。下面是一个 `whois` 指定域名目录服务的 GUI 客户端示例。 + +```bash +#!/bin/bash +# Get domain name +_zenity="/usr/bin/zenity" +_out="/tmp/whois.output.$$" +domain=$(${_zenity} --title "Enter domain" \ + --entry --text "Enter the domain you would like to see whois info" ) + +if [ $? -eq 0 ] +then + # Display a progress dialog while searching whois database + whois $domain | tee >(${_zenity} --width=200 --height=100 \ + --title="whois" --progress \ + --pulsate --text="Searching domain info..." \ + --auto-kill --auto-close \ + --percentage=10) >${_out} + + # Display back output + ${_zenity} --width=800 --height=600 \ + --title "Whois info for $domain" \ + --text-info --filename="${_out}" +else + ${_zenity} --error \ + --text="No input provided" +fi +``` + +示例输出: + +![Fig.04: zenity in Action][8] + +参见手册获取更多 `zenity` 信息以及其他支持 GTK+ 的组件: + +```bash +zenity --help +man zenity +``` + +### 5、kdialog 命令 + +`kdialog` 命令与 `zenity` 类似,但它是为 KDE 桌面和 QT 应用设计。你可以使用 `kdialog` 展示对话框。下面示例将在屏幕上显示信息: + +```bash +kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found." +``` + +示例输出: + +![Fig.05: Suppressing the display of a dialog ][9] + +参见 《[KDE 对话框 Shell 脚本编程][10]》 教程获取更多信息。 + +### 6、Dialog + +[Dialog 是一个使用 Shell 脚本的应用][11],显示用户界面组件的文本。它使用 curses 或者 ncurses 库。下面是一个示例代码: + +```bash +#!/bin/bash +dialog --title "Delete file" \ +--backtitle "Linux Shell Script Tutorial Example" \ +--yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60 + +# Get exit status +# 0 means user hit [yes] button. +# 1 means user hit [no] button. +# 255 means user hit [Esc] key. +response=$? +case $response in + 0) echo "File deleted.";; + 1) echo "File not deleted.";; + 255) echo "[ESC] key pressed.";; +esac +``` + +参见 `dialog` 手册获取详细信息:`man dialog`。 + +#### 关于其他用户界面工具的注意事项 + +UNIX、Linux 提供了大量其他工具来显示和控制命令行中的应用程序,shell 脚本可以使用一些 KDE、Gnome、X 组件集: + + * `gmessage` - 基于 GTK xmessage 的克隆 + * `xmessage` - 在窗口中显示或询问消息(基于 X 的 /bin/echo) + * `whiptail` - 显示来自 shell 脚本的对话框 + * `python-dialog` - 用于制作简单文本或控制台模式用户界面的 Python 模块 + +### 7、logger 命令 + +`logger` 命令将信息写到系统日志文件,如:`/var/log/messages`。它为系统日志模块 syslog 提供了一个 shell 命令行接口: + +```bash +logger "MySQL database backup failed." +tail -f /var/log/messages +logger -t mysqld -p daemon.error "Database Server failed" +tail -f /var/log/syslog +``` + +示例输出: + +```bash +Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal +Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed +``` + +参见 《[如何写消息到 syslog 或 日志文件][12]》 获得更多信息。此外,你也可以查看 logger 手册获取详细信息:`man logger` + +### 8、setterm 命令 + +`setterm` 命令可设置不同的终端属性。下面的示例代码会强制屏幕在 15 分钟后变黑,监视器则 60 分钟后待机。 + +```bash +setterm -blank 15 -powersave powerdown -powerdown 60 +``` + +下面的例子将 xterm 窗口中的文本以下划线展示: + +```bash +setterm -underline on; +echo "Add Your Important Message Here" +setterm -underline off +``` + +另一个有用的选项是打开或关闭光标显示: + +```bash +setterm -cursor off +``` + +打开光标: + +```bash +setterm -cursor on +``` + +参见 setterm 命令手册获取详细信息:`man setterm` + +### 9、smbclient:给 MS-Windows 工作站发送消息 + +`smbclient` 命令可以与 SMB/CIFS 服务器通讯。它可以向 MS-Windows 系统上选定或全部用户发送消息。 + +```bash +smbclient -M WinXPPro </dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close" +``` + +下面的代码片段,你可以利用 [bash 循环找出已打开的端口][14]: + +```bash +echo "Scanning TCP ports..." +for p in {1..1023} +do + (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open" +done +``` + +示例输出: + +```bash +Scanning TCP ports... +22 open +53 open +80 open +139 open +445 open +631 open +``` + +下面的示例中,你的 bash 脚本将像 HTTP 客户端一样工作: + +```bash +#!/bin/bash +exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80 + +printf "GET / HTTP/1.0\r\n" >&3 +printf "Accept: text/html, text/plain\r\n" >&3 +printf "Accept-Language: en\r\n" >&3 +printf "User-Agent: nixCraft_BashScript v.%s\r\n" "${BASH_VERSION}" >&3 +printf "\r\n" >&3 + +while read LINE <&3 +do + # do something on $LINE + # or send $LINE to grep or awk for grabbing data + # or simply display back data with echo command + echo $LINE +done +``` + +参见 bash 手册获取更多信息:`man bash` + +### 关于 GUI 工具和 cron 任务的注意事项 + +如果你 [使用 crontab][15] 来启动你的脚本,你需要使用 `export DISPLAY=[用户机器]:0` 命令请求本地显示或输出服务。举个例子,使用 `zenity` 工具调用 `/home/vivek/scripts/monitor.stock.sh`: + +``` +@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh +``` + +你有喜欢的可以增加 shell 脚本趣味的 UNIX 工具么?请在下面的评论区分享它吧。 + +### 关于作者 + +本文作者是 nixCraft 创始人、一个老练的系统管理员、Linux 操作系统和 UNIX shell 编程培训师。他服务来自全球的客户和不同的行业,包括 IT 、教育、防务和空间探索、还有非营利组织。你可以在 [Twitter][16],[Facebook][17],[Google+][18] 上面关注他。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/spice-up-your-unix-linux-shell-scripts.html + +作者:[Vivek Gite][a] +译者:[pygmalion666](https://github.com/pygmalion666) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) +[2]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[3]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info) +[4]:https://www.cyberciti.biz/media/new/tips/2010/04/notify-send.png (notify-send: Shell Script Get Or Send Desktop Notifications ) +[5]:https://www.cyberciti.biz/media/new/tips/2010/04/notify-send-with-icons-timeout.png (Linux / UNIX: Display Notifications From Your Shell Scripts With notify-send) +[6]:https://www.cyberciti.biz/media/new/tips/2010/04/tput-options.png (Linux / UNIX Script Colours and Cursor Movement With tput) +[7]:https://bash.cyberciti.biz/guide/Zenity:_Shell_Scripting_with_Gnome +[8]:https://www.cyberciti.biz/media/new/tips/2010/04/zenity-outputs.png (zenity: Linux / UNIX display Dialogs Boxes From The Shell Scripts) +[9]:https://www.cyberciti.biz/media/new/tips/2010/04/KDialog.png (Kdialog: Suppressing the display of a dialog ) +[10]:http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs +[11]:https://bash.cyberciti.biz/guide/Bash_display_dialog_boxes +[12]:https://www.cyberciti.biz/tips/howto-linux-unix-write-to-syslog.html +[13]:https://www.cyberciti.biz/tips/freebsd-sending-a-message-to-windows-workstation.html +[14]:https://www.cyberciti.biz/faq/bash-for-loop/ +[15]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ +[16]:https://twitter.com/nixcraft +[17]:https://facebook.com/nixcraft +[18]:https://plus.google.com/+CybercitiBiz \ No newline at end of file diff --git a/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md b/published/201804/20150703 Let-s Build A Simple Interpreter. Part 2..md similarity index 68% rename from translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md rename to published/201804/20150703 Let-s Build A Simple Interpreter. Part 2..md index a22a94bae0..e9591cddd1 100644 --- a/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md +++ b/published/201804/20150703 Let-s Build A Simple Interpreter. Part 2..md @@ -1,9 +1,9 @@ -让我们做个简单的解释器(2) +让我们做个简单的解释器(二) ====== -在一本叫做 《高效思考的 5 要素》 的书中,作者 Burger 和 Starbird 讲述了一个关于他们如何研究 Tony Plog 的故事,一个举世闻名的交响曲名家,为一些有才华的演奏者开创了一个大师班。这些学生一开始演奏复杂的乐曲,他们演奏的非常好。然后他们被要求演奏非常基础简单的乐曲。当他们演奏这些乐曲时,与之前所演奏的相比,听起来非常幼稚。在他们结束演奏后,老师也演奏了同样的乐曲,但是听上去非常娴熟。差别令人震惊。Tony 解释道,精通简单符号可以让人更好的掌握复杂的部分。这个例子很清晰 - 要成为真正的名家,必须要掌握简单基础的思想。 +在一本叫做 《高效思考的 5 要素》 的书中,作者 Burger 和 Starbird 讲述了一个关于他们如何研究 Tony Plog 的故事,他是一位举世闻名的交响曲名家,为一些有才华的演奏者开创了一个大师班。这些学生一开始演奏复杂的乐曲,他们演奏的非常好。然后他们被要求演奏非常基础简单的乐曲。当他们演奏这些乐曲时,与之前所演奏的相比,听起来非常幼稚。在他们结束演奏后,老师也演奏了同样的乐曲,但是听上去非常娴熟。差别令人震惊。Tony 解释道,精通简单音符可以让人更好的掌握复杂的部分。这个例子很清晰 —— 要成为真正的名家,必须要掌握简单基础的思想。 -故事中的例子明显不仅仅适用于音乐,而且适用于软件开发。这个故事告诉我们不要忽视繁琐工作中简单基础的概念的重要性,哪怕有时候这让人感觉是一种倒退。尽管熟练掌握一门工具或者框架非常重要,了解他们背后的原理也是极其重要的。正如 Palph Waldo Emerson 所说: +故事中的例子明显不仅仅适用于音乐,而且适用于软件开发。这个故事告诉我们不要忽视繁琐工作中简单基础的概念的重要性,哪怕有时候这让人感觉是一种倒退。尽管熟练掌握一门工具或者框架非常重要,了解它们背后的原理也是极其重要的。正如 Palph Waldo Emerson 所说: > “如果你只学习方法,你就会被方法束缚。但如果你知道原理,就可以发明自己的方法。” @@ -15,11 +15,11 @@ 2. 识别输入字符串中的多位整数 3. 做两个整数之间的减法(目前它仅能加减整数) - 新版本计算器的源代码在这里,它可以做到上述的所有事情: + ``` # 标记类型 -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' @@ -168,9 +168,10 @@ if __name__ == '__main__': main() ``` -把上面的代码保存到 calc2.py 文件中,或者直接从 [GitHub][2] 上下载。试着运行它。看看它是不是正常工作:它应该能够处理输入中任意位置的空白符;能够接受多位的整数,并且能够对两个整数做减法和加法。 +把上面的代码保存到 `calc2.py` 文件中,或者直接从 [GitHub][2] 上下载。试着运行它。看看它是不是正常工作:它应该能够处理输入中任意位置的空白符;能够接受多位的整数,并且能够对两个整数做减法和加法。 这是我在自己的笔记本上运行的示例: + ``` $ python calc2.py calc> 27 + 3 @@ -182,21 +183,21 @@ calc> 与 [第一部分][1] 的版本相比,主要的代码改动有: - 1. get_next_token 方法重写了很多。增加指针位置的逻辑之前是放在一个单独的方法中。 - 2. 增加了一些方法:skip_whitespace 用于忽略空白字符,integer 用于处理输入字符的多位整数。 - 3. expr 方法修改成了可以识别 “整数 -> 减号 -> 整数” 词组和 “整数 -> 加号 -> 整数” 词组。在成功识别相应的词组后,这个方法现在可以解释加法和减法。 + 1. `get_next_token` 方法重写了很多。增加指针位置的逻辑之前是放在一个单独的方法中。 + 2. 增加了一些方法:`skip_whitespace` 用于忽略空白字符,`integer` 用于处理输入字符的多位整数。 + 3. `expr` 方法修改成了可以识别 “整数 -> 减号 -> 整数” 词组和 “整数 -> 加号 -> 整数” 词组。在成功识别相应的词组后,这个方法现在可以解释加法和减法。 -[第一部分][1] 中你学到了两个重要的概念,叫做 **标记** 和 **词法分析**。现在我想谈一谈 **词法**, **解析**,和**解析器**。 +[第一部分][1] 中你学到了两个重要的概念,叫做 标记token词法分析lexical analyzer。现在我想谈一谈词法lexeme解析parsing解析器parser。 -你已经知道标记。但是为了让我详细的讨论标记,我需要谈一谈词法。词法是什么?**词法** 是一个标记中的字符序列。在下图中你可以看到一些关于标记的例子,还好这可以让它们之间的关系变得清晰: +你已经知道了标记。但是为了让我详细的讨论标记,我需要谈一谈词法。词法是什么?词法lexeme是一个标记token中的字符序列。在下图中你可以看到一些关于标记的例子,这可以让它们之间的关系变得清晰: ![][3] -现在还记得我们的朋友,expr 方法吗?我之前说过,这是数学表达式实际被解释的地方。但是你要先识别这个表达式有哪些词组才能解释它,比如它是加法还是减法。expr 方法最重要的工作是:它从 get_next_token 方法中得到流,并找出标记流的结构然后解释已经识别出的词组,产生数学表达式的结果。 +现在还记得我们的朋友,`expr` 方法吗?我之前说过,这是数学表达式实际被解释的地方。但是你要先识别这个表达式有哪些词组才能解释它,比如它是加法还是减法。`expr` 方法最重要的工作是:它从 `get_next_token` 方法中得到流,并找出该标记流的结构,然后解释已经识别出的词组,产生数学表达式的结果。 -在标记流中找出结构的过程,或者换种说法,识别标记流中的词组的过程就叫 **解析**。解释器或者编译器中执行这个任务的部分就叫做 **解析器**。 +在标记流中找出结构的过程,或者换种说法,识别标记流中的词组的过程就叫解析parsing。解释器或者编译器中执行这个任务的部分就叫做解析器parser。 -现在你知道 expr 方法就是你的解释器的部分,**解析** 和 **解释** 都在这里发生 - expr 方法首先尝试识别(**解析**)标记流里的 “整数 -> 加法 -> 整数” 或者 “整数 -> 减法 -> 整数” 词组,成功识别后 (**解析**) 其中一个词组,这个方法就开始解释它,返回两个整数的和或差。 +现在你知道 `expr` 方法就是你的解释器的部分,解析parsing解释interpreting都在这里发生 —— `expr` 方法首先尝试识别(解析)标记流里的 “整数 -> 加法 -> 整数” 或者 “整数 -> 减法 -> 整数” 词组,成功识别后 (解析了) 其中一个词组,这个方法就开始解释它,返回两个整数的和或差。 又到了练习的时间。 @@ -206,15 +207,12 @@ calc> 2. 扩展这个计算器,让它能够计算两个整数的除法 3. 修改代码,让它能够解释包含了任意数量的加法和减法的表达式,比如 “9 - 5 + 3 + 11” - - **检验你的理解:** 1. 词法是什么? 2. 找出标记流结构的过程叫什么,或者换种说法,识别标记流中一个词组的过程叫什么? 3. 解释器(编译器)执行解析的部分叫什么? - 希望你喜欢今天的内容。在该系列的下一篇文章里你就能扩展计算器从而处理更多复杂的算术表达式。敬请期待。 -------------------------------------------------------------------------------- @@ -223,12 +221,12 @@ via: https://ruslanspivak.com/lsbasi-part2/ 作者:[Ruslan Spivak][a] 译者:[BriFuture](https://github.com/BriFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://ruslanspivak.com -[1]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) +[1]:https://linux.cn/article-9399-1.html [2]:https://github.com/rspivak/lsbasi/blob/master/part2/calc2.py [3]:https://ruslanspivak.com/lsbasi-part2/lsbasi_part2_lexemes.png [4]:https://ruslanspivak.com/lsbasi-part2/lsbasi_part2_exercises.png diff --git a/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md b/published/201804/20150812 Let-s Build A Simple Interpreter. Part 3..md similarity index 83% rename from translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md rename to published/201804/20150812 Let-s Build A Simple Interpreter. Part 3..md index d50e5ce8f4..a70c10f9b0 100644 --- a/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md +++ b/published/201804/20150812 Let-s Build A Simple Interpreter. Part 3..md @@ -1,11 +1,11 @@ -让我们做个简单的解释器(3) +让我们做个简单的解释器(三) ====== 早上醒来的时候,我就在想:“为什么我们学习一个新技能这么难?” 我不认为那是因为它很难。我认为原因可能在于我们花了太多的时间,而这件难事需要有丰富的阅历和足够的知识,然而我们要把这样的知识转换成技能所用的练习时间又不够。 -拿游泳来说,你可以花上几天时间来阅读很多有关游泳的书籍,花几个小时和资深的游泳者和教练交流,观看所有可以获得的训练视频,但你第一次跳进水池的时候,仍然会像一个石头那样沉入水中, +拿游泳来说,你可以花上几天时间来阅读很多有关游泳的书籍,花几个小时和资深的游泳者和教练交流,观看所有可以获得的训练视频,但你第一次跳进水池的时候,仍然会像一个石头那样沉入水中, 要点在于:你认为自己有多了解那件事都无关紧要 —— 你得通过练习把知识变成技能。为了帮你练习,我把训练放在了这个系列的 [第一部分][1] 和 [第二部分][2] 了。当然,你会在今后的文章中看到更多练习,我保证 :) @@ -17,7 +17,7 @@ ![][3] -什么是语法图? **语法图** 是对一门编程语言中的语法规则进行图像化的表示。基本上,一个语法图就能告诉你哪些语句可以在程序中出现,哪些不能出现。 +什么是语法图syntax diagram? **语法图** 是对一门编程语言中的语法规则进行图像化的表示。基本上,一个语法图就能告诉你哪些语句可以在程序中出现,哪些不能出现。 语法图很容易读懂:按照箭头指向的路径。某些路径表示的是判断,有些表示的是循环。 @@ -28,9 +28,7 @@ * 它们用图形的方式表示一个编程语言的特性(语法)。 * 它们可以用来帮你写出解析器 —— 你可以根据下列简单规则把图片转换成代码。 - - -你已经知道,识别出记号流中的词组的过程就叫做 **解析**。解释器或者编译器执行这个任务的部分叫做 **解析器**。解析也称为 **语法分析**,并且解析器这个名字很合适,你猜的对,就是 **语法分析**。 +你已经知道,识别出记号流中的词组的过程就叫做 **解析**。解释器或者编译器执行这个任务的部分叫做 **解析器**。解析也称为 **语法分析**,并且解析器这个名字很合适,你猜的对,就是 **语法分析器**。 根据上面的语法图,下面这些表达式都是合法的: @@ -38,9 +36,8 @@ * 3 + 4 * 7 - 3 + 2 - 1 - - 因为算术表达式的语法规则在不同的编程语言里面是很相近的,我们可以用 Python shell 来“测试”语法图。打开 Python shell,运行下面的代码: + ``` >>> 3 3 @@ -53,6 +50,7 @@ 意料之中。 表达式 “3 + ” 不是一个有效的数学表达式,根据语法图,加号后面必须要有个 term (整数),否则就是语法错误。然后,自己在 Python shell 里面运行: + ``` >>> 3 + File "", line 1 @@ -63,9 +61,10 @@ SyntaxError: invalid syntax 能用 Python shell 来做这样的测试非常棒,让我们把上面的语法图转换成代码,用我们自己的解释器来测试,怎么样? -从之前的文章里([第一部分][1] 和 [第二部分][2])你知道 expr 方法包含了我们的解析器和解释器。再说一遍,解析器仅仅识别出结构,确保它与某些特性对应,而解释器实际上是在解析器成功识别(解析)特性之后,就立即对表达式进行评估。 +从之前的文章里([第一部分][1] 和 [第二部分][2])你知道 `expr` 方法包含了我们的解析器和解释器。再说一遍,解析器仅仅识别出结构,确保它与某些特性对应,而解释器实际上是在解析器成功识别(解析)特性之后,就立即对表达式进行评估。 以下代码片段显示了对应于图表的解析器代码。语法图里面的矩形方框(term)变成了 term 方法,用于解析整数,expr 方法和语法图的流程一致: + ``` def term(self): self.eat(INTEGER) @@ -85,9 +84,10 @@ def expr(self): self.term() ``` -你能看到 expr 首先调用了 term 方法。然后 expr 方法里面的 while 循环可以执行 0 或多次。在循环里面解析器基于标记做出判断(是加号还是减号)。花一些时间,你就知道,上述代码确实是遵循着语法图的算术表达式流程。 +你能看到 `expr` 首先调用了 `term` 方法。然后 `expr` 方法里面的 `while` 循环可以执行 0 或多次。在循环里面解析器基于标记做出判断(是加号还是减号)。花一些时间,你就知道,上述代码确实是遵循着语法图的算术表达式流程。 + +解析器并不解释任何东西:如果它识别出了一个表达式,它就静默着,如果没有识别出来,就会抛出一个语法错误。改一下 `expr` 方法,加入解释器的代码: -解析器并不解释任何东西:如果它识别出了一个表达式,它就静默着,如果没有识别出来,就会抛出一个语法错误。改一下 expr 方法,加入解释器的代码: ``` def term(self): """Return an INTEGER token value""" @@ -113,14 +113,16 @@ def expr(self): return result ``` -因为解释器需要评估一个表达式, term 方法被改成返回一个整型值,expr 方法被改成在合适的地方执行加法或减法操作,并返回解释的结果。尽管代码很直白,我建议花点时间去理解它。 +因为解释器需要评估一个表达式, `term` 方法被改成返回一个整型值,`expr` 方法被改成在合适的地方执行加法或减法操作,并返回解释的结果。尽管代码很直白,我建议花点时间去理解它。 + 进行下一步,看看完整的解释器代码,好不? -这时新版计算器的源代码,它可以处理包含有任意多个加法和减法运算的有效的数学表达式。 +这是新版计算器的源代码,它可以处理包含有任意多个加法和减法运算的有效的数学表达式。 + ``` # 标记类型 # -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' @@ -265,9 +267,10 @@ if __name__ == '__main__': main() ``` -把上面的代码保存到 calc3.py 文件中,或者直接从 [GitHub][4] 上下载。试着运行它。看看它能不能处理我之前给你看过的语法图里面派生出的数学表达式。 +把上面的代码保存到 `calc3.py` 文件中,或者直接从 [GitHub][4] 上下载。试着运行它。看看它能不能处理我之前给你看过的语法图里面派生出的数学表达式。 这是我在自己的笔记本上运行的示例: + ``` $ python calc3.py calc> 3 @@ -297,15 +300,13 @@ Traceback (most recent call last): Exception: Invalid syntax ``` - -记得我在文章开始时提过的练习吗:他们在这儿,我保证过的:) +记得我在文章开始时提过的练习吗:它们在这儿,我保证过的:) ![][5] * 画出只包含乘法和除法的数学表达式的语法图,比如 “7 * 4 / 2 * 3”。认真点,拿只钢笔或铅笔,试着画一个。 修改计算器的源代码,解释只包含乘法和除法的数学表达式。比如 “7 * 4 / 2 * 3”。 - * 从头写一个可以处理像 “7 - 3 + 2 - 1” 这样的数学表达式的解释器。用你熟悉的编程语言,不看示例代码自己思考着写出代码。做的时候要想一想这里面包含的组件:一个 lexer,读取输入并转换成标记流,一个解析器,从 lexer 提供的记号流中取食,并且尝试识别流中的结构,一个解释器,在解析器成功解析(识别)有效的数学表达式后产生结果。把这些要点串起来。花一点时间把你获得的知识变成一个可以运行的数学表达式的解释器。 - + * 从头写一个可以处理像 “7 - 3 + 2 - 1” 这样的数学表达式的解释器。用你熟悉的编程语言,不看示例代码自己思考着写出代码。做的时候要想一想这里面包含的组件:一个词法分析器,读取输入并转换成标记流,一个解析器,从词法分析器提供的记号流中获取,并且尝试识别流中的结构,一个解释器,在解析器成功解析(识别)有效的数学表达式后产生结果。把这些要点串起来。花一点时间把你获得的知识变成一个可以运行的数学表达式的解释器。 **检验你的理解。** @@ -314,8 +315,6 @@ Exception: Invalid syntax 3. 什么是语法分析器? - - 嘿,看!你看完了所有内容。感谢你们坚持到今天,而且没有忘记练习。:) 下次我会带着新的文章回来,尽请期待。 -------------------------------------------------------------------------------- @@ -323,14 +322,14 @@ Exception: Invalid syntax via: https://ruslanspivak.com/lsbasi-part3/ 作者:[Ruslan Spivak][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[BriFuture](https://github.com/BriFuture) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://ruslanspivak.com -[1]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) -[2]:http://ruslanspivak.com/lsbasi-part2/ (Part 2) +[1]:https://linux.cn/article-9399-1.html +[2]:https://linux.cn/article-9520-1.html [3]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_syntax_diagram.png [4]:https://github.com/rspivak/lsbasi/blob/master/part3/calc3.py [5]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_exercises.png diff --git a/published/201804/20170101 How to resolve mount.nfs- Stale file handle error.md b/published/201804/20170101 How to resolve mount.nfs- Stale file handle error.md new file mode 100644 index 0000000000..056c9bf450 --- /dev/null +++ b/published/201804/20170101 How to resolve mount.nfs- Stale file handle error.md @@ -0,0 +1,96 @@ +如何解决 “mount.nfs: Stale file handle”错误 +====== + +> 了解如何解决 Linux 平台上的 `mount.nfs: Stale file handle` 错误。这个 NFS 错误可以在客户端或者服务端解决。 + + _![][1]_ + +当你在你的环境中使用网络文件系统时,你一定不时看到 `mount.nfs:Stale file handle` 错误。此错误表示 NFS 共享无法挂载,因为自上次配置后有些东西已经更改。 + +无论是你重启 NFS 服务器或某些 NFS 进程未在客户端或服务器上运行,或者共享未在服务器上正确输出,这些都可能是导致这个错误的原因。此外,当这个错误发生在先前挂载的 NFS 共享上时,它会令人不快。因为这意味着配置部分是正确的,因为是以前挂载的。在这种情况下,可以尝试下面的命令: + +确保 NFS 服务在客户端和服务器上运行良好。 + +``` +# service nfs status +rpc.svcgssd is stopped +rpc.mountd (pid 11993) is running... +nfsd (pid 12009 12008 12007 12006 12005 12004 12003 12002) is running... +rpc.rquotad (pid 11988) is running... +``` + +如果 NFS 共享目前挂载在客户端上,则强制卸载它并尝试在 NFS 客户端上重新挂载它。通过 `df` 命令检查它是否正确挂载,并更改其中的目录。 + +``` +# umount -f /mydata_nfs + +# mount -t nfs server:/nfs_share /mydata_nfs + +#df -k +------ output clipped ----- +server:/nfs_share 41943040 892928 41050112 3% /mydata_nfs +``` + +在上面的挂载命令中,服务器可以是 NFS 服务器的 IP 或[主机名][4]。 + +如果你在强制取消挂载时遇到像下面错误: + +``` +# umount -f /mydata_nfs +umount2: Device or resource busy +umount: /mydata_nfs: device is busy +umount2: Device or resource busy +umount: /mydata_nfs: device is busy +``` + +然后你可以用 `lsof` 命令来检查哪个进程或用户正在使用该挂载点,如下所示: + +``` +# lsof |grep mydata_nfs +lsof: WARNING: can't stat() nfs file system /mydata_nfs + Output information may be incomplete. +su 3327 root cwd unknown /mydata_nfs/dir (stat: Stale NFS file handle) +bash 3484 grid cwd unknown /mydata_nfs/MYDB (stat: Stale NFS file handle) +bash 20092 oracle11 cwd unknown /mydata_nfs/MPRP (stat: Stale NFS file handle) +bash 25040 oracle11 cwd unknown /mydata_nfs/MUYR (stat: Stale NFS file handle) +``` + +如果你在上面的示例中看到共有 4 个 PID 正在使用该挂载点上的某些文件。尝试杀死它们以释放挂载点。完成后,你将能够正确卸载它。 + +有时 `mount` 命令会有相同的错误。接着使用下面的命令在客户端重启 NFS 服务后挂载。 + +``` +# service nfs restart +Shutting down NFS daemon: [ OK ] +Shutting down NFS mountd: [ OK ] +Shutting down NFS quotas: [ OK ] +Shutting down RPC idmapd: [ OK ] +Starting NFS services: [ OK ] +Starting NFS quotas: [ OK ] +Starting NFS mountd: [ OK ] +Starting NFS daemon: [ OK ] +``` + +另请阅读:[如何在 HPUX 中逐步重启 NFS][5] + +即使这没有解决你的问题,最后一步是在 NFS 服务器上重启服务。警告!这将断开从该 NFS 服务器输出的所有 NFS 共享。所有客户端将看到挂载点断开。这一步将 99% 解决你的问题。如果没有,请务必检查 [NFS 配置][6],提供你修改的配置并发布你启动时看到的错误。 + +上面文章中的输出来自 RHEL6.3 服务器。请将你的评论发送给我们。 + +-------------------------------------------------------------------------------- + +via: https://kerneltalks.com/troubleshooting/resolve-mount-nfs-stale-file-handle-error/ + +作者:[KernelTalks][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://kerneltalks.com +[1]:http://kerneltalks.com/wp-content/uploads/2017/01/nfs_error-2-150x150.png +[2]:https://www.clouddesktoponline.com/ +[3]:http://www.apps4rent.com +[4]:https://kerneltalks.com/linux/all-you-need-to-know-about-hostname-in-linux/ +[5]:http://kerneltalks.com/hpux/restart-nfs-in-hpux/ +[6]:http://kerneltalks.com/linux/nfs-configuration-linux-hpux/ diff --git a/published/201804/20170201 Prevent Files And Folders From Accidental Deletion Or Modification In Linux.md b/published/201804/20170201 Prevent Files And Folders From Accidental Deletion Or Modification In Linux.md new file mode 100644 index 0000000000..0af616dccd --- /dev/null +++ b/published/201804/20170201 Prevent Files And Folders From Accidental Deletion Or Modification In Linux.md @@ -0,0 +1,296 @@ + +如何在 Linux 系统中防止文件和目录被意外的删除或修改 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2017/02/Prevent-Files-And-Folders-From-Accidental-Deletion-Or-Modification-In-Linux-720x340.jpg) + +有时,我会不小心的按下 `SHIFT+DELETE`来删除我的文件数据。是的,我是个笨蛋,没有再次确认下我实际准备要删除的东西。而且我太笨或者说太懒,没有备份我的文件数据。结果呢?数据丢失了!在一瞬间就丢失了。 + +这种事时不时就会发生在我身上。如果你和我一样,有个好消息告诉你。有个简单又有用的命令行工具叫`chattr`(**Ch**ange **Attr**ibute 的缩写),在类 Unix 等发行版中,能够用来防止文件和目录被意外的删除或修改。 + +通过给文件或目录添加或删除某些属性,来保证用户不能删除或修改这些文件和目录,不管是有意的还是无意的,甚至 root 用户也不行。听起来很有用,是不是? + +在这篇简短的教程中,我们一起来看看怎么在实际应用中使用 `chattr` 命令,来防止文件和目录被意外删除。 + +### Linux中防止文件和目录被意外删除和修改 + +默认,`chattr` 命令在大多数现代 Linux 操作系统中是可用的。 + +默认语法是: + +``` +chattr [operator] [switch] [file] +``` + +`chattr` 具有如下操作符: + + * 操作符 `+`,追加指定属性到文件已存在属性中 + * 操作符 `-`,删除指定属性 + * 操作符 `=`,直接设置文件属性为指定属性 + +`chattr` 提供不同的属性,也就是 `aAcCdDeijsStTu`。每个字符代表一个特定文件属性。 + + * `a` – 只能向文件中添加数据 + * `A` – 不更新文件或目录的最后访问时间 + * `c` – 将文件或目录压缩后存放 + * `C` – 不适用写入时复制机制(CoW) + * `d` – 设定文件不能成为 `dump` 程序的备份目标 + * `D` – 同步目录更新 + * `e` – extend 格式存储 + * `i` – 文件或目录不可改变 + * `j` – 设定此参数使得当通过 `mount` 参数:`data=ordered` 或者 `data=writeback` 挂载的文件系统,文件在写入时会先被记录在日志中 + * `P` – project 层次结构 + * `s` – 安全删除文件或目录 + * `S` – 即时更新文件或目录 + * `t` – 不进行尾部合并 + * `T` – 顶层目录层次结构 + * `u` – 不可删除 + +在本教程中,我们将讨论两个属性的使用,即 `a`、`i` ,这个两个属性可以用于防止文件和目录的被删除。这是我们今天的主题,对吧?来开始吧! + +### 防止文件被意外删除和修改 + +我先在我的当前目录创建一个`file.txt`文件。 + +``` +$ touch file.txt +``` + +现在,我将给文件应用 `i` 属性,让文件不可改变。就是说你不能删除或修改这个文件,就算你是文件的拥有者和 root 用户也不行。 + +``` +$ sudo chattr +i file.txt +``` + +使用`lsattr`命令检查文件已有属性: + +``` +$ lsattr file.txt +``` + +输出: + +``` +----i---------e---- file.txt +``` + +现在,试着用普通用户去删除文件: + +``` +$ rm file.txt +``` + +输出: + +``` +# 不能删除文件,非法操作 +rm: cannot remove 'file.txt': Operation not permitted +``` + +我来试试 `sudo` 特权: + +``` +$ sudo rm file.txt +``` + +输出: + +``` +# 不能删除文件,非法操作 +rm: cannot remove 'file.txt': Operation not permitted +``` + +我们试试追加写内容到这个文本文件: + +``` +$ echo 'Hello World!' >> file.txt +``` + +输出: + +``` +# 非法操作 +bash: file.txt: Operation not permitted +``` + +试试 `sudo` 特权: + +``` +$ sudo echo 'Hello World!' >> file.txt +``` + +输出: + +``` +# 非法操作 +bash: file.txt: Operation not permitted +``` + +你应该注意到了,我们不能删除或修改这个文件,甚至 root 用户或者文件所有者也不行。 + +要撤销属性,使用 `-i` 即可。 + +``` +$ sudo chattr -i file.txt +``` + +现在,这不可改变属性已经被删除掉了。你现在可以删除或修改这个文件了。 + +``` +$ rm file.txt +``` + +类似的,你能够限制目录被意外删除或修改,如下一节所述。 + +### 防止目录被意外删除和修改 + +创建一个 `dir1` 目录,放入文件 `file.txt`。 + +``` +$ mkdir dir1 && touch dir1/file.txt +``` + +现在,让目录及其内容(`file.txt` 文件)不可改变: + +``` +$ sudo chattr -R +i dir1 +``` + +命令中, + + * `-R` – 递归使 `dir1` 目录及其内容不可修改 + * `+i` – 使目录不可修改 + + +现在,来试试删除这个目录,要么用普通用户,要么用 `sudo` 特权。 + +``` +$ rm -fr dir1 +$ sudo rm -fr dir1 +``` + +你会看到如下输出: + +``` +# 不可删除'dir1/file.txt':非法操作 +rm: cannot remove 'dir1/file.txt': Operation not permitted +``` + +尝试用 `echo` 命令追加内容到文件,你成功了吗?当然,你做不到。 + +撤销此属性,输入: + +``` +$ sudo chattr -R -i dir1 +``` + +现在你就能想平常一样删除或修改这个目录内容了。 + +### 防止文件和目录被意外删除,但允许追加操作 + +我们现已知道如何防止文件和目录被意外删除和修改了。接下来,我们将防止文件被删除但仅仅允许文件被追加内容。意思是你不可以编辑修改文件已存在的数据,或者重命名这个文件或者删除这个文件,你仅可以使用追加模式打开这个文件。 + +为了设置追加属性到文件或目录,我们像下面这么操作: + +针对文件: + +``` +$ sudo chattr +a file.txt +``` + +针对目录: + +``` +$ sudo chattr -R +a dir1 +``` + +一个文件或目录被设置了 `a` 这个属性就仅仅能够以追加模式打开进行写入。 + +添加些内容到这个文件以测试是否有效果。 + +``` +$ echo 'Hello World!' >> file.txt +$ echo 'Hello World!' >> dir1/file.txt +``` + +查看文件内容使用cat命令 + +``` +$ cat file.txt +$ cat dir1/file.txt +``` + +输出: + +``` +Hello World! +``` + +你将看到你现在可以追加内容。就表示我们可以修改这个文件或目录。 + +现在让我们试试删除这个文件或目录。 + +``` +$ rm file.txt +``` + +输出: + +``` +# 不能删除文件'file.txt':非法操作 +rm: cannot remove 'file.txt': Operation not permitted +``` + +让我们试试删除这个目录: + +``` +$ rm -fr dir1/ +``` + +输出: + +``` +# 不能删除文件'dir1/file.txt':非法操作 +rm: cannot remove 'dir1/file.txt': Operation not permitted +``` + +删除这个属性,执行下面这个命令: + +针对文件: + +``` +$ sudo chattr -R -a file.txt +``` + +针对目录: + +``` +$ sudo chattr -R -a dir1/ +``` + +现在,你可以想平常一样删除或修改这个文件和目录了。 + +更多详情,查看 man 页面。 + +``` +man chattr +``` + +### 总结 + +保护数据是系统管理人员的主要工作之一。市场上有众多可用的免费和收费的数据保护软件。幸好,我们已经拥有这个内置命令可以帮助我们去保护数据被意外的删除和修改。在你的 Linux 系统中,`chattr` 可作为保护重要系统文件和数据的附加工具。 + +然后,这就是今天所有内容了。希望对大家有所帮助。接下来我将会在这提供其他有用的文章。在那之前,敬请期待。再见! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/prevent-files-folders-accidental-deletion-modification-linux/ + +作者:[SK][a] +译者:[yizhuoyan](https://github.com/yizhuoyan) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ diff --git a/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md b/published/201804/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md similarity index 88% rename from translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md rename to published/201804/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md index 5af00db0f9..6b31355f02 100644 --- a/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md +++ b/published/201804/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md @@ -39,7 +39,7 @@ $ ansible -m setup -a "filter=ansible_distribution" ### 传输文件 -对于传输文件,我们使用模块 “copy” ,完整的命令是这样的: +对于传输文件,我们使用模块 `copy` ,完整的命令是这样的: ``` $ ansible -m copy -a "src=/home/dan dest=/tmp/home" @@ -47,7 +47,7 @@ $ ansible -m copy -a "src=/home/dan dest=/tmp/home" ### 管理用户 -要管理已连接主机上的用户,我们使用一个名为 “user” 的模块,并如下使用它。 +要管理已连接主机上的用户,我们使用一个名为 `user` 的模块,并如下使用它。 #### 创建新用户 @@ -65,7 +65,7 @@ $ ansible -m user -a "name=testuser state=absent" ### 更改权限和所有者 -要改变已连接主机文件的所有者,我们使用名为 ”file“ 的模块,使用如下。 +要改变已连接主机文件的所有者,我们使用名为 `file` 的模块,使用如下。 #### 更改文件权限 @@ -81,7 +81,7 @@ $ ansible -m file -a "dest=/home/dan/file1.txt mode=777 owner=dan group= ### 管理软件包 -我们可以通过使用 ”yum“ 和 ”apt“ 模块来管理所有已连接主机的软件包,完整的命令如下: +我们可以通过使用 `yum` 和 `apt` 模块来管理所有已连接主机的软件包,完整的命令如下: #### 检查包是否已安装并更新 @@ -109,7 +109,7 @@ $ ansible -m yum -a "name=ntp state=absent" ### 管理服务 -要管理服务,我们使用模块 “service” ,完整命令如下: +要管理服务,我们使用模块 `service` ,完整命令如下: #### 启动服务 @@ -129,7 +129,7 @@ $ ansible -m service -a "name=httpd state=stopped" $ ansible -m service -a "name=httpd state=restarted" ``` -这样我们简单的,单行 Ansible 命令的教程就完成了。此外,在未来的教程中,我们将学习创建 playbook,来帮助我们更轻松高效地管理主机。 +这样我们简单的、单行 Ansible 命令的教程就完成了。此外,在未来的教程中,我们将学习创建 playbook,来帮助我们更轻松高效地管理主机。 -------------------------------------------------------------------------------- diff --git a/published/201804/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md b/published/201804/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md new file mode 100644 index 0000000000..43c2c988f6 --- /dev/null +++ b/published/201804/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md @@ -0,0 +1,81 @@ +深度学习战争:Facebook 支持的 PyTorch 与 Google 的 TensorFlow +====== + +![](https://hub.packtpub.com/wp-content/uploads/2018/03/iStock-621901930-1068x832.jpg) + +有一个令人震惊的事实,即人工智能和机器学习的工具和技术在近期迅速兴起。深度学习,或者说“注射了激素的机器学习”,数据科学家和机器学习专家在这个领域有数不胜数等可用的库和框架。很多这样的框架都是基于 Python 的,因为 Python 是一个更通用,相对简单的语言。[Theano] [1]、[Keras] [2]、 [TensorFlow] [3] 是几个基于 Python 构建的流行的深度学习库,目的是使机器学习专家更轻松。 + +Google 的 TensorFlow 是一个被广泛使用的机器学习和深度学习框架。 TensorFlow 开源于 2015 年,得到了机器学习专家社区的广泛支持,TensorFlow 已经迅速成长为许多机构根据其机器学习和深度学习等需求而选择的框架。 另一方面,PyTorch 是由 Facebook 最近开发的用于训练神经网络的 Python 包,改编自基于 Lua 的深度学习库 Torch。 PyTorch 是少数可用的深度学习框架之一,它使用基于磁带的自动梯度系统tape-based autograd system,以快速和灵活的方式构建动态神经网络。 + +在这篇文章中,我们将 PyTorch 与 TensorFlow 进行不同方面的比较。 + +让我们开始吧! + +### 什么编程语言支持 PyTorch 和 TensorFlow? + +虽然主要是用 C++ 和 CUDA 编写的,但 TensorFlow 包含一个位于核心引擎上的 Python API,使得更便于被Python 支持者Pythonistas使用。 除了 Python,它还包括 C++、Haskell、Java、Go 和 Rust 等其他 API,这意味着开发人员可以用他们的首选语言进行编码。 + +虽然 PyTorch 是一个 Python 软件包,但你也可以提供使用基本的 C/C++ 语言的 API 进行编码。 如果你习惯使用 Lua 编程语言,你也可以使用 Torch API 在 PyTorch 中编写神经网络模型。 + +### PyTorch 和 TensorFlow 有多么易于使用? + +如果将 TensorFlow 作为一个独立的框架使用,它可能会有点复杂,并且会给深度学习模型的训练带来一些困难。 为了减少这种复杂性,可以使用位于 TensorFlow 复杂引擎之上的 Keras 封装,以简化深度学习模型的开发和训练。 TensorFlow 也支持 PyTorch 目前没有的[分布式培训] [4]。 由于包含 Python API,TensorFlow 也可以在生产环境中使用,即可用于培训练和部署企业级深度学习模型。 + +PyTorch 由于 Torch 的复杂用 Python 重写。 这使得 PyTorch 对于开发人员更为原生。 它有一个易于使用的框架,提供最大化的灵活和速度。 它还允许在训练过程中快速更改代码而不妨碍其性能。 如果你已经有了一些深度学习的经验,并且以前使用过 Torch,那么基于它的速度、效率和易用性,你会更喜欢 PyTorch。 PyTorch 包含定制的 GPU 分配器,这使得深度学习模型具有更高的内存效率。 由此,训练大型深度学习模型变得更容易。 因此,Pytorch +在 Facebook、Twitter、Salesforce 等大型组织广受欢迎。 + +### 用 PyTorch 和 TensorFlow 训练深度学习模型 + +PyTorch 和 TensorFlow 都可以用来建立和训练神经网络模型。 + +TensorFlow 工作于 SCG(静态计算图)上,包括在模型开始执行之前定义静态图。 但是,一旦开始执行,在模型内的调整更改的唯一方法是使用 [tf.session and tf.placeholder tensors][5]。 + +PyTorch 非常适合训练 RNN(递归神经网络),因为它们在 [PyTorch] [6] 中比在 TensorFlow 中运行得更快。 它适用于 DCG(动态计算图),可以随时在模型中定义和更改。 在 DCG 中,每个模块可以单独调试,这使得神经网络的训练更简单。 + +TensorFlow 最近提出了 TensorFlow Fold,这是一个旨在创建 TensorFlow 模型的库,用于处理结构化数据。 像 PyTorch 一样,它实现了 DCG,在 CPU 上提供高达 10 倍的计算速度,在 GPU 上提供超过 100 倍的计算速度! 在 [Dynamic Batching] [7] 的帮助下,你现在可以执行尺寸和结构都不相同的深度学习模型。 + +### GPU 和 CPU 优化的比较 + +TensorFlow 的编译时间比 PyTorch 短,为构建真实世界的应用程序提供了灵活性。 它可以从 CPU、GPU、TPU、移动设备到 Raspberry Pi(物联网设备)等各种处理器上运行。 + +另一方面,PyTorch 包括张量tensor计算,可以使用 GPU 将深度神经网络模型加速到 [50 倍或更多] [8]。 这些张量可以停留在 CPU 或 GPU 上。 CPU 和 GPU 都是独立的库, 无论神经网络大小如何,PyTorch 都可以高效地利用。 + +### 社区支持 + +TensorFlow 是当今最流行的深度学习框架之一,由此也给它带来了庞大的社区支持。 它有很好的文档和一套详细的在线教程。 TensorFlow 还包括许多预先训练过的模型,这些模型托管和提供于 [GitHub] [9]。 这些模型提供给热衷于使用 TensorFlow 开发者和研究人员一些现成的材料来节省他们的时间和精力。 + +另一方面,PyTorch 的社区相对较小,因为它最近才发展起来。 与 TensorFlow 相比,文档并不是很好,代码也不是很容易获得。 然而,PyTorch 确实允许个人与他人分享他们的预训练模型。 + +### PyTorch 和 TensorFlow —— 力量悬殊的故事 + +就目前而言,由于各种原因,TensorFlow 显然比 PyTorch 更受青睐。 + +TensorFlow 很大,经验丰富,最适合实际应用。 是大多数机器学习和深度学习专家明显的选择,因为它提供了大量的功能,最重要的是它在市场上的成熟应用。 它具有更好的社区支持以及多语言 API 可用。 它有一个很好的文档库,由于从准备到使用的代码使之易于生产。 因此,它更适合想要开始深度学习的人,或者希望开发深度学习模型的组织。 + +虽然 PyTorch 相对较新,社区较小,但它速度快,效率高。 总之,它给你所有的优势在于 Python 的有用性和易用性。 由于其效率和速度,对于基于研究的小型项目来说,这是一个很好的选择。 如前所述,Facebook、Twitter 等公司正在使用 PyTorch 来训练深度学习模型。 但是,使用它尚未成为主流。 PyTorch 的潜力是显而易见的,但它还没有准备好去挑战这个 TensorFlow 野兽。 然而,考虑到它的增长,PyTorch 进一步优化并提供更多功能的日子并不遥远,直到与 TensorFlow可以 比较。 + +作者: Savia Lobo,非常喜欢数据科学。 喜欢更新世界各地的科技事件。 喜欢歌唱和创作歌曲。 相信才智上的艺术。 + +-------------------------------------------------------------------------------- + +via: https://datahub.packtpub.com/deep-learning/dl-wars-pytorch-vs-tensorflow/ + +作者:[Savia Lobo][a] +译者:[Wuod3n](https://github.com/Wuod3n) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://datahub.packtpub.com/author/savial/ +[1]:https://www.packtpub.com/web-development/deep-learning-theano +[2]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-keras +[3]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-tensorflow +[4]:https://www.tensorflow.org/deploy/distributed +[5]:https://www.tensorflow.org/versions/r0.12/get_started/basic_usage +[6]:https://www.reddit.com/r/MachineLearning/comments/66rriz/d_rnns_are_much_faster_in_pytorch_than_tensorflow/ +[7]:https://arxiv.org/abs/1702.02181 +[8]:https://github.com/jcjohnson/pytorch-examples#pytorch-tensors +[9]:https://github.com/tensorflow/models + + + diff --git a/published/201804/20170927 Best Linux Distros for the Enterprise.md b/published/201804/20170927 Best Linux Distros for the Enterprise.md new file mode 100644 index 0000000000..516a01ef58 --- /dev/null +++ b/published/201804/20170927 Best Linux Distros for the Enterprise.md @@ -0,0 +1,81 @@ +面向企业的最佳 Linux 发行版 +==== + +在这篇文章中,我将分享企业环境下顶级的 Linux 发行版。其中一些发行版用于服务器和云环境以及桌面任务。所有这些可选的 Linux 具有的一个共同点是它们都是企业级 Linux 发行版 —— 所以你可以期待更高程度的功能性,当然还有支持程度。 + +### 什么是企业级的 Linux 发行版? + +企业级的 Linux 发行版可以归结为以下内容 —— 稳定性和支持。在企业环境中,使用的 Linux 版本必须满足这两点。稳定性意味着所提供的软件包既稳定又可用,同时仍然保持预期的安全性。 + +企业级的支持因素意味着有一个可靠的支持机制。有时这是单一的(官方)来源,如公司。在其他情况下,它可能是一个非营利性的治理机构,向优秀的第三方支持供应商提供可靠的建议。很明显,前者是最好的选择,但两者都可以接受。 + +### Red Hat 企业级 Linux(RHEL) + +[Red Hat][1] 有很多很棒的产品,都有企业级的支持来保证可用。其核心重点如下: + +- Red Hat 企业级 Linux 服务器:这是一组服务器产品,包括从容器托管到 SAP 服务的所有内容,还有其他衍生的服务器。 +- Red Hat 企业级 Linux 桌面:这些是严格控制的用户环境,运行 Red Hat Linux,提供基本的桌面功能。这些功能包括访问最新的应用程序,如 web 浏览器、电子邮件、LibreOffice 等。 +- Red Hat 企业级 Linux 工作站:这基本上是 Red Hat 企业级 Linux 桌面,但针对高性能任务进行了优化。它也非常适合于大型部署和持续管理。 + +#### 为什么选择 Red Hat 企业级 Linux? + +Red Hat 是一家非常成功的大型公司,销售围绕 Linux 的服务。基本上,Red Hat 从那些想要避免供应商锁定和其他相关问题的公司赚钱。这些公司认识到聘用开源软件专家和管理他们的服务器和其他计算需求的价值。一家公司只需要购买订阅来让 Red Hat 做支持工作就行。 + +Red Hat 也是一个可靠的社会公民。他们赞助开源项目以及像 OpenSource.com 这样的 FoSS 支持网站(LCTT 译注:FoSS 是 Free and Open Source Software 的缩写,意为自由及开源软件),并为 Fedora 项目提供支持。Fedora 不是由 Red Hat 所有的,而是由它赞助开发的。这使 Fedora 得以发展,同时也使 Red Hat 受益匪浅。Red Hat 可以从 Fedora 项目中获得他们想要的,并将其用于他们的企业级 Linux 产品中。 就目前来看,Fedora 充当了红帽企业 Linux 的上游渠道。 + +### SUSE Linux 企业版本 + +[SUSE][2] 是一家非常棒的公司,为企业用户提供了可靠的 Linux 选择。SUSE 的产品类似于 Red Hat,桌面和服务器都是该公司所关注的。从我自己使用 SUSE 的经验来看,我相信 YaST 已经证明了,对于希望在工作场所使用 Linux 操作系统的非 Linux 管理员而言,它拥有巨大的优势。YaST 为那些需要一些基本的 Linux 命令行知识的任务提供了一个友好的 GUI。 + +SUSE 的核心重点如下: + +- SUSE Linux 企业级服务器(SLES):包括任务特定的解决方案,从云到 SAP,以及任务关键计算和基于软件的数据存储。 +- SUSE Linux 企业级桌面:对于那些希望为员工提供可靠的 Linux 工作站的公司来说,SUSE Linux 企业级桌面是一个不错的选择。和 Red Hat 一样,SUSE 通过订阅模式来对其提供支持。你可以选择三个不同级别的支持。 + +#### 为什么选择 SUSE Linux 企业版? + +SUSE 是一家围绕 Linux 销售服务的公司,但他们仍然通过专注于简化操作来实现这一目标。从他们的网站到其提供的 Linux 发行版,重点是易用性,而不会牺牲安全性或可靠性。尽管在美国毫无疑问 Red Hat 是服务器的标准,但 SUSE 作为公司和开源社区的贡献成员都做得很好。 + +我还会继续说,SUSE 不会太严肃,当你在 IT 领域建立联系的时候,这是一件很棒的事情。从他们关于 Linux 的有趣音乐视频到 SUSE 贸易展位中使用的 Gecko 以获得有趣的照片机会,SUSE 将自己描述成简单易懂和平易近人的形象。 + +### Ubuntu LTS Linux + +[Ubuntu Long Term Release][3] (LTS) Linux 是一个简单易用的企业级 Linux 发行版。Ubuntu 看起来比上面提到的其他发行版更新更频繁(有时候也更不稳定)。但请不要误解,Ubuntu LTS 版本被认为是相当稳定的,不过,我认为一些专家可能不太同意它们是安全可靠的。 + +#### Ubuntu 的核心重点如下: + +- Ubuntu 桌面版:毫无疑问,Ubuntu 桌面非常简单,可以快速地学习并运行。也许在高级安装选项中缺少一些东西,但这使得其更简单直白。作为额外的奖励,Ubuntu 相比其他版本有更多的软件包(除了它的父亲,Debian 发行版)。我认为 Ubuntu 真正的亮点在于,你可以在网上找到许多销售 Ubuntu 的厂商,包括服务器、台式机和笔记本电脑。 +- Ubuntu 服务器版:这包括服务器、云和容器产品。Ubuntu 还提供了 Juju 云“应用商店”这样一个有趣的概念。对于任何熟悉 Ubuntu 或 Debian 的人来说,Ubuntu 服务器都很有意义。对于这些人来说,它就像手套一样,为你提供了你已经熟知并喜爱的命令行工具。 +- Ubuntu IoT:最近,Ubuntu 的开发团队已经把目标瞄准了“物联网”(IoT)的创建解决方案。包括数字标识、机器人技术和物联网网关。我的猜测是,我们将在 Ubuntu 中看到大量增长的物联网用户来自企业,而不是普通家庭用户。 + +#### 为什么选择 Ubuntu LTS? + +社区是 Ubuntu 最大的优点。除了在已经拥挤的服务器市场上的巨大增长之外,它还与普通用户在一起。Ubuntu 的开发和用户社区是坚如磐石的。因此,虽然它可能被认为比其他企业版更不稳定,但是我发现将 Ubuntu LTS 安装锁定到 “security updates only” 模式下提供了非常稳定的体验。 + +### CentOS 或者 Scientific Linux 怎么样呢? + +首先,让我们把 [CentOS][4] 作为一个企业发行版,如果你有自己的内部支持团队来维护它,那么安装 CentOS 是一个很好的选择。毕竟,它与 Red Hat 企业级 Linux 兼容,并提供了与 Red Hat 产品相同级别的稳定性。不幸的是,它不能完全取代 Red Hat 支持订阅。 + +那么 [Scientific Linux][5] 呢?它的发行版怎么样?好吧,它就像 CentOS,它是基于 Red Hat Linux 的。但与 CentOS 不同的是,它与 Red Hat 没有任何隶属关系。 Scientific Linux 从一开始就有一个目标 —— 为世界各地的实验室提供一个通用的 Linux 发行版。今天,Scientific Linux 基本上是 Red Hat 减去所包含的商标资料。 + +这两种发行版都不能真正地与 Red Hat 互换,因为它们缺少 Red Hat 支持组件。 + +哪一个是顶级企业发行版?我认为这取决于你需要为自己确定的许多因素:订阅范围、可用性、成本、服务和提供的功能。这些是每个公司必须自己决定的因素。就我个人而言,我认为 Red Hat 在服务器上获胜,而 SUSE 在桌面环境中轻松获胜,但这只是我的意见 —— 你不同意?点击下面的评论部分,让我们来谈谈它。 + + +-------------------------------------------------------------------------------- + +via: https://www.datamation.com/open-source/best-linux-distros-for-the-enterprise.html + +作者:[Matt Hartley][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.datamation.com/author/Matt-Hartley-3080.html +[1]:https://www.redhat.com/en +[2]:https://www.suse.com/ +[3]:http://releases.ubuntu.com/16.04/ +[4]:https://www.centos.org/ +[5]:https://www.scientificlinux.org/ diff --git a/published/201804/20170927 Linux directory structure- -lib explained.md b/published/201804/20170927 Linux directory structure- -lib explained.md new file mode 100644 index 0000000000..66ec8e41f4 --- /dev/null +++ b/published/201804/20170927 Linux directory structure- -lib explained.md @@ -0,0 +1,105 @@ +Linux 目录结构:/lib 分析 +====== + +[![linux 目录 lib][1]][1] + +我们在之前的文章中已经分析了其他重要系统目录,比如 `/bin`、`/boot`、`/dev`、 `/etc` 等。可以根据自己的兴趣进入下列链接了解更多信息。本文中,让我们来看看 `/lib` 目录都有些什么。 + +- [目录结构分析:/bin 文件夹][2] +- [目录结构分析:/boot 文件夹][3] +- [目录结构分析:/dev 文件夹][4] +- [目录结构分析:/etc 文件夹][5] +- [目录结构分析:/lost+found 文件夹][6] +- [目录结构分析:/home 文件夹][7] + +### Linux 中,/lib 文件夹是什么? + +`/lib` 文件夹是 **库文件目录** ,包含了所有对系统有用的库文件。简单来说,它是应用程序、命令或进程正确执行所需要的文件。在 `/bin` 或 `/sbin` 目录中的命令的动态库文件正是在此目录中。内核模块同样也在这里。 + +以 `pwd` 命令执行为例。执行它需要调用一些库文件。让我们来探索一下 `pwd` 命令执行时都发生了什么。我们需要使用 [strace 命令][8] 找出调用的库文件。 + +示例: + +``` +root@linuxnix:~# strace -e open pwd +open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 +open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 +open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 +/root ++++ exited with 0 +++ +root@linuxnix:~# +``` + +如果你注意到的话,会发现我们使用的 `pwd` 命令的执行需要调用两个库文件。 + +### Linux 中 /lib 文件夹内部信息 + +正如之前所说,这个文件夹包含了目标文件和一些库文件,如果能了解这个文件夹的一些重要子文件,想必是极好的。下面列举的内容是基于我自己的系统,对于你的来说,可能会有所不同。 + +``` +root@linuxnix:/lib# find . -maxdepth 1 -type d +./firmware +./modprobe.d +./xtables +./apparmor +./terminfo +./plymouth +./init +./lsb +./recovery-mode +./resolvconf +./crda +./modules +./hdparm +./udev +./ufw +./ifupdown +./systemd +./modules-load.d +``` + +`/lib/firmware` - 这个文件夹包含了一些硬件、固件Firmware代码。 + +> **硬件和固件之间有什么不同?** + +> 为了使硬件正常运行,很多设备软件由两部分软件组成。加载到实际硬件的代码部分就是固件,用于在固件和内核之间通讯的软件被称为驱动程序。这样一来,内核就可以直接与硬件通讯,并确保硬件完成内核指派的工作。 + +`/lib/modprobe.d` - modprobe 命令的配置目录。 + +`/lib/modules` - 所有的可加载内核模块都存储在这个目录下。如果你有多个内核,你会在这个目录下看到代表美国内核的目录。 + +`/lib/hdparm` - 包含 SATA/IDE 硬盘正确运行的参数。 + +`/lib/udev` - 用户空间 /dev 是 Linux 内核设备管理器。这个文件夹包含了所有的 udev 相关的文件和文件夹,例如 `rules.d` 包含了 udev 规范文件。 + +### /lib 的姊妹文件夹:/lib32 和 /lib64 + +这两个文件夹包含了特殊结构的库文件。它们几乎和 `/lib` 文件夹一样,除了架构级别的差异。 + +### Linux 其他的库文件 + +`/usr/lib` - 所有软件的库都安装在这里。但是不包含系统默认库文件和内核库文件。 + +`/usr/local/lib` - 放置额外的系统文件。这些库能够用于各种应用。 + +`/var/lib` - 存储动态数据的库和文件,例如 rpm/dpkg 数据和游戏记录。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxnix.com/linux-directory-structure-lib-explained/ + +作者:[Surendra Anne][a] +译者:[CYLeft](https://github.com/CYLeft) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxnix.com/author/surendra/ +[1]:https://www.linuxnix.com/wp-content/uploads/2017/09/The-lib-folder-explained.png +[2]:https://www.linuxnix.com/linux-directory-structure-explained-bin-folder/ +[3]:https://www.linuxnix.com/linux-directory-structure-explained-boot-folder/ +[4]:https://www.linuxnix.com/linux-directory-structure-explained-dev-folder/ +[5]:https://www.linuxnix.com/linux-directory-structure-explainedetc-folder/ +[6]:https://www.linuxnix.com/lostfound-directory-linuxunix/ +[7]:https://www.linuxnix.com/linux-directory-structure-home-root-folders/ +[8]:https://www.linuxnix.com/10-strace-command-examples-linuxunix/ diff --git a/published/201804/20170928 Process Monitoring.md b/published/201804/20170928 Process Monitoring.md new file mode 100644 index 0000000000..b8654a1a42 --- /dev/null +++ b/published/201804/20170928 Process Monitoring.md @@ -0,0 +1,55 @@ +对进程的监视 +====== + +由于复刻了 mon 项目到 [etbemon][1] 中,我花了一些时间做监视脚本。事实上监视一些事情通常很容易,但是决定监视什么才是困难的部分。进程监视脚本 `ps.monitor` 是我重新设计过的一个。 + +对于进程监视我有一些思路。如果你对进程监视如何做的更好有任何建议,请通过评论区告诉我。 + +给不使用 mon 的人介绍一下,如果一切 OK 该监视脚本就返回 0,而如果有问题它会返回 1,并使用标准输出显示错误信息。虽然我并不知道有谁将 mon 脚本挂进一个不同的监视系统中,但是,那样做其实很容易实现。我计划去做的一件事情就是,将来实现 mon 和其它的监视系统如 Nagios 之间的互操作性。 + +### 基本监视 + +``` +ps.monitor tor:1-1 master:1-2 auditd:1-1 cron:1-5 rsyslogd:1-1 dbus-daemon:1- sshd:1- watchdog:1-2 +``` + +我现在计划重写该进程监视脚本的某些部分。现在的功能是在命令行上列出进程名字,它包含了要监视的进程的最小和最大实例数量。上面的示例是一个监视的配置。在这里有一些限制,在这个实例中的 `master` 进程指的是 Postfix 的主进程,但是其它的守护进程使用了相同的进程名(这是那些错误的名字之一,因为它太直白了)。一个显而易见的解决方案是,给一个指定完整路径的选项,这样,那个 `/usr/lib/postfix/sbin/master` 就可以与其它命名为 `master` 的程序区分开了。 + +下一个问题是那些可能以多个用户身份运行的进程。比如 `sshd`,它有一个以 root 身份运行的单独的进程去接受新的连接请求,以及在每个登入用户的 UID 下运行的进程。因此,作为 root 用户运行的 sshd 进程的数量将比 root 登录会话的数量大 1。这意味着如果一个系统管理员直接以 root 身份通过 `ssh` 登入系统(这是有争议的,但它不是本文的主题—— 只是有些人需要这样做,所以我们必须支持这种情形),然后 master 进程崩溃了(或者系统管理员意外或者故意杀死了它),这时对于该进程丢失并不会产生警报。当然正确的做法是监视 22 号端口,查找字符串 `SSH-2.0-OpenSSH_`。有时候,守护进程的多个实例运行在需要单独监视的不同 UID 下面。因此,我们需要通过 UID 监视进程的能力。 + +在许多情形中,进程监视可以被替换为对服务端口的监视。因此,如果在 25 号端口上监视,那么有可能意味着,Postfix 的 `master` 在运行着,不用去理会其它的 `master` 进程。但是对于我而言,我可以在方便地进行多个监视,如果我得到一个关于无法向一个服务器发送邮件的 Jabber 消息,我可以通过这个来自服务器的 Jabber 消息断定 `master` 没有运行,而不需要挨个查找才能发现问题所在。 + +### SE Linux + +我想要的一个功能就是,监视进程的 SE Linux 上下文,就像监视 UID 一样。虽然我对为其它安全系统编写一个测试不感兴趣,但是,我很乐意将别人写好的代码包含进去。因此,不管我做什么,都希望它能与多个安全系统一起灵活地工作。 + +### 短暂进程 + +大多数守护进程在进程启动期间都有一个相同名字的次级进程second process。这意味着如果你为了精确地监视一个进程的一个实例,当 `logrotate` 或者类似的守护进程重启时,你或许会收到一个警报说有两个进程运行。如果在重启期间,恰好在一个错误的时间进行检查,你也或许会收到一个警报说,有 0 个实例。我现在处理这种情况的方法是,在与 `alertafter 2` 指令一起的次级进程失败事件之前我的服务器不发出警报。当监视处于一个失败的状态时,`failure_interval` 指令允许指定检查的时间间隔,将其设置为一个较低值时,意味着在等待一个次级进程失败结果时并不会使提示延迟太多。 + +为处理这种情况,我考虑让 `ps.monitor` 脚本在一个指定的延迟后再次进行自动检查。我认为使用一个单个参数的监视脚本来解决这个问题比起使用两个配置指令的 mon 要好一些。 + +### CPU 使用 + +mon 现在有一个 `loadavg.monitor` 脚本,它用于检查平均负载。但是它并不能捕获一个单个进程使用了太多的 CPU 时间而没有使系统平均负载上升的情况。同样,也没有捕获一个渴望获得 CPU 的进程进入沉默(例如,SETI at Home 停止运行)(LCTT 译注:SETI,由加州大学伯克利分校创建的一项利用全球的联网计算机的空闲计算资源来搜寻地外文明的科学实验计划),而其它的进程进入一个无限循环状态的情况。解决这种问题的一个方法是,让 `ps.monitor` 脚本也配置另外的一个选项去监视 CPU 的使用,但是这也可能会让人产生迷惑。另外的选择是,使用一个独立的脚本,它用来报警任何在它的生命周期或者最后几秒中,使用 CPU 时间超过指定百分比的进程,除非它在一个豁免这种检查的进程或用户的白名单中。或者每个普通用户都应该豁免这种检查,因为你压根就不知道他们什么时候运行一个文件压缩程序。也应该有一个包含排除的守护进程(像 BOINC)和系统进程(像 gzip,有几个定时任务会运行它)的简短列表。 + +### 对例外的监视 + +一个常见的编程错误是在 `setgid()` 之前调用 `setuid()`,这意味着那个程序没有权限去调用 `setgid()`。如果没有检查返回代码(而犯这种低级错误的人往往不会去检查返回代码),那么进程会保持较高的权限。检查以 GID 0 而不是 UID 0 运行的进程是很方便的。顺利说一下,对一个 Debian/Testing 工作站运行的一个快速检查显示,一个使用 GID 0 的进程并没有获得较高的权限,但是可以使用一个 `chmod 770` 命令去改变它。 + +在一个 SE Linux 系统上,应该只有一个进程与 `init_t` 域一起运行。目前在运行守护进程(比如,mysqld 和 tor)的 Debian Stretch 系统中,并不会发生策略与守护进程服务文件所请求的 systemd 的最新功能不匹配的情况。这样的问题将会不断发生,我们需要对它进行自动化测试。 + +对配置错误的自动测试可能会影响系统安全,这是一个很大的问题,我将来或许写一篇关于这方面的单独的博客文章。 + +-------------------------------------------------------------------------------- + +via: https://etbe.coker.com.au/2017/09/28/process-monitoring/ + +作者:[Andrew][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://etbe.coker.com.au +[1]:https://doc.coker.com.au/projects/etbe-mon/ diff --git a/translated/tech/20171002 Linux Gunzip Command Explained with Examples.md b/published/201804/20171002 Linux Gunzip Command Explained with Examples.md similarity index 99% rename from translated/tech/20171002 Linux Gunzip Command Explained with Examples.md rename to published/201804/20171002 Linux Gunzip Command Explained with Examples.md index 9d509c56e5..fb6a25bcba 100644 --- a/translated/tech/20171002 Linux Gunzip Command Explained with Examples.md +++ b/published/201804/20171002 Linux Gunzip Command Explained with Examples.md @@ -74,7 +74,6 @@ gunzip -c file1.gz > /home/himanshu/file1 > `gunzip` 在命令行接受一系列的文件,并且将每个文件内容以正确的魔法数开始,且后缀名为 `.gz`、`-gz`、`.z`、`-z` 或 `_z` (忽略大小写)的压缩文件,用未压缩的文件替换它,并删除其原扩展名。 `gunzip` 也可识别一些特殊扩展名的压缩文件,如 `.tgz` 和 `.taz` 分别是 `.tar.gz` 和 `.tar.Z` 的缩写。在压缩时,`gzip` 在必要情况下使用 `.tgz` 作为扩展名,而不是只截取掉 `.tar` 后缀。 > `gunzip` 目前可以解压 `gzip`、`zip`、`compress`、`compress -H`(`pack`)产生的文件。`gunzip` 自动检测输入文件格式。在使用前两种压缩格式时,`gunzip` 会检验 32 位循环冗余校验码(CRC)。对于 pack 包,`gunzip` 会检验压缩长度。标准压缩格式在设计上不允许相容性检测。不过 `gunzip` 有时可以检测出坏的 `.Z` 文件。如果你解压 `.Z` 文件时出错,不要因为标准解压没报错就认为 `.Z` 文件一定是正确的。这通常意味着标准解压过程不检测它的输入,而是直接产生一个错误的输出。SCO 的 `compress -H` 格式(lzh 压缩方法)不包括 CRC 校验码,但也允许一些相容性检查。 -``` ### 结语 diff --git a/sources/tech/20171010 How to test internet speed in Linux terminal.md b/published/201804/20171010 How to test internet speed in Linux terminal.md similarity index 58% rename from sources/tech/20171010 How to test internet speed in Linux terminal.md rename to published/201804/20171010 How to test internet speed in Linux terminal.md index 85c1832153..066d473d69 100644 --- a/sources/tech/20171010 How to test internet speed in Linux terminal.md +++ b/published/201804/20171010 How to test internet speed in Linux terminal.md @@ -1,21 +1,21 @@ -Translating by FelixYFZ -How to test internet speed in Linux terminal +如何在Linux的终端测试网速 ====== -Learn how to use speedtest cli tool to test internet speed in Linux terminal. Also includes one liner python command to get speed details right away. -![test internet speed in linux terminal][1] +> 学习如何在 Linux 终端使用命令行工具 `speedtest` 测试网速,或者仅用一条 python 命令立刻获得网速的测试结果。 -Most of us check the internet bandwidth speed whenever we connect to new network or wifi. So why not our servers! Here is a tutorial which will walk you through to test internet speed in Linux terminal. +![在Linux终端测试网速][1] -Everyone of us generally uses [Speedtest by Ookla][2] to check internet speed. Its pretty simple process for a desktop. Goto their website and just click GO button. It will scans your location and speed test with nearest server. If you are on mobile, they have their app for you. But if you are on terminal with command line interface things are little different. Lets see how to check internet speed from Linux terminal. +我们都会在连接到一个新的网络或者 WIFI 的时候去测试网络带宽。 为什么不用我们自己的服务器!下面将会教你如何在 Linux 终端测试网速。 -If you want to speed check only once and dont want to download tool on server, jump here and see one liner command. +我们多数都会使用 [Ookla 的 Speedtest][2] 来测试网速。 这在桌面上是很简单的操作,访问他们的网站点击“Go”浏览即可。它将使用最近的服务器来扫描你的本地主机来测试网速。 如果你使用的是移动设备,他们有对应的移动端 APP。但如果你使用的是只有命令行终端,界面的则会有些不同。下面让我们一起看看如何在Linux的终端来测试网速。 -### Step 1 : Download speedtest cli tool +如果你只是想偶尔的做一次网速测试而不想去下载测试工具,那么请往下看如何使用命令完成测试。 -First of all, you have to download speedtest CLI tool from [github repository][3]. Now a days, its also included in many well known Linux repositories as well. If its their in yours then you can directly [install that package on your Linux distro][4]. +### 第一步:下载网速测试命令行工具。 -Lets proceed with Github download and install process. [Install git package][4] depending on your distro. Then clone Github repo of speedtest like belwo : +首先,你需要从 [GitHub][3] 上下载 `speedtest` 命令行工具。现在,它也被包含在许多其它的 Linux 仓库中,如果已经在你的库中,你可以直接[在你的 Linux 发行版上进行安装][4]。 + +让我们继续下载和安装过程,安装的 git 包取决于你的 Linux 发行版。然后按照下面的方法来克隆 Github speedtest 存储库 ``` [root@kerneltalks ~]# git clone https://github.com/sivel/speedtest-cli.git @@ -24,10 +24,9 @@ remote: Counting objects: 913, done. remote: Total 913 (delta 0), reused 0 (delta 0), pack-reused 913 Receiving objects: 100% (913/913), 251.31 KiB | 143.00 KiB/s, done. Resolving deltas: 100% (518/518), done. - ``` -It will be cloned to your present working directory. New directory named `speedtest-cli` will be created. You can see below files in it. +它将会被克隆到你当前的工作目录,新的名为 `speedtest-cli` 的目录将会被创建,你将在新的目录下看到如下的文件。 ``` [root@kerneltalks ~]# cd speedtest-cli @@ -45,13 +44,13 @@ total 96 -rw-r--r--. 1 root root 333 Oct 7 16:55 tox.ini ``` -The python script `speedtest.py` is the one we will be using to check internet speed. +名为 `speedtest.py` 的 Python 脚本文件就是用来测试网速的。 -You can link this script for a command in /usr/bin so that all users on server can use it. Or you can even create [command alias][5] for it and it will be easy for all users to use it. +你可以将这个脚本链接到 `/usr/bin` 下,以便这台机器上的所有用户都能使用。或者你可以为这个脚本创建一个[命令别名][5],这样就能让所有用户很容易使用它。 -### Step 2 : Run python script +### 运行 Python 脚本 -Now, run python script without any argument and it will search nearest server and test your internet speed. +现在,直接运行这个脚本,不需要添加任何参数,它将会搜寻最近的服务器来测试你的网速。 ``` [root@kerneltalks speedtest-cli]# python speedtest.py @@ -66,13 +65,13 @@ Testing upload speed............................................................ Upload: 323.95 Mbit/s ``` -Oh! Dont amaze with speed. 😀 I am on [AWS EC2 Linux server][6]. Thats the bandwidth of Amazon data center! 🙂 +Oh! 不要被这个网速惊讶道。我在 AWE EX2 的服务器上。那是亚马逊数据中心的网速! -### Different options with script +### 这个脚本可以添加有不同的选项。 -Few options which might be useful are as below : +下面的几个选项对这个脚本可能会很有用处: - **To search speedtest servers** nearby your location use `--list` switch and `grep` for your location name. +**要搜寻你附近的网路测试服务器**,使用 `--list` 和 `grep` 加上地名来列出所有附近的服务器。 ``` [root@kerneltalks speedtest-cli]# python speedtest.py --list | grep -i mumbai @@ -90,11 +89,11 @@ Few options which might be useful are as below : 6403) YOU Broadband India Pvt Ltd., Mumbai (Mumbai, India) [1.15 km] ``` -You can see here, first column is server identifier followed by name of company hosting that server, location and finally its distance from your location. +然后你就能从搜寻结果中看到,第一列是服务器识别号,紧接着是公司的名称和所在地,最后是离你的距离。 - **To test internet speed using specific server** use `--server` switch and server identifier from previous output as argument. +**如果要使用指定的服务器来测试网速**,后面跟上 `--server` 加上服务器的识别号。 -``` +``` [root@kerneltalks speedtest-cli]# python speedtest.py --server 2827 Retrieving speedtest.net configuration... Testing from Amazon (35.154.184.126)... @@ -107,7 +106,7 @@ Testing upload speed............................................................ Upload: 69.25 Mbit/s ``` -**To get share link of your speed test** , use `--share` switch. It will give you URL of your test hosted on speedtest website. You can share this URL. +**如果想得到你的测试结果的分享链接**,使用 `--share`,你将会得到测试结果的链接。 ``` [root@kerneltalks speedtest-cli]# python speedtest.py --share @@ -121,24 +120,23 @@ Download: 621.00 Mbit/s Testing upload speed................................................................................................ Upload: 367.37 Mbit/s Share results: http://www.speedtest.net/result/6687428141.png - ``` -Observe last line which includes URL of your test result. If I download that image its the one below : +输出中的最后一行就是你的测试结果的链接。下载下来的图片内容如下 : ![Speedtest result on Linux][7] -Thats it! But hey if you dont want all this technical jargon, you can even use below one liner to get speed test done right away. +这就是全部的过程!如果你不想了解这些技术细节,你也可以使用如下的一行命令迅速测出你的网速。 -### Internet speed test using one liner in terminal +### 要想在终端使用一条命令测试网速。 -We are going to use [curl tool ][8]to fetch above said python script online and supply it to python for execution on the go! +我们将使用 `curl` 工具来在线抓取上面使用的 Python 脚本然后直接用 Python 执行脚本。 ``` [root@kerneltalks ~]# curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python - ``` -Above command will run the script and show you result on screen! +上面的脚本将会运行脚本输出结果到屏幕上。 ``` [root@kerneltalks speedtest-cli]# curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python - @@ -153,24 +151,24 @@ Testing upload speed............................................................ Upload: 355.84 Mbit/s ``` -I tested this tool on RHEL 7 server but process is same on Ubuntu, Debian, Fedora or CentOS. +这是在 RHEL 7 上执行的结果,在 Ubuntu、Debian、Fedora 或者 CentOS 上一样可以执行。 -------------------------------------------------------------------------------- via: https://kerneltalks.com/tips-tricks/how-to-test-internet-speed-in-linux-terminal/ 作者:[Shrikant Lavhate][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[FelixYFZ](https://github.com/FelixYFZ) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://kerneltalks.com -[1]:https://c1.kerneltalks.com/wp-content/uploads/2017/10/check-internet-speed-from-Linux.png +[1]:https://a1.kerneltalks.com/wp-content/uploads/2017/10/check-internet-speed-from-Linux.png [2]:http://www.speedtest.net/ [3]:https://github.com/sivel/speedtest-cli [4]:https://kerneltalks.com/tools/package-installation-linux-yum-apt/ [5]:https://kerneltalks.com/commands/command-alias-in-linux-unix/ [6]:https://kerneltalks.com/howto/install-ec2-linux-server-aws-with-screenshots/ -[7]:https://c3.kerneltalks.com/wp-content/uploads/2017/10/speedtest-on-linux.png +[7]:https://a3.kerneltalks.com/wp-content/uploads/2017/10/speedtest-on-linux.png [8]:https://kerneltalks.com/tips-tricks/4-tools-download-file-using-command-line-linux/ diff --git a/translated/tech/20171014 Proxy Models in Container Environments.md b/published/201804/20171014 Proxy Models in Container Environments.md similarity index 53% rename from translated/tech/20171014 Proxy Models in Container Environments.md rename to published/201804/20171014 Proxy Models in Container Environments.md index 4e5b329d68..3592ce567e 100644 --- a/translated/tech/20171014 Proxy Models in Container Environments.md +++ b/published/201804/20171014 Proxy Models in Container Environments.md @@ -1,41 +1,43 @@ 容器环境中的代理模型 ============================================================ -### 我们大多数人都熟悉代理如何工作,但在基于容器的环境中有什么不同?看看有什么改变。 +> 我们大多数人都熟悉代理如何工作,但在基于容器的环境中有什么不同?让我们来看看有什么改变。 -内联,side-arm,反向和前向。这些曾经是我们用来描述网络代理架构布局的术语。 +内联、侧臂side-arm、反向和前向。这些曾经是我们用来描述网络代理架构布局的术语。 如今,容器使用一些相同的术语,但它们正在引入新的东西。这对我是个机会来阐述我最爱的所有主题:代理。 -云的主要驱动之一(我们曾经有过成果控制的白日梦)就是可扩展性。在过去五年中,扩展在各种调查中面临着敏捷性的挑战(有时甚至获胜),因为这是机构在云计算环境中部署应用的最大追求。 +云的主要驱动之一(我们曾经有过成本控制的白日梦)就是可扩展性。在过去五年中,扩展在各种调查中面临着敏捷性的挑战(有时甚至获胜),因为这是机构在云计算环境中部署应用的最大追求。 -这在一定程度上是因为在数字经济 (我们现在运营的) 中,应用已经成为数字等同于实体店的“开放/关闭”的标志和数字客户援助的体现。缓慢、无响应的应用程序等同于把灯关闭或者商店人员不足。 +这在一定程度上是因为在(我们现在运营的)数字经济中,应用已经成为像实体店的“营业/休息”的标牌和导购一样的东西。缓慢、无响应的应用如同商店关灯或缺少营业人员一样。 -应用程序需要可用且响应满足需求。扩展是实现这一业务目标的技术响应。云不仅提供了扩展的能力,而且还提供了_自动_扩展的能力。要做到这一点,需要一个负载均衡器。因为这就是我们扩展应用程序的方式 - 使用代理负载均衡流量/请求。 + [![](https://devcentral.f5.com/Portals/0/Users/038/38/38/unavailable_is_closed_thumb.png?ver=2017-09-12-082119-957)][4] + +应用需要随时可用且能够满足需求。扩展是实现这一业务目标的技术响应。云不仅提供了扩展的能力,而且还提供了_自动_扩展的能力。要做到这一点,需要一个负载均衡器。因为这就是我们扩展应用程序的方式 :使用代理来负载均衡流量/请求。 -容器在扩展上与预期没有什么不同。容器必须进行扩展 - 并自动扩展 - 这意味着使用负载均衡器(代理)。 +容器在扩展上与预期没有什么不同。容器必须进行扩展(并自动扩展)这意味着使用负载均衡器(代理)。 -如果你使用的是本机,则你正在基于 TCP/UDP 进行基本的负载平衡。一般来说,基于容器的代理实现在 HTTP 或其他应用层协议中不流畅,除了一般的旧的负载均衡([POLB][1])之外,不提供其他功能。这通常足够好,因为容器扩展是在一个克隆的水平预置环境中进行的 - 要扩展一个应用程序,添加另一个副本并在其上分发请求。在入口处(在[入口控制器][2]和 API 网关中)可以找到第 7 层(HTTP)路由功能,并且可以使用尽可能多(或更多)的应用程序路由来扩展应用程序。 +如果你使用的是原有的代理机制,那就是采用基于 TCP/UDP 进行基本的负载平衡。一般来说,基于容器的代理的实现在 HTTP 或其他应用层协议中并不流畅,并不能在旧式的负载均衡([POLB][1])之外提供其他功能。这通常足够了,因为容器扩展是在一个克隆的、假定水平扩展的环境中进行的:要扩展一个应用程序,就添加另一个副本并在其上分发请求。在入口处(在[入口控制器][2]和 API 网关中)可以找到第 7 层(HTTP)路由功能,并且可以使用尽可能多(或更多)的应用路由来扩展应用程序。 -然而,在某些情况下,这还不够。如果你希望(或需要)更多以应用程序为中心的扩展或插入其他服务的能力,那么你将获得更健壮的产品,可提供可编程性或以应用程序为中心的可伸缩性,或者两者兼而有之。 +然而,在某些情况下,这还不够。如果你希望(或需要)更多以应用程序为中心的扩展或插入其他服务的能力,那么你就可以获得更健壮的产品,可提供可编程性或以应用程序为中心的可伸缩性,或者两者兼而有之。 -这意味着[插入代理][3]。你正在使用的容器编排环境在很大程度上决定了代理的部署模型,无论它是反向代理还是前向代理。为了让事情有趣,还有第三个模型 - sidecar - 这是由新兴的服务网格实现支持的可扩展性的基础。 +这意味着[插入代理][3]。你正在使用的容器编排环境在很大程度上决定了代理的部署模型,无论它是反向代理还是前向代理。更有趣的是,还有第三个模型挎斗模式 ,这是由新兴的服务网格实现支持的可扩展性的基础。 ### 反向代理 - [![Image title](https://devcentral.f5.com/Portals/0/Users/038/38/38/unavailable_is_closed_thumb.png?ver=2017-09-12-082119-957 "Image title")][4] +![](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-app_reverse_proxy.jpg) -反向代理最接近于传统模型,在这种模型中,虚拟服务器接受所有传入请求,并将其分发到资源池(服务器中心,集群)中。 +反向代理最接近于传统模型,在这种模型中,虚拟服务器接受所有传入请求,并将其分发到资源池(服务器中心、集群)中。 -每个“应用程序”有一个代理。任何想要连接到应用程序的客户端连接到代理,代理然后选择并转发请求到适当的实例。如果绿色应用想要与蓝色应用通信,它会向蓝色代理发送请求,蓝色代理会确定蓝色应用的两个实例中的哪一个应该响应该请求。 +每个“应用程序”有一个代理。任何想要连接到应用程序的客户端都连接到代理,代理然后选择并转发请求到适当的实例。如果绿色应用想要与蓝色应用通信,它会向蓝色代理发送请求,蓝色代理会确定蓝色应用的两个实例中的哪一个应该响应该请求。 在这个模型中,代理只关心它正在管理的应用程序。蓝色代理不关心与橙色代理关联的实例,反之亦然。 ### 前向代理 - [![Image title](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-node_forward_proxy_thumb.jpg?ver=2017-09-14-072422-213)][5] + [![](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-node_forward_proxy.jpg?ver=2017-09-14-072422-213)][5] -这种模式更接近传统出站防火墙的模式。 +这种模式更接近传统的出站防火墙的模式。 在这个模型中,每个容器 **节点** 都有一个关联的代理。如果客户端想要连接到特定的应用程序或服务,它将连接到正在运行的客户端所在的容器节点的本地代理。代理然后选择一个适当的应用实例,并转发客户端的请求。 @@ -43,31 +45,31 @@ 在这个模型中,每个代理必须知道每个应用,以确保它可以将请求转发给适当的实例。 -### sidecar 代理 +### 挎斗代理 - [![Image title](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-pod_sidecar_proxy_thumb.jpg?ver=2017-09-14-072425-620)][6] + [![](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-pod_sidecar_proxy.jpg?ver=2017-09-14-072425-620)][6] 这种模型也被称为服务网格路由。在这个模型中,每个**容器**都有自己的代理。 -如果客户想要连接到一个应用,它将连接到 sidecar 代理,它会选择一个合适的应用程序实例并转发客户端的请求。此行为与_前向代理_模型相同。 +如果客户想要连接到一个应用,它将连接到挎斗代理,它会选择一个合适的应用程序实例并转发客户端的请求。此行为与_前向代理_模型相同。 -sidecar 和前向代理之间的区别在于,sidecar 代理不需要修改容器编排环境。例如,为了插入一个前向代理到 k8s,你需要代理_和_一个 kube-proxy 的替代。sidecar 代理不需要此修改,因为应用会自动连接到 “sidecar” 代理而不是通过代理路由。 +挎斗代理和前向代理之间的区别在于,挎斗代理不需要修改容器编排环境。例如,为了插入一个前向代理到 k8s,你需要代理_和_一个 kube-proxy 的替代。挎斗代理不需要这种修改,因为应用会自动连接到 “挎斗” 代理而不是通过代理路由。 ### 总结 -每种模式都有其优点和缺点。三者共同依赖环境数据(远程监控和配置变化),以及融入生态系统的需求。有些模型是根据你选择的环境预先确定的,因此需要仔细考虑将来的需求 - 服务插入、安全性、网络复杂性 - 在建立模型之前需要进行评估。 +每种模式都有其优点和缺点。三者共同依赖环境数据(远程监控和配置变化),以及融入生态系统的需求。有些模型是根据你选择的环境预先确定的,因此需要仔细考虑将来的需求(服务插入、安全性、网络复杂性)在建立模型之前需要进行评估。 在容器及其在企业中的发展方面,我们还处于早期阶段。随着它们继续延伸到生产环境中,了解容器化环境发布的应用程序的需求以及它们在代理模型实现上的差异是非常重要的。 -我是急性写下这篇文章的。现在就这么多。 +这篇文章是匆匆写就的。现在就这么多。 -------------------------------------------------------------------------------- via: https://dzone.com/articles/proxy-models-in-container-environments -作者:[Lori MacVittie ][a] +作者:[Lori MacVittie][a] 译者:[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/) 荣誉推出 diff --git a/published/201804/20171016 5 SSH alias examples in Linux.md b/published/201804/20171016 5 SSH alias examples in Linux.md new file mode 100644 index 0000000000..bcfc643750 --- /dev/null +++ b/published/201804/20171016 5 SSH alias examples in Linux.md @@ -0,0 +1,210 @@ +Linux 中的 5 个 SSH 别名例子 +====== + +[![][1]][1] + +作为一个 Linux 用户,我们常用 [ssh 命令][2] 来登入远程机器。`ssh` 命令你用得越多,你在键入一些重要的命令上花的时间也越多。我们可以用 [定义在你的 .bashrc 文件里的别名][3] 或函数来大幅度缩减花在命令行界面(CLI)的时间。但这不是最佳解决之道。最佳办法是在 `ssh` 配置文件中使用 **SSH 别名** 。 + +这里是我们能把 `ssh` 命令用得更好的几个例子。 + +ssh 登入到 AWS(译注:Amazon Web Services,亚马逊公司旗下云计算服务平台)实例的连接是一种痛。仅仅输入以下命令,每次也完全是浪费你时间。 + +``` +ssh -p 3000 -i /home/surendra/mysshkey.pem ec2-user@ec2-54-20-184-202.us-west-2.compute.amazonaws.com +``` + +缩短到: + +``` +ssh aws1 +``` + +调试时连接到系统。 + +``` +ssh -vvv the_good_user@red1.taggle.abc.com.au +``` + +缩短到: + +``` +ssh xyz +``` + +在本篇中,我们将看到如何不使用 bash 别名或函数实现 `ssh` 命令的缩短。`ssh` 别名的主要优点是所有的 `ssh` 命令快捷方式都存储在一个单一文件,如此就易于维护。其他优点是 **对于类似于 SSH 和 SCP 的命令** 我们能用相同的别名。 + +在我们进入实际配置之前,我们应该知道 `/etc/ssh/ssh_config`、`/etc/ssh/sshd_config` 和 `~/.ssh/config` 文件三者的区别。以下是对这些文件的解释。 + +### /etc/ssh/ssh_config 和 ~/.ssh/config 间的区别 + +系统级别的 SSH 配置项存放在 `/etc/ssh/ssh_config`,而用户级别的 SSH 配置项存放在 `~/.ssh/config` 文件中。 + +### /etc/ssh/ssh_config 和 /etc/ssh/sshd_config 间的区别 + +系统级别的 SSH 配置项是在 `/etc/ssh/ssh_config` 文件中,而系统级别的 SSH **服务端**配置项存放在 `/etc/ssh/sshd_config` 文件。 + +### 在 ~/.ssh/config 文件里配置项的语法 + +`~/.ssh/config` 文件内容的语法: + +``` +配置项 值 +配置项 值1 值2 +``` + +**例 1:** 创建主机(www.linuxnix.com)的 SSH 别名 + +编辑 `~/.ssh/config` 文件写入以下内容: + +``` +Host tlj + User root + HostName 18.197.176.13 + port 22 +``` + +保存此文件。 + +以上 ssh 别名用了 + + 1. `tlj` 作为一个别名的名称 + 2. `root` 作为将要登入的用户 + 3. `18.197.176.13` 作为主机的 IP 地址 + 4. `22` 作为访问 SSH 服务的端口 + +输出: + +``` +sanne@Surendras-MacBook-Pro:~ > ssh tlj +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud +Last login: Sat Oct 14 01:00:43 2017 from 20.244.25.231 +root@linuxnix:~# exit +logout +Connection to 18.197.176.13 closed. +``` + +**例 2:** 不用密码用 ssh 密钥登到系统要用 `IdentityFile` 。 + +例: + +``` +Host aws + User ec2-users + HostName ec2-54-200-184-202.us-west-2.compute.amazonaws.com + IdentityFile ~/Downloads/surendra.pem + port 22 +``` + +**例 3:** 对同一主机使用不同的别名。在下例中,我们对同一 IP/主机 18.197.176.13 用了 `tlj`、 `linuxnix`、`linuxnix.com` 三个别名。 + +~/.ssh/config 文件内容 +``` +Host tlj linuxnix linuxnix.com + User root + HostName 18.197.176.13 + port 22 +``` + +**输出:** + +``` +sanne@Surendras-MacBook-Pro:~ > ssh tlj +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) +* Documentation: https://help.ubuntu.com +* Management: https://landscape.canonical.com +* Support: https://ubuntu.com/advantage +Get cloud support with Ubuntu Advantage Cloud Guest: +http://www.ubuntu.com/business/services/cloud +Last login: Sat Oct 14 01:00:43 2017 from 220.244.205.231 +root@linuxnix:~# exit +logout +Connection to 18.197.176.13 closed. +sanne@Surendras-MacBook-Pro:~ > ssh linuxnix.com +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) +* Documentation: https://help.ubuntu.com +* Management: https://landscape.canonical.com +* Support: https://ubuntu.com/advantage +``` +``` +Get cloud support with Ubuntu Advantage Cloud Guest: +http://www.ubuntu.com/business/services/cloud +Last login: Sun Oct 15 20:31:08 2017 from 1.129.110.13 +root@linuxnix:~# exit +logout +Connection to 138.197.176.103 closed. +[6571] sanne@Surendras-MacBook-Pro:~ > ssh linuxnix +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) +* Documentation: https://help.ubuntu.com +* Management: https://landscape.canonical.com +* Support: https://ubuntu.com/advantage +Get cloud support with Ubuntu Advantage Cloud Guest: +http://www.ubuntu.com/business/services/cloud +Last login: Sun Oct 15 20:31:20 2017 from 1.129.110.13 +root@linuxnix:~# exit +logout +Connection to 18.197.176.13 closed. +``` + +**例 4:** 用相同的 SSH 别名复制文件到远程系统 + +语法: + +``` +scp <文件名> :<位置> +``` + +例子: + +``` +sanne@Surendras-MacBook-Pro:~ > scp abc.txt tlj:/tmp +abc.txt 100% 12KB 11.7KB/s 00:01 +sanne@Surendras-MacBook-Pro:~ > +``` + +若我们已经将 ssh 主机设置好一个别名,由于 `ssh` 和 `scp` 两者用几乎相同的语法和选项,`scp` 也可以轻易使用。 + +请在下面尝试从本机 `scp` 一个文件到远程机器。 + +**例 5:** 解决 Linux 中的 SSH 超时问题。默认情况,如果你不积极地使用终端,你的 ssh 登入就会超时 + +[SSH 超时问题][5] 是一个更痛的点意味着你在一段时间后不得不重新登入到远程机器。我们能在 `~/.ssh/config` 文件里边恰当地设置 SSH 超时时间来使你的会话不管在什么时间总是激活的。我们将用 2 个能保持会话存活的 SSH 选项来实现这一目的。之一是 `ServerAliveInterval` 保持你会话存活的秒数和 `ServerAliveCountMax` 在(经历了一个)给定数值的会话之后初始化会话。 + +``` +ServerAliveInterval A +ServerAliveCountMax B +``` + +**例:** + +``` +Host tlj linuxnix linuxnix.com + User root + HostName 18.197.176.13 + port 22 + ServerAliveInterval 60 + ServerAliveCountMax 30 +``` + +在下篇中我们将会看到一些其他的退出方式。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxnix.com/5-ssh-alias-examples-using-ssh-config-file/ + +作者:[SURENDRA ANNE][a] +译者:[ch-cn](https://github.com/ch-cn) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxnix.com +[1]:https://www.linuxnix.com/wp-content/uploads/2017/10/SSH-alias-1.png +[2]:https://www.linuxnix.com/ssh-access-remote-linux-server/ +[3]:https://www.linuxnix.com/linux-alias-command-explained-with-examples/ +[4]:/cdn-cgi/l/email-protection +[5]:https://www.linuxnix.com/how-to-auto-logout/ diff --git a/published/201804/20171018 Install a Centralized Log Server with Rsyslog in Debian 9.md b/published/201804/20171018 Install a Centralized Log Server with Rsyslog in Debian 9.md new file mode 100644 index 0000000000..f13a69acab --- /dev/null +++ b/published/201804/20171018 Install a Centralized Log Server with Rsyslog in Debian 9.md @@ -0,0 +1,258 @@ +在 Debian 9 上使用 Rsyslog 安装一台中央日志服务器 +====== + +在 Linux 上,日志文件包含了系统功能的信息,系统管理员经常使用日志来确认机器上的问题所在。日志可以帮助管理员还原在过去的时间中在系统中发生的事件。一般情况下,Linux 中所有的日志文件都保存在 `/var/log` 目录下。在这个目录中,有保存着各种信息的几种类型的日志文件。比如,记录系统事件的日志文件、记录安全相关信息的日志文件、内核专用的日志文件、用户或者 cron 作业使用的日志文件。日志文件的主要作用是系统调试。Linux 中的大部分的日志文件都由 rsyslogd 服务来管理。在最新的 Linux 发行版中,日志文件也可能是由 journald 系统服务来管理和控制的。journald 服务是 systemd 初始化程序的一部分。journald 以二进制的格式存储日志,以易失性的方式写入到内存和 `/run/log/journal/` 中的环状缓冲区中,但是,journald 也可以配置为永久存储到 syslog 中。 + +在 Linux 中,可以配置运行一个 Rsyslog 服务器来中央化管理日志,在流行的服务端—客户端模式中,通过 TCP 或者 UDP 传输协议基于网络来发送日志信息,或者从网络设备、服务器、路由器、交换机、以及其它系统或嵌入式设备中接受生成的日志。 + +Rsyslog 守护程序可以被同时配置为以客户端或者服务端方式运行。配置作为服务器时,Rsyslog 将缺省监听 TCP 和 UDP 的 514 端口,来收集远程系统基于网络发送的日志信息。配置为客户端运行时,Rsyslog 将通过相同的 TCP 或 UDP 端口基于网络来发送内部日志信息。 + +Rsyslog 可以根据选定的属性和动作来过滤 syslog 信息。Rsyslog 拥有的过滤器如下: + + 1. 设备或者优先级过滤器 + 2. 基于特性的过滤器 + 3. 基于表达式的过滤器 + +设备过滤器代表了生成日志的 Linux 内部子系统。它们目前的分类如下: + + * `auth/authpriv` = 由验证进程产生的信息 + * `cron` = cron 任务相关的日志 + * `daemon` = 正在运行的系统服务相关的信息 + * `kernel` = Linux 内核信息 + * `mail` = 邮件服务器信息 + * `syslog` = syslog 或者其它守护程序(DHCP 服务器发送的日志在这里)相关的信息 + * `lpr` = 打印机或者打印服务器信息 + * `local0` ~ `local7` = 管理员控制下的自定义信息 + +优先级或者严重程度级别分配如下所述的一个关键字或者一个数字。 + + * `emerg` = 紧急 - 0 + * `alert` = 警报 - 1 + * `err` = 错误 - 3 + * `warn` = 警告 - 4 + * `notice` = 提示 - 5 + * `info` = 信息 - 6 + * `debug` = 调试 - 7 (最高级别) + +此外也有一些 Rsyslog 专用的关键字,比如星号(`*`)可以用来定义所有的设备和优先级,`none` 关键字更具体地表示没有优先级,等号(`=`)表示仅那个优先级,感叹号(`!`)表示取消这个优先级。 + +Rsyslog 的动作部分由声明的目的地来表示。日志信息的目的地可以是:存储在文件系统中的一个文件、 `/var/log/` 目录下的一个文件、通过命名管道或者 FIFO 作为输入的另一个本地进程。日志信息也可以直达用户,或者丢弃到一个“黑洞”(`/dev/null`)中、或者发送到标准输出、或者通过一个 TCP/UDP 协议发送到一个远程 syslog 服务器。日志信息也可以保存在一个数据库中,比如 MySQL 或者 PostgreSQL。 + +### 配置 Rsyslog 为服务器 + +在大多数 Linux 发行版中 Rsyslog 守护程序是自动安装的。如果你的系统中没有安装 Rsyslog,你可以根据你的系统发行版执行如下之一的命令去安装这个服务。_运行这个命令必须有 root 权限_。 + +在基于 Debian 的发行版中: + +``` +sudo apt-get install rsyslog +``` + +在基于 RHEL 的发行版中,比如像 CentOS: + +``` +sudo yum install rsyslog +``` + +验证 Rsyslog 守护进程是否在你的系统中运行,根据发行版不同,可以选择运行下列的命令: + +在新的使用 systemd 的 Linux 发行版中: + +``` +systemctl status rsyslog.service +``` + +在老的使用 init 的 Linux 发行版中: + +``` +service rsyslog status +``` + +或 + +``` +/etc/init.d/rsyslog status +``` + +启动 rsyslog 守护进程运行如下的命令。 + +在使用 init 的老的 Linux 版本: + +``` +service rsyslog start +``` + +或 + +``` +/etc/init.d/rsyslog start +``` + +在最新的 Linux 发行版: + +``` +systemctl start rsyslog.service +``` + +安装一个 rsyslog 程序运行为服务器模式,可以编辑主要的配置文件 `/etc/rsyslog.conf` 。可以使用下列所示的命令去改变它。 + +``` +sudo vi /etc/rsyslog.conf +``` + +为了允许在 UDP 的 514 端口上接收日志信息,找到并删除下列行前面的井号(`#`)以取消注释。缺省情况下,UDP 端口用于 syslog 去接收信息。 + +``` +$ModLoad imudp +$UDPServerRun 514 +``` + +因为在网络上使用 UDP 协议交换数据并不可靠,你可以设置 Rsyslog 使用 TCP 协议去向远程服务器输出日志信息。为了启用 TCP 协议去接受日志信息,打开 `/etc/rsyslog.conf` 文件并删除如下行前面的井号(`#`)以取消注释。这将允许 rsyslog 守护程序去绑定并监听 TCP 协议的 514 端口。 + +``` +$ModLoad imtcp +$InputTCPServerRun 514 +``` + +_在 rsyslog 上可以**同时**启用两种协议_。 + +如果你想去指定哪个发送者被允许访问 rsyslog 守护程序,可以在启用协议行的后面添加如下的行: + +``` +$AllowedSender TCP, 127.0.0.1, 10.110.50.0/24, *.yourdomain.com +``` + +在接收入站日志信息之前,你需要去创建一个 rsyslog 守护程序解析日志的新模板,这个模板将指示本地 Rsyslog 服务器在哪里保存入站的日志信息。在 `$AllowedSender` 行后以如下示例去创建一个合适的模板。 + +``` +$template Incoming-logs,"/var/log/%HOSTNAME%/%PROGRAMNAME%.log"  +*.*  ?Incoming-logs +& ~ +``` + +为了仅接收内核生成的日志信息,可以使用如下的语法。 + +``` +kern.*   ?Incoming-logs +``` + +接收到的日志由上面的模板来解析,它将保存在本地文件系统的 `/var/log/` 目录的文件中,之后的是以客户端主机名客户端设备名命名的日志文件名字:`%HOSTNAME%` 和 `%PROGRAMNAME%` 变量。 + +下面的 `& ~` 重定向规则,配置 Rsyslog 守护程序去保存入站日志信息到由上面的变量名字指定的文件中。否则,接收到的日志信息将被进一步处理,并将保存在本地的日志文件中,比如,`/var/log/syslog` 文件中。 + +为添加一个规则去丢弃所有与邮件相关的日志信息,你可以使用下列的语法。 + +``` +mail.* ~ +``` + +可以在输出文件名中使用的其它变量还有:`%syslogseverity%`、`%syslogfacility%`、`%timegenerated%`、`%HOSTNAME%`、`%syslogtag%`、`%msg%`、`%FROMHOST-IP%`、`%PRI%`、`%MSGID%`、`%APP-NAME%`、`%TIMESTAMP%`、%$year%、`%$month%`、`%$day%`。 + +从 Rsyslog 版本 7 开始,将使用一个新的配置格式,在一个 Rsyslog 服务器中声明一个模板。 + +一个版本 7 的模板应该看起来是如下行的样子。 + +``` +template(name="MyTemplate" type="string" +         string="/var/log/%FROMHOST-IP%/%PROGRAMNAME:::secpath-replace%.log" +        ) +``` + +另一种模式是,你也可以使用如下面所示的样子去写上面的模板: + +``` +template(name="MyTemplate" type="list") { +    constant(value="/var/log/") +    property(name="fromhost-ip") +    constant(value="/") +    property(name="programname" SecurePath="replace") +    constant(value=".log") +    } +``` + +为了让 Rsyslog 配置文件的变化生效,你必须重启守护程序来加载新的配置。 + +``` +sudo service rsyslog restart +``` + +``` +sudo systemctl restart rsyslog +``` + +在 Debian Linux 系统上去检查它监听哪个套接字,你可以用 root 权限去运行 `netstat` 命令。将输出传递给一个过滤程序,比如 `grep`。 + +``` +sudo netstat -tulpn | grep rsyslog +``` + +请注意: 为了允许建立入站连接,你必须在防火墙上打开 Rsyslog 的端口。 + +在使用 Firewalld 的基于 RHEL 的发行版上,运行如下的命令: + +``` +firewall-cmd --permanent --add-port=514/tcp +firewall-cmd --permanent --add-port=514/tcp +firewall-cmd -reload +``` + +在使用 UFW 的基于 Debian 的发行版上,运行如下的命令: + +``` +ufw allow 514/tcp +ufw allow 514/udp +``` + +Iptables 防火墙规则: + +``` +iptables -A INPUT -p tcp -m tcp --dport 514 -j ACCEPT +iptables -A INPUT -p udp --dport 514 -j ACCEPT +``` + +### 配置 Rsyslog 作为一个客户端 + +启用 Rsyslog 守护程序以客户端模式运行,并将输出的本地日志信息发送到远程 Rsyslog 服务器,编辑 `/etc/rsyslog.conf` 文件并增加下列的行: + +``` +*. * @IP_REMOTE_RSYSLOG_SERVER:514 +*. * @FQDN_RSYSLOG_SERVER:514 +``` + +这个行启用了 Rsyslog 服务,并将输出的所有内部日志发送到一个远处的 UDP 的 514 端口上运行的 Rsyslog 服务器上。 + +为了使用 TCP 协议去发送日志信息,使用下列的模板: + +``` +*. *  @@IP_reomte_syslog_server:514 +``` + +输出所有优先级的、仅与 cron 相关的日志信息到一个 Rsyslog 服务器上,使用如下的模板: + +``` +cron.* @ IP_reomte_syslog_server:514 +``` + +在 `/etc/rsyslog.conf` 文件中添加下列行,可以在 Rsyslog 服务器无法通过网络访问时,临时将客户端的日志信息存储在它的一个磁盘缓冲文件中,当网络或者服务器恢复时,再次进行发送。 + +``` +$ActionQueueFileName queue +$ActionQueueMaxDiskSpace 1g +$ActionQueueSaveOnShutdown on +$ActionQueueType LinkedList +$ActionResumeRetryCount -1 +``` + +为使上述规则生效,需要重新 Rsyslog 守护程序,以激活为客户端模式。 + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/tutorial/rsyslog-centralized-log-server-in-debian-9/ + +作者:[Matt Vas][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com diff --git a/published/201804/20171027 Scary Linux commands for Halloween.md b/published/201804/20171027 Scary Linux commands for Halloween.md new file mode 100644 index 0000000000..4f88023a72 --- /dev/null +++ b/published/201804/20171027 Scary Linux commands for Halloween.md @@ -0,0 +1,106 @@ +可怕的万圣节 Linux 命令 +====== + +![](https://images.idgesg.net/images/article/2017/10/animal-skeleton-100739983-large.jpg) + +虽然现在不是万圣节,也可以关注一下 Linux 可怕的一面。什么命令可能会显示鬼、巫婆和僵尸的图像?哪个会鼓励“不给糖果就捣蛋”的精神? + +### crypt + +好吧,我们一直看到 `crypt`。尽管名称不同,crypt 不是一个地窖,也不是垃圾文件的埋葬坑,而是一个加密文件内容的命令。现在,`crypt` 通常用一个脚本实现,通过调用一个名为 `mcrypt` 的二进制文件来模拟以前的 `crypt` 命令来完成它的工作。直接使用 `mycrypt` 命令是更好的选择。 + +``` +$ mcrypt x +Enter the passphrase (maximum of 512 characters) +Please use a combination of upper and lower case letters and numbers. +Enter passphrase: +Enter passphrase: + +File x was encrypted. +``` + +请注意,`mcrypt` 命令会创建第二个扩展名为 `.nc` 的文件。它不会覆盖你正在加密的文件。 + +`mcrypt` 命令有密钥大小和加密算法的选项。你也可以再选项中指定密钥,但 `mcrypt` 命令不鼓励这样做。 + +### kill + +还有 `kill` 命令 - 当然并不是指谋杀,而是用来强制和非强制地结束进程,这取决于正确终止它们的要求。当然,Linux 并不止于此。相反,它有各种 `kill` 命令来终止进程。我们有 `kill`、`pkill`、`killall`、`killpg`、`rfkill`、`skill`()读作 es-kill)、`tgkill`、`tkill` 和 `xkill`。 + +``` +$ killall runme +[1] Terminated ./runme +[2] Terminated ./runme +[3]- Terminated ./runme +[4]+ Terminated ./runme +``` + +### shred + +Linux 系统也支持一个名为 `shred` 的命令。`shred` 命令会覆盖文件以隐藏其以前的内容,并确保使用硬盘恢复工具无法恢复它们。请记住,`rm` 命令基本上只是删除文件在目录文件中的引用,但不一定会从磁盘上删除内容或覆盖它。`shred` 命令覆盖文件的内容。 + +``` +$ shred dupes.txt +$ more dupes.txt +▒oΛ▒▒9▒lm▒▒▒▒▒o▒1־▒▒f▒f▒▒▒i▒▒h^}&▒▒▒{▒▒ +``` + +### 僵尸 + +虽然不是命令,但僵尸在 Linux 系统上是很顽固的存在。僵尸基本上是没有完全清理掉的死亡进程的遗骸。进程_不应该_这样工作 —— 让死亡进程四处游荡,而不是简单地让它们死亡并进入数字天堂,所以僵尸的存在表明了让他们遗留于此的进程有一些缺陷。 + +一个简单的方法来检查你的系统是否有僵尸进程遗留,看看 `top` 命令的标题行。 + +``` +$ top +top - 18:50:38 up 6 days, 6:36, 2 users, load average: 0.00, 0.00, 0.00 +Tasks: 171 total, 1 running, 167 sleeping, 0 stopped, 3 zombie `< ==` +%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.9 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st +KiB Mem : 2003388 total, 250840 free, 545832 used, 1206716 buff/cache +KiB Swap: 9765884 total, 9765764 free, 120 used. 1156536 avail Mem +``` + +可怕!上面显示有三个僵尸进程。 + +### at midnight + +有时会在万圣节这么说,死者的灵魂从日落开始游荡直到午夜。Linux 可以通过 `at midnight` 命令跟踪它们的离开。用于安排在下次到达指定时间时运行的作业,`at` 的作用类似于一次性的 cron。 + +``` +$ at midnight +warning: commands will be executed using /bin/sh +at> echo 'the spirits of the dead have left' +at> +job 3 at Thu Oct 31 00:00:00 2017 +``` + +### 守护进程 + +Linux 系统也高度依赖守护进程 —— 在后台运行的进程,并提供系统的许多功能。许多守护进程的名称以 “d” 结尾。这个 “d” 代表守护进程daemon,表明这个进程一直运行并支持一些重要功能。有的会用单词 “daemon” 。 + +``` +$ ps -ef | grep sshd +root 1142 1 0 Oct19 ? 00:00:00 /usr/sbin/sshd -D +root 25342 1142 0 18:34 ? 00:00:00 sshd: shs [priv] +$ ps -ef | grep daemon | grep -v grep +message+ 790 1 0 Oct19 ? 00:00:01 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation +root 836 1 0 Oct19 ? 00:00:02 /usr/lib/accountsservice/accounts-daemon +``` + +### 万圣节快乐! + +在 [Facebook][1] 和 [LinkedIn][2] 上加入 Network World 社区来对主题进行评论。 + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3235219/linux/scary-linux-commands-for-halloween.html + +作者:[Sandra Henry-Stocker][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]:https://www.facebook.com/NetworkWorld/ +[2]:https://www.linkedin.com/company/network-world diff --git a/translated/tech/20171102 Testing IPv6 Networking in KVM- Part 1.md b/published/201804/20171102 Testing IPv6 Networking in KVM- Part 1.md similarity index 64% rename from translated/tech/20171102 Testing IPv6 Networking in KVM- Part 1.md rename to published/201804/20171102 Testing IPv6 Networking in KVM- Part 1.md index 45a696511f..ca05272493 100644 --- a/translated/tech/20171102 Testing IPv6 Networking in KVM- Part 1.md +++ b/published/201804/20171102 Testing IPv6 Networking in KVM- Part 1.md @@ -1,53 +1,55 @@ 在 KVM 中测试 IPv6 网络(第 1 部分) ====== +> 在这个两篇的系列当中,我们将学习关于 IPv6 私有地址的知识,以及如何在 KVM 中配置测试网络。 + ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ipv6-networking.png?itok=swQPV8Ey) 要理解 IPv6 地址是如何工作的,没有比亲自动手去实践更好的方法了,在 KVM 中配置一个小的测试实验室非常容易 —— 也很有趣。这个系列的文章共有两个部分,我们将学习关于 IPv6 私有地址的知识,以及如何在 KVM 中配置测试网络。 ### QEMU/KVM/虚拟机管理器 -我们先来了解什么是 KVM。在这里,我将使用 KVM 来表示 QEMU、KVM、以及虚拟机管理器的一个组合,虚拟机管理器在 Linux 发行版中一般内置了。简单解释就是,QEMU 模拟硬件,而 KVM 是一个内核模块,它在你的 CPU 上创建一个 “访客领地”,并去管理它们对内存和 CPU 的访问。虚拟机管理器是一个涵盖虚拟化和管理程序的图形工具。 +我们先来了解什么是 KVM。在这里,我将使用 KVM 来表示 QEMU、KVM、以及虚拟机管理器的一个组合,虚拟机管理器在 Linux 发行版中一般都内置了。简单解释就是,QEMU 模拟硬件,而 KVM 是一个内核模块,它在你的 CPU 上创建一个 “访客领地”,并去管理它们对内存和 CPU 的访问。虚拟机管理器是一个涵盖虚拟化和管理程序的图形工具。 -但是你不能被图形界面下 “点击” 操作的方式 "缠住" ,因为,它们也有命令行工具可以使用 —— 比如 virsh 和 virt-install。 +但是你不能被图形界面下 “点击” 操作的方式 “缠住” ,因为,它们也有命令行工具可以使用 —— 比如 `virsh` 和 `virt-install`。 如果你在使用 KVM 方面没有什么经验,你可以从 [在 KVM 中创建虚拟机:第 1 部分][1] 和 [在 KVM 中创建虚拟机:第 2 部分 - 网络][2] 开始学起。 ### IPv6 唯一本地地址 -在 KVM 中配置 IPv6 网络与配置 IPv4 网络很类似。它们的主要不同在于这些怪异的长地址。[上一次][3],我们讨论了 IPv6 地址的不同类型。其中有一个 IPv6 单播地址类,fc00::/7(详细情况请查阅 [RFC 4193][4]),它类似于 IPv4 中的私有地址 —— 10.0.0.0/8、172.16.0.0/12、和 192.168.0.0/16。 +在 KVM 中配置 IPv6 网络与配置 IPv4 网络很类似。它们的主要不同在于这些怪异的长地址。[上一次][3],我们讨论了 IPv6 地址的不同类型。其中有一个 IPv6 单播地址类,`fc00::/7`(详细情况请查阅 [RFC 4193][4]),它类似于 IPv4 中的私有地址 —— `10.0.0.0/8`、`172.16.0.0/12`、和 `192.168.0.0/16`。 下图解释了这个唯一本地地址空间的结构。前 48 位定义了前缀和全局 ID,随后的 16 位是子网,剩余的 64 位是接口 ID: -``` -| 7 bits |1| 40 bits | 16 bits | 64 bits | -+--------|-+------------|-----------|----------------------------+ -| Prefix |L| Global ID | Subnet ID | Interface ID | -+--------|-+------------|-----------|----------------------------+ +``` +| 7 bits |1| 40 bits | 16 bits | 64 bits | ++--------+-+------------+-----------+----------------------------+ +| Prefix |L| Global ID | Subnet ID | Interface ID | ++--------+-+------------+-----------+----------------------------+ ``` 下面是另外一种表示方法,它可能更有助于你理解这些地址是如何管理的: -``` -| Prefix | Global ID | Subnet ID | Interface ID | -+--------|--------------|-------------|----------------------+ -| fd | 00:0000:0000 | 0000 | 0000:0000:0000:0000 | -+--------|--------------|-------------|----------------------+ +``` +| Prefix | Global ID | Subnet ID | Interface ID | ++--------+--------------+-------------+----------------------+ +| fd | 00:0000:0000 | 0000 | 0000:0000:0000:0000 | ++--------+--------------+-------------+----------------------+ ``` -fc00::/7 共分成两个 /8 地址块,fc00::/8 和 fd00::/8。fc00::/8 是为以后使用保留的。因此,唯一本地地址通常都是以 fd 开头的,而剩余部分是由你使用的。L 位,也就是第八位,它总是设置为 1,这样它可以表示为 fd00::/8。设置为 0 时,它就表示为 fc00::/8。你可以使用 `subnetcalc` 来看到这些东西: +`fc00::/7` 共分成两个 `/8` 地址块,`fc00::/8` 和 `fd00::/8`。`fc00::/8` 是为以后使用保留的。因此,唯一本地地址通常都是以 `fd` 开头的,而剩余部分是由你使用的。`L` 位,也就是第八位,它总是设置为 `1`,这样它可以表示为 `fd00::/8`。设置为 `0` 时,它就表示为 `fc00::/8`。你可以使用 `subnetcalc` 来看到这些东西: + ``` $ subnetcalc fd00::/8 -n -Address = fd00:: - fd00 = 11111101 00000000 +Address = fd00:: + fd00 = 11111101 00000000 $ subnetcalc fc00::/8 -n -Address = fc00:: - fc00 = 11111100 00000000 - +Address = fc00:: + fc00 = 11111100 00000000 ``` -RFC 4193 要求地址必须随机产生。你可以用你选择的任何方法来造出个地址,只要它们以 `fd` 打头就可以,因为 IPv6 范围非常大,它不会因为地址耗尽而无法使用。当然,最佳实践还是按 RFCs 的要求来做。地址不能按顺序分配或者使用众所周知的数字。RFC 4193 包含一个构建伪随机地址生成器的算法,或者你可以在线找到任何生成器产生的数字。 +RFC 4193 要求地址必须随机产生。你可以用你选择的任何方法来造出个地址,只要它们以 `fd` 打头就可以,因为 IPv6 范围非常大,它不会因为地址耗尽而无法使用。当然,最佳实践还是按 RFC 的要求来做。地址不能按顺序分配或者使用众所周知的数字。RFC 4193 包含一个构建伪随机地址生成器的算法,或者你可以找到各种在线生成器。 唯一本地地址不像全局单播地址(它由你的因特网服务提供商分配)那样进行中心化管理,即使如此,发生地址冲突的可能性也是非常低的。当你需要去合并一些本地网络或者想去在不相关的私有网络之间路由时,这是一个非常好的优势。 @@ -61,7 +63,7 @@ RFC4193 建议,不要混用全局单播地址的 AAAA 和 PTR 记录,因为 下周我们将讲解如何在 KVM 中配置这些 IPv6 的地址,并现场测试它们。 -通过来自 Linux 基金会和 edX 的免费在线课程 ["Linux 入门" ][6] 学习更多的 Linux 知识。 +通过来自 Linux 基金会和 edX 的免费在线课程 [“Linux 入门”][6] 学习更多的 Linux 知识。 -------------------------------------------------------------------------------- @@ -69,7 +71,7 @@ via: https://www.linux.com/learn/intro-to-linux/2017/11/testing-ipv6-networking- 作者:[Carla Schroder][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/tech/20171109 How to record statistics about a Linux machine-s uptime.md b/published/201804/20171109 How to record statistics about a Linux machine-s uptime.md similarity index 65% rename from sources/tech/20171109 How to record statistics about a Linux machine-s uptime.md rename to published/201804/20171109 How to record statistics about a Linux machine-s uptime.md index 1a5be11efa..f1684bc9c8 100644 --- a/sources/tech/20171109 How to record statistics about a Linux machine-s uptime.md +++ b/published/201804/20171109 How to record statistics about a Linux machine-s uptime.md @@ -1,27 +1,37 @@ -How to record statistics about a Linux machine’s uptime -====== -Linux/Unix sysadmins have a weird obsession with server uptime. There is a xkcd comic devoted to this subject where a good sysadmin is an unstoppable force that it stands between the forces of darkness and your cat blog's servers. +如何记录 Linux 的系统运行时间的统计信息 +===== + +Linux/Unix 系统管理员对服务器的系统运行时间有一种奇怪的痴迷。这里有一个关于这个主题的 xkcd 漫画,一个好的系统管理员是一股不可阻挡的力量,他伫立在你家猫咪博客的服务器之前,对抗黑暗势力。 + [![Fig.01: Devotion to Duty https://xkcd.com/705/][1]][1] -One can tell how long the Linux system has been running using the uptime command or [w command][2] or top command. I can get [a report of the historical and statistical running time of the system][3], keeping it between restarts using tuptime tool. -Like uptime command but with the more impressive output. Recently I discovered another tool called uptimed that records statistics about a machine's uptime. Let us see how to get uptime record statistics using uptimed and uprecords on Linux operating system. +我们可以使用 `uptime` 命令或 [w 命令][2] 或 `top` 命令来判断 Linux 系统运行了多久。我可以使用 `tuptime` 工具保留每次重新启动的运行时间,以[获得系统运行时间的历史和统计报告][3]。 + +这就像 `uptime` 命令一样,但输出结果更令人印象深刻。最近我发现了另一种称为 `uptimed` 的工具,用于记录关于机器的系统运行时间和统计信息。让我们看看如何使用 Linux 操作系统上的 `uptimed` 和 `uprecords` 来获得运行时间的记录统计信息。 + +查找系统运行时间非常简单,只需在基于 Linux 的系统上键入以下命令即可: -Finding uptime is pretty easy, just type the following on your Linux based system: ``` -$ **uptime -p** +$ uptime -p up 2 weeks, 4 days, 7 hours, 28 minutes ``` -To keep historical stats about uptime use either [tuptime][3] or uptimed tool. -## uptimed installation +要保留有关 `uptime` 的历史统计信息,请使用 [tuptime][3] 或 `uptimed` 工具。 -The simplest way to install uptimed locally is through your package managers such as apt/apt-get/yum and friends as per your Linux distro. +### 安装 uptimed -### Install uptimed on a Debian/Ubuntu Linux +安装 `uptimed` 的最简单的方式是通过你的软件包管理器,比如 apt/apt-get/yum 这些你的 Linux 发行版的朋友。 + +#### 在 Debian/Ubuntu Linux 上安装 uptimed + +键入以下 [apt 命令][4]/[apt-get 命令][5]: + +``` +$ sudo apt-get install uptimed +``` + +示例输出: -Type the following [apt command][4]/[apt-get command][5]: -`$ sudo apt-get install uptimed` -Sample outputs: ``` Reading package lists... Done Building dependency tree @@ -55,13 +65,22 @@ Processing triggers for systemd (229-4ubuntu21) ... Processing triggers for ureadahead (0.100.0-19) ... ``` -### Install uptimed on a CentOS/RHEL/Fedora/Oracle/Scientific Linux +#### 在 CentOS/RHEL/Fedora/Oracle/Scientific Linux 上安装 uptimed + +首先 [在 CentOS/RHEL 使用 EPEL 仓库][6]: + +``` +$ sudo yum -y install epel-release +``` + +然后,键入以下 [yum 命令][7]: + +``` +$ sudo yum install uptimed +``` + +示例输出: -First [enable EPEL repo on a CentOS/RHEL][6]: -`$ sudo yum -y install epel-release` -Next, type the following [yum command][7]: -`$ sudo yum install uptimed` -Sample outputs: ``` Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile @@ -104,35 +123,53 @@ Installed: Complete! ``` -If you are using **a Fedora Linux** , run the following dnf command: -`$ sudo dnf install uptimed` +如果你正在使用 Fedora Linux,运行以下 `dnf` 命令: -### Install uptimed on an Arch Linux +``` +$ sudo dnf install uptimed +``` -Type the following pacman command: -`$ sudo pacman -S uptimed` +#### 在 Arch Linux 上安装 uptimed -### Install uptimed on a Gentoo Linux +键入以下 `pacman` 命令: -Type the following emerge command: -`$ sudo emerge --ask uptimed` +``` +$ sudo pacman -S uptimed +``` -## How to configure uptimed +#### 在 Gentoo Linux 上安装 uptimed + +键入以下 `emerge` 命令: + +``` +$ sudo emerge --ask uptimed +``` + +### 如何配置 uptimed + +使用文本编辑器编辑 `/etc/uptimed.conf` 文件,例如 `vim` 命令: + +``` +$ sudo vim /etc/uptimed.conf +``` + +最少设置一个 email 地址来发送记录。假定有个兼容 sendmail 的 MTA 安装在 `/usr/lib/sendmail`。 -Edit the file /etc/uptimed.conf using a text editor such as vim command: -`$ sudo vim /etc/uptimed.conf` -At least set an email address to mail milestones/records to. Assumes sendmail compatible MTA installed as /usr/lib/sendmail. ``` EMAIL=vivek@server1.cyberciti.biz ``` -Save and close the file. -### How do I enable uptimed service at boot time? +保存并关闭文件。 -Enable uptimed service using the systemctl command: -`$ sudo systemctl enable uptimed` +### 如何在系统启动时启动 uptimed 服务? -### How do I start/stop/restart or view status of uptimed service? +使用 `systemctl` 命令启动 `uptimed` 服务: + +``` +$ sudo systemctl enable uptimed +``` + +### 我该如何 启动/停止/重启 或者查看 uptimed 服务的状态? ``` $ sudo systemctl start uptimed ## start it ## @@ -140,7 +177,9 @@ $ sudo systemctl stop uptimed ## stop it ## $ sudo systemctl restart uptimed ## restart it ## $ sudo systemctl status uptimed ## view status ## ``` -Sample outputs: + +示例输出: + ``` ● uptimed.service - uptime record daemon Loaded: loaded (/lib/systemd/system/uptimed.service; enabled; vendor preset: enabled) @@ -152,19 +191,26 @@ Sample outputs: Nov 09 17:49:14 gfs04 systemd[1]: Started uptime record daemon. ``` -## How to see uptime record +### 如何查看 uptime 记录 + +只需键入以下命令即可查看 `uptimed(8)` 程序的统计信息: -Simply type the following command to see statistics from the uptimed(8) program: ``` $ uprecords ``` -Sample outputs: + +示例输出: + [![Fig.02: uprecords in action][9]][9] -uprecords has a few more option: + +`uprecords` 有一些选项: + ``` $ uprecords -? ``` -Sample outputs: + +示例输出: + ``` usage: uprecords [OPTION]... @@ -185,19 +231,19 @@ usage: uprecords [OPTION]... -v version information ``` -## Conclusion +### 结论 + +这是一个极好的小工具,可以显示服务器正常运行时间的记录,以证明机器正常运行时间和你的业务连续性。在相关说明中,你可以看到官方的 [XKCD 系统管理员 T恤][10] 因为漫画被制作成衬衫,其中包括背面的新插图。 -This is an excellent little tool to show your server uptime records to prove your uptime and business continuity. On a related note, you should get the official [XKCD sysadmin t-shirt][10] as comic was made into a shirt, which includes a new illustration on the back. [![Fig.03: Sysadmin XKCD shirt features the original comic on the front and a new illustration on the back.][11]][11] - -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/hardware/see-records-statistics-about-a-linux-servers-uptime/ -作者:[][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +作者:[Vivek Gite][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20171113 My Adventure Migrating Back To Windows.md b/published/201804/20171113 My Adventure Migrating Back To Windows.md new file mode 100644 index 0000000000..4d2017bf8d --- /dev/null +++ b/published/201804/20171113 My Adventure Migrating Back To Windows.md @@ -0,0 +1,121 @@ +我的冒险旅程之迁移回 Windows +====== + +我已经主要使用 Linux 大约 10 年了,而且主要是 Ubuntu。但在最新发布的版本中,我决定重新回到我通常不喜欢的操作系统: Windows 10。 + +![Ubuntu On Windows][1] + +我一直是 Linux 的粉丝,我最喜欢的两个发行版是 Debian 和 Ubuntu。现今作为一个服务器操作系统,Linux 是完美无暇的,但在桌面上一直存在不同程度的问题。 + +最近一系列的问题让我意识到,我不需要使用 Linux 作为我的桌面操作系统,我仍然是一个 Linux 粉丝,但基于我安装 Ubuntu 17.10 的经验,我已经决定回到 Windows。 + +### 什么使我选择了回归 + +问题是,当 Ubuntu 17.10 出来后,我像往常一样进行全新安装,但遇到了一些非常奇怪的新问题。 + +* Dell D3100 Dock 不再工作(包括临时规避方案也没用) +* Ubuntu 意外死机(随机) +* 双击桌面上的图标没反应 +* 使用 HUD 搜索诸如“tweaks”之类的程序会尝试安装 META 桌面版本 +* GUI 比标准的 GNOME 感觉更糟糕 + +现在我确实考虑回到使用 Ubuntu 16.04 或另一个发行版,但是我觉得 Unity 7 是最精致的桌面环境,而另外唯一一个优雅且稳定的是 Windows 10。 + +除此之外,使用 Linux 而不是使用 Windows 也有一些固有的问题,如: + +* 大多数商用软件不可用,E.G Maya、 PhotoShop、 Microsoft Office(大多数情况下,替代品并不相同)等等。 +* 大多数游戏都没有移植到 Linux 上,包括来自 EA、 Rockstar Ect. 等主要工作室的游戏。 +* 对于大多数硬件来说,其 Linux 驱动程序是厂商的次要考虑。 + +在决定使用 Windows 之前,我确实考虑过其他发行版和操作系统。 + +与此同时,我看到了更多的“微软爱 Linux ”的行动,并且了解了 WSL。他们的新开发者的关注角度对我来说很有意思,于是我试了一下。 + +### 我在 Windows 找到了什么 + +我使用计算机主要是为了编程,我也使用虚拟机、git 和 ssh,并且大部分工作依赖于 bash。我偶尔也会玩游戏,观看 netflix 和一些轻松的办公室工作。 + +总之,我期待在 Ubuntu 中保留当前的工作流程并将其移植到 Windows 上。我也想利用 Windows 的优点。 + +* 所有的 PC 游戏支持 Windows +* 大多数程序是原生的 +* 微软办公软件 + +虽然使用 Windows 有很多坑,但是我打算正确对待它,所以我不担心一般的 Windows 故障,例如病毒和恶意软件。 + +### Windows 的子系统 Linux(Windows 上的 Ubuntu 中的 Bash) + +微软与 Canonical 的密切合作将 Ubuntu 带到了 Windows 上。在经过快速设置和启动程序之后,你将拥有非常熟悉的 bash 界面。 + +我一直在研究其局限性,但是在写这篇文章时我碰到的唯一真正的限制是它从硬件中抽象了出来。例如,`lsblk` 不会显示你有什么分区,因为子系统里的 Ubuntu 没有提供这些信息。 + +但是除了访问底层工具之外,我发现其体验非常熟悉,也很棒。 + +我在下面的工作流程中使用了它。 + +* 生成 SSH 密钥对 +* 使用 Git 和 Github 来管理我的仓库 +* SSH 到几个服务器,包括不用密码 +* 为本地数据库运行 MySQL +* 监视系统资源 +* 使用 Vim 编辑配置文件 +* 运行 Bash 脚本 +* 运行本地 Web 服务器 +* 运行 PHP、NodeJS + +到目前为止,它已经被证明是非常强大的工具。除了是在 Windows 10 用户界面之中,我的工作流程感觉和我在 Ubuntu 上几乎一样。尽管我的多数工作可以在 WSL 中处理,但我仍然打算通过虚拟机进行更深入的工作,这可能超出了 WSL 的范围。 + +### 不需要用 Wine + +我遇到的另一个主要问题是兼容性问题。我很少使用 Wine 来使用 Windows 软件。(LCTT 译注:Wine 是可以使 Linux 上运行 Windows 应用的软件)但是有时它是必需的,尽管通常体验不是很好。 + +#### HeidiSQL + +我首先安装的程序之一是 HeidiSQL,它是我最喜欢的数据库客户端之一。它可以在 Wine 下工作,但是感觉很不好,所以我在 Linux 下丢掉它而使用了 MySQL Workbench。回到了 Windows 中,就像一个可靠的老朋友回来了。 + +#### 游戏平台 / Steam + +没有游戏的 Windows 电脑是无法想象的。我从 Steam 的网站上安装了它,我的 Linux 游戏,加上我的 Windows 游戏就变大了 5 倍,并且包括 GTA V (LCTT 译注: GTA V 是一款名叫侠盗飞车的游戏) 等 AAA 级游戏。而这些我在 Ubuntu 中只能梦想。 + +我对 SteamOS 有很大的期望,并且一直会持续如此。但是我认为在可预见的将来,它不会在任何地方的游戏市场中崭露头角。所以如果你想在 PC 上玩游戏,你确实需要 Windows。 + +还有一点需要注意的是, 你的 nvidia 显卡的驱动程序会得到很好的支持,这使得像 TF2 (LCTT 译注: 这是一款名叫军团要塞 2 的游戏)这样的一些 Linux 原生游戏运行的稍好一些。 + +**Windows 在游戏方面总是优越的,所以这并不令人感到意外。** + +### 从 USB 硬盘运行,为什么 + +我在我的主固态硬盘上运行 Linux,但在过去,我是从 usb 棒和 usb 硬盘运行它的。我习惯了 Linux 的这种持久性,这让我可以在不丢失主要操作系统的情况下长期尝试多个版本。现在我尝试将 Windows 安装到 USB 连接的硬盘上时,它无法工作也不可能工作。所以当我将 Windows 硬盘分区的克隆作为备份时,我很惊讶我可以通过 USB 启动它。 + +这对我来说已经成为一个方便的选择,因为我打算将我的工作笔记本电脑迁移回 Windows,但如果不想冒险,那就把它扔在那里吧。 + +所以我在过去的几天里,我使用 USB 来运行它,除了一些错误的消息外,我没有通过 USB 运行发现它真正的缺点。 + +这样做主要的问题是: + +* 较慢的启动速度 +* 恼人的信息:不要拔掉你的 USB +* 无法激活它 + +**我可能会写一篇关于 USB 驱动器上的 Windows 的文章,这样我们可以有更详细的了解。** + +### 那么结论是什么? + +我使用 Windows 10 大约两周了,并没有注意到它对我的工作流程有任何的负面影响。尽管过程会有一些小问题,但我需要的所以工具都在手边,并且操作系统一般都在运行。 + +### 我会留在 Windows吗? + +虽然现在还为时尚早,但我想在可见的未来我会坚持使用 Windows。 + +-------------------------------------------------------------------------------- + +via: [https://www.chris-shaw.com/blog/my-adventure-migrating-back-to-windows](https://www.chris-shaw.com/blog/my-adventure-migrating-back-to-windows) + +作者:[Christopher Shaw][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.chris-shaw.com +[1]:https://winaero.com/blog/wp-content/uploads/2016/07/Ubutntu-on-Windows-10-logo-banner.jpg diff --git a/published/201804/20171113 The big break in computer languages.md b/published/201804/20171113 The big break in computer languages.md new file mode 100644 index 0000000000..720100a600 --- /dev/null +++ b/published/201804/20171113 The big break in computer languages.md @@ -0,0 +1,90 @@ +计算机语言的巨变 +==================================================== + +我的上一篇博文《[与 C 语言长别离][3]》引来了我的老朋友,一位 C++ 专家的评论。在评论里,他推荐把 C++ 作为 C 的替代品。这是不可能发生的,如果 C++ 代替 C 是趋势的话,那么 Go 和 Rust 也就不会出现了。 + +![](https://static1.squarespace.com/static/586bd48d03596e5605450cee/t/5880d61b29687f4fd5a5712d/1484838431523/) + +但是我不能只给我的读者一个光秃秃的看法(LCTT 译注:此处是双关语)。所以,在这篇文章中,我来讲述一下为什么我不再碰 C++ 的故事。这是关于计算机语言设计经济学专题文章的起始点。这篇文章会讨论为什么一些真心不好的决策会被做出来,然后进入语言的基础设计之中,以及我们该如何修正这些问题。 + +在这篇文章中,我会一点一点的指出人们(当然也包括我)自从 20 世纪 80 年代以来就存在的关于未来的编程语言的预见失误。直到最近,我们才找到了证明我们错了的证据。 + +我记得我第一次学习 C++ 是因为我需要使用 GNU eqn 输出 MathXML,而 eqn 是使用 C++ 写的。那个项目不错。在那之后,21 世纪初,我在韦诺之战Battle For Wesnoth那边当了多年的资深开发人生,并且与 C++ 相处甚欢。 + +在那之后啊,有一天我们发现一个不小心被我们授予提交权限的人已经把游戏的 AI 核心搞崩掉了。显然,在团队中只有我是不那么害怕查看代码的。最终,我把一切都恢复正常了 —— 我折腾了整整两周。再那之后,我就发誓我再也不靠近 C++ 了。 + +在那次经历过后,我发现这个语言的问题就是它在尝试使得本来就复杂的东西更加复杂,来粗陋补上因为基础概念的缺失造成的漏洞。对于裸指针这样东西,它说“别这样做”,这没有问题。对于小规模的个人项目(比如我的魔改版 eqn),遵守这些规定没有问题。 + +但是对于大型项目,或者开发者水平参差不齐的多人项目(这是我经常要处理的情况)就不能这样。随着时间的推移以及代码行数的增加,有的人就会捅篓子。当别人指出有 BUG 时,因为诸如 STL 之类的东西给你增加了一层复杂度,你处理这种问题所需要的精力就比处理同等规模的 C 语言的问题就要难上很多。我在韦诺之战时,我就知道了,处理这种问题真的相当棘手。 + +我给 Stell Heller(我的老朋友,C++ 的支持者)写代码时不会发生的问题在我与非 Heller 们合作时就被放大了,我和他们合作的结局可能就是我得给他们擦屁股。所以我就不用 C++ ,我觉得不值得为了其花时间。 C 是有缺陷的,但是 C 有 C++ 没有的优点 —— 如果你能在脑内模拟出硬件,那么你就能很简单的看出程序是怎么运行的。如果 C++ 真的能解决 C 的问题(也就是说,C++ 是类型安全以及内存安全的),那么失去其透明性也是值得的。但是,C++ 并没有这样。 + +我们判断 C++ 做的还不够的方法之一是想象一个 C++ 已经搞得不错的世界。在那个世界里,老旧的 C 语言项目会被迁移到 C++ 上来。主流的操作系统内核会是 C++ 写就,而现存的内核实现,比如 Linux 会渐渐升级成那样。在现实世界,这些都没有发生。C++ 不仅没有打消语言设计者设想像 D、Go 以及 Rust 那样的新语言的想法,它甚至都没有取代它的前辈。不改变 C++ 的核心思想,它就没有未来,也因此,C++ 的抽象泄露leaky abstraction也不会消失。 + +既然我刚刚提到了 D 语言,那我就说说为什么我不把 D 视为一个够格的 C 语言竞争者的原因吧。尽管它比 Rust 早出现了八年(和 Rust 相比是九年)Walter Bright 早在那时就有了构建那样一个语言的想法。但是在 2001 年,以 Python 和 Perl 为首的语言的出现已经确定了,专有语言能和开源语言抗衡的时代已经过去。官方 D 语言库/运行时和 Tangle 的无谓纷争也打击了其发展。它从未修正这些错误。 + +然后就是 Go 语言(我本来想说“以及 Rust”。但是如前文所述,我认为 Rust 还需要几年时间才能有竞争力)。它_的确是_类型安全以及内存安全的(好吧,是在大多数时候是这样,但是如果你要使用接口的话就不是如此了,但是自找麻烦可不是正常人的做法)。我的一位好友,Mark Atwood,曾指出过 Go 语言是脾气暴躁的老头子因为愤怒而创造出的语言,主要是 _C 语言的作者之一_(Ken Thompson) 因为 C++ 的混乱臃肿造成的愤怒,我深以为然。 + +我能理解 Ken 恼火的原因。这几十年来我就一直认为 C++ 搞错了需要解决的问题。C 语言的后继者有两条路可走。其一就是 C++ 那样,接受 C 的抽象泄漏、裸指针等等,以保证兼容性。然后以此为基础,构建一个最先进的语言。还有一条道路,就是从根源上解决问题 —— _修正_ C语言的抽象泄露。这一来就会破环其兼容性,但是也会杜绝 C/C++ 现有的问题。 + +对于第二条道路,第一次严谨的尝试就是 1995 年出现的 Java。Java 搞得不错,但是在语言解释器上构建这门语言使其不适合系统编程。这就在系统编程那留下一个巨大的洞,在 Go 以及 Rust 出现之前的 15 年里,都没有语言来填补这个空白。这也就是我的 GPSD 和 NTPsec 等软件在 2017 年仍然主要用 C 写成的原因,尽管 C 的问题也很多。 + +在许多方面这都是很糟糕的情况。尽管由于缺少足够多样化的选择,我们很难认识到 C/C++ 做的不够好的地方。我们都认为在软件里面出现缺陷以及基于安全方面考虑的妥协是理所当然的,而不是想想这其中多少是真的由于语言的设计问题导致的,就像缓存区溢出漏洞一样。 + +所以,为什么我们花了这么长时间才开始解决这个问题?从 C 1972 年面世到 Go 2009 年出现,这其中隔了 37 年;Rust 也是在其仅仅一年之前出现。我想根本原因还是经济。 + +从最早的计算机语言开始,人们就已经知道,每种语言的设计都体现了程序员时间与机器资源的相对价值的权衡。在机器这端,就是汇编语言,以及之后的 C 语言,这些语言以牺牲开发人员的时间为代价来提高性能。 另一方面,像 Lisp 和(之后的)Python 这样的语言则试图自动处理尽可能多的细节,但这是以牺牲机器性能为代价的。 + +广义地说,这两端的语言的最重要的区别就是有没有自动内存管理。这与经验一致,内存管理缺陷是以机器为中心的语言中最常见的一类缺陷,程序员需要手动管理资源。 + +当相对价值断言与软件开发在某个特定领域的实际成本动因相匹配时,这个语言就是在经济上可行的。语言设计者通过设计一个适合处理现在或者不远的将来出现的情况的语言,而不是使用现有的语言来解决他们遇到的问题。 + +随着时间的推移,时兴的编程语言已经渐渐从需要手动管理内存的语言变为带有自动内存管理以及垃圾回收(GC)机制的语言。这种变化对应了摩尔定律导致的计算机硬件成本的降低,使得程序员的时间与之前相比更加的宝贵。但是,除了程序员的时间以及机器效率的变化之外,至少还有两个维度与这种变化相关。 + +其一就是距离底层硬件的距离。底层软件(内核与服务代码)的低效率会被成倍地扩大。因此我们可以发现,以机器为中心的语言向底层推进,而以程序员为中心的语言向着高级发展。因为大多数情况下面向用户的语言仅仅需要以人类的反应速度(0.1 秒)做出回应即可。 + +另一个维度就是项目的规模。由于程序员抽象发生的问题的漏洞以及自身的疏忽,任何语言都会有可预期的每千行代码的出错率。这个比率在以机器为中心的语言上很高,而在程序员为中心的带有 GC 的语言里就大大降低。随着项目规模的增大,带有 GC 的语言作为一个防止出错率不堪入目的策略就显得愈发重要起来。 + +当我们使用这三种维度来看当今的编程语言的形势 —— C 语言在底层,蓬勃发展的带有 GC 的语言在上层,我们会发现这基本上很合理。但是还有一些看似不合理的是 —— C 语言的应用不合理地广泛。 + +我为什么这么说?想想那些经典的 Unix 命令行工具吧。那些小程序通常都可以使用带有完整的 POSIX 支持的脚本语言快速实现出来。重新编码那些程序将使得它们调试、维护和拓展起来都会更加简单。 + +但是为什么还是使用 C (或者某些像 eqn 的项目,使用 C++)?因为有转换成本。就算是把相当小、相当简单的程序使用新的语言重写并且确认你已经忠实地保留了所有非错误行为都是相当困难的。笼统地说,在任何一个领域的应用编程或者系统编程在一种语言的权衡过时之后,仍然坚持使用它。 + +这就是我和其他预测者犯的大错。 我们认为,降低机器资源成本(增加程序员时间的相对成本)本身就足以取代 C 语言(以及没有 GC 的语言)。 在这个过程中,我们有一部分或者甚至一大部分都是错误的 —— 自 20 世纪 90 年代初以来,脚本语言、Java 以及像 Node.js 这样的东西的兴起显然都是这样兴起的。 + +但是,竞争系统编程语言的新浪潮并非如此。 Rust 和 Go 都明确地回应了_增加项目规模_ 这一需求。 脚本语言是先是作为编写小程序的有效途径,并逐渐扩大规模,而 Rust 和 Go 从一开始就定位为减少_大型项目_中的缺陷率。 比如 Google 的搜索服务和 Facebook 的实时聊天复用。 + +我认为这就是对 “为什么不再早点儿” 这个问题的回答。Rust 和 Go 实际上并不算晚,它们相对迅速地回应了一个直到最近才被发现低估的成本动因问题。 + +好,说了这么多理论上的问题。按照这些理论我们能预言什么?它告诉我们在 C 之后会出现什么? + +推动 GC 语言发展的趋势还没有扭转,也不要期待其扭转。这是大势所趋。因此:最终我们*将*拥有具有足够低延迟的 GC 技术,可用于内核和底层固件,这些技术将以语言实现方式被提供。 这些才是真正结束 C 长期统治的语言应有的特性。 + +我们能从 Go 语言开发团队的工作文件中发现端倪,他们正朝着这个方向前进 —— 可参见关于并发 GC 的学术研究 —— 从未停止研究。 如果 Go 语言自己没有选择这么做,其他的语言设计师也会这样。 但我认为他们会这么做 —— 谷歌推动他们的项目的能力是显而易见的(我们从 “Android 的发展”就能看出来)。 + +在我们拥有那么理想的 GC 之前,我把能替换 C 语言的赌注押在 Go 语言上。因为其 GC 的开销是可以接受的 —— 也就是说不只是应用,甚至是大部分内核外的服务都可以使用。原因很简单: C 的出错率无药可医,转化成本还很高。 + +上周我尝试将 C 语言项目转化到 Go 语言上,我发现了两件事。其一就是这活很简单, C 的语言和 Go 对应的很好。还有就是写出的代码相当简单。由于 GC 的存在以及把集合视为首要的数据结构,人们会预期代码减少,但是我意识到我写的代码比我最初期望的减少的更多,比例约为 2:1 —— 和 C 转 Python 类似。 + +抱歉呐,Rust 粉们。你们在内核以及底层固件上有着美好的未来,但是你们在别的 C 领域被 Go 压的很惨。没有 GC ,再加上难以从 C 语言转化过来,还有就是 API 的标准部分还是不够完善。(我的 `select(2)` 又哪去了啊?)。 + +对你们来说,唯一的安慰就是,C++ 粉比你们更糟糕 —— 如果这算是安慰的话。至少 Rust 还可以在 Go 顾及不到的 C 领域内大展宏图。C++ 可不能。 + +-------------------------------------------------------------------------------- + +via: http://esr.ibiblio.org/?p=7724 + +作者:[Eric Raymond][a] +译者:[name1e5s](https://github.com/name1e5s) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://esr.ibiblio.org/?author=2 +[1]:http://esr.ibiblio.org/?author=2 +[2]:http://esr.ibiblio.org/?p=7724 +[3]:https://linux.cn/article-9268-1.html +[4]:http://esr.ibiblio.org/?cat=13 +[5]:http://esr.ibiblio.org/?author=2 +[6]:http://esr.ibiblio.org/?p=7724 diff --git a/published/201804/20171123 Why microservices are a security issue.md b/published/201804/20171123 Why microservices are a security issue.md new file mode 100644 index 0000000000..816baaba85 --- /dev/null +++ b/published/201804/20171123 Why microservices are a security issue.md @@ -0,0 +1,93 @@ +为什么微服务是一个安全问题 +============================================================ + +> 你可能并不想把所有的遗留应用全部分解为微服务,或许你可以考虑从安全功能开始。 + +![Why microservices are a security issue](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003601_05_mech_osyearbook2016_security_cc.png?itok=3V07Lpko) + +Image by : Opensource.com + +我为了给这篇文章起个标题,使出 “洪荒之力”,也很担心这会变成标题党。如果你点击它,是因为它激起了你的好奇,那么我表示抱歉 ^[注1][5] 。我当然是希望你留下来阅读的 ^[注2][6] :我有很多有趣的观点以及很多 ^[注3][7] 脚注。我不是故意提出微服务会导致安全问题——尽管如同很多组件一样都有安全问题。当然,这些微服务是那些安全方面的人员的趣向所在。进一步地说,我认为对于那些担心安全的人来说,它们是优秀的架构。 + +为什么这样说?这是个好问题,对于我们这些有[系统安全][16] 经验的人来说,此时这个世界才是一个有趣的地方。我们看到随着带宽便宜了并且延迟降低了,分布式系统在增长。加上部署到云愈加便利,越来越多的架构师们开始意识到应用是可以分解的,不只是分成多个层,并且层内还能分为多个组件。当然,均衡负载可以用于让一个层内的各个组件协同工作,但是将不同的服务输出为各种小组件的能力导致了微服务在设计、实施和部署方面的增长。 + +所以,[到底什么是微服务呢][23]?我同意[维基百科的定义][24],尽管没有提及安全性方面的内容^[注4][17] 。 我喜欢微服务的一点是,经过精心设计,其符合 Peter H. Salus 描述的 [UNIX 哲学][25] 的前俩点: + +1. 程序应该只做一件事,并尽可能把它做好。 +2. 让程序能够互相协同工作。 +3. 应该让程序处理文本数据流,因为这是一个通用的接口。 + +三者中最后一个有点不太相关,因为 UNIX 哲学通常被用来指代独立应用,它常有一个实例化的命令。但是,它确实包含了微服务的基本要求之一:必须具有“定义明确”的接口。 + +这里的“定义明确”,我指的不仅仅是可外部访问的 API 的方法描述,也指正常的微服务输入输出操作——以及,如果有的话,还有其副作用。就像我之前的文章描述的,“[良好的系统架构的五个特征][18]”,如果你能够去设计一个系统,数据和主体描述是至关重要的。在此,在我们的微服务描述上,我们要去看看为什么这些是如此重要。因为对我来说,微服务架构的关键定义是可分解性。如果你要分解 ^[注5][8] 你的架构,你必须非常、非常地清楚每个细节(“组件”)要做什么。 + +在这里,就要开始考虑安全了。特定组件的准确描述可以让你: + +* 审查您的设计 +* 确保您的实现符合描述 +* 提出可重用测试单元来审查功能 +* 跟踪实施中的错误并纠正错误 +* 测试意料之外的产出 +* 监视不当行为 +* 审核未来可能的实际行为 + +现在,这些微服务能用在一个大型架构里了吗?是的。但如果实体是在更复杂的配置中彼此链接或组合在一起,它们会随之越来越难。当你让一小部分可以彼此配合工作时,确保正确的实施和行为是非常、非常容易的。并且如果你不能确定单个组件正在做它们应该作的,那么确保其衍生出来的复杂系统的正确行为及不正确行为就困难的多了。 + +而且还不止于此。如我已经在许多[以往场合][19]提过的,写足够安全的代码是困难的^[注7][9] ,证实它应该做的更加困难。因此,有理由限制有特定安全要求的代码——密码检测、加密、加密密钥管理、授权等等——将它们变成小而定义明确的代码块。然后你就可以执行我上面提及所有工作,以确保正确完成。 + +还有,我们都知道并不是每个人都擅长于编写与安全相关的代码。通过分解你的体系架构,将安全敏感的代码限制到定义明确的组件中,你就可以把你最棒的安全人员放到这方面,并限制了 J.佛系.码奴 ^[注8][10] 绕过或降级一些关键的安全控制措施的危险。 + +它可以作为学习的机会:它对于设计/实现/测试/监视的兄弟们都是好的,而且给他们说:“听、读、标记、学习,并且引为己用 ^[注9][11] 。这是应该做的。” + +是否应该将所有遗留应用程序分解为微服务? 不一定。 但是考虑到其带来的好处,你可以考虑从安全入手。 + +* * * + +- 注1、有一点——有读者总是好的。 +- 注2、这是我写下文章的意义。 +- 注3、可能没那么有趣。 +- 注4、在我写这篇文章时。我或你们中的一个可能会去编辑改变它。 +- 注5、这很有趣,听起来想一个园艺术语。并不是说我很喜欢园艺,但仍然... ^[注6][12] +- 注6、有意思的是,我最先写的 “如果你要分解你的架构....” 听起来想是一个 IT 主题的谋杀电影标题。 +- 注7、长期读者可能会记得提到的优秀电影 “The Thick of It” +- 注8、其他的什么人:请随便选择。 +- 注9、不是加密摘要digest:我不认同原作者的想法。 + +这篇文章最初出在[爱丽丝、伊娃与鲍伯](https://zh.wikipedia.org/zh-hans/%E6%84%9B%E9%BA%97%E7%B5%B2%E8%88%87%E9%AE%91%E4%BC%AF)——一个安全博客上,并被许可转载。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/11/microservices-are-security-issue + +作者:[Mike Bursell][a] +译者:[erlinux](https://itxdm.me) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mikecamel +[1]:https://blog.openshift.com/microservices-how-to-explain-them-to-your-ceo/?intcmp=7016000000127cYAAQ&amp;amp;amp;amp;amp;amp;amp;src=microservices_resource_menu1 +[2]:https://www.openshift.com/promotions/microservices.html?intcmp=7016000000127cYAAQ&amp;amp;amp;amp;amp;amp;amp;src=microservices_resource_menu2 +[3]:https://opensource.com/business/16/11/secured-devops-microservices?src=microservices_resource_menu3 +[4]:https://opensource.com/article/17/11/microservices-are-security-issue?rate=GDH4xOWsgYsVnWbjEIoAcT_92b8gum8XmgR6U0T04oM +[5]:https://opensource.com/article/17/11/microservices-are-security-issue#1 +[6]:https://opensource.com/article/17/11/microservices-are-security-issue#2 +[7]:https://opensource.com/article/17/11/microservices-are-security-issue#3 +[8]:https://opensource.com/article/17/11/microservices-are-security-issue#5 +[9]:https://opensource.com/article/17/11/microservices-are-security-issue#7 +[10]:https://opensource.com/article/17/11/microservices-are-security-issue#8 +[11]:https://opensource.com/article/17/11/microservices-are-security-issue#9 +[12]:https://opensource.com/article/17/11/microservices-are-security-issue#6 +[13]:https://aliceevebob.com/2017/10/31/why-microservices-are-a-security-issue/ +[14]:https://opensource.com/user/105961/feed +[15]:https://opensource.com/tags/security +[16]:https://aliceevebob.com/2017/03/14/systems-security-why-it-matters/ +[17]:https://opensource.com/article/17/11/microservices-are-security-issue#4 +[18]:https://opensource.com/article/17/10/systems-architect +[19]:https://opensource.com/users/mikecamel +[20]:https://opensource.com/users/mikecamel +[21]:https://opensource.com/users/mikecamel +[22]:https://opensource.com/article/17/11/microservices-are-security-issue#comments +[23]:https://opensource.com/resources/what-are-microservices +[24]:https://en.wikipedia.org/wiki/Microservices +[25]:https://en.wikipedia.org/wiki/Unix_philosophy diff --git a/published/201804/20171205 7 rules for avoiding documentation pitfalls.md b/published/201804/20171205 7 rules for avoiding documentation pitfalls.md new file mode 100644 index 0000000000..76cc9b6eaf --- /dev/null +++ b/published/201804/20171205 7 rules for avoiding documentation pitfalls.md @@ -0,0 +1,72 @@ +防止文档陷阱的 7 条准则 +====== +> 让我们了解一下如何使国外读者更容易理解你的技术文章。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-docdish-typewriterkeys-4-series.png?itok=ccZISDxR) + +英语是开源社区的通用语言。为了减少翻译成本,很多团队都改成用英语来写他们的文档。 但奇怪的是,为国际读者写英语并不一定就意味着以英语为母语的人就占据更多的优势。 相反, 他们往往忘记了该文档用的语言可能并不是读者的母语。 + +我们以下面这个简单的句子为例: “Encrypt the password using the `foo bar` command。”语法上来说,这个句子是正确的。 鉴于动名词的 “-ing” 形式在英语中很常见,大多数的母语人士都认为这是一种优雅的表达方式, 他们通常会很自然的写出这样的句子。 但是仔细观察, 这个句子存在歧义因为 “using” 可能指的宾语(“the password”)也可能指的动词(“encrypt”)。 因此这个句子有两种解读方式: + + * “加密使用了 `foo bar` 命令的密码。” + * “使用命令 `foo bar` 来加密密码。” + +如果你有相关的先验知识(密码加密或者 `foo bar` 命令),你可以消除这种不确定性并且明白第二种方式才是真正的意思。 但是若你没有足够深入的知识怎么办呢? 如果你并不是这方面的专家,而只是一个拥有泛泛相关知识的翻译者而已怎么办呢? 再或者,如果你只是个非母语人士且对像动名词这种高级语法不熟悉怎么办呢? + +即使是英语为母语的人也需要经过训练才能写出清晰直接的技术文档。训练的第一步就是提高对文本可用性以及潜在问题的警觉性, 下面让我们来看一下可以帮助避免常见陷阱的 7 条规则。 + +### 1、了解你的目标读者并代入其中。 + +如果你是一名开发者,而写作的对象是最终用户, 那么你需要站在他们的角度来看这个产品。 文档的结构是否反映了用户的目标? [人格面具persona 技术][1] 能帮你专注于目标受众并为你的读者提供合适层次的细节。 + +### 2、遵循 KISS 原则——保持文档简短而简单 + +这个原则适用于多个层次,从语法,句子到单词。 比如: + + * 使用合适的最简单时态。比如, 当提到一个动作的结果时使用现在时: + * " ~~Click 'OK.' The 'Printer Options' dialog will appear.~~ " -> "Click 'OK.' The 'Printer Options' dialog appears." + * 按经验来说,一个句子表达一个主题;然而, 短句子并不一定就容易理解(尤其当这些句子都是由名词组成时)。 有时, 将句子裁剪过度可能会引起歧义,而反过来太多单词则又难以理解。 + * 不常用的以及很长的单词会降低阅读速度,而且可能成为非母语人士的障碍。 使用更简单的替代词语: + * " ~~utilize~~ " -> "use" + * " ~~indicate~~ " -> "show","tell" 或 "say" + * " ~~prerequisite~~ " -> "requirement" + +### 3、不要干扰阅读流 + +将虚词和较长的插入语移到句子的首部或者尾部: + + * " ~~They are not, however, marked as installed.~~ " -> "However, they are not marked as installed." + +将长命令放在句子的末尾可以让自动/半自动的翻译拥有更好的断句。 + +### 4、区别对待两种基本的信息类型 + +描述型信息以及任务导向型信息有必要区分开来。描述型信息的一个典型例子就是命令行参考, 而 HOWTO 则是属于基于任务的信息;(LCTT 译注:HOWTO 文档是 Linux 文档中的一种)然而, 技术写作中都会涉及这两种类型的信息。 仔细观察, 就会发现许多文本都同时包含了两种类型的信息。 然而如果能够清晰地划分这两种类型的信息那必是极好的。 为了更好地区分它们,可以对它们进行分别标记。 标题应该能够反映章节的内容以及信息的类型。 对描述性章节使用基于名词的标题(比如“Types of Frobnicators”),而对基于任务的章节使用口头表达式的标题(例如“Installing Frobnicators”)。 这可以让读者快速定位感兴趣的章节而跳过对他无用的章节。 + +### 5、考虑不同的阅读场景和阅读模式 + +有些读者在阅读产品文档时会由于自己搞不定而感到十分的沮丧。他们在一个嘈杂的环境中工作,也很难专注于阅读。 同时,不要期望你的读者会一页一页的进行阅读,很多人都是快速浏览文本,搜索关键字或者通过表格、索引以及全文搜索的方式来查找主题。 请牢记这一点, 从不同的角度来看待你的文字。 通常需要折中才能找到一种适合多种情况的文本结构。 + +### 6、将复杂的信息分成小块 + +这会让读者更容易记住和吸收信息。例如, 过程不应该超过 7 到 10 个步骤(根据认知心理学中的 [米勒法则][2])。 如果需要更多的步骤, 那么就将任务分拆成不同的过程。 + +### 7、形式遵循功能 + +根据以下问题检查你的文字:某句话/段落/章节的 _目的_(功能)是什么?比如,它是一个指令呢?还是一个结果呢?还是一个警告呢?如果是指令, 使用主动语气: “Configure the system.” 被动语气可能适合于进行描述: “The system is configured automatically.” 将警告放在危险操作的 _前面_ 。 专注于目的还有助于发现冗余的内容,可以清除类似 “basically” 或者 “easily” 这一类的填充词,类似 “~~already~~ existing ” 或“ ~~completely~~ new” 这一类的不必要的修饰, 以及任何与你的目标大众无关的内容。 + +你现在可能已经猜到了,写作就是一个不断重写的过程。 好的写作需要付出努力和练习。 即使你只是偶尔写点东西, 你也可以通过关注目标大众并遵循上述规则来显著地改善你的文字。 文字的可读性越好, 理解就越容易, 这一点对不同语言能力的读者来说都是适合的。 尤其是当进行本地化时, 高质量的原始文本至关重要:“垃圾进, 垃圾出”。 如果原始文本就有缺陷, 翻译所需要的时间就会变长, 从而导致更高的成本。 最坏的情况下, 翻译会导致缺陷成倍增加,需要在不同的语言版本中修正这个缺陷。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/7-rules + +作者:[Tanja Roth][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com +[1]:https://en.wikipedia.org/wiki/Persona_(user_experience) +[2]:https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two diff --git a/translated/tech/20171205 What DevOps teams really need from a CIO.md b/published/201804/20171205 What DevOps teams really need from a CIO.md similarity index 64% rename from translated/tech/20171205 What DevOps teams really need from a CIO.md rename to published/201804/20171205 What DevOps teams really need from a CIO.md index 4780ca8a26..b26a62e485 100644 --- a/translated/tech/20171205 What DevOps teams really need from a CIO.md +++ b/published/201804/20171205 What DevOps teams really need from a CIO.md @@ -1,14 +1,17 @@ CIO 真正需要 DevOps 团队做什么? ====== -IT 领导者可以从大量的 [DevOps][1] 材料和 [向 DevOps 转变][2] 所要求的文化挑战中学习。但是,你在一个 DevOps 团队面对长期或短期挑战的调整中 —— 一个 CIO 真正需要他们做的是什么呢? + +> DevOps 团队需要 IT 领导者关注三件事:沟通、技术债务和信任。 + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/cio_cloud_2.png?itok=wGdeAHVn) + +IT 领导者可以从大量的 [DevOps][1] 材料和 [向 DevOps 转变][2] 所要求的文化挑战中学习。但是,你在一个 DevOps 团队面对长期或短期的团结挑战的调整中 —— 一个 CIO 真正需要他们做的是什么呢? 在我与 DevOps 团队成员的谈话中,我听到的其中一些内容让你感到非常的意外。DevOps 专家(无论是内部团队的还是外部团队的)都希望将下列的事情放在你的 CIO 优先关注的级别。 ### 1. 沟通 -第一个也是最重要的一个,DevOps 专家需要面对面的沟通。一个经验丰富的 DevOps 团队是非常了解当前 DevOps 的趋势,以及成功、和失败的经验,并且他们非常乐意去分享这些信息。表达 DevOps 的概念是很困难的,因此,要在这种新的工作关系中保持开放,定期(不用担心,不用每周)讨论有关你的 IT 的当前状态,如何评价你的沟通环境,以及你的整体的 IT 产业。 - -**[想从领导 DevOps 的 CIO 们处学习更多的知识吗?查看我们的综合资源,[DevOps: IT 领导者指南][3]。 ]** +第一个也是最重要的一个,DevOps 专家需要面对面的沟通。一个经验丰富的 DevOps 团队是非常了解当前 DevOps 的趋势,以及成功和失败的经验,并且他们非常乐意去分享这些信息。表达 DevOps 的概念是很困难的,因此,要在这种新的工作关系中保持开放,定期(不用担心,不用每周)讨论有关你的 IT 的当前状态,如何评价你的沟通环境,以及你的整体的 IT 产业。 相反,你应该准备好与 DevOps 团队去共享当前的业务需求和目标。业务不再是独立于 IT 的东西:它们现在是驱动 IT 发展的重要因素,并且 IT 决定了你的业务需求和目标运行的效果如何。 @@ -16,19 +19,17 @@ IT 领导者可以从大量的 [DevOps][1] 材料和 [向 DevOps 转变][2] 所 ### 2. 降低技术债务 -第二,力争更好地理解技术债务,并在 DevOps 中努力降低它。你的 DevOps 团队面对的工作都非常难。在这种情况下,技术债务是指在一个庞大的、不可持续的环境(查看 Rube Goldberg)之中,通过维护和增加新功能而占用的人力资源和基础设备资源。 +第二,力争更好地理解技术债务,并在 DevOps 中努力降低它。你的 DevOps 团队都工作于一线。这里,“技术债务”是指在一个庞大的、不可持续发展的环境之中,通过维护和增加新功能而占用的人力资源和基础设备资源(查看 Rube Goldberg)。 -常见的 CIO 问题包括: +CIO 常见的问题包括: * 为什么我们要用一种新方法去做这件事情? * 为什么我们要在它上面花费时间和金钱? * 如果这里没有新功能,只是现有组件实现了自动化,那么我们的收益是什么? +“如果没有坏,就不要去修理它”,这样的事情是可以理解的。但是,如果你正在路上好好的开车,而每个人都加速超过你,这时候,你的环境就被破坏了。持续投入宝贵的资源去支撑或扩张拼凑起来的环境。 - -"如果没有坏,就不要去修理它“ ,这样的事情是可以理解的。但是,如果你正在路上好好的开车,而每个人都加速超过你,这时候,你的环境就被破坏了。持续投入宝贵的资源去支撑或扩张拼凑起来的环境。 - -选择妥协,并且一个接一个的打补丁,以这种方式去处理每个独立的问题,结果将从一开始就变得很糟糕 —— 在一个不能支撑建筑物的地基上,一层摞一层地往上堆。事实上,这种方法就像不断地在电脑中插入坏磁盘一样。迟早有一天,面对出现的问题,你将会毫无办法。在外面持续增加的压力下,整个事情将变得一团糟,完全吞噬掉你的资源。 +选择妥协,并且一个接一个的打补丁,以这种方式去处理每个独立的问题,结果将从一开始就变得很糟糕 —— 在一个不能支撑建筑物的地基上,一层摞一层地往上堆。事实上,这种方法就像不断地在电脑中插入坏磁盘一样。迟早有一天,面对出现的问题你将会毫无办法。在外面持续增加的压力下,整个事情将变得一团糟,完全吞噬掉你的资源。 这种情况下,解决方案就是:自动化。使用自动化的结果是良好的可伸缩性 —— 每个维护人员在 IT 环境的维护和增长方面花费更少的努力。如果增加人力资源是实现业务增长的唯一办法,那么,可伸缩性就是白日做梦。 @@ -36,7 +37,7 @@ IT 领导者可以从大量的 [DevOps][1] 材料和 [向 DevOps 转变][2] 所 ### 3. 信任 -最后,相信你的 DevOps 团队并且一定要理解他们。DevOps 专家也知道这个要求很难,但是他们必须有你的强大支持和你参与实践的意愿。因为 DevOps 团队持续改进你的 IT 环境,他们自身也在不断地适应这些变化的技术,而这些变化通常正是 “你要去学习的经验”。 +最后,相信你的 DevOps 团队并且一定要理解他们。DevOps 专家也知道这个要求很难,但是他们必须得到你的强大支持和你积极参与的意愿。因为 DevOps 团队持续改进你的 IT 环境,他们自身也在不断地适应这些变化的技术,而这些变化通常正是 “你要去学习的经验”。 倾听,倾听,倾听他们,并且相信他们。DevOps 的改变是非常有价值的,而且也是值的去投入时间和金钱的。它可以提高效率、生产力、和业务响应能力。信任你的 DevOps 团队,并且给予他们更多的自由,实现更高效率的 IT 改进。 @@ -48,7 +49,7 @@ via: https://enterprisersproject.com/article/2017/12/what-devops-teams-really-ne 作者:[John Allessio][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/tech/20171207 How to use KVM cloud images on Ubuntu Linux.md b/published/201804/20171207 How to use KVM cloud images on Ubuntu Linux.md similarity index 56% rename from sources/tech/20171207 How to use KVM cloud images on Ubuntu Linux.md rename to published/201804/20171207 How to use KVM cloud images on Ubuntu Linux.md index 4420807de7..4358b13428 100644 --- a/sources/tech/20171207 How to use KVM cloud images on Ubuntu Linux.md +++ b/published/201804/20171207 How to use KVM cloud images on Ubuntu Linux.md @@ -1,15 +1,16 @@ -How to use KVM cloud images on Ubuntu Linux -====== +如何在 Ubuntu Linux 上使用 KVM 云镜像 +===== -Kernel-based Virtual Machine (KVM) is a virtualization module for the Linux kernel that turns it into a hypervisor. You can create an Ubuntu cloud image with KVM from the command line using Ubuntu virtualisation front-end for libvirt and KVM. +如何下载并使用运行在 Ubuntu Linux 服务器上的 KVM 云镜像?如何在 Ubuntu Linux 16.04 LTS 服务器上无需完整安装即可创建虚拟机?如何在 Ubuntu Linux 上使用 KVM 云镜像? -How do I download and use a cloud image with kvm running on an Ubuntu Linux server? How do I create create a virtual machine without the need of a complete installation on an Ubuntu Linux 16.04 LTS server?Kernel-based Virtual Machine (KVM) is a virtualization module for the Linux kernel that turns it into a hypervisor. You can create an Ubuntu cloud image with KVM from the command line using Ubuntu virtualisation front-end for libvirt and KVM. +基于内核的虚拟机(KVM)是 Linux 内核的虚拟化模块,可将其转变为虚拟机管理程序。你可以在命令行使用 Ubuntu 为 libvirt 和 KVM 提供的虚拟化前端通过 KVM 创建 Ubuntu 云镜像。 -This quick tutorial shows to install and use uvtool that provides a unified and integrated VM front-end to Ubuntu cloud image downloads, libvirt, and cloud-init. +这个快速教程展示了如何安装和使用 uvtool,它为 Ubuntu 云镜像下载,libvirt 和 clout_int 提供了统一的集成虚拟机前端。 -### Step 1 - Install KVM +### 步骤 1 - 安装 KVM + +你必须安装并配置 KVM。使用 [apt 命令][1]/[apt-get 命令][2],如下所示: -You must have kvm installed and configured. Use the [apt command][1]/[apt-get command][2] as follows: ``` $ sudo apt install qemu-kvm libvirt-bin virtinst bridge-utils cpu-checker $ kvm-ok @@ -18,15 +19,19 @@ $ sudo vi /etc/network/interfaces $ sudo systemctl restart networking $ sudo brctl show ``` -See "[How to install KVM on Ubuntu 16.04 LTS Headless Server][4]" for more info. -### Step 2 - Install uvtool +参阅[如何在 Ubuntu 16.04 LTS Headless 服务器上安装 KVM][4] 以获得更多信息。(LCTT 译注:Headless 服务器是指没有本地接口的计算设备,专用于向其他计算机及其用户提供服务。) + +### 步骤 2 - 安装 uvtool + +键入以下 [apt 命令][1]/[apt-get 命令][2]: -Type the following [apt command][1]/[apt-get command][2]: ``` $ sudo apt install uvtool ``` -Sample outputs: + +示例输出: + ``` [sudo] password for vivek: Reading package lists... Done @@ -96,47 +101,68 @@ Processing triggers for man-db (2.7.6.1-2) ... Setting up uvtool-libvirt (0~git122-0ubuntu1) ... ``` +### 步骤 3 - 下载 Ubuntu 云镜像 -### Step 3 - Download the Ubuntu Cloud image +你需要使用 `uvt-simplestreams-libvirt` 命令。它维护一个 libvirt 容量存储池,作为一个简单流simplestreams源的镜像子集的本地镜像,比如 Ubuntu 云镜像。要使用当前所有 amd64 镜像更新 uvtool 的 libvirt 容量存储池,运行: + +``` +$ uvt-simplestreams-libvirt sync arch=amd64 +``` + +要更新/获取 Ubuntu 16.04 LTS (xenial/amd64) 镜像,运行: + +``` +$ uvt-simplestreams-libvirt --verbose sync release=xenial arch=amd64 +``` + +示例输出: -You need to use the uvt-simplestreams-libvirt command. It maintains a libvirt volume storage pool as a local mirror of a subset of images available from a simplestreams source, such as Ubuntu cloud images. To update uvtool's libvirt volume storage pool with all current amd64 images, run: -`$ uvt-simplestreams-libvirt sync arch=amd64` -To just update/grab Ubuntu 16.04 LTS (xenial/amd64) image run: -`$ uvt-simplestreams-libvirt --verbose sync release=xenial arch=amd64` -Sample outputs: ``` Adding: com.ubuntu.cloud:server:16.04:amd64 20171121.1 ``` -Pass the query option to queries the local mirror: -`$ uvt-simplestreams-libvirt query` -Sample outputs: +通过 query 选项查询本地镜像: + +``` +$ uvt-simplestreams-libvirt query +``` + +示例输出: + ``` release=xenial arch=amd64 label=release (20171121.1) ``` -Now, I have an image for Ubuntu xenial and I create the VM. +现在,我为 Ubuntu xenial 创建了一个镜像,接下来我会创建虚拟机。 -### Step 4 - Create the SSH keys +### 步骤 4 - 创建 SSH 密钥 -You need ssh keys for login into KVM VMs. Use the ssh-keygen command to create a new one if you do not have any keys at all. -`$ ssh-keygen` -See "[How To Setup SSH Keys on a Linux / Unix System][5]" and "[Linux / UNIX: Generate SSH Keys][6]" for more info. +你需要使用 SSH 密钥才能登录到 KVM 虚拟机。如果你根本没有任何密钥,请使用 `ssh-keygen` 命令创建一个新的密钥。 -### Step 5 - Create the VM +``` +$ ssh-keygen +``` -It is time to create the VM named vm1 i.e. create an Ubuntu Linux 16.04 LTS VM: -`$ uvt-kvm create vm1` -By default vm1 created using the following characteristics: +参阅“[如何在 Linux / Unix 系统上设置 SSH 密钥][5]” 和 “[Linux / UNIX: 生成 SSH 密钥][6]” 以获取更多信息。 - 1. RAM/memory : 512M - 2. Disk size: 8GiB - 3. CPU: 1 vCPU core +### 步骤 5 - 创建 VM +是时候创建虚拟机了,它叫 vm1,即创建一个 Ubuntu Linux 16.04 LTS 虚拟机: +``` +$ uvt-kvm create vm1 +``` -To control ram, disk, cpu, and other characteristics use the following syntax: -`$ uvt-kvm create vm1 \ +默认情况下 vm1 使用以下配置创建: + + 1. 内存:512M + 2. 磁盘大小:8GiB + 3. CPU:1 vCPU core + +要控制内存、磁盘、CPU 和其他配置,使用以下语法: + +``` +$ uvt-kvm create vm1 \ --memory MEMORY \ --cpu CPU \ --disk DISK \ @@ -145,80 +171,100 @@ To control ram, disk, cpu, and other characteristics use the following syntax: --packages PACKAGES1, PACKAGES2, .. \ --run-script-once RUN_SCRIPT_ONCE \ --password PASSWORD -` -Where, +``` - 1. **\--password PASSWORD** : Set the password for the ubuntu user and allow login using the ubuntu user (not recommended use ssh keys). - 2. **\--run-script-once RUN_SCRIPT_ONCE** : Run RUN_SCRIPT_ONCE script as root on the VM the first time it is booted, but never again. Give full path here. This is useful to run custom task on VM such as setting up security or other stuff. - 3. **\--packages PACKAGES1, PACKAGES2, ..** : Install the comma-separated packages on first boot. +其中 + 1. `--password PASSWORD`:设置 ubuntu 用户的密码和允许使用 ubuntu 的用户登录(不推荐,使用 ssh 密钥)。 + 2. `--run-script-once RUN_SCRIPT_ONCE` : 第一次启动时,在虚拟机上以 root 身份运行 `RUN_SCRIPT_ONCE` 脚本,但再也不会运行。这里给出完整的路径。这对于在虚拟机上运行自定义任务时非常有用,例如设置安全性或其他内容。 + 3. `--packages PACKAGES1, PACKAGES2, ..` : 在第一次启动时安装以逗号分隔的软件包。 +要获取帮助,运行: -To get help, run: ``` $ uvt-kvm -h $ uvt-kvm create -h ``` -#### How do I delete my VM? +#### 如何删除虚拟机? -To destroy/delete your VM named vm1, run (please use the following command with care as there would be no confirmation box): -`$ uvt-kvm destroy vm1` +要销毁/删除名为 vm1 的虚拟机,运行(请小心使用以下命令,因为没有确认框): -#### To find out the IP address of the vm1, run: +``` +$ uvt-kvm destroy vm1 +``` -`$ uvt-kvm ip vm1` +#### 获取 vm1 的 IP 地址,运行: + +``` +$ uvt-kvm ip vm1 192.168.122.52 +``` -#### To list all VMs run +#### 列出所有运行的虚拟机 + +``` +$ uvt-kvm list +``` + +示例输出: -`$ uvt-kvm list` -Sample outputs: ``` vm1 freebsd11.1 - ``` -### Step 6 - How to login to the vm named vm1 +### 步骤 6 - 如何登录 vm1 + +语法是: + +``` +$ uvt-kvm ssh vm1 +``` + +示例输出: -The syntax is: -`$ uvt-kvm ssh vm1` -Sample outputs: ``` Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-101-generic x86_64) - comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated 选题模板.txt 中文排版指北.md Documentation: https://help.ubuntu.com - comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated 选题模板.txt 中文排版指北.md Management: https://landscape.canonical.com - comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated 选题模板.txt 中文排版指北.md Support: https://ubuntu.com/advantage + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage - Get cloud support with Ubuntu Advantage Cloud Guest: - http://www.ubuntu.com/business/services/cloud + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. -Last login: Thu Dec 7 09:55:06 2017 from 192.168.122.1 - +Last login: Thu Dec 7 09:55:06 2017 from 192.168.122.1 ``` -Another option is to use the regular ssh command from macOS/Linux/Unix/Windows client: -`$ ssh [[email protected]][7] -$ ssh -i ~/.ssh/id_rsa [[email protected]][7]` -Sample outputs: -[![Connect to the running VM using ssh][8]][8] -Once vim created you can use the virsh command as usual: -`$ virsh list` +另一个选择是从 macOS/Linux/Unix/Windows 客户端使用常规的 ssh 命令: +``` +$ ssh ubuntu@192.168.122.52 +$ ssh -i ~/.ssh/id_rsa ubuntu@192.168.122.52 +``` + +示例输出: + +[![Connect to the running VM using ssh][8]][8] + +一旦创建了 vim,你可以照常使用 `virsh` 命令: + +``` +$ virsh list +``` -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/faq/how-to-use-kvm-cloud-images-on-ubuntu-linux/ 作者:[Vivek Gite][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20171212 Oh My Fish- Make Your Shell Beautiful.md b/published/201804/20171212 Oh My Fish- Make Your Shell Beautiful.md new file mode 100644 index 0000000000..4920b7c021 --- /dev/null +++ b/published/201804/20171212 Oh My Fish- Make Your Shell Beautiful.md @@ -0,0 +1,283 @@ +Oh My Fish! 让你的 Shell 漂亮起来 +===== + +![](https://www.ostechnix.com/wp-content/uploads/2017/12/oh-my-fish-720x340.jpg) + +几天前,我们讨论了如何[安装 Fish shell][1],这是一个健壮的、完全可用的 shell,带有许多很酷的功能,如自动建议、内置搜索功能、语法高亮显示、基于 web 配置等等。今天,我们将讨论如何使用 Oh My Fish (简称 `omf` ) 让我们的 Fish shell 变得漂亮且优雅。它是一个 Fishshell 框架,允许你安装扩展或更改你的 shell 外观的软件包。它简单易用,快速可扩展。使用 `omf`,你可以根据你的想法,很容易地安装主题,丰富你的外观和安装插件来调整你的 Fish shell。 + +### 安装 Oh My Fish + +安装 omf 很简单。你要做的只是在你的 Fish shell 中运行下面的命令。 + +``` +curl -L https://get.oh-my.fish | fish +``` + +![][3] + +一旦安装完成,你将看到提示符已经自动更改,如上图所所示。另外,你会注意到当前时间在 shell 窗口的右边。 + +就是这样。让我们继续并调整我们的 fish shell。 + +### 现在,让我们将 Fish Shell 变漂亮 + +列出所有的安装包,运行: + +``` +omf list +``` + +这条命令将显示已安装的主题和插件。请注意,包可以是主题或插件。安装包意味着安装主题和插件。 + +所有官方和社区支持的包(包括插件和主题)都托管在 [Omf 主仓库][4] 中。在这个主仓库中,你可以看到大量的仓库,其中包含大量的插件和主题。 + +现在让我们看一下可用的和已安装的主题列表。为此,运行: + +``` +omf theme +``` + +![][5] + +如你所见,我们只有一个已安装的主题,这是默认的,但是还有大量可用的主题。在安装之前,你在[这里][6]可以预览所有可用的主题。这个页面包含了所有的主题细节,特性,每个主题的截图示例,以及哪个主题适合谁。 + +#### 安装一个新主题 + +请允许我安装一个主题,例如 clearance 主题,这是一个极简的 fish shell 主题,供那些经常使用 `git` 的人使用。为此,运行: + +``` +omf install clearance +``` + +![][7] + +如上图所示,在安装新主题后,Fish shell 的提示立即发生了变化。 + +让我浏览一下系统文件,看看它如何显示。 + +![][8] + +看起来不错!这是一个非常简单的主题。它将当前工作目录,文件夹和文件以不同的颜色区分开来。你可能会注意到,它还会在提示符的顶部显示当前工作目录。现在,clearance 是我的默认主题。 + +#### 改变主题 + +就像我之前说的一样,这个主题在安装后被立即应用。如果你有多个主题,你可以使用以下命令切换到另一个不同的主题: + +``` +omf theme +``` + +例如: + +``` +omf theme agnoster +``` + +现在我正在使用 agnoster 主题。 agnoster 就是这样改变了我 shell 的外观。 + +![][9] + +#### 安装插件 + +例如,我想安装一个天气插件。为此,只要运行: + +``` +omf install weather +``` + +天气插件依赖于 [jq][10](LCTT 译注:jq 是一个轻量级且灵活的命令行JSON处理器)。所以,你可能也需要安装 `jq`。它通常在 Linux 发行版的默认仓库中存在。因此,你可以使用默认的包管理器来安装它。例如,以下命令将在 Arch Linux 及其衍生版中安装 `jq`。 + +``` +sudo pacman -S jq +``` + +现在,在 Fish shell 中使用以下命令查看天气: + +``` +weather +``` + +![][11] + +#### 寻找包 + +要搜索主题或插件,请执行以下操作: + +``` +omf search +``` + +例如: + +``` +omf search nvm +``` + +为了限制搜索的主题范围,使用 `-t` 选项。 + +``` +omf search -t chain +``` + +这条命令只会搜索主题名字中包含 “chain” 的主题。 + +为了限制搜索的插件范围,使用 `-p` 选项。 + +``` +omf search -p emacs +``` + +#### 更新包 + +要仅更新核心功能(`omf` 本身),运行: + +``` +omf update omf +``` + +如果是最新的,你会看到以下输出: + +``` +Oh My Fish is up to date. +You are now using Oh My Fish version 6. +Updating https://github.com/oh-my-fish/packages-main master... Done! +``` + +更新所有包: + +``` +omf update +``` + +要有选择地更新软件包,只需包含如下所示的包名称: + +``` +omf update clearance agnoster +``` + +#### 显示关于包的信息 + +当你想知道关于一个主题或插件的信息时,使用以下命令: + +``` +omf describe clearance +``` + +这条命令将显示关于包的信息。 + +``` +Package: clearance +Description: A minimalist fish shell theme for people who use git +Repository: https://github.com/oh-my-fish/theme-clearance +Maintainer: +``` + +#### 移除包 + +移除一个包,例如 emacs,运行: + +``` +omf remove emacs +``` + +#### 管理仓库 + +默认情况下,当你安装了 Oh My Fish 时,会自动添加官方仓库。这个仓库包含了开发人员构建的所有包。要管理用户安装的仓库包,使用这条命令: + +``` +omf repositories [list|add|remove] +``` + +列出所有安装的仓库,运行: + +``` +omf repositories list +``` + +添加一个仓库: + +``` +omf repositories add +``` + +例如: + +``` +omf repositories add https://github.com/ostechnix/theme-sk +``` + +移除一个仓库: + +``` +omf repositories remove +``` + +#### Oh My Fish 排错 + +如果出现了错误,`omf` 足够聪明来帮助你,它可以列出解决问题的方法。例如,我安装了 clearance 包,得到了文件冲突的错误。幸运的是,在继续之前,Oh My Fish 会指示我该怎么做。因此,我只是简单地运行了以下代码来了解如何修正错误。 + +``` +omf doctor +``` + +通过运行以下命令来解决错误: + +``` +rm ~/.config/fish/functions/fish_prompt.fish +``` + +![][12] + +无论你何时遇到问题,只要运行 `omf doctor` 命令,并尝试所有的建议方法。 + +#### 获取帮助 + +显示帮助部分,运行: + +``` +omf -h +``` + +或者 + +``` +omf --help +``` + +#### 卸载 Oh My Fish + +卸载 Oh My Fish,运行以下命令: + +``` +omf destroy +``` + +继续前进,开始自定义你的 fish shell。获取更多细节,请参考项目的 GitHub 页面。 + +这就是全部了。我很快将会在这里开始另一个有趣的指导。在此之前,请继续关注我们! + +干杯! + + +-------------------------------------------------------------------------------- +via: https://www.ostechnix.com/oh-fish-make-shell-beautiful/ + +作者:[SK][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/install-fish-friendly-interactive-shell-linux/ +[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[3]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-1-1.png() +[4]:https://github.com/oh-my-fish +[5]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-5.png() +[6]:https://github.com/oh-my-fish/oh-my-fish/blob/master/docs/Themes.md +[7]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-3.png() +[8]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-4.png() +[9]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-6.png() +[10]:https://stedolan.github.io/jq/ +[11]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-7.png() +[12]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-8.png() diff --git a/translated/tech/20171219 How to generate webpages using CGI scripts.md b/published/201804/20171219 How to generate webpages using CGI scripts.md similarity index 61% rename from translated/tech/20171219 How to generate webpages using CGI scripts.md rename to published/201804/20171219 How to generate webpages using CGI scripts.md index 47d424303a..f8a7861716 100644 --- a/translated/tech/20171219 How to generate webpages using CGI scripts.md +++ b/published/201804/20171219 How to generate webpages using CGI scripts.md @@ -1,28 +1,33 @@ 如何使用 CGI 脚本生成网页 ====== -回到互联网的开端,当我第一次创建了我的第一个商业网站,生活是无比的美好。 +> 通用网关接口(CGI)提供了使用任何语言生成动态网站的简易方法。 -我安装 Apache 并写了一些简单的 HTML 网页,网页上列出了一些关于我的业务的重要信息,比如产品概览以及如何联系我。这是一个静态网站,因为内容很少改变。由于网站的内容很少改变这一性质,因此维护起来也很简单。 +回到互联网的开端,当我第一次创建了我的第一个商业网站,生活是如此的美好。 -## 静态内容 +我安装 Apache 并写了一些简单的 HTML 网页,网页上列出了一些关于我的业务的重要信息,比如产品概览以及如何联系我。这是一个静态网站,因为内容很少改变。由于网站的内容很少发生改变这一性质,因此维护起来也很简单。 -静态内容很简单,同时也很常见。让我们快速的浏览一些静态网页的例子。你不需要一个可运行网站来执行这些小实验,只需要把这些文件放到 home 目录,然后使用浏览器打开。你所看到的内容将和通过 web 服务器提供这一文件看到的内容一样。 +### 静态内容 + +静态内容很简单,同时也很常见。让我们快速的浏览一些静态网页的例子。你不需要一个可运行网站来执行这些小实验,只需要把这些文件放到家目录,然后使用浏览器打开。你所看到的内容将和通过 Web 服务器提供这一文件看到的内容一样。 + +对于一个静态网站,你需要的第一件东西就是 `index.html` 文件,该文件通常放置在 `/var/www/html` 目录下。这个文件的内容可以非常简单,比如可以是像 “Hello, world” 这样一句短文本,没有任何 HTML 标记。它将简单的展示文本串内容。在你的家目录创建 `index.html` 文件,并添加 “hello, world” 作为内容(不需要引号)。在浏览器中通过下面的链接来打开这一文件: -对于一个静态网站,你需要的第一件东西就是 index.html 文件,该文件通常放置在 `/var/www/html` 目录下。这个文件的内容可以非常简单,比如可以是像 "Hello, world" 这样一句短文本,没有任何 HTML 标记。它将简单的展示文本串内容。在你的 home 目录创建 index.html 文件,并添加 "hello, world" 作为内容(不需要引号)。在浏览器中通过下面的链接来打开这一文件: ``` -file:///home//index.html +file:///home/<你的家目录>/index.html ``` 所以 HTML 不是必须的,但是,如果你有大量需要格式化的文本,那么,不用 HTML 编码的网页的结果将会令人难以理解。 所以,下一步就是通过使用一些 HTML 编码来提供格式化,从而使内容更加可读。下面这一命令创建了一个具有 HTML 静态网页所需要的绝对最小标记的页面。你也可以使用你最喜欢的编辑器来创建这一内容。 + ``` echo "

Hello World

" > test1.html ``` -现在,再次查看 index.html 文件,将会看到和刚才有些不同。 +现在,再次查看 `index.html` 文件,将会看到和刚才有些不同。 + +当然,你可以在实际的内容行上添加大量的 HTML 标记,以形成更加完整和标准的网页。下面展示的是更加完整的版本,尽管在浏览器中会看到同样的内容,但这也为更加标准化的网站奠定了基础。继续在 `index.html` 中写入这些内容并通过浏览器查看。 -当然,你可以在实际的内容行上添加大量的 HTML 标记,以形成更加完整和标准的网页。下面展示的是更加完整的版本,尽管在浏览器中会看到同样的内容,但这也为更加标准化的网站奠定了基础。继续在 index.html 中写入这些内容并通过浏览器查看。 ``` @@ -37,24 +42,25 @@ echo "

Hello World

" > test1.html 我使用这些技术搭建了一些静态网站,但我的生活正在改变。 -## 动态网页 +### 动态网页 -我找了一份新工作,这份工作的主要任务就是创建并维护用于一个动态网站的 CGI([公共网关接口][6])代码。字面意思来看,动态意味着在浏览器中生成的网页所需要的 HTML 是由每次访问页面时所访问到的数据生成的。这些数据包括网页表格中的用户输入,以用来在数据库中进行数据查找,结果数据被一些恰当的 HTML 包围着并展示在所请求的浏览器中。但是这不需要非常复杂。 +我找了一份新工作,这份工作的主要任务就是创建并维护用于一个动态网站的 CGI([公共网关接口][6]Common Gateway InterfaceM)代码。字面意思来看,动态意味着在浏览器中生成的网页所需要的 HTML 是由每次访问页面时不同的数据所生成的。这些数据包括网页表单中的用户输入,以用来在数据库中进行数据查找,结果数据被一些恰当的 HTML 包围着并展示在所请求的浏览器中。但是这不需要非常复杂。 通过使用 CGI 脚本,你可以创建一些简单或复杂的交互式程序,通过运行这些程序能够生成基于输入、计算、服务器的当前条件等改变的动态页面。有许多种语言可以用来写 CGI 脚本,在这篇文章中,我将谈到的是 Perl 和 Bash ,其他非常受欢迎的 CGI 语言包括 PHP 和 Python 。 -这篇文章不会介绍 Apache 或其他任何 web 服务器的安装和配置。如果你能够访问一个你可以进行实验的 web 服务器,那么你可以直接查看它们在浏览器中出现的结果。否则,你可以在命令行中运行程序来查看它们所创建的 HTML 文本。你也可以重定向 HTML 输出到一个文件中,然后通过浏览器查看结果文件。 +这篇文章不会介绍 Apache 或其他任何 web 服务器的安装和配置。如果你能够访问一个你可以进行实验的 Web 服务器,那么你可以直接查看它们在浏览器中出现的结果。否则,你可以在命令行中运行程序来查看它们所创建的 HTML 文本。你也可以重定向 HTML 输出到一个文件中,然后通过浏览器查看结果文件。 ### 使用 Perl Perl 是一门非常受欢迎的 CGI 脚本语言,它的优势是强大的文本操作能力。 -为了使 CGI 脚本可执行,你需要在你的网站的 httpd.conf 中添加下面这行内容。这会告诉服务器可执行 CGI 文件的位置。在这次实验中,不必担心这个问题。 +为了使 CGI 脚本可执行,你需要在你的网站的 `httpd.conf` 中添加下面这行内容。这会告诉服务器可执行 CGI 文件的位置。在这次实验中,不必担心这个问题。 + ``` ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" ``` -把下面的 Perl 代码添加到文件 index.cgi,在这次实验中,这个文件应该放在你的 home 目录下。如果你使用 web 服务器,那么应把文件的所有者更改为 apache.apache,同时将文件权限设置为 755,因为无论位于哪,它必须是可执行的。 +把下面的 Perl 代码添加到文件 `index.cgi`,在这次实验中,这个文件应该放在你的家目录下。如果你使用 Web 服务器,那么应把文件的所有者更改为 `apache.apache`,同时将文件权限设置为 755,因为无论位于哪,它必须是可执行的。 ``` #!/usr/bin/perl @@ -67,11 +73,11 @@ print "\n"; 在命令行中运行这个程序并查看结果,它将会展示出它所生成的 HTML 内容 -现在,在浏览器中查看 index.cgi 文件,你所看到的只是文件的内容。浏览器的确将它看做 CGI 内容,但是,Apache 不知道需要将这个文件作为 CGI 程序运行,除非 Apache 的配置中包括上面所展示的 "ScriptAlias" 定义。没有这一配置,Apache 只会简单地将文件中的数据发送给浏览器。如果你能够访问 web 服务器,那么你可以将可执行文件放到 `/var/www/cgi-bin` 目录下。 +现在,在浏览器中查看 `index.cgi` 文件,你所看到的只是文件的内容。浏览器需要将它看做 CGI 内容,但是,Apache 不知道需要将这个文件作为 CGI 程序运行,除非 Apache 的配置中包括上面所展示的 `ScriptAlias` 定义。没有这一配置,Apache 只会简单地将文件中的数据发送给浏览器。如果你能够访问 Web 服务器,那么你可以将可执行文件放到 `/var/www/cgi-bin` 目录下。 如果想知道这个脚本的运行结果在浏览器中长什么样,那么,重新运行程序并把输出重定向到一个新文件,名字可以是任何你想要的。然后使用浏览器来查看这一文件,它包含了脚本所生成的内容。 -上面这个 CGI 程序依旧生成静态内容,因为它总是生成相同的输出。把下面这行内容添加到 CGI 程序中 "Hello, world" 这一行后面。Perl 的 "system" 命令将会执行跟在它后面的 shell 命令,并把结果返回给程序。此时,我们将会通过 `free` 命令获得当前的 RAM 使用量。 +上面这个 CGI 程序依旧生成静态内容,因为它总是生成相同的输出。把下面这行内容添加到 CGI 程序中 “Hello, world” 这一行后面。Perl 的 `system` 命令将会执行跟在它后面的 shell 命令,并把结果返回给程序。此时,我们将会通过 `free` 命令获得当前的内存使用量。 ``` system "free | grep Mem\n"; @@ -83,7 +89,7 @@ system "free | grep Mem\n"; Bash 可能是用于 CGI 脚本中最简单的语言。用 Bash 来进行 CGI 编程的最大优势是它能够直接访问所有的标准 GNU 工具和系统程序。 -把已经存在的 index.cgi 文件重命名为 Perl.index.cgi ,然后创建一个新的 index.cgi 文件并添加下面这些内容。记得设置权限使它可执行。 +把已经存在的 `index.cgi` 文件重命名为 `Perl.index.cgi`,然后创建一个新的 `index.cgi 文件并添加下面这些内容。记得设置权限使它可执行。 ``` #!/bin/bash @@ -105,7 +111,7 @@ exit 0 在命令行中执行这个文件并查看输出,然后再次运行并把结果重定向到一个临时结果文件中。然后,刷新浏览器查看它所展示的网页是什么样子。 -## 结论 +### 结论 创建能够生成许多种动态网页的 CGI 程序实际上非常简单。尽管这是一个很简单的例子,但是现在你应该看到一些可能性了。 @@ -115,7 +121,7 @@ via: https://opensource.com/article/17/12/cgi-scripts 作者:[David Both][a] 译者:[ucasFL](https://github.com/ucasFL) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20171219 How to set GNOME to display a custom slideshow.md b/published/201804/20171219 How to set GNOME to display a custom slideshow.md new file mode 100644 index 0000000000..5c9160033c --- /dev/null +++ b/published/201804/20171219 How to set GNOME to display a custom slideshow.md @@ -0,0 +1,111 @@ +如何设置 GNOME 显示自定义幻灯片 +====== + +> 使用一个简单的 XML,你就可以设置 GNOME 能够在桌面上显示一个幻灯片。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_keyboard_laptop_development_blue.png?itok=IfckxN48) + +在 GNOME 中,一个非常酷、但却鲜为人知的特性是它能够将幻灯片显示为墙纸。你可以从 [GNOME 控制中心][1]的 “背景设置” 面板中选择墙纸幻灯片。在预览的右下角显示一个小时钟标志,可以将幻灯片的墙纸与静态墙纸区别开来。 + +一些发行版带有预装的幻灯片壁纸。 例如,Ubuntu 包含了库存的 GNOME 定时壁纸幻灯片,以及 Ubuntu 壁纸大赛胜出的墙纸。 + +如果你想创建自己的自定义幻灯片用作壁纸怎么办?虽然 GNOME 没有为此提供一个用户界面,但是在你的主目录中使用一些简单的 XML 文件来创建一个是非常容易的。 幸运的是,GNOME 控制中心的背景选择支持一些常见的目录路径,这样就可以轻松创建幻灯片,而不必编辑你的发行版所提供的任何内容。 + +### 开始 + +使用你最喜欢的文本编辑器在 `$HOME/.local/share/gnome-background-properties/` 创建一个 XML 文件。 虽然文件名不重要,但目录名称很重要(你可能需要创建该目录)。 举个例子,我创建了带有以下内容的 `/home/ken/.local/share/gnome-background-properties/osdc-wallpapers.xml`: + +``` + + + + + Opensource.com Wallpapers + /home/ken/Pictures/Wallpapers/osdc/osdc.xml + zoom + + +``` + +每一个你需要包含在 GNOME 控制中心的 “背景面板”中的每个幻灯片或静态壁纸,你都要在上面的 XML 文件需要为其增加一个 `` 节点。 + +在这个例子中,我的 `osdc.xml` 文件看起来是这样的: + + +``` + + + + + 30.0 + /home/ken/Pictures/Wallpapers/osdc/osdc_2.png + + + + 0.5 + /home/ken/Pictures/Wallpapers/osdc/osdc_2.png + /home/ken/Pictures/Wallpapers/osdc/osdc_1.png + + + 30.0 + /home/ken/Pictures/Wallpapers/osdc/osdc_1.png + + + 0.5 + /home/ken/Pictures/Wallpapers/osdc/osdc_1.png + /home/ken/Pictures/Wallpapers/osdc/osdc_2.png + + +``` + +上面的 XML 中有几个重要的部分。 XML 中的 `` 节点是你的外部节点。 每个背景都支持多个 `` 和 `` 节点。 + +`` 节点定义用 `` 节点要显示的图像以及用 `` 显示它的持续时间。 + +`` 节点定义 ``(变换时长),`` 和 `` 定义了起止的图像。 + +### 全天更换壁纸 + +另一个很酷的 GNOME 功能是基于时间的幻灯片。 你可以定义幻灯片的开始时间,GNOME 将根据它计算时间。 这对于根据一天中的时间设置不同的壁纸很有用。 例如,你可以将开始时间设置为 06:00,并在 12:00 之前显示一张墙纸,然后在下午和 18:00 再次更改。 + +这是通过在 XML 中定义 `` 来完成的,如下所示: + +``` + + + 2017 + 11 + 21 + 6 + 00 + 00 + +``` + +上述 XML 文件定义于 2017 年 11 月 21 日 06:00 开始动画,时长为 21,600.00,相当于六个小时。 这段时间将显示你的早晨壁纸直到 12:00,12:00 时它会更改为你的下一张壁纸。 你可以继续以这种方式每隔一段时间更换一次壁纸,但确保所有持续时间的总计为 86,400 秒(等于 24 小时)。 + +GNOME 将计算开始时间和当前时间之间的增量,并显示当前时间的正确墙纸。 例如,如果你在 16:00 选择新壁纸,则GNOME 将在 06:00 开始时间之后显示 36,000 秒的适当壁纸。 + +有关完整示例,请参阅大多数发行版中由 gnome-backgrounds 包提供的 adwaita-timed 幻灯片。 它通常位于 `/usr/share/backgrounds/gnome/adwaita-timed.xml` 中。 + + +### 了解更多信息 + +希望这可以鼓励你深入了解创建自己的幻灯片壁纸。 如果你想下载本文中引用的文件的完整版本,那么你可以在 [GitHub][2] 上找到它们。 + +如果你对用于生成 XML 文件的实用程序脚本感兴趣,你可以在互联网上搜索 `gnome-backearth-generator`。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/create-your-own-wallpaper-slideshow-gnome + +作者:[Ken Vandine][a] +译者:[Auk7F7](https://github.com/Auk7F7) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/kenvandine +[1]:http://manpages.ubuntu.com/manpages/xenial/man1/gnome-control-center.1.html +[2]:https://github.com/kenvandine/misc/tree/master/articles/osdc/gnome/slide-show-backgrounds/osdc + diff --git a/published/201804/20171228 Testing Ansible Playbooks With Vagrant.md b/published/201804/20171228 Testing Ansible Playbooks With Vagrant.md new file mode 100644 index 0000000000..e05aa98499 --- /dev/null +++ b/published/201804/20171228 Testing Ansible Playbooks With Vagrant.md @@ -0,0 +1,127 @@ +使用 Vagrant 测试 Ansible 剧本 +====== + +我使用 Ansible 来自动部署站点 ([LinuxJobs.fr][1]、[Journal du hacker][2]) 与应用 ([Feed2toot][3]、[Feed2tweet][4])。在本文中将会讲述我是如何配置以实现在本地测试 ansbile 剧本playbook的。 + +![ansible](https://carlchenet.com/wp-content/uploads/2017/12/ansible-300x300.png) + +### 为何要测试 Ansible 剧本 + +我需要一种简单而迅速的方法来在我的本地笔记本上测试 Ansible 剧本的部署情况,尤其在刚开始写一个新剧本的时候,因为直接部署到生产服务器上不仅特别慢而且风险还很大。 + +我使用 [Vagrant][6] 来将剧本部署到 [VirtualBox][5] 虚拟机上而不是部署到远程服务器。这使得修改的结果很快就能看到,以实现快速迭代和修正。 + +责任声明:我并不是专业程序员。我只是描述一种我觉得适合我的,即简单又有效的用来测试 Ansible 剧本的解决方案,但可能还有其他更好的方法。 + +### 我的流程 + + 1. 开始写新的 Ansible 剧本 + 2. 启动一台新的虚拟机(VM)并使用 Vagrantt 将剧本部署到这台虚拟机中 + 3. 修复剧本或应用中的错误 + 4. 重新在虚拟机上部署 + 5. 如果还有问题,回到第三步。否则销毁这台虚拟机,重新创建新虚拟机然后测试一次全新部署 + 6. 若没有问题出现,则标记你的 Ansible 剧本版本,可以在生产环境上发布产品了 + +### 你需要哪些东西 + +首先,你需要 Virtualbox。若你使用的是 [Debian][7] 发行版,[这个链接][8] 描述了安装的方法,可以从 Debian 仓库中安装,也可以通过官网来安装。 + +[![][9]][5] + +其次,你需要 Vagrant。为什么要 Vagrant?因为它是介于开发环境和虚拟机之间的中间件,它允许通过编程的方式重复操作,而且可以很方便地将你的部署环境与虚拟机连接起来。通过下面命令可以安装 Vagrant: +``` +# apt install vagrant +``` + +[![][10]][6] + +### 设置 Vagrant + +Vagrant 的一切信息都存放在 `Vagrantfile` 文件中。这是我的内容: + +``` +Vagrant.require_version ">= 2.0.0" + +Vagrant.configure(1) do |config| + + config.vm.box = "debian/stretch64" + config.vm.provision "shell", inline: "apt install --yes git python3-pip" + config.vm.provision "ansible" do |ansible| + ansible.verbose = "v" + ansible.playbook = "site.yml" + ansible.vault_password_file = "vault_password_file" + end +end +``` + 1. 第一行指明了需要用哪个版本的 Vagrant 来执行 `Vagrantfile`。 + 2. 文件中的第一个循环,你要定义为多少台虚拟机执行下面的操作(这里为 `1`)。 + 3. 第三行指定了用来创建虚拟机的官方 Vagrant 镜像。 + 4. 第四行非常重要:有一些需要的应用没有安装到虚拟机中。这里我们用 `apt` 安装 `git` 和 `python3-pip`。 + 5. 下一行指明了 Ansible 配置开始的地方 + 6. 第六行说明我们想要 Ansible 输出详细信息。 + 7. 第七行,我们定义了 Ansible 剧本的入口。 + 8. 第八行,若你使用 Ansible Vault 加密了一些文件,在这里指定这些文件。 + +当 Vagrant 启动 Ansible 时,类似于执行这样的操作: + +``` +$  ansible-playbook --inventory-file=/home/me/ansible/test-ansible-playbook/.vagrant/provisioners/ansible/inventory -v --vault-password-file=vault_password_file site.yml +``` + +### 执行 Vagrant + +写好 `Vagrantfile` 后,就可以启动虚拟机了。只需要简单地运行下面命令: + +``` +$ vagrant up +``` + +这个操作会很慢,因为它会启动虚拟机,安装 `Vagrantfile` 中定义的附加软件,最终应用你的剧本。你不要太频繁地使用这条命令。 + +Ok,现在你可以快速迭代了。在做出修改后,可以通过下面命令来快速测试你的部署: + +``` +$ vagrant provision +``` + +Ansible 剧本搞定后,通常要经过多次迭代(至少我是这样的),你应该一个全新安装的虚拟机上再测试一次,因为你在迭代的过程中可能会对虚拟机造成修改从而引发意料之外的结果。 + +使用下面命令进行全新测试: + +``` +$ vagrant destroy && vagrant up +``` + +这又是一个很慢的操作。你应该在 Ansible 剧本差不多完成了的情况下才这样做。在全新虚拟机上测试部署之后,就可以发布到生产上去了。至少准备要充分不少了吧 :p + +### 有什么改进意见?请告诉我 + +本文中描述的配置对我自己来说很有用。我可以做到快速迭代(尤其在编写新的剧本的时候),除了剧本外,对我的最新应用,尚未准备好部署到生产环境上的应用也很有帮助。直接部署到远程服务器上对我的生产服务来说不仅缓慢而且很危险。 + +我本也可以使用持续集成(CI)服务器,但这不是本文的主题。如前所述,本文的目的是在编写新的 Ansible 剧本之初尽可能的快速迭代。 + +在编写 Ansible 剧本之初就提交,推送到你的 Git 仓库然后等待 CI 测试的执行结果,这有点太过了,因为这个时期的错误总是很多,你需要一一个地去调试。我觉得 CI 在编写 Ansible 剧本的后期会有用的多,尤其当多个人同时对它进行修改而且你有一整套代码质量规范要遵守的时候。不过,这只是我自己的观念,还有待讨论,再重申一遍,我不是个专业的程序员。 + +如果你有更好的测试 Ansible 剧本的方案或者能对这里描述的方法做出一些改进,请告诉我。你可以把它写到留言框中或者通过社交网络联系我,我会很高兴的。 + +-------------------------------------------------------------------------------- + +via: https://carlchenet.com/testing-ansible-playbooks-with-vagrant/ + +作者:[Carl Chenet][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://carlchenet.com +[1]:https://www.linuxjobs.fr +[2]:https://www.journalduhacker.net +[3]:https://gitlab.com/chaica/feed2toot +[4]:https://gitlab.com/chaica/feed2tweet +[5]:https://www.virtualbox.org/ +[6]:https://www.vagrantup.com/ +[7]:https://www.debian.org +[8]:https://wiki.debian.org/VirtualBox +[9]:https://carlchenet.com/wp-content/uploads/2017/12/virtualbox-150x150.png +[10]:https://carlchenet.com/wp-content/uploads/2017/12/vagrant-300x98.png diff --git a/published/201804/20180102 The Uniq Command Tutorial With Examples For Beginners.md b/published/201804/20180102 The Uniq Command Tutorial With Examples For Beginners.md new file mode 100644 index 0000000000..2ab0c6f81c --- /dev/null +++ b/published/201804/20180102 The Uniq Command Tutorial With Examples For Beginners.md @@ -0,0 +1,174 @@ +为初学者提供的 uniq 命令教程及示例 +===== + +如果你主要是在命令行上工作,并且每天处理大量的文本文件,那么你应该了解下 `uniq` 命令。该命令会帮助你轻松地从文件中找到重复的行。它不仅用于查找重复项,而且我们还可以使用它来删除重复项,显示重复项的出现次数,只显示重复的行,只显示唯一的行等。由于 `uniq` 命令是 GNU coreutils 包的一部分,所以它预装在大多数 Linux 发行版中,让我们不需要费心安装。来看一些实际的例子。 + +请注意,除非重复行是相邻的,否则 `uniq` 不会删除它们。因此,你可能需要先对它们进行排序,或将排序命令与 `uniq` 组合以获得结果。让我给你看一些例子。 + +首先,让我们创建一个带有一些重复行的文件: + +``` +vi ostechnix.txt +``` +``` +welcome to ostechnix +welcome to ostechnix +Linus is the creator of Linux. +Linux is secure by default +Linus is the creator of Linux. +Top 500 super computers are powered by Linux +``` + +正如你在上面的文件中看到的,我们有一些重复的行(第一行和第二行,第三行和第五行是重复的)。 + +### 1、 使用 uniq 命令删除文件中的连续重复行 + +如果你在不使用任何参数的情况下使用 `uniq` 命令,它将删除所有连续的重复行,只显示唯一的行。 + +``` +uniq ostechnix.txt +``` + +示例输出: + +![][2] + +如你所见, `uniq` 命令删除了给定文件中的所有连续重复行。你可能还注意到,上面的输出仍然有第二行和第四行重复了。这是因为 `uniq` 命令只有在相邻的情况下才会删除重复的行,当然,我们也可以删除非连续的重复行。请看下面的第二个例子。 + +### 2、 删除所有重复的行 + +``` +sort ostechnix.txt | uniq +``` + +示例输出: + +![][3] + +看到了吗?没有重复的行。换句话说,上面的命令将显示在 `ostechnix.txt` 中只出现一次的行。我们使用 `sort` 命令与 `uniq` 命令结合,因为,就像我提到的,除非重复行是相邻的,否则 `uniq` 不会删除它们。 + +### 3、 只显示文件中唯一的一行 + +为了只显示文件中唯一的一行,可以这样做: + +``` +sort ostechnix.txt | uniq -u +``` + +示例输出: + +``` +Linux is secure by default +Top 500 super computers are powered by Linux +``` + +如你所见,在给定的文件中只有两行是唯一的。 + +### 4、 只显示重复的行 + +同样的,我们也可以显示文件中重复的行,就像下面这样: + +``` +sort ostechnix.txt | uniq -d +``` + +示例输出: + +``` +Linus is the creator of Linux. +welcome to ostechnix +``` + +这两行在 `ostechnix.txt` 文件中是重复的行。请注意 `-d`(小写 `d`) 将会只打印重复的行,每组显示一个。打印所有重复的行,使用 `-D`(大写 `D`),如下所示: + +``` +sort ostechnix.txt | uniq -D +``` + +在下面的截图中看两个选项的区别: + +![][4] + +### 5、 显示文件中每一行的出现次数 + +由于某种原因,你可能想要检查给定文件中每一行重复出现的次数。要做到这一点,使用 `-c` 选项,如下所示: + +``` +sort ostechnix.txt | uniq -c +``` + +示例输出: + +``` + 2 Linus is the creator of Linux. + 1 Linux is secure by default + 1 Top 500 super computers are powered by Linux + 2 welcome to ostechnix +``` + +我们还可以按照每一行的出现次数进行排序,然后显示,如下所示: + +``` +sort ostechnix.txt | uniq -c | sort -nr +``` + +示例输出: + +``` + 2 welcome to ostechnix + 2 Linus is the creator of Linux. + 1 Top 500 super computers are powered by Linux + 1 Linux is secure by default +``` + +### 6、 将比较限制为 N 个字符 + +我们可以使用 `-w` 选项来限制对文件中特定数量字符的比较。例如,让我们比较文件中的前四个字符,并显示重复行,如下所示: + +``` +uniq -d -w 4 ostechnix.txt +``` + +### 7、 忽略比较指定的 N 个字符 + +像对文件中行的前 N 个字符进行限制比较一样,我们也可以使用 `-s` 选项来忽略比较前 N 个字符。 + +下面的命令将忽略在文件中每行的前四个字符进行比较: + +``` +uniq -d -s 4 ostechnix.txt +``` + +为了忽略比较前 N 个字段(LCTT 译注:即前几列)而不是字符,在上面的命令中使用 `-f` 选项。 + +欲了解更多详情,请参考帮助部分: + +``` +uniq --help +``` + +也可以使用 `man` 命令查看: + +``` +man uniq +``` + +今天就到这里!我希望你现在对 `uniq` 命令及其目的有一个基本的了解。如果你发现我们的指南有用,请在你的社交网络上分享,并继续支持我们。更多好东西要来了,请继续关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/uniq-command-tutorial-examples-beginners/ + +作者:[SK][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2018/01/uniq-2.png +[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/uniq-1-1.png +[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/uniq-4.png diff --git a/translated/tech/20180104 How does gdb call functions.md b/published/201804/20180104 How does gdb call functions.md similarity index 83% rename from translated/tech/20180104 How does gdb call functions.md rename to published/201804/20180104 How does gdb call functions.md index 575563ad3d..28c26ba615 100644 --- a/translated/tech/20180104 How does gdb call functions.md +++ b/published/201804/20180104 How does gdb call functions.md @@ -1,13 +1,13 @@ gdb 如何调用函数? ============================================================ -(之前的 gdb 系列文章:[gdb 如何工作(2016)][4] 和[通过 gdb 你能够做的三件事(2014)][5]) +(之前的 gdb 系列文章:[gdb 如何工作(2016)][4] 和[三步上手 gdb(2014)][5]) -在这个周,我发现,我可以从 gdb 上调用 C 函数。这看起来很酷,因为在过去我认为 gdb 最多只是一个只读调试工具。 +在这周,我发现我可以从 gdb 上调用 C 函数。这看起来很酷,因为在过去我认为 gdb 最多只是一个只读调试工具。 我对 gdb 能够调用函数感到很吃惊。正如往常所做的那样,我在 [Twitter][6] 上询问这是如何工作的。我得到了大量的有用答案。我最喜欢的答案是 [Evan Klitzke 的示例 C 代码][7],它展示了 gdb 如何调用函数。代码能够运行,这很令人激动! -我相信(通过一些跟踪和实验)那个示例 C 代码和 gdb 实际上如何调用函数不同。因此,在这篇文章中,我将会阐述 gdb 是如何调用函数的,以及我是如何知道的。 +我(通过一些跟踪和实验)认为那个示例 C 代码和 gdb 实际上如何调用函数不同。因此,在这篇文章中,我将会阐述 gdb 是如何调用函数的,以及我是如何知道的。 关于 gdb 如何调用函数,还有许多我不知道的事情,并且,在这儿我写的内容有可能是错误的。 @@ -15,17 +15,14 @@ gdb 如何调用函数? 在开始讲解这是如何工作之前,我先快速的谈论一下我是如何发现这件令人惊讶的事情的。 -所以,你已经在运行一个 C 程序(目标程序)。你可以运行程序中的一个函数,只需要像下面这样做: +假如,你已经在运行一个 C 程序(目标程序)。你可以运行程序中的一个函数,只需要像下面这样做: * 暂停程序(因为它已经在运行中) - * 找到你想调用的函数的地址(使用符号表) - * 使程序(目标程序)跳转到那个地址 - * 当函数返回时,恢复之前的指令指针和寄存器 -通过符号表来找到想要调用的函数的地址非常容易。下面是一段非常简单但能够工作的代码,我在 Linux 上使用这段代码作为例子来讲解如何找到地址。这段代码使用 [elf crate][8]。如果我想找到 PID 为 2345 的进程中的 foo 函数的地址,那么我可以运行 `elf_symbol_value("/proc/2345/exe", "foo")`。 +通过符号表来找到想要调用的函数的地址非常容易。下面是一段非常简单但能够工作的代码,我在 Linux 上使用这段代码作为例子来讲解如何找到地址。这段代码使用 [elf crate][8]。如果我想找到 PID 为 2345 的进程中的 `foo` 函数的地址,那么我可以运行 `elf_symbol_value("/proc/2345/exe", "foo")`。 ``` fn elf_symbol_value(file_name: &str, symbol_name: &str) -> Result> { @@ -42,7 +39,6 @@ fn elf_symbol_value(file_name: &str, symbol_name: &str) -> Result Result @@ -66,7 +62,6 @@ int foo() { int main() { sleep(1000); } - ``` 接下来,编译并运行它: @@ -74,7 +69,6 @@ int main() { ``` $ gcc -o test test.c $ ./test - ``` 最后,我们使用 gdb 来跟踪 `test` 这一程序: @@ -84,54 +78,42 @@ $ sudo gdb -p $(pgrep -f test) (gdb) p foo() $1 = 3 (gdb) quit - ``` 我运行 `p foo()` 然后它运行了这个函数!这非常有趣。 -### 为什么这是有用的? +### 这有什么用? 下面是一些可能的用途: -* 它使得你可以把 gdb 当成一个 C 应答式程序,这很有趣,我想对开发也会有用 - +* 它使得你可以把 gdb 当成一个 C 应答式程序(REPL),这很有趣,我想对开发也会有用 * 在 gdb 中进行调试的时候展示/浏览复杂数据结构的功能函数(感谢 [@invalidop][1]) - * [在进程运行时设置一个任意的名字空间][2](我的同事 [nelhage][3] 对此非常惊讶) - * 可能还有许多我所不知道的用途 ### 它是如何工作的 -当我在 Twitter 上询问从 gdb 中调用函数是如何工作的时,我得到了大量有用的回答。许多答案是”你从符号表中得到了函数的地址“,但这并不是完整的答案。 +当我在 Twitter 上询问从 gdb 中调用函数是如何工作的时,我得到了大量有用的回答。许多答案是“你从符号表中得到了函数的地址”,但这并不是完整的答案。 -有个人告诉了我两篇关于 gdb 如何工作的系列文章:[和本地人一起调试-第一部分][9],[和本地人一起调试-第二部分][10]。第一部分讲述了 gdb 是如何调用函数的(指出了 gdb 实际上完成这件事并不简单,但是我将会尽力)。 +有个人告诉了我两篇关于 gdb 如何工作的系列文章:[原生调试:第一部分][9],[原生调试:第二部分][10]。第一部分讲述了 gdb 是如何调用函数的(指出了 gdb 实际上完成这件事并不简单,但是我将会尽力)。 步骤列举如下: 1. 停止进程 - 2. 创建一个新的栈框(远离真实栈) - 3. 保存所有寄存器 - 4. 设置你想要调用的函数的寄存器参数 - -5. 设置栈指针指向新的栈框 - +5. 设置栈指针指向新的栈框stack frame 6. 在内存中某个位置放置一条陷阱指令 - 7. 为陷阱指令设置返回地址 - 8. 设置指令寄存器的值为你想要调用的函数地址 - 9. 再次运行进程! (LCTT 译注:如果将这个调用的函数看成一个单独的线程,gdb 实际上所做的事情就是一个简单的线程上下文切换) 我不知道 gdb 是如何完成这些所有事情的,但是今天晚上,我学到了这些所有事情中的其中几件。 -**创建一个栈框** +#### 创建一个栈框 如果你想要运行一个 C 函数,那么你需要一个栈来存储变量。你肯定不想继续使用当前的栈。准确来说,在 gdb 调用函数之前(通过设置函数指针并跳转),它需要设置栈指针到某个地方。 @@ -154,14 +136,13 @@ Breakpoint 1 at 0x40052a Breakpoint 1, 0x000000000040052a in foo () (gdb) p $rsp $8 = (void *) 0x7ffea3d0bc00 - ``` -这看起来符合”gdb 在当前栈的栈顶构造了一个新的栈框“这一理论。因为栈指针(`$rsp`)从 `0x7ffea3d0bca8` 变成了 `0x7ffea3d0bc00` - 栈指针从高地址往低地址长。所以 `0x7ffea3d0bca8` 在 `0x7ffea3d0bc00` 的后面。真是有趣! +这看起来符合“gdb 在当前栈的栈顶构造了一个新的栈框”这一理论。因为栈指针(`$rsp`)从 `0x7ffea3d0bca8` 变成了 `0x7ffea3d0bc00` —— 栈指针从高地址往低地址长。所以 `0x7ffea3d0bca8` 在 `0x7ffea3d0bc00` 的后面。真是有趣! 所以,看起来 gdb 只是在当前栈所在位置创建了一个新的栈框。这令我很惊讶! -**改变指令指针** +#### 改变指令指针 让我们来看一看 gdb 是如何改变指令指针的! @@ -181,7 +162,7 @@ $3 = (void (*)()) 0x40052a 我盯着输出看了很久,但仍然不理解它是如何改变指令指针的,但这并不影响什么。 -**如何设置断点** +#### 如何设置断点 上面我写到 `break foo` 。我跟踪 gdb 运行程序的过程,但是没有任何发现。 @@ -202,10 +183,9 @@ $3 = (void (*)()) 0x40052a // 将 0x400528 处的指令更改为之前的样子 25622 ptrace(PTRACE_PEEKTEXT, 25618, 0x400528, [0x5d00000003cce589]) = 0 25622 ptrace(PTRACE_POKEDATA, 25618, 0x400528, 0x5d00000003b8e589) = 0 - ``` -**在某处放置一条陷阱指令** +#### 在某处放置一条陷阱指令 当 gdb 运行一个函数的时候,它也会在某个地方放置一条陷阱指令。这是其中一条。它基本上是用 `cc` 来替换一条指令(`int3`)。 @@ -213,7 +193,6 @@ $3 = (void (*)()) 0x40052a 5908 ptrace(PTRACE_PEEKTEXT, 5810, 0x7f6fa7c0b260, [0x48f389fd89485355]) = 0 5908 ptrace(PTRACE_PEEKTEXT, 5810, 0x7f6fa7c0b260, [0x48f389fd89485355]) = 0 5908 ptrace(PTRACE_POKEDATA, 5810, 0x7f6fa7c0b260, 0x48f389fd894853cc) = 0 - ``` `0x7f6fa7c0b260` 是什么?我查看了进程的内存映射,发现它位于 `/lib/x86_64-linux-gnu/libc-2.23.so` 中的某个位置。这很奇怪,为什么 gdb 将陷阱指令放在 libc 中? @@ -226,7 +205,7 @@ $3 = (void (*)()) 0x40052a 我将要在这儿停止了(现在已经凌晨 1 点),但是我知道的多一些了! -看起来”gdb 如何调用函数“这一问题的答案并不简单。我发现这很有趣并且努力找出其中一些答案,希望你也能够找到。 +看起来“gdb 如何调用函数”这一问题的答案并不简单。我发现这很有趣并且努力找出其中一些答案,希望你也能够找到。 我依旧有很多未回答的问题,关于 gdb 是如何完成这些所有事的,但是可以了。我不需要真的知道关于 gdb 是如何工作的所有细节,但是我很开心,我有了一些进一步的理解。 @@ -236,7 +215,7 @@ via: https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/ 作者:[Julia Evans][a] 译者:[ucasFL](https://github.com/ucasFL) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -244,8 +223,8 @@ via: https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/ [1]:https://twitter.com/invalidop/status/949161146526781440 [2]:https://github.com/baloo/setns/blob/master/setns.c [3]:https://github.com/nelhage -[4]:https://jvns.ca/blog/2016/08/10/how-does-gdb-work/ -[5]:https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/ +[4]:https://linux.cn/article-9491-1.html +[5]:https://linux.cn/article-9276-1.html [6]:https://twitter.com/b0rk/status/948060808243765248 [7]:https://github.com/eklitzke/ptrace-call-userspace/blob/master/call_fprintf.c [8]:https://cole14.github.io/rust-elf diff --git a/published/201804/20180109 Linux size Command Tutorial for Beginners (6 Examples).md b/published/201804/20180109 Linux size Command Tutorial for Beginners (6 Examples).md new file mode 100644 index 0000000000..fae2306150 --- /dev/null +++ b/published/201804/20180109 Linux size Command Tutorial for Beginners (6 Examples).md @@ -0,0 +1,133 @@ +六个例子带你入门 size 命令 +====== + +正如你所知道的那样,Linux 中的目标文件或着说可执行文件由多个段组成(比如文本段和数据段)。若你想知道每个段的大小,那么确实存在这么一个命令行工具 —— 那就是 `size`。在本教程中,我们将会用几个简单易懂的案例来讲解该工具的基本用法。 + +在我们开始前,有必要先声明一下,本文的所有案例都在 Ubuntu 16.04 LTS 中测试过了。 + +### Linux size 命令 + +`size` 命令基本上就是输出指定输入文件各段及其总和的大小。下面是该命令的语法: + +``` +size [-A|-B|--format=compatibility] +            [--help] +            [-d|-o|-x|--radix=number] +            [--common] +            [-t|--totals] +            [--target=bfdname] [-V|--version] +            [objfile...] +``` + +man 页是这样描述它的: + +> GNU 的 `size` 程序列出参数列表中各目标文件或存档库文件的段大小 — 以及总大小。默认情况下,对每个目标文件或存档库中的每个模块都会产生一行输出。 +> +> `objfile...` 是待检查的目标文件。如果没有指定,则默认为文件 `a.out`。 + +下面是一些问答方式的案例,希望能让你对 `size` 命令有所了解。 + +### Q1、如何使用 size 命令? + +`size` 的基本用法很简单。你只需要将目标文件/可执行文件名称作为输入就行了。下面是一个例子: + +``` +size apl +``` + +该命令在我的系统中的输出如下: + +[![How to use size command][1]][2] + +前三部分的内容是文本段、数据段和 bss 段及其相应的大小。然后是十进制格式和十六进制格式的总大小。最后是文件名。 + +### Q2、如何切换不同的输出格式? + +根据 man 页的说法,`size` 的默认输出格式类似于 Berkeley 的格式。然而,如果你想的话,你也可以使用 System V 规范。要做到这一点,你可以使用 `--format` 选项加上 `SysV` 值。 + +``` +size apl --format=SysV +``` + +下面是它的输出: + +[![How to switch between different output formats][3]][4] + +### Q3、如何切换使用其他的单位? + +默认情况下,段的大小是以十进制的方式来展示。然而,如果你想的话,也可以使用八进制或十六进制来表示。对应的命令行参数分别为 `o` 和 `-x`。 + +[![How to switch between different size units][5]][6] + +关于这些参数,man 页是这么说的: + +> -d + +> -o + +> -x + +> --radix=number + +> 使用这几个选项,你可以让各个段的大小以十进制(`-d` 或 `--radix 10`)、八进制(`-o` 或 `--radix 8`);或十六进制(`-x` 或 `--radix 16`)数字的格式显示。`--radix number` 只支持三个数值参数(8、 10、 16)。总共大小以两种进制给出; `-d` 或 `-x` 的十进制和十六进制输出,或 `-o` 的八进制和十六进制输出。 + +### Q4、如何让 size 命令显示所有对象文件的总大小? + +如果你用 `size` 一次性查找多个文件的段大小,则通过使用 `-t` 选项还可以让它显示各列值的总和。 + +``` +size -t [file1] [file2] ... +``` + +下面是该命令的执行的截屏: + +[![How to make size command show totals of all object files][7]][8] + +`-t` 选项让它多加了最后那一行。 + +### Q5、如何让 size 输出每个文件中公共符号的总大小? + +若你为 `size` 提供多个输入文件作为参数,而且想让它显示每个文件中公共符号(指 common segment 中的 symbol)的大小,则你可以带上 `--common` 选项。 + +``` +size --common [file1] [file2] ... +``` + +另外需要指出的是,当使用 Berkeley 格式时,这些公共符号的大小被纳入了 bss 大小中。 + +### Q6、还有什么其他的选项? + +除了刚才提到的那些选项外,`size` 还有一些一般性的命令行选项,比如 `v` (显示版本信息)和 `-h` (可选参数和选项的汇总)。 + +[![What are the other available command line options][9]][10] + +除此之外,你也可以使用 `@file` 选项来让 `size` 从文件中读取命令行选项。下面是详细的相关说明: + +> 读出来的选项会插入并替代原来的 `@file` 选项。若文件不存在或着无法读取,则该选项不会被替换,而是会以字面意义来解释该选项。文件中的选项以空格分隔。当选项中要包含空格时需要用单引号或双引号将整个选项包起来。通过在字符前面添加一个反斜杠可以将任何字符(包括反斜杠本身)纳入到选项中。文件本身也能包含其他的 `@file` 选项;任何这样的选项都会被递归处理。 + +### 结论 + +很明显,`size` 命令并不适用于所有人。它的目标群体是那些需要处理 Linux 中目标文件/可执行文件结构的人。因此,如果你刚好是目标受众,那么多试试我们这里提到的那些选项,你应该做好每天都使用这个工具的准备。想了解关于 `size` 的更多信息,请阅读它的 [man 页 ][11]。 + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/linux-size-command/ + +作者:[Himanshu Arora][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com +[1]:https://www.howtoforge.com/images/command-tutorial/size-basic-usage.png +[2]:https://www.howtoforge.com/images/command-tutorial/big/size-basic-usage.png +[3]:https://www.howtoforge.com/images/command-tutorial/size-format-option.png +[4]:https://www.howtoforge.com/images/command-tutorial/big/size-format-option.png +[5]:https://www.howtoforge.com/images/command-tutorial/size-o-x-options.png +[6]:https://www.howtoforge.com/images/command-tutorial/big/size-o-x-options.png +[7]:https://www.howtoforge.com/images/command-tutorial/size-t-option.png +[8]:https://www.howtoforge.com/images/command-tutorial/big/size-t-option.png +[9]:https://www.howtoforge.com/images/command-tutorial/size-v-x1.png +[10]:https://www.howtoforge.com/images/command-tutorial/big/size-v-x1.png +[11]:https://linux.die.net/man/1/size diff --git a/published/201804/20180110 8 simple ways to promote team communication.md b/published/201804/20180110 8 simple ways to promote team communication.md new file mode 100644 index 0000000000..0be4c5b53a --- /dev/null +++ b/published/201804/20180110 8 simple ways to promote team communication.md @@ -0,0 +1,72 @@ +八种敏捷团队的提升方法 +====== + +> 在这个列表中,没有项目管理软件,这里不包含清单,也没有与 GitHub 整合,只是几种组织思维和提高团队交流的方法。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/world_remote_teams.png?itok=Wk1yBFv6) + +图片来源:opensource.com + +你也许经常听说下面这句话:工具太多,时间太少。为了节约您的时间,我列出了几款我最常用的提高敏捷团队工作效率的工具。如果你也是一名敏捷主义者,你可能听说过类似的工具,但我这里提到的仅限于开源工具。 + +**请注意!** 这些工具和你想象的可能有点不同。它们并不是项目管理软件——这领域已经有一篇[好文章][1]了。因此这里不包含清单,也没有与 GitHub 整合,只是几种组织思维和提高团队交流的方法。 + +### 组建一个充满积极反馈的团队 + +如果在产业中大部分人都习惯了输出、接收负面消息,就很难有人对同事进行正面反馈的输出。这并不奇怪,当人们乐于给出赞美时,人们就会竞相向别人说“干得漂亮!”、“没有你我们很难完成任务。”赞美别人干的漂亮并不会使你痛苦,它通常能激励大家更好地为团队工作。下面两个软件可以帮助你向同事表达赞扬。 + +* 对开发团队来说,[Management 3.0][2] 是个有着大量[免费资源][3]的宝箱,可以尽情使用。其中 Feedback Wraps 的观念最引人注目(不仅仅是因为它让我们联想到墨西哥卷)。 [Feedback Wraps][4] 是一个经过六步对用户进行反馈的程序,也许你会认为它是为了负面反馈而设计的,但我们发现它在表达积极评论方面十分有效。 +* [Happiness Packets][5] 为用户提供了在开源社区内匿名正面反馈的服务。它尤其适合不太习惯人际交往的用户或是不知道说什么好的情况。Happiness Packets 拥有一份[公开的评论档案][6](这些评论都已经得到授权分享),你可以浏览大家的评论,从中得到灵感,对别人做出暖心的称赞。它还有个特殊功能,能够屏蔽恶意消息。 + +### 思考工作的意义 + +这很难定义。在敏捷领域中,成功的关键包括定义人物角色和产品愿景,还要向整个敏捷团队说明此项工作的意义。产品开发人员和项目负责人能够获得的开源工具数量极为有限,对于这一点我们有些失望。 + +在 Rat Hat 公司,最受尊敬也最为常用于训练敏捷团队的开源工具之一是 Product Vision Board 。它出自产品管理专家 Roman Pichler 之手,Roman Pichler 提供了[大量工具和模版][7]来帮助敏捷团队理解他们工作的意义。(你需要提供电子邮箱地址才能下载这些工具。) + +* [Product Vision Board][8] 的模版通过简单但有效的问题引导团队转变思考方式,将思考工作的意义置于具体工作方法之前。 +* 我们也很喜欢 Roman 的 [Product Management Test][9],它能够通过简便快捷的网页表单,引领团队重新定义产品开发人员的角色,并且找出程序漏洞。我们推荐产品开发团队周期性地完成此项测试,重新分析失败原因。 + +### 对工作内容的直观化 + +你是否曾为一个大案子焦头烂额,连熟悉的步骤也在脑海中乱成一团?我们也遇到过这种情况。使用思维导图可以梳理你脑海中的想法,使其直观化。你不需要一下就想出整件事该怎么进行,你只需要你的头脑,一块白板(或者是思维导图软件)和一些思考的时间。 + +* 在这个领域中我们最喜欢的开源工具是 [Xmind3][10]。它支持多种平台运行(Linux、MacOS 和 Windows),以便与他人共享文件。如果你对工具的要求很高,推荐使用[其更新版本][11],提供电子邮箱地址即可免费下载使用。 +* 如果你很看重灵活性,Eduard Lucena 在 Fedora Magazine 中提供的 [三个附加选项][12] 就十分适合。你可以在 Fedora 杂志上找到这些软件的获取方式,其他信息可以在它们的项目页找到。 + + * [Labyrinth][13] + * [View Your Mind][14] + * [FreeMind][15] + +像我们开头说的一样,提高敏捷团队工作效率的工具有很多,如果你有特别喜欢的相关开源工具,请在评论中与大家分享。 + +### 作者简介 + +Jen Krieger :Red Hat 的首席敏捷架构师,在软件开发领域已经工作超过 20 年,曾在瀑布及敏捷生命周期等领域扮演多种角色。目前在 Red Hat 负责针对 CI/CD 最佳效果的部际 DevOps 活动。最近她在与 Project Atomic & OpenShift 团队合作。她最近在引领公司向着敏捷团队改革,并增加开源项目在公司内的认知度。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/foss-tools-agile-teams + +作者:[Jen Krieger][a] +译者:[Valoniakim](https://github.com/Valoniakim) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jkrieger +[1]:https://opensource.com/business/16/3/top-project-management-tools-2016 +[2]:https://management30.com/ +[3]:https://management30.com/leadership-resource-hub/ +[4]:https://management30.com/en/practice/feedback-wraps/ +[5]:https://happinesspackets.io/ +[6]:https://www.happinesspackets.io/archive/ +[7]:http://www.romanpichler.com/tools/ +[8]:http://www.romanpichler.com/tools/vision-board/ +[9]:http://www.romanpichler.com/tools/romans-product-management-test/ +[10]:https://sourceforge.net/projects/xmind3/?source=recommended +[11]:http://www.xmind.net/ +[12]:https://fedoramagazine.org/three-mind-mapping-tools-fedora/ +[13]:https://people.gnome.org/~dscorgie/labyrinth.html +[14]:http://www.insilmaril.de/vym/ +[15]:http://freemind.sourceforge.net/wiki/index.php/Main_Page diff --git a/published/201804/20180110 Why isn-t open source hot among computer science students.md b/published/201804/20180110 Why isn-t open source hot among computer science students.md new file mode 100644 index 0000000000..aeca417f66 --- /dev/null +++ b/published/201804/20180110 Why isn-t open source hot among computer science students.md @@ -0,0 +1,86 @@ +为什么开源在计算机专业的学生中不那么流行? +=============== + +> 高中和大学生们或许因先入为主的观念而畏于参与开源项目。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_OSDC_OpenClass_520x292_FINAL_JD.png?itok=ly78pMqu) + +图片来自:opensource.com + +年轻程序员的技术悟性和创造力是充满活力的。 + +这一点可以从我参加今年的(美国)国内最大的黑客马拉松 [PennApps][1] 时所目睹的他们勤奋的工作中可以看出。在 48 小时内,我的高中和大学年龄段的同龄人们创建了从[可以通过眨眼来让不能说话或行动不便的人来交流的设备][2] 到 [带有物联网功能的煎饼机][3] 的项目。在整个过程中,开源的精神是切实可见的,不同群体之间建立了共同的愿望,思想和技术诀窍的自由流通,无畏的实验和快速的原型设计,以及热衷于参与的渴望。 + +那么我想知道,为什么在我的这些技术极客伙伴中,开源并不是一个热门话题? + +为了更多地了解大学生在听到“开源”时的想法,我调查了几个大学生,他们都是我所属的专业计算机科学团体的成员。这个社团的所有成员都必须在高中或大学期间申请,并根据他们的计算机科学成就和领导能力进行选择——即是否领导过一个学校的机器人团队,建立过将编码带入资金不足的课堂的非营利组织,或其他一些值得努力的地方。鉴于这些个人在计算机科学方面的成就,我认为他们的观点将有助于理解年轻程序员对开源项目的吸引力(或不吸引人)。 + +我编写和发布的在线调查包括以下问题: + + * 你喜欢编写个人项目吗?您是否曾经参与过开源项目? + * 你觉得自己开发自己的编程项目,还是对现有的开源工作做出贡献会更有益处? + * 你将如何比较为开源软件组织和专有软件的组织编码获得的声望? + +尽管绝大多数人表示,他们至少偶尔会喜欢在业余时间编写个人项目,但大多数人从未参与过开源项目。当我进一步探索这一趋势时,一些关于开源项目和组织的常见的偏见逐渐浮出水面。为了说服我的伙伴们,开源项目值得他们花时间,并且为教育工作者和开源组织提供他们对学生的见解,我将谈谈三个首要的偏见。 + +### 偏见 1:从零开始创建个人项目比为现有的开源项目做贡献更好。 + +在我所调查的大学年龄程序员中,26 人中有 24 人声称,开发自己的个人项目比开源项目更有益。 + +作为一名计算机科学专业的大一新生,我也相信这一点。我经常听到年长的同学说,个人项目会让我成为更有吸引力的实习生。没有人提到过为开源项目做出贡献的可能性——所以在我看来,这是无关紧要的。 + +我现在意识到开源项目为现实世界提供了强大的准备工作。对开源项目的贡献培养了一种意识,即[工具和语言如何拼合在一起][4],而单个项目却不能。而且,开源是一个协调与协作的练习,可以培养[学生的沟通,团队合作和解决问题的专业技能][5]。 + +### 偏见 2:我的编码技能是不够的。 + +一些受访者表示,他们被开源项目吓倒了,不知道该从哪里开始贡献,或者担心项目进展缓慢。不幸的是,自卑感往往也会对女性程序员产生影响,而这种感觉并不止于开源社区。事实上,“冒名顶替综合症”甚至可能会被放大,因为[开源的倡导者通常会拒绝官僚主义][6] —— 而且和官僚主义一样难以在内部流动,它有助于新加入的人了解他们在一个组织中的位置。 + +我还记得第一次在 GitHub 上查看开源项目时,我对阅读贡献指南感到害怕。然而,这些指南并非旨在吓跑别人,而是提供[指导][7]。为此,我认为贡献指南是建立期望而不依赖于等级结构的一种方式。 + +有几个开源项目积极为新的项目贡献者创造了一个地方。[TEAMMATES][8] 是一种教育反馈管理工具,是为初学者们解决了这个问题一个开源项目。在评论中,各种技能水平的程序员都详细阐述了实现的细节,这表明开源项目是属于热切的新程序员和经验丰富的软件老手的地方。对于那些还在犹豫的年轻程序员来说,一些[开源项目][9]已经考虑周全,采用了[冒名顶替综合症的免责声明][10]。 + +### 偏见 3:专有软件公司比开源软件组织做得更好。 + +在接受调查的 26 位受访者中,只有 5 位认为开源组织和专有软件组织在声望上是平等的。这可能是由于“开源”意味着“无利可图”,因此质量低下的误解(查看 [“开源”不只是意味着是免费][11])。 + +然而,开源软件和盈利软件并不相互排斥。事实上,小型和大型企业通常都为免费的开源软件的技术支持服务而付款。正如[红帽公司首席执行官 Jim Whitehurst][12] 所解释的那样:“我们拥有一批工程团队,负责跟踪 Linux 的每一项变更--错误修复、安全性增强等等,确保我们客户的关键任务系统保持最新状态和稳定“。 + +另外,开源的本质是通过使更多的人能够检查源代码来提升而不是阻碍质量的提高。[Mobify 首席执行官 Igor Faletski][13] 写道,Mobify 的 “25 位软件开发人员和专业的质量保证人员团队无法满足世界上所有可能使用 [Mobify 的开源]平台的软件开发者,而他们每个人都是该项目的潜在测试者或贡献者。” + +另一个问题可能是年轻的程序员不知道他们每天使用的开源软件。 我使用了许多工具——包括 MySQL、Eclipse、Atom、Audacity 和 WordPress——几个月甚至几年,却没有意识到它们是开源的。 经常急于下载教学大纲指定软件以完成课堂作业的大学生可能不知道哪个软件是开源的。 这使得开源看起来比现在更加陌生。 + +所以学生们,在尝试之前不要敲开源码。 看看这个[初学者友好的项目][14]列表和这[六个起点][15],开始你的开源之旅。 + +教育工作者们,提醒您的学生开源社区的成功创新的历史,并引导他们走向课堂之外的开源项目。你将帮助培养更敏锐、更有准备、更自信的学生。 + +### 关于作者 + +Susie Choi - Susie 是杜克大学计算机科学专业的本科生。她对技术革新和开放源码原则对教育和社会经济不平等问题的影响非常感兴趣。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/students-and-open-source-3-common-preconceptions + +作者:[Susie Choi][a] +译者:[amwps290](https://github.com/amwps290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/susiechoi +[1]:http://pennapps.com/ +[2]:https://devpost.com/software/blink-9o2iln +[3]:https://devpost.com/software/daburrito +[4]:https://hackernoon.com/benefits-of-contributing-to-open-source-2c97b6f529e9 +[5]:https://opensource.com/education/16/8/5-reasons-student-involvement-open-source +[6]:https://opensource.com/open-organization/17/7/open-thinking-curb-bureaucracy +[7]:https://opensource.com/life/16/3/contributor-guidelines-template-and-tips +[8]:https://github.com/TEAMMATES/teammates/issues?q=is%3Aissue+is%3Aopen+label%3Ad.FirstTimers +[9]:https://github.com/adriennefriend/imposter-syndrome-disclaimer/blob/master/examples.md +[10]:https://github.com/adriennefriend/imposter-syndrome-disclaimer +[11]:https://opensource.com/resources/what-open-source +[12]:https://hbr.org/2013/01/yes-you-can-make-money-with-op +[13]:https://hbr.org/2012/10/open-sourcing-may-be-worth +[14]:https://github.com/MunGell/awesome-for-beginners +[15]:https://opensource.com/life/16/1/6-beginner-open-source diff --git a/translated/talk/20180111 AI and machine learning bias has dangerous implications.md b/published/201804/20180111 AI and machine learning bias has dangerous implications.md similarity index 72% rename from translated/talk/20180111 AI and machine learning bias has dangerous implications.md rename to published/201804/20180111 AI and machine learning bias has dangerous implications.md index 3484b21163..ea6723b2f7 100644 --- a/translated/talk/20180111 AI and machine learning bias has dangerous implications.md +++ b/published/201804/20180111 AI and machine learning bias has dangerous implications.md @@ -1,6 +1,8 @@ -AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开源社区做些什么 +AI 和机器学习中暗含的算法偏见 ====== +> 我们又能通过开源社区做些什么? + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW_goodbadugly.png?itok=ZxaimUWU) 图片来源:opensource.com @@ -9,21 +11,21 @@ AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开 很难想像,我们经常忽略的一点是这二者的交集:计算机算法中存在的偏见。 -与我们大多数人所认为的相反,科技并不是客观的。 AI 算法和它们的决策程序是由它们的研发者塑造的,他们写入的代码,使用的“[训练][1]”数据还有他们对算法进行[应力测试][2] 的过程,都会影响这些算法今后的选择。这意味着研发者的价值观,偏见和人类缺陷都会反映在软件上。如果我只给实验室中的人脸识别算法提供白人的照片,当遇到不是白人照片时,它[不会认为照片中的是人类][3] 。这结论并不意味着 AI 是“愚蠢的”或是“天真的”,它显示的是训练数据的分布偏差:缺乏多种的脸部照片。这会引来非常严重的后果。 +与我们大多数人的认知相反,科技并不是客观的。 AI 算法和它们的决策程序是由它们的研发者塑造的,他们写入的代码,使用的“[训练][1]”数据还有他们对算法进行[应力测试][2] 的过程,都会影响这些算法今后的选择。这意味着研发者的价值观、偏见和人类缺陷都会反映在软件上。如果我只给实验室中的人脸识别算法提供白人的照片,当遇到不是白人照片时,它[不会认为照片中的是人类][3] 。这结论并不意味着 AI 是“愚蠢的”或是“天真的”,它显示的是训练数据的分布偏差:缺乏多种的脸部照片。这会引来非常严重的后果。 -这样的例子并不少。全美范围内的[州法院系统][4] 都使用“黑箱子”对罪犯进行宣判。由于训练数据的问题,[这些算法对黑人有偏见][5] ,他们对黑人罪犯会选择更长的服刑期,因此监狱中的种族差异会一直存在。而这些都发生在科技的客观性伪装下,这是“科学的”选择。 +这样的例子并不少。全美范围内的[州法院系统][4] 都使用“黑盒”对罪犯进行宣判。由于训练数据的问题,[这些算法对黑人有偏见][5] ,他们对黑人罪犯会选择更长的服刑期,因此监狱中的种族差异会一直存在。而这些都发生在科技的客观性伪装下,这是“科学的”选择。 美国联邦政府使用机器学习算法来计算福利性支出和各类政府补贴。[但这些算法中的信息][6],例如它们的创造者和训练信息,都很难找到。这增加了政府工作人员进行不平等补助金分发操作的几率。 -算法偏见情况还不止这些。从 Facebook 的新闻算法到医疗系统再到警方使用的相机,我们作为社会的一部分极有可能对这些算法输入各式各样的偏见,性别歧视,仇外思想,社会经济地位歧视,确认偏误等等。这些被输入了偏见的机器会大量生产分配,将种种社会偏见潜藏于科技客观性的面纱之下。 +算法偏见情况还不止这些。从 Facebook 的新闻算法到医疗系统再到警用携带相机,我们作为社会的一部分极有可能对这些算法输入各式各样的偏见、性别歧视、仇外思想、社会经济地位歧视、确认偏误等等。这些被输入了偏见的机器会大量生产分配,将种种社会偏见潜藏于科技客观性的面纱之下。 这种状况绝对不能再继续下去了。 在我们对人工智能进行不断开发研究的同时,需要降低它的开发速度,小心仔细地开发。算法偏见的危害已经足够大了。 -## 我们能怎样减少算法偏见? +### 我们能怎样减少算法偏见? -最好的方式是从算法训练的数据开始审查,根据 [Microsoft 的研究者][2] 所说,这方法很有效。 +最好的方式是从算法训练的数据开始审查,根据 [微软的研究人员][2] 所说,这方法很有效。 数据分布本身就带有一定的偏见性。编程者手中的美国公民数据分布并不均衡,本地居民的数据多于移民者,富人的数据多于穷人,这是极有可能出现的情况。这种数据的不平均会使 AI 对我们是社会组成得出错误的结论。例如机器学习算法仅仅通过统计分析,就得出“大多数美国人都是富有的白人”这个结论。 @@ -37,7 +39,7 @@ AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开 这些对于 AI 来说是十分复杂的数据,但我们可以通过多项测试对它们进行定义和传达。 -## 为什么开源很适合这项任务? +### 为什么开源很适合这项任务? 开源方法和开源技术都有着极大的潜力改变算法偏见。 @@ -45,17 +47,17 @@ AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开 调试工具如哥伦比亚大学和理海大学推出的 [DeepXplore][9],增强了 AI 应力测试的强度,同时提高了其操控性。还有 [麻省理工学院的计算机科学和人工智能实验室][10]完成的项目,它开发出敏捷快速的样机研究软件,这些应该会被开源社区采纳。 -开源技术也已经证明了其在审查和分类大组数据方面的能力。最明显的体现在开源工具在数据分析市场的占有率上(Weka , Rapid Miner 等等)。应当由开源社区来设计识别数据偏见的工具,已经在网上发布的大量训练数据组比如 [Kaggle][11]也应当使用这种技术进行识别筛选。 +开源技术也已经证明了其在审查和分类大组数据方面的能力。最明显的体现在开源工具在数据分析市场的占有率上(Weka、Rapid Miner 等等)。应当由开源社区来设计识别数据偏见的工具,已经在网上发布的大量训练数据组比如 [Kaggle][11] 也应当使用这种技术进行识别筛选。 -开源方法本身十分适合消除偏见程序的设计。内部谈话,私人软件开发及非民主的决策制定引起了很多问题。开源社区能够进行软件公开的谈话,进行大众化,维持好与大众的关系,这对于处理以上问题是十分重要的。如果线上社团,组织和院校能够接受这些开源特质,那么由开源社区进行消除算法偏见的机器设计也会顺利很多。 +开源方法本身十分适合消除偏见程序的设计。内部谈话、私人软件开发及非民主的决策制定引起了很多问题。开源社区能够进行软件公开的谈话,进行大众化,维持好与大众的关系,这对于处理以上问题是十分重要的。如果线上社团,组织和院校能够接受这些开源特质,那么由开源社区进行消除算法偏见的机器设计也会顺利很多。 -## 我们怎样才能够参与其中? +### 我们怎样才能够参与其中? -教育是一个很重要的环节。我们身边有很多还没意识到算法偏见的人,但算法偏见在立法,社会公正,政策及更多领域产生的影响与他们息息相关。让这些人知道算法偏见是怎样形成的和它们带来的重要影响是很重要的,因为想要改变目前是局面,从我们自身做起是唯一的方法。 +教育是一个很重要的环节。我们身边有很多还没意识到算法偏见的人,但算法偏见在立法、社会公正、政策及更多领域产生的影响与他们息息相关。让这些人知道算法偏见是怎样形成的和它们带来的重要影响是很重要的,因为想要改变目前的局面,从我们自身做起是唯一的方法。 -对于我们中间那些与人工智能一起工作的人来说,这种沟通尤其重要。不论是人工智能的研发者,警方或是科研人员,当他们为今后设计人工智能时,应当格外意识到现今这种偏见存在的危险性,很明显,想要消除人工智能中存在的偏见,就要从意识到偏见的存在开始。 +对于我们中间那些与人工智能一起工作的人来说,这种沟通尤其重要。不论是人工智能的研发者、警方或是科研人员,当他们为今后设计人工智能时,应当格外意识到现今这种偏见存在的危险性,很明显,想要消除人工智能中存在的偏见,就要从意识到偏见的存在开始。 -最后,我们需要围绕 AI 伦理化建立并加强开源社区。不论是需要建立应力实验训练模型,软件工具,或是从千兆字节的训练数据中筛选,现在已经到了我们利用开源方法来应对数字化时代最大的威胁的时间了。 +最后,我们需要围绕 AI 伦理化建立并加强开源社区。不论是需要建立应力实验训练模型、软件工具,或是从千兆字节的训练数据中筛选,现在已经到了我们利用开源方法来应对数字化时代最大的威胁的时间了。 -------------------------------------------------------------------------------- @@ -63,7 +65,7 @@ via: https://opensource.com/article/18/1/how-open-source-can-fight-algorithmic-b 作者:[Justin Sherman][a] 译者:[Valoniakim](https://github.com/Valoniakim) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180116 Monitor your Kubernetes Cluster.md b/published/201804/20180116 Monitor your Kubernetes Cluster.md similarity index 69% rename from translated/tech/20180116 Monitor your Kubernetes Cluster.md rename to published/201804/20180116 Monitor your Kubernetes Cluster.md index a8c8db5e5d..d7427bc6e0 100644 --- a/translated/tech/20180116 Monitor your Kubernetes Cluster.md +++ b/published/201804/20180116 Monitor your Kubernetes Cluster.md @@ -1,27 +1,30 @@ -监视 Kubernetes 集群 +使用 Graylog 和 Prometheus 监视 Kubernetes 集群 ====== -这篇文章最初发表在 [Kevin Monroe 的博客][1] 上 + +这篇文章最初发表在 [Kevin Monroe 的博客][1] 上。 监视日志和指标状态是集群管理员的重点工作。它的好处很明显:指标能帮你设置一个合理的性能目标,而日志分析可以发现影响你工作负载的问题。然而,困难的是如何找到一个与大量运行的应用程序一起工作的监视解决方案。 -在本文中,我将使用 [Graylog][2] (用于日志)和 [Prometheus][3] (用于指标)去打造一个Kubernetes 集群的监视解决方案。当然了,这不仅是将三个东西连接起来那么简单,实现上,最终结果看起来应该如下图所示: +在本文中,我将使用 [Graylog][2] (用于日志)和 [Prometheus][3] (用于指标)去打造一个 Kubernetes 集群的监视解决方案。当然了,这不仅是将三个东西连接起来那么简单,实现上,最终结果看起来应该如下图所示: ![][4] -正如你所了解的,Kubernetes 不仅做一件事情 —— 它是 master、workers、networking bit 等等。同样,Graylog 是一个配角(apache2、mongodb、等等),Prometheus 也一样(telegraf、grafana 等等)。在部署中连接这些点看起来似乎有些让人恐惧,但是使用合适的工具将不会那么困难。 +正如你所了解的,Kubernetes 不是一件东西 —— 它由主控节点、工作节点、网络连接、配置管理等等组成。同样,Graylog 是一个配角(apache2、mongodb、等等),Prometheus 也一样(telegraf、grafana 等等)。在部署中连接这些点看起来似乎有些让人恐惧,但是使用合适的工具将不会那么困难。 -我将使用 [conjure-up][5] 和 [Canonical Distribution of Kubernetes][6] (CDK) 去探索 Kubernetes。我发现 conjure-up 接口对部署大型软件很有帮助,但是我知道一些人可能不喜欢 GUIs、TUIs 以及其它 UIs。对于这些人,我将用命令行再去部署一遍。 +我将使用 [conjure-up][5] 和 [Canonical 版本的 Kubernetes][6] (CDK) 去探索 Kubernetes。我发现 `conjure-up` 接口对部署大型软件很有帮助,但是我知道一些人可能不喜欢 GUI、TUI 以及其它用户界面。对于这些人,我将用命令行再去部署一遍。 -在开始之前需要注意的一点是,Graylog 和 Prometheus 是部署在 Kubernetes 侧而不是集群上。像 Kubernetes 仪表盘和 Heapster 是运行的集群中非常好的信息来源,但是我的目标是为日志/指标提供一个分析机制,而不管集群运行与否。 +在开始之前需要注意的一点是,Graylog 和 Prometheus 是部署在 Kubernetes 外侧而不是集群上。像 Kubernetes 仪表盘和 Heapster 是运行的集群的非常好的信息来源,但是我的目标是为日志/指标提供一个分析机制,而不管集群运行与否。 ### 开始探索 -如果你的系统上没有 conjure-up,首先要做的第一件事情是,请先安装它,在 Linux 上,这很简单: +如果你的系统上没有 `conjure-up`,首先要做的第一件事情是,请先安装它,在 Linux 上,这很简单: + ``` sudo snap install conjure-up --classic ``` 对于 macOS 用户也提供了 brew 包: + ``` brew install conjure-up ``` @@ -29,34 +32,33 @@ brew install conjure-up 你需要最新的 2.5.2 版,它的好处是添加了 CDK spell,因此,如果你的系统上已经安装了旧的版本,请使用 `sudo snap refresh conjure-up` 或者 `brew update && brew upgrade conjure-up` 去更新它。 安装完成后,运行它: + ``` conjure-up ``` ![][7] -你将发现有一个 spell 列表。选择 CDK 然后按下 `Enter`。 +你将发现有一个 spell 列表。选择 CDK 然后按下回车。 ![][8] -这个时候,你将看到 CDK spell 可用的附加组件。我们感兴趣的是 Graylog 和 Prometheus,因此选择这两个,然后点击 `Continue`。 +这个时候,你将看到 CDK spell 可用的附加组件。我们感兴趣的是 Graylog 和 Prometheus,因此选择这两个,然后点击 “Continue”。 它将引导你选择各种云,以决定你的集群部署的地方。之后,你将看到一些部署的后续步骤,接下来是回顾屏幕,让你再次确认部署内容: ![][9] -除了典型的 K8s 相关的应用程序(etcd、flannel、load-balancer、master、以及 workers)之外,你将看到我们选择的日志和指标相关的额外应用程序。 +除了典型的 K8s 相关的应用程序(etcd、flannel、load-balancer、master 以及 workers)之外,你将看到我们选择的日志和指标相关的额外应用程序。 Graylog 栈包含如下: - * apache2:graylog web 接口的反向代理 + * apache2:graylog web 界面的反向代理 * elasticsearch:日志使用的文档数据库 * filebeat:从 K8s master/workers 转发日志到 graylog * graylog:为日志收集器提供一个 api,以及提供一个日志分析界面 * mongodb:保存 graylog 元数据的数据库 - - Prometheus 栈包含如下: * grafana:指标相关的仪表板的 web 界面 @@ -64,18 +66,18 @@ Prometheus 栈包含如下: * telegraf:发送主机的指标到 prometheus 中 +你可以在回顾屏幕上微调部署,但是默认组件是必选 的。点击 “Deploy all Remaining Applications” 继续。 -你可以在回顾屏幕上微调部署,但是默认组件是必选 的。点击 `Deploy all Remaining Applications` 继续。 - -部署工作将花费一些时间,它将部署你的机器和配置你的云。完成后,conjure-up 将展示一个摘要屏幕,它包含一些链连,你可以用你的终端去浏览各种感兴趣的内容: +部署工作将花费一些时间,它将部署你的机器和配置你的云。完成后,`conjure-up` 将展示一个摘要屏幕,它包含一些链接,你可以用你的终端去浏览各种感兴趣的内容: ![][10] #### 浏览日志 -现在,Graylog 已经部署和配置完成,我们可以看一下采集到的一些数据。默认情况下,filebeat 应用程序将从 Kubernetes 的 master 和 workers 中转发系统日志( `/var/log/*.log` )和容器日志(`/var/log/containers/*.log`)到 graylog 中。 +现在,Graylog 已经部署和配置完成,我们可以看一下采集到的一些数据。默认情况下,filebeat 应用程序将从 Kubernetes 的 master 和 worker 中转发系统日志( `/var/log/*.log` )和容器日志(`/var/log/containers/*.log`)到 graylog 中。 记住如下的 apache2 的地址和 graylog 的 admin 密码: + ``` juju status --format yaml apache2/0 | grep public-address public-address: @@ -83,15 +85,15 @@ juju run-action --wait graylog/0 show-admin-password admin-password: ``` -在浏览器中输入 `http://` ,然后以管理员用户名(admin)和密码()登入。 +在浏览器中输入 `http://` ,然后以管理员用户名(admin)和密码(\)登入。 **注意:** 如果这个界面不可用,请等待大约 5 分钟时间,以便于配置的反向代理生效。 -登入后,顶部的 `Sources` 选项卡可以看到从 K8s 的 master 和 workers 中收集日志的概述: +登入后,顶部的 “Sources” 选项卡可以看到从 K8s 的 master 和 workers 中收集日志的概述: ![][11] -通过点击 `System / Inputs` 选项卡深入这些日志,选择 `Show received messages` 查看 filebeat 的输入: +通过点击 “System / Inputs” 选项卡深入这些日志,选择 “Show received messages” 查看 filebeat 的输入: ![][12] @@ -99,9 +101,10 @@ juju run-action --wait graylog/0 show-admin-password #### 浏览指标 -我们的部署通过 grafana 仪表板提供了两种类型的指标:系统指标,包括像 K8s master 和 workers 的 cpu/内存/磁盘使用情况,以及集群指标,包括像从 K8s cAdvisor 端点上收集的容器级指标。 +我们的部署通过 grafana 仪表板提供了两种类型的指标:系统指标,包括像 K8s master 和 worker 的 CPU /内存/磁盘使用情况,以及集群指标,包括像从 K8s cAdvisor 端点上收集的容器级指标。 记住如下的 grafana 的地址和 admin 密码: + ``` juju status --format yaml grafana/0 | grep public-address public-address: @@ -109,46 +112,50 @@ juju run-action --wait grafana/0 get-admin-password password: ``` -在浏览器中输入 `http://:3000`,输入管理员用户(admin)和密码()登入。成功登入后,点击 `Home` 下拉框,选取 `Kubernetes Metrics (via Prometheus)` 去查看集群指标仪表板: +在浏览器中输入 `http://:3000`,输入管理员用户(admin)和密码(\)登入。成功登入后,点击 “Home” 下拉框,选取 “Kubernetes Metrics (via Prometheus)” 去查看集群指标仪表板: ![][14] -我们也可以通过下拉框切换到 `Node Metrics (via Telegraf) ` 去查看 K8s 主机的系统指标。 +我们也可以通过下拉框切换到 “Node Metrics (via Telegraf) ” 去查看 K8s 主机的系统指标。 ![][15] - ### 另一种方法 -正如在文章开始的介绍中提到的,我喜欢 conjure-up 的 “魔法之杖” 去指导我完成像 Kubernetes 这种复杂软件的部署。现在,我们来看一下 conjure-up 的另一种方法,你可能希望去看到实现相同结果的一些命令行的方法。还有其它的可能已经部署了前面的 CDK,想去扩展使用上述的 Graylog/Prometheus 组件。不管什么原因你既然看到这了,既来之则安之,继续向下看吧。 +正如在文章开始的介绍中提到的,我喜欢用 `conjure-up` 的向导去完成像 Kubernetes 这种复杂软件的部署。现在,我们来看一下 `conjure-up` 的另一种方法,你可能希望去看到实现相同结果的一些命令行的方法。还有其它的可能已经部署了前面的 CDK,并想去扩展使用上述的 Graylog/Prometheus 组件。不管什么原因你既然看到这了,既来之则安之,继续向下看吧。 -支持 conjure-up 的工具是 [Juju][16]。CDK spell 所做的一切,都可以使用 juju 命令行来完成。我们来看一下,如何一步步完成这些工作。 +支持 `conjure-up` 的工具是 [Juju][16]。CDK spell 所做的一切,都可以使用 `juju` 命令行来完成。我们来看一下,如何一步步完成这些工作。 -**从 Scratch 中启动** +#### 从 Scratch 中启动 如果你使用的是 Linux,安装 Juju 很简单,命令如下: + ``` sudo snap install juju --classic ``` 对于 macOS,Juju 也可以从 brew 中安装: + ``` brew install juju ``` 现在为你选择的云配置一个控制器。你或许会被提示请求一个凭据(用户名密码): + ``` juju bootstrap ``` 我们接下来需要基于 CDK 捆绑部署: + ``` juju deploy canonical-kubernetes ``` -**从 CDK 开始** +#### 从 CDK 开始 使用我们部署的 Kubernetes 集群,我们需要去添加 Graylog 和 Prometheus 所需要的全部应用程序: + ``` ## deploy graylog-related applications juju deploy xenial/apache2 @@ -165,6 +172,7 @@ juju deploy xenial/telegraf ``` 现在软件已经部署完毕,将它们连接到一起,以便于它们之间可以相互通讯: + ``` ## relate graylog applications juju relate apache2:reverseproxy graylog:website @@ -182,6 +190,7 @@ juju relate kubernetes-worker:juju-info telegraf:juju-info ``` 这个时候,所有的应用程序已经可以相互之间进行通讯了,但是我们还需要多做一点配置(比如,配置 apache2 反向代理、告诉 prometheus 如何从 K8s 中取数、导入到 grafana 仪表板等等): + ``` ## configure graylog applications juju config apache2 enable_modules="headers proxy_html proxy_http" @@ -199,17 +208,17 @@ juju run-action --wait grafana/0 import-dashboard \ dashboard="$(base64 )" ``` -以上的步骤需要根据你的部署来指定一些值。你可以用与 conjure-up 相同的方法得到这些: - - * : 从 github 获取我们的示例 [模板][17] - * : `juju run --unit graylog/0 'unit-get private-address'` - * : `juju config elasticsearch cluster-name` - * : 从 github 获取我们的示例 [scraper][18] ;`[K8S_PASSWORD][20]` 和 `[K8S_API_ENDPOINT][21]` [substitute][19] 的正确值 - * : 从 github 获取我们的 [主机][22] 和 [k8s][23] 仪表板 +以上的步骤需要根据你的部署来指定一些值。你可以用与 `conjure-up` 相同的方法得到这些: + * ``: 从 github 获取我们的示例 [模板][17] + * ``: `juju run --unit graylog/0 'unit-get private-address'` + * ``: `juju config elasticsearch cluster-name` + * ``: 从 github 获取我们的示例 [scraper][18] ;`[K8S_PASSWORD][20]` 和 `[K8S_API_ENDPOINT][21]` [substitute][19] 的正确值 + * ``: 从 github 获取我们的 [主机][22] 和 [k8s][23] 仪表板 最后,发布 apache2 和 grafana 应用程序,以便于可以通过它们的 web 界面访问: + ``` ## expose relevant endpoints juju expose apache2 @@ -222,7 +231,7 @@ juju expose grafana 我的目标是向你展示如何去部署一个 Kubernetes 集群,很方便地去监视它的日志和指标。无论你是喜欢向导的方式还是命令行的方式,我希望你清楚地看到部署一个监视系统并不复杂。关键是要搞清楚所有部分是如何工作的,并将它们连接到一起工作,通过断开/修复/重复的方式,直到它们每一个都能正常工作。 -这里有一些非常好的工具像 conjure-up 和 Juju。充分发挥这个生态系统贡献者的专长让管理大型软件变得更容易。从一套可靠的应用程序开始,按需定制,然后投入到工作中! +这里有一些像 conjure-up 和 Juju 一样非常好的工具。充分发挥这个生态系统贡献者的专长让管理大型软件变得更容易。从一套可靠的应用程序开始,按需定制,然后投入到工作中! 大胆去尝试吧,然后告诉我你用的如何。你可以在 Freenode IRC 的 **#conjure-up** 和 **#juju** 中找到像我这样的爱好者。感谢阅读! @@ -236,7 +245,7 @@ via: https://insights.ubuntu.com/2018/01/16/monitor-your-kubernetes-cluster/ 作者:[Kevin Monroe][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md b/published/201804/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md similarity index 77% rename from translated/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md rename to published/201804/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md index fdd9c678c2..5fcbb6b05b 100644 --- a/translated/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md +++ b/published/201804/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md @@ -1,14 +1,20 @@ -(再次)在 Ubuntu 16.04 上配置 MSMTP +在 Ubuntu 16.04 上配置 msmtp ====== -这篇文章是在我之前的博客中发表过的在 Ubuntu 16.04 上配置 MSMTP 的一个副本。我再次发表是为了后续,我并不知道它是否能在更高版本上工作。由于我没有再托管自己的 Ubuntu/MSMTP 服务器了,所以我现在看不到有更新的,但是如果我需要重新设置,我会创建一个更新的帖子!无论如何,这是我现有的。 + +这篇文章是在我之前的博客中发表过的在 Ubuntu 16.04 上配置 MSMTP 的一个副本。我再次发表是为了后续,我并不知道它是否能在更高版本上工作。由于我没有再托管自己的 Ubuntu/MSMTP 服务器了,所以我现在看不到有需要更新的地方,但是如果我需要重新设置,我会创建一个更新的帖子!无论如何,这是我现有的。 我之前写了一篇在 Ubuntu 12.04 上配置 msmtp 的文章,但是正如我在之前的文章中暗示的那样,当我升级到 Ubuntu 16.04 后出现了一些问题。接下来的内容基本上是一样的,但 16.04 有一些小的更新。和以前一样,这里假定你使用 Apache 作为 Web 服务器,但是我相信如果你选择其他的 Web 服务器,也应该相差不多。 -我使用 [msmtp][1] 发送来自这个博客的邮件俩通知我评论和更新等。这里我会记录如何配置它通过 Google Apps 帐户发送电子邮件,虽然这应该与标准帐户一样。 +我使用 [msmtp][1] 发送来自这个博客的邮件俩通知我评论和更新等。这里我会记录如何配置它通过 Google Apps 帐户发送电子邮件,虽然这应该与标准的 Google 帐户一样。 首先,我们需要安装 3 个软件包: -`sudo apt-get install msmtp msmtp-mta ca-certificates` -安装完成后,就需要一个默认配置。默认情况下,msmtp 会在 `/etc/msmtprc` 中查找,所以我使用 vim 创建了这个文件,尽管任何文本编辑器都可以做到这一点。这个文件看起来像这样: + +``` +sudo apt-get install msmtp msmtp-mta ca-certificates +``` + +安装完成后,就需要一个默认配置。默认情况下,msmtp 会在 `/etc/msmtprc` 中查找,所以我使用 `vim` 创建了这个文件,尽管任何文本编辑器都可以做到这一点。这个文件看起来像这样: + ``` # Set defaults. defaults @@ -17,50 +23,57 @@ tls on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt # Setup WP account's settings. -account +account GMAIL host smtp.gmail.com port 587 auth login -user -password -from +user YOUR USERNAME +password YOUR PASSWORD +from FROM@ADDRESS logfile /var/log/msmtp/msmtp.log account default : - ``` -任何大写项(即``)都是需要替换为你特定的配置。日志文件是一个例外,当然你也可以将活动/警告/错误放在任何你想要的地方。 +任何大写选项都是需要替换为你特定的配置。日志文件是一个例外,当然你也可以将活动/警告/错误放在任何你想要的地方。 文件保存后,我们将更新上述配置文件的权限 ,如果该文件的权限过于开放,msmtp 将不会运行,并且创建日志文件的目录。 + ``` sudo mkdir /var/log/msmtp sudo chown -R www-data:adm /var/log/msmtp sudo chmod 0600 /etc/msmtprc - ``` 接下来,我选择为 msmtp 日志配置 logrotate,以确保日志文件不会太大并让日志目录更加整洁。为此,我们创建 `/etc/logrotate.d/msmtp` 并使用按以下内容配置。请注意,这是可选的,你可以选择不这样做,或者你可以选择以不同方式配置日志。 ``` /var/log/msmtp/*.log { -rotate 12 -monthly -compress -missingok -notifempty + rotate 12 + monthly + compress + missingok + notifempty } ``` 现在配置了日志,我们需要通过编辑 `/etc/php/7.0/apache2/php.ini` 告诉 PHP 使用 msmtp,并将 sendmail 路径从 -`sendmail_path =` + +``` +sendmail_path = +``` + 变成 -`sendmail_path = "/usr/bin/msmtp -C /etc/msmtprc -a -t"` + +``` +sendmail_path = "/usr/bin/msmtp -C /etc/msmtprc -a -t" +``` + 这里我遇到了一个问题,即使我指定了帐户名称,但是当我测试它时,它并没有正确发送电子邮件。这就是为什么 `account default : ` 这行被放在 msmtp 配置文件的末尾。要测试配置,请确保 PHP 文件已保存并运行 `sudo service apache2 restart`,然后运行 `php -a` 并执行以下命令 + ``` mail ('personal@email.com', 'Test Subject', 'Test body text'); exit(); - ``` 此时发生的任何错误都将显示在输出中,因此错误诊断会相对容易。如果一切顺利,你现在应该可以使用 PHP sendmail(至少 WordPress 可以)中用 Gmail(或 Google Apps)从 Ubuntu 服务器发送电子邮件。 @@ -74,7 +87,7 @@ via: https://codingproductivity.wordpress.com/2018/01/18/configuring-msmtp-on-ub 作者:[JOE][a] 译者:[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/) 荣誉推出 diff --git a/published/201804/20180118 Securing the Linux filesystem with Tripwire.md b/published/201804/20180118 Securing the Linux filesystem with Tripwire.md new file mode 100644 index 0000000000..f82584a772 --- /dev/null +++ b/published/201804/20180118 Securing the Linux filesystem with Tripwire.md @@ -0,0 +1,103 @@ +使用 Tripwire 保护 Linux 文件系统 +====== + +> 如果恶意软件或其情况改变了你的文件系统,Linux 完整性检查工具会提示你。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/file_system.jpg?itok=pzCrX1Kc) + +尽管 Linux 被认为是最安全的操作系统(排在 Windows 和 MacOS 之前),但它仍然容易受到 rootkit 和其他恶意软件的影响。因此,Linux 用户需要知道如何保护他们的服务器或个人电脑免遭破坏,他们需要采取的第一步就是保护文件系统。 + +在本文中,我们将看看 [Tripwire][1],这是保护 Linux 文件系统的绝佳工具。Tripwire 是一个完整性检查工具,使得系统管理员、安全工程师和其他人能够检测系统文件的变更。虽然它不是唯一的选择([AIDE][2] 和 [Samhain][3] 提供类似功能),但 Tripwire 可以说是 Linux 系统文件中最常用的完整性检查程序,并在 GPLv2 许可证下开源。 + +### Tripwire 如何工作 + +了解 Tripwire 如何运行对了解 Tripwire 在安装后会做什么有所帮助。Tripwire 主要由两个部分组成:策略和数据库。策略列出了完整性检查器应该生成快照的所有文件和目录,还创建了用于识别对目录和文件更改违规的规则。数据库由 Tripwire 生成的快照组成。 + +Tripwire 还有一个配置文件,它指定数据库、策略文件和 Tripwire 可执行文件的位置。它还提供两个加密密钥 —— 站点密钥和本地密钥 —— 以保护重要文件免遭篡改。站点密钥保护策略和配置文件,而本地密钥保护数据库和生成的报告。 + +Tripwire 会定期将目录和文件与数据库中的快照进行比较并报告所有的更改。 + +### 安装 Tripwire + +要 Tripwire,我们需要先下载并安装它。Tripwire 适用于几乎所有的 Linux 发行版。你可以从 [Sourceforge][4] 下载一个开源版本,并如下根据你的 Linux 版本进行安装。 + +Debian 和 Ubuntu 用户可以使用 `apt-get` 直接从仓库安装 Tripwire。非 root 用户应该输入 `sudo` 命令通过 `apt-get` 安装 Tripwire。 + +``` +sudo apt-get update +sudo  apt-get install tripwire   +``` + +CentOS 和其他基于 RPM 的发行版使用类似的过程。为了最佳实践,请在安装新软件包(如 Tripwire)之前更新仓库。命令 `yum install epel-release` 意思是我们想要安装额外的存储库。 (`epel` 代表 Extra Packages for Enterprise Linux。) + +``` +yum update +yum install epel-release +yum install tripwire   +``` + +此命令会在安装中运行让 Tripwire 有效运行所需的配置。另外,它会在安装过程中询问你是否使用密码。你可以两个选择都选择 “Yes”。 + +另外,如果需要构建配置文件,请选择 “Yes”。选择并确认站点密钥和本地密钥的密码。(建议使用复杂的密码,例如 `Il0ve0pens0urce` 这样的。) + +### 建立并初始化 Tripwire 数据库 + +接下来,按照以下步骤初始化 Tripwire 数据库: + +``` +tripwire --init +``` + +你需要提供本地密钥密码才能运行这些命令。 + +### 使用 Tripwire 进行基本的完整性检查 + +你可以使用以下命令让 Tripwire 检查你的文件或目录是否已被修改。Tripwire 将文件和目录与数据库中的初始快照进行比较的能力依赖于你在活动策略中创建的规则。 + +``` +tripwire  --check   +``` + +你还可以将 `-check` 命令限制为特定的文件或目录,如下所示: + +``` +tripwire   --check   /usr/tmp   +``` + +另外,如果你需要使用 Tripwire 的 `-check` 命令的更多帮助,该命令能够查阅 Tripwire 的手册: + +``` +tripwire  --check  --help   +``` + +### 使用 Tripwire 生成报告 + +要轻松生成每日系统完整性报告,请使用以下命令创建一个 crontab 任务: + +``` +crontab -e +``` + +之后,你可以编辑此文件(使用你选择的文本编辑器)来引入由 cron 运行的任务。例如,你可以使用以下命令设置一个 cron 任务,在每天的 5:40 将 Tripwire 的报告发送到你的邮箱: + +``` +40 5  *  *  *  usr/sbin/tripwire   --check +``` + +无论你决定使用 Tripwire 还是其他具有类似功能的完整性检查程序,关键问题都是确保你有解决方案来保护 Linux 文件系统的安全。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/securing-linux-filesystem-tripwire + +作者:[Michael Kwaku Aboagye][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/revoks +[1]:https://www.tripwire.com/ +[2]:http://aide.sourceforge.net/ +[3]:http://www.la-samhna.de/samhain/ +[4]:http://sourceforge.net/projects/tripwire diff --git a/translated/tech/20180122 How to Create a Docker Image.md b/published/201804/20180122 How to Create a Docker Image.md similarity index 76% rename from translated/tech/20180122 How to Create a Docker Image.md rename to published/201804/20180122 How to Create a Docker Image.md index ec0810a10a..241af3faa7 100644 --- a/translated/tech/20180122 How to Create a Docker Image.md +++ b/published/201804/20180122 How to Create a Docker Image.md @@ -3,181 +3,160 @@ ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/container-image_0.jpg?itok=G_Gz80R9) -在 [前面的文章][1] 中,我们学习了在 Linux、macOS、以及 Windows 上如何使用 Docker 的基础知识。在这篇文章中,我们将去学习创建 Docker 镜像的基本知识。我们可以在 DockerHub 上得到你可以用于你自己的项目的预构建镜像,并且也可以将你自己的镜像发布到这里。 +在 [前面的文章][1] 中,我们学习了在 Linux、macOS、以及 Windows 上如何使用 Docker 的基础知识。在这篇文章中,我们将学习创建 Docker 镜像的基本知识。我们可以在 DockerHub 上得到可用于你自己的项目的预构建镜像,并且也可以将你自己的镜像发布到这里。 -我们使用预构建镜像得到一个基本的 Linux 子系统,因为,从头开始构建需要大量的工作。你可以得到 Alpine( Docker 版使用的官方版本)、Ubuntu、BusyBox、或者 scratch。在我们的示例中,我将使用 Ubuntu。 +我们使用预构建镜像得到一个基本的 Linux 子系统,因为,从头开始构建需要大量的工作。你可以使用 Alpine( Docker 版使用的官方版本)、Ubuntu、BusyBox、或者 scratch。在我们的示例中,我将使用 Ubuntu。 在我们开始构建镜像之前,让我们先“容器化”它们!我的意思是,为你的所有 Docker 镜像创建目录,这样你就可以维护不同的项目和阶段,并保持它们彼此隔离。 + ``` $ mkdir dockerprojects - cd dockerprojects - ``` 现在,在 `dockerprojects` 目录中,你可以使用自己喜欢的文本编辑器去创建一个 `Dockerfile` 文件;我喜欢使用 nano,它对新手来说很容易上手。 + ``` $ nano Dockerfile - ``` 然后添加这样的一行内容: + ``` FROM Ubuntu - ``` -![m7_f7No0pmZr2iQmEOH5_ID6MDG2oEnODpQZkUL7][2] +![][2] -使用 Ctrl+Exit 然后选择 Y 去保存它。 +使用 `Ctrl+Exit` 然后选择 `Y` 去保存它。 现在开始创建你的新镜像,然后给它起一个名字(在刚才的目录中运行如下的命令): + ``` $ docker build -t dockp . - ``` (注意命令后面的圆点)这样就创建成功了,因此,你将看到如下内容: + ``` -Sending build context to Docker daemon 2.048kB - +Sending build context to Docker daemon 2.048kB Step 1/1 : FROM ubuntu - ---> 2a4cca5ac898 - Successfully built 2a4cca5ac898 - Successfully tagged dockp:latest - ``` 现在去运行和测试一下你的镜像: + ``` $ docker run -it Ubuntu - ``` 你将看到 root 提示符: + ``` root@c06fcd6af0e8:/# - ``` 这意味着在 Linux、Windows、或者 macOS 中你可以运行一个最小的 Ubuntu 了。你可以运行所有的 Ubuntu 原生命令或者 CLI 实用程序。 -![vpZ8ts9oq3uk--z4n6KP3DD3uD_P4EpG7fX06MC3][3] +![][3] 我们来查看一下在你的目录下你拥有的所有 Docker 镜像: + ``` $docker images - REPOSITORY TAG IMAGE ID CREATED SIZE - dockp latest 2a4cca5ac898 1 hour ago 111MB - ubuntu latest 2a4cca5ac898 1 hour ago 111MB - hello-world latest f2a91732366c 8 weeks ago 1.85kB - ``` -你可以看到共有三个镜像:dockp、Ubuntu、和 hello-world, hello-world 是我在几周前创建的,这一系列的前面的文章就是在它下面工作的。构建一个完整的 LAMP 栈可能是一个挑战,因此,我们使用 Dockerfile 去创建一个简单的 Apache 服务器镜像。 +你可以看到共有三个镜像:`dockp`、`Ubuntu`、和 `hello-world`, `hello-world` 是我在几周前创建的,这一系列的前面的文章就是在它下面工作的。构建一个完整的 LAMP 栈可能是一个挑战,因此,我们使用 Dockerfile 去创建一个简单的 Apache 服务器镜像。 从本质上说,Dockerfile 是安装所有需要的包、配置、以及拷贝文件的一套指令。在这个案例中,它是安装配置 Apache 和 Nginx。 你也可以在 DockerHub 上去创建一个帐户,然后在构建镜像之前登入到你的帐户,在这个案例中,你需要从 DockerHub 上拉取一些东西。从命令行中登入 DockerHub,运行如下所求的命令: + ``` $ docker login - ``` 在登入时输入你的用户名和密码。 接下来,为这个 Docker 项目,在目录中创建一个 Apache 目录: + ``` $ mkdir apache - ``` 在 Apache 目录中创建 Dockerfile 文件: + ``` $ nano Dockerfile - ``` 然后,粘贴下列内容: + ``` FROM ubuntu - MAINTAINER Kimbro Staken version: 0.1 - RUN apt-get update && apt-get install -y apache2 && apt-get clean && rm -rf /var/lib/apt/lists/* - ENV APACHE_RUN_USER www-data - ENV APACHE_RUN_GROUP www-data - ENV APACHE_LOG_DIR /var/log/apache2 - EXPOSE 80 - CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"] - ``` 然后,构建镜像: + ``` docker build -t apache . - ``` (注意命令尾部的空格和圆点) 这将花费一些时间,然后你将看到如下的构建成功的消息: + ``` Successfully built e7083fd898c7 - Successfully tagged ng:latest - Swapnil:apache swapnil$ - ``` 现在,我们来运行一下这个服务器: + ``` $ docker run -d apache - a189a4db0f7c245dd6c934ef7164f3ddde09e1f3018b5b90350df8be85c8dc98 - ``` 发现了吗,你的容器镜像已经运行了。可以运行如下的命令来检查所有运行的容器: + ``` $ docker ps - CONTAINER ID IMAGE COMMAND CREATED - a189a4db0f7 apache "/usr/sbin/apache2ctl" 10 seconds ago - ``` -你可以使用 docker kill 命令来杀死容器: +你可以使用 `docker kill` 命令来杀死容器: + ``` $docker kill a189a4db0f7 - ``` -正如你所见,这个 "镜像" 它已经永久存在于你的目录中了,而不论运行与否。现在你可以根据你的需要创建很多的镜像,并且可以从这些镜像中繁衍出来更多的镜像。 +正如你所见,这个 “镜像” 它已经永久存在于你的目录中了,而不论运行与否。现在你可以根据你的需要创建很多的镜像,并且可以从这些镜像中繁衍出来更多的镜像。 这就是如何去创建镜像和运行容器。 -想学习更多内容,你可以打开你的浏览器,然后找到更多的关于如何构建像 LAMP 栈这样的完整的 Docker 镜像的文档。这里有一个帮你实现它的 [ Dockerfile][4] 文件。在下一篇文章中,我将演示如何推送一个镜像到 DockerHub。 +想学习更多内容,你可以打开你的浏览器,然后找到更多的关于如何构建像 LAMP 栈这样的完整的 Docker 镜像的文档。这里有一个帮你实现它的 [Dockerfile][4] 文件。在下一篇文章中,我将演示如何推送一个镜像到 DockerHub。 -你可以通过来自 Linux 基金会和 edX 的 ["介绍 Linux" ][5] 免费课程来学习更多的知识。 +你可以通过来自 Linux 基金会和 edX 的 [“介绍 Linux”][5] 免费课程来学习更多的知识。 -------------------------------------------------------------------------------- @@ -185,7 +164,7 @@ via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-create-docker-im 作者:[SWAPNIL BHARTIYA][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180123 Migrating to Linux- The Command Line.md b/published/201804/20180123 Migrating to Linux- The Command Line.md similarity index 58% rename from translated/tech/20180123 Migrating to Linux- The Command Line.md rename to published/201804/20180123 Migrating to Linux- The Command Line.md index 4d9d98f0f9..f99b49f980 100644 --- a/translated/tech/20180123 Migrating to Linux- The Command Line.md +++ b/published/201804/20180123 Migrating to Linux- The Command Line.md @@ -1,37 +1,43 @@ 迁徙到 Linux:命令行环境 ====== +> 刚接触 Linux?在这篇教程中将学习如何轻松地在命令行列出、移动和编辑文件。 + ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/migrate.jpg?itok=2PBkvV7s) -这是关于迁徙到 Linux 系列的第四篇文章了。如果您错过了之前的内容,可以回顾我们之前谈到的内容 [新手之 Linux][1]、[文件和文件系统][2]、和 [图形环境][3]。Linux 无处不在,它可以运行在大部分的网络服务器,如 web、email 和其他服务器;它同样可以在您的手机、汽车控制台和其他很多设备上使用。现在,您可能会开始好奇 Linux 系统,并对学习 Linux 的工作原理萌发兴趣。 +这是关于迁徙到 Linux 系列的第四篇文章了。如果您错过了之前的内容,可以回顾我们之前谈到的内容 [新手之 Linux][1]、[文件和文件系统][2]、和 [图形环境][3]。Linux 无处不在,它可以用于运行大部分的网络服务器,如 Web、email 和其他服务器;它同样可以在您的手机、汽车控制台和其他很多设备上使用。现在,您可能会开始好奇 Linux 系统,并对学习 Linux 的工作原理萌发兴趣。 -在 Linux 下,命令行非常实用。Linux 的桌面系统中,尽管命令行只是可选操作,但是您依旧能看见很多朋友开着一个命令行窗口和其他应用窗口并肩作战。在运行 Linux 系统的网络服务器中,命令行通常是唯一能直接与操作系统交互的工具。因此,命令行是有必要了解的,至少应当涉猎一些基础命令。 +在 Linux 下,命令行非常实用。Linux 的桌面系统中,尽管命令行只是可选操作,但是您依旧能看见很多朋友开着一个命令行窗口和其他应用窗口并肩作战。在互联网服务器上和在设备中运行 Linux 时(LCTT 译注:指 IoT),命令行通常是唯一能直接与操作系统交互的工具。因此,命令行是有必要了解的,至少应当涉猎一些基础命令。 在命令行(通常称之为 Linux shell)中,所有操作都是通过键入命令完成。您可以执行查看文件列表、移动文件位置、显示文件内容、编辑文件内容等一系列操作,通过命令行,您甚至可以查看网页中的内容。 -如果您在 Windows(CMD 或者 PowerShell) 上已经熟悉关于命令行的使用,您是否想跳转到了解 Windows 命令行的章节上去?先了阅读这些内容吧。 +如果您在 Windows(CMD 或者 PowerShell) 上已经熟悉关于命令行的使用,您是否想跳转到“Windows 命令行用户”的章节上去?先阅读这些内容吧。 -### 导语 +### 导航 + +在命令行中,这里有一个当前工作目录(文件夹和目录是同义词,在 Linux 中它们通常都被称为目录)的概念。如果没有特别指定目录,许多命令的执行会在当前目录下生效。比如,键入 `ls` 列出文件目录,当前工作目录的文件将会被列举出来。看一个例子: -在命令行中,这里有一个当前工作目录(文件夹和目录是同义词,在 Linux 中它们通常都被称为目录)的概念。如果没有特别指定目录,许多命令的执行会在当前目录下生效。比如,键入 ls 列出文件目录,当前工作目录的文件将会被列举出来。看一个例子: ``` $ ls Desktop Documents Downloads Music Pictures README.txt Videos ``` `ls Documents` 这条命令将会列出 `Documents` 目录下的文件: + ``` $ ls Documents report.txt todo.txt EmailHowTo.pdf ``` 通过 `pwd` 命令可以显示当前您的工作目录。比如: + ``` $ pwd /home/student ``` 您可以通过 `cd` 命令改变当前目录并切换到您想要抵达的目录。比如: + ``` $ pwd /home/student @@ -40,11 +46,12 @@ $ pwd /home/student/Downloads ``` -路径中的目录由 `/`(左斜杠)字符分隔。路径中有一个隐含的层次关系,比如 `/home/student` 目录中,home 是顶层目录,而 student 是 home 的子目录。 +路径中的目录由 `/`(左斜杠)字符分隔。路径中有一个隐含的层次关系,比如 `/home/student` 目录中,home 是顶层目录,而 `student` 是 `home` 的子目录。 路径要么是绝对路径,要么是相对路径。绝对路径由一个 `/` 字符打头。 -相对路径由 `.` 或者 `..` 开始。在一个路径中,一个 `.` 意味着当前目录,`..` 意味着当前目录的上级目录。比如,`ls ../Documents` 意味着在此寻找当前目录的上级名为 `Documets` 的目录: +相对路径由 `.` 或者 `..` 开始。在一个路径中,一个 `.` 意味着当前目录,`..` 意味着当前目录的上级目录。比如,`ls ../Documents` 意味着在此寻找当前目录的上级名为 `Documents` 的目录: + ``` $ pwd /home/student @@ -57,9 +64,10 @@ $ ls ../Documents report.txt todo.txt EmailHowTo.pdf ``` -当您第一次打开命令行窗口时,您当前的工作目录被设置为您的家目录,通常为 `/home/<您的登录名>`。家目录专用于登陆之后存储您的专属文件。 +当您第一次打开命令行窗口时,您当前的工作目录被设置为您的家目录,通常为 `/home/<您的登录名>`。家目录专用于登录之后存储您的专属文件。 + +环境变量 `$HOME` 会展开为您的家目录,比如: -设置环境变量 `$HOME` 到您的家目录,比如: ``` $ echo $HOME /home/student @@ -67,59 +75,67 @@ $ echo $HOME 下表显示了用于目录导航和管理简单的文本文件的一些命令摘要。 -![table](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table-1_0.png?itok=j4Sgv6Vy) +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table-1_0.png?itok=j4Sgv6Vy) ### 搜索 有时我们会遗忘文件的位置,或者忘记了我要寻找的文件名。Linux 命令行有几个命令可以帮助您搜索到文件。 -第一个命令是 `find`。您可以使用 `find` 命令通过文件名或其他属性搜索文件和目录。举个例子,当您遗忘了 todo.txt 文件的位置,我们可以执行下面的代码: +第一个命令是 `find`。您可以使用 `find` 命令通过文件名或其他属性搜索文件和目录。举个例子,当您遗忘了 `todo.txt` 文件的位置,我们可以执行下面的代码: + ``` $ find $HOME -name todo.txt /home/student/Documents/todo.txt ``` `find` 程序有很多功能和选项。一个简单的例子: + ``` find <要寻找的目录> -name <文件名> ``` -如果这里有 `todo.txt` 文件且不止一个,它将向我们列出拥有这个名字的所有文件的所有所在位置。`find` 命令有很多便于搜索的选项比如类型(文件或是目录等等)、时间、大小和其他一些选项。更多内容您可以同通过:`man find` 获取关于如何使用 `find` 命令的帮助。 +如果这里有 `todo.txt` 文件且不止一个,它将向我们列出拥有这个名字的所有文件的所有所在位置。`find` 命令有很多便于搜索的选项比如类型(文件或是目录等等)、时间、大小和其他一些选项。更多内容您可以同通过 `man find` 获取关于如何使用 `find` 命令的帮助。 + +您还可以使用 `grep` 命令搜索文件的特定内容,比如: -您还可以使用 `grep` 命令搜索文件的特殊内容,比如: ``` grep "01/02/2018" todo.txt ``` + 这将为您展示 `todo` 文件中 `01/02/2018` 所在行。 ### 获取帮助 -Linux 有很多命令,这里,我们没有办法一一列举。授人以鱼不如授人以渔,所以下一步我们将向您介绍帮助命令。 +Linux 有很多命令,这里,我们没有办法一一列举。授人以鱼不如授人以渔,所以下一步我们将向您介绍帮助命令。 + +`apropos` 命令可以帮助您查找需要使用的命令。也许您想要查找能够操作目录或是获得文件列表的所有命令,但是您不知道该运行哪个命令。您可以这样尝试: -`apropos` 命令可以帮助您查找需要使用的命令。也许您想要查找能够操作目录或是获得文件列表的所有命令,但是您并不希望让这些命令执行。您可以这样尝试: ``` apropos directory ``` 要在帮助文档中,得到一个于 `directiory` 关键字的相关命令列表,您可以这样操作: + ``` apropos "list open files" ``` -这将提供一个 `lsof` 命令给您,帮助您打开文件列表。 +这将提供一个 `lsof` 命令给您,帮助您列出打开文件的列表。 + +当您明确知道您要使用的命令,但是不确定应该使用什么选项完成预期工作,您可以使用 `man` 命令,它是 manual 的缩写。您可以这样使用: -当您明确您要使用的命令,但是不确定应该使用什么选项完成预期工作,您可以使用 man 命令,它是 manual 的缩写。您可以这样使用: ``` man ls ``` 您可以在自己的设备上尝试这个命令。它会提供给您关于使用这个命令的完整信息。 -通常,很多命令都会有能够给 `help` 选项(比如说,`ls --help`),列出命令使用的提示。`man` 页面的内容通常太繁琐,`--help` 选项可能更适合快速浏览。 +通常,很多命令都能够接受 `help` 选项(比如说,`ls --help`),列出命令使用的提示。`man` 页面的内容通常太繁琐,`--help` 选项可能更适合快速浏览。 ### 脚本 -Linux 命令行中最贴心的功能是能够运行脚本文件,并且能重复运行。Linux 命令可以存储在文本文件中,您可以在文件的开头写入 `#!/bin/sh`,之后追加命令。之后,一旦文件被存储为可执行文件,您就可以像执行命令一样运行脚本文件,比如, +Linux 命令行中最贴心的功能之一是能够运行脚本文件,并且能重复运行。Linux 命令可以存储在文本文件中,您可以在文件的开头写入 `#!/bin/sh`,后面的行是命令。之后,一旦文件被存储为可执行文件,您就可以像执行命令一样运行脚本文件,比如, + ``` --- contents of get_todays_todos.sh --- #!/bin/sh @@ -127,44 +143,53 @@ todays_date=`date +"%m/%d/%y"` grep $todays_date $HOME/todos.txt ``` -在一个确定的工作中脚本可以帮助自动化重复执行命令。如果需要的话,脚本也可以很复杂,能够使用循环、判断语句等。限于篇幅,这里不细述,但是您可以在网上查询到相关信息。 +脚本可以以一套可重复的步骤自动化执行特定命令。如果需要的话,脚本也可以很复杂,能够使用循环、判断语句等。限于篇幅,这里不细述,但是您可以在网上查询到相关信息。 -您是否已经熟悉了 Windows 命令行? +### Windows 命令行用户 如果您对 Windows CMD 或者 PowerShell 程序很熟悉,在命令行输入命令应该是轻车熟路的。然而,它们之间有很多差异,如果您没有理解它们之间的差异可能会为之困扰。 -首先,在 Linux 下的 PATH 环境于 Windows 不同。在 Windows 中,当前目录被认为是路径中的第一个文件夹,尽管该目录没有在环境变量中列出。而在 Linux 下,当前目录不会在路径中显示表示。Linux 下设置环境变量会被认为是风险操作。在 Linux 的当前目录执行程序,您需要使用 ./(代表当前目录的相对目录表示方式) 前缀。这可能会干扰很多 CMD 用户。比如: +首先,在 Linux 下的 `PATH` 环境与 Windows 不同。在 Windows 中,当前目录被认为是该搜索路径(`PATH`)中的第一个文件夹,尽管该目录没有在环境变量中列出。而在 Linux 下,当前目录不会明确的放在搜索路径中。Linux 下设置环境变量会被认为是风险操作。在 Linux 的当前目录执行程序,您需要使用 `./`(代表当前目录的相对目录表示方式) 前缀。这可能会搞糊涂很多 CMD 用户。比如: + ``` ./my_program ``` 而不是 + ``` my_program ``` 另外,在 Windows 环境变量的路径中是以 `;`(分号) 分割的。在 Linux 中,由 `:` 分割环境变量。同样,在 Linux 中路径由 `/` 字符分隔,而在 Windows 目录中路径由 `\` 字符分割。因此 Windows 中典型的环境变量会像这样: + ``` PATH="C:\Program Files;C:\Program Files\Firefox;" -while on Linux it might look like: +``` +而在 Linux 中看起来像这样: + +``` PATH="/usr/bin:/opt/mozilla/firefox" ``` -还要注意,在 Linux 中环境变量由 `$` 拓展,而在 Windows 中您需要使用百分号(就是这样: %PATH%)。 +还要注意,在 Linux 中环境变量由 `$` 拓展,而在 Windows 中您需要使用百分号(就是这样: `%PATH%`)。 在 Linux 中,通过 `-` 使用命令选项,而在 Windows 中,使用选项要通过 `/` 字符。所以,在 Linux 中您应该: + ``` a_prog -h ``` 而不是 + ``` a_prog /h ``` -在 Linux 下,文件拓展名并没有意义。例如,将 `myscript` 重命名为 `myscript.bat` 并不会因此而可执行,需要设置文件的执行权限。文件执行权限会在下次的内容中覆盖到。 +在 Linux 下,文件拓展名并没有意义。例如,将 `myscript` 重命名为 `myscript.bat` 并不会因此而变得可执行,需要设置文件的执行权限。文件执行权限会在下次的内容中覆盖到。 + +在 Linux 中,如果文件或者目录名以 `.` 字符开头,意味着它们是隐藏文件。比如,如果您申请编辑 `.bashrc` 文件,您不能在家目录中找到它,但是它可能真的存在,只不过它是隐藏文件。在命令行中,您可以通过 `ls` 命令的 `-a` 选项查看隐藏文件,比如: -在 Linux 中,如果文件或者目录名以 `.` 字符开头,意味着它们是隐藏文件。比如,如果您申请编辑 `.bashrc` 文件,您不能在 `home` 目录中找到它,但是它可能真的存在,只不过它是隐藏文件。在命令行中,您可以通过 `ls` 命令的 `-a` 选项查看隐藏文件,比如: ``` ls -a ``` @@ -179,11 +204,11 @@ via: https://www.linux.com/blog/learn/2018/1/migrating-linux-command-line 作者:[John Bonesio][a] 译者:[CYLeft](https://github.com/CYLeft) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.linux.com/users/johnbonesio -[1]:https://www.linux.com/blog/learn/intro-to-linux/2017/10/migrating-linux-introduction -[2]:https://www.linux.com/blog/learn/intro-to-linux/2017/11/migrating-linux-disks-files-and-filesystems -[3]:https://www.linux.com/blog/learn/2017/12/migrating-linux-graphical-environments +[1]:https://linux.cn/article-9212-1.html +[2]:https://linux.cn/article-9213-1.html +[3]:https://linux.cn/article-9293-1.html diff --git a/translated/tech/20180125 BUILDING A FULL-TEXT SEARCH APP USING DOCKER AND ELASTICSEARCH.md b/published/201804/20180125 BUILDING A FULL-TEXT SEARCH APP USING DOCKER AND ELASTICSEARCH.md similarity index 82% rename from translated/tech/20180125 BUILDING A FULL-TEXT SEARCH APP USING DOCKER AND ELASTICSEARCH.md rename to published/201804/20180125 BUILDING A FULL-TEXT SEARCH APP USING DOCKER AND ELASTICSEARCH.md index 3210c7d284..053f70bff3 100644 --- a/translated/tech/20180125 BUILDING A FULL-TEXT SEARCH APP USING DOCKER AND ELASTICSEARCH.md +++ b/published/201804/20180125 BUILDING A FULL-TEXT SEARCH APP USING DOCKER AND ELASTICSEARCH.md @@ -1,59 +1,55 @@ -使用 DOCKER 和 ELASTICSEARCH 构建一个全文搜索应用程序 +使用 Docker 和 Elasticsearch 构建一个全文搜索应用程序 ============================================================ - _如何在超过 500 万篇文章的 Wikipedia 上找到与你研究相关的文章?_ +![](https://blog-images.patricktriest.com/uploads/library.jpg) - _如何在超过 20 亿用户的 Facebook 中找到你的朋友(并且还拼错了名字)?_ +_如何在超过 500 万篇文章的 Wikipedia 上找到与你研究相关的文章?_ - _谷歌如何在整个因特网上搜索你的模糊的、充满拼写错误的查询?_ +_如何在超过 20 亿用户的 Facebook 中找到你的朋友(并且还拼错了名字)?_ -在本教程中,我们将带你探索如何配置我们自己的全文探索应用程序(与上述问题中的系统相比,它的复杂度要小很多)。我们的示例应用程序将提供一个 UI 和 API 去从 100 部经典文学(比如,_Peter Pan_ ,  _Frankenstein_ , 和  _Treasure Island_ )中搜索完整的文本。 +_谷歌如何在整个因特网上搜索你的模糊的、充满拼写错误的查询?_ -你可以在这里([https://search.patricktriest.com][6])预览教程中应用程序的完整版本。 +在本教程中,我们将带你探索如何配置我们自己的全文搜索应用程序(与上述问题中的系统相比,它的复杂度要小很多)。我们的示例应用程序将提供一个 UI 和 API 去从 100 部经典文学(比如,《彼得·潘》 、  《弗兰肯斯坦》 和  《金银岛》)中搜索完整的文本。 + +你可以在这里([https://search.patricktriest.com][6])预览该教程应用的完整版本。 ![preview webapp](https://cdn.patricktriest.com/blog/images/posts/elastic-library/sample_4_0.png) -这个应用程序的源代码是 100% 公开的,可以在 GitHub 仓库上找到它们 —— [https://github.com/triestpa/guttenberg-search][7] +这个应用程序的源代码是 100% 开源的,可以在 GitHub 仓库上找到它们 —— [https://github.com/triestpa/guttenberg-search][7] 。 -在应用程序中添加一个快速灵活的全文搜索可能是个挑战。大多数的主流数据库,比如,[PostgreSQL][8] 和 [MongoDB][9],在它们的查询和索引结构中都提供一个有限的、基础的、文本搜索的功能。为实现高质量的全文搜索,通常的最佳选择是单独数据存储。[Elasticsearch][10] 是一个开源数据存储的领导者,它专门为执行灵活而快速的全文搜索进行了优化。 +在应用程序中添加一个快速灵活的全文搜索可能是个挑战。大多数的主流数据库,比如,[PostgreSQL][8] 和 [MongoDB][9],由于受其查询和索引结构的限制只能提供一个非常基础的文本搜索功能。为实现高质量的全文搜索,通常的最佳选择是单独的数据存储。[Elasticsearch][10] 是一个开源数据存储的领导者,它专门为执行灵活而快速的全文搜索进行了优化。 -我们将使用 [Docker][11] 去配置我们自己的项目环境和依赖。Docker 是一个容器化引擎,它被 [Uber][12]、[Spotify][13]、[ADP][14]、以及 [Paypal][15] 使用。构建容器化应用的一个主要优势是,项目的设置在 Windows、macOS、以及 Linux 上都是相同的 —— 这使我写这个教程快速又简单。如果你还没有使用过 Docker,不用担心,我们接下来将经历完整的项目配置。 +我们将使用 [Docker][11] 去配置我们自己的项目环境和依赖。Docker 是一个容器化引擎,它被 [Uber][12]、[Spotify][13]、[ADP][14] 以及 [Paypal][15] 使用。构建容器化应用的一个主要优势是,项目的设置在 Windows、macOS、以及 Linux 上都是相同的 —— 这使我写这个教程快速又简单。如果你还没有使用过 Docker,不用担心,我们接下来将经历完整的项目配置。 -我也会使用 [Node.js][16] (使用 [Koa][17] 框架)、和 [Vue.js][18],用它们分别去构建我们自己的搜索 API 和前端 Web 应用程序。 +我也会使用 [Node.js][16] (使用 [Koa][17] 框架)和 [Vue.js][18],用它们分别去构建我们自己的搜索 API 和前端 Web 应用程序。 -### 1 - ELASTICSEARCH 是什么? +### 1 - Elasticsearch 是什么? -全文搜索在现代应用程序中是一个有大量需求的特性。搜索也可能是最难的一项特性 —— 许多流行的网站的搜索功能都不合格,要么返回结果太慢,要么找不到精确的结果。通常,这种情况是被底层的数据库所局限:大多数标准的关系型数据库在基本的 `CONTAINS` 或 `LIKE` SQL 查询上有局限性,它仅提供大多数基本的字符串匹配功能。 +全文搜索在现代应用程序中是一个有大量需求的特性。搜索也可能是最难的一项特性 —— 许多流行的网站的搜索功能都不合格,要么返回结果太慢,要么找不到精确的结果。通常,这种情况是被底层的数据库所局限:大多数标准的关系型数据库局限于基本的 `CONTAINS` 或 `LIKE` SQL 查询上,它仅提供最基本的字符串匹配功能。 我们的搜索应用程序将具备: 1. **快速** - 搜索结果将快速返回,为用户提供一个良好的体验。 - -2. **灵活** - 我们希望能够去修改搜索如何执行,这是为了便于在不同的数据库和用户场景下进行优化。 - -3. **容错** - 如果搜索内容有拼写错误,我们将仍然会返回相关的结果,而这个结果可能正是用户希望去搜索的结果。 - -4. **全文** - 我们不想限制我们的搜索只能与指定的关键字或者标签相匹配 —— 我们希望它可以搜索在我们的数据存储中的任何东西(包括大的文本域)。 +2. **灵活** - 我们希望能够去修改搜索如何执行的方式,这是为了便于在不同的数据库和用户场景下进行优化。 +3. **容错** - 如果所搜索的内容有拼写错误,我们将仍然会返回相关的结果,而这个结果可能正是用户希望去搜索的结果。 +4. **全文** - 我们不想限制我们的搜索只能与指定的关键字或者标签相匹配 —— 我们希望它可以搜索在我们的数据存储中的任何东西(包括大的文本字段)。 ![Elastic Search Logo](https://storage.googleapis.com/cdn.patricktriest.com/blog/images/posts/elastic-library/Elasticsearch-Logo.png) -为了构建一个功能强大的搜索功能,通常最理想的方法是使用一个为全文搜索任务优化过的用户数据存储。在这里我们使用 [Elasticsearch][19],Elasticsearch 是一个开源的内存中的数据存储,它是用 Java 写的,最初是在 [Apache Lucene][20] 库上构建的。 +为了构建一个功能强大的搜索功能,通常最理想的方法是使用一个为全文搜索任务优化过的数据存储。在这里我们使用 [Elasticsearch][19],Elasticsearch 是一个开源的内存中的数据存储,它是用 Java 写的,最初是在 [Apache Lucene][20] 库上构建的。 这里有一些来自 [Elastic 官方网站][21] 上的 Elasticsearch 真实使用案例。 * Wikipedia 使用 Elasticsearch 去提供带高亮搜索片断的全文搜索功能,并且提供按类型搜索和 “did-you-mean” 建议。 - -* Guardian 使用 Elasticsearch 把社交网络数据和访客日志相结合,为编辑去提供大家对新文章的实时的反馈。 - +* Guardian 使用 Elasticsearch 把社交网络数据和访客日志相结合,为编辑去提供新文章的公众意见的实时反馈。 * Stack Overflow 将全文搜索和地理查询相结合,并使用 “类似” 的方法去找到相关的查询和回答。 - * GitHub 使用 Elasticsearch 对 1300 亿行代码进行查询。 ### 与 “普通的” 数据库相比,Elasticsearch 有什么不一样的地方? -Elasticsearch 之所以能够提供快速灵活的全文搜索,秘密在于它使用 _反转索引_ 。 +Elasticsearch 之所以能够提供快速灵活的全文搜索,秘密在于它使用反转索引inverted index 。 -“索引” 是数据库中的一种数据结构,它能够以超快的速度进行数据查询和检索操作。数据库通过存储与表中行相关联的字段来生成索引。在一种可搜索的数据结构(一般是 [B树][22])中排序索引,在优化过的查询中,数据库能够达到接近线速的时间(比如,“使用 ID=5 查找行)。 +“索引” 是数据库中的一种数据结构,它能够以超快的速度进行数据查询和检索操作。数据库通过存储与表中行相关联的字段来生成索引。在一种可搜索的数据结构(一般是 [B 树][22])中排序索引,在优化过的查询中,数据库能够达到接近线性的时间(比如,“使用 ID=5 查找行”)。 ![Relational Index](https://cdn.patricktriest.com/blog/images/posts/elastic-library/db_index.png) @@ -63,41 +59,38 @@ Elasticsearch 之所以能够提供快速灵活的全文搜索,秘密在于它 ![Inverted Index](https://cdn.patricktriest.com/blog/images/posts/elastic-library/invertedIndex.jpg) -这种反转索引数据结构可以使我们非常快地查询到,所有出现 ”football" 的文档。通过使用大量优化过的内存中的反转索引,Elasticsearch 可以让我们在存储的数据上,执行一些非常强大的和自定义的全文搜索。 +这种反转索引数据结构可以使我们非常快地查询到,所有出现 “football” 的文档。通过使用大量优化过的内存中的反转索引,Elasticsearch 可以让我们在存储的数据上,执行一些非常强大的和自定义的全文搜索。 ### 2 - 项目设置 -### 2.0 - Docker +#### 2.0 - Docker 我们在这个项目上使用 [Docker][23] 管理环境和依赖。Docker 是个容器引擎,它允许应用程序运行在一个独立的环境中,不会受到来自主机操作系统和本地开发环境的影响。现在,许多公司将它们的大规模 Web 应用程序主要运行在容器架构上。这样将提升灵活性和容器化应用程序组件的可组构性。 ![Docker Logo](https://storage.googleapis.com/cdn.patricktriest.com/blog/images/posts/elastic-library/docker.png) -对我们来说,使用 Docker 的优势是,它对本教程非常友好,它的本地环境设置量最小,并且跨 Windows、macOS、和 Linux 系统的一致性很好。我们只需要在 Docker 配置文件中定义这些依赖关系,而不是按安装说明分别去安装 Node.js、Elasticsearch、和 Nginx,然后,就可以使用这个配置文件在任何其它地方运行我们的应用程序。而且,因为每个应用程序组件都运行在它自己的独立容器中,它们受本地机器上的其它 “垃圾” 干扰的可能性非常小,因此,在调试问题时,像 "But it works on my machine!" 这类的问题将非常少。 +对我来说,使用 Docker 的优势是,它对本教程的作者非常方便,它的本地环境设置量最小,并且跨 Windows、macOS 和 Linux 系统的一致性很好。我们只需要在 Docker 配置文件中定义这些依赖关系,而不是按安装说明分别去安装 Node.js、Elasticsearch 和 Nginx,然后,就可以使用这个配置文件在任何其它地方运行我们的应用程序。而且,因为每个应用程序组件都运行在它自己的独立容器中,它们受本地机器上的其它 “垃圾” 干扰的可能性非常小,因此,在调试问题时,像“它在我这里可以工作!”这类的问题将非常少。 -### 2.1 - 安装 Docker & Docker-Compose +#### 2.1 - 安装 Docker & Docker-Compose 这个项目只依赖 [Docker][24] 和 [docker-compose][25],docker-compose 是 Docker 官方支持的一个工具,它用来将定义的多个容器配置 _组装_  成单一的应用程序栈。 -安装 Docker - [https://docs.docker.com/engine/installation/][26] -安装 Docker Compose - [https://docs.docker.com/compose/install/][27] +- 安装 Docker - [https://docs.docker.com/engine/installation/][26] +- 安装 Docker Compose - [https://docs.docker.com/compose/install/][27] -### 2.2 - 设置项目主目录 +#### 2.2 - 设置项目主目录 为项目创建一个主目录(名为 `guttenberg_search`)。我们的项目将工作在主目录的以下两个子目录中。 * `/public` - 保存前端 Vue.js Web 应用程序。 - * `/server` - 服务器端 Node.js 源代码。 -### 2.3 - 添加 Docker-Compose 配置 +#### 2.3 - 添加 Docker-Compose 配置 接下来,我们将创建一个 `docker-compose.yml` 文件来定义我们的应用程序栈中的每个容器。 1. `gs-api` - 后端应用程序逻辑使用的 Node.js 容器 - 2. `gs-frontend` - 前端 Web 应用程序使用的 Ngnix 容器。 - 3. `gs-search` - 保存和搜索数据的 Elasticsearch 容器。 ``` @@ -140,12 +133,11 @@ services: volumes: # Define seperate volume for Elasticsearch data esdata: - ``` -这个文件定义了我们全部的应用程序栈 —— 不需要在你的本地系统上安装 Elasticsearch、Node、和 Nginx。每个容器都将端口转发到宿主机系统(`localhost`)上,以便于我们在宿主机上去访问和调试 Node API、Elasticsearch instance、和前端 Web 应用程序。 +这个文件定义了我们全部的应用程序栈 —— 不需要在你的本地系统上安装 Elasticsearch、Node 和 Nginx。每个容器都将端口转发到宿主机系统(`localhost`)上,以便于我们在宿主机上去访问和调试 Node API、Elasticsearch 实例和前端 Web 应用程序。 -### 2.4 - 添加 Dockerfile +#### 2.4 - 添加 Dockerfile 对于 Nginx 和 Elasticsearch,我们使用了官方预构建的镜像,而 Node.js 应用程序需要我们自己去构建。 @@ -169,7 +161,6 @@ COPY . . # Start app CMD [ "npm", "start" ] - ``` 这个 Docker 配置扩展了官方的 Node.js 镜像、拷贝我们的应用程序源代码、以及在容器内安装 NPM 依赖。 @@ -181,12 +172,11 @@ node_modules/ npm-debug.log books/ public/ - ``` -> 请注意:我们之所以不拷贝 `node_modules` 目录到我们的容器中 —— 是因为我们要在容器中运行 `npm install` 来构建这个进程。从宿主机系统拷贝 `node_modules` 可能会引起错误,因为一些包需要在某些操作系统上专门构建。比如说,在 macOS 上安装 `bcrypt` 包,然后尝试将这个模块直接拷贝到一个 Ubuntu 容器上将不能工作,因为 `bcyrpt` 需要为每个操作系统构建一个特定的二进制文件。 +> 请注意:我们之所以不拷贝 `node_modules` 目录到我们的容器中 —— 是因为我们要在容器构建过程里面运行 `npm install`。从宿主机系统拷贝 `node_modules` 到容器里面可能会引起错误,因为一些包需要为某些操作系统专门构建。比如说,在 macOS 上安装 `bcrypt` 包,然后尝试将这个模块直接拷贝到一个 Ubuntu 容器上将不能工作,因为 `bcyrpt` 需要为每个操作系统构建一个特定的二进制文件。 -### 2.5 - 添加基本文件 +#### 2.5 - 添加基本文件 为了测试我们的配置,我们需要添加一些占位符文件到应用程序目录中。 @@ -194,7 +184,6 @@ public/ ``` Hello World From The Frontend Container - ``` 接下来,在 `server/app.js` 中添加 Node.js 占位符文件。 @@ -213,10 +202,9 @@ app.listen(port, err => { if (err) console.error(err) console.log(`App Listening on Port ${port}`) }) - ``` -最后,添加我们的 `package.json` 节点应用配置。 +最后,添加我们的 `package.json`  Node 应用配置。 ``` { @@ -244,14 +232,13 @@ app.listen(port, err => { "koa-router": "7.2.1" } } - ``` 这个文件定义了应用程序启动命令和 Node.js 包依赖。 -> 注意:不要运行 `npm install` —— 当它构建时,这个依赖将在容器内安装。 +> 注意:不要运行 `npm install` —— 当它构建时,依赖会在容器内安装。 -### 2.6 - 测试它的输出 +#### 2.6 - 测试它的输出 现在一切新绪,我们来测试应用程序的每个组件的输出。从应用程序的主目录运行 `docker-compose build`,它将构建我们的 Node.js 应用程序容器。 @@ -261,13 +248,13 @@ app.listen(port, err => { ![docker compose output](https://cdn.patricktriest.com/blog/images/posts/elastic-library/sample_0_2.png) -> 这一步可能需要几分钟时间,因为 Docker 要为每个容器去下载基础镜像,接着再去运行,启动应用程序非常快,因为所需要的镜像已经下载完成了。 +> 这一步可能需要几分钟时间,因为 Docker 要为每个容器去下载基础镜像。以后再次运行,启动应用程序会非常快,因为所需要的镜像已经下载完成了。 -在你的浏览器中尝试访问 `localhost:8080` —— 你将看到简单的 “Hello World" Web 页面。 +在你的浏览器中尝试访问 `localhost:8080` —— 你将看到简单的 “Hello World” Web 页面。 ![frontend sample output](https://cdn.patricktriest.com/blog/images/posts/elastic-library/sample_0_0.png) -访问 `localhost:3000` 去验证我们的 Node 服务器,它将返回 "Hello World" 信息。 +访问 `localhost:3000` 去验证我们的 Node 服务器,它将返回 “Hello World” 信息。 ![backend sample output](https://cdn.patricktriest.com/blog/images/posts/elastic-library/sample_0_1.png) @@ -289,16 +276,15 @@ app.listen(port, err => { }, "tagline" : "You Know, for Search" } - ``` -如果三个 URLs 都显示成功,祝贺你!整个容器栈已经正常运行了,接下来我们进入最有趣的部分。 +如果三个 URL 都显示成功,祝贺你!整个容器栈已经正常运行了,接下来我们进入最有趣的部分。 -### 3 - 连接到 ELASTICSEARCH +### 3 - 连接到 Elasticsearch 我们要做的第一件事情是,让我们的应用程序连接到我们本地的 Elasticsearch 实例上。 -### 3.0 - 添加 ES 连接模块 +#### 3.0 - 添加 ES 连接模块 在新文件 `server/connection.js` 中添加如下的 Elasticsearch 初始化代码。 @@ -328,7 +314,6 @@ async function checkConnection () { } checkConnection() - ``` 现在,我们重新构建我们的 Node 应用程序,我们将使用 `docker-compose build` 来做一些改变。接下来,运行 `docker-compose up -d` 去启动应用程序栈,它将以守护进程的方式在后台运行。 @@ -351,12 +336,11 @@ checkConnection() number_of_in_flight_fetch: 0, task_max_waiting_in_queue_millis: 0, active_shards_percent_as_number: 50 } - ``` 继续之前,我们先删除最下面的 `checkConnection()` 调用,因为,我们最终的应用程序将调用外部的连接模块。 -### 3.1 - 添加函数去重置索引 +#### 3.1 - 添加函数去重置索引 在 `server/connection.js` 中的 `checkConnection` 下面添加如下的函数,以便于重置 Elasticsearch 索引。 @@ -370,12 +354,11 @@ async function resetIndex (index) { await client.indices.create({ index }) await putBookMapping() } - ``` -### 3.2 - 添加图书模式 +#### 3.2 - 添加图书模式 -接下来,我们将为图书的数据模式添加一个 "mapping"。在 `server/connection.js` 中的 `resetIndex` 函数下面添加如下的函数。 +接下来,我们将为图书的数据模式添加一个 “映射”。在 `server/connection.js` 中的 `resetIndex` 函数下面添加如下的函数。 ``` /** Add book section schema mapping to ES */ @@ -389,12 +372,11 @@ async function putBookMapping () { return client.indices.putMapping({ index, type, body: { properties: schema } }) } - ``` -这是为 `book` 索引定义了一个 mapping。一个 Elasticsearch 的 `index` 大概类似于 SQL 的 `table` 或者 MongoDB 的  `collection`。我们通过添加 mapping 来为存储的文档指定每个字段和它的数据类型。Elasticsearch 是无模式的,因此,从技术角度来看,我们是不需要添加 mapping 的,但是,这样做,我们可以更好地控制如何处理数据。 +这是为 `book` 索引定义了一个映射。Elasticsearch 中的 `index` 大概类似于 SQL 的 `table` 或者 MongoDB 的  `collection`。我们通过添加映射来为存储的文档指定每个字段和它的数据类型。Elasticsearch 是无模式的,因此,从技术角度来看,我们是不需要添加映射的,但是,这样做,我们可以更好地控制如何处理数据。 -比如,我们给 "title" 和 ”author" 字段分配 `keyword` 类型,给 “text" 字段分配 `text` 类型。之所以这样做的原因是,搜索引擎可以区别处理这些字符串字段 —— 在搜索的时候,搜索引擎将在 `text` 字段中搜索可能的匹配项,而对于 `keyword` 类型字段,将对它们进行全文匹配。这看上去差别很小,但是它们对在不同的搜索上的速度和行为的影响非常大。 +比如,我们给 `title` 和 `author` 字段分配 `keyword` 类型,给 `text` 字段分配 `text` 类型。之所以这样做的原因是,搜索引擎可以区别处理这些字符串字段 —— 在搜索的时候,搜索引擎将在 `text` 字段中搜索可能的匹配项,而对于 `keyword` 类型字段,将对它们进行全文匹配。这看上去差别很小,但是它们对在不同的搜索上的速度和行为的影响非常大。 在文件的底部,导出对外发布的属性和函数,这样我们的应用程序中的其它模块就可以访问它们了。 @@ -402,31 +384,29 @@ async function putBookMapping () { module.exports = { client, index, type, checkConnection, resetIndex } - ``` ### 4 - 加载原始数据 -我们将使用来自 [Gutenberg 项目][28] 的数据 ——  它致力于为公共提供免费的线上电子书。在这个项目中,我们将使用 100 本经典图书来充实我们的图书馆,包括_《The Adventures of Sherlock Holmes》_、_《Treasure Island》_、_《The Count of Monte Cristo》_、_《Around the World in 80 Days》_、_《Romeo and Juliet》_ 、和_《The Odyssey》_。 +我们将使用来自 [古登堡项目][28] 的数据 ——  它致力于为公共提供免费的线上电子书。在这个项目中,我们将使用 100 本经典图书来充实我们的图书馆,包括《福尔摩斯探案集》、《金银岛》、《基督山复仇记》、《环游世界八十天》、《罗密欧与朱丽叶》 和《奥德赛》。 ![Book Covers](https://storage.googleapis.com/cdn.patricktriest.com/blog/images/posts/elastic-library/books.jpg) -### 4.1 - 下载图书文件 +#### 4.1 - 下载图书文件 我将这 100 本书打包成一个文件,你可以从这里下载它 —— [https://cdn.patricktriest.com/data/books.zip][29] 将这个文件解压到你的项目的 `books/` 目录中。 -你可以使用以下的命令来完成(需要在命令行下使用 [wget][30] 和 ["The Unarchiver"][31])。 +你可以使用以下的命令来完成(需要在命令行下使用 [wget][30] 和 [The Unarchiver][31])。 ``` wget https://cdn.patricktriest.com/data/books.zip unar books.zip - ``` -### 4.2 - 预览一本书 +#### 4.2 - 预览一本书 尝试打开其中的一本书的文件,假设打开的是 `219-0.txt`。你将注意到它开头是一个公开访问的协议,接下来是一些标识这本书的书名、作者、发行日期、语言和字符编码的行。 @@ -441,7 +421,6 @@ Last Updated: September 7, 2016 Language: English Character set encoding: UTF-8 - ``` 在 `*** START OF THIS PROJECT GUTENBERG EBOOK HEART OF DARKNESS ***` 这些行后面,是这本书的正式内容。 @@ -450,7 +429,7 @@ Character set encoding: UTF-8 下一步,我们将使用程序从文件头部来解析书的元数据,提取 `*** START OF` 和 `***END OF` 之间的内容。 -### 4.3 - 读取数据目录 +#### 4.3 - 读取数据目录 我们将写一个脚本来读取每本书的内容,并将这些数据添加到 Elasticsearch。我们将定义一个新的 Javascript 文件 `server/load_data.js` 来执行这些操作。 @@ -486,7 +465,6 @@ async function readAndInsertBooks () { } readAndInsertBooks() - ``` 我们将使用一个快捷命令来重构我们的 Node.js 应用程序,并更新运行的容器。 @@ -501,7 +479,7 @@ readAndInsertBooks() ![docker exec output](https://cdn.patricktriest.com/blog/images/posts/elastic-library/sample_1_1.png) -### 4.4 - 读取数据文件 +#### 4.4 - 读取数据文件 接下来,我们读取元数据和每本书的内容。 @@ -536,32 +514,26 @@ function parseBookFile (filePath) { console.log(`Parsed ${paragraphs.length} Paragraphs\n`) return { title, author, paragraphs } } - ``` 这个函数执行几个重要的任务。 1. 从文件系统中读取书的文本。 - 2. 使用正则表达式(关于正则表达式,请参阅 [这篇文章][1] )解析书名和作者。 - -3. 通过匹配 ”Guttenberg 项目“ 头部和尾部,识别书的正文内容。 - +3. 通过匹配 “古登堡项目” 的头部和尾部,识别书的正文内容。 4. 提取书的内容文本。 - 5. 分割每个段落到它的数组中。 - 6. 清理文本并删除空白行。 -它的返回值,我们将构建一个对象,这个对象包含书名、作者、以及书中各段落的数据。 +它的返回值,我们将构建一个对象,这个对象包含书名、作者、以及书中各段落的数组。 -再次运行 `docker-compose up -d --build` 和 `docker exec gs-api "node" "server/load_data.js"`,你将看到如下的输出,在输出的末尾有三个额外的行。 +再次运行 `docker-compose up -d --build` 和 `docker exec gs-api "node" "server/load_data.js"`,你将看到输出同之前一样,在输出的末尾有三个额外的行。 ![docker exec output](https://cdn.patricktriest.com/blog/images/posts/elastic-library/sample_2_0.png) 成功!我们的脚本从文本文件中成功解析出了书名和作者。脚本再次以错误结束,因为到现在为止,我们还没有定义辅助函数。 -### 4.5 - 在 ES 中索引数据文件 +#### 4.5 - 在 ES 中索引数据文件 最后一步,我们将批量上传每个段落的数组到 Elasticsearch 索引中。 @@ -596,12 +568,11 @@ async function insertBookData (title, author, paragraphs) { await esConnection.client.bulk({ body: bulkOps }) console.log(`Indexed Paragraphs ${paragraphs.length - (bulkOps.length / 2)} - ${paragraphs.length}\n\n\n`) } - ``` -这个函数将使用书名、作者、和附加元数据的段落位置来索引书中的每个段落。我们通过批量操作来插入段落,它比逐个段落插入要快的多。 +这个函数将使用书名、作者和附加元数据的段落位置来索引书中的每个段落。我们通过批量操作来插入段落,它比逐个段落插入要快的多。 -> 我们分批索引段落,而不是一次性插入全部,是为运行这个应用程序的、内存稍有点小(1.7 GB)的服务器  `search.patricktriest.com` 上做的一个重要优化。如果你的机器内存还行(4 GB 以上),你或许不用分批上传。 +> 我们分批索引段落,而不是一次性插入全部,是为运行这个应用程序的内存稍有点小(1.7 GB)的服务器  `search.patricktriest.com` 上做的一个重要优化。如果你的机器内存还行(4 GB 以上),你或许不用分批上传。 运行 `docker-compose up -d --build` 和 `docker exec gs-api "node" "server/load_data.js"` 一次或多次 —— 现在你将看到前面解析的 100 本书的完整输出,并插入到了 Elasticsearch。这可能需要几分钟时间,甚至更长。 @@ -611,13 +582,13 @@ async function insertBookData (title, author, paragraphs) { 现在,Elasticsearch 中已经有了 100 本书了(大约有 230000 个段落),现在我们尝试搜索查询。 -### 5.0 - 简单的 HTTP 查询 +#### 5.0 - 简单的 HTTP 查询 首先,我们使用 Elasticsearch 的 HTTP API 对它进行直接查询。 在你的浏览器上访问这个 URL - `http://localhost:9200/library/_search?q=text:Java&pretty` -在这里,我们将执行一个极简的全文搜索,在我们的图书馆的书中查找 ”Java" 这个词。 +在这里,我们将执行一个极简的全文搜索,在我们的图书馆的书中查找 “Java” 这个词。 你将看到类似于下面的一个 JSON 格式的响应。 @@ -663,12 +634,11 @@ async function insertBookData (title, author, paragraphs) { ] } } - ``` 用 Elasticseach 的 HTTP 接口可以测试我们插入的数据是否成功,但是如果直接将这个 API 暴露给 Web 应用程序将有极大的风险。这个 API 将会暴露管理功能(比如直接添加和删除文档),最理想的情况是完全不要对外暴露它。而是写一个简单的 Node.js API 去接收来自客户端的请求,然后(在我们的本地网络中)生成一个正确的查询发送给 Elasticsearch。 -### 5.1 - 查询脚本 +#### 5.1 - 查询脚本 我们现在尝试从我们写的 Node.js 脚本中查询 Elasticsearch。 @@ -694,7 +664,6 @@ module.exports = { return client.search({ index, type, body }) } } - ``` 我们的搜索模块定义一个简单的 `search` 函数,它将使用输入的词 `match` 查询。 @@ -702,13 +671,9 @@ module.exports = { 这是查询的字段分解 - * `from` - 允许我们分页查询结果。默认每个查询返回 10 个结果,因此,指定 `from: 10` 将允许我们取回 10-20 的结果。 - * `query` - 这里我们指定要查询的词。 - -* `operator` - 我们可以修改搜索行为;在本案例中,我们使用 "and" 操作去对查询中包含所有 tokens(要查询的词)的结果来确定优先顺序。 - +* `operator` - 我们可以修改搜索行为;在本案例中,我们使用 `and` 操作去对查询中包含所有字元(要查询的词)的结果来确定优先顺序。 * `fuzziness` - 对拼写错误的容错调整,`auto` 的默认为 `fuzziness: 2`。模糊值越高,结果越需要更多校正。比如,`fuzziness: 1` 将允许以 `Patricc` 为关键字的查询中返回与 `Patrick` 匹配的结果。 - * `highlights` - 为结果返回一个额外的字段,这个字段包含 HTML,以显示精确的文本字集和查询中匹配的关键词。 你可以去浏览 [Elastic Full-Text Query DSL][32],学习如何随意调整这些参数,以进一步自定义搜索查询。 @@ -717,7 +682,7 @@ module.exports = { 为了能够从前端应用程序中访问我们的搜索功能,我们来写一个快速的 HTTP API。 -### 6.0 - API 服务器 +#### 6.0 - API 服务器 用以下的内容替换现有的 `server/app.js` 文件。 @@ -761,7 +726,6 @@ app if (err) throw err console.log(`App Listening on Port ${port}`) }) - ``` 这些代码将为 [Koa.js][33] Node API 服务器导入服务器依赖,设置简单的日志,以及错误处理。 @@ -782,10 +746,9 @@ router.get('/search', async (ctx, next) => { ctx.body = await search.queryTerm(term, offset) } ) - ``` -使用 `docker-compose up -d --build` 重启动应用程序。之后在你的浏览器中尝试调用这个搜索端点。比如,`http://localhost:3000/search?term=java` 这个请求将搜索整个图书馆中提到 “Jave" 的内容。 +使用 `docker-compose up -d --build` 重启动应用程序。之后在你的浏览器中尝试调用这个搜索端点。比如,`http://localhost:3000/search?term=java` 这个请求将搜索整个图书馆中提到 “Java” 的内容。 结果与前面直接调用 Elasticsearch HTTP 界面的结果非常类似。 @@ -835,7 +798,6 @@ router.get('/search', async (ctx, next) => { ] } } - ``` ### 6.2 - 输入校验 @@ -864,7 +826,6 @@ router.get('/search', ctx.body = await search.queryTerm(term, offset) } ) - ``` 现在,重启服务器,如果你使用一个没有搜索关键字的请求(`http://localhost:3000/search`),你将返回一个带相关消息的 HTTP 400 错误,比如像 `Invalid URL Query - child "term" fails because ["term" is required]`。 @@ -875,7 +836,7 @@ router.get('/search', 现在我们的 `/search` 端点已经就绪,我们来连接到一个简单的 Web 应用程序来测试这个 API。 -### 7.0 - Vue.js 应用程序 +#### 7.0 - Vue.js 应用程序 我们将使用 Vue.js 去协调我们的前端。 @@ -934,14 +895,13 @@ const vm = new Vue ({ } } }) - ``` -这个应用程序非常简单 —— 我们只定义了一些共享的数据属性,以及添加了检索和分页搜索结果的方法。为防止每按键一次都调用 API,搜索输入有一个 100 毫秒的除颤功能。 +这个应用程序非常简单 —— 我们只定义了一些共享的数据属性,以及添加了检索和分页搜索结果的方法。为防止每次按键一次都调用 API,搜索输入有一个 100 毫秒的除颤功能。 解释 Vue.js 是如何工作的已经超出了本教程的范围,如果你使用过 Angular 或者 React,其实一些也不可怕。如果你完全不熟悉 Vue,想快速了解它的功能,我建议你从官方的快速指南入手 —— [https://vuejs.org/v2/guide/][36] -### 7.1 - HTML +#### 7.1 - HTML 使用以下的内容替换 `/public/index.html` 文件中的占位符,以便于加载我们的 Vue.js 应用程序和设计一个基本的搜索界面。 @@ -1004,10 +964,9 @@ const vm = new Vue ({ - ``` -### 7.2 - CSS +#### 7.2 - CSS 添加一个新文件 `/public/styles.css`,使用一些自定义的 UI 样式。 @@ -1098,10 +1057,9 @@ body { font-family: 'EB Garamond', serif; } justify-content: space-around; background: white; } - ``` -### 7.3 - 尝试输出 +#### 7.3 - 尝试输出 在你的浏览器中打开 `localhost:8080`,你将看到一个简单的带结果分页功能的搜索界面。在顶部的搜索框中尝试输入不同的关键字来查看它们的搜索情况。 @@ -1113,7 +1071,7 @@ body { font-family: 'EB Garamond', serif; } ### 8 - 分页预览 -如果点击每个搜索结果,然后查看到来自书中的内容,那将是非常棒的体验。 +如果能点击每个搜索结果,然后查看到来自书中的内容,那将是非常棒的体验。 ### 8.0 - 添加 Elasticsearch 查询 @@ -1137,12 +1095,11 @@ getParagraphs (bookTitle, startLocation, endLocation) { return client.search({ index, type, body }) } - ``` 这个新函数将返回给定的书的开始位置和结束位置之间的一个排序后的段落数组。 -### 8.1 - 添加 API 端点 +#### 8.1 - 添加 API 端点 现在,我们将这个函数链接到 API 端点。 @@ -1170,10 +1127,9 @@ router.get('/paragraphs', ctx.body = await search.getParagraphs(bookTitle, start, end) } ) - ``` -### 8.2 - 添加 UI 功能 +#### 8.2 - 添加 UI 功能 现在,我们的新端点已经就绪,我们为应用程序添加一些从书中查询和显示全部页面的前端功能。 @@ -1217,10 +1173,9 @@ router.get('/paragraphs', document.body.style.overflow = 'auto' this.selectedParagraph = null } - ``` -这五个函数了提供了通过页码从书中下载和分页(每次十个段落)的逻辑。 +这五个函数提供了通过页码从书中下载和分页(每次十个段落)的逻辑。 现在,我们需要添加一个 UI 去显示书的页面。在 `/public/index.html` 的 `` 注释下面添加如下的内容。 @@ -1258,7 +1213,6 @@ router.get('/paragraphs', - ``` 再次重启应用程序服务器(`docker-compose up -d --build`),然后打开 `localhost:8080`。当你再次点击搜索结果时,你将能看到关键字附近的段落。如果你感兴趣,你现在甚至可以看这本书的剩余部分。 @@ -1269,42 +1223,38 @@ router.get('/paragraphs', 你可以去比较你的本地结果与托管在这里的完整示例 —— [https://search.patricktriest.com/][37] -### 9 - ELASTICSEARCH 的缺点 +### 9 - Elasticsearch 的缺点 -### 9.0 - 耗费资源 +#### 9.0 - 耗费资源 -Elasticsearch 是计算密集型的。[官方建议][38] 运行 ES 的机器最好有 64 GB 的内存,强烈反对在低于 8 GB 内存的机器上运行它。Elasticsearch 是一个 _内存中_ 数据库,这样使它的查询速度非常快,但这也非常占用系统内存。在生产系统中使用时,[他们强烈建议在一个集群中运行多个 Elasticsearch 节点][39],以实现高可用、自动分区、和一个节点失败时的数据冗余。 +Elasticsearch 是计算密集型的。[官方建议][38] 运行 ES 的机器最好有 64 GB 的内存,强烈反对在低于 8 GB 内存的机器上运行它。Elasticsearch 是一个 _内存中_ 数据库,这样使它的查询速度非常快,但这也非常占用系统内存。在生产系统中使用时,[他们强烈建议在一个集群中运行多个 Elasticsearch 节点][39],以实现高可用、自动分区和一个节点失败时的数据冗余。 我们的这个教程中的应用程序运行在一个 $15/月 的 GCP 计算实例中( [search.patricktriest.com][40]),它只有 1.7 GB 的内存,它勉强能运行这个 Elasticsearch 节点;有时候在进行初始的数据加载过程中,整个机器就 ”假死机“ 了。在我的经验中,Elasticsearch 比传统的那些数据库,比如,PostgreSQL 和 MongoDB 耗费的资源要多很多,这样会使托管主机的成本增加很多。 ### 9.1 - 与数据库的同步 -在大多数应用程序,将数据全部保存在 Elasticsearch 并不是个好的选择。最好是使用 ES 作为应用程序的主要事务数据库,但是一般不推荐这样做,因为在 Elasticsearch 中缺少 ACID,如果在处理数据的时候发生伸缩行为,它将丢失写操作。在许多案例中,ES 服务器更多是一个特定的角色,比如做应用程序中的一个文本搜索功能。这种特定的用途,要求它从主数据库中复制数据到 Elasticsearch 实例中。 +对于大多数应用程序,将数据全部保存在 Elasticsearch 并不是个好的选择。可以使用 ES 作为应用程序的主要事务数据库,但是一般不推荐这样做,因为在 Elasticsearch 中缺少 ACID,如果大量读取数据的时候,它能导致写操作丢失。在许多案例中,ES 服务器更多是一个特定的角色,比如做应用程序中的一个文本搜索功能。这种特定的用途,要求它从主数据库中复制数据到 Elasticsearch 实例中。 -比如,假设我们将用户信息保存在一个 PostgreSQL 表中,但是用 Elasticsearch 去驱动我们的用户搜索功能。如果一个用户,比如,"Albert",决定将他的名字改成 "Al",我们将需要把这个变化同时反映到我们主要的 PostgreSQL 数据库和辅助的 Elasticsearch 集群中。 +比如,假设我们将用户信息保存在一个 PostgreSQL 表中,但是用 Elasticsearch 去提供我们的用户搜索功能。如果一个用户,比如,“Albert”,决定将他的名字改成 “Al”,我们将需要把这个变化同时反映到我们主要的 PostgreSQL 数据库和辅助的 Elasticsearch 集群中。 正确地集成它们可能比较棘手,最好的答案将取决于你现有的应用程序栈。这有多种开源方案可选,从 [用一个进程去关注 MongoDB 操作日志][41] 并自动同步检测到的变化到 ES,到使用一个 [PostgresSQL 插件][42] 去创建一个定制的、基于 PSQL 的索引来与 Elasticsearch 进行自动沟通。 -如果没有有效的预构建选项可用,你可能需要在你的服务器代码中增加一些钩子,这样可以基于数据库的变化来手动更新 Elasticsearch 索引。最后一招,我认为是一个最后的选择,因为,使用定制的业务逻辑去保持 ES 的同步可能很复杂,这将会给应用程序引入很多的 bugs。 +如果没有有效的预构建选项可用,你可能需要在你的服务器代码中增加一些钩子,这样可以基于数据库的变化来手动更新 Elasticsearch 索引。最后一招,我认为是一个最后的选择,因为,使用定制的业务逻辑去保持 ES 的同步可能很复杂,这将会给应用程序引入很多的 bug。 让 Elasticsearch 与一个主数据库同步,将使它的架构更加复杂,其复杂性已经超越了 ES 的相关缺点,但是当在你的应用程序中考虑添加一个专用的搜索引擎的利弊得失时,这个问题是值的好好考虑的。 ### 总结 -在很多现在流行的应用程序中,全文搜索是一个非常重要的功能 —— 而且是很难实现的一个功能。对于在你的应用程序中添加一个快速而又可定制的文本搜索,Elasticsearch 是一个非常好的选择,但是,在这里也有一个替代者。[Apache Solr][43] 是一个类似的开源搜索平台,它是基于 Apache Lucene 构建的,它与 Elasticsearch 的核心库是相同的。[Algolia][44] 是一个搜索即服务的 Web 平台,它已经很快流行了起来,并且它对新手非常友好,很易于上手(但是作为折衷,它的可定制性较小,并且使用成本较高)。 +在很多现在流行的应用程序中,全文搜索是一个非常重要的功能 —— 而且是很难实现的一个功能。对于在你的应用程序中添加一个快速而又可定制的文本搜索,Elasticsearch 是一个非常好的选择,但是,在这里也有一个替代者。[Apache Solr][43] 是一个类似的开源搜索平台,它是基于 Apache Lucene 构建的,与 Elasticsearch 的核心库是相同的。[Algolia][44] 是一个搜索即服务的 Web 平台,它已经很快流行了起来,并且它对新手非常友好,很易于上手(但是作为折衷,它的可定制性较小,并且使用成本较高)。 -“搜索” 特性并不是 Elasticsearch 唯一功能。ES 也是日志存储和分析的常用工具,在一个 ELK(Elasticsearch、Logstash、Kibana)栈配置中通常会使用它。灵活的全文搜索功能使得 Elasticsearch 在数据量非常大的科学任务中用处很大 —— 比如,在一个数据集中正确的/标准化的条目拼写,或者为了类似的词组搜索一个文本数据集。 +“搜索” 特性并不是 Elasticsearch 唯一功能。ES 也是日志存储和分析的常用工具,在一个 ELK(Elasticsearch、Logstash、Kibana)架构配置中通常会使用它。灵活的全文搜索功能使得 Elasticsearch 在数据量非常大的科学任务中用处很大 —— 比如,在一个数据集中正确的/标准化的条目拼写,或者为了类似的词组搜索一个文本数据集。 对于你自己的项目,这里有一些创意。 * 添加更多你喜欢的书到教程的应用程序中,然后创建你自己的私人图书馆搜索引擎。 - * 利用来自 [Google Scholar][2] 的论文索引,创建一个学术抄袭检测引擎。 - * 通过将字典中的每个词索引到 Elasticsearch,创建一个拼写检查应用程序。 - * 通过将 [Common Crawl Corpus][3] 加载到 Elasticsearch 中,构建你自己的与谷歌竞争的因特网搜索引擎(注意,它可能会超过 50 亿个页面,这是一个成本极高的数据集)。 - * 在 journalism 上使用 Elasticsearch:在最近的大规模泄露的文档中搜索特定的名字和关键词,比如, [Panama Papers][4] 和 [Paradise Papers][5]。 本教程中应用程序的源代码是 100% 公开的,你可以在 GitHub 仓库上找到它们 —— [https://github.com/triestpa/guttenberg-search][45] @@ -1324,7 +1274,7 @@ via: https://blog.patricktriest.com/text-search-docker-elasticsearch/ 作者:[Patrick Triest][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180127 Your instant Kubernetes cluster.md b/published/201804/20180127 Your instant Kubernetes cluster.md similarity index 83% rename from translated/tech/20180127 Your instant Kubernetes cluster.md rename to published/201804/20180127 Your instant Kubernetes cluster.md index ac06ba730f..a2ccd874fe 100644 --- a/translated/tech/20180127 Your instant Kubernetes cluster.md +++ b/published/201804/20180127 Your instant Kubernetes cluster.md @@ -1,19 +1,15 @@ “开箱即用” 的 Kubernetes 集群 ============================================================ - -这是我以前的 [10 分钟内配置 Kubernetes][10] 教程的精简版和更新版。我删除了一些我认为可以去掉的内容,所以,这个指南仍然是可理解的。当你想在云上创建一个集群或者尽可能快地构建基础设施时,你可能会用到它。 +这是我以前的 [10 分钟内配置 Kubernetes][10] 教程的精简版和更新版。我删除了一些我认为可以去掉的内容,所以,这个指南仍然是通顺的。当你想在云上创建一个集群或者尽可能快地构建基础设施时,你可能会用到它。 ### 1.0 挑选一个主机 我们在本指南中将使用 Ubuntu 16.04,这样你就可以直接拷贝/粘贴所有的指令。下面是我用本指南测试过的几种环境。根据你运行的主机,你可以从中挑选一个。 * [DigitalOcean][1] - 开发者云 - * [Civo][2] - UK 开发者云 - * [Packet][3] - 裸机云 - * 2x Dell Intel i7 服务器 —— 它在我家中 > Civo 是一个相对较新的开发者云,我比较喜欢的一点是,它开机时间只有 25 秒,我就在英国,因此,它的延迟很低。 @@ -25,14 +21,12 @@ 下面是一些其他的指导原则: * 最好选至少有 2 GB 内存的双核主机 - * 在准备主机的时候,如果你可以自定义用户名,那么就不要使用 root。例如,Civo 通常让你在 `ubuntu`、`civo` 或者 `root` 中选一个。 -现在,在每台机器上都运行以下的步骤。它将需要 5-10 钟时间。如果你觉得太慢了,你可以使用我的脚本 [kept in a Gist][11]: +现在,在每台机器上都运行以下的步骤。它将需要 5-10 钟时间。如果你觉得太慢了,你可以使用我[放在 Gist][11] 的脚本 : ``` $ curl -sL https://gist.githubusercontent.com/alexellis/e8bbec45c75ea38da5547746c0ca4b0c/raw/23fc4cd13910eac646b13c4f8812bab3eeebab4c/configure.sh | sh - ``` ### 1.2 登入和安装 Docker @@ -42,7 +36,6 @@ $ curl -sL https://gist.githubusercontent.com/alexellis/e8bbec45c75ea38da5547746 ``` $ sudo apt-get update \ && sudo apt-get install -qy docker.io - ``` ### 1.3 禁用 swap 文件 @@ -69,7 +62,6 @@ $ sudo apt-get update \ kubelet \ kubeadm \ kubernetes-cni - ``` ### 1.5 创建集群 @@ -80,7 +72,6 @@ $ sudo apt-get update \ ``` $ sudo kubeadm init - ``` 如果你错过一个步骤或者有问题,`kubeadm` 将会及时告诉你。 @@ -90,41 +81,37 @@ $ sudo kubeadm init ``` mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config -sudo chown $(id -u):$(id -g) $HOME/.kube/config - +sudo chown $(id -u):$(id -g) $HOME/.kube/config ``` -确保你一定要记下如下的加入 token 命令。 +确保你一定要记下如下的加入 `token` 的命令。 ``` $ sudo kubeadm join --token c30633.d178035db2b4bb9a 10.0.0.5:6443 --discovery-token-ca-cert-hash sha256: - ``` ### 2.0 安装网络 -Kubernetes 可用于任何网络供应商的产品或服务,但是,默认情况下什么也没有,因此,我们使用来自  [Weaveworks][12] 的 Weave Net,它是 Kebernetes 社区中非常流行的选择之一。它倾向于不需要额外配置的 “开箱即用”。 +许多网络提供商提供了 Kubernetes 支持,但是,默认情况下 Kubernetes 都没有包括。这里我们使用来自  [Weaveworks][12] 的 Weave Net,它是 Kebernetes 社区中非常流行的选择之一。它近乎不需要额外配置的 “开箱即用”。 ``` $ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')" - ``` -如果在你的主机上启用了私有网络,那么,你可能需要去修改 Weavenet 使用的私有子网络,以便于为 Pods(容器)分配 IP 地址。下面是命令示例: +如果在你的主机上启用了私有网络,那么,你可能需要去修改 Weavenet 使用的私有子网络,以便于为 Pod(容器)分配 IP 地址。下面是命令示例: ``` $ curl -SL "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.IPALLOC_RANGE=172.16.6.64/27" \ | kubectl apply -f - - ``` -> Weave 也有很酷的称为 Weave Cloud 的可视化工具。它是免费的,你可以在它上面看到你的 Pods 之间的路径流量。[这里有一个使用 OpenFaaS 项目的示例][6]。 +> Weave 也有很酷的称为 Weave Cloud 的可视化工具。它是免费的,你可以在它上面看到你的 Pod 之间的路径流量。[这里有一个使用 OpenFaaS 项目的示例][6]。 ### 2.2 在集群中加入工作节点 现在,你可以切换到你的每一台工作节点,然后使用 1.5 节中的 `kubeadm join` 命令。运行完成后,登出那个工作节点。 -### 3.0 收益 +### 3.0 收获 到此为止 —— 我们全部配置完成了。你现在有一个正在运行着的集群,你可以在它上面部署应用程序。如果你需要设置仪表板 UI,你可以去参考 [Kubernetes 文档][13]。 @@ -134,21 +121,21 @@ NAME STATUS ROLES AGE VERSION openfaas1 Ready master 20m v1.9.2 openfaas2 Ready 19m v1.9.2 openfaas3 Ready 19m v1.9.2 - ``` 如果你想看到我一步一步创建集群并且展示 `kubectl` 如何工作的视频,你可以看下面我的视频,你可以订阅它。 +![](https://youtu.be/6xJwQgDnMFE) -想在你的 Mac 电脑上,使用 Minikube 或者 Docker 的 Mac Edge 版本,安装一个 “开箱即用” 的 Kubernetes 集群,[阅读在这里的我的评估和第一印象][14]。 +你也可以在你的 Mac 电脑上,使用 Minikube 或者 Docker 的 Mac Edge 版本,安装一个 “开箱即用” 的 Kubernetes 集群。[阅读在这里的我的评估和第一印象][14]。 -------------------------------------------------------------------------------- via: https://blog.alexellis.io/your-instant-kubernetes-cluster/ -作者:[Alex Ellis ][a] +作者:[Alex Ellis][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md b/published/201804/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md similarity index 50% rename from sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md rename to published/201804/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md index bf7772ef1a..ba63c49894 100644 --- a/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md +++ b/published/201804/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md @@ -1,63 +1,73 @@ -How to add network bridge with nmcli (NetworkManager) on Linux +如何在 Linux 里使用 nmcli 添加网桥 ====== -I am using Debian Linux 9 "stretch" on the desktop. I would like to create network bridge with NetworkManager. But, I am unable to find the option to add br0. How can I create or add network bridge with nmcli for NetworkManager on Linux? +Q:我正在电脑上使用 Debian Linux 9 “stretch”。 我想用 NetworkManager 来建网桥。但是根本就没有添加 br0的选项。我该如何在 Linux 里使用 nmcli 来为 NetworkManager 创建或者添加网桥呢? -A bridge is nothing but a device which joins two local networks into one network. It works at the data link layer, i.e., layer 2 of the OSI model. Network bridge often used with virtualization and other software. Disabling NetworkManager for a simple bridge especially on Linux Laptop/desktop doesn't make any sense. The nmcli tool can create Persistent bridge configuration without editing any files. **This page shows how to create a bridge interface using the Network Manager command line tool called nmcli**. +网桥没什么特别的,只是把两个网络连在一起。它工作在数据链路层,即 OSI 模型的第二层。网桥经常用在虚拟机或别的一些软件中。为了使用网桥而关闭桌面 Linux 上的 NetworkManager 显然是不明智的。`nmcli` 可以创建一个永久的网桥而不需要编辑任何文件。 +本文将展示如何使用 NetworkManager 的命令行工具 `nmcli` 来创建网桥。 +### 如何使用 nmcli 来创建/添加网桥 -### How to create/add network bridge with nmcli +使用 NetworkManager 在 Linux 上添加网桥接口的步骤如下: -The procedure to add a bridge interface on Linux is as follows when you want to use Network Manager: - -1. Open the Terminal app -2. Get info about the current connection: +1. 打开终端 +2. 获取当前连接状态: ``` nmcli con show ``` -3. Add a new bridge: +3. 添加新的网桥: ``` nmcli con add type bridge ifname br0 ``` -4. Create a slave interface: +4. 创建子网卡: ``` nmcli con add type bridge-slave ifname eno1 master br0 ``` -5. Turn on br0: +5. 打开 br0: ``` nmcli con up br0 ``` -Let us see how to create a bridge, named br0 in details. +让我们从细节层面看看如何创建一个名为 br0 的网桥。 -### Get current network config +### 获取当前网络配置 + +你可以通过 NetworkManager 的 GUI 来了解本机的网络连接: -You can view connection from the Network Manager GUI in settings: [![Getting Network Info on Linux][1]][1] -Another option is to type the following command: + +也可以使用如下命令行来查看: + ``` $ nmcli con show $ nmcli connection show --active ``` -[![View the connections with nmcli][2]][2] -I have a "Wired connection 1" which uses the eno1 Ethernet interface. My system has a VPN interface too. I am going to setup a bridge interface named br0 and add, (or enslave) an interface to eno1. -### How to create a bridge, named br0 +[![View the connections with nmcli][2]][2] + +我有一个使用网卡 `eno1` 的 “有线连接”。我的系统还有一个 VPN 接口。我将要创建一个名为 `br0` 的网桥,并连接到 `eno1`。 + +### 如何创建一个名为 br0 的网桥 ``` $ sudo nmcli con add ifname br0 type bridge con-name br0 $ sudo nmcli con add type bridge-slave ifname eno1 master br0 $ nmcli connection show ``` + [![Create bridge interface using nmcli on Linux][3]][3] -You can disable STP too: + +你也可以禁用 STP: + ``` $ sudo nmcli con modify br0 bridge.stp no $ nmcli con show $ nmcli -f bridge con show br0 ``` -The last command shows the bridge settings including disabled STP: + +最后一条命令展示了禁用 STP 后的网桥参数: + ``` bridge.mac-address: -- bridge.stp: no @@ -69,27 +79,35 @@ bridge.ageing-time: 300 bridge.multicast-snooping: yes ``` +### 如何打开网桥 -### How to turn on bridge interface +你必须先关闭 `Wired connection 1` ,然后打开 `br0`: -You must turn off "Wired connection 1" and turn on br0: ``` $ sudo nmcli con down "Wired connection 1" $ sudo nmcli con up br0 $ nmcli con show ``` -Use [ip command][4] to view the IP settings: + +使用 [ip 命令][4] 来查看 IP 信息: + ``` $ ip a s $ ip a s br0 ``` + [![Build a network bridge with nmcli on Linux][5]][5] -### Optional: How to use br0 with KVM +### 附录: 如何在 KVM 上使用 br0 + +现在你可以使用 KVM/VirtualBox/VMware workstation 创建的 VM(虚拟机)来直接连接网络而非通过 NAT。使用 `vi` 或者 [cat 命令][6]为虚拟机创建一个名为 `br0.xml` 的文件: + +``` +$ cat /tmp/br0.xml +``` + +添加以下代码: -Now you can connect VMs (virtual machine) created with KVM/VirtualBox/VMware workstation to a network directly without using NAT. Create a file named br0.xml for KVM using vi command or [cat command][6]: -`$ cat /tmp/br0.xml` -Append the following code: ``` br0 @@ -98,14 +116,17 @@ Append the following code: ``` -Run virsh command as follows: +如下所示运行 `virsh`命令: + ``` # virsh net-define /tmp/br0.xml # virsh net-start br0 # virsh net-autostart br0 # virsh net-list --all ``` -Sample outputs: + +输出: + ``` Name State Autostart Persistent ---------------------------------------------------------- @@ -113,24 +134,24 @@ Sample outputs: default inactive no yes ``` +阅读 man 页面获取更多信息: -For more info read the following man page: ``` $ man ip $ man nmcli ``` -### about the author +### 关于作者 -The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9]. +作者是 nixCraft 的创建者、老练的系统管理员和一个 Linux/Unix shell 脚本编程培训师。他为全球客户和各种公司工作,包括 IT,教育,国防,空间研究以及非营利组织。 他的联系方式 [Twitter][7]、 [Facebook][8]、 [Google+][9]。 -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/faq/how-to-add-network-bridge-with-nmcli-networkmanager-on-linux/ 作者:[Vivek Gite][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[kennethXia](https://github.com/kennethXia) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20180129 A look inside Facebooks open source program.md b/published/201804/20180129 A look inside Facebooks open source program.md new file mode 100644 index 0000000000..1684d005bb --- /dev/null +++ b/published/201804/20180129 A look inside Facebooks open source program.md @@ -0,0 +1,64 @@ +Facebook 的开源计划一窥 +============================================================ + +> Facebook 开发人员 Christine Abernathy 讨论了开源如何帮助公司分享见解并推动创新。 + +![A look inside Facebook's open source program](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW-Internet_construction_9401467_520x292_0512_dc.png?itok=RPkPPtDe "A look inside Facebook's open source program") + +图像来源:opensource.com + +开源逐年变得无处不在,从[政府直辖市][11]到[大学][12]都有。各种规模的公司也越来越多地转向开源软件。事实上,一些公司正在通过财务支持项目或与开发人员合作进一步推进开源。 + +例如,Facebook 的开源计划鼓励其他人开源发布他们的代码,同时与社区合作支持开源项目。 [Christine Abernathy][13],是一名 Facebook 开发者、开源支持者,也是该公司开源团队成员,去年 11 月访问了罗切斯特理工学院,在 [11 月][14] 的 FOSS 系列演讲中发表了演讲。在她的演讲中,Abernathy 解释了 Facebook 如何开源以及为什么它是公司所做工作的重要组成部分。 + +### Facebook 和开源 + +Abernathy 说,开源在 Facebook 创建社区并使世界更加紧密的使命中扮演着重要的角色。这种意识形态的匹配是 Facebook 参与开源的一个激励因素。此外,Facebook 面临着独特的基础设施和开发挑战,而开源则为公司提供了一个平台,以共享可帮助他人的解决方案。开源还提供了一种加速创新和创建更好软件的方法,帮助工程团队生产更好的软件并更透明地工作。今天,Facebook 在 GitHub 的 443 个项目有 122,000 个分支、292,000 个提交和 732,000 个关注。 + +![open source projects by Facebook](https://opensource.com/sites/default/files/images/life-uploads/blog-article-facebook-open-source-projects.png "open source projects by Facebood") + +*一些以开源方式发布的 Facebook 项目包括 React、GraphQL、Caffe2 等等。(图片提供:Christine Abernathy 图片,经许可使用)* + +### 得到的教训 + +Abernathy 强调说 Facebook 已经从开源社区吸取了很多教训,并期待学到更多。她明确了三个最重要的: + +* 分享有用的东西 +* 突出你的英雄 +* 修复常见的痛点 + + _Christine Abernathy 作为 FOSS 演讲系列的嘉宾一员参观了 RIT。每个月,来自开源世界的演讲嘉宾都会与对自由和开源软件感兴趣的学生分享关于开源世界智慧、见解、建议。 [FOSS @MAGIC][3]社区感谢 Abernathy 作为演讲嘉宾出席。_ + +### 关于作者 + +Justin 是[罗切斯特理工学院][4]主修网络与系统管理的学生。他目前是 [Fedora Project][5] 的贡献者。在 Fedora 中,Justin 是 [Fedora Magazine][6] 的主编,[社区的领导][7]... [更多关于 Justin W. Flory]​​[8] + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/inside-facebooks-open-source-program + +作者:[Justin W. Flory][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jflory +[1]:https://opensource.com/file/383786 +[2]:https://opensource.com/article/18/1/inside-facebooks-open-source-program?rate=H9_bfSwXiJfi2tvOLiDxC_tbC2xkEOYtCl-CiTq49SA +[3]:http://foss.rit.edu/ +[4]:https://www.rit.edu/ +[5]:https://fedoraproject.org/wiki/Overview +[6]:https://fedoramagazine.org/ +[7]:https://fedoraproject.org/wiki/CommOps +[8]:https://opensource.com/users/jflory +[9]:https://opensource.com/users/jflory +[10]:https://opensource.com/user/74361/feed +[11]:https://opensource.com/article/17/8/tirana-government-chooses-open-source +[12]:https://opensource.com/article/16/12/2016-election-night-hackathon +[13]:https://twitter.com/abernathyca +[14]:https://www.eventbrite.com/e/fossmagic-talks-open-source-facebook-with-christine-abernathy-tickets-38955037566# +[15]:https://opensource.com/users/jflory +[16]:https://opensource.com/users/jflory +[17]:https://opensource.com/users/jflory +[18]:https://opensource.com/article/18/1/inside-facebooks-open-source-program#comments \ No newline at end of file diff --git a/published/201804/20180129 How to Use DockerHub.md b/published/201804/20180129 How to Use DockerHub.md new file mode 100644 index 0000000000..0eaeaab289 --- /dev/null +++ b/published/201804/20180129 How to Use DockerHub.md @@ -0,0 +1,143 @@ +如何使用 DockerHub +======== + +> 在这个 Docker 系列的最后一篇文章中,我们将讲述在 DockerHub 上使用和发布镜像。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dockerhub-container.jpg?itok=tvraxGzh) + +在前面的文章中,我们了解到了基本的 [Docker 术语][1],在 Linux 桌面、MacOS 和 Windows上 [如何安装 Docker][2],[如何创建容器镜像][3] 并且在系统上运行它们。在本系列的最后一篇文章中,我们将讨论如何使用 DockerHub 中的镜像以及将自己的镜像发布到 DockerHub。 + +首先:什么是 DockerHub 以及为什么它很重要?DockerHub 是一个由 Docker 公司运行和管理的基于云的存储库。它是一个在线存储库,Docker 镜像可以由其他用户发布和使用。有两种库:公共存储库和私有存储库。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。 + +你也可以使用公开发布的官方 Docker 镜像。我使用了很多这样的镜像,包括我的试验 WordPress 环境、KDE plasma 应用程序等等。虽然我们上次学习了如何创建自己的 Docker 镜像,但你不必这样做。DockerHub 上发布了数千镜像供你使用。DockerHub 作为默认存储库硬编码到 Docker 中,所以当你对任何镜像运行 `docker pull` 命令时,它将从 DockerHub 下载。 + +### 从 Docker Hub 下载镜像并在本地运行 + +开始请查看本系列的前几篇文章,以便继续。然后,一旦 Docker 在你的系统上运行,你就可以打开终端并运行: + +``` +$ docker images +``` + +该命令将显示当前系统上所有的 docker 镜像。假设你想在本地机器上部署 Ubuntu,你可能会: + +``` +$ docker pull ubuntu +``` + +如果你的系统上已经存在 Ubuntu 镜像,那么该命令会自动将该系统更新到最新版本。因此,如果你想要更新现有的镜像,只需运行 `docker pull` 命令,易如反掌。这就像 `apt-get update` 一样,没有任何的混乱和麻烦。 + +你已经知道了如何运行镜像: + +``` +$ docker run -it +$ docker run -it ubuntu +``` + +命令提示符应该变为如下内容: + +``` +root@1b3ec4621737:/# +``` + +现在你可以运行任何属于 Ubuntu 的命令和实用程序,这些都被包含在内而且安全。你可以在 Ubuntu 上运行你想要的所有实验和测试。一旦你完成了测试,你就可以销毁镜像并下载一个新的。在虚拟机中不存在系统开销。 + +你可以通过运行 exit 命令退出该容器: + +``` +$ exit +``` + +现在假设你想在系统上安装 Nginx,运行 `search` 命令来找到需要的镜像: + +``` +$ docker search nginx +``` + +![](https://lh3.googleusercontent.com/aizMFFysICAEsgDDYrsrlqwoCgGbWVHtcOzgV9mAtV8IdBZgHPJTdHIZhWBNCRvOyJb108ZBajJ_Nz10yCxGSvk-AF-yvFxpojLdVu3Jjihcwaup6CQLc67A5nglBuGDaOZWcrbV) + +正如你所看到的,DockerHub 上有很多 Nginx 镜像。为什么?因为任何人都可以发布镜像,各种镜像针对不同的项目进行了优化,因此你可以选择合适的镜像。你只需要为你的需求安装合适的镜像。 + +假设你想要拉取 Bitnami 的 Nginx 镜像: + +``` +$ docker pull bitnami/nginx +``` + +现在运行: + +``` +$ docker run -it bitnami/nginx +``` + +### 如何发布镜像到 Docker Hub? + +在此之前,[我们学习了如何创建 Docker 镜像][3],我们可以轻松地将该镜像发布到 DockerHub 中。首先,你需要登录 DockerHub,如果没有账户,请 [创建账户][5]。然后,你可以打开终端应用,登录: + +``` +$ docker login --username= +``` + +将 “\” 替换为你自己的 Docker Hub 用户名。我这里是 arnieswap: + +``` +$ docker login --username=arnieswap +``` + +输入密码,你就登录了。现在运行 `docker images` 命令来获取你上次创建的镜像的 ID。 + +``` +$ docker images +``` + +![](https://lh6.googleusercontent.com/tW1jDOugkX7J2FfyFyToM6B8m5OYFwMba-Ag5aezVGf2A5gsKJ47QrCh_TOKWgIKfE824Uc2Cwwwj9jWps1yJlUZqDyIceVQs-nEbKavFDxuUxLyd4thBA4_rsXrQH4r7hrG8FnD) + +现在,假设你希望将镜像 `ng` 推送到 DockerHub,首先,我们需要标记该镜像([了解更多关于标记的信息][1]): + +``` +$ docker tag e7083fd898c7 arnieswap/my_repo:testing +``` + +现在推送镜像: + +``` +$ docker push arnieswap/my_repo +``` + +推送指向的是 [docker.io/arnieswap/my_repo] 仓库: + +``` +12628b20827e: Pushed +8600ee70176b: Mounted from library/ubuntu +2bbb3cec611d: Mounted from library/ubuntu +d2bb1fc88136: Mounted from library/ubuntu +a6a01ad8b53f: Mounted from library/ubuntu +833649a3e04c: Mounted from library/ubuntu +testing: digest: sha256:286cb866f34a2aa85c9fd810ac2cedd87699c02731db1b8ca1cfad16ef17c146 size: 1569 +``` + +哦耶!你的镜像正在上传。一旦完成,打开 DockerHub,登录到你的账户,你就能看到你的第一个 Docker 镜像。现在任何人都可以部署你的镜像。这是开发软件和发布软件最简单,最快速的方式。无论你何时更新镜像,用户都可以简单地运行: + +``` +$ docker run arnieswap/my_repo +``` + +现在你知道为什么人们喜欢 Docker 容器了。它解决了传统工作负载所面临的许多问题,并允许你在任何时候开发、测试和部署应用程序。通过遵循本系列中的步骤,你自己可以尝试以下。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-use-dockerhub + +作者:[Swapnil Bhartiya][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/arnieswap +[1]:https://www.linux.com/blog/intro-to-linux/2017/12/container-basics-terms-you-need-know +[2]:https://www.linux.com/blog/learn/intro-to-linux/how-install-docker-ce-your-desktop +[3]:https://linux.cn/article-9541-1.html +[4]:https://lh3.googleusercontent.com/aizMFFysICAEsgDDYrsrlqwoCgGbWVHtcOzgV9mAtV8IdBZgHPJTdHIZhWBNCRvOyJb108ZBajJ_Nz10yCxGSvk-AF-yvFxpojLdVu3Jjihcwaup6CQLc67A5nglBuGDaOZWcrbV +[5]:https://hub.docker.com/ +[6]:https://lh6.googleusercontent.com/tW1jDOugkX7J2FfyFyToM6B8m5OYFwMba-Ag5aezVGf2A5gsKJ47QrCh_TOKWgIKfE824Uc2Cwwwj9jWps1yJlUZqDyIceVQs-nEbKavFDxuUxLyd4thBA4_rsXrQH4r7hrG8FnD \ No newline at end of file diff --git a/published/201804/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md b/published/201804/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md new file mode 100644 index 0000000000..6245810c69 --- /dev/null +++ b/published/201804/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md @@ -0,0 +1,80 @@ +在 Ubuntu 17.10 上安装 AWFFull Web 服务器日志分析应用程序 +====== + +AWFFull 是基于 “Webalizer” 的 Web 服务器日志分析程序。AWFFull 以 HTML 格式生成使用统计信息以便用浏览器查看。结果以柱状和图形两种格式显示,这有利于解释数据。它提供每年、每月、每日和每小时的使用统计数据,并显示网站、URL、referrer、user agent(浏览器)、用户名、搜索字符串、进入/退出页面和国家(如果一些信息不存在于处理后日志中那么就没有)。AWFFull 支持 CLF(通用日志格式)日志文件,以及由 NCSA 等定义的组合日志格式,它还能只能地处理这些格式的变体。另外,AWFFull 还支持 wu-ftpd xferlog 格式的日志文件,它能够分析 ftp 服务器和 squid 代理日志。日志也可以通过 gzip 压缩。 + +如果检测到压缩日志文件,它将在读取时自动解压缩。压缩日志必须是 .gz 扩展名的标准 gzip 压缩。 + +### 对于 Webalizer 的修改 + +AWFFull 基于 Webalizer 的代码,并有许多或大或小的变化。包括: + +- 不止原始统计数据:利用已发布的公式,提供额外的网站使用情况。 +- GeoIP IP 地址能更准确地检测国家。 +- 可缩放的图形 +- 与 GNU gettext 集成,能够轻松翻译。目前支持 32 种语言。 +- 在首页显示超过 12 个月的网站历史记录。 +- 额外的页面计数跟踪和排序。 +- 一些小的可视化调整,包括 Geolizer 用量中使用 Kb、Mb。 +- 额外的用于 URL 计数、进入和退出页面、站点的饼图 +- 图形上的水平线更有意义,更易于阅读。 +- User Agent 和 Referral 跟踪现在通过 PAGES 而非 HITS 进行计算。 +- 现在支持 GNU 风格的长命令行选项(例如 --help)。 +- 可以通过排除“什么不是”以及原始的“什么是”来选择页面。 +- 对被分析站点的请求以匹配的引用 URL 显示。 +- 404 错误表,并且可以生成引用 URL。 +- 生成的 html 可以使用外部 CSS 文件。 +- POST 分析总结使得手动优化配置文件性能更简单。 +- 可以将指定的 IP 和地址分配给指定的国家。 +- 便于使用其他工具详细分析的转储选项。 +- 支持检测并处理 Lotus Domin- v6 日志。 + +### 在 Ubuntu 17.10 上安装 AWFFull + +``` +sud- apt-get install awffull +``` + +### 配置 AWFFull + +你必须在 `/etc/awffull/awffull.conf` 中编辑 AWFFull 配置文件。如果你在同一台计算机上运行多个虚拟站点,​​则可以制作多个默认配置文件的副本。 + +``` +sud- vi /etc/awffull/awffull.conf +``` + +确保有下面这几行: + +``` +LogFile /var/log/apache2/access.log.1 +OutputDir /var/www/html/awffull +``` + +保存并退出文件。 + +你可以使用以下命令运行 awffull。 + +``` +awffull -c [your config file name] +``` + +这将在 `/var/www/html/awffull` 目录下创建所有必需的文件,以便你可以使用 http://serverip/awffull/ 。 + +你应该看到类似于下面的页面: + +![](http://www.ubuntugeek.com/wp-content/uploads/2015/12/11.png) + + +如果你有更多站点,你可以使用 shell 和计划任务自动化这个过程。 + +-------------------------------------------------------------------------------- + +via: http://www.ubuntugeek.com/install-awffull-web-server-log-analysis-application-on-ubuntu-17-10.html + +作者:[ruchi][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.ubuntugeek.com/author/ubuntufix diff --git a/translated/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md b/published/201804/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md similarity index 50% rename from translated/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md rename to published/201804/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md index 8c6f0ba124..f96f8f1a6a 100644 --- a/translated/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md +++ b/published/201804/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md @@ -1,29 +1,28 @@ -为初学者准备的 Linux ln 命令教程(5 个示例) +为初学者准备的 ln 命令教程(5 个示例) ====== -当我们在命令行上工作时,您可能需要在文件之间创建链接。这时,您可以可以借助一个专用命令,**ln**。本教程中,我们将通过一些简单易理解的例子来讨论此工具的基础知识。在此之前,值得一提的是,本教程所有例子都已在 Ubuntu 16.04 上测试通过。 +当我们在命令行上工作时,您可能需要在文件之间创建链接。这时,您可以可以借助一个专用命令,`ln`。本教程中,我们将通过一些简单易理解的例子来讨论此工具的基础知识。在此之前,值得一提的是,本教程所有例子都已在 Ubuntu 16.04 上测试通过。 ### Linux ln 命令 -正如你现在所了解的,ln 命令能够让您在文件之间创建链接。下面就是 ln 工具的语法(或者使用其他一些可行的语法)。 +正如你现在所了解的,`ln` 命令能够让您在文件之间创建链接。下面就是 `ln` 工具的语法(或者使用其他一些可行的语法)。 ``` -ln [OPTION]... [-T] TARGET LINK_NAME (1st form) -ln [OPTION]... TARGET (2nd form) -ln [OPTION]... TARGET... DIRECTORY (3rd form) -ln [OPTION]... -t DIRECTORY TARGET... (4th form) +ln [OPTION]... [-T] TARGET LINK_NAME (第一种形式) +ln [OPTION]... TARGET (第二种形式) +ln [OPTION]... TARGET... DIRECTORY (第三种形式) +ln [OPTION]... -t DIRECTORY TARGET... (第四种形式) ``` -下面是 ln 工具 man 文档描述的内容: -``` -在第一种形式下,为 TARGET 创建一个叫 LINK_NAME 的链接。在第二种形式下,为 TARGET 在当前目录下创建一个链接( LCTT 译注:创建的为同名链接)。在第三和第四中形式中,在 DIRECTORY 目录下为每一个 TARGET 创建链接。默认创建硬链接,符号链接需要 --symbolic 选项。默认创建的每一个目标(新链接的名字)都不能已经存在。当创建硬链接时,TARGET 文件必须存在。符号链接可以保存任意文本,如果之后解析,相对链接的解析与其父目录有关。 -``` +下面是 `ln` 工具 man 文档描述的内容: + +> 在第一种形式下,为目标位置(TARGET)创建一个叫 LINK_NAME 的链接。在第二种形式下,为目标位置(TARGET)在当前目录下创建一个链接(LCTT 译注:创建的为同名链接)。在第三和第四种形式中,在 DIRECTORY 目录下为每一个目标位置(TARGET)创建链接。默认创建硬链接,符号链接需要 `--symbolic` 选项。默认创建的每一个创建的链接(新链接的名字)都不能已经存在。当创建硬链接时,目标位置(TARGET)文件必须存在;符号链接可以保存任意文本,如果之后解析,相对链接的解析与其父目录有关。 通过下面问答风格的例子,可能会给你更好的理解。但是在此之前,建议您先了解 [硬链接和软链接的区别][1]. ### Q1. 如何使用 ln 命令创建硬链接? -这很简单,你只需要像下面使用 ln 命令: +这很简单,你只需要像下面使用 `ln` 命令: ``` ln [file] [hard-link-to-file] @@ -37,11 +36,11 @@ ln test.txt test_hard_link.txt [![如何使用 ln 命令创建硬链接][2]][3] -如此,您便可以看见一个已经创建好的,名为 test_hard_link.txt 的硬链接。 +如此,您便可以看见一个已经创建好的,名为 `test_hard_link.txt` 的硬链接。 ### Q2. 如何使用 ln 命令创建软/符号链接? -使用 -s 命令行选项 +使用 `-s` 命令行选项: ``` ln -s [file] [soft-link-to-file] @@ -55,39 +54,39 @@ ln -s test.txt test_soft_link.txt [![如何使用 ln 命令创建软/符号链接][4]][5] -test_soft_link.txt 文件就是一个软/符号链接,被天蓝色文本 [标识][6]。 +`test_soft_link.txt` 文件就是一个软/符号链接,以天蓝色文本 [标识][6]。 ### Q3. 如何使用 ln 命令删除既存的同名目标文件? -默认情况下,ln 不允许您在目标目录下创建已存在的链接。 +默认情况下,`ln` 不允许您在目标目录下创建已存在的链接。 [![ln 命令示例][7]][8] -然而,如果一定要这么做,您可以使用 **-f** 命令行选项覆盖此行为。 +然而,如果一定要这么做,您可以使用 `-f` 命令行选项覆盖此行为。 [![如何使用 ln 命令创建软/符号链接][9]][10] -**贴士** : 如果您想在此删除过程中有所交互,您可以使用 **-i** 选项。 +提示:如果您想在此删除过程中有所交互,您可以使用 `-i` 选项。 ### Q4. 如何使用 ln 命令创建现有文件的同名备份? -如果您不想 ln 删除同名的现有文件,您可以为这些文件创建备份。使用 **-b** 即可实现此效果,以这种方式创建的备份文件,会在其文件名结尾处包含一个波浪号(~)。 +如果您不想 `ln` 删除同名的现有文件,您可以为这些文件创建备份。使用 `-b` 即可实现此效果,以这种方式创建的备份文件,会在其文件名结尾处包含一个波浪号(`~`)。 [![如何使用 ln 命令创建现有文件的同名备份][11]][12] ### Q5. 如何在当前目录以外的其它目录创建链接? -使用 **-t** 选项指定一个文件目录(除了当前目录)。比如: +使用 `-t` 选项指定一个文件目录(除了当前目录)。比如: ``` ls test* | xargs ln -s -t /home/himanshu/Desktop/ ``` -上述命令会为所有 test* 文件(当前目录下的 test* 文件)创建链接,并放到桌面目录下。 +上述命令会为(当前目录下的)所有 `test*` 文件创建链接,并放到桌面目录下。 ### 总结 -当然,尤其对于新手来说,**ln** 并不是日常必备命令。但是,这是一个有用的命令,因为你永远不知道它什么时候能够节省你一天的时间。对于这个命令,我们已经讨论了一些实用的选项,如果你已经完成了这些,可以查询 [man 文档][13] 来了解更多详情。 +当然,尤其对于新手来说,`ln` 并不是日常必备命令。但是,这是一个有用的命令,因为你永远不知道它什么时候能够节省你一天的时间。对于这个命令,我们已经讨论了一些实用的选项,如果你已经完成了这些,可以查询 [man 文档][13] 来了解更多详情。 -------------------------------------------------------------------------------- diff --git a/published/201804/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md b/published/201804/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md new file mode 100644 index 0000000000..e891707cb0 --- /dev/null +++ b/published/201804/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md @@ -0,0 +1,79 @@ +一个基于 Arch 的独立 Linux 发行版 MagpieOS +====== + +目前使用的大多数 Linux 发行版都是由欧美创建和开发的。一位来自孟加拉国的年轻开发人员想要改变这一切。 + +### 谁是 Rizwan? + +[Rizwan][1] 是来自孟加拉国的计算机科学专业的学生。他目前正在学习成为一名专业的 Python 程序员。他在 2015 年开始使用 Linux。使用 Linux 启发他创建了自己的 Linux 发行版。他还希望让世界其他地方知道孟加拉国正在升级到 Linux。 + +他还致力于从头创建 [LFS 的 live 版本][2]。 + +![MagpieOS Linux][3] + +### 什么是 MagpieOS? + +Rizwan 的新发行版被命名为 MagpieOS。 [MagpieOS][4] 非常简单。它基本上是 GNOME3 桌面环境的 Arch。 MagpieOS 还包括一个自定义的仓库,其中包含图标和主题(据称)在其他基于 Arch 的发行版或 AUR 没有。 + +下面是 MagpieOS 包含的软件列表:Firefox、LibreOffice、Uget、Bleachbit、Notepadqq、SUSE Studio Image Writer、Pamac 软件包管理器、Gparted、Gimp、Rhythmbox、简单屏幕录像机等包括 Totem 视频播放器在内的所有默认 GNOME 软件,以及一套新的定制壁纸。 + +目前,MagpieOS 仅支持 GNOME 桌面环境。Rizwan 选择它是因为这是他的最爱。但是,他计划在未来添加更多的桌面环境。 + +不幸的是,MagpieOS 不支持孟加拉语或任何其他当地语言。它支持 GNOME 的默认语言,如英语、印地语等。 + +Rizwan 命名他的发行为 MagpieOS,因为[喜鹊][5]magpie 是孟加拉国的官方鸟。 + +![MagpieOS Linux][6] + +### 为什么选择 Arch? + +和大多数人一样,Rizwan 通过使用 [Ubuntu][7] 开始了他的 Linux 旅程。一开始,他对此感到满意。但是,有时他想安装的软件在仓库中没有,他不得不通过 Google 寻找正确的 PPA。他决定切换到 [Arch][8],因为 Arch 有许多在 Ubuntu 上没有的软件包。Rizwan 也喜欢 Arch 是一个滚动版本,并且始终是最新的。 + +Arch 的问题在于它的安装非常复杂和耗时。所以,Rizwan 尝试了几个基于 Arch 的发行版,并且对任何一个都不满意。他不喜欢 [Manjaro][9],因为它们没有权限使用 Arch 的仓库。此外,Arch 仓库镜像比 Manjaro 更快并且拥有更多软件。他喜欢 [Antergos][10],但要安装需要一个持续的互联网连接。如果在安装过程中连接失败,则必须重新开始。 + +由于这些问题,Rizwan 决定创建一个简单的发行版,让他和其他人无需麻烦地安装 Arch。他还希望通过使用他的发行版让他的祖国的开发人员从 Ubuntu 切换到 Arch。 + +### 如何通过 MagpieOS 帮助 Rizwan + +如果你有兴趣帮助 Rizwan 开发 MagpieOS,你可以通过 [MagpieOS 网站][4]与他联系。你也可以查看该项目的 [GitHub 页面][11]。Rizwan 表示,他目前不寻求财政支持。 + +![MagpieOS Linux][12] + +### 最后的想法 + +我快速地安装过一次 MagpieOS。它使用 [Calamares 安装程序][13],这意味着安装它相对快速轻松。重新启动后,我听到一封欢迎我来到 MagpieOS 的音频消息。 + +说实话,这是我第一次听到安装后的问候。(Windows 10 可能也有,但我不确定)屏幕底部还有一个 Mac OS 风格的应用程序停靠栏。除此之外,它感觉像我用过的其他任何 GNOME 3 桌面。 + +考虑到这是一个刚刚起步的独立项目,我不会推荐它作为你的主要操作系统。但是,如果你是一个发行版尝试者,你一定会试试看。 + +话虽如此,对于一个想把自己的国家放在技术地图上的学生来说,这是一个不错的尝试。做得很好,Rizwan。 + +你有没有听说过 MagpieOS?你最喜欢的地区或本地制作的 Linux 发行版是什么?请在下面的评论中告诉我们。 + +如果你发现这篇文章有趣,请花点时间在社交媒体上分享。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/magpieos/ + +作者:[John Paul][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/john/ +[1]:https://twitter.com/Linux_Saikat +[2]:https://itsfoss.com/linux-from-scratch-live-cd/ +[3]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos1.jpg +[4]:http://www.magpieos.net +[5]:https://en.wikipedia.org/wiki/Magpie +[6]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos2.jpg +[7]:https://www.ubuntu.com +[8]:https://www.archlinux.org +[9]:http://manjaro.org +[10]:https://antergos.com +[11]:https://github.com/Rizwan-Hasan/MagpieOS +[12]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos3.png +[13]:https://calamares.io diff --git a/published/201804/20180206 How to start an open source program in your company.md b/published/201804/20180206 How to start an open source program in your company.md new file mode 100644 index 0000000000..43a6e09736 --- /dev/null +++ b/published/201804/20180206 How to start an open source program in your company.md @@ -0,0 +1,49 @@ +如何在企业中开展开源计划 +====== + +> 有 65% 的企业使用开源软件,并非只有互联网企业才能受惠于开源计划。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW_openisopen.png?itok=FjmDxIaL) + +很多互联网企业如 Google、 Facebook、 Twitter 等,都已经正式建立了开源计划(有的公司中建立了单独的开源计划部门open source program office(OSPO)),这是在公司内部消化和支持开源产品的地方。在这样一个实际的部门中,企业可以清晰透明地执行开源策略,这是企业成功开源化的一个必要过程。开源计划部门的职责包括:制定使用、分配、选择和审查代码的相关政策;培育开源社区;培训开发技术人员和确保法律合规。 + +互联网企业并不是唯一建立开源计划的企业,有调查发现各种行业中有 [65% 的企业][1]的在使用开源和向开源贡献。在过去几年中 [VMware][2]、 [Amazon][3]、 [Microsoft][4] 等企业,甚至连[英国政府][5]都开始聘用开源管理人员,开展开源计划。可见近年来商业领域乃至政府都十分重视开源策略,在这样的环境下,各界也需要跟上他们的步伐,建立开源计划。 + +### 怎样建立开源计划 + +虽然根据企业的需求不同,各开源计划部门会有特殊的调整,但下面几个基本步骤是建立每个公司都会经历的,它们是: + + * **选定一位领导者:** 选出一位合适的领导之是建立开源计划的第一步。 [TODO Group][6] 发布了一份[开源人员基础工作任务清单][7],你可以根据这个清单筛选人员。 + * **确定计划构架:** 开源计划部门可以根据其服务的企业类型的侧重点,来适应不同种类的企业需求,以在各类企业中成功运行。知识型企业可以把开源计划放在法律事务部运行,技术驱动型企业可以把开源计划放在着眼于提高企业效能的部门中,如工程部。其他类型的企业可以把开源计划放在市场部内运行,以此促进开源产品的销售。TODO Group 发布的[开源计划案例][8]或许可以给你些启发。 + * **制定规章制度:** 开源策略的实施需要有一套规章制度,其中应当具体列出企业成员进行开源工作的标准流程,来减少失误的发生。这个流程应当简洁明了且简单易行,最好可以用设备进行自动化。如果工作人员有质疑标准流程的热情和能力,并提出改进意见,那再好不过了。许多活跃在开源领域的企业中,Google 发布的规章制度十分值得借鉴。你可以参照 [Google 发布的制度][9]起草适用于自己企业的规章制度,用 [TODO 提供其它开源策略][10]也可以参考。 +  +### 建立开源计划是企业发展中的关键一步 + +建立开源计划部门对很多企业来说是关键一步,尤其是对于那些软件公司或是想要转型进入软件领域的公司。不论雇员的满意度或是开发效率上,在开源计划中企业可以获得巨大的利益,这些利益远远大于对开源计划所需要的长期投资。在开源之路上有很多资源可以帮助你成功,例如 TODO Group 的[《怎样创建开源计划》][11]、[《开源计划的价值评估》][12]和[《管理开源计划的几种工具》][13]都很适合初学者阅读。 + +随着越来越多的企业形成开源计划,开源社区自身的可持续性逐渐加强,这会对这些企业的开源计划产生积极影响,促进企业的发展,这是企业和开源间的良性循环。我希望以上这些信息能够帮到你,祝你在建立开源计划的路上一路顺风。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/how-start-open-source-program-your-company + +作者:[Chris Aniszczyk][a] +译者:[Valoniakim](https://github.com/Valoniakim) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/caniszczyk +[1]:https://www.blackducksoftware.com/2016-future-of-open-source +[2]:http://www.cio.com/article/3095843/open-source-tools/vmware-today-has-a-strong-investment-in-open-source-dirk-hohndel.html +[3]:http://fortune.com/2016/12/01/amazon-open-source-guru/ +[4]:https://opensource.microsoft.com/ +[5]:https://www.linkedin.com/jobs/view/169669924 +[6]:http://todogroup.org +[7]:https://github.com/todogroup/job-descriptions +[8]:https://github.com/todogroup/guides/tree/master/casestudies +[9]:https://opensource.google.com/docs/why/ +[10]:https://github.com/todogroup/policies +[11]:https://github.com/todogroup/guides/blob/master/creating-an-open-source-program.md +[12]:https://github.com/todogroup/guides/blob/master/measuring-your-open-source-program.md +[13]:https://github.com/todogroup/guides/blob/master/tools-for-managing-open-source-programs.md diff --git a/translated/tech/20180206 Manage printers and printing.md b/published/201804/20180206 Manage printers and printing.md similarity index 59% rename from translated/tech/20180206 Manage printers and printing.md rename to published/201804/20180206 Manage printers and printing.md index 4ba3ace0ec..b849e8ebef 100644 --- a/translated/tech/20180206 Manage printers and printing.md +++ b/published/201804/20180206 Manage printers and printing.md @@ -1,12 +1,11 @@ -Linux 中如何打印和管理打印机 +完全指南:在 Linux 中如何打印和管理打印机 ====== - ### Linux 中的打印 虽然现在大量的沟通都是电子化和无纸化的,但是在我们的公司中还有大量的材料需要打印。银行结算单、公用事业帐单、财务和其它报告、以及收益结算单等一些东西还是需要打印的。本教程将介绍在 Linux 中如何使用 CUPS 去打印。 -CUPS,是通用 Unix 打印系统(Common UNIX Printing System)的首字母缩写,它是 Linux 中的打印机和打印任务的管理者。早期计算机上的打印机一般是在特定的字符集和字体大小下打印文本文件行。现在的图形打印机可以打印各种字体和大小的文本和图形。尽管如此,现在你所使用的一些命令,在它们以前的历史上仍旧使用的是古老的行打印守护进程(LPD)技术。 +CUPS,是通用 Unix 打印系统Common UNIX Printing System的首字母缩写,它是 Linux 中的打印机和打印任务的管理者。早期计算机上的打印机一般是在特定的字符集和字体大小下打印文本文件行。现在的图形打印机可以打印各种字体和大小的文本和图形。尽管如此,现在你所使用的一些命令,在古老的行式打印守护进程(LPD)技术的历史中仍能找到它们。 本教程将帮你了解 Linux 服务器专业考试(LPIC-1)的第 108 号主题的 108.4 目标。这个目标的权重为 2。 @@ -20,38 +19,39 @@ CUPS,是通用 Unix 打印系统(Common UNIX Printing System)的首字母 这一小部分历史并不是 LPI 目标的,但它有助于你理解这个目标的相关环境。 -早期的计算机大都使用行打印机。这些都是击打式打印机,一段时间以来,它们使用固定间距的字符和单一的字体来打印文本行。为提升整个系统性能,早期的主机都对慢速的外围设备如读卡器、卡片穿孔机、和运行其它工作的行打印进行交叉工作。因此就产生了在行上或者假脱机上的同步外围操作,这一术语目前在谈到计算机打印时仍然在使用。 +早期的计算机大都使用行式打印机。这些都是击打式打印机,那时,它们使用固定间距的字符和单一的字体来打印文本行。为提升整个系统性能,早期的主机要与慢速的外围设备(如读卡器、卡片穿孔机、和运行其它工作的行式打印机)交叉进行工作。因此就产生了在线的或者假脱机的同步外围操作,这一术语目前在谈到计算机打印时仍然在使用。 -在 UNIX 和 Linux 系统上,打印初始化使用的是 BSD(Berkeley Software Distribution)打印子系统,它是由一个作为服务器运行的行打印守护程序(LPD)组成,而客户端命令如 `lpr` 是用于提交打印作业。这个协议后来被 IETF 标准化为 RFC 1179 —— **行打印机守护协议**。 +在 UNIX 和 Linux 系统上,打印初始化使用的是 BSD(伯克利软件分发版Berkeley Software Distribution)打印子系统,它是由一个作为服务器运行的行式打印守护程序(LPD)组成,而客户端命令如 `lpr` 是用于提交打印作业。这个协议后来被 IETF 标准化为 RFC 1179 —— **行式打印机守护进程协议**。 -系统也有一个打印守护程序。它的功能与BSD 的 LPD 守护程序类似,但是它们的命令集不一样。你在后面会经常看到完成相同的任务使用不同选项的两个命令。例如,对于打印文件的命令,`lpr` 是伯克利实现的,而 `lp` 是 System V 实现的。 +System V 也有一个打印守护程序。它的功能与BSD 的 LPD 守护程序类似,但是它们的命令集不一样。你在后面会经常看到完成相同的任务使用不同选项的两个命令。例如,对于打印文件的命令,伯克利实现版本是 `lpr`,而 System V 实现版本是 `lp`。 -随着打印机技术的进步,在一个页面上混合出现不同字体成为可能,并且可以将图片像文字一样打印。可变间距字体,以及更多先进的打印技术,比如 kerning 和 ligatures,现在都已经标准化。它们对基本的 lpd/lpr 方法进行了改进设计,比如 LPRng,下一代的 LPR、以及 CUPS。 +随着打印机技术的进步,在一个页面上混合出现不同字体成为可能,并且可以将图片像文字一样打印。可变间距字体,以及更多先进的打印技术,比如间距和连字符,现在都已经标准化。出现了几种对基本的 lpd/lpr 方法等改进设计,比如 LPRng,下一代的 LPR,以及 CUPS。 -许多可以打印图形的打印机,使用 Adobe PostScript 语言进行初始化。一个 PostScript 打印机有一个解释器引擎,它可以解释打印任务中的命令并从这些命令中生成最终的页面。PostScript 经常被用做原始文件和打印机之间的中间层,比如一个文本文件或者一个图像文件,以及没有适合 PostScript 功能的特定打印机的最终格式。转换这些特定的打印任务,比如一个 ASCII 文本文件或者一个 JPEG 图像转换为 PostScript,然后再使用过滤器转换 PostScript 到非 PostScript 打印机所需要的最终光栅格式。 +许多可以打印图形的打印机,使用 Adobe PostScript 语言进行初始化。一个 PostScript 打印机有一个解释器引擎,它可以解释打印任务中的命令并从这些命令中生成最终的页面。PostScript 经常被用做原始文件(比如一个文本文件或者一个图像文件)和最终格式没有适合的 PostScript 功能的特定打印机之间的中间层。转换这些特定的打印任务,比如将一个 ASCII 文本文件或者一个 JPEG 图像转换为 PostScript,然后再使用过滤器转换 PostScript 到非 PostScript 打印机所需要的最终光栅格式。 -现在的便携式文档格式(PDF),它就是基于 PostScript 的,已经替换了传统的原始 PostScript。PDF 设计为与硬件和软件无关,它封装了要打印的页面的完整描述。你可以查看 PDF 文件,同时也可以打印它们。 +现在的便携式文档格式Portable Document Format(PDF),它就是基于 PostScript 的,已经替换了传统的原始 PostScript。PDF 设计为与硬件和软件无关,它封装了要打印的页面的完整描述。你可以查看 以及打印 PDF 文件。 ### 管理打印队列 -用户直接打印作业到一个名为打印队列的逻辑实体。在单用户系统中,一个打印队列和一个打印机通常是几乎相同的意思。但是,CUPS 允许系统对最终在一个远程系统上的打印,并不附属打印机到一个队列打印作业上,而是通过使用类,允许将打印作业重定向到该类第一个可用的打印机上。 +用户直接打印作业到一个名为打印队列print queue的逻辑实体。在单用户系统中,打印队列和打印机通常是几乎相同的意思。但是,CUPS 允许系统不用连接到一个打印机上,而最终在一个远程系统上的排队打印作业,并且通过使用分类,允许将定向到一个分类的打印作业在该分类第一个可用的打印机上打印。 -你可以检查和管理打印队列。对于 CUPS 来说,其中一些命令还是很新的。另外的一些是源于 LPD 的兼容命令,不过现在的一些选项通常是原始 LPD 打印系统选项的有限子集。 +你可以检查和管理打印队列。对于 CUPS 来说,其中一些命令实现了一些新操作。另外的一些是源于 LPD 的兼容命令,不过现在的一些选项通常是最初的 LPD 打印系统选项的有限子集。 -你可以使用 CUPS 的 `lpstat` 命令去检查队列,以了解打印系统。一些常见命令如下表 1。 - -###### 表 1. lpstat 命令的选项 -| 选项 | 作用 | -| -a | 显示打印机状态 | -| -c | 显示打印类 | -| -p | 显示打印状态:enabled 或者 disabled. | -| -s | 显示默认打印机、打印机和类。相当于 -d -c -v。**注意:为指定多个选项,这些选项必须像值一样分隔开。**| -| -s | 显示打印机和它们的设备。 | +你可以使用 CUPS 的 `lpstat` 命令去检查队列,以了解打印系统。一些常见选项如下表 1。 -你也可以使用 LPD 的 `lpc` 命令,它可以在 /usr/sbin 中找到,使用它的 `status` 选项。如果你不想指定打印机名字,将列出所有的队列。列表 1 展示了命令的一些示例。 +| 选项 | 作用 | +| --- | --- | +| `-a` | 显示打印机状态 | +| `-c` | 显示打印分类 | +| `-p` | 显示打印状态:`enabled` 或者 `disabled` | +| `-s` | 显示默认打印机、打印机和类。相当于 `-d -c -v`。**注意:要指定多个选项,这些选项必须像值一样分隔开。**| +| `-v` | 显示打印机和它们的设备。| + +*表 1. lpstat 命令的选项* + +你也可以使用 LPD 的 `lpc` 命令(它可以在 `/usr/sbin` 中找到)使用它的 `status` 选项。如果你不想指定打印机名字,将列出所有的队列。列表 1 展示了命令的一些示例。 -###### 列表 1. 显示可用打印队列 ``` [ian@atticf27 ~]$ lpstat -d system default destination: HL-2280DW @@ -77,11 +77,12 @@ HL-2280DW: ``` -这个示例展示了两台打印机 —— HL-2280DW 和 XP-610,和一个类 `anyprint`,它允许打印作业定向到这两台打印机中的第一个可用打印机。 +*列表 1. 显示可用打印队列* -在这个示例中,已经禁用了打印到 HL-2280DW 队列,但是打印是启用的,这样便于打印机脱机维护之前可以完成打印队列中的任务。无论队列是启用还是禁用,都可以使用 `cupsaccept` 和 `cupsreject` 命令来管理它们。你或许可能在 /usr/sbin 中找到这些命令,它们现在都是链接到新的命令上。同样,无论打印是启用还是禁用,你都可以使用 `cupsenable` 和 `cupsdisable` 命令来管理它们。在早期版本的 CUPS 中,这些被称为 `enable` 和 `disable`,它也许会与 bash shell 内置的 `enable` 混淆。列表 2 展示了如何去启用打印机 HL-2280DW 上的队列,不过它的打印还是禁止的。CUPS 的几个命令支持使用一个 `-r` 选项去提供一个动作的理由。这个理由会在你使用 `lpstat` 时显示,但是如果你使用的是 `lpc` 命令则不会显示它。 +这个示例展示了两台打印机 —— HL-2280DW 和 XP-610,和一个分类 `anyprint`,它允许打印作业定向到这两台打印机中的第一个可用打印机。 + +在这个示例中,已经禁用了打印到 HL-2280DW 队列,但是打印功能是启用的,这样便于将打印机脱机维护之前可以完成打印队列中的任务。启用还是禁用队列,可以使用 `cupsaccept` 和 `cupsreject` 命令来管理。以前它们叫做 `accept` 和 `reject`,你或许可能在 `/usr/sbin` 中找到这些命令,但它们现在都是符号链接到新的命令上了。同样,启用还是禁用打印,你可以使用 `cupsenable` 和 `cupsdisable` 命令来管理。在早期版本的 CUPS 中,这些被称为 `enable` 和 `disable`,它也许会与 bash shell 内置的 `enable` 混淆。列表 2 展示了如何去启用打印机 HL-2280DW 上的队列,而禁止它的打印。CUPS 的几个命令支持使用 `-r` 选项去提供一个该操作的理由。这个理由会在你使用 `lpstat` 时显示,但是如果你使用的是 `lpc` 命令则不会显示它。 -###### 列表 2. 启用队列和禁用打印 ``` [ian@atticf27 ~]$ lpstat -a -p HL-2280DW anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST @@ -100,16 +101,16 @@ printer XP-610 is idle. enabled since Thu 27 Apr 2017 05:53:59 PM EDT anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST HL-2280DW accepting requests since Mon 29 Jan 2018 04:03:50 PM EST XP-610 accepting requests since Thu 27 Apr 2017 05:53:59 PM EDT - ``` -注意:用户执行这些任务必须经过授权。它可能要求是 root 用户或者其它的授权用户。在 /etc/cups/cups-files.conf 中可以看到 SystemGroup 的条目,cups-files.conf 的 man 页面有更多授权用户组的信息。 +*列表 2. 启用队列和禁用打印* + +注意:用户执行这些任务必须经过授权。它可能要求是 root 用户或者其它的授权用户。在 `/etc/cups/cups-files.conf` 中可以看到 `SystemGroup` 的条目,`cups-files.conf` 的 man 页面有更多授权用户组的信息。 ### 管理用户打印作业 现在,你已经知道了一些如何去检查打印队列和类的方法,我将给你展示如何管理打印队列上的作业。你要做的第一件事是,如何找到一个特定打印机或者全部打印机上排队的任意作业。完成上述工作要使用 `lpq` 命令。如果没有指定任何选项,`lpq` 将显示默认打印机上的队列。使用 `-P` 选项和一个打印机名字将指定打印机,或者使用 `-a` 选项去指定所有的打印机,如下面的列表 3 所示。 -###### 列表 3. 使用 lpq 检查打印队列 ``` [pat@atticf27 ~]$ # As user pat (non-administrator) [pat@atticf27 ~]$ lpq @@ -132,16 +133,16 @@ Rank Owner Job File(s) Total Size 3rd pat 7 bitlib.C 6144 bytes 4th ian 8 .bashrc 1024 bytes 5th ian 9 .bashrc 1024 bytes - ``` -在这个示例中,共有五个作业,它们是 4、6、7、8、和 9,并且它是名为 HL-2280DW 的打印机的队列,而不是 XP-610 的。在这个示例中使用 `-P` 选项,可简单地显示那个打印机已经准备好,但是没有队列任务。注意,CUPS 的打印机命名,大小写是不敏感的。还要注意的是,用户 ian 提交了同样的作业两次,当一个作业第一次没有打印时,经常能看到用户的这种动作。 +*列表 3. 使用 lpq 检查打印队列* -一般情况下,你可能查看或者维护你自己的打印作业,但是,root 用户或者其它授权的用户通常会去管理其它打印作业。大多数 CUPS 命令都可以使用一个 `-E` 选项,对 CUPS 服务器与客户端之间的通讯进行加密。 +在这个示例中,共有五个作业,它们是 4、6、7、8、和 9,并且它是名为 HL-2280DW 的打印机的队列,而不是 XP-610 的。在这个示例中使用 `-P` 选项,可简单地显示哪个打印机已经准备好,但是没有队列任务。注意,CUPS 的打印机命名,是大小写不敏感的。还要注意的是,用户 ian 提交了同样的作业两次,当一个作业没有第一时间打印时,经常能看到用户的这种动作。 -使用 `lprm` 命令从队列中去删除 .bashrc 作业。如果不使用选项,将删除当前的作业。使用 `-` 选项,将删除全部的作业。要么就如列表 4 那样,指定一个要删除的作业列表。 +一般情况下,你可能会查看或者维护你自己的打印作业,但是,root 用户或者其它授权的用户通常会去管理其它打印作业。大多数 CUPS 命令都可以使用一个 `-E` 选项,对 CUPS 服务器与客户端之间的通讯进行加密。 + +使用 `lprm` 命令从队列中去删除一个 `.bashrc` 作业。如果不使用选项,将删除当前的作业。使用 `-` 选项,将删除全部的作业。要么就如列表 4 那样,指定一个要删除的作业列表。 -###### 列表 4. 使用 lprm 删除打印作业 ``` [[pat@atticf27 ~]$ # As user pat (non-administrator) [pat@atticf27 ~]$ lprm @@ -156,14 +157,14 @@ Rank Owner Job File(s) Total Size 2nd pat 6 bitlib.h 6144 bytes 3rd pat 7 bitlib.C 6144 bytes 4th ian 9 .bashrc 1024 bytes - ``` +*列表 4. 使用 lprm 删除打印作业* + 注意,用户 pat 不能删除队列中的第一个作业,因为它是用户 ian 的。但是,ian 可以删除他自己的 8 号作业。 另外的可以帮你操作打印队列中的作业的命令是 `lp`。使用它可以去修改作业属性,比如打印数量或者优先级。我们假设用户 ian 希望他的作业 9 在用户 pat 的作业之前打印,并且希望打印两份。作业优先级的默认值是 50,它的优先级范围从最低的 1 到最高的 100 之间。用户 ian 可以使用 `-i`、`-n`、以及 `-q` 选项去指定一个要修改的作业,而新的打印数量和优先级可以如下面的列表 5 所示的那样去修改。注意,使用 `-l` 选项的 `lpq` 命令可以提供更详细的输出。 -###### 列表 5. 使用 lp 去改变打印数量和优先级 ``` [ian@atticf27 ~]$ lpq HL-2280DW is not ready @@ -180,12 +181,12 @@ Rank Owner Job File(s) Total Size 2nd ian 4 permutation.C 6144 bytes 3rd pat 6 bitlib.h 6144 bytes 4th pat 7 bitlib.C 6144 bytes - ``` -最后,`lpmove` 命令可以允许一个作业从一个队列移动到另一个队列。例如,我们可能因为打印机 HL-2280DW 现在不能使用,而想去移动一个作业到另外的队列上。你可以指定一个作业编号,比如 9,或者你可以用一个队列名加一个连字符去限定它,比如,HL-2280DW-0。`lpmove` 命令的操作要求一个授权用户。列表 6 展示了如何去从一个队列移动作业到另外的队列,通过打印机和作业 ID 指定第一个,然后指定打印机的所有作业都移动到第二个队列。稍后我们可以去再次检查队列,其中一个作业已经在打印中了。 +*列表 5. 使用 lp 去改变打印数量和优先级* + +最后,`lpmove` 命令可以允许一个作业从一个队列移动到另一个队列。例如,我们可能因为打印机 HL-2280DW 现在不能使用,而想去移动一个作业到另外的队列上。你可以指定一个作业编号,比如 9,或者你可以用一个队列名加一个连字符去限定它,比如,HL-2280DW-0。`lpmove` 命令的操作要求是授权用户。列表 6 展示了如何去从一个队列移动作业到另外的队列,先是指定打印机和作业 ID 移动,然后是移动指定打印机的所有作业。稍后我们可以去再次检查队列,其中一个作业已经在打印中了。 -###### 列表 6. 使用 lpmove 移动作业到另外一个打印队列 ``` [ian@atticf27 ~]$ lpmove HL-2280DW-9 anyprint [ian@atticf27 ~]$ lpmove HL-2280DW xp-610 @@ -200,44 +201,46 @@ active ian 9 .bashrc 1024 bytes Rank Owner Job File(s) Total Size active pat 6 bitlib.h 6144 bytes 1st pat 7 bitlib.C 6144 bytes - ``` -如果你使用的是打印服务器而不是 CUPS,比如 LPD 或者 LPRng,大多数的队列管理功能是由 `lpc` 命令的子命令来处理的。例如,你可以使用 `lpc topq` 去移动一个作业到队列的顶端。其它的 `lpc` 子命令包括 `disable`、`down`、`enable`、`hold`、`move`、`redirect`、`release`、和 `start`。这些子命令在 CUPS 的兼容命令中没有实现。 +*列表 6. 使用 lpmove 移动作业到另外一个打印队列* + +如果你使用的是 CUPS 之外的打印服务器,比如 LPD 或者 LPRng,大多数的队列管理功能是由 `lpc` 命令的子命令来处理的。例如,你可以使用 `lpc topq` 去移动一个作业到队列的顶端。其它的 `lpc` 子命令包括 `disable`、`down`、`enable`、`hold`、`move`、`redirect`、`release`、和 `start`。这些子命令在 CUPS 的兼容命令中没有实现。 #### 打印文件 如何去打印创建的作业?大多数图形界面程序都提供了一个打印方法,通常是 **文件** 菜单下面的选项。这些程序为选择打印机、设置页边距、彩色或者黑白打印、打印数量、选择每张纸打印的页面数(每张纸打印两个页面,通常用于讲义)等等,都提供了图形化的工具。现在,我将为你展示如何使用命令行工具去管理这些功能,然后和图形化实现进行比较。 -打印文件最简单的方法是使用 `lpr` 命令,然后提供一个文件名字。这将在默认打印机上打印这个文件。`lp` 命令不仅可以打印文件,也可以修改打印作业。列表 7 展示了使用这个命令的一个简单示例。注意,`lpr` 会静默处理这个作业,但是 `lp` 会显示处理后的作业的 ID。 +打印文件最简单的方法是使用 `lpr` 命令,然后提供一个文件名字。这将在默认打印机上打印这个文件。而 `lp` 命令不仅可以打印文件,也可以修改打印作业。列表 7 展示了使用这个命令的一个简单示例。注意,`lpr` 会静默处理这个作业,但是 `lp` 会显示处理后的作业的 ID。 -###### 列表 7. 使用 lpr 和 lp 打印 ``` [ian@atticf27 ~]$ echo "Print this text" > printexample.txt [ian@atticf27 ~]$ lpr printexample.txt [ian@atticf27 ~]$ lp printexample.txt request id is HL-2280DW-12 (1 file(s)) - ``` +*列表 7. 使用 lpr 和 lp 打印* + 表 2 展示了 `lpr` 上你可以使用的一些选项。注意, `lp` 的选项和 `lpr` 的很类似,但是名字可能不一样;例如,`-#` 在 `lpr` 上是相当于 `lp` 的 `-n` 选项。查看 man 页面了解更多的信息。 -###### 表 2. lpr 的选项 -| 选项 | 作用 | -| -C, -J, or -T | 设置一个作业名字。 | -| -P | 选择一个指定的打印机。 | -| -# | 指定打印数量。注意它与 lp 命令的 -n 有点差别。| -| -m | 在作业完成时发送电子邮件。 | -| -l | 表示打印文件已经为打印做好格式准备。相当于 -o raw。 | -| -o | 设置一个作业选项。 | -| -p | 格式化一个带有阴影标题的文本文件。相关于 -o prettyprint。 | -| -q | 暂缓(或排队)最后的打印作业。 | -| -r | 在文件进入打印池之后,删除文件。 | +| 选项 | 作用 | +|---|---| +| `-C`, `-J` 或 `-T` | 设置一个作业名字。 | +| `-P` | 选择一个指定的打印机。| +| `-#` | 指定打印数量。注意这不同于 `lp` 命令的 `-n` 选项。| +| `-m` | 在作业完成时发送电子邮件。| +| `-l` | 表示打印文件已经为打印做好格式准备。相当于 `-o raw`。 | +| `-o` | 设置一个作业选项。| +| `-p` | 格式化一个带有阴影标题的文本文件。相关于 `-o prettyprint`。| +| `-q` | 暂缓(或排队)后面的打印作业。| +| `-r` | 在文件进入打印池之后,删除文件。 | + +*表 2. lpr 的选项* 列表 8 展示了一些选项。我要求打印之后给我发确认电子邮件,那个作业被暂缓执行,并且在打印之后删除文件。 -###### 列表 8. 使用 lpr 打印 ``` [ian@atticf27 ~]$ lpr -P HL-2280DW -J "Ian's text file" -#2 -m -p -q -r printexample.txt [[ian@atticf27 ~]$ lpq -l @@ -248,20 +251,20 @@ ian: 1st [job 13 localhost] 2 copies of Ian's text file 1024 bytes [ian@atticf27 ~]$ ls printexample.txt ls: cannot access 'printexample.txt': No such file or directory - ``` -我现在有一个在 HL-2280DW 打印队列上暂缓执行的作业。怎么做到这样?`lp` 命令有一个选项可以暂缓或者投放作业,使用 `-H` 选项是使用各种值。列表 9 展示了如何投放被暂缓的作业。检查 `lp` 命令的 man 页面了解其它选项的信息。 +*列表 8. 使用 lpr 打印* + +我现在有一个在 HL-2280DW 打印队列上暂缓执行的作业。然后怎么做?`lp` 命令可以通过使用 `-H` 的各种选项来暂缓或者投放作业。列表 9 展示了如何投放被暂缓的作业。查看 `lp` 命令的 man 页面了解其它选项的信息。 -###### 列表 9. 重启一个暂缓的打印作业 ``` [ian@atticf27 ~]$ lp -i 13 -H resume - ``` +*列表 9. 重启一个暂缓的打印作业* + 并不是所有的可用打印机都支持相同的选项集。使用 `lpoptions` 命令去查看一个打印机的常用选项。添加 `-l` 选项去显示打印机专用的选项。列表 10 展示了两个示例。许多常见的选项涉及到人像/风景打印、页面大小和输出在纸张上的布局。详细信息查看 man 页面。 -###### 列表 10. 检查打印机选项 ``` [ian@atticf27 ~]$ lpoptions -p HL-2280DW copies=1 device-uri=dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ @@ -296,21 +299,22 @@ StpImageType/Image Type: None Text Graphics *TextGraphics Photo LineArt ``` -大多数的 GUI 应用程序有一个打印对话框,通常你可以使用 **文件 >打印** 菜单去选择它。图 1 展示了在 GIMP 中的一个示例,GIMP 是一个图像处理程序。 +*列表 10. 检查打印机选项* -###### 图 1. 在 GIMP 中打印 +大多数的 GUI 应用程序有一个打印对话框,通常你可以使用 **文件 >打印** 菜单去选择它。图 1 展示了在 GIMP 中的一个示例,GIMP 是一个图像处理程序。 ![Printing from the GIMP][3] -到目前为止,我们所有的命令都是隐式指向到本地的 CUPS 打印服务器上。你也可以通过指定 `-h` 选项和一个端口号(如果不是 CUPS 的默认端口号 631的话)将打印转向到另外一个系统上的服务器。 +*图 1. 在 GIMP 中打印* + +到目前为止,我们所有的命令都是隐式指向到本地的 CUPS 打印服务器上。你也可以通过指定 `-h` 选项和一个端口号(如果不是 CUPS 的默认端口号 631 的话)将打印转向到另外一个系统上的服务器。 ### CUPS 和 CUPS 服务器 -CUPS 打印系统的核心是 `cupsd` 打印服务器,它是一个运行的守护进程。CUPS 配置文件一般位于 /etc/cups/cupsd.conf。/etc/cups 目录也有与 CUPS 相关的其它的配置文件。CUPS 一般在系统初始化期间启动,根据你的发行版不同,它也可能通过位于 /etc/rc.d/init.d 或者 /etc/init.d 目录中的 CUPS 脚本来控制。对于 最新使用 systemd 来初始化的系统,CUPS 服务脚本可能在 /usr/lib/systemd/system/cups.service 中。和大多数使用脚本的服务一样,你可以停止、启动、或者重启守护程序。查看我们的教程:[学习 Linux,101:运行级别、引导目标、关闭、和重启动][4],了解使用初始化脚本的更多信息。 +CUPS 打印系统的核心是 `cupsd` 打印服务器,它是一个运行的守护进程。CUPS 配置文件一般位于 `/etc/cups/cupsd.conf`。`/etc/cups` 目录也有与 CUPS 相关的其它的配置文件。CUPS 一般在系统初始化期间启动,根据你的发行版不同,它也可能通过位于 `/etc/rc.d/init.d` 或者 `/etc/init.d` 目录中的 CUPS 脚本来控制。对于 最新使用 systemd 来初始化的系统,CUPS 服务脚本可能在 `/usr/lib/systemd/system/cups.service` 中。和大多数使用脚本的服务一样,你可以停止、启动、或者重启守护程序。查看我们的教程:[学习 Linux,101:运行级别、引导目标、关闭、和重启动][4],了解使用初始化脚本的更多信息。 -配置文件 /etc/cups/cupsd.conf 包含管理一些事情的参数,比如访问打印系统、是否允许远程打印、本地打印池文件等等。在一些系统上,一个辅助的部分单独描述打印队列,它一般是由配置工具自动生成的。列表 11 展示了一个默认的 cupsd.conf 文件中的一些条目。注意,注释是以 # 字符开头的。默认值通常以注释的方式显示,并且可以通过删除前面的 # 字符去改变默认值。 +配置文件 `/etc/cups/cupsd.conf` 包含一些管理参数,比如访问打印系统、是否允许远程打印、本地打印池文件等等。在一些系统上,第二部分单独描述了打印队列,它一般是由配置工具自动生成的。列表 11 展示了一个默认的 `cupsd.conf` 文件中的一些条目。注意,注释是以 `#` 字符开头的。默认值通常以注释的方式显示,并且可以通过删除前面的 `#` 字符去改变默认值。 -###### Listing 11. 默认的 /etc/cups/cupsd.conf 文件的部分内容 ``` # Only listen for connections from the local machine. Listen localhost:631 @@ -338,12 +342,12 @@ WebInterface Yes Order deny,allow - ``` -能够允许在 cupsd.conf 中使用的文件、目录、和用户配置命令,现在都存储在作为替代的 cups-files.conf 中。这是为了防范某些类型的提权攻击。列表 12 展示了 cups-files.conf 文件中的一些条目。注意,正如在文件层次结构标准(FHS)中所期望的那样,打印池文件默认保存在文件系统的 /var/spool 目录中。查看 man 页面了解 cupsd.conf 和 cups-files.conf 配置文件的更多信息。 +*列表 11. 默认的 /etc/cups/cupsd.conf 文件的部分内容* + +可以用在 `cupsd.conf` 中使用的文件、目录、和用户配置命令,现在都存储在作为替代的 `cups-files.conf` 中。这是为了防范某些类型的提权攻击。列表 12 展示了 `cups-files.conf` 文件中的一些条目。注意,正如在文件层次结构标准(FHS)中所期望的那样,打印池文件默认保存在文件系统的 `/var/spool` 目录中。查看 man 页面了解 `cupsd.conf` 和 `cups-files.conf` 配置文件的更多信息。 -###### 列表 12. 默认的 /etc/cups/cups-files.conf 配置文件的部分内容 ``` # Location of the file listing all of the local printers... #Printcap /etc/printcap @@ -364,12 +368,13 @@ WebInterface Yes # Location of other configuration files... #ServerRoot /etc/cups - ``` -列表 12 引用了 /etc/printcap 文件。这是 LPD 打印服务器的配置文件的名字,并且一些应用程序仍然使用它去确定可用的打印机和它们的属性。它通常是在 CUPS 系统上自动生成的,因此,你可能没有必要去修改它。但是,如果你在诊断用户打印问题,你可能需要去检查它。列表 13 展示了一个示例。 +*列表 12. 默认的 /etc/cups/cups-files.conf 配置文件的部分内容* + + +列表 12 提及了 `/etc/printcap` 文件。这是 LPD 打印服务器的配置文件的名字,并且一些应用程序仍然使用它去确定可用的打印机和它们的属性。它通常是在 CUPS 系统上自动生成的,因此,你可能没有必要去修改它。但是,如果你在诊断用户打印问题,你可能需要去检查它。列表 13 展示了一个示例。 -###### 列表 13. 自动生成的 /etc/printcap ``` # This file was automatically generated by cupsd(8) from the # /etc/cups/printers.conf file. All changes to this file @@ -377,18 +382,19 @@ WebInterface Yes HL-2280DW|Brother HL-2280DW:rm=atticf27:rp=HL-2280DW: anyprint|Any available printer:rm=atticf27:rp=anyprint: XP-610|EPSON XP-610 Series:rm=atticf27:rp=XP-610: - ``` -这个文件中的每一行都有一个打印机名字、打印机描述,远程机器(rm)的名字、以及那个远程机器上的远程打印机(rp)。老的 /etc/printcap 文件也描述了打印机的能力。 +*列表 13. 自动生成的 /etc/printcap* + +这个文件中的每一行都有一个打印机名字、打印机描述,远程机器(`rm`)的名字、以及那个远程机器上的远程打印机(`rp`)。老的 `/etc/printcap` 文件也描述了打印机的能力。 #### 文件转换过滤器 -你可以使用 CUPS 打印许多类型的文件,包括明文的文本文件、PDF、PostScript、和各种格式的图像文件,你只需要提供要打印的文件名,除此之外你再无需向 `lpr` 或 `lp` 命令提供更多的信息。这个神奇的壮举是通过使用过滤器来实现的。实际上,这些年来最流行的过滤器就命名为 magicfilter。 +你可以使用 CUPS 打印许多类型的文件,包括明文的文本文件、PDF、PostScript、和各种格式的图像文件,你只需要提供要打印的文件名,除此之外你再无需向 `lpr` 或 `lp` 命令提供更多的信息。这个神奇的壮举是通过使用过滤器来实现的。实际上,这些年来最流行的过滤器就就叫做 magicfilter(神奇的过滤器)。 -当打印一个文件时,CUPS 使用多用途因特网邮件扩展(MIME)类型去决定合适的转换过滤器。其它的打印包可能使用由 `file` 命令使用的神奇数字机制。关于 `file` 或者 `magic` 的更多信息可以查看它们的 man 页面。 +当打印一个文件时,CUPS 使用多用途因特网邮件扩展(MIME)类型去决定合适的转换过滤器。其它的打印数据包可能使用由 `file` 命令使用的神奇数字机制。关于 `file` 或者神奇数的更多信息可以查看它们的 man 页面。 -输入文件被过滤器转换成中间层的光栅格式或者 PostScript 格式。一些作业信息,比如打印数量也会被添加进去。数据最终通过一个 bechend 发送到目标打印机。还有一些可以用手动过滤的输入文件的过滤器。你可以通过这些过滤器获得特殊格式的结果,或者去处理一些 CUPS 原生并不支持的文件格式。 +输入文件被过滤器转换成中间层的光栅格式或者 PostScript 格式。一些作业信息,比如打印数量也会被添加进去。数据最终通过一个后端发送到目标打印机。还有一些可以用手动过滤的输入文件的过滤器(如 a2ps 或 dvips)。你可以通过这些过滤器获得特殊格式的结果,或者去处理一些 CUPS 原生并不支持的文件格式。 #### 添加打印机 @@ -401,25 +407,22 @@ CUPS 支持多种打印机,包括: * 使用 NCP 的 Novell 打印机 * HP Jetdirect 打印机 - - 当系统启动或者设备连接时,现在的大多数系统都会尝试自动检测和自动配置本地硬件。同样,许多网络打印机也可以被自动检测到。使用 CUPS 的 web 管理工具( 或者 )去搜索或添加打印机。许多发行版都包含它们自己的配置工具,比如,在 SUSE 系统上的 YaST。图 2 展示了使用 localhost:631 的 CUPS 界面,图 3 展示了 Fedora 27 上的 GNOME 打印机设置对话框。 -###### 图 2. 使用 CUPS 的 web 界面 - ![Using the CUPS web interface][5] -###### 图 3. Fedora 27 上的打印机设置 +*图 2. 使用 CUPS 的 web 界面* ![Using printer settings on Fedora 27][6] +*图 3. Fedora 27 上的打印机设置* + 你也可以从命令行配置打印机。在配置打印机之前,你需要一些关于打印机和它的连接方式的基本信息。如果是一个远程系统,你还需要一个用户 ID 和密码。 -你需要去知道你的打印机使用什么样的驱动程序。不是所有的打印机都支持 Linux,有些打印机在 Linux 上压根就不能使用,或者功能受限。你可以去 OpenPrinting.org(查看相关主题)去查看是否有你的特定的打印机的驱动程序。`lpinfo` 命令也可以帮你识别有效的设备类型和驱动程序。使用 `-v` 选项去列出支持的设备,使用 `-m` 选项去列出驱动程序,如列表 14 所示。 +你需要去知道你的打印机使用什么样的驱动程序。不是所有的打印机都支持 Linux,有些打印机在 Linux 上压根就不能使用,或者功能受限。你可以去 OpenPrinting.org 去查看是否有你的特定的打印机的驱动程序。`lpinfo` 命令也可以帮你识别有效的设备类型和驱动程序。使用 `-v` 选项去列出支持的设备,使用 `-m` 选项去列出驱动程序,如列表 14 所示。 -###### 列表 14. 可用的打印机驱动程序 ``` [ian@atticf27 ~]$ lpinfo -m | grep -i xp-610 lsb/usr/Epson/epson-inkjet-printer-escpr/Epson-XP-610_Series-epson-escpr-en.ppd.gz @@ -443,16 +446,16 @@ network dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ network dnssd://EPSON%20XP-610%20Series._ipp._tcp.local/?uuid=cfe92100-67c4-11d4-a45f-ac18266c48aa network lpd://BRN001BA98A1891/BINARY_P1 network lpd://192.168.1.38:515/PASSTHRU - ``` -Epson-XP-610_Series-epson-escpr-en.ppd.gz 驱动程序在我的系统上位于 /usr/share/ppd/Epson/epson-inkjet-printer-escpr/ 目录中。 +*列表 14. 可用的打印机驱动程序* -如果你找不到驱动程序,你可以到打印机生产商的网站看看,说不上会有专用的驱动程序。例如,在写这篇文章的时候,Brother 就有一个我的 HL-2280DW 打印机的驱动程序,但是,这个驱动程序在 OpenPrinting.org 上还没有列出来。 +这个 Epson-XP-610_Series-epson-escpr-en.ppd.gz 驱动程序在我的系统上位于 `/usr/share/ppd/Epson/epson-inkjet-printer-escpr/` 目录中。 + +如果你找不到驱动程序,你可以到打印机生产商的网站看看,说不定会有专用的驱动程序。例如,在写这篇文章的时候,Brother 就有一个我的 HL-2280DW 打印机的驱动程序,但是,这个驱动程序在 OpenPrinting.org 上还没有列出来。 如果你收集齐了基本信息,你可以如列表 15 所示的那样,使用 `lpadmin` 命令去配置打印机。为此,我将为我的 HL-2280DW 打印机创建另外一个实例,以便于双面打印。 -###### 列表 15. 配置一台打印机 ``` [ian@atticf27 ~]$ lpinfo -m | grep -i "hl.*2280" HL2280DW.ppd Brother HL2280DW for CUPS @@ -465,16 +468,16 @@ anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST HL-2280DW accepting requests since Tue 30 Jan 2018 10:56:10 AM EST HL-2280DW-duplex accepting requests since Wed 31 Jan 2018 11:41:16 AM EST HXP-610 accepting requests since Mon 29 Jan 2018 10:34:49 PM EST - ``` -你可以使用带 `-c` 选项的 `lpadmin` 命令去创建一个仅用于双面打印的新类,而不用为了双面打印去创建一个打印机的副本。 +*列表 15. 配置一台打印机* + +你可以使用带 `-c` 选项的 `lpadmin` 命令去创建一个仅用于双面打印的新分类,而不用为了双面打印去创建一个打印机的副本。 如果你需要删除一台打印机,使用带 `-x` 选项的 `lpadmin` 命令。 列表 16 展示了如何去删除打印机和创建一个替代类。 -###### 列表 16. 删除一个打印机和创建一个类 ``` [ian@atticf27 ~]$ lpadmin -x HL-2280DW-duplex [ian@atticf27 ~]$ lpadmin -p HL-2280DW -c duplex -E -D "Duplex printing" -o sides=two-sided-long-edge @@ -485,34 +488,33 @@ anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST duplex accepting requests since Wed 31 Jan 2018 12:12:05 PM EST HL-2280DW accepting requests since Wed 31 Jan 2018 11:51:16 AM EST XP-610 accepting requests since Mon 29 Jan 2018 10:34:49 PM EST - ``` +*列表 16. 删除一个打印机和创建一个类* + 你也可以使用 `lpadmin` 或者 `lpoptions` 命令去设置各种打印机选项。详细信息请查看 man 页面。 ### 排错 -如果你有一个打印问题,尝试下列的提示: +如果你有打印问题,尝试下列的提示: * 确保 CUPS 服务器正在运行。你可以使用 `lpstat` 命令,如果它不能连接到 cupsd 守护程序,它将会报告一个错误。或者,你可以使用 `ps -ef` 命令在输出中去检查是否有 cupsd。 - * 如果你尝试为打印去排队一个作业,而得到一个错误信息,指示打印机不接受这个作业,你可以使用 `lpstat -a` 或者 `lpc status` 去检查那个打印机可接受的作业。 + * 如果你试着排队一个打印作业而得到一个错误信息,指示打印机不接受这个作业,你可以使用 `lpstat -a` 或者 `lpc status` 去检查那个打印机是否接受作业。 * 如果一个队列中的作业没有打印,使用 `lpstat -p` 或 `lpc status` 去检查那个打印机是否接受作业。如前面所讨论的那样,你可能需要将这个作业移动到其它的打印机。 * 如果这个打印机是远程的,检查它在远程系统上是否存在,并且是可操作的。 * 检查配置文件,确保特定的用户或者远程系统允许在这个打印机上打印。 * 确保防火墙允许远程打印请求,是否允许从其它系统到你的系统,或者从你的系统到其它系统的数据包通讯。 * 验证是否有正确的驱动程序。 - - -正如你所见,打印涉及到你的系统中的几个组件,甚至还有网络。在本教程中,基于篇幅的考虑,我们仅为诊断给你提供了几个着手点。大多数的 CUPS 系统也有实现我们所讨论的命令行功能的图形界面。一般情况下,这个界面是从本地主机使用浏览器指向 631 端口()来访问的,如前面的图 2 所示。 +正如你所见,打印涉及到你的系统中的几个组件,甚至还有网络。在本教程中,基于篇幅的考虑,我们仅能给你的诊断提供了几个着手点。大多数的 CUPS 系统也有实现我们所讨论的命令行功能的图形界面。一般情况下,这个界面是从本地主机使用浏览器指向 631 端口()来访问的,如前面的图 2 所示。 你可以通过将 CUPS 运行在前台而不是做为一个守护进程来诊断它的问题。如果有需要,你也可以通过这种方式去测试替代的配置文件。运行 `cupsd -h` 获得更多信息,或者查看 man 页面。 -CUPS 也管理一个访问日志和错误日志。你可以在 cupsd.conf 中使用 LogLevel 语句来改变日志级别。默认情况下,日志是保存在 /var/log/cups 目录。它们可以在浏览器界面()下,从 **Administration** 选项卡中查看。使用不带任何选项的 `cupsctl` 命令可以显示日志选项。也可以编辑 cupsd.conf 或者使用 `cupsctl` 去调整各种日志参数。查看 `cupsctl` 命令的 man 页面了解更多信息。 +CUPS 也带有一个访问日志和错误日志。你可以在 `cupsd.conf` 中使用 `LogLevel` 语句来改变日志级别。默认情况下,日志是保存在 `/var/log/cups` 目录。它们可以在浏览器界面()下,从 **Administration** 选项卡中查看。使用不带任何选项的 `cupsctl` 命令可以显示日志选项。也可以编辑 `cupsd.conf` 或者使用 `cupsctl` 去调整各种日志参数。查看 `cupsctl` 命令的 man 页面了解更多信息。 在 Ubuntu 的 Wiki 页面上的 [调试打印问题][7] 页面也是一个非常好的学习的地方。 -它包含了打印和 CUPS 的介绍。 +这就是关于打印和 CUPS 的介绍。 -------------------------------------------------------------------------------- @@ -520,7 +522,7 @@ via: https://www.ibm.com/developerworks/library/l-lpic1-108-4/index.html 作者:[Ian Shields][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180206 Programming in Color with ncurses.md b/published/201804/20180206 Programming in Color with ncurses.md similarity index 62% rename from translated/tech/20180206 Programming in Color with ncurses.md rename to published/201804/20180206 Programming in Color with ncurses.md index 18960de398..b2ab9d273f 100755 --- a/translated/tech/20180206 Programming in Color with ncurses.md +++ b/published/201804/20180206 Programming in Color with ncurses.md @@ -1,103 +1,92 @@ -使用ncurses进行颜色编程 +使用 ncurses 进行颜色编程 ====== -在我的使用ncurses库进行编程的系列文章的[第一篇][1]和[第二篇][2]中,我已经介绍了一些curses的函数来在屏幕上作画、从屏幕上查询和从键盘读取字符。为了搞清楚这些函数,我使用curses来利用简单字符绘制游戏地图和玩家字符创建了一个简单的冒险游戏。在这篇紧接着的文章里,我展示了如何为你的curses程序添加颜色。 -在屏幕上绘图一切都挺好的,但是如果只有黑底白字的文本,你的程序可能看起来很无趣。颜色可以帮助传递更多的信息。举个例子,如果你的程序需要报告(执行)成功或者(执行)失败时。在这样的情况下你可以使用绿色或者红色来帮助强调输出。或者,你只是简单地想要“潮艺”一下给你的程序来让它看起来更美观。 +![](https://www.linuxjournal.com/sites/default/files/styles/850x500/public/nodeimage/story/quest-color-1.png?itok=lOK4ldl6) -在这篇文章中,我用一个简单的例子来展示通过curses函数进行颜色操作。在我先前的文章中,我写了一个允许你在一个粗糙绘制的地图上移动玩家字符的初级冒险类游戏。但是那里面的地图完全是白色和黑色的文本,通过形状来表明是水(~)或者山(^)。所以,让我们将游戏更新到使用颜色(的版本)吧。 +> Jim 给他的终端冒险游戏添加了颜色,演示了如何用 curses 操纵颜色。 + +在我的使用 ncurses 库进行编程的系列文章的[第一篇][1]和[第二篇][2]中,我已经介绍了一些 curses 函数来在屏幕上作画、从屏幕上查询和从键盘读取字符。为了搞清楚这些函数,我使用 curses 来利用简单字符绘制游戏地图和玩家角色,创建了一个简单的冒险游戏。在这篇紧接着的文章里,我展示了如何为你的 curses 程序添加颜色。 + +在屏幕上绘图一切都挺好的,但是如果只有黑底白字的文本,你的程序可能看起来很无趣。颜色可以帮助传递更多的信息。举个例子,如果你的程序需要报告执行成功或者执行失败时。在这样的情况下你可以使用绿色或者红色来帮助强调输出。或者,你只是简单地想要“潮艺”一下给你的程序来让它看起来更美观。 + +在这篇文章中,我用一个简单的例子来展示通过 curses 函数进行颜色操作。在我先前的文章中,我写了一个可以让你在一个粗糙绘制的地图上移动玩家角色的初级冒险类游戏。但是那里面的地图完全是白色和黑色的文本,通过形状来表明是水(`~`)或者山(`^`)。所以,让我们将游戏更新到使用颜色的版本吧。 ### 颜色要素 -在你可以使用颜色之前,你的程序得要知道它是否可以依靠终端正确地显示颜色。在现代操作系统上,此处应该永远为true。但是在经典的计算机上,一些终端是单色的,例如令人尊敬的VT52和VT100终端,一般(它们)提供黑底白色或者黑底绿色的文本。 +在你可以使用颜色之前,你的程序需要知道它是否可以依靠终端正确地显示颜色。在现代操作系统上,此处应该永远为true。但是在经典的计算机上,一些终端是单色的,例如古老的 VT52 和 VT100 终端,一般它们提供黑底白色或者黑底绿色的文本。 -可以使用has_colors()函数查询终端的颜色功能。这个函数将会在终端可以显示颜色的时候返回true,否则将会返回false。这个函数一般用于if块的开头,就像这样: +可以使用 `has_colors()` 函数查询终端的颜色功能。这个函数将会在终端可以显示颜色的时候返回 `true`,否则将会返回 `false`。这个函数一般用于 `if` 块的开头,就像这样: ``` - if (has_colors() == FALSE) { endwin(); printf("Your terminal does not support color\n"); exit(1); } - ``` -在知道终端可以显示颜色之后,你可以使用start_color()函数来设置curses使用颜色。现在是时候定义程序将要使用的颜色了。 +在知道终端可以显示颜色之后,你可以使用 `start_color()` 函数来设置 curses 使用颜色。现在是时候定义程序将要使用的颜色了。 -在curses中,你应该按对定义颜色:一个前景色放在一个背景色上。这样允许curses一次性设置两个颜色属性,这也是一般你想要使用的方式。通过init_pair()函数可以定义一个前景色和背景色并关联到索引数字来设置颜色对。大致语法如下: +在 curses 中,你应该按对定义颜色:一个前景色放在一个背景色上。这样允许 curses 一次性设置两个颜色属性,这也是一般你想要使用的方式。通过 `init_pair()` 函数可以定义一个前景色和背景色并关联到索引数字来设置颜色对。大致语法如下: ``` - init_pair(index, foreground, background); - ``` 控制台支持八种基础的颜色:黑色、红色、绿色、黄色、蓝色、品红色、青色和白色。这些颜色通过下面的名称为你定义好了: -* COLOR_BLACK - -* COLOR_RED - -* COLOR_GREEN - -* COLOR_YELLOW - -* COLOR_BLUE - -* COLOR_MAGENTA - -* COLOR_CYAN - -* COLOR_WHITE +* `COLOR_BLACK` +* `COLOR_RED` +* `COLOR_GREEN` +* `COLOR_YELLOW` +* `COLOR_BLUE` +* `COLOR_MAGENTA` +* `COLOR_CYAN` +* `COLOR_WHITE` ### 应用颜色 -在我的冒险游戏中,我想要让草地呈现绿色而玩家的足迹变成不易察觉的绿底黄色点迹。水应该是蓝色,那些(表示波浪的)腭化符号应该是近似青色的。我想让山是灰色的,但是我可以用白底黑色文本做一个可用的折中方案。(译注:意为终端预设的颜色没有灰色,使用白底黑色文本做一个折中方案)为了让玩家的字符更易见,我想要使用一个刺目的品红底红色设计。我可以像这样定义这些颜色对: +在我的冒险游戏中,我想要让草地呈现绿色而玩家的足迹变成不易察觉的绿底黄色点迹。水应该是蓝色,那些表示波浪的 `~` 符号应该是近似青色的。我想让山(`^`)是灰色的,但是我可以用白底黑色文本做一个可用的折中方案。(LCTT 译注:意为终端预设的颜色没有灰色,使用白底黑色文本做一个折中方案)为了让玩家的角色更易见,我想要使用一个刺目的品红底红色设计。我可以像这样定义这些颜色对: ``` - start_color(); init_pair(1, COLOR_YELLOW, COLOR_GREEN); init_pair(2, COLOR_CYAN, COLOR_BLUE); init_pair(3, COLOR_BLACK, COLOR_WHITE); init_pair(4, COLOR_RED, COLOR_MAGENTA); - ``` 为了让颜色对更容易记忆,我的程序中定义了一些符号常量: -``` +``` #define GRASS_PAIR 1 #define EMPTY_PAIR 1 #define WATER_PAIR 2 #define MOUNTAIN_PAIR 3 #define PLAYER_PAIR 4 - ``` 有了这些常量,我的颜色定义就变成了: -``` +``` start_color(); init_pair(GRASS_PAIR, COLOR_YELLOW, COLOR_GREEN); init_pair(WATER_PAIR, COLOR_CYAN, COLOR_BLUE); init_pair(MOUNTAIN_PAIR, COLOR_BLACK, COLOR_WHITE); init_pair(PLAYER_PAIR, COLOR_RED, COLOR_MAGENTA); - ``` -在任何时候你想要使用颜色显示文本,你只需要告诉curses设置那种颜色属性。为了更好的编程实践,你同样应该在你完成了颜色使用的时候告诉curses取消颜色组合。为了设置颜色,应该在调用像mvaddch()这样的函数之前使用attron(),然后通过attroff()关闭颜色属性。例如,在我绘制玩家的字符的时候,我应该这样做: -``` +在任何时候你想要使用颜色显示文本,你只需要告诉 curses 设置哪种颜色属性。为了更好的编程实践,你同样应该在你完成了颜色使用的时候告诉 curses 取消颜色组合。为了设置颜色,应该在调用像 `mvaddch()` 这样的函数之前使用`attron()`,然后通过 `attroff()` 关闭颜色属性。例如,在我绘制玩家角色的时候,我应该这样做: +``` attron(COLOR_PAIR(PLAYER_PAIR)); mvaddch(y, x, PLAYER); attroff(COLOR_PAIR(PLAYER_PAIR)); - ``` -记住将颜色应用到你的程序添加了不可见的改变到你如何查询屏幕。一般来讲,由mvinch()函数返回的值是**没有**带颜色属性的类型chtype,这个值基本上是一个整型值也可以就当作整型值来用。但是,由于(使用)颜色添加了额外的属性到屏幕上的字符上,所以chtype按照扩展的位模式携带了额外的颜色信息。一旦你使用mvinch(),返回值将会包含这些额外的颜色值。为了只提取**文本**值,例如在is_move_okay()函数中,你需要和A_CHARTEXT做&位运算: -``` +记住将颜色应用到你的程序对你如何查询屏幕有一些微妙的影响。一般来讲,由 `mvinch()` 函数返回的值是**没有**带颜色属性的类型 `chtype`,这个值基本上是一个整型值,也可以当作整型值来用。但是,由于使用颜色添加了额外的属性到屏幕上的字符上,所以 `chtype` 按照扩展的位模式携带了额外的颜色信息。一旦你使用 `mvinch()`,返回值将会包含这些额外的颜色值。为了只提取**文本**值,例如在 `is_move_okay()` 函数中,你需要和 `A_CHARTEXT` 做 `&` 位运算: +``` int is_move_okay(int y, int x) { int testch; @@ -108,16 +97,15 @@ int is_move_okay(int y, int x) return (((testch & A_CHARTEXT) == GRASS) || ((testch & A_CHARTEXT) == EMPTY)); } - ``` 通过这些修改,我可以用颜色更新这个冒险游戏: -``` +``` /* quest.c */ -#include -#include +#include +#include #define GRASS ' ' #define EMPTY '.' @@ -280,12 +268,11 @@ void draw_map(void) } attroff(COLOR_PAIR(WATER_PAIR)); } - ``` -你可能不能认出所有为了在冒险游戏里面支持颜色需要的修改,除非你目光敏锐。diff工具展示了所有为了支持颜色而添加的函数或者修改的代码: -``` +你可能不能认出所有为了在冒险游戏里面支持颜色需要的修改,除非你目光敏锐。`diff` 工具展示了所有为了支持颜色而添加的函数或者修改的代码: +``` $ diff quest-color/quest.c quest/quest.c 12,17d11 < #define GRASS_PAIR 1 @@ -350,28 +337,27 @@ $ diff quest-color/quest.c quest/quest.c < attron(COLOR_PAIR(WATER_PAIR)); 164d125 < attroff(COLOR_PAIR(WATER_PAIR)); - ``` ### 开始玩吧--现在有颜色了 -程序现在有了更舒服的颜色设计了,更匹配起初的桌游地图,有绿地、蓝色的湖和壮观的灰色山峰。英雄穿着红色的制服十分夺目。 +程序现在有了更舒服的颜色设计了,更匹配原来的桌游地图,有绿色的地、蓝色的湖和壮观的灰色山峰。英雄穿着红色的制服十分夺目。 ![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-map_0.jpg) -图 1\. 一个简单的带湖和山的桌游地图 +*图 1. 一个简单的带湖和山的桌游地图* ![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-color-start.png) -图 2\.玩家站在左下角 +*图 2. 玩家站在左下角* ![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-color-1.png) -图 3\. 玩家可以在游戏区域移动,比如围绕湖,通过山的通道到达未知的区域。 +*图 3. 玩家可以在游戏区域移动,比如围绕湖,通过山的通道到达未知的区域。* -通过颜色,你可以更清楚地展示信息。这个例子使用颜色指出可游戏的区域(绿色)相对着不可通过的区域(蓝色或者灰色)。我希望你可以使用这个示例游戏作为你自己的程序的一个起点或者参照。取决于你需要你的程序做什么,你可以通过curses做得更多。 +通过颜色,你可以更清楚地展示信息。这个例子使用颜色指出可游戏的区域(绿色)相对着不可通过的区域(蓝色或者灰色)。我希望你可以使用这个示例游戏作为你自己的程序的一个起点或者参照。这取决于你需要你的程序做什么,你可以通过 curses 做得更多。 -在下一篇文章,我计划展示ncurses库的其它特性,比如怎样创建窗口和边框。同时,如果你对于学习 curses 有兴趣,我建议你去读位于 [Linux 文档计划](http://www.tldp.org)的 Pradeep Padala 写的 [NCURSES Programming HOWTO](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO)。 +在下一篇文章,我计划展示 ncurses 库的其它特性,比如怎样创建窗口和边框。同时,如果你对于学习 curses 有兴趣,我建议你去读位于 [Linux 文档计划](http://www.tldp.org) 的 Pradeep Padala 写的 [NCURSES Programming HOWTO](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO)。 -------------------------------------------------------------------------------- @@ -379,11 +365,11 @@ via: http://www.linuxjournal.com/content/programming-color-ncurses 作者:[Jim Hall][a] 译者:[leemeans](https://github.com/leemeans) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:http://www.linuxjournal.com/users/jim-hall -[1]:http://www.linuxjournal.com/content/getting-started-ncurses -[2]:http://www.linuxjournal.com/content/creating-adventure-game-terminal-ncurses +[1]:https://linux.cn/article-9348-1.html +[2]:https://linux.cn/article-9383-1.html [3]:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO \ No newline at end of file diff --git a/translated/tech/20180207 Python Global Keyword (With Examples).md b/published/201804/20180207 Python Global Keyword (With Examples).md similarity index 51% rename from translated/tech/20180207 Python Global Keyword (With Examples).md rename to published/201804/20180207 Python Global Keyword (With Examples).md index 981de74983..1a15db8e44 100644 --- a/translated/tech/20180207 Python Global Keyword (With Examples).md +++ b/published/201804/20180207 Python Global Keyword (With Examples).md @@ -1,12 +1,14 @@ -Python Global 关键字(含示例) +初识 Python: global 关键字 ====== -在读这篇文章之前,确保你对 [Python Global,Local 和 Nonlocal 变量][1] 有一定的基础。 + +在读这篇文章之前,确保你对 [Python 全局、本地和非本地变量][1] 有一定的基础。 ### global 关键字简介 在 Python 中,`global` 关键字允许你修改当前范围之外的变量。它用于创建全局变量并在本地上下文中更改变量。 ### global 关键字的规则 + 在 Python 中,有关 `global` 关键字基本规则如下: * 当我们在一个函数中创建一个变量时,默认情况下它是本地变量。 @@ -14,63 +16,72 @@ Python Global 关键字(含示例) * 我们使用 `global` 关键字在一个函数中来读写全局变量。 * 在一个函数外使用 `global` 关键字没有效果。 -#### 使用 global 关键字(含示例) +### 使用 global 关键字(含示例) 我们来举个例子。 -##### 示例 1:从函数内部访问全局变量 +#### 示例 1:从函数内部访问全局变量 - c = 1 # 全局变量 +``` +c = 1 # 全局变量 +def add(): + print(c) - def add(): - print(c) - - add() +add() +``` 运行程序,输出为: - 1 +``` +1 +``` 但是我们可能有一些场景需要从函数内部修改全局变量。 -##### 示例 2:在函数内部修改全局变量 +#### 示例 2:在函数内部修改全局变量 - c = 1 # 全局变量 - - def add(): - c = c + 2 # 将 c 增加 2 - print(c) - - add() +``` +c = 1 # 全局变量 +def add(): + c = c + 2 # 将 c 增加 2 + print(c) +add() +``` 运行程序,输出显示错误: - UnboundLocalError: local variable 'c' referenced before assignment +``` +UnboundLocalError: local variable 'c' referenced before assignment +``` 这是因为在函数中,我们只能访问全局变量但是不能修改它。 解决的办法是使用 `global` 关键字。 -##### 示例 3:使用 global 在函数中改变全局变量 +#### 示例 3:使用 global 在函数中改变全局变量 - c = 0 # global variable +``` +c = 0 # global variable - def add(): - global c - c = c + 2 # 将 c 增加 2 - print("Inside add():", c) - - add() - print("In main:", c) +def add(): + global c + c = c + 2 # 将 c 增加 2 + print("Inside add():", c) + +add() +print("In main:", c) +``` 运行程序,输出为: - Inside add(): 2 - In main: 2 +``` +Inside add(): 2 +In main: 2 +``` -在上面的程序中,我们在 `add()` 函数中定义了 c 将其作为 global 关键字。 +在上面的程序中,我们在 `add()` 函数中定义了 `c` 将其作为全局关键字。 -然后,我们给变量 c 增加 `1`,(译注:这里应该是给 c 增加 `2` )即 `c = c + 2`。之后,我们调用了 `add()` 函数。最后,打印全局变量 c。 +然后,我们给变量 `c` 增加 `2`,即 `c = c + 2`。之后,我们调用了 `add()` 函数。最后,打印全局变量 `c`。 正如我们所看到的,在函数外的全局变量也发生了变化,`c = 2`。 @@ -80,68 +91,79 @@ Python Global 关键字(含示例) 以下是如何通过 Python 模块共享全局变量。 -##### 示例 4:在Python模块中共享全局变量 +#### 示例 4:在Python模块中共享全局变量 创建 `config.py` 文件来存储全局变量 - a = 0 - b = "empty" +``` +a = 0 +b = "empty" +``` 创建 `update.py` 文件来改变全局变量 - import config +``` +import config - config.a = 10 - config.b = "alphabet" +config.a = 10 +config.b = "alphabet" +``` 创建 `main.py` 文件来测试其值的变化 - import config - import update +``` +import config +import update - print(config.a) - print(config.b) +print(config.a) +print(config.b) +``` 运行 `main.py`,输出为: - 10 - alphabet +``` +10 +alphabet +``` 在上面,我们创建了三个文件: `config.py`, `update.py` 和 `main.py`。 -在 `config.py` 模块中保存了全局变量 a 和 b。在 `update.py` 文件中,我们导入了 `config.py` 模块并改变了 a 和 b 的值。同样,在 `main.py` 文件,我们导入了 `config.py` 和 `update.py` 模块。最后,我们打印并测试全局变量的值,无论它们是否被改变。 +在 `config.py` 模块中保存了全局变量 `a` 和 `b`。在 `update.py` 文件中,我们导入了 `config.py` 模块并改变了 `a` 和 `b` 的值。同样,在 `main.py` 文件,我们导入了 `config.py` 和 `update.py` 模块。最后,我们打印并测试全局变量的值,无论它们是否被改变。 ### 在嵌套函数中的全局变量 以下是如何在嵌套函数中使用全局变量。 -##### 示例 5:在嵌套函数中使用全局变量 +#### 示例 5:在嵌套函数中使用全局变量 - def foo(): - x = 20 - - def bar(): - global x - x = 25 +``` +def foo(): + x = 20 + def bar(): + global x + x = 25 - print("Before calling bar: ", x) - print("Calling bar now") - bar() - print("After calling bar: ", x) + print("Before calling bar: ", x) + print("Calling bar now") + bar() + print("After calling bar: ", x) - foo() - print("x in main : ", x) +foo() +print("x in main : ", x) +``` 输出为: - Before calling bar: 20 - Calling bar now - After calling bar: 20 - x in main : 25 +``` +Before calling bar: 20 +Calling bar now +After calling bar: 20 +x in main : 25 +``` -在上面的程序中,我们在一个嵌套函数 `bar()` 中声明了全局变量。在 `foo()` 函数中, 变量 x 没有全局关键字的作用。 +在上面的程序中,我们在一个嵌套函数 `bar()` 中声明了全局变量。在 `foo()` 函数中, 变量 `x` 没有全局关键字的作用。 -调用 `bar()` 之前和之后, 变量 x 取本地变量的值,即 `x = 20`。在 `foo()` 函数之外,变量 x 会取在函数 `bar()` 中的值,即 `x = 25`。这是因为在 `bar()` 中,我们对 x 使用 `global` 关键字创建了一个全局变量(本地范围)。 +调用 `bar()` 之前和之后, 变量 `x` 取本地变量的值,即 `x = 20`。在 `foo()` 函数之外,变量 `x` 会取在函数 `bar()` 中的值,即 `x = 25`。这是因为在 `bar()` 中,我们对 `x` 使用 `global` 关键字创建了一个全局变量(本地范围)。 如果我们在 `bar()` 函数内进行了任何修改,那么这些修改就会出现在本地范围之外,即 `foo()`。 @@ -151,7 +173,7 @@ via: [https://www.programiz.com/python-programming/global-keyword](https://www.p 作者:[programiz][a] 译者:[MjSeven](https://github.com/MjSeven) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20180208 Become a Hollywood movie hacker with these three command line tools.md b/published/201804/20180208 Become a Hollywood movie hacker with these three command line tools.md new file mode 100644 index 0000000000..a131f84969 --- /dev/null +++ b/published/201804/20180208 Become a Hollywood movie hacker with these three command line tools.md @@ -0,0 +1,78 @@ +假装很忙的三个命令行工具 +====== + +> 有时候你很忙。而有时候你只是需要看起来很忙,就像电影中的黑客一样。有一些开源工具就是干这个的。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_terminals.png?itok=CfBqYBah) + +如果在你在消磨时光时看过谍战片、动作片或犯罪片,那么你就会清晰地在脑海中勾勒出黑客的电脑屏幕的样子。就像是在《黑客帝国》电影中,[代码雨][1] 一样的十六进制数字流,又或是一排排快速移动的代码。 + +也许电影中出现一幅世界地图,其中布满了闪烁的光点和一些快速更新的图表。不可或缺的,也可能有 3D 旋转的几何形状。甚至,这一切都会显示在一些完全不符合人类习惯的数量荒谬的显示屏上。 在《剑鱼行动》电影中黑客就使用了七个显示屏。 + +当然,我们这些从事计算机行业的人一下子就明白这完全是胡说八道。虽然在我们中,许多人都有双显示器(或更多),但一个闪烁的数据仪表盘、刷新的数据通常和专注工作是相互矛盾的。编写代码、项目管理和系统管理与日常工作不同。我们遇到的大多数情况,为了解决问题,都需要大量的思考,与客户沟通所得到一些研究和组织的资料,然后才是少许的 [敲代码][7]。 + +然而,这与我们想追求电影中的效果并不矛盾,也许,我们只是想要看起来“忙于工作”而已。 + +**注:当然,我仅仅是在此胡诌。**如果您公司实际上是根据您繁忙程度来评估您的工作时,无论您是蓝领还是白领,都需要亟待解决这样的工作文化。假装工作很忙是一种有毒的文化,对公司和员工都有害无益。 + +这就是说,让我们找些乐子,用一些老式的、毫无意义的数据和代码片段填充我们的屏幕。(当然,数据或许有意义,但不是在这种没有上下文的环境中。)当然有一些用于此用途的有趣的图形界面程序,如 [hackertyper.net][8] 或是 [GEEKtyper.com][9] 网站(LCTT 译注:是在线假装黑客操作的网站),为什么不使用标准的 Linux 终端程序呢?对于更老派的外观,可以考虑使用 [酷炫复古终端][10],这听起来确实如此:一个酷炫的复古终端程序。我将在下面的屏幕截图中使用酷炫复古终端,因为它看起来的确很酷。 + +### Genact + +我们来看下第一个工具——Genact。Genact 的原理很简单,就是慢慢地无尽循环播放您选择的一个序列,让您的代码在您外出休息时“编译”。由您来决定播放顺序,但是其中默认包含数字货币挖矿模拟器、Composer PHP 依赖关系管理工具、内核编译器、下载器、内存转储等工具。其中我最喜欢的是其中类似《模拟城市》加载显示。所以只要没有人仔细检查,你可以花一整个下午等待您的电脑完成进度条。 + +Genact [发布了][11] 支持 Linux、OS X 和 Windows 的版本。并且其 Rust [源代码][12] 在 GitHub 上开源(遵循 [MIT 许可证][13])。 + +![](https://opensource.com/sites/default/files/uploads/genact.gif) + +### Hollywood + +Hollywood 采取更直接的方法。它本质上是在终端中创建一个随机的数量和配置的分屏,并启动那些看起来很繁忙的应用程序,如 htop、目录树、源代码文件等,并每隔几秒将其切换。它被组织成一个 shell 脚本,所以可以非常容易地根据需求进行修改。 + +Hollywood的 [源代码][14] 在 GitHub 上开源(遵循 [Apache 2.0 许可证][15])。 + +![](https://opensource.com/sites/default/files/uploads/hollywood.gif) + +### Blessed-contrib + +Blessed-contrib 是我个人最喜欢的应用,实际上并不是为了这种表演而专门设计的应用。相反地,它是一个基于 Node.js 的终端仪表盘的构建库的演示文件。与其他两个不同,实际上我已经在工作中使用 Blessed-contrib 的库,而不是用于假装忙于工作。因为它是一个相当有用的库,并且可以使用一组在命令行显示信息的小部件。与此同时填充虚拟数据也很容易,所以可以很容易实现你在计算机上模拟《战争游戏》的想法。 + +Blessed-contrib 的[源代码][16]在 GitHub 上(遵循 [MIT 许可证][17])。 + +![](https://opensource.com/sites/default/files/uploads/blessed.gif) + +当然,尽管这些工具很容易使用,但也有很多其他的方式使你的屏幕丰富。在你看到电影中最常用的工具之一就是Nmap,这是一个开源的网络安全扫描工具。实际上,它被广泛用作展示好莱坞电影中,黑客电脑屏幕上的工具。因此 Nmap 的开发者创建了一个 [页面][18],列出了它出现在其中的一些电影,从《黑客帝国 2:重装上阵》到《谍影重重3》、《龙纹身的女孩》,甚至《虎胆龙威 4》。 + +当然,您可以创建自己的组合,使用终端多路复用器(如 `screen` 或 `tmux`)启动您希望使用的任何数据切分程序。 + +那么,您是如何使用您的屏幕的呢? + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/command-line-tools-productivity + +作者:[Jason Baker][a] +译者:[wyxplus](https://github.com/wyxplus) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jason-baker +[1]:http://tvtropes.org/pmwiki/pmwiki.php/Main/MatrixRainingCode +[2]:https://opensource.com/resources/what-is-linux?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent +[3]:https://opensource.com/resources/what-are-linux-containers?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent +[4]:https://developers.redhat.com/promotions/linux-cheatsheet/?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent +[5]:https://developers.redhat.com/cheat-sheet/advanced-linux-commands-cheatsheet?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent +[6]:https://opensource.com/tags/linux?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent +[7]:http://tvtropes.org/pmwiki/pmwiki.php/Main/RapidFireTyping +[8]:https://hackertyper.net/ +[9]:http://geektyper.com +[10]:https://github.com/Swordfish90/cool-retro-term +[11]:https://github.com/svenstaro/genact/releases +[12]:https://github.com/svenstaro/genact +[13]:https://github.com/svenstaro/genact/blob/master/LICENSE +[14]:https://github.com/dustinkirkland/hollywood +[15]:http://www.apache.org/licenses/LICENSE-2.0 +[16]:https://github.com/yaronn/blessed-contrib +[17]:http://opensource.org/licenses/MIT +[18]:https://nmap.org/movies/ diff --git a/translated/tech/20180213 How to clone, modify, add, and delete files in Git.md b/published/201804/20180213 How to clone, modify, add, and delete files in Git.md similarity index 64% rename from translated/tech/20180213 How to clone, modify, add, and delete files in Git.md rename to published/201804/20180213 How to clone, modify, add, and delete files in Git.md index 9cc05462d4..d552a0f54f 100644 --- a/translated/tech/20180213 How to clone, modify, add, and delete files in Git.md +++ b/published/201804/20180213 How to clone, modify, add, and delete files in Git.md @@ -1,29 +1,28 @@ -在 Git 中怎样克隆,修改,添加和删除文件? +在 Git 中怎样克隆、修改、添加和删除文件? ===== ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LIFE_cat.png?itok=ta54QTAf) -在 [本系列的第一篇文章][1] 开始使用 Git 时,我们创建了一个简单的 Git 仓库,并通过它连接到我们的计算机向其中添加一个文件。在本文中,我们将学习一些关于 Git 的其他内容,即如何克隆(下载),修改,添加和删除 Git 仓库中的文件。 - +在 [本系列的第一篇文章][1] 开始使用 Git 时,我们创建了一个简单的 Git 仓库,并用我们的计算机连接到它,向其中添加一个文件。在本文中,我们将学习一些关于 Git 的其他内容,即如何克隆(下载)、修改、添加和删除 Git 仓库中的文件。 ### 让我们来克隆一下 -假设你在 GitHub 上已经有一个 Git 仓库,并且想从它那里获取你的文件-也许你在你的计算机上丢失了本地副本,或者你正在另一台计算机上工作,但是想访问仓库中的文件,你该怎么办?从 GitHub 下载你的文件?没错!我们称之为 Git 术语中的“克隆”。(你也可以将仓库作为 ZIP 文件下载,但我们将在本文中探讨克隆方法。) +假设你在 GitHub 上已经有一个 Git 仓库,并且想从它那里获取你的文件——也许你在你的计算机上丢失了本地副本,或者你正在另一台计算机上工作,但是想访问仓库中的文件,你该怎么办?从 GitHub 下载你的文件?没错!在 Git 术语中我们称之为“克隆clone”。(你也可以将仓库作为 ZIP 文件下载,但我们将在本文中探讨克隆方式。) -让我们克隆在上一篇文章中创建的称为 Demo 的仓库。(如果你还没有创建 Demo 仓库,请跳回到那篇文章并在继续之前执行那些步骤。)要克隆文件,只需打开浏览器并导航到 `https://github.com//Demo` (其中 `` 是你仓库的名称。例如,我的仓库是 `https://github.com/kedark3/Demo`)。一旦你导航到该 URL,点击“克隆或下载”按钮,你的浏览器看起来应该是这样的: +让我们克隆在上一篇文章中创建的名为 Demo 的仓库。(如果你还没有创建 Demo 仓库,请跳回到[那篇文章][1]并在继续之前执行那些步骤)要克隆文件,只需打开浏览器并导航到 `https://github.com//Demo` (其中 `` 是你仓库的名称。例如,我的仓库是 `https://github.com/kedark3/Demo`)。一旦你导航到该 URL,点击“克隆或下载Clone or download”按钮,你的浏览器看起来应该是这样的: ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide11.png?itok=wJYqZyBX) -正如你在上面看到的,“使用 HTTPS 克隆”选项已打开。从该下拉框中复制你的仓库地址(`https://github.com//Demo.git`),打开终端并输入以下命令将 GitHub 仓库克隆到你的计算机: +正如你在上面看到的,“使用 HTTPS 克隆Clone with HTTPS”选项已打开。从该下拉框中复制你的仓库地址(`https://github.com//Demo.git`),打开终端并输入以下命令将 GitHub 仓库克隆到你的计算机: + ``` git clone https://github.com//Demo.git - ``` 然后,要查看 `Demo` 目录中的文件列表,请输入以下命令: + ``` ls Demo/ - ``` 终端看起来应该是这样的: @@ -33,19 +32,14 @@ ls Demo/ ### 修改文件 现在我们已经克隆了仓库,让我们修改文件并在 GitHub 上更新它们。首先,逐个输入下面的命令,将目录更改为 `Demo/`,检查 `README.md` 中的内容,添加新的(附加的)内容到 `README.md`,然后使用 `git status` 检查状态: + ``` cd Demo/ - ls - cat README.md - echo "Added another line to REAMD.md" >> README.md - cat README.md - git status - ``` 如果你逐一运行这些命令,终端看起开将会是这样: @@ -53,13 +47,13 @@ git status ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide12.5.png?itok=jhb-EPH1) 让我们看一下 `git status` 的输出,并了解它的意思。不要担心这样的语句: + ``` On branch master - Your branch is up-to-date with 'origin/master'.". - ``` -因为我们还没有学习这些。(译注:学了你就知道了)下一行说:`Changes not staged for commit`;这是告诉你,它下面列出的文件没有标记就绪(“分阶段”)提交。如果你运行 `git add`,Git 会把这些文件标记为 `Ready for commit`;换句话说就是 `Changes staged for commit`。在我们这样做之前,让我们用 `git diff` 命令来检查我们添加了什么到 Git 中,然后运行 `git add`。 + +因为我们还没有学习这些。(LCTT 译注:学了你就知道了)下一行说:`Changes not staged for commit`(变化未筹划提交);这是告诉你,它下面列出的文件没有被标记准备(“筹划stage”)提交。如果你运行 `git add`,Git 会把这些文件标记为 `Ready for commit`(准备提交);换句话说就是 `Changes staged for commit`(变化筹划提交)。在我们这样做之前,让我们用 `git diff` 命令来检查我们添加了什么到 Git 中,然后运行 `git add`。 这里是终端输出: @@ -70,12 +64,11 @@ Your branch is up-to-date with 'origin/master'.". * `diff --git a/README.md b/README.md` 是 Git 比较的内容(在这个例子中是 `README.md`)。 * `--- a/README.md` 会显示从文件中删除的任何东西。 * `+++ b/README.md` 会显示从文件中添加的任何东西。 -* 任何添加到文件中的内容都以绿色文本打印,并在该行的开头加上 + 号。 -* 如果我们删除了任何内容,它将以红色文本打印,并在该行的开头加上 - 号。 -* 现在 git status 显示“Changes to be committed:”,并列出文件名(即 `README.md`)以及该文件发生了什么(即它已经被 `modified` 并准备提交)。 +* 任何添加到文件中的内容都以绿色文本打印,并在该行的开头加上 `+` 号。 +* 如果我们删除了任何内容,它将以红色文本打印,并在该行的开头加上 `-` 号。 +* 现在 `git status` 显示 `Changes to be committed:`(变化将被提交),并列出文件名(即 `README.md`)以及该文件发生了什么(即它已经被 `modified` 并准备提交)。 - -提示:如果你已经运行了 `git add`,现在你想看看文件有什么不同,通常 `git diff` 不会产生任何东西,因为你已经添加了文件。相反,你必须使用 `git diff --cached`。它会告诉你 Git 添加的当前版本和以前版本文件之间的差别。你的终端输出看起来会是这样: +提示:如果你已经运行了 `git add`,现在你想看看文件有什么不同,通常 `git diff` 不会输出任何东西,因为你已经添加了文件。相反,你必须使用 `git diff --cached`。它会告诉你 Git 添加的当前版本和以前版本文件之间的差别。你的终端输出看起来会是这样: ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide14.png?itok=bva9fHJj) @@ -84,47 +77,47 @@ Your branch is up-to-date with 'origin/master'.". 我们用一些新内容修改了 `README.md` 文件,现在是时候将它上传到 GitHub。 让我们提交更改并将其推送到 GitHub。运行: -``` -git commit -m "更新文件的名字" +``` +git commit -m "Updated Readme file" ``` -这告诉 Git 你正在“提交”已经“添加”的更改,你可能还记得,从本系列的第一部分中,添加一条消息来解释你在提交中所做的操作是非常重要的,以便你在稍后回顾 Git 日志时了解当时的目的。(我们将在下一篇文章中更多地关注这个话题。)`Updated Readme file` 是这个提交的消息--如果你认为这不是解释你所做的事情的最合理的方式,那么请随便写下你的提交消息。 +这告诉 Git 你正在“提交”已经“添加”的更改,你可能还记得,从本系列的第一部分中,添加一条消息来解释你在提交中所做的操作是非常重要的,以便你在稍后回顾 Git 日志时了解当时的目的。(我们将在下一篇文章中更多地关注这个话题。)`Updated Readme file` 是这个提交的消息——如果你认为这没有合理解释你所做的事情,那么请根据需要写下你的提交消息。 运行 `git push -u origin master`,这会提示你输入用户名和密码,然后将文件上传到你的 GitHub 仓库。刷新你的 GitHub 页面,你应该会看到刚刚对 `README.md` 所做的更改。 ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide15.png?itok=Qa3spy13) -终端的右下角显示我提交了更改,检查了 Git 状态,并将更改推送到了 GitHub。git status 显示: +终端的右下角显示我提交了更改,检查了 Git 状态,并将更改推送到了 GitHub。`git status` 显示: + ``` Your branch is ahead of 'origin/master' by 1 commit -   (use "git push" to publish your local commits) - ``` -第一行表示在本地仓库中有一个提交,但不在原始/主文件中(即在 GitHub 上)。下一行指示我们将这些更改推送到原始/主文件中,这就是我们所做的。(在本例中,请参阅本系列的第一篇文章,以唤醒你对“原始”含义的记忆。我将在下一篇文章中讨论分支的时候,解释“主文件”的含义。) +第一行表示在本地仓库中有一个提交,但不在 `origin/master` 中(即在 GitHub 上)。下一行指示我们将这些更改推送到 `origin/master` 中,这就是我们所做的。(在本例中,请参阅本系列的第一篇文章,以唤醒你对 `origin` 含义的记忆。我将在下一篇文章中讨论分支的时候,解释 `master` 的含义。) ### 添加新文件到 Git 现在我们修改了一个文件并在 GitHub 上更新了它,让我们创建一个新文件,将它添加到 Git,然后将其上传到 GitHub。 运行: + ``` echo "This is a new file" >> file.txt - ``` 这将会创建一个名为 `file.txt` 的新文件。 如果使用 `cat` 查看它: + ``` cat file.txt - ``` + 你将看到文件的内容。现在继续运行: + ``` git status - ``` Git 报告说你的仓库中有一个未跟踪的文件(名为 `file.txt`)。这是 Git 告诉你说在你的计算机中的仓库目录下有一个新文件,然而你并没有告诉 Git,Git 也没有跟踪你所做的任何修改。 @@ -132,17 +125,17 @@ Git 报告说你的仓库中有一个未跟踪的文件(名为 `file.txt`) ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide16.png?itok=UZpSKL13) 我们需要告诉 Git 跟踪这个文件,以便我们可以提交并上传文件到我们的仓库。以下是执行该操作的命令: + ``` git add file.txt - git status - ``` 终端输出如下: + ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide17.png?itok=quV-75Na) -git status 告诉你有 `file.txt` 被修改,对于 Git 来说它是一个 `new file`,Git 在此之前并不知道。现在我们已经为 Git 添加了 `file.txt`,我们可以提交更改并将其推送到 原始/主文件。 +`git status` 告诉你有 `file.txt` 被修改,对于 Git 来说它是一个 `new file`,Git 在此之前并不知道。现在我们已经为 Git 添加了 `file.txt`,我们可以提交更改并将其推送到 `origin/master`。 ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide18.png?itok=e0D7-eol) @@ -155,26 +148,25 @@ Git 现在已经将这个新文件上传到 GitHub;如果刷新 GitHub 页面 ### 从 Git 中删除文件 如果我们发现我们犯了一个错误,并且需要从我们的仓库中删除 `file.txt`,该怎么办?一种方法是使用以下命令从本地副本中删除文件: + ``` rm file.txt - ``` -如果你现在做 `git status`,Git 就会说有一个文件 `not staged for commit`,并且它已经从仓库的本地拷贝中删除了。如果我们现在运行: +如果你现在做 `git status`,Git 就会说有一个文件 `not staged for commit`(未筹划提交),并且它已经从仓库的本地拷贝中删除了。如果我们现在运行: + ``` git add file.txt - git status - ``` -我知道我们正在删除这个文件,但是我们仍然运行 `git add`,因为我们需要告诉 Git 我们正在做的**更改**,`git add` 可以用在我们添加新文件,修改一个已存在文件的内容,或者从仓库中删除文件。实际上,`git add` 将所有更改考虑在内,并将这些更改分阶段进行提交。如果有疑问,请仔细查看下面终端屏幕截图中每个命令的输出。 + +我知道我们正在删除这个文件,但是我们仍然运行 `git add`,因为我们需要告诉 Git 我们正在做的**更改**,`git add` 可以用于我们添加新文件、修改一个已存在文件的内容、或者从仓库中删除文件时。实际上,`git add` 将所有更改考虑在内,并将这些筹划提交这些更改。如果有疑问,请仔细查看下面终端屏幕截图中每个命令的输出。 Git 会告诉我们已删除的文件正在进行提交。只要你提交此更改并将其推送到 GitHub,该文件也将从 GitHub 的仓库中删除。运行以下命令: + ``` git commit -m "Delete file.txt" - git push -u origin master - ``` 现在你的终端看起来像这样: @@ -185,8 +177,7 @@ git push -u origin master ![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide21.png?itok=RhXM4Gua) -现在你知道如何从你的仓库克隆,添加,修改和删除 Git 文件。本系列的下一篇文章将检查 Git 分支。 - +现在你知道如何从你的仓库克隆、添加、修改和删除 Git 文件。本系列的下一篇文章将检查 Git 分支。 -------------------------------------------------------------------------------- @@ -194,9 +185,9 @@ via: https://opensource.com/article/18/2/how-clone-modify-add-delete-git-files 作者:[Kedar Vijay Kulkarni][a] 译者:[MjSeven](https://github.com/MjSeven) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://opensource.com/users/kkulkarn -[1]:https://opensource.com/article/18/1/step-step-guide-git +[1]:https://linux.cn/article-9319-1.html diff --git a/published/201804/20180214 11 awesome vi tips and tricks.md b/published/201804/20180214 11 awesome vi tips and tricks.md new file mode 100644 index 0000000000..530e2e1347 --- /dev/null +++ b/published/201804/20180214 11 awesome vi tips and tricks.md @@ -0,0 +1,95 @@ +11 个超棒的 Vi 技巧和窍门 +====== + +> 是否你刚刚接触 Vi 还是想进阶,这些技巧可以很快让你成为高级用户。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/keyboaord_enter_writing_documentation.jpg?itok=kKrnXc5h) + +[Vi][1] 编辑器是 Unix 和像 Linux 这样的类 Unix 系统中 Linux 最流行的编辑器之一。无论您是 vi 新手还是想进阶,这里有 11 个技巧可以增强你使用的方式。 + +### 编辑 + +编辑长文本时可能很难受,特别是编辑其中某一行时,需要移动许久才能到这行。这有个很快的方法: + +1、 `:set number` 这个命令可是在编辑器左边显示行号。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/setnum.png?itok=sFVA97mG) + +您可以在命令行中输入 `vi +26 samp.txt` 命令直接打开文件到达 26 行,在 vi 编辑器中也可以输入 `:26` 跳转到 26 行。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/number.png?itok=d7FE0LL3) + +### 快速导航 + +2、 `i` 将工作方式从“命令模式”更改为“输入模式”,并在当前光标位置开始插入内容。 + +3、 `a` 除了是光标之后开始插入内容,与上面的效果是一样的。 + +4、 `o` 在光标的下一行位置开始插入内容。 + +### 删除 + +如果您发现错误或错别字,能快速的修正是很重要的。好在 Vi 都事先想好了。 + +了解 Vi 的删除功能,保证你不会意外按下某个键并永久删除一行或多段内容,这点至关重要。 + +5、 `x` 删除当前光标的字符。 + +6、 `dd` 删除当前行 (是的,整行内容!) + +下面看可怕的部分:`30dd` 从当前行开始删除以下 30 行!使用此命令请慎重。 + +### 搜索 + +您可以在“命令模式”搜索关键字,而不用在大量文本内容中手动导航查找特定的单词或内容。 + +7、 `:/` 搜索 `< >` 中的单词并将光标移动到第一个匹配项。 + +8、 导航到该单词的下一个匹配项,请输入 `n` 并继续按下, 直到找到您要找的内容。 + +例如,在这个图像中我要搜索包含 `ssh` 的内容, Vi 光标就会突出第一个结果的开始位置。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/ssh-search.png?itok=tJ-7FujH) + +按下 `n` 之后, Vi 光标就会突出下一个匹配项。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/n-search.png?itok=wU-u3LiI) + +### 保存并退出 + +开发人员 (或其他人) 可能会发现这个命令很有用。 + +9、 `:x` 保存您的工作并退出 Vi 。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/x.png?itok=kfoHx84m) + +10、 如果你想节省哪怕是纳秒,那么这有个更快的回到终端的方法。不用在键盘上按 `Shift+:` ,而是按下 `Shift+q` (或者大写字母 Q ) 来进入 [Ex 模式][2] 。但是如果你只是想按下 `x` 来保存退出,那就没有什么区别(如上所示)。 + +### 替换 + +如果您想将文中的某个单词全部替换为一个单词,这有个很巧妙的招式。例如,如果您想在一个大文件中将 “desktop” 替换为 “laptop” ,那么单调的搜索每个出现的 “desktop” 将其删掉,然后再输入 “laotop” ,是很浪费时间的。 + +11、 `:%s/desktop/laptop/g` 这个命令将在整个文件中的 “desktop” 用 “laptop” 替换,他就像 Linux 的 `sed` 命令一样。 + + +这个例子中我用 “user” 替换了 “root” : + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/subs-command.png?itok=M8MN72sp) + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/subs-result.png?itok=34zzVdUt) + +这些技巧应该能帮组任何想开始学 Vi 的人。我有遗漏其他巧妙的提示吗?请在评论中分享他们。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/top-11-vi-tips-and-tricks + +作者:[Archit Modi][a] +译者:[MZqk](https://github.com/MZqk) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux 中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/architmodi +[1]:http://ex-vi.sourceforge.net/ +[2]:https://en.wikibooks.org/wiki/Learning_the_vi_Editor/Vim/Modes#Ex-mode diff --git a/translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md b/published/201804/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md similarity index 52% rename from translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md rename to published/201804/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md index 87cd2d7e1f..abf68aeb2b 100644 --- a/translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md +++ b/published/201804/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md @@ -1,267 +1,197 @@ -用 PGP 保护代码完整性 - 第一部分: 基本概念和工具 +用 PGP 保护代码完整性(一): 基本概念和工具 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/pgp-security.jpg?itok=lulwyzYc) 在本系列文章中,我们将深度探讨如何使用 PGP 确保软件完整性。这些文章将为工作于自由软件项目的开发者提供实用指南,并且将包含以下主题: - - 1. PGP 基础和最佳实践 - + 1. PGP 基础和最佳实践 2. 如何用 Git 使用 PGP - 3. 如何保护你的开发者账户 - -我们使用与“Freedom”含义相同的词项“Free”,但这个系列中列出的指南也可以被任何其它类型的依赖于分布式团队开发者贡献的软件中。如果你编写进入公共源仓库的代码,你可以从了解和遵循这篇指南中受益。 +我们使用与“Freedom”含义相同的词项 “Free”,但这个系列中列出的指南也可以被任何其它类型的依赖于分布式团队开发者贡献的软件中。如果你编写进入公共源仓库的代码,你可以从了解和遵循这篇指南中受益。 ### 结构 每节分为两个部分: * 适用于你项目需求的清单 - - * 自由形式的考虑事项的列表,解释这些决定取决于什么,并伴随着配置指令 - - - + * 形式自由的考虑事项的列表,解释这些决定取决于什么,并伴随着配置指令 #### 清单优先级 每个清单中各项包含着优先级,用来帮助指导你的决定: - * (ESSENTIAL) 该项一定要排在考虑事项列表的前面。如果没有这样做,它们将给提交到开源项目中的代码带来高风险。 - - * (NICE) 包含该项将提升整体安全性,但会影响你与工作环境的交互方式,并且可能需要学习新的习惯或者放弃旧的习惯。 - - - + * (必要)该项一定要排在考虑事项列表的前面。如果没有这样做,它们将给提交到开源项目中的代码带来高风险。 + * (推荐)包含该项将提升整体安全性,但会影响你与工作环境的交互方式,并且可能需要学习新的习惯或者放弃旧的习惯。 记住,这些只是指导。如果你感到这些优先级不能反映你项目提交的安全,你应该根据自己的需要调整它们。 -## PGP 基本概念和工具 +### PGP 基本概念和工具 -### 清单 +#### 清单 - 1. 理解 PGP 在自由软件开发中的作用 (ESSENTIAL) - - 2. 理解公钥密码学(Public Key Cryptography)的基础知识 (ESSENTIAL) - - 3. 理解 PGP 加密和签名的不同 (ESSENTIAL) - - 4. 理解 PGP 密钥身份(key identities) (ESSENTIAL) - - 5. 理解 PGP 密钥有效性(key validity) (ESSENTIAL) - - 6. 安装 GnuPG 工具(版本 2.x) (ESSENTIAL) + 1. 理解 PGP 在自由软件开发中的作用 (必要) + 2. 理解公钥密码学Public Key Cryptography的基础知识 (必要) + 3. 理解 PGP 加密和签名的不同 (必要) + 4. 理解 PGP 密钥身份key identities (必要) + 5. 理解 PGP 密钥有效性key validity (必要) + 6. 安装 GnuPG 工具(版本 2.x) (必要) +#### 考虑事项 - - -### 考虑事项 - -自由软件社区长期依赖于 PGP 确保它生产的软件产品的真实性和完整性。你可能没有注意到,但无论你是一个 linux,Mac 和 Windowas 用户,你都曾依赖 PGP 来确保你电脑环境的完整性: +自由软件社区长期依赖于 PGP 确保它生产的软件产品的真实性和完整性。你可能没有注意到,但无论你是一个 Linux +、Mac 和 Windowas 用户,你都曾依赖 PGP 来确保你电脑环境的完整性: * Linux 发行版依赖 PGP 来确保当二进制或者原代码包从被生产出来到被终端用户安装之间没被更改过 - - * 自由软件项目通常会提供分离的 PGP 签名以伴随发行软件存档,使得下游的项目可以把下载的版本集成到自己的分布式下载之前,验证下载版本的完整性。 - + * 自由软件项目通常会伴随发行软件的存档提供分离的 PGP 签名,使得下游的项目可以在把下载的版本集成到自己的分布式下载之前,验证下载版本的完整性。 * 自由软件项目通常依赖代码本身的 PGP 签名来跟踪起源,并验证项目开发者提交的代码的完整性 - - - - -这与工作于专有平台的程序员使用的开发者证书或代码签名机制非常相似。实际上,这两种技术背后的核心概念非常相似 -- 尽管它们在实现的技术层面和它们委托信任方式的大多不同。PGP 不依赖于集中式认证机构,而是让每个用户为每个证书分配自己的信任。 +这与工作于专有平台的程序员使用的开发者证书或代码签名机制非常相似。实际上,这两种技术背后的核心概念非常相似 —— 尽管它们在实现的技术层面和它们委托信任方式的大多不同。PGP 不依赖于集中式认证机构,而是让每个用户为每个证书赋予自己的信任。 我们的目标是使你的项目通过使用 PGP 来进行代码起源和完整性追踪,遵循最佳实践并遵守基本的安全预防措施。 -### 极其基本的 PGP 操作概括 +#### 极其基本的 PGP 操作概括 -你不需要知道 PGP 如何工作的具体细节 -- 理解核心概念足以成功地达到我们的目的。PGP 依赖于公钥密码学来将明文转换为密文。这个过程需要两种不同的密钥: +你不需要知道 PGP 如何工作的具体细节 —— 理解核心概念足以成功地达到我们的目的。PGP 依赖于公钥密码学来将明文转换为密文。这个过程需要两种不同的密钥: * 公钥,被所有人知道 - * 私钥,只被拥有者知道 - - - -#### 加密 +##### 加密 对加密来说,PGP 使用拥有者的公钥创造一条只能通过拥有者私钥解密的消息: - 1. 发送者生成一条随机的加密密钥(“会话密钥”) - - 2. 发送者使用该会话密钥(使用对称密码)加密内容 - + 1. 发送者生成一个随机的加密密钥(“会话密钥”) + 2. 发送者使用该会话密钥(使用对称算法)加密内容 3. 发送者使用接收者的 PGP 公钥加密会话密钥 - 4. 发送者向接收者发送加密后的内容和加密后的会话密钥 +要解密: + 1. 接收者使用他们的 PGP 私钥解密会话密钥 + 2. 接收者使用会话密钥解密消息的内容 +##### 签名 -对于解密: - - 1. 接受者使用他们的 PGP 私钥解密会话密钥 - - 2. 接受者使用会话密钥解密消息的内容 - - - - -#### 签名 为了创建签名,PGP 私钥或公钥会以相反的方式使用: 1. 签名者生成内容的校检和哈希 2. 签名者使用自己的 PGP 私钥来加密该校检和 3. 签名者伴随内容提供加密后的校检和 - - - -为了验证签名: +要验证签名: 1. 验证者生成自己的内容校检和哈希 - 2. 验证者使用签名者的 PGP 公钥来解密提供的校检和 - 3. 如果校检和匹配,就验证了内容的完整性 - - - - +##### 结合使用 通常,加密消息也被发送者自己的 PGP 密钥签名。无论何时使用加密消息,这应当是默认的,因为没有认证的加密没有很大意义(除非你是一个告密者或秘密代理并且需要可行的可否认性) -``` -Bob Designer (obsolete 1024-bit key) +#### 理解密钥身份 -``` -### 理解密钥身份 +每个 PGP 密钥必须有一个或多个与之关联的身份。通常,“身份Identity”指的是以下格式中的人物全名和邮件地址: -每个 PGP 密钥必须有一个或多个与之关联的身份。通常,一个“身份”指的是以下格式中的人物全名和邮件地址: ``` Alice Engineer - ``` 有时也会在括号中包含说明,来告诉终端用户关于该特定密钥的更多信息: + ``` Bob Designer (obsolete 1024-bit key) - ``` - - 由于人们可以和多个职业和个人实体相关联,因此在同一密钥上可以有多个身份: + ``` Alice Engineer Alice Engineer Alice Engineer - ``` -当使用多个身份时,其中之一将被标记为“primary identity”(主要身份)来让检索更简单。 +当使用多个身份时,其中之一将被标记为“primary identity主要身份”来让检索更简单。 -### 理解密钥有效性 +#### 理解密钥有效性 -为了能使用其他人的公钥来加密或验证,你需要确保它确实属于正确的人(Alice)而不属于冒牌的(Eve)。在 PGP 中,这被称为密钥有效性: +为了能使用其他人的公钥来加密或验证,你需要确保它确实属于正确的人(Alice)而不属于冒牌的(Eve)。在 PGP 中,这被称为“密钥有效性”: - * Validity: full -- 意味着非常确认该密钥属于 Alice - * Validity: marginal -- 意味着大致确认该密钥属于 Alice - * Validity: unknown -- 意味着不确认该密钥是否属于 Alice + * 有效性:完全full -- 意味着非常确认该密钥属于 Alice + * 有效性:临界marginal -- 意味着大致确认该密钥属于 Alice + * 有效性:未知unknown -- 意味着不确认该密钥是否属于 Alice + +#### Web of Trust (WOT) 与 Trust on First Use (TOFU) +PGP 使用了一种信任委托机制叫“Web of Trust”。它的核心是尝试替代 HTTPS/TLS 世界中对集中式认证机构的需求。PGP 把这个责任交给了每个用户,而不是各种软件开发商来决定谁应该是你的可信认证实体。 - -#### Web of Trust (WOT) vs. Trust on First Use (TOFU) - -PGP 使用了一种信任委托机制叫“Web of Trust”。它的核心是尝试替代 HTTPS/TLS 世界中对集中式认证机构的需求。PGP 把这个责任交给了每个用户,而非各种软件制作商来决定谁应该是你的可信认证实体。 - -不幸的是,很少有人理解 Web of Trust 的是如何工作的,能让继续工作的人更少。它仍然是 OpenPGP 规范的一个重要方面,但 GnuPG 的近期版本(2.2 及以上)已经实现了一种替代机制叫“Trust on First Use”(TOFU)。 +不幸的是,很少有人理解 Web of Trust 的是如何工作的,能使用它的人更少。它仍然是 OpenPGP 规范的一个重要方面,但 GnuPG 的近期版本(2.2 及以上)已经实现了一种替代机制叫“Trust on First Use”(TOFU)。 你可以把 TOFU 当作类似 SSH 的信任方式。使用 SSH,当你第一次连接到远程系统,它的密钥指纹会被记录和保存。如果将来密钥改变,SSH 客户端将会提醒你并拒绝连接,迫使你决定是否信任已改变的的密钥。 同样,当你第一次导入某人的 PGP 密钥,它被假定可信。如果在将来的任何时候,GnuPG 碰巧发现另一同样身份的密钥,过去导入的密钥和新密钥都将被标记为无效,并且你需要手动指出保留哪个。 +#### 安装 OpenPGP 软件 -### 安装 OpenPGP 软件 +首先,理解 PGP、OpenPGP、GnuPG 和 gpg 之间的不同很重要: -首先,理解 PGP, OpenPGP, GnuPG 和 gpg 之间的不同很重要: - - * PGP ("Pretty Good Privacy") 是原始商业软件的名字 - - * OpenPGP 是与原始 PGP 工具兼容的 IETF 标准 - - * GnuPG ("Gnu Privacy Guard")是实现了 OpenPGP 标准的自由软件 - + * PGP (“Pretty Good Privacy”) 是最初商业软件的名字 + * OpenPGP 是与最初 PGP 工具兼容的 IETF 标准 + * GnuPG (“Gnu Privacy Guard”)是实现了 OpenPGP 标准的自由软件 * GnuPG 的命令行工具称为 “gpg” +今天,“PGP”这个词几乎被普遍用来表示开放的 OpenPGP 标准,而不是最初的商业软件,因此“PGP”和“OpenPGP”是可以互换的。“GnuPG”和“pgp”这两个词应该仅在提及工具时使用,而不用于它们产生的输出或它们实现的 OpenPGP 功能。举例: - - - -今天,“PGP”这个词几乎被普遍用来表示开放的 OpenPGP 标准,而不是原始的商业软件,因此“PGP”和“OpenPGP”是可以互换的。“GnuPG”和“pgp”这两个词应该仅在提及工具时使用,而不用于它们产生的输出或它们实现的 OpenPGP 功能。举例: - - * PGP(而非 GnuPG 或 GPG)密钥 - - * PGP(而非 GnuPG 或 GPG)签名 - - * PGP(而非 GnuPG 或 GPG)密钥服务器 - - - + * PGP(而非 GnuPG 或 GPG)密钥 + * PGP(而非 GnuPG 或 GPG)签名 + * PGP(而非 GnuPG 或 GPG)密钥服务器 理解这一点应该可以保护你免受来自你遇到的其他 PGP 用户“实际上”不可避免的迂腐。 -#### 安装 GnuPG +##### 安装 GnuPG -如果你正在使用 Linux,你应该已经安装过了 GnuPG。在 Mac 上,你应该安装[GPG-Suite][1],或者使用 brew 安装 gnupg2。在 windows 上,你应该安装[GPG4Win][2],并且为了奏效你可能需要调整指南中的部分命令,除非你设置了类似 unix 的环境。对其他平台来说,你需要自行查找正确的地址来下载和安装 GnuPG。 +如果你正在使用 Linux,你应该已经安装过了 GnuPG。在 Mac 上,你应该安装 [GPG-Suite][1],或者使用 `brew` 安装 `gnupg2`。在 Windows 上,你应该安装 [GPG4Win][2],并且为了可以工作,你可能需要调整指南中的部分命令,除非你设置了类似 Unix 的环境。对其他平台来说,你需要自行查找正确的地址来下载和安装 GnuPG。 -#### GnuPG 1 vs. 2 +##### GnuPG 1 vs. 2 -GnuPG v.1 和 GnuPG v.2 都实现了同样的标准,但它们提供不兼容的库和命令行工具,所以许多发行版都发布了旧版本 1 和最新版本 2。你需要确保你总是使用 GnuPG v.2。 +GnuPG v.1 和 GnuPG v.2 都实现了同样的标准,但它们提供不兼容的库和命令行工具,所以许多发行版都带有了旧的版本 1 和最新的版本 2。你需要确保你总是使用 GnuPG v.2。 首先,运行: + ``` $ gpg --version | head -n1 - ``` -如果你看到 gpg (GnuPG) 1.4.x,说明你正使用 GnuPG v.1。尝试 gpg2 命令: +如果你看到 `gpg (GnuPG) 1.4.x`,说明你正使用 GnuPG v.1。尝试下 `gpg2` 命令: + ``` $ gpg2 --version | head -n1 - ``` -如果你看到 gpg (GnuPG) 2.x.x,说明你可以继续了。这篇指南将假设你使用 GnuPG 2.2 版本(或更晚)。如果你正使用 GnuPG 的 2.0 版本,本指南中某些命令可能无效,你应该考虑安装 GnuPG 最新的 2.2 版本 +如果你看到 `gpg (GnuPG) 2.x.x`,说明你可以继续了。这篇指南将假设你使用 GnuPG 2.2 版本(或更新)。如果你正使用 GnuPG 的 2.0 版本,本指南中某些命令可能无效,你应该考虑安装 GnuPG 最新的 2.2 版本 -#### 确保你总是使用 GnuPG v.2 +##### 确保你总是使用 GnuPG v.2 + +如果你 `gpg` 和 `gpg2` 命令都有,你应该确保总是使用 GnuPG v.2,而不是旧的版本。你可以通过设置别名来确保这一点: -如果你 gpg 和 gpg2 命令都有,你应该确保总是使用 GnuPG v.2,而不是旧的版本。你可以通过设置别名来确保这一点: ``` $ alias gpg=gpg2 - ``` -你可以把它放在你的 .bashrc 中,以确保它在你使用 gpg 命令时总是被加载。 +你可以把它放在你的 `.bashrc` 中,以确保它在你使用 `gpg` 命令时总是被加载。 在本系列的第 2 部分中,我们将介绍生成和保护你的 PGP 主密钥的基本步骤。 通过 Linux 基金会和 edX 的免费[“Introduction to Linux” ][3]课程了解关于 Linux 的更多信息。 - - - -------------------------------------------------------------------------------- via: https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools 作者:[Konstantin Ryabitsev][a] 译者:[kimii](https://github.com/kimii) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20180215 Check Linux Distribution Name and Version.md b/published/201804/20180215 Check Linux Distribution Name and Version.md new file mode 100644 index 0000000000..a4b8d45c56 --- /dev/null +++ b/published/201804/20180215 Check Linux Distribution Name and Version.md @@ -0,0 +1,251 @@ +查看 Linux 发行版名称和版本号的 8 种方法 +====== + +如果你加入了一家新公司,要为开发团队安装所需的软件并重启服务,这个时候首先要弄清楚它们运行在什么发行版以及哪个版本的系统上,你才能正确完成后续的工作。作为系统管理员,充分了解系统信息是首要的任务。 + +查看 Linux 发行版名称和版本号有很多种方法。你可能会问,为什么要去了解这些基本信息呢? + +因为对于诸如 RHEL、Debian、openSUSE、Arch Linux 这几种主流发行版来说,它们各自拥有不同的包管理器来管理系统上的软件包,如果不知道所使用的是哪一个发行版的系统,在软件包安装的时候就会无从下手,而且由于大多数发行版都是用 systemd 命令而不是 SysVinit 脚本,在重启服务的时候也难以执行正确的命令。 + +下面来看看可以使用那些基本命令来查看 Linux 发行版名称和版本号。 + +### 方法总览 + + * `lsb_release` 命令 + * `/etc/*-release` 文件 + * `uname` 命令 + * `/proc/version` 文件 + * `dmesg` 命令 + * YUM 或 DNF 命令 + * RPM 命令 + * APT-GET 命令 + +### 方法 1: lsb_release 命令 + +LSB(Linux 标准库Linux Standard Base)能够打印发行版的具体信息,包括发行版名称、版本号、代号等。 + +``` +# lsb_release -a +No LSB modules are available. +Distributor ID: Ubuntu +Description: Ubuntu 16.04.3 LTS +Release: 16.04 +Codename: xenial +``` + +### 方法 2: /etc/*-release 文件 + +release 文件通常被视为操作系统的标识。在 `/etc` 目录下放置了很多记录着发行版各种信息的文件,每个发行版都各自有一套这样记录着相关信息的文件。下面是一组在 Ubuntu/Debian 系统上显示出来的文件内容。 + +``` +# cat /etc/issue +Ubuntu 16.04.3 LTS \n \l + +# cat /etc/issue.net +Ubuntu 16.04.3 LTS + +# cat /etc/lsb-release +DISTRIB_ID=Ubuntu +DISTRIB_RELEASE=16.04 +DISTRIB_CODENAME=xenial +DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS" + +# cat /etc/os-release +NAME="Ubuntu" +VERSION="16.04.3 LTS (Xenial Xerus)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 16.04.3 LTS" +VERSION_ID="16.04" +HOME_URL="http://www.ubuntu.com/" +SUPPORT_URL="http://help.ubuntu.com/" +BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" +VERSION_CODENAME=xenial +UBUNTU_CODENAME=xenial + +# cat /etc/debian_version +9.3 +``` + +下面这一组是在 RHEL/CentOS/Fedora 系统上显示出来的文件内容。其中 `/etc/redhat-release` 和 `/etc/system-release` 文件是指向 `/etc/[发行版名称]-release` 文件的一个连接。 + +``` +# cat /etc/centos-release +CentOS release 6.9 (Final) + +# cat /etc/fedora-release +Fedora release 27 (Twenty Seven) + +# cat /etc/os-release +NAME=Fedora +VERSION="27 (Twenty Seven)" +ID=fedora +VERSION_ID=27 +PRETTY_NAME="Fedora 27 (Twenty Seven)" +ANSI_COLOR="0;34" +CPE_NAME="cpe:/o:fedoraproject:fedora:27" +HOME_URL="https://fedoraproject.org/" +SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" +BUG_REPORT_URL="https://bugzilla.redhat.com/" +REDHAT_BUGZILLA_PRODUCT="Fedora" +REDHAT_BUGZILLA_PRODUCT_VERSION=27 +REDHAT_SUPPORT_PRODUCT="Fedora" +REDHAT_SUPPORT_PRODUCT_VERSION=27 +PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" + +# cat /etc/redhat-release +Fedora release 27 (Twenty Seven) + +# cat /etc/system-release +Fedora release 27 (Twenty Seven) +``` + +### 方法 3: uname 命令 + +uname(unix name 的意思) 是一个打印系统信息的工具,包括内核名称、版本号、系统详细信息以及所运行的操作系统等等。 + +- **建议阅读:** [6种查看系统 Linux 内核的方法][1] + +``` +# uname -a +Linux localhost.localdomain 4.12.14-300.fc26.x86_64 #1 SMP Wed Sep 20 16:28:07 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux +``` + +以上运行结果说明使用的操作系统版本是 Fedora 26。 + +### 方法 4: /proc/version 文件 + +这个文件记录了 Linux 内核的版本、用于编译内核的 gcc 的版本、内核编译的时间,以及内核编译者的用户名。 + +``` +# cat /proc/version +Linux version 4.12.14-300.fc26.x86_64 ([email protected]) (gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC) ) #1 SMP Wed Sep 20 16:28:07 UTC 2017 +``` + +### 方法 5: dmesg 命令 + +dmesg(展示信息display message驱动程序信息driver message)是大多数类 Unix 操作系统上的一个命令,用于打印内核的消息缓冲区的信息。 + +``` +# dmesg | grep "Linux" +[ 0.000000] Linux version 4.12.14-300.fc26.x86_64 ([email protected]) (gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC) ) #1 SMP Wed Sep 20 16:28:07 UTC 2017 +[ 0.001000] SELinux: Initializing. +[ 0.001000] SELinux: Starting in permissive mode +[ 0.470288] SELinux: Registering netfilter hooks +[ 0.616351] Linux agpgart interface v0.103 +[ 0.630063] usb usb1: Manufacturer: Linux 4.12.14-300.fc26.x86_64 ehci_hcd +[ 0.688949] usb usb2: Manufacturer: Linux 4.12.14-300.fc26.x86_64 ohci_hcd +[ 2.564554] SELinux: Disabled at runtime. +[ 2.564584] SELinux: Unregistering netfilter hooks +``` + +### 方法 6: Yum/Dnf 命令 + +Yum(Yellowdog 更新器修改版Yellowdog Updater Modified)是 Linux 操作系统上的一个包管理工具,而 `yum` 命令被用于一些基于 RedHat 的 Linux 发行版上安装、更新、查找、删除软件包。 + +- **建议阅读:** [在 RHEL/CentOS 系统上使用 yum 命令管理软件包][2] + +``` +# yum info nano +Loaded plugins: fastestmirror, ovl +Loading mirror speeds from cached hostfile + * base: centos.zswap.net + * extras: mirror2.evolution-host.com + * updates: centos.zswap.net +Available Packages +Name : nano +Arch : x86_64 +Version : 2.3.1 +Release : 10.el7 +Size : 440 k +Repo : base/7/x86_64 +Summary : A small text editor +URL : http://www.nano-editor.org +License : GPLv3+ +Description : GNU nano is a small and friendly text editor. +``` + +下面的 `yum repolist` 命令执行后显示了 yum 的基础源仓库、额外源仓库、更新源仓库都来自 CentOS 7 仓库。 + +``` +# yum repolist +Loaded plugins: fastestmirror, ovl +Loading mirror speeds from cached hostfile + * base: centos.zswap.net + * extras: mirror2.evolution-host.com + * updates: centos.zswap.net +repo id repo name status +base/7/x86_64 CentOS-7 - Base 9591 +extras/7/x86_64 CentOS-7 - Extras 388 +updates/7/x86_64 CentOS-7 - Updates 1929 +repolist: 11908 +``` + +使用 `dnf` 命令也同样可以查看发行版名称和版本号。 + +- **建议阅读:** [在 Fedora 系统上使用 DNF(YUM 的一个分支)命令管理软件包][3] + +``` +# dnf info nano +Last metadata expiration check: 0:01:25 ago on Thu Feb 15 01:59:31 2018. +Installed Packages +Name : nano +Version : 2.8.7 +Release : 1.fc27 +Arch : x86_64 +Size : 2.1 M +Source : nano-2.8.7-1.fc27.src.rpm +Repo : @System +From repo : fedora +Summary : A small text editor +URL : https://www.nano-editor.org +License : GPLv3+ +Description : GNU nano is a small and friendly text editor. +``` + +### 方法 7: RPM 命令 + +RPM(红帽包管理器RedHat Package Manager)是在 CentOS、Oracle Linux、Fedora 这些基于 RedHat 的操作系统上的一个强大的命令行包管理工具,同样也可以帮助我们查看系统的版本信息。 + +- **建议阅读:** [在基于 RHEL 的系统上使用 RPM 命令管理软件包][4] + +``` +# rpm -q nano +nano-2.8.7-1.fc27.x86_64 +``` + +### 方法 8: APT-GET 命令 + +Apt-Get(高级打包工具Advanced Packaging Tool)是一个强大的命令行工具,可以自动下载安装新软件包、更新已有的软件包、更新软件包列表索引,甚至更新整个 Debian 系统。 + +- **建议阅读:** [在基于 Debian 的系统上使用 Apt-Get 和 Apt-Cache 命令管理软件包][5] + +``` +# apt-cache policy nano +nano: + Installed: 2.5.3-2ubuntu2 + Candidate: 2.5.3-2ubuntu2 + Version table: + * 2.5.3-2ubuntu2 500 + 500 http://nova.clouds.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages + 100 /var/lib/dpkg/status + 2.5.3-2 500 + 500 http://nova.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 Packages +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/check-find-linux-distribution-name-and-version/ + +作者:[Magesh Maruthamuthu][a] +译者:[HankChow](https://github.com/HankChow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/magesh/ +[1]:https://www.2daygeek.com/check-find-determine-running-installed-linux-kernel-version/ +[2]:https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/ +[3]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/ +[4]:https://www.2daygeek.com/rpm-command-examples/ +[5]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/ diff --git a/published/201804/20180215 What is a Linux -oops.md b/published/201804/20180215 What is a Linux -oops.md new file mode 100644 index 0000000000..a8e6f56f25 --- /dev/null +++ b/published/201804/20180215 What is a Linux -oops.md @@ -0,0 +1,71 @@ +什么是 Linux “oops”? +====== +> Linux 内核正在盯着你,当它检测到系统上运行的某些东西违反了正常内核行为时,它会关闭系统并发出一个“oops”! + +![](https://images.idgesg.net/images/article/2018/02/broken-wine-glass-100749404-large.jpg) + +如果你检查你的 Linux 系统上运行的进程,你可能会对一个叫做 “kerneloops” 的进程感到好奇。提示一下,它是 “kernel oops”,而不是 “kerne loops”。 + +坦率地说,“oops” 是 Linux 内核的一部分出现了偏差行为。你有做错了什么吗?可能没有。但有一些不对劲。而那个做了错事的进程可能已经被 CPU 结束。最糟糕的是,内核可能会报错并突然关闭系统。 + +请注意,“oops” 不是首字母缩略词。它不代表像“面向对象的编程和系统object-oriented programming and systems” 或“超出程序规范out of procedural specs” 之类的东西。它实际上就是“哎呀” (oops),就像你刚掉下一杯酒或踩在你的猫身上。哎呀! “oops” 的复数是 “oopses”。 + +oops 意味着系统上运行的某些东西违反了内核有关正确行为的规则。也许代码尝试采取不允许的代码路径或使用无效指针。不管它是什么,内核 —— 总是在监测进程的错误行为 —— 很可能会阻止特定进程,并将它做了什么的消息写入控制台、 `/var/log/dmesg` 或 `/var/log/kern.log` 中。 + +oops 可能是由内核本身引起的,也可能是某些进程试图让内核违反在系统上能做的事以及它们被允许做的事。 + +oops 将生成一个崩溃签名crash signature,这可以帮助内核开发人员找出错误并提高代码质量。 + +系统上运行的 kerneloops 进程可能如下所示: + +``` +kernoops 881 1 0 Feb11 ? 00:00:01 /usr/sbin/kerneloops +``` + +你可能会注意到该进程不是由 root 运行的,而是由名为 “kernoops” 的用户运行的,并且它的运行时间极少。实际上,分配给这个特定用户的唯一任务是运行 kerneloops。 + +``` +$ sudo grep kernoops /etc/passwd +kernoops:x:113:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false +``` + +如果你的 Linux 系统不带有 kerneloops(比如 Debian),你可以考虑添加它。查看这个 [Debian 页面][1]了解更多信息。 + +### 什么时候应该关注 oops? + +一般 oops 没什么大不了的。它在一定程度上取决于特定进程所扮演的角色。它也取决于 oops 的类别。 + +有些 oops 很严重,会导致系统恐慌system panic。从技术上讲,系统恐慌是 oops 的一个子集(即更严重的 oops)。当内核检测到的问题足够严重以至于内核认为它(内核)必须立即停止运行以防止数据丢失或对系统造成其他损害时会出现。因此,系统需要暂停并重新启动,以防止任何不一致导致不可用或不可靠。所以系统恐慌实际上是为了保护自己免受不可挽回的损害。 + +总之,所有的内核恐慌都是 oops,但并不是所有的 oops 都是内核恐慌。 + +`/var/log/kern.log` 和相关的轮转日志(`/var/log/kern.log.1`、`/var/log/kern.log.2` 等)包含由内核生成并由 syslog 处理的日志。 + +kerneloops 程序收集并默认将错误信息提交到 ,在那里它会被分析并呈现给内核开发者。此进程的配置详细信息在 `/etc/kerneloops.conf` 文件中指定。你可以使用下面的命令轻松查看设置: + +``` +$ sudo cat /etc/kerneloops.conf | grep -v ^# | grep -v ^$ +[sudo] password for shs: +allow-submit = ask +allow-pass-on = yes +submit-url = http://oops.kernel.org/submitoops.php +log-file = /var/log/kern.log +submit-pipe = /usr/share/apport/kernel_oops +``` + +在上面的(默认)设置中,内核问题可以被提交,但要求用户获得许可。如果设置为 `allow-submit = always`,则不会询问用户。 + +调试内核问题是使用 Linux 系统的更高级技巧之一。幸运的是,大多数 Linux 用户很少或从没有经历过 oops 或内核恐慌。不过,知道 kerneloops 这样的进程在系统中执行什么操作,了解可能会报告什么以及系统何时遇到严重的内核冲突也是很好的。 + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3254778/linux/what-is-a-linux-oops.html + +作者:[Sandra Henry-Stocker][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]:https://packages.debian.org/stretch/kerneloops diff --git a/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md b/published/201804/20180220 How to Get Started Using WSL in Windows 10.md similarity index 54% rename from translated/tech/20180220 How to Get Started Using WSL in Windows 10.md rename to published/201804/20180220 How to Get Started Using WSL in Windows 10.md index 5816c6fdfd..68f507399f 100644 --- a/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md +++ b/published/201804/20180220 How to Get Started Using WSL in Windows 10.md @@ -1,9 +1,11 @@ -如何在 Windows 10 上开启 WSL(Windows Subsystem for Linux) 之旅 +如何在 Windows 10 上开启 WSL 之旅 ====== +> WSL 可以让你访问 Windows 上的 Linux Bash shell。 + ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-main.png?itok=wJ5WrU9U) -在 [上一篇文章][1] 中,我们讨论过关于 Windows 的子系统 Linux(WSL)的目标用户。本文,我们将在 Windows 10 的设备上,开启 WSL 的旅程。 +在 [上一篇文章][1] 中,我们讨论过关于 Windows 的子系统 LinuxWindows Subsystem for Linux(WSL)的目标用户。本文,我们将在 Windows 10 的设备上,开启 WSL 的旅程。 ### 为 WSL 做准备 @@ -11,85 +13,82 @@ 这里有一张关于我的操作系统的截图。 -![kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9m][2] +![][2] -如果您安装了之前的版本,您有必要在 [这里][3] 下载并且安装 Windows 10 Fall Creator Update (FCU)。安装完毕后,更新设置(在开始菜单的搜索框中搜索 “updates”)。 +如果您安装了之前的版本,您需要在 [这里][3] 下载并且安装 Windows 10 Fall Creator Update (FCU)。安装完毕后,安装可用的更新(在开始菜单的搜索框中搜索 “updates”)。 -前往 `启用或关闭 Windows 功能` 页面,然后滚动至底部,如截图所示,勾选 `适用于 Linux 的 Windows 子系统`,点击确定。它将会下载安装需要的包。 +前往 “启用或关闭 Windows 功能” ,然后滚动至底部,如截图所示,勾选 “适用于 Linux 的 Windows 子系统”,点击确定。它将会下载安装需要的包。 -![oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7x][4] +![][4] 安装完成之后,系统将会询问是否重启。是的,重启设备吧。WSL 在系统重启之前不会启动,如下所示: -![GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aN][5] +![][5] -一旦您的系统重启,返回 `启用或关闭 Windows 功能` 页面,确认 `适用于 Linux 的 Windows 子系统` 已经被勾选。 +一旦您的系统重启,返回 “启用或关闭 Windows 功能” 页面,确认 “适用于 Linux 的 Windows 子系统” 已经被勾选。 ### 在 Windows 中安装 Linux 在 Windows 中安装 Linux,有很多方式,这里我们选择一种最简单的方式。打开 Microsoft Store,搜索 Linux。您将看到下面的选项: -![YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7][6] +![][6] -点击 `获取`,之后 Windows 商店将会提供三个选项:Ubuntu,openSUSE Leap 42 和 SUSE Linux Enterprise Server。您可以一并安装上述三个发行版,并且它们可以同时运行。为了能使用 SLE,您需要订阅消息。 +点击 “获取”,之后 Windows 商店将会提供三个选项:Ubuntu、openSUSE Leap 42 和 SUSE Linux Enterprise Server。您可以一并安装上述三个发行版,并且它们可以同时运行。为了能使用 SLE,您需要一份订阅。 -在此,我将安装 openSUSE Leap 42 和 Ubuntu。选中您想要的发行版,点击获得按钮并安装。一旦安装完毕,您就可以在 Windows 中启动 openSUSE。为了方便访问,可以将其固定到开始菜单中。 +在此,我将安装 openSUSE Leap 42 和 Ubuntu。选中您想要的发行版,点击“获得”按钮并安装。一旦安装完毕,您就可以在 Windows 中启动 openSUSE。为了方便访问,可以将其固定到开始菜单中。 -![4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OA][7] +![][7] ### 在 Windwods 中使用 Linux -当您启动发行版,它将会打开一个 Bash Shell 并且安装此发行版。安装完毕之后,您就可以开始使用了。您需要留意,openSUSE 中并没有用户,它直接运行在 root 用户下,但是 Ubuntu 会询问您是否创建用户。在 Ubuntu,您可以执行 sudo 用户管理任务。 +当您启动该发行版,它将会打开一个 Bash Shell 并且安装此发行版。安装完毕之后,您就可以开始使用了。您需要留意,openSUSE 中并没有(普通)用户,它直接运行在 `root` 用户下,但是 Ubuntu 会询问您是否创建用户。在 Ubuntu,您可以以 `sudo` 用户执行管理任务。 在 openSUSE 上,您可以很轻松的创建一个用户: + ``` # useradd [username] - # passwd [username] - ``` 为此用户创建一个新的密码。例如: + ``` # useradd swapnil - # passwd swapnil - ``` -您可以通过 su 命令从 root 用户切换过来。 +您可以通过 `su` 命令从 root 用户切换过来。 + ``` su swapnil - ``` -您需要非根用户来执行许多任务,比如使用 rsync 移动文件到本地设备。 +您需要非根用户来执行许多任务,比如使用 `rsync` 移动文件到本地设备。 而首要任务是更新发行版。对于 openSUSE 来说,您应该: + ``` zypper up - ``` 而对于 Ubuntu: + ``` sudo apt-get update - sudo apt-get dist-upgrade - ``` -![7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9][8] +![][8] -现在,您就在 Windows 上拥有了原生 Linux Bash shell。想在 Windows 10 上通过 ssh 连接您的服务器?不需要安装 puTTY 或是 Cygwin。打开 Bash 之后,就可以通过 ssh 进入您的服务器。简单之至。 +现在,您就在 Windows 上拥有了原生的 Linux Bash shell。想在 Windows 10 上通过 `ssh` 连接您的服务器?不需要安装 puTTY 或是 Cygwin。打开 Bash 之后,就可以通过 `ssh` 进入您的服务器。简单之至。 -想通过 rsync 同步文件到您的服务器?直接使用 rsync。它切实的将我们的 Windows 设备转变得更为实用,帮助那些需要使用原生 Linux 命令和 Linux 工具的用户避开虚拟机,大开方便之门。 +想通过 `rsync` 同步文件到您的服务器?直接使用 `rsync`。它切实的将我们的 Windows 设备转变得更为实用,帮助那些需要使用原生 Linux 命令和 Linux 工具的用户避开虚拟机,大开方便之门。 -### 找不到 Fedora? +### Fedora 在哪里? -您可能想了解 Fedora。可惜,商城里并没有 Fedora。Fedora 项目发布负责人在 Twitter 上表示,“我们正在解决一些非技术性问题。现在可能提供不了更多了。” +您可能奇怪为什么没有 Fedora。可惜,商城里并没有 Fedora。Fedora 项目发布负责人在 Twitter 上表示,“我们正在解决一些非技术性问题。现在可能提供不了更多了。” -我们并不确定这些非技术性问题是什么。当一些用户询问 WSL 团队为何不发布 Fedora,毕竟它也是一个开源项目。项目负责人 Rich Turner 在 Microsoft [回应][9],“我们没有发布其他 IP 到应用商店的政策。我们相信,相较于被微软或是其他非权威人士,社区更希望看到发行版由发行版所有者发布。” +我们并不确定这些非技术性问题是什么。当一些用户询问 WSL 团队为何不发布 Fedora,毕竟它也是一个开源项目。项目负责人 Rich Turner 在 Microsoft [回应][9],“我们有一个不发布其他知识产权到应用商店的政策。我们相信,相较于被微软或是其他非权威人士,社区更希望看到发行版由发行版所有者发布。” 因此,微软不方便在 Windows 商店中直接发布 Debian 或是 Arch 系统。这些任务应该落在他们的官方团队中,应该由他们将发行版带给 Windows 10 的用户。 @@ -103,7 +102,7 @@ via: https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-1 作者:[SWAPNIL BHARTIYA][a] 译者:[CYLeft](https://github.com/CYLeft) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180221 Getting started with SQL.md b/published/201804/20180221 Getting started with SQL.md similarity index 64% rename from translated/tech/20180221 Getting started with SQL.md rename to published/201804/20180221 Getting started with SQL.md index f579c03c76..167b2d6f89 100644 --- a/translated/tech/20180221 Getting started with SQL.md +++ b/published/201804/20180221 Getting started with SQL.md @@ -1,11 +1,13 @@ -开始使用 SQL +SQL 入门 ====== +> 使用 SQL 构建一个关系数据库比你想的更容易。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X) -使用 SQL 构建数据库比大多数人想象得要简单。实际上,你甚至不需要成为一个有经验的程序员来使用 SQL 创建数据库。在本文中,我将解释如何使用 MySQL 5.6 来创建简单的关系型数据库管理系统(RDMS)。在开始之前,我想快速地感谢 [SQL Fiddle][1],这是我用来运行脚本的工具。它提供了一个用于测试简单脚本的有用的沙箱。 +使用 SQL 构建数据库比大多数人想象得要简单。实际上,你甚至不需要成为一个有经验的程序员就可以使用 SQL 创建数据库。在本文中,我将解释如何使用 MySQL 5.6 来创建简单的关系型数据库管理系统(RDMS)。在开始之前,我想顺便感谢一下 [SQL Fiddle][1],这是我用来运行脚本的工具。它提供了一个用于测试简单脚本的有用的沙箱。 -在本教程中,我将构建一个使用下面实体关系图(ERD)中显示的简单架构的数据库。数据库列出了学生和正在学习的课程。为了保持简单,我使用了两个实体(即表),只有一种关系和依赖关系。这两个实体称为 `dbo_students` 和 `dbo_courses`。 +在本教程中,我将构建一个使用如下实体关系图(ERD)中显示的简单架构的数据库。数据库列出了学生和正在学习的课程。为了保持简单,我使用了两个实体(即表),只有一种关系和依赖。这两个实体称为 `dbo_students` 和 `dbo_courses`。 ![](https://opensource.com/sites/default/files/u128651/erd.png) @@ -20,87 +22,62 @@ ### 构建架构 -要构建数据库,使用 `CREATE TABLE <表名>` 命令,然后定义每个字段的名称和数据类型。数据库使用 `VARCHAR(n)` (字符串)和 `INT(n)` (整数),其中 n 表示可以存储的值的长度。例如 `INT(2)` 可能是 01。 +要构建数据库,使用 `CREATE TABLE <表名>` 命令,然后定义每个字段的名称和数据类型。数据库使用 `VARCHAR(n)` (字符串)和 `INT(n)` (整数),其中 `n` 表示可以存储的值的长度。例如 `INT(2)` 可以是 `01`。 这是用于创建两个表的代码: + ``` CREATE TABLE dbo_students - ( - -  student_id INT(2) AUTO_INCREMENT NOT NULL, - -  student_name VARCHAR(50), - -  course_studied INT(2), - -  PRIMARY KEY (student_id) - + student_id INT(2) AUTO_INCREMENT NOT NULL, + student_name VARCHAR(50), + course_studied INT(2), + PRIMARY KEY (student_id) ); - - CREATE TABLE dbo_courses - ( - -  course_id INT(2) AUTO_INCREMENT NOT NULL, - -  course_name VARCHAR(30), - -  PRIMARY KEY (course_id) - + course_id INT(2) AUTO_INCREMENT NOT NULL, + course_name VARCHAR(30), + PRIMARY KEY (course_id) ); ``` -`NOT NULL` 意味着字段不能为空,`AUTO_INCREMENT` 意味着当一个新的元组被添加时,ID 号将自动生成,并将 1 添加到先前存储的 ID 号,来强化各实体之间的完整参照性。 `PRIMARY KEY` 是每个表的惟一标识符属性。这意味着每个元组都有自己的不同的标识。 +`NOT NULL` 意味着字段不能为空,`AUTO_INCREMENT` 意味着当一个新的元组被添加时,ID 号将自动生成,是对先前存储的 ID 号加 1,以强化各实体之间的完整参照性。 `PRIMARY KEY` 是每个表的惟一标识符属性。这意味着每个元组都有自己的不同的标识。 ### 关系作为一种约束 就目前来看,这两张表格是独立存在的,没有任何联系或关系。要连接它们,必须标识一个外键。在 `dbo_students` 中,外键是 `course_studied`,其来源在 `dbo_courses` 中,意味着该字段被引用。SQL 中的特定命令为 `CONSTRAINT`,并且将使用另一个名为 `ALTER TABLE` 的命令添加这种关系,这样即使在架构构建完毕后,也可以编辑表。 以下代码将关系添加到数据库构造脚本中: + ``` ALTER TABLE dbo_students - ADD CONSTRAINT FK_course_studied - FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); ``` + 使用 `CONSTRAINT` 命令实际上并不是必要的,但这是一个好习惯,因为它意味着约束可以被命名并且使维护更容易。现在数据库已经完成了,是时候添加一些数据了。 ### 将数据添加到数据库 -`INSERT INTO <表名>`是用于直接选择将数据添加到哪些属性(即字段)的命令。首先声明实体名称,然后声明属性。命令下边是添加到实体的数据,从而创建一个元组。如果指定了 `NOT NULL`,这表示该属性不能留空。以下代码将展示如何向表中添加记录: +`INSERT INTO <表名>` 是用于直接选择要添加哪些属性(即字段)数据的命令。首先声明实体名称,然后声明属性,下边是添加到实体的数据,从而创建一个元组。如果指定了 `NOT NULL`,这表示该属性不能留空。以下代码将展示如何向表中添加记录: + ``` INSERT INTO dbo_courses(course_id,course_name) - VALUES(001,'Software Engineering'); - INSERT INTO dbo_courses(course_id,course_name) - VALUES(002,'Computer Science'); - INSERT INTO dbo_courses(course_id,course_name) - VALUES(003,'Computing'); - - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(001,'student1',001); - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(002,'student2',002); - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(003,'student3',002); - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(004,'student4',003); ``` @@ -109,128 +86,89 @@ VALUES(004,'student4',003); ### 查询 查询遵循使用以下命令的集合结构: + ``` SELECT - FROM - WHERE ``` -要显示 `dbo_courses` 实体内的所有记录并显示课程代码和课程名称,请使用 * 。 这是一个通配符,它消除了键入所有属性名称的需要。(在生产数据库中不建议使用它。)此处查询的代码是: +要显示 `dbo_courses` 实体内的所有记录并显示课程代码和课程名称,请使用 `*` 。 这是一个通配符,它消除了键入所有属性名称的需要。(在生产数据库中不建议使用它。)此处查询的代码是: + ``` SELECT * - FROM dbo_courses ``` 此处查询的输出显示表中的所有元组,因此可显示所有可用课程: + ``` | course_id |          course_name | - |-----------|----------------------| - |         1 | Software Engineering | - |         2 |     Computer Science | - |         3 |            Computing | ``` -在以后的文章中,我将使用三种类型的连接之一来解释更复杂的查询:Inner,Outer 或 Cross。 +在后面的文章中,我将使用三种类型的连接之一来解释更复杂的查询:内连接、外连接和交叉连接。 这是完整的脚本: + ``` CREATE TABLE dbo_students - ( - -  student_id INT(2) AUTO_INCREMENT NOT NULL, - -  student_name VARCHAR(50), - -  course_studied INT(2), - -  PRIMARY KEY (student_id) - + student_id INT(2) AUTO_INCREMENT NOT NULL, + student_name VARCHAR(50), + course_studied INT(2), + PRIMARY KEY (student_id) ); - - CREATE TABLE dbo_courses - ( - -  course_id INT(2) AUTO_INCREMENT NOT NULL, - -  course_name VARCHAR(30), - -  PRIMARY KEY (course_id) - + course_id INT(2) AUTO_INCREMENT NOT NULL, + course_name VARCHAR(30), + PRIMARY KEY (course_id) ); - - ALTER TABLE dbo_students - ADD CONSTRAINT FK_course_studied - FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); - - INSERT INTO dbo_courses(course_id,course_name) - VALUES(001,'Software Engineering'); - INSERT INTO dbo_courses(course_id,course_name) - VALUES(002,'Computer Science'); - INSERT INTO dbo_courses(course_id,course_name) - VALUES(003,'Computing'); - - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(001,'student1',001); - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(002,'student2',002); - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(003,'student3',002); - INSERT INTO dbo_students(student_id,student_name,course_studied) - VALUES(004,'student4',003); - - SELECT * - FROM dbo_courses ``` ### 学习更多 -SQL 并不困难;我认为它比编程简单,并且该语言对于不同的数据库系统是通用的。 请注意,`dbo.<实体>` (译者注:文章中使用的是 `dbo_<实体>`) 不是必需的实体命名约定;我之所以使用,仅仅是因为它是 Microsoft SQL Server 中的标准。 +SQL 并不困难;我认为它比编程简单,并且该语言对于不同的数据库系统是通用的。 请注意,实体关系图中 `dbo.<实体>` (LCTT 译注:文章中使用的是 `dbo_<实体>`)不是必需的实体命名约定;我之所以使用,仅仅是因为它是 Microsoft SQL Server 中的标准。 如果你想了解更多,在网络上这方面的最佳指南是 [W3Schools.com][2] 中对所有数据库平台的 SQL 综合指南。 -请随意使用我的数据库。另外,如果你有任何建议或疑问,请在评论中回复。(译注:请点击原文地址进行评论回应) +请随意使用我的数据库。另外,如果你有任何建议或疑问,请在评论中回复。 -------------------------------------------------------------------------------- -via: [https://opensource.com/article/18/2/getting-started-sql](https://opensource.com/article/18/2/getting-started-sql) +via: https://opensource.com/article/18/2/getting-started-sql 作者:[Aaron Cocker][a] 译者:[MjSeven](https://github.com/MjSeven) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md b/published/201804/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md similarity index 54% rename from translated/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md rename to published/201804/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md index e6e53b1f63..9eb5f84eca 100644 --- a/translated/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md +++ b/published/201804/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md @@ -1,4 +1,4 @@ -用 PGP 保护代码完整性 - 第二部分:生成你的主密钥 +用 PGP 保护代码完整性(二):生成你的主密钥 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/binary-1538717_1920.png?itok=kv_sxSnf) @@ -7,127 +7,101 @@ ### 清单 - 1. 生成一个 4096 位的 RSA 主密钥 (ESSENTIAL) - - 2. 使用 paperkey 备份你的 RSA 主密钥 (ESSENTIAL) - - 3. 添加所有相关的身份 (ESSENTIAL) - - - + 1. 生成一个 4096 位的 RSA 主密钥 (必要) + 2. 使用 paperkey 备份你的 RSA 主密钥 (必要) + 3. 添加所有相关的身份 (必要) ### 考虑事项 -#### 理解“主”(认证)密钥 +### 理解“主”(认证)密钥 在本节和下一节中,我们将讨论“主密钥”和“子密钥”。理解以下内容很重要: - 1. 在“主密钥”和“子密钥”之间没有技术上的区别。 - - 2. 在创建时,我们赋予每个密钥特定的能力来分配功能限制 - + 1. 在“主密钥”和“子密钥”之间没有技术上的区别。 + 2. 在创建时,我们赋予每个密钥特定的能力来分配功能限制。 3. 一个 PGP 密钥有四项能力 - * [S] 密钥可以用于签名 - * [E] 密钥可以用于加密 - - * [A] 密钥可以用于身份认证 - + * \[A] 密钥可以用于身份认证 * [C] 密钥可以用于认证其他密钥 - 4. 一个密钥可能有多种能力 - - - -带有[C] (认证)能力的密钥被认为是“主”密钥,因为它是唯一可以用来表明与其他密钥关系的密钥。只有[C]密钥可以被用于: +带有 [C] (认证)能力的密钥被认为是“主”密钥,因为它是唯一可以用来表明与其他密钥关系的密钥。只有 [C] 密钥可以被用于: * 添加或撤销其他密钥(子密钥)的 S/E/A 能力 - - * 添加,更改或撤销密钥关联的身份(uids) - + * 添加、更改或撤销密钥关联的身份(uid) * 添加或更改本身或其他子密钥的到期时间 - * 为了网络信任目的为其它密钥签名 +在自由软件的世界里,[C] 密钥就是你的数字身份。一旦你创建该密钥,你应该格外小心地保护它并且防止它落入坏人的手中。 - - -在自由软件的世界里,[C]密钥就是你的数字身份。一旦你创建该密钥,你应该格外小心地保护它并且防止它落入坏人的手中。 - -#### 在你创建主密钥前 +### 在你创建主密钥前 在你创建的你的主密钥前,你需要选择你的主要身份和主密码。 -##### 主要身份 +#### 主要身份 身份使用邮件中发件人一栏相同格式的字符串: + ``` Alice Engineer - ``` -你可以在任何时候创建新的身份,取消旧的,并且更改你的“主要”身份。由于主要身份在所有 GnuPG 操作中都展示,你应该选择正式的和最有可能用于 PGP 保护通信的名字和邮件地址,比如你的工作地址或者用于在项目提交(commit)时签名的地址。 +你可以在任何时候创建新的身份,取消旧的,并且更改你的“主要”身份。由于主要身份在所有 GnuPG 操作中都展示,你应该选择正式的和最有可能用于 PGP 保护通信的名字和邮件地址,比如你的工作地址或者用于在项目提交commit时签名的地址。 -##### 密码 +#### 密码 -密码(passphrase)专用于在存储在磁盘上时使用对称加密算法对私钥进行加密。如果你的 .gnupg 目录的内容被泄露,那么一个好的密码就是小偷能够在线模拟你的最后一道防线,这就是为什么设置一个好的密码很重要的原因。 +密码passphrase专用于私钥存储在磁盘上时使用对称加密算法对其进行加密。如果你的 `.gnupg` 目录的内容被泄露,那么一个好的密码就是小偷能够在线假冒你的最后一道防线,这就是为什么设置一个好的密码很重要的原因。 -一个强密码的好的指导是用丰富或混合的词典的 3-4 个词,而不引用自流行来源(歌曲,书籍,口号)。由于你将相当频繁地使用该密码,所以它应当易于 输入和记忆。 +一个强密码最好使用丰富或混合的词典的 3-4 个词,而不引用自流行来源(歌曲、书籍、口号)。由于你将相当频繁地使用该密码,所以它应当易于输入和记忆。 -##### 算法和密钥强度 +#### 算法和密钥强度 -尽管现在 GnuPG 已经支持椭圆曲线加密一段时间了,我们仍坚持使用 RSA 密钥,至少稍长一段时间。虽然现在就可以开始使用 ED25519 密钥,但你可能会碰到无法正确处理它们的工具和硬件设备。 +尽管现在 GnuPG 已经支持椭圆曲线加密一段时间了,但我们仍坚持使用 RSA 密钥,至少较长一段时间会这样。虽然现在就可以开始使用 ED25519 密钥,但你可能会碰到无法正确处理它们的工具和硬件设备。 -如果后续的指南中我们说 2048 位的密钥对 RSA 公钥加密的生命周期已经足够,你可能也会好奇主密钥为什么是 4096 位。 原因很大程度是由于社会因素而非技术上的:主密钥在密钥链上恰好是最明显的,同时如果你的主密钥位数比一些你交互的开发者的少,他们将不可避免地负面评价你。 +在后续的指南中我们说 2048 位的密钥对 RSA 公钥加密的生命周期已经足够,你可能也会好奇主密钥为什么是 4096 位。 原因很大程度是由于社会因素而非技术上的:主密钥在密钥链上是最显眼的,如果你的主密钥位数比一些和你交互的开发者的少,他们肯定会鄙视你。 #### 生成主密钥 -为了生成你的主密钥,请使用以下命令,并且将“Alice Engineer:”替换为正确值 +为了生成你的主密钥,请使用以下命令,并且将 “Alice Engineer” 替换为正确值。 + ``` $ gpg --quick-generate-key 'Alice Engineer ' rsa4096 cert - ``` -一个要求输入密码的对话框将弹出。然后,你可能需要移动鼠标或输入一些密钥才能生成足够的熵,直到命令完成。 +这将弹出一个要求输入密码的对话框。然后,你可能需要移动鼠标或随便按一些键才能生成足够的熵,直到该命令完成。 查看命令输出,它就像这样: + ``` pub rsa4096 2017-12-06 [C] [expires: 2019-12-06] 111122223333444455556666AAAABBBBCCCCDDDD uid Alice Engineer - ``` -注意第二行的长字符串 -- 它是你新生成的密钥的完整指纹。密钥 ID(key IDs)可以用以下三种不同形式表达: +注意第二行的长字符串 —— 它是你新生成的密钥的完整指纹。密钥 ID(Key ID)可以用以下三种不同形式表达: - * Fingerprint,一个完整的 40 个字符的密钥标识符 - - * Long,指纹的最后 16 个字符(AAAABBBBCCCCDDDD) - - * Short,指纹的最后 8 个字符(CCCCDDDD) + * 指纹Fingerprint,一个完整的 40 个字符的密钥标识符 + * 长密钥 IDLong,指纹的最后 16 个字符(AAAABBBBCCCCDDDD) + * 短密钥 IDShort,指纹的最后 8 个字符(CCCCDDDD) - - - -你应该避免使用 8 个字符的短密钥 ID(short key IDs),因为它们不足够唯一。 +你应该避免使用 8 个字符的短密钥 ID,因为它们不足够唯一。 这里,我建议你打开一个文本编辑器,复制你新密钥的指纹并粘贴。你需要在接下来几步中用到它,所以将它放在旁边会很方便。 #### 备份你的主密钥 -出于灾后恢复的目的 -- 同时特别的如果你试图使用 Web of Trust 并且收集来自其他项目开发者的密钥签名 -- 你应该创建你的私钥的 硬拷贝备份。万一所有其它的备份机制都失败了,这应当是最后的补救措施。 +出于灾后恢复的目的 —— 同时特别的如果你试图使用 Web of Trust 并且收集来自其他项目开发者的密钥签名 —— 你应该创建你的私钥的硬拷贝备份。万一所有其它的备份机制都失败了,这应当是最后的补救措施。 -创建一个你的私钥的可打印的硬拷贝的最好方法是使用为此而写的软件 paperkey。Paperkey 在所有 Linux 发行版上可用,在 Mac 上也可以通过 brew 安装 paperkey。 +创建一个你的私钥的可打印的硬拷贝的最好方法是使用为此而写的软件 `paperkey`。`paperkey` 在所有 Linux 发行版上可用,在 Mac 上也可以通过 brew 安装 `paperkey`。 + +运行以下命令,用你密钥的完整指纹替换 `[fpr]`: -运行以下命令,用你密钥的完整指纹替换[fpr]: ``` $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt - ``` -输出将采用易于 OCR 或手动输入的格式,以防如果你需要恢复它的话。打印出该文件,然后拿支笔,并在纸的边缘写下密钥的密码。这是必要的一步,因为密钥输出仍然使用密码加密,并且如果你更改了密钥的密码,你不会记得第一次创建的密钥是什么 -- 我保证。 +输出将采用易于 OCR 或手动输入的格式,以防如果你需要恢复它的话。打印出该文件,然后拿支笔,并在纸的边缘写下密钥的密码。这是必要的一步,因为密钥输出仍然使用密码加密,并且如果你更改了密钥的密码,你不会记得第一次创建的密钥是什么 —— 我保证。 将打印结果和手写密码放入信封中,并存放在一个安全且保护好的地方,最好远离你家,例如银行保险库。 @@ -135,26 +109,26 @@ $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt #### 添加相关身份 -如果你有多个相关的邮件地址(个人,工作,开源项目等),你应该将其添加到主密钥中。你不需要为任何你不希望用于 PGP 的地址(例如,可能不是你的校友地址)这样做。 +如果你有多个相关的邮件地址(个人、工作、开源项目等),你应该将其添加到主密钥中。你不需要为任何你不希望用于 PGP 的地址(例如,可能不是你的校友地址)这样做。 + +该命令是(用你完整的密钥指纹替换 `[fpr]`): -该命令是(用你完整的密钥指纹替换[fpr]): ``` $ gpg --quick-add-uid [fpr] 'Alice Engineer ' - ``` -你可以查看你已经使用的 UIDs: +你可以查看你已经使用的 UID: + ``` $ gpg --list-key [fpr] | grep ^uid - ``` -##### 选择主 UID +#### 选择主 UID GnuPG 将会把你最近添加的 UID 作为你的主 UID,如果这与你想的不同,你应该改回来: + ``` $ gpg --quick-set-primary-uid [fpr] 'Alice Engineer ' - ``` 下次,我们将介绍如何生成 PGP 子密钥,它是你实际用于日常工作的密钥。 @@ -167,10 +141,10 @@ via: https://www.linux.com/blog/learn/PGP/2018/2/protecting-code-integrity-pgp-p 作者:[KONSTANTIN RYABITSEV][a] 译者:[kimii](https://github.com/kimii) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.linux.com/users/mricon -[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools +[1]:https://linux.cn/article-9524-1.html [2]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/published/201804/20180221 cTop - A CLI Tool For Container Monitoring.md b/published/201804/20180221 cTop - A CLI Tool For Container Monitoring.md new file mode 100644 index 0000000000..a32ecf7701 --- /dev/null +++ b/published/201804/20180221 cTop - A CLI Tool For Container Monitoring.md @@ -0,0 +1,132 @@ +cTop:用于容器监控的命令行工具 +====== + +最近 Linux 容器很火,我们中的大多数人甚至已经在使用它,同时一些人也开始学习它。 + +我们已经介绍了有名的 GUI(用户图形界面) 工具如 Portainer 和 Rancher 。这将会有助于我们通过 GUI 管理容器。 + +这篇指南将会通过 cTop 命令帮助我们理解和监控 Linux 容器。它是一个类似 `top` 命令的命令行工具。 + +### 什么是 cTop + +[ctop][1] 为多个容器提供了一个简洁凝练的实时指标概览。它是一个类 `top` 的针对容器指标的界面。 + +它展示了容器指标比如 CPU 利用率、内存利用率、磁盘 I/O 读写、进程 ID(PID)和网络发送(TX - 从此服务器发送)以及接受(RX - 此服务器接受)。 + +`ctop` 带有对 Docker 和 runc 的内建支持;对其他容器和集群系统的连接计划在未来版本中推出。 + +它不需要任何参数并且默认使用 Docker 主机变量。 + +**建议阅读:** + +- [Portainer – 一个简单的 Docker 图形管理界面][2] +- [Rancher – 一个完整的生产环境容器管理平台][3] + +### 如何安装 cTop + +开发者提供了一个简单的 shell 脚本来帮助我们直接使用 `ctop`。我们要做的,只是在 `/bin` 目录下下载 `ctop` shell 文件来保证全局访问。最后给予 `ctop` 脚本文件执行权限。 + +在 `/usr/local/bin` 目录下下载 ctop shell 脚本。 + +``` +$ sudo wget https://github.com/bcicen/ctop/releases/download/v0.7/ctop-0.7-linux-amd64 -O /usr/local/bin/ctop +``` + +对 `ctop` shell 脚本设置执行权限。 + +``` +$ sudo chmod +x /usr/local/bin/ctop +``` + +另外你可以通过 docker 来安装和运行 `ctop`。在此之前先确保你已经安装过 docker。为了安装 docker,参考以下链接。 + +**建议阅读:** + +- [如何在 Linux 上安装 Docker][4] +- [如何在 Linux 上玩转 Docker 镜像][5] +- [如何在 Linux 上玩转 Docker 容器][6] +- [如何在 Docker 容器中安装,运行应用][7] + +``` +$ docker run --rm -ti \ + --name=ctop \ + -v /var/run/docker.sock:/var/run/docker.sock \ + quay.io/vektorlab/ctop:latest +``` + +### 如何使用 cTop + +直接启动 `ctop` 程序而不用任何参数。默认它绑定的 `a` 键用来展示所有容器(运行的和没运行的)。 + +`ctop` 头部显示你的系统时间和容器的总数。 + +``` +$ ctop +``` + +你可能得到以下类似输出。 + +![][9] + +### 如何管理容器 + +你可以使用 `ctop` 来管理容器。选择一个你想要管理的容器然后按下回车键,选择所需选项如 `start`、`stop`、`remove` 等。 + +![][10] + +### 如何给容器排序 + +默认 `ctop` 使用 `state` 字段来给容器排序。按下 `s` 键来按不同的方面给容器排序。 + +![][11] + +### 如何查看容器指标 + +如何你想要查看关于容器的更多细节和指标,只用选择你想要查看的相应容器然后按 `o` 键。 + +![][12] + +### 如何查看容器日志 + +选择你想要查看日志的相应容器然后按 `l` 键。 + +![][13] + +### 仅显示活动容器 + +使用 `-a` 选项运行 `ctop` 命令来仅显示活动容器 + +![][14] + +### 打开帮助对话框 + +运行 `ctop`,只需按 `h` 键来打开帮助部分。 + +![][15] + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux/ + +作者:[2DAYGEEK][a] +译者:[kimii](https://github.com/kimii) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/2daygeek/ +[1]:https://github.com/bcicen/ctop +[2]:https://www.2daygeek.com/portainer-a-simple-docker-management-gui/ +[3]:https://www.2daygeek.com/rancher-a-complete-container-management-platform-for-production-environment/ +[4]:https://www.2daygeek.com/install-docker-on-centos-rhel-fedora-ubuntu-debian-oracle-archi-scentific-linux-mint-opensuse/ +[5]:https://www.2daygeek.com/list-search-pull-download-remove-docker-images-on-linux/ +[6]:https://www.2daygeek.com/create-run-list-start-stop-attach-delete-interactive-daemonized-docker-containers-on-linux/ +[7]:https://www.2daygeek.com/install-run-applications-inside-docker-containers/ +[8]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[9]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-1.png +[10]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-2.png +[11]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-3.png +[12]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-4a.png +[13]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-7.png +[14]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-5.png +[15]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-6.png diff --git a/translated/tech/20180222 How to configure an Apache web server.md b/published/201804/20180222 How to configure an Apache web server.md similarity index 58% rename from translated/tech/20180222 How to configure an Apache web server.md rename to published/201804/20180222 How to configure an Apache web server.md index a6c0d2cd73..dd8d68cf2b 100644 --- a/translated/tech/20180222 How to configure an Apache web server.md +++ b/published/201804/20180222 How to configure an Apache web server.md @@ -1,23 +1,25 @@ -# 配置 Apache Web 服务器 +如何配置 Apache Web 服务器 +========== + +> 学习如何在 Apache 上托管你自己的网站,这是一个可靠、流行且易于配置的 Web 服务器。 ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openweb-osdc-lead.png?itok=yjU4KliG) -我自己的网站已经有很多年了。自从 20 多年前从 OS/2 切换到 Linux 以来,我已经将 [Apache][1] 作为我的服务器软件。Apache 是可靠的、众所周知的,并且基本的安装配置也很容易。对于更复杂的设置(比如多个网站)并不是那么困难。 +我托管自己的网站已经有很多年了。自从 20 多年前从 OS/2 切换到 Linux 以来,我一直将 [Apache][1] 作为我的服务器软件。Apache 是可靠、流行的,且基本的安装配置也很容易。对于更复杂的设置(比如多个网站)也并不是那么困难。 Apache Web 服务器的安装和配置必须以 root 身份执行。 防火墙的配置也需要以 root 身份执行。 使用浏览器查看安装配置的结果应该以非 root 用户的身份完成。 (我在我的虚拟主机上使用 `student` 这个用户。) ### 安装 -注意:我使用的实验环境是安装有 Fedora 27 的虚拟机,Apache 版本为 2.4.29。 如果您使用的是不同的发行版或不同版本的Fedora,您的命令以及配置文件的位置和内容可能会有所不同。 但是,您需要修改的配置行是相同的。 +注意:我使用的实验环境是安装有 Fedora 27 的虚拟机,Apache 版本为 2.4.29。 如果您使用的是不同的发行版或不同版本的 Fedora,您的命令以及配置文件的位置和内容可能会有所不同。 但是,您需要修改的配置行是相同的。 Apache Web 服务器非常容易安装。 在我的 CentOS 6.x 服务器上,它只需要一个简单的 `yum` 命令。 它会安装所有必要的依赖(如果需要的话)。 我在我的 Fedora 虚拟机上使用了下面的 `dnf` 命令。 除了命令本身的名称之外, `dnf` 和 `yum` 的语法是相同的。 ``` dnf -y install httpd - ``` -VM (虚拟机) 非常容易安装,我正在使用它作为编写书籍的测试平台。 即使在这个系统上,在一分钟内只安装了六个依赖项。 +这个虚拟机是个非常基础的桌面环境,我正在使用它作为编写书籍的测试平台。 即使在这个系统上,也只安装了六个依赖项,用了一分钟。 Apache 的所有配置文件都位于 `/etc/httpd/conf` 和 `/etc/httpd/conf.d` 。网站的数据默认位于 `/var/www`,但如果你愿意,你可以改变它。 @@ -25,203 +27,142 @@ Apache 的所有配置文件都位于 `/etc/httpd/conf` 和 `/etc/httpd/conf.d` Apache 主要的配置文件是 `/etc/httpd/conf/httpd.conf` 。 它包含许多在基本安装中不需要更改的配置。 实际上,只需对此文件进行一些更改即可启动并运行一个简单的网站。 该文件非常大,因此,我不会将这篇文章与大量不必要的东西混淆起来,而只会显示那些需要更改的指令。 -首先,花点时间熟悉一下 `httpd.conf` 文件。我喜欢 Red Hat 的一个原因是它的配置文件注释非常的详细。 `httpd.conf` 文件也不例外,因为它有很好的注释。 使用这些注释来了解文件的配置。 +首先,花点时间熟悉一下 `httpd.conf` 文件。我喜欢 Red Hat 的一个原因是它的配置文件注释非常的详细。 `httpd.conf` 文件也不例外,因为它有很好的注释。可以使用这些注释来了解文件的配置。 -第一个要修改的是 `Listen` 配置项,它定义了 Apache 要监听页面请求的 IP 地址和端口。 现在,你只需要使这个网站可以从本地访问,所以使用 `localhost` 地址。 完成后,该行应该看起来像这样:( LCTT 注:localhost 既是 127.0.0.1,80 是端口) +第一个要修改的是 `Listen` 配置项,它定义了 Apache 要监听页面请求的 IP 地址和端口。 现在,你只需要使这个网站可以从本地访问,所以使用 `localhost` 地址。 完成后,该行应该看起来像这样:( LCTT 译注:`localhost` 的 IP 地址是 `127.0.0.1`,`80` 是端口) ``` Listen 127.0.0.1:80 - ``` -通过将此配置项设置为`localhost`的 IP 地址,Apache 将只侦听来自本地主机的连接。 如果您希望 Web 服务器侦听来自远程主机的连接,则可以使用主机的外部 IP 地址。 +通过将此配置项设置为 `localhost`的 IP 地址,Apache 将只侦听来自本地主机的连接。 如果您希望 Web 服务器侦听来自远程主机的连接,则可以使用主机的外部 IP 地址。 `DocumentRoot` 配置项指定组成网站页面的 HTML 文件的位置。 该配置项不需要更改,因为它已经指向标准位置。 该行应该看起来像这样: ``` DocumentRoot "/var/www/html" - ``` -Apache 安装包创建 `/var /www` 目录。 如果您想更改存储网站文件的位置,则使用此配置项来完成此操作。 例如,您可能想要为 `www` 子目录使用不同的名称,以更明确地识别网站。 这可能是这样的: +Apache 安装包会创建 `/var/www` 目录。 如果您想更改存储网站文件的位置,则使用此配置项来完成此操作。 例如,您可能想要为 `www` 目录使用不同的名称,以更明确地识别网站。 这可以是这样的: ``` DocumentRoot "/var/mywebsite/html" - ``` 这些是创建一个简单网站需要唯一修改的 Apache 配置项。 对于这个小练习,只对 `httpd.conf` 文件(`Listen` 配置项)进行了一些修改。 其它的配置项对于一个简单的 Web 服务器暂时无需配置。 -另一个需要改变的地方是:在我们的防火墙中打开端口 80。 我使用 [iptables][2] 作为我的防火墙,因此我更改 `/etc/ sysconfig/iptables` 文件以添加允许使用 HTTP 协议。 整个文件看起来像这样: +另一个需要改变的地方是:在我们的防火墙中打开端口 80。 我使用 [iptables][2] 作为我的防火墙,因此我更改 `/etc/sysconfig/iptables` 文件以添加允许使用 HTTP 协议。 整个文件看起来像这样: ``` # sample configuration for iptables service - # you can edit this manually or use system-config-firewall - # please do not ask us to add additional ports/services to this default configuration - *filter - :INPUT ACCEPT [0:0] - :FORWARD ACCEPT [0:0] - :OUTPUT ACCEPT [0:0] - -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT - -A INPUT -p icmp -j ACCEPT - -A INPUT -i lo -j ACCEPT - -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT - -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT - -A INPUT -j REJECT --reject-with icmp-host-prohibited - -A FORWARD -j REJECT --reject-with icmp-host-prohibited - COMMIT - ``` -我在文件的倒数第三行上添加了一个新行,它允许在端口 80 上输入流量。现在我重新加载 iptables 配置文件。 +我在文件的倒数第三行上添加了一个新行,它允许在端口 `80` 上输入流量。现在我重新加载 iptables 配置文件。 ``` [root@testvm1 ~]# cd /etc/sysconfig/ ; iptables-restore iptables - ``` ### 创建 index.html 文件 -`index.html` 文件是你使用域名访问网站而不是访问特定网页时的默认文件。在 `/var/www/html `中,创建一个名字为 `index.html` 的文件,在其中添加 `Hello World` 。你不需要添加任何的 HTML 标志去完成这项工作。web 服务器的唯一任务是提供文本数据流,服务器不知道日期是什么,也不知道如何呈现数据流。它只是将数据流传输给请求主机。 +`index.html` 文件是你使用域名访问网站而不是访问特定网页时的默认文件。在 `/var/www/html`中,创建一个名字为 `index.html` 的文件,在其中添加字符串 `Hello World` 。你不需要添加任何的 HTML 标志去完成这项工作。web 服务器的唯一任务是提供文本数据流,服务器不知道数据是什么,也不知道如何呈现它。它只是将数据流传输给请求主机。 保存文件后,将所有权设置为 `apache.apache` 。 ``` [root@testvm1 html]# chown apache.apache index.html - ``` ### 启动 Apache -Apache 很容易启动。 当前版本的 Fedora 使用 `systemd` 。 运行以下命令启动它,然后检查服务器的状态:(LCTT 注:systemctl 是一个 systemd 工具) +Apache 很容易启动。 当前版本的 Fedora 使用 systemd 。 运行以下命令启动它,然后检查服务器的状态:(LCTT 译注:`systemctl` 是一个 systemd 工具) ``` [root@testvm1 ~]# systemctl start httpd - [root@testvm1 ~]# systemctl status httpd - ● httpd.service - The Apache HTTP Server - -   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) - -   Active: active (running) since Thu 2018-02-08 13:18:54 EST; 5s ago - -     Docs: man:httpd.service(8) - - Main PID: 27107 (httpd) - -   Status: "Processing requests..." - -    Tasks: 213 (limit: 4915) - -   CGroup: /system.slice/httpd.service - -           ├─27107 /usr/sbin/httpd -DFOREGROUND - -           ├─27108 /usr/sbin/httpd -DFOREGROUND - -           ├─27109 /usr/sbin/httpd -DFOREGROUND - -           ├─27110 /usr/sbin/httpd -DFOREGROUND - -           └─27111 /usr/sbin/httpd -DFOREGROUND - - + Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) + Active: active (running) since Thu 2018-02-08 13:18:54 EST; 5s ago + Docs: man:httpd.service(8) + Main PID: 27107 (httpd) + Status: "Processing requests..." + Tasks: 213 (limit: 4915) + CGroup: /system.slice/httpd.service + ├─27107 /usr/sbin/httpd -DFOREGROUND + ├─27108 /usr/sbin/httpd -DFOREGROUND + ├─27109 /usr/sbin/httpd -DFOREGROUND + ├─27110 /usr/sbin/httpd -DFOREGROUND + └─27111 /usr/sbin/httpd -DFOREGROUND Feb 08 13:18:54 testvm1 systemd[1]: Starting The Apache HTTP Server... - Feb 08 13:18:54 testvm1 systemd[1]: Started The Apache HTTP Server. - ``` -您的服务器上的命令可能不同。在使用 SystemV 启动脚本的Linux系统上,命令如下: +您的服务器上的命令可能不同。在使用 SystemV 启动脚本的 Linux 系统上,命令如下: ``` [root@testvm1 ~]# service httpd start - Starting httpd: [Fri Feb 09 08:18:07 2018]          [  OK  ] - [root@testvm1 ~]# service httpd status - httpd (pid  14649) is running... - ``` -如果您的主机上有像 Firefox 或 Chrome 这样的浏览器,您可以在浏览器的 URL 行上使用 URL `localhost` 来显示您的 web 页面,尽管它很简单。您还可以使用像 [Lynx][3] 这样的文本模式 web 浏览器来查看 web 页面。首先,安装 Lynx (如果它还没有被安装)。 +如果您的主机上有像 Firefox 或 Chrome 这样的浏览器,您可以在浏览器的 URL 行上使用 URL `localhost` 来显示您的 web 页面,尽管看起来很简单。您还可以使用像 [Lynx][3] 这样的文本模式 web 浏览器来查看 web 页面。首先,安装 Lynx (如果它还没有被安装)。 ``` [root@testvm1 ~]# dnf -y install lynx - ``` 然后使用下面的命令来显示网页。 ``` [root@testvm1 ~]# lynx localhost - ``` 结果在我的终端中是这样的。我已经删除了页面上的很多空白。 ``` -  Hello World - - + Hello World - - - Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back. - -  Arrow keys: Up and Down to move.  Right to follow a link; Left to go back. - - H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list - + Arrow keys: Up and Down to move. Right to follow a link; Left to go back. + H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list``` ``` 接下来,编辑您的 `index.html` 文件并添加一些 HTML 标记,使其看起来像这样: ```

Hello World

- ``` -现在刷新浏览器。对于 Lynx,使用组合键 Ctrl + R 。 结果看起来有点不同。如果你的终端支持彩色的话文本是彩色显示的,Lynx 会显示标题,现在它处于居中状态。 在 GUI 浏览器中,文本将以大字体显示。 +现在刷新浏览器。对于 Lynx,使用组合键 `Ctrl + R` 。 结果看起来有点不同。如果你的终端支持彩色的话文本是彩色显示的,Lynx 会显示标题,现在它处于居中状态。 在 GUI 浏览器中,文本将以大字体显示。 ``` -                                   Hello World - - + Hello World - - - Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back. - -  Arrow keys: Up and Down to move.  Right to follow a link; Left to go back. - - H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list - + Arrow keys: Up and Down to move. Right to follow a link; Left to go back. + H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list ``` ### 后记 @@ -236,7 +177,7 @@ via: https://opensource.com/article/18/2/how-configure-apache-web-server 作者:[David Both][a] 译者:[amwps290](https://github.com/amwps290) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201804/20180226 5 keys to building open hardware.md b/published/201804/20180226 5 keys to building open hardware.md new file mode 100644 index 0000000000..e1ea822451 --- /dev/null +++ b/published/201804/20180226 5 keys to building open hardware.md @@ -0,0 +1,74 @@ +构建开源硬件的 5 个关键点 +====== + +> 最大化你的项目影响。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openhardwaretools.png?itok=DC1RC_1f) + +科学社区正在加速拥抱自由及开源硬件Free and Open Source Hardware([FOSH][1])。 研究员正忙于[改进他们自己的装备][2]并创造数以百计的基于分布式数字制造模型的设备来推动他们的研究。 + +热衷于 FOSH 的主要原因还是钱: 有研究表明,和专用设备相比,FOSH 可以[节省 90% 到 99% 的花费][3]。基于[开源硬件商业模式][4]的科学 FOSH 的商业化已经推动其快速地发展为一个新的工程领域,并为此定期[举行 GOSH 年会][5]。 + +特别的是,不止一本,而是关于这个主题的[两本学术期刊]:[Journal of Open Hardware] (由 Ubiquity 出版,一个新的自由访问出版商,同时出版了 [Journal of Open Research Software][8] )以及 [HardwareX][9](由 Elsevier 出版的一种[自由访问期刊][10],它是世界上最大的学术出版商之一)。 + +由于学术社区的支持,科学 FOSH 的开发者在获取制作乐趣并推进科学快速发展的同时获得学术声望。 + +### 科学 FOSH 的5个步骤 + +Shane Oberloier 和我在名为 Designs 的自由访问工程期刊上共同发表了一篇关于设计 FOSH 科学设备原则的[文章][11]。我们以滑动式烘干机为例,制造成本低于 20 美元,仅是专用设备价格的三百分之一。[科学][1]和[医疗][12]设备往往比较复杂,开发 FOSH 替代品将带来巨大的回报。 + +我总结了 5 个步骤(包括 6 条设计原则),它们在 Shane Oberloier 和我发表的文章里有详细阐述。这些设计原则也可以推广到非科学设备,而且制作越复杂的设计越能带来更大的潜在收益。 + +如果你对科学项目的开源硬件设计感兴趣,这些步骤将使你的项目的影响最大化。 + +1. 评估类似现有工具的功能,你的 FOSH 设计目标应该针对实际效果而不是现有的设计(LCTT 译注:作者的意思应该是不要被现有设计缚住手脚)。必要的时候需进行概念证明。 +2. 使用下列设计原则: + * 在设备生产中,仅使用自由和开源的软件工具链(比如,开源的 CAD 工具,例如 [OpenSCAD][13]、 [FreeCAD][14] 或 [Blender][15])和开源硬件。 + * 尝试减少部件的数量和类型并降低工具的复杂度 + * 减少材料的数量和制造成本。 + * 尽量使用能够分发的部件或使用方便易得的工具(比如 [RepRap 3D 打印机][16])进行部件的数字化生产。 + * 对部件进行[参数化设计][17],这使他人可以对你的设计进行个性化改动。相较于特例化设计,参数化设计会更有用。在未来的项目中,使用者可以通过修改核心参数来继续利用它们。 + * 所有不能使用现有的开源硬件以分布式的方式轻松且经济地制造的零件,必须选择现货产品以方便采购。 +3. 验证功能设计。 +4. 提供关于设计、生产、装配、校准和操作的详尽设备文档。包括原始设计文件而不仅仅是用于生产的。开源硬件协会Open Source Hardware Association对于开源设计的发布和文档化有额外的[指南][18],总结如下: + * 以通用的形式分享设计文件。 + * 提供详尽的材料清单,包括价格和采购信息。 + * 如果涉及软件,确保代码对大众来说清晰易懂。 + * 作为生产时的参考,必须提供足够的照片,以确保没有任何被遮挡的部分。 + * 在描述方法的章节,整个制作过程必须被细化成简单步骤以便复制此设计。 + * 在线上分享并指定许可证。这为用户提供了合理使用该设计的信息。 +5. 主动分享!为了使 FOSH 发扬光大,设计必须被广泛、频繁和有效地分享以提升它们的存在感。所有的文档应该在自由访问文献中发表,并与适当的社区共享。[开源科学框架][19]Open Science Framework是一个值得考虑的优雅的通用存储库,它由开源科学中心Center for Open Science主办,该中心设置为接受任何类型的文件并处理大型数据集。 + +这篇文章得到了 [Fulbright Finland][20] 的支持,该公司赞助了芬兰 Fulbright-Aalto 大学的特聘校席 Joshua Pearce 在开源科学硬件方面的研究工作。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/5-steps-creating-successful-open-hardware + +作者:[Joshua Pearce][a] +译者:[kennethXia](https://github.com/kennethXia) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jmpearce +[1]:https://opensource.com/business/16/4/how-calculate-open-source-hardware-return-investment +[2]:https://opensource.com/node/16840 +[3]:http://www.appropedia.org/Open-source_Lab +[4]:https://www.academia.edu/32004903/Emerging_Business_Models_for_Open_Source_Hardware +[5]:http://openhardware.science/ +[6]:https://opensource.com/life/16/7/hardwarex-open-access-journal +[7]:https://openhardware.metajnl.com/ +[8]:https://openresearchsoftware.metajnl.com/ +[9]:https://www.journals.elsevier.com/hardwarex +[10]:https://opensource.com/node/30041 +[11]:https://www.academia.edu/35603319/General_Design_Procedure_for_Free_and_Open-Source_Hardware_for_Scientific_Equipment +[12]:https://www.academia.edu/35382852/Maximizing_Returns_for_Public_Funding_of_Medical_Research_with_Open_source_Hardware +[13]:http://www.openscad.org/ +[14]:https://www.freecadweb.org/ +[15]:https://www.blender.org/ +[16]:http://reprap.org/ +[17]:https://en.wikipedia.org/wiki/Parametric_design +[18]:https://www.oshwa.org/sharing-best-practices/ +[19]:https://osf.io/ +[20]:http://www.fulbright.fi/en diff --git a/published/201804/20180226 How to Use WSL Like a Linux Pro.md b/published/201804/20180226 How to Use WSL Like a Linux Pro.md new file mode 100644 index 0000000000..18e0edd1a8 --- /dev/null +++ b/published/201804/20180226 How to Use WSL Like a Linux Pro.md @@ -0,0 +1,105 @@ +如何像 Linux 专家那样使用 WSL +============================================================ + +> 在本 WSL 教程中了解如何执行像挂载 USB 驱动器和操作文件等任务。 + +![WSL](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-pro.png?itok=e65wEEAw "WSL") + +在[之前的教程][4]中,我们学习了如何在 Windows 10 上设置 WSL。你可以在 Windows 10 中使用 WSL 执行许多 Linux 命令。无论是基于 Linux 的系统还是 macOS,它们的许多系统管理任务都是在终端内部完成的。然而,Windows 10 缺乏这样的功能。你想运行一个 cron 任务么?不行。你想 SSH 进入你的服务器,然后 `rsync` 文件么?没门。如何用强大的命令行工具管理本地文件,而不是使用缓慢和不可靠的 GUI 工具呢? + +在本教程中,你将看到如何使用 WSL 执行除了管理之外的任务 —— 例如挂载 USB 驱动器和操作文件。你需要运行一个完全更新的 Windows 10 并选择一个 Linux 发行版。我在[上一篇文章][5]中介绍了这些步骤,所以如果你跟上进度,那就从那里开始。让我们开始吧。 + +### 保持你的 Linux 系统更新 + +事实上,当你通过 WSL 运行 Ubuntu 或 openSUSE 时,其底层并没有运行 Linux 内核。然而,你必须保持你的发行版完整更新,以保护你的系统免受任何新的已知漏洞的影响。由于在 Windows 应用商店中只有两个免费的社区发行版,所以教程将只覆盖以下两个:openSUSE 和 Ubuntu。 + +更新你的 Ubuntu 系统: + +``` +# sudo apt-get update +# sudo apt-get dist-upgrade +``` + +运行 openSUSE 的更新: + +``` +# zypper up +``` + +您还可以使用 `dup` 命令将 openSUSE 升级到最新版本。但在运行系统升级之前,请使用上一个命令运行更新。 + +``` +# zypper dup +``` + +**注意:** openSUSE 默认为 root 用户。如果你想执行任何非管理员任务,请切换到非特权用户。您可以这篇[文章][6]中了解如何在 openSUSE上 创建用户。 + +### 管理本地文件 + +如果你想使用优秀的 Linux 命令行工具来管理本地文件,你可以使用 WSL 轻松完成此操作。不幸的是,WSL 还不支持像 `lsblk` 或 `mount` 这样的东西来挂载本地驱动器。但是,你可以 `cd` 到 C 盘并管理文件: + +``` +/mnt/c/Users/swapnil/Music +``` + +我现在在 C 盘的 Music 目录下。 + +要安装其他驱动器、分区和外部 USB 驱动器,你需要创建一个挂载点,然后挂载该驱动器。 + +打开文件资源管理器并检查该驱动器的挂载点。假设它在 Windows 中被挂载为 S:\。 + +在 Ubuntu/openSUSE 终端中,为驱动器创建一个挂载点。 + +``` +sudo mkdir /mnt/s +``` + +现在挂载驱动器: + +``` +mount -f drvfs S: /mnt/s +``` + +挂载完毕后,你现在可以从发行版访问该驱动器。请记住,使用 WSL 方式运行的发行版将会看到 Windows 能看到的内容。因此,你无法挂载在 Windows 上无法原生挂载的 ext4 驱动器。 + +现在你可以在这里使用所有这些神奇的 Linux 命令。想要将文件从一个文件夹复制或移动到另一个文件夹?只需运行 `cp` 或 `mv` 命令。 + +``` +cp /source-folder/source-file.txt /destination-folder/ +cp /music/classical/Beethoven/symphony-2.mp3 /plex-media/music/classical/ +``` + +如果你想移动文件夹或大文件,我会推荐 `rsync` 而不是 `cp` 命令: + +``` +rsync -avzP /music/classical/Beethoven/symphonies/ /plex-media/music/classical/ +``` + +耶! + +想要在 Windows 驱动器中创建新目录,只需使用 `mkdir` 命令。 + +想要在某个时间设置一个 cron 作业来自动执行任务吗?继续使用 `crontab -e` 创建一个 cron 作业。十分简单。 + +你还可以在 Linux 中挂载网络/远程文件夹,以便你可以使用更好的工具管理它们。我的所有驱动器都插在树莓派或者服务器上,因此我只需 `ssh` 进入该机器并管理硬盘。在本地计算机和远程系统之间传输文件可以再次使用 `rsync` 命令完成。 + +WSL 现在已经不再是测试版了,它将继续获得更多新功能。我很兴奋的两个特性是 `lsblk` 命令和 `dd` 命令,它们允许我在 Windows 中本机管理我的驱动器并创建可引导的 Linux 驱动器。如果你是 Linux 命令行的新手,[前一篇教程][7]将帮助你开始使用一些最基本的命令。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/how-use-wsl-linux-pro + +作者:[SWAPNIL BHARTIYA][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/arnieswap +[1]:https://www.linux.com/licenses/category/used-permission +[2]:https://blogs.msdn.microsoft.com/commandline/learn-about-windows-console-and-windows-subsystem-for-linux-wsl/ +[3]:https://www.linux.com/files/images/wsl-propng +[4]:https://linux.cn/article-9545-1.html +[5]:https://linux.cn/article-9545-1.html +[6]:https://linux.cn/article-9545-1.html +[7]:https://www.linux.com/learn/how-use-linux-command-line-basics-cli diff --git a/published/201804/20180301 How to add fonts to Fedora.md b/published/201804/20180301 How to add fonts to Fedora.md new file mode 100644 index 0000000000..55e089758a --- /dev/null +++ b/published/201804/20180301 How to add fonts to Fedora.md @@ -0,0 +1,57 @@ +如何将字体添加到 Fedora +=================== + +![](https://fedoramagazine.org/wp-content/uploads/2017/11/install-fonts-1024x433.jpg) + +字体可帮助你通过设计以创意的方式表达你的想法。无论给图片加标题、编写演示文稿,还是设计问候语或广告,字体都可以将你的想法提升到更高水平。很容易仅仅为了它们的审美品质而爱上它们。幸运的是,Fedora 使安装字体变得简单。以下是如何做的。 + +### 全系统安装 + +如果你在系统范围内安装字体,那么它可以让所有用户使用。此方式的最佳方法是使用官方软件库中的 RPM 软件包。 + +开始前打开 Fedora Workstation 中的 “Software” 工具,或者其他使用官方仓库的工具。选择横栏中选择 “Add-ons” 类别。接着在该类别中选择 “Fonts”。你会看到类似于下面截图中的可用字体: + + [![](https://fedoramagazine.org/wp-content/uploads/2017/11/Software-fonts-1024x768.png)][1] + +当你选择一种字体时,会出现一些细节。根据几种情况,你可能能够预览字体的一些示例文本。点击 “Install” 按钮将其添加到你的系统。根据系统速度和网络带宽,完成此过程可能需要一些时间。 + +你还可以在字体细节中通过 “Remove” 按钮删除前面带有勾的已经安装的字体。 + +### 个人安装 + +如果你以兼容格式:.ttf、 otf 、.ttc、.pfa 、.pfb 或者 .pcf 下载了字体,则此方法效果更好。这些字体扩展名不应通过将它们放入系统文件夹来安装在系统范围内。这种类型的非打包字体不能自动更新。它们也可能会在稍后干扰一些软件操作。安装这些字体的最佳方法是安装在你自己的个人数据目录中。 + +打开 Fedora Workstation 中的 “Files” 应用或你选择的类似文件管理器应用。如果你使用 “Files”,那么可能需要使用 `Ctrl+H` 组合键来显示隐藏的文件和文件夹。查找 `.fonts` 文件夹并将其打开。如果你没有 `.fonts` 文件夹,请创建它。 (记住最前面的点并全部使用小写。) + +将已下载的字体文件复制到 `.fonts` 文件夹中。此时你可以关闭文件管理器。打开一个终端并输入以下命令: + +``` +fc-cache +``` + +这将重建字体缓存,帮助 Fedora 可以找到并引用它。你可能还需要重新启动需要使用新字体的应用程序,例如 Inkscape 或 LibreOffice。你重新启动后,新的字体应该就可以使用了。 + +* * * + +照片由 [Raphael Schaller][2] 发布在 [Unsplash][3] 中。 + +-------------------------------------------------------------------------------- + +作者简介: + +Paul W. Frields 自 1997 年以来一直是 Linux 用户和爱好者,并于 2003 年 Fedora 发布不久后加入项目。他是 Fedora 项目委员会的创始成员之一,并从事文档、网站发布、倡导、工具链开发和维护软件工作。他于 2008 年 2 月至 2010 年 7 月在红帽担任 Fedora 项目负责人,现任红帽公司工程部经理。他目前和他的妻子和两个孩子一起住在弗吉尼亚州。 + +----------------------------- + +via: https://fedoramagazine.org/add-fonts-fedora/ + +作者:[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/wp-content/uploads/2017/11/Software-fonts.png +[2]:https://unsplash.com/photos/GkinCd2enIY?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[3]:https://unsplash.com/search/photos/fonts?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText diff --git a/published/201804/20180302 10 Quick Tips About sudo command for Linux systems.md b/published/201804/20180302 10 Quick Tips About sudo command for Linux systems.md new file mode 100644 index 0000000000..bb6280ff4b --- /dev/null +++ b/published/201804/20180302 10 Quick Tips About sudo command for Linux systems.md @@ -0,0 +1,212 @@ +Linux 系统中 sudo 命令的 10 个技巧 +====== + +![Linux-sudo-command-tips][1] + +### 概览 + +`sudo` 表示 “**s**uper**u**ser **do**”。 它允许已验证的用户以其他用户的身份来运行命令。其他用户可以是普通用户或者超级用户。然而,大部分时候我们用它来以提升的权限来运行命令。 + +`sudo` 命令与安全策略配合使用,默认安全策略是 `sudoers`,可以通过文件 `/etc/sudoers` 来配置。其安全策略具有高度可拓展性。人们可以开发和分发他们自己的安全策略作为插件。 + +### 与 su 的区别 + +在 GNU/Linux 中,有两种方式可以用提升的权限来运行命令: + + * 使用 `su` 命令 + * 使用 `sudo` 命令 + +`su` 表示 “**s**witch **u**ser”。使用 `su`,我们可以切换到 root 用户并且执行命令。但是这种方式存在一些缺点: + + * 我们需要与他人共享 root 的密码。 + * 因为 root 用户为超级用户,我们不能授予受控的访问权限。 + * 我们无法审查用户在做什么。 + +`sudo` 以独特的方式解决了这些问题。 + + 1. 首先,我们不需要妥协来分享 root 用户的密码。普通用户使用他们自己的密码就可以用提升的权限来执行命令。 + 2. 我们可以控制 `sudo` 用户的访问,这意味着我们可以限制用户只执行某些命令。 + 3. 除此之外,`sudo` 用户的所有活动都会被记录下来,因此我们可以随时审查进行了哪些操作。在基于 Debian 的 GNU/Linux 中,所有活动都记录在 `/var/log/auth.log` 文件中。 + +本教程后面的部分阐述了这些要点。 + +### 实际动手操作 sudo + +现在,我们对 sudo 有了大致的了解。让我们实际动手操作吧。为了演示,我使用 Ubuntu。但是,其它发行版本的操作应该是相同的。 + +#### 允许 sudo 权限 + +让我们添加普通用户为 `sudo` 用户吧。在我的情形中,用户名为 `linuxtechi`。 + +1) 按如下所示编辑 `/etc/sudoers` 文件: + +``` +$ sudo visudo +``` + +2) 添加以下行来允许用户 `linuxtechi` 有 sudo 权限: + +``` +linuxtechi ALL=(ALL) ALL +``` + +上述命令中: + + * `linuxtechi` 表示用户名 + * 第一个 `ALL` 指示允许从任何终端、机器访问 `sudo` + * 第二个 `(ALL)` 指示 `sudo` 命令被允许以任何用户身份执行 + * 第三个 `ALL` 表示所有命令都可以作为 root 执行 + + +#### 以提升的权限执行命令 + +要用提升的权限执行命令,只需要在命令前加上 `sudo`,如下所示: + +``` +$ sudo cat /etc/passwd +``` + +当你执行这个命令时,它会询问 `linuxtechi` 的密码,而不是 root 用户的密码。 + +#### 以其他用户执行命令 + +除此之外,我们可以使用 `sudo` 以另一个用户身份执行命令。例如,在下面的命令中,用户 `linuxtechi` 以用户 `devesh` 的身份执行命令: + +``` +$ sudo -u devesh whoami +[sudo] password for linuxtechi: +devesh +``` + +#### 内置命令行为 + +`sudo` 的一个限制是 —— 它无法使用 Shell 的内置命令。例如, `history` 记录是内置命令,如果你试图用 `sudo` 执行这个命令,那么会提示如下的未找到命令的错误: + +``` +$ sudo history +[sudo] password for linuxtechi: +sudo: history: command not found + +``` + +**访问 root shell** + +为了克服上述问题,我们可以访问 root shell,并在那里执行任何命令,包括 Shell 的内置命令。 + +要访问 root shell, 执行下面的命令: + +``` +$ sudo bash +``` + +执行完这个命令后——您将观察到提示符变为井号(`#`)。 + +### 技巧 + +这节我们将讨论一些有用的技巧,这将有助于提高生产力。大多数命令可用于完成日常任务。 + +#### 以 sudo 用户执行之前的命令 + +让我们假设你想用提升的权限执行之前的命令,那么下面的技巧将会很有用: + +``` +$ sudo !4 +``` + +上面的命令将使用提升的权限执行历史记录中的第 4 条命令。 + +#### 在 Vim 里面使用 sudo 命令 + +很多时候,我们编辑系统的配置文件时,在保存时才意识到我们需要 root 访问权限来执行此操作。因为这个可能让我们丢失我们对文件的改动。没有必要惊慌,我们可以在 Vim 中使用下面的命令来解决这种情况: + +``` +:w !sudo tee % +``` + +上述命令中: + + * 冒号 (`:`) 表明我们处于 Vim 的退出模式 + * 感叹号 (`!`) 表明我们正在运行 shell 命令 + * `sudo` 和 `tee` 都是 shell 命令 + * 百分号 (`%`) 表明从当前行开始的所有行 + + + +#### 使用 sudo 执行多个命令 + +至今我们用 `sudo` 只执行了单个命令,但我们可以用它执行多个命令。只需要用分号 (`;`) 隔开命令,如下所示: + +``` +$ sudo -- bash -c 'pwd; hostname; whoami' + +``` + +上述命令中 + + * 双连字符 (`--`) 停止命令行切换 + * `bash` 表示要用于执行命令的 shell 名称 + * `-c` 选项后面跟着要执行的命令 + + + +#### 无密码运行 sudo 命令 + +当第一次执行 `sudo` 命令时,它会提示输入密码,默认情形下密码被缓存 15 分钟。但是,我们可以避免这个操作,并使用 `NOPASSWD` 关键字禁用密码认证,如下所示: + +``` +linuxtechi ALL=(ALL) NOPASSWD: ALL +``` + +#### 限制用户执行某些命令 + +为了提供受控访问,我们可以限制 `sudo` 用户只执行某些命令。例如,下面的行只允许执行 `echo` 和 `ls` 命令 。 + +``` +linuxtechi ALL=(ALL) NOPASSWD: /bin/echo /bin/ls +``` + +#### 深入了解 sudo + +让我们进一步深入了解 `sudo` 命令。 + +``` +$ ls -l /usr/bin/sudo +-rwsr-xr-x 1 root root 145040 Jun 13  2017 /usr/bin/sudo +``` + +如果仔细观察文件权限,则发现 `sudo` 上启用了 setuid 位。当任何用户运行这个二进制文件时,它将以拥有该文件的用户权限运行。在所示情形下,它是 root 用户。 + + +为了演示这一点,我们可以使用 `id` 命令,如下所示: + +``` +$ id +uid=1002(linuxtechi) gid=1002(linuxtechi) groups=1002(linuxtechi) +``` + +当我们不使用 `sudo` 执行 `id` 命令时,将显示用户 `linuxtechi` 的 id。 + +``` +$ sudo id +uid=0(root) gid=0(root) groups=0(root) + +``` + +但是,如果我们使用 `sudo` 执行 `id` 命令时,则会显示 root 用户的 id。 + +### 结论 + +从这篇文章可以看出 —— `sudo` 为普通用户提供了更多受控访问。使用这些技术,多用户可以用安全的方式与 GNU/Linux 进行交互。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxtechi.com/quick-tips-sudo-command-linux-systems/ + +作者:[Pradeep Kumar][a] +译者:[szcf-weiya](https://github.com/szcf-weiya) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxtechi.com/author/pradeep/ +[1]:https://www.linuxtechi.com/wp-content/uploads/2018/03/Linux-sudo-command-tips.jpg diff --git a/translated/tech/20180307 An Open Source Desktop YouTube Player For Privacy-minded People.md b/published/201804/20180307 An Open Source Desktop YouTube Player For Privacy-minded People.md similarity index 82% rename from translated/tech/20180307 An Open Source Desktop YouTube Player For Privacy-minded People.md rename to published/201804/20180307 An Open Source Desktop YouTube Player For Privacy-minded People.md index 20a352349d..4dc842ff4c 100644 --- a/translated/tech/20180307 An Open Source Desktop YouTube Player For Privacy-minded People.md +++ b/published/201804/20180307 An Open Source Desktop YouTube Player For Privacy-minded People.md @@ -1,4 +1,4 @@ -注重隐私的开源桌面 YouTube 播放器 +FreeTube:注重隐私的开源桌面 YouTube 播放器 ====== ![](https://www.ostechnix.com/wp-content/uploads/2018/03/Freetube-720x340.png) @@ -13,36 +13,34 @@ * 本地存储订阅、历史记录和已保存的视频。 * 导入/备份订阅。 * 迷你播放器。 -* 轻/黑暗的主题。 +* 亮/暗的主题。 * 免费、开源。 * 跨平台。 - - ### 安装 FreeTube -进入[**发布页面**][1]并根据你使用的操作系统获取版本。在本指南中,我将使用 **.tar.gz** 文件。 +进入[发布页面][1]并根据你使用的操作系统获取版本。在本指南中,我将使用 **.tar.gz** 文件。 + ``` $ wget https://github.com/FreeTubeApp/FreeTube/releases/download/v0.1.3-beta/FreeTube-linux-x64.tar.xz - ``` 解压下载的归档: + ``` $ tar xf FreeTube-linux-x64.tar.xz - ``` 进入 Freetube 文件夹: + ``` $ cd FreeTube-linux-x64/ - ``` 使用命令启动 Freeube: + ``` $ ./FreeTub - ``` 这就是 FreeTube 默认界面的样子。 @@ -51,7 +49,7 @@ $ ./FreeTub ### 用法 -FreeTube 目前使用 **YouTube API ** 搜索视频。然后,它使用 **Youtube-dl HTTP API** 获取原始视频文件并在基础的 HTML5 视频播放器中播放它们。由于订阅、历史记录和已保存的视频都存储在本地系统中,因此你的详细信息将不会发送给 Google 或其他任何人。 +FreeTube 目前使用 **YouTube API** 搜索视频。然后,它使用 **Youtube-dl HTTP API** 获取原始视频文件并在基础的 HTML5 视频播放器中播放它们。由于订阅、历史记录和已保存的视频都存储在本地系统中,因此你的详细信息将不会发送给 Google 或其他任何人。 在搜索框中输入视频名称,然后按下回车键。FreeTube 会根据你的搜索查询列出结果。 @@ -67,9 +65,7 @@ FreeTube 目前使用 **YouTube API ** 搜索视频。然后,它使用 **Youtu 请注意,FreeTube 仍处于 **beta** 阶段,所以仍然有 bug。如果有任何 bug,请在本指南最后给出的 GitHub 页面上报告。 -干杯! - - +干杯! -------------------------------------------------------------------------------- @@ -77,7 +73,7 @@ via: https://www.ostechnix.com/freetube-an-open-source-desktop-youtube-player-fo 作者:[SK][a] 译者:[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/) 荣誉推出 diff --git a/published/201804/20180308 Dive into BPF a list of reading material.md b/published/201804/20180308 Dive into BPF a list of reading material.md new file mode 100644 index 0000000000..9137cfd3a6 --- /dev/null +++ b/published/201804/20180308 Dive into BPF a list of reading material.md @@ -0,0 +1,733 @@ +深入理解 BPF:一个阅读清单 +============================================================ + +_~ [更新于][146] 2017-11-02 ~_ + +## 什么是 BPF? + +BPF,及伯克利包过滤器**B**erkeley **P**acket **F**ilter,最初构想提出于 1992 年,其目的是为了提供一种过滤包的方法,并且要避免从内核空间到用户空间的无用的数据包复制行为。它最初是由从用户空间注入到内核的一个简单的字节码构成,它在那个位置利用一个校验器进行检查 —— 以避免内核崩溃或者安全问题 —— 并附着到一个套接字上,接着在每个接收到的包上运行。几年后它被移植到 Linux 上,并且应用于一小部分应用程序上(例如,`tcpdump`)。其简化的语言以及存在于内核中的即时编译器(JIT),使 BPF 成为一个性能卓越的工具。 + +然后,在 2013 年,Alexei Starovoitov 对 BPF 进行彻底地改造,并增加了新的功能,改善了它的性能。这个新版本被命名为 eBPF (意思是 “extended BPF”),与此同时,将以前的 BPF 变成 cBPF(意思是 “classic” BPF)。新版本出现了如映射和尾调用tail call这样的新特性,并且 JIT 编译器也被重写了。新的语言比 cBPF 更接近于原生机器语言。并且,在内核中创建了新的附着点。 + +感谢那些新的钩子,eBPF 程序才可以被设计用于各种各样的情形下,其分为两个应用领域。其中一个应用领域是内核跟踪和事件监控。BPF 程序可以被附着到探针(kprobe),而且它与其它跟踪模式相比,有很多的优点(有时也有一些缺点)。 + +另外一个应用领域是网络编程。除了套接字过滤器外,eBPF 程序还可以附加到 tc(Linux 流量控制工具)的入站或者出站接口上,以一种很高效的方式去执行各种包处理任务。这种使用方式在这个领域开创了一个新的天地。 + +并且 eBPF 通过使用为 IO Visor 项目开发的技术,使它的性能进一步得到提升:也为 XDP(“eXpress Data Path”)添加了新的钩子,XDP 是不久前添加到内核中的一种新式快速路径。XDP 与 Linux 栈组合,然后使用 BPF ,使包处理的速度更快。 + +甚至一些项目,如 P4、Open vSwitch,[考虑][155] 或者开始去接洽使用 BPF。其它的一些,如 CETH、Cilium,则是完全基于它的。BPF 是如此流行,因此,我们可以预计,不久之后,将围绕它有更多工具和项目出现 … + +## 深入理解字节码 + +就像我一样:我的一些工作(包括 [BEBA][156])是非常依赖 eBPF 的,并且在这个网站上以后的几篇文章将关注于这个主题。按理说,在深入到细节之前,我应该以某种方式去介绍 BPF —— 我的意思是,真正的介绍,在第一节所提供的简要介绍上更多地介绍在 BPF 上开发的新功能:什么是 BPF 映射?尾调用?内部结构是什么样子?等等。但是,在这个网站上已经有很多这个主题的介绍了,而且,我也不希望去写另一篇 “BPF 介绍” 的重复文章。 + +毕竟,我花费了很多的时间去阅读和学习关于 BPF 的知识,因此,在这里我们将要做什么呢,我收集了非常多的关于 BPF 的阅读材料:介绍、文档,也有教程或者示例。这里有很多的材料可以去阅读,但是,为了去阅读它,首先要去 _找到_ 它。因此,为了能够帮助更多想去学习和使用 BPF 的人,现在的这篇文章给出了一个资源清单。这里有各种阅读材料,它可以帮你深入理解内核字节码的机制。 + +## 资源 + +![](https://qmonnet.github.io/whirl-offload/img/icons/pic.svg) + +### 简介 + +这篇文章中下面的链接提供了 BPF 的基本概述,或者,一些与它密切相关的一些主题。如果你对 BPF 非常陌生,你可以在这些介绍文章中挑选出一篇你喜欢的文章去阅读。如果你已经理解了 BPF,你可以针对特定的主题去阅读,下面是阅读清单。 + +#### 关于 BPF + +**关于 eBPF 的常规介绍**: + +* [全面介绍 eBPF][193](Matt Flemming,on LWN.net,December 2017): + + 一篇写的很好的,并且易于理解的,介绍 eBPF 子系统组件的概述文章。 + +* [利用 BPF 和 XDP 实现可编程的内核网络数据路径][53]  (Daniel Borkmann, OSSNA17, Los Angeles, September 2017): + + 快速理解所有的关于 eBPF 和 XDP 的基础概念的最好讲稿中的一篇(主要是关于网络处理的) + +* [BSD 包过滤器][54] (Suchakra Sharma, June 2017):  + + 一篇非常好的介绍文章,主要是关于跟踪方面的。 + +* [BPF:跟踪及更多][55](Brendan Gregg, January 2017): + + 主要内容是跟踪使用案例相关的。 + +* [Linux BPF 的超强功能][56] (Brendan Gregg, March 2016): + + 第一部分是关于火焰图flame graph的使用。 + +* [IO Visor][57](Brenden Blanco, SCaLE 14x, January 2016): + + 介绍了 **IO Visor 项目**。 + +* [大型机上的 eBPF][58](Michael Holzheu, LinuxCon, Dubin, October 2015) + +* [在 Linux 上新的(令人激动的)跟踪新产品][59](Elena Zannoni, LinuxCon, Japan, 2015) + +* [BPF — 内核中的虚拟机][60](Alexei Starovoitov, February 2015): + + eBPF 的作者写的一篇讲稿。 + +* [扩展 extended BPF][61] (Jonathan Corbet, July 2014) + +**BPF 内部结构**: + +* Daniel Borkmann 正在做的一项令人称奇的工作,它用于去展现 eBPF 的 **内部结构**,尤其是,它的关于 **随同 tc 使用** 的几次演讲和论文。 + * [使用 tc 的 cls_bpf 的高级可编程和它的最新更新][30](netdev 1.2, Tokyo, October 2016): + + Daniel 介绍了 eBPF 的细节,及其用于隧道和封装、直接包访问和其它特性。 + + * [自 netdev 1.1 以来的 cls_bpf/eBPF 更新][31]  (netdev 1.2, Tokyo, October 2016, part of [this tc workshop][32]) + + * [使用 cls_bpf 实现完全可编程的 tc 分类器][33]  (netdev 1.1, Sevilla, February 2016): + + 介绍 eBPF 之后,它提供了许多 BPF 内部机制(映射管理、尾调用、校验器)的见解。对于大多数有志于 BPF 的人来说,这是必读的![全文在这里][34]。 + + * [Linux tc 和 eBPF][35] (fosdem16, Brussels, Belgium, January 2016) + + * [eBPF 和 XDP 攻略和最新更新][36] (fosdem17, Brussels, Belgium, February 2017) + + 这些介绍可能是理解 eBPF 内部机制设计与实现的最佳文档资源之一。 + +[IO Visor 博客][157] 有一些关于 BPF 的值得关注技术文章。它们中的一些包含了一点营销讨论。 + +**内核跟踪**:总结了所有的已有的方法,包括 BPF: + +* [邂逅 eBPF 和内核跟踪][62] (Viller Hsiao, July 2016): + + Kprobes、uprobes、ftrace + +* [Linux 内核跟踪][63](Viller Hsiao, July 2016): + + Systemtap、Kernelshark、trace-cmd、LTTng、perf-tool、ftrace、hist-trigger、perf、function tracer、tracepoint、kprobe/uprobe … + +关于 **事件跟踪和监视**,Brendan Gregg 大量使用了 eBPF,并且就其使用 eBPFR 的一些案例写了极好的文档。如果你正在做一些内核跟踪方面的工作,你应该去看一下他的关于 eBPF 和火焰图相关的博客文章。其中的大多数都可以 [从这篇文章中][158] 访问,或者浏览他的博客。 + +介绍 BPF,也介绍 **Linux 网络的一般概念**: + +* [Linux 网络详解][64] (Thomas Graf, LinuxCon, Toronto, August 2016) + +* [内核网络攻略][65]  (Thomas Graf, LinuxCon, Seattle, August 2015) + +**硬件卸载offload**(LCTT 译注:“卸载”是指原本由软件来处理的一些操作交由硬件来完成,以提升吞吐量,降低 CPU 负荷。): + +* eBPF 与 tc 或者 XDP 一起支持硬件卸载,开始于 Linux 内核版本 4.9,是由 Netronome 提出的。这里是关于这个特性的介绍:[eBPF/XDP 硬件卸载到 SmartNICs][147](Jakub Kicinski 和 Nic Viljoen, netdev 1.2, Tokyo, October 2016) + +* 一年后出现的更新版: + + [综合 XDP 卸载——处理边界案例][194](Jakub Kicinski 和 Nic Viljoen,netdev 2.2 ,Seoul,November 2017) + +* 我现在有一个简短的,但是在 2018 年的 FOSDEM 上有一个更新版: + + [XDP 硬件卸载的挑战][195](Quentin Monnet,FOSDEM 2018,Brussels,February 2018) + +关于 **cBPF**: + +* [BSD 包过滤器:一个用户级包捕获的新架构][66] (Steven McCanne 和 Van Jacobson, 1992): + + 它是关于(经典)BPF 的最早的论文。 + +* [BPF 的 FreeBSD 手册][67] 是理解 cBPF 程序有用的资源。 + +* 关于 cBPF,Daniel Borkmann 做至少两个演讲,[一是,在 2013 年 mmap 中,BPF 和 Netsniff-NG][68],以及 [在 2014 中关于 tc 和 cls_bpf 的的一个非常完整的演讲][69]。 + +* 在 Cloudflare 的博客上,Marek Majkowski 提出的他的 [与 iptables 的 `xt_bpf` 模块一起使用 BPF 字节码][70]。值得一提的是,从 Linux 内核 4.10 开始,eBPF 也是通过这个模块支持的。(虽然,我并不知道关于这件事的任何讨论或者文章) + +* [Libpcap 过滤器语法][71] + +#### 关于 XDP + +* 在 IO Visor 网站上的 [XDP 概述][72]。 + +* [eXpress Data Path (XDP)][73]  (Tom Herbert, Alexei Starovoitov, March 2016): + + 这是第一个关于 XDP 的演讲。 + +* [BoF - BPF 能为你做什么?][74]  (Brenden Blanco, LinuxCon, Toronto, August 2016)。 + +* [eXpress Data Path][148] (Brenden Blanco, Linux Meetup at Santa Clara, July 2016): + + 包含一些(有点营销的意思?)**基准测试结果**!使用单一核心: + + * ip 路由丢弃: ~3.6 百万包每秒(Mpps) + + * 使用 BPF,tc(使用 clsact qdisc)丢弃: ~4.2 Mpps + + * 使用 BPF,XDP 丢弃:20 Mpps (CPU 利用率 < 10%) + + * XDP 重写转发(在端口上它接收到的包):10 Mpps + + (测试是用 mlx4 驱动程序执行的)。 + +* Jesper Dangaard Brouer 有几个非常好的幻灯片,它可以从本质上去理解 XDP 的内部结构。 + + * [XDP − eXpress Data Path,介绍及将来的用法][37] (September 2016): + + “Linux 内核与 DPDK 的斗争” 。**未来的计划**(在写这篇文章时)它用 XDP 和 DPDK 进行比较。 + + * [网络性能研讨][38]  (netdev 1.2, Tokyo, October 2016): + + 关于 XDP 内部结构和预期演化的附加提示。 + + * [XDP – eXpress Data Path, 可用于 DDoS 防护][39] (OpenSourceDays, March 2017): + + 包含了关于 XDP 的详细情况和使用案例,以及 **性能测试** 的 **性能测试结果** 和 **代码片断**,以及使用 eBPF/XDP(基于一个 IP 黑名单模式)的用于 **基本的 DDoS 防护**。 + + * [内存 vs. 网络,激发和修复内存瓶颈][40] (LSF Memory Management Summit, March 2017): + + 提供了许多 XDP 开发者当前所面对 **内存问题** 的许多细节。不要从这一个开始,但如果你已经理解了 XDP,并且想去了解它在页面分配方面的真实工作方式,这是一个非常有用的资源。 + + * [XDP 能为其它人做什么][41](netdev 2.1, Montreal, April 2017),及 Andy Gospodarek: + + 普通人怎么开始使用 eBPF 和 XDP。这个演讲也由 Julia Evans 在 [她的博客][42] 上做了总结。 + + * [XDP 能为其它人做什么][205],第二版(netdev 2.2, Seoul, November 2017),同一个作者: + + 该演讲的修订版本,包含了新的内容。 + +(Jesper 也创建了并且尝试去扩展了有关 eBPF 和 XDP 的一些文档,查看 [相关节][75]。) + +* [XDP 研讨 — 介绍、体验和未来发展][76](Tom Herbert, netdev 1.2, Tokyo, October 2016) + + 在这篇文章中,只有视频可用,我不知道是否有幻灯片。 + +* [在 Linux 上进行高速包过滤][149] (Gilberto Bertin, DEF CON 25, Las Vegas, July 2017) + + 在 Linux 上的最先进的包过滤的介绍,面向 DDoS 的保护、讨论了关于在内核中进行包处理、内核旁通、XDP 和 eBPF。 + +#### 关于 基于 eBPF 或者 eBPF 相关的其它组件 + +* [在边界上的 P4][77] (John Fastabend, May 2016): + + 提出了使用 **P4**,一个包处理的描述语言,使用 BPF 去创建一个高性能的可编程交换机。 + +* 如果你喜欢音频的演讲,这里有一个相关的 [OvS Orbit 片断(#11),叫做 在边界上的 P4][78],日期是 2016 年 8 月。OvS Orbit 是对 Ben Pfaff 的访谈,它是 Open vSwitch 的其中一个核心维护者。在这个场景中,John Fastabend 是被访谈者。 + +* [P4, EBPF 和 Linux TC 卸载][79] (Dinan Gunawardena 和 Jakub Kicinski, August 2016): + + 另一个 **P4** 的演讲,一些有关于 Netronome 的 **NFP**(网络流处理器)架构上的 eBPF 硬件卸载的因素。 + +* **Cilium** 是一个由 Cisco 最先发起的技术,它依赖 BPF 和 XDP 去提供 “基于 eBPF 程序即时生成的,用于容器的快速内核强制的网络和安全策略”。[这个项目的代码][150] 在 GitHub 上可以访问到。Thomas Graf 对这个主题做了很多的演讲: + * [Cilium:对容器利用 BPF & XDP 实现网络 & 安全][43],也特别展示了一个负载均衡的使用案例(Linux Plumbers conference, Santa Fe, November 2016) + + * [Cilium:对容器利用 BPF & XDP 实现网络 & 安全][44] (Docker Distributed Systems Summit, October 2016 — [video][45]) + + * [Cilium:使用 BPF 和 XDP 的快速 IPv6 容器网络][46] (LinuxCon, Toronto, August 2016) + + * [Cilium: 用于容器的 BPF & XDP][47] (fosdem17, Brussels, Belgium, February 2017) + + 在上述不同的演讲中重复了大量的内容;嫌麻烦就选最近的一个。Daniel Borkmann 作为 Google 开源博客的特邀作者,也写了 [Cilium 简介][80]。 + +* 这里也有一个关于 **Cilium** 的播客节目:一个是 [OvS Orbit episode (#4)][81],它是 Ben Pfaff 访谈 Thomas Graf (2016 年 5 月),和 [另外一个 Ivan Pepelnjak 的播客][82],仍然是 Thomas Graf 关于 eBPF、P4、XDP 和 Cilium 方面的(2016 年 10 月)。 + +* **Open vSwitch** (OvS),它是 **Open Virtual Network**(OVN,一个开源的网络虚拟化解决方案)相关的项目,正在考虑在不同的层次上使用 eBPF,它已经实现了几个概念验证原型: + + * [使用 eBPF 卸载 OVS 流处理器][48] (William (Cheng-Chun) Tu, OvS conference, San Jose, November 2016) + + * [将 OVN 的灵活性与 IOVisor 的高效率相结合][49] (Fulvio Risso, Matteo Bertrone 和 Mauricio Vasquez Bernal, OvS conference, San Jose, November 2016) + + 据我所知,这些 eBPF 的使用案例看上去仅处于提议阶段(并没有合并到 OvS 的主分支中),但是,看它带来了什么将是非常值得关注的事情。 + +* XDP 的设计对分布式拒绝访问(DDoS)攻击是非常有用的。越来越多的演讲都关注于它。例如,在 2017 年 4 月加拿大蒙特利尔举办的 netdev 2.1 会议上,来自 Cloudflare 的人们的讲话([XDP 实践:将 XDP 集成到我们的 DDoS 缓解管道][83])或者来自 Facebook 的([Droplet:由 BPF + XDP 驱动的 DDoS 对策][84])都存在这样的很多使用案例。 + +* Kubernetes 可以用很多种方式与 eBPF 交互。这里有一篇关于 [在 Kubernetes 中使用 eBPF][196] 的文章,它解释了现有的产品(Cilium、Weave Scope)如何支持 eBPF 与 Kubernetes 一起工作,并且进一步描述了,在容器部署环境中,eBPF 感兴趣的交互内容是什么。 + +* [CETH for XDP][85] (Yan Chan 和 Yunsong Lu、Linux Meetup、Santa Clara、July 2016): + + **CETH**,是由 Mellanox 发起的,为实现更快的网络 I/O 而主张的通用以太网驱动程序架构。 + +* [**VALE 交换机**][86],另一个虚拟交换机,它可以与 netmap 框架结合,有 [一个 BPF 扩展模块][87]。 + +* **Suricata**,一个开源的入侵检测系统,它的旁路捕获旁特性依赖于 XDP。有一些关于它的资源: + + * [Suricate 文档的 eBPF 和 XDP 部分][197] + + * [SEPTun-Mark-II][198] (Suricata Extreme 性能调优指南 — Mark II), Michal Purzynski 和 Peter Manev 发布于 2018 年 3 月。 + + * [介绍这个特性的博客文章][199] Éric Leblond 发布于 2016 年 9 月。 + * [Suricate 的 eBPF 历险记][89]  (Éric Leblond, netdev 1.2, Tokyo, October 2016) + * [eBPF 和 XDP 一窥][90]  (Éric Leblond, Kernel Recipes, Paris, September 2017) + + 当使用原生驱动的 XDP 时,这个项目要求实现非常高的性能。 + +* [InKeV:对于 DCN 的内核中分布式网络虚拟化][91] (Z. Ahmed, M. H. Alizai 和 A. A. Syed, SIGCOMM, August 2016): + + **InKeV** 是一个基于 eBPF 的虚拟网络、目标数据中心网络的数据路径架构。它最初由 PLUMgrid 提出,并且声称相比基于 OvS 的 OpenStack 解决方案可以获得更好的性能。 + +* [gobpf - 在 Go 中使用 eBPF][92] (Michael Schubert, fosdem17, Brussels, Belgium, February 2017): + + “一个来自 Go 库,可以去创建、加载和使用 eBPF 程序” + +* [ply][93] 是为 Linux 实现的一个小而灵活的开源动态 **跟踪器**,它的一些特性非常类似于 bcc 工具,是受 awk 和 dtrace 启发,但使用一个更简单的语言。它是由 Tobias Waldekranz 写的。 + +* 如果你读过我以前的文章,你可能对我在这篇文章中的讨论感兴趣,[使用 eBPF 实现 OpenState 接口][151],关于包状态处理,在 fosdem17 中。 + +![](https://qmonnet.github.io/whirl-offload/img/icons/book.svg) + +### 文档 + +一旦你对 BPF 是做什么的有一个大体的理解。你可以抛开一般的演讲而深入到文档中了。下面是 BPF 的规范和功能的最全面的文档,按你的需要挑一个开始阅读吧! + +#### 关于 BPF + +* **BPF 的规范**(包含 classic 和 extended 版本)可以在 Linux 内核的文档中,和特定的文件 [linux/Documentation/networking/filter.txt][94] 中找到。BPF 使用以及它的内部结构也被记录在那里。此外,当加载 BPF 代码失败时,在这里可以找到 **被校验器抛出的错误信息**,这有助于你排除不明确的错误信息。 + +* 此外,在内核树中,在 eBPF 那里有一个关于 **常见问答** 的文档,它在文件 [linux/Documentation/bpf/bpf\_design\_QA.txt][95] 中。 + +* … 但是,内核文档是非常难懂的,并且非常不容易阅读。如果你只是去查找一个简单的 eBPF 语言的描述,可以去 IO Visor 的 GitHub 仓库,那儿有 [它的概括性描述][96]。 + +* 顺便说一下,IO Visor 项目收集了许多 **关于 BPF 的资源**。大部分分别在 bcc 仓库的 [文档目录][97] 中,和 [bpf-docs 仓库][98] 的整个内容中,它们都在 GitHub 上。注意,这个非常好的 [BPF 参考指南][99] 包含一个详细的 BPF C 和 bcc Python 的 helper 的描述。 + +* 想深入到 BPF,那里有一些必要的 **Linux 手册页**。第一个是 [bpf(2) man 页面][100] 关于 `bpf()` **系统调用**,它用于从用户空间去管理 BPF 程序和映射。它也包含一个 BPF 高级特性的描述(程序类型、映射等等)。第二个是主要是处理希望附加到 tc 接口的 BPF 程序:它是 [tc-bpf(8) man 页面][101],是 **使用 BPF 和 tc** 的一个参考,并且包含一些示例命令和参考代码。 + +* Jesper Dangaard Brouer 发起了一个 **更新 eBPF Linux 文档** 的尝试,包含 **不同的映射**。[他有一个草案][102],欢迎去贡献。一旦完成,这个文档将被合并进 man 页面并且进入到内核文档。 + +* Cilium 项目也有一个非常好的 [BPF 和 XDP 参考指南][103],它是由核心的 eBPF 开发者写的,它被证明对于 eBPF 开发者是极其有用的。 + +* David Miller 在 [xdp-newbies][152] 邮件列表中发了几封关于 eBPF/XDP 内部结构的富有启发性的电子邮件。我找不到一个单独的地方收集它们的链接,因此,这里是一个列表: + + * [bpf.h 和你 …][50] + + * [从语境上讲…][51] + + * [BPF 校验器概述][52] + + 最后一个可能是目前来说关于校验器的最佳的总结。 + +* Ferris Ellis 发布的 [一个关于 eBPF 的系列博客文章][104]。作为我写的这个短文,第一篇文章是关于 eBPF 的历史背景和未来期望。接下来的文章将更多的是技术方面,和前景展望。 + +* [每个内核版本的 BPF 特性列表][153] 在 bcc 仓库中可以找到。如果你想去知道运行一个给定的特性所要求的最小的内核版本,它是非常有用的。我贡献和添加了链接到提交中,它介绍了每个特性,因此,你也可以从那里很容易地去访问提交历史。 + +#### 关于 tc + +当为了网络目的结合使用 BPF 与 tc (Linux 流量控制**t**raffic **c**ontrol工具)时,它可用于收集 tc 的常规功能的信息。这里有几个关于它的资源。 + +* 找到关于 **Linux 上 QoS** 的简单教程是很困难的。这里有两个链接,它们很长而且很难懂,但是,如果你可以抽时间去阅读它,你将学习到几乎关于 tc 的任何东西(虽然,没有什么关于 BPF 的)。它们在这里:[怎么去实现流量控制  (Martin A. Brown, 2006)][105],和 [怎么去实现 Linux 的高级路由 & 流量控制 (LARTC) (Bert Hubert & al., 2002)][106]。 + +* 在你的系统上的 **tc 手册页面** 并不是最新的,因为它们中的几个最近已经增加了内容。如果你没有找到关于特定的队列规则、分类或者过滤器的文档,它可能在最新的 [tc 组件的手册页面][107] 中。 + +* 一些额外的材料可以在 iproute2 包自已的文件中找到:这个包中有 [一些文档][108],包括一些文件,它可以帮你去理解 [tc 的 action 的功能][109]。 + + **注意:** 这些文件在 2017 年 10 月 已经从 iproute2 中删除,然而,从 Git 历史中却一直可用。 + +* 不完全是文档:[有一个关于 tc 的几个特性的研讨会][110](包含过滤、BPF、tc 卸载、…) 由 Jamal Hadi Salim 在 netdev 1.2 会议上组织的(October 2016)。 + +* 额外信息 — 如果你使用 `tc` 较多,这里有一些好消息:我用这个工具 [写了一个 bash 补完功能][111],并且它被包 iproute2 带到内核版本 4.6 和更高版中! + +#### 关于 XDP + +* 对于 XDP 的一些 [进展中的文档(包括规范)][112] 已经由 Jesper Dangaard Brouer 启动,并且意味着将成为一个协作工作。正在推进的(2016 年 9 月):你期望它去改变,并且或许在一些节点上移动(Jesper [称为贡献][113],如果你想去改善它)。 + +* 自来 Cilium 项目的 [BPF 和 XDP 参考指南][114] … 好吧,这个名字已经说明了一切。 + +#### 关于 P4 和 BPF + +[P4][159] 是一个用于指定交换机行为的语言。它可以为多种目标硬件或软件编译。因此,你可能猜到了,这些目标中的一个就是 BPF … 仅部分支持的:一些 P4 特性并不能被转化到 BPF 中,并且,用类似的方法,BPF 可以做的事情,而使用 P4 却不能表达出现。不过,**P4 与 BPF 使用** 的相关文档,[被隐藏在 bcc 仓库中][160]。这个改变在 P4_16 版本中,p4c 引用的编辑器包含 [一个 eBPF 后端][161]。 + +![](https://qmonnet.github.io/whirl-offload/img/icons/flask.svg) + +### 教程 + +Brendan Gregg 为想要 **使用 bcc 工具** 跟踪和监视内核中的事件的人制作了一个非常好的 **教程**。[第一个教程是关于如何使用 bcc 工具][162],它有许多章节,可以教你去理解怎么去使用已有的工具,而 [针对 Python 开发者的一篇][163] 专注于开发新工具,它总共有十七节 “课程”。 + +Sasha Goldshtein 也有一些 [Linux 跟踪研究材料][164] 涉及到使用几个 BPF 工具进行跟踪。 + +Jean-Tiare Le Bigot 的另一篇文章提供了一个详细的(和有指导意义的)[使用 perf 和 eBPF 去设置一个低级的跟踪器][165] 的示例。 + +对于网络相关的 eBPF 使用案例也有几个教程。有一些值得关注的文档,包括一篇 _eBPF 卸载入门指南_,是关于在 [Open NFP][166] 平台上用 Netronome 操作的。其它的那些,来自 Jesper 的演讲,[XDP 能为其它人做什么][167](及其[第二版][205]),可能是 XDP 入门的最好的方法之一。 + +![](https://qmonnet.github.io/whirl-offload/img/icons/gears.svg) + +### 示例 + +有示例是非常好的。看看它们是如何工作的。但是 BPF 程序示例是分散在几个项目中的,因此,我列出了我所知道的所有的示例。示例并不是总是使用相同的 helper(例如,tc 和 bcc 都有一套它们自己的 helper,使它可以很容易地去用 C 语言写 BPF 程序) + +#### 来自内核的示例 + +内核中包含了大多数类型的程序:过滤器绑定到套接字或者 tc 接口、事件跟踪/监视、甚至是 XDP。你可以在 [linux/samples/bpf/][168] 目录中找到这些示例。 + +现在,更多的示例已经作为单元测试被添加到 [linux/tools/testing/selftests/bpf][200] 目录下,这里面包含对硬件卸载的测试或者对于 libbpf 的测试。 + +Jesper 的 Dangaard Brouer 在他的 [prototype-kernel][201] 仓库中也维护了一套专门的示例。 这些示例与那些内核中提供的示例非常类似,但是它们可以脱离内核架构(Makefile 和头文件)编译。 + +也不要忘记去看一下 git 相关的提交历史,它们介绍了一些特定的特性,也许包含了一些特性的详细示例。 + +#### 来自包 iproute2 的示例 + +iproute2 包也提供了几个示例。它们都很明显地偏向网络编程,因此,这个程序是附着到 tc 入站或者出站接口上。这些示例在 [iproute2/examples/bpf/][169] 目录中。 + +#### 来自 bcc 工具集的示例 + +许多示例都是 [与 bcc 一起提供的][170]: + +* 一些网络的示例放在相关的目录下面。它们包括套接字过滤器、tc 过滤器、和一个 XDP 程序。 + +* `tracing` 目录包含许多 **跟踪编程** 的示例。前面的教程中提到的都在那里。那些程序涉及了很大部分的事件监视功能,并且,它们中的一些是面向生产系统的。注意,某些 Linux 发行版(至少是 Debian、Ubuntu、Fedora、Arch Linux)、这些程序已经被 [打包了][115] 并且可以很 “容易地” 通过比如 `# apt install bcc-tools` 进行安装。但是在写这篇文章的时候(除了 Arch Linux),首先要求安装 IO Visor 的包仓库。 + +* 也有一些 **使用 Lua** 作为一个不同的 BPF 后端(那是因为 BPF 程序是用 Lua 写的,它是 C 语言的一个子集,它允许为前端和后端使用相同的语言)的一些示例,它在第三个目录中。 + +* 当然,[bcc 工具][202] 自身就是 eBPF 程序使用案例的值得关注示例。 + +#### 手册页面 + +虽然 bcc 一般很容易在内核中去注入和运行一个 BPF 程序,将程序附着到 tc 接口也能通过 `tc` 工具自己完成。因此,如果你打算将 **BPF 与 tc 一起使用**,你可以在 [`tc-bpf(8)` 手册页面][171] 中找到一些调用示例。 + +![](https://qmonnet.github.io/whirl-offload/img/icons/srcfile.svg) + +### 代码 + +有时候,BPF 文档或者示例并不够,而且你只想在你喜欢的文本编辑器(它当然应该是 Vim)中去显示代码并去阅读它。或者,你可能想深入到代码中去做一个补丁程序或者为机器增加一些新特性。因此,这里对有关的文件的几个建议,找到你想要的函数只取决于你自己! + +#### 在内核中的 BPF 代码 + +* 文件 [linux/include/linux/bpf.h][116] 及其相对的 [linux/include/uapi/bpf.h][117] 包含有关 eBPF 的 **定义**,它们分别用在内核中和用户空间程序的接口。 + +* 相同的方式,文件 [linux/include/linux/filter.h][118] 和 [linux/include/uapi/filter.h][119] 包含了用于 **运行 BPF 程序** 的信息。 + +* BPF 相关的 **主要的代码片断** 在 [linux/kernel/bpf/][120] 目录下面。**系统调用的不同操作许可**,比如,程序加载或者映射管理是在文件 `syscall.c` 中实现,而 `core.c` 包含了 **解析器**。其它文件的命名显而易见:`verifier.c` 包含 **校验器**(不是开玩笑的),`arraymap.c` 的代码用于与数组类型的 **映射** 交互,等等。 + +* 有几个与网络(及 tc、XDP )相关的函数和 **helpers** 是用户可用,其实现在 [linux/net/core/filter.c][121] 中。它也包含了移植 cBPF 字节码到 eBPF 的代码(因为在运行之前,内核中的所有的 cBPF 程序被转换成 eBPF)。 + +* 相关于 **事件跟踪** 的函数和 **helpers** 都在 [linux/kernel/trace/bpf_trace.c][203] 中。 + +* **JIT 编译器** 在它们各自的架构目录下面,比如,x86 架构的在 [linux/arch/x86/net/bpf_jit_comp.c][122] 中。例外是用于硬件卸载的 JIT 编译器,它们放在它们的驱动程序下,例如 Netronome NFP 网卡的就放在 [linux/drivers/net/ethernet/netronome/nfp/bpf/jit.c][206] 。 + +* 在 [linux/net/sched/][123] 目录下,你可以找到 **tc 的 BPF 组件** 相关的代码,尤其是在文件 `act_bpf.c` (action)和 `cls_bpf.c`(filter)中。 + +* 我并没有在 BPF 上深入到 **事件跟踪** 中,因此,我并不真正了解这些程序的钩子。在 [linux/kernel/trace/bpf_trace.c][124] 那里有一些东西。如果你对它感 兴趣,并且想去了解更多,你可以在 Brendan Gregg 的演示或者博客文章上去深入挖掘。 + +* 我也没有使用过 **seccomp-BPF**,不过你能在 [linux/kernel/seccomp.c][125] 找到它的代码,并且可以在 [linux/tools/testing/selftests/seccomp/seccomp_bpf.c][126] 中找到一些它的使用示例。 + +#### XDP 钩子代码 + +一旦装载进内核的 BPF 虚拟机,由一个 Netlink 命令将 **XDP** 程序从用户空间钩入到内核网络路径中。接收它的是在 [linux/net/core/dev.c][172] 文件中的 `dev_change_xdp_fd()` 函数,它被调用并设置一个 XDP 钩子。钩子被放在支持的网卡的驱动程序中。例如,用于 Netronome 硬件钩子的 ntp 驱动程序实现放在 [drivers/net/ethernet/netronome/nfp/][207] 中。文件 `nfp_net_common.c` 接受 Netlink 命令,并调用 `nfp_net_xdp_setup()`,它会转而调用 `nfp_net_xdp_setup_drv()` 实例来安装该程序。 + +#### 在 bcc 中的 BPF 逻辑 + +[在 bcc 的 GitHub 仓库][174] 能找到的 **bcc** 工具集的代码。其 **Python 代码**,包含在 `BPF` 类中,最初它在文件 [bcc/src/python/bcc/\_\_init\_\_.py][175] 中。但是许多我觉得有意思的东西,比如,加载 BPF 程序到内核中,出现在 [libbcc 的 C 库][176]中。 + +#### 使用 tc 去管理 BPF 的代码 + +当然,这些代码与 iproute2 包中的 **tc 中的** BPF 相关。其中的一些在 [iproute2/tc/][177] 目录中。文件 `f_bpf.c` 和 `m_bpf.c`(和 `e_bpf.c`)各自用于处理 BPF 的过滤器和动作的(和 tc `exec` 命令,等等)。文件 `q_clsact.c` 定义了为 BPF 特别创建的 `clsact` qdisc。但是,**大多数的 BPF 用户空间逻辑** 是在 [iproute2/lib/bpf.c][178] 库中实现的,因此,如果你想去使用 BPF 和 tc,这里可能是会将你搞混乱的地方(它是从文件 iproute2/tc/tc_bpf.c 中移动而来的,你也可以在旧版本的包中找到相同的代码)。 + +#### BPF 实用工具 + +内核中也带有 BPF 相关的三个工具的源代码(`bpf_asm.c`、 `bpf_dbg.c`、 `bpf_jit_disasm.c`),根据你的版本不同,在 [linux/tools/net/][179] (直到 Linux 4.14)或者 [linux/tools/bpf/][180] 目录下面: + +* `bpf_asm` 是一个极小的 cBPF 汇编程序。 + +* `bpf_dbg` 是一个很小的 cBPF 程序调试器。 + +* `bpf_jit_disasm` 对于两种 BPF 都是通用的,并且对于 JIT 调试来说非常有用。 + +* `bpftool` 是由 Jakub Kicinski 写的通用工具,它可以与 eBPF 程序交互并从用户空间的映射,例如,去展示、转储、pin 程序、或者去展示、创建、pin、更新、删除映射。 + +阅读在源文件顶部的注释可以得到一个它们使用方法的概述。 + +与 eBPF 一起工作的其它必需的文件是来自内核树的两个**用户空间库**,它们可以用于管理 eBPF 程序或者映射来自外部的程序。这个函数可以通过 [linux/tools/lib/bpf/][204] 目录中的头文件 `bpf.h` 和 `libbpf.h`(更高层面封装)来访问。比如,工具 `bpftool` 主要依赖这些库。 + +#### 其它值得关注的部分 + +如果你对关于 BPF 的不常见的语言的使用感兴趣,bcc 包含 [一个 BPF 目标的 **P4 编译器**][181]以及 [**一个 Lua 前端**][182],它可以被用以代替 C 的一个子集,并且(用 Lua )替代 Python 工具。 + +#### LLVM 后端 + +这个 BPF 后端用于 clang / LLVM 将 C 编译到 eBPF ,是在 [这个提交][183] 中添加到 LLVM 源代码的(也可以在 [这个 GitHub 镜像][184] 上访问)。 + +#### 在用户空间中运行 + +到目前为止,我知道那里有至少两种 eBPF 用户空间实现。第一个是 [uBPF][185],它是用 C 写的。它包含一个解析器、一个 x86_64 架构的 JIT 编译器、一个汇编器和一个反汇编器。 + +uBPF 的代码似乎被重用来产生了一个 [通用实现][186],其声称支持 FreeBSD 内核、FreeBSD 用户空间、Linux 内核、Linux 用户空间和 Mac OSX 用户空间。它被 [VALE 交换机的 BPF 扩展模块][187]使用。 + +其它用户空间的实现是我做的:[rbpf][188],基于 uBPF,但是用 Rust 写的。写了解析器和 JIT 编译器 (Linux 下两个都有,Mac OSX 和 Windows 下仅有解析器),以后可能会有更多。 + +#### 提交日志 + +正如前面所说的,如果你希望得到更多的关于一些特定的 BPF 特性的信息,不要犹豫,去看一些提交日志。你可以在许多地方搜索日志,比如,在 [git.kernel.org][189]、[在 GitHub 上][190]、或者如果你克隆过它还有你的本地仓库中。如果你不熟悉 git,你可以尝试像这些去做 `git blame ` 去看看介绍特定代码行的提交内容,然后,`git show ` 去看详细情况(或者在 `git log` 的结果中按关键字搜索,但是这样做通常比较单调乏味)也可以看在 bcc 仓库中的 [按内核版本区分的 eBPF 特性列表][191],它链接到相关的提交上。 + +![](https://qmonnet.github.io/whirl-offload/img/icons/wand.svg) + +### 排错 + +对 eBPF 的追捧是最近的事情,因此,到目前为止我还找不到许多关于怎么去排错的资源。所以这里只有几个,是我在使用 BPF 进行工作的时候,对自己遇到的问题进行的记录。 + +#### 编译时的错误 + +* 确保你有一个最新的 Linux 内核版本(也可以看 [这个文档][127])。 + +* 如果你自己编译内核:确保你安装了所有正确的组件,包括内核镜像、头文件和 libc。 + +* 当使用 `tc-bpf`(用于去编译 C 代码到 BPF 中)的 man 页面提供的 `bcc` shell 函数时:我曾经必须添加包含 clang 调用的头文件: + + ``` + __bcc() { + clang -O2 -I "/usr/src/linux-headers-$(uname -r)/include/" \ + -I "/usr/src/linux-headers-$(uname -r)/arch/x86/include/" \ + -emit-llvm -c $1 -o - | \ + llc -march=bpf -filetype=obj -o "`basename $1 .c`.o" + } + ``` + + (现在似乎修复了)。 + +* 对于使用 `bcc` 的其它问题,不要忘了去看一看这个工具集的 [答疑][128]。 + +* 如果你从一个并不精确匹配你的内核版本的 iproute2 包中下载了示例,可能会由于在文件中包含的头文件触发一些错误。这些示例片断都假设安装在你的系统中内核的头文件与 iproute2 包是相同版本的。如果不是这种情况,下载正确的 iproute2 版本,或者编辑示例中包含的文件的路径,指向到 iproute2 中包含的头文件上(在运行时一些问题可能或者不可能发生,取决于你使用的特性)。 + +#### 在加载和运行时的错误 + +* 使用 `tc` 去加载一个程序,确保你使用了一个与使用中的内核版本等价的 iproute2 中的 `tc` 二进制文件。 + +* 使用 `bcc` 去加载一个程序,确保在你的系统上安装了 bcc(仅下载源代码去运行 Python 脚本是不够的)。 + +* 使用 `tc`,如果 BPF 程序不能返回一个预期值,检查调用它的方式:过滤器,或者动作,或者使用 “直传” 模式的过滤器。 + +* 还是 `tc`,注意不使用过滤器,动作不会直接附着到 qdiscs 或者接口。 + +* 通过内核校验器抛出错误到解析器可能很难。[内核文档][129]或许可以提供帮助,因此,可以 [参考指南][130] 或者,万不得一的情况下,可以去看源代码(祝你好运!)。记住,校验器 _不运行_ 程序,对于这种类型的错误,记住这点是非常重要的。如果你得到一个关于无效内存访问或者关于未初始化的数据的错误,它并不意味着那些问题真实发生了(或者有时候是,它们完全有可能发生)。它意味着你的程序是以校验器预计可能发生错误的方式写的,并且因此而拒绝这个程序。 + +* 注意 `tc` 工具有一个 `verbose` 模式,它与 BPF 一起工作的很好:在你的命令行尾部尝试追加一个 `verbose`。 + +* `bcc` 也有一个 `verbose` 选项:`BPF` 类有一个 `debug` 参数,它可以带 `DEBUG_LLVM_IR`、`DEBUG_BPF` 和 `DEBUG_PREPROCESSOR` 三个标志中任何组合(详细情况在 [源文件][131]中)。 为调试该代码,它甚至嵌入了 [一些条件去打印输出代码][132]。 + +* LLVM v4.0+ 为 eBPF 程序 [嵌入一个反汇编器][133]。因此,如果你用 clang 编译你的程序,在编译时添加 `-g` 标志允许你通过内核校验器去以人类可读的格式去转储你的程序。处理转储文件,使用: + + ``` + $ llvm-objdump -S -no-show-raw-insn bpf_program.o + ``` + +* 使用映射?你应该去看看 [bpf-map][134],这是一个为 Cilium 项目而用 Go 创建的非常有用的工具,它可以用于去转储内核中 eBPF 映射的内容。也有一个用 Rust 开发的 [克隆][135]。 + +* [在 **StackOverflow** 上有个旧的 bpf 标签][136],但是,在这篇文章中从没用过它(并且那里几乎没有与新版本的 eBPF 相关的东西)。如果你是一位来自未来的阅读者,你可能想去看看在这方面是否有更多的活动(LCTT 译注:意即只有旧东西)。 + +![](https://qmonnet.github.io/whirl-offload/img/icons/zoomin.svg) + +### 更多! + +* 如果你想轻松地 **测试 XDP**,有 [一个配置好的 Vagrant ][137] 可以使用。你也可以 [在 Docker 容器中][138] **测试 bcc**。 + +* 想知道 BPF 的 **开发和活动** 在哪里吗?好吧,内核补丁总是出自于 [netdev 上的邮件列表][139](相关 Linux 内核的网络栈开发):以关键字 “BPF” 或者 “XDP” 来搜索。自 2017 年 4 月开始,那里也有 [一个专门用于 XDP 编程的邮件列表][140](是为了架构或者寻求帮助)。[在 IO Visor 的邮件列表上][141]也有许多的讨论和辨论,因为 BPF 是一个重要的项目。如果你只是想随时了解情况,那里也有一个 [@IOVisor Twitter 帐户][142]。 + +请经常会回到[这篇博客][0]中,来看一看 [关于 BPF][192] 有没有新的文章! + +_特别感谢 Daniel Borkmann 指引我找到了 [更多的文档][154],因此我才完成了这个合集。_ + +-------------------------------------------------------------------------------- + +via: https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/ + +作者:[Quentin Monnet][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://qmonnet.github.io/whirl-offload/about/ +[0]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/ +[1]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-bpf +[2]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-xdp +[3]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-other-components-related-or-based-on-ebpf +[4]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-bpf-1 +[5]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-tc +[6]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-xdp-1 +[7]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-p4-and-bpf +[8]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#from-the-kernel +[9]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#from-package-iproute2 +[10]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#from-bcc-set-of-tools +[11]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#manual-pages +[12]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#bpf-code-in-the-kernel +[13]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#xdp-·s-code +[14]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#bpf-logic-in-bcc +[15]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#code-to-manage-bpf-with-tc +[16]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#bpf-utilities +[17]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#other-interesting-chunks +[18]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#llvm-backend +[19]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#running-in-userspace +[20]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#commit-logs +[21]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#errors-at-compilation-time +[22]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#errors-at-load-and-run-time +[23]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#generic-presentations +[24]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#documentation +[25]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#tutorials +[26]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#examples +[27]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#the-code +[28]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#troubleshooting +[29]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#and-still-more +[30]:http://netdevconf.org/1.2/session.html?daniel-borkmann +[31]:http://netdevconf.org/1.2/slides/oct5/07_tcws_daniel_borkmann_2016_tcws.pdf +[32]:http://netdevconf.org/1.2/session.html?jamal-tc-workshop +[33]:http://www.netdevconf.org/1.1/proceedings/slides/borkmann-tc-classifier-cls-bpf.pdf +[34]:http://www.netdevconf.org/1.1/proceedings/papers/On-getting-tc-classifier-fully-programmable-with-cls-bpf.pdf +[35]:https://archive.fosdem.org/2016/schedule/event/ebpf/attachments/slides/1159/export/events/attachments/ebpf/slides/1159/ebpf.pdf +[36]:https://fosdem.org/2017/schedule/event/ebpf_xdp/ +[37]:http://people.netfilter.org/hawk/presentations/xdp2016/xdp_intro_and_use_cases_sep2016.pdf +[38]:http://netdevconf.org/1.2/session.html?jesper-performance-workshop +[39]:http://people.netfilter.org/hawk/presentations/OpenSourceDays2017/XDP_DDoS_protecting_osd2017.pdf +[40]:http://people.netfilter.org/hawk/presentations/MM-summit2017/MM-summit2017-JesperBrouer.pdf +[41]:http://netdevconf.org/2.1/session.html?gospodarek +[42]:http://jvns.ca/blog/2017/04/07/xdp-bpf-tutorial/ +[43]:http://www.slideshare.net/ThomasGraf5/clium-container-networking-with-bpf-xdp +[44]:http://www.slideshare.net/Docker/cilium-bpf-xdp-for-containers-66969823 +[45]:https://www.youtube.com/watch?v=TnJF7ht3ZYc&amp;amp;list=PLkA60AVN3hh8oPas3cq2VA9xB7WazcIgs +[46]:http://www.slideshare.net/ThomasGraf5/cilium-fast-ipv6-container-networking-with-bpf-and-xdp +[47]:https://fosdem.org/2017/schedule/event/cilium/ +[48]:http://openvswitch.org/support/ovscon2016/7/1120-tu.pdf +[49]:http://openvswitch.org/support/ovscon2016/7/1245-bertrone.pdf +[50]:https://www.spinics.net/lists/xdp-newbies/msg00179.html +[51]:https://www.spinics.net/lists/xdp-newbies/msg00181.html +[52]:https://www.spinics.net/lists/xdp-newbies/msg00185.html +[53]:http://schd.ws/hosted_files/ossna2017/da/BPFandXDP.pdf +[54]:https://speakerdeck.com/tuxology/the-bsd-packet-filter +[55]:http://www.slideshare.net/brendangregg/bpf-tracing-and-more +[56]:http://fr.slideshare.net/brendangregg/linux-bpf-superpowers +[57]:https://www.socallinuxexpo.org/sites/default/files/presentations/Room%20211%20-%20IOVisor%20-%20SCaLE%2014x.pdf +[58]:https://events.linuxfoundation.org/sites/events/files/slides/ebpf_on_the_mainframe_lcon_2015.pdf +[59]:https://events.linuxfoundation.org/sites/events/files/slides/tracing-linux-ezannoni-linuxcon-ja-2015_0.pdf +[60]:https://events.linuxfoundation.org/sites/events/files/slides/bpf_collabsummit_2015feb20.pdf +[61]:https://lwn.net/Articles/603983/ +[62]:http://www.slideshare.net/vh21/meet-cutebetweenebpfandtracing +[63]:http://www.slideshare.net/vh21/linux-kernel-tracing +[64]:http://www.slideshare.net/ThomasGraf5/linux-networking-explained +[65]:http://www.slideshare.net/ThomasGraf5/linuxcon-2015-linux-kernel-networking-walkthrough +[66]:http://www.tcpdump.org/papers/bpf-usenix93.pdf +[67]:http://www.gsp.com/cgi-bin/man.cgi?topic=bpf +[68]:http://borkmann.ch/talks/2013_devconf.pdf +[69]:http://borkmann.ch/talks/2014_devconf.pdf +[70]:https://blog.cloudflare.com/introducing-the-bpf-tools/ +[71]:http://biot.com/capstats/bpf.html +[72]:https://www.iovisor.org/technology/xdp +[73]:https://github.com/iovisor/bpf-docs/raw/master/Express_Data_Path.pdf +[74]:https://events.linuxfoundation.org/sites/events/files/slides/iovisor-lc-bof-2016.pdf +[75]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#about-xdp-1 +[76]:http://netdevconf.org/1.2/session.html?herbert-xdp-workshop +[77]:https://schd.ws/hosted_files/2016p4workshop/1d/Intel%20Fastabend-P4%20on%20the%20Edge.pdf +[78]:https://ovsorbit.benpfaff.org/#e11 +[79]:http://open-nfp.org/media/pdfs/Open_NFP_P4_EBPF_Linux_TC_Offload_FINAL.pdf +[80]:https://opensource.googleblog.com/2016/11/cilium-networking-and-security.html +[81]:https://ovsorbit.benpfaff.org/ +[82]:http://blog.ipspace.net/2016/10/fast-linux-packet-forwarding-with.html +[83]:http://netdevconf.org/2.1/session.html?bertin +[84]:http://netdevconf.org/2.1/session.html?zhou +[85]:http://www.slideshare.net/IOVisor/ceth-for-xdp-linux-meetup-santa-clara-july-2016 +[86]:http://info.iet.unipi.it/~luigi/vale/ +[87]:https://github.com/YutaroHayakawa/vale-bpf +[88]:https://www.stamus-networks.com/2016/09/28/suricata-bypass-feature/ +[89]:http://netdevconf.org/1.2/slides/oct6/10_suricata_ebpf.pdf +[90]:https://www.slideshare.net/ennael/kernel-recipes-2017-ebpf-and-xdp-eric-leblond +[91]:https://github.com/iovisor/bpf-docs/blob/master/university/sigcomm-ccr-InKev-2016.pdf +[92]:https://fosdem.org/2017/schedule/event/go_bpf/ +[93]:https://wkz.github.io/ply/ +[94]:https://www.kernel.org/doc/Documentation/networking/filter.txt +[95]:https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/Documentation/bpf/bpf_design_QA.txt?id=2e39748a4231a893f057567e9b880ab34ea47aef +[96]:https://github.com/iovisor/bpf-docs/blob/master/eBPF.md +[97]:https://github.com/iovisor/bcc/tree/master/docs +[98]:https://github.com/iovisor/bpf-docs/ +[99]:https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md +[100]:http://man7.org/linux/man-pages/man2/bpf.2.html +[101]:http://man7.org/linux/man-pages/man8/tc-bpf.8.html +[102]:https://prototype-kernel.readthedocs.io/en/latest/bpf/index.html +[103]:http://docs.cilium.io/en/latest/bpf/ +[104]:https://ferrisellis.com/tags/ebpf/ +[105]:http://linux-ip.net/articles/Traffic-Control-HOWTO/ +[106]:http://lartc.org/lartc.html +[107]:https://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/man/man8 +[108]:https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git/tree/doc?h=v4.13.0 +[109]:https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git/tree/doc/actions?h=v4.13.0 +[110]:http://netdevconf.org/1.2/session.html?jamal-tc-workshop +[111]:https://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/commit/bash-completion/tc?id=27d44f3a8a4708bcc99995a4d9b6fe6f81e3e15b +[112]:https://prototype-kernel.readthedocs.io/en/latest/networking/XDP/index.html +[113]:https://marc.info/?l=linux-netdev&amp;amp;m=147436253625672 +[114]:http://docs.cilium.io/en/latest/bpf/ +[115]:https://github.com/iovisor/bcc/blob/master/INSTALL.md +[116]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/bpf.h +[117]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/bpf.h +[118]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/filter.h +[119]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/filter.h +[120]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf +[121]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/filter.c +[122]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/net/bpf_jit_comp.c +[123]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/sched +[124]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/trace/bpf_trace.c +[125]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/seccomp.c +[126]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/seccomp/seccomp_bpf.c +[127]:https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md +[128]:https://github.com/iovisor/bcc/blob/master/FAQ.txt +[129]:https://www.kernel.org/doc/Documentation/networking/filter.txt +[130]:https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md +[131]:https://github.com/iovisor/bcc/blob/master/src/python/bcc/__init__.py +[132]:https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#output +[133]:https://www.spinics.net/lists/netdev/msg406926.html +[134]:https://github.com/cilium/bpf-map +[135]:https://github.com/badboy/bpf-map +[136]:https://stackoverflow.com/questions/tagged/bpf +[137]:https://github.com/iovisor/xdp-vagrant +[138]:https://github.com/zlim/bcc-docker +[139]:http://lists.openwall.net/netdev/ +[140]:http://vger.kernel.org/vger-lists.html#xdp-newbies +[141]:http://lists.iovisor.org/pipermail/iovisor-dev/ +[142]:https://twitter.com/IOVisor +[143]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#what-is-bpf +[144]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#dive-into-the-bytecode +[145]:https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/#resources +[146]:https://github.com/qmonnet/whirl-offload/commits/gh-pages/_posts/2016-09-01-dive-into-bpf.md +[147]:http://netdevconf.org/1.2/session.html?jakub-kicinski +[148]:http://www.slideshare.net/IOVisor/express-data-path-linux-meetup-santa-clara-july-2016 +[149]:https://cdn.shopify.com/s/files/1/0177/9886/files/phv2017-gbertin.pdf +[150]:https://github.com/cilium/cilium +[151]:https://fosdem.org/2017/schedule/event/stateful_ebpf/ +[152]:http://vger.kernel.org/vger-lists.html#xdp-newbies +[153]:https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md +[154]:https://github.com/qmonnet/whirl-offload/commit/d694f8081ba00e686e34f86d5ee76abeb4d0e429 +[155]:http://openvswitch.org/pipermail/dev/2014-October/047421.html +[156]:https://qmonnet.github.io/whirl-offload/2016/07/15/beba-research-project/ +[157]:https://www.iovisor.org/resources/blog +[158]:http://www.brendangregg.com/blog/2016-03-05/linux-bpf-superpowers.html +[159]:http://p4.org/ +[160]:https://github.com/iovisor/bcc/tree/master/src/cc/frontends/p4 +[161]:https://github.com/p4lang/p4c/blob/master/backends/ebpf/README.md +[162]:https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md +[163]:https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md +[164]:https://github.com/goldshtn/linux-tracing-workshop +[165]:https://blog.yadutaf.fr/2017/07/28/tracing-a-packet-journey-using-linux-tracepoints-perf-ebpf/ +[166]:https://open-nfp.org/dataplanes-ebpf/technical-papers/ +[167]:http://netdevconf.org/2.1/session.html?gospodarek +[168]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/samples/bpf +[169]:https://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/examples/bpf +[170]:https://github.com/iovisor/bcc/tree/master/examples +[171]:http://man7.org/linux/man-pages/man8/tc-bpf.8.html +[172]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c +[173]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/mellanox/mlx4/ +[174]:https://github.com/iovisor/bcc/ +[175]:https://github.com/iovisor/bcc/blob/master/src/python/bcc/__init__.py +[176]:https://github.com/iovisor/bcc/blob/master/src/cc/libbpf.c +[177]:https://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/tc +[178]:https://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/lib/bpf.c +[179]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/net +[180]:https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/tools/bpf +[181]:https://github.com/iovisor/bcc/tree/master/src/cc/frontends/p4/compiler +[182]:https://github.com/iovisor/bcc/tree/master/src/lua +[183]:https://reviews.llvm.org/D6494 +[184]:https://github.com/llvm-mirror/llvm/commit/4fe85c75482f9d11c5a1f92a1863ce30afad8d0d +[185]:https://github.com/iovisor/ubpf/ +[186]:https://github.com/YutaroHayakawa/generic-ebpf +[187]:https://github.com/YutaroHayakawa/vale-bpf +[188]:https://github.com/qmonnet/rbpf +[189]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git +[190]:https://github.com/torvalds/linux +[191]:https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md +[192]:https://qmonnet.github.io/whirl-offload/categories/#BPF +[193]:https://lwn.net/Articles/740157/ +[194]:https://www.netdevconf.org/2.2/session.html?viljoen-xdpoffload-talk +[195]:https://fosdem.org/2018/schedule/event/xdp/ +[196]:http://blog.kubernetes.io/2017/12/using-ebpf-in-kubernetes.html +[197]:http://suricata.readthedocs.io/en/latest/capture-hardware/ebpf-xdp.html?highlight=XDP#ebpf-and-xdp +[198]:https://github.com/pevma/SEPTun-Mark-II +[199]:https://www.stamus-networks.com/2016/09/28/suricata-bypass-feature/ +[200]:https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/tools/testing/selftests/bpf +[201]:https://github.com/netoptimizer/prototype-kernel/tree/master/kernel/samples/bpf +[202]:https://github.com/iovisor/bcc/tree/master/tools +[203]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/trace/bpf_trace.c +[204]:https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/tools/lib/bpf +[205]:https://www.netdevconf.org/2.2/session.html?gospodarek-xdp-workshop +[206]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/netronome/nfp/bpf/jit.c +[207]:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/netronome/nfp/ \ No newline at end of file diff --git a/published/201804/20180312 Continuous integration in Fedora.md b/published/201804/20180312 Continuous integration in Fedora.md new file mode 100644 index 0000000000..f32383f78e --- /dev/null +++ b/published/201804/20180312 Continuous integration in Fedora.md @@ -0,0 +1,51 @@ +Fedora 社区的持续集成 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2017/07/ci-mar2018-945x400.jpg) + +持续集成Continuous Integration(CI) 是为项目的每一项变更运行测试的过程,如同这是新的交付项目一样。如果持续执行,这意味着软件随时可以发布。 CI 是整个 IT 行业以及自由开源项目非常成熟的流程。Fedora 在这方面有点落后,但我们正在赶上。阅读以下内容了解进展。 + +### 我们为什么需要这个? + +CI 将全面改善 Fedora。它通过尽早揭示 bug 提供更稳定和一致的操作系统。它让你在遇到问题时添加测试,以免再次发生(避免回归)。CI 可以运行来自上游的项目测试,还有测试集成在发行版中 Fedora 特定的测试。 + +最重要的是,一致的 CI 能自动化并减少手工劳动。它释放了我们宝贵的志愿者和贡献者,让他们将更多时间花在 Fedora 的新事物上。 + +### 它看起来如何? + +对于初学者,我们将对在 Fedora 包仓库 (dist-git) 的每个提交运行测试。这些测试独立于构建时运行的每个软件包的测试。但是,它们在尽可能接近 Fedora 用户运行环境的环境中测试软件包的功能。除了特定的软件包测试外,Fedora 还运行一些发行版测试,例如从 F27 升级到 F28 或者全新安装。 + +软件包根据测试结果进行“控制”:测试失败会阻止将更新推送给用户。但是,有时由于各种原因,测试会失败。也许测试本身是错误的,或者不是最新的软件。或者可能发生基础架构问题,并阻止测试正常运行。维护人员能够重新触发测试或放弃测试结果,直到测试更新。 + +最终,当在 上有合并请求或者更新时,Fedora 的 CI 将运行测试。这将使维护者了解建议的更改对包稳定性的影响,并帮助他们决定如何进行。 + +### 我们如今有什么? + +目前,CI 管道在 Fedora Atomic Host 的部分软件包上运行测试。其他软件包可以在 dist-git 中进行测试,但它们不会自动运行。发行版特定的测试已经在我们所有的软件包上运行。这些测试结果被用于过滤测试失败的软件包。 + +### 我该如何参与? + +最好的入门方法是阅读关于 [Fedora 持续集成][1]的文档。你应该熟悉[标准测试接口][2],它描述了很多术语以及如何编写测试和使用现有的测试。 + +有了这些知识,如果你是一个软件包维护者,你可以开始添加测试到你的软件包。你可以在本地或虚拟机上运行它们。 (对于破坏性测试来说后者是明智的!) + +标准测试接口使测试保持一致。因此,你可以轻松地将任何测试添加到你喜欢的包中,并在 [仓库]​​[3] 提交合并请求给维护人员。 + +在 irc.freenode.net 上与 #fedora-ci 联系,提供反馈,问题或关于 CI 的一般性讨论。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/continuous-integration-fedora/ + +作者:[Pierre-Yves Chibon][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 +[1]:http://fedoraproject.org/wiki/CI +[2]:http://fedoraproject.org/wiki/CI/Standard_Test_Interface +[3]:https://src.fedoraproject.org +[4]:https://unsplash.com/photos/77oXlGwwOw0?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[5]:https://unsplash.com/search/photos/factory-line?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText diff --git a/published/201804/20180313 Running DOS on the Raspberry Pi.md b/published/201804/20180313 Running DOS on the Raspberry Pi.md new file mode 100644 index 0000000000..94d380f534 --- /dev/null +++ b/published/201804/20180313 Running DOS on the Raspberry Pi.md @@ -0,0 +1,84 @@ +在树莓派上运行 DOS 系统 +====== + +> 不同的 CPU 架构意味着在树莓派上运行 DOS 并非唾手可得,但其实也没多麻烦。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wings_freedos_game.jpg?itok=7j8x-A-w) + +[FreeDOS][1] 对大家来说也许并不陌生。它是一个完整、免费并且对 DOS 兼容良好的操作系统,它可以运行一些比较老旧的 DOS 游戏或者商用软件,也可以开发嵌入式的应用。只要在 MS-DOS 上能够运行的程序,在 FreeDOS 上都可以运行。 + +作为 FreeDOS 的发起者和项目协调人员,很多用户会把我作为内行人士进行发问。而我最常被问到的问题是:“FreeDOS 可以在树莓派上运行吗?” + +这个问题并不令人意外。毕竟 Linux 在树莓派上能够很好地运行,而 FreeDOS 和 Linux 相比是一个更古老、占用资源更少的操作系统,那 FreeDOS 为啥不能树莓派上运行呢? + +简单来说。由于 CPU 架构的原因,FreeDOS 并不能在树莓派中独立运行。和其它 DOS 类的系统一样,FreeDOS 需要英特尔 x86 架构 CPU 以及 BIOS 来提供基础的运行时服务。而树莓派运行在 ARM 架构的 CPU 上,与英特尔 CPU 二进制不兼容,也没有 BIOS。因此树莓派在硬件层面就不支持 FreeDOS。 + +不过通过 PC 模拟器还是能在树莓派上运行 FreeDOS 的,虽然这样也许稍有不足,但也不失为一个能在树莓派上运行 FreeDOS 的方法。 + +### DOSBox 怎么样? + +有人可能会问:“为什么不用 DOSBox 呢?” DOSBox 是一个开源的跨平台 x86 模拟器,在 Linux 上也能使用,它能够为应用软件尤其是游戏软件提供了一个类 DOS 的运行环境,所以如果你只是想玩 DOS 游戏的话,DOSBox 是一个不错的选择。但在大众眼中,DOSBox 是专为 DOS 游戏而设的,而在运行一些别的 DOS 应用软件方面,DOSBox 只是表现平平。 + +对多数人来说,这只是个人偏好的问题,我喜欢用 FreeDOS 来运行 DOS 游戏和其它程序,完整的 DOS 系统和 DOSBox 相比能让我体验到更好的灵活性和操控性。我只用 DOSBox 来玩游戏,在其它方面还是选择完整的 FreeDOS。 + +### 在树莓派上安装 FreeDOS + +[QEMU][3](Quick EMUlator)是一款能在 Linux 系统上运行 DOS 系统的开源的虚拟机软件。很多流行的 Linux 系统都自带 QEMU。QEMU 在我的树莓派上的 Raspbian 系统中也同样能够运行,下文就有一些我在树莓派 [Raspbian GNU/Linux 9 (Stretch)][4] 系统中使用 QEMU 的截图。 + +去年我在写了一篇关于[如何在 Linux 系统中运行 DOS 程序][5]的文章的时候就用到了 QEMU,在树莓派上使用 QEMU 来安装运行 FreeDOS 的步骤基本上和在别的基于 GNOME 的系统上没有什么太大的区别。 + +在 QEMU 中你需要通过添加各种组件来搭建虚拟机。先指定一个用来安装运行 DOS 的虚拟磁盘镜像,通过 `qemu-img` 命令来创建一个虚拟磁盘镜像,对于 FreeDOS 来说不需要太大的空间,所以我只创建了一个 200MB 的虚拟磁盘: + +``` +qemu-img create freedos.img 200M +``` + +和 VMware 或者 VirtualBox 这些 PC 模拟器不同,使用 QEMU 需要通过添加各种组件来搭建虚拟机,尽管有点麻烦,但是并不困难。我使用了以下这些参数来在树莓派上使用 QEMU 安装 FreeDOS 系统: + +``` +qemu-system-i386 -m 16 -k en-us -rtc base=localtime -soundhw sb16,adlib -device cirrus-vga -hda freedos.img -cdrom FD12CD.iso -boot order=d +``` + +你可以在我其它的[文章][5]中找到这些命令的完整介绍。简单来说,上面这条命令指定了一个英特尔 i386 兼容虚拟机,并且分配了 16MB 内存、一个英文输入键盘、一个基于系统时间的实时时钟、一个声卡、一个音乐卡以及一个 VGA 卡。文件 `freedos.img` 指定为第一个硬盘(`C:`),`FD12CD.iso` 镜像作为 CD-ROM (`D:`)驱动。QEMU 设定为从 `D:` 的 CD-ROM 启动。 + +你只需要按照提示就可以轻松安装好 FreeDOS 1.2 了。但是由于 microSD 卡在面对大量的 I/O 时速度比较慢,所以安装操作系统需要花费很长时间。 + +### 在树莓派上运行 FreeDOS + +你的运行情况取决于使用哪一种 microSD 卡。我用的是 SanDisk Ultra 64GB microSDXC UHS-I U1A1 ,其中 U1 这种型号专用于支持 1080p 的视频录制(例如 GoPro),它的最低串行写速度能够达到 10MB/s。相比之下,V60 型号专用于 4K 视频录制,最低连续写入速度能达到 60MB/s。如果你的树莓派使用的是 V60 的 microSD 卡甚至是 V30(也能达到 30MB/s),你就能明显看到它的 I/O 性能会比我的好。 + +FreeDOS 安装好之后,你可以直接从 `C:` 进行启动。只需要按照下面的命令用 `-boot order=c` 来指定 QEMU 的启动顺序即可: + +``` +​qemu-system-i386 -m 16 -k en-us -rtc base=localtime -soundhw sb16,adlib -device cirrus-vga -hda freedos.img -cdrom FD12CD.iso -boot order=c​ +``` + +只要树莓派的 QEMU 上安装了 FreeDOS,就不会出现明显的性能问题。例如游戏通常在每一关开始的时候会加载地图、怪物、声音等一系列的数据,尽管这些内容需要加载一段时间,但在正常玩的时候并没有出现性能不足的现象。 + +FreeDOS 1.2 自带了很多游戏以及其它应用软件,可以使用 `FDIMPLES` 包管理程序来安装它们。FreeDOS 1.2 里面我最喜欢的是一款叫 WING 的太空射击游戏,让人想起经典的街机游戏 Galaga(WING 就是 Wing Is Not Galaga 的递归缩写词)。 + +As-Easy-As 是我最喜欢的一个 DOS 应用程序,作为 20 世纪八九十年代流行的电子表格程序,它和当时的 Lotus 1-2-3 以及现在的 Microsoft Excel、LibreOffice Calc 一样具有强大的威力。As-Easy-As 和 Lotus 1-2-3 都将数据保存为 WKS 文件,现在新版本的 Microsoft Excel 已经无法读取这种文件了,而 LibreOffice Calc 视兼容性而定有可能支持。鉴于 As-Easy-As 的初始版本是一个共享软件,TRIUS 仍然为 As-Easy-As 5.7 免费提供[激活码][6]。 + +我也非常喜欢 GNU Emacs 编辑器,FreeDOS 也自带了一个叫 Freemacs 的类 Emacs 的文本编辑器。它比 FreeDOS 默认的 FreeDOS Edit 编辑器更强大,也能带来 GNU Emacs 的体验。如果你也需要,可以在 FreeDOS 1.2 中通过`FDIMPLES`包管理程序来安装。 + +### 是的,你或许真的可以在树莓派上运行 DOS + +即使树莓派在硬件上不支持 DOS,但是在模拟器的帮助下,DOS 还是能够在树莓派上运行。得益于 QEMU PC 模拟器,一些经典的 DOS 游戏和 DOS 应用程序能够运行在树莓派上。在执行磁盘 I/O ,尤其是大量密集操作(例如写入大量数据)的时候,性能可能会受到轻微的影响。当你使用 QEMU 并且在虚拟机里安装好 FreeDOS 之后,你就可以尽情享受经典的 DOS 程序了。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/can-you-run-dos-raspberry-pi + +作者:[Jim Hall][a] +译者:[HankChow](https://github.com/HankChow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jim-hall +[1]:http://www.freedos.org/ +[2]:https://opensource.com/article/18/3/raspberry-pi-week-giveaway +[3]:https://www.qemu.org/ +[4]:https://www.raspberrypi.org/downloads/ +[5]:https://linux.cn/article-9014-1.html +[6]:http://www.triusinc.com/forums/viewtopic.php?t=10 diff --git a/published/201804/20180313 The Type Command Tutorial With Examples For Beginners.md b/published/201804/20180313 The Type Command Tutorial With Examples For Beginners.md new file mode 100644 index 0000000000..5db9fd5426 --- /dev/null +++ b/published/201804/20180313 The Type Command Tutorial With Examples For Beginners.md @@ -0,0 +1,78 @@ +给初学者的 type 命令教程 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/Type-command-720x340.png) + +`type` 命令用于查找 Linux 命令的信息。顾名思义,你可以使用 `type` 命令轻松找出给定的命令是否是别名、shell 内置命令、文件、函数或关键字。另外,你也可以找到命令的实际路径。为什么有人需要找到命令类型?例如,如果你经常在共享的计算机上工作,则某些人可能会故意或意外地为特定的 Linux 命令创建别名来执行不需要的操作,例如 `alias ls = rm -rf /`。因此,在发生更糟糕的事情之前检查它们总是一个好主意。这是 `type` 命令有用的地方。 + +让我给你看一些例子。 + +不带任何选项运行 `type` 命令。 + +``` +$ type ls +ls is aliased to `ls --color=auto' +``` + +正如你在上面的输出中看到的那样,`ls` 命令已被别名为 `ls -color-auto`。但是,它是无害的。但只要想想 `ls` 如果被别名为了其他一些危险的命令。你不想那样,是吗? + +你可以使用 `-t` 选项仅找出 Linux 命令的类型。例如: + +``` +$ type -t ls +alias + +$ type -t mkdir +file + +$ type -t pwd +builtin + +$ type -t if +keyword + +$ type -t rvm +function +``` + +该命令仅显示命令的类型,例如别名。它不显示被别名的内容。如果该命令找不到,你将在终端中看不到任何内容。 + +`type` 命令的另一个有用的地方是我们可以很容易地找出给定 Linux 命令的绝对路径。为此,请使用 `-p` 选项,如下所示。 + +``` +$ type -p cal +/usr/bin/cal +``` + +这与 `which ls` 命令类似。如果给定的命令是别名,则不会打印任何内容。 + +要显示命令的所有信息,请使用 `-a` 选项。 + +``` +$ type -a ls +ls is aliased to `ls --color=auto' +ls is /usr/bin/ls +ls is /bin/ls +``` + +如你所见,`-a` 标志显示给定命令的类型及其绝对路径。有关更多详细信息,请参阅手册页。 + +``` +$ man type +``` + +希望这有帮助。会有更多的好东西。请继续访问! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/the-type-command-tutorial-with-examples-for-beginners/ + +作者:[SK][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ diff --git a/published/201804/20180314 Playing with water.md b/published/201804/20180314 Playing with water.md new file mode 100644 index 0000000000..f4b275d3cd --- /dev/null +++ b/published/201804/20180314 Playing with water.md @@ -0,0 +1,41 @@ +尝试 H2o 做机器学习 +====== + +![H2o Flow gradient boosting job][1] + +我目前正在参加一个机器学习班,虽然工作量很疯狂,但我非常喜欢。我最初计划使用 [R][2] 来训练我的数据库,但老师建议我使用一个 FOSS 机器学习框架 [H2o][3]。 + +起初我有点怀疑,因为我已经对 R 掌握得不错了,但后来我发现你可以简单地将 H2o 作为 R 库导入。H2o 将大多数 R 函数替换为其自己的并行化函数,以减少处理时间(不再需要 `doParallel` 调用),并且使用“外部”服务端来运行,而不是直接调用 R。 + +![H2o Flow gradient boosting model][4] + +直到我真正在实际中开始在 H2o 中使用 R 时,我对这种情况都非常满意。我在使用非常大的数据库时,库变得笨重,我几乎不能做任何有用得事情。大多数时候,我最后只是得到一个很长的 Java 回溯调用。 + +我相信正确地将 H2o 作为一个库使用将非常强大,但可惜的是,它似乎在我的 R 技能中无效。 + +![H2o Flow variable importance weights][5] + +我生了一整天的气 —— 无法实现我想做的事 —— 直到我意识到 H2o 有一个名为 Flow 的 WebUI。我通常不喜欢使用 web 来完成重要的工作,比如编写代码,但是 Flow 简直太不可思议了。 + +自动绘图功能,运行资源密集模型时集成 ETA(预计剩余时间),每个模型参数的描述(这些参数甚至会根据您熟悉的统计模型分成不同部分),Flow 似乎拥有所有功能。我很快就能够运行 3 种基本的机器学习模型并获得实际可解释的结果。 + +所以,如果你一直渴望使用最先进的机器学习模型分析非常大的数据库,我会推荐使用 H2o。首先尝试使用 Flow,而不是 Python 或 R 的钩子,来看看它能做什么。 + +唯一缺点是,H2o 是用 Java 编写的,并依赖 Java 1.7 来运行。并且需要警告的是:它需要非常强大的处理器和大量的内存。即使有 10 个可用的内核和 10Gb 的 RAM,我可怜的服务器也苦苦挣扎了一段时间。 + +-------------------------------------------------------------------------------- + +via: https://veronneau.org/playing-with-water.html + +作者:[Louis-Philippe Véronneau][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://veronneau.org/ +[1]:https://veronneau.org/media/blog/2018-03-14/h2o_job.png (H2o Flow gradient boosting job) +[2]:https://en.wikipedia.org/wiki/R_(programming_language) +[3]:https://www.h2o.ai +[4]:https://veronneau.org/media/blog/2018-03-14/h2o_model.png (H2o Flow gradient boosting model) +[5]:https://veronneau.org/media/blog/2018-03-14/h2o_var_importance.png (H2o Flow variable importance weights) diff --git a/published/201804/20180318 How To Manage Disk Partitions Using Parted Command.md b/published/201804/20180318 How To Manage Disk Partitions Using Parted Command.md new file mode 100644 index 0000000000..eb9bfd0850 --- /dev/null +++ b/published/201804/20180318 How To Manage Disk Partitions Using Parted Command.md @@ -0,0 +1,443 @@ +怎样用 parted 管理硬盘分区 +====== + +众所周知,对硬盘分区是 Linux 管理员一项最重要的管理任务之一,他们不能不知道这个。 + +在最糟糕的时候,你至少每周会收到一次依赖小组的请求,而在更大的环境里会更加频繁 。 + +你可能会问为什么我们要用 `parted` 而不是 `fdisk`? 它们有什么区别?好问题,我会告诉你这两者的区别。 + + * `parted` 支持用户在大于 2TB 的硬盘上创建硬盘分区, 但 `fdisk` 命令不支持 + * 对比 `fdisk` 来说,`parted` 是一个更高级的工具 + * 支持更多的分区表类型,包括 GPT (LCTT 译注:全局唯一标识分区表) + * 它允许用户调整分区大小, 但当缩减分区空间的时候,它没有如我意料的工作,多数情况下我会得到错误消息。所以我会建议用户不要用 `parted` 来缩减分区大小。 + +### 什么是 parted + +`parted` 是一个操作硬盘分区的程序。它支持多种分区表类型,包括 MS-DOS 和 GPT。 + +它允许用户创建、删除、调整、缩减、移动和复制分区,以及重新组织硬盘的使用,复制数据到新的硬盘上。`gparted` 是 `parted` 的图形界面前端。 + +### 怎样安装 parted + +大部分发行版已经预安装了 `parted`。如果没有,用下列命令来安装 `parted`。 + +对于 Debian/Ubuntu 用户, 使用 [APT-GET 命令][1] 或者 [APT 命令][2] 来安装 `parted`。 + +``` +$ sudo apt install parted +``` + +对于 RHEL/CentOS 用户,用 [YUM 命令][3] 来安装 `parted`。 + +``` +$ sudo yum install parted +``` + +对于 Fedora 用户,用 [DNF 命令][4] 来安装 `parted`。 + +``` +$ sudo dnf install parted +``` + +对于 Arch Linux 用户,用 [Pacman 命令][5]来安装 `parted`。 +``` +$ sudo pacman -S parted + +``` + +对于 openSUSE 用户, 用 [Zypper 命令][6]来安装 `parted`。 + +``` +$ sudo zypper in parted +``` + +### 怎样启动 parted + +下面的 `parted` 命令会自动选择 `/dev/sda` ,因为这是系统的第一个硬盘。 + +``` +$ sudo parted +GNU parted 3.2 +Using /dev/sda +Welcome to GNU parted! Type 'help' to view a list of commands. +(parted) +``` + +同时我们也可以用下面的命令来重新选择对应的的硬盘。 + +``` +(parted) select /dev/sdb +Using /dev/sdb +(parted) +``` + +如果你想选择特定的硬盘, 用下列的格式来输入命令。 这次 ,我们将选择 `/dev/sdb`。 + +``` +$ sudo parted [Device Name] +``` + +``` +$ sudo parted /dev/sdb +GNU parted 3.2 +Using /dev/sdb +Welcome to GNU parted! Type 'help' to view a list of commands. +(parted) +``` + +### 怎样用 parted 列出所有可用的硬盘 + +如果你不知道你的电脑上有什么硬盘,只需要运行下列命令,该命令会显示所有可用硬盘的名字,以及其它的有用信息比如储存空间、型号、扇区大小、硬盘标志以及分区信息。 + +``` +$ sudo parted -l +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sda: 32.2GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 1 1049kB 32.2GB 32.2GB primary ext4 boot + + +Error: /dev/sdb: unrecognised disk label +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: unknown +Disk Flags: +``` + +上面的错误信息清晰地显示出硬盘 `/dev/sdb` 没有有效的磁盘标签disk label。 它不会自动得到磁盘标签,所以, 我们便要自己设置硬盘标签。 + +### 怎样用 parted 创建硬盘分区 + +`parted` 允许用户创建主分区或者拓展分区。创建这两种类型的分区的步骤还是一样,但请确保你已经指定了需要的分区类型,比如 `primary` (主分区)或者 `extended` (扩展分区)。 + +为了演示这项操作 ,我们安装了一个新的 `50 GB` 的硬盘到到电脑上,挂载在 `/dev/sdb` 上。 + +有两种方法创建分区,第一种是更详细的方法,另一种只是一个命令。 在下面的例子中,我们将用更详细的方法添加一个主分区。提醒一下, 我们应该先设置磁盘标签,因为它不会自动设置任何标签。 + +在下面的例子中,我们将要创建一个 `10 GB` 的分区 + +``` +$ sudo parted /dev/sdb +GNU parted 3.2 +Using /dev/sdb +Welcome to GNU parted! Type 'help' to view a list of commands. +(parted) mklabel msdos +(parted) unit GB +(parted) mkpart +Partition type? primary/extended? primary +File system type? [ext2]? ext4 +Start? 0.00GB +End? 10.00GB +(parted) print +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 1 0.00GB 10.0GB 10.0GB primary ext4 lba + +(parted) quit +Information: You may need to update /etc/fstab. +``` + +同时,我们也可以使用单条 `parted` 命令 + +在下面的例子中,我们将在硬盘上创建一个 `10 GB` 的分区。 + +``` +$ sudo parted [Disk Name] [mkpart] [Partition Type] [Filesystem Type] [Partition Start Size] [Partition End Size] +``` + +``` +$ sudo parted /dev/sdb mkpart primary ext4 10.0GB 20.0GB +Information: You may need to update /etc/fstab. +``` + +### 怎样使用所有剩余空间创建分区 + +你已经创建了除了 `/home` 之外等所有要求的分区,而且你想要用硬盘上所有剩余的空间来创建 `/home` 分区,要怎样做?可以使用下面的命令来创建分区。 + +下面的命令创建了一个 33.7 GB 的分区,从 `20 GB` 开始到 `53 GB` 结束。 `100%` 使用率允许用户用硬盘上所有剩余的空余空间。 + +``` +$ sudo parted [Disk Name] [mkpart] [Partition Type] [Filesystem Type] [Partition Start Size] [Partition End Size] + +$ sudo parted /dev/sdb mkpart primary ext4 20.0GB 100% +Information: You may need to update /etc/fstab. +``` + +### 怎样用 parted 列出所有的分区 + +你也许注意到了,我们已经在上述步骤中创建了三个分区,如果你想要列出所有在硬盘上可用的分区,可以使用 `print` 命令。 + +``` +$ sudo parted /dev/sdb print +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 1 1049kB 10.0GB 9999MB primary ext4 + 2 10.0GB 20.0GB 9999MB primary ext4 + 3 20.0GB 53.7GB 33.7GB primary ext4 +``` + +### 怎样用 mkfs 格式化分区 + +用户可以用 `mkfs` 命令格式化分区。下面的步骤会用 `mkfs` 来格式化分区。 + +``` +$ sudo mkfs.ext4 /dev/sdb1 +mke2fs 1.43.4 (31-Jan-2017) +Creating filesystem with 2621440 4k blocks and 656640 inodes +Filesystem UUID: 415cf467-634c-4403-8c9f-47526bbaa381 +Superblock backups stored on blocks: + 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 + +Allocating group tables: done +Writing inode tables: done +Creating journal (16384 blocks): done +Writing superblocks and filesystem accounting information: done +``` + +同样的。 + +``` +$ sudo mkfs.ext4 /dev/sdb2 +$ sudo mkfs.ext4 /dev/sdb3 +``` + +创建必要的文件夹然后将这些分区挂载在上面。 + +``` +$ sudo mkdir /par1 /par2 /par3 +``` + +``` +$ sudo mount /dev/sdb1 /par1 +$ sudo mount /dev/sdb2 /par2 +$ sudo mount /dev/sdb3 /par3 +``` + +运行下列命令来检查是否成功挂载上新创建的分区。 + +``` +$ df -h /dev/sdb[1-3] +Filesystem Size Used Avail Use% Mounted on +/dev/sdb1 9.2G 37M 8.6G 1% /par1 +/dev/sdb2 9.2G 37M 8.6G 1% /par2 +/dev/sdb3 31G 49M 30G 1% /par3 +``` + +### 怎样检查硬盘空闲空间 + +运行下列命令来检查硬盘上的空闲空间,这块硬盘上有 `25.7 GB` 的空闲空间。 + +``` +$ sudo parted /dev/sdb print free +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 32.3kB 1049kB 1016kB Free Space + 1 1049kB 10.0GB 9999MB primary ext4 + 2 10.0GB 20.0GB 9999MB primary ext4 + 3 20.0GB 28.0GB 8001MB primary ext4 + 28.0GB 53.7GB 25.7GB Free Space +``` + +### 怎样使用 parted 命令来重新调整分区大小 + +`parted` 允许用户重新调整分区大小。不过我已在文章的开头说了,不要缩小分区大小,不然会有许多错误。 + +运行下列命令来检查硬盘分区以及所有可用空间。 可以看到硬盘上有 `25.7GB` 的可用空间。 + +``` +$ sudo parted /dev/sdb print free +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 32.3kB 1049kB 1016kB Free Space + 1 1049kB 10.0GB 9999MB primary ext4 + 2 10.0GB 20.0GB 9999MB primary ext4 + 3 20.0GB 28.0GB 8001MB primary ext4 + 28.0GB 53.7GB 25.7GB Free Space +``` + +运行下列命令来重新调整分区大小。 我们将要重新调整(增加)分区 3 的结束位置,从 `28GB` 到 `33GB`。 + +``` +$ sudo parted [Disk Name] [resizepart] [Partition Number] [Partition New End Size] + +$ sudo parted /dev/sdb resizepart 3 33.0GB +Information: You may need to update /etc/fstab. +``` + +运行下列命令来确认分区是否已经扩容。可以看到,分区 3 已经从 `8GB` 增加到 `13GB`。 + +``` +$ sudo parted /dev/sdb print +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 1 1049kB 10.0GB 9999MB primary ext4 + 2 10.0GB 20.0GB 9999MB primary ext4 + 3 20.0GB 33.0GB 13.0GB primary ext4 + +``` + +重新调整文件系统大小。 + +``` +$ sudo resize2fs /dev/sdb3 +resize2fs 1.43.4 (31-Jan-2017) +Resizing the filesystem on /dev/sdb3 to 3173952 (4k) blocks. +The filesystem on /dev/sdb3 is now 3173952 (4k) blocks long. +``` + +最后,确认分区是否已经扩容。 + +``` +$ df -h /dev/sdb[1-3] +Filesystem Size Used Avail Use% Mounted on +/dev/sdb1 9.2G 5.1G 3.6G 59% /par1 +/dev/sdb2 9.2G 2.1G 6.6G 24% /par2 +/dev/sdb3 12G 1.1G 11G 10% /par3 +``` + +### 怎样用 parted 删除分区 + +我们用 `rm` 命令方便地删除未使用的分区(如果该分区不会再被用到了)。下列步骤中,我们将会删除分区 3 (`/dev/sdb3`)。 + +``` +$ sudo parted [Disk Name] [rm] [Partition Number] + +$ sudo parted /dev/sdb rm 3 +Warning: Partition /dev/sdb3 is being used. Are you sure you want to continue? +Yes/No? Yes +Error: Partition(s) 3 on /dev/sdb have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use. As a result, the old partition(s) will remain in use. +You should reboot now before making further changes. +Ignore/Cancel? Ignore +Information: You may need to update /etc/fstab. +``` + +我们也可以用下列的命令检查。可以看到,分区 3 已经被成功移除。 + +``` +$ sudo parted /dev/sdb print +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 1 1049kB 10.0GB 9999MB primary ext4 + 2 10.0GB 20.0GB 9999MB primary ext4 + +``` + +### 怎样用 parted 命令设置/更改分区标志 + +我们可以用下列的命令来轻易更改分区的标志。 我们将对 `/dev/sdb2` 设置 `lvm` 标志。 + +``` +$ sudo parted [Disk Name] [set] [Partition Number] [Flags Name] [Flag On/Off] + +$ sudo parted /dev/sdb set 2 lvm on +Information: You may need to update /etc/fstab. +``` + +我们可以列出分区来验证这次的更改。 + +``` +$ sudo parted /dev/sdb print +Model: ATA VBOX HARDDISK (scsi) +Disk /dev/sdb: 53.7GB +Sector size (logical/physical): 512B/512B +Partition Table: msdos +Disk Flags: + +Number Start End Size Type File system Flags + 1 1049kB 10.0GB 9999MB primary ext4 + 2 10.0GB 20.0GB 9999MB primary ext4 lvm + +``` + +如果你想知道可用的标志,只需要用如下的命令。 + +``` +$ (parted) help set + set NUMBER FLAG STATE change the FLAG on partition NUMBER + + NUMBER is the partition number used by Linux. On MS-DOS disk labels, the primary partitions number from 1 to 4, logical partitions from 5 onwards. + FLAG is one of: boot, root, swap, hidden, raid, lvm, lba, hp-service, palo, prep, msftres, bios_grub, atvrecv, diag, legacy_boot, msftdata, irst, esp + STATE is one of: on, off +``` + +如果你想知道 `parted` 的其它可用命令, 只需要去到 `help` 页面。 + +``` +$ sudo parted +GNU parted 3.2 +Using /dev/sda +Welcome to GNU parted! Type 'help' to view a list of commands. +(parted) help + align-check TYPE N check partition N for TYPE(min|opt) alignment + help [COMMAND] print general help, or help on COMMAND + mklabel,mktable LABEL-TYPE create a new disklabel (partition table) + mkpart PART-TYPE [FS-TYPE] START END make a partition + name NUMBER NAME name partition NUMBER as NAME + print [devices|free|list,all|NUMBER] display the partition table, available devices, free space, all found partitions, or a particular partition + quit exit program + rescue START END rescue a lost partition near START and END + resizepart NUMBER END resize partition NUMBER + rm NUMBER delete partition NUMBER + select DEVICE choose the device to edit + disk_set FLAG STATE change the FLAG on selected device + disk_toggle [FLAG] toggle the state of FLAG on selected device + set NUMBER FLAG STATE change the FLAG on partition NUMBER + toggle [NUMBER [FLAG]] toggle the state of FLAG on partition NUMBER + unit UNIT set the default unit to UNIT + version display the version number and copyright information of GNU parted +(parted) quit +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-manage-disk-partitions-using-parted-command/ + +作者:[Magesh Maruthamuthu][a] +译者:[zyk2290](https://github.com/zyk2290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/magesh/ +[1]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/ +[2]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/ +[3]:https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/ +[4]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/ +[5]:https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/ +[6]:https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/ diff --git a/published/201804/20180321 The Command line Personal Assistant For Your Linux System.md b/published/201804/20180321 The Command line Personal Assistant For Your Linux System.md new file mode 100644 index 0000000000..c483ed94be --- /dev/null +++ b/published/201804/20180321 The Command line Personal Assistant For Your Linux System.md @@ -0,0 +1,413 @@ +Yoda:您的 Linux 系统命令行个人助理 +=========== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/Yoda-720x340.png) + +不久前,我们介绍了一个名为 [“Betty”][1] 的命令行虚拟助手。今天,我偶然发现了一个类似的实用程序,叫做 “Yoda”。Yoda 是一个命令行个人助理,可以帮助您在 Linux 中完成一些琐碎的任务。它是用 Python 编写的一个自由开源应用程序。在本指南中,我们将了解如何在 GNU/Linux 中安装和使用 Yoda。 + +### 安装 Yoda,命令行私人助理。 + +Yoda 需要 Python 2 和 PIP 。如果在您的 Linux 中没有安装 PIP,请参考下面的指南来安装它。只要确保已经安装了 python2-pip 。Yoda 可能不支持 Python 3。 + +- [如何使用 pip 管理 Python 包](https://www.ostechnix.com/manage-python-packages-using-pip/) + +注意:我建议你在 Python 虚拟环境下试用 Yoda。 不仅仅是 Yoda,应该总在虚拟环境中尝试任何 Python 应用程序,让它们不会干扰全局安装的软件包。 您可以按照上文链接中标题为“创建虚拟环境”一节中所述设置虚拟环境。 + +在您的系统上安装了 `pip` 之后,使用下面的命令克隆 Yoda 库。 + +``` +$ git clone https://github.com/yoda-pa/yoda +``` + +上面的命令将在当前工作目录中创建一个名为 `yoda` 的目录,并在其中克隆所有内容。转到 `yoda` 目录: + +``` +$ cd yoda/ +``` + +运行以下命令安装 Yoda 应用程序。 + +``` +$ pip install . +``` + +请注意最后的点(`.`)。 现在,所有必需的软件包将被下载并安装。 + +### 配置 Yoda + +首先,设置配置以将您的信息保存在本地系统上。 + +运行下面的命令: + +``` +$ yoda setup new +``` + +填写下列的问题: + +``` +Enter your name: +Senthil Kumar +What's your email id? +[email protected] +What's your github username? +sk +Enter your github password: +Password: +Where shall your config be stored? (Default: ~/.yoda/) + +A configuration file already exists. Are you sure you want to overwrite it? (y/n) +y +``` + +你的密码在加密后保存在配置文件中,所以不用担心。 + +要检查当前配置,请运行: + +``` +$ yoda setup check +``` + +你会看到如下的输出。 + +``` +Name: Senthil Kumar +Email: sk@senthilkumar.com +Github username: sk +``` + +默认情况下,您的信息存储在 `~/.yoda` 目录中。 + +要删除现有配置,请执行以下操作: + +``` +$ yoda setup delete +``` + +### 用法 + +Yoda 包含一个简单的聊天机器人。您可以使用下面的聊天命令与它交互。 + +``` +$ yoda chat who are you +``` + +样例输出: + +``` +Yoda speaks: +I'm a virtual agent + +$ yoda chat how are you +Yoda speaks: +I'm doing very well. Thanks! +``` + +以下是我们可以用 Yoda 做的事情: + +#### 测试网络速度 + +让我们问一下 Yoda 关于互联网速度的问题。运行: + +``` +$ yoda speedtest +Speed test results: +Ping: 108.45 ms +Download: 0.75 Mb/s +Upload: 1.95 Mb/s +``` + +#### 缩短和展开网址 + +Yoda 还有助于缩短任何网址: + +``` +$ yoda url shorten https://www.ostechnix.com/ +Here's your shortened URL: +https://goo.gl/hVW6U0 +``` + +要展开缩短的网址: + +``` +$ yoda url expand https://goo.gl/hVW6U0 +Here's your original URL: +https://www.ostechnix.com/ +``` + +#### 阅读 Hacker News + +我是 Hacker News 网站的常客。 如果你像我一样,你可以使用 Yoda 从下面的 Hacker News 网站阅读新闻。 + +``` +$ yoda hackernews +News-- 1/513 + +Title-- Show HN: a Yelp for iOS developers +Description-- I came up with this idea "a Yelp for developers" when talking with my colleagues. My hypothesis is that, it would be very helpful if we know more about a library before choosing to use it. It's similar to that we want to know more about a restaurant by checki… +url-- https://news.ycombinator.com/item?id=16636071 + +Continue? [press-"y"] +``` + +Yoda 将一次显示一个项目。 要阅读下一条新闻,只需输入 `y` 并按下回车。 + +#### 管理个人日记 + +我们也可以保留个人日记以记录重要事件。 + +使用命令创建一个新的日记: + +``` +$ yoda diary nn +Input your entry for note: +Today I learned about Yoda +``` + +要创建新笔记,请再次运行上述命令。 + +查看所有笔记: + +``` +$ yoda diary notes +Today's notes: +---------------- + Time | Note +--------|----- +16:41:41| Today I learned about Yoda +``` + +不仅仅是笔记,Yoda 还可以帮助你创建任务。 + +要创建新任务,请运行: + +``` +$ yoda diary nt +Input your entry for task: +Write an article about Yoda and publish it on OSTechNix +``` + +要查看任务列表,请运行: + +``` +$ yoda diary tasks +Today's agenda: +---------------- +Status | Time | Text +-------|---------|----- + O | 16:44:03: Write an article about Yoda and publish it on OSTechNix +---------------- + +Summary: +---------------- +Incomplete tasks: 1 +Completed tasks: 0 +``` + +正如你在上面看到的,我有一个未完成的任务。 要将其标记为已完成,请运行以下命令并输入已完成的任务序列号并按下回车键: + +``` +$ yoda diary ct +Today's agenda: +---------------- +Number | Time | Task +-------|---------|----- + 1 | 16:44:03: Write an article about Yoda and publish it on OSTechNix +Enter the task number that you would like to set as completed +1 +``` + +您可以随时使用命令分析当前月份的任务: + +``` +$ yoda diary analyze +Percentage of incomplete task : 0 +Percentage of complete task : 100 +Frequency of adding task (Task/Day) : 3 +``` + +有时候,你可能想要记录一个关于你爱的或者敬佩的人的个人资料。 + +#### 记录关于爱人的笔记 + +首先,您需要设置配置来存储朋友的详细信息。 请运行: + +``` +$ yoda love setup +``` + +输入你的朋友的详细信息: + +``` +Enter their name: +Abdul Kalam +Enter sex(M/F): +M +Where do they live? +Rameswaram +``` + +要查看此人的详细信息,请运行: + +``` +$ yoda love status +{'place': 'Rameswaram', 'name': 'Abdul Kalam', 'sex': 'M'} +``` + +要添加你的爱人的生日: + +``` +$ yoda love addbirth +Enter birthday +15-10-1931 +``` + +查看生日: + +``` +$ yoda love showbirth +Birthday is 15-10-1931 +``` + +你甚至可以添加关于该人的笔记: + +``` +$ yoda love note +Avul Pakir Jainulabdeen Abdul Kalam better known as A. P. J. Abdul Kalam, was the 11th President of India from 2002 to 2007. +``` + +您可以使用命令查看笔记: + +``` +$ yoda love notes +Notes: +1: Avul Pakir Jainulabdeen Abdul Kalam better known as A. P. J. Abdul Kalam, was the 11th President of India from 2002 to 2007. +``` + +你也可以写下这个人喜欢的东西: + +``` +$ yoda love like +Add things they like +Physics, Aerospace +Want to add more things they like? [y/n] +n +``` + +要查看他们喜欢的东西,请运行: + +``` +$ yoda love likes +Likes: +1: Physics, Aerospace +``` + +#### 跟踪资金费用 + +您不需要单独的工具来维护您的财务支出。 Yoda 会替您处理好。 + +首先,使用命令设置您的金钱支出配置: + +``` +$ yoda money setup +``` + +输入您的货币代码和初始金额: + +``` +Enter default currency code: +INR +{u'USD': 0.015338, u'IDR': 211.06, u'BGN': 0.024436, u'ISK': 1.5305, u'ILS': 0.053402, u'GBP': 0.010959, u'DKK': 0.093063, u'CAD': 0.020041, u'MXN': 0.28748, u'HUF': 3.8873, u'RON': 0.058302, u'MYR': 0.060086, u'SEK': 0.12564, u'SGD': 0.020208, u'HKD': 0.12031, u'AUD': 0.019908, u'CHF': 0.014644, u'KRW': 16.429, u'CNY': 0.097135, u'TRY': 0.06027, u'HRK': 0.092986, u'NZD': 0.021289, u'THB': 0.47854, u'EUR': 0.012494, u'NOK': 0.11852, u'RUB': 0.88518, u'JPY': 1.6332, u'CZK': 0.31764, u'BRL': 0.050489, u'PLN': 0.052822, u'PHP': 0.79871, u'ZAR': 0.1834} +₹ +Indian rupee +Enter initial amount: +10000 + +``` + +要查看金钱配置,只需运行: + +``` +$ yoda money status +{'initial_money': 10000, 'currency_code': 'INR'} +``` + +让我们假设你买了一本价值 250 卢比的书。 要添加此费用,请运行: + +``` +$ yoda money exp +Spend 250 INR on books +output: +``` + +要查看花费,请运行: + +``` +$ yoda money exps +2018-03-21 17:12:31 INR 250 books +``` + +#### 创建想法列表 + +创建一个新的想法: + +``` +$ yoda ideas add --task --inside +``` + +列出想法: + +``` +$ yoda ideas show +``` + +从任务中移除一个想法: + +``` +$ yoda ideas remove --task --inside +``` + +要完全删除这个想法,请运行: + +``` +$ yoda ideas remove --project +``` + +#### 学习英语词汇 + +Yoda 帮助你学习随机英语单词并追踪你的学习进度。 + +要学习一个新单词,请输入: + +``` +$ yoda vocabulary word +``` + +它会随机显示一个单词。 按回车键显示单词的含义。 再一次,Yoda 问你是否已经知道这个词的意思。 如果您已经知道,请输入“是”。 如果您不知道,请输入“否”。 这可以帮助你跟踪你的进度。 使用以下命令来了解您的进度。 + +``` +$ yoda vocabulary accuracy +``` + +此外,Yoda 可以帮助您做其他一些事情,比如找到单词的定义和创建插卡以轻松学习任何内容。 有关更多详细信息和可用选项列表,请参阅帮助部分。 + +``` +$ yoda --help +``` + +更多好的东西来了。请继续关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/yoda-the-command-line-personal-assistant-for-your-linux-system/ + +作者:[SK][a] +译者:[amwps290](https://github.com/amwps290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/betty-siri-like-commandline-virtual-assistant-linux/ diff --git a/published/201804/20180322 How To Find If A CPU Supports Virtualization Technology (VT).md b/published/201804/20180322 How To Find If A CPU Supports Virtualization Technology (VT).md new file mode 100644 index 0000000000..29796cf7b3 --- /dev/null +++ b/published/201804/20180322 How To Find If A CPU Supports Virtualization Technology (VT).md @@ -0,0 +1,177 @@ +如何知道 CPU 是否支持虚拟化技术(VT) +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/Virtualization-Technology-720x340.png) + +我们已经知道如何[检查你的 Linux 操作系统是 32 位还是 64 位] [1]以及如何[知道你的 Linux 系统是物理机还是虚拟机] [2]。今天,我们将学习另一个有用的话题 - 如何知道 CPU 是否支持虚拟化技术 (VT)?在安装虚拟化程序(如 VirtualBox 或 VMWare workstation)以在 Linux 系统上运行虚拟机之前,你应该首先验证这一点。现在让我们来看看你的电脑是否支持 VT。相信我,这真的很简单! + +### 了解 CPU 是否支持虚拟化技术 (VT) + +我们可以通过几种方法检查 CPU 是否支持 VT。在这里我向你展示四种方法。 + +#### 方法 1:使用 egrep 命令 + +`egrep` 是 [grep][3] 命令的变体之一,用于使用正则表达式搜索文本文件。为了本指南的目的,我们将 grep `/cpu/procinfo/` 文件来确定 CPU 是否支持 VT。 + +要使用 `egrep` 命令查明你的CPU是否支持VT,请运行: + +``` +$ egrep "(svm|vmx)" /proc/cpuinfo +``` + +示例输出: + +你将在输出中看到 `vmx`(Intel-VT 技术)或 `svm` (AMD-V 支持)。 + +``` +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave avx lahf_lm epb pti tpr_shadow vnmi flexpriority ept vpid xsaveopt dtherm arat pln pts +[...] +``` + +由于输出很长,你可能会发现很难在输出中找到 `vmx` 或 `svm`。别担心!你可以像下面那样用颜色来区分这些术语。 + +``` +$ egrep --color -i "svm|vmx" /proc/cpuinfo +``` + +![][5] + +如果你没有看到任何输出,这意味着你的系统不支持虚拟化。 + +请注意,`cpuinfo` 中的这些 CPU 标志(`vmx` 或 `svm`)表示你的系统支持 VT。在某些 CPU 型号中,默认情况下,可能会在 BIOS 中禁用 VT 支持。在这种情况下,你应该检查 BIOS 设置以启用 VT 支持。 + +有关 `grep`/`egrep` 命令的更多详细信息,请参阅手册页。 + +``` +$ man grep +``` + +#### 方法 2: 使用 lscpu 命令 + +`lscpu` 命令用于显示有关 CPU 架构的信息。它从 `sysfs`、`/proc/cpuinfo` 收集信息,并显示主机系统的 CPU、线程、内核、套接字和非统一内存访问 (NUMA) 节点的数量。 + +要确定是否启用 VT 支持,只需运行: + +``` +$ lscpu +``` + +![][6] + +有关更多详细信息,请查看手册页。 + +``` +$ man lscpu +``` + +#### 方法 3:使用 cpu-checker 工具 + +cpu-checker 是另一个有用的工具,用于测试你的 CPU 是否支持虚拟化。就我在网上搜索得到的,该程序仅适用于基于 Ubuntu 的系统。要安装它,请运行: + +``` +$ sudo apt-get install cpu-checker +``` + +安装 cpu-checker 包之后,运行以下命令来检查是否启用 VT 支持: + +``` +$ sudo kvm-ok +``` + +如果您的 CPU 支持 VT,你将得到以下输出: + +``` +INFO: /dev/kvm exists +KVM acceleration can be used +``` + +如果你的 CPU 不支持 VT,你会看到如下的输出。 + +``` +INFO: Your CPU does not support KVM extensions +KVM acceleration can NOT be used +``` + +#### 方法 4:使用 virt-host-validate 工具 + +该工具专门用于基于 RHEL 的发行版,如 CentOS 和 Scientific Linux。 libvirt-client 包提供 `virt-host-validate` 二进制文件。所以你需要安装 libvert-client 包来使用这个工具。 + +``` +$ sudo yum install libvirt-client +``` + +现在,运行 `virt-host-validate` 命令来确定基于 RHEL 的系统中是否启用了 VT。 + +``` +$ sudo virt-host-validate +``` + +如果所有的结果是 `pass`,那么你的系统支持 VT。 + +``` + QEMU: Checking for hardware virtualization : PASS + QEMU: Checking if device /dev/vhost-net exists : PASS + QEMU: Checking if device /dev/net/tun exists : PASS + QEMU: Checking for cgroup 'memory' controller support : PASS + QEMU: Checking for cgroup 'memory' controller mount-point : PASS + QEMU: Checking for cgroup 'cpu' controller support : PASS + QEMU: Checking for cgroup 'cpu' controller mount-point : PASS + QEMU: Checking for cgroup 'cpuacct' controller support : PASS + QEMU: Checking for cgroup 'cpuacct' controller mount-point : PASS + QEMU: Checking for cgroup 'cpuset' controller support : PASS + QEMU: Checking for cgroup 'cpuset' controller mount-point : PASS + QEMU: Checking for cgroup 'devices' controller support : PASS + QEMU: Checking for cgroup 'devices' controller mount-point : PASS + QEMU: Checking for cgroup 'blkio' controller support : PASS + QEMU: Checking for cgroup 'blkio' controller mount-point : PASS + QEMU: Checking for device assignment IOMMU support : PASS + LXC: Checking for Linux >= 2.6.26 : PASS + LXC: Checking for namespace ipc : PASS + LXC: Checking for namespace mnt : PASS + LXC: Checking for namespace pid : PASS + LXC: Checking for namespace uts : PASS + LXC: Checking for namespace net : PASS + LXC: Checking for namespace user : PASS + LXC: Checking for cgroup 'memory' controller support : PASS + LXC: Checking for cgroup 'memory' controller mount-point : PASS + LXC: Checking for cgroup 'cpu' controller support : PASS + LXC: Checking for cgroup 'cpu' controller mount-point : PASS + LXC: Checking for cgroup 'cpuacct' controller support : PASS + LXC: Checking for cgroup 'cpuacct' controller mount-point : PASS + LXC: Checking for cgroup 'cpuset' controller support : PASS + LXC: Checking for cgroup 'cpuset' controller mount-point : PASS + LXC: Checking for cgroup 'devices' controller support : PASS + LXC: Checking for cgroup 'devices' controller mount-point : PASS + LXC: Checking for cgroup 'blkio' controller support : PASS + LXC: Checking for cgroup 'blkio' controller mount-point : PASS +``` + +如果你的系统不支持 VT,你会看到下面的输出。 + +``` +QEMU: Checking for hardware virtualization : FAIL (Only emulated CPUs are available, performance will be significantly limited) +[...] +``` + +就是这样了。在本文中,我们讨论了确定 CPU 是否支持 VT 的不同方法。如你所见,这很简单。希望这个有用。还有更多好的东西。敬请关注! + +干杯! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-find-if-a-cpu-supports-virtualization-technology-vt/ + +作者:[SK][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/check-linux-system-32-bit-64-bit/ +[2]:https://www.ostechnix.com/check-linux-system-physical-virtual-machine/ +[3]:https://www.ostechnix.com/the-grep-command-tutorial-with-examples-for-beginners/ +[4]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[5]:http://www.ostechnix.com/wp-content/uploads/2018/03/cpuinfo.png +[6]:http://www.ostechnix.com/wp-content/uploads/2018/03/cpuinfo-1-2.png diff --git a/published/201804/20180323 How to tell when moving to blockchain is a bad idea.md b/published/201804/20180323 How to tell when moving to blockchain is a bad idea.md new file mode 100644 index 0000000000..f849cad6ee --- /dev/null +++ b/published/201804/20180323 How to tell when moving to blockchain is a bad idea.md @@ -0,0 +1,76 @@ +区块链不适用的若干场景 +====== + +> 这三个问题可以帮你避开不实宣传。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/blocks_building.png?itok=eMOT-ire) + +不错,“区块链”这个概念异常的火热。 + +众所周知,我一直关注区块链及相关技术的成熟度发展情况,思考我们是否对其评价过高了;但从目前的情况来看,还没有这个迹象。我在文中提到的区块链技术是广义上的,包含了狭义上不属于区块链的分布式账本技术(DLT)。我对私有链permissioned blockchain更感兴趣,其中私有链的定义可以参考我的文章《[区块链是安全性方面的话题吗?][1]》。简而言之,我对加密货币之外的区块链业务应用特别感兴趣^[注1](#footnote1) 。 + +我们对区块链的技术成熟度的判断应该有一部分可以得到证实^[注2](#footnote2) 。如果我们判断正确,未来将会出现海量的区块链应用。这很可能会变成现实,但并不是所有的应用都是优秀的区块链应用,其中一部分很可能是非常糟糕的。 + +但区块链所处的技术成熟度意味着,大量业务将快速拥抱新技术^[注3](#footnote3) ,但对于可能的前景却一知半解。促成这种情况的原因可以大致分为三种: + + 1. 对于涉及多用户数据存储的业务应用,在投入精力的情况下,几乎都可以改造为基于区块链的版本; + 2. 很多区块链相关的会议和“专家”呼吁尽快拥抱区块链,否则可能会在半年内被淘汰^[注4](#footnote4) ; + 3. 完全理解区块链技术是很难的,支持其在企业中落地的往往是工程师。 + +对于最后一条,我必须补充几句,不然很容易被引起众怒^[注5](#footnote5) 。作为一名工程师,我显然无意贬低工程师。但工程师的天性使然,我们对见到的新鲜事物(亮点)热情澎湃,却对业务本身深入fully grok^[注6](#footnote6) 不足,故对于新技术给业务带来的影响理解可能并不深刻。在业务领导者看来,这些影响不一定是有利的。 + +上面提到的三种促因可能导致一种风险,即在没有充分评估利弊的情况下,将业务改造为区块链应用。在另一文([区块链:每个人都应该参与进来吗?][2])中提到几个场景,用于判断一个业务什么情况下适合采用区块链技术。这些场景是有益的,但更进一步,我坚信人们更加需要的是,业务完全不适用区块链的几种简单的场景判定。我总结了三种场景判定,如果对于其中任何一个问题你给出了肯定的回答,那么很大概率上区块链不适合你。 + +### 场景判定 1:业务是否需要集中式的管控或授权? + +如果你给出了肯定的回答,那么区块链不适合你。 + +例如,假设你是一个普通销售商,具有唯一的订单系统,那么对于何时发货你有唯一的授权,显然区块链不适合你。假设你是一个内容提供商,所有提供的内容都会经过唯一的编辑和发布过程,显然区块链不适合你。 + +**经验总结:只有当任务对应的执行流程及相应的认证流程是分布于众多主体时,区块链是有价值的。** + +### 场景判定 2:业务使用经典数据库是否工作良好? + +如果你给出了肯定的回答,那么区块链不适合你。 + +该场景似乎与上一个场景是强相关的,但并不总是如此。在一些应用中,处理流程是分布的,但信息存储是中心化的;在另外一些应用中,处理流程需要中心化的授权,但信息存储是分布的,即总有一个并不是分布式的。但如果业务使用经典数据库可以工作量良好的话,使用经典数据库是一个好主意。 + +经典数据库不仅性能良好,在设计与运营成本方面低比区块链或分布式账本,而且我们在这方面技术积累丰厚。区块链让所有人^[注8](#footnote8) 可以查看和持有数据,但间接成本和潜在成本都比较高昂。 + +### 场景判定 3:业务采用新技术是否成本高昂或对合作伙伴有负面效果? + +如果你给出了肯定的回答,那么区块链不适合你。 + +我曾听过这种观点,即区块链会让所有人获益。但这显然是不可能的。假设你正在为某个流程设计一个应用,改变合作伙伴与你及应用的交互方式,那么你需要判断这个改变是否符合合作伙伴的想法。不论是否涉及区块链,可以很容易的设计并引入一个应用,虽然降低了你自己的业务阻力,但与此同时增加了合作伙伴的业务阻力。 + +假设我为汽车行业生产发动机配件,那么使用区块链追溯和管理配件会让我受益匪浅。例如,我可以查看购买的滚珠轴承的生产商、生产时间和钢铁材料供应商等。换一个角度,假设我是滚珠轴承生产商,已经为40多个客户公司建立了处理流程。为一家客户引入新的流程会涉及工作方式、系统体系、储藏和安全性标准等方面的变更,这无法让我感兴趣,相反,这会导致复杂性和高开销。 + +### 总结 + +这几个场景判定用于提纲挈领,并不是一成不变的。其中数据库相关的那个场景判定更像是技术方面的,但也是紧密结合业务定位和功能的。希望这几个判定可以为区块链技术引进促因带来的过热进行降温。 + +- 注 1. 请不要误解我的意思,加密货币显然是一种有趣的区块链业务应用,只是不在本文的讨论范畴而已。 +- 注 2. 知道具体是哪些部分是很有意义的,如果你知道,请告诉我好吗? +- 注 3. 坦率的说,它其实更像是一大堆技术的集合体。 +- 注 4. 这显然是不太可能的,如果被淘汰的主体是这些会议和“专家”本身倒十分有可能。 +- 注 5. 由于比方打得有些不恰当,估计还是会引起众怒。 +- 注 6. 我太喜欢 grok 这个单词了,我把它放在这里作为我的工程师标志^[注7](#footnote7) 。 +- 注 7. 你可能已经想到了,我读过*Stranger in a Strange Land*一书,包括删减版和原版。 +- 注 8. 在合理的情况下。 + +原文最初发表于[爱丽丝, 夏娃和鲍勃 – 一个安全性主题博客][3],已获得转载许可。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/3-tests-not-moving-blockchain + +作者:[Mike Bursell][a] +译者:[pinewall](https://github.com/pinewall) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mikecamel +[1]:https://opensource.com/article/17/12/blockchain-security-topic +[2]:https://aliceevebob.com/2017/09/12/blockchain-should-we-all-play/ +[3]:https://aliceevebob.com/2018/02/13/3-tests-for-not-moving-to-blockchain/ diff --git a/published/201804/20180323 Transfer Files From Computer To Mobile Devices By Scanning QR Codes.md b/published/201804/20180323 Transfer Files From Computer To Mobile Devices By Scanning QR Codes.md new file mode 100644 index 0000000000..6d12ac858f --- /dev/null +++ b/published/201804/20180323 Transfer Files From Computer To Mobile Devices By Scanning QR Codes.md @@ -0,0 +1,132 @@ +通过扫描二维码将文件从计算机传输到移动设备 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/03/qr-filetransfer-720x340.png) + +将文件从计算机传输到智能手机并不是什么大问题。你可以使用 USB 线将手机挂载到系统上,然后从文件管理器传输文件。此外,某些第三方应用程序(例如 [KDE Connect][1] 和 [AirDroid] [2])可帮助你轻松管理和传输系统中的文件至 Android 设备。今天,我偶然发现了一个名为 “Qr-filetransfer” 的超酷工具。它允许你通过扫描二维码通过 WiFi 将文件从计算机传输到移动设备而无须离开终端。是的,你没有看错! Qr-filetransfer 是一个使用 Go 语言编写的自由开源命令行工具。在这个简短的教程中,我们将学习如何使用 Qr-filetransfer 将文件从 Linux 传输到任何移动设备。 + +### 安装 Qr-filetransfer + +首先,在你的系统上安装 Go 语言。 + +在 Arch Linux 及其衍生版上: + +``` +$ sudo pacman -S go +``` + +在基于 RPM 的系统(如 RHEL、CentOS、Fedora)上运行: + +``` +$ sudo yum install golang +``` + +或者: + +``` +$ sudo dnf install golang +``` + +在基于 DEB 的系统上,例如 Debian、Ubuntu、Linux Mint,你可以使用命令安装它: + +``` +$ sudo apt-get install golang +``` + +在 SUSE/openSUSE 上: + +``` +$ sudo zypper install golang +``` + +安装 Go 语言后,运行以下命令下载 Qr-filetransfer 应用。 + +``` +$ go get github.com/claudiodangelis/qr-filetransfer +``` + +上述命令将在当前工作目录下的一个名为 `go` 的目录中下载 Qr-filetransfer GitHub 仓库的内容。 + +将 Qr-filetransfer 的二进制文件复制到 PATH 中,例如 `/usr/local/bin/`。 + +``` +$ sudo cp go/bin/qr-filetransfer /usr/local/bin/ +``` + +最后,如下使其可执行: + +``` +$ sudo chmod +x /usr/local/bin/qr-filetransfer +``` + +### 通过扫描二维码将文件从计算机传输到移动设备 + +确保你的智能手机已连接到与计算机相同的 WiFi 网络。 + +然后,使用要传输的文件的完整路径启动 `qt-filetransfer`。 + +比如,我要传输一个 mp3 文件。 + +``` +$ qr-filetransfer Chill\ Study\ Beats.mp3 +``` + +首次启动时,`qr-filetransfer` 会要求你选择使用的网络接口,如下所示。 + +``` +Choose the network interface to use (type the number): +[0] enp5s0 +[1] wlp9s0 +``` + +我打算使用 wlp9s0 接口传输文件,因此我输入 “1”。`qr-filetransfer` 会记住这个选择,除非你通过 `-force` 参数或删除程序存储在当前用户的家目录中的 `.qr-filetransfer.json` 文件,否则永远不会再提示你。 + +然后,你将看到二维码,如下图所示。 + +![][4] + +打开二维码应用(如果尚未安装,请从 Play 商店安装任何一个二维码读取程序)并扫描终端中显示的二维码。 + +读取二维码后,系统会询问你是要复制链接还是打开链接。你可以复制链接并手动将其粘贴到移动网络浏览器上,或者选择“打开链接”以在移动浏览器中自动打开它。 + +![][5] + +共享链接打开后,该文件将下载到智能手机中。 + +![][6] + +如果文件太大,请压缩文件,然后传输它: + +``` +$ qr-filetransfer -zip /path/to/file.txt +``` + +要传输整个目录,请运行: + +``` +$ qr-filetransfer /path/to/directory +``` + +请注意,目录在传输之前会被压缩。 + +`qr-filetransfer` 只能将系统中的内容传输到移动设备,反之不能。这个项目非常新,所以会有 bug。如果你遇到了任何 bug,请在本指南最后给出的 GitHub 页面上报告。 + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/transfer-files-from-computer-to-mobile-devices-by-scanning-qr-codes/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.ostechnix.com/kde-connect-access-files-notifications-android-devices/ +[2]:https://www.ostechnix.com/airdroid-share-files-and-folders-between-linux-and-android/ +[4]:http://www.ostechnix.com/wp-content/uploads/2018/03/qr-filetransfer-5.png +[5]:http://www.ostechnix.com/wp-content/uploads/2018/03/qr-filetransfer-6-4.png +[6]:http://www.ostechnix.com/wp-content/uploads/2018/03/qr-filetransfer-4.png diff --git a/published/201804/20180326 Working with calendars on Linux.md b/published/201804/20180326 Working with calendars on Linux.md new file mode 100644 index 0000000000..c89090addd --- /dev/null +++ b/published/201804/20180326 Working with calendars on Linux.md @@ -0,0 +1,273 @@ +在 Linux 命令行上使用日历 +===== + +> 通过 Linux 上的日历,不仅仅可以提醒你今天是星期几。诸如 date、cal、 ncal 和 calendar 等命令可以提供很多有用信息。 + +![](https://images.idgesg.net/images/article/2018/03/calendars-100753173-large.jpg) + +Linux 系统可以为你的日程安排提供更多帮助,而不仅仅是提醒你今天是星期几。日历显示有很多选项 —— 有些可能很有帮助,有些可能会让你大开眼界。 + +### 日期 + +首先,你可能知道可以使用 `date` 命令显示当前日期。 + +``` +$ date +Mon Mar 26 08:01:41 EDT 2018 +``` + +### cal 和 ncal + +你可以使用 `cal` 命令显示整个月份。没有参数时,`cal` 显示当前月份,默认情况下,通过反转前景色和背景颜色来突出显示当天。 + +``` +$ cal + March 2018 +Su Mo Tu We Th Fr Sa + 1 2 3 + 4 5 6 7 8 9 10 +11 12 13 14 15 16 17 +18 19 20 21 22 23 24 +25 26 27 28 29 30 31 +``` + +如果你想以“横向”格式显示当前月份,则可以使用 `ncal` 命令。 + +``` +$ ncal + March 2018 +Su 4 11 18 25 +Mo 5 12 19 26 +Tu 6 13 20 27 +We 7 14 21 28 +Th 1 8 15 22 29 +Fr 2 9 16 23 30 +Sa 3 10 17 24 31 +``` + +例如,如果你只想查看特定周几的日期,这个命令可能特别有用。 + +``` +$ ncal | grep Th +Th 1 8 15 22 29 +``` + +`ncal` 命令还可以以“横向”格式显示一整年,只需在命令后提供年份。 + +``` +$ ncal 2018 + 2018 + January February March April +Su 7 14 21 28 4 11 18 25 4 11 18 25 1 8 15 22 29 +Mo 1 8 15 22 29 5 12 19 26 5 12 19 26 2 9 16 23 30 +Tu 2 9 16 23 30 6 13 20 27 6 13 20 27 3 10 17 24 +We 3 10 17 24 31 7 14 21 28 7 14 21 28 4 11 18 25 +Th 4 11 18 25 1 8 15 22 1 8 15 22 29 5 12 19 26 +Fr 5 12 19 26 2 9 16 23 2 9 16 23 30 6 13 20 27 +Sa 6 13 20 27 3 10 17 24 3 10 17 24 31 7 14 21 28 +... +``` + +你也可以使用 `cal` 命令显示一整年。请记住,你需要输入年份的四位数字。如果你输入 `cal 18`,你将获得公元 18 年的历年,而不是 2018 年。 + +``` +$ cal 2018 + 2018 + January February March +Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa + 1 2 3 4 5 6 1 2 3 1 2 3 + 7 8 9 10 11 12 13 4 5 6 7 8 9 10 4 5 6 7 8 9 10 +14 15 16 17 18 19 20 11 12 13 14 15 16 17 11 12 13 14 15 16 17 +21 22 23 24 25 26 27 18 19 20 21 22 23 24 18 19 20 21 22 23 24 +28 29 30 31 25 26 27 28 25 26 27 28 29 30 31 + + + April May June +Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa + 1 2 3 4 5 6 7 1 2 3 4 5 1 2 + 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9 +15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16 +22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23 +29 30 27 28 29 30 31 24 25 26 27 28 29 30 + + + July August September +Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa + 1 2 3 4 5 6 7 1 2 3 4 1 + 8 9 10 11 12 13 14 5 6 7 8 9 10 11 2 3 4 5 6 7 8 +15 16 17 18 19 20 21 12 13 14 15 16 17 18 9 10 11 12 13 14 15 +22 23 24 25 26 27 28 19 20 21 22 23 24 25 16 17 18 19 20 21 22 +29 30 31 26 27 28 29 30 31 23 24 25 26 27 28 29 + 30 + + October November December +Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa + 1 2 3 4 5 6 1 2 3 1 + 7 8 9 10 11 12 13 4 5 6 7 8 9 10 2 3 4 5 6 7 8 +14 15 16 17 18 19 20 11 12 13 14 15 16 17 9 10 11 12 13 14 15 +21 22 23 24 25 26 27 18 19 20 21 22 23 24 16 17 18 19 20 21 22 +28 29 30 31 25 26 27 28 29 30 23 24 25 26 27 28 29 + 30 31 +``` + +要指定年份和月份,使用 `-d` 选项,如下所示: + +``` +$ cal -d 1949-03 + March 1949 +Su Mo Tu We Th Fr Sa + 1 2 3 4 5 + 6 7 8 9 10 11 12 +13 14 15 16 17 18 19 +20 21 22 23 24 25 26 +27 28 29 30 31 +``` + +另一个可能有用的日历选项是 `cal` 命令的 `-j` 选项。让我们来看看它显示的是什么。 + +``` +$ cal -j + March 2018 + Su Mo Tu We Th Fr Sa + 60 61 62 + 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 + 77 78 79 80 81 82 83 + 84 85 86 87 88 89 90 +``` + +你可能会问:“什么鬼???” OK, `-j` 选项显示 Julian 日期 -- 一年中从 1 到 365 年的数字日期。所以,1 是 1 月 1 日,32 是 2 月 1 日。命令 `cal -j 2018` 将显示一整年的数字,像这样: + +``` +$ cal -j 2018 | tail -9 + + November December + Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa + 305 306 307 335 +308 309 310 311 312 313 314 336 337 338 339 340 341 342 +315 316 317 318 319 320 321 343 344 345 346 347 348 349 +322 323 324 325 326 327 328 350 351 352 353 354 355 356 +329 330 331 332 333 334 357 358 359 360 361 362 363 + 364 365 +``` + +这种显示可能有助于提醒你,自从你做了新年计划之后,你已经有多少天没有采取行动了。 + +运行类似的命令,对于 2020 年,你会注意到这是一个闰年: + +``` +$ cal -j 2020 | tail -9 + + November December + Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa +306 307 308 309 310 311 312 336 337 338 339 340 +313 314 315 316 317 318 319 341 342 343 344 345 346 347 +320 321 322 323 324 325 326 348 349 350 351 352 353 354 +327 328 329 330 331 332 333 355 356 357 358 359 360 361 +334 335 362 363 364 365 366 +``` + +### calendar + +另一个有趣但潜在的令人沮丧的命令可以告诉你关于假期的事情,这个命令有很多选项,但我们这里介绍下你想看到即将到来的假期和值得注意的日历列表。日历的 `-l` 选项允许你选择今天想要查看的天数,因此 `0` 表示“仅限今天”。 + +``` +$ calendar -l 0 +Mar 26 Benjamin Thompson born, 1753, Count Rumford; physicist +Mar 26 David Packard died, 1996; age of 83 +Mar 26 Popeye statue unveiled, Crystal City TX Spinach Festival, 1937 +Mar 26 Independence Day in Bangladesh +Mar 26 Prince Jonah Kuhio Kalanianaole Day in Hawaii +Mar 26* Seward's Day in Alaska (last Monday) +Mar 26 Emerson, Lake, and Palmer record "Pictures at an Exhibition" live, 1971 +Mar 26 Ludwig van Beethoven dies in Vienna, Austria, 1827 +Mar 26 Bonne fête aux Lara ! +Mar 26 Aujourd'hui, c'est la St(e) Ludger. +Mar 26 N'oubliez pas les Larissa ! +Mar 26 Ludwig van Beethoven in Wien gestorben, 1827 +Mar 26 Emánuel +``` + +对于我们大多数人来说,这庆祝活动有点多。如果你看到类似这样的内容,可以将其归咎于你的 `calendar.all` 文件,该文件告诉系统你希望包含哪些国际日历。当然,你可以通过删除此文件中包含其他文件的一些行来削减此问题。文件看起来像这样: + +``` +#include +#include +#include +#include +#include +#include +#include +``` + +假设我们只通过移除除上面显示的第一个 `#include` 行之外的所有行,将我们的显示切换到世界日历。 我们会看到这个: + +``` +$ calendar -l 0 +Mar 26 Benjamin Thompson born, 1753, Count Rumford; physicist +Mar 26 David Packard died, 1996; age of 83 +Mar 26 Popeye statue unveiled, Crystal City TX Spinach Festival, 1937 +Mar 26 Independence Day in Bangladesh +Mar 26 Prince Jonah Kuhio Kalanianaole Day in Hawaii +Mar 26* Seward's Day in Alaska (last Monday) +Mar 26 Emerson, Lake, and Palmer record "Pictures at an Exhibition" live, 1971 +Mar 26 Ludwig van Beethoven dies in Vienna, Austria, 1827 +``` + +显然,世界日历的特殊日子非常多。但是,像这样的展示可以让你不要忘记所有重要的“大力水手雕像”揭幕日以及在庆祝“世界菠菜之都”中它所扮演的角色。 + +更有用的日历选择可能是将与工作相关的日历放入特殊文件中,并在 `calendar.all` 文件中使用该日历来确定在运行命令时将看到哪些事件。 + +``` +$ cat /usr/share/calendar/calendar.all +/* + * International and national calendar files + * + * This is the calendar master file. In the standard setup, it is + * included by /etc/calendar/default, so you can make any system-wide + * changes there and they will be kept when you upgrade. If you want + * to edit this file, copy it into /etc/calendar/calendar.all and + * edit it there. + * + */ + +#ifndef _calendar_all_ +#define _calendar_all_ + +#include +#include <== + +#endif /* !_calendar_all_ */ +``` + +日历文件的格式非常简单 - `mm/dd` 格式日期,空格和事件描述。 + +``` +$ cat calendar.work +03/26 Describe how the cal and calendar commands work +03/27 Throw a party! +``` + +### 注意事项和怀旧 + +注意,有关日历的命令可能不适用于所有 Linux 发行版,你可能必须记住自己的“大力水手”雕像。 + +如果你想知道,你可以显示一个日历,远至 9999 —— 即使是预言性的 [2525][1]。 + +在 [Facebook][2] 和 [LinkedIn][3] 上加入网络社区,对那些重要的话题发表评论。 + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3265752/linux/working-with-calendars-on-linux.html + +作者:[Sandra Henry-Stocker][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]:https://www.youtube.com/watch?v=izQB2-Kmiic +[2]:https://www.facebook.com/NetworkWorld/ +[3]:https://www.linkedin.com/company/network-world diff --git a/published/201804/20180328 Do continuous deployment with Github and Python.md b/published/201804/20180328 Do continuous deployment with Github and Python.md new file mode 100644 index 0000000000..12138bfdad --- /dev/null +++ b/published/201804/20180328 Do continuous deployment with Github and Python.md @@ -0,0 +1,175 @@ +使用 GitHub 和 Python 实现持续部署 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/03/cd-github-python-945x400.jpg) + +借助 GitHub 的网络钩子webhook,开发者可以创建很多有用的服务。从触发一个 Jenkins 实例上的 CI(持续集成) 任务到配置云中的机器,几乎有着无限的可能性。这篇教程将展示如何使用 Python 和 Flask 框架来搭建一个简单的持续部署(CD)服务。 + +在这个例子中的持续部署服务是一个简单的 Flask 应用,其带有接受 GitHub 的网络钩子webhook请求的 REST 端点endpoint。在验证每个请求都来自正确的 GitHub 仓库后,服务器将拉取pull更改到仓库的本地副本。这样每次一个新的提交commit推送到远程 GitHub 仓库,本地仓库就会自动更新。 + +### Flask web 服务 + +用 Flask 搭建一个小的 web 服务非常简单。这里可以先看看项目的结构。 + +``` +├── app +│ ├── __init__.py +│ └── webhooks.py +├── requirements.txt +└── wsgi.py +``` + +首先,创建应用。应用代码在 `app` 目录下。 + +两个文件(`__init__.py` 和 `webhooks.py`)构成了 Flask 应用。前者包含有创建 Flask 应用并为其添加配置的代码。后者有端点endpoint逻辑。这是该应用接收 GitHub 请求数据的地方。 + +这里是 `app/__init__.py` 的内容: + +``` +import os +from flask import Flask + +from .webhooks import webhook + +def create_app(): + """ Create, configure and return the Flask application """ + + app = Flask(__name__) + app.config['GITHUB_SECRET'] = os.environ.get('GITHUB_SECRET') + app.config['REPO_PATH'] = os.environ.get('REPO_PATH') + app.register_blueprint(webhook) + + return(app) +``` + +该函数创建了两个配置变量: + + * `GITHUB_SECRET` 保存一个密码,用来认证 GitHub 请求。 + * `REPO_PATH` 保存了自动更新的仓库路径。 + +这份代码使用[Flask 蓝图][1]Flask Blueprints来组织应用的端点endpoint。使用蓝图可以对 API 进行逻辑分组,使应用程序更易于维护。通常认为这是一种好的做法。 + +这里是 `app/webhooks.py` 的内容: + +``` +import hmac +from flask import request, Blueprint, jsonify, current_app +from git import Repo + +webhook = Blueprint('webhook', __name__, url_prefix='') + +@webhook.route('/github', methods=['POST']) +def handle_github_hook(): + """ Entry point for github webhook """ + + signature = request.headers.get('X-Hub-Signature') + sha, signature = signature.split('=') + + secret = str.encode(current_app.config.get('GITHUB_SECRET')) + + hashhex = hmac.new(secret, request.data, digestmod='sha1').hexdigest() + if hmac.compare_digest(hashhex, signature): + repo = Repo(current_app.config.get('REPO_PATH')) + origin = repo.remotes.origin + origin.pull('--rebase') + + commit = request.json['after'][0:6] + print('Repository updated with commit {}'.format(commit)) + return jsonify({}), 200 +``` + +首先代码创建了一个新的蓝图 `webhook`。然后它使用 Flask `route` 为蓝图添加了一个端点。任何请求 `/GitHub` URL 端点的 POST 请求都将调用这个路由。 + +#### 验证请求 + +当服务在该端点上接到请求时,首先它必须验证该请求是否来自 GitHub 以及来自正确的仓库。GitHub 在请求头的 `X-Hub-Signature` 中提供了一个签名。该签名由一个密码(`GITHUB_SECRET`),请求体的 HMAC 十六进制摘要,并使用 `sha1` 哈希生成。 + +为了验证请求,服务需要在本地计算签名并与请求头中收到的签名做比较。这可以由 `hmac.compare_digest` 函数完成。 + +#### 自定义钩子逻辑 + +在验证请求后,现在就可以处理了。这篇教程使用 [GitPython][3] 模块来与 git 仓库进行交互。GitPython 模块中的 `Repo` 对象用于访问远程仓库 `origin`。该服务在本地拉取 `origin` 仓库的最新更改,还用 `--rebase` 选项来避免合并的问题。 + +调试打印语句显示了从请求体收到的短提交哈希。这个例子展示了如何使用请求体。更多关于请求体的可用数据的信息,请查询 [GitHub 文档][4]。 + +最后该服务返回了一个空的 JSON 字符串和 200 的状态码。这用于告诉 GitHub 的网络钩子服务已经收到了请求。 + +### 部署服务 + +为了运行该服务,这个例子使用 [gunicorn][5] web 服务器。首先安装服务依赖。在支持的 Fedora 服务器上,以 [sudo][6] 运行这条命令: + +``` +sudo dnf install python3-gunicorn python3-flask python3-GitPython +``` + +现在编辑 gunicorn 使用的 `wsgi.py` 文件来运行该服务: + +``` +from app import create_app +application = create_app() +``` + +为了部署服务,使用以下命令克隆这个 git [仓库][7]或者使用你自己的 git 仓库: + +``` +git clone https://github.com/cverna/github_hook_deployment.git /opt/ +``` + +下一步是配置服务所需的环境变量。运行这些命令: + +``` +export GITHUB_SECRET=asecretpassphraseusebygithubwebhook +export REPO_PATH=/opt/github_hook_deployment/ +``` + +这篇教程使用网络钩子服务的 GitHub 仓库,但你可以使用你想要的不同仓库。最后,使用这些命令开启该 web 服务: + +``` +cd /opt/github_hook_deployment/ +gunicorn --bind 0.0.0.0 wsgi:application --reload +``` + +这些选项中绑定了 web 服务的 IP 地址为 `0.0.0.0`,意味着它将接收来自任何的主机的请求。选项 `--reload` 确保了当代码更改时重启 web 服务。这就是持续部署的魔力所在。每次接收到 GitHub 请求时将拉取仓库的最近更新,同时 gunicore 检测这些更改并且自动重启服务。 + +**注意: **为了能接收到 GitHub 请求,web 服务必须部署到具有公有 IP 地址的服务器上。做到这点的简单方法就是使用你最喜欢的云提供商比如 DigitalOcean,AWS,Linode等。 + +### 配置 GitHub + +这篇教程的最后一部分是配置 GitHub 来发送网络钩子请求到 web 服务上。这是持续部署的关键。 + +从你的 GitHub 仓库的设置中,选择 Webhook 菜单,并且点击“Add Webhook”。输入以下信息: + + * “Payload URL”: 服务的 URL,比如 `` + * “Content type”: 选择 “application/json” + * “Secret”: 前面定义的 `GITHUB_SECRET` 环境变量 + +然后点击“Add Webhook” 按钮。 + +![][8] + +现在每当该仓库发生推送事件时,GitHub 将向服务发送请求。 + +### 总结 + +这篇教程向你展示了如何写一个基于 Flask 的用于接收 GitHub 的网络钩子请求,并实现持续集成的 web 服务。现在你应该能以本教程作为起点来搭建对自己有用的服务。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/continuous-deployment-github-python/ + +作者:[Clément Verna][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[kimii](https://github.com/kimii) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:http://flask.pocoo.org/docs/0.12/blueprints/ +[2]:https://en.wikipedia.org/wiki/HMAC +[3]:https://gitpython.readthedocs.io/en/stable/index.html +[4]:https://developer.github.com/v3/activity/events/types/#webhook-payload-example-26 +[5]:http://gunicorn.org/ +[6]:https://fedoramagazine.org/howto-use-sudo/ +[7]:https://github.com/cverna/github_hook_deployment.git +[8]:https://fedoramagazine.org/wp-content/uploads/2018/03/Screenshot-2018-3-26-cverna-github_hook_deployment1.png diff --git a/published/201804/20180328 How To Create-Extend Swap Partition In Linux Using LVM.md b/published/201804/20180328 How To Create-Extend Swap Partition In Linux Using LVM.md new file mode 100644 index 0000000000..dd27d0ba42 --- /dev/null +++ b/published/201804/20180328 How To Create-Extend Swap Partition In Linux Using LVM.md @@ -0,0 +1,145 @@ +如何在 Linux 中使用 LVM 创建和扩展交换分区 +====== + +我们使用 LVM 进行灵活的卷管理,为什么我们不能将 LVM 用于交换分区呢? + +这可以让用户在需要时增加交换分区。如果你升级系统中的内存,则需要添加更多交换空间。这有助于你管理运行需要大量内存的应用的系统。 + +可以通过三种方式创建交换分区 + + * 创建一个新的交换分区 + * 创建一个新的交换文件 + * 在现有逻辑卷(LVM)上扩展交换分区 + +建议创建专用交换分区而不是交换文件。 + +**建议阅读:** + +* [3 种简单的方法在 Linux 中创建或扩展交换空间][1] +* [使用 Shell 脚本在 Linux 中自动创建/删除和挂载交换文件][2] + +Linux 中推荐的交换大小是多少? + +### 什么是交换空间 + +当物理内存 (RAM) 已满时,将使用 Linux 中的交换空间。当物理内存已满时,内存中的非活动页将移到交换空间。 + +这有助于系统连续运行应用程序,但它不能当做是更多内存的替代品。 + +交换空间位于硬盘上,因此它不能像物理内存那样处理请求。 + +### 如何使用 LVM 创建交换分区 + +由于我们已经知道如何创建逻辑卷,所以交换分区也是如此。只需按照以下过程。 + +创建你需要的逻辑卷。在我这里,我要创建 `5GB` 的交换分区。 + +``` +$ sudo lvcreate -L 5G -n LogVol_swap1 vg00 + Logical volume "LogVol_swap1" created. +``` + +格式化新的交换空间。 + +``` +$ sudo mkswap /dev/vg00/LogVol_swap1 +Setting up swapspace version 1, size = 5 GiB (5368705024 bytes) +no label, UUID=d278e9d6-4c37-4cb0-83e5-2745ca708582 +``` + +将以下条目添加到 `/etc/fstab` 中。 + +``` +# vi /etc/fstab +/dev/mapper/vg00-LogVol_swap1 swap swap defaults 0 0 +``` + +启用扩展逻辑卷。 + +``` +$ sudo swapon -va +swapon: /swapfile: already active -- ignored +swapon: /dev/mapper/vg00-LogVol_swap1: found signature [pagesize=4096, signature=swap] +swapon: /dev/mapper/vg00-LogVol_swap1: pagesize=4096, swapsize=5368709120, devsize=5368709120 +swapon /dev/mapper/vg00-LogVol_swap1 +``` + +测试交换空间是否已正确添加。 + +``` +$ cat /proc/swaps +Filename Type Size Used Priority +/swapfile file 1459804 526336 -1 +/dev/dm-0 partition 5242876 0 -2 + +$ free -g + total used free shared buff/cache available +Mem: 1 1 0 0 0 0 +Swap: 6 0 6 +``` + +### 如何使用 LVM 扩展交换分区 + +只需按照以下过程来扩展 LVM 交换逻辑卷。 + +禁用相关逻辑卷的交换。 + +``` +$ sudo swapoff -v /dev/vg00/LogVol_swap1 +swapoff /dev/vg00/LogVol_swap1 +``` + +调整逻辑卷的大小。我将把交换空间从 `5GB` 增加到 `11GB`。 + +``` +$ sudo lvresize /dev/vg00/LogVol_swap1 -L +6G + Size of logical volume vg00/LogVol_swap1 changed from 5.00 GiB (1280 extents) to 11.00 GiB (2816 extents). + Logical volume vg00/LogVol_swap1 successfully resized. +``` + +格式化新的交换空间。 + +``` +$ sudo mkswap /dev/vg00/LogVol_swap1 +mkswap: /dev/vg00/LogVol_swap1: warning: wiping old swap signature. +Setting up swapspace version 1, size = 11 GiB (11811155968 bytes) +no label, UUID=2e3b2ee0-ad0b-402c-bd12-5a9431b73623 +``` + +启用扩展逻辑卷。 + +``` +$ sudo swapon -va +swapon: /swapfile: already active -- ignored +swapon: /dev/mapper/vg00-LogVol_swap1: found signature [pagesize=4096, signature=swap] +swapon: /dev/mapper/vg00-LogVol_swap1: pagesize=4096, swapsize=11811160064, devsize=11811160064 +swapon /dev/mapper/vg00-LogVol_swap1 +``` + +测试逻辑卷是否已正确扩展。 + +``` +$ free -g + total used free shared buff/cache available +Mem: 1 1 0 0 0 0 +Swap: 12 0 12 + +$ cat /proc/swaps +Filename Type Size Used Priority +/swapfile file 1459804 237024 -1 +/dev/dm-0 partition 11534332 0 -2 +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-create-extend-swap-partition-in-linux-using-lvm/ + +作者:[Ramya Nuvvula][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/ramya/ +[1]:https://www.2daygeek.com/add-extend-increase-swap-space-memory-file-partition-linux/ +[2]:https://www.2daygeek.com/shell-script-create-add-extend-swap-space-linux/ diff --git a/published/201804/20180329 Protect Your Websites with Let-s Encrypt.md b/published/201804/20180329 Protect Your Websites with Let-s Encrypt.md new file mode 100644 index 0000000000..cc5e851acb --- /dev/null +++ b/published/201804/20180329 Protect Your Websites with Let-s Encrypt.md @@ -0,0 +1,92 @@ +使用 Let's Encrypt 保护你的网站 +====== + +> 未加密的 HTTP 会话暴露于滥用之中,用 Let's Encrypt 把它们保护起来。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/lock-1920.jpg?itok=7sjbOYkU) + +曾几何时,通过证书授权机构搭建基本的 HTTPS 网站需要每年花费数百美元,而且搭建的过程复杂且容易出错。现在我们免费使用 [Let's Encrypt][1],而且搭建过程也只需要几分钟。 + +### 为何进行加密? + +为什么要加密网站呢?这是因为未经加密的 HTTP 会话可以被多种方式滥用: + + + 窃听用户数据包 + + 捕捉用户登录 + + 注入[广告][12]和[“重要”消息][13] + + 注入[木马][14] + + 注入 [SEO 垃圾邮件和链接][15] + + 注入[挖矿脚本][16] + +网络服务提供商就是最大的代码注入者。那么如何挫败它们的非法行径呢?你最好的防御手段就是 HTTPS。让我们回顾一下 HTTPS 的工作原理。 + +### 信任链 + +你可以在你的网站和每个授权访问用户之间建立非对称加密。这是一种非常强的保护:GPG(GNU Privacy Guard, 参考[如何在 Linux 中加密邮件][2])和 OpenSSH 就是非对称加密的通用工具。它们依赖于公钥-私钥对,其中公钥可以任意分享,但私钥必须受到保护且不能分享。公钥用于加密,私钥用于解密。 + +但上述方法无法适用于随机的网页浏览,因为建立会话之前需要交换公钥,你需要生成并管理密钥对。HTTPS 会话可以自动完成公钥分发,而且购物或银行之类的敏感网站还会使用第三方证书颁发机构(CA)验证证书,例如 Comodo、 Verisign 和 Thawte。 + +当你访问一个 HTTPS 网站时,网站给你的网页浏览器返回了一个数字证书。这个证书说明你的会话被强加密,而且提供了该网站信息,包括组织名称、颁发证书的组织和证书颁发机构名称等。你可以点击网页浏览器地址栏的小锁头来查看这些信息(图 1),也包括了证书本身。 + +![][4] + +*图1: 点击网页浏览器地址栏上的锁头标记查看信息* + +包括 Opera、 Chromium 和 Chrome 在内的主流浏览器,验证网站数字证书的合法性都依赖于证书颁发机构。小锁头标记可以让你一眼看出证书状态;绿色意味着使用强 SSL 加密且运营实体经过验证。网页浏览器还会对恶意网站、SSL 证书配置有误的网站和不被信任的自签名证书网站给出警告。 + +那么网页浏览器如何判断网站是否可信呢?浏览器自带根证书库,包含了一系列根证书,存储在 `/usr/share/ca-certificates/mozilla/` 之类的地方。网站证书是否可信可以通过根证书库进行检查。就像你 Linux 系统上其它软件那样,根证书库也由包管理器维护。对于 Ubuntu,对应的包是 `ca-certificates`,这个 Linux 根证书库本身是[由 Mozilla 维护][6]的。 + +可见,整个工作流程需要复杂的基础设施才能完成。在你进行购物或金融等敏感在线操作时,你信任了无数陌生人对你的保护。 + +### 无处不加密 + +Let's Encrypt 是一家全球证书颁发机构,类似于其它商业根证书颁发机构。Let's Encrpt 由非营利性组织因特网安全研究小组Internet Security Research Group(ISRG)创立,目标是简化网站的安全加密。在我看来,出于后面我会提到的原因,该证书不足以胜任购物及银行网站的安全加密,但很适合加密博客、新闻和信息门户这类不涉及金融操作的网站。 + +使用 Let's Encrypt 有三种方式。推荐使用电子前沿基金会Electronic Frontier Foundation(EFF)开发的 [Cerbot 客户端][7]。使用该客户端需要在网站服务器上执行 shell 操作。 + +如果你使用的是共享托管主机,你很可能无法执行 shell 操作。这种情况下,最简单的方法是使用[支持 Let's Encrpt 的托管主机][8]。 + +如果你的托管主机不支持 Let's Encrypt,但支持自定义证书,那么你可以使用 Certbot [手动创建并上传你的证书][8]。这是一个复杂的过程,你需要彻底地研究文档。 + +安装证书后,使用 [SSL 服务器测试][9]来测试你的服务器。 + +Let's Encrypt 的电子证书有效期为 90 天。Certbot 安装过程中添加了一个证书自动续期的计划任务,也提供了测试证书自动续期是否成功的命令。允许使用已有的私钥或证书签名请求certificate signing request(CSR),允许创建通配符证书。 + +### 限制 + +Let's Encrypt 有如下限制:它只执行域名验证,即只要有域名控制权就可以获得证书。这是比较基础的 SSL。它不支持组织验证Organization Validation(OV)或扩展验证Extended Validation(EV),因为运营实体验证无法自动完成。我不会信任使用 Let's Encrypt 证书的购物或银行网站,它们应该购买支持运营实体验证的完整版本。 + +作为非营利性组织提供的免费服务,不提供商业支持,只提供不错的文档和社区支持。 + +因特网中恶意无处不在,一切数据都应该加密。从使用 [Let's Encrypt][10] 保护你的网站用户开始吧。 + +想要学习更多 Linux 知识,请参考 Linux 基金会和 edX 提供的免费课程 [“Linux 入门”][11]。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/3/protect-your-websites-lets-encrypt + +作者:[CARLA SCHRODER][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[pinewall](https://github.com/pinewall) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/cschroder +[1]:https://letsencrypt.org +[2]:https://www.linux.com/learn/how-encrypt-email-linux +[3]:https://www.linux.com/files/images/fig-11png-0 +[4]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fig-1_1_1.png?itok=_PPiSNx6 (页面信息) +[5]:https://www.linux.com/licenses/category/used-permission +[6]:https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/ +[7]:https://certbot.eff.org/ +[8]:https://community.letsencrypt.org/t/web-hosting-who-support-lets-encrypt/6920 +[9]:https://www.ssllabs.com/ssltest/ +[10]:https://letsencrypt.org/ +[11]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux +[12]:https://www.thesslstore.com/blog/third-party-content-injection/ +[13]:https://blog.ryankearney.com/2013/01/comcast-caught-intercepting-and-altering-your-web-traffic/ +[14]:https://www.eff.org/deeplinks/2018/03/we-still-need-more-https-government-middleboxes-caught-injecting-spyware-ads-and +[15]:https://techglimpse.com/wordpress-injected-with-spam-security/ +[16]:https://thehackernews.com/2018/03/cryptocurrency-spyware-malware.html diff --git a/published/201804/20180402 Advanced SSH Cheat Sheet.md b/published/201804/20180402 Advanced SSH Cheat Sheet.md new file mode 100644 index 0000000000..e8dae156e8 --- /dev/null +++ b/published/201804/20180402 Advanced SSH Cheat Sheet.md @@ -0,0 +1,91 @@ +高级 SSH 速查表 +=========================== + +所有人都知道 SSH 是一种远程登录工具,然而它也有许多其他用途。 + +创建一个 SOCKS 代理来浏览网页(也就是翻墙啦): +> ``` +ssh -D +``` +> 设置 `localhost:` 作为你浏览器的代理 + +连接一个堡垒机后的 Windows RDP 主机: + +> ``` +ssh -L ::3389 +``` +> 让你的 RDP 客户端连接到 `localhost:` + +在不使用 VNC 端口的情况下,连接远程 VNC 主机: + +> ``` +ssh -L 5901:localhost:5901 +``` +> 让你的 VNC 客户端连接到 `localhost:5901` + +按照这个思路,你可以映射任意端口:LDAP (389)、631 (CUPS)、8080 (替代的 HTTP),等等。 + +产生一个新的 SSH 密钥对: + +> ``` +ssh-keygen +``` + +更新密钥对的密码: + +> ``` +ssh-keygen -p +``` + +把公钥复制到远程主机上: + +> ``` +ssh-copy-id -i +``` + +SSH 有一堆命令行选项,但是如果有一些是你经常使用的,你可以为它们在 SSH 配置文件 (${HOME}/.ssh/config) 里创建一个入口。比如: + +>``` +host myhouse + User itsme +    HostName house.example.com +``` + +那么你就可以输入 `ssh myhouse` 来代替 `ssh itsme@house.example.com`。 + +以下是常用的命令行选项和他们的配置文件写法。一些是常用的简化写法。请查看 `ssh(1)` 和 `ssh_config(5)` 的手册页来获取详尽信息。 + +|命令行|配置文件|描述 +|:--|:--|:--| +| `-l ` | `User ` | 远程主机的登录用户名。| +| `-i ` | `IdentityFile ` |指定要使用的鉴权文件(SSH 密码对)。 | +| `-p ` | `Port ` | 远程 SSH 守护进程监听的端口号。 (默认为 22) | +| `-C` | `Compression ` | 压缩往来信息。 (默认为 no) | +| `-D ` | `DynamicForward ` | 把本地端口的报文转发到远程主机。 | +| `-X` | `ForwardX11 ` | 把 X11 的图像数据转发到远程主机的端口. (默认为 no) | +| `-A` | `ForwardAgent ` | 把授权代理的报文转发给远程主机。如果你使用第三方主机登录,这个功能将很有用。 (默认为 no) | +| `-4`(仅使用 IPv4) `-6` (仅使用 IPv6)| `AddressFamily ` | 指定仅使用 IPv4 或者 IPv6。 | +| `-L ::` | `LocalForward ::` | 把本地主机指定端口的报文转发到远程主机的某个端口。| + +opensource.com Twitter @opensourceway | facebook.com/opensourceway | IRC: #opensource.com on Freenode + + + +-------------------------------------------------------------------------------- + +作者简介: + +Ben Cotton 是业余的气象学家和职业的高性能计算工程师。Ben 是微软 Azure 的产品营销经理,专注于高性能计算。他是一个 Fedora 用户和贡献者,共同创立了一个当地的开放源码群,并且是开源促进会的成员和保护自由软件的支持者。通过以下方式联系他 Twitter (@FunnelFiasco) 或者 FunnelFiasco.com. + +------------- + +via: https://opensource.com/sites/default/files/gated-content/cheat_sheet_ssh_v03.pdf + +作者:[BEN COTTON][a] +译者:[kennethXia](https://github.com/kennethXia) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/bcotton +[1]:https://web.kamihq.com/web/upgrade.html diff --git a/published/201804/20180405 How to find files in Linux.md b/published/201804/20180405 How to find files in Linux.md new file mode 100644 index 0000000000..5af7e476fe --- /dev/null +++ b/published/201804/20180405 How to find files in Linux.md @@ -0,0 +1,75 @@ +如何在 Linux 中查找文件 +====== + +> 使用简单的命令在 Linux 下基于类型、内容等快速查找文件。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/find-file-linux-code_magnifying_glass_zero.png?itok=E2HoPDg0) + +如果你是 Windows 或 OSX 的非资深用户,那么可能使用 GUI 来查找文件。你也可能发现界面受限,令人沮丧,或者两者兼而有之,并学会了组织文件并记住它们的确切顺序。你也可以在 Linux 中做到这一点 —— 但你不必这样做。 + +Linux 的好处之一是它提供了多种方式来处理。你可以打开任何文件管理器或按下 `Ctrl+F`,你也可以使用程序手动打开文件,或者你可以开始输入字母,它会过滤当前目录列表。 + +![Screenshot of how to find files in Linux with Ctrl+F][2] + +*使用 Ctrl+F 在 Linux 中查找文件的截图* + +但是如果你不知道你的文件在哪里,又不想搜索整个磁盘呢?对于这个以及其他各种情况,Linux 都很合适。 + +### 按命令名查找程序位置 + +如果你习惯随心所欲地放文件,Linux 文件系统看起来会让人望而生畏。对我而言,最难习惯的一件事是找到程序在哪里。 + +例如,`which bash` 通常会返回 `/bin/bash`,但是如果你下载了一个程序并且它没有出现在你的菜单中,那么 `which` 命令就是一个很好的工具。 + +一个类似的工具是 `locate` 命令,我发现它对于查找配置文件很有用。我不喜欢输入程序名称,因为像 `locate php` 这样的简单程序通常会提供很多需要进一步过滤的结果。 + +有关 `locate` 和 `which` 的更多信息,请参阅 `man` 页面: + + * `man which` + * `man locate` + +### find + +`find` 工具提供了更先进的功能。以下是我安装在许多服务器上的脚本示例,我用于确保特定模式的文件(也称为 glob)仅存在五天,并且所有早于此的文件都将被删除。 (自上次修改以来,分数用于保留最多 240 分钟的偏差) + +``` +find ./backup/core-files*.tar.gz -mtime +4.9 -exec rm {} \; +``` + +`find` 工具有许多高级用法,但最常见的是对结果执行命令,而不用链式地按照类型、创建日期、修改日期过滤文件。 + +`find` 的另一个有趣用处是找到所有有可执行权限的文件。这有助于确保没有人在你昂贵的服务器上安装比特币挖矿程序或僵尸网络。 + +``` +find / -perm /+x +``` + +有关 `find` 的更多信息,请使用 `man find` 参考 `man` 页面。 + +### grep + +想通过内容中查找文件? Linux 已经实现了。你可以使用许多 Linux 工具来高效搜索符合模式的文件,但是 `grep` 是我经常使用的工具。 + +假设你有一个程序发布代码引用和堆栈跟踪的错误消息。你要在日志中找到这些。 `grep` 不总是最好的方法,但如果文件是一个给定的值,我经常使用 `grep -R`。 + +越来越多的 IDE 正在实现查找功能,但是如果你正在访问远程系统或出于任何原因没有 GUI,或者如果你想在当前目录递归查找,请使用:`grep -R {searchterm} ` 或在支持 `egrep` 别名的系统上,只需将 `-e` 标志添加到命令 `egrep -r {regex-pattern}`。 + +我在去年给 [Raspbian][3] 中的 `dhcpcd5` 打补丁时使用了这种技术,这样我就可以在[树莓派基金会][4]发布新的 Debian 时继续操作网络接入点了。 + +哪些提示可帮助你在 Linux 上更有效地搜索文件? + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/how-find-files-linux + +作者:[Lewis Cowles][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/lewiscowles1986 +[2]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/uploads/find-files-in-linux-ctrlf.png?itok=1gf9kIut (Screenshot of how to find files in Linux with Ctrl+F) +[3]:https://www.raspbian.org/ +[4]:https://www.raspberrypi.org/ diff --git a/published/201804/20180405 The fc Command Tutorial With Examples For Beginners.md b/published/201804/20180405 The fc Command Tutorial With Examples For Beginners.md new file mode 100644 index 0000000000..cecf5f055c --- /dev/null +++ b/published/201804/20180405 The fc Command Tutorial With Examples For Beginners.md @@ -0,0 +1,308 @@ +给初学者的 fc 示例教程 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/04/fc-command-720x340.png) + +`fc` (**F**ix **C**ommands 的缩写)是个 shell 内置命令,用于在交互式 shell 里列出、编辑和执行最近输入的命令。你可以用你喜欢的编辑器编辑最近的命令并再次执行,而不用把它们整个重新输入一遍。除了可以避免重复输入又长又复杂的命令,它对修正拼写错误来说也很有用。因为是 shell 内置命令,大多 shell 都包含它,比如 Bash 、 Zsh 、 Ksh 等。在这篇短文中,我们来学一学在 Linux 中使用 `fc` 命令。 + +### fc 命令教程及示例 + +#### 列出最近执行的命令 + +执行不带其它参数的 `fc -l` 命令,它会列出最近 16 个命令。 + +``` +$ fc -l +507 fish +508 fc -l +509 sudo netctl restart wlp9s0sktab +510 ls -l +511 pwd +512 uname -r +513 uname -a +514 touch ostechnix.txt +515 vi ostechnix.txt +516 echo "Welcome to OSTechNix" +517 sudo apcman -Syu +518 sudo pacman -Syu +519 more ostechnix.txt +520 wc -l ostechnix.txt +521 cat ostechnix.txt +522 clear +``` + +`-r` 选项用于将输出反向排序。 + +``` +$ fc -lr +``` + +`-n` 选项用于隐藏行号。 + +``` +$ fc -ln + nano ~/.profile + source ~/.profile + source ~/.profile + fc -ln + fc -l + sudo netctl restart wlp9s0sktab + ls -l + pwd + uname -r + uname -a + echo "Welcome to OSTechNix" + sudo apcman -Syu + cat ostechnix.txt + wc -l ostechnix.txt + more ostechnix.txt + clear +``` + +这样行号就不再显示了。 + +如果想以某个命令开始,只需在 `-l` 选项后面加上行号即可。比如,要显示行号 520 至最近的命令,可以这样: + +``` +$ fc -l 520 +520 ls -l +521 pwd +522 uname -r +523 uname -a +524 echo "Welcome to OSTechNix" +525 sudo apcman -Syu +526 cat ostechnix.txt +527 wc -l ostechnix.txt +528 more ostechnix.txt +529 clear +530 fc -ln +531 fc -l +``` + +要列出一段范围内的命令,将始、末行号作为 `fc -l` 的参数即可,比如 520 至 525: + +``` +$ fc -l 520 525 +520 ls -l +521 pwd +522 uname -r +523 uname -a +524 echo "Welcome to OSTechNix" +525 sudo apcman -Syu +``` + +除了使用行号,我们还可以使用字符。比如,要列出最近一个 `pwd` 至最近一个命令之间的所有命令,只需要像下面这样使用起始字母即可: + +``` +$ fc -l p +521 pwd +522 uname -r +523 uname -a +524 echo "Welcome to OSTechNix" +525 sudo apcman -Syu +526 cat ostechnix.txt +527 wc -l ostechnix.txt +528 more ostechnix.txt +529 clear +530 fc -ln +531 fc -l +532 fc -l 520 +533 fc -l 520 525 +534 fc -l 520 +535 fc -l 522 +536 fc -l l +``` + +要列出所有 `pwd` 和 `more` 之间的命令,你可以都使用起始字母,像这样: + +``` +$ fc -l p m +``` + +或者,使用开始命令的首字母以及结束命令的行号: + +``` +$ fc -l p 528 +``` + +或者都使用行号: + +``` +$ fc -l 521 528 +``` + +这三个命令都显示一样的结果。 + +#### 编辑并执行上一个命令 + +我们经常敲错命令,这时你可以用默认编辑器修正拼写错误并执行而不用将命令重新再敲一遍。 + +编辑并执行上一个命令: + +``` +$ fc +``` + +这会在默认编辑器里载入上一个命令。 + +![][2] + +你可以看到,我上一个命令是 `fc -l`。你可以随意修改,它会在你保存退出编辑器时自动执行。这在命令或参数又长又复杂时很有用。需要注意的是,它同时也可能是**毁灭性**的。比如,如果你的上一个命令是危险的 `rm -fr `,当它自动执行时你可能丢掉你的重要数据。所以,小心谨慎对待每一个命令。 + +#### 更改默认编辑器 + +另一个有用的选项是 `-e` ,它可以用来为 `fc` 命令选择不同的编辑器。比如,如果我们想用 `nano` 来编辑上一个命令: + +``` +$ fc -e nano +``` + +这个命令会打开 `nano` 编辑器(而不是默认编辑器)编辑上一个命令。 + +![][3] + +如果你觉得用 `-e` 选项太麻烦,你可以修改你的默认编辑器,只需要将环境变量 `FCEDIT` 设为你想要让 `fc` 使用的编辑器名称即可。 + +比如,要把 `nano` 设为默认编辑器,编辑你的 `~/.profile` 或其他初始化文件: (LCTT 译注:如果 `~/.profile` 不存在可自己创建;如果使用的是 bash ,可以编辑 `~/.bash_profile` ) + +``` +$ vi ~/.profile +``` + +添加下面一行: + +``` +FCEDIT=nano +# LCTT译注:如果在子 shell 中会用到 fc ,最好在这里 export FCEDIT +``` + +你也可以使用编辑器的完整路径: + +``` +FCEDIT=/usr/local/bin/emacs +``` + +输入 `:wq` 保存退出。要使改动立即生效,运行以下命令: + +``` +$ source ~/.profile +``` + +现在再输入 `fc` 就可以使用 `nano` 编辑器来编辑上一个命令了。 + +#### 不编辑而直接执行上一个命令 + +我们现在知道 `fc` 命令不带任何参数的话会将上一个命令载入编辑器。但有时你可能不想编辑,仅仅是想再次执行上一个命令。这很简单,在末尾加上连字符(`-`)就可以了: + +``` +$ echo "Welcome to OSTechNix" +Welcome to OSTechNix + +$ fc -e - +echo "Welcome to OSTechNix" +Welcome to OSTechNix +``` + +如你所见,`fc` 带了 `-e` 选项,但并没有编辑上一个命令(例中的 `echo " Welcome to OSTechNix"`)。 + +需要注意的是,有些选项仅对指定 shell 有效。比如下面这些选项可以用在 zsh 中,但在 Bash 或 Ksh 中则不能用。 + +#### 显示命令的执行时间 + +想要知道命令是在什么时候执行的,可以用 `-d` 选项: + +``` +fc -ld +1 18:41 exit +2 18:41 clear +3 18:42 fc -l +4 18:42 sudo netctl restart wlp9s0sktab +5 18:42 ls -l +6 18:42 pwd +7 18:42 uname -r +8 18:43 uname -a +9 18:43 cat ostechnix.txt +10 18:43 echo "Welcome to OSTechNix" +11 18:43 more ostechnix.txt +12 18:43 wc -l ostechnix.txt +13 18:43 cat ostechnix.txt +14 18:43 clear +15 18:43 fc -l +``` + +这样你就可以查看最近命令的具体执行时间了。 + +使用选项 `-f` ,可以为每个命令显示完整的时间戳。 + +``` + fc -lf + 1 4/5/2018 18:41 exit + 2 4/5/2018 18:41 clear + 3 4/5/2018 18:42 fc -l + 4 4/5/2018 18:42 sudo netctl restart wlp9s0sktab + 5 4/5/2018 18:42 ls -l + 6 4/5/2018 18:42 pwd + 7 4/5/2018 18:42 uname -r + 8 4/5/2018 18:43 uname -a + 9 4/5/2018 18:43 cat ostechnix.txt + 10 4/5/2018 18:43 echo "Welcome to OSTechNix" + 11 4/5/2018 18:43 more ostechnix.txt + 12 4/5/2018 18:43 wc -l ostechnix.txt + 13 4/5/2018 18:43 cat ostechnix.txt + 14 4/5/2018 18:43 clear + 15 4/5/2018 18:43 fc -l + 16 4/5/2018 18:43 fc -ld +``` + +当然,欧洲的老乡们还可以使用 `-E` 选项来显示欧洲时间格式。 + +``` + fc -lE + 2 5.4.2018 18:41 clear + 3 5.4.2018 18:42 fc -l + 4 5.4.2018 18:42 sudo netctl restart wlp9s0sktab + 5 5.4.2018 18:42 ls -l + 6 5.4.2018 18:42 pwd + 7 5.4.2018 18:42 uname -r + 8 5.4.2018 18:43 uname -a + 9 5.4.2018 18:43 cat ostechnix.txt + 10 5.4.2018 18:43 echo "Welcome to OSTechNix" + 11 5.4.2018 18:43 more ostechnix.txt + 12 5.4.2018 18:43 wc -l ostechnix.txt + 13 5.4.2018 18:43 cat ostechnix.txt + 14 5.4.2018 18:43 clear + 15 5.4.2018 18:43 fc -l + 16 5.4.2018 18:43 fc -ld + 17 5.4.2018 18:49 fc -lf +``` + +### fc 用法总结 + + * 当不带任何参数时,`fc` 将上一个命令载入默认编辑器。 + * 当带一个数字作为参数时,`fc` 将数字指定的命令载入默认编辑器。 + * 当带一个字符作为参数时,`fc` 将最近一个以指定字符开头的命令载入默认编辑器。 + * 当有两个参数时,它们分别指定需要列出的命令范围的开始和结束。 + +更多细节,请参考 man 手册。 + +``` +$ man fc +``` + +好了,今天就这些。希望这篇文章能帮助到你。更多精彩内容,敬请期待! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/the-fc-command-tutorial-with-examples-for-beginners/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[Dotcra](https://github.com/Dotcra) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[2]:http://www.ostechnix.com/wp-content/uploads/2018/04/fc-command-1.png +[3]:http://www.ostechnix.com/wp-content/uploads/2018/04/fc-command-2.png diff --git a/published/201804/20180407 12 Git tips for Git-s 12th birthday.md b/published/201804/20180407 12 Git tips for Git-s 12th birthday.md new file mode 100644 index 0000000000..a38d2b6c11 --- /dev/null +++ b/published/201804/20180407 12 Git tips for Git-s 12th birthday.md @@ -0,0 +1,157 @@ +13 个 Git 技巧献给 Git 13 岁生日 +===== + +> 这 13 个 Git 技巧将使你的版本控制技能 +1、+1、+1…… + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/party_anniversary_flag_birthday_celebrate.jpg?itok=KqfMENa7) + +[Git][1] 是一个分布式版本控制系统,它已经成为开源世界中源代码控制的默认工具,在 4 月 7 日这天,它 13 岁了。使用 Git 令人沮丧的事情之一是你需要知道更多才能有效地使用 Git。但这也可能是使用 Git 比较美妙的一件事,因为没有什么比发现一个新技巧来简化或提高你的工作流的效率更令人快乐了。 + +为了纪念 Git 的 13 岁生日,这里有 13 条技巧和诀窍来让你的 Git 经验更加有用和强大。从你可能忽略的一些基本知识开始,并扩展到一些真正的高级用户技巧! + +### 1、 你的 ~/.gitconfig 文件 + +当你第一次尝试使用 `git` 命令向仓库提交一个更改时,你可能会收到这样的欢迎信息: + +``` +*** Please tell me who you are. + +Run + +  git config --global user.email "you@example.com" + +  git config --global user.name "Your Name" + +to set your account's default identity. +``` + +你可能没有意识到正是这些命令在修改 `~/.gitconfig` 的内容,这是 Git 存储全局配置选项的地方。你可以通过 `~/.gitconfig` 文件来做大量的事,包括定义别名、永久性打开(或关闭)特定命令选项,以及修改 Git 工作方式(例如,`git diff` 使用哪个 diff 算法,或者默认使用什么类型的合并策略)。你甚至可以根据仓库的路径有条件地包含其他配置文件!所有细节请参阅 `man git-config`。 + +### 2、 你仓库中的 .git/config 文件 + +在之前的技巧中,你可能想知道 `git config` 命令中 `--global` 标志是干什么的。它告诉 Git 更新 `~/.gitconfig` 中的“全局”配置。当然,有全局配置也意味着会有本地配置,显然,如果你省略 `--global` 标志,`git config` 将改为更新仓库特有的配置,该配置存储在 `.git/config` 中。 + +在 `.git/config` 文件中设置的选项将覆盖 `~/.gitconfig` 文件中的所有设置。因此,例如,如果你需要为特定仓库使用不同的电子邮件地址,则可以运行 `git config user.email "also_you@example.com"`。然后,该仓库中的任何提交都将使用你单独配置的电子邮件地址。如果你在开源项目中工作,而且希望它们显示自己的电子邮件地址,同时仍然使用自己工作邮箱作为主 Git 配置,这非常有用。 + +几乎任何你可以在 `~/.gitconfig` 中设置的东西,你也可以在 `.git/config` 中进行设置,以使其作用于特定的仓库。在下面的技巧中,当我提到将某些内容添加到 `~/.gitconfig` 时,只需记住你也可以在特定仓库的 `.git/config` 中添加来设置那个选项。 + +### 3、 别名 + +别名是你可以在 `~/.gitconfig` 中做的另一件事。它的工作原理就像命令行中的 shell —— 它们设定一个新的命令名称,可以调用一个或多个其他命令,通常使用一组特定的选项或标志。它们对于那些你经常使用的又长又复杂的命令来说非常有效。 + +你可以使用 `git config` 命令来定义别名 —— 例如,运行 `git config --global --add alias.st status` 将使运行 `git st` 与运行 `git status` 做同样的事情 —— 但是我在定义别名时发现,直接编辑 `~/.gitconfig` 文件通常更容易。 + +如果你选择使用这种方法,你会发现 `~/.gitconfig` 文件是一个 [INI 文件][2]。INI 是一种带有特定段落的键值对文件格式。当添加一个别名时,你将改变 `[alias]` 段落。例如,定义上面相同的 `git st` 别名时,添加如下到文件: + +``` +[alias] +st = status +``` + +(如果已经有 `[alias]` 段落,只需将第二行添加到现有部分。) + +### 4、 shell 命令中的别名 + +别名不仅仅限于运行其他 Git 子命令 —— 你还可以定义运行其他 shell 命令的别名。这是一个用来处理一个反复发生的、罕见和复杂的任务的很好方式:一旦你确定了如何完成它,就可以在别名下保存该命令。例如,我有一些复刻fork的开源项目的仓库,并进行了一些本地修改。我想跟上项目正在进行的开发工作,并保存我本地的变化。为了实现这个目标,我需要定期将来自上游仓库的更改合并到我复刻的项目中 —— 我通过使用我称之为 `upstream-merge` 的别名来完成。它是这样定义的: + +``` +upstream-merge = !"git fetch origin -v && git fetch upstream -v && git merge upstream/master && git push" +``` + +别名定义开头的 `!` 告诉 Git 通过 shell 运行这个命令。这个例子涉及到运行一些 `git` 命令,但是以这种方式定义的别名可以运行任何 shell 命令。 + +(注意,如果你想复制我的 `upstream-merge` 别名,你需要确保你有一个名为 `upstream` 的 Git 远程仓库,指向你已经分配的上游仓库,你可以通过运行 `git remote add upstream ` 来添加一个。) + +### 5、 可视化提交图 + +如果你在一个有很多分支活动的项目上开发,有时可能很难掌握所有正在发生的工作以及它们之间的相关性。各种图形用户界面工具可让你获取不同分支的图片并在所谓的“提交图表”中提交。例如,以下是我使用 [GitLab][3] 提交图表查看器可视化的我的一个仓库的一部分: + +![GitLab commit graph viewer][5] + +如果你是一个专注于命令行的用户或者发现分支切换工具让人分心,那么可以从命令行获得类似的提交视图。这就是 `git log` 命令的 `--graph` 参数出现的地方: + +![Repository visualized with --graph command][7] + +以下命令可视化相同仓库可达到相同效果: + +``` +git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative +``` + +`--graph` 选项将图添加到日志的左侧,`--abbrev-commit` 缩短提交的 [SHA][8] 值,`--date=relative` 以相对方式表示日期,以及 `--pretty` 来处理所有其他自定义格式。我有个 `git lg` 别名用于这个功能,它是我最常用的 10 个命令之一。 + +### 6、 更优雅的强制推送 + +有时,你越是想避开越避不开,你会发现你需要运行 `git push --force` 来覆盖仓库远程副本上的历史记录。你可能得到了一些反馈,需要你进行交互式变基rebase,或者你可能已经搞砸了,并希望隐藏“罪证”。 + +当其他人在仓库的远程副本的同一分支上进行更改时,会发生强制推送的危险。当你强制推送已重写的历史记录时,这些提交将会丢失。这就是 `git push --force-with-lease` 出现的原因 -- 如果远程分支已经更新,它不会允许你强制推送,这确保你不会丢掉别人的工作。 + +### 7、 git add -N + +你是否使用过 `git commit -a` 在一次行动中提交所有未完成的修改,但在你推送完提交后才发现 `git commit -a` 忽略了新添加的文件?你可以使用 `git add -N` (想想 “notify”) 来解决这个问题,告诉 Git 在第一次实际提交它们之前,你希望在提交中包含新增文件。 + +### 8、 git add -p + +使用 Git 时的最佳做法是确保每次提交都只包含一个逻辑修改 —— 无论这是修复错误还是添加新功能。然而,有时当你在工作时,你的仓库中的修改最终应该使用多个提交。你怎样才能设法把事情分开,使每个提交只包含适当的修改呢?`git add --patch` 来拯救你了! + +这个标志会让 `git add` 命令查看你工作副本中的所有变化,并为每个变化询问你是否想要将它提交、跳过,或者推迟决定(你可以在运行该命令后选择 `?` 来查看其他更强大的选项)。`git add -p` 是生成结构良好的提交的绝佳工具。 + +### 9、 git checkout -p + +与 `git add -p` 类似,`git checkout` 命令也接受 `--patch` 或 `-p` 选项,这会使其在本地工作副本中显示每个“大块”的改动,并允许丢弃它 —— 简单来说就是将本地工作副本恢复到更改之前的状态。 + +这真的很棒。例如,当你追踪一个 bug 时引入了一堆调试日志语句,修正了这个 bug 之后,你可以先使用 `git checkout -p` 移除所有新的调试日志,然后 `git add -p` 来添加 bug 修复。没有比组合一个优雅的、结构良好的提交更令人满意! + +### 10、 变基时执行命令 + +有些项目有一个规则,即存储库中的每个提交都必须处于可工作状态 —— 也就是说,在每次提交时,应该可以编译该代码,或者应该运行测试套件而不会失败。 当你在分支上工作时,这并不困难,但是如果你最终因为某种原因需要变基rebase时,那么需要逐步完成每个变基的提交以确保你没有意外地引入一个中断,而这个过程是乏味的。 + +幸运的是,`git rebase` 已经覆盖了 `-x` 或 `--exec` 选项。`git rebase -x ` 将在每个提交在变基中被应用后运行该命令。因此,举个例子,如果你有一个项目,其中使用 `npm run tests` 运行你的测试套件,`git rebase -x npm run tests` 将在变基期间每次提交之后运行测试套件。这使你可以查看测试套件是否在任何变基的提交中失败,以便你可以确认测试套件在每次提交时仍能通过。 + +### 11、 基于时间的修订引用 + +很多 Git 子命令都接受一个修订参数来决定命令作用于仓库的哪个部分,可以是某次特定的提交的 SHA1 值,一个分支的名称,甚至是一个符号性的名称如 `HEAD`(代表当前检出分支最后一次的提交),除了这些简单的形式以外,你还可以附加一个指定的日期或时间作为参数,表示“这个时间的引用”。 + +这个功能在某些时候会变得十分有用。当你处理最新出现的 bug,自言自语道:“这个功能昨天还是好好的,到底又改了些什么”,不用盯着满屏的 `git log` 的输出试图弄清楚什么时候更改了提交,你只需运行 `git diff HEAD@{yesterday}`,看看从昨天以来的所有修改。这也适用于更长的时间段(例如 `git diff HEAD@{'2 months ago'}`),以及一个确切的日期(例如 `git diff HEAD@{'2010-01-01 12:00:00'}`)。 + +你也可以将这些基于日期的修订参数与使用修订参数的任何 Git 子命令一起使用。在 `gitrevisions` 手册页中有关于具体使用哪种格式的详细信息。 + +### 12、 全知的 reflog + +你是不是试过在变基时干掉过某次提交,然后发现你需要保留那个提交中一些东西?你可能觉得这些信息已经永远找不回来了,只能重新创建。但是如果你在本地工作副本中提交了,提交就会被添加到引用日志(reflog)中 ,你仍然可以访问到。 + +运行 `git reflog` 将在本地工作副本中显示当前分支的所有活动的列表,并为你提供每个提交的 SHA1 值。一旦发现你变基时放弃的那个提交,你可以运行 `git checkout ` 跳转到该提交,复制任何你需要的信息,然后再运行 `git checkout HEAD` 返回到分支最近的提交去。 + +### 13、自己清理 + +哎呦! 事实证明,我的基本数学技能不如我的 Git 技能。 Git 最初是在 2005 年发布的,这意味着它今年会变成 13 岁,而不是 12 岁(LCTT 译注:本文原来是以 12 岁生日为题的)。为了弥补这个错误,这里有可以让我们变成十三岁的第 13 条技巧。 + +如果你使用基于分支的工作流,随着在一个长期项目上的工作,除非你在每个分支合并时清理干净,否则你最终会得到一大堆分支。这使得你难于找到想要的分支,分支的森林会让你无从找起。甚至更糟糕的是,如果你有大量活跃的分支,确定一个分支是否被合并(可以被安全删除)或仍然没有被合并而应该留下会非常繁琐。幸运的是,Git 可以帮到你:只需要运行 `git branch --merged` 就可以得到已经被合并到你的当前分支的分支列表,或者 `git branch --no-merged` 找出被合并到其它分支的分支。默认情况下这会列出你本地工作副本的分支,但是如果你在命令行包括 `--remote` 或 `-r` 参数,它也会列出仅存于远程仓库的已合并分支。 + +重要提示:如果你计划使用 `git branch --merged` 的输出来清理那些已合并的分支,你要小心它的输出也包括了当前分支(毕竟,这个当前的分支就被合并到当前分支!)。确保你在任何销毁动作之前排除了该分支(如果你忘记了,参见第 12 条技巧来学习 reflog 怎样帮你把分支找回来,希望有用……)。 + +### 以上是全部内容 + +希望这些技巧中至少有一个能够教给你一些关于 Git 的新东西,Git 是一个有 13 年历史的项目,并且在持续创新和增加新功能中。你最喜欢的 Git 技巧是什么? + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/git-tips + +作者:[John SJ Anderson][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/genehack +[1]:https://git-scm.com/ +[2]:https://en.wikipedia.org/wiki/INI_file +[3]:https://gitlab.com/ +[4]:/file/392941 +[5]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/gui_graph.png?itok=3GovYfG1 (GitLab commit graph viewer) +[6]:/file/392936 +[7]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/console_graph.png?itok=XogY1P8M (Repository visualized with --graph command) +[8]:https://en.wikipedia.org/wiki/Secure_Hash_Algorithms diff --git a/published/201804/20180411 Awesome GNOME extensions for developers.md b/published/201804/20180411 Awesome GNOME extensions for developers.md new file mode 100644 index 0000000000..9ec1d05a67 --- /dev/null +++ b/published/201804/20180411 Awesome GNOME extensions for developers.md @@ -0,0 +1,143 @@ +开发者的最佳 GNOME 扩展 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/04/gnome-extensions-for-developers-816x345.jpg) + +扩展给予 GNOME3 桌面环境以非常大的灵活性,这种灵活性赋予了用户在定制化桌面上的优势,从而使他们的工作流程变得更加舒适和有效率。Fedora Magazine 已经介绍了一些很棒的桌面扩展,例如 [EasyScreenCast][1]、 [gTile][2] 和 [OpenWeather][3] ,本文接下来会重点报道这些为开发者而改变的扩展。 + +如果你需要帮助来安装 GNOME 扩展,那么可以参考《[如何安装一个 GNOME Shell 扩展][4]》这篇文章。 + +### Docker 集成(Docker Integration) + +![Docker Integration extension icon][5] + +![Docker Integration extension status menu][6] + +对于为自己的应用使用 Docker 的开发者而言,这个 [Docker 集成][7] 扩展是必不可少的。这个状态菜单提供了一个带着启动、停止、暂停、甚至删除它们的选项的 Docker 容器列表,这个列表会在新容器加入到这个系统时自动更新。 + +在安装完这个扩展后,Fedora 用户可能会收到这么一条消息:“Error occurred when fetching containers.(获取容器时发生错误)”。这是因为 Docker 命令默认需要 `sudo` 或 root 权限。要设置你的用户权限来运行 Docker,可以参考 [Fedora 开发者门户网站上的 Docker 安装这一页][8]。 + +你可以在该[扩展的站点][9]上找到更多的信息。 + +### Jenkins CI 服务器指示器(Jenkins CI Server Indicator) + +![Jenkins CI Server Indicator icon][10] + +![Jenkins CI Server Indicator extension status menu][11] + +[Jenkins CI 服务器指示器][12]这个扩展可以使开发者在 Jenkins CI 服务器建立应用很简单,它展示了一个菜单,包含有任务列表及那些任务的状态。它也包括了一些如轻松访问 Jenkins 网页前端、任务完成提示、以及触发和过滤任务等特性。 + +如果想要更多的信息,请去浏览[开发者站点][13]。 + +### 安卓工具(android-tool) + +![android-tool extension icon][14] + +![android-tool extension status menu][15] + +[安卓工具][16]对于 Android 开发者来说会是一个非常有价值的扩展,它的特性包括捕获错误报告、设备截屏和屏幕录像。它可以通过 usb 和 tcp 连接两种方式来连接 Android 设备。 + +这个扩展需要 `adb` 的包,从 Fedora 官方仓库安装 `adb` 只需要[运行这条命令][17]: + +``` +sudo dnf install android-tools +``` + +你可以在这个[扩展的 GitHub 网页][18]里找到更多信息。 + +### GnomeHub + +![GnomeHub extension icon][19] + +![GnomeHub extension status menu][20] + +对于自己的项目使用 GitHub 的 GNOME 用户来说,[GnomeHub][21] 是一个非常好的扩展,它可以显示 GitHub 上的仓库,还可以通知用户有新提交的拉取请求。除此之外,用户可以把他们最喜欢的仓库加在这个扩展的设置里。 + +如果想要更多信息,可以参考一下这个[项目的 GitHub 页面][22]。 + +### gistnotes + +![gistnotes extension icon][23] + +简单地说,[gistnotes][24] 为 gist 用户提供了一种创建、存储和管理注释和代码片段的简单方式。如果想要更多的信息,可以参考这个[项目的网站][25]。 + +![gistnotes window][26] + +### Arduino 控制器(Arduino Control) + +![Arduino Control extension icon][27] + +这个 [Arduino 控制器][28]扩展允许用户去连接或者控制他们自己的 Arduino 电路板,它同样允许用户在状态菜单里增加滑块或者开关。除此之外,开发者放在扩展目录里的脚本可以通过以太网或者 usb 来连接 Arduino 电路板。 + +最重要的是,这个扩展可以被定制化来适合你的项目,在器 README 文件里的提供例子是,它能够“通过网络上任意的电脑来控制你房间里的灯”。 + +你可以从这个[项目的 GitHub 页面][29]上得到更多的产品信息并安装这个扩展。 + +### Hotel Manager + +![Hotel Manager extension icon][30] + +![Hotel Manager extension status menu][31] + +使用 Hotel 进程管理器开发网站的开发人员,应该尝试一下 [Hotel Manager][32] 这个扩展。它展示了一个增加到 Hotel 里的网页应用的列表,并给与了用户开始、停止和重启这些应用的能力。此外,还可以通过右边的电脑图标快速打开、浏览这些网页应用。这个扩展同样可以启动、停止或重启 Hotel 的后台程序。 + +本文发布时,GNOME 3.26 版本的 Hotel Manager 版本 4 没有在该扩展的下拉式菜单里列出网页应用。版本 4 还会在 Fedora 28 (GNOME 3.28) 上安装时报错。然而,版本 3 工作在 Fedora 27 和 Fedora 28。 + +如果想要更多细节,可以去看这个[项目在 GitHub 上的网页][33]。 + +### VSCode 搜索插件(VSCode Search Provider) + +[VSCode 搜索插件][34]是一个简单的扩展,它能够在 GNOME 综合搜索结果里展示 Visual Studio Code 项目。对于重度 VSCode 用户来说,这个扩展可以让用户快速连接到他们的项目,从而节省时间。你可以从这个[项目在 GitHub 上的页面][35]来得到更多的信息。 + +![GNOME Overview search results showing VSCode projects.][36] + +在开发环境方面,你有没有一个最喜欢的扩展呢?发在评论区里,一起来讨论下吧。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/awesome-gnome-extensions-developers/ + +作者:[Shaun Assam][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[hopefully2333](https://github.com/hopefully2333) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org/author/sassam/ +[1]:https://fedoramagazine.org/screencast-gnome-extension/ +[2]:https://fedoramagazine.org/must-have-gnome-extension-gtile/ +[3]:https://fedoramagazine.org/weather-updates-openweather-gnome-shell-extension/ +[4]:https://linux.cn/article-9447-1.html +[5]:https://fedoramagazine.org/wp-content/uploads/2017/08/dockericon.png +[6]:https://fedoramagazine.org/wp-content/uploads/2017/08/docker-extension-menu.png +[7]:https://extensions.gnome.org/extension/1065/docker-status/ +[8]:https://developer.fedoraproject.org/tools/docker/docker-installation.html +[9]:https://github.com/gpouilloux/gnome-shell-extension-docker +[10]:https://fedoramagazine.org/wp-content/uploads/2017/08/jenkinsicon.png +[11]:https://fedoramagazine.org/wp-content/uploads/2017/08/jenkins-extension-menu.png +[12]:https://extensions.gnome.org/extension/399/jenkins-ci-server-indicator/ +[13]:https://www.philipphoffmann.de/gnome-3-shell-extension-jenkins-ci-server-indicator/ +[14]:https://fedoramagazine.org/wp-content/uploads/2017/08/androidtoolicon.png +[15]:https://fedoramagazine.org/wp-content/uploads/2017/08/android-tool-extension-menu.png +[16]:https://extensions.gnome.org/extension/1232/android-tool/ +[17]:https://fedoramagazine.org/howto-use-sudo/ +[18]:https://github.com/naman14/gnome-android-tool +[19]:https://fedoramagazine.org/wp-content/uploads/2017/08/gnomehubicon.png +[20]:https://fedoramagazine.org/wp-content/uploads/2017/08/gnomehub-extension-menu.png +[21]:https://extensions.gnome.org/extension/1263/gnomehub/ +[22]:https://github.com/lagartoflojo/gnomehub +[23]:https://fedoramagazine.org/wp-content/uploads/2017/08/gistnotesicon.png +[24]:https://extensions.gnome.org/extension/917/gistnotes/ +[25]:https://github.com/mohan43u/gistnotes +[26]:https://fedoramagazine.org/wp-content/uploads/2018/04/gistnoteswindow.png +[27]:https://fedoramagazine.org/wp-content/uploads/2017/08/arduinoicon.png +[28]:https://extensions.gnome.org/extension/894/arduino-control/ +[29]:https://github.com/simonthechipmunk/arduinocontrol +[30]:https://fedoramagazine.org/wp-content/uploads/2017/08/hotelicon.png +[31]:https://fedoramagazine.org/wp-content/uploads/2017/08/hotelmanager-extension-menu.png +[32]:https://extensions.gnome.org/extension/1285/hotel-manager/ +[33]:https://github.com/hardpixel/hotel-manager +[34]:https://extensions.gnome.org/extension/1207/vscode-search-provider/ +[35]:https://github.com/jomik/vscode-search-provider +[36]:https://fedoramagazine.org/wp-content/uploads/2018/04/vscodesearch.png diff --git a/published/201804/20180412 3 password managers for the Linux command line.md b/published/201804/20180412 3 password managers for the Linux command line.md new file mode 100644 index 0000000000..cf0b6e75b7 --- /dev/null +++ b/published/201804/20180412 3 password managers for the Linux command line.md @@ -0,0 +1,78 @@ +3 个 Linux 命令行密码管理器 +===== + +> 给在终端窗口花费大量时间的人们的密码管理器。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/password.jpg?itok=ec6z6YgZ) + +我们都希望我们的密码安全可靠。为此,许多人转向密码管理应用程序,如 [KeePassX][1] 和 [Bitwarden][2]。 + +如果你在终端中花费了大量时间而且正在寻找更简单的解决方案,那么你需要了解下诸多的 Linux 命令行密码管理器。它们快速,易于使用且安全。 + +让我们来看看其中的三个。 + +### Titan + +[Titan][3] 是一个密码管理器,也可作为文件加密工具。我不确定 Titan 在加密文件方面效果有多好;我只是把它看作密码管理器,在这方面,它确实做的很好。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/titan.png?itok=5QoQ1aY7) + +Titan 将你的密码存储在加密的 [SQLite 数据库][4]中,你可以在第一次启动该应用程序时创建并添加主密码。告诉 Titan 增加一个密码,它需要一个用来识别它的名字、用户名、密码本身、URL 和关于密码的注释。 + +你可以让 Titan 为你生成一个密码,你可以通过条目名称或数字 ID、名称、注释或使用正则表达式来搜索数据库,但是,查看特定的密码可能会有点笨拙,你要么必须列出所有密码滚动查找你想要使用的密码,要么你可以通过使用其数字 ID(如果你知道)列出条目的详细信息来查看密码。 + +### Gopass + +[Gopass][5] 被称为“团队密码管理器”。不要因此感到失望,它对个人的使用也很好。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/gopass.png?itok=1Uodlute) + +Gopass 是用 Go 语言编写的经典 Unix 和 Linux [Pass][6] 密码管理器的更新版本。安装纯正的 Linux 方式,你可以[编译源代码][7]或[使用安装程序][8]以在你的计算机上使用 gopass。 + +在开始使用 gopass 之前,确保你的系统上有 [GNU Privacy Guard (GPG)][9] 和 [Git][10]。前者对你的密码存储进行加密和解密,后者将提交到一个 [Git 仓库][11]。如果 gopass 是给个人使用,你仍然需要 Git。你不需要担心提交到仓库。如果你感兴趣,你可以[在文档中][12]了解这些依赖关系。 + +当你第一次启动 gopass 时,你需要创建一个密码存储库并生成一个[密钥][13]以确保存储的安全。当你想添加一个密码(gopass 中称之为“secret”)时,gopass 会要求你提供一些信息,比如 URL、用户名和密码。你可以让 gopass 为你添加的“secret”生成密码,或者你可以自己输入密码。 + +根据需要,你可以编辑、查看或删除密码。你还可以查看特定的密码或将其复制到剪贴板,以将其粘贴到登录表单或窗口中。 + + +### Kpcli + +许多人选择的是开源密码管理器 [KeePass][14] 和 [KeePassX][15]。 [Kpcli][16] 将 KeePass 和 KeePassX 的功能带到你的终端窗口。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/kpcli.png?itok=kMmOHTJz) + +Kpcli 是一个键盘驱动的 shell,可以完成其图形化的表亲的大部分功能。这包括打开密码数据库、添加和编辑密码和组(组帮助你组织密码),甚至重命名或删除密码和组。 + +当你需要时,你可以将用户名和密码复制到剪贴板以粘贴到登录表单中。为了保证这些信息的安全,kpcli 也有清除剪贴板的命令。对于一个小终端应用程序来说还不错。 + +你有最喜欢的命令行密码管理器吗?何不通过发表评论来分享它? + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/3-password-managers-linux-command-line + +作者:[Scott Nesbitt][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/scottnesbitt +[1]:https://www.keepassx.org/ +[2]:https://opensource.com/article/18/3/managing-passwords-bitwarden +[3]:https://www.titanpasswordmanager.org/ +[4]:https://en.wikipedia.org/wiki/SQLite +[5]:https://www.justwatch.com/gopass/ +[6]:https://www.passwordstore.org/ +[7]:https://github.com/justwatchcom/gopass +[8]:https://justwatch.com/gopass/#install +[9]:https://www.gnupg.org +[10]:https://git-scm.com/ +[11]:https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository +[12]:https://github.com/justwatchcom/gopass/blob/master/docs/setup.md +[13]:http://searchsecurity.techtarget.com/definition/private-key +[14]:https://keepass.info/ +[15]:https://www.keepassx.org +[16]:http://kpcli.sourceforge.net/ diff --git a/published/20180401 9 Useful touch command examples in Linux.md b/published/20180401 9 Useful touch command examples in Linux.md new file mode 100644 index 0000000000..d6feddf595 --- /dev/null +++ b/published/20180401 9 Useful touch command examples in Linux.md @@ -0,0 +1,241 @@ +在 Linux 下 9 个有用的 touch 命令示例 +===== + +`touch` 命令用于创建空文件,也可以更改 Unix 和 Linux 系统上现有文件时间戳。这里所说的更改时间戳意味着更新文件和目录的访问以及修改时间。 + +![touch-command-examples-linux][2] + +让我们来看看 `touch` 命令的语法和选项: + +**语法**: + +``` +# touch {选项} {文件} +``` + +`touch` 命令中使用的选项: + +![touch-command-options][3] + +在这篇文章中,我们将介绍 Linux 中 9 个有用的 `touch` 命令示例。 + +### 示例:1 使用 touch 创建一个空文件 + +要在 Linux 系统上使用 `touch` 命令创建空文件,键入 `touch`,然后输入文件名。如下所示: + +``` +[root@linuxtechi ~]# touch devops.txt +[root@linuxtechi ~]# ls -l devops.txt +-rw-r--r--. 1 root root 0 Mar 29 22:39 devops.txt +``` + +### 示例:2 使用 touch 创建批量空文件 + +可能会出现一些情况,我们必须为某些测试创建大量空文件,这可以使用 `touch` 命令轻松实现: + +``` +[root@linuxtechi ~]# touch sysadm-{1..20}.txt +``` + +在上面的例子中,我们创建了 20 个名为 `sysadm-1.txt` 到 `sysadm-20.txt` 的空文件,你可以根据需要更改名称和数字。 + +### 示例:3 改变/更新文件和目录的访问时间 + +假设我们想要改变名为 `devops.txt` 文件的访问时间,在 `touch` 命令中使用 `-a` 选项,然后输入文件名。如下所示: + +``` +[root@linuxtechi ~]# touch -a devops.txt +``` + +现在使用 `stat` 命令验证文件的访问时间是否已更新: +``` +[root@linuxtechi ~]# stat devops.txt + File: 'devops.txt' + Size: 0 Blocks: 0 IO Block: 4096 regular empty file +Device: fd00h/64768d Inode: 67324178 Links: 1 +Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) +Context: unconfined_u:object_r:admin_home_t:s0 +Access: 2018-03-29 23:03:10.902000000 -0400 +Modify: 2018-03-29 22:39:29.365000000 -0400 +Change: 2018-03-29 23:03:10.902000000 -0400 + Birth: - +``` + +**改变目录的访问时间:** + +假设我们在 `/mnt` 目录下有一个 `nfsshare` 文件夹,让我们用下面的命令改变这个文件夹的访问时间: + +``` +[root@linuxtechi ~]# touch -m /mnt/nfsshare/ +[root@linuxtechi ~]# stat /mnt/nfsshare/ +  File: '/mnt/nfsshare/' +  Size: 6               Blocks: 0          IO Block: 4096   directory +Device: fd00h/64768d    Inode: 2258        Links: 2 +Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root) +Context: unconfined_u:object_r:mnt_t:s0 +Access: 2018-03-29 23:34:38.095000000 -0400 +Modify: 2018-03-03 10:42:45.194000000 -0500 +Change: 2018-03-29 23:34:38.095000000 -0400 + Birth: - +``` + +### 示例:4 更改访问时间而不用创建新文件 + +在某些情况下,如果文件存在,我们希望更改文件的访问时间,并避免创建文件。在 touch 命令中使用 `-c` 选项即可,如果文件存在,那么我们可以改变文件的访问时间,如果不存在,我们也可不会创建它。 + +``` +[root@linuxtechi ~]# touch -c sysadm-20.txt +[root@linuxtechi ~]# touch -c winadm-20.txt +[root@linuxtechi ~]# ls -l winadm-20.txt +ls: cannot access winadm-20.txt: No such file or directory +``` + +### 示例:5 更改文件和目录的修改时间 + +在 `touch` 命令中使用 `-m` 选项,我们可以更改文件和目录的修改时间。 + +让我们更改名为 `devops.txt` 文件的更改时间: + +``` +[root@linuxtechi ~]# touch -m devops.txt +``` + +现在使用 `stat` 命令来验证修改时间是否改变: + +``` +[root@linuxtechi ~]# stat devops.txt +  File: 'devops.txt' +  Size: 0               Blocks: 0          IO Block: 4096   regular empty file +Device: fd00h/64768d    Inode: 67324178    Links: 1 +Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root) +Context: unconfined_u:object_r:admin_home_t:s0 +Access: 2018-03-29 23:03:10.902000000 -0400 +Modify: 2018-03-29 23:59:49.106000000 -0400 +Change: 2018-03-29 23:59:49.106000000 -0400 + Birth: - +``` + +同样的,我们可以改变一个目录的修改时间: + +``` +[root@linuxtechi ~]# touch -m /mnt/nfsshare/ +``` + +使用 `stat` 交叉验证访问和修改时间: + +``` +[root@linuxtechi ~]# stat devops.txt +  File: 'devops.txt' +  Size: 0               Blocks: 0          IO Block: 4096   regular empty file +Device: fd00h/64768d    Inode: 67324178    Links: 1 +Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root) +Context: unconfined_u:object_r:admin_home_t:s0 +Access: 2018-03-30 00:06:20.145000000 -0400 +Modify: 2018-03-30 00:06:20.145000000 -0400 +Change: 2018-03-30 00:06:20.145000000 -0400 + Birth: - +``` + +### 示例:7 将访问和修改时间设置为特定的日期和时间 + +每当我们使用 `touch` 命令更改文件和目录的访问和修改时间时,它将当前时间设置为该文件或目录的访问和修改时间。 + +假设我们想要将特定的日期和时间设置为文件的访问和修改时间,这可以使用 `touch` 命令中的 `-c` 和 `-t` 选项来实现。 + +日期和时间可以使用以下格式指定: + +``` +{CCYY}MMDDhhmm.ss +``` + +其中: + + * `CC` – 年份的前两位数字 + * `YY` – 年份的后两位数字 + * `MM` – 月份 (01-12) + * `DD` – 天 (01-31) + * `hh` – 小时 (00-23) + * `mm` – 分钟 (00-59) + +让我们将 `devops.txt` 文件的访问和修改时间设置为未来的一个时间(2025 年 10 月 19 日 18 时 20 分)。 + +``` +[root@linuxtechi ~]# touch -c -t 202510191820 devops.txt +``` + +使用 `stat` 命令查看更新访问和修改时间: + +![stat-command-output-linux][4] + +根据日期字符串设置访问和修改时间,在 `touch` 命令中使用 `-d` 选项,然后指定日期字符串,后面跟文件名。如下所示: + +``` +[root@linuxtechi ~]# touch -c -d "2010-02-07 20:15:12.000000000 +0530" sysadm-29.txt +``` + +使用 `stat` 命令验证文件的状态: + +``` +[root@linuxtechi ~]# stat sysadm-20.txt +  File: ‘sysadm-20.txt’ +  Size: 0               Blocks: 0          IO Block: 4096   regular empty file +Device: fd00h/64768d    Inode: 67324189    Links: 1 +Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root) +Context: unconfined_u:object_r:admin_home_t:s0 +Access: 2010-02-07 20:15:12.000000000 +0530 +Modify: 2010-02-07 20:15:12.000000000 +0530 +Change: 2018-03-30 10:23:31.584000000 +0530 + Birth: - +``` + +**注意:**在上述命令中,如果我们不指定 `-c`,如果系统中不存在该文件那么 `touch` 命令将创建一个新文件,并将时间戳设置为命令中给出的。 + +### 示例:8 使用参考文件设置时间戳(-r) + +在 `touch` 命令中,我们可以使用参考文件来设置文件或目录的时间戳。假设我想在 `devops.txt` 文件上设置与文件 `sysadm-20.txt` 文件相同的时间戳,`touch` 命令中使用 `-r` 选项可以轻松实现。 + +**语法:** + +``` +# touch -r {参考文件} 真正文件 +``` + +``` +[root@linuxtechi ~]# touch -r sysadm-20.txt devops.txt +``` + +### 示例:9 在符号链接文件上更改访问和修改时间 + +默认情况下,每当我们尝试使用 `touch` 命令更改符号链接文件的时间戳时,它只会更改原始文件的时间戳。如果你想更改符号链接文件的时间戳,则可以使用 `touch` 命令中的 `-h` 选项来实现。 + +**语法:** + +``` +# touch -h {符号链接文件} +``` + +``` +[root@linuxtechi opt]# ls -l /root/linuxgeeks.txt +lrwxrwxrwx. 1 root root 15 Mar 30 10:56 /root/linuxgeeks.txt -> linuxadmins.txt +[root@linuxtechi ~]# touch -t 203010191820 -h linuxgeeks.txt +[root@linuxtechi ~]# ls -l linuxgeeks.txt +lrwxrwxrwx. 1 root root 15 Oct 19  2030 linuxgeeks.txt -> linuxadmins.txt +``` + +这就是本教程的全部了。我希望这些例子能帮助你理解 `touch` 命令。请分享你的宝贵意见和评论。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxtechi.com/9-useful-touch-command-examples-linux/ + +作者:[Pradeep Kumar][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxtechi.com/author/pradeep/ +[1]:https://www.linuxtechi.com/wp-content/plugins/lazy-load/images/1x1.trans.gif +[2]:https://www.linuxtechi.com/wp-content/uploads/2018/03/touch-command-examples-linux.jpg +[3]:https://www.linuxtechi.com/wp-content/uploads/2018/03/touch-command-options.jpg +[4]:https://www.linuxtechi.com/wp-content/uploads/2018/03/stat-command-output-linux.jpg diff --git a/published/20180403 10 fundamental commands for new Linux users.md b/published/20180403 10 fundamental commands for new Linux users.md new file mode 100644 index 0000000000..a423d7671e --- /dev/null +++ b/published/20180403 10 fundamental commands for new Linux users.md @@ -0,0 +1,139 @@ +每个 Linux 新手都应该知道的 10 个命令 +===== + +> 通过这 10 个基础命令开始掌握 Linux 命令行。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_terminals.png?itok=CfBqYBah) + +你可能认为你是 Linux 新手,但实际上并不是。全球互联网用户有 [3.74 亿][1],他们都以某种方式使用 Linux,因为 Linux 服务器占据了互联网的 90%。大多数现代路由器运行 Linux 或 Unix,[TOP500 超级计算机][2] 也依赖于 Linux。如果你拥有一台 Android 智能手机,那么你的操作系统就是由 Linux 内核构建的。 + +换句话说,Linux 无处不在。 + +但是使用基于 Linux 的技术和使用 Linux 本身是有区别的。如果你对 Linux 感兴趣,但是一直在使用 PC 或者 Mac 桌面,你可能想知道你需要知道什么才能使用 Linux 命令行接口(CLI),那么你来到了正确的地方。 + +下面是你需要知道的基本的 Linux 命令。每一个都很简单,也很容易记住。换句话说,你不必成为比尔盖茨就能理解它们。 + +### 1、 ls + +你可能会想:“这是(is)什么东西?”不,那不是一个印刷错误 —— 我真的打算输入一个小写的 l。`ls`,或者说 “list”, 是你需要知道的使用 Linux CLI 的第一个命令。这个 list 命令在 Linux 终端中运行,以显示在存放在相应文件系统下的所有主要目录。例如,这个命令: + +``` +ls /applications +``` + +显示存储在 `applications` 文件夹下的每个文件夹,你将使用它来查看文件、文件夹和目录。 + +显示所有隐藏的文件都可以使用命令 `ls -a`。 + +### 2、 cd + +这个命令是你用来跳转(或“更改”)到一个目录的。它指导你如何从一个文件夹导航到另一个文件夹。假设你位于 `Downloads` 文件夹中,但你想到名为 `Gym Playlist` 的文件夹中,简单地输入 `cd Gym Playlist` 将不起作用,因为 shell 不会识别它,并会报告你正在查找的文件夹不存在(LCTT 译注:这是因为目录名中有空格)。要跳转到那个文件夹,你需要包含一个反斜杠。改命令如下所示: + +``` +cd Gym\ Playlist +``` + +要从当前文件夹返回到上一个文件夹,你可以在该文件夹输入 `cd ..`。把这两个点想象成一个后退按钮。 + +### 3、 mv + +该命令将文件从一个文件夹转移到另一个文件夹;`mv` 代表“移动”。你可以使用这个简单的命令,就像你把一个文件拖到 PC 上的一个文件夹一样。 + +例如,如果我想创建一个名为 `testfile` 的文件来演示所有基本的 Linux 命令,并且我想将它移动到我的 `Documents` 文件夹中,我将输入这个命令: + +``` +mv /home/sam/testfile /home/sam/Documents/ +``` + +命令的第一部分(`mv`)说我想移动一个文件,第二部分(`home/sam/testfile`)表示我想移动的文件,第三部分(`/home/sam/Documents/`)表示我希望传输文件的位置。 + +### 4、 快捷键 + +好吧,这不止一个命令,但我忍不住把它们都包括进来。为什么?因为它们能节省时间并避免经历头痛。 + +- `CTRL+K` 从光标处剪切文本直至本行结束 +- `CTRL+Y` 粘贴文本 +- `CTRL+E` 将光标移到本行的末尾 +- `CTRL+A` 将光标移动到本行的开头 +- `ALT+F` 跳转到下一个空格处 +- `ALT+B` 回到前一个空格处 +- `ALT+Backspace` 删除前一个词 +- `CTRL+W` 剪切光标前一个词 +- `Shift+Insert` 将文本粘贴到终端中 +- `Ctrl+D` 注销 + +这些命令在许多方面都能派上用场。例如,假设你在命令行文本中拼错了一个单词: + +``` +sudo apt-get intall programname +``` + +你可能注意到 `install` 拼写错了,因此该命令无法工作。但是快捷键可以让你很容易回去修复它。如果我的光标在这一行的末尾,我可以按下两次 `ALT+B` 来将光标移动到下面用 `^` 符号标记的地方: + +``` +sudo apt-get^intall programname +``` + +现在,我们可以快速地添加字母 `s` 来修复 `install`,十分简单! + +### 5、 mkdir + +这是你用来在 Linux 环境下创建目录或文件夹的命令。例如,如果你像我一样喜欢 DIY,你可以输入 `mkdir DIY` 为你的 DIY 项目创建一个目录。 + +### 6、 at + +如果你想在特定时间运行 Linux 命令,你可以将 `at` 添加到语句中。语法是 `at` 后面跟着你希望命令运行的日期和时间,然后命令提示符变为 `at>`,这样你就可以输入在上面指定的时间运行的命令。 + +例如: + +``` +at 4:08 PM Sat +at> cowsay 'hello' +at> CTRL+D +``` + +这将会在周六下午 4:08 运行 `cowsay` 程序。 + +### 7、 rmdir + +这个命令允许你通过 Linux CLI 删除一个目录。例如: + +``` +rmdir testdirectory +``` + +请记住,这个命令不会删除里面有文件的目录。这只在删除空目录时才起作用。 + +### 8、 rm + +如果你想删除文件,`rm` 命令就是你想要的。它可以删除文件和目录。要删除一个文件,键入 `rm testfile`,或者删除一个目录和里面的文件,键入 `rm -r`。 + +### 9、 touch + +`touch` 命令,也就是所谓的 “make file 的命令”,允许你使用 Linux CLI 创建新的、空的文件。很像 `mkdir` 创建目录,`touch` 会创建文件。例如,`touch testfile` 将会创建一个名为 testfile 的空文件。 + +### 10、 locate + +这个命令是你在 Linux 系统中用来查找文件的命令。就像在 Windows 中搜索一样,如果你忘了存储文件的位置或它的名字,这是非常有用的。 + +例如,如果你有一个关于区块链用例的文档,但是你忘了标题,你可以输入 `locate -blockchain` 或者通过用星号分隔单词来查找 "blockchain use cases",或者星号(`*`)。例如: + +``` +locate -i*blockchain*use*cases* +``` + +还有很多其他有用的 Linux CLI 命令,比如 `pkill` 命令,如果你开始关机但是你意识到你并不想这么做,那么这条命令很棒。但是这里描述的 10 个简单而有用的命令是你开始使用 Linux 命令行所需的基本知识。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/10-commands-new-linux-users + +作者:[Sam Bocetta][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/sambocetta +[1]:https://hostingcanada.org/state-of-the-internet/ +[2]:https://www.top500.org/statistics/details/osfam/1 diff --git a/published/20180403 Why I love ARM and PowerPC.md b/published/20180403 Why I love ARM and PowerPC.md new file mode 100644 index 0000000000..60ed069e36 --- /dev/null +++ b/published/20180403 Why I love ARM and PowerPC.md @@ -0,0 +1,80 @@ +为什么我喜欢 ARM 和 PowerPC? +====== + +> 一个学生在搜寻强劲而节能的工作站的历程中怎样对开源系统的热情与日俱增的。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/desk_clock_job_work.jpg?itok=Nj4fuhl6) + +最近我被问起为什么在博客和推特里经常提到 [ARM][1] 和 [PowerPC][2]。我有两个答案:一个是个人原因,另一个是技术上的。 + +### 个人原因 + +从前,我是学环境保护的。在我读博的时候,我准备买个新电脑。作为一个环保人士,我需要一台强劲且节能的电脑。这就是我开始对 PowerPC 感兴趣的原因,我找到了 [Pegasos][3],这是一台 [Genesi][4] 公司制造的 PowerPC 工作站。 + +我还用过 [RS/6000][5] (PowerPC)、 [SGI][6] (MIPS)、 [HP-UX][7] (PA-RISC)和 [VMS][8] (Alpha)的服务器和工作站,由于我的 PC 使用 Linux 而非 Windows,所以使用不同的 CPU 架构对我来说并没有什么区别。 [Pegasos][9] 是我第一台工作站,它小型而节能而且对家用来说性能足够。 + +很快我就开始为 Genesi 工作,为 Pegasos 移植 [openSUSE][10]、 Ubuntu 和其他 Linux 发行版,并提供质量保证和社区支持。继 Pegasos 之后是 [EFIKA][11],这是另一款基于 PowerPC 的开发板。在用过工作站之后,刚开始使用嵌入式系统会感觉有点奇怪。但是作为第一代普及价位的开发板,这是一场革命的开端。 + +我工作于一个大规模的服务器项目时,我收到 Genesi 的另一块有趣的开发板:基于 ARM 的 [Smarttop][12] 和 [Smartbook][13]。我最喜欢的 Linux 发行版——openSUSE,也收到了一打这种机器。这在当时 ARM 电脑非常稀缺的情况下,极大地促进了 ARM 版 openSUSE 项目的开发。 + +尽管最近我很忙,我尽量保持对 ARM 和 PowerPC 新闻的关注。这有助于我支持非 x86 平台上的 syslog-ng 用户。只要有半个小时的空,我就会去捣鼓一下 ARM 机器。我在[树莓派2][14]上做了很多 [syslog-ng][15] 的测试,结果令人振奋。我最近在树莓派上做了个音乐播放器,用了一块 USB 声卡和[音乐播放守护进程][17],我经常使用它。 + +### 技术方面 + +美好的多样性:它创造了竞争,而竞争创造了更好的产品。虽然 x86 是一款强劲的通用处理器,但 ARM 和 PowerPC (以及许多其他)这样的芯片在多种特定场景下显得更适合。 + +如果你有一部运行[安卓][18]的移动设备或者[苹果][19]的 iPhone 或 iPad,极有可能它使用的就是基于ARM 的 SoC (片上系统)。网络存储服务器也一样。原因很简单:省电。你不会希望手机一直在充电,也不想为你的路由器付更多的电费。 + +ARM 亦在使用 64 位 ARMv8 芯片征战企业级服务器市场。很多任务只需要极少的计算能力,另一方面省电和快速 IO 才是关键,想想存储、静态网页服务器、电子邮件和其他网络/存储相关的功能。一个最好的例子就是 [Ceph][20],一个分布式的面向对象文件系统。[SoftIron][21] 就是一个基于 ARMv8 开发版,使用 CentOS 作为基准软件,运行在 Ceph 上的完整存储应用。 + +众所周知 PowerPC 是旧版苹果 [Mac][22] 电脑上的 CPU。虽然它不再作为通用桌面电脑的 CPU ,它依然在路由器和电信设备里发挥作用。而且 [IBM][23] 仍在为高端服务器制造芯片。几年前,随着 Power8 的引入, IBM 在 [OpenPower 基金会][24] 的支持下开放了架构。 Power8 对于关心内存带宽的设备,比如 HPC 、大数据、数据挖掘来说,是非常理想的平台。目前,Power9 也正呼之欲出。 + +这些都是服务器应用,但也有计划用于终端用户。猛禽工程团队正在开发一款基于 [Power9 的工作站][25],也有一个基于飞思卡尔/恩智浦 QORIQ E6500 芯片[制造笔记本] [26]的倡议。当然,这些电脑并不适合所有人,你不能在它们上面安装 Windows 游戏或者商业应用。但它们对于 PowerPC 开发人员和爱好者,或者任何想要完全开放系统的人来说是理想的选择,因为从硬件到固件到应用程序都是开放的。 + +### 梦想 + +我的梦想是完全没有 x86 的环境,不是因为我讨厌 x86 ,而是因为我喜欢多样化而且总是希望使用最适合工作的工具。如果你看看猛禽工程网页上的[图][27],根据不同的使用情景, ARM 和 POWER 完全可以代替 x86 。现在,我在笔记本的 x86 虚拟机上编译、打包和测试 syslog-ng。如果能用上足够强劲的 ARMv8 或者 PowerPC 电脑,无论工作站还是服务器,我就能避免在 x86 上做这些事。 + +现在我正在等待下一代[菠萝本][28]的到来,就像我在二月份 [FOSDEM][29] 上说的,下一代有望提供更高的性能。和 Chrome 本不同的是,这个 ARM 笔记本设计用于运行 Linux 而非仅是个客户端(LCTT 译注:Chrome 笔记本只提供基于网页的应用)。作为桌面系统,我在寻找 ARMv8 工作站级别的硬件。有些已经接近完成——就像 Avantek 公司的 [雷神 X 台式机][30]——不过他们还没有装备最新最快最重要也最节能的 ARMv8 CPU。当这些都实现了,我将用我的 Pixel C 笔记本运行安卓。它不像 Linux 那样简单灵活,但它以强大的 ARM SoC 和 Linux 内核为基础。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/why-i-love-arm-and-powerpc + +作者:[Peter Czanik][a] +译者:[kennethXia](https://github.com/kennethXia) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/czanik +[1]:https://en.wikipedia.org/wiki/ARM_architecture +[2]:https://en.wikipedia.org/wiki/PowerPC +[3]:https://genesi.company/products/opendesktop +[4]:https://genesi.company/ +[5]:https://en.wikipedia.org/wiki/RS/6000 +[6]:https://en.wikipedia.org/wiki/Silicon_Graphics#Workstations +[7]:https://en.wikipedia.org/wiki/HP-UX +[8]:https://en.wikipedia.org/wiki/OpenVMS#Port_to_DEC_Alpha +[9]:https://en.wikipedia.org/wiki/Pegasos +[10]:https://www.opensuse.org/ +[11]:https://genesi.company/products/efika/5200b +[12]:https://genesi.company/products/efika +[13]:https://genesi.company/products/smartbook +[14]:https://www.raspberrypi.org/products/raspberry-pi-2-model-b/ +[15]:https://syslog-ng.com/open-source-log-management +[16]:https://syslog-ng.com/blog/syslog-ng-raspberry-pi-2/ +[17]:https://www.musicpd.org/ +[18]:https://www.android.com/ +[19]:http://www.apple.com/ +[20]:http://ceph.com/ +[21]:http://softiron.co.uk/ +[22]:https://en.wikipedia.org/wiki/Power_Macintosh +[23]:https://www.ibm.com/us-en/ +[24]:http://openpowerfoundation.org/ +[25]:https://www.raptorcs.com/TALOSII/ +[26]:http://www.powerpc-notebook.org/en/ +[27]:https://secure.raptorengineering.com/TALOS/power_advantages.php +[28]:https://www.pine64.org/?page_id=3707 +[29]:https://fosdem.org/2018/ +[30]:https://www.avantek.co.uk/store/avantek-32-core-cavium-thunderx-arm-desktop.html diff --git a/published/20180405 Getting started with Vagrant.md b/published/20180405 Getting started with Vagrant.md new file mode 100644 index 0000000000..4377098e7d --- /dev/null +++ b/published/20180405 Getting started with Vagrant.md @@ -0,0 +1,134 @@ +开始 Vagrant 之旅 +===== + +> 用管理虚拟机和容器的工具 Vagrant 清理你的开发环境和依赖。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_scale_performance.jpg?itok=R7jyMeQf) + +如果你和我一样,你可能在某一个地方有一个“沙盒”,你可以在那里进行你正在做的任何项目。随着时间的推移,沙盒会变得杂乱无章,充斥着各种想法、工具链元素、你不使用的代码模块,以及其他你不需要的东西。当你完成某件事情时,这会使你的部署变得复杂,因为你可能不确定项目的实际依赖关系 —— 随着时间推移你在沙盒中已经有了一些工具,但是你忘了必须安装它。你需要一个干净的环境,将所有的依赖关系放在一个地方,以便以后更方便。 + +或者你可能工作在 DevOps 中,你所服务的开发人员用模糊的依赖关系来编写代码,这使得测试变得更加困难。你需要一种方法来获得一个干净的盒子,将代码放入其中,并通过它运行代码,而且你希望这些环境是一次性的和可重复的。 + +那么选择 [Vagrant][1] 吧。由 HashiCorp 在 [MIT 许可证][2]下创建,Vagrant 可充当 VirtualBox、Microsoft Hyper-V 或 Docker 容器的包装器和前端,并且可以通过[许多其他供应商][3]的插件进行扩展。你可以配置 Vagrant 以提供可重复的、干净的环境,并且已安装需要的基础架构。配置脚本是可移植的,因此,如果你的仓库和 Vagrant 配置脚本位于基于云存储上,那么你只需要很少的限制就可以启动并在多台机器机器上工作。让我们来看一看。 + +### 安装 + +对于本次安装,我的环境是 Linux Mint 桌面,版本是 18.3 Cinnamon 64 位,在其他大多数 Debian 派生系统上安装非常类似。在大多数发行版中,对于基于 RPM 的系统也有类似的安装程序。Vagrant 的[安装页面][4]为 Debian、 Windows、 CentOS、 MacOS 和 Arch Linux 都提供下载,但是我在我的软件包管理器中找到了它,所以我在那进行了安装。 + +最简单的安装使用了 VirtualBox 作为虚拟化提供者,所以我需要安装它: + +``` +sudo apt-get install virtualbox vagrant +``` + +安装程序将会获取依赖项 —— 主要是 Ruby 的一些东西,安装它们。 + +### 建立一个项目 + +在设置你的项目之前,你需要了解一些你想要运行它的环境。你可以在 [Vagrant Boxes 仓库][5]中找到为许多虚拟化供应商提供的大量预配置的系统box。许多会预先配置一些你可能需要的核心基础设置,比如 PHP、 MySQL 和 Apache,但是对于本次测试,我将安装一个 Debian 8 64 位 “Jessie” 裸机沙盒并手动安装一些东西,这样你就可以看到具体过程了。 + +``` +mkdir ~/myproject +cd ~/myproject +vagrant init debian/contrib-jessie64 +vagrant up +``` + +最后一条命令将根据需要从仓库中获取或更新 VirtualBox 镜像,然后运行启动器,你的系统上会出现一个运行的系统!下次启动这个项目时,除非镜像已经在仓库中更新,否则不会花费太长时间。 + +要访问该沙盒,只需要输入 `vagrant ssh`,你将进入虚拟机的全功能 SSH 会话中,你将会是 `vagrant` 用户,但也是 `sudo` 组的成员,所以你可以切换到 root,并在这里做你想做的任何事情。 + +你会在沙盒中看到一个名为 `/vagrant` 目录,对这个目录小心点,因为它与你主机上的 `~/myproject` 文件夹保持同步。在虚拟机 `/vagrant` 下建立一个文件它会立即复制到主机上,反之亦然。注意,有些沙盒并没有安装 VirtualBox 的附加功能,所以拷贝只能在启动时才起作用。有一些用于手动同步的命令行工具,这可能是测试环境中非常有用的特性。我倾向于坚持使用那些有附加功能的沙盒,所以这个目录可以正常工作,不必考虑它。 + +这个方案的好处很快显现出来了: 如果你在主机上有一个代码编辑工具链,并处于某种原因不希望它出现在虚拟机上,那么这不是问题 —— 在主机上进行编辑,虚拟机会立刻更改。快速更改虚拟机,它也将其同步到主机上的“官方”副本 +。 + +让我们关闭这个系统,这样我们就可以在这个系统里提供一些我们需要的东西: + +``` +vagrant halt +``` + +### 在虚拟机上安装额外的软件 + +对于这个例子,我将使用 [Apache][6]、 [PostgreSQL][7] 和 Perl 的 [Dancer][8] web 框架进行项目开发。我将修改Vagrant 配置脚本,以便我需要的东西已经安装。 为了使之稍后更容易保持更新,我将在项目根目录下创建一个脚本`~/myproject/Vagrantfile`: + +``` +$provision_script = <