diff --git a/translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md b/published/20171122 How DevOps eliminated bottlenecks for Ranger community.md similarity index 63% rename from translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md rename to published/20171122 How DevOps eliminated bottlenecks for Ranger community.md index a231fcefce..e795016475 100644 --- a/translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md +++ b/published/20171122 How DevOps eliminated bottlenecks for Ranger community.md @@ -1,8 +1,11 @@ -DevOps 如何消除掉 Ranger 社区的瓶颈 +DevOps 如何消除了 Ranger 社区的瓶颈 ====== + +> 拥抱 DevOps 让 Ranger 成员们变得更灵活、快捷和成为开发者社区更有价值的成员。 + ![配图](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/traffic-light-go.png?itok=nC_851ys) -Visual Studio Application Lifecycle Management(ALM)项目 —— [Ranger][1] 是一个志愿者社区,它提供专业的指导、实践经验、以及开发者社区的漏洞修补解决方案。它创建于 2006 年,作为微软内部社区去 "connect the product group with the field and remove adoption blockers"。 在 2009 时,社区已经有超过 200 位成员,这导致了协作和计划面临很大的挑战,在依赖和手工流程上产生了瓶颈,并导致了开发者社区不断增加的延迟和各种报怨。在 2010 时,计划进一步去扩充包括微软最有价值专家(MVP)在内的分布在全球的社区。 +Visual Studio 的应用周期管理Application Lifecycle Management(ALM)项目 —— [Ranger][1] 是一个志愿者社区,它提供专业的指导、实践经验、以及开发者社区的漏洞修补解决方案。它创建于 2006 年,作为微软内部社区去 “将产品组与大家相连接,并去除推广阻力”。 在 2009 时,社区已经有超过 200 位成员,这导致了协作和计划面临很大的挑战,在依赖和手工流程上产生了瓶颈,并导致了开发者社区不断增加的延迟和各种报怨。在 2010 时,计划进一步去扩充包括微软最有价值专家(MVP)在内的分布在全球的社区。 这个社区被分割成十几个活跃的团队。每个团队都致力于通过它的生命周期去设计、构建和支持一个指导或处理项目。在以前,团队的瓶颈在团队管理级别上,原因是严格的、瀑布式的流程和高度依赖一个或多个项目经理。在制作、发布和“为什么、做什么、和怎么做”驱动的决定上,项目经理都要介入其中。另外,缺乏一个实时的指标阻止了团队对他们的解决方案效率的监控,以及对来自社区的关于 bug 和常见问题的关注。 @@ -10,21 +13,21 @@ Visual Studio Application Lifecycle Management(ALM)项目 —— [Ranger][1 ### DevOps 去“灭火” -> "DevOps 是人员、流程、和产品的结合,使我们的最终用户能够持续传递价值。" --[Donovan Brown][2] +> “DevOps 是人员、流程和产品的结合,使我们的最终用户能够持续传递价值。” --[Donovan Brown][2] -为解决这些挑战,社区停止了所有对新项目的冲刺,去探索敏捷实践和新产品。致力于使社区重新活跃起来,为找到促进自治、掌控、和目标的方法,正如在 Daniel H. Pink 的书 —— [Drive][3] 中所说的那样,对僵化的流程和产品进行彻底的改革。 +为解决这些挑战,社区停止了所有对新项目的冲刺,去探索敏捷实践和新产品。致力于使社区重新活跃起来,为找到促进自治、掌控、和目标的方法,正如在 Daniel H. Pink 的书《[Drive][3]》中所说的那样,对僵化的流程和产品进行彻底的改革。 -> “成熟的自组织、自管理、和跨职能团队,在自治、掌控、和目标上茁壮成长。" --Drive, Daniel H. Pink. +> “成熟的自组织、自管理和跨职能团队,在自治、掌控和目标上茁壮成长。" --Drive, Daniel H. Pink. 从文化开始 —— 人 —— 第一步是去拥抱 DevOps。社区实现了 [Scrum][4] 框架,使用 [kanban][5] 去提升工程化流程,并且通过可视化去提升透明度、意识和最重要的东西 —— 信任。使用自组织团队后,传统的等级制度和指挥系统消失了。自管理促使团队去积极监视和设计它们自己的流程。 -在 2010 年 4 月份,社区再次实施了另外的关键一步,切换并提交它们的文化、流程、以及产品到云上。虽然开放的”为社区而社区“的核心 [解决方案][6] 仍然是指导和补充,但是在开源解决方案(OSS)上大量增加投资去研究和共享 DevOps 转换的成就。 +在 2010 年 4 月份,社区再次实施了另外的关键一步,切换并提交它们的文化、流程、以及产品到云上。虽然开放的“为社区而社区”的核心 [解决方案][6] 仍然是指导和补充,但是在开源解决方案(OSS)上大量增加投资去研究和共享 DevOps 转换的成就。 持续集成(CI)和持续交付(CD)使用自动化流水线代替了死板的人工流程。这使得团队在不受来自项目经理的干预的情况下为早期问题和早期应用者部署解决方案。增加遥测技术可以使团队关注他们的解决方案,以及在用户注意到它们之前,检测和处理未知的问题。 -DevOps 转变是一个持续进化的过程,通过实验去探索和验证人、流程、和产品的改革。最新的试验引入了流水线革新,它可以持续提升价值流。自动扫描组件、持续地、以及静默地检查安全、协议、和开源组件的品质。部署环和特性标志允许团队对所有或者特定用户进行更细粒度的控制。 +DevOps 转变是一个持续进化的过程,通过实验去探索和验证人、流程和产品的改革。最新的试验引入了流水线革新,它可以持续提升价值流。自动扫描组件、持续地以及静默地检查安全、协议和开源组件的品质。部署环和特性标志允许团队对所有或者特定用户进行更细粒度的控制。 -在 2017 年 10 月,社区将大部分的私有版本控制仓库转移到 [GitHub][7] 上。对所有仓库转移所有者和管理职责到 ALM DevOps Rangers 社区,给团队提供自治和机会,去激励更多的社区对开源解决方案作贡献。团队被授权向他们的最终用户交付质量和价值。 +在 2017 年 10 月,社区将大部分的私有版本控制仓库转移到 [GitHub][7] 上。将所有仓库转移所有者和管理职责到 ALM DevOps Rangers 社区,给团队提供自治和机会,去激励更多的社区对开源解决方案作贡献。团队被授权向他们的最终用户交付质量和价值。 ### 好处和成就 @@ -32,7 +35,7 @@ DevOps 转变是一个持续进化的过程,通过实验去探索和验证人 下面是从这个转变中观察到的一个列表,排列没有特定的顺序: - * 自治、掌控、和目标是核心。 + * 自治、掌控和目标是核心。 * 从可触摸的和可迭代的东西开始 —— 避免摊子铺的过大。 * 可触摸的和可操作的指标很重要 —— 确保不要掺杂其它东西。 * 人(文化)的转变是最具挑战的部分。 @@ -42,10 +45,22 @@ DevOps 转变是一个持续进化的过程,通过实验去探索和验证人 * 使用工程化流程去强化预期行为。 +转换变化表: -转换变化表:~~(致核对:以下是表格,格式转换造成错乱了。)~~ - -PAST CURRENT ENVISIONED Branching Servicing and release isolation Feature Master Build Manual and error prone Automated and consistent Issue detection Call from user Proactive telemetry Issue resolution Days to weeks Minutes to days Minutes Planning Detailed design Prototyping and storyboards Program management 2 program managers (PM) 0.25 PM 0.125 PM Release cadence 6 to 12 months 3 to 5 sprints Every sprint Release Manual and error prone Automated and consistent Sprints 1 month 3 weeks Team size 10 to 15 2 to 5 Time to build Hours Seconds Time to release Days Minutes +| | 过去 | 当前 | 想象 | +|---|------|---------|-----------| +| 分支 | 服务于发布隔离 | 特性 | 主分支 | +| 构建 |手动且易错 | 自动而一致 | | +| 问题检测 | 来自用户 | 主动感知 | +| 问题解决 | 几天到几周 | 几分钟到几天 | 几分钟 | +| 计划 | 详细的设计 | 原型与故事板 | | +| 流程管理 | 2 个流程经理(PM) | 0.25 个 PM | 0.125 个 PM | +| 发布终止 | 6 到 12 个月 | 3 到 5 周期 | 每个周期 | +| 发布 | 手动且易错 | 自动而一致 || +| 周期 | 1 个月 | 3 周 || +| 团队规模 | 10 到 15 | 2 到 5 || +| 构建时间 | 几小时 | 几秒钟 || +| 发布时间 | 几天 | 几分钟 || 但是,我们还没有做完,相反,我们就是一个令人兴奋的、持续不断的、几乎从不结束的转变的一部分。 @@ -57,7 +72,7 @@ via: https://opensource.com/article/17/11/devops-rangers-transformation 作者:[Willy Schaub][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/20180327 Loop better- A deeper look at iteration in Python.md b/published/20180327 Loop better- A deeper look at iteration in Python.md similarity index 87% rename from translated/tech/20180327 Loop better- A deeper look at iteration in Python.md rename to published/20180327 Loop better- A deeper look at iteration in Python.md index 32cd9842e7..715d84867a 100644 --- a/translated/tech/20180327 Loop better- A deeper look at iteration in Python.md +++ b/published/20180327 Loop better- A deeper look at iteration in Python.md @@ -1,9 +1,11 @@ -Loop better:更深入的理解Python 中的迭代 +更深入的理解 Python 中的迭代 ==== +> 深入探讨 Python 的 `for` 循环来看看它们在底层如何工作,以及为什么它们会按照它们的方式工作。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/pez-candy.png?itok=tRoOn_iy) -Python 的 `for` 循环不会像其他语言中的 `for` 循环那样工作。在这篇文章中,我们将深入探讨 Python 的 `for` 循环来看看它们如何在底层工作,以及为什么它们会按照它们的方式工作。 +Python 的 `for` 循环不会像其他语言中的 `for` 循环那样工作。在这篇文章中,我们将深入探讨 Python 的 `for` 循环来看看它们在底层如何工作,以及为什么它们会按照它们的方式工作。 ### 循环的问题 @@ -12,27 +14,24 @@ Python 的 `for` 循环不会像其他语言中的 `for` 循环那样工作。 #### 问题 1:循环两次 假设我们有一个数字列表和一个生成器,生成器会返回这些数字的平方: + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> squares = (n**2 for n in numbers) - ``` 我们可以将生成器对象传递给 `tuple` 构造器,从而使其变为一个元组: + ``` >>> tuple(squares) - (1, 4, 9, 25, 49) - ``` -如果我们使用相同的生成器对象并将其传给 `sum` 函数,我们可能会期望得到这些数的和,即 88。 +如果我们使用相同的生成器对象并将其传给 `sum` 函数,我们可能会期望得到这些数的和,即 `88`。 + ``` >>> sum(squares) - 0 - ``` 但是我们得到了 `0`。 @@ -40,6 +39,7 @@ Python 的 `for` 循环不会像其他语言中的 `for` 循环那样工作。 #### 问题 2:包含的检查 让我们使用相同的数字列表和相同的生成器对象: + ``` >>> numbers = [1, 2, 3, 5, 7] @@ -48,15 +48,12 @@ Python 的 `for` 循环不会像其他语言中的 `for` 循环那样工作。 ``` 如果我们询问 `9` 是否在 `squares` 生成器中,Python 将会告诉我们 9 在 `squares` 中。但是如果我们再次询问相同的问题,Python 会告诉我们 9 不在 `squares` 中。 + ``` >>> 9 in squares - True - >>> 9 in squares - False - ``` 我们询问相同的问题两次,Python 给了两个不同的答案。 @@ -64,57 +61,51 @@ False #### 问题 3 :拆包 这个字典有两个键值对: + ``` >>> counts = {'apples': 2, 'oranges': 1} - ``` 让我们使用多个变量来对这个字典进行拆包: + ``` >>> x, y = counts - ``` 你可能会期望当我们对这个字典进行拆包时,我们会得到键值对或者得到一个错误。 但是解包字典不会引发错误,也不会返回键值对。当你解包一个字典时,你会得到键: + ``` >>> x - 'apples' - ``` -### 回顾:Python 的 __for__ 循环 +### 回顾:Python 的 for 循环 在我们了解一些关于这些 Python 片段的逻辑之后,我们将回到这些问题。 Python 没有传统的 `for` 循环。为了解释我的意思,让我们看一看另一种编程语言的 `for` 循环。 这是一种传统 C 风格的 `for` 循环,用 JavaScript 编写: + ``` let numbers = [1, 2, 3, 5, 7]; - for (let i = 0; i < numbers.length; i += 1) { -     print(numbers[i]) - } - ``` -JavaScript, C, C++, Java, PHP, 和一大堆其他编程语言都有这种风格的 `for` 循环,但是 Python **确实没**。 +JavaScript、 C、 C++、 Java、 PHP 和一大堆其他编程语言都有这种风格的 `for` 循环,但是 Python **确实没有**。 -Python **确实没** 有传统 C 风格的 `for` 循环。在 Python 中确实有一些我们称之为 `for` 循环的东西,但是它的工作方式类似于 [foreach loop][1]。 +Python **确实没有** 传统 C 风格的 `for` 循环。在 Python 中确实有一些我们称之为 `for` 循环的东西,但是它的工作方式类似于 [foreach 循环][1]。 这是 Python 的 `for` 循环的风格: + ``` numbers = [1, 2, 3, 5, 7] - for n in numbers: -     print(n) - ``` 与传统 C 风格的 `for` 循环不同,Python 的 `for` 循环没有索引变量,没有索引变量初始化,边界检查,或者索引递增。Python 的 `for` 循环完成了对我们的 `numbers` 列表进行遍历的所有工作。 @@ -126,98 +117,75 @@ for n in numbers: 既然我们已经解决了 Python 世界中无索引的 `for` 循环,那么让我们在此之外来看一些定义。 **可迭代**是任何你可以用 Python 中的 `for` 循环遍历的东西。可迭代意味着可以遍历,任何可以遍历的东西都是可迭代的。 + ``` for item in some_iterable: -     print(item) - ``` 序列是一种非常常见的可迭代类型,列表,元组和字符串都是序列。 + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> coordinates = (4, 5, 7) - >>> words = "hello there" - ``` 序列是可迭代的,它有一些特定的特征集。它们可以从 `0` 开始索引,以小于序列的长度结束,它们有一个长度并且它们可以被切分。列表,元组,字符串和其他所有序列都是这样工作的。 + ``` >>> numbers[0] - 1 - >>> coordinates[2] - 7 - >>> words[4] - 'o' - ``` -Python 中很多东西都是可迭代的,但不是所有可迭代的东西都是序列。集合,字典,文件和生成器都是可迭代的,但是它们都不是序列。 +Python 中很多东西都是可迭代的,但不是所有可迭代的东西都是序列。集合、字典、文件和生成器都是可迭代的,但是它们都不是序列。 + ``` >>> my_set = {1, 2, 3} - >>> my_dict = {'k1': 'v1', 'k2': 'v2'} - >>> my_file = open('some_file.txt') - >>> squares = (n**2 for n in my_set) - ``` 因此,任何可以用 `for` 循环遍历的东西都是可迭代的,序列只是一种可迭代的类型,但是 Python 也有许多其他种类的迭代器。 -### Python 的 __for__ 循环不使用索引 +### Python 的 for 循环不使用索引 + +你可能认为,Python 的 `for` 循环在底层使用了索引进行循环。在这里我们使用 `while` 循环和索引手动遍历: -你可能认为,在 hood 下的 `for` 循环中使用索引进行循环。在这里我们使用 `while` 循环和索引手动遍历: ``` numbers = [1, 2, 3, 5, 7] - i = 0 - while i < len(numbers): -     print(numbers[i]) -     i += 1 - ``` 这适用于列表,但它不会对所有东西都起作用。这种循环方式**只适用于序列**。 如果我们尝试用索引去手动遍历一个集合,我们会得到一个错误: + ``` >>> fruits = {'lemon', 'apple', 'orange', 'watermelon'} - >>> i = 0 - >>> while i < len(fruits): - ...     print(fruits[i]) - ...     i += 1 - ... - Traceback (most recent call last): - File "", line 2, in - TypeError: 'set' object does not support indexing - ``` 集合不是序列,所以它们不支持索引。 我们不能使用索引手动对 Python 中的每一个迭代对象进行遍历。对于那些不是序列的迭代器来说,这是行不通的。 -### 迭代器驱动 __for__ 循环 +### 迭代器驱动 for 循环 因此,我们已经看到,Python 的 `for` 循环在底层不使用索引。相反,Python 的 `for` 循环使用**迭代器**。 @@ -226,148 +194,116 @@ TypeError: 'set' object does not support indexing 让我们来看看它是如何工作的。 这里有三个可迭代对象:一个集合,一个元组和一个字符串。 + ``` >>> numbers = {1, 2, 3, 5, 7} - >>> coordinates = (4, 5, 7) - >>> words = "hello there" - ``` 我们可以使用 Python 的内置 `iter` 函数来访问这些迭代器,将一个迭代器传递给 `iter` 函数总会给我们返回一个迭代器,无论我们正在使用哪种类型的迭代器。 + ``` >>> iter(numbers) - - >>> iter(coordinates) - - >>> iter(words) - - ``` 一旦我们有了迭代器,我们可以做的事情就是通过将它传递给内置的 `next` 函数来获取它的下一项。 ``` >>> numbers = [1, 2, 3] - >>> my_iterator = iter(numbers) - >>> next(my_iterator) - 1 - >>> next(my_iterator) - 2 - ``` 迭代器是有状态的,这意味着一旦你从它们中消耗了一项,它就消失了。 如果你从迭代器中请求 `next` 项,但是其中没有更多的项了,你将得到一个 `StopIteration` 异常: + ``` >>> next(my_iterator) - 3 - >>> next(my_iterator) - Traceback (most recent call last): -   File "", line 1, in - StopIteration - ``` 所以你可以从每个迭代中获得一个迭代器,迭代器唯一能做的事情就是用 `next` 函数请求它们的下一项。如果你将它们传递给 `next`,但它们没有下一项了,那么就会引发 `StopIteration` 异常。 -你可以将迭代器想象成 Pez 分配器(译注:Pez 是一个结合玩具的独特复合式糖果),不能重新分配。你可以把 Pez 拿出去,但是一旦 Pez 被移走,它就不能被放回去,一旦分配器空了,它就没用了。 +你可以将迭代器想象成 Pez 分配器(LCTT 译注:Pez 是一个结合玩具的独特复合式糖果),不能重新分配。你可以把 Pez 拿出去,但是一旦 Pez 被移走,它就不能被放回去,一旦分配器空了,它就没用了。 -### 没有 __for__ 的循环 +### 没有 for 的循环 既然我们已经了解了迭代器和 `iter` 以及 `next` 函数,我们将尝试在不使用 `for` 循环的情况下手动遍历迭代器。 我们将通过尝试将这个 `for` 循环变为 `while` 循环: + ``` def funky_for_loop(iterable, action_to_do): -     for item in iterable: -         action_to_do(item) - ``` 为了做到这点,我们需要: + 1. 从给定的可迭代对象中获得迭代器 2. 反复从迭代器中获得下一项 3. 如果我们成功获得下一项,就执行 `for` 循环的主体 4. 如果我们在获得下一项时得到了一个 `StopIteration` 异常,那么就停止循环 - ``` def funky_for_loop(iterable, action_to_do): -     iterator = iter(iterable) -     done_looping = False -     while not done_looping: -         try: -             item = next(iterator) -         except StopIteration: -             done_looping = True -         else: -             action_to_do(item) - ``` 我们只是通过使用 `while` 循环和迭代器重新定义了 `for` 循环。 上面的代码基本上定义了 Python 在底层循环的工作方式。如果你理解内置的 `iter` 和 `next` 函数的遍历循环的工作方式,那么你就会理解 Python 的 `for` 循环是如何工作的。 -事实上,你不仅仅会理解 `for` 循环在 Python 中式如何工作的,所有形式的遍历一个可迭代对象都是这样工作的。 +事实上,你不仅仅会理解 `for` 循环在 Python 中是如何工作的,所有形式的遍历一个可迭代对象都是这样工作的。 -**迭代器协议** 是一种很好的方式,它表示 "在 Python 中遍历迭代器是如何工作的"。它本质上是对 `iter` 和 `next` 函数在 Python 中是如何工作的定义。Python 中所有形式的迭代都是由迭代器协议驱动的。 +迭代器协议iterator protocol 是一种很好表示 “在 Python 中遍历迭代器是如何工作的”的方式。它本质上是对 `iter` 和 `next` 函数在 Python 中是如何工作的定义。Python 中所有形式的迭代都是由迭代器协议驱动的。 迭代器协议被 `for` 循环使用(正如我们已经看到的那样): + ``` for n in numbers: -     print(n) - ``` 多重赋值也使用迭代器协议: + ``` x, y, z = coordinates - ``` 星型表达式也是用迭代器协议: + ``` a, b, *rest = numbers - print(*numbers) - ``` 许多内置函数依赖于迭代器协议: + ``` unique_numbers = set(numbers) - ``` 在 Python 中任何与迭代器一起工作的东西都可能以某种方式使用迭代器协议。每当你在 Python 中遍历一个可迭代对象时,你将依赖于迭代器协议。 @@ -379,41 +315,31 @@ unique_numbers = set(numbers) 我有消息告诉你:在 Python 中直接使用迭代器是很常见的。 这里的 `squares` 对象是一个生成器: + ``` >>> numbers = [1, 2, 3] - >>> squares = (n**2 for n in numbers) - ``` 生成器是迭代器,这意味着你可以在生成器上调用 `next` 来获得它的下一项: + ``` >>> next(squares) - 1 - >>> next(squares) - 4 - ``` 但是如果你以前用过生成器,你可能也知道可以循环遍历生成器: + ``` >>> squares = (n**2 for n in numbers) - >>> for n in squares: - ...     print(n) - ... - 1 - 4 - 9 - ``` 如果你可以在 Python 中循环遍历某些东西,那么它就是**可迭代的**。 @@ -424,90 +350,84 @@ unique_numbers = set(numbers) 所以在我之前解释迭代器如何工作时,我跳过了它们的某些重要的细节。 -**生成器是可迭代的。** +#### 生成器是可迭代的 我再说一遍:Python 中的每一个迭代器都是可迭代的,意味着你可以循环遍历迭代器。 因为迭代器也是可迭代的,所以你可以使用内置 `next` 函数从可迭代对象中获得迭代器: + ``` >>> numbers = [1, 2, 3] - >>> iterator1 = iter(numbers) - >>> iterator2 = iter(iterator1) - ``` 请记住,当我们在可迭代对象上调用 `iter` 时,它会给我们返回一个迭代器。 当我们在迭代器上调用 `iter` 时,它会给我们返回它自己: + ``` >>> iterator1 is iterator2 - True - ``` 迭代器是可迭代的,所有的迭代器都是它们自己的迭代器。 + ``` def is_iterator(iterable): -     return iter(iterable) is iterable - ``` 迷惑了吗? 让我们回顾一些这些措辞。 + * 一个**可迭代对象**是你可以迭代的东西 -* 一个**可迭代对象**是一种可以迭代遍历迭代的代理 -(这句话不是很理解) +* 一个**迭代对象器**是一种实际上遍历可迭代对象的代理 此外,在 Python 中迭代器也是可迭代的,它们充当它们自己的迭代器。 所以迭代器是可迭代的,但是它们没有一些可迭代对象拥有的各种特性。 迭代器没有长度,它们不能被索引: + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> iterator = iter(numbers) - >>> len(iterator) - TypeError: object of type 'list_iterator' has no len() - >>> iterator[0] - TypeError: 'list_iterator' object is not subscriptable - ``` 从我们作为 Python 程序员的角度来看,你可以使用迭代器来做的唯一有用的事情是将其传递给内置的 `next` 函数,或者对其进行循环遍历: + ``` >>> next(iterator) - 1 - >>> list(iterator) - [2, 3, 5, 7] - ``` 如果我们第二次循环遍历迭代器,我们将一无所获: + ``` >>> list(iterator) - [] - ``` 你可以把迭代器看作是**惰性迭代器**,它们是**一次性使用**,这意味着它们只能循环遍历一次。 正如你在下面的真值表中所看到的,可迭代对象并不总是迭代器,但是迭代器总是可迭代的: -可迭代对象?迭代器?可迭代的? ✔️ ❓ 迭代器 ✔️ ✔️ 生成器 ✔️ ✔️ 列表 ✔️ ❌ + +对象 | 可迭代? | 迭代器? +---------|---------|------ +可迭代对象 | V | ? +迭代器 | V | V +生成器 | V | V +列表 | V | X + ### 全部的迭代器协议 @@ -535,45 +455,33 @@ TypeError: 'list_iterator' object is not subscriptable ### 迭代器无处不在 你已经在 Python 中看到过许多迭代器,我也提到过生成器是迭代器。Python 的许多内置类型也是迭代器。例如,Python 的 `enumerate` 和 `reversed` 对象就是迭代器。 + ``` >>> letters = ['a', 'b', 'c'] - >>> e = enumerate(letters) - >>> e - - >>> next(e) - (0, 'a') - ``` 在 Python 3 中,`zip`, `map` 和 `filter` 也是迭代器。 + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> letters = ['a', 'b', 'c'] - >>> z = zip(numbers, letters) - >>> z - - >>> next(z) - (1, 'a') - ``` -Python 中的 文件对象也是迭代器。 +Python 中的文件对象也是迭代器。 + ``` >>> next(open('hello.txt')) - 'hello world\n' - ``` 在 Python 标准库和第三方库中内置了大量的迭代器。这些迭代器首先惰性迭代器一样,延迟工作直到你请求它们下一项。 @@ -584,51 +492,37 @@ Python 中的 文件对象也是迭代器。 知道你已经在使用迭代器是很有用的,但是我希望你也知道,你可以创建自己的迭代器和你自己的惰性迭代器。 下面这个类构造了一个迭代器接受一个可迭代的数字,并在循环结束时提供每个数字的平方。 + ``` class square_all: -     def __init__(self, numbers): -         self.numbers = iter(numbers) -     def __next__(self): -         return next(self.numbers) * 2 -     def __iter__(self): -         return self - ``` 但是在我们开始对该类的实例进行循环遍历之前,没有任何工作要做。 这里,我们有一个无限长的可迭代对象 `count`,你可以看到 `square_all` 接受 `count` 而不用完全循环遍历这个无限长的迭代: + ``` >>> from itertools import count - >>> numbers = count(5) - >>> squares = square_all(numbers) - >>> next(squares) - 25 - >>> next(squares) - 36 - ``` 这个迭代器类是有效的,但我们通常不会这样做。通常,当我们想要做一个定制的迭代器时,我们会生成一个生成器函数: + ``` def square_all(numbers): - for n in numbers: - yield n**2 - ``` 这个生成器函数等价于我们上面所做的类,它的工作原理是一样的。 @@ -636,14 +530,13 @@ def square_all(numbers): 这种 `yield` 语句似乎很神奇,但它非常强大:`yield` 允许我们在调用 `next` 函数之间暂停生成器函数。`yield` 语句是将生成器函数与常规函数分离的东西。 另一种实现相同迭代器的方法是使用生成器表达式。 + ``` def square_all(numbers): - return (n**2 for n in numbers) - ``` -这和我们的生成器函数确实是一样的,但是它使用的语法看起来[像列表一样容易理解][2]。如果你需要在代码中使用惰性迭代,请考虑迭代器,并考虑使用生成器函数或生成器表达式。 +这和我们的生成器函数确实是一样的,但是它使用的语法看起来[像是一个列表推导一样][2]。如果你需要在代码中使用惰性迭代,请考虑迭代器,并考虑使用生成器函数或生成器表达式。 ### 迭代器如何改进你的代码 @@ -652,33 +545,24 @@ def square_all(numbers): #### 惰性求和 这是一个 `for` 循环,它对 Django queryset 中的所有工作时间求和: + ``` hours_worked = 0 - for event in events: - if event.is_billable(): - hours_worked += event.duration - ``` 下面是使用生成器表达式进行惰性评估的代码: + ``` billable_times = ( - event.duration - for event in events - if event.is_billable() - ) - - hours_worked = sum(billable_times) - ``` 请注意,我们代码的形状发生了巨大变化。 @@ -688,27 +572,21 @@ hours_worked = sum(billable_times) #### 惰性和打破循环 这段代码打印出日志文件的前 10 行: + ``` for i, line in enumerate(log_file): - if i >= 10: - break - print(line) - ``` 这段代码做了同样的事情,但是我们使用的是 `itertools.islice` 函数来惰性地抓取文件中的前 10 行: + ``` from itertools import islice - first_ten_lines = islice(log_file, 10) - for line in first_ten_lines: - print(line) - ``` 我们定义的 `first_ten_lines` 变量是迭代器,同样,使用迭代器允许我们给以前未命名的东西命名(`first_ten_lines`)。命名事物可以使我们的代码更具描述性,更具可读性。 @@ -722,15 +600,12 @@ for line in first_ten_lines: 你可以在标准库和第三方库中找到用于循环的辅助函数,但你也可以自己创建! 这段代码列出了序列中连续值之间的差值列表。 + ``` current = readings[0] - for next_item in readings[1:]: - differences.append(next_item - current) - current = next_item - ``` 请注意,这段代码中有一个额外的变量,我们每次循环时都要指定它。还要注意,这段代码只适用于我们可以切片的东西,比如序列。如果 `readings` 是一个生成器,一个 zip 对象或其他任何类型的迭代器,那么这段代码就会失败。 @@ -738,47 +613,36 @@ for next_item in readings[1:]: 让我们编写一个辅助函数来修复代码。 这是一个生成器函数,它为给定的迭代中的每个项目提供了当前项和下一项: + ``` def with_next(iterable): - """Yield (current, next_item) tuples for each item in iterable.""" - iterator = iter(iterable) - current = next(iterator) - for next_item in iterator: - yield current, next_item - current = next_item - ``` 我们从可迭代对象中手动获取一个迭代器,在它上面调用 `next` 来获取第一项,然后循环遍历迭代器获取后续所有的项目,跟踪后一个项目。这个函数不仅适用于序列,而且适用于任何类型迭代。 -这段代码和以前代码是一样的,但是我们使用的是辅助函数而不是手动跟踪 `next_item`: +这段代码和以前代码是一样的,但是我们使用的是辅助函数而不是手动跟踪 `next_item`: + ``` differences = [] - for current, next_item in with_next(readings): - differences.append(next_item - current) - ``` 请注意,这段代码不会挂在我们循环周围的 `next_item` 上,`with_next` 生成器函数处理跟踪 `next_item` 的工作。 -还要注意,这段代码已足够紧凑,如果我们愿意,我们甚至可以[将方法复制到列表中来理解][2]。 +还要注意,这段代码已足够紧凑,如果我们愿意,我们甚至可以[将方法复制到列表推导中来][2]。 + ``` differences = [ - (next_item - current) - for current, next_item in with_next(readings) - ] - ``` ### 再次回顾循环问题 @@ -787,40 +651,34 @@ differences = [ #### 问题 1:耗尽的迭代器 -这里我们有一个生成器对象 `squares`: +这里我们有一个生成器对象 `squares`: + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> squares = (n**2 for n in numbers) - ``` 如果我们把这个生成器传递给 `tuple` 构造函数,我们将会得到它的一个元组: + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> squares = (n**2 for n in numbers) - >>> tuple(squares) - (1, 4, 9, 25, 49) - ``` -如果我们试着计算这个生成器中数字的和,使用 `sum`,我们就会得到 `0`: +如果我们试着计算这个生成器中数字的和,使用 `sum`,我们就会得到 `0`: + ``` >>> sum(squares) - 0 - ``` 这个生成器现在是空的:我们已经把它耗尽了。如果我们试着再次创建一个元组,我们会得到一个空元组: + ``` >>> tuple(squares) - () - ``` 生成器是迭代器,迭代器是一次性的。它们就像 Hello Kitty Pez 分配器那样不能重新加载。 @@ -828,43 +686,35 @@ differences = [ #### 问题 2:部分消耗一个迭代器 再次使用那个生成器对象 `squares`: + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> squares = (n**2 for n in numbers) - ``` -如果我们询问 `9` 是否在 `squares` 生成器中,我们会得到 `True`: +如果我们询问 `9` 是否在 `squares` 生成器中,我们会得到 `True`: + ``` >>> 9 in squares - True - ``` -但是我们再次询问相同的问题,我们会得到 `False`: +但是我们再次询问相同的问题,我们会得到 `False`: + ``` >>> 9 in squares - False - ``` 当我们询问 `9` 是否在迭代器中时,Python 必须对这个生成器进行循环遍历来找到 `9`。如果我们在检查了 `9` 之后继续循环遍历,我们只会得到最后两个数字,因为我们已经在找到 9 之前消耗了这些数字: + ``` >>> numbers = [1, 2, 3, 5, 7] - >>> squares = (n**2 for n in numbers) - >>> 9 in squares - True - >>> list(squares) - [25, 49] - ``` 询问迭代器中是否包含某些东西将会部分地消耗迭代器。如果没有循环遍历迭代器,那么是没有办法知道某个东西是否在迭代器中。 @@ -872,36 +722,29 @@ True #### 问题 3:拆包是迭代 当你在字典上循环时,你会得到键: + ``` >>> counts = {'apples': 2, 'oranges': 1} - >>> for key in counts: - ... print(key) - ... - apples - oranges - ``` 当你对一个字典进行拆包时,你也会得到键: + ``` >>> x, y = counts - >>> x, y - ('apples', 'oranges') - ``` 循环依赖于迭代器协议,可迭代对象拆包也依赖于有迭代器协议。拆包一个字典与在字典上循环遍历是一样的,两者都使用迭代器协议,所以在这两种情况下都得到相同的结果。 ### 回顾 -序列是迭代器,但是不是所有的迭代器都是序列。当有人说“迭代器”这个词时,你只能假设他们的意思是“你可以迭代的东西”。不要假设迭代器可以被循环遍历两次,询问它们的长度,或者索引。 +序列是迭代器,但是不是所有的迭代器都是序列。当有人说“迭代器”这个词时,你只能假设他们的意思是“你可以迭代的东西”。不要假设迭代器可以被循环遍历两次、询问它们的长度或者索引。 迭代器是 Python 中最基本的可迭代形式。如果你想在代码中做一个惰性迭代,请考虑迭代器,并考虑使用生成器函数或生成器表达式。 @@ -909,8 +752,15 @@ oranges 这里有一些我推荐的相关文章和视频: -本文是基于作者去年在 [DjangoCon AU][6], [PyGotham][7] 和 [North Bay Python][8] 中发表的 Loop Better 演讲。有关更多内容,请参加将于 2018 年 5 月 9 日至 17 日在 Columbus, Ohio 举办的 [PYCON][9]。 +- [Loop Like a Native](https://nedbatchelder.com/text/iter.html), Ned Batchelder 在 PyCon 2013 的讲演 +- [Loop Better](https://www.youtube.com/watch?v=V2PkkMS2Ack) ,这篇文章是基于这个讲演的 +- [The Iterator Protocol: How For Loops Work](http://treyhunner.com/2016/12/python-iterator-protocol-how-for-loops-work/),我写的关于迭代器协议的短文 +- [Comprehensible Comprehensions](https://www.youtube.com/watch?v=5_cJIcgM7rw),关于推导和迭代器表达器的讲演 +- [Python: Range is Not an Iterator](http://treyhunner.com/2018/02/python-range-is-not-an-iterator/),我关于范围和迭代器的文章 +- [Looping Like a Pro in Python](https://www.youtube.com/watch?v=u8g9scXeAcI),DB 的 PyCon 2017 讲演 + +本文是基于作者去年在 [DjangoCon AU][6]、 [PyGotham][7] 和 [North Bay Python][8] 中发表的 Loop Better 演讲。有关更多内容,请参加将于 2018 年 5 月 9 日至 17 日在 Columbus, Ohio 举办的 [PYCON][9]。 -------------------------------------------------------------------------------- @@ -919,7 +769,7 @@ via: https://opensource.com/article/18/3/loop-better-deeper-look-iteration-pytho 作者:[Trey Hunner][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/20180502 zzupdate - Single Command To Upgrade Ubuntu.md b/published/20180502 zzupdate - Single Command To Upgrade Ubuntu.md similarity index 86% rename from translated/tech/20180502 zzupdate - Single Command To Upgrade Ubuntu.md rename to published/20180502 zzupdate - Single Command To Upgrade Ubuntu.md index e9ed956d9e..abd1a4be19 100644 --- a/translated/tech/20180502 zzupdate - Single Command To Upgrade Ubuntu.md +++ b/published/20180502 zzupdate - Single Command To Upgrade Ubuntu.md @@ -1,5 +1,6 @@ -zzupdate —— 升级 Ubuntu 的简单命令 +zzupdate:单条命令升级 Ubuntu 18.04 LTS ====== + Ubuntu 18.04 版本已经发布,并得到各个社区的一致好评,因为 Ubuntu 18.04 可能是 Ubuntu 多年来最令人兴奋的版本。 通常情况下,Ubuntu 及其衍生版可以使用命令从一个版本升级到最新版本或者其它版本,这也是官方推荐的升级方式。 @@ -16,20 +17,21 @@ Ubuntu 18.04 版本已经发布,并得到各个社区的一致好评,因为 - 笔记本电脑在使用电池供电时会在无操作 20 分钟后自动待机 - 不再提供 32 位的 Ubuntu 桌面安装程序映像 +注意: -**注意:** 1. 不要忘记备份重要数据。如果升级出现问题,我们将重新安装并恢复数据。 2. 安装所需时间取决于您的网络状况和安装的程序。 ### zzupdate 是什么? -我们可以通过使用 [zzupdate][2] 工具中的单个命令将 Ubuntu PC/Server 从一个版本升级到另一个版本。它是一个免费的开源工具,使用它不需要任何脚本知识,因为它只需要配置文件即可运行。 +我们可以只通过一条命令使用 [zzupdate][2] 工具中将 Ubuntu PC/Server 从一个版本升级到另一个版本。它是一个自由开源工具,使用它不需要任何脚本知识,因为它只需要配置文件即可运行。 工具中提供两个默认 shell 文件。`setup.sh` 自动安装、更新代码,将脚本转换为一个简单的 zzupdate shell 命令。`zzupdate.sh` 将执行版本间的升级。 -### 如何安装 zzipdate? +### 如何安装 zzupdate? + +要安装 `zzupdate`,只需执行以下命令: -要安装 zzupdate,只需执行以下命令。 ``` $ curl -s https://raw.githubusercontent.com/TurboLabIt/zzupdate/master/setup.sh | sudo sh . @@ -46,24 +48,24 @@ Already up-to-date. Setup completed! ---------------- See https://github.com/TurboLabIt/zzupdate for the quickstart guide. - ``` -将 Ubuntu 系统从一个版本升级到另一个版本,您不需要输入很多命令,也不需要重新启动,只需要运行下面的 zzupdate 命令并坐下喝杯咖啡就可以了。 +将 Ubuntu 系统从一个版本升级到另一个版本,您不需要输入很多命令,也不需要重新启动,只需要运行下面的 `zzupdate` 命令并坐下喝杯咖啡就可以了。 请注意,当您远程升级系统时,建议您使用以下的工具来帮助您在任何断开连接时重新连接会话。 -**建议阅读:** [如何让一个进程/命令在 SSH 连接断开后继续运行][3] +建议阅读: [如何让一个进程/命令在 SSH 连接断开后继续运行][3] ### 如何配置 zzupdate(可选) -默认情况下,zzupdate 可以直接使用,不需要配置任何东西。当然,如果您想要自己配置一些内容,可以的。复制提供的实例配置文件 `zzupdate.default.conf` 到 `zzupdate.conf` 并在 `zzupdate.conf` 中配置您的首选项。 +默认情况下,`zzupdate` 可以开箱即用,不需要配置任何东西。当然,如果您想要自己配置一些内容也是可以的。复制提供的示例配置文件 `zzupdate.default.conf` 到 `zzupdate.conf`,并在 `zzupdate.conf` 中配置您的首选项。 + ``` $ sudo cp /usr/local/turbolab.it/zzupdate/zzupdate.default.conf /etc/turbolab.it/zzupdate.conf - ``` 打开文件,默认配置如下。 + ``` $ sudo nano /etc/turbolab.it/zzupdate.conf @@ -73,19 +75,18 @@ VERSION_UPGRADE=1 VERSION_UPGRADE_SILENT=0 COMPOSER_UPGRADE=1 SWITCH_PROMPT_TO_NORMAL=0 - ``` - * **`REBOOT=1 :`**系统在更新完成后自动重启 - * **`REBOOT_TIMEOUT=15 :`**重启的默认超时值 - * **`VERSION_UPGRADE=1 :`**执行从一个版本到另一个版本的版本升级 - * **`VERSION_UPGRADE_SILENT=0 :`**禁用自动升级 - * **`COMPOSER_UPGRADE=1 :`**自动升级 - * **`SWITCH_PROMPT_TO_NORMAL=0 :`**如果值为 `0`,将寻找相同种类的版本升级。例如您正在运行 LTS 的版本,那么将寻找 LTS 的版本升级,而不是用于正常版本升级。如果值为 `1`,那么无论您是运行 LTS 还是正常版本,都会查找最新版本 + * `REBOOT=1`:系统在更新完成后自动重启 + * `REBOOT_TIMEOUT=15`:重启的默认超时值 + * `VERSION_UPGRADE=1`:执行从一个版本到另一个版本的版本升级 + * `VERSION_UPGRADE_SILENT=0`:禁用自动升级 + * `COMPOSER_UPGRADE=1`:自动升级 + * `SWITCH_PROMPT_TO_NORMAL=0`:如果值为 `0`,将寻找相同种类的版本升级。例如您正在运行 LTS 的版本,那么将寻找 LTS 的版本升级,而不是用于正常版本升级。如果值为 `1`,那么无论您是运行 LTS 还是正常版本,都会查找最新版本 +我现在正在使用 Ubuntu 17.10 ,查看一下详细信息。 -我现在使用 Ubuntu 17.10 并查看详细信息。 ``` $ cat /etc/*-release DISTRIB_ID=Ubuntu @@ -107,7 +108,8 @@ UBUNTU_CODENAME=artful ``` -要升级 Ubuntu 到最新版本,只需要执行以下命令。 +要升级 Ubuntu 到最新版本,只需要执行以下命令: + ``` $ sudo zzupdate @@ -181,10 +183,10 @@ Fetched 0 B in 6s (0 B/s) Reading package lists... Done Building dependency tree Reading state information... Done - ``` -我们需要按下 `Enter` 按钮禁用 `Third Party` 仓库以继续升级。 +我们需要按下回车键禁用第三方仓库以继续升级。 + ``` Updating repository information @@ -209,10 +211,10 @@ Reading state information... Done Calculating the changes Calculating the changes - ``` 开始下载 `Ubuntu 18.04 LTS` 软件包,所需时间取决于您的网络状况,一般情况下这将需要几分钟。 + ``` Do you want to start the upgrade? @@ -244,10 +246,10 @@ Get:1480 http://in.archive.ubuntu.com/ubuntu bionic/main amd64 usb-modeswitch am Get:1481 http://in.archive.ubuntu.com/ubuntu bionic/main amd64 usb-modeswitch-data all 20170806-2 [30.7 kB] Get:1482 http://in.archive.ubuntu.com/ubuntu bionic/main amd64 xbrlapi amd64 5.5-4ubuntu2 [61.8 kB] Fetched 999 MB in 6s (721 kB/s) - ``` 安装新软件包时,很少有服务需要重新启动。 点击 `Yes` 按钮,它会自动重启所需的服务。 + ``` Upgrading Inhibiting until Ctrl+C is pressed... @@ -279,7 +281,8 @@ Progress: [ 95%] ``` -现在删除旧版的、系统不再需要的包。点击 `y` 以删除。 +现在删除旧版的、系统不再需要的包。点击 `y` 以删除。 + ``` Searching for obsolete software ing package lists... 97% @@ -312,7 +315,8 @@ Fetched 0 B in 0s (0 B/s) ``` -升级成功,需要重启系统。点击 `Y` 以重启系统。 +升级成功,需要重启系统。点击 `y` 以重启系统。 + ``` System upgrade is complete. @@ -325,9 +329,10 @@ Continue [yN]y ``` -**注意:** 少数情况下,会要求您确认配置文件替换以继续安装。 +注意: 少数情况下,会要求您确认配置文件替换以继续安装。 + +查看升级后的系统详情: -查看升级后的系统详情。 ``` $ cat /etc/*-release DISTRIB_ID=Ubuntu @@ -346,7 +351,6 @@ BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic - ``` -------------------------------------------------------------------------------- @@ -356,7 +360,7 @@ via: https://www.2daygeek.com/zzupdate-single-command-to-upgrade-ubuntu-18-04/ 作者:[PRAKASH SUBRAMANIAN][a] 选题:[lujun9972](https://github.com/lujun9972) 译者:[XiatianSummer](https://github.com/XiatianSummer) -校对:[校对者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/20180517 How to find your IP address in Linux.md b/published/20180517 How to find your IP address in Linux.md similarity index 83% rename from translated/tech/20180517 How to find your IP address in Linux.md rename to published/20180517 How to find your IP address in Linux.md index 1450fb3c8c..3c171b5a33 100644 --- a/translated/tech/20180517 How to find your IP address in Linux.md +++ b/published/20180517 How to find your IP address in Linux.md @@ -1,7 +1,11 @@ 如何在 Linux 中找到你的 IP 地址 ====== + +> 每个网站都有一个独有的公开 IP 地址,可供任何人从任何地方访问。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/satellite_radio_location.jpg?itok=KJUKSB6x) -互联网协议(IP)不需要介绍 - 我们每天都在使用它。即使你不直接使用它,当你在浏览器上输入 website-name.com 时,它会查找该 URL 的 IP 地址,然后加载该网站。 + +互联网协议Internet Protocol(IP)不需要介绍 —— 我们每天都在使用它。即使你不直接使用它,当你在浏览器上输入 website-name.com 时,它会查找该 URL 的 IP 地址,然后加载该网站。 我们将 IP 地址分为两类:私有和公共。私有 IP 地址是你的无线路由(和公司内网)提供的私有 IP 地址。它们的范围是 10.xxx、172.16.xx-172.31.xx 和 192.168.xx,其中 x=0 到 255。公有 IP 地址,顾名思义,是“公共”的,你可以在世界上任何地方访问它。每个网站都有一个唯一的 IP 地址,任何人可在任何地点访问,这可被视为公共 IP 地址。 @@ -9,7 +13,7 @@ IPv4 地址格式为 x.x.x.x,其中 x=0 到 255。有 2^32(大约 40 亿个)可能的 IPv4 地址。 -IPv6 地址使用更复杂的十六进制。总的比特数是 128,这意味着有 2^128-340 后面有 36 个零! - 可能的 IPv6 地址。IPv6 已经被引入解决了可预见的 IPv4 地址耗尽问题。 +IPv6 地址使用更复杂的十六进制。总的比特数是 128,这意味着有 2^128 (340 后面有 36 个零!)个可能的 IPv6 地址。IPv6 已经被引入解决了可预见的 IPv4 地址耗尽问题。 作为网络工程师,我建议不要与任何人共享你机器的公有 IP 地址。你的 WiFi 路由器有公共 IP,即 WAN(广域网)IP 地址,并且连接到该 WiFi 的任何设备都是相同的。连接到相同 WiFi 的所有设备都有上面所说的私有 IP 地址。例如,我的笔记本电脑的 IP 地址 192.168.0.5,而我的电话是 192.168.0.8。这些是私有 IP 地址,但两者都有相同的公有 IP 地址。 @@ -26,8 +30,6 @@ IPv6 地址使用更复杂的十六进制。总的比特数是 128,这意味 9. `curl bot.whatismyipaddress.com` 10. `curl ipecho.net/plain` - - 以下命令将为你提供接口的私有 IP 地址: 1. `ifconfig -a` @@ -37,8 +39,6 @@ IPv6 地址使用更复杂的十六进制。总的比特数是 128,这意味 5. `(Fedora) Wifi-Settings→ click the setting icon next to the Wifi name that you are connected to → Ipv4 and Ipv6 both can be seen` 6. `nmcli -p device show` - - _注意:一些工具需要根据你正在使用的 Linux 发行版安装在你的系统上。另外,一些提到的命令使用第三方网站来获取 IP_ -------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ via: https://opensource.com/article/18/5/how-find-ip-address-linux 作者:[Archit Modi][a] 选题:[lujun9972](https://github.com/lujun9972) 译者:[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/20180517 What You Need to Know About Cryptocurrency Malware Found on Ubuntus Snap Store.md b/published/20180517 What You Need to Know About Cryptocurrency Malware Found on Ubuntus Snap Store.md new file mode 100644 index 0000000000..5ed1a9fa7f --- /dev/null +++ b/published/20180517 What You Need to Know About Cryptocurrency Malware Found on Ubuntus Snap Store.md @@ -0,0 +1,108 @@ +在 Ubuntu Snap 应用商店上发现的加密货币 ‘恶意软件’ 是怎么回事? +====== + +最近,有发现称一些 Ubuntu Snap 应用商店上的应用包含加密货币挖矿程序。Canonical 公司迅速下架了这些违规的应用,但是留下了几个有待回答的问题。 + +### 在 Snap 应用商店上发现了加密矿工 + +![Crypto Miner Malware on Ubuntu Snap Store][1] + +5 月 11 号,一位名叫 [tarwirdur][2] 的用户在 [snapcraft.io repository][3] 开了一个新的工单 ,他提到一个由 Nicolas Tomb 开发,叫做 2048buntu 的 snap 应用包含加密货币矿工。tarwirdur 询问,他怎样才能出于安全的原因而“投诉该应用” 。tarwirdur 后来发表说其它由 Nicolas Tomb 开发的 snap 应用也都包含加密货币矿工。 + +看起来该 snap 应用使用了 systemd 在系统启动时自动地运行代码,并在用户不知情的情况下在后台运行。 + +> 对那些不熟悉相关术语的人来说,加密货币cryptocurrency矿工miner是一段使用计算机的主处理器或者图形处理器来“挖掘”数字货币的程序。“挖矿”通常涉及到解决一个数学等式。在这种情况下,如果你在运行 2048buntu 游戏,这个游戏将会额外使用处理器的计算能力去进行加密货币的挖掘。 + +Snapcraft 团队迅速地下架了所有由该违规者开发的应用来做出回应。他们同时也开展了调查。 + +### 隐匿者发声 + +5 月 13 号,一位同名为 Nicolas Tomb 的 Disqus 用户在 OMGUbuntu 的新闻报道上发表了[评论][4],他在评论中称自己向 snap 应用中添加了加密货币矿工,从而获取收益。他为他的行为道歉,同时承诺将所有挖矿所得的收益送给 Ubuntu 基金会。 + +我们不能确认这个评论就是由 Nicolas Tomb 发表的,因为这个 Disqus 账户最近才被创建,也只有一条评论与之相关联。现在,我们假设他是。 + +### Canonical 公司发表了声明 + +5 月 15 号,Canonical 公司在这种情况下发表了一份声明。标题为 [“在 Snap 应用商店中的信任与安全”][5],声明开头重申了当下的情况。他们也补充道[重新发布的 snap 应用中已经被删除了加密货币挖矿程序][6]。 + +Canonical 公司随后尝试调查 Nicolas Tomb 的动机。他们指出,他告诉他们说自己这样做是为了通过应用赚钱(如上所诉),而当面对质疑时就停止了。他们也指出“挖掘加密货币本身并非不合法和不道德的”。然而,他们仍对他没有在 snap 应用描述中披露加密矿工这件事表示了不满意。 + +随后 Canonical 公司将话题转移到审核软件上。根据这份申明,Snap 应用商店将会采用一种类似 iOS、Android、Windows 的质量控制系统,这个系统将有“自动化的检查点,安装包必须在被接受前通过检查,同时在特殊问题被标记时会进行人工审核”。 + +然后,Canonical 公司声称“对大规模的软件仓库来说,只接受每个单独文件都被仔细审核过的软件是不可能的”。因此,他们需要信任软件源而不是内容。毕竟,软件源是现在 Ubuntu 软件仓库系统的基础。 + +Canonical 公司紧接着谈到了 Snap 应用的未来。他们承认现在的系统是不完美的。他们也在不断地进行改善。他们“在开发非常有趣的安全功能,这些功能将会在改善系统安全性同时提升人们在服务器或桌面上进行软件开发的体验”。 + +其中一个他们正在开发的功能是查看一个软件发布者是否已通过验证。其他的改进包括:“将所有 AppArmor 内核补丁递交到上游”和其它底层修复。 + +### 一些关于“Snap 应用商店中的恶意软件”的想法 + +基于我所了解的所有内容,我产生了一些想法和问题。 + +#### 这种挖矿软件运行多久了? + +首先,这些挖矿软件存在于 Snap 应用商店多久了?因为它们已经被下架了,我们没有这样的数据。我可以通过 Google 快照抓取一些 2048buntu 页面的图片,但这没有提供任何可用的信息。根据该软件运行时间,多少系统安装过,挖掘出了什么加密货币,我们能否知道违规者获取的是一点钱还是一笔钱。一个更长远的问题是:Canonical 公司将来有能力捕捉到这样的违规情况吗? + +#### 这真的是一个恶意软件吗? + +许多新闻网站将之报道为恶意软件感染。我想我甚至可以看到这个事件被称为 Linux 的第一个恶意软件。我不确定这个术语是否精确。Dictionary.com 这样定义 [恶意软件][7]:“意图损害计算机、移动设备、计算机系统或者计算机网络,或者对其运作进行部分控制的软件”。 + +这个有问题的 snap 应用并没有损害或者控制涉及到的计算机。它同样没有感染其他计算机。它也不能这样做,因为所有的 snap 应用位于沙盒之中。它们最多利用了处理器的计算能力,就是这样。所以,我不会称之为恶意软件。 + +#### 无孔不入 + +Nicolas Tomb 使用的一个辩解是在他上传应用的时候 Snap 应用商店没有任何反对加密货币挖矿的规则。(我敢向你打赌他们正在纠正这个错误。)他们之所以没有这样的规则,原因很简单,之前没有人做过这种事。如果 Tomb 想正确地做事,他应该提前询问是否允许这种行为。而事实是他似乎没有指出他知道 Canonical 公司可能会拒绝的事实。至少,Canonical 公司会告诉他将这些写在软件的描述中。 + +#### 一看就不对劲 + +![][8] + +如我之前说的,我从 Google 快照获取了一个 2048buntu 的页面截图。仅仅看它就会感觉到一些危险的信号。首先,截图中几乎没有真实的描述。它是这样描述的“类似 2048 的游戏。这个游戏用 ubuntu 主题克隆了流行的游戏 2048。”哇,这将会引来容易上当受骗的人。当我读到类似空洞的描述时,我会多考虑下。 + +我注意到的另一件事是软件的大小。2048buntu 的 1.0 版本大小将近 140 MB。一个简单的游戏怎么需要这么多的空间?有用 Javascript 写的浏览器版本大概只用了不到它的四分之一。其他 snap 应用商店的 2048 游戏的大小没有一个达到了这个软件的一半。 + +然后,它有个许可证。这是一个使用了 Ubuntu 主题的流行游戏的克隆。它怎么能被认为是专有软件?我确信,其他合法的开发者会因为该内容而使用了 FOSS (自由开源软件)许可证来上传它。 + +单是这些因素就使得这个 snap 应用很特殊,应该进行审核。 + +#### 谁是 Nicolas Tomb? + +当第一次了解到这些之后,我决定看看我能否找出造成这些混乱的人。当我搜索 Nicolas Tomb 的时候,我什么都没找到。所有我找到的只是一大堆关于加密货币挖矿 snap 应用的新闻和文章,以及去 tomb of St. Nicolas 旅游的信息。在 Twiter 和 Github 上都没有 Nicolas Tomb 的标志。看起来似乎是为了上传这些 snap 应用才创建的名称。 + +这同样引出了 Canonical 公司发表的申明中的一点,关于验证发布者。上一次我查看的时候,相当多的 snap 应用不是由应用的维护者发布的。这让我感到担忧。我更乐意相信由 Mozilla 基金会发布的 firefox 的 snap 应用,而不是 Leonard Borsch。如果对应用维护者来说关注应用的 snap 版本太耗费精力,应该有办法让维护者在他们软件的 snap 版本上贴上批准的标签。就像是 Firefox 的 snap 版本由 Fredrick 发布,经 Mozilla 基金会批准。这样才能让用户对下载的内容更放心。 + +#### 无疑 Snap 应用商店还有改善的空间 + +在我看来,Snap 应用商店团队应该实现的第一个特性是报告可疑应用的方式。tarwirdur 必须找到该网站的 Github 页面才行。而大多数用户不会想到这一点。如果 Snap 应用商店不能审核每一行代码,那么使用户能够报告问题是退而求其次的办法。即使评分系统也是一个不差的补充。我确信一定有部分人因为 2048buntu 使用了太多系统资源而给它很低的评分。 + +### 结论 + +从我所知道的情况来说,我认为这是某个人创建了一些简单的应用,在每个应用中嵌入了加密货币矿工,之后将这些应用上传到 Snap 应用商店,想着捞一笔钱。一旦他们被抓了,他们就声称这仅仅为了通过应用程序获利。如果真的是这样,他们应该在 snap 应用的描述中提到才对。隐藏加密矿工并不是什么[新鲜事][9]。他们通常是一种盗取计算能力的方法。 + +我希望 Canonical 公司已经具备了解决这个问题的功能,盼望这些功能能很快出来。 + +你对 Snap 应用商店的“恶意软件风波”有什么看法?你将如何改善这种情况?请在下面的评论中告诉我们。 + +如果你觉得这篇文章有趣,请花费一点时间将它分享到社交媒体上。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/snapstore-cryptocurrency-saga/ + +作者:[John Paul][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[paperzhang](https://github.com/paperzhang) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/john/ +[1]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/ubuntu-snap-malware-800x450.jpeg +[2]:https://github.com/tarwirdur +[3]:https://github.com/canonical-websites/snapcraft.io/issues/651 +[4]:https://disqus.com/home/discussion/omgubuntu/malware_found_on_the_ubuntu_snap_store/#comment-3899153046 +[5]:https://blog.ubuntu.com/2018/05/15/trust-and-security-in-the-snap-store +[6]:https://forum.snapcraft.io/t/action-against-snap-store-malware/5417/8 +[7]:http://www.dictionary.com/browse/malware?s=t +[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/2048buntu.png +[9]:https://krebsonsecurity.com/2018/03/who-and-what-is-coinhive/ \ No newline at end of file diff --git a/sources/talk/20180107 7 leadership rules for the DevOps age.md b/sources/talk/20180107 7 leadership rules for the DevOps age.md deleted file mode 100644 index fd875cc63b..0000000000 --- a/sources/talk/20180107 7 leadership rules for the DevOps age.md +++ /dev/null @@ -1,124 +0,0 @@ -Translating by FelixYFZ 7 leadership rules for the DevOps age -====== - -![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/CIO_DigitalAcumen_2.png?itok=TGeMQYs4) - -If [DevOps][1] is ultimately more about culture than any particular technology or platform, then remember this: There isn't a finish line. It's about continuous change and improvement - and the C-suite doesn't get a pass. - -Rather, leaders need to [revise some of their traditional approaches][2] if they expect DevOps to help drive the outcomes they seek. Let's consider seven ideas for more effective IT leadership in the DevOps era. - -### 1. Say "yes" to failure - -The word "failure" has long had very specific connotations in IT, and they're almost universally bad: server failure, backup failure, hard drive failure - you get the picture. - -A healthy DevOps culture, however, depends upon redefining failure - IT leaders should rewrite their thesaurus to make the word synonymous with "opportunity." - -"Prior to DevOps, we had a culture of punishing failure," says Robert Reeves, CTO and co-founder of [Datical][3]. "The only learning we had was to avoid mistakes. The number one way to avoid mistakes in IT is to not change anything: Don't accelerate the release schedule, don't move to the cloud, don't do anything differently!" - -That's a playbook for a bygone era and, as Reeves puts plainly, it doesn't work. In fact, that kind of stasis is actual failure. - -"Companies that release slowly and avoid the cloud are paralyzed by fear - and they will fail," Reeves says. "IT leaders must embrace failure as an opportunity. Humans not only learn from their mistakes, they learn from others' mistakes. A culture of openness and ['psychological safety'][4] fosters learning and improvement." - -**[ Related article: [Why agile leaders must move beyond talking about "failure."][5] ]** - -### 2. Live, eat, and breathe DevOps in the C-suite - -While DevOps culture can certainly grow organically in all directions, companies that are shifting from monolithic, siloed IT practices - and likely encountering headwinds en route - need total buy-in from executive leadership. Without it, you're sending mixed messages and likely emboldening those who'd rather push a _but this is the way we 've always done things_ agenda. [Culture change is hard][6]; people need to see leadership fully invested in that change for it to actually happen. - -"Top management must fully support DevOps in order for it to be successful in delivering the benefits," says Derek Choy, CIO at [Rainforest QA][7]. - -Becoming a DevOps shop. Choy notes, touches pretty much everything in the organization, from technical teams to tools to processes to roles and responsibilities. - -"Without unified sponsorship from top management, DevOps implementation will not be successful," Choy says. "Therefore, it is important to have leaders aligned at the top level before transitioning to DevOps." - -### 3. Don 't just declare "DevOps" - define it - -Even in IT organizations that have welcomed DevOps with open arms, it's possible that's not everyone's on the same page. - -**[Read our related article,**[ **3 areas where DevOps and CIOs must get on the same page**][8] **.]** - -One fundamental reason for such disconnects: People might be operating with different definitions for what the term even means. - -"DevOps can mean different things to different people," Choy says. "It is important for C-level [and] VP-level execs to define the goals of DevOps, clearly stating the expected outcome, understand how this outcome can benefit the business and be able to measure and report on success along the way." - -Indeed, beyond the baseline definition and vision, DevOps requires ongoing and frequent communication, not just in the trenches but throughout the organization. IT leaders must make that a priority. - -"Inevitably, there will be hiccups, there will be failures and disruptions to the business," Choy says. "Leaders need to clearly communicate the journey to the rest of the company and what they can expect as part of the process." - -### 4.DevOps is as much about business as technology - -IT leaders running successful DevOps shops have embraced its culture and practices as a business strategy as much as an approach to building and operating software. DevOps culture is a great enabler of IT's shift from support arm to strategic business unit. - -"IT leaders must shift their thinking and approach from being cost/service centers to driving business outcomes, and a DevOps culture helps speed up those outcomes via automation and stronger collaboration," says Mike Kail, CTO and co-founder at [CYBRIC][9]. - -Indeed, this is a strong current that runs through much of these new "rules" for leading in the age of DevOps. - -"Promoting innovation and encouraging team members to take smart risks is a key part of a DevOps culture and IT leaders need to clearly communicate that on a continuous basis," Kail says. - -"An effective IT leader will need to be more engaged with the business than ever before," says Evan Callendar, director, performance services at [West Monroe Partners][10]. "Gone are the days of yearly or quarterly reviews - you need to welcome the [practice of] [bi-weekly backlog grooming][11]. The ability to think strategically at the year level, but interact at the sprint level, will be rewarded when business expectations are met." - -### 5. Change anything that hampers DevOps goals - - -While DevOps veterans generally agree that DevOps is much more a matter of culture than technology, success does depend on enabling that culture with the right processes and tools. Declaring your department a DevOps shop while resisting the necessary changes to processes or technologies is like buying a Ferrari but keeping the engine from your 20-year-old junker that billows smoke each time you turn the key. - -Exhibit A: [Automation][12]. It's critical parallel strategy for DevOps success. - -"IT leadership has to put an emphasis on automation," Callendar says. "This will be an upfront investment, but without it, DevOps simply will engulf itself with inefficiency and lack of delivery." - -Automation is a fundamental, but change doesn't stop there. - -"Leaders need to push for automation, monitoring, and a continuous delivery process. This usually means changes to many existing practices, processes, team structures, [and] roles," Choy says. "Leaders need to be willing to change anything that'll hinder the team's ability to fully automate the process." - -### 6. Rethink team structure and performance metrics - -While we're on the subject of change...if that org chart collecting dust on your desktop is the same one you've been plugging names into for the better part of a decade (or more), it's time for an overhaul. - -"IT executives need to take a completely different approach to organizational structure in this new era of DevOps culture," Kail says. "Remove strict team boundaries, which tend to hamper collaboration, and allow for the teams to be self-organizing and agile." - -Kail says this kind of rethinking can and should extend to other areas in the DevOps age, too, including how you measure individual and team success, and even how you interact with people. - -"Measure initiatives in terms of business outcomes and overall positive impact," Kail advises. "Finally, and something that I believe to be the most important aspect of management: Be empathetic." - -Beware easily collected measurements that are not truly DevOps metrics, writes [Red Hat ][13]technology evangelist Gordon Haff. "DevOps metrics should be tied to business outcomes in some manner," he notes. "You probably don't really care about how many lines of code your developers write, whether a server had a hardware failure overnight, or how comprehensive your test coverage is. In fact, you may not even directly care about the responsiveness of your website or the rapidity of your updates. But you do care to the degree such metrics can be correlated with customers abandoning shopping carts or leaving for a competitor." See his full article, [DevOps metrics: Are you measuring what matters?][14] - -### 7. Chuck conventional wisdom out the window - -If the DevOps age requires new ways of thinking about IT leadership, it follows that some of the old ways need to be retired. But which ones? - -"To be honest, all of them," Kail says. "Get rid of the 'because that's the way we've always done things' mindset. The transition to a culture of DevOps is a complete paradigm shift, not a few subtle changes to the old days of Waterfall and Change Advisory Boards." - -Indeed, IT leaders recognize that real transformation requires more than minor touch-ups to old approaches. Often, it requires a total reboot of a previous process or strategy. - -Callendar of West Monroe Partners shares a parting example of legacy leadership thinking that hampers DevOps: Failing to embrace hybrid IT models and modern infrastructure approaches such as containers and microservices. - -"One of the big rules I see going out the window is architecture consolidation, or the idea that long-term maintenance is cheaper if done within a homogenous environment," Callendar says. - -**Want more wisdom like this, IT leaders? [Sign up for our weekly email newsletter][15].** - --------------------------------------------------------------------------------- - -via: https://enterprisersproject.com/article/2018/1/7-leadership-rules-devops-age - -作者:[Kevin Casey][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://enterprisersproject.com/user/kevin-casey -[1]:https://enterprisersproject.com/tags/devops -[2]:https://enterprisersproject.com/article/2017/7/devops-requires-dumping-old-it-leadership-ideas -[3]:https://www.datical.com/ -[4]:https://rework.withgoogle.com/guides/understanding-team-effectiveness/steps/foster-psychological-safety/ -[5]:https://enterprisersproject.com/article/2017/10/why-agile-leaders-must-move-beyond-talking-about-failure?sc_cid=70160000000h0aXAAQ -[6]:https://enterprisersproject.com/article/2017/10/how-beat-fear-and-loathing-it-change -[7]:https://www.rainforestqa.com/ -[8]:https://enterprisersproject.com/article/2018/1/3-areas-where-devops-and-cios-must-get-same-page -[9]:https://www.cybric.io/ -[10]:http://www.westmonroepartners.com/ -[11]:https://www.scrumalliance.org/community/articles/2017/february/product-backlog-grooming -[12]:https://www.redhat.com/en/topics/automation?intcmp=701f2000000tjyaAAA -[13]:https://www.redhat.com/en?intcmp=701f2000000tjyaAAA -[14]:https://enterprisersproject.com/article/2017/7/devops-metrics-are-you-measuring-what-matters -[15]:https://enterprisersproject.com/email-newsletter?intcmp=701f2000000tsjPAAQ diff --git a/sources/talk/20180115 Why DevSecOps matters to IT leaders.md b/sources/talk/20180115 Why DevSecOps matters to IT leaders.md index e731013e2b..bb9ec99360 100644 --- a/sources/talk/20180115 Why DevSecOps matters to IT leaders.md +++ b/sources/talk/20180115 Why DevSecOps matters to IT leaders.md @@ -1,4 +1,4 @@ -Why DevSecOps matters to IT leaders + Translating by FelixYFZ Why DevSecOps matters to IT leaders ====== ![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/TEP_SecurityTraining1_620x414_1014.png?itok=zqxqJGDG) diff --git a/sources/tech/20171121 How To Kill The Largest Process In An Unresponsive Linux System.md b/sources/tech/20171121 How To Kill The Largest Process In An Unresponsive Linux System.md deleted file mode 100644 index e87a206d61..0000000000 --- a/sources/tech/20171121 How To Kill The Largest Process In An Unresponsive Linux System.md +++ /dev/null @@ -1,140 +0,0 @@ -translating by cizezsy - -How To Kill The Largest Process In An Unresponsive Linux System -====== -![](https://www.ostechnix.com/wp-content/uploads/2017/11/Kill-The-Largest-Process-720x340.png) - -I, as a blog writer, have bookmarked many blogs, websites and forums to refer Linux and Unix related notes. Sometimes, I had a lot of open tabs in my browser, so my system goes unresponsive for several minutes. I couldn't move the mouse cursor, or kill a process or close any opened tabs. At that times, I had no choice but to forcibly reset the system. Of course, I use **OneTab** and The **Great Suspender** extensions, but they didn 't help much either. I often ran out of memory. This is where **Early OOM** comes in help. For those wondering, it will kill the largest process in an unresponsive system when it has absolutely no other choices. Early OOM checks the amount of available memory and free swap 10 times a second. If both are below 10%, it will kill the largest process. - -### Why Early OOM? Why not built-in OOM killer? - -Before going into further, let me you give a short explanation of OOM killer, also known as **O** ut **O** f **M** emory killer. OOM killer is a process that the Kernel uses when the system is critically low on memory. The main task of OOM killer is to continue killing processes until enough memory is freed for the smooth functioning of the rest of the process that the Kernel is attempting to run. OOM killer will choose the best processes that are least important to the system and free up maximum memory and kill them. We can view the oom_score of each process in **/proc** directory under **pid** section. - -Example: -``` -$ cat /proc/10299/oom_score -1 -``` - -The higher the value of oom_score of any process, the higher is its likelihood of getting killed by the OOM Killer when the system is running out of memory. - -The developer of Early OOM claims that it has one big advantage over the in-kernel OOM killer. As I stated earlier, the Linux oom killer kills the process with the highest score, so the Chrome browser will always be the first victim of the oom killer. To avoid this, Early OOM uses **/proc/*/status** instead of **echo f > /proc/sysrq-trigger**. He also claims that triggering the oom killer manually may not work at all in latest Linux Kernel. - -### Installing Early OOM - -Early OOM is available in AUR, so you can install it using any AUR helper programs in Arch Linux and its derivatives. - -Using [**Pacaur**][1]: -``` -pacaur -S earlyoom -``` - -Using [**Packer**][2]: -``` -packer -S earlyoom -``` - -Using [**Yaourt**][3]: -``` -yaourt -S earlyoom -``` - -Enable and start Early OOM daemon: -``` -sudo systemctl enable earlyoom -``` -``` -sudo systemctl start earlyoom -``` - -On other Linux distributions, compile and install it manually as shown below. -``` -git clone https://github.com/rfjakob/earlyoom.git -cd earlyoom -make -sudo make install -``` - -### Early OOM - Kill The Largest Process In An Unresponsive Linux System - -Run the following command to start Early OOM: -``` -earlyoom -``` - -If you compiled it from source, run the following command to start Early OOM: -``` -./earlyoom -``` - -The sample output would be: -``` -earlyoom 0.12 -mem total: 3863 MiB, min: 386 MiB (10 %) -swap total: 2047 MiB, min: 204 MiB (10 %) -mem avail: 1770 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1771 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) -mem avail: 1784 MiB (46 %), swap free: 2047 MiB (99 %) -[...] -``` - -As you see in the above output, Early OOM will display how much memory and swap you have, what the minimum is, how much memory is available and how much swap is free. Remember it will keep running until you manually stop by pressing CTRL+C. - -If both memory and swap reaches below 10%, Early OOM will automatically kill the largest processes until the system has enough memory to run smoothly. You can also configure the minimum percentage value as per your requirement. - -To set available memory minimum to PERCENT of total, run:`` -``` -earlyoom -m -``` - -To set available swap minimum to PERCENT of total, run:`` -``` -earlyoom -s -``` - -For more details, refer the help section. -``` -$ earlyoom -h -earlyoom 0.12 -Usage: earlyoom [OPTION]... - - -m PERCENT set available memory minimum to PERCENT of total (default 10 %) - -s PERCENT set free swap minimum to PERCENT of total (default 10 %) - -M SIZE set available memory minimum to SIZE KiB - -S SIZE set free swap minimum to SIZE KiB - -k use kernel oom killer instead of own user-space implementation - -i user-space oom killer should ignore positive oom_score_adj values - -d enable debugging messages - -v print version information and exit - -r INTERVAL memory report interval in seconds (default 1), set to 0 to - disable completely - -p set niceness of earlyoom to -20 and oom_score_adj to -1000 - -h this help text -``` - -Now, you don't need to worry about highest memory consumption processes. Hope this helps. More good stuffs to come. Stay tuned! - -Cheers! - - - --------------------------------------------------------------------------------- - -via: https://www.ostechnix.com/kill-largest-process-unresponsive-linux-system/ - -作者:[Aditya Goturu][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.ostechnix.com -[1]:https://www.ostechnix.com/install-pacaur-arch-linux/ -[2]:https://www.ostechnix.com/install-packer-arch-linux-2/ -[3]:https://www.ostechnix.com/install-yaourt-arch-linux/ diff --git a/sources/tech/20180423 An introduction to Python bytecode.md b/sources/tech/20180423 An introduction to Python bytecode.md deleted file mode 100644 index fc6661e6d0..0000000000 --- a/sources/tech/20180423 An introduction to Python bytecode.md +++ /dev/null @@ -1,156 +0,0 @@ -Translating by qhwdw -An introduction to Python bytecode -====== -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82) -If you've ever written, or even just used, Python, you're probably used to seeing Python source code files; they have names ending in `.py`. And you may also have seen another type of file, with a name ending in `.pyc`, and you may have heard that they're Python "bytecode" files. (These are a bit harder to see on Python 3—instead of ending up in the same directory as your `.py` files, they go into a subdirectory called `__pycache__`.) And maybe you've heard that this is some kind of time-saver that prevents Python from having to re-parse your source code every time it runs. - -But beyond "oh, that's Python bytecode," do you really know what's in those files and how Python uses them? - -If not, today's your lucky day! I'll take you through what Python bytecode is, how Python uses it to execute your code, and how knowing about it can help you. - -### How Python works - -Python is often described as an interpreted language—one in which your source code is translated into native CPU instructions as the program runs—but this is only partially correct. Python, like many interpreted languages, actually compiles source code to a set of instructions for a virtual machine, and the Python interpreter is an implementation of that virtual machine. This intermediate format is called "bytecode." - -So those `.pyc` files Python leaves lying around aren't just some "faster" or "optimized" version of your source code; they're the bytecode instructions that will be executed by Python's virtual machine as your program runs. - -Let's look at an example. Here's a classic "Hello, World!" written in Python: -``` -def hello() - -    print("Hello, World!") - -``` - -And here's the bytecode it turns into (translated into a human-readable form): -``` -2           0 LOAD_GLOBAL              0 (print) - -            2 LOAD_CONST               1 ('Hello, World!') - -            4 CALL_FUNCTION            1 - -``` - -If you type up that `hello()` function and use the [CPython][1] interpreter to run it, the above listing is what Python will execute. It might look a little weird, though, so let's take a deeper look at what's going on. - -### Inside the Python virtual machine - -CPython uses a stack-based virtual machine. That is, it's oriented entirely around stack data structures (where you can "push" an item onto the "top" of the structure, or "pop" an item off the "top"). - -CPython uses three types of stacks: - - 1. The **call stack**. This is the main structure of a running Python program. It has one item—a "frame"—for each currently active function call, with the bottom of the stack being the entry point of the program. Every function call pushes a new frame onto the call stack, and every time a function call returns, its frame is popped off. - 2. In each frame, there's an **evaluation stack** (also called the **data stack** ). This stack is where execution of a Python function occurs, and executing Python code consists mostly of pushing things onto this stack, manipulating them, and popping them back off. - 3. Also in each frame, there's a **block stack**. This is used by Python to keep track of certain types of control structures: loops, `try`/`except` blocks, and `with` blocks all cause entries to be pushed onto the block stack, and the block stack gets popped whenever you exit one of those structures. This helps Python know which blocks are active at any given moment so that, for example, a `continue` or `break` statement can affect the correct block. - - - -Most of Python's bytecode instructions manipulate the evaluation stack of the current call-stack frame, although there are some instructions that do other things (like jump to specific instructions or manipulate the block stack). - -To get a feel for this, suppose we have some code that calls a function, like this: `my_function(my_variable, 2)`. Python will translate this into a sequence of four bytecode instructions: - - 1. A `LOAD_NAME` instruction that looks up the function object `my_function` and pushes it onto the top of the evaluation stack - 2. Another `LOAD_NAME` instruction to look up the variable `my_variable` and push it on top of the evaluation stack - 3. A `LOAD_CONST` instruction to push the literal integer value `2` on top of the evaluation stack - 4. A `CALL_FUNCTION` instruction - - - -The `CALL_FUNCTION` instruction will have an argument of 2, which indicates that Python needs to pop two positional arguments off the top of the stack; then the function to call will be on top, and it can be popped as well (for functions involving keyword arguments, a different instruction—`CALL_FUNCTION_KW`—is used, but with a similar principle of operation, and a third instruction, `CALL_FUNCTION_EX`, is used for function calls that involve argument unpacking with the `*` or `**` operators). Once Python has all that, it will allocate a new frame on the call stack, populate the local variables for the function call, and execute the bytecode of `my_function` inside that frame. Once that's done, the frame will be popped off the call stack, and in the original frame the return value of `my_function` will be pushed on top of the evaluation stack. - -### Accessing and understanding Python bytecode - -If you want to play around with this, the `dis` module in the Python standard library is a huge help; the `dis` module provides a "disassembler" for Python bytecode, making it easy to get a human-readable version and look up the various bytecode instructions. [The documentation for the `dis` module][2] goes over its contents and provides a full list of bytecode instructions along with what they do and what arguments they take. - -For example, to get the bytecode listing for the `hello()` function above, I typed it into a Python interpreter, then ran: -``` -import dis - -dis.dis(hello) - -``` - -The function `dis.dis()` will disassemble a function, method, class, module, compiled Python code object, or string literal containing source code and print a human-readable version. Another handy function in the `dis` module is `distb()`. You can pass it a Python traceback object or call it after an exception has been raised, and it will disassemble the topmost function on the call stack at the time of the exception, print its bytecode, and insert a pointer to the instruction that raised the exception. - -It's also useful to look at the compiled code objects Python builds for every function since executing a function makes use of attributes of those code objects. Here's an example looking at the `hello()` function: -``` ->>> hello.__code__ - -", line 1> - ->>> hello.__code__.co_consts - -(None, 'Hello, World!') - ->>> hello.__code__.co_varnames - -() - ->>> hello.__code__.co_names - -('print',) - -``` - -The code object is accessible as the attribute `__code__` on the function and carries a few important attributes: - - * `co_consts` is a tuple of any literals that occur in the function body - * `co_varnames` is a tuple containing the names of any local variables used in the function body - * `co_names` is a tuple of any non-local names referenced in the function body - - - -Many bytecode instructions—particularly those that load values to be pushed onto the stack or store values in variables and attributes—use indices in these tuples as their arguments. - -So now we can understand the bytecode listing of the `hello()` function: - - 1. `LOAD_GLOBAL 0`: tells Python to look up the global object referenced by the name at index 0 of `co_names` (which is the `print` function) and push it onto the evaluation stack - 2. `LOAD_CONST 1`: takes the literal value at index 1 of `co_consts` and pushes it (the value at index 0 is the literal `None`, which is present in `co_consts` because Python function calls have an implicit return value of `None` if no explicit `return` statement is reached) - 3. `CALL_FUNCTION 1`: tells Python to call a function; it will need to pop one positional argument off the stack, then the new top-of-stack will be the function to call. - - - -The "raw" bytecode—as non-human-readable bytes—is also available on the code object as the attribute `co_code`. You can use the list `dis.opname` to look up the names of bytecode instructions from their decimal byte values if you'd like to try to manually disassemble a function. - -### Putting bytecode to use - -Now that you've read this far, you might be thinking "OK, I guess that's cool, but what's the practical value of knowing this?" Setting aside curiosity for curiosity's sake, understanding Python bytecode is useful in a few ways. - -First, understanding Python's execution model helps you reason about your code. People like to joke about C being a kind of "portable assembler," where you can make good guesses about what machine instructions a particular chunk of C source code will turn into. Understanding bytecode will give you the same ability with Python—if you can anticipate what bytecode your Python source code turns into, you can make better decisions about how to write and optimize it. - -Second, understanding bytecode is a useful way to answer questions about Python. For example, I often see newer Python programmers wondering why certain constructs are faster than others (like why `{}` is faster than `dict()`). Knowing how to access and read Python bytecode lets you work out the answers (try it: `dis.dis("{}")` versus `dis.dis("dict()")`). - -Finally, understanding bytecode and how Python executes it gives a useful perspective on a particular kind of programming that Python programmers don't often engage in: stack-oriented programming. If you've ever used a stack-oriented language like FORTH or Factor, this may be old news, but if you're not familiar with this approach, learning about Python bytecode and understanding how its stack-oriented programming model works is a neat way to broaden your programming knowledge. - -### Further reading - -If you'd like to learn more about Python bytecode, the Python virtual machine, and how they work, I recommend these resources: - - * [Inside the Python Virtual Machine][3] by Obi Ike-Nwosu is a free online book that does a deep dive into the Python interpreter, explaining in detail how Python actually works. - * [A Python Interpreter Written in Python][4] by Allison Kaptur is a tutorial for building a Python bytecode interpreter in—what else—Python itself, and it implements all the machinery to run Python bytecode. - * Finally, the CPython interpreter is open source and you can [read through it on GitHub][1]. The implementation of the bytecode interpreter is in the file `Python/ceval.c`. [Here's that file for the Python 3.6.4 release][5]; the bytecode instructions are handled by the `switch` statement beginning on line 1266. - - - -To learn more, attend James Bennett's talk, [A Bit about Bytes: Understanding Python Bytecode][6], at [PyCon Cleveland 2018][7]. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/4/introduction-python-bytecode - -作者:[James Bennett][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/ubernostrum -[1]:https://github.com/python/cpython -[2]:https://docs.python.org/3/library/dis.html -[3]:https://leanpub.com/insidethepythonvirtualmachine -[4]:http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html -[5]:https://github.com/python/cpython/blob/d48ecebad5ac78a1783e09b0d32c211d9754edf4/Python/ceval.c -[6]:https://us.pycon.org/2018/schedule/presentation/127/ -[7]:https://us.pycon.org/2018/ diff --git a/sources/tech/20180507 4 Firefox extensions to install now.md b/sources/tech/20180507 4 Firefox extensions to install now.md deleted file mode 100644 index 50acaba725..0000000000 --- a/sources/tech/20180507 4 Firefox extensions to install now.md +++ /dev/null @@ -1,78 +0,0 @@ -Translating by MjSeven - - -4 Firefox extensions to install now -====== -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/redpanda_firefox_pet_animal.jpg?itok=aSpKsyna) -As I mentioned in my [original article][1] on Firefox extensions, the web browser has become a critical component of the computing experience for many users. Modern browsers have evolved into powerful and extensible platforms, and extensions can add or modify their functionality. Extensions for Firefox are built using the WebExtensions API, a cross-browser development system. - -In the first article, I asked readers: "Which extensions should you install?" To reiterate, that decision largely comes down to how you use your browser, your views on privacy, how much you trust extension developers, and other personal preferences. Since that article was published, one extension I recommended (Xmarks) has been discontinued. Additionally, that article received a ton of feedback that has been taken into account for this update. - -Once again, I'd like to point out that browser extensions often require the ability to read and/or change everything on the web pages you visit. You should consider the ramifications of this very carefully. If an extension has modify access to all the web pages you visit, it could act as a keylogger, intercept credit card information, track you online, insert advertisements, and perform a variety of other nefarious activities. That doesn't mean every extension will surreptitiously do these things, but you should carefully consider the installation source, the permissions involved, your risk profile, and other factors before you install any extension. Keep in mind you can use profiles to manage how an extension impacts your attack surface—for example, using a dedicated profile with no extensions to perform tasks such as online banking. - -With that in mind, here are four open source Firefox extensions you may want to consider. - -### uBlock Origin - -![ublock origin ad blocker screenshot][2] - -My first recommendation remains unchanged. [uBlock Origin][3] is a fast, low memory, wide-spectrum blocker that allows you to not only block ads but also enforce your own content filtering. The default behavior of uBlock Origin is to block ads, trackers, and malware sites using multiple, predefined filter lists. From there it allows you to arbitrarily add lists and rules, or even lock down to a default-deny mode. Despite being powerful, the extension has proven to be efficient and performant. It continues to be updated regularly and is one of the best options available for this functionality. - -### Privacy Badger - -![privacy badger ad blocker][4] - -My second recommendation also remains unchanged. If anything, privacy has been brought even more to the forefront since my previous article, making this extension an easy recommendation. As the name indicates, [Privacy Badger][5] is a privacy-focused extension that blocks ads and other third-party trackers. It's a project of the Electronic Freedom Foundation, which says: - -> "Privacy Badger was born out of our desire to be able to recommend a single extension that would automatically analyze and block any tracker or ad that violated the principle of user consent; which could function well without any settings, knowledge, or configuration by the user; which is produced by an organization that is unambiguously working for its users rather than for advertisers; and which uses algorithmic methods to decide what is and isn't tracking." - -Why is Privacy Badger on this list when the previous item may seem similar? A couple reasons. The first is that it fundamentally works differently than uBlock Origin. The second is that a practice of defense in depth is a sound policy to follow. Speaking of defense in depth, the EFF also maintains [HTTPS Everywhere][6] to automatically ensure https is used for many major websites. When you're installing Privacy Badger, you may want to consider HTTPS Everywhere as well. - -In case you were starting to think this article was simply going to be a rehash of the last one, here's where my recommendations diverge. - -### Bitwarden - -![Bitwarden][7] - -When recommending LastPass in the previous article, I mentioned it was likely going to be a controversial selection. That certainly proved true. Whether you should use a password manager at all—and if you do, whether you should choose one that has a browser plugin—is a hotly debated topic, and the answer very much depends on your personal risk profile. I asserted that most casual computer users should use one because it's much better than the most common alternative: using the same weak password everywhere. I still believe that. - -[Bitwarden][8] has really matured since the last time I checked it out. Like LastPass, it is user-friendly, supports two-factor authentication, and is reasonably secure. Unlike LastPass, it is [open source][9]. It can be used with or without the browser plugin and supports importing from other solutions including LastPass. The core functionality is completely free, and there is a premium version that is $10/year. - -### Vimium-FF - -![Vimium][10] - -[Vimium][11] is another open source extension that provides Firefox keyboard shortcuts for navigation and control in the spirit of Vim. They call it "The Hacker's Browser." Modifier keys are specified as **< c-x>**, **< m-x>**, and **< a-x>** for Ctrl+x, Meta+x, and Alt+x, respectively, and the defaults can be easily customized. Once you have Vimium installed, you can see this list of key bindings at any time by typing **?**. Note that if you prefer Emacs, there are also a couple of extensions for those keybindings as well. Either way, I think keyboard shortcuts are an underutilized productivity booster. - -### Bonus: Grammarly - -Not everyone is lucky enough to write a column on Opensource.com—although you should seriously consider writing for the site; if you have questions, are interested, or would like a mentor, reach out and let's chat. But even without a column to write, proper grammar is beneficial in a large variety of situations. Enter [Grammarly][12]. This extension is not open source, unfortunately, but it does make sure everything you type is clear, effective, and mistake-free. It does this by scanning your text for common and complex grammatical mistakes, spanning everything from subject-verb agreement to article use to modifier placement. Basic functionality is free, with a premium version with additional checks available for a monthly charge. I used it for this article and it caught multiple errors that my proofreading didn't. - -Again, Grammarly is the only extension included on this list that is not open source, so if you know of a similar high-quality open source replacement, let us know in the comments. - -These extensions are ones I've found useful and recommend to others. Let me know in the comments what you think of the updated recommendations. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/5/firefox-extensions - -作者:[Jeremy Garcia][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/jeremy-garcia -[1]:https://opensource.com/article/18/1/top-5-firefox-extensions -[2]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/ublock.png?itok=_QFEbDmq (ublock origin ad blocker screenshot) -[3]:https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/ -[4]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/privacy_badger_1.0.1.png?itok=qZXQeKtc (privacy badger ad blocker screenshot) -[5]:https://www.eff.org/privacybadger -[6]:https://www.eff.org/https-everywhere -[7]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/bitwarden.png?itok=gZPrCYoi (Bitwarden) -[8]:https://bitwarden.com/ -[9]:https://github.com/bitwarden -[10]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/vimium.png?itok=QRESXjWG (Vimium) -[11]:https://addons.mozilla.org/en-US/firefox/addon/vimium-ff/ -[12]:https://www.grammarly.com/ diff --git a/sources/tech/20180517 What You Need to Know About Cryptocurrency Malware Found on Ubuntus Snap Store.md b/sources/tech/20180517 What You Need to Know About Cryptocurrency Malware Found on Ubuntus Snap Store.md deleted file mode 100644 index dae40507ac..0000000000 --- a/sources/tech/20180517 What You Need to Know About Cryptocurrency Malware Found on Ubuntus Snap Store.md +++ /dev/null @@ -1,107 +0,0 @@ -What You Need to Know About Cryptocurrency ‘Malware’ Found on Ubuntu’s Snap Store -====== -Recently, it was discovered that a couple of apps in the Ubuntu Snaps store contained cryptocurrency mining software. Canonical swiftly removed the offending apps, but several questions are left unanswered. - -### Discovery of Crypto Miner on Snap Store - -![Crypto Miner Malware on Ubuntu Snap Store][1] - -On May 11, a user named [tarwirdur][2] opened a new issue on the [snapcraft.io repository][3]. In the issue, he noted that a snap entitled 2048buntu created by Nicolas Tomb contained a cryptocurrency miner. He asked how he could “complain about the application” for security reasons. tarwirdur later posted to say that all the others snaps created by Nicolas Tomb also contained cryptocurrency miners. - -It appears that the snaps used systemd to automatically launch the code at boot and run it in the background with the user none the wiser. - -{For those unfamiliar with the terminology, a cryptocurrency miner is a piece of software that uses a computer’s main processor or graphics processor to “mine” digital currency. “Mining” usually involves solving a mathematical equation. In this case, if you were running the 2048buntu game, the game used additional processing power for cryptocurrency mining.} - -The Snapcraft team responded by quickly removing all apps created by the offender. They also started an investigation. - -### The Man Behind the Mask Speaks - -On May 13, a Disqus user named Nicolas Tomb [posted a comment][4] on OMGUbuntu’s coverage of the news. In this comment, he stated that he added the cryptocurrency miner to monetize the snaps. He apologized for his actions and promised to send any funds that had been mined to the Ubuntu foundation. - -We can’t say for sure if this comment was posted by the same Nicolas Tomb since the Disqus account was just recently created and only has one comment associated with it. For now, we’ll assume that it is. - -### Canonical Makes a Statement - -On May 15, Canonical issued a statement on the situation. Entitled [“Trust and security in the Snap Store”][5], the post starts out by restating the situation. They add that the snaps have been [reissued with the cryptocurrency mining code removed][6]. - -Canonical then attempts to examine the motives of Nicolas Tomb. They note that he told them he did it in an attempt to monetize the apps (as stated above) and stopped doing it when confronted. They also note that “mining cryptocurrency is not illegal or unethical by itself”. They are however unhappy about the fact that he did not disclose the cryptocurrency miner in the snap description. - -From there Canonical moves to the subject of reviewing software. According to the post, the Snap Store uses a quality control system similar to iOS, Android, and Windows: “automated checkpoints that packages must go through before they are accepted, and manual reviews by a human when specific issues are flagged”. - -However, Canonical says “it’s impossible for a large scale repository to only accept software after every individual file has been reviewed in detail”. Therefore, they need to trust the source, not the content. After all, that is what the current Ubuntu repo system is based on. - -Canonical follows this up by talking about the future of snaps. They acknowledge that the current system is not perfect. They are continually working to improve it. They have “very interesting security features in the works that will improve the safety of the system and also the experience of people handling software deployments in servers and desktops”. - -One of the features they are working on is the ability to see if a publisher is verified. Other improvements include: “upstreaming of all the AppArmor kernel patches” and other under-the-hood fixes. - -### Thoughts on the ‘Snap store malware’ - -Based on all that I’ve read, I’ve got a few thoughts and questions of my own. - -#### How Long Was This Running? - -First of all, how long have these mining snaps been available on the Snap Store? Since they have all been removed, we don’t have that data. I was able to grab an image of the 2048buntu page from the Google cache, but it doesn’t show much of anything. Depending on how long it ran, how many systems it got installed on, and what cryptocurrency was being mined, we could either be talks about a little bit of money or a pile. A further question is: would Canonical have been able to catch this in the future? - -#### Was it Really a Malware? - -A lot of news sites are reporting this as a malware infection. I think I might have even seen this incident referred to as Linux’s first malware. I’m not sure that term is accurate. Dictionary.com defines [malware][7] as: “software intended to damage a computer, mobile device, computer system, or computer network, or to take partial control over its operation”. - -The snaps in question did not damage or take control of the computers involved. it also did not infect other computers. It couldn’t have because all snaps are sandboxed. At the most, they leached processor power, that’s about it. So, I wouldn’t call it malware. - -#### Nothing Like a Loophole - -The one defense that Nicolas Tomb uses is that the Snap Store didn’t have any rules against cryptocurrency mining when he uploaded the snaps. {I can bet you that they are rectifying that problem right now.} They didn’t have that rule for the simple reason that no one had done it before. If Tomb was trying to do things correctly, he should have asked if this kind of behavior was allowed. The fact that he didn’t seems to point to the fact that he knew they would probably say no. At the very least, they would have told him to put it in the description. - -![][8] - -#### Something Looks Hinkey - -As I said before, I got a screenshot of the 2048buntu page from Google cache. Just looking at it raises several red flags. First, there is almost no real description. This is all it says “Game like 2048. This game is clone popular game – 2048 with ubuntu colors.” Wow. {That’ll bring in the suckers.} When I read something as empty as that, I get nervous. - -Another thing to notice is the size of it. Version 1.0 of the 2048buntu snap weighs almost 140 MB. Why would a game this simple need that much space? There are browser versions written in Javascript that probably use less than a quarter of that. There other snaps of 2048 games on the Snap Store and none of them has half the file size. - -Then, you have the license. This is a clone of a popular game using Ubuntu colors. How can it be considered proprietary? I’m sure that legit devs in the audience would have uploaded it with a FOSS (Free and Open Source Software) license just because of the content. - -These factors alone should have made this snap, in particular, stand out and call for a review. - -#### Who is Nicolas Tomb? - -After first reading about this, I decided to see what I could find out about the guy who started this mess. When I searched for Nicolas Tomb, I found nothing, zip, nada, zilch. All I found were a bunch of news articles about the cryptocurrency mining snaps and information about taking a trip to the tomb of St. Nicolas. There is no sign of Nicolas Tomb on Twitter or Github either. This seems like a name created just to upload these snaps. - -This also leads to a point in the Canonical blog post about verifying publishers. The last time I looked, quite a few snaps were not published by the maintainers of the applications. This makes me nervous. I would be more willing to trust a snap of say Firefox if it was published by Mozilla, instead of Leonard Borsch. If it’s too much work for the application maintainer to also take care of the snap, there should be a way for the maintainer to put their stamp of approval on the snap for their program. Something like Firefox snap published by Fredrick Ham, approved by Mozilla Foundation. Just something to give the user more confidence in what they are downloading. - -#### Snap Store Definitely has Room to Improve - -It seems to me that one of the first features that the Snap Store team should have implemented was a way to report suspicious snaps. tarwirdur had to find the site’s Github page. The average user would not have thought of that. If the Snap Store can’t review every line of code, enabling the users to reports problems is the next best thing. Even rating system would not be a bad addition. I’m sure there would have been a couple people who would have given 2048buntu a low rating for using too many system resources. - -#### Conclusion - -From all the I have seen, I think that someone created a number of simple apps, embedded a cryptocurrency miner in each, and uploaded them to the Snap Store with the goal of raking in piles of money. Once they got caught, they claimed it was only to monetize the snaps. If that was true, they would have mentioned it in the snap description. Hidden crypto miners are nothing [new][9]. They are generally a method of computing power theft. - -I wish that Canonical already have features in place to combat this problem and I hope they appear quickly. - -What do you think of the Snap Store ‘malware episode’? What would you do to improve it? Let us know in the comments below. - -If you found this article interesting, please take a minute to share it on social media. - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/snapstore-cryptocurrency-saga/ - -作者:[John Paul][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://itsfoss.com/author/john/ -[1]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/ubuntu-snap-malware-800x450.jpeg -[2]:https://github.com/tarwirdur -[3]:https://github.com/canonical-websites/snapcraft.io/issues/651 -[4]:https://disqus.com/home/discussion/omgubuntu/malware_found_on_the_ubuntu_snap_store/#comment-3899153046 -[5]:https://blog.ubuntu.com/2018/05/15/trust-and-security-in-the-snap-store -[6]:https://forum.snapcraft.io/t/action-against-snap-store-malware/5417/8 -[7]:http://www.dictionary.com/browse/malware?s=t -[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/2048buntu.png -[9]:https://krebsonsecurity.com/2018/03/who-and-what-is-coinhive/ diff --git a/sources/tech/20180521 How to Install and Configure KVM on Ubuntu 18.04 LTS Server.md b/sources/tech/20180521 How to Install and Configure KVM on Ubuntu 18.04 LTS Server.md index 051ca46bc1..34e2527b4f 100644 --- a/sources/tech/20180521 How to Install and Configure KVM on Ubuntu 18.04 LTS Server.md +++ b/sources/tech/20180521 How to Install and Configure KVM on Ubuntu 18.04 LTS Server.md @@ -1,3 +1,4 @@ +translating by wyxplus How to Install and Configure KVM on Ubuntu 18.04 LTS Server ====== **KVM** (Kernel-based Virtual Machine) is an open source full virtualization solution for Linux like systems, KVM provides virtualization functionality using the virtualization extensions like **Intel VT** or **AMD-V**. Whenever we install KVM on any linux box then it turns it into the hyervisor by loading the kernel modules like **kvm-intel.ko** ( for intel based machines) and **kvm-amd.ko** ( for amd based machines). diff --git a/translated/talk/20180107 7 leadership rules for the DevOps age.md b/translated/talk/20180107 7 leadership rules for the DevOps age.md new file mode 100644 index 0000000000..587d7761fb --- /dev/null +++ b/translated/talk/20180107 7 leadership rules for the DevOps age.md @@ -0,0 +1,119 @@ +DevOps时代的7个领导准则 +====== + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/CIO_DigitalAcumen_2.png?itok=TGeMQYs4) + +如果[DevOps]最终更多的是关于文化而不是任何其他的技术或者平台,那么请记住:没有终点线。而是继续改变和提高--而且最高管理层并没有通过。 + +然而,如果期望DevOps能够帮助获得更多的成果,领导者需要[修订他们的一些传统的方法][2]让我们考虑7个在DevOps时代更有效的IT领导的想法。 + +### 1. 向失败说“是的” + +“失败”这个词在IT领域中一直包含着特殊的内涵,而且通常是糟糕的意思:服务器失败,备份失败,硬盘驱动器失败-你得了解这些情况。 + +然而一种健康的DevOps文化取决于重新定义失败-IT领导者在他们的字典里应该重新定义这个单词将它的含义和“机会”对等起来。 + +“在DevOps之前,我们曾有一种惩罚失败者的文化,”罗伯特·里夫斯说,[Datical][3]的首席技术官兼联合创始人。“我们学到的仅仅是去避免错误。在IT领域避免错误的首要措施就是不要去改变任何东西:不要加速版本迭代的日程,不要迁移到云中,不要去做任何不同的事” + +那是过去的一个时代的剧本,里夫斯坦诚的说,它已经不起作用了,事实上,那种停滞是失败的。 + +“那些缓慢的释放并逃避云的公司被恐惧所麻痹-他们将会走向失败,”里夫斯说道。“IT领导者必须拥抱失败并把它当做成一个机遇。人们不仅仅从他们的过错中学习,也会从其他的错误中学习。一种开放和[安全心里][4]的文化促进学习和提高” +**[相关文章:[为什么敏捷领导者谈论“失败”必须超越它本义]] +### 2. 在管理层渗透开发运营的理念 + +尽管DevOps文化可以在各个方向有机的发展,那些正在从整体中转变,孤立的IT实践,而且可能遭遇逆风的公司-需要执行领导层的全面支持。你正在传达模糊的信息 +而且可能会鼓励那些愿意推一把的人,这是我们一贯的做事方式。[改变文化是困难的][6];人们需要看到领导层完全投入进去并且知道改变已经实际发生了。 + +“为了成功的实现利益的兑现高层管理必须全力支持DevOps,”来自[Rainforest QA][7]的首席技术官说道。 + +成为一个DevOps商店。德里克指出,涉及到公司的一切,从技术团队到工具到进程到规则和责任。 + +"没有高层管理的统一赞助支持,DevOps的实施将很难成功,"德里克说道。"因此,在转变到DevOps之前在高层中有支持的领导同盟是很重要的。" + +### 3. 不要只是声明“DevOps”-要明确它 +即使IT公司也已经开始拥抱欢迎DevOps,每个人可能不是在同一个进程上。 +**[参考我们的相关文章,**][**3 阐明了DevOps和首席技术官们必须在同一进程上**][8] **.]** + +造成这种脱节的一个根本原因是:人们对这个术语的有着不同的定义理解。 + +“DevOps 对不同的人可能意味着不同的含义,”德里克解释道。“对高管层和副总裁层来说,执行明确的DevOps的目标,清楚的声明期望的成果,充分理解带来的成果将如何使公司的商业受益并且能够衡量和报告成功的过程。” + +事实上,在基线和视野之上,DevOps要求正在进行频繁的交流,不是仅仅在小团队里,而是要贯穿到整个组织。IT领导者必须为它设置优先级。 + +“不可避免的,将会有些阻碍,在商业中将会存在失败和破坏,”德里克说道。“领导者名需要清楚的将这个过程向公司的其他人阐述清楚告诉他们他们作为这个过程的一份子能够期待的结果。” + +### 4. DevOps和技术同样重要 + +IT领导者们成功的将DevOps商店的这种文化和实践当做一项商业策略,与构建和运营软件的方法相结合。DevOps是将IT从支持部门转向战略部门的推动力。 + +IT领导者们必须转变他们的思想和方法,从成本和服务中心转变到驱动商业成果,而且DevOps的文化能够通过自动化和强大的协作加速收益。来自[CYBRIC][9]的首席技术官和联合创始人迈克说道。 + +事实上,这是一个强烈的趋势通过更多的这些规则在DevOps时代走在前沿。 + +“促进创新并且鼓励团队成员去聪明的冒险是DevOps文化的一个关键部分,IT领导者们需要在一个持续的基础上清楚的和他们交流,”凯尔说道。 + +“一个高效的IT领导者需要比以往任何时候都要积极的参与到商业中去,”来自[West Monroe Partners][10]的性能服务部门的主任埃文说道。“每年或季度回顾的日子一去不复返了-你需要欢迎每两周一次的待办事项。[11]你需要有在年度水平上的思考战略能力,在冲刺阶段的互动能力,在商业期望满足时将会被给予一定的奖励。” + +### 5. 改变妨碍DevOps目标的任何事情 + +虽然DevOps的老兵们普遍认为DevOps更多的是一种文化而不是技术,成功取决于通过正确的过程和工具激活文化。当你声称自己的部门是一个DevOps商店却拒绝对进程或技术做必要的改变,这就是你买了辆法拉利却使用了用过20年的引擎,每次转动钥匙都会冒烟。 + +展览 A: [自动化][12].这是DevOps成功的重要并行策略。 + +“IT领导者需要重点强调自动化,”卡伦德说。“这将是DevOps的前期投资,但是如果没有它,DevOps将会很容易被低效吞噬自己而且将会无法完整交付。” + +自动化是基石,但改变不止于此。 + +“领导者们需要推动自动化,监控和持续的交付过程。这意着对现有的实践,过程,团队架构以及规则的很多改变,”Choy说。“领导者们需要改变一切会阻碍隐藏团队去全利实现自动化的因素。” + +### 6. 重新思考团队架构和能力指标 + +当你想改变时...如果你桌面上的组织结构图和你过去大部分时候嵌入的名字都是一样的,那么你是时候该考虑改革了。 + +“在这个DevOps的新时代文化中,IT执行者需要采取一个全新的方法来组织架构。”Kail说。“消除组织的边界限制,它会阻碍团队间的合作,允许团队自我组织,敏捷管理。” + +Kail告诉我们在DevOps时代,这种反思也应该拓展应用到其他领域,包括你怎样衡量个人或者团队的成功,甚至是你和人们的互动。 + +“根据业务成果和总体的积极影响来衡量主动性,”Kail建议。“最后,我认为管理中最重要的一个方面是:有同理心。” + +注意很容易收集的到测量值不是DevOps真正的指标,[Red Hat]的技术专员Gardon Half写到,“DevOps应该把指标以某种形式和商业成果绑定在一起,”他指出。“你可能真的不在乎开发者些了多少代码,是否有一台服务器在深夜硬件损坏,或者是你的测试是多么的全面。你甚至都不直接关注你的网站的响应情况或者是你更新的速度。但是你要注意的是这些指标可能和顾客放弃购物车去竞争对手那里有关,”参考他的文章,[DevOps 指标:你在测量什么?] + +### 7. 丢弃传统的智慧 + +如果DevOps时代要求关于IT领导能力的新的思考方式,那么也就意味着一些旧的方法要被淘汰。但是是哪些呢? + +“是实话,是全部,”Kail说道。“要摆脱‘因为我们一直都是以这种方法做事的’的心态。过渡到DevOps文化是一种彻底的思维模式的转变,不是对瀑布式的过去和变革委员会的一些细微改变。” + +事实上,IT领导者们认识到真正的变革要求的不只是对旧方法的小小接触。它更多的是要求对之前的进程或者策略的一个重新启动。 + +West Monroe Partners的卡伦德分享了一个阻碍DevOps的领导力的例子:未能拥抱IT混合模型和现代的基础架构比如说容器和微服务 + +“我所看到的一个大的规则就是架构整合,或者认为在一个同质的环境下长期的维护会更便宜,”卡伦德说。 + +**想要更多像这样的智慧吗?[注册我们的每周邮件新闻报道][15].** +-------------------------------------------------------------------------------- + +via: https://enterprisersproject.com/article/2018/1/7-leadership-rules-devops-age + +作者:[Kevin Casey][a] +译者:[译者FelixYFZ](https://github.com/FelixYFZ) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://enterprisersproject.com/user/kevin-casey +[1]:https://enterprisersproject.com/tags/devops +[2]:https://enterprisersproject.com/article/2017/7/devops-requires-dumping-old-it-leadership-ideas +[3]:https://www.datical.com/ +[4]:https://rework.withgoogle.com/guides/understanding-team-effectiveness/steps/foster-psychological-safety/ +[5]:https://enterprisersproject.com/article/2017/10/why-agile-leaders-must-move-beyond-talking-about-failure?sc_cid=70160000000h0aXAAQ +[6]:https://enterprisersproject.com/article/2017/10/how-beat-fear-and-loathing-it-change +[7]:https://www.rainforestqa.com/ +[8]:https://enterprisersproject.com/article/2018/1/3-areas-where-devops-and-cios-must-get-same-page +[9]:https://www.cybric.io/ +[10]:http://www.westmonroepartners.com/ +[11]:https://www.scrumalliance.org/community/articles/2017/february/product-backlog-grooming +[12]:https://www.redhat.com/en/topics/automation?intcmp=701f2000000tjyaAAA +[13]:https://www.redhat.com/en?intcmp=701f2000000tjyaAAA +[14]:https://enterprisersproject.com/article/2017/7/devops-metrics-are-you-measuring-what-matters +[15]:https://enterprisersproject.com/email-newsletter?intcmp=701f2000000tsjPAAQ diff --git a/translated/tech/20171121 How To Kill The Largest Process In An Unresponsive Linux System.md b/translated/tech/20171121 How To Kill The Largest Process In An Unresponsive Linux System.md new file mode 100644 index 0000000000..042cd39684 --- /dev/null +++ b/translated/tech/20171121 How To Kill The Largest Process In An Unresponsive Linux System.md @@ -0,0 +1,138 @@ +如何在无响应的 Linux 系统中杀掉最大的进程 +====== +![](https://www.ostechnix.com/wp-content/uploads/2017/11/Kill-The-Largest-Process-720x340.png) + +作为一名博客作者,我收藏了很多博客、网站和论坛用来标记 Linux 和 Unix 相关的内容。有时候,我在浏览器中开启了非常多的标签页,导致操作系统会无响应好几分钟。我不能移动我的鼠标去杀掉一个进程或关闭任何开启的标签页。在这种情况下,我别无选择,只能强制重启系统。当然我也用了 **OneTab** (译者注:OneTab 是一个 Chrome 的 Extension, 可以将标签页转化成一个列表保存。)和 **Greate Suspender** (译者注:Great Suspender 是一个 Chrome 的 Extension, 可以自动冻结标签页)这样浏览器拓展,但它们在这里也起不到太大的作用。 我经常耗尽我的内存。而这就是 **Early OOM** 起作用的时候了。在情况严重,它会杀掉一个未响应系统中的最大的进程。Early OOM 每秒会检测可用内存和空余交换区 10 次,一旦两者都低于 10%,它就会把最大的进程杀死。 + +### 为什么用 Early OOM?为什么不用系统内置的 OOM killer? + +在继续讨论下去之前,我想先简短的介绍下 OOM killer,也就是 **O** ut **O** f **M** emory killer。OOM killer 是一个由内核在可用内存非常低的时候使用的进程。它的主要任务是不断的杀死进程,直到释放出足够的内存,是内核正在运行的进程的其余部分能顺利运行。OOM killer 会找到系统中最不重要并且能释放出最多内存的进程,然后杀掉他们。在 **/proc** 目录下的 **pid** 目录中,我们可以看到每个进程的 oom_score。 + +示例: +``` +$ cat /proc/10299/oom_score +1 +``` + +一个进程的 oom_score 的值越高,这个进程越有可能在系统内存耗尽的时候被 OOM killer 杀死。 + +Early OOM 的开发者表示,相对于内置的 OOM killer,Early OOM 有一个很大的优点。就像我之前说的那样,OOM killer 会杀掉 oom_score 最高的进程,而这也导致 Chrome 浏览器总是会成为第一个被杀死的进程。为了避免这种情况发生,Early OOM 使用 **/proc/*/status** 而不是 **echo f > /proc/sysrq-trigger**(译者注:这条命令会调用 OOM killer 杀死进程)。开发者还表示,手动触发 OOM killer 在最新版本的 Linux 内核中很可能不会起作用。 + +### 安装 Early OOM + +Early OOM 在AUR(Arch User Repository)中可以被找到,所以你可以在 Arch 和它的衍生版本中使用任何 AUR 工具安装它。 + +使用 [**Pacaur**][1]: +``` +pacaur -S earlyoom +``` + +使用 [**Packer**][2]: +``` +packer -S earlyoom +``` + +使用 [**Yaourt**][3]: +``` +yaourt -S earlyoom +``` + +启用并启动 Early OOM daemon: +``` +sudo systemctl enable earlyoom +``` +``` +sudo systemctl start earlyoom +``` + +在其它的 Linux 发行版中,可以按如下方法编译安装它 +``` +git clone https://github.com/rfjakob/earlyoom.git +cd earlyoom +make +sudo make install +``` + +### Early OOM - Kill The Largest Process In An Unresponsive Linux System杀掉无响应 Linux 系统中的最大的进程 + +运行如下命令启动 Early OOM: +``` +earlyoom +``` + +如果是通过编译源代码安装的, 运行如下命令启动 Early OOM: +``` +./earlyoom +``` + +示例输出: +``` +earlyoom 0.12 +mem total: 3863 MiB, min: 386 MiB (10 %) +swap total: 2047 MiB, min: 204 MiB (10 %) +mem avail: 1770 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1771 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %) +mem avail: 1784 MiB (46 %), swap free: 2047 MiB (99 %) +[...] +``` + +就像你在上面的输出中可以看到的,Early OOM 将会显示你有多少内存和交换区,以及有多少可用的内存和交换区。记住它会一直保持运行,直到你按下 CTRL+C。 + +如果可用的内存和交换区大小都低于 10%,Early OOM 将会自动杀死最大的进程,直到系统有足够的内存可以流畅的运行。你也可以根据你的需求配置最小百分比值。 + +设置最小的可用内存百分比,运行: +``` +earlyoom -m +``` + +设置最小可用交换区百分比, 运行: +``` +earlyoom -s +``` + +在帮助部分,可以看到更多详细信息: +``` +$ earlyoom -h +earlyoom 0.12 +Usage: earlyoom [OPTION]... + + -m PERCENT set available memory minimum to PERCENT of total (default 10 %) + -s PERCENT set free swap minimum to PERCENT of total (default 10 %) + -M SIZE set available memory minimum to SIZE KiB + -S SIZE set free swap minimum to SIZE KiB + -k use kernel oom killer instead of own user-space implementation + -i user-space oom killer should ignore positive oom_score_adj values + -d enable debugging messages + -v print version information and exit + -r INTERVAL memory report interval in seconds (default 1), set to 0 to + disable completely + -p set niceness of earlyoom to -20 and oom_score_adj to -1000 + -h this help text +``` + +现在,你再也不用担心内存消耗最高的进程了。希望这能给你帮助。更多的好内容将会到来,敬请期待。 + +谢谢! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/kill-largest-process-unresponsive-linux-system/ + +作者:[Aditya Goturu][a] +译者:[cizezsy](https://github.com/cizezsy) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com +[1]:https://www.ostechnix.com/install-pacaur-arch-linux/ +[2]:https://www.ostechnix.com/install-packer-arch-linux-2/ +[3]:https://www.ostechnix.com/install-yaourt-arch-linux/ diff --git a/sources/tech/20180406 How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN).md b/translated/tech/20180406 How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN).md similarity index 75% rename from sources/tech/20180406 How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN).md rename to translated/tech/20180406 How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN).md index 34e6c36401..92c8407884 100644 --- a/sources/tech/20180406 How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN).md +++ b/translated/tech/20180406 How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN).md @@ -1,58 +1,57 @@ -Translating by qhwdw -How To Register The Oracle Linux System With The Unbreakable Linux Network (ULN) +Oracle Linux 系统如何去注册使用坚不可摧 Linux 网络(ULN) ====== -Most of us knows about RHEL subscription but only few of them knows about Oracle subscription and its details. +大多数人都知道 RHEL 的订阅 ,但是知道 Oracle 订阅及细节的人却很少。 -Even i don’t know the information about this and i recently came to know about this and wants to share this with others so, i’m going to write a article which will guide you to register the Oracle Linux system with the Unbreakable Linux Network (ULN). +甚至我也不知道关于它的信息,我是最近才了解了有关它的信息,想将这些内容共享给其他人。因此写了这篇文章,它将指导你去注册 Oracle Linux 系统去使用坚不可摧 Linux 网络(ULN) 。 -This allows the register systems to get software update and other patches ASAP. +这将允许你去注册系统以获得软件更新和其它的 ASAP 补丁。 -### What Is Unbreakable Linux Network +### 什么是坚不可摧 Linux 网络 -ULN stands for Unbreakable Linux Network which is owned by Oracle. If you have a active subscription to Oracle OS Support, you can register your system with Unbreakable Linux Network (ULN). +ULN 代表坚不可摧 Linux 网络,它是由 Oracle 所拥有的。如果你去 Oracle OS 支持中去激活这个订阅,你就可以注册你的系统去使用坚不可摧 Linux 网络(ULN)。 -ULN offers software patches, updates, and fixes for Oracle Linux and Oracle VM, as well as information on yum, Ksplice, and support policies. You can also download useful packages that are not included in the original distribution. +ULN 为 Oracle Linux 和 Oracle VM 提供软件补丁、更新、以及修复,此外还有在 yum、Ksplice、以及支持策略上的信息。你也可以通过它来下载原始发行版中没有包含的有用的安装包。 -The ULN Alert Notification Tool periodically checks with ULN and alerts you when updates are available. +ULN 的告警提示工具周期性地使用 ULN 去检查,当有更新的时候它给你发送警报信息。 -If you want to use ULN repository with yum to manage your systems, make sure your system should registered with ULN and subscribe each system to one or more ULN channels. When you register a system with ULN, automatically it will choose latest version of channel based on the system architecture and OS. +如果你想在 yum 上使用 ULN 仓库去管理你的系统,需要确保你的系统已经注册到 ULN 上,并且订阅了一个或多个 ULN 频道。当你注册一个系统使用 ULN,它将基于你的系统架构和操作系统去自动选择频道中最新的版本。 -### How To Register As A ULN User +### 如何注册为一个 ULN 用户 -To register as a ULN user, make sure you have a valid customer support identifier (CSI) for Oracle Linux support or Oracle VM support. +去注册为一个 ULN 用户,需要你有一个 Oracle Linux 支持或者 Oracle VM 支持的有效客户支持代码(CSI)。 -Follow the below steps to register as a ULN user. +请按以下步骤去注册为一个 ULN 用户。 -Visit @ [linux.oracle.com][1] +请访问 [linux.oracle.com][1] ![][3] -If you already have an SSO account, click Sign On. +如果你已经有一个 SSO 帐户,请点击 “Sign On”。 ![][4] -If you don’t have a account, click Create New Single Signon Account and follow the onscreen instructions to create one. +如果你没有帐户,点击 “Create New Single Signon Account” 然后按屏幕上的要求去创建一个帐户。 ![][5] -Verify your email address to complete your account setup. +验证你的电子邮件地址以完成帐户设置。 -Log in using your SSO user name and password. On the Create New ULN User page, enter your CSI and click Create New User. +使用你的 SSO 帐户的用户名和密码去登入。在 “Create New ULN User” 页面上,输入你的 CSI 然后点击 “Create New User”。 ![][6] -**Note :** +**注意:** - * If no administrator is currently assigned to manage the CSI, you are prompted to click Confirm to become the CSI administrator. - * If your user name already exists on the system, you are prompted to proceed to ULN by clicking the link Unbreakable Linux Network. + * 如果当前没有分配管理员去管理 CSI,将会提示你去点击确认让你成为 CSI 管理员。 + * 如果你的用户名已经在系统上存在,你将被提示通过点击坚不可摧 Linux 网络的链接去操作 ULN。 -### How To Register The Oracle Linux 6/7 System With ULN +### 如何注册 Oracle Linux 6/7 系统使用 ULN -Just run the below command and follow the instruction to register the system. +只需要运行下列的命令,并按随后的指令提示去注册系统。 ``` # uln_register ``` -Make sure your system is having active internet connection. Also keep ready your Oracle Single Sign-On Login & password (SSO) details then hit `Next`. +确保你的系统有一个活动的因特网连接。同时准备好你的 Oracle 单点登陆帐户(SSO)的用户名和密码,然后点击 `Next`。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -78,7 +77,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -Input your login information for Unbreakable Linux Network, then hit `Next`. +输入你的 ULN 登陆信息,然后点击 `Next`。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -101,7 +100,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -Register a System Profile – Hardware information, then hit `Next`. +注册一个系统概要 – 硬件信息,然后点击 `Next`。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -130,7 +129,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -Register a System Profile – Packages configuration, then hit `Next`. +注册一个系统概要 – 包配置,然后点击 `Next`。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -168,7 +167,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -Press “Next” to send this System Profile to Unbreakable Linux Network. +按下 “Next” 去发送系统概要到 ULN。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -188,7 +187,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -Sending Profile to Unbreakable Linux Network is under processing. +发送概要到 ULN 是如下的一个过程。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -202,7 +201,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -ULN registration has been done and review system subscription details. If everything is fine, then hit `ok`. +ULN 注册做完后,重新回顾系统订阅的详细情况。如果一切正确,然后点击 `ok`。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -237,7 +236,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -Finally hit `Finish` to complete the registration. +最后点击 `Finish` 完成注册。 ``` Copyright © 2006--2010 Red Hat, Inc. All rights reserved. @@ -256,7 +255,7 @@ Copyright © 2006--2010 Red Hat, Inc. All rights reserved. ``` -ULN registration has been done successfully, in order to get repository from ULN run the following command. +ULN 注册已经成功,为了从 ULN 中得到仓库,运行如下的命令。 ``` # yum repolist Loaded plugins: aliases, changelog, presto, refresh-packagekit, rhnplugin, security, tmprepo, ulninfo, verify, versionlock @@ -271,13 +270,13 @@ repolist: 40,966 ``` -Also, you can check the same in ULN website. Go to the `System` tab to view the list of registered systems. +另外,你也可以在 ULN 网站上查看到相同的信息。转到 `System` 标签页去查看已注册的系统列表。 ![][7] -To view list of the enabled repositories. Go to the `System` tab then hit the corresponding system. Also, you can able to see the available updates for the system for errata. +去查看已经启用的仓库列表。转到 `System` 标签页,然后点击相应的系统。另外,你也能够看到系统勘误及可用更新。 ![][8] -To manage subscription channel. Go to the `System` tab, then hit appropriate `system name` and finally hit `Manage Subscriptions`. +去管理订阅的频道。转到 `System` 标签页,然后点击有关的 `system name`,最后点击 `Manage Subscriptions`。 ![][9] -------------------------------------------------------------------------------- @@ -285,7 +284,7 @@ To manage subscription channel. Go to the `System` tab, then hit appropriate `sy via: https://www.2daygeek.com/how-to-register-the-oracle-linux-system-with-the-unbreakable-linux-network-uln/ 作者:[Vinoth Kumar][a] -译者:[译者ID](https://github.com/译者ID) +译者:[qhwdw](https://github.com/qhwdw) 校对:[校对者ID](https://github.com/校对者ID) 选题:[lujun9972](https://github.com/lujun9972) diff --git a/translated/tech/20180423 An introduction to Python bytecode.md b/translated/tech/20180423 An introduction to Python bytecode.md new file mode 100644 index 0000000000..c27346bc91 --- /dev/null +++ b/translated/tech/20180423 An introduction to Python bytecode.md @@ -0,0 +1,155 @@ +Python 字节码介绍 +====== +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82) +如果你从没有写过 Python,或者甚至只是使用过 Python,你或许已经习惯于看 Python 源代码文件;它们的名字以 `.py` 结尾。你可能还看到过其它类型的文件,比如使用 `.pyc` 结尾的文件,或许你可能听说过,它们就是 Python 的 "字节码" 文件。(在 Python 3 上这些可能不容易看到 — 因为它们与你的 `.py` 文件不在同一个目录下,它们在一个叫 `__pycache__` 的子目录中)或者你也听说过,这是节省时间的一种方法,它可以避免每次运行 Python 时去重新解析源代码。 + +但是,除了 “噢,原来这就是 Python 字节码” 之外,你还知道这些文件能做什么吗?以及 Python 是如何使用它们的? + +如果你不知道,那你走运了!今天我将带你了解 Python 的字节码是什么,Python 如何使用它去运行你的代码,以及知道它是如何帮助你的。 + +### Python 如何工作 + +Python 经常被介绍为它是一个解释型语言 — 其中一个原因是程序运行时,你的源代码被转换成 CPU 的原生指令 — 但这样认为只是部分正确。Python 与大多数解释型语言一样,确实是将源代码编译为一组虚拟机指令,并且 Python 解释器是针对相应的虚拟机实现的。这种中间格式被称为 “字节码”。 + +因此,这些 `.pyc` 文件是 Python 悄悄留下的,是为了让它们运行的 “更快”,或者是针对你的源代码的 “优化” 版本;它们是你的程序在 Python 虚拟机上运行的字节码指令。 + +我们来看一个示例。这里是用 Python 写的经典程序 "Hello, World!": +``` +def hello() + +    print("Hello, World!") + +``` + +下面是转换后的字节码(转换为人类可读的格式): +``` +2           0 LOAD_GLOBAL              0 (print) + +            2 LOAD_CONST               1 ('Hello, World!') + +            4 CALL_FUNCTION            1 + +``` + +如果你输入那个 `hello()` 函数,然后使用 [CPython][1] 解释器去运行它,上面的 Python 程序将会运行。它看起来可能有点奇怪,因此,我们来深入了解一下它都做了些什么。 + +### Python 虚拟机内幕 + +CPython 使用一个基于栈的虚拟机。也就是说,它完全面向栈数据结构的(你可以 “推入” 一个东西到栈 “顶”,或者,从栈 “顶” 上 “弹出” 一个东西来)。 + +CPython 使用三种类型的栈: + + 1. **调用栈**。这是运行 Python 程序的主要结构。它为每个当前活动的函数调用使用了一个东西 — "帧“,栈底是程序的入口点。每个函数调用推送一个新帧到调用栈,每当函数调用返回后,这个帧被销毁。 + 2. 在每个帧中,有一个 **计算栈** (也称为 **数据栈**)。这个栈就是 Python 函数运行的地方,运行的 Python 代码大多数是由推入到这个栈中的东西组成的,操作它们,然后在返回后销毁它们。 + 3. 在每个帧中,还有一个 **块栈**。它被 Python 用于去跟踪某些类型的控制结构:loops、`try`/`except` 块、以及 `with` 块,全部推入到块栈中,当你退出这些控制结构时,块栈被销毁。这将帮助 Python 了解任意给定时刻哪个块是活动的,比如,一个 `continue` 或者 `break` 语句可能影响正确的块。 + + + +大多数 Python 字节码指令操作的是当前调用栈帧的计算栈,虽然,还有一些指令可以做其它的事情(比如跳转到指定指令,或者操作块栈)。 + +为了更好地理解,假设我们有一些调用函数的代码,比如这个:`my_function(my_variable, 2)`。Python 将转换为一系列字节码指令: + + 1. 一个 `LOAD_NAME` 指令去查找函数对象 `my_function`,然后将它推入到计算栈的顶部 + 2. 另一个 `LOAD_NAME` 指令去查找变量 `my_variable`,然后将它推入到计算栈的顶部 + 3. 一个 `LOAD_CONST` 指令去推入一个实整数值 `2` 到计算栈的顶部 + 4. 一个 `CALL_FUNCTION` 指令 + + + +这个 `CALL_FUNCTION` 指令将有 2 个参数,它表示那个 Python 需要从栈顶弹出两个位置参数;然后函数将在它上面进行调用,并且它也同时被弹出(对于函数涉及的关键字参数,它使用另一个不同的指令 — `CALL_FUNCTION_KW`,但使用的操作原则类似,以及第三个指令 — `CALL_FUNCTION_EX`,它适用于函数调用涉及到使用 `*` 或 `**` 操作符的情况)。一旦 Python 拥有了这些之后,它将在调用栈上分配一个新帧,填充到函数调用的本地变量上,然后,运行那个帧内的 `my_function` 字节码。运行完成后,这个帧将被调用栈销毁,最初的帧内返回的 `my_function` 将被推入到计算栈的顶部。 + +### 访问和理解 Python 字节码 + +如果你想玩转字节码,那么,Python 标准库中的 `dis` 模块将对你有非常大的帮助;`dis` 模块为 Python 字节码提供了一个 "反汇编",它可以让你更容易地得到一个人类可读的版本,以及查找各种字节码指令。[`dis` 模块的文档][2] 可以让你遍历它的内容,并且提供一个字节码指令能够做什么和有什么样的参数的完整清单。 + +例如,获取上面的 `hello()` 函数的列表,可以在一个 Python 解析器中输入如下内容,然后运行它: +``` +import dis + +dis.dis(hello) + +``` + +函数 `dis.dis()` 将反汇编一个函数、方法、类、模块、编译过的 Python 代码对象、或者字符串包含的源代码,以及显示出一个人类可读的版本。`dis` 模块中另一个方便的功能是 `distb()`。你可以给它传递一个 Python 追溯对象,或者发生预期外情况时调用它,然后它将反汇编发生预期外情况时在调用栈上最顶端的函数,并显示它的字节码,以及插入一个指向到引发意外情况的指令的指针。 + +它也可以用于查看 Python 为每个函数构建的编译后的代码对象,因为运行一个函数将会用到这些代码对象的属性。这里有一个查看 `hello()` 函数的示例: +``` +>>> hello.__code__ + +", line 1> + +>>> hello.__code__.co_consts + +(None, 'Hello, World!') + +>>> hello.__code__.co_varnames + +() + +>>> hello.__code__.co_names + +('print',) + +``` + +代码对象在函数中可以作为属性 `__code__` 来访问,并且携带了一些重要的属性: + + * `co_consts` 是存在于函数体内的任意实数的元组 + * `co_varnames` 是函数体内使用的包含任意本地变量名字的元组 + * `co_names` 是在函数体内引用的任意非本地名字的元组 + + + +许多字节码指令 — 尤其是那些推入到栈中的加载值,或者在变量和属性中的存储值 — 在这些用作它们参数的元组中使用索引。 + +因此,现在我们能够理解 `hello()` 函数中所列出的字节码: + + 1. `LOAD_GLOBAL 0`:告诉 Python 通过 `co_names` (它是 `print` 函数)的索引 0 上的名字去查找它指向的全局对象,然后将它推入到计算栈 + 2. `LOAD_CONST 1`:带入 `co_consts` 在索引 1 上的实数值,并将它推入(索引 0 上的实数值是 `None`,它表示在 `co_consts` 中,因为 Python 函数调用有一个隐式的返回值 `None`,如果没有显式的返回表达式,就返回这个隐式的值 )。 + 3. `CALL_FUNCTION 1`:告诉 Python 去调用一个函数;它需要从栈中弹出一个位置参数,然后,新的栈顶将被函数调用。 + + + +"原始的" 字节码 — 是非人类可读格式的字节 — 也可以在代码对象上作为 `co_code` 属性可用。如果你有兴趣尝试手工反汇编一个函数时,你可以从它们的十进制字节值中,使用列出 `dis.opname` 的方式去查看字节码指令的名字。 + +### 字节码的用处 + +现在,你已经了解的足够多了,你可能会想 ” OK,我认为它很酷,但是知道这些有什么实际价值呢?“由于对它很好奇,我们去了解它,但是除了好奇之外,Python 字节码在几个方面还是非常有用的。 + +首先,理解 Python 的运行模型可以帮你更好地理解你的代码。人们都开玩笑说,C 将成为一个 ”便携式汇编器“,在那里你可以很好地猜测出一段 C 代码转换成什么样的机器指令。理解 Python 字节码之后,你在使用 Python 时也具备同样的能力 — 如果你能预料到你的 Python 源代码将被转换成什么样的字节码,那么你可以知道如何更好地写和优化 Python 源代码。 + +第二,理解字节码可以帮你更好地回答有关 Python 的问题。比如,我经常看到一些 Python 新手困惑为什么某些结构比其它结构运行的更快(比如,为什么 `{}` 比 `dict()` 快)。知道如何去访问和阅读 Python 字节码将让你很容易回答这样的问题(尝试对比一下: `dis.dis("{}")` 与 `dis.dis("dict()")` 就会明白)。 + +最后,理解字节码和 Python 如何运行它,为 Python 程序员不经常使用的一种特定的编程方式提供了有用的视角:面向栈的编程。如果你以前从来没有使用过像 FORTH 或 Fator 这样的面向栈的编程语言,它们可能有些古老,但是,如果你不熟悉这种方法,学习有关 Python 字节码的知识,以及理解面向栈的编程模型是如何工作的,将有助你开拓你的编程视野。 + +### 延伸阅读 + +如果你想进一步了解有关 Python 字节码、Python 虚拟机、以及它们是如何工作的更多知识,我推荐如下的这些资源: + + * [Python 虚拟机内幕][3],它是 Obi Ike-Nwosu 写的一本免费在线电子书,它深入 Python 解析器,解释了 Python 如何工作的细节。 + * [一个用 Python 编写的 Python 解析器][4],它是由 Allison Kaptur 写的一个教程,它是用 Python 构建的 Python 字节码解析器,并且它实现了运行 Python 字节码的全部构件。 + * 最后,CPython 解析器是一个开源软件,你可以在 [GitHub][1] 上阅读它。它在文件 `Python/ceval.c` 中实现了字节码解析器。[这是 Python 3.6.4 发行版中那个文件的链接][5];字节码指令是由第 1266 行开始的 `switch` 语句来处理的。 + + + +学习更多内容,参与到 James Bennett 的演讲,[有关字节的知识:理解 Python 字节码][6],将在 [PyCon Cleveland 2018][7] 召开。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/introduction-python-bytecode + +作者:[James Bennett][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/ubernostrum +[1]:https://github.com/python/cpython +[2]:https://docs.python.org/3/library/dis.html +[3]:https://leanpub.com/insidethepythonvirtualmachine +[4]:http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html +[5]:https://github.com/python/cpython/blob/d48ecebad5ac78a1783e09b0d32c211d9754edf4/Python/ceval.c +[6]:https://us.pycon.org/2018/schedule/presentation/127/ +[7]:https://us.pycon.org/2018/ diff --git a/translated/tech/20180507 4 Firefox extensions to install now.md b/translated/tech/20180507 4 Firefox extensions to install now.md new file mode 100644 index 0000000000..db97507357 --- /dev/null +++ b/translated/tech/20180507 4 Firefox extensions to install now.md @@ -0,0 +1,77 @@ +4 个 Firefox 扩展 +===== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/redpanda_firefox_pet_animal.jpg?itok=aSpKsyna) +正如我在关于 Firefox 扩展的[原创文章][1]中提到的,web 浏览器已成为许多用户计算(机)验的关键组件。现代浏览器已经发展成为功能强大且可扩展的平台,扩展可以添加或修改其功能。Firefox 的扩展是使用 WebExtensions API(一种跨浏览器开发系统)构建的。 + +在第一篇文章中,我问读者:“你应该安装哪些扩展?” 重申一下,这一决定主要取决于你如何使用浏览器,你对隐私的看法,你对扩展程序开发人员的信任程度以及其他个人偏好。自文章发表以来,我推荐的一个扩展(Xmarks)已经停止。另外,该文章收到了大量的反馈,在这篇更新中,这些反馈已经被考虑到。 + +我想再次指出,浏览器扩展通常需要能够阅读和(或)更改你访问的网页上的所有内容。你应该仔细考虑这一点。如果扩展程序修改了你访问的所有网页的访问权限,那么它可能充当键盘记录程序,拦截信用卡信息,在线跟踪,插入广告以及执行各种其他恶意活动。这并不意味着每个扩展程序都会暗中执行这些操作,但在安装任何扩展程序之前,你应该仔细考虑安装源,涉及的权限,风险配置文件以及其他因素。请记住,你可以使用配置文件来管理扩展如何影响你的攻击面 - 例如,使用没有扩展的专用配置文件来 执行网上银行等任务。 + +考虑到这一点,这里有你可能想要考虑的四个开源 Firefox 扩展。 + +### uBlock Origin + +![ublock origin ad blocker screenshot][2] + +我的第一个建议保持不变。[uBlock Origin][3] 是一款快速,低内存,广泛的拦截器,它不仅可以拦截广告,而且还可以执行你自己的内容过滤。 uBlock Origin 的默认行为是使用多个预定义的过滤器列表来拦截广告,跟踪器和恶意软件站点。它允许你任意添加列表和规则,甚至可以锁定到默认拒绝模式。尽管它很强大,但它已被证明是高效和高性能的。它将继续定期更新,并且是该功能的最佳选择之一。 + +### Privacy Badger + +![privacy badger ad blocker][4] + +我的第二个建议也保持不变。如果说有什么区别的话,那就是自从我上一篇文章发表以来,隐私问题就一直被带到最前沿,这使得这个扩展成为一个简单的建议。顾名思义,[Privacy Badger][5] 是一个专注于隐私的扩展,可以拦截广告和其他第三方跟踪器。这是 Electronic Freedom (to 校正者:这里 Firefox 添加此扩展后,弹出页面译为电子前哨基金会)基金会的一个项目,他们说: + +> Privacy Badger 诞生于我们希望能够推荐一个单独的扩展,它可以自动分析和拦截任何违反用户同意原则的追踪器或广告;在用户没有任何设置、有关知识或配置的情况下,它可以很好地运行;它是由一个明确为其用户而不是为广告商工作的组织所产生的;它使用了算法的方法来决定什么是什么,什么是不跟踪的。” + +为什么 Privacy Badger 会出现在这个列表上,它的功能与上一个扩展看起来很类似?因为一些原因。首先,它从根本上工作原理与 uBlock Origin 不同。其次,深度防御的实践是一项合理的策略。说到深度防御,EFF 还维护着 [HTTPS Everywhere][6] 扩展,它自动确保 https 用于许多主流网站。当你安装 Privacy Badger 时,你也可以考虑使用 HTTPS Everywhere。 + +如果你开始认为这篇文章只是对上一篇文章的重新讨论,那么以下是我的建议分歧。 + +### Bitwarden + +![Bitwarden][7] + +在上一篇文章中推荐 LastPass 时,我提到这可能是一个有争议的选择。这无疑属实。无论你是否应该使用密码管理器 - 如果你使用,那么是否应该选择带有浏览器插件的密码管理器 - 这是一个备受争议的话题,答案很大程度上取决于你的个人风险状况。我认为大多数普通的计算机用户应该使用一个,因为它比最常见的选择要好得多:在任何地方都使用相同的弱密码。我仍然相信这一点。 + +[Bitwarden][8] 自从我上次审视以后确实成熟了。像 LastPass 一样,它对用户友好,支持双因素身份验证,并且相当安全。与 LastPass 不同的是,它是[开源的][9]。它可以使用或不使用浏览器插件,并支持从其他解决方案(包括 LastPass)导入。它的核心功能完全免费,它还有一个 10 美元/年的高级版本。 + +### Vimium-FF + +![Vimium][10] + +[Vimium][11] 是另一个开源的扩展,它为 Firefox 键盘快捷键提供了类似 Vim 一样的导航和控制,其称之为“黑客的浏览器”。对于 Ctrl+x, Meta+x 和 Alt+x,分别对应 **< c-x>**, **< m-x>** 和 **< a-x>**,默认值可以轻松定制。一旦你安装了 Vimium,你可以随时键入 **?** 来查看键盘绑定列表。请注意,如果你更喜欢 Emacs,那么也有一些针对这些键绑定的扩展。无论哪种方式,我认为键盘快捷键是未充分利用的生产力推动力。 + +### 额外福利: Grammarly + +不是每个人都有幸在 Opensource.com 上撰写专栏 - 尽管你应该认真考虑为网站撰写文章;如果你有问题,有兴趣,或者想要一个导师,伸出手,让我们聊天吧。但是,即使没有专栏撰写,正确的语法在各种各样的情况下都是有益的。试一下 [Grammarly][12]。不幸的是,这个扩展不是开源的,但它确实可以确保你输入的所有东西都是清晰的,有效的并且没有错误。它通过扫描你文本中的常见的和复杂的语法错误来实现这一点,涵盖了从主谓一致到文章使用到修饰词的放置这些所有内容。它的基本功能是免费的,它有一个高级版本,每月收取额外的费用。我在这篇文章中使用了它,它发现了许多我的校对没有发现的错误。 + +再次说明,Grammarly 是这个列表中包含的唯一不是开源的扩展,因此如果你知道类似的高质量开源替代品,请在评论中告诉我们。 + +这些扩展是我发现有用并推荐给其他人的扩展。请在评论中告诉我你对更新建议的看法。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/5/firefox-extensions + +作者:[Jeremy Garcia][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jeremy-garcia +[1]:https://opensource.com/article/18/1/top-5-firefox-extensions +[2]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/ublock.png?itok=_QFEbDmq (ublock origin ad blocker screenshot) +[3]:https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/ +[4]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/images/life-uploads/privacy_badger_1.0.1.png?itok=qZXQeKtc (privacy badger ad blocker screenshot) +[5]:https://www.eff.org/privacybadger +[6]:https://www.eff.org/https-everywhere +[7]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/bitwarden.png?itok=gZPrCYoi (Bitwarden) +[8]:https://bitwarden.com/ +[9]:https://github.com/bitwarden +[10]:https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/vimium.png?itok=QRESXjWG (Vimium) +[11]:https://addons.mozilla.org/en-US/firefox/addon/vimium-ff/ +[12]:https://www.grammarly.com/