From 9f3506b91d9bcc2525bc2193dd8fcb91ece72584 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 5 Oct 2017 16:53:13 +0800 Subject: [PATCH 01/39] PRF:20170516 What's the point of DevOps.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @zhousiyu325 @apemost 这篇涉及很多管理学知识,我也只能校对到这样了。 --- .../20170516 What's the point of DevOps.md | 74 +++++++++---------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/translated/tech/20170516 What's the point of DevOps.md b/translated/tech/20170516 What's the point of DevOps.md index 6cca11ead5..ca3dc1197e 100644 --- a/translated/tech/20170516 What's the point of DevOps.md +++ b/translated/tech/20170516 What's the point of DevOps.md @@ -1,106 +1,102 @@ DevOps 的意义 ======================================== -> 真正的组织文化变革有助于你弥合你原先认为无法跨过的鸿沟 +> 真正的组织文化变革有助于弥合你原以为无法跨过的鸿沟 -![What's the point of DevOps?](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/BUSINESS_creativity.png?itok=x2HTRKVW "What's the point of DevOps?") +![What's the point of DevOps?](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_creativity.png?itok=zxGNSqJ1 "What's the point of DevOps?") +回想一下你最近一次尝试改掉一个个人习惯的事情,你可能遇到过这样的情形,你需要改变你思考的方式并且改掉之前的习惯。这很艰难,你只能试着改变_你自己的_思维方式。 -回想你最近一次尝试改掉一个个人习惯的事情,你可能遇到过这样的情形,你需要改变你思考的方式并且改掉之前的习惯。这很艰难,你只是试着改变 _你自己的_ 思维方式而已。 +所以你可能会试着让自己置身于新的环境。新的环境实际上可帮助我们养成_新的_习惯,它反过来又会促成新的思维方式。 -所以你可能会努力让自己处于新的环境。新的环境实际上可帮助我们养成 _新的_ 习惯,它反过来又会促成新的思维方式。 +那就是能否成功改变的所在:思考的越多,得到的越多。你需要知道你在改变的原因以及你的目的所在(而不仅仅你要怎么做),因为改变本身往往是短暂和短视的。 -那就是能否成功改变的所在:看起来是那么回事,实际上它就是那么回事 。你需要知道 _为什么_ 你正在改变以及你的目的 _所在_ (而不是仅仅你要怎么做),因为改变本身往往是短暂和短视的。 +现在想想你的 IT 组织需要做出的改变。也许你正在考虑采用像 DevOps 这样的东西。这个我们称之为 “DevOps” 的东西有三个组件:人、流程和工具。人和流程是_任何_团体组织的基础。因此,采用 DevOps 需要对大多数组织的核心进行根本性的改变,而不仅仅是学习新的工具。 -现在想想你的 IT 组织需要做出的改变。也许你正在考虑采用像 DevOps 这样的东西。这个我们称之为 “DevOps” 的东西有三个组件:人、流程和工具。人和流程是 _任何_ 团体组织的基础。因此,采用 DevOps 需要对大多数组织的核心进行根本性的改变,而不仅仅是学习新的工具。 +如同其它的改变一样,它也是短视的。如果您将注意力集中在将改变作为单点解决方案 —— 例如,“获得更好的报警工具” —— 你可能只是管中窥豹。这种思维方式或许可以提供一套拥有更多铃声、口哨以及可以更好地处理呼叫轮询的工具,但是它不能解决这样的实际问题:警报不能送达到正确的团队,或者故障得不到解决,因为实际上没有人知道如何修复服务。 -和其他改变一样,它也是短视的。如果您将注意力集中在改变作为单点解决方案——例如,“获得更好的工具进行报警”——你可能想出一个狭隘的问题。这种思维方式或许可以提供一套拥有更多铃声和口哨并且可以有一种可以更好地处理随叫随到的方式的工具,但是它不能解决这样的实际问题:警报不能到达正确的团队,或者故障得不到解决,因为实际上没有人知道如何修复服务。 - -新的工具(或者至少一个新工具的想法)创造了一个时刻来谈论困扰你的团队对监控的评价的潜在问题。新工具让你能够做出更大的改变——信仰和做法的改变——它们作为你组织的基础而显得更加重要。 +新的工具(或者至少一个新工具的想法)创造了一个讨论潜在问题的机会,可以让你的团队讨论对监控的看法。新工具让你能够做出更大的改变 —— 信仰和做法的改变 —— 它们作为你组织的基础而显得更加重要。 创造更深层次的变革需要一种可以全新地改变观念的方法。要找到这种方法,我们首先需要更好的理解变革的驱动力。 ### 清除栅栏 -> 就改革而言,它不同于腐化。有一条明显且简单的原则,这个原则可能被称为悖论。在这种情况下,存在某种制度或法律;让我们说,为了简单起见,在一条路上架设了一个栅栏或门。现代化的改革者们来到这儿,并说:“我看不到它的用处,让我们把它清除掉。”聪明的改革者会很好地回答:“如果你看不到它的用处,我肯定不会让你清除它,回去想想,然后你可以回来告诉我你看到它的用处,我会允许你摧毁它。” — G.K Chesterton, 1929 +> 就改革而言,它不同于推翻。这是一条直白且简单的原则,这个原则或许被视作悖论。在这种情况下,存在某种制度或法律;这么说吧,为了简单起见,在一条路上架设了一个栅栏或门。当今的改革者们来到这儿,并说:“我看不到它的用处,让我们把它清除掉。”更聪明的改革者会很好地回答:“如果你看不到它的用处,我肯定不会让你清除它,回去想想,然后你可以回来告诉我你知道了它的用处,我也许会允许你摧毁它。” — G.K Chesterton, 1929 -为了了解对 DevOps 的需求——它试图将传统意义上分开的开发部门和运维部门进行重新组合——我们首先必须明白这个分开是如何产生的。一旦我们"知道了它的用处",然后我们就会知道将它们分开是为了什么,并且在必要的时候可以取消分开。 +为了了解对 DevOps 的需求 —— 它试图将传统意义上分开的开发部门和运维部门进行重新组合 —— 我们首先必须明白这个分开是如何产生的。一旦我们"知道了它的用处",然后我们就会知道将它们分开是为了什么,并且在必要的时候可以取消分开。 -今天我们没有一个单一的管理理论,但是我们可以将大多数现代管理理论的起源追溯到弗雷德里克·温斯洛·泰勒。泰勒是一名机械工程师,他创建了一个衡量钢厂工人效率的系统。泰勒认为,他可以对工厂的劳动者应用科学分析,不仅为了改进个人任务,还为了证明有一个可以发现的用来执行 _任何_ 任务最佳方法。 +今天我们没有一个单一的管理理论,但是大多数现代管理理论的起源可以追溯到弗雷德里克·温斯洛·泰勒Frederick Winslow Taylor。泰勒是一名机械工程师,他创建了一个衡量钢厂工人效率的系统。泰勒认为,他可以对工厂的劳动者运用科学分析的方法,不仅可以改进个人任务,也证明发现了有一个可以用来执行_任何_任务最佳方法。 -我们可以很容易地画一个以 Taylor 为起源的历史树。基于泰勒早在 18 世纪 80 年代后期的研究而出现的时间运动研究和其他质量改进计划跨越 20 世纪 20 年代一直到今天,我们可以从中看到六西格玛、精益,等等一些。自上而下、指导式管理,再加上研究过程的有条理的方法,今天主宰主流商业文化。它主要侧重于把效率作为工人成功的测量标准。 +我们可以很容易地画一个以泰勒为起源的历史树。从泰勒早在 18 世纪 80 年代后期的研究出现的时间运动研究和其他质量改进计划,跨越 20 世纪 20 年代一直到今天,我们可以从中看到六西格玛、精益,等等类似方法。自上而下、指导式管理,再加上研究过程的系统方法,主宰了今天主流商业文化。它主要侧重于把效率作为工人成功的测量标准。 -> “开发”和“运维”的分开不是因为人的原因,不同的技能,或者放在新员工头上的一顶魔术帽,它是 Taylor 和 Sloan 的理论的副产品。 +如果泰勒是我们这颗历史树的根,那么我们主干上的下一个主叉将是 20 世纪 20 年代通用汽车公司的阿尔弗雷德·斯隆Alfred P. Sloan。通用汽车公司创造的斯隆结构不仅持续强劲到 21 世纪初,而且在未来五十年的大部分时间里,都将成为该公司的主要模式。 -如果 Taylor 是我们的历史树的根,那么我们主干上的下一个主叉将是 20 世纪 20 年代通用汽车公司的 Alfred P. Sloan。通用汽车公司创造的斯隆结构不仅持续强劲到 21 世纪初,而且在未来五十年的大部分时间里,都将成为该公司的主要模式。 +1920 年,通用公司正经历一场管理危机,或者说是缺乏管理的危机。斯隆向董事会写了一份为通用汽车的多个部门提出了一个新的结构《组织研究》。这一新结构的核心概念是“集中管理下放业务”。与雪佛兰,凯迪拉克和别克等品牌相关的各个部门将独立运作,同时为中央管理层提供推动战略和控制财务的手段。 -1920 年,通用公司正经历一场管理危机,或者说是缺乏管理的危机。Sloan 向董事会写了一份为通用汽车的多个部门提出了一个新的结构《组织研究》。这一新结构的核心概念是“集中管理下放业务”。与雪佛兰,凯迪拉克和别克等品牌相关的各个部门将独立运作,同时为中央管理层提供推动战略和控制财务的手段。 +在斯隆的建议下(以及后来就任 CEO 的指导下),通用汽车在美国汽车工业中占据了主导地位。斯隆的计划把一个处于灾难边缘公司创造成了一个非常成功的公司。从中间来看,自治单位是黑盒子,激励和目标被设置在顶层,而团队在底层推动。 -在 Sloan 的建议下(以及后来就任 CEO 的指导),通用汽车在美国汽车工业中占据了主导地位。Sloan 的计划把一个处于灾难边缘公司创造成了一个非常成功的公司。从中间来看,自治单位是黑盒子,激励和目标被设置在顶层,而团队在底层推动。 +泰勒思想的“最佳实践” —— 标准、可互换和可重复的行为 —— 仍然在今天的管理理念中占有一席之地,与斯隆公司结构的层次模式相结合,主导了僵化部门的分裂和孤岛化以实现最大的控制。 -泰勒思想的“最佳实践”——标准、可互换和可重复的行为——仍然在今天的管理理念中占有一席之地,与斯隆公司结构的层次模式相结合,主导了僵化的部门分裂和孤岛以实现最大的控制。 +我们可以指出几份管理研究来证明这一点,但商业文化不是通过阅读书籍而创造和传播的。组织文化是 *真实的* 人在 *实际的* 情形下执行推动文化规范的 *具体的* 行为的产物。这就是为何类似泰勒和斯隆这样的理论变得固化而不可动摇的原因。 -我们可以指出几份管理研究来证明这一点,但商业文化不是通过阅读书籍而创造和传播的。组织文化是 *真实的* 人在 *实际的* 情形下执行推动文化规范的 *具体的* 行为的产物。这就是为何类似 Taylor 和 Sloan 的主张这样的事情变得固化而不可动摇的原因。 +技术部门投资就是一个例子。以下是这个周期是如何循环的:投资者只投资于他们认为可以实现 *他们的* 特定成功观点的公司。这个成功的模式并不一定源于公司本身(和它的特定的目标);它来自董事会对一家成功的公司 *应该* 如何看待的想法。许多投资者来自从经营企业的尝试和苦难中幸存下来的公司,因此他们对什么会使一个公司成功有 *不同的* 理念。他们为那些能够被教导模仿他们的成功模式的公司提供资金,希望获得资金的公司学会模仿。这样,初创公司孵化器就是一种重现理想的结构和文化的*直接的*方式。 -技术部门投资就是一个例子。以下是这个周期是如何循环的:投资者只投资于他们认为可以实现 *他们的* 特定成功观点的公司。这个成功的模式并不一定源于公司本身(和它的特定的目标);它来自董事会对一家成功的公司 *应该* 如何看待的想法。许多投资者来自在经营企业的尝试和苦难中幸存下来的公司,因此他们对什么会使一个公司成功有 *不同的* 蓝图。他们为那些能够被教导模仿他们的成功模式的公司提供资金,所以希望获得资金的公司学会模仿。这样,初创公司孵化器就是一种重现理想的结构和文化的直接的方式。 - -开发和运维的分开是不是因为人的原因,不同的技能,或者放在新员工头上的一顶魔术帽;它是 Taylor 和 Sloan 的理论的副产品。责任与人员之间的透明和不可渗透的界线是一个管理功能,同时也注重员工的工作效率。管理上的分开可以很容易的落在产品或者项目界线上,而不是技能上,但是通过今天的业务管理理论的历史告诉我们,基于技能的分组是“最好”的高效方式。 +“开发”和“运维”的分开不是因为人的原因,也不是因为不同的技能,或者放在新员工头上的一顶魔法分院帽;它是泰勒和斯隆的理论的副产品。责任与人员之间的清晰而不可渗透的界线是一个管理功能,同时也注重员工的工作效率。管理上的分开可以很容易的落在产品或者项目界线上,而不是技能上,但是通过今天的业务管理理论的历史告诉我们,基于技能的分组是“最好”的高效方式。 不幸的是,那些界线造成了紧张局势,这些紧张局势是由不同的管理链出于不同的目标设定的相反目标的直接结果。例如: * 敏捷 ⟷ 稳定 * 吸引新用户 ⟷ 现有用户的体验 -* 让应用程序增加新功能 ⟷ 让应用程序可以使用 -* 打败竞争对手 ⟷ 保护收入 +* 让应用程序增加新功能 ⟷ 让应用程序保持可用 +* 打败竞争对手 ⟷ 维持收入 * 修复出现的问题 ⟷ 在问题出现之前就进行预防 -今天,我们可以看到组织的高层领导人越来越认识到,现有的商业文化(并扩大了它所产生的紧张局势)是一个严重的问题。在 2016 年的 Gartner 报告中,57% 的受访者表示,文化变革是 2020 年之前企业面临的主要挑战之一。像作为一种影响组织变革的手段的敏捷和DevOps这样的新方法的兴起反映了这一认识。"[shadow IT][7]" 的出现是硬币的反面;最近的估计有将近 30% 的 IT 支出在 IT 组织的控制之外。 +今天,我们可以看到组织的高层领导人越来越认识到,现有的商业文化(并扩大了它所产生的紧张局势)是一个严重的问题。在 2016 年的 Gartner 报告中,57% 的受访者表示,文化变革是 2020 年之前企业面临的主要挑战之一。像作为一种影响组织变革的手段的敏捷和 DevOps 这样的新方法的兴起反映了这一认识。“[影子 IT][7]” 的出现更是事物的另一个方面;最近的估计有将近 30% 的 IT 支出在 IT 组织的控制之外。 这些只是企业正在面临的一些“文化担忧”。改变的必要性是明确的,但前进的道路仍然受到昨天的决定的约束。 ### 抵抗并不是没用的 -> Bert Lance 认为如果他能让政府采纳一条简单的格言“如果东西还没损坏,那就别去修理它”,他就可以为山姆拯救三十亿。他解释说:“这是政府的麻烦:‘修复没有损坏的东西,而不是修复已经损坏了的东西。’” — Nation's Business, 1977.5 +> Bert Lance 认为如果他能让政府采纳一条简单的格言“如果东西还没损坏,那就别去修理它”,他就可以为国家节省三十亿。他解释说:“这是政府的问题:‘修复没有损坏的东西,而不是修复已经损坏了的东西。’” — Nation's Business, 1977.5 -通常,改革是组织针对所出现的错误所做的应对。在这个意义上说,如果紧张局势(即使逆境)是变革的正常催化剂,那么 *抵抗* 变化就是成功的指标。但是过分强调成功的道路会使组织变得僵硬、衰竭和独断。重视有效结果的政策导航是这种不断增长的僵局的症状。 +通常,改革是组织针对所出现的错误所做的应对。在这个意义上说,如果紧张局势(即使逆境)是变革的正常催化剂,那么对变化的 *抵抗* 就是成功的指标。但是过分强调成功的道路会使组织变得僵硬、衰竭和独断。重视有效结果的政策导向是这种不断增长的僵局的症状。 -传统 IT 部门的成功加剧了 IT 仓库的墙壁。其他部门现在变成了“顾客”,而不是同事。试图将 IT 从成本中心转移出来创建一个新的操作模式,它可以将 IT 与其他业务目标断开。这反过来又会对敏捷性造成限制,增加摩擦,降低反应能力。合作被搁置而支持“专家方向”。结果是一个孤立主义的观点,IT 只能带来更多的伤害而不是好处。 +传统 IT 部门的成功加剧了 IT 孤岛的壁垒。其他部门现在变成了“顾客”,而不是伙伴。试图将 IT 从成本中心转移出来创建一个新的操作模式,它可以将 IT 与其他业务目标断开。这反过来又会对敏捷性造成限制,增加摩擦,降低反应能力。合作被搁置转而偏向“专家方向”。结果是一个孤立主义的观点,IT 只能带来更多的伤害而不是好处。 正如“软件吃掉世界”,IT 越来越成为组织整体成功的核心。具有前瞻性的 IT 组织认识到这一点,并且已经对其战略规划进行了有意义的改变,而不是将改变视为恐惧。 -> 改革不仅仅只是重构组织,它也是关于跨越历史上不可跨越的鸿沟的新途径。 - -例如,Facebook 与人类学家罗宾·邓巴(Robin Dunbar)就社会团体的方法进行了磋商,而且意识到这一点对公司成长的内部团体(不仅仅是网站的外部用户)的影响。扎波斯的文化得到了很多的赞誉,该组织创立了一个部门,专注于培养他人对于核心价值观和企业文化的看法。当然,这本书是 _The Open Organization_ 的姊妹篇, 一本描述被应用于管理的开放原则——透明度、参与度和社区——可以如何为我们快节奏的有联系的时代重塑组织。 +例如,Facebook 与人类学家罗宾·邓巴Robin Dunbar就社会团体的方法进行了磋商,而且意识到这一点对公司成长的内部团体(不仅仅是该网站的外部用户)的影响。扎波斯Zappos的文化得到了很多的赞誉,该组织创立了一个部门,专注于培养他人对于核心价值观和企业文化的看法。当然,这本书是 《开放式组织》的姊妹篇,那是一本描述被应用于管理的开放原则 —— 透明度、参与度和社区 —— 可以如何为我们快节奏的互联时代重塑组织。 ### 决心改变 > “如果外界的变化率超过了内部的变化率,那末日就不远了。” — Jack Welch, 2004 -一位同事曾经告诉我他可以只用 [Information Technology Infrastructure Library][9] 框架里面的词汇向一位项目经理解释 DevOps。 +一位同事曾经告诉我他可以只用 “[信息技术基础设施库(ITIL)][9]” 框架里面的词汇向一位项目经理解释 DevOps。 -虽然这些框架 *似乎* 是反对的,但实际上它们都集中在风险和变革管理上。他们简单地介绍了这种管理的不同流程和工具。在 IT 圈子外面谈论 DevOps 时,这一点需要注意。不要强调流程故障和故障,而是显示更小的变化引起的风险 *更小* 等等。这是强调改变团队文化的有益方式:专注于 *新的* 功能而不是老问题是改变的有效代理,特别是当您采用别人的参考框架时。 +虽然这些框架 *似乎* 是反面的,但实际上它们都集中在风险和变革管理上。它们简单地介绍了这种管理的不同流程和工具。在 IT 圈子外面谈论 DevOps 时,这一点需要注意。不要强调流程问题和故障,而是显示更小的变化引起的风险 *更小* 等等。这是强调改变团队文化的有益方式:专注于 *新的* 功能而不是老问题,是改变的有效中介,特别是当您采用别人的框架进行参考时。 -改革不仅仅只是 *重构* 组织;它也是关于跨越历史上不可跨越的鸿沟的新途径——通过拒绝把像“敏捷”和“稳定”这样的东西作为互相排斥的力量来解决我之前提到的那些紧张局势。建立注重 *结果* 胜过 *功能* 的跨部门团队是一个有效的策略。把不同的团队——其中每个人的工作依赖于其他人——聚集起来围绕一个项目或目标是最常见的方法之一。消除这些团队之间的摩擦和改善沟通能够产生巨大的改进——即使在坚持铁仓管理结构时(如果可以掌握,则不需要拆除筒仓)。在这些情况下,*抵抗* 改革不是成功的一个指标;而拥抱改革是一个指标。 +改革不仅仅只是 *重构* 组织;它也是跨越历史上不可跨越的鸿沟的新途径 —— 通过拒绝把像“敏捷”和“稳定”这样的东西作为互相排斥的力量来解决我之前提到的那些紧张局势。建立注重 *结果* 胜过 *功能* 的跨部门团队是一个有效的策略。把不同的团队 —— 其中每个人的工作依赖于其他人 —— 聚集起来围绕一个项目或目标是最常见的方法之一。消除这些团队之间的摩擦和改善沟通能够产生巨大的改进 —— 即使在坚持铁仓管理结构时(如果可以掌握,则不需要拆除孤岛)。在这些情况下,对改革的 *抵抗* 不是成功的一个指标;而对改革的拥抱才是。 -这些也不是“最佳实例”,它们只是一种检查你自己的栅栏的方式。每个组织都会有独特的由他们内部人员创造的栅栏。一旦你“知道了它的用途”,你就可以决定它是需要拆解还是掌握。 +这些也不是“最佳实例”,它们只是一种检查你自己的栅栏的方式。每个组织都会有独特的、由他们内部人员创造的栅栏。一旦你“知道了它的用途”,你就可以决定它是需要拆解还是掌握。 -** 本文是 Opensource.com 即将推出的关于开放组织和 IT 文化指南的一部分。[你可以在这注册以便当它发布时收到通知][5] +** 本文是 Opensource.com 即将推出的关于开放组织和 IT 文化指南的一部分。[你可以在这注册以便当它发布时收到通知][5]** (题图 : opensource.com) + -------------------------------------------------------------------------------- 作者简介: -Matt Micene——Matt Micene 是 Red Hat 公司的 Linux 和容器传播者。他在信息技术方面拥有超过 15 年的经验,从架构和系统设计到数据中心设计。他对关键技术(如容器,云计算和虚拟化)有深入的了解。他目前的重点是宣传红帽企业版 Linux,以及操作系统如何与计算环境的新时代相关。 +Matt Micene 是 Red Hat 公司的 Linux 和容器传播者。从架构和系统设计到数据中心设计,他在信息技术方面拥有超过 15 年的经验。他对关键技术(如容器,云计算和虚拟化)有深入的了解。他目前的重点是宣传红帽企业版 Linux,以及操作系统如何与计算环境的新时代相关。 ------------------------------------------ via: https://opensource.com/open-organization/17/5/what-is-the-point-of-DevOps -作者:[Matt Micene ][a] +作者:[Matt Micene][a] 译者:[zhousiyu325](https://github.com/zhousiyu325) -校对:[apemost](https://github.com/apemost) +校对:[apemost](https://github.com/apemost),[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From b6f6a97a01b5c1e242ad9951cef564652903d45a Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 5 Oct 2017 16:54:07 +0800 Subject: [PATCH 02/39] PUB:20170516 What's the point of DevOps.md @zhousiyu325 @apemost https://linux.cn/article-8931-1.html --- .../tech => published}/20170516 What's the point of DevOps.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170516 What's the point of DevOps.md (100%) diff --git a/translated/tech/20170516 What's the point of DevOps.md b/published/20170516 What's the point of DevOps.md similarity index 100% rename from translated/tech/20170516 What's the point of DevOps.md rename to published/20170516 What's the point of DevOps.md From e93f299eee493c2683f1c209a9720d7e86ab0427 Mon Sep 17 00:00:00 2001 From: feng lv Date: Thu, 5 Oct 2017 18:37:57 +0800 Subject: [PATCH 03/39] translated --- ...out Linux you may not have known so far.md | 104 ------------------ ...out Linux you may not have known so far.md | 104 ++++++++++++++++++ 2 files changed, 104 insertions(+), 104 deletions(-) delete mode 100644 sources/tech/20170907 Seven things about Linux you may not have known so far.md create mode 100644 translated/tech/20170907 Seven things about Linux you may not have known so far.md diff --git a/sources/tech/20170907 Seven things about Linux you may not have known so far.md b/sources/tech/20170907 Seven things about Linux you may not have known so far.md deleted file mode 100644 index c940668ff9..0000000000 --- a/sources/tech/20170907 Seven things about Linux you may not have known so far.md +++ /dev/null @@ -1,104 +0,0 @@ -ucasFL translating - -Seven things about Linux you may not have known so far -============================================================ - -![Hidden features of Linux](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2015/12/Linux-Kernel-sys-visual5.jpg?resize=750%2C563) - -One of the coolest parts about using Linux is the knowledge you gain over time. Each day, you’re likely to come across a new utility or maybe just an unfamiliar flag that does something helpful. These bits and pieces aren’t always life-changing, but they are the building blocks for expertise. - -Even experts don’t know that all, though. No matter how much experience you might have, there is always more to learn, so we’ve put together this list of seven things about Linux you may not have known. - -**There is an interactive mode for command history** - -You’re probably familiar with `history`, which reads your bash history to `stdout`in a handy numbered list. However, if you find yourself searching for a specific URL in a sea of `curl` commands, this list isn’t always easy to read. - -As an alternative, Linux comes with an interactive reverse search that helps you to avoid the headache. You can activate it with `ctrl+r`. This enables an interactive prompt that will search backwards through your bash history for a string you provide. You can cycle back through older commands by pressing `ctrl+r` again or cycle forward using `ctrl+s`. - -Note that `ctrl+s` sometimes collides with XON/XOFF flow control, you can disable the same by running `stty –ixon`. This will usually be fine on your own personal machines, but as always, make sure you don’t need XON/XOFF before you disable it. - -**Cron isn’t the only way to schedule jobs** - -Cron jobs are incredibly useful for sysadmins of any level — from absolute beginner to seasoned expert. But if you need to schedule a one-off task, the `at` command provides a quick way to create jobs without touching your crontab. - -Run the `at` command followed by the time you’d like to run your job. The time is flexible and accepts a variety of time formats. A few examples include: - -“at 12:00 PM September 30 2017” -“at now + 1 hour” -“at 9:00 AM tomorrow” - -Once you enter the `at` command with arguments, you’ll be prompted for the commands you would like to run on your Linux machine. This can be a backup script, a set of maintenance tasks or even a normal bash command. To finalise the job, enter `ctrl+d`. - -Further, you can view all jobs for the current user with `atq` or for all users with `sudo atq`. This will display the scheduled jobs with an ID for each one. To cancel a scheduled job, use `atrm` with the job ID as an argument. - -**You can search commands by function, not just name** - -Remembering command names can be difficult, especially as a beginner. Luckily, Linux comes with a tool to search the man pages by both name and description. - -Next time, if you would struggle to remember the name of the tool you want to use, you can try `apropos` with a description of what you are trying to achieve. For instance, `apropos build filesystem` will return a list of names and descriptions of utilities that include the words “build” or “filesystem.” - -The `apropos` command accepts a string or multiple strings as arguments, but it also has options like `-r`, which allows you to search by regular expression. - -**An alternatives system allows you to manage versions** - -If you have ever been involved in software development, you know the importance of managing support for different versions of a language across projects. Many Linux distributions have tools to handle different versions built in. - -Executables like `java` are often symbolically linked to `/etc/alternatives`. This directory, in turn, stores symlinks to binary files and offers an interface for managing those links. Java is probably the most commonly used language with alternatives, but with a bit of configuration, it can also act as a replacement for applications like NVM and RVM (version managers for NodeJS and Ruby, respectively). - -In Debian-based systems, you can create and manage these links with `update-alternatives`. In CentOS, the tool is simply called `alternatives`. By changing the links in your alternatives file, you can install multiple versions of a language and use different binaries in different situations. Of course, this is not just limited to programming languages. The alternatives system also offers support for any executable that you might want to run from the command line. - -**Shred command is a more secure way to delete files** - -Most of us probably use `rm` to delete files. But where do those files go? The truth is that `rm` might not be doing what you think — it simply removes the hardlink between the filesystem and the data on disk. The 1s and 0s remain in storage until they are overwritten by another application. For extremely sensitive data, this can be a huge security concern. - -The `shred` command is a hardcore version of `rm`. When you shred a file, its data is randomly overwritten multiple times. There is even an option to run a final pass and “zero out” the data after the random overwrites. - -To securely delete a file and overwrite it with zeros: - -`shred -u -z [file name]` - -You can also add the `-n` option with a number as an argument. This allows you to specify how many iterations will be made when randomly overwriting the data. - -**Autocorrect to avoid frustration when typing long filepaths** - -How many times have you typed out an absolute file path only to see the “No such file or directory” message? Even the best of us know the pain of a typo in a long string. Fortunately, there is an easy fix. - -The built-in `shopt` command allows you to set different options to change the behavior of your shell. Setting the `cdspell` option is a simple way to avoid the headache of one-letter mistakes when typing out file paths. You can turn it on by running `shopt -s cdspell`. Once it has been activated, file paths will autocorrect to the closest match when you try to change directories. - -Shell options are a great way to save time (not to mention hassle), and there are plenty of others. To see a full list of options on your system, run `shopt` with no arguments. Be aware that this is a feature of bash, so if you’re running zsh or another alternative shell, you may not have access to it. - -**Easily return to the current directory with subshells** - -If you’ve ever had to configure a system with even a moderate level of complexity, you’ve probably found yourself changing directories so often that it can be hard to keep track of where you are. Wouldn’t it be great if there was a way to automatically return to your current location after running a command? - -Linux actually offers a solution to this problem, and it’s dead simple. If you need to `cd` to another location to do something and then return to your current working directory, wrap the command in parentheses. Here’s an example you can try on your machine. Make a note of your current directory, then run: - -`(cd /etc && ls -a)` - -This will output the contents of your `/etc` directory. Now recheck your current working directory. It should be the same one you were in before, not `/etc`. - -So how does it work? Running a command in parentheses spawns a subshell or a forked copy of the current shell process. The subshell has access to all of the parent’s variables, but not vice versa, so keep that in mind if you’re running an especially complex one-liner. - -Subshells are often used in scripts for parallel processing, but you can bring that same power to the command line to make your life easier when navigating the filesystem. - --------------------------------------------------------------------------------- - -作者简介: - -Phil Zona - -The author is a technical writer for Linux Academy. He has written guides and tutorials on AWS, Microsoft Azure, and Linux systems administration. He also manages the Cloud Assessments blog, which aims to help individuals reach their career goals through technology. - ------------------ - -via: http://opensourceforu.com/2017/09/top-7-things-linux-may-not-known-far/ - -作者:[PHIL ZONA ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://opensourceforu.com/author/phil-zona/ -[1]:http://opensourceforu.com/2017/09/top-7-things-linux-may-not-known-far/#disqus_thread -[2]:http://opensourceforu.com/author/phil-zona/ diff --git a/translated/tech/20170907 Seven things about Linux you may not have known so far.md b/translated/tech/20170907 Seven things about Linux you may not have known so far.md new file mode 100644 index 0000000000..0403b78bc1 --- /dev/null +++ b/translated/tech/20170907 Seven things about Linux you may not have known so far.md @@ -0,0 +1,104 @@ +关于 Linux 你可能不是非常了解的七件事 +=== + +![Hidden features of Linux](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2015/12/Linux-Kernel-sys-visual5.jpg?resize=750%2C563) + +使用 Linux 最酷的事情之一就是随着时间的推移,你可以不断获得新的知识。每天,你都可能会遇到一个新的实用工具,或者只是一个不太熟悉的奇技淫巧,但是却非常有用。这些零碎的东西并不总是能够改变生活,但是却是专业知识的基础。 + +即使是专家,也不可能事事皆知。无论你有多少经验,可能总会有更多的东西需要你去学习。所以,在这儿我列出了七件关于 Linux 你可能不知道的事情。 + +### 有一个查找命令历史的交互模式 + +你可能对 `history` 命令非常熟悉,它会读取 bash 历史,然后以编号列表的方式输出到标准输出(`stdout`)。然而,如果你在 `curl` 命令的海洋里寻找一个特定的链接(URL),那么这个列表并不总是非常容易阅读的。 + +你还可以有另一个选择,Linux 有一个交互式的反向搜索可以帮助你解决这个问题。你可以通过快捷键 `CTRL+R`启动交互模式,然后进入一个交互提示中,它将会根据你提供的字符串来向后搜索 bash 历史,你可以通过再次按下 `CTRL+R` 向后搜索更老的命令,或者按下 `CTRL+S` 向前搜索。 + +注意,`CTRL+S` 有时会与 XON/XOFF 流控制冲突,即 XON/OFF 流控制也会使用该快捷键。你可以通过运行 `stty -ixon` 命令来禁用该快捷键。在你的个人电脑上,这通常是有用的,但是在禁用前,确保你不需要 XON/XOFF 。 + +### Cron 不是安排任务的唯一方式 + +Cron jobs 对于任何水平的系统管理员,无论是毫无经验的初学者,还是经验丰富的专家来说,都是非常有用的。但是,如果你需要安排一个一次性的任务,那么 `at` 命令为你提供了一个快捷的方式来创建任务,从而你不需要接触 crontab 。 + +`at` 命令的运行方式是在后面紧跟着你想要运行任务的运行时间。时间是灵活的,因为它支持许多时间格式。包括下面这些例子: + +“at 12:00 PM September 30 2017” +“at now + 1 hour” +“at 9:00 AM tomorrow” + +当你以带参数的方式输入 `at` 命令以后,将会提示你该命令将在你的 Linux 系统上运行。这可能是一个备份脚本,一套维护任务,或者甚至是一个普通的 bash 命令。如果要结束任务,可以按 `CTRL+D` 。 + +另外,你可以使用 `atq` 命令查看当前用户的所有任务,或者使用 `sudo atq` 查看所有用户的任务。它将会展示出所有排定好的任务,并且每个任务都伴有一个 ID 。如果你想取消一个排定好的任务,可以使用 `atrm` 命令,并且以任务 ID 作为参数。 + +### 你可以通过函数搜索命令,而不仅仅是通过名字 + +记住命令的名字非常困难,特别是对于初学者来说。幸运的是,Linux 附带了一个通过名字和描述来搜索 man 页面的工具。 + +下次,如果你没有记住你想要使用的工具的名称,你可以尝试使用 `apropos` 命令加上你想要干的事情的描述。比如,`apropos build filesystem` 将会返回一系列工具的名字和描述,包括 build 和 filesystem 。 + +`apropos` 命令接受一个或多个字符串作为参数,但同时它也有其他参数,比如你可以使用 `-r` 参数,从而通过正则表达式来搜索。 + +### 有一个可供选择的系统允许你来管理系统版本 + +如果你曾进行过软件开发,你就会明白跨项目管理不同版本的语言的支持的重要性。许多 Linux 发行版都有工具可以来处理不同的内建版本。 + +可执行文件比如 `java` 往往象征性地链接到目录 `/etc/alternatives` 下。反过来,该目录会将符号链接存储为二进制文件并提供一个管理这些链接的接口。Java 可能是 alternatives 最常管理的语言,但是,经过一些配置,它也可以作为其他应用程序,比如 NVM 和 RVM 的替代品(NVM 和 RVM 分别是 NodeJS 和 Ruby 的版本管理器)。 + +在基于 Debian 的系统中,你可以使用 `update-alternatives` 命令创建和管理这些链接。在 CentOS 中,这个工具就叫做 `alternatives` 。通过更改你的 alternatives 文件中的链接,你便可以安装一个语言的多个版本并且在不同的情况下使用不同的二进制。该可供选择的系统也提供了对任何你可能在命令行运行的程序的支持。 + +### `shred` 命令是更加安全的删除文件方式 + +我们大多数时候总是使用 `rm` 命令来删除文件。但是文件去哪儿了呢?真相是 `rm` 命令所做的事情并不是像你所想像的那样,它仅仅删除了文件系统和硬盘上的数据的硬链接。硬盘上的数据依旧存在,直到被另一个应用重写覆盖。对于非常敏感的数据来说,这会带来一个很大的安全隐患。 + +`shred` 命令是 `rm` 命令的升级版。当你使用 `shred` 命令删除一个文件之后,文件中的数据会被随机多次重写。甚至有一个选项可以在随机重写之后对所有的数据进行清零。 + +如果你想安全的删除一个文件并且以零覆盖,那么可以使用下面的命令: + +`shred -u -z [file name]` + +同时,你也可以使用 `-n` 选项和一个数字作为参数,从而指定在随机覆盖数据的时候迭代多少次。 + +**** + +### 通过自动更正来避免输入很长的无效文件路径 + +有多少次,你输入一个文件的绝对路径,然而却看到“没有该文件或目录”的消息。任何人都会明白输入一个很长的字符串的痛苦。幸运的是,有一个很简单的解决办法。 + +内建的 `shopt` 命令允许你设置不同的选项来改变 shell 的行为。设置 `cdspell` 选项是避免输入文件路径时一个字母出错的头痛的一个简单方式。你可以通过运行 `shopt -s cdspell` 命令来启用该选项。启用该选项后,当你想要更改目录时,会自动更正为最匹配的目录。 + +Shell 选项是节省时间的一个好方法(更不用说减少麻烦),此外还有许许多多的其他选项。如果想查看你的系统中所有选项的完整列表,可以运行不带参数的 `shopt` 命令。需要注意的是,这是 bash 的特性,如果你运行 zsh 或者其他可供选择的 shell,可能无法访问。 + +**** + +### 通过子 shell 返回到当前目录 + +如果你曾经配置过一个中等难度的复杂系统,那么你可能会发现你需要频繁的更换目录,从而很难跟踪你所在的位置。如果在运行完一个命令后自动返回到当前位置,不是很好吗? + +Linux 系统实际上提供了一个解决该问题的方法,并且非常简单。如果你想通过 `cd` 命令进入另一个目录完成一些任务,然后再返回当前工作目录,那么你可以将命令置于括号中。你可以在你的 Linux 系统上尝试下面这个命令。记住你当前的工作目录,然后运行: + +`(cd /etc && ls -a)` + +该命令会输出 `/etc` 目录的内容。现在,检查你的当前工作目录。它和执行该命令前的目录一样,而不是 `/etc` 目录。 + +它是如何工作的呢?运行一个括号中的命令会创建一个子 shell 或者一个当前 shell 进程的复刻。该子 shell 可以访问所有的父变量,反之亦然。所以请记住,你是在运行一个非常复杂的单命令。 + +在并行处理中经常使用子 shell ,但是在命令行中,它也能为你带来同样的力量,从而使你在浏览文件系统时更加容易。 + +-------------------------------------------------------------------------------- + +作者简介: + +Phil Zona 是 Linux Academy 的技术作家。他编写了 AWS、Microsoft Azure 和 Linux 系统管理的指南和教程。他同时也管理着云评估博客,该博客旨在帮助个人通过技术实现他们的事业目标。 + +----------------- + +via: http://opensourceforu.com/2017/09/top-7-things-linux-may-not-known-far/ + +作者:[PHIL ZONA][a] +译者:[ucasFL](https://github.com/ucasFL) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://opensourceforu.com/author/phil-zona/ +[1]:http://opensourceforu.com/2017/09/top-7-things-linux-may-not-known-far/#disqus_thread +[2]:http://opensourceforu.com/author/phil-zona/ From 4740456ec817d482f516f42ad39aad252bae486a Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 5 Oct 2017 21:29:11 +0800 Subject: [PATCH 04/39] PRF:20170312 OpenGL Go Tutorial Part 1.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @GitFuture 翻译的不错~ --- .../20170312 OpenGL Go Tutorial Part 1.md | 116 +++++++++--------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/translated/tech/20170312 OpenGL Go Tutorial Part 1.md b/translated/tech/20170312 OpenGL Go Tutorial Part 1.md index a419e08806..9bc26776ba 100644 --- a/translated/tech/20170312 OpenGL Go Tutorial Part 1.md +++ b/translated/tech/20170312 OpenGL Go Tutorial Part 1.md @@ -1,48 +1,50 @@ -OpenGL 与 Go 教程 第一节: Hello, OpenGL +OpenGL 与 Go 教程(一)Hello, OpenGL ============================================================ - _[第一节: Hello, OpenGL][6]_  |  _[第二节: 绘制游戏面板][7]_  |  _[第三节: 实现游戏功能][8]_ +- [第一节: Hello, OpenGL][6] +- [第二节: 绘制游戏面板][7] +- [第三节: 实现游戏功能][8] - _这篇教程的所有源代码都可以在 [GitHub][9] 上找到。_ +这篇教程的所有源代码都可以在 [GitHub][9] 上找到。 ### 介绍 -[OpenGL][19] 是一门相当好的技术,适用于多种类型的绘图工作,从桌面的 GUI 到游戏,到移动应用甚至 web 应用。我敢保证,你今天看到的图形有些就是用 OpenGL 渲染的。可是,不管 OpenGL 多受欢迎、有多好用,与学习其它高层次的绘图库相比,学习 OpenGL 是要相当足够的决心的。 +[OpenGL][19] 是一门相当好的技术,适用于从桌面的 GUI 到游戏,到移动应用甚至 web 应用的多种类型的绘图工作。我敢保证,你今天看到的图形有些就是用 OpenGL 渲染的。可是,不管 OpenGL 多受欢迎、有多好用,与学习其它高级绘图库相比,学习 OpenGL 是要相当足够的决心的。 这个教程的目的是给你一个切入点,让你对 OpenGL 有个基本的了解,然后教你怎么用 [Go][20] 操作它。几乎每种编程语言都有绑定 OpenGL 的库,Go 也不例外,它有 [go-gl][21] 这个包。这是一个完整的套件,可以绑定 OpenGL ,适用于多种版本的 OpenGL。 -这篇教程会按照下面列出的几个阶段进行介绍,我们最终的目标是用 OpenGL 在桌面窗口绘制游戏面板,进而实现 [Conway's Game of Life][22]。完整的源代码可以在 GitHub [github.com/KyleBanks/conways-gol][23] 上获得,当你有疑惑的时候可以随时查看源代码,或者你要按照自己的方式学习也可以参考这个代码。 +这篇教程会按照下面列出的几个阶段进行介绍,我们最终的目标是用 OpenGL 在桌面窗口绘制游戏面板,进而实现[康威生命游戏][22]。完整的源代码可以在 GitHub [github.com/KyleBanks/conways-gol][23] 上获得,当你有疑惑的时候可以随时查看源代码,或者你要按照自己的方式学习也可以参考这个代码。 -在我们开始之前,我们要先弄明白 _Conway's Game of Life_ 到底是什么。这里是 [Wikipedia][24] 上面的总结: +在我们开始之前,我们要先弄明白康威生命游戏Conway's Game of Life 到底是什么。这里是 [Wikipedia][24] 上面的总结: -> 《Game of Life》,也可以简称为 Life,是一个细胞自动变化的过程,由英国数学家 John Horton Conway 于 1970 年提出。 +> 《生命游戏》,也可以简称为 Life,是一个细胞自动变化的过程,由英国数学家 John Horton Conway 于 1970 年提出。 > -> 这个“游戏”没有玩家,也就是说它的发展依靠的是它的初始状态,不需要输入。用户通过创建初始配置文件、观察它如何演变,或者对于高级“玩家”可以创建特殊属性的模式,进而与《Game of Life》进行交互。 +> 这个“游戏”没有玩家,也就是说它的发展依靠的是它的初始状态,不需要输入。用户通过创建初始配置文件、观察它如何演变,或者对于高级“玩家”可以创建特殊属性的模式,进而与《生命游戏》进行交互。 > -> 规则 +> `规则` > -> 《Game of Life》的世界是一个无穷多的二维正交的正方形细胞的格子,每一个格子都有两种可能的状态,“存活”或者“死亡”,也可以说是“填充态”或“未填充态”(区别可能很小,除非把它看作一个模拟人类/哺乳动物行为的早期模型,或者在一个人如何看待方格里的空白时)。每一个细胞与它周围的八个细胞相关联,这八个细胞分别是水平、垂直、斜对角相接的。在游戏中的每一步,下列事情中的一件将会发生: +> 《生命游戏》的世界是一个无穷多的二维正交的正方形细胞的格子世界,每一个格子都有两种可能的状态,“存活”或者“死亡”,也可以说是“填充态”或“未填充态”(区别可能很小,可以把它看作一个模拟人类/哺乳动物行为的早期模型,这要看一个人是如何看待方格里的空白)。每一个细胞与它周围的八个细胞相关联,这八个细胞分别是水平、垂直、斜对角相接的。在游戏中的每一步,下列事情中的一件将会发生: > -> 1. 任何存活着的细胞当任何一个存活的 cell 的附近少于 2 个存活的 cell 时,该 cell 将会消亡,就像人口过少所导致的结果一样 -> 2. 当任何一个存活的 cell 的附近有 2 至 3 个存活的 cell 时,该 cell 在下一代中仍然存活。 -> 3. 当任何一个存活的 cell 的附近多于 3 个存活的 cell 时,该 cell 将会消亡,就像人口过多所导致的结果一样 -> 4. 任何一个消亡的 cell 附近刚好有 3 个存活的 cell,该 cell 会变为存活的状态,就像重生一样。 +> 1. 当任何一个存活的细胞的附近少于 2 个存活的细胞时,该细胞将会消亡,就像人口过少所导致的结果一样 +> 2. 当任何一个存活的细胞的附近有 2 至 3 个存活的细胞时,该细胞在下一代中仍然存活。 +> 3. 当任何一个存活的细胞的附近多于 3 个存活的细胞时,该细胞将会消亡,就像人口过多所导致的结果一样 +> 4. 任何一个消亡的细胞附近刚好有 3 个存活的细胞,该细胞会变为存活的状态,就像重生一样。 -不需要其他工具,这里由一个我们将会制作的演示程序: +不需要其他工具,这里有一个我们将会制作的演示程序: - ![OpenGL 与 Go 语言教程中的 Conway's Game of Life - 示例游戏](https://kylewbanks.com/images/post/golang-opengl-conway-1.gif) +![Conway's Game of Life - 示例游戏](https://kylewbanks.com/images/post/golang-opengl-conway-1.gif) 在我们的运行过程中,白色的细胞表示它是存活着的,黑色的细胞表示它已经死亡。 ### 概述 -本教程将会涉及到很多基础内容,从最基本的开始,但是你还是要对 Go 由一些最基本的了解 - 至少你应该知道变量,切片,函数和结构体,并且装了一个 Go 的运行环境。我写这篇教程用的 Go 版本是 1.8,但它应该与之前的版本兼容。这里用 Go 语言实现没有什么特别新奇的东西,因此只要你有过类似的编程经历就行。 +本教程将会涉及到很多基础内容,从最基本的开始,但是你还是要对 Go 由一些最基本的了解 —— 至少你应该知道变量、切片、函数和结构体,并且装了一个 Go 的运行环境。我写这篇教程用的 Go 版本是 1.8,但它应该与之前的版本兼容。这里用 Go 语言实现没有什么特别新奇的东西,因此只要你有过类似的编程经历就行。 这里是我们在这个教程里将会讲到的东西: -* [第一节: Hello, OpenGL][10]: 安装 OpenGL 和 [GLFW][11],在窗口上绘制一个三角形。 -* [第二节: 绘制游戏面板][12]: 用三角形拼成方形,在窗口上用方形绘成格子。 -* [第三节: 实现游戏功能][13]: 实现 Conway 游戏 +* [第一节: Hello, OpenGL][10]: 安装 OpenGL 和 [GLFW][11],在窗口上绘制一个三角形。 +* [第二节: 绘制游戏面板][12]: 用三角形拼成方形,在窗口上用方形绘成格子。 +* [第三节: 实现游戏功能][13]: 实现 Conway 游戏 最后的源代码可以在 [GitHub][25] 上获得,每一节的末尾有个_回顾_,包含该节相关的代码。如果有什么不清楚的地方或者是你感到疑惑的,看看每一节末尾的完整代码。 @@ -50,9 +52,9 @@ OpenGL 与 Go 教程 第一节: Hello, OpenGL ### 安装 OpenGL 和 GLFW -我们介绍过 OpenGL,但是为了使用它,我们要有个窗口可以绘制东西。 [GLFW][26] 是一款对于 OpenGL 跨平台的 API,允许我们创建窗口并使用,而且它是 [go-gl][27] 套件中提供的。 +我们介绍过 OpenGL,但是为了使用它,我们要有个窗口可以绘制东西。 [GLFW][26] 是一款用于 OpenGL 的跨平台 API,允许我们创建并使用窗口,而且它也是 [go-gl][27] 套件中提供的。 -我们要做的第一件事就是确定 OpenGL 的版本。为了方便本教程,我们将会使用 **OpenGL v4.1**,但你也可以用 **v2.1** 要是你的操作系统不支持最新的 OpenGL。要安装 OpenGL,我们需要做这些事: +我们要做的第一件事就是确定 OpenGL 的版本。为了方便本教程,我们将会使用 `OpenGL v4.1`,但要是你的操作系统不支持最新的 OpenGL,你也可以用 `v2.1`。要安装 OpenGL,我们需要做这些事: ``` # 对于 OpenGL 4.1 @@ -68,7 +70,7 @@ $ go get github.com/go-gl/gl/v2.1/gl $ go get github.com/go-gl/glfw/v3.2/glfw ``` -安装好这两个包之后,我们就可以开始了!先创建 **main.go** 文件,导入相应的包(我们待会儿会用到的其他东西)。 +安装好这两个包之后,我们就可以开始了!先创建 `main.go` 文件,导入相应的包(我们待会儿会用到的其它东西)。 ``` package main @@ -82,8 +84,7 @@ import ( ) ``` -Next lets define the **main** function, the purpose of which is to initialize OpenGL and GLFW and display the window: -接下来定义一个叫做 **main** 的函数,这是用来初始化 OpenGL 以及 GLFW,显示窗口的: +接下来定义一个叫做 `main` 的函数,这是用来初始化 OpenGL 以及 GLFW,并显示窗口的: ``` const ( @@ -124,11 +125,11 @@ func initGlfw() *glfw.Window { } ``` -好了,让我们花一分钟来运行一下这个程序,看看会发生什么。首先定义了一些常量, **width** 和 **height** - 它们决定窗口的像素大小。 +好了,让我们花一分钟来运行一下这个程序,看看会发生什么。首先定义了一些常量, `width` 和 `height` —— 它们决定窗口的像素大小。 -然后就是 **main** 函数。这里我们使用了 **runtime** 包的 **LockOSThread()**,这能确保我们总是在操作系统的一个线程中运行代码,这对 GLFW 来说很重要,GLFW 被初始化之后需要在同一个进程里被调用多次。讲完这个,接下来我们调用 **initGlfw** 来获得一个窗口的引用,并且 defer glfw 的 terminating 方法。窗口的引用会被用在一个 for 循环中,只要窗口是打开的状态,就执行某些事情。我们待会儿会讲要做的事情是什么。 +然后就是 `main` 函数。这里我们使用了 `runtime` 包的 `LockOSThread()`,这能确保我们总是在操作系统的同一个线程中运行代码,这对 GLFW 来说很重要,GLFW 需要在其被初始化之后的线程里被调用。讲完这个,接下来我们调用 `initGlfw` 来获得一个窗口的引用,并且推迟(`defer`)其终止。窗口的引用会被用在一个 `for` 循环中,只要窗口处于打开的状态,就执行某些事情。我们待会儿会讲要做的事情是什么。 -**initGlfw** 是另一个函数,这里我们调用 **glfw.Init()** 来初始化 GLFW 包。然后我们定义了 GLFW 的一些全局属性,包括禁用调整窗口大小和改变 OpenGL 的属性。然后创建了 **glfw.Window**,这会在稍后的绘图中用到。我们仅仅告诉它我们想要的宽度和高度,以及标题,然后调用 **window.MakeContextCurrent**,将窗口绑定到当前的进程中。最后就是返回窗口的引用了。 +`initGlfw` 是另一个函数,这里我们调用 `glfw.Init()` 来初始化 GLFW 包。然后我们定义了 GLFW 的一些全局属性,包括禁用调整窗口大小和改变 OpenGL 的属性。然后创建了 `glfw.Window`,这会在稍后的绘图中用到。我们仅仅告诉它我们想要的宽度和高度,以及标题,然后调用 `window.MakeContextCurrent`,将窗口绑定到当前的线程中。最后就是返回窗口的引用了。 如果你现在就构建、运行这个程序,你看不到任何东西。很合理,因为我们还没有用这个窗口做什么实质性的事。 @@ -149,9 +150,9 @@ func initOpenGL() uint32 { } ``` -**initOpenGL** 就像之前的 **initGlfw** 函数一样,初始化 OpenGL 库,创建一个_程序_。这个程序是一个包含了着色器的引用,稍后会用于绘图。待会儿会讲这一点,现在只用知道 OpenGL 已经初始化完成了,我们有一个 **program** 的引用。我们还打印了 OpenGL 的版本,这对于 debug 很有帮助。 +`initOpenGL` 就像之前的 `initGlfw` 函数一样,初始化 OpenGL 库,创建一个程序program。“程序”是一个包含了着色器shader的引用,稍后会用着色器shader绘图。待会儿会讲这一点,现在只用知道 OpenGL 已经初始化完成了,我们有一个程序的引用。我们还打印了 OpenGL 的版本,可以用于之后的调试。 -回到 **main** 函数里,调用这个新函数: +回到 `main` 函数里,调用这个新函数: ``` func main() { @@ -168,7 +169,7 @@ func main() { } ``` -你应该注意到了现在我们有 **program** 的引用,在我们的窗口循环中,调用新的 **draw** 函数。最终这个函数会绘制出所有细胞,让游戏状态变得可视化,但是现在它做的仅仅是情况窗口,所以我们只能看到一个全黑的屏幕: +你应该注意到了现在我们有 `program` 的引用,在我们的窗口循环中,调用新的 `draw` 函数。最终这个函数会绘制出所有细胞,让游戏状态变得可视化,但是现在它做的仅仅是清除窗口,所以我们只能看到一个全黑的屏幕: ``` func draw(window *glfw.Window, program uint32) { @@ -180,19 +181,19 @@ func draw(window *glfw.Window, program uint32) { } ``` -我们首先做的是调用 **gl.clear** 函数来清除上一帧在窗口中绘制的东西,给我们一个干净的面板。然后我们告诉 OpenGL 去使用程序引用,这个引用还没有做什么事。最终我们告诉 GLFW 用 **PollEvents** 去检查是否有鼠标或者键盘事件(这一节里还不会对这些事件进行处理),告诉窗口 **SwapBuffers**。 [Buffer swapping][28](交换缓冲区) 很重要,因为 GLFW(像其他图形库一样)使用双缓冲,也就是说你绘制的所有东西实际上是绘制到一个不可见的画布上,当你准备好进行展示的时候就把绘制的这些东西放到可见的画布中 - 这种情况下,就需要调用 **SwapBuffers** 函数。 +我们首先做的是调用 `gl.clear` 函数来清除上一帧在窗口中绘制的东西,给我们一个干净的面板。然后我们告诉 OpenGL 去使用我们的程序引用,这个引用还没有做什么事。最终我们告诉 GLFW 用 `PollEvents` 去检查是否有鼠标或者键盘事件(这一节里还不会对这些事件进行处理),告诉窗口去交换缓冲区 `SwapBuffers`。 [交换缓冲区][28] 很重要,因为 GLFW(像其他图形库一样)使用双缓冲,也就是说你绘制的所有东西实际上是绘制到一个不可见的画布上,当你准备好进行展示的时候就把绘制的这些东西放到可见的画布中 —— 这种情况下,就需要调用 `SwapBuffers` 函数。 好了,到这里我们已经讲了很多东西,花一点时间看看我们的实验成果。运行这个程序,你应该可以看到你所绘制的第一个东西: - ![OpenGL 与 Go 语言教程中的 Conway's Game of Life - 第一个窗口](https://kylewbanks.com/images/post/golang-opengl-conway-2.png) +![Conway's Game of Life - 第一个窗口](https://kylewbanks.com/images/post/golang-opengl-conway-2.png) 完美! ### 在窗口里绘制三角形 -我们已经完成了一些复杂的步骤,即使看上去和图片不像,但我们仍然需要绘制一些东西。我们会以三角形绘制开始,可能这第一眼看上去要比我们最终要绘制的方形更难,但你会知道这样的想法是错的。你可能不知道的是三角形或许是绘制的图形中最简单的,实际上我们最终会用某种方式把三角形拼成方形。 +我们已经完成了一些复杂的步骤,即使看起来不多,但我们仍然需要绘制一些东西。我们会以三角形绘制开始,可能这第一眼看上去要比我们最终要绘制的方形更难,但你会知道这样的想法是错的。你可能不知道的是三角形或许是绘制的图形中最简单的,实际上我们最终会用某种方式把三角形拼成方形。 -好吧,那么我们想要绘制一个三角形,怎么做呢?我们通过定义图形的顶点来绘制图形,把它们交给 OpenGL 来进行绘制。先在 **main.go** 的顶部里定义我们的三角形: +好吧,那么我们想要绘制一个三角形,怎么做呢?我们通过定义图形的顶点来绘制图形,把它们交给 OpenGL 来进行绘制。先在 `main.go` 的顶部里定义我们的三角形: ``` var ( @@ -204,9 +205,9 @@ var ( ) ``` -这看上去很奇怪,让我们分开来看。首先我们用了一个 **float32** 切片(slice),这是一种我们总会在向 OpenGL 传递顶点时用到的数据类型。这个切片包含 9 个值,每三个值构成三角形的一个点。第一行, **0, 0.5, 0** 表示的是 X、Y、Z 坐标,是最上方的顶点,第二行是左边的顶点,第三行是右边的顶点。每一组的三个点都表示相对于窗口中心点的 X、Y、Z 坐标,在 **-1 和 1** 之间。因此最上面的顶点 X 坐标是 0,因为它在 X 方向上位于窗口中央,Y 坐标是 _0.5_ 意味着它会相对窗口中央上移 1/4 个单位(因为窗口的范围是 -1 到 1),Z 坐标是 0.因为我们只需要在二维空间中绘图,所以 Z 值永远是 0。现在看一看左右两边的顶点,看看你能不能理解为什么它们是这样定义的 —— 如果不能立刻就弄清楚也没关系,我们将会在屏幕上去观察它,因此我们需要一个完美的图形来进行观察。 +这看上去很奇怪,让我们分开来看。首先我们用了一个 `float32` 切片slice,这是一种我们总会在向 OpenGL 传递顶点时用到的数据类型。这个切片包含 9 个值,每三个值构成三角形的一个点。第一行, `0, 0.5, 0` 表示的是 X、Y、Z 坐标,是最上方的顶点,第二行是左边的顶点,第三行是右边的顶点。每一组的三个点都表示相对于窗口中心点的 X、Y、Z 坐标,大小在 `-1` 和 `1` 之间。因此最上面的顶点 X 坐标是 `0`,因为它在 X 方向上位于窗口中央,Y 坐标是 `0.5` 意味着它会相对窗口中央上移 1/4 个单位(因为窗口的范围是 `-1` 到 `1`),Z 坐标是 0。因为我们只需要在二维空间中绘图,所以 Z 值永远是 `0`。现在看一看左右两边的顶点,看看你能不能理解为什么它们是这样定义的 —— 如果不能立刻就弄清楚也没关系,我们将会在屏幕上去观察它,因此我们需要一个完美的图形来进行观察。 -好了,我们定义了一个三角形,但是现在我们得把它画出来。要画出这个三角形,我们需要一个叫做 **Vertex Array Object** 或者叫 **vao** 的东西,这是由一系列的点(也就是我们定义的三角形)创造的,这个东西可以提供给 OpenGL 来进行绘制。创建一个叫做 **makeVao** 的函数,然后我们可以提供一组切片的点,让它返回一个指向 OpenGL vertex array object 的指针: +好了,我们定义了一个三角形,但是现在我们得把它画出来。要画出这个三角形,我们需要一个叫做顶点数组对象Vertex Array Object或者叫 vao 的东西,这是由一系列的点(也就是我们定义的三角形)创造的,这个东西可以提供给 OpenGL 来进行绘制。创建一个叫做 `makeVao` 的函数,然后我们可以提供一个点的切片,让它返回一个指向 OpenGL 顶点数组对象的指针: ``` // makeVao 执行初始化并从提供的点里面返回一个顶点数组 @@ -227,11 +228,11 @@ func makeVao(points []float32) uint32 { } ``` -首先我们创造了 **Vertex Buffer Object** 或者说 **vbo** 绑定到我们的 **vao** 上,**vbo** 是通过所占空间(也就是**4 x len(points)**大小的空间)和一个指向顶点的指针(**gl.Ptr(points)**)来创建的。你也许会好奇为什么它是 **4 x len(points)** - 而不是 6 或者 3 或者 1078 呢?原因在于我们用的是 **float32** 切片,32 个 bit 的 float 浮点型变量是 4 个字节,因此我们说这个缓冲区以字节为单位的大小是点个数的 4 倍。 +首先我们创造了顶点缓冲区对象Vertex Buffer Object 或者说 vbo 绑定到我们的 `vao` 上,`vbo` 是通过所占空间(也就是 4 倍 `len(points)` 大小的空间)和一个指向顶点的指针(`gl.Ptr(points)`)来创建的。你也许会好奇为什么它是 4 倍 —— 而不是 6 或者 3 或者 1078 呢?原因在于我们用的是 `float32` 切片,32 个位的浮点型变量是 4 个字节,因此我们说这个缓冲区以字节为单位的大小是点个数的 4 倍。 -现在我们有缓冲区了,可以创建 **vao** 并用 **gl.BindBuffer** 把它绑定到缓冲区上,最后返回 **vao**。这个 **vao** 将会被用于绘制三角形! +现在我们有缓冲区了,可以创建 `vao` 并用 `gl.BindBuffer` 把它绑定到缓冲区上,最后返回 `vao`。这个 `vao` 将会被用于绘制三角形! -回到 **main** 函数: +回到 `main` 函数: ``` func main() { @@ -243,7 +244,7 @@ func main() { } } -这里我们调用了 **makeVao** ,从我们之前定义的 **triangle** 顶点中获得 **vao** 引用,将它作为一个新的参数传递给 **draw** 函数: +这里我们调用了 `makeVao` ,从我们之前定义的 `triangle` 顶点中获得 `vao` 引用,将它作为一个新的参数传递给 `draw` 函数: func draw(vao uint32, window *glfw.Window, program uint32) { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) @@ -257,13 +258,13 @@ func draw(vao uint32, window *glfw.Window, program uint32) { } ``` -然后我们把 OpenGL 绑定到 **vao** 上,这样当我们告诉 OpenGL 三角形切片的顶点数(除以 3,是因为每一个点有 X、Y、Z 坐标),让它去 **DrawArrays** ,它就知道要画多少个顶点了。 +然后我们把 OpenGL 绑定到 `vao` 上,这样当我们告诉 OpenGL 三角形切片的顶点数(除以 3,是因为每一个点有 X、Y、Z 坐标),让它去 `DrawArrays` ,它就知道要画多少个顶点了。 如果你这时候运行程序,你可能希望在窗口中央看到一个美丽的三角形,但是不幸的是你还看不到。还有一件事情没做,我们告诉 OpenGL 我们要画一个三角形,但是我们还要告诉它_怎么_画出来。 -要让它画出来,我们需要叫做片元着色器和顶点着色器的东西,这些已经超出本教程的范围了(老实说,也超出了我对 OpenGL 的了解),但 [Harold Serrano On Quora][29] 关于它们是什么给出了完美的介绍。我们只需要理解,对于这个应用来说,着色器是它内部的小程序(用 [OpenGL Shader Language or GLSL][30] 编写的),操作顶点进行绘制,也可用于确定图形的颜色。 +要让它画出来,我们需要叫做片元着色器fragment shader顶点着色器vertex shader的东西,这些已经超出本教程的范围了(老实说,也超出了我对 OpenGL 的了解),但 [Harold Serrano 在 Quora][29] 上对对它们是什么给出了完美的介绍。我们只需要理解,对于这个应用来说,着色器是它内部的小程序(用 [OpenGL Shader Language 或 GLSL][30] 编写的),它操作顶点进行绘制,也可用于确定图形的颜色。 -添加两个 imports 和一个叫做 **compileShader** 的函数: +添加两个 `import` 和一个叫做 `compileShader` 的函数: ``` import ( @@ -297,7 +298,7 @@ func compileShader(source string, shaderType uint32) (uint32, error) { 这个函数的目的是以字符串的形式接受着色器源代码和它的类型,然后返回一个指向这个编译好的着色器的指针。如果编译失败,我们就会获得出错的详细信息。 -现在定义着色器,在 **makeProgram** 里编译。回到我们的 **const** 块中,我们在这里定义了 **width** 和 **hegiht**。 +现在定义着色器,在 `makeProgram` 里编译。回到我们的 `const` 块中,我们在这里定义了 `width` 和 `hegiht`。 ``` vertexShaderSource = ` @@ -317,11 +318,11 @@ fragmentShaderSource = ` ` + "\x00" ``` -你能看到这是两个着色器程序,包含了 GLSL 源代码的字符串,一个是_顶点着色器_,另一个是_片元着色器_。唯一比较特殊的地方是它们都要在末尾加上一个空终止字符,**\x00** —— OpenGL 需要它才能编译着色器。注意 **fragmentShaderSource**,这是我们用 RGBA 形式的值通过 **vec4** 来定义我们图形的颜色。你可以修改这里的值来改变这个三角形的颜色,现在的值是 **RGBA(1, 1, 1, 1)** 或者说是 _white_。 +如你所见,这是两个包含了 GLSL 源代码字符串的着色器,一个是顶点着色器vertex shader,另一个是片元着色器fragment shader。唯一比较特殊的地方是它们都要在末尾加上一个空终止字符,`\x00` —— OpenGL 需要它才能编译着色器。注意 `fragmentShaderSource`,这是我们用 RGBA 形式的值通过 `vec4` 来定义我们图形的颜色。你可以修改这里的值来改变这个三角形的颜色,现在的值是 `RGBA(1, 1, 1, 1)` 或者说是白色。 -同样需要注意的是这两个程序都是运行在 **#version 410** 版本下,如果你用的是 OpenGL 2.1,那你也可以改成 **#version 120**。**120** 不是打错的,如果你用的是 OpenGL 2.1,要用 **120** 而不是 **210**! +同样需要注意的是这两个程序都是运行在 `#version 410` 版本下,如果你用的是 OpenGL 2.1,那你也可以改成 `#version 120`。这里 `120` 不是打错的,如果你用的是 OpenGL 2.1,要用 `120` 而不是 `210`! -接下来在 **initOpenGL** 中我们会编译着色器,把它们附加到我们的 **program** 中。 +接下来在 `initOpenGL` 中我们会编译着色器,把它们附加到我们的 `program` 中。 ``` func initOpenGL() uint32 { @@ -348,27 +349,24 @@ func initOpenGL() uint32 { } ``` -这里我们用 _顶点着色器_ 调用了 **compileShader** 函数,指定它的类型是 **gl.VERTEX_SHADER**,对 _片元着色器_ 做了同样的事情,但是指定的类型是 **gl.FRAGMENT_SHADER**。编译完成后,我们把它们附加到程序中,调用 **gl.AttachShader**,传递程序以及编译好的着色器。 +这里我们用顶点着色器(`vertexShader`)调用了 `compileShader` 函数,指定它的类型是 `gl.VERTEX_SHADER`,对片元着色器(`fragmentShader`)做了同样的事情,但是指定的类型是 `gl.FRAGMENT_SHADER`。编译完成后,我们把它们附加到程序中,调用 `gl.AttachShader`,传递程序(`prog`)以及编译好的着色器作为参数。 现在我们终于可以看到我们漂亮的三角形了!运行程序,如果一切顺利的话你会看到这些: - ![OpenGL 与 Go 语言教程中的 Conway's Game of Life - Hello, Triangle!](https://kylewbanks.com/images/post/golang-opengl-conway-3.png) +![Conway's Game of Life - Hello, Triangle!](https://kylewbanks.com/images/post/golang-opengl-conway-3.png) ### 总结 -是不是很惊喜!这些代码画出了一个三角形,但我保证我们已经完成了大部分的 OpenGL 代码,在接下来的章节中我们还会用到这些代码。我十分推荐你花几分钟修改一下代码,看看你能不能移动三角形,改变三角形的大小和颜色。OpenGL 可以令人心生畏惧,有时想要理解发生了什么很困难,但是要记住,这不是魔术 - 它就是它看上去的东西。 +是不是很惊喜!这些代码画出了一个三角形,但我保证我们已经完成了大部分的 OpenGL 代码,在接下来的章节中我们还会用到这些代码。我十分推荐你花几分钟修改一下代码,看看你能不能移动三角形,改变三角形的大小和颜色。OpenGL 可以令人心生畏惧,有时想要理解发生了什么很困难,但是要记住,这不是魔法 - 它只不过看上去像魔法。 -下一节里我们讲会用两个锐角三角形拼出一个方形 - 看看你能不能试着修改这一节的代码,再进入下一节。不能也没有关系,因为我们在 [第二节][31] 还会编写代码, 按照创建一个有许多方形的格子,我们把它当做游戏面板。 +下一节里我们讲会用两个锐角三角形拼出一个方形 - 看看你能不能在进入下一节前试着修改这一节的代码。不能也没有关系,因为我们在 [第二节][31] 还会编写代码, 接着创建一个有许多方形的格子,我们把它当做游戏面板。 最后,在[第三节][32] 里我们会用格子来实现 _Conway’s Game of Life_! - _[第一节: Hello, OpenGL][14]_ | _[第二节: 绘制游戏面板][15]_ | _[第三节:实现游戏功能][16]_ - - _本教程的完整源代码可在 [GitHub][17] 上获得。_ ### 回顾 -本教程 **main.go** 文件的内容如下: +本教程 `main.go` 文件的内容如下: ``` package main @@ -528,9 +526,9 @@ func compileShader(source string, shaderType uint32) (uint32, error) { via: https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-1-hello-opengl -作者:[kylewbanks ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +作者:[kylewbanks][a] +译者:[GitFuture](https://github.com/GitFuture) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From b9265a04cd8b52c441a3a4d2d72d592355a5db02 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 5 Oct 2017 21:29:25 +0800 Subject: [PATCH 05/39] PUB:20170312 OpenGL Go Tutorial Part 1.md @GitFuture https://linux.cn/article-8933-1.html --- .../tech => published}/20170312 OpenGL Go Tutorial Part 1.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170312 OpenGL Go Tutorial Part 1.md (100%) diff --git a/translated/tech/20170312 OpenGL Go Tutorial Part 1.md b/published/20170312 OpenGL Go Tutorial Part 1.md similarity index 100% rename from translated/tech/20170312 OpenGL Go Tutorial Part 1.md rename to published/20170312 OpenGL Go Tutorial Part 1.md From f34441ed82bb1f6c89e051e23bbb74f3c7692795 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 5 Oct 2017 22:09:03 +0800 Subject: [PATCH 06/39] PRF:20170907 Seven things about Linux you may not have known so far.md @ucasFL --- ...out Linux you may not have known so far.md | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/translated/tech/20170907 Seven things about Linux you may not have known so far.md b/translated/tech/20170907 Seven things about Linux you may not have known so far.md index 0403b78bc1..8ba018c076 100644 --- a/translated/tech/20170907 Seven things about Linux you may not have known so far.md +++ b/translated/tech/20170907 Seven things about Linux you may not have known so far.md @@ -7,49 +7,51 @@ 即使是专家,也不可能事事皆知。无论你有多少经验,可能总会有更多的东西需要你去学习。所以,在这儿我列出了七件关于 Linux 你可能不知道的事情。 -### 有一个查找命令历史的交互模式 +### 一个查找命令历史的交互模式 -你可能对 `history` 命令非常熟悉,它会读取 bash 历史,然后以编号列表的方式输出到标准输出(`stdout`)。然而,如果你在 `curl` 命令的海洋里寻找一个特定的链接(URL),那么这个列表并不总是非常容易阅读的。 +你可能对 `history` 命令非常熟悉,它会读取 bash 历史,然后以编号列表的方式输出到标准输出(`stdout`)。然而,如果你在 `curl` 命令的海洋里寻找一个特定的链接(URL),那么这个列表并不总是那么容易阅读的。 -你还可以有另一个选择,Linux 有一个交互式的反向搜索可以帮助你解决这个问题。你可以通过快捷键 `CTRL+R`启动交互模式,然后进入一个交互提示中,它将会根据你提供的字符串来向后搜索 bash 历史,你可以通过再次按下 `CTRL+R` 向后搜索更老的命令,或者按下 `CTRL+S` 向前搜索。 +你还可以有另一个选择,Linux 有一个交互式的反向搜索可以帮助你解决这个问题。你可以通过快捷键 `ctrl+r`启动交互模式,然后进入一个交互提示中,它将会根据你提供的字符串来向后搜索 bash 历史,你可以通过再次按下 `ctrl+r` 向后搜索更老的命令,或者按下 `ctrl+s` 向前搜索。 -注意,`CTRL+S` 有时会与 XON/XOFF 流控制冲突,即 XON/OFF 流控制也会使用该快捷键。你可以通过运行 `stty -ixon` 命令来禁用该快捷键。在你的个人电脑上,这通常是有用的,但是在禁用前,确保你不需要 XON/XOFF 。 +注意,`ctrl+s` 有时会与 XON/XOFF 流控制冲突,即 XON/XOFF 流控制也会使用该快捷键。你可以通过运行 `stty -ixon` 命令来禁用该快捷键。在你的个人电脑上,这通常是有用的,但是在禁用前,确保你不需要 XON/XOFF 。 ### Cron 不是安排任务的唯一方式 -Cron jobs 对于任何水平的系统管理员,无论是毫无经验的初学者,还是经验丰富的专家来说,都是非常有用的。但是,如果你需要安排一个一次性的任务,那么 `at` 命令为你提供了一个快捷的方式来创建任务,从而你不需要接触 crontab 。 +Cron 任务对于任何水平的系统管理员,无论是毫无经验的初学者,还是经验丰富的专家来说,都是非常有用的。但是,如果你需要安排一个一次性的任务,那么 `at` 命令为你提供了一个快捷的方式来创建任务,从而你不需要接触 crontab 。 `at` 命令的运行方式是在后面紧跟着你想要运行任务的运行时间。时间是灵活的,因为它支持许多时间格式。包括下面这些例子: -“at 12:00 PM September 30 2017” -“at now + 1 hour” -“at 9:00 AM tomorrow” +``` +at 12:00 PM September 30 2017 +at now + 1 hour +at 9:00 AM tomorrow +``` -当你以带参数的方式输入 `at` 命令以后,将会提示你该命令将在你的 Linux 系统上运行。这可能是一个备份脚本,一套维护任务,或者甚至是一个普通的 bash 命令。如果要结束任务,可以按 `CTRL+D` 。 +当你以带参数的方式输入 `at` 命令以后,将会提示你该命令将在你的 Linux 系统上运行。这可能是一个备份脚本,一套维护任务,或者甚至是一个普通的 bash 命令。如果要结束任务,可以按 `ctrl+d` 。 另外,你可以使用 `atq` 命令查看当前用户的所有任务,或者使用 `sudo atq` 查看所有用户的任务。它将会展示出所有排定好的任务,并且每个任务都伴有一个 ID 。如果你想取消一个排定好的任务,可以使用 `atrm` 命令,并且以任务 ID 作为参数。 -### 你可以通过函数搜索命令,而不仅仅是通过名字 +### 你可以按照功能搜索命令,而不仅仅是通过名字 记住命令的名字非常困难,特别是对于初学者来说。幸运的是,Linux 附带了一个通过名字和描述来搜索 man 页面的工具。 -下次,如果你没有记住你想要使用的工具的名称,你可以尝试使用 `apropos` 命令加上你想要干的事情的描述。比如,`apropos build filesystem` 将会返回一系列工具的名字和描述,包括 build 和 filesystem 。 +下次,如果你没有记住你想要使用的工具的名称,你可以尝试使用 `apropos` 命令加上你想要干的事情的描述。比如,`apropos build filesystem` 将会返回一系列名字和描述包括了 “build” 和 “filesystem” 单词的工具。 `apropos` 命令接受一个或多个字符串作为参数,但同时它也有其他参数,比如你可以使用 `-r` 参数,从而通过正则表达式来搜索。 -### 有一个可供选择的系统允许你来管理系统版本 +### 一个允许你来管理系统版本的替代系统 如果你曾进行过软件开发,你就会明白跨项目管理不同版本的语言的支持的重要性。许多 Linux 发行版都有工具可以来处理不同的内建版本。 -可执行文件比如 `java` 往往象征性地链接到目录 `/etc/alternatives` 下。反过来,该目录会将符号链接存储为二进制文件并提供一个管理这些链接的接口。Java 可能是 alternatives 最常管理的语言,但是,经过一些配置,它也可以作为其他应用程序,比如 NVM 和 RVM 的替代品(NVM 和 RVM 分别是 NodeJS 和 Ruby 的版本管理器)。 +可执行文件比如 `java` 往往符号链接到目录 `/etc/alternatives` 下。反过来,该目录会将符号链接存储为二进制文件并提供一个管理这些链接的接口。Java 可能是替代系统最常管理的语言,但是,经过一些配置,它也可以作为其他应用程序替代品,比如 NVM 和 RVM (NVM 和 RVM 分别是 NodeJS 和 Ruby 的版本管理器)。 -在基于 Debian 的系统中,你可以使用 `update-alternatives` 命令创建和管理这些链接。在 CentOS 中,这个工具就叫做 `alternatives` 。通过更改你的 alternatives 文件中的链接,你便可以安装一个语言的多个版本并且在不同的情况下使用不同的二进制。该可供选择的系统也提供了对任何你可能在命令行运行的程序的支持。 +在基于 Debian 的系统中,你可以使用 `update-alternatives` 命令创建和管理这些链接。在 CentOS 中,这个工具就叫做 `alternatives` 。通过更改你的 alternatives 文件中的链接,你便可以安装一个语言的多个版本,并且在不同的情况下使用不同的二进制。这个替代系统也提供了对任何你可能在命令行运行的程序的支持。 ### `shred` 命令是更加安全的删除文件方式 我们大多数时候总是使用 `rm` 命令来删除文件。但是文件去哪儿了呢?真相是 `rm` 命令所做的事情并不是像你所想像的那样,它仅仅删除了文件系统和硬盘上的数据的硬链接。硬盘上的数据依旧存在,直到被另一个应用重写覆盖。对于非常敏感的数据来说,这会带来一个很大的安全隐患。 -`shred` 命令是 `rm` 命令的升级版。当你使用 `shred` 命令删除一个文件之后,文件中的数据会被随机多次重写。甚至有一个选项可以在随机重写之后对所有的数据进行清零。 +`shred` 命令是 `rm` 命令的升级版。当你使用 `shred` 命令删除一个文件之后,文件中的数据会被多次随机覆写。甚至有一个选项可以在随机覆写之后对所有的数据进行清零。 如果你想安全的删除一个文件并且以零覆盖,那么可以使用下面的命令: @@ -57,29 +59,27 @@ Cron jobs 对于任何水平的系统管理员,无论是毫无经验的初学 同时,你也可以使用 `-n` 选项和一个数字作为参数,从而指定在随机覆盖数据的时候迭代多少次。 -**** - ### 通过自动更正来避免输入很长的无效文件路径 有多少次,你输入一个文件的绝对路径,然而却看到“没有该文件或目录”的消息。任何人都会明白输入一个很长的字符串的痛苦。幸运的是,有一个很简单的解决办法。 -内建的 `shopt` 命令允许你设置不同的选项来改变 shell 的行为。设置 `cdspell` 选项是避免输入文件路径时一个字母出错的头痛的一个简单方式。你可以通过运行 `shopt -s cdspell` 命令来启用该选项。启用该选项后,当你想要更改目录时,会自动更正为最匹配的目录。 +内建的 `shopt` 命令允许你设置不同的选项来改变 shell 的行为。设置 `cdspell` 选项是避免输入文件路径时一个字母出错的头痛的一个简单方式。你可以通过运行 `shopt -s cdspell` 命令来启用该选项。启用该选项后,当你想要切换目录时,会自动更正为最匹配的目录。 -Shell 选项是节省时间的一个好方法(更不用说减少麻烦),此外还有许许多多的其他选项。如果想查看你的系统中所有选项的完整列表,可以运行不带参数的 `shopt` 命令。需要注意的是,这是 bash 的特性,如果你运行 zsh 或者其他可供选择的 shell,可能无法访问。 - -**** +Shell 选项是节省时间的一个好方法(更不用说减少麻烦),此外还有许许多多的其他选项。如果想查看你的系统中所有选项的完整列表,可以运行不带参数的 `shopt` 命令。需要注意的是,这是 bash 的特性,如果你运行 zsh 或者其他可供选择的 shell,可能无法使用。 ### 通过子 shell 返回到当前目录 -如果你曾经配置过一个中等难度的复杂系统,那么你可能会发现你需要频繁的更换目录,从而很难跟踪你所在的位置。如果在运行完一个命令后自动返回到当前位置,不是很好吗? +如果你曾经配置过一个比较复杂的系统,那么你可能会发现你需要频繁的更换目录,从而很难跟踪你所在的位置。如果在运行完一个命令后自动返回到当前位置,不是很好吗? Linux 系统实际上提供了一个解决该问题的方法,并且非常简单。如果你想通过 `cd` 命令进入另一个目录完成一些任务,然后再返回当前工作目录,那么你可以将命令置于括号中。你可以在你的 Linux 系统上尝试下面这个命令。记住你当前的工作目录,然后运行: -`(cd /etc && ls -a)` +``` +(cd /etc && ls -a) +``` 该命令会输出 `/etc` 目录的内容。现在,检查你的当前工作目录。它和执行该命令前的目录一样,而不是 `/etc` 目录。 -它是如何工作的呢?运行一个括号中的命令会创建一个子 shell 或者一个当前 shell 进程的复刻。该子 shell 可以访问所有的父变量,反之亦然。所以请记住,你是在运行一个非常复杂的单命令。 +它是如何工作的呢?运行一个括号中的命令会创建一个子 shell 或一个当前 shell 进程的复刻副本。该子 shell 可以访问所有的父变量,反之则不行。所以请记住,你是在运行一个非常复杂的单行命令。 在并行处理中经常使用子 shell ,但是在命令行中,它也能为你带来同样的力量,从而使你在浏览文件系统时更加容易。 @@ -87,7 +87,7 @@ Linux 系统实际上提供了一个解决该问题的方法,并且非常简 作者简介: -Phil Zona 是 Linux Academy 的技术作家。他编写了 AWS、Microsoft Azure 和 Linux 系统管理的指南和教程。他同时也管理着云评估博客,该博客旨在帮助个人通过技术实现他们的事业目标。 +Phil Zona 是 Linux Academy 的技术作家。他编写了 AWS、Microsoft Azure 和 Linux 系统管理的指南和教程。他同时也管理着 Cloud Assessments 博客,该博客旨在帮助个人通过技术实现他们的事业目标。 ----------------- @@ -95,7 +95,7 @@ via: http://opensourceforu.com/2017/09/top-7-things-linux-may-not-known-far/ 作者:[PHIL ZONA][a] 译者:[ucasFL](https://github.com/ucasFL) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 69333643ab69009be06f0196933f412da90ce01b Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 5 Oct 2017 22:09:33 +0800 Subject: [PATCH 07/39] PUB:20170907 Seven things about Linux you may not have known so far.md @ucasFL https://linux.cn/article-8934-1.html --- ...0907 Seven things about Linux you may not have known so far.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170907 Seven things about Linux you may not have known so far.md (100%) diff --git a/translated/tech/20170907 Seven things about Linux you may not have known so far.md b/published/20170907 Seven things about Linux you may not have known so far.md similarity index 100% rename from translated/tech/20170907 Seven things about Linux you may not have known so far.md rename to published/20170907 Seven things about Linux you may not have known so far.md From 5ecb72816e603cac7fb930597e1543708540ac0f Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 6 Oct 2017 11:15:49 +0800 Subject: [PATCH 08/39] PRF&PUB:20170818 Go vs .NET Core in terms of HTTP performance.md @runningwater https://linux.cn/article-8935-1.html --- ... .NET Core in terms of HTTP performance.md | 120 +++++++----------- 1 file changed, 45 insertions(+), 75 deletions(-) rename {translated/tech => published}/20170818 Go vs .NET Core in terms of HTTP performance.md (83%) diff --git a/translated/tech/20170818 Go vs .NET Core in terms of HTTP performance.md b/published/20170818 Go vs .NET Core in terms of HTTP performance.md similarity index 83% rename from translated/tech/20170818 Go vs .NET Core in terms of HTTP performance.md rename to published/20170818 Go vs .NET Core in terms of HTTP performance.md index ed12da0b10..14b8eb9258 100644 --- a/translated/tech/20170818 Go vs .NET Core in terms of HTTP performance.md +++ b/published/20170818 Go vs .NET Core in terms of HTTP performance.md @@ -1,4 +1,4 @@ -论 HTTP 性能,Go 与 .NET Core 谁争雌雄 +论 HTTP 性能,Go 与 .NET Core 一争雌雄 ============================================================ ![](https://cdn-images-1.medium.com/max/1200/1*60T60jSMO5yxUqJQmLZa4A.png) @@ -9,25 +9,25 @@ 因为是新出的,我不想立马就比较两个不同的东西,所以我耐心等待,想等发布更稳定的版本后再进行。 -本周一,微软[发布 .NET Core 2.0 版本][7],因此,我准备开始。您们认为呢? +本周一(8 月 14 日),微软[发布 .NET Core 2.0 版本][7],因此,我准备开始。您们认为呢? -如前面所提的,我们会比较他们相同的东西,比如应用程序、预期响应及运行时的稳定性,所以我们不会把像对 `JSON` 或者 `XML` 的编码、解码这些烦多的事情加入比较游戏中来,仅仅只会使用简单的文本消息。为了公平起见,我们会分别使用 Go 和 .NET Core 的[ MVC 架构模式][8]。 +如前面所提的,我们会比较它们相同的东西,比如应用程序、预期响应及运行时的稳定性,所以我们不会把像对 JSON 或者 XML 的编码、解码这些烦多的事情加入比较游戏中来,仅仅只会使用简单的文本消息。为了公平起见,我们会分别使用 Go 和 .NET Core 的 [MVC 架构模式][8]。 -### 先决条件 +### 参赛选手 -[Go][9] (或者 Golang): 是一种[快速增长][10]的开源编程语言,旨在构建出简单、快捷和稳定可靠的应用软件。 +[Go][9] (或称 Golang): 是一种[快速增长][10]的开源编程语言,旨在构建出简单、快捷和稳定可靠的应用软件。 用于支持 Go 语言的 MVC web 框架并不多,还好我们找到了 Iris ,可胜任此工作。 -[Iris][11]: 支持 Go 语言的快速、简单和高效的微型 Web 框架。它为您的下一代网站、API 或分布式应用程序奠定了精美的表现方式和易于使用的基础。 +[Iris][11]: 支持 Go 语言的快速、简单和高效的微型 Web 框架。它为您的下一代网站、API 或分布式应用程序奠定了精美的表现方式和易于使用的基础。 -[C#][12]: 是一种通用的,面向对象的编程语言。其开发团队由 [Anders Hejlsberg][13] 领导。 +[C#][12]: 是一种通用的、面向对象的编程语言。其开发团队由 [Anders Hejlsberg][13] 领导。 -[.NET Core][14]: 跨平台,可以在极少时间内开发出高性能的应用程序。 +[.NET Core][14]: 跨平台,可以在极少时间内开发出高性能的应用程序。 -从 [https://golang.org/dl][15] 下载 Go ,从 [https://www.microsoft.com/net/core][16] 下载 .NET Core。 +可从 [https://golang.org/dl][15] 下载 Go ,从 [https://www.microsoft.com/net/core][16] 下载 .NET Core。 -在下载和安装好这些软件后,还需要在 Go 端安装 Iris。安装很简单,仅仅只需要打开终端,然后执行如下语句: +在下载和安装好这些软件后,还需要为 Go 安装 Iris。安装很简单,仅仅只需要打开终端,然后执行如下语句: ``` go get -u github.com/kataras/iris @@ -37,31 +37,27 @@ go get -u github.com/kataras/iris #### 硬件 -* 处理器: Intel(R) Core(TM) i7–4710HQ CPU @ 2.50GHz 2.50GHz - -* 内存: 8.00 GB +* 处理器: Intel(R) Core(TM) i7–4710HQ CPU @ 2.50GHz 2.50GHz +* 内存: 8.00 GB #### 软件 -* 操作系统: 微软 Windows [10.0.15063 版本], 电源计划设置为“高性能” - -* HTTP 基准工具: [https://github.com/codesenberg/bombardier][1], 使用最新的 1.1 版本。 - -* .NET Core: [https://www.microsoft.com/net/core][2], 使用最新的 2.0 版本。 - -* Iris: [https://github.com/kataras/iris][3], 使用基于 [Go 1.8.3][4] 构建的新新 8.3 版本。 +* 操作系统: 微软 Windows [10.0.15063 版本], 电源计划设置为“高性能” +* HTTP 基准工具: [https://github.com/codesenberg/bombardier][1], 使用最新的 1.1 版本。 +* .NET Core: [https://www.microsoft.com/net/core][2], 使用最新的 2.0 版本。 +* Iris: [https://github.com/kataras/iris][3], 使用基于 [Go 1.8.3][4] 构建的最新 8.3 版本。 两个应用程序都通过请求路径 “api/values/{id}” 返回文本“值”。 -.NET Core MVC - +##### .NET Core MVC ![](https://cdn-images-1.medium.com/max/1600/1*v2VJL3-I3bLyuehntuqfng.png) + Logo 由 [Pablo Iglesias][5] 设计。 可以使用 `dotnet new webapi` 命令创建项目,其 `webapi` 模板会为您生成代码,代码包含 `GET` 请求方法的 `返回“值”`。 - _源代码_ +源代码: ``` using System; @@ -165,8 +161,7 @@ namespace netcore_mvc.Controllers } ``` - - _运行 .NET Core web 服务项目_ +运行 .NET Core web 服务项目: ``` $ cd netcore-mvc @@ -177,7 +172,7 @@ Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down. ``` - _运行和定位 HTTP 基准工具_ +运行和定位 HTTP 基准工具: ``` $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 @@ -193,13 +188,13 @@ Statistics Avg Stdev Max Throughput: 8.91MB/s ``` -Iris MVC - +##### Iris MVC ![](https://cdn-images-1.medium.com/max/1600/1*zf4BjL-7MQNJGikw5E-iNA.png) + Logo 由 [Santosh Anand][6] 设计。 - _源代码_ +源代码: ``` package main @@ -217,7 +212,6 @@ func main() { view raw ``` - ``` package controllers @@ -242,8 +236,7 @@ func (vc *ValuesController) Put() {} func (vc *ValuesController) Delete() {} ``` - - _运行 Go web 服务项目_ +运行 Go web 服务项目: ``` $ cd iris-mvc @@ -252,7 +245,7 @@ Now listening on: http://localhost:5000 Application started. Press CTRL+C to shut down. ``` - _运行和定位 HTTP 基准工具_ +运行和定位 HTTP 基准工具: ``` $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 @@ -275,55 +268,44 @@ Statistics Avg Stdev Max #### 总结 * 完成 `5000000 个请求`的时间 - 越短越好。 - * 请求次数/每秒 - 越大越好。 - * 等待时间 — 越短越好。 - * 吞吐量 — 越大越好。 - * 内存使用 — 越小越好。 - * LOC (代码行数) — 越少越好。 -.NET Core MVC 应用程序,使用 86 行代码,运行 2 分钟 8 秒,每秒接纳 39311.56 个请求,平均每秒有 3.19ms 等待,最大时到 229.73ms,内存使用大约为 126MB(不包括 dotnet 框架)。 +.NET Core MVC 应用程序,使用 86 行代码,运行 2 分钟 8 秒,每秒接纳 39311.56 个请求,平均 3.19ms 等待,最大时到 229.73ms,内存使用大约为 126MB(不包括 dotnet 框架)。 -Iris MVC 应用程序,使用 27 行代码,运行 47 秒,每秒接纳 105643.71 个请求,平均每秒有 1.18ms 等待,最大时到 22.01ms,内存使用大约为 12MB。 +Iris MVC 应用程序,使用 27 行代码,运行 47 秒,每秒接纳 105643.71 个请求,平均 1.18ms 等待,最大时到 22.01ms,内存使用大约为 12MB。 > 还有另外一个模板的基准,滚动到底部。 -2017 年 8 月 20 号更新 +**2017 年 8 月 20 号更新** [Josh Clark] [24] 和 [Scott Hanselman] [25]在此 [tweet 评论] [26]上指出,.NET Core `Startup.cs` 文件中 `services.AddMvc();` 这行可以替换为 `services.AddMvcCore();`。我听从他们的意见,修改代码,重新运行基准,该文章的 .NET Core 应用程序的基准输出已经修改。 +@topdawgevh @shanselman 他们也在使用 `AddMvc()` 而不是 `AddMvcCore()` ...,难道都不包含中间件? -@topdawgevh @shanselman 他们也在使用 AddMvc() 而不是 AddMvcCore() ...,难道都不包含中间件? - - — @clarkis117 + —  @clarkis117 @clarkis117 @topdawgevh Cool @MakisMaropoulos @ben_a_adams @davidfowl 我们来看看。认真学习下怎么使用更简单的性能默认值。 - — @shanselman + —  @shanselman @shanselman @clarkis117 @topdawgevh @ben_a_adams @davidfowl @shanselman @ben_a_adams @davidfowl 谢谢您们的反馈意见。我已经修改,更新了结果,没什么不同。对其它的建议,我非常欢迎。 - — @MakisMaropoulos - ->它有点稍微的不同但相差不大(从 8.61MB/s 到 8.91MB/s) - + —  @MakisMaropoulos +> 它有点稍微的不同但相差不大(从 8.61MB/s 到 8.91MB/s) 想要了解跟 `services.AddMvc()` 标准比较结果的,可以点击[这儿][27]。 -* * * - ### 想再多了解点儿吗? 我们再制定一个基准,产生 `1000000 次请求`,这次会通过视图引擎由模板生成 `HTML` 页面。 #### .NET Core MVC 使用的模板 - ``` using System; @@ -477,8 +459,7 @@ https://github.com/kataras/iris/tree/master/_benchmarks/netcore-mvc-templates ``` - _运行 .NET Core 服务项目_ - +运行 .NET Core 服务项目: ``` $ cd netcore-mvc-templates @@ -489,7 +470,7 @@ Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down. ``` - _运行和定位 HTTP 基准工具_ +运行 HTTP 基准工具: ``` Bombarding http://localhost:5000 with 1000000 requests using 125 connections @@ -620,10 +601,7 @@ https://github.com/kataras/iris/tree/master/_benchmarks/iris-mvc-templates ``` - - - _运行 Go 服务项目_ - +运行 Go 服务项目: ``` $ cd iris-mvc-templates @@ -633,7 +611,7 @@ Application started. Press CTRL+C to shut down. ``` - _运行和定位 HTTP 基准工具_ +运行 HTTP 基准工具: ``` Bombarding http://localhost:5000 with 1000000 requests using 125 connections @@ -648,22 +626,17 @@ Statistics Avg Stdev Max Throughput: 192.51MB/s ``` -总结 +#### 总结 * 完成 `1000000 个请求`的时间 - 越短越好。 - * 请求次数/每秒 - 越大越好。 - * 等待时间 — 越短越好。 - * 内存使用 — 越小越好。 - * 吞吐量 — 越大越好。 +.NET Core MVC 模板应用程序,运行 1 分钟 20 秒,每秒接纳 11738.60 个请求,同时每秒生成 89.03M 页面,平均 10.10ms 等待,最大时到 1.97s,内存使用大约为 193MB(不包括 dotnet 框架)。 -.NET Core MVC 模板应用程序,运行 1 分钟 20 秒,每秒接纳 11738.60 个请求,同时每秒生成 89.03M 页面,平均每秒有 10.10ms 等待,最大时到 1.97s,内存使用大约为 193MB(不包括 dotnet 框架)。 - -Iris MVC 模板应用程序,运行 37 秒,每秒接纳 26656.76 个请求,同时每秒生成 192.51M 页面,平均每秒有 1.18ms 等待,最大时到 22.52ms,内存使用大约为 17MB。 +Iris MVC 模板应用程序,运行 37 秒,每秒接纳 26656.76 个请求,同时每秒生成 192.51M 页面,平均 1.18ms 等待,最大时到 22.52ms,内存使用大约为 17MB。 ### 接下来呢? @@ -673,10 +646,6 @@ Iris MVC 模板应用程序,运行 37 秒,每秒接纳 26656.76 个请求, 我也需要亲自感谢下 [dev.to][34] 团队,感谢把我的这篇文章分享到他们的 Twitter 账户。 -论 HTTP 性能,Go 与 .NET Core 谁争雌雄 {作者:@MakisMaropoulos} https://t.co/IXL5LSpnjX - - — @ThePracticalDev - 感谢大家真心反馈,玩得开心! @@ -684,15 +653,15 @@ Iris MVC 模板应用程序,运行 37 秒,每秒接纳 26656.76 个请求, 很多人联系我,希望看到一个基于 .NET Core 的较低级别 Kestrel 的基准测试文章。 -因此我完成了,请点击下面的链接来了解 Kestrel 和 Iris 之间的性能差异,它还包含一个会话存储管理基准! +因此我完成了,请点击下面的[链接][35]来了解 Kestrel 和 Iris 之间的性能差异,它还包含一个会话存储管理基准! -------------------------------------------------------------------------------- via: https://hackernoon.com/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8 -作者:[ Gerasimos Maropoulos][a] +作者:[Gerasimos Maropoulos][a] 译者:[runningwater](https://github.com/runningwater) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -731,3 +700,4 @@ via: https://hackernoon.com/go-vs-net-core-in-terms-of-http-performance-7535a61b [32]:https://github.com/kataras/iris/tree/master/_benchmarks [33]:https://github.com/kataras/iris [34]:https://dev.to/kataras/go-vsnet-core-in-terms-of-http-performance +[35]:https://medium.com/@kataras/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5 \ No newline at end of file From b55930f4ee79830b4b3abb60ffc0960503d86f62 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 6 Oct 2017 18:13:03 +0800 Subject: [PATCH 09/39] PRF&PUB:20170726 Writing a Linux Debugger Part 9 Handling variables.md @geekpi --- ...inux Debugger Part 9 Handling variables.md | 111 ++++++------------ 1 file changed, 34 insertions(+), 77 deletions(-) rename {translated/tech => published}/20170726 Writing a Linux Debugger Part 9 Handling variables.md (77%) diff --git a/translated/tech/20170726 Writing a Linux Debugger Part 9 Handling variables.md b/published/20170726 Writing a Linux Debugger Part 9 Handling variables.md similarity index 77% rename from translated/tech/20170726 Writing a Linux Debugger Part 9 Handling variables.md rename to published/20170726 Writing a Linux Debugger Part 9 Handling variables.md index 455b184d94..8b378e38ec 100644 --- a/translated/tech/20170726 Writing a Linux Debugger Part 9 Handling variables.md +++ b/published/20170726 Writing a Linux Debugger Part 9 Handling variables.md @@ -1,118 +1,79 @@ 开发一个 Linux 调试器(九):处理变量 ============================================================ -变量是偷偷摸摸的。有时,它们会很高兴地呆在寄存器中,但是一转头就会跑到堆栈中。为了优化,编译器可能会完全将它们从窗口中抛出。无论变量在内存中的移动频率如何,我们都需要一些方法在调试器中跟踪和操作它们。这篇文章将会教你如何处理调试器中的变量,并使用 `libelfin` 演示一个简单的实现。 - -* * * +变量是偷偷摸摸的。有时,它们会很高兴地呆在寄存器中,但是一转头就会跑到堆栈中。为了优化,编译器可能会完全将它们从窗口中抛出。无论变量在内存中的如何移动,我们都需要一些方法在调试器中跟踪和操作它们。这篇文章将会教你如何处理调试器中的变量,并使用 `libelfin` 演示一个简单的实现。 ### 系列文章索引 -1. [设置][1] - +1. [准备环境][1] 2. [断点][2] - 3. [寄存器和内存][3] - 4. [ELF 和 DWARF][4] - -5. [源和信号][5] - -6. [源码级单步调试][6] - +5. [源码和信号][5] +6. [源码级逐步执行][6] 7. [源码级断点][7] - 8. [堆栈展开][8] - 9. [处理变量][9] - 10. [高级话题][10] -* * * +在开始之前,请确保你使用的 `libelfin` 版本是[我分支上的 `fbreg`][11]。这包含了一些 hack 来支持获取当前堆栈帧的基址并评估位置列表,这些都不是由原生的 `libelfin` 提供的。你可能需要给 GCC 传递 `-gdwarf-2` 参数使其生成兼容的 DWARF 信息。但是在实现之前,我将详细说明 DWARF 5 最新规范中的位置编码方式。如果你想要了解更多信息,那么你可以从[这里][12]获取该标准。 -在开始之前,请确保你使用的 `libelfin` 版本是[我分支上的 `fbreg`][11]。这包含了一些 hack 来支持获取当前堆栈帧的基址并评估位置列表,这些都不是由原生的 `libelfin` 提供的。你可能需要给 GCC 传递 `-gdwarf-2` 参数使其生成兼容的 DWARF 信息。但是在实现之前,我将详细说明 DWARF 5 最新规范中的位置编码方式。如果你想要了解更多信息,那么你可以从[这里][12]获取标准。 +### DWARF 位置 -### DWARF 未知 +某一给定时刻的内存中变量的位置使用 `DW_AT_location` 属性编码在 DWARF 信息中。位置描述可以是单个位置描述、复合位置描述或位置列表。 -使用 `DW_AT_location` 属性在 DWARF 信息中编码给定时刻内存中变量的位置。位置描述可以是单个位置描述,复合位置描述或位置列表。 +* 简单位置描述:描述了对象的一个​​连续的部分(通常是所有部分)的位置。简单位置描述可以描述可寻址存储器或寄存器中的位置,或缺少位置(具有或不具有已知值)。比如,`DW_OP_fbreg -32`: 一个整个存储的变量 - 从堆栈帧基址开始的32个字节。 +* 复合位置描述:根据片段描述对象,每个对象可以包含在寄存器的一部分中或存储在与其他片段无关的存储器位置中。比如, `DW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2`:前四个字节位于寄存器 3 中,后两个字节位于寄存器 10 中的一个变量。 +* 位置列表:描述了具有有限生存期或在生存期内更改位置的对象。比如: + * `` + * `[ 0]DW_OP_reg0` + * `[ 1]DW_OP_reg3` + * `[ 2]DW_OP_reg2` + * 根据程序计数器的当前值,位置在寄存器之间移动的变量。 -* 简单的位置描述描述对象的一个​​连续的部分(通常是所有)的位置。简单位置描述可以描述可寻址存储器或寄存器中的位置,或缺少位置(具有或不具有已知值)。 - * 比如: - * `DW_OP_fbreg -32` - - * 一个完全存储的变量 - 从堆栈帧基址开始的32个字节 - -* 复合位置描述根据片段描述对象,每个对象可以包含在寄存器的一部分中或存储在与其他片段无关的存储器位置中。 - * 比如: - * `DW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2` - - * 前四个字节位于寄存器 3 中,后两个字节位于寄存器 10 中的一个变量。 - -* 位置列表描述了具有有限周期或在周期内更改位置的对象。 - * 比如: - * `` - * `[ 0]DW_OP_reg0` - - * `[ 1]DW_OP_reg3` - - * `[ 2]DW_OP_reg2` - - * 根据程序计数器的当前值,位置在寄存器之间移动的变量 - -根据位置描述的种类,`DW_AT_location` 以三种不同的方式进行编码。`exprloc` 编码简单和复合的位置描述。它们由一个字节长度组成,后跟一个 DWARF 表达式或位置描述。`loclist` 和 `loclistptr` 的编码位置列表。它们在 `.debug_loclists` 部分中提供索引或偏移量,该部分描述了实际的位置列表。 +根据位置描述的种类,`DW_AT_location` 以三种不同的方式进行编码。`exprloc` 编码简单和复合的位置描述。它们由一个字节长度组成,后跟一个 DWARF 表达式或位置描述。`loclist` 和 `loclistptr` 的编码位置列表,它们在 `.debug_loclists` 部分中提供索引或偏移量,该部分描述了实际的位置列表。 ### DWARF 表达式 -使用 DWARF 表达式计算变量的实际位置。这包括操作堆栈值的一系列操作。有很多 DWARF 操作可用,所以我不会详细解释它们。相反,我会从每一个表达式中给出一些例子,给你一个可用的东西。另外,不要害怕这些; `libelfin` 将为我们处理所有这些复杂性。 +使用 DWARF 表达式计算变量的实际位置。这包括操作堆栈值的一系列操作。有很多 DWARF 操作可用,所以我不会详细解释它们。相反,我会从每一个表达式中给出一些例子,给你一个可用的东西。另外,不要害怕这些;`libelfin` 将为我们处理所有这些复杂性。 * 字面编码 - * `DW_OP_lit0`、`DW_OP_lit1`。。。`DW_OP_lit31` - * 将字面值压入堆栈 - + * `DW_OP_lit0`、`DW_OP_lit1`……`DW_OP_lit31` + * 将字面量压入堆栈 * `DW_OP_addr ` * 将地址操作数压入堆栈 - * `DW_OP_constu ` * 将无符号值压入堆栈 - * 寄存器值 * `DW_OP_fbreg ` * 压入在堆栈帧基址找到的值,偏移给定值 - - * `DW_OP_breg0`、`DW_OP_breg1`。。。 `DW_OP_breg31 ` + * `DW_OP_breg0`、`DW_OP_breg1`…… `DW_OP_breg31 ` * 将给定寄存器的内容加上给定的偏移量压入堆栈 - * 堆栈操作 * `DW_OP_dup` * 复制堆栈顶部的值 - * `DW_OP_deref` * 将堆栈顶部视为内存地址,并将其替换为该地址的内容 - * 算术和逻辑运算 * `DW_OP_and` * 弹出堆栈顶部的两个值,并压回它们的逻辑 `AND` - * `DW_OP_plus` * 与 `DW_OP_and` 相同,但是会添加值 - * 控制流操作 * `DW_OP_le`、`DW_OP_eq`、`DW_OP_gt` 等 * 弹出前两个值,比较它们,并且如果条件为真,则压入 `1`,否则为 `0` - * `DW_OP_bra ` * 条件分支:如果堆栈的顶部不是 `0`,则通过 `offset` 在表达式中向后或向后跳过 - * 输入转化 * `DW_OP_convert ` * 将堆栈顶部的值转换为不同的类型,它由给定偏移量的 DWARF 信息条目描述 - * 特殊操作 * `DW_OP_nop` - * 什么都能不做! + * 什么都不做! ### DWARF 类型 -DWARF 的类型表示需要足够强大来为调试器用户提供有用的变量表示。用户经常希望能够在应用程序级别进行调试,而不是在机器级别进行调试,并且他们需要了解他们的变量正在做什么。 +DWARF 类型的表示需要足够强大来为调试器用户提供有用的变量表示。用户经常希望能够在应用程序级别进行调试,而不是在机器级别进行调试,并且他们需要了解他们的变量正在做什么。 DWARF 类型与大多数其他调试信息一起编码在 DIE 中。它们可以具有指示其名称、编码、大小、字节等的属性。无数的类型标签可用于表示指针、数组、结构体、typedef 以及 C 或 C++ 程序中可以看到的任何其他内容。 @@ -168,7 +129,7 @@ struct test{ ``` -每个成员都有一个名称,一个类型(它是一个 DIE 偏移量),一个声明文件和行,以及一个字节偏移到该成员所在的结构体中。类型指向下一个。 +每个成员都有一个名称、一个类型(它是一个 DIE 偏移量)、一个声明文件和行,以及一个指向其成员所在的结构体的字节偏移。其类型指向如下。 ``` < 1><0x00000063> DW_TAG_base_type @@ -195,11 +156,9 @@ struct test{ 如你所见,我笔记本电脑上的 `int` 是一个 4 字节的有符号整数类型,`float`是一个 4 字节的浮点数。整数数组类型通过指向 `int` 类型作为其元素类型,`sizetype`(可以认为是 `size_t`)作为索引类型,它具有 `2a` 个元素。 `test *` 类型是 `DW_TAG_pointer_type`,它引用 `test` DIE。 -* * * - ### 实现简单的变量读取器 -如上所述,`libelfin` 将处理我们大部分的复杂性。但是,它并没有实现用于表示可变位置的所有不同方法,并且在我们的代码中处理这些将变得非常复杂。因此,我现在选择只支持 `exprloc`。请随意添加对更多类型表达式的支持。如果你真的有勇气,请提交补丁到 `libelfin` 中来帮助完成必要的支持! +如上所述,`libelfin` 将为我们处理大部分复杂性。但是,它并没有实现用于表示可变位置的所有方法,并且在我们的代码中处理这些将变得非常复杂。因此,我现在选择只支持 `exprloc`。请根据需要添加对更多类型表达式的支持。如果你真的有勇气,请提交补丁到 `libelfin` 中来帮助完成必要的支持! 处理变量主要是将不同部分定位在存储器或寄存器中,读取或写入与之前一样。为了简单起见,我只会告诉你如何实现读取。 @@ -305,29 +264,27 @@ void debugger::read_variables() { 编写一些具有一些变量的小功能,不用优化并带有调试信息编译它,然后查看是否可以读取变量的值。尝试写入存储变量的内存地址,并查看程序改变的行为。 -* * * - 已经有九篇文章了,还剩最后一篇!下一次我会讨论一些你可能会感兴趣的更高级的概念。现在你可以在[这里][13]找到这个帖子的代码。 -------------------------------------------------------------------------------- via: https://blog.tartanllama.xyz/writing-a-linux-debugger-variables/ -作者:[ Simon Brand][a] +作者:[Simon Brand][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.twitter.com/TartanLlama -[1]:https://blog.tartanllama.xyz/writing-a-linux-debugger-setup/ -[2]:https://blog.tartanllama.xyz/writing-a-linux-debugger-breakpoints/ -[3]:https://blog.tartanllama.xyz/writing-a-linux-debugger-registers/ -[4]:https://blog.tartanllama.xyz/writing-a-linux-debugger-elf-dwarf/ -[5]:https://blog.tartanllama.xyz/writing-a-linux-debugger-source-signal/ -[6]:https://blog.tartanllama.xyz/writing-a-linux-debugger-dwarf-step/ -[7]:https://blog.tartanllama.xyz/writing-a-linux-debugger-source-break/ -[8]:https://blog.tartanllama.xyz/writing-a-linux-debugger-unwinding/ +[1]:https://linux.cn/article-8626-1.html +[2]:https://linux.cn/article-8645-1.html +[3]:https://linux.cn/article-8663-1.html +[4]:https://linux.cn/article-8719-1.html +[5]:https://linux.cn/article-8812-1.html +[6]:https://linux.cn/article-8813-1.html +[7]:https://linux.cn/article-8890-1.html +[8]:https://linux.cn/article-8930-1.html [9]:https://blog.tartanllama.xyz/writing-a-linux-debugger-variables/ [10]:https://blog.tartanllama.xyz/writing-a-linux-debugger-advanced-topics/ [11]:https://github.com/TartanLlama/libelfin/tree/fbreg From 7521f42df712b705dbbc25d0c91ed2f67b903fdf Mon Sep 17 00:00:00 2001 From: penghuster Date: Sat, 7 Oct 2017 14:46:14 +0800 Subject: [PATCH 10/39] translating by penghuster --- ...Code Like The Top Programmers At NASA — 10 Critical Rules.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160611 How To Code Like The Top Programmers At NASA — 10 Critical Rules.md b/sources/tech/20160611 How To Code Like The Top Programmers At NASA — 10 Critical Rules.md index f0944d8fe9..cb86edc19a 100644 --- a/sources/tech/20160611 How To Code Like The Top Programmers At NASA — 10 Critical Rules.md +++ b/sources/tech/20160611 How To Code Like The Top Programmers At NASA — 10 Critical Rules.md @@ -1,3 +1,5 @@ +translating by penghuster + How To Code Like The Top Programmers At NASA — 10 Critical Rules ============================================================ From 13955dc8820dbb80e84df1e93586e68e5084db45 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 7 Oct 2017 22:37:20 +0800 Subject: [PATCH 11/39] PRF:20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md @GitFuture --- ... Tutorial Part 2 Drawing the Game Board.md | 85 +++++++++---------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/translated/tech/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md b/translated/tech/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md index fda44d34a5..d9dc87282e 100644 --- a/translated/tech/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md +++ b/translated/tech/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md @@ -1,9 +1,11 @@ -OpenGL 与 Go 教程第二节:绘制游戏面板 +OpenGL 与 Go 教程(二)绘制游戏面板 ============================================================ - _[第一节: Hello, OpenGL][6]_  |  _[第二节: 绘制游戏面板][7]_  |  _[第三节:实现游戏功能][8]_ +- [第一节: Hello, OpenGL][6] +- [第二节: 绘制游戏面板][7] +- [第三节:实现游戏功能][8] - _这篇教程的所有源代码都可以在 [GitHub][9] 上找到._ +这篇教程的所有源代码都可以在 [GitHub][9] 上找到。 欢迎回到《OpenGL 与 Go 教程》。如果你还没有看过[第一节][15],那就要回过头去看看那一节。 @@ -13,7 +15,7 @@ OpenGL 与 Go 教程第二节:绘制游戏面板 ### 利用三角形绘制方形 -在我们绘制方形之前,先把三角形变成直角三角形。打开 **main.go** 文件,把 **triangle** 的定义改成像这个样子: +在我们绘制方形之前,先把三角形变成直角三角形。打开 `main.go` 文件,把 `triangle` 的定义改成像这个样子: ``` triangle = []float32{ @@ -23,11 +25,11 @@ triangle = []float32{ } ``` -我们做的事情是,把最上面的顶点 X 坐标移动到左边(也就是变为**-0.5**),这就变成了像这样的三角形: +我们做的事情是,把最上面的顶点 X 坐标移动到左边(也就是变为 `-0.5`),这就变成了像这样的三角形: - ![Conway's Game of Life in OpenGL and Golang Tutorial - Right-Angle Triangle](https://kylewbanks.com/images/post/golang-opengl-conway-4.png) +![Conway's Game of Life - 右弦三角形](https://kylewbanks.com/images/post/golang-opengl-conway-4.png) -很简单,对吧?现在让我们用两个这样的三角形顶点做成正方形。把 **triangle** 重命名为 **square**,然后添加第二个三角形的顶点数据,把直角三角形变成这样的: +很简单,对吧?现在让我们用两个这样的三角形顶点做成正方形。把 `triangle` 重命名为 `square`,然后添加第二个倒置的三角形的顶点数据,把直角三角形变成这样的: ``` square = []float32{ @@ -41,17 +43,17 @@ square = []float32{ } ``` -注意:你也要把在 **main** 和 **draw** 里面命名的 **triangle** 改为 **square**。 +注意:你也要把在 `main` 和 `draw` 里面命名的 `triangle` 改为 `square`。 我们通过添加三个顶点,把顶点数增加了一倍,这三个顶点就是右上角的三角形,用来拼成方形。运行它看看效果: - ![Conway's Game of Life in OpenGL and Golang Tutorial - Two Triangles Make a Square](https://kylewbanks.com/images/post/golang-opengl-conway-5.png) + ![Conway's Game of Life - 两个三角形构成方形](https://kylewbanks.com/images/post/golang-opengl-conway-5.png) 很好,现在我们能够绘制正方形了!OpenGL 一点都不难,对吧? ### 在窗口中绘制方形格子 -现在我们能画一个方形,怎么画 100 个吗?我们来创建一个 **cell** 结构体,用来表示格子的每一个单元,因此我们能够很灵活的选择绘制的数量: +现在我们能画一个方形,怎么画 100 个吗?我们来创建一个 `cell` 结构体,用来表示格子的每一个单元,因此我们能够很灵活的选择绘制的数量: ``` type cell struct { @@ -62,7 +64,7 @@ type cell struct { } ``` -**cell** 结构体包含一个 **drawable** 属性,这是一个 **Vertex Array Object(顶点数组对象)**,就像我们在之前创建的一样,这个结构体还包含 X 和 Y 坐标,用来表示这个格子的位置。 +`cell` 结构体包含一个 `drawable` 属性,这是一个顶点数组对象,就像我们在之前创建的一样,这个结构体还包含 X 和 Y 坐标,用来表示这个格子的位置。 我们还需要两个常量,用来设定格子的大小和形状: @@ -91,9 +93,9 @@ func makeCells() [][]*cell { } ``` -这里我们创建多维的 slice(注:这是 Go 语言中的一种动态数组),代表我们的游戏面板,用 **newCell** 新函数创建的 **cell** 来填充矩阵的每个元素,我们待会就来实现 **newCell** 这个函数。 +这里我们创建多维的切片slice,代表我们的游戏面板,用名为 `newCell` 的新函数创建的 `cell` 来填充矩阵的每个元素,我们待会就来实现 `newCell` 这个函数。 -在接着往下阅读前,我们先花一点时间来看看 **makeCells** 函数做了些什么。我们创造了一个 slice(切片),这个 slice 的长度和格子的行数相等,每一个 slice 里面都有一个用 slice 包含的一系列格子,这些格子的数量与列数相等。如果我们把 **rows** 和 **columns** 都设定成 2,那么就会创建如下的矩阵: +在接着往下阅读前,我们先花一点时间来看看 `makeCells` 函数做了些什么。我们创造了一个切片,这个切片的长度和格子的行数相等,每一个切片里面都有一个细胞cell的切片,这些细胞的数量与列数相等。如果我们把 `rows` 和 `columns` 都设定成 2,那么就会创建如下的矩阵: ``` [ @@ -102,7 +104,7 @@ func makeCells() [][]*cell { ] ``` -还可以创建一个更大的矩阵,包含 **10x10** 个格子: +还可以创建一个更大的矩阵,包含 `10x10` 个细胞: ``` [ @@ -119,7 +121,7 @@ func makeCells() [][]*cell { ] ``` -现在应该理解了我们创造的矩阵的形状和表示方法。让我们看看 **newCell** 函数到底是怎么填充矩阵的: +现在应该理解了我们创造的矩阵的形状和表示方法。让我们看看 `newCell` 函数到底是怎么填充矩阵的: ``` func newCell(x, y int) *cell { @@ -156,15 +158,15 @@ func newCell(x, y int) *cell { } ``` -这个函数里有很多内容,我们把它分成几个部分。我们做的第一件事是复制了 **square** 的定义。这让我们能够修改该定义,定制当前的格子位置,而不会影响其它使用 **square** 定义的格子。然后我们基于当前索引迭代复制后的 **points**。我们用求余数的方法来判断我们是在操作 X 坐标(**i % 3 == 0**),还是在操作 Y 坐标(**i % 3 == 1**)(跳过 Z 坐标是因为我们仅在二维层面上进行操作),跟着确定格子的大小(也就是占据整个游戏面板的比例),当然它的位置是基于格子在 **相对游戏面板的** X 和 Y 坐标。 +这个函数里有很多内容,我们把它分成几个部分。我们做的第一件事是复制了 `square` 的定义。这让我们能够修改该定义,定制当前的细胞位置,而不会影响其它使用 `square` 切片定义的细胞。然后我们基于当前索引迭代 `points` 副本。我们用求余数的方法来判断我们是在操作 X 坐标(`i % 3 == 0`),还是在操作 Y 坐标(`i % 3 == 1`)(跳过 Z 坐标是因为我们仅在二维层面上进行操作),跟着确定细胞的大小(也就是占据整个游戏面板的比例),当然它的位置是基于细胞在 `相对游戏面板的` X 和 Y 坐标。 -接着,我们改变那些包含在 **square** slice 中定义的 **0.5**,**0**, **-0.5** 这样的点。如果点小于 0,我们就把它设置成原来的 2 倍(因为 OpenGL 坐标的范围在 **-1** 到 **1** 之间,范围大小是 2),减 1 是为了归一化 OpenGL 坐标。如果点大于等于 0,我们的做法还是一样的,不过要加上我们计算出的尺寸。 +接着,我们改变那些包含在 `square` 切片中定义的 `0.5`,`0`, `-0.5` 这样的点。如果点小于 0,我们就把它设置成原来的 2 倍(因为 OpenGL 坐标的范围在 `-1` 到 `1` 之间,范围大小是 2),减 1 是为了归一化 OpenGL 坐标。如果点大于等于 0,我们的做法还是一样的,不过要加上我们计算出的尺寸。 -这样做是为了设置每个格子的大小,这样它就能只填充它在面板中的部分。因为我们有 10 行 10 列,每一个格子能分到游戏面板的 10% 宽度和高度。 +这样做是为了设置每个细胞的大小,这样它就能只填充它在面板中的部分。因为我们有 10 行 10 列,每一个格子能分到游戏面板的 10% 宽度和高度。 -最后,确定了所有点的位置和大小,我们用提供的 X 和 Y 坐标创建一个格子,设置 **drawable** 字段和我们刚刚操作 **points** 得到的 **Vertex Array Object** 对象一致。 +最后,确定了所有点的位置和大小,我们用提供的 X 和 Y 坐标创建一个 `cell`,并设置 `drawable` 字段与我们刚刚操作 `points` 得到的顶点数组对象(vao)一致。 -好了,现在我们在 **main** 函数里可以移去对 **makeVao** 的调用了,用 **makeCells** 代替。我们还修改了 **draw**,让它绘制一系列的格子而不是一个 **vao**。 +好了,现在我们在 `main` 函数里可以移去对 `makeVao` 的调用了,用 `makeCells` 代替。我们还修改了 `draw`,让它绘制一系列的细胞而不是一个 `vao`。 ``` func main() { @@ -189,7 +191,7 @@ func draw(cells [][]*cell, window *glfw.Window, program uint32) { } ``` -现在我们要让每个格子知道怎么绘制出自己。在 **cell** 里面添加一个 **draw** 函数: +现在我们要让每个细胞知道怎么绘制出自己。在 `cell` 里面添加一个 `draw` 函数: ``` func (c *cell) draw() { @@ -198,9 +200,9 @@ func (c *cell) draw() { } ``` -这看上去很熟悉,它很像我们之前在 **vao** 里写的 **draw**,唯一的区别是我们的 **BindVertexArray** 函数用的是 **c.drawable**,这是我们在 **newCell** 中创造的格子的 **vao**。 +这看上去很熟悉,它很像我们之前在 `vao` 里写的 `draw`,唯一的区别是我们的 `BindVertexArray` 函数用的是 `c.drawable`,这是我们在 `newCell` 中创造的细胞的 `vao`。 -回到 main 中的 **draw** 函数上,我们可以循环每个格子,让它们自己绘制自己: +回到 main 中的 `draw` 函数上,我们可以循环每个细胞,让它们自己绘制自己: ``` func draw(cells [][]*cell, window *glfw.Window, program uint32) { @@ -218,13 +220,13 @@ func draw(cells [][]*cell, window *glfw.Window, program uint32) { } ``` -你看到了我们循环每一个格子,调用它的 **draw** 函数。如果运行这段代码,你能看到像下面这样的东西: +如你所见,我们循环每一个细胞,调用它的 `draw` 函数。如果运行这段代码,你能看到像下面这样的东西: - ![Conway's Game of Life in OpenGL and Golang Tutorial - Full Grid](https://kylewbanks.com/images/post/golang-opengl-conway-6.png) +![Conway's Game of Life - 全部格子](https://kylewbanks.com/images/post/golang-opengl-conway-6.png) 这是你想看到的吗?我们做的是在格子里为每一行每一列创建了一个方块,然后给它上色,这就填满了整个面板! -注释掉 for 循环,我们就可以看到分隔的格子,像这样: +注释掉 for 循环,我们就可以看到一个明显独立的细胞,像这样: ``` // for x := range cells { @@ -236,26 +238,21 @@ func draw(cells [][]*cell, window *glfw.Window, program uint32) { cells[2][3].draw() ``` - ![Conway's Game of Life in OpenGL and Golang Tutorial - A Single Cell](https://kylewbanks.com/images/post/golang-opengl-conway-7.png) +![Conway's Game of Life - 一个单独的细胞](https://kylewbanks.com/images/post/golang-opengl-conway-7.png) -这只绘制坐标在 **(X=2, Y=3)** 的格子。你可以看到,每一个独立的格子占据着面板的一小块部分,并且会绘制自己那部分空间。我们也能看到游戏面板有自己的原点,也就是坐标为 **(X=0, Y=0)** 的点,在窗口的左下方。这仅仅是我们的 **newCell** 函数计算位置的方式,也可以用右上角,右下角,左上角,中央,或者其它任何位置当作原点。 +这只绘制坐标在 `(X=2, Y=3)` 的格子。你可以看到,每一个独立的细胞占据着面板的一小块部分,并且负责绘制自己那部分空间。我们也能看到游戏面板有自己的原点,也就是坐标为 `(X=0, Y=0)` 的点,在窗口的左下方。这仅仅是我们的 `newCell` 函数计算位置的方式,也可以用右上角,右下角,左上角,中央,或者其它任何位置当作原点。 -接着往下做,移除 **cells[2][3].draw()** 这一行,取消 for 循环的那部分注释,变成之前那样全部绘制的样子。 +接着往下做,移除 `cells[2][3].draw()` 这一行,取消 for 循环的那部分注释,变成之前那样全部绘制的样子。 ### 总结 好了,我们现在能用两个三角形画出一个正方形了,我们还有一个游戏的面板了!我们该为此自豪,目前为止我们已经接触到了很多零碎的内容,老实说,最难的部分还在前面等着我们! -在接下来的 [第三节],我们会实现游戏核心逻辑,看到很酷的东西! - - _[第 1 节: Hello, OpenGL][10]_  |  _[第二节: 绘制游戏面板][11]_  |  _[第三节:实现游戏功能][12]_ - - _该教程的完整源代码可以在 [GitHub][13] 上获得。_ - +在接下来的第三节,我们会实现游戏核心逻辑,看到很酷的东西! ### 回顾 -这是这一部分教程中 **main.go** 文件的内容: +这是这一部分教程中 `main.go` 文件的内容: ``` package main @@ -390,7 +387,7 @@ func (c *cell) draw() { gl.DrawArrays(gl.TRIANGLES, 0, int32(len(square)/3)) } -// initGlfw initializes glfw and returns a Window to use. 初始化 glfw,返回一个可用的 Window +// 初始化 glfw,返回一个可用的 Window func initGlfw() *glfw.Window { if err := glfw.Init(); err != nil { panic(err) @@ -410,7 +407,7 @@ func initGlfw() *glfw.Window { return window } -// initOpenGL initializes OpenGL and returns an intiialized program. 初始化 OpenGL 并返回一个可用的着色器程序 +// 初始化 OpenGL 并返回一个可用的着色器程序 func initOpenGL() uint32 { if err := gl.Init(); err != nil { panic(err) @@ -435,7 +432,7 @@ func initOpenGL() uint32 { return prog } -// makeVao initializes and returns a vertex array from the points provided. 初始化并返回由 points 提供的顶点数组 +// 初始化并返回由 points 提供的顶点数组 func makeVao(points []float32) uint32 { var vbo uint32 gl.GenBuffers(1, &vbo) @@ -483,9 +480,9 @@ func compileShader(source string, shaderType uint32) (uint32, error) { via: https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-2-drawing-the-game-board -作者:[kylewbanks ][a] +作者:[kylewbanks][a] 译者:[GitFtuture](https://github.com/GitFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -495,16 +492,16 @@ via: https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-2-drawing-the- [3]:https://twitter.com/intent/tweet?text=OpenGL%20%26%20Go%20Tutorial%20Part%202%3A%20Drawing%20the%20Game%20Board%20https%3A%2F%2Fkylewbanks.com%2Fblog%2Ftutorial-opengl-with-golang-part-2-drawing-the-game-board%20by%20%40kylewbanks [4]:mailto:?subject=Check%20Out%20%22OpenGL%20%26%20Go%20Tutorial%20Part%202%3A%20Drawing%20the%20Game%20Board%22&body=https%3A%2F%2Fkylewbanks.com%2Fblog%2Ftutorial-opengl-with-golang-part-2-drawing-the-game-board [5]:https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fkylewbanks.com%2Fblog%2Ftutorial-opengl-with-golang-part-2-drawing-the-game-board -[6]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-1-hello-opengl +[6]:https://linux.cn/article-8933-1.html [7]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-2-drawing-the-game-board [8]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-3-implementing-the-game [9]:https://github.com/KyleBanks/conways-gol -[10]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-1-hello-opengl +[10]:https://linux.cn/article-8933-1.html [11]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-2-drawing-the-game-board [12]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-3-implementing-the-game [13]:https://github.com/KyleBanks/conways-gol [14]:https://twitter.com/kylewbanks -[15]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-1-hello-opengl +[15]:https://linux.cn/article-8933-1.html [16]:https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-3-implementing-the-game [17]:https://twitter.com/intent/tweet?text=OpenGL%20%26%20Go%20Tutorial%20Part%202%3A%20Drawing%20the%20Game%20Board%20https%3A%2F%2Fkylewbanks.com%2Fblog%2Ftutorial-opengl-with-golang-part-2-drawing-the-game-board%20by%20%40kylewbanks [18]:mailto:?subject=Check%20Out%20%22OpenGL%20%26%20Go%20Tutorial%20Part%202%3A%20Drawing%20the%20Game%20Board%22&body=https%3A%2F%2Fkylewbanks.com%2Fblog%2Ftutorial-opengl-with-golang-part-2-drawing-the-game-board From 3640fbe12442674aa47a84f54c179a19d87fa1c3 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 7 Oct 2017 22:37:47 +0800 Subject: [PATCH 12/39] PUB:20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md @GitFuture https://linux.cn/article-8937-1.html --- .../20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md (100%) diff --git a/translated/tech/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md b/published/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md similarity index 100% rename from translated/tech/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md rename to published/20170312 OpenGL Go Tutorial Part 2 Drawing the Game Board.md From 487ba9e1c6b9d13a4f8f7d71873b0b857037501c Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 8 Oct 2017 11:48:22 +0800 Subject: [PATCH 13/39] PRF&PUB:20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md @geekpi --- ...ot kit runs on Raspberry Pi and Arduino.md | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) rename {translated/tech => published}/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md (51%) diff --git a/translated/tech/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md b/published/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md similarity index 51% rename from translated/tech/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md rename to published/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md index cf2849bfdc..b08147f7e6 100644 --- a/translated/tech/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md +++ b/published/20170621 Open source social robot kit runs on Raspberry Pi and Arduino.md @@ -1,61 +1,65 @@ -# [开源社交机器人套件运行在 Raspberry Pi 和 Arduino 上][22] - - +运行在树莓派和 Arduino 上的开源社交机器人套件 +============ ![](http://linuxgizmos.com/files/thecorpora_qboone-thm.jpg) -Thecorpora 的发布的 “Q.bo One” 机器人基于 RPi 3 和 Arduino,并提供立体相机、麦克风、扬声器,以及视觉和语言识别。 -2010 年,机器人开发商 Francisco Paz 及其巴塞罗那的 Thecorpora 公司推出了首款 [Qbo][6] “Cue-be-oh” 机器人作为一个开源概念验证和用于探索 AI 在多传感器、交互式机器人的能力的研究项目。目前,在 2 月移动世界大会上的预览之后,Thecorpora 把它放到了 Indiegogo 上,与 Arrow 合作推出了第一个批量生产的社交机器人版本。 +*Thecorpora 的发布的 “Q.bo One” 机器人基于 RPi 3 和 Arduino,并提供立体相机、麦克风、扬声器,以及视觉和语言识别。* - [![](http://linuxgizmos.com/files/thecorpora_qboone-sm.jpg)][7]   [![](http://linuxgizmos.com/files/thecorpora_qboone2-sm.jpg)][8] -**Q.bo One 的左侧和顶部** +2010 年,作为一个开源概念验证和用于探索 AI 在多传感器、交互式机器人的能力的研究项目,机器人开发商 Francisco Paz 及它在巴塞罗那的 Thecorpora 公司推出了首款 [Qbo][6] “Cue-be-oh” 机器人。在今年 2 月移动世界大会上的预览之后,Thecorpora 把它放到了 Indiegogo 上,与 Arrow 合作推出了第一个批量生产的社交机器人版本。 +[![](http://linuxgizmos.com/files/thecorpora_qboone-sm.jpg)][7]   -像原来一样,新的 Q.bo One 有一个带眼睛的球形头(双立体相机)、耳朵(3 个麦克风)和嘴(扬声器),并由 WiFi 和蓝牙控制。 Q.bo One 也同样有开源 Linux 软件和开放规格硬件。然而,它不是使用基于 Intel Atom 的 Mini-ITX 板,而是在与 Arduino 兼容的主板相连的 Raspberry Pi 3 上运行 Raspbian。 +*Q.bo One 的左侧* +[![](http://linuxgizmos.com/files/thecorpora_qboone2-sm.jpg)][8] - [![](http://linuxgizmos.com/files/thecorpora_qboone_side-sm.jpg)][9] -**Q.bo One side views** +*Q.bo One 的顶部* +像原来一样,新的 Q.bo One 有一个带眼睛的球形头(双立体相机)、耳朵(3 个麦克风)和嘴(扬声器),并由 WiFi 和蓝牙控制。 Q.bo One 也同样采用开源 Linux 软件和开放规格硬件。然而,它不是使用基于 Intel Atom 的 Mini-ITX 板,而是在与 Arduino 兼容的主板相连的 Raspberry Pi 3 上运行 Raspbian。 -Q.bo One 于 7 月中旬在 Indiegogo 上架,起价为 369 美元(早期买家)或 399 美元,有包括内置的 Raspberry Pi 3 和基于 Arduino 的 “Qboard” 控制器板。它还有售价 $499 的完整套装。目前,Indiegogo 上的弹性目标是 $100,000,现在大概达成了 15%,并且它 12 月出货。 +[![](http://linuxgizmos.com/files/thecorpora_qboone_side-sm.jpg)][9] -更专业的机器人工程师和嵌入式开发人员可能会想要使用只有 RPI 和 Qboard PCB 和软件的价值 $99 的版本,或者提供没有电路板的机器人套件的 $249 版本。使用此版本,你可以用自己的 Arduino 控制器替换 Qboard,并将 RPi 3 替换为另一个 Linux SBC。该公司列出了 Banana Pi、BeagleBone、Tinker Board 以及[即将退市的 Intel Edison][10],作为兼容替代品的示例。 +*Q.bo One 侧视图** -
- [![](http://linuxgizmos.com/files/thecorpora_qboone_kit-sm.jpg)][11] -**Q.bo One kit** -(click image to enlarge) -
+Q.bo One 于 7 月中旬在 Indiegogo 上架,起价为 369 美元(早期买家)或 399 美元,有包括内置的树莓派 3 和基于 Arduino 的 “Qboard” 控制器板。它还有售价 $499 的完整套装。目前,Indiegogo 上的众筹目标是 $100,000,现在大概达成了 15%,并且它 12 月出货。 -与 2010 年的 Qbo 不同,Q.bo One 除了球面头部之外无法移动,它在双重伺服系统的帮助下在底座上旋转,以便跟踪声音和动作。Robotis Dynamixel 舵机,也在开源中找到,Raspberry Pi 基于 [TurtleBot 3][23] 机器人工具包,除了左右之外,还可以上下移动。 +更专业的机器人工程师和嵌入式开发人员可能会想要使用价值 $99 的只有树莓派和 Qboard PCB 和软件的版本,或者提供没有电路板的机器人套件的 $249 版本。使用此版本,你可以用自己的 Arduino 控制器替换 Qboard,并将树莓派 3 替换为另一个 Linux SBC。该公司列出了 Banana Pi、BeagleBone、Tinker Board 以及[即将退市的 Intel Edison][10],作为兼容替代品的示例。 -
- [![](http://linuxgizmos.com/files/thecorpora_qboone_detail-sm.jpg)][12]   [![](http://linuxgizmos.com/files/thecorpora_qboone_qboard-sm.jpg)][13] -**Q.bo One detail view (left) and Qboard detail** -(click images to enlarge) -
+[![](http://linuxgizmos.com/files/thecorpora_qboone_kit-sm.jpg)][11] -Q.bo One 也可类似地与基于 Linux 的 [Jibo][24] “社交机器人”相比,它于 2014 年在 Indiegogo 推出,最后达到 360 万美元。然而,Jibo 还没有出货,[最近的推迟][25]迫使它在今年的某个时候发布一个版本。 +*Q.bo One 套件* + +与 2010 年的 Qbo 不同,Q.bo One 除了球面头部之外无法移动,它可以在双重伺服系统的帮助下在底座上旋转,以便跟踪声音和动作。Robotis Dynamixel 舵机同样开源,树莓派基于 [TurtleBot 3][23] 机器人工具包,除了左右之外,还可以上下移动。 + +[![](http://linuxgizmos.com/files/thecorpora_qboone_detail-sm.jpg)][12]   + +*Q.bo One 细节* + +[![](http://linuxgizmos.com/files/thecorpora_qboone_qboard-sm.jpg)][13] + +*Qboard 细节* + +Q.bo One 类似于基于 Linux 的 [Jibo][24] “社交机器人”,它于 2014 年在 Indiegogo 众筹,最后达到 360 万美元。然而,Jibo 还没有出货,[最近的推迟][25]迫使它在今年的某个时候发布一个版本。 -| ![](http://linuxgizmos.com/files/thecorpora_qboone_mouth.jpg) -**Q.bo One** | +*Q.bo One* -我们大胆预测 Q.bo One 将会在 2017 年接近 12 月出货。核心技术和 AI 软件已被证明,而 Raspberry Pi 和 Arduino 技术也是如此。Qboard 主板已经由 Arrow 制造和认证。 +我们大胆预测 Q.bo One 将会在 2017 年接近 12 月出货。核心技术和 AI 软件已被证明,而树莓派和 Arduino 技术也是如此。Qboard 主板已经由 Arrow 制造和认证。 -开源设计表明, 即使是移动版本也不会有问题。这使它更像是滚动的人形生物 [Pepper][14],一个来自 Softbank 和 Aldeberan 类似的人工智能对话机器人。 +开源设计表明,即使是移动版本也不会有问题。这使它更像是滚动的人形生物 [Pepper][14],这是一个来自 Softbank 和 Aldeberan 类似的人工智能对话机器人。 -Q.bo One 自原版以来添加了一些技巧,例如由 20 个 LED 组成的“嘴巴”, 它以不同的、可编程的方式在语音中模仿嘴唇移动。如果你想点击机器人获得关注,那么它的头上还有三个触摸传感器。但是,你真正需要做的就是说话,而 Q.bo One 会像一个可卡犬一样转身并凝视着你。 +Q.bo One 自原始版以来添加了一些技巧,例如由 20 个 LED 组成的“嘴巴”, 它以不同的、可编程的方式在语音中模仿嘴唇开合。如果你想点击机器人获得关注,那么它的头上还有三个触摸传感器。但是,你其实只需要说话就行,而 Q.bo One 会像一个可卡犬一样转身并凝视着你。 -接口和你在 Raspberry Pi 3 上的一样,它在我们的[2017 黑客电路板调查][15]中消灭了其他对手。为 RPi 3 的 WiFi 和蓝牙安装了天线。 +接口和你在树莓派 3 上的一样,它在我们的 [2017 黑客电路板调查][15]中消灭了其他对手。为树莓派 3 的 WiFi 和蓝牙安装了天线。 -
- [![](http://linuxgizmos.com/files/thecorpora_qboone_arch-sm.jpg)][16]   [![](http://linuxgizmos.com/files/thecorpora_qboone_scratch-sm.jpg)][17] -**Q.bo One software architecture (left) and Q.bo One with Scratch screen** -(click images to enlarge) -
+[![](http://linuxgizmos.com/files/thecorpora_qboone_arch-sm.jpg)][16]   + +*Q.bo One 软件架构* + +[![](http://linuxgizmos.com/files/thecorpora_qboone_scratch-sm.jpg)][17] + +*Q.bo One 及 Scratch 编程* Qboard(也称为 Q.board)在 Atmel ATSAMD21 MCU 上运行 Arduino 代码,并有三个麦克风、扬声器、触摸传感器、Dynamixel 控制器和用于嘴巴的 LED 矩阵。其他功能包括 GPIO、I2C接口和可连接到台式机的 micro-USB 口。 @@ -66,19 +70,17 @@ Q.bo One 可以识别脸部和追踪移动,机器人甚至可以在镜子中 基于 Raspbian 的软件使用 OpenCV 进行视觉处理,并可以使用各种语言(包括 C++)进行编程。该软件还提供了 IBM Bluemix、NodeRED 和 ROS 的钩子。大概你也可以整合 [Alexa][18] 或 [Google Assistant][19]语音代理,虽然 Thecorpora 没有提及这一点。 - **更多信息** -Q.bo One 在 7 月中旬在 Indiegogo 上架,起价为 $369 的完整套件和 $499 的所有组合 -。出货量预计在 2017 年 12 月。更多信息请参见[ Q.bo One 的 Indiegogo 页面][20] 和[ Thecorpora 网站][21]。 +Q.bo One 在 7 月中旬在 Indiegogo 上架,起价为完整套件 $369 和完整组合 $499 。出货预计在 2017 年 12 月。更多信息请参见 [Q.bo One 的 Indiegogo 页面][20] 和[Thecorpora 网站][21]。 -------------------------------------------------------------------------------- via: http://linuxgizmos.com/open-source-social-robot-kit-runs-on-raspberry-pi-and-arduino/ -作者:[ Eric Brown][a] +作者:[Eric Brown][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 902a37fa0a02773a0ec37beaf91c175768b6269d Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 11:50:48 +0800 Subject: [PATCH 14/39] Update 20170703 Brewing beer with Linux python and raspberry pi.md --- .../20170703 Brewing beer with Linux python and raspberry pi.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md index bea84931c7..d9bd699d63 100644 --- a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -1,3 +1,4 @@ +hwlife is translating Brewing beer with Linux, Python, and Raspberry Pi ============================================================ From 0b2e1bb4fe78d15fa55de3736479f0ba052824c6 Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 11:51:08 +0800 Subject: [PATCH 15/39] Update 20170703 Brewing beer with Linux python and raspberry pi.md --- .../20170703 Brewing beer with Linux python and raspberry pi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md index d9bd699d63..f96cf25179 100644 --- a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -1,4 +1,4 @@ -hwlife is translating +hwlife is translating Brewing beer with Linux, Python, and Raspberry Pi ============================================================ From e3accc39ef8b3b9c5a9f7d3e4218b97a3a54293f Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 11:51:41 +0800 Subject: [PATCH 16/39] Update 20170703 Brewing beer with Linux python and raspberry pi.md hwlife is translating --- .../20170703 Brewing beer with Linux python and raspberry pi.md | 1 - 1 file changed, 1 deletion(-) diff --git a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md index f96cf25179..bea84931c7 100644 --- a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -1,4 +1,3 @@ -hwlife is translating Brewing beer with Linux, Python, and Raspberry Pi ============================================================ From 33fbce6d9fc31a96c69df9e21247ee604065d24f Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 11:59:30 +0800 Subject: [PATCH 17/39] Create 20170703 Brewing beer with Linux python and raspberry pi.md --- ...beer with Linux python and raspberry pi.md | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md diff --git a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md new file mode 100644 index 0000000000..bea84931c7 --- /dev/null +++ b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -0,0 +1,192 @@ +Brewing beer with Linux, Python, and Raspberry Pi +============================================================ + +### A handy how-to for building a homemade homebrew setup with Python and the Raspberry Pi. + + +![Brewing beer with Linux, Python, and Raspberry Pi](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/beer-drink-sample-sampler.png?itok=20jJLB8V "Brewing beer with Linux, Python, and Raspberry Pi") +Image by :  + +[Quinn Dombrowski][21]. Modified by Opensource.com. [CC BY-SA 4.0][22]. + +I started brewing my own beer more than 10 years ago. Like most homebrewers, I started in my kitchen making extract-based brews. This required the least equipment and still resulted in really tasty beer. Eventually I stepped up to all-grain brewing using a big cooler for my mash tun. For several years I was brewing 5 gallons at a time, but brewing 10 gallons takes the same amount of time and effort (and only requires slightly larger equipment), so a few years ago I stepped it up. After moving up to 10 gallons, I stumbled across [StrangeBrew Elsinore][23] and realized what I  _really_  needed to do was convert my whole system to be all-electric, and run it with a [Raspberry Pi][24]. + +There is a ton of great information available for building your own all-electric homebrew system, and most brewers start out at [TheElectricBrewery.com][25]. Just putting together the control panel can get pretty complicated, although the simplest approach is outlined well there. Of course you can also take [a less expensive approach][26] and still end up with the same result—a boil kettle and hot liquor tank powered by heating elements and managed by a PID controller. I think that's a little too boring though (and it also means you don't get neat graphs of your brew process). + +More on Raspberry Pi + +* [Our latest on Raspberry Pi][1] + +* [What is Raspberry Pi?][2] + +* [Getting started with Raspberry Pi][3] + +* [Send us your Raspberry Pi projects and tutorials][4] + +### Hardware supplies + +Before I talked myself out of the project, I decided to start buying parts. My basic design was a Hot Liquor Tank (HLT) and boil kettle with 5500w heating elements in them, plus a mash tun with a false bottom. I would use a pump to recirculate the mash through a 50' stainless coil in the HLT (a ["heat exchanger recirculating mash system", known as HERMS][27]). I would need a second pump to circulate the water in the HLT, and to help with transferring water to the mash tun. All of the electrical components would be controlled with a Raspberry Pi. + +Building my electric brew system and automating as much of it as possible meant I was going to need the following: + +* HLT with a 5500w electric heating element + +* HERMS coil (50' 1/2" stainless steel) in the HLT + +* boil kettle with a 5500w electric heating element + +* multiple solid-state relays to switch the heaters on and off + +* 2 high-temp food-grade pumps + +* relays for switching the pumps on and off + +* fittings and high-temp silicon tubing + +* stainless ball valves + +* 1-wire temperature probes + +* lots of wire + +* electrical box to hold everything + +### [aedo-f1.png][11] + +![Brew system](https://opensource.com/sites/default/files/aedo-f1.png "Brew system") + +Brew system (photo by Christopher Aedo. [CC BY-SA 4.0)][5] + +The details of building out the electrical side of the system are really well covered by [The Electric Brewery][28], so I won't repeat their detailed information. You can read through and follow their suggestions while planning to replace the PID controllers with a Raspberry Pi. + +One important thing to note is the solid-state relay (SSR) signal voltage. Many tutorials suggest using SSRs that need a 12-volt signal to close the circuit. The Raspberry Pi GPIO pins will only output 3v, however. Be sure to purchase relays that will trigger on 3 volts. + +### [aedo-f2.png][12] + +![Inkbird SSR](https://opensource.com/sites/default/files/aedo-f2.png "Inkbird SSR") + +Inkbird SSR (photo by Christopher Aedo. [CC BY-SA 4.0)][6] + +To run your brew system, your Pi must do two key things: sense temperature from a few different places, and turn relays on and off to control the heating elements. The Raspberry Pi easily is able to handle these tasks. + +There are a few different ways to connect temp sensors to a Pi, but I've found the most convenient approach is to use the [1-Wire bus][29]. This allows for multiple sensors to share the same wire (actually three wires), which makes it a convenient way to instrument multiple components in your brew system. If you look for waterproof DS18B20 temperature sensors online, you'll find lots of options available. I used [Hilitchi DS18B20 Waterproof Temperature Sensors][30] for my project. + +To control the heating elements, the Raspberry Pi includes several General Purpose IO (GPIO) pins that are software addressable. This allows you to send 3.3v to a relay by simply putting a **1** or a **0** in a file. The  _Raspberry Pi—Driving a Relay using GPIO_  tutorial was the most helpful for me when I was first learning how all this worked. The GPIO controls multiple solid-state relays, turning on and off the heating elements as directed by the brewing software. + +I first started working on the box to hold all the components. Because this would all be on a rolling cart, I wanted it to be relatively portable rather than permanently mounted. If I had a spot (for example, inside a garage, utility room, or basement), I would have used a larger electrical box mounted on the wall. Instead I found a decent-size [waterproof project box][31] that I expected I could shoehorn everything into. In the end, it turned out to be a little bit of a tight fit, but it worked out. In the bottom left corner is the Pi with a breakout board for connecting the GPIO to the 1-Wire temperature probes and the [solid state relays][32]. + +To keep the 240v SSRs cool, I cut holes in the case and stacked [copper shims][33] with CPU cooling grease between them and heat sinks mounted on the outside of the box. It worked out well and there haven't been any cooling issues inside the box. On the cover I put two switches for 120v outlets, plus two 240v LEDs to show which heating element was energized. I used dryer plugs and outlets for all connections so disconnecting a kettle from everything is easy. Everything worked right on the first try, too. (Sketching a wiring diagram first definitely pays off.) + +The pictures are from the "proof-of-concept" version—the final production system should have two more SSRs so that both legs of the 240v circuit would be switched. The other thing I would like to switch via software is the pumps. Right now they're controlled via physical switches on the front of the box, but they could easily be controlled with relays. + +### [aedo-f3.png][13] + +![Control box](https://opensource.com/sites/default/files/aedo-f3.png "Control box") + +Control box (photo by Christopher Aedo. [CC BY-SA 4.0)][7] + +The only other thing I needed that was a little tricky to find was a compression fitting for the temperature probes. The probes were mounted in T fittings before the valve on the lowest bulkhead in both the HLT and the mash tun. As long as the liquid is flowing past the temp sensor, it's going to be accurate. I thought about adding a thermowell into the kettles as well, but realized that's not going to be useful for me based on my brewing process. Anyway, I purchased [1/4" compression fittings][34] and they worked out perfectly. + +### Software + +Once the hardware was sorted out, I had time to play with the software. I ran the latest [Raspbian distribution][35] on the Pi; nothing special was required on the operating-system side. + +I started with [Strangebrew Elsinore][36] brewing software, which I had discovered when a friend asked whether I had heard of [Hosehead][37], a Raspberry Pi-based brewing controller. I thought Hosehead looked great, but rather than buying a brewing controller, I wanted the challenge of building my own. + +Setting up Strangebrew Elsinore was straightforward—the [documentation][38] was thorough and I did not encounter any problems. Even though Strangebrew Elsinore was working fine, Java seemed to be taxing my first-generation Pi sometimes, and it crashed on me more than once. I also was sad to see development stall and there did not seem to be a big community of additional contributors (although there were—and still are—plenty of people using it). + +### CraftBeerPi + +Then I stumbled across [CraftBeerPI][39], which is written in Python and supported by a development community of active contributors. The original author (and current maintainer) Manuel Fritsch is great about handling contributions and giving feedback on issues that folks open. Cloning [the repo][40] and getting started only took me a few minutes. The README also has a good example of connecting DS1820 temp sensors, along with notes on interfacing hardware to a Pi or a [C.H.I.P. computer][41]. + +On startup, CraftBeerPi walks users through a configuration process that discovers the temperature probes available and lets you specify which GPIO pins are managing which pieces of equipment. + +### [aedo-f4.png][14] + +![CraftBeerPi](https://opensource.com/sites/default/files/images/life/aedo-f4.png "CraftBeerPi") + +CraftBeerPi (photo by Christopher Aedo. [CC BY-SA 4.0)][8] + +Running a brew with this system is easy. I can count on it holding temperatures reliably, and I can input steps for a multi-temp step mash. Using CraftBeerPi has made my brew days a little bit boring, but I'm happy to trade off the "excitement" of traditional manually managed propane burners for the efficiency and consistency of this system. + +CraftBeerPI's user-friendliness inspired me to set up another controller to run a "fermentation chamber." In my case, that was a second-hand refrigerator I found for US$ 50 plus a $25 heater) on the inside. CraftBeerPI easily can control the cooling and heating elements, and you can set up multiple temperature steps. For instance, this graph shows the fermentation temperatures for a session IPA I made recently. The fermentation chamber held the fermenting wort at 67F for four days, then ramped up one degree every 12 hours until it was at 72F. That temp was held for a two-day diacetyl rest. After that it was set to drop down to 65F for five days, during which time I "dry hopped" the beer. Finally, the beer was cold-crashed down to 38F. CraftBeerPI made adding each step and letting the software manage the fermentation easy. + +### [aedo-f5.png][15] + +![SIPA fermentation profile](https://opensource.com/sites/default/files/aedo-f5.png "SIPA fermentation profile") + +SIPA fermentation profile (photo by Christopher Aedo. [CC BY-SA 4.0)][9] + +I have also been experimenting with the [TILT hydrometer][42] to monitor the gravity of the fermenting beer via a Bluetooth-connected floating sensor. There are integration plans for this to get it working with CraftBeerPI, but for now it logs the gravity to a Google spreadsheet. Once this hydrometer can talk to the fermentation controller, setting automated fermentation profiles that take action directly based on the yeast activity would be easy—rather than banking on primary fermentation completing in four days, you can set the temperature ramp to kick off after the gravity is stable for 24 hours. + +As with any project like this, imaging and planning improvements and additional components is easy. Still, I'm happy with where things stand today. I've brewed a lot of beer with this setup and am hitting the expected mash efficiency every time, and the beer has been consistently tasty. My most important customer—me!—is pleased with what I've been putting on tap in my kitchen. + +### [aedo-f6.png][16] + +![Homebrew on tap](https://opensource.com/sites/default/files/aedo-f6.png "Homebrew on tap") + +Homebrew on tap (photo by Christopher Aedo. [CC BY-SA 4.0)][10] + + _This article is based on Christopher's OpenWest talk, [Brewing Beer with Linux, Python and a RaspberryPi][18]. [OpenWest][19] will be held July 12-15, 2017 in Salt Lake City, Utah._ + +-------------------------------------------------------------------------------- + +作者简介: + +Christopher Aedo - Christopher Aedo has been working with and contributing to open source software since his college days. Most recently he can be found leading an amazing team of upstream developers at IBM who are also developer advocates. When he’s not at work or speaking at a conference, he’s probably using a RaspberryPi to brew and ferment a tasty homebrew in Portland OR. + + +via: https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi + +作者:[ Christopher Aedo][a] +译者:[译者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/docaedo +[1]:https://opensource.com/tags/raspberry-pi?src=raspberry_pi_resource_menu1 +[2]:https://opensource.com/resources/what-raspberry-pi?src=raspberry_pi_resource_menu2 +[3]:https://opensource.com/article/16/12/getting-started-raspberry-pi?src=raspberry_pi_resource_menu3 +[4]:https://opensource.com/article/17/2/raspberry-pi-submit-your-article?src=raspberry_pi_resource_menu4 +[5]:https://creativecommons.org/licenses/by-sa/4.0/ +[6]:https://creativecommons.org/licenses/by-sa/4.0/ +[7]:https://creativecommons.org/licenses/by-sa/4.0/ +[8]:https://creativecommons.org/licenses/by-sa/4.0/ +[9]:https://creativecommons.org/licenses/by-sa/4.0/ +[10]:https://creativecommons.org/licenses/by-sa/4.0/ +[11]:https://opensource.com/file/358661 +[12]:https://opensource.com/file/358666 +[13]:https://opensource.com/file/358676 +[14]:https://opensource.com/file/359061 +[15]:https://opensource.com/file/358681 +[16]:https://opensource.com/file/359071 +[17]:https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi?rate=fbKzT1V9gqGsmNCTuQIashC1xaHT5P_2LUaeTn6Kz1Y +[18]:https://www.openwest.org/custom/description.php?id=139 +[19]:https://www.openwest.org/ +[20]:https://opensource.com/user/145976/feed +[21]:https://www.flickr.com/photos/quinndombrowski/ +[22]:https://creativecommons.org/licenses/by-sa/4.0/ +[23]:https://github.com/DougEdey/SB_Elsinore_Server +[24]:https://opensource.com/tags/raspberry-pi +[25]:http://www.theelectricbrewery.com/ +[26]:http://www.instructables.com/id/Electric-Brewery-Control-Panel-on-the-Cheap/ +[27]:https://byo.com/hops/item/1325-rims-and-herms-brewing-advanced-homebrewing +[28]:http://theelectricbrewery.com/ +[29]:https://en.wikipedia.org/wiki/1-Wire +[30]:https://smile.amazon.com/gp/product/B018KFX5X0/ +[31]:http://amzn.to/2hupFCr +[32]:http://amzn.to/2hL8JDS +[33]:http://amzn.to/2i4DYwy +[34]:https://www.brewershardware.com/CF1412.html +[35]:https://www.raspberrypi.org/downloads/raspbian/ +[36]:https://github.com/DougEdey/SB_Elsinore_Server +[37]:https://brewtronix.com/ +[38]:http://dougedey.github.io/SB_Elsinore_Server/ +[39]:http://www.craftbeerpi.com/ +[40]:https://github.com/manuel83/craftbeerpi +[41]:https://www.nextthing.co/pages/chip +[42]:https://tilthydrometer.com/ +[43]:https://opensource.com/users/docaedo +[44]:https://opensource.com/users/docaedo +[45]:https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi#comments From 1922af107e6067d17abec5279abe5ad1513a2a2a Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 12:02:08 +0800 Subject: [PATCH 18/39] Update 20170703 Brewing beer with Linux python and raspberry pi.md --- .../20170703 Brewing beer with Linux python and raspberry pi.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md index bea84931c7..d9bd699d63 100644 --- a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -1,3 +1,4 @@ +hwlife is translating Brewing beer with Linux, Python, and Raspberry Pi ============================================================ From 80376481b137d499afe4dc8e69d1c1aea583a5e5 Mon Sep 17 00:00:00 2001 From: liruifeng Date: Sun, 8 Oct 2017 12:02:13 +0800 Subject: [PATCH 19/39] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 申请翻译:20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md --- ...ng tunnels with SSH The 8 possible scenarios using OpenSSH.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md b/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md index 3c6481471d..b96921df89 100644 --- a/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md +++ b/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md @@ -1,3 +1,4 @@ +【toutoudnf@gmail.com】翻译中 Creating TCP / IP (port forwarding) tunnels with SSH: The 8 possible scenarios using OpenSSH ============================================================ From c9dc680fe71599bf4483defad562a15c209a0ec8 Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 14:36:43 +0800 Subject: [PATCH 20/39] Update 20170703 Brewing beer with Linux python and raspberry pi.md --- ...beer with Linux python and raspberry pi.md | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md index bea84931c7..cea388ac23 100644 --- a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -1,7 +1,7 @@ -Brewing beer with Linux, Python, and Raspberry Pi +用Linux,Python和树莓派酿制啤酒 ============================================================ -### A handy how-to for building a homemade homebrew setup with Python and the Raspberry Pi. +### 怎样在家用python和树莓派搭建一个家用便携的自制酿啤酒装置 ![Brewing beer with Linux, Python, and Raspberry Pi](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/beer-drink-sample-sampler.png?itok=20jJLB8V "Brewing beer with Linux, Python, and Raspberry Pi") @@ -9,57 +9,59 @@ Image by :  [Quinn Dombrowski][21]. Modified by Opensource.com. [CC BY-SA 4.0][22]. -I started brewing my own beer more than 10 years ago. Like most homebrewers, I started in my kitchen making extract-based brews. This required the least equipment and still resulted in really tasty beer. Eventually I stepped up to all-grain brewing using a big cooler for my mash tun. For several years I was brewing 5 gallons at a time, but brewing 10 gallons takes the same amount of time and effort (and only requires slightly larger equipment), so a few years ago I stepped it up. After moving up to 10 gallons, I stumbled across [StrangeBrew Elsinore][23] and realized what I  _really_  needed to do was convert my whole system to be all-electric, and run it with a [Raspberry Pi][24]. +大约十年前我开始酿制自制啤酒,和许多自己酿酒的人一样,我开始在厨房制造提纯啤酒。这需要一些设备并且做出来后确实是好的啤酒,最终,我用一个大的贮藏罐放入了所有大麦作为我的麦芽浆桶。几年之后我曾酿制了5加仑啤酒,但是酿制10加仑时会花费同样的时间和效用(只是容器比之前大些),之前我是这么做的。容量提升到10加仑之后,我偶然发现并意识到我真正需要的是将整个酿酒过程转换成全电子化的,用树莓派来运行它。 -There is a ton of great information available for building your own all-electric homebrew system, and most brewers start out at [TheElectricBrewery.com][25]. Just putting together the control panel can get pretty complicated, although the simplest approach is outlined well there. Of course you can also take [a less expensive approach][26] and still end up with the same result—a boil kettle and hot liquor tank powered by heating elements and managed by a PID controller. I think that's a little too boring though (and it also means you don't get neat graphs of your brew process). +建造自己的家用电动化酿酒系统需要大量这方面的技术信息,许多学习酿酒的是在TheElectricBrewery.com这个网站起步的,只不过将那些控制版搭建在一起是十分复杂的,尽管最简单的办法在这个网站上总结的很好。当然你也能用一个小成本的方法并且依旧可以用相同的结果得到-用一个热水壶和热酒容器通过一个PID控制器来加热你的酿酒原料。但是我认为这有点太无聊(这也意味着你不能get到完成酿酒过程) -More on Raspberry Pi +关于树莓派更多信息 -* [Our latest on Raspberry Pi][1] +* [关于树莓派最新消息[1] -* [What is Raspberry Pi?][2] +* [树莓派是什么?][2] -* [Getting started with Raspberry Pi][3] +* [树莓派如何开始使用][3] -* [Send us your Raspberry Pi projects and tutorials][4] +* [发送给我们你的树莓派项目和教程][4] -### Hardware supplies +### 需要用到的硬件 -Before I talked myself out of the project, I decided to start buying parts. My basic design was a Hot Liquor Tank (HLT) and boil kettle with 5500w heating elements in them, plus a mash tun with a false bottom. I would use a pump to recirculate the mash through a 50' stainless coil in the HLT (a ["heat exchanger recirculating mash system", known as HERMS][27]). I would need a second pump to circulate the water in the HLT, and to help with transferring water to the mash tun. All of the electrical components would be controlled with a Raspberry Pi. +在我开始我得这个项目之前, 我决定开始买零件,我最基础的设计是一个可以将液体加热到5500w的热酒容器和开水壶,加一个活底的麦芽浆桶,我通过一个50的不锈钢线圈在热酒容器里让泵来再循环麦芽浆(a ["热量交换再循环麦芽浆系统, 也叫 HERMS][27]).同时我需要另一个泵来在热酒容器里循环水,并且把水传输到麦芽浆桶里,整个电子部件全部是用树莓派来控制的。 -Building my electric brew system and automating as much of it as possible meant I was going to need the following: -* HLT with a 5500w electric heating element +建立我得电子酿酒系统并且尽可能的自动化意味着我需要以下的东东: -* HERMS coil (50' 1/2" stainless steel) in the HLT -* boil kettle with a 5500w electric heating element +* 一个5500瓦的电子加热酒精容器 -* multiple solid-state relays to switch the heaters on and off +* 能够放入加热酒精容器里的一英尺(0.5英寸)长的不锈钢线圈(热量交换再循环麦芽浆系统) -* 2 high-temp food-grade pumps +* 一个5500瓦的电子加热水壶 -* relays for switching the pumps on and off +* 多个固态继电器加热开关 -* fittings and high-temp silicon tubing +* 2个高温食品级泵 -* stainless ball valves +* 泵的开关用继电器 -* 1-wire temperature probes +* 可拆除装置和一个硅管 -* lots of wire +* 不锈钢球阀 -* electrical box to hold everything +* 一个测量温度的探针 + +* 很多线 + +* 一个来容纳这些配件的电路盒子 ### [aedo-f1.png][11] ![Brew system](https://opensource.com/sites/default/files/aedo-f1.png "Brew system") -Brew system (photo by Christopher Aedo. [CC BY-SA 4.0)][5] +酿酒系统 (photo by Christopher Aedo. [CC BY-SA 4.0)][5] -The details of building out the electrical side of the system are really well covered by [The Electric Brewery][28], so I won't repeat their detailed information. You can read through and follow their suggestions while planning to replace the PID controllers with a Raspberry Pi. +建立酿酒系统的电气化方面的细节The Electric Brewery这个网站概括的很好,这里我不再重复,当你计划用树莓派代替这个PID控制器的话,你可以读以下的建议。 -One important thing to note is the solid-state relay (SSR) signal voltage. Many tutorials suggest using SSRs that need a 12-volt signal to close the circuit. The Raspberry Pi GPIO pins will only output 3v, however. Be sure to purchase relays that will trigger on 3 volts. +一个重要的事情需要注意,固态继电器信号电压,许多教程建议使用一个12伏的固态继电器来关闭电路,树莓派的GPIO针插口只支持输出电压3伏,然而,必须购买继电器将电压变为3伏。 ### [aedo-f2.png][12] @@ -67,23 +69,25 @@ One important thing to note is the solid-state relay (SSR) signal voltage. Many Inkbird SSR (photo by Christopher Aedo. [CC BY-SA 4.0)][6] -To run your brew system, your Pi must do two key things: sense temperature from a few different places, and turn relays on and off to control the heating elements. The Raspberry Pi easily is able to handle these tasks. +要运行酿酒系统,你的树莓派必须做两个关键事情:来自不同位置的敏感温度,用继电器开关来控制加热元件,树莓派很容易来处理这些任务。 -There are a few different ways to connect temp sensors to a Pi, but I've found the most convenient approach is to use the [1-Wire bus][29]. This allows for multiple sensors to share the same wire (actually three wires), which makes it a convenient way to instrument multiple components in your brew system. If you look for waterproof DS18B20 temperature sensors online, you'll find lots of options available. I used [Hilitchi DS18B20 Waterproof Temperature Sensors][30] for my project. +这里有一些不同的方法来将温度传感器连到树莓派上,但是我找到了最方便的方法用单总线。这就可以让多个传感器分享相同的线路(实际上三根线),这三根线可以使酿酒系统的多个设备更方便的工作,如果你要从网上找一个DS18B20 防水的温度传感器,你将会找到更多的选择。我用的是日立DS18B20防水温度传感器。 -To control the heating elements, the Raspberry Pi includes several General Purpose IO (GPIO) pins that are software addressable. This allows you to send 3.3v to a relay by simply putting a **1** or a **0** in a file. The  _Raspberry Pi—Driving a Relay using GPIO_  tutorial was the most helpful for me when I was first learning how all this worked. The GPIO controls multiple solid-state relays, turning on and off the heating elements as directed by the brewing software. +要控制加热元件,树莓派包括几个用来软件寻址的总线扩展器(GPIO),它会通过在某个文件写入0或者1让你发送3.3v的电压到一个继电器,在我第一次了解树莓派是怎样工作的时候,这个用GPIO驱动继电器的树莓派教程对我来说是最有帮助的,总线控制器控制多个固态继电器,通过酿酒软件来直接控制加热元件的开关。 -I first started working on the box to hold all the components. Because this would all be on a rolling cart, I wanted it to be relatively portable rather than permanently mounted. If I had a spot (for example, inside a garage, utility room, or basement), I would have used a larger electrical box mounted on the wall. Instead I found a decent-size [waterproof project box][31] that I expected I could shoehorn everything into. In the end, it turned out to be a little bit of a tight fit, but it worked out. In the bottom left corner is the Pi with a breakout board for connecting the GPIO to the 1-Wire temperature probes and the [solid state relays][32]. +我第一次将所有部件放到这个电路盒子,因为这将成为一个滚动的小车,我要让他方便移动,而不是固定不动的,如果我有一个店(比如说在车库,工具房,或者地下室),我需要要用一个更大的电路盒挂到墙上,而现在我找到一个大小正好的防水工程盒子,能放进每件东西,最后它成为紧密的结合工具盒,并且能够工作。在左下角是和树莓派连接的为总线控制器到单总线温度探针和固态继电器的扩展板。 -To keep the 240v SSRs cool, I cut holes in the case and stacked [copper shims][33] with CPU cooling grease between them and heat sinks mounted on the outside of the box. It worked out well and there haven't been any cooling issues inside the box. On the cover I put two switches for 120v outlets, plus two 240v LEDs to show which heating element was energized. I used dryer plugs and outlets for all connections so disconnecting a kettle from everything is easy. Everything worked right on the first try, too. (Sketching a wiring diagram first definitely pays off.) +要保持240v的固态继电器温度不高,我在盒子上切了个洞,在盒子的外面用降温凝胶安装铜片散热片冷却cpu的温度。它工作的很好,盒子里没有温度上的问题了,在盒子盖上我放了两个开关为120v的插座,加两个240v的led来显示加热元件是否通电。我用干燥器的插座和插头很容易的开关电热水壶的连接。第一次尝试每件事情都弄好了。(决定第一次手画电路图.) + + +照片是从“概念”版的最终生产系统应该有两个固态继电器,以至于240v的电路两个针脚能够切换,另外我将通过软件来切换泵的开关,。现在他们通过盒子前面的物理开关控制,但是他们很容易用继电器控制。 -The pictures are from the "proof-of-concept" version—the final production system should have two more SSRs so that both legs of the 240v circuit would be switched. The other thing I would like to switch via software is the pumps. Right now they're controlled via physical switches on the front of the box, but they could easily be controlled with relays. ### [aedo-f3.png][13] ![Control box](https://opensource.com/sites/default/files/aedo-f3.png "Control box") -Control box (photo by Christopher Aedo. [CC BY-SA 4.0)][7] +控制盒子 (photo by Christopher Aedo. [CC BY-SA 4.0)][7] The only other thing I needed that was a little tricky to find was a compression fitting for the temperature probes. The probes were mounted in T fittings before the valve on the lowest bulkhead in both the HLT and the mash tun. As long as the liquid is flowing past the temp sensor, it's going to be accurate. I thought about adding a thermowell into the kettles as well, but realized that's not going to be useful for me based on my brewing process. Anyway, I purchased [1/4" compression fittings][34] and they worked out perfectly. From 50cf00f1a668cd25abce926d4b29795dc49e5935 Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 16:10:22 +0800 Subject: [PATCH 21/39] Rename 20170703 Brewing beer with Linux python and raspberry pi.md to Transleted20170703 Brewing beer with Linux python and raspberry pi.md Transletd by hwlife --- ...eer with Linux python and raspberry pi.md} | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) rename translated/tech/{20170703 Brewing beer with Linux python and raspberry pi.md => Transleted20170703 Brewing beer with Linux python and raspberry pi.md} (65%) diff --git a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/translated/tech/Transleted20170703 Brewing beer with Linux python and raspberry pi.md similarity index 65% rename from translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md rename to translated/tech/Transleted20170703 Brewing beer with Linux python and raspberry pi.md index cea388ac23..29a9613204 100644 --- a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/translated/tech/Transleted20170703 Brewing beer with Linux python and raspberry pi.md @@ -89,21 +89,22 @@ Inkbird SSR (photo by Christopher Aedo. [CC BY-SA 4.0)][6] 控制盒子 (photo by Christopher Aedo. [CC BY-SA 4.0)][7] -The only other thing I needed that was a little tricky to find was a compression fitting for the temperature probes. The probes were mounted in T fittings before the valve on the lowest bulkhead in both the HLT and the mash tun. As long as the liquid is flowing past the temp sensor, it's going to be accurate. I thought about adding a thermowell into the kettles as well, but realized that's not going to be useful for me based on my brewing process. Anyway, I purchased [1/4" compression fittings][34] and they worked out perfectly. +另一个事情是我要为温度探针找一个微型压缩装置,这个探针以T字型装置在加热酒精容器和麦芽浆桶球形阀门的最底部,只要是液体流过温度传感器,温度是准确显示的。我考虑加一个套管到热水壶里,但是基于我的酿造工艺没有什么用。无论如何,我买四分之一英寸的压缩配件,他们是完美的。 -### Software +### 软件 -Once the hardware was sorted out, I had time to play with the software. I ran the latest [Raspbian distribution][35] on the Pi; nothing special was required on the operating-system side. +一旦硬件整理好,我有时间来处理软件,我在树莓派上跑了最新的发行版,操作系统方面没有什么特别的。 -I started with [Strangebrew Elsinore][36] brewing software, which I had discovered when a friend asked whether I had heard of [Hosehead][37], a Raspberry Pi-based brewing controller. I thought Hosehead looked great, but rather than buying a brewing controller, I wanted the challenge of building my own. +我开始使用Strangebrew Elsinore酿酒软件,当我的朋友问我是否我听说过[Hosehead],一个基于树莓派的酿酒控制器,那时我已经听说过这个软件了。我认为[Hosehead]很棒,但并不是要买一个酿酒控制器,贰拾我要挑战自己搭建我自己的一个。 + +设置Strangebrew Elsinore 这个软件是按照说明文档操作,没有遇到任何的问题。尽管Strangebrew Elsinore工作的很好,在一代树莓派上运行java有时是费力的,不止崩溃一次。我看到这个软件开发停顿也很伤心,因为他们没有几个看起来很大的贡献者的社区(尽管有很多人还在用它) -Setting up Strangebrew Elsinore was straightforward—the [documentation][38] was thorough and I did not encounter any problems. Even though Strangebrew Elsinore was working fine, Java seemed to be taxing my first-generation Pi sometimes, and it crashed on me more than once. I also was sad to see development stall and there did not seem to be a big community of additional contributors (although there were—and still are—plenty of people using it). ### CraftBeerPi -Then I stumbled across [CraftBeerPI][39], which is written in Python and supported by a development community of active contributors. The original author (and current maintainer) Manuel Fritsch is great about handling contributions and giving feedback on issues that folks open. Cloning [the repo][40] and getting started only took me a few minutes. The README also has a good example of connecting DS1820 temp sensors, along with notes on interfacing hardware to a Pi or a [C.H.I.P. computer][41]. +之后我偶然遇到了一个用Python写的支持活跃的贡献者的开发社区的CraftbeerPI,应该叫手工啤酒派吧。原作者和当前维护者Manuel Fritsch在做贡献和反馈问题是友好的。克隆这个仓库然后开始花了我一些时间。README文档也是一个连接DS1820温度传感器的好例子,同时注意关于硬件接口到树莓派或者芯片电脑。 -On startup, CraftBeerPi walks users through a configuration process that discovers the temperature probes available and lets you specify which GPIO pins are managing which pieces of equipment. +在启动的时候,CraftbeerPI引导用户通过一个设置过程来发现温度探针是否可用,并且让你用GPIO总线控制器来管理树莓派上的特定设备部件 ### [aedo-f4.png][14] @@ -111,33 +112,34 @@ On startup, CraftBeerPi walks users through a configuration process that discove CraftBeerPi (photo by Christopher Aedo. [CC BY-SA 4.0)][8] -Running a brew with this system is easy. I can count on it holding temperatures reliably, and I can input steps for a multi-temp step mash. Using CraftBeerPi has made my brew days a little bit boring, but I'm happy to trade off the "excitement" of traditional manually managed propane burners for the efficiency and consistency of this system. +运行自制酿酒系统是容易的,我能够依靠它掌握可靠的温度,我能输入多个温度段来控制麦芽浆温度,用CraftbeerPi酿酒的日子有一点点累,但是传统手工管理丙烷燃烧器为系统的有效性和持续性我还是很高兴的。 -CraftBeerPI's user-friendliness inspired me to set up another controller to run a "fermentation chamber." In my case, that was a second-hand refrigerator I found for US$ 50 plus a $25 heater) on the inside. CraftBeerPI easily can control the cooling and heating elements, and you can set up multiple temperature steps. For instance, this graph shows the fermentation temperatures for a session IPA I made recently. The fermentation chamber held the fermenting wort at 67F for four days, then ramped up one degree every 12 hours until it was at 72F. That temp was held for a two-day diacetyl rest. After that it was set to drop down to 65F for five days, during which time I "dry hopped" the beer. Finally, the beer was cold-crashed down to 38F. CraftBeerPI made adding each step and letting the software manage the fermentation easy. +CraftBeerPI的用户友好性鼓舞我设置了另一个控制器来运行“发酵室”。就我来说,那是一个二手冰箱,我用了50美元加25美元的加热器设置在里边。CraftBeerPI很容易控制电器元件的冷热,你也能够设置多个温度阶段。举个例子,这个图表显示我最近做的IPA进程的发酵温度。发酵室发酵麦芽汁在67F的温度下需要4天,然后每到12小时上升一度直到温度到达72F。温度保持剩下两天是为了双乙酰生成。之后5天温度降到65F,这段时间是让啤酒变“干”,最后啤酒发酵温度直接降到38F。CraftBeerPI加入了每个阶段,让软件管理发酵更加容易。 ### [aedo-f5.png][15] ![SIPA fermentation profile](https://opensource.com/sites/default/files/aedo-f5.png "SIPA fermentation profile") -SIPA fermentation profile (photo by Christopher Aedo. [CC BY-SA 4.0)][9] +SIPA 发酵文档 (photo by Christopher Aedo. [CC BY-SA 4.0)][9] -I have also been experimenting with the [TILT hydrometer][42] to monitor the gravity of the fermenting beer via a Bluetooth-connected floating sensor. There are integration plans for this to get it working with CraftBeerPI, but for now it logs the gravity to a Google spreadsheet. Once this hydrometer can talk to the fermentation controller, setting automated fermentation profiles that take action directly based on the yeast activity would be easy—rather than banking on primary fermentation completing in four days, you can set the temperature ramp to kick off after the gravity is stable for 24 hours. +我也试验过用液体比重计来发对酵啤酒的重力进行监测,通过蓝牙连接的浮动传感器可以达到。有一个整合的计划能让CraftbeerPi很好工作,但是现在它记录这些重力数据到谷歌的电子表格里。一旦这个液体比重计能连接到发酵控制器,设置的自动发酵文档会基于酵母的活动性直接运行且更加容易,而不是在4天存贮的主要发酵完成,可以在重力24小时稳定在设定温度。 -As with any project like this, imaging and planning improvements and additional components is easy. Still, I'm happy with where things stand today. I've brewed a lot of beer with this setup and am hitting the expected mash efficiency every time, and the beer has been consistently tasty. My most important customer—me!—is pleased with what I've been putting on tap in my kitchen. + +像这样的一些项目,想象力和计划改进和额外的部件是很容易,不过,我很高兴今天经历过的事情。我用这种装置酿造了很多啤酒,每次都能达到预期的麦芽汁效率,而且啤酒一直都很美味。我最重要的消费者!-我,很高兴我可以随时饮用。 ### [aedo-f6.png][16] ![Homebrew on tap](https://opensource.com/sites/default/files/aedo-f6.png "Homebrew on tap") -Homebrew on tap (photo by Christopher Aedo. [CC BY-SA 4.0)][10] +随时饮用 (photo by Christopher Aedo. [CC BY-SA 4.0)][10] - _This article is based on Christopher's OpenWest talk, [Brewing Beer with Linux, Python and a RaspberryPi][18]. [OpenWest][19] will be held July 12-15, 2017 in Salt Lake City, Utah._ + 这篇文章基于克里斯托弗的开放的西部的谈话,用Linux,Python和树莓派酿制啤酒。 这次谈话将在2017年7月12-15日盐湖城举行。 -------------------------------------------------------------------------------- 作者简介: -Christopher Aedo - Christopher Aedo has been working with and contributing to open source software since his college days. Most recently he can be found leading an amazing team of upstream developers at IBM who are also developer advocates. When he’s not at work or speaking at a conference, he’s probably using a RaspberryPi to brew and ferment a tasty homebrew in Portland OR. +Christopher Aedo - Christopher Aedo 从他的学生时代就从事并且贡献于开源软件事业。最近他被发现是他在IBM领导一个逆流而上的开发者团队,同时他也是开发者拥护者。当他不再工作或者实在会议室演讲的时候,他可能在波特兰市俄勒冈州用树莓派酿制和发酵一杯美味的啤酒。 via: https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi From a093b7363847738002fc2df4e56764d0375210cc Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 16:22:31 +0800 Subject: [PATCH 22/39] Rename Transleted20170703 Brewing beer with Linux python and raspberry pi.md to 20170703 Brewing beer with Linux python and raspberry pi.md --- ...> 20170703 Brewing beer with Linux python and raspberry pi.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename translated/tech/{Transleted20170703 Brewing beer with Linux python and raspberry pi.md => 20170703 Brewing beer with Linux python and raspberry pi.md} (100%) diff --git a/translated/tech/Transleted20170703 Brewing beer with Linux python and raspberry pi.md b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md similarity index 100% rename from translated/tech/Transleted20170703 Brewing beer with Linux python and raspberry pi.md rename to translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md From 2cde5eeda1062b4de508210b3905e97dde98d8ce Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 8 Oct 2017 17:40:16 +0800 Subject: [PATCH 23/39] =?UTF-8?q?=E8=A1=A5=E5=AE=8C=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @hwlife --- ...beer with Linux python and raspberry pi.md | 193 ------------------ 1 file changed, 193 deletions(-) delete mode 100644 sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md diff --git a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md deleted file mode 100644 index d9bd699d63..0000000000 --- a/sources/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ /dev/null @@ -1,193 +0,0 @@ -hwlife is translating -Brewing beer with Linux, Python, and Raspberry Pi -============================================================ - -### A handy how-to for building a homemade homebrew setup with Python and the Raspberry Pi. - - -![Brewing beer with Linux, Python, and Raspberry Pi](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/beer-drink-sample-sampler.png?itok=20jJLB8V "Brewing beer with Linux, Python, and Raspberry Pi") -Image by :  - -[Quinn Dombrowski][21]. Modified by Opensource.com. [CC BY-SA 4.0][22]. - -I started brewing my own beer more than 10 years ago. Like most homebrewers, I started in my kitchen making extract-based brews. This required the least equipment and still resulted in really tasty beer. Eventually I stepped up to all-grain brewing using a big cooler for my mash tun. For several years I was brewing 5 gallons at a time, but brewing 10 gallons takes the same amount of time and effort (and only requires slightly larger equipment), so a few years ago I stepped it up. After moving up to 10 gallons, I stumbled across [StrangeBrew Elsinore][23] and realized what I  _really_  needed to do was convert my whole system to be all-electric, and run it with a [Raspberry Pi][24]. - -There is a ton of great information available for building your own all-electric homebrew system, and most brewers start out at [TheElectricBrewery.com][25]. Just putting together the control panel can get pretty complicated, although the simplest approach is outlined well there. Of course you can also take [a less expensive approach][26] and still end up with the same result—a boil kettle and hot liquor tank powered by heating elements and managed by a PID controller. I think that's a little too boring though (and it also means you don't get neat graphs of your brew process). - -More on Raspberry Pi - -* [Our latest on Raspberry Pi][1] - -* [What is Raspberry Pi?][2] - -* [Getting started with Raspberry Pi][3] - -* [Send us your Raspberry Pi projects and tutorials][4] - -### Hardware supplies - -Before I talked myself out of the project, I decided to start buying parts. My basic design was a Hot Liquor Tank (HLT) and boil kettle with 5500w heating elements in them, plus a mash tun with a false bottom. I would use a pump to recirculate the mash through a 50' stainless coil in the HLT (a ["heat exchanger recirculating mash system", known as HERMS][27]). I would need a second pump to circulate the water in the HLT, and to help with transferring water to the mash tun. All of the electrical components would be controlled with a Raspberry Pi. - -Building my electric brew system and automating as much of it as possible meant I was going to need the following: - -* HLT with a 5500w electric heating element - -* HERMS coil (50' 1/2" stainless steel) in the HLT - -* boil kettle with a 5500w electric heating element - -* multiple solid-state relays to switch the heaters on and off - -* 2 high-temp food-grade pumps - -* relays for switching the pumps on and off - -* fittings and high-temp silicon tubing - -* stainless ball valves - -* 1-wire temperature probes - -* lots of wire - -* electrical box to hold everything - -### [aedo-f1.png][11] - -![Brew system](https://opensource.com/sites/default/files/aedo-f1.png "Brew system") - -Brew system (photo by Christopher Aedo. [CC BY-SA 4.0)][5] - -The details of building out the electrical side of the system are really well covered by [The Electric Brewery][28], so I won't repeat their detailed information. You can read through and follow their suggestions while planning to replace the PID controllers with a Raspberry Pi. - -One important thing to note is the solid-state relay (SSR) signal voltage. Many tutorials suggest using SSRs that need a 12-volt signal to close the circuit. The Raspberry Pi GPIO pins will only output 3v, however. Be sure to purchase relays that will trigger on 3 volts. - -### [aedo-f2.png][12] - -![Inkbird SSR](https://opensource.com/sites/default/files/aedo-f2.png "Inkbird SSR") - -Inkbird SSR (photo by Christopher Aedo. [CC BY-SA 4.0)][6] - -To run your brew system, your Pi must do two key things: sense temperature from a few different places, and turn relays on and off to control the heating elements. The Raspberry Pi easily is able to handle these tasks. - -There are a few different ways to connect temp sensors to a Pi, but I've found the most convenient approach is to use the [1-Wire bus][29]. This allows for multiple sensors to share the same wire (actually three wires), which makes it a convenient way to instrument multiple components in your brew system. If you look for waterproof DS18B20 temperature sensors online, you'll find lots of options available. I used [Hilitchi DS18B20 Waterproof Temperature Sensors][30] for my project. - -To control the heating elements, the Raspberry Pi includes several General Purpose IO (GPIO) pins that are software addressable. This allows you to send 3.3v to a relay by simply putting a **1** or a **0** in a file. The  _Raspberry Pi—Driving a Relay using GPIO_  tutorial was the most helpful for me when I was first learning how all this worked. The GPIO controls multiple solid-state relays, turning on and off the heating elements as directed by the brewing software. - -I first started working on the box to hold all the components. Because this would all be on a rolling cart, I wanted it to be relatively portable rather than permanently mounted. If I had a spot (for example, inside a garage, utility room, or basement), I would have used a larger electrical box mounted on the wall. Instead I found a decent-size [waterproof project box][31] that I expected I could shoehorn everything into. In the end, it turned out to be a little bit of a tight fit, but it worked out. In the bottom left corner is the Pi with a breakout board for connecting the GPIO to the 1-Wire temperature probes and the [solid state relays][32]. - -To keep the 240v SSRs cool, I cut holes in the case and stacked [copper shims][33] with CPU cooling grease between them and heat sinks mounted on the outside of the box. It worked out well and there haven't been any cooling issues inside the box. On the cover I put two switches for 120v outlets, plus two 240v LEDs to show which heating element was energized. I used dryer plugs and outlets for all connections so disconnecting a kettle from everything is easy. Everything worked right on the first try, too. (Sketching a wiring diagram first definitely pays off.) - -The pictures are from the "proof-of-concept" version—the final production system should have two more SSRs so that both legs of the 240v circuit would be switched. The other thing I would like to switch via software is the pumps. Right now they're controlled via physical switches on the front of the box, but they could easily be controlled with relays. - -### [aedo-f3.png][13] - -![Control box](https://opensource.com/sites/default/files/aedo-f3.png "Control box") - -Control box (photo by Christopher Aedo. [CC BY-SA 4.0)][7] - -The only other thing I needed that was a little tricky to find was a compression fitting for the temperature probes. The probes were mounted in T fittings before the valve on the lowest bulkhead in both the HLT and the mash tun. As long as the liquid is flowing past the temp sensor, it's going to be accurate. I thought about adding a thermowell into the kettles as well, but realized that's not going to be useful for me based on my brewing process. Anyway, I purchased [1/4" compression fittings][34] and they worked out perfectly. - -### Software - -Once the hardware was sorted out, I had time to play with the software. I ran the latest [Raspbian distribution][35] on the Pi; nothing special was required on the operating-system side. - -I started with [Strangebrew Elsinore][36] brewing software, which I had discovered when a friend asked whether I had heard of [Hosehead][37], a Raspberry Pi-based brewing controller. I thought Hosehead looked great, but rather than buying a brewing controller, I wanted the challenge of building my own. - -Setting up Strangebrew Elsinore was straightforward—the [documentation][38] was thorough and I did not encounter any problems. Even though Strangebrew Elsinore was working fine, Java seemed to be taxing my first-generation Pi sometimes, and it crashed on me more than once. I also was sad to see development stall and there did not seem to be a big community of additional contributors (although there were—and still are—plenty of people using it). - -### CraftBeerPi - -Then I stumbled across [CraftBeerPI][39], which is written in Python and supported by a development community of active contributors. The original author (and current maintainer) Manuel Fritsch is great about handling contributions and giving feedback on issues that folks open. Cloning [the repo][40] and getting started only took me a few minutes. The README also has a good example of connecting DS1820 temp sensors, along with notes on interfacing hardware to a Pi or a [C.H.I.P. computer][41]. - -On startup, CraftBeerPi walks users through a configuration process that discovers the temperature probes available and lets you specify which GPIO pins are managing which pieces of equipment. - -### [aedo-f4.png][14] - -![CraftBeerPi](https://opensource.com/sites/default/files/images/life/aedo-f4.png "CraftBeerPi") - -CraftBeerPi (photo by Christopher Aedo. [CC BY-SA 4.0)][8] - -Running a brew with this system is easy. I can count on it holding temperatures reliably, and I can input steps for a multi-temp step mash. Using CraftBeerPi has made my brew days a little bit boring, but I'm happy to trade off the "excitement" of traditional manually managed propane burners for the efficiency and consistency of this system. - -CraftBeerPI's user-friendliness inspired me to set up another controller to run a "fermentation chamber." In my case, that was a second-hand refrigerator I found for US$ 50 plus a $25 heater) on the inside. CraftBeerPI easily can control the cooling and heating elements, and you can set up multiple temperature steps. For instance, this graph shows the fermentation temperatures for a session IPA I made recently. The fermentation chamber held the fermenting wort at 67F for four days, then ramped up one degree every 12 hours until it was at 72F. That temp was held for a two-day diacetyl rest. After that it was set to drop down to 65F for five days, during which time I "dry hopped" the beer. Finally, the beer was cold-crashed down to 38F. CraftBeerPI made adding each step and letting the software manage the fermentation easy. - -### [aedo-f5.png][15] - -![SIPA fermentation profile](https://opensource.com/sites/default/files/aedo-f5.png "SIPA fermentation profile") - -SIPA fermentation profile (photo by Christopher Aedo. [CC BY-SA 4.0)][9] - -I have also been experimenting with the [TILT hydrometer][42] to monitor the gravity of the fermenting beer via a Bluetooth-connected floating sensor. There are integration plans for this to get it working with CraftBeerPI, but for now it logs the gravity to a Google spreadsheet. Once this hydrometer can talk to the fermentation controller, setting automated fermentation profiles that take action directly based on the yeast activity would be easy—rather than banking on primary fermentation completing in four days, you can set the temperature ramp to kick off after the gravity is stable for 24 hours. - -As with any project like this, imaging and planning improvements and additional components is easy. Still, I'm happy with where things stand today. I've brewed a lot of beer with this setup and am hitting the expected mash efficiency every time, and the beer has been consistently tasty. My most important customer—me!—is pleased with what I've been putting on tap in my kitchen. - -### [aedo-f6.png][16] - -![Homebrew on tap](https://opensource.com/sites/default/files/aedo-f6.png "Homebrew on tap") - -Homebrew on tap (photo by Christopher Aedo. [CC BY-SA 4.0)][10] - - _This article is based on Christopher's OpenWest talk, [Brewing Beer with Linux, Python and a RaspberryPi][18]. [OpenWest][19] will be held July 12-15, 2017 in Salt Lake City, Utah._ - --------------------------------------------------------------------------------- - -作者简介: - -Christopher Aedo - Christopher Aedo has been working with and contributing to open source software since his college days. Most recently he can be found leading an amazing team of upstream developers at IBM who are also developer advocates. When he’s not at work or speaking at a conference, he’s probably using a RaspberryPi to brew and ferment a tasty homebrew in Portland OR. - - -via: https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi - -作者:[ Christopher Aedo][a] -译者:[译者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/docaedo -[1]:https://opensource.com/tags/raspberry-pi?src=raspberry_pi_resource_menu1 -[2]:https://opensource.com/resources/what-raspberry-pi?src=raspberry_pi_resource_menu2 -[3]:https://opensource.com/article/16/12/getting-started-raspberry-pi?src=raspberry_pi_resource_menu3 -[4]:https://opensource.com/article/17/2/raspberry-pi-submit-your-article?src=raspberry_pi_resource_menu4 -[5]:https://creativecommons.org/licenses/by-sa/4.0/ -[6]:https://creativecommons.org/licenses/by-sa/4.0/ -[7]:https://creativecommons.org/licenses/by-sa/4.0/ -[8]:https://creativecommons.org/licenses/by-sa/4.0/ -[9]:https://creativecommons.org/licenses/by-sa/4.0/ -[10]:https://creativecommons.org/licenses/by-sa/4.0/ -[11]:https://opensource.com/file/358661 -[12]:https://opensource.com/file/358666 -[13]:https://opensource.com/file/358676 -[14]:https://opensource.com/file/359061 -[15]:https://opensource.com/file/358681 -[16]:https://opensource.com/file/359071 -[17]:https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi?rate=fbKzT1V9gqGsmNCTuQIashC1xaHT5P_2LUaeTn6Kz1Y -[18]:https://www.openwest.org/custom/description.php?id=139 -[19]:https://www.openwest.org/ -[20]:https://opensource.com/user/145976/feed -[21]:https://www.flickr.com/photos/quinndombrowski/ -[22]:https://creativecommons.org/licenses/by-sa/4.0/ -[23]:https://github.com/DougEdey/SB_Elsinore_Server -[24]:https://opensource.com/tags/raspberry-pi -[25]:http://www.theelectricbrewery.com/ -[26]:http://www.instructables.com/id/Electric-Brewery-Control-Panel-on-the-Cheap/ -[27]:https://byo.com/hops/item/1325-rims-and-herms-brewing-advanced-homebrewing -[28]:http://theelectricbrewery.com/ -[29]:https://en.wikipedia.org/wiki/1-Wire -[30]:https://smile.amazon.com/gp/product/B018KFX5X0/ -[31]:http://amzn.to/2hupFCr -[32]:http://amzn.to/2hL8JDS -[33]:http://amzn.to/2i4DYwy -[34]:https://www.brewershardware.com/CF1412.html -[35]:https://www.raspberrypi.org/downloads/raspbian/ -[36]:https://github.com/DougEdey/SB_Elsinore_Server -[37]:https://brewtronix.com/ -[38]:http://dougedey.github.io/SB_Elsinore_Server/ -[39]:http://www.craftbeerpi.com/ -[40]:https://github.com/manuel83/craftbeerpi -[41]:https://www.nextthing.co/pages/chip -[42]:https://tilthydrometer.com/ -[43]:https://opensource.com/users/docaedo -[44]:https://opensource.com/users/docaedo -[45]:https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi#comments From a2dc84c2a0a4825e2c8eb70e484b72044693af96 Mon Sep 17 00:00:00 2001 From: hwlife <30950568+hwlife@users.noreply.github.com> Date: Sun, 8 Oct 2017 19:15:40 +0800 Subject: [PATCH 24/39] Update 20170908 Betting on the Web.md --- sources/tech/20170908 Betting on the Web.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20170908 Betting on the Web.md b/sources/tech/20170908 Betting on the Web.md index 84d70e164f..5a5746e681 100644 --- a/sources/tech/20170908 Betting on the Web.md +++ b/sources/tech/20170908 Betting on the Web.md @@ -1,3 +1,4 @@ +translate by hwlife [Betting on the Web][27] ============================================================ From 097d87744330c68f9b6e5abadd7006eb1c07d9b9 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 8 Oct 2017 21:28:57 +0800 Subject: [PATCH 25/39] PRF:20170703 Brewing beer with Linux python and raspberry pi.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @hwlife 语言能力不错,也对所翻译领域比较熟悉。不过后半部分有点疲倦了。此外, 要注意保留文章中的 markdown 标记(尤其是链接)。 --- ...beer with Linux python and raspberry pi.md | 129 ++++++------------ 1 file changed, 45 insertions(+), 84 deletions(-) diff --git a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md index 29a9613204..08a7a1cd55 100644 --- a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md +++ b/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md @@ -1,152 +1,112 @@ -用Linux,Python和树莓派酿制啤酒 +用 Linux、Python 和树莓派酿制啤酒 ============================================================ -### 怎样在家用python和树莓派搭建一个家用便携的自制酿啤酒装置 - +> 怎样在家用 Python 和树莓派搭建一个家用便携的自制酿啤酒装置 -![Brewing beer with Linux, Python, and Raspberry Pi](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/beer-drink-sample-sampler.png?itok=20jJLB8V "Brewing beer with Linux, Python, and Raspberry Pi") -Image by :  +![Brewing beer with Linux, Python, and Raspberry Pi](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/beer-drink-sample-sampler.png?itok=JV4E4iVY "Brewing beer with Linux, Python, and Raspberry Pi") -[Quinn Dombrowski][21]. Modified by Opensource.com. [CC BY-SA 4.0][22]. +大约十年前我开始酿制自制啤酒,和许多自己酿酒的人一样,我开始在厨房制造提纯啤酒。这需要一些设备并且做出来后确实是好的啤酒,最终,我用一个放入了所有大麦的大贮藏罐作为我的麦芽浆桶。几年之后我一次酿制过 5 加仑啤酒,但是酿制 10 加仑时也会花费同样的时间和效用(只是容器比之前大些),之前我就是这么做的。容量提升到 10 加仑之后,我偶然看到了 [StrangeBrew Elsinore][38] ,我意识到我真正需要的是将整个酿酒过程转换成全电子化的,用树莓派来运行它。 -大约十年前我开始酿制自制啤酒,和许多自己酿酒的人一样,我开始在厨房制造提纯啤酒。这需要一些设备并且做出来后确实是好的啤酒,最终,我用一个大的贮藏罐放入了所有大麦作为我的麦芽浆桶。几年之后我曾酿制了5加仑啤酒,但是酿制10加仑时会花费同样的时间和效用(只是容器比之前大些),之前我是这么做的。容量提升到10加仑之后,我偶然发现并意识到我真正需要的是将整个酿酒过程转换成全电子化的,用树莓派来运行它。 - -建造自己的家用电动化酿酒系统需要大量这方面的技术信息,许多学习酿酒的是在TheElectricBrewery.com这个网站起步的,只不过将那些控制版搭建在一起是十分复杂的,尽管最简单的办法在这个网站上总结的很好。当然你也能用一个小成本的方法并且依旧可以用相同的结果得到-用一个热水壶和热酒容器通过一个PID控制器来加热你的酿酒原料。但是我认为这有点太无聊(这也意味着你不能get到完成酿酒过程) - -关于树莓派更多信息 - -* [关于树莓派最新消息[1] - -* [树莓派是什么?][2] - -* [树莓派如何开始使用][3] - -* [发送给我们你的树莓派项目和教程][4] +建造自己的家用电动化酿酒系统需要大量这方面的技术信息,许多学习酿酒的人是在 [TheElectricBrewery.com][28] 这个网站起步的,只不过将那些控制版搭建在一起是十分复杂的,尽管最简单的办法在这个网站上总结的很好。当然你也能用[一个小成本的方法][26]并且依旧可以得到相同的结果 —— 用一个热水壶和热酒容器通过一个 PID 控制器来加热你的酿酒原料。但是我认为这有点太无聊(这也意味着你不能体验到完整的酿酒过程)。 ### 需要用到的硬件 -在我开始我得这个项目之前, 我决定开始买零件,我最基础的设计是一个可以将液体加热到5500w的热酒容器和开水壶,加一个活底的麦芽浆桶,我通过一个50的不锈钢线圈在热酒容器里让泵来再循环麦芽浆(a ["热量交换再循环麦芽浆系统, 也叫 HERMS][27]).同时我需要另一个泵来在热酒容器里循环水,并且把水传输到麦芽浆桶里,整个电子部件全部是用树莓派来控制的。 +在我开始我的这个项目之前, 我决定开始买零件,我最基础的设计是一个可以将液体加热到 5500 瓦的热酒容器(HLT)和开水壶,加一个活底的麦芽浆桶,我通过一个 50 英尺的不锈钢线圈在热酒容器里让泵来再循环麦芽浆(["热量交换再循环麦芽浆系统, 也叫 HERMS][27])。同时我需要另一个泵来在热酒容器里循环水,并且把水传输到麦芽浆桶里,整个电子部件全部是用树莓派来控制的。 +建立我的电子酿酒系统并且尽可能的自动化意味着我需要以下的组件: -建立我得电子酿酒系统并且尽可能的自动化意味着我需要以下的东东: - - -* 一个5500瓦的电子加热酒精容器 - -* 能够放入加热酒精容器里的一英尺(0.5英寸)长的不锈钢线圈(热量交换再循环麦芽浆系统) - -* 一个5500瓦的电子加热水壶 - +* 一个 5500 瓦的电子加热酒精容器(HLT) +* 能够放入加热酒精容器里的 50 英尺(0.5 英寸)的不锈钢线圈(热量交换再循环麦芽浆系统) +* 一个 5500 瓦的电子加热水壶 * 多个固态继电器加热开关 - -* 2个高温食品级泵 - +* 2 个高温食品级泵 * 泵的开关用继电器 - * 可拆除装置和一个硅管 - * 不锈钢球阀 - * 一个测量温度的探针 - * 很多线 - * 一个来容纳这些配件的电路盒子 -### [aedo-f1.png][11] - ![Brew system](https://opensource.com/sites/default/files/aedo-f1.png "Brew system") -酿酒系统 (photo by Christopher Aedo. [CC BY-SA 4.0)][5] +*酿酒系统 (photo by Christopher Aedo. [CC BY-SA 4.0)][5]* -建立酿酒系统的电气化方面的细节The Electric Brewery这个网站概括的很好,这里我不再重复,当你计划用树莓派代替这个PID控制器的话,你可以读以下的建议。 +建立酿酒系统的电气化方面的细节 [The Electric Brewery][28] 这个网站概括的很好,这里我不再重复,当你计划用树莓派代替这个 PID 控制器的话,你可以读以下的建议。 -一个重要的事情需要注意,固态继电器信号电压,许多教程建议使用一个12伏的固态继电器来关闭电路,树莓派的GPIO针插口只支持输出电压3伏,然而,必须购买继电器将电压变为3伏。 - -### [aedo-f2.png][12] +一个重要的事情需要注意,固态继电器(SSR)信号电压,许多教程建议使用一个 12 伏的固态继电器来关闭电路,树莓派的 GPIO 针插口只支持 3 伏输出电压,然而,必须购买继电器将电压变为 3 伏。 ![Inkbird SSR](https://opensource.com/sites/default/files/aedo-f2.png "Inkbird SSR") -Inkbird SSR (photo by Christopher Aedo. [CC BY-SA 4.0)][6] +*Inkbird SSR (photo by Christopher Aedo. [CC BY-SA 4.0)][6]* -要运行酿酒系统,你的树莓派必须做两个关键事情:来自不同位置的敏感温度,用继电器开关来控制加热元件,树莓派很容易来处理这些任务。 +要运行酿酒系统,你的树莓派必须做两个关键事情:测量来自几个不同位置的温度,用继电器开关来控制加热元件,树莓派很容易来处理这些任务。 -这里有一些不同的方法来将温度传感器连到树莓派上,但是我找到了最方便的方法用单总线。这就可以让多个传感器分享相同的线路(实际上三根线),这三根线可以使酿酒系统的多个设备更方便的工作,如果你要从网上找一个DS18B20 防水的温度传感器,你将会找到更多的选择。我用的是日立DS18B20防水温度传感器。 +这里有一些不同的方法来将温度传感器连到树莓派上,但是我找到了最方便的方法用[单总线][29]。这就可以让多个传感器分享相同的线路(实际上是三根线),这三根线可以使酿酒系统的多个设备更方便的工作,如果你要从网上找一个防水的 DS18B20 温度传感器,你可以会找到很多选择。我用的是[日立 DS18B20 防水温度传感器][30]。 -要控制加热元件,树莓派包括几个用来软件寻址的总线扩展器(GPIO),它会通过在某个文件写入0或者1让你发送3.3v的电压到一个继电器,在我第一次了解树莓派是怎样工作的时候,这个用GPIO驱动继电器的树莓派教程对我来说是最有帮助的,总线控制器控制多个固态继电器,通过酿酒软件来直接控制加热元件的开关。 +要控制加热元件,树莓派包括了几个用来软件寻址的总线扩展器(GPIO),它会通过在某个文件写入 0 或者 1 让你发送3.3v 的电压到一个继电器,在我第一次了解树莓派是怎样工作的时候,这个[用 GPIO 驱动继电器的树莓派教程][46]对我来说是最有帮助的,总线扩展器控制着多个固态继电器,通过酿酒软件来直接控制加热元件的开关。 -我第一次将所有部件放到这个电路盒子,因为这将成为一个滚动的小车,我要让他方便移动,而不是固定不动的,如果我有一个店(比如说在车库,工具房,或者地下室),我需要要用一个更大的电路盒挂到墙上,而现在我找到一个大小正好的防水工程盒子,能放进每件东西,最后它成为紧密的结合工具盒,并且能够工作。在左下角是和树莓派连接的为总线控制器到单总线温度探针和固态继电器的扩展板。 +我首先将所有部件放到这个电路盒子,因为这将成为一个滚动的小车,我要让它便于移动,而不是固定不动的,如果我有一个店(比如说在车库、工具房、或者地下室),我需要要用一个装在墙上的更大的电路盒,而现在我找到一个大小正好的[防水工程盒子][31],能放进每件东西,最后它成为小巧紧凑工具盒,并且能够工作。在左下角是和树莓派连接的为总线扩展器到单总线温度探针和[固态继电器][32]的扩展板。 -要保持240v的固态继电器温度不高,我在盒子上切了个洞,在盒子的外面用降温凝胶安装铜片散热片冷却cpu的温度。它工作的很好,盒子里没有温度上的问题了,在盒子盖上我放了两个开关为120v的插座,加两个240v的led来显示加热元件是否通电。我用干燥器的插座和插头很容易的开关电热水壶的连接。第一次尝试每件事情都弄好了。(决定第一次手画电路图.) +要保持 240v 的固态继电器温度不高,我在盒子上切了个洞,在盒子的外面用 CPU 降温凝胶把[铜片散热片][33]安装到盒子外面的热槽之间。它工作的很好,盒子里没有温度上的问题了,在盒子盖上我放了两个开关为 120v 的插座,加两个240v 的 led 来显示加热元件是否通电。我用干燥器的插座和插头,所以可以很容易的断开电热水壶的连接。首次尝试每件事情都工作正常。(第一次绘制电路图必有回报) - -照片是从“概念”版的最终生产系统应该有两个固态继电器,以至于240v的电路两个针脚能够切换,另外我将通过软件来切换泵的开关,。现在他们通过盒子前面的物理开关控制,但是他们很容易用继电器控制。 - - -### [aedo-f3.png][13] +这个照片来自“概念”版,最终生产系统应该有两个以上的固态继电器,以便 240v 的电路两个针脚能够切换,另外我将通过软件来切换泵的开关。现在通过盒子前面的物理开关控制它们,但是也很容易用继电器控制它们。 ![Control box](https://opensource.com/sites/default/files/aedo-f3.png "Control box") -控制盒子 (photo by Christopher Aedo. [CC BY-SA 4.0)][7] +*控制盒子 (photo by Christopher Aedo. [CC BY-SA 4.0)][7]* -另一个事情是我要为温度探针找一个微型压缩装置,这个探针以T字型装置在加热酒精容器和麦芽浆桶球形阀门的最底部,只要是液体流过温度传感器,温度是准确显示的。我考虑加一个套管到热水壶里,但是基于我的酿造工艺没有什么用。无论如何,我买四分之一英寸的压缩配件,他们是完美的。 +唯一剩下有点棘手的事情是温度探针的压合接头,这个探针安装在加热酒精容器和麦芽浆桶球形的最底部阀门前的 T 字型接头上。当液体流过温度传感器,温度可以准确显示。我考虑加一个套管到热水壶里,但是对于我的酿造工艺没有什么用。最后,我买到了[四分之一英寸的压合接头][34],它们工作完美。 ### 软件 -一旦硬件整理好,我有时间来处理软件,我在树莓派上跑了最新的发行版,操作系统方面没有什么特别的。 +一旦硬件整理好,我就有时间来处理软件了,我在树莓派上跑了最新的 [Raspbian 发行版][35],操作系统方面没有什么特别的。 -我开始使用Strangebrew Elsinore酿酒软件,当我的朋友问我是否我听说过[Hosehead],一个基于树莓派的酿酒控制器,那时我已经听说过这个软件了。我认为[Hosehead]很棒,但并不是要买一个酿酒控制器,贰拾我要挑战自己搭建我自己的一个。 +我开始使用 [Strangebrew Elsinore][36] 酿酒软件,当我的朋友问我是否我听说过 [Hosehead][37](一个基于树莓派的酿酒控制器),我找到了 [Strangebrew Elsinore][36] 。我认为 [Hosehead][37] 很棒,但我并不是要买一个酿酒控制器,而是要挑战自己,搭建一个自己的。 -设置Strangebrew Elsinore 这个软件是按照说明文档操作,没有遇到任何的问题。尽管Strangebrew Elsinore工作的很好,在一代树莓派上运行java有时是费力的,不止崩溃一次。我看到这个软件开发停顿也很伤心,因为他们没有几个看起来很大的贡献者的社区(尽管有很多人还在用它) +设置 [Strangebrew Elsinore][36] 很简单,其[文档][38]直白,没有遇到任何的问题。尽管 Strangebrew Elsinore 工作的很好,但在我的一代树莓派上运行 java 有时是费力的,不止崩溃一次。我看到这个软件开发停顿也很伤心,似乎他们也没有更多贡献者的大型社区(尽管有很多人还在用它)。 +#### CraftBeerPi -### CraftBeerPi +之后我偶然遇到了一个用 Python 写的 [CraftbeerPI][39],它有活跃的贡献者支持的开发社区。原作者(也是当前维护者) Manuel Fritsch 在贡献和反馈问题处理方面做的很好。克隆[这个仓库][40]然后开始只用了我一点时间。其 README 文档也是一个连接 DS1820 温度传感器的好例子,同时也有关于硬件接口到树莓派或者[芯片电脑][41] 的注意事项。 -之后我偶然遇到了一个用Python写的支持活跃的贡献者的开发社区的CraftbeerPI,应该叫手工啤酒派吧。原作者和当前维护者Manuel Fritsch在做贡献和反馈问题是友好的。克隆这个仓库然后开始花了我一些时间。README文档也是一个连接DS1820温度传感器的好例子,同时注意关于硬件接口到树莓派或者芯片电脑。 - -在启动的时候,CraftbeerPI引导用户通过一个设置过程来发现温度探针是否可用,并且让你用GPIO总线控制器来管理树莓派上的特定设备部件 - -### [aedo-f4.png][14] +在启动的时候,CraftbeerPI 引导用户通过一个设置过程来发现温度探针是否可用,并且让你指定哪个 GPIO 总线扩展器指针来管理树莓派上哪个配件。 ![CraftBeerPi](https://opensource.com/sites/default/files/images/life/aedo-f4.png "CraftBeerPi") -CraftBeerPi (photo by Christopher Aedo. [CC BY-SA 4.0)][8] +*CraftBeerPi (photo by Christopher Aedo. [CC BY-SA 4.0)][8]* -运行自制酿酒系统是容易的,我能够依靠它掌握可靠的温度,我能输入多个温度段来控制麦芽浆温度,用CraftbeerPi酿酒的日子有一点点累,但是传统手工管理丙烷燃烧器为系统的有效性和持续性我还是很高兴的。 +用这个系统进行自制酿酒是容易的,我能够依靠它掌握可靠的温度,我能输入多个温度段来控制麦芽浆温度,用CraftbeerPi 酿酒的日子有一点点累,但是我很高兴用传统的手工管理丙烷燃烧器的“兴奋”来换取这个系统的有效性和持续性。 -CraftBeerPI的用户友好性鼓舞我设置了另一个控制器来运行“发酵室”。就我来说,那是一个二手冰箱,我用了50美元加25美元的加热器设置在里边。CraftBeerPI很容易控制电器元件的冷热,你也能够设置多个温度阶段。举个例子,这个图表显示我最近做的IPA进程的发酵温度。发酵室发酵麦芽汁在67F的温度下需要4天,然后每到12小时上升一度直到温度到达72F。温度保持剩下两天是为了双乙酰生成。之后5天温度降到65F,这段时间是让啤酒变“干”,最后啤酒发酵温度直接降到38F。CraftBeerPI加入了每个阶段,让软件管理发酵更加容易。 - -### [aedo-f5.png][15] +CraftBeerPI 的用户友好性鼓舞我设置了另一个控制器来运行“发酵室”。就我来说,那是一个二手冰箱,我用了 50 美元加上放在里面的 25 美元的加热器。CraftBeerPI 很容易控制电器元件的冷热,你也能够设置多个温度阶段。举个例子,这个图表显示我最近做的 IPA 进程的发酵温度。发酵室发酵麦芽汁在 67F° 的温度下需要 4 天,然后每 12 小时上升一度直到温度到达 72F°。剩下两天温度保持不变是为了双乙酰生成。之后 5 天温度降到 65F°,这段时间是让啤酒变“干”,最后啤酒发酵温度直接降到 38F°。CraftBeerPI 可以加入各个阶段,让软件管理发酵更加容易。 ![SIPA fermentation profile](https://opensource.com/sites/default/files/aedo-f5.png "SIPA fermentation profile") -SIPA 发酵文档 (photo by Christopher Aedo. [CC BY-SA 4.0)][9] +*SIPA 发酵设置 (photo by Christopher Aedo. [CC BY-SA 4.0)][9]* -我也试验过用液体比重计来发对酵啤酒的重力进行监测,通过蓝牙连接的浮动传感器可以达到。有一个整合的计划能让CraftbeerPi很好工作,但是现在它记录这些重力数据到谷歌的电子表格里。一旦这个液体比重计能连接到发酵控制器,设置的自动发酵文档会基于酵母的活动性直接运行且更加容易,而不是在4天存贮的主要发酵完成,可以在重力24小时稳定在设定温度。 +我也试验过用[液体比重计][42]来对酵啤酒的比重进行监测,通过蓝牙连接的浮动传感器可以达到。有一个整合的计划能让 CraftbeerPi 很好工作,现在它记录这些比重数据到谷歌的电子表格里。一旦这个液体比重计能连接到发酵控制器,设置的自动发酵设置会基于酵母的活动性直接运行且更加容易,而不是在 4 天内完成主要发酵,可以在比重稳定 24 小时后设定温度。 - -像这样的一些项目,想象力和计划改进和额外的部件是很容易,不过,我很高兴今天经历过的事情。我用这种装置酿造了很多啤酒,每次都能达到预期的麦芽汁效率,而且啤酒一直都很美味。我最重要的消费者!-我,很高兴我可以随时饮用。 - -### [aedo-f6.png][16] +像这样的一些项目,构想并计划改进和增加组件是很容易,不过,我很高兴今天经历过的事情。我用这种装置酿造了很多啤酒,每次都能达到预期的麦芽汁比率,而且啤酒一直都很美味。我的最重要的消费者 —— 就是我!很高兴我可以随时饮用。 ![Homebrew on tap](https://opensource.com/sites/default/files/aedo-f6.png "Homebrew on tap") -随时饮用 (photo by Christopher Aedo. [CC BY-SA 4.0)][10] +*随时饮用 (photo by Christopher Aedo. [CC BY-SA 4.0)][10]* - 这篇文章基于克里斯托弗的开放的西部的谈话,用Linux,Python和树莓派酿制啤酒。 这次谈话将在2017年7月12-15日盐湖城举行。 +这篇文章基于 Christopher 的开放的西部的讲话《用Linux、Python 和树莓派酿制啤酒》。 + +(题图:[Quinn Dombrowski][21]. Modified by Opensource.com. [CC BY-SA 4.0][22]) -------------------------------------------------------------------------------- 作者简介: -Christopher Aedo - Christopher Aedo 从他的学生时代就从事并且贡献于开源软件事业。最近他被发现是他在IBM领导一个逆流而上的开发者团队,同时他也是开发者拥护者。当他不再工作或者实在会议室演讲的时候,他可能在波特兰市俄勒冈州用树莓派酿制和发酵一杯美味的啤酒。 - +Christopher Aedo 从他的学生时代就从事并且贡献于开源软件事业。最近他在 IBM 领导一个极棒的上游开发者团队,同时他也是开发者拥护者。当他不再工作或者实在会议室演讲的时候,他可能在波特兰市俄勒冈州用树莓派酿制和发酵一杯美味的啤酒。 +---- via: https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi -作者:[ Christopher Aedo][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +作者:[Christopher Aedo][a] +译者:[hwlife](https://github.com/hwlife) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -196,3 +156,4 @@ via: https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi [43]:https://opensource.com/users/docaedo [44]:https://opensource.com/users/docaedo [45]:https://opensource.com/article/17/7/brewing-beer-python-and-raspberry-pi#comments +[46]:http://www.susa.net/wordpress/2012/06/raspberry-pi-relay-using-gpio/ \ No newline at end of file From 011215e2b4a655c36dafe8df1d519ceefe928fc5 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 8 Oct 2017 21:32:53 +0800 Subject: [PATCH 26/39] PUB:20170703 Brewing beer with Linux python and raspberry pi.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @hwlife 本文发表地址: https://linux.cn/article-8942-1.html --- .../20170703 Brewing beer with Linux python and raspberry pi.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170703 Brewing beer with Linux python and raspberry pi.md (100%) diff --git a/translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md b/published/20170703 Brewing beer with Linux python and raspberry pi.md similarity index 100% rename from translated/tech/20170703 Brewing beer with Linux python and raspberry pi.md rename to published/20170703 Brewing beer with Linux python and raspberry pi.md From cda4543a9871375acfeac8d655b0f0365193a2a6 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 8 Oct 2017 22:41:06 +0800 Subject: [PATCH 27/39] PRF&PUB:20170801 Writing a Linux Debugger Part 10 Advanced topics.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @geekpi 终于又搞完一个系列。 --- ... Linux Debugger Part 10 Advanced topics.md | 79 ++++++------------- 1 file changed, 25 insertions(+), 54 deletions(-) rename {translated/tech => published}/20170801 Writing a Linux Debugger Part 10 Advanced topics.md (53%) diff --git a/translated/tech/20170801 Writing a Linux Debugger Part 10 Advanced topics.md b/published/20170801 Writing a Linux Debugger Part 10 Advanced topics.md similarity index 53% rename from translated/tech/20170801 Writing a Linux Debugger Part 10 Advanced topics.md rename to published/20170801 Writing a Linux Debugger Part 10 Advanced topics.md index 7e0d882082..61a02eb69d 100644 --- a/translated/tech/20170801 Writing a Linux Debugger Part 10 Advanced topics.md +++ b/published/20170801 Writing a Linux Debugger Part 10 Advanced topics.md @@ -1,95 +1,68 @@ 开发一个 Linux 调试器(十):高级主题 ============================================================ -我们终于来到这个系列的最后一篇文章!这一次,我将对调试中的一些更高级的概念进行高层的概述:远程调试、共享库支持、表达式计算和多线程支持。这些想法实现起来比较复杂,所以我不会详细说明如何做,但是如果有的话,我很乐意回答有关这些概念的问题。 - -* * * +我们终于来到这个系列的最后一篇文章!这一次,我将对调试中的一些更高级的概念进行高层的概述:远程调试、共享库支持、表达式计算和多线程支持。这些想法实现起来比较复杂,所以我不会详细说明如何做,但是如果你有问题的话,我很乐意回答有关这些概念的问题。 ### 系列索引 1. [准备环境][1] - 2. [断点][2] - 3. [寄存器和内存][3] - 4. [Elves 和 dwarves][4] - 5. [源码和信号][5] - 6. [源码层逐步执行][6] - 7. [源码层断点][7] - 8. [调用栈][8] - 9. [处理变量][9] - 10. [高级主题][10] -* * * - ### 远程调试 -远程调试对于嵌入式系统或不同环境的调试非常有用。它还在高级调试器操作和与操作系统和硬件的交互之间设置了一个很好的分界线。事实上,像 GDB 和 LLDB 这样的调试器即使在调试本地程序时也可以作为远程调试器运行。一般架构是这样的: +远程调试对于嵌入式系统或对不同环境进行调试非常有用。它还在高级调试器操作和与操作系统和硬件的交互之间设置了一个很好的分界线。事实上,像 GDB 和 LLDB 这样的调试器即使在调试本地程序时也可以作为远程调试器运行。一般架构是这样的: ![debugarch](https://blog.tartanllama.xyz/assets/debugarch.png) -调试器是我们通过命令行交互的组件。也许如果你使用的是 IDE,那么顶层中另一个层可以通过_机器接口_与调试器进行通信。在目标机器上(可能与本机一样)有一个 _debug stub_ ,它理论上是一个非常小的操作系统调试库的包装程序,它执行所有的低级调试任务,如在地址上设置断点。我说“在理论上”,因为如今 stub 变得越来越大。例如,我机器上的 LLDB debug stub 大小是 7.6MB。debug stub 通过一些使用特定于操作系统的功能(在我们的例子中是 “ptrace”)和被调试进程以及通过远程协议的调试器通信。 +调试器是我们通过命令行交互的组件。也许如果你使用的是 IDE,那么在其上有另一个层可以通过_机器接口_与调试器进行通信。在目标机器上(可能与本机一样)有一个调试存根debug stub ,理论上它是一个非常小的操作系统调试库的包装程序,它执行所有的低级调试任务,如在地址上设置断点。我说“在理论上”,因为如今调试存根变得越来越大。例如,我机器上的 LLDB 调试存根大小是 7.6MB。调试存根通过使用一些特定于操作系统的功能(在我们的例子中是 `ptrace`)和被调试进程以及通过远程协议的调试器通信。 -最常见的远程调试协议是 GDB 远程协议。这是一种基于文本的数据包格式,用于在调试器和 debug - stub 之间传递命令和信息。我不会详细介绍它,但你可以在[这里][11]阅读你想知道的。如果你启动 LLDB 并执行命令 `log enable gdb-remote packets`,那么你将获得通过远程协议发送的所有数据包的跟踪。在 GDB 上,你可以用 `set remotelogfile ` 做同样的事情。 +最常见的远程调试协议是 GDB 远程协议。这是一种基于文本的数据包格式,用于在调试器和调试存根之间传递命令和信息。我不会详细介绍它,但你可以在[这里][11]进一步阅读。如果你启动 LLDB 并执行命令 `log enable gdb-remote packets`,那么你将获得通过远程协议发送的所有数据包的跟踪信息。在 GDB 上,你可以用 `set remotelogfile ` 做同样的事情。 -作为一个简单的例子,这是数据包设置断点: +作为一个简单的例子,这是设置断点的数据包: ``` $Z0,400570,1#43 - ``` `$` 标记数据包的开始。`Z0` 是插入内存断点的命令。`400570` 和 `1` 是参数,其中前者是设置断点的地址,后者是特定目标的断点类型说明符。最后,`#43` 是校验值,以确保数据没有损坏。 GDB 远程协议非常易于扩展自定义数据包,这对于实现平台或语言特定的功能非常有用。 -* * * - ### 共享库和动态加载支持 -调试器需要知道调试程序加载了哪些共享库,以便它可以设置断点,获取源代码级别的信息和符号等。除查找被动态链接的库之外,调试器还必须跟踪在运行时通过 `dlopen` 加载的库。为了打到这个目的,动态链接器维护一个 _交会结构体_。该结构体维护共享描述符的链表以及指向每当更新链表时调用的函数的指针。这个结构存储在 ELF 文件的 `.dynamic` 段中,在程序执行之前被初始化。 +调试器需要知道被调试程序加载了哪些共享库,以便它可以设置断点、获取源代码级别的信息和符号等。除查找被动态链接的库之外,调试器还必须跟踪在运行时通过 `dlopen` 加载的库。为了达到这个目的,动态链接器维护一个 _交汇结构体_。该结构体维护共享库描述符的链表,以及一个指向每当更新链表时调用的函数的指针。这个结构存储在 ELF 文件的 `.dynamic` 段中,在程序执行之前被初始化。 一个简单的跟踪算法: -* 追踪程序在 ELF 头中查找程序的入口(或者可以使用存储在 `/proc//aux` 中的辅助向量) - +* 追踪程序在 ELF 头中查找程序的入口(或者可以使用存储在 `/proc//aux` 中的辅助向量)。 * 追踪程序在程序的入口处设置一个断点,并开始执行。 - * 当到达断点时,通过在 ELF 文件中查找 `.dynamic` 的加载地址找到交汇结构体的地址。 - * 检查交汇结构体以获取当前加载的库的列表。 - -* 链接器更新函数上设置断点 - -* 每当到达断点时,列表都会更新 - +* 链接器更新函数上设置断点。 +* 每当到达断点时,列表都会更新。 * 追踪程序无限循环,继续执行程序并等待信号,直到追踪程序信号退出。 我给这些概念写了一个小例子,你可以在[这里][12]找到。如果有人有兴趣,我可以将来写得更详细一点。 -* * * - ### 表达式计算 表达式计算是程序的一项功能,允许用户在调试程序时对原始源语言中的表达式进行计算。例如,在 LLDB 或 GDB 中,可以执行 `print foo()` 来调用 `foo` 函数并打印结果。 -根据表达的复杂程度,有几种不同的计算方法。如果表达式只是一个简单的标识符,那么调试器可以查看调试信息,找到变量并打印出该值,就像我们在本系列最后一部分中所做的那样。如果表达式有点复杂,则可能将代码编译成中间表达式 (IR) 并解释来获得结果。例如,对于某些表达式,LLDB 将使用 Clang 将表达式编译为 LLVM IR 并将其解释。如果表达式更复杂,或者需要调用某些函数,那么代码可能需要 JIT 到目标并在被调试者的地址空间中执行。这涉及到调用 `mmap` 来分配一些可执行内存,然后将编译的代码复制到该块并执行。LLDB 通过使用 LLVM 的 JIT 功能来实现。 +根据表达式的复杂程度,有几种不同的计算方法。如果表达式只是一个简单的标识符,那么调试器可以查看调试信息,找到该变量并打印出该值,就像我们在本系列最后一部分中所做的那样。如果表达式有点复杂,则可能将代码编译成中间表达式 (IR) 并解释来获得结果。例如,对于某些表达式,LLDB 将使用 Clang 将表达式编译为 LLVM IR 并将其解释。如果表达式更复杂,或者需要调用某些函数,那么代码可能需要 JIT 到目标并在被调试者的地址空间中执行。这涉及到调用 `mmap` 来分配一些可执行内存,然后将编译的代码复制到该块并执行。LLDB 通过使用 LLVM 的 JIT 功能来实现。 -如果你想更多地了解 JIT 编译,我强烈推荐[ Eli Bendersky 关于这个主题的文章][13]。 - -* * * +如果你想更多地了解 JIT 编译,我强烈推荐 [Eli Bendersky 关于这个主题的文章][13]。 ### 多线程调试支持 -本系列展示的调试器仅支持单线程应用程序,但是为了调试大多数真实程序,多线程支持是非常需要的。支持这一点的最简单的方法是跟踪线程创建并解析 procfs 以获取所需的信息。 +本系列展示的调试器仅支持单线程应用程序,但是为了调试大多数真实程序,多线程支持是非常需要的。支持这一点的最简单的方法是跟踪线程的创建,并解析 procfs 以获取所需的信息。 Linux 线程库称为 `pthreads`。当调用 `pthread_create` 时,库会使用 `clone` 系统调用来创建一个新的线程,我们可以用 `ptrace` 跟踪这个系统调用(假设你的内核早于 2.5.46)。为此,你需要在连接到调试器之后设置一些 `ptrace` 选项: @@ -97,7 +70,7 @@ Linux 线程库称为 `pthreads`。当调用 `pthread_create` 时,库会使用 ptrace(PTRACE_SETOPTIONS, m_pid, nullptr, PTRACE_O_TRACECLONE); ``` -现在当 `clone` 被调用时,该进程将收到我们的老朋友 `SIGTRAP` 发出信号。对于本系列中的调试器,你可以将一个例子添加到 `handle_sigtrap` 来处理新线程的创建: +现在当 `clone` 被调用时,该进程将收到我们的老朋友 `SIGTRAP` 信号。对于本系列中的调试器,你可以将一个例子添加到 `handle_sigtrap` 来处理新线程的创建: ``` case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): @@ -115,32 +88,30 @@ GDB 使用 `libthread_db`,它提供了一堆帮助函数,这样你就不需 多线程支持中最复杂的部分是调试器中线程状态的建模,特别是如果你希望支持[不间断模式][15]或当你计算中涉及不止一个 CPU 的某种异构调试。 -* * * - ### 最后! -呼!这个系列花了很长时间才写完,但是我在这个过程中学到了很多东西,我希望它是有帮助的。如果你聊有关调试或本系列中的任何问题,请在 Twitter [@TartanLlama][16]或评论区联系我。如果你有想看到的其他任何调试主题,让我知道我或许会再发其他的文章。 +呼!这个系列花了很长时间才写完,但是我在这个过程中学到了很多东西,我希望它是有帮助的。如果你有关于调试或本系列中的任何问题,请在 Twitter [@TartanLlama][16]或评论区联系我。如果你有想看到的其他任何调试主题,让我知道我或许会再发其他的文章。 -------------------------------------------------------------------------------- via: https://blog.tartanllama.xyz/writing-a-linux-debugger-advanced-topics/ -作者:[Simon Brand ][a] +作者:[Simon Brand][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.twitter.com/TartanLlama -[1]:https://blog.tartanllama.xyz/writing-a-linux-debugger-setup/ -[2]:https://blog.tartanllama.xyz/writing-a-linux-debugger-breakpoints/ -[3]:https://blog.tartanllama.xyz/writing-a-linux-debugger-registers/ -[4]:https://blog.tartanllama.xyz/writing-a-linux-debugger-elf-dwarf/ -[5]:https://blog.tartanllama.xyz/writing-a-linux-debugger-source-signal/ -[6]:https://blog.tartanllama.xyz/writing-a-linux-debugger-dwarf-step/ -[7]:https://blog.tartanllama.xyz/writing-a-linux-debugger-source-break/ -[8]:https://blog.tartanllama.xyz/writing-a-linux-debugger-unwinding/ -[9]:https://blog.tartanllama.xyz/writing-a-linux-debugger-variables/ +[1]:https://linux.cn/article-8626-1.html +[2]:https://linux.cn/article-8645-1.html +[3]:https://linux.cn/article-8663-1.html +[4]:https://linux.cn/article-8719-1.html +[5]:https://linux.cn/article-8812-1.html +[6]:https://linux.cn/article-8813-1.html +[7]:https://linux.cn/article-8890-1.html +[8]:https://linux.cn/article-8930-1.html +[9]:https://linux.cn/article-8936-1.html [10]:https://blog.tartanllama.xyz/writing-a-linux-debugger-advanced-topics/ [11]:https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html [12]:https://github.com/TartanLlama/dltrace From 4be6a454d36d5692869064bfc019117ccfc17f3c Mon Sep 17 00:00:00 2001 From: toutoudnf Date: Mon, 9 Oct 2017 00:24:26 +0800 Subject: [PATCH 28/39] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成文章:20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH 的翻译 --- ... The 8 possible scenarios using OpenSSH.md | 436 ------------------ ... The 8 possible scenarios using OpenSSH.md | 412 +++++++++++++++++ 2 files changed, 412 insertions(+), 436 deletions(-) delete mode 100644 sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md create mode 100644 translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md diff --git a/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md b/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md deleted file mode 100644 index b96921df89..0000000000 --- a/sources/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md +++ /dev/null @@ -1,436 +0,0 @@ -【toutoudnf@gmail.com】翻译中 -Creating TCP / IP (port forwarding) tunnels with SSH: The 8 possible scenarios using OpenSSH -============================================================ - -The typical function of the [Secure Shell (SSH)][21] network protocol is to access a remote system in terminal mode and execute commands there safely, because the data is encrypted. In addition, through this secure data connection, it is possible to create tunnels (  _port forwarding_  ) between the connected ends so that the TCP / IP connections are channeled through the SSH connection so that we can get away with any Firewall or port blocking whenever we have the possibility to connect with SSH. - -As this topic is very much addressed by the entire network: - -* [Wikipedia: SSH Tunneling][12] - -* [O’Reilly: Using SSH Tunneling][13] - -* [Ssh.com: Tunneling Explained][14] - -* [Ssh.com: Port Forwarding][15] - -* [SecurityFocus: SSH Port Forwarding][16] - -* [Red Hat Magazine: SSH Port Forwarding][17] - -In this entry we will not go into the details of port forwarding, but pretend to be a  _cheat sheet_ , a quick reference (  _cheat sheet_  ) on how to forward TCP ports with [OpenSSH][22] in the 8 different scenarios that can be given. Other SSH clients such as [PuTTY][23] also allow port forwarding, but the configuration will be done with a graphical interface. We will focus on OpenSSH. - -In the following examples and situations we will assume that we have an external network and an internal network and between both networks, the only possible connection is an SSH connection between the node of the external external  _network1_  and the node of the internal internal  _network1_  . The  _external node2_  is on the external network and has full connectivity with  _external1_ . The node  _interno2_  is on the internal network and has full connectivity with  _interno1_ . - -![SSH tunnels: no tunnel](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_sin_tunel.png) - -Table of Contents [[hide][1]] - -* [1 Scenario 1: Use on external1 a TCP service offered by internal1 (Local port forwarding / bind_address = localhost / host = localhost)][2] - -* [2 Scenario 2: Use on external2 a TCP service offered by internal1 (Local port forwarding / bind_address = 0.0.0.0 / host = localhost)][3] - -* [3 Scenario 3: Use in internal1 a TCP service offered by external1 (Remote port forwarding / bind_address = localhost / host = localhost)][4] - -* [4 Scenario 4: Use in internal2 a TCP service offered by external1 (Remote port forwarding / bind_address = 0.0.0.0 / host = localhost)][5] - -* [5 Scenario 5: Use in external1 a TCP service offered by internal2 (Local port forwarding / bind_address = localhost / host = internal2)][6] - -* [6 Scenario 6: Use in internal1 a TCP service offered by external2 (Remote port forwarding / bind_address = localhost / host = external2)][7] - -* [7 Scenario 7: Use in external2 a TCP service offered by internal2 (Local port forwarding / bind_address = 0.0.0.0 / host = internal2)][8] - -* [8 Scenario 8: Use in internal2 a TCP service offered by external2 (Remote port forwarding / bind_address = 0.0.0.0 / host = external2)][9] - -#### Scenario 1: Use on  _external1_  a TCP service offered by  _internal1_  (Local port forwarding / bind_address = localhost / host = localhost) - -The system  _externo1_  can be connected to the system  _interno1 _ through OpenSSH and also wants to connect to the system server VNC (port 5900)  _interno1_ : - -![SSH Tunnels: Scenario 1](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_1.png) - -We will achieve this with this command: - -``` -External1 $ ssh -L 7900: localhost: 5900 user @ internal1 -``` - -Now in the  _external system1_  we can verify that port 7900 is waiting for connections: - -``` -External1 $ netstat -ltn -Active Internet connections (only servers) -Proto Recv-Q Send-Q Local Address Foreign Address State       -... -Tcp 0 0 127.0.0.1:7900 0.0.0.0:* LISTEN   -... -``` - -We only need to execute now on  _external1_  : - -``` -External1 $ vncviewer localhost :: 7900 -``` - -To connect to the  _internal_  VNC  _server1_ . - -Note: This way to change the port is not documented in the  - -``` -man vncviewer -``` - -. Appears in: [About VNCViewer configuration of the output TCP port][18]. This is also how [the TightVNC vncviewer][19] does. - -#### Scenario 2: Use on  _external2_  a TCP service offered by  _internal1_  (Local port forwarding / bind_address = 0.0.0.0 / host = localhost) - -This time we start from a situation similar to the previous one but now we want it to be  _external2_  who connects to the  _internal_  VNC  _server1_ : - -![SSH Tunnels: Scenario 2](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_2.png) - -The appropriate command would be this: - -``` -External1 $ ssh -L 0.0.0.0:7900:localhost:5900 user @ internal1 -``` - -It is similar to the first scenario; But in that, if we look at the output of  - -``` -netstat -``` - -the port, 7900 had been associated with the address of localhost, at 127.0.0.1, so only local processes could connect to it. This time we specify that the port is associated with 0.0.0.0, so that the system accepts connections to any local IP of the machine: - -``` -External1 $ netstat -ltn -Active Internet connections (only servers) -Proto Recv-Q Send-Q Local Address Foreign Address State       -... -Tcp 0 0 0.0.0.0:7900 0.0.0.0:* LISTEN -... -``` - -So now, from  _external2_  , we can execute: - -``` -External2 $ vncviewer external1 :: 7900 -``` - -To connect to the  _internal_  VNC  _server1_ . - -Instead of specifying the IP  - -``` -0.0.0.0 -``` - -, we could also use the option  - -``` --g -``` - -(  _Allows remote hosts to connect to local forwarded ports_  ) like this: - -``` -External1 $ ssh -g -L 7900: localhost: 5900 user @ internal1 -``` - -With exactly the same result as the previous command: - -``` -External1 $ ssh -L 0.0.0.0:7900:localhost:5900 user @ internal1 -``` - -On the other hand, if we had wanted to restrict the connection to only one of the local IPs of the system, we could have been more specific: - -``` -External1 $ ssh -L 192.168.24.80:7900:localhost:5900 user @ internal1 - -External1 $ netstat -ltn -Active Internet connections (only servers) -Proto Recv-Q Send-Q Local Address Foreign Address State -... -Tcp 0 0 192.168.24.80:7900 0.0.0.0:* LISTEN -... -``` - -#### Scenario 3: Use in  _internal1_  a TCP service offered by  _external1_  (Remote port forwarding / bind_address = localhost / host = localhost) - -In the first scenario, it was the system itself with the SSH server that offered another service. Now the system with the SSH client is the one that offers the service that the system with the SSH server wants to use: - -![SSH Tunnels: Scenario 3](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_3.png) - -The command we will use is the same as in the first scenario by changing the parameter  - -``` --L -``` - -to  - -``` --R -``` - -: - -``` -External1 $ ssh -R 7900: localhost: 5900 user @ internal1 -``` - - -And now where we will see that we have port 7900 listening is in  _interno1_ : - -``` -Internal1 $ netstat -lnt -Active Internet connections (only servers) -Proto Recv-Q Send-Q Local Address Foreign Address State -... -Tcp 0 0 127.0.0.1:7900 0.0.0.0:* LISTEN -... -``` - -So now from  _internal1_  we can use the VNC server from  _external1_  like this: - -``` -Internal1 $ vncviewer localhost :: 7900 -``` - - -#### Scenario 4: Use in  _internal2_  a TCP service offered by  _external1_  (Remote port forwarding / bind_address = 0.0.0.0 / host = localhost) - -Similar to the third scenario but now, as we did in the second scenario, we will associate the forwarded port with the IP  - -``` -0.0.0.0 -``` - -so that other nodes can use the service: - -![SSH Tunnels: Scenario 4](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_4-1.png) - -The appropriate command is: - -``` -External1 $ ssh -R 0.0.0.0:7900:localhost:5900 user @ internal1 -``` - - -However, it is important to understand that, for security reasons, this will not work if in the configuration of the SSH server we do not modify the value of the parameter  - -``` -GatewayPorts -``` - - -that by default is  - -``` -no -``` - -: - -``` -GatewayPorts -``` - -> Specifies whether remote hosts are allowed to connect to ports forwarded for the client. By default, sshd(8) binds remote port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports. GatewayPorts can be used to specify that sshd should allow remote port forwardings to bind to non-loopback addresses, thus allowing other hosts to connect. The argument may be “no” to force remote port forwardings to be available to the local host only, “yes” to force remote port forwardings to bind to the wildcard address, or “clientspecified” to allow the client to select the address to which the forwarding is bound. The default is “no”. - - - -If we do not have the possibility to modify the configuration of the server, we will not be able to use this type of port forwarding. At least not simply because, if there are no other impediments, a user can open a port (> 1024) to listen to external connections and forward that request to  - -``` -localhost:7900 -``` - - -. This could be done, for example, with [netcat][24] ( [Debian # 310431: sshd_config should warn about the GatewayPorts workaround.][25] ) - -So we  - -``` -/etc/ssh/sshd_config -``` - -will add: - -``` -GatewayPorts clientspecified -``` - - -After which we will have to reread the configuration with ”  - -``` -sudo /etc/init.d/ssh reload -``` - - -” (Debian and Ubuntu). - -We verify that  _internal1_  is listening for requests from all IPs: - -``` -Internal1 $ netstat -ltn -Active Internet connections (only servers) -Proto Recv-Q Send-Q Local Address Foreign Address State -... -Tcp 0 0 0.0.0.0:7900 0.0.0.0:* LISTEN -... -``` - -And we can already use the VNC service from  _internal2_  : - -``` -Internal2 $ internal vncviewer1 :: 7900 -``` - - -#### Scenario 5: Use in  _external1_  a TCP service offered by  _internal2_  (Local port forwarding / bind_address = localhost / host = internal2) - -![SSH Tunnels: Scenario 5](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_5.png) - -In this scenario we will use the following command: - -``` -External1 $ ssh -L 7900: internal2: 5900 user @ internal1 -``` - -And we will access the service by running the command in  _external1_ : - -``` -External1 $ vncviewer localhost :: 7900 -``` - -#### Scenario 6: Use in  _internal1_  a TCP service offered by  _external2_  (Remote port forwarding / bind_address = localhost / host = external2) - -![SSH Tunnels: Scenario 6](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_6.png) - -In this scenario we will use the following command: - -``` -External1 $ ssh -R 7900: external2: 5900 user @ internal1 -``` - -And we will access the service by running the command in  _internal1_ : - -``` -Internal1 $ vncviewer localhost :: 7900 -``` - -#### Scenario 7: Use in  _external2_  a TCP service offered by  _internal2_  (Local port forwarding / bind_address = 0.0.0.0 / host = internal2) - -![SSH Tunnels: Scenario 7](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_7.png) - -In this scenario we will use the following command: - -``` -External1 $ ssh -L 0.0.0.0:7900:internal2:5900 user @ internal1 -``` - - -Or alternatively: - -``` -External1 $ ssh -g -L 7900: internal2: 5900 user @ internal1 -``` - - -And we will access the service by running the command in  _external2_  : - -``` -External2 $ vncviewer external1 :: 7900 -``` - -#### Scenario 8: Use in  _internal2_  a TCP service offered by  _external2_  (Remote port forwarding / bind_address = 0.0.0.0 / host = external2) - -![SSH Tunnels: Scenario 8](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_8.png) - -In this scenario we will use the following command: - -``` -External1 $ ssh -R 0.0.0.0:7900:external2:5900 user @ internal1 -``` - -The SSH server must be configured with ”  - -``` -GatewayPorts clientspecified -``` - -”, as we have seen in scenario 4. - -And we will access the service by running the command in  _internal2_ : - -``` -Internal2 $ internal vncviewer1 :: 7900 -``` - -If we want to create many tunnels at once, it may be convenient to use a configuration file instead of composing a very long command. Let’s imagine that our only entry point to a network is through SSH and we need to create tunnels to access the different servers in the network via SSH, VNC or [Remote Desktop][26]. We could compose a file like the following with all the redirects that we will need (in relation to the mentioned SOCKS server. - -``` -# SOCKS server -DynamicForward 1080 - -# SSH redirects -LocalForward 2221 serverlinux1: 22 -LocalForward 2222 serverlinux2: 22 -LocalForward 2223 172.16.23.45:22 -LocalForward 2224 172.16.23.48:22 - -# RDP redirects for Windows systems -LocalForward 3391 serverwindows1: 3389 -LocalForward 3392 serverwindows2: 3389 - -# VNC redirects for systems with "vncserver" -LocalForward 5902 serverlinux1: 5901 -LocalForward 5903 172.16.23.45:5901 -``` - - -And we only need to execute this to create all the redirects: - -``` -External1 $ ssh -F $ HOME / redirects user @ internal1 -``` - --------------------------------------------------------------------------------- - -via: https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/ - -作者:[ Ahmad][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://wesharethis.com/author/ahmad/ -[1]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/# -[2]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_1_Use_onexternal1a_TCP_service_offered_byinternal1Local_port_forwarding_bind_address_localhost_host_localhost -[3]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_2_Use_onexternal2a_TCP_service_offered_byinternal1Local_port_forwarding_bind_address_0000_host_localhost -[4]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_3_Use_ininternal1a_TCP_service_offered_byexternal1Remote_port_forwarding_bind_address_localhost_host_localhost -[5]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_4_Use_ininternal2a_TCP_service_offered_byexternal1Remote_port_forwarding_bind_address_0000_host_localhost -[6]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_5_Use_inexternal1a_TCP_service_offered_byinternal2Local_port_forwarding_bind_address_localhost_host_internal2 -[7]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_6_Use_ininternal1a_TCP_service_offered_byexternal2Remote_port_forwarding_bind_address_localhost_host_external2 -[8]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_7_Use_inexternal2a_TCP_service_offered_byinternal2Local_port_forwarding_bind_address_0000_host_internal2 -[9]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_8_Use_ininternal2a_TCP_service_offered_byexternal2Remote_port_forwarding_bind_address_0000_host_external2 -[10]:https://wesharethis.com/author/ahmad/ -[11]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#comments -[12]:http://en.wikipedia.org/wiki/Tunneling_protocol#SSH_tunneling -[13]:http://www.oreillynet.com/pub/a/wireless/2001/02/23/wep.html -[14]:http://www.ssh.com/support/documentation/online/ssh/winhelp/32/Tunneling_Explained.html -[15]:http://www.ssh.com/support/documentation/online/ssh/adminguide/32/Port_Forwarding.html -[16]:http://www.securityfocus.com/infocus/1816 -[17]:http://magazine.redhat.com/2007/11/06/ssh-port-forwarding/ -[18]:http://www.realvnc.com/pipermail/vnc-list/2006-April/054551.html -[19]:http://www.tightvnc.com/vncviewer.1.html -[20]:https://bufferapp.com/add?url=https%3A%2F%2Fwesharethis.com%2F2017%2F07%2Fcreating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh%2F&text=Creating%20TCP%20/%20IP%20(port%20forwarding)%20tunnels%20with%20SSH:%20The%208%20possible%20scenarios%20using%20OpenSSH -[21]:http://en.wikipedia.org/wiki/Secure_Shell -[22]:http://www.openssh.com/ -[23]:http://www.chiark.greenend.org.uk/~sgtatham/putty/ -[24]:http://en.wikipedia.org/wiki/Netcat -[25]:http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=310431 -[26]:http://en.wikipedia.org/wiki/Remote_Desktop_Services diff --git a/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md b/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md new file mode 100644 index 0000000000..2df7a5f3c0 --- /dev/null +++ b/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md @@ -0,0 +1,412 @@ +通过 SSH 实现 TCP / IP 隧道(端口转发):使用 OpenSSH 可能的 8 种场景 +============================================================ + +对于 [Secure Shell (SSH)][21] 这样的网络协议来说,其主要职责就是在终端模式下访问一个远程系统。因为 SSH 协议对传输数据进行了加密,所以通过它在远端系统执行命令是非常安全的。此外,我们还可以在这种加密后的连接上通过创建隧道(端口转发)的方式,来实现两个不同终端间的互联。凭借这种方式,只要我们能通过 SSH 创建连接,就可以绕开防火墙或者端口禁用的限制。 + +这个话题在网络领域被广泛应用和讨论: + +* [Wikipedia: SSH Tunneling][12] + +* [O’Reilly: Using SSH Tunneling][13] + +* [Ssh.com: Tunneling Explained][14] + +* [Ssh.com: Port Forwarding][15] + +* [SecurityFocus: SSH Port Forwarding][16] + +* [Red Hat Magazine: SSH Port Forwarding][17] + +我们在接下来的内容中并不讨论端口转发的细节,而是准备介绍一个如何使用 [OpenSSH][22] 来完成 TCP 端口转发的速查表,其中包含了八种常见的场景。有些 SSH 客户端,比如 [PuTTY][23],也允许通过界面配置的方式来实现端口转发。而我们着重关注的是通过 OpenSSH 来实现的的方式。 + +在下面的例子当中,我们假设环境中的网络划分为外部网络(network1)和内部网络(network2)两部分,并且这两个网络之间,只能在 external1 与 internal1 之间通过 SSH 连接的方式来互相访问。外部网络的节点之间和内部网络的节点之间是完全联通的。 + +![SSH tunnels: no tunnel](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_sin_tunel.png) + +内容列表: + +* [1 场景 1 :在 external1 节点访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = localhost / 主机 = localhost )][2] + +* [2 场景 2:在 external2 节点上访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost)][3] + +* [3 场景 3:在 internal1 上访问由 external1 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / 主机 = localhost)][4] + +* [4 场景 4 :internal2 使用 external1 上提供的 TCP 服务(远端端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost)][5] + +* [5 场景 5 :在 external1 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 localhost / 主机 = internal2 )][6] + +* [6 场景 6 :在 internal1 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / host = external2)][7] + +* [7 场景7 :在 external2 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = internal2)][8] + +* [8 场景 8 : 在 internal2 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = 0.0.0.0 / 主机 = external2)][9] + +#### 场景 1 :在 external1 节点访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = localhost / 主机 = localhost ) + +externo1 节点可以通过 OpenSSH 连接到 interno1 节点,之后我们想通过其访问运行在 5900 端口上的 VNC 服务。 + +![SSH Tunnels: Scenario 1](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_1.png) + +我们可以通过下面的命令来实现: + +``` +External1 $ ssh -L 7900: localhost: 5900 user @ internal1 +``` + +现在,我们可以在 externo1 节点上确认下 7900 端口是否处于监听状态中: + +``` +External1 $ netstat -ltn +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State       +... +Tcp 0 0 127.0.0.1:7900 0.0.0.0:* LISTEN   +... +``` + +我们只需要在 external1 节点上执行如下命令即可访问 internal 节点的 VNC 服务。: + +``` +External1 $ vncviewer localhost :: 7900 +``` + +注意:在下面的文档中并未提及这种修改端口号的方式。在[About VNCViewer configuration of the output TCP port][18] 中可以看到。这也是 [the TightVNC vncviewer][19] 所介绍的的。 + +``` +man vncviewer +``` + +#### 场景 2:在 external2 节点上访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost) + +这次的场景跟方案 1 的场景的类似,但是我们这次想从 external2 节点来连接到 internal1 上的 VNC 服务: + +![SSH Tunnels: Scenario 2](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_2.png) + +正确的命令如下: + +``` +External1 $ ssh -L 0.0.0.0:7900:localhost:5900 user @ internal1 +``` + +看起来跟方案 1 中的命令类似,但是让我们看看 netstat 命令的输出上的区别: + +``` +netstat +``` + +7900 端口被绑定到了本地(127.0.0.1),所以只有本地进程可以访问。这次我们将端口关联到了 0.0.0.0,所以系统允许任何 IP 地址的机器访问 7900 这个端口。 + +``` +External1 $ netstat -ltn +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State       +... +Tcp 0 0 0.0.0.0:7900 0.0.0.0:* LISTEN +... +``` + +所以现在在 external2 节点上,我们可移执行: + +``` +External2 $ vncviewer external1 :: 7900 +``` + +来连接到 internal1 节点上的 VNC 服务。 + +除了将 IP 指定为 + +``` +0.0.0.0 +``` + +之外,我们还可以使用如下参数: + +``` +-g +``` + +(允许远程机器使用本地端口转发),完整命令如下: + +``` +External1 $ ssh -g -L 7900: localhost: 5900 user @ internal1 +``` + +这条命令与前面的命令能实现相同效果: + +``` +External1 $ ssh -L 0.0.0.0:7900:localhost:5900 user @ internal1 +``` + +换句话说,如果我们想限制只有指定 IP 的机器才能访问转发端口,可以像下面这样定义: + +``` +External1 $ ssh -L 192.168.24.80:7900:localhost:5900 user @ internal1 + +External1 $ netstat -ltn +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +... +Tcp 0 0 192.168.24.80:7900 0.0.0.0:* LISTEN +... +``` + +#### 场景 3:在 internal1 上访问由 external1 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / 主机 = localhost) + +在场景 1 中 SSH 服务器与 TCP 服务(VNC)提供者在同一个节点上。现在我们想在 SSH 客户端所在的节点上,提供一个 TCP 服务(VNC)供 SSH 服务端来访问: + +![SSH Tunnels: Scenario 3](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_3.png) + +将方案 1 中的命令参数由: + +``` +-L +``` + +替换为 + +``` +-R +``` + +完整命令如下: + +``` +External1 $ ssh -R 7900: localhost: 5900 user @ internal1 +``` + +然后我们就能看到 interno1 节点上对 7900 端口正在监听: + +``` +Internal1 $ netstat -lnt +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +... +Tcp 0 0 127.0.0.1:7900 0.0.0.0:* LISTEN +... +``` + +现在在 internal1 节点上,我们可以使用如下命令来访问 external1 上的 VNC 服务。 + +``` +Internal1 $ vncviewer localhost :: 7900 +``` + +#### 场景 4 :internal2 使用 external1 上提供的 TCP 服务(远端端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost) + +与场景 3 类似,但是现在我们尝试指定允许访问转发端口的 IP(就像方案 2 中做的一样) + +``` +0.0.0.0 +``` + +这样其他节点也可以访问 VNC 服务: + +![SSH Tunnels: Scenario 4](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_4-1.png) + +正确的命令是: + +``` +External1 $ ssh -R 0.0.0.0:7900:localhost:5900 user @ internal1 +``` + +但是如果我们直接执行该命令的话可能不会生效,因为我们需要修改 SSH 服务端的一个参数值: + +``` +GatewayPorts +``` + +他的默认值是: + +``` +no +``` + +> GatewayPorts +> +> 该参数指定了是否允许远程主机访问转发端口。默认情况下,sshd(8) 只允许本机进程访问转发端口。这是为了阻止其他主机连接到该转发端口。GatewayPorts 参数可用于指定 sshd 允许哪些远程主机访问转发端口。当参数值设置为 “no” 的时候只有本机可以访问转发端口;“yes” 则表示允许符合远程主机 IP 地址通配符规则的远程主机访问该转发端口;“clientspecified” 则表示由客户端来选择哪些主机地址允许访问转发端口。默认值是 “no”。 + +如果我们没有修改服务器配置的权限,我们将不能使用该方案来进行端口转发。这是因为如果没有其他的限制,用户可以开启一个端口(> 1024)来监听来自外部的请求并转发到: + +``` +localhost:7900 +``` + +参照这个案例:[netcat][24] ( [Debian # 310431: sshd_config should warn about the GatewayPorts workaround.][25] ) + +所以我们修改: + +``` +/etc/ssh/sshd_config +``` + +添加如下内容: + +``` +GatewayPorts clientspecified +``` + +然后,我们使用如下命令来重载修改后的配置文件(在 Debian 和 Ubuntu 上)。 + +``` +sudo /etc/init.d/ssh reload +``` + +我们确认现在 internal1 节点上存在 7900 端口的监听程序,监听来自不同 IP 的请求: + +``` +Internal1 $ netstat -ltn +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +... +Tcp 0 0 0.0.0.0:7900 0.0.0.0:* LISTEN +... +``` + +然后我们就可以在 internal2 节点上使用 VNC 服务了: + +``` +Internal2 $ internal vncviewer1 :: 7900 +``` + +#### 场景 5 :在 external1 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 localhost / 主机 = internal2 ) + +![SSH Tunnels: Scenario 5](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_5.png) + +在这种场景下我们使用如下命令: + +``` +External1 $ ssh -L 7900: internal2: 5900 user @ internal1 +``` + +然后我们就能在 external1 节点上,通过执行如下命令来使用 VNC 服务了: + +``` +External1 $ vncviewer localhost :: 7900 +``` + +#### 场景 6 :在 internal1 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / host = external2) + +![SSH Tunnels: Scenario 6](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_6.png) + +在这种场景下,我们使用如下命令: + +``` +External1 $ ssh -R 7900: external2: 5900 user @ internal1 +``` + +然后我们可以在 internal1 上通过执行如下命令来访问 VNC 服务: + +``` +Internal1 $ vncviewer localhost :: 7900 +``` + +#### 场景7 :在 external2 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = internal2) + +![SSH Tunnels: Scenario 7](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_7.png) + +本场景下,我们使用如下命令: + +``` +External1 $ ssh -L 0.0.0.0:7900:internal2:5900 user @ internal1 +``` + +或者: + +``` +External1 $ ssh -g -L 7900: internal2: 5900 user @ internal1 +``` + +然后我们就可以在 external2 上执行如下命令来访问 vnc 服务: + +``` +External2 $ vncviewer external1 :: 7900 +``` + +#### 场景 8 : 在 internal2 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = 0.0.0.0 / 主机 = external2) + +![SSH Tunnels: Scenario 8](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_8.png) + +本场景下我们使用如下命令: + +``` +External1 $ ssh -R 0.0.0.0:7900:external2:5900 user @ internal1 +``` + +SSH 服务器需要配置为: + +``` +GatewayPorts clientspecified +``` + +就像我们在场景 4 中讲过的那样。 + +然后我们可以在 internal2 节点上执行如下命令来访问 VNC 服务: + +``` +Internal2 $ internal vncviewer1 :: 7900 +``` + +如果我们需要一次性的创建多个隧道,使用配置文件的方式替代一个可能很长的命令是一个更好的选择。假设我们只能通过 SSH 的方式访问某个特定网络,同时又需要创建多个隧道来访问该网络内不同服务器上的服务,比如 VNC 或者 [远程桌面][26]。此时只需要创建一个如下的配置文件即可(在 SOCKS 服务器 上)。 + +``` +# SOCKS server +DynamicForward 1080 + +# SSH redirects +LocalForward 2221 serverlinux1: 22 +LocalForward 2222 serverlinux2: 22 +LocalForward 2223 172.16.23.45:22 +LocalForward 2224 172.16.23.48:22 + +# RDP redirects for Windows systems +LocalForward 3391 serverwindows1: 3389 +LocalForward 3392 serverwindows2: 3389 + +# VNC redirects for systems with "vncserver" +LocalForward 5902 serverlinux1: 5901 +LocalForward 5903 172.16.23.45:5901 +``` + +然后我们只需要执行如下命令: + +``` +External1 $ ssh -F $ HOME / redirects user @ internal1 +``` + +-------------------------------------------------------------------------------- + +via: https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/ + +作者:[ Ahmad][a] +译者:[toutoudnf](https://github.com/toutoudnf) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://wesharethis.com/author/ahmad/ +[1]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/# +[2]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_1_Use_onexternal1a_TCP_service_offered_byinternal1Local_port_forwarding_bind_address_localhost_host_localhost +[3]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_2_Use_onexternal2a_TCP_service_offered_byinternal1Local_port_forwarding_bind_address_0000_host_localhost +[4]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_3_Use_ininternal1a_TCP_service_offered_byexternal1Remote_port_forwarding_bind_address_localhost_host_localhost +[5]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_4_Use_ininternal2a_TCP_service_offered_byexternal1Remote_port_forwarding_bind_address_0000_host_localhost +[6]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_5_Use_inexternal1a_TCP_service_offered_byinternal2Local_port_forwarding_bind_address_localhost_host_internal2 +[7]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_6_Use_ininternal1a_TCP_service_offered_byexternal2Remote_port_forwarding_bind_address_localhost_host_external2 +[8]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_7_Use_inexternal2a_TCP_service_offered_byinternal2Local_port_forwarding_bind_address_0000_host_internal2 +[9]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_8_Use_ininternal2a_TCP_service_offered_byexternal2Remote_port_forwarding_bind_address_0000_host_external2 +[10]:https://wesharethis.com/author/ahmad/ +[11]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#comments +[12]:http://en.wikipedia.org/wiki/Tunneling_protocol#SSH_tunneling +[13]:http://www.oreillynet.com/pub/a/wireless/2001/02/23/wep.html +[14]:http://www.ssh.com/support/documentation/online/ssh/winhelp/32/Tunneling_Explained.html +[15]:http://www.ssh.com/support/documentation/online/ssh/adminguide/32/Port_Forwarding.html +[16]:http://www.securityfocus.com/infocus/1816 +[17]:http://magazine.redhat.com/2007/11/06/ssh-port-forwarding/ +[18]:http://www.realvnc.com/pipermail/vnc-list/2006-April/054551.html +[19]:http://www.tightvnc.com/vncviewer.1.html +[20]:https://bufferapp.com/add?url=https%3A%2F%2Fwesharethis.com%2F2017%2F07%2Fcreating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh%2F&text=Creating%20TCP%20/%20IP%20(port%20forwarding)%20tunnels%20with%20SSH:%20The%208%20possible%20scenarios%20using%20OpenSSH +[21]:http://en.wikipedia.org/wiki/Secure_Shell +[22]:http://www.openssh.com/ +[23]:http://www.chiark.greenend.org.uk/~sgtatham/putty/ +[24]:http://en.wikipedia.org/wiki/Netcat +[25]:http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=310431 +[26]:http://en.wikipedia.org/wiki/Remote_Desktop_Services From fda649e7fd99dcc6226b358cfec32a7dafb5bd48 Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 9 Oct 2017 08:44:31 +0800 Subject: [PATCH 29/39] translating --- ...0170421 A Window Into the Linux Desktop.md | 103 ------------------ ...0170421 A Window Into the Linux Desktop.md | 100 +++++++++++++++++ 2 files changed, 100 insertions(+), 103 deletions(-) delete mode 100644 sources/talk/20170421 A Window Into the Linux Desktop.md create mode 100644 translated/talk/20170421 A Window Into the Linux Desktop.md diff --git a/sources/talk/20170421 A Window Into the Linux Desktop.md b/sources/talk/20170421 A Window Into the Linux Desktop.md deleted file mode 100644 index 2091ead8e8..0000000000 --- a/sources/talk/20170421 A Window Into the Linux Desktop.md +++ /dev/null @@ -1,103 +0,0 @@ -traslating---geekp - -A Window Into the Linux Desktop -============================================================ - -![linux-desktop](http://www.linuxinsider.com/article_images/story_graphics_xlarge/xl-2016-linux-1.jpg) - -![](http://www.linuxinsider.com/images/2015/image-credit-adobe-stock_130x15.gif) - -"What can it do that Windows can't?" - -That is the first question many people ask when considering Linux for their desktop. While the open source philosophy that underpins Linux is a good enough draw for some, others want to know just how different its look, feel and functionality can get. To a degree, that depends on whether you choose a desktop environment or a window manager. - -If you want a desktop experience that is lightning fast and uncompromisingly efficient, foregoing the classic desktop environment for a window manager might be for you. - -### What's What - -"Desktop environment" is the technical term for a typical, full-featured desktop -- that is, the complete graphical layout of your system. Besides displaying your programs, the desktop environment includes accoutrements such as app launchers, menu panels and widgets. - -In Microsoft Windows, the desktop environment consists of, among other things, the Start menu, the taskbar of open applications and notification center, all the Windows programs that come bundled with the OS, and the frames enclosing open applications (with a dash, square and X in the upper right corner). - -There are many similarities in Linux. - -The Linux [Gnome][3] desktop environment, for instance, has a slightly different design, but it shares all of the Microsoft Windows basics -- from an app menu to a panel showing open applications, to a notification bar, to the windows framing programs. - -Window program frames rely on a component for drawing them and letting you move and resize them: It's called the "window manager." So, as they all have windows, every desktop environment includes a window manager. - -However, not every window manager is part of a desktop environment. You can run window managers by themselves, and there are reasons to consider doing just that. - -### Out of Your Environment - -For the purpose of this column, references to "window manager" refer to those that can stand alone. If you install a window manager on an existing Linux system, you can log out without shutting down, choose the new window manager on your login screen, and log back in. - -You might not want to do this without researching your window manager first, though, because you will be greeted by a blank screen and sparse status bar that may or may not be clickable. - -There typically is a straightforward way to bring up a terminal in a window manager, because that's how you edit its configuration file. There you will find key- and mouse-bindings to launch programs, at which point you actually can use your new setup. - -In the popular i3 window manager, for instance, you can launch a terminal by hitting the Super (i.e., Windows) key plus Enter -- or press Super plus D to bring up the app launcher. There you can type an app name and hit Enter to open it. All the existing apps can be found that way, and they will open to full screen once selected. - - [![i3 window manager](http://www.linuxinsider.com/article_images/2017/84473_620x388-small.jpg)][4] (Click Image to Enlarge) - -i3 is also a tiling window manager, meaning it ensures that all windows expand to evenly fit the screen, neither overlapping nor wasting space. When a new window pops up, it reduces the existing windows, nudging them aside to make room. Users can toggle to open the next window either vertically or horizontally adjacent. - -### Features Can Be Friends or Foes - -Desktop environments have their advantages, of course. First and foremost, they provide a feature-rich, recognizable interface. Each has its signature style, but overall they provide unobtrusive default settings out of the box, which makes desktop environments ready to use right from the start. - -Another strong point is that desktop environments come with a constellation of programs and media codecs, allowing users to accomplish simple tasks immediately. Further, they include handy features like battery monitors, wireless widgets and system notifications. - -As comprehensive as desktop environments are, the large software base and user experience philosophy unique to each means there are limits on how far they can go. That means they are not always very configurable. With desktop environments that emphasize flashy looks, oftentimes what you see is what you get. - -Many desktop environments are notoriously heavy on system resources, so they're not friendly to lower-end hardware. Because of the visual effects running on them, there are more things that can go wrong, too. I once tried tweaking networking settings that were unrelated to the desktop environment I was running, and the whole thing crashed. When I started a window manager, I was able to change the settings. - -Those prioritizing security may want to avoid desktop environments, since more programs means greater attack surface -- that is, entry points where malicious actors can break in. - -However, if you want to give a desktop environment a try, XFCE is a good place to start, as its smaller software base trims some bloat, leaving less clutter behind if you don't stick with it. - -It's not the prettiest at first sight, but after downloading some GTK theme packs (every desktop environment serves up either these or Qt themes, and XFCE is in the GTK camp) and enabling them in the Appearance section of settings, you easily can touch it up. You can even shop around at this [centralized gallery][5] to find the theme you like best. - -### You Can Save a Lot of Time... if You Take the Time First - -If you'd like to see what you can do outside of a desktop environment, you'll find a window manager allows plenty of room to maneuver. - -More than anything, window managers are about customization. In fact, their customizability has spawned numerous galleries hosting a vibrant community of users whose palette of choice is a window manager. - -The modest resource needs of window managers make them ideal for lower specs, and since most window managers don't come with any programs, they allow users who appreciate modularity to add only those they want. - -Perhaps the most noticeable distinction from desktop environments is that window managers generally focus on efficiency by emphasizing mouse movements and keyboard hotkeys to open programs or launchers. - -Keyboard-driven window managers are especially streamlined, since you can bring up new windows, enter text or more keyboard commands, move them around, and close them again -- all without moving your hands from the home row. Once you acculturate to the design logic, you will be amazed at how quickly you can blaze through your tasks. - -In spite of the freedom they provide, window managers have their drawbacks. Most significantly, they are extremely bare-bones out of the box. Before you can make much use of one, you'll have to spend time reading your window manager's documentation for configuration syntax, and probably some more time getting the hang of said syntax. - -Although you will have some user programs if you switched from a desktop environment (the likeliest scenario), you also will start out missing familiar things like battery indicators and network widgets, and it will take some time to set up new ones. - -If you want to dive into window managers, i3 has [thorough documentation][6] and straightforward configuration syntax. The configuration file doesn't use any programming language -- it simply defines a variable-value pair on each line. Creating a hotkey is as easy as writing "bindsym", the key combination, and the action for that combination to launch. - -While window managers aren't for everyone, they offer a distinctive computing experience, and Linux is one of the few OSes that allows them. No matter which paradigm you ultimately go with, I hope this overview gives you enough information to feel confident about the choice you've made -- or confident enough to venture out of your familiar zone and see what else is available.  - --------------------------------------------------------------------------------- - -作者简介: - -**Jonathan Terrasi** has been an ECT News Network columnist since 2017\. His main interests are computer security (particularly with the Linux desktop), encryption, and analysis of politics and current affairs. He is a full-time freelance writer and musician. His background includes providing technical commentaries and analyses in articles published by the Chicago Committee to Defend the Bill of Rights. - - ------------ - -via: http://www.linuxinsider.com/story/84473.html?rss=1 - -作者:[ ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: -[1]:http://www.linuxinsider.com/story/84473.html?rss=1# -[2]:http://www.linuxinsider.com/perl/mailit/?id=84473 -[3]:http://en.wikipedia.org/wiki/GNOME -[4]:http://www.linuxinsider.com/article_images/2017/84473_1200x750.jpg -[5]:http://www.xfce-look.org/ -[6]:https://i3wm.org/docs/ diff --git a/translated/talk/20170421 A Window Into the Linux Desktop.md b/translated/talk/20170421 A Window Into the Linux Desktop.md new file mode 100644 index 0000000000..53d7e6f311 --- /dev/null +++ b/translated/talk/20170421 A Window Into the Linux Desktop.md @@ -0,0 +1,100 @@ +进入 Linux 桌面的窗口 +============================================================ + +![linux-desktop](http://www.linuxinsider.com/article_images/story_graphics_xlarge/xl-2016-linux-1.jpg) + +![](http://www.linuxinsider.com/images/2015/image-credit-adobe-stock_130x15.gif) + +“它能做什么 Windows 不能做的吗?” + +这是许多人在考虑使用 Linux 桌面时的第一个问题。虽然支撑 Linux 的开源哲学对于某些人来说就是一个很好的理由,但是一些人想知道它在外观、感受和功能上有多么不同。在某种程度上,这取决于你是否选择桌面环境或窗口管理器。 + +如果你想要的是闪电般快速的桌面体验且向高效妥协, 那么上述的经典桌面中的窗口管理器可能适合你。 + +### 什么是什么 + +“桌面环境”是典型的全功能桌面的技术术语,即系统的完整图形化布局。除了显示你的程序,桌面环境还包括应用程序启动器,菜单面板和小部件等。 + +在 Microsoft Windows 中,桌面环境包括开始菜单,打开的程序的任务栏和通知中心,还有与操作系统捆绑在一起的所有 Windows 程序,以及打开程序的框架(有破折号、正方形和右上角的 X)。 + +Linux 中有很多相似之处。 + +例如,Linux [Gnome][3] 桌面环境的设计略有不同,但它共享了所有的 Microsoft Windows 的基本 - 从应用程序菜单到显示打开的应用程序的面板、通知栏、窗口框架程序。 + +窗口程序框架依赖于一个组件来绘制它们,并允许你移动并调整大小:它被称为“窗口管理器”。因为它们都有窗口,每个桌面环境都包含一个窗口管理器。 + +然而,并不是每个窗口管理器都是桌面环境的一部分。你可以只运行窗口管理器,并且有理由考虑这么做。 + +### 离开你的环境 + +在本专栏中,对“窗口管理器”的引用指的是可以独立进行的。如果在现有的 Linux 系统上安装了一个窗口管理器,你可以在不关闭的情况下注销,在登录屏幕上选择新的窗口管理器,然后重新登录。 + +不过, 在研究你的窗口管理器之前,你可能不想这么做,因为你会看到空白屏幕和稀疏的状态栏,这可能可以或不可以点击的。 + +通常情况下,可以直接在窗口管理器中启动终端,因为这是你编辑其配置文件的方式。在那里你会发现按键和鼠标绑定来启动程序,此时你实际上可以使用你的新设置。 + +例如,在流行的 i3 窗口管理器中,你可以通过按下 Super(即 Windows)键加 Enter 键来启动终端,或者按 Super + D 启动应用程序启动器。你可以在其中输入应用程序名称,然后按 Enter 键将其打开。所有现有的应用程序都可以通过这种方式找到,一旦选择后,它们将会全屏打开。 + + [![i3 window manager](http://www.linuxinsider.com/article_images/2017/84473_620x388-small.jpg)][4] (Click Image to Enlarge) + +i3 还是一个平铺的窗口管理器,这意味着它可以确保所有的窗口均匀地扩展到屏幕,既不重叠也不浪费空间。当弹出新窗口时,它会减少现有的窗口,将它们推到一边腾出空间。用户可以以垂直或水平的方式切换到相邻的窗口打开。 + +### 功能可以是朋友或敌人 + +当然,桌面环境有其优点。首先,它们提供功能丰富,可识别的界面。每个都有其签名风格,但总体而言,它们提供了不引人注目的默认设置,这使得桌面环境从一开始就可以使用。 + +另一个优点是桌面环境有一组程序和媒体编解码器,允许用户立即完成简单的任务。此外,它们还包括便携式功能,如电池监视器、无线小部件和系统通知。 + +如桌面环境一样完善,大型软件基础和用户体验理念独一无二,这就意味着它们能走多远都是有限度的。这意味着它们并不总是非常可配置。桌面环境强调的是漂亮的外表,很多时候你所见并不是你所得的。 + +许多桌面环境对系统资源的要求是众所周知的,所以它们对低端硬件不友善。因为在它们身上运行的视觉效果,还有更多的事情可能会出错。我曾经尝试调整与我正在运行的桌面环境无关的网络设置,但系统崩溃了。当我打开一个窗口管理器,我就可以改变设置。 + +那些优先考虑安全性的人可能希望避免桌面环境,因为更多的程序意味着更大的攻击面 - 也就是恶意角色可以突破的入口点。 + +然而,如果你想尝试一下桌面环境,XFCE 是一个很好的开始,因为它的较小的软件基础删除了一些膨胀,如果你不坚持使用,可以留下更少的混乱。 + +乍一看,它不是最漂亮的,但在下载了一些 GTK 主题包(每个桌面环境都可以提供这些或 Qt 主题,XFCE 在 GTK 阵营中),并且在“外观”部分的设置中,你可以轻松地修改。你甚至可以在这个[集中式画廊][5]中找到你最喜欢的主题。 + +### 你可以节省大量的时间..如果你把时间放在第一位 + +如果你想了解桌面环境之外可以做什么,你会发现窗口管理器有足够的空间来操纵。 + +无论如何,窗口管理器都是关于定制的。事实上,它们的可定制性已经催生了无数的画廊, 承载着一个充满活力的社区用户,他们选择的调色板是窗口管理器。 + +窗口管理器的少量资源需求使它们成为较低规格硬件的理想选择,并且由于大多数窗口管理器不附带任何程序,因此允许喜欢模块化的用户只添加所需的程序。 + +与桌面环境最为显著的区别可能是,窗口管理器通常通过鼠标移动和键盘热键来打开程序或启动器来聚焦效率。 + +键盘驱动的窗口管理器特别精简,因为你可以启动新的窗口、输入文本或更多的键盘命令、移动它们,并再次关闭它们,这一切无需将手从主页移开。一旦你符合设计逻辑,你会惊讶于你能够快速地完成任务。 + +尽管它们提供了自由,窗口管理器也有其缺点。最显著的是,它们是赤裸裸的开箱即用。在你可以使用其中一个之前,你必须花时间阅读窗口管理器的文档以获取配置语法,可能还需要更多的时间来获取所说语法的窍门。 + +如果你从桌面环境(最可能的情况)切换过来,尽管你会有一些用户程序,你也将缺少熟悉的东西,如电池指示器和网络小部件,并且需要一些时间来设置新的。 + +如果你想深入窗口管理器,i3 有[完整的文档][6]和简单的配置语法。配置文件不使用任何编程语言 - 它只是在每行上定义一个变量值对。创建热键只要输入 “bindsym”,它是键盘绑定以及该组合启动的动作。 + +虽然窗口管理器不适合每个人,但它们提供独特的计算体验,而 Linux 是少数允许使用的操作系统之一。无论你最终采用哪种模式,我希望这个概述能够给你足够的信息,以便对你所做的选择感到自信 - 或者有足够的信心跨出您熟悉的区域来看看还有什么可用的。 + +-------------------------------------------------------------------------------- + +作者简介: + +** Jonathan Terrasi ** 自 2017 年以来一直是 ECT 新闻网专栏作家。他的主要兴趣是计算机安全(特别是 Linux 桌面)、加密和分析政治和时事。他是全职自由作家和音乐家。他的背景包括在芝加哥委员会发表的关于维护人权法案的文章中提供技术评论和分析。 + +----------- + +via: http://www.linuxinsider.com/story/84473.html?rss=1 + +作者:[ ][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: +[1]:http://www.linuxinsider.com/story/84473.html?rss=1# +[2]:http://www.linuxinsider.com/perl/mailit/?id=84473 +[3]:http://en.wikipedia.org/wiki/GNOME +[4]:http://www.linuxinsider.com/article_images/2017/84473_1200x750.jpg +[5]:http://www.xfce-look.org/ +[6]:https://i3wm.org/docs/ From 253e25c556f5843b0772f31892f469f2fd74ba3b Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 9 Oct 2017 08:48:30 +0800 Subject: [PATCH 30/39] translating --- sources/tech/20170617 What all you need to know about HTML5.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20170617 What all you need to know about HTML5.md b/sources/tech/20170617 What all you need to know about HTML5.md index b5adee5fb2..fb366a77de 100644 --- a/sources/tech/20170617 What all you need to know about HTML5.md +++ b/sources/tech/20170617 What all you need to know about HTML5.md @@ -1,3 +1,5 @@ +translating---geekpi + What all you need to know about HTML5 ============================================================ From a7f376b56871677c2caac7bbc5456d682a5c0472 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 9 Oct 2017 10:47:19 +0800 Subject: [PATCH 31/39] PRF:20170421 A Window Into the Linux Desktop.md @geekpi --- ...0170421 A Window Into the Linux Desktop.md | 74 +++++++++---------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/translated/talk/20170421 A Window Into the Linux Desktop.md b/translated/talk/20170421 A Window Into the Linux Desktop.md index 53d7e6f311..6a3d50f3f0 100644 --- a/translated/talk/20170421 A Window Into the Linux Desktop.md +++ b/translated/talk/20170421 A Window Into the Linux Desktop.md @@ -1,93 +1,91 @@ -进入 Linux 桌面的窗口 +进入 Linux 桌面之窗 ============================================================ ![linux-desktop](http://www.linuxinsider.com/article_images/story_graphics_xlarge/xl-2016-linux-1.jpg) -![](http://www.linuxinsider.com/images/2015/image-credit-adobe-stock_130x15.gif) +> “它能做什么 Windows 不能做的吗?” -“它能做什么 Windows 不能做的吗?” - -这是许多人在考虑使用 Linux 桌面时的第一个问题。虽然支撑 Linux 的开源哲学对于某些人来说就是一个很好的理由,但是一些人想知道它在外观、感受和功能上有多么不同。在某种程度上,这取决于你是否选择桌面环境或窗口管理器。 +这是许多人在考虑使用 Linux 桌面时的第一个问题。虽然支撑 Linux 的开源哲学对于某些人来说就是一个很好的理由,但是有些人想知道它在外观、感受和功能上有多么不同。在某种程度上,这取决于你是否选择桌面环境或窗口管理器。 如果你想要的是闪电般快速的桌面体验且向高效妥协, 那么上述的经典桌面中的窗口管理器可能适合你。 -### 什么是什么 +### 事实之真相 -“桌面环境”是典型的全功能桌面的技术术语,即系统的完整图形化布局。除了显示你的程序,桌面环境还包括应用程序启动器,菜单面板和小部件等。 +“桌面环境Desktop Environment(DE)”是一个技术术语,指典型的、全功能桌面,即你的操作系统的完整图形化布局。除了显示你的程序,桌面环境还包括应用程序启动器,菜单面板和小部件等组成部分。 -在 Microsoft Windows 中,桌面环境包括开始菜单,打开的程序的任务栏和通知中心,还有与操作系统捆绑在一起的所有 Windows 程序,以及打开程序的框架(有破折号、正方形和右上角的 X)。 +在 Microsoft Windows 中,桌面环境包括开始菜单、显示打开的程序的任务栏和通知中心,还有与操作系统捆绑在一起的所有 Windows 程序,以及围绕这打开的程序的框架(包括右上角的最小按钮、最大按钮和关闭按钮)。 Linux 中有很多相似之处。 -例如,Linux [Gnome][3] 桌面环境的设计略有不同,但它共享了所有的 Microsoft Windows 的基本 - 从应用程序菜单到显示打开的应用程序的面板、通知栏、窗口框架程序。 +例如,Linux [Gnome][3] 桌面环境的设计略有不同,但它共享了所有的 Microsoft Windows 的基本元素 - 从应用程序菜单到显示打开的应用程序的面板、通知栏、窗框式程序。 -窗口程序框架依赖于一个组件来绘制它们,并允许你移动并调整大小:它被称为“窗口管理器”。因为它们都有窗口,每个桌面环境都包含一个窗口管理器。 +窗口程序框架依赖于一个组件来绘制它们,并允许你移动并调整大小:它被称为“窗口管理器Window Manager(WM)”。因为它们都有窗口,所以每个桌面环境都包含一个窗口管理器。 -然而,并不是每个窗口管理器都是桌面环境的一部分。你可以只运行窗口管理器,并且有理由考虑这么做。 +然而,并不是每个窗口管理器都是桌面环境的一部分。你可以只运行窗口管理器,并且完全有这么做的需要。 ### 离开你的环境 -在本专栏中,对“窗口管理器”的引用指的是可以独立进行的。如果在现有的 Linux 系统上安装了一个窗口管理器,你可以在不关闭的情况下注销,在登录屏幕上选择新的窗口管理器,然后重新登录。 +对本专栏而言,所谓的“窗口管理器”指的是可以那种独立进行的。如果在现有的 Linux 系统上安装了一个窗口管理器,你可以在不关闭系统的情况下注销,在登录屏幕上选择新的窗口管理器,然后重新登录。 -不过, 在研究你的窗口管理器之前,你可能不想这么做,因为你会看到空白屏幕和稀疏的状态栏,这可能可以或不可以点击的。 +不过, 在研究你的窗口管理器之前,你可能不想这么做,因为你将会看到一个空白屏幕和稀疏的状态栏,而且它或许能、或许不能点击。 -通常情况下,可以直接在窗口管理器中启动终端,因为这是你编辑其配置文件的方式。在那里你会发现按键和鼠标绑定来启动程序,此时你实际上可以使用你的新设置。 +通常情况下,可以直接在窗口管理器中直接启动终端,因为这是你编辑其配置文件的方式。在那里你会发现用来启动程序的按键和鼠标组合,你实际上也可以使用你的新设置。 -例如,在流行的 i3 窗口管理器中,你可以通过按下 Super(即 Windows)键加 Enter 键来启动终端,或者按 Super + D 启动应用程序启动器。你可以在其中输入应用程序名称,然后按 Enter 键将其打开。所有现有的应用程序都可以通过这种方式找到,一旦选择后,它们将会全屏打开。 +例如,在流行的 i3 窗口管理器中,你可以通过按下 `Super` 键(即 `Windows` 键)加 `Enter` 键来启动终端,或者按 `Super + D` 启动应用程序启动器app launcher。你可以在其中输入应用程序名称,然后按 `Enter` 键将其打开。所有已有的应用程序都可以通过这种方式找到,一旦选择后,它们将会全屏打开。 - [![i3 window manager](http://www.linuxinsider.com/article_images/2017/84473_620x388-small.jpg)][4] (Click Image to Enlarge) + [![i3 window manager](http://www.linuxinsider.com/article_images/2017/84473_620x388-small.jpg)][4] -i3 还是一个平铺的窗口管理器,这意味着它可以确保所有的窗口均匀地扩展到屏幕,既不重叠也不浪费空间。当弹出新窗口时,它会减少现有的窗口,将它们推到一边腾出空间。用户可以以垂直或水平的方式切换到相邻的窗口打开。 +i3 还是一个平铺式窗口管理器,这意味着它可以确保所有的窗口均匀地扩展到屏幕,既不重叠也不浪费空间。当弹出新窗口时,它会减少现有的窗口,将它们推到一边腾出空间。用户可以以垂直或水平相邻的方式打开下一个窗口。 -### 功能可以是朋友或敌人 +### 功能亦敌亦友 -当然,桌面环境有其优点。首先,它们提供功能丰富,可识别的界面。每个都有其签名风格,但总体而言,它们提供了不引人注目的默认设置,这使得桌面环境从一开始就可以使用。 +当然,桌面环境有其优点。首先,它们提供功能丰富、可识别的界面。每个都有其特征鲜明的风格,但总体而言,它们提供了普适的默认设置,这使得桌面环境从一开始就可以使用。 -另一个优点是桌面环境有一组程序和媒体编解码器,允许用户立即完成简单的任务。此外,它们还包括便携式功能,如电池监视器、无线小部件和系统通知。 +另一个优点是桌面环境带有一组程序和媒体编解码器,允许用户立即完成简单的任务。此外,它们还包括一些方便的功能,如电池监视器、无线小部件和系统通知。 -如桌面环境一样完善,大型软件基础和用户体验理念独一无二,这就意味着它们能走多远都是有限度的。这意味着它们并不总是非常可配置。桌面环境强调的是漂亮的外表,很多时候你所见并不是你所得的。 +与桌面环境的完善相应的,是这种大型软件库和用户体验理念独一无二,这就意味着它们所能做的都是有限度的。这也意味着它们并不总是非常可配置。桌面环境强调的是漂亮的外表,很多时候是金玉其外的。 -许多桌面环境对系统资源的要求是众所周知的,所以它们对低端硬件不友善。因为在它们身上运行的视觉效果,还有更多的事情可能会出错。我曾经尝试调整与我正在运行的桌面环境无关的网络设置,但系统崩溃了。当我打开一个窗口管理器,我就可以改变设置。 +许多桌面环境对系统资源的渴求是众所周知的,所以它们不太喜欢低端硬件。因为在其上运行的视觉效果,还有更多的东西可能会出错。我曾经尝试调整与我正在运行的桌面环境无关的网络设置,然后整个崩溃了。而当我打开一个窗口管理器,我就可以改变设置。 -那些优先考虑安全性的人可能希望避免桌面环境,因为更多的程序意味着更大的攻击面 - 也就是恶意角色可以突破的入口点。 +那些优先考虑安全性的人可能希望不要桌面环境,因为更多的程序意味着更大的攻击面 —— 也就是坏人可以突破的入口点。 -然而,如果你想尝试一下桌面环境,XFCE 是一个很好的开始,因为它的较小的软件基础删除了一些膨胀,如果你不坚持使用,可以留下更少的混乱。 +然而,如果你想尝试一下桌面环境,XFCE 是一个很好的起点,因为它的较小的软件库消除了一些臃肿,如果你不往里面塞东西,垃圾就会更少。 -乍一看,它不是最漂亮的,但在下载了一些 GTK 主题包(每个桌面环境都可以提供这些或 Qt 主题,XFCE 在 GTK 阵营中),并且在“外观”部分的设置中,你可以轻松地修改。你甚至可以在这个[集中式画廊][5]中找到你最喜欢的主题。 +乍一看,它不是最漂亮的,但在下载了一些 GTK 主题包(每个桌面环境都可以提供这些主题或 Qt 主题,而 XFCE 在 GTK 阵营之中),并且在“外观”部分的设置中,你可以轻松地修改。你甚至可以在这个[集中式画廊][5]中找到你最喜欢的主题。 -### 你可以节省大量的时间..如果你把时间放在第一位 +### 时间就是生命 -如果你想了解桌面环境之外可以做什么,你会发现窗口管理器有足够的空间来操纵。 +如果你想了解桌面环境之外可以做什么,你会发现窗口管理器给了你足够的回旋余地。 -无论如何,窗口管理器都是关于定制的。事实上,它们的可定制性已经催生了无数的画廊, 承载着一个充满活力的社区用户,他们选择的调色板是窗口管理器。 +无论如何,窗口管理器都是与定制有关的。事实上,它们的可定制性已经催生了无数的画廊,承载着一个充满活力的社区用户,他们手中的调色板就是窗口管理器。 窗口管理器的少量资源需求使它们成为较低规格硬件的理想选择,并且由于大多数窗口管理器不附带任何程序,因此允许喜欢模块化的用户只添加所需的程序。 -与桌面环境最为显著的区别可能是,窗口管理器通常通过鼠标移动和键盘热键来打开程序或启动器来聚焦效率。 +可能与桌面环境最为显著的区别是,窗口管理器通常通过鼠标移动和键盘热键来打开程序或启动器来聚焦效率。 -键盘驱动的窗口管理器特别精简,因为你可以启动新的窗口、输入文本或更多的键盘命令、移动它们,并再次关闭它们,这一切无需将手从主页移开。一旦你符合设计逻辑,你会惊讶于你能够快速地完成任务。 +键盘驱动的窗口管理器特别流畅,你可以启动新的窗口、输入文本或更多的键盘命令、移动它们,并再次关闭它们,这一切无需将手从键盘中间home row移开。一旦你适应了其设计逻辑,你会惊讶于你能够如此快速地完成任务。 -尽管它们提供了自由,窗口管理器也有其缺点。最显著的是,它们是赤裸裸的开箱即用。在你可以使用其中一个之前,你必须花时间阅读窗口管理器的文档以获取配置语法,可能还需要更多的时间来获取所说语法的窍门。 +尽管它们提供了自由,窗口管理器也有其缺点。最显著的是,它们是赤裸裸的开箱即用。在你可以使用其中一个之前,你必须花时间阅读窗口管理器的文档以获取配置语法,可能还需要更多的时间来找到该语法的窍门。 -如果你从桌面环境(最可能的情况)切换过来,尽管你会有一些用户程序,你也将缺少熟悉的东西,如电池指示器和网络小部件,并且需要一些时间来设置新的。 +如果你从桌面环境(这是最可能的情况)切换过来,尽管你会有一些用户程序,你也会缺少一些熟悉的东西,如电池指示器和网络小部件,并且需要一些时间来设置新的。 -如果你想深入窗口管理器,i3 有[完整的文档][6]和简单的配置语法。配置文件不使用任何编程语言 - 它只是在每行上定义一个变量值对。创建热键只要输入 “bindsym”,它是键盘绑定以及该组合启动的动作。 +如果你想深入窗口管理器,i3 有[完整的文档][6]和简明直白的配置语法。配置文件不使用任何编程语言 - 它只是每行定义一个变量值对。创建热键只要输入 `bindsym`、键盘绑定以及该组合启动的动作即可。 -虽然窗口管理器不适合每个人,但它们提供独特的计算体验,而 Linux 是少数允许使用的操作系统之一。无论你最终采用哪种模式,我希望这个概述能够给你足够的信息,以便对你所做的选择感到自信 - 或者有足够的信心跨出您熟悉的区域来看看还有什么可用的。 +虽然窗口管理器不适合每个人,但它们提供了独特的计算体验,而 Linux 是少数允许使用它们的操作系统之一。无论你最终采用哪种模式,我希望这个概观能够给你足够的信息,以便对你所做的选择感到自信 —— 或者有足够的信心跨出您熟悉的区域来看看还有什么可用的。 -------------------------------------------------------------------------------- 作者简介: -** Jonathan Terrasi ** 自 2017 年以来一直是 ECT 新闻网专栏作家。他的主要兴趣是计算机安全(特别是 Linux 桌面)、加密和分析政治和时事。他是全职自由作家和音乐家。他的背景包括在芝加哥委员会发表的关于维护人权法案的文章中提供技术评论和分析。 +Jonathan Terrasi - 自 2017 年以来一直是 ECT 新闻网专栏作家。他的主要兴趣是计算机安全(特别是 Linux 桌面)、加密和分析政治和时事。他是全职自由作家和音乐家。他的背景包括在芝加哥委员会发表的关于维护人权法案的文章中提供技术评论和分析。 ----------- -via: http://www.linuxinsider.com/story/84473.html?rss=1 +via: http://www.linuxinsider.com/story/84473.html -作者:[ ][a] +作者:[Jonathan Terrasi][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 7f9834a0a1f0dd8d1b5e529621778dd72512c099 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 9 Oct 2017 10:47:41 +0800 Subject: [PATCH 32/39] PUB:20170421 A Window Into the Linux Desktop.md @geekpi https://linux.cn/article-8944-1.html --- .../20170421 A Window Into the Linux Desktop.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/talk => published}/20170421 A Window Into the Linux Desktop.md (100%) diff --git a/translated/talk/20170421 A Window Into the Linux Desktop.md b/published/20170421 A Window Into the Linux Desktop.md similarity index 100% rename from translated/talk/20170421 A Window Into the Linux Desktop.md rename to published/20170421 A Window Into the Linux Desktop.md From d5061b1c127fe5c2b8f8d5876717eb20a8b6fd7a Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 9 Oct 2017 23:35:00 +0800 Subject: [PATCH 33/39] PRF:20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @toutoudnf 原文中前后名称不一致,以及命令中存在多余的空格。要是更仔细些就更好了。 --- ... The 8 possible scenarios using OpenSSH.md | 229 +++++++----------- 1 file changed, 82 insertions(+), 147 deletions(-) diff --git a/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md b/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md index 2df7a5f3c0..4f5a75e902 100644 --- a/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md +++ b/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md @@ -1,47 +1,26 @@ 通过 SSH 实现 TCP / IP 隧道(端口转发):使用 OpenSSH 可能的 8 种场景 ============================================================ -对于 [Secure Shell (SSH)][21] 这样的网络协议来说,其主要职责就是在终端模式下访问一个远程系统。因为 SSH 协议对传输数据进行了加密,所以通过它在远端系统执行命令是非常安全的。此外,我们还可以在这种加密后的连接上通过创建隧道(端口转发)的方式,来实现两个不同终端间的互联。凭借这种方式,只要我们能通过 SSH 创建连接,就可以绕开防火墙或者端口禁用的限制。 +对于 [Secure Shell (SSH)][21] 这样的网络协议来说,其主要职责就是在终端模式下访问一个远程系统。因为 SSH 协议对传输数据进行了加密,所以通过它在远端系统执行命令是安全的。此外,我们还可以在这种加密后的连接上通过创建隧道(端口转发)的方式,来实现两个不同终端间的互联。凭借这种方式,只要我们能通过 SSH 创建连接,就可以绕开防火墙或者端口禁用的限制。 -这个话题在网络领域被广泛应用和讨论: +这个话题在网络领域有大量的应用和讨论: * [Wikipedia: SSH Tunneling][12] - * [O’Reilly: Using SSH Tunneling][13] - * [Ssh.com: Tunneling Explained][14] - * [Ssh.com: Port Forwarding][15] - * [SecurityFocus: SSH Port Forwarding][16] - * [Red Hat Magazine: SSH Port Forwarding][17] 我们在接下来的内容中并不讨论端口转发的细节,而是准备介绍一个如何使用 [OpenSSH][22] 来完成 TCP 端口转发的速查表,其中包含了八种常见的场景。有些 SSH 客户端,比如 [PuTTY][23],也允许通过界面配置的方式来实现端口转发。而我们着重关注的是通过 OpenSSH 来实现的的方式。 -在下面的例子当中,我们假设环境中的网络划分为外部网络(network1)和内部网络(network2)两部分,并且这两个网络之间,只能在 external1 与 internal1 之间通过 SSH 连接的方式来互相访问。外部网络的节点之间和内部网络的节点之间是完全联通的。 +在下面的例子当中,我们假设环境中的网络划分为外部网络(network1)和内部网络(network2)两部分,并且这两个网络之间,只能在 externo1 与 interno1 之间通过 SSH 连接的方式来互相访问。外部网络的节点之间和内部网络的节点之间是完全联通的。 ![SSH tunnels: no tunnel](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_sin_tunel.png) -内容列表: +### 场景 1 -* [1 场景 1 :在 external1 节点访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = localhost / 主机 = localhost )][2] - -* [2 场景 2:在 external2 节点上访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost)][3] - -* [3 场景 3:在 internal1 上访问由 external1 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / 主机 = localhost)][4] - -* [4 场景 4 :internal2 使用 external1 上提供的 TCP 服务(远端端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost)][5] - -* [5 场景 5 :在 external1 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 localhost / 主机 = internal2 )][6] - -* [6 场景 6 :在 internal1 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / host = external2)][7] - -* [7 场景7 :在 external2 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = internal2)][8] - -* [8 场景 8 : 在 internal2 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = 0.0.0.0 / 主机 = external2)][9] - -#### 场景 1 :在 external1 节点访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = localhost / 主机 = localhost ) +> 在 externo1 节点访问由 interno1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = localhost / 主机 = localhost ) externo1 节点可以通过 OpenSSH 连接到 interno1 节点,之后我们想通过其访问运行在 5900 端口上的 VNC 服务。 @@ -50,13 +29,13 @@ externo1 节点可以通过 OpenSSH 连接到 interno1 节点,之后我们想 我们可以通过下面的命令来实现: ``` -External1 $ ssh -L 7900: localhost: 5900 user @ internal1 +externo1 $ ssh -L 7900:localhost:5900 user@interno1 ``` 现在,我们可以在 externo1 节点上确认下 7900 端口是否处于监听状态中: ``` -External1 $ netstat -ltn +externo1 $ netstat -ltn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State       ... @@ -64,40 +43,32 @@ Tcp 0 0 127.0.0.1:7900 0.0.0.0:* LISTEN   ... ``` -我们只需要在 external1 节点上执行如下命令即可访问 internal 节点的 VNC 服务。: +我们只需要在 externo1 节点上执行如下命令即可访问 internal 节点的 VNC 服务: ``` -External1 $ vncviewer localhost :: 7900 +externo1 $ vncviewer localhost::7900 ``` -注意:在下面的文档中并未提及这种修改端口号的方式。在[About VNCViewer configuration of the output TCP port][18] 中可以看到。这也是 [the TightVNC vncviewer][19] 所介绍的的。 +注意:在 [vncviewer 的 man 手册](http://www.realvnc.com/products/free/4.1/man/vncviewer.html)中并未提及这种修改端口号的方式。在 [About VNCViewer configuration of the output TCP port][18] 中可以看到。这也是 [the TightVNC vncviewer][19] 所介绍的的。 -``` -man vncviewer -``` +### 场景 2 -#### 场景 2:在 external2 节点上访问由 internal1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost) +> 在 externo2 节点上访问由 interno1 节点提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost) -这次的场景跟方案 1 的场景的类似,但是我们这次想从 external2 节点来连接到 internal1 上的 VNC 服务: +这次的场景跟方案 1 的场景的类似,但是我们这次想从 externo2 节点来连接到 interno1 上的 VNC 服务: ![SSH Tunnels: Scenario 2](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_2.png) 正确的命令如下: ``` -External1 $ ssh -L 0.0.0.0:7900:localhost:5900 user @ internal1 +externo1 $ ssh -L 0.0.0.0:7900:localhost:5900 user@interno1 ``` -看起来跟方案 1 中的命令类似,但是让我们看看 netstat 命令的输出上的区别: +看起来跟方案 1 中的命令类似,但是让我们看看 `netstat` 命令的输出上的区别。7900 端口被绑定到了本地(`127.0.0.1`),所以只有本地进程可以访问。这次我们将端口关联到了 `0.0.0.0`,所以系统允许任何 IP 地址的机器访问 7900 这个端口。 ``` -netstat -``` - -7900 端口被绑定到了本地(127.0.0.1),所以只有本地进程可以访问。这次我们将端口关联到了 0.0.0.0,所以系统允许任何 IP 地址的机器访问 7900 这个端口。 - -``` -External1 $ netstat -ltn +externo1 $ netstat -ltn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State       ... @@ -105,44 +76,32 @@ Tcp 0 0 0.0.0.0:7900 0.0.0.0:* LISTEN ... ``` -所以现在在 external2 节点上,我们可移执行: +所以现在在 externo2 节点上,我们可以执行: ``` -External2 $ vncviewer external1 :: 7900 +externo2 $ vncviewer externo1::7900 ``` -来连接到 internal1 节点上的 VNC 服务。 +来连接到 interno1 节点上的 VNC 服务。 -除了将 IP 指定为 +除了将 IP 指定为 `0.0.0.0` 之外,我们还可以使用参数 `-g`(允许远程机器使用本地端口转发),完整命令如下: ``` -0.0.0.0 -``` - -之外,我们还可以使用如下参数: - -``` --g -``` - -(允许远程机器使用本地端口转发),完整命令如下: - -``` -External1 $ ssh -g -L 7900: localhost: 5900 user @ internal1 +externo1 $ ssh -g -L 7900:localhost:5900 user@interno1 ``` 这条命令与前面的命令能实现相同效果: ``` -External1 $ ssh -L 0.0.0.0:7900:localhost:5900 user @ internal1 +externo1 $ ssh -L 0.0.0.0:7900:localhost:5900 user@interno1 ``` -换句话说,如果我们想限制只有指定 IP 的机器才能访问转发端口,可以像下面这样定义: +换句话说,如果我们想限制只能连接到系统上的某个 IP,可以像下面这样定义: ``` -External1 $ ssh -L 192.168.24.80:7900:localhost:5900 user @ internal1 +externo1 $ ssh -L 192.168.24.80:7900:localhost:5900 user@interno1 -External1 $ netstat -ltn +externo1 $ netstat -ltn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State ... @@ -150,34 +109,26 @@ Tcp 0 0 192.168.24.80:7900 0.0.0.0:* LISTEN ... ``` -#### 场景 3:在 internal1 上访问由 external1 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / 主机 = localhost) +### 场景 3 + +> 在 interno1 上访问由 externo1 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / 主机 = localhost) 在场景 1 中 SSH 服务器与 TCP 服务(VNC)提供者在同一个节点上。现在我们想在 SSH 客户端所在的节点上,提供一个 TCP 服务(VNC)供 SSH 服务端来访问: ![SSH Tunnels: Scenario 3](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_3.png) -将方案 1 中的命令参数由: - -``` --L -``` - -替换为 - -``` --R -``` +将方案 1 中的命令参数由 `-L` 替换为 `-R`。 完整命令如下: ``` -External1 $ ssh -R 7900: localhost: 5900 user @ internal1 +externo1 $ ssh -R 7900:localhost:5900 user@interno1 ``` 然后我们就能看到 interno1 节点上对 7900 端口正在监听: ``` -Internal1 $ netstat -lnt +interno1 $ netstat -lnt Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State ... @@ -185,61 +136,37 @@ Tcp 0 0 127.0.0.1:7900 0.0.0.0:* LISTEN ... ``` -现在在 internal1 节点上,我们可以使用如下命令来访问 external1 上的 VNC 服务。 +现在在 interno1 节点上,我们可以使用如下命令来访问 externo1 上的 VNC 服务: ``` -Internal1 $ vncviewer localhost :: 7900 +interno1 $ vncviewer localhost::7900 ``` -#### 场景 4 :internal2 使用 external1 上提供的 TCP 服务(远端端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost) +### 场景 4 -与场景 3 类似,但是现在我们尝试指定允许访问转发端口的 IP(就像方案 2 中做的一样) +> interno2 使用 externo1 上提供的 TCP 服务(远端端口转发 / 绑定地址 = 0.0.0.0 / 主机 = localhost) -``` -0.0.0.0 -``` - -这样其他节点也可以访问 VNC 服务: +与场景 3 类似,但是现在我们尝试指定允许访问转发端口的 IP(就像场景 2 中做的一样)为 `0.0.0.0`,这样其他节点也可以访问 VNC 服务: ![SSH Tunnels: Scenario 4](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_4-1.png) 正确的命令是: ``` -External1 $ ssh -R 0.0.0.0:7900:localhost:5900 user @ internal1 +externo1 $ ssh -R 0.0.0.0:7900:localhost:5900 user@interno1 ``` -但是如果我们直接执行该命令的话可能不会生效,因为我们需要修改 SSH 服务端的一个参数值: - -``` -GatewayPorts -``` - -他的默认值是: - -``` -no -``` +但是这里有个重点需要了解,出于安全的原因,如果我们直接执行该命令的话可能不会生效,因为我们需要修改 SSH 服务端的一个参数值 `GatewayPorts`,它的默认值是:`no`。 > GatewayPorts > -> 该参数指定了是否允许远程主机访问转发端口。默认情况下,sshd(8) 只允许本机进程访问转发端口。这是为了阻止其他主机连接到该转发端口。GatewayPorts 参数可用于指定 sshd 允许哪些远程主机访问转发端口。当参数值设置为 “no” 的时候只有本机可以访问转发端口;“yes” 则表示允许符合远程主机 IP 地址通配符规则的远程主机访问该转发端口;“clientspecified” 则表示由客户端来选择哪些主机地址允许访问转发端口。默认值是 “no”。 +> 该参数指定了远程主机是否允许客户端访问转发端口。默认情况下,sshd(8) 只允许本机进程访问转发端口。这是为了阻止其他主机连接到该转发端口。GatewayPorts 参数可用于让 sshd 允许远程转发端口绑定到非回环地址上,从而可以让远程主机访问。当参数值设置为 “no” 的时候只有本机可以访问转发端口;“yes” 则表示允许远程转发端口绑定到通配地址上;或者设置为 “clientspecified” 则表示由客户端来选择哪些主机地址允许访问转发端口。默认值是 “no”。 -如果我们没有修改服务器配置的权限,我们将不能使用该方案来进行端口转发。这是因为如果没有其他的限制,用户可以开启一个端口(> 1024)来监听来自外部的请求并转发到: - -``` -localhost:7900 -``` +如果我们没有修改服务器配置的权限,我们将不能使用该方案来进行端口转发。这是因为如果没有其他的限制,用户可以开启一个端口(> 1024)来监听来自外部的请求并转发到 `localhost:7900`。 参照这个案例:[netcat][24] ( [Debian # 310431: sshd_config should warn about the GatewayPorts workaround.][25] ) -所以我们修改: - -``` -/etc/ssh/sshd_config -``` - -添加如下内容: +所以我们修改 `/etc/ssh/sshd_config`,添加如下内容: ``` GatewayPorts clientspecified @@ -251,10 +178,10 @@ GatewayPorts clientspecified sudo /etc/init.d/ssh reload ``` -我们确认现在 internal1 节点上存在 7900 端口的监听程序,监听来自不同 IP 的请求: +我们确认一下现在 interno1 节点上存在 7900 端口的监听程序,监听来自不同 IP 的请求: ``` -Internal1 $ netstat -ltn +interno1 $ netstat -ltn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State ... @@ -262,74 +189,82 @@ Tcp 0 0 0.0.0.0:7900 0.0.0.0:* LISTEN ... ``` -然后我们就可以在 internal2 节点上使用 VNC 服务了: +然后我们就可以在 interno2 节点上使用 VNC 服务了: ``` -Internal2 $ internal vncviewer1 :: 7900 +interno2 $ internal vncviewer1::7900 ``` -#### 场景 5 :在 external1 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 localhost / 主机 = internal2 ) +### 场景 5 + +> 在 externo1 上使用由 interno2 提供的 TCP 服务(本地端口转发 / 绑定地址 localhost / 主机 = interno2 ) ![SSH Tunnels: Scenario 5](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_5.png) 在这种场景下我们使用如下命令: ``` -External1 $ ssh -L 7900: internal2: 5900 user @ internal1 +externo1 $ ssh -L 7900:interno2:5900 user@interno1 ``` -然后我们就能在 external1 节点上,通过执行如下命令来使用 VNC 服务了: +然后我们就能在 externo1 节点上,通过执行如下命令来使用 VNC 服务了: ``` -External1 $ vncviewer localhost :: 7900 +externo1 $ vncviewer localhost::7900 ``` -#### 场景 6 :在 internal1 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / host = external2) +### 场景 6 + +> 在 interno1 上使用由 externo2 提供的 TCP 服务(远程端口转发 / 绑定地址 = localhost / host = externo2) ![SSH Tunnels: Scenario 6](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_6.png) 在这种场景下,我们使用如下命令: ``` -External1 $ ssh -R 7900: external2: 5900 user @ internal1 +externo1 $ ssh -R 7900:externo2:5900 user@interno1 ``` -然后我们可以在 internal1 上通过执行如下命令来访问 VNC 服务: +然后我们可以在 interno1 上通过执行如下命令来访问 VNC 服务: ``` -Internal1 $ vncviewer localhost :: 7900 +interno1 $ vncviewer localhost::7900 ``` -#### 场景7 :在 external2 上使用由 internal2 提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = internal2) +### 场景7 + +> 在 externo2 上使用由 interno2 提供的 TCP 服务(本地端口转发 / 绑定地址 = 0.0.0.0 / 主机 = interno2) ![SSH Tunnels: Scenario 7](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_7.png) 本场景下,我们使用如下命令: ``` -External1 $ ssh -L 0.0.0.0:7900:internal2:5900 user @ internal1 +externo1 $ ssh -L 0.0.0.0:7900:interno2:5900 user@interno1 ``` 或者: ``` -External1 $ ssh -g -L 7900: internal2: 5900 user @ internal1 +externo1 $ ssh -g -L 7900:interno2:5900 user@interno1 ``` -然后我们就可以在 external2 上执行如下命令来访问 vnc 服务: +然后我们就可以在 externo2 上执行如下命令来访问 vnc 服务: ``` -External2 $ vncviewer external1 :: 7900 +externo2 $ vncviewer externo1::7900 ``` -#### 场景 8 : 在 internal2 上使用由 external2 提供的 TCP 服务(远程端口转发 / 绑定地址 = 0.0.0.0 / 主机 = external2) +### 场景 8 + +> 在 interno2 上使用由 externo2 提供的 TCP 服务(远程端口转发 / 绑定地址 = 0.0.0.0 / 主机 = externo2) ![SSH Tunnels: Scenario 8](https://wesharethis.com/wp-content/uploads/2017/07/ssh_tunnel_8.png) 本场景下我们使用如下命令: ``` -External1 $ ssh -R 0.0.0.0:7900:external2:5900 user @ internal1 +externo1 $ ssh -R 0.0.0.0:7900:externo2:5900 user@interno1 ``` SSH 服务器需要配置为: @@ -340,13 +275,13 @@ GatewayPorts clientspecified 就像我们在场景 4 中讲过的那样。 -然后我们可以在 internal2 节点上执行如下命令来访问 VNC 服务: +然后我们可以在 interno2 节点上执行如下命令来访问 VNC 服务: ``` -Internal2 $ internal vncviewer1 :: 7900 +interno2 $ internal vncviewer1::7900 ``` -如果我们需要一次性的创建多个隧道,使用配置文件的方式替代一个可能很长的命令是一个更好的选择。假设我们只能通过 SSH 的方式访问某个特定网络,同时又需要创建多个隧道来访问该网络内不同服务器上的服务,比如 VNC 或者 [远程桌面][26]。此时只需要创建一个如下的配置文件即可(在 SOCKS 服务器 上)。 +如果我们需要一次性的创建多个隧道,使用配置文件的方式替代一个可能很长的命令是一个更好的选择。假设我们只能通过 SSH 的方式访问某个特定网络,同时又需要创建多个隧道来访问该网络内不同服务器上的服务,比如 VNC 或者 [远程桌面][26]。此时只需要创建一个如下的配置文件 `$HOME/redirects` 即可(在 SOCKS 服务器 上)。 ``` # SOCKS server @@ -370,29 +305,29 @@ LocalForward 5903 172.16.23.45:5901 然后我们只需要执行如下命令: ``` -External1 $ ssh -F $ HOME / redirects user @ internal1 +externo1 $ ssh -F $HOME/redirects user@interno1 ``` -------------------------------------------------------------------------------- via: https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/ -作者:[ Ahmad][a] +作者:[Ahmad][a] 译者:[toutoudnf](https://github.com/toutoudnf) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://wesharethis.com/author/ahmad/ [1]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/# -[2]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_1_Use_onexternal1a_TCP_service_offered_byinternal1Local_port_forwarding_bind_address_localhost_host_localhost -[3]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_2_Use_onexternal2a_TCP_service_offered_byinternal1Local_port_forwarding_bind_address_0000_host_localhost -[4]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_3_Use_ininternal1a_TCP_service_offered_byexternal1Remote_port_forwarding_bind_address_localhost_host_localhost -[5]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_4_Use_ininternal2a_TCP_service_offered_byexternal1Remote_port_forwarding_bind_address_0000_host_localhost -[6]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_5_Use_inexternal1a_TCP_service_offered_byinternal2Local_port_forwarding_bind_address_localhost_host_internal2 -[7]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_6_Use_ininternal1a_TCP_service_offered_byexternal2Remote_port_forwarding_bind_address_localhost_host_external2 -[8]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_7_Use_inexternal2a_TCP_service_offered_byinternal2Local_port_forwarding_bind_address_0000_host_internal2 -[9]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_8_Use_ininternal2a_TCP_service_offered_byexternal2Remote_port_forwarding_bind_address_0000_host_external2 +[2]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_1_Use_onexterno1a_TCP_service_offered_byinterno1Local_port_forwarding_bind_address_localhost_host_localhost +[3]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_2_Use_onexterno2a_TCP_service_offered_byinterno1Local_port_forwarding_bind_address_0000_host_localhost +[4]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_3_Use_ininterno1a_TCP_service_offered_byexterno1Remote_port_forwarding_bind_address_localhost_host_localhost +[5]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_4_Use_ininterno2a_TCP_service_offered_byexterno1Remote_port_forwarding_bind_address_0000_host_localhost +[6]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_5_Use_inexterno1a_TCP_service_offered_byinterno2Local_port_forwarding_bind_address_localhost_host_interno2 +[7]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_6_Use_ininterno1a_TCP_service_offered_byexterno2Remote_port_forwarding_bind_address_localhost_host_externo2 +[8]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_7_Use_inexterno2a_TCP_service_offered_byinterno2Local_port_forwarding_bind_address_0000_host_interno2 +[9]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#Scenario_8_Use_ininterno2a_TCP_service_offered_byexterno2Remote_port_forwarding_bind_address_0000_host_externo2 [10]:https://wesharethis.com/author/ahmad/ [11]:https://wesharethis.com/2017/07/creating-tcp-ip-port-forwarding-tunnels-ssh-8-possible-scenarios-using-openssh/#comments [12]:http://en.wikipedia.org/wiki/Tunneling_protocol#SSH_tunneling From 31aac1ef1f668574d5121eea3e9d9af636ca62b5 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 9 Oct 2017 23:35:30 +0800 Subject: [PATCH 34/39] PUB:20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md @toutoudnf https://linux.cn/article-8945-1.html --- ...ing tunnels with SSH The 8 possible scenarios using OpenSSH.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md (100%) diff --git a/translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md b/published/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md similarity index 100% rename from translated/tech/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md rename to published/20170714 Creating TCP IP port forwarding tunnels with SSH The 8 possible scenarios using OpenSSH.md From bcfe6740e58a815994423a92a3b1a7b6713a8acc Mon Sep 17 00:00:00 2001 From: geekpi Date: Tue, 10 Oct 2017 08:36:23 +0800 Subject: [PATCH 35/39] translated --- ...7 What all you need to know about HTML5.md | 274 ------------------ 1 file changed, 274 deletions(-) delete mode 100644 sources/tech/20170617 What all you need to know about HTML5.md diff --git a/sources/tech/20170617 What all you need to know about HTML5.md b/sources/tech/20170617 What all you need to know about HTML5.md deleted file mode 100644 index fb366a77de..0000000000 --- a/sources/tech/20170617 What all you need to know about HTML5.md +++ /dev/null @@ -1,274 +0,0 @@ -translating---geekpi - -What all you need to know about HTML5 -============================================================ - - - _![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/handwritten-html5-peter-booth-e-plus-getty-images-56a6faec5f9b58b7d0e5d1cf.jpg?resize=700%2C467)_ - - _HTML5, the fifth and current version of the HTML standard, is a markup language used to structure and present content on the World Wide Web. This article will help readers get acquainted with it._ - -HTML5 has evolved through the cooperation between the W3C and the Web Hypertext Application Technology Working Group. It is a higher version of HTML, and its many new elements make your pages more semantic and dynamic. It was developed to provide a greater Web experience for everyone. HTML5 offers great features that make the Web more dynamic and interactive. - -The new features of HTML5 are: - -* New sets of tags such as
and
- -* element for 2D drawing - -* Local storage - -* New form controls like calendar, date and time - -* New media functionality - -* Geo-location - -HTML5 is not an official standard as yet; hence, not all browsers support it or some of its features. One of the most important reasons behind developing HTML5 was to prevent users from having to download and install multiple plugins like Silverlight and Flash. - -**New tags and elements** - -**Semantic elements:** Figure 1 displays a few useful semantic elements. -**Form elements:** The form elements present in HTML5 are shown in Figure 2. -**Graphic elements:** The graphic elements in HTML5 can be seen in Figure 3. -**Media elements:** The new media elements in HTML5 are listed in Figure 4. - - [![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/Figure-1-7.jpg?resize=350%2C277)][3] - -Figure 1: Semantic elements - - [![](https://i1.wp.com/opensourceforu.com/wp-content/uploads/2017/05/Figure-2-5.jpg?resize=350%2C108)][4] - -Figure 2: Form elements - -**Advanced features of HTML5** - -**Geo-location** - -It is an HTML5 API that is used to get the geographical location of a website’s user, who has to first permit the site to fetch his or her location. This usually happens via a button and/or browser popup. All the latest versions of Chrome, Firefox, IE, Safari and Opera can use the geo-location feature of HTML5. - -Some uses of geo-location are: - -* Public transportation websites - -* Taxi and other transportation websites - -* To calculate shipping costs on an e-commerce site - -* Travel agency websites - -* Real estate websites - -* Movie theatre websites can find movies playing nearby - -* Online gaming - -* For sites to feature local headlines and weather on their front page - -* Job postings can automatically include commute times - -**How it works:** Geo-location works by scanning common sources of location information, which include the following: - -* Global Positioning System (GPS), which is the most accurate - -* Network signals—IP address, RFID, Wi-Fi and Bluetooth MAC addresses - -* GSM/CDMA cell IDs - -* User inputs - -The API offers a very handy function to detect geo-location support in browsers: - -| `if` `(navigator.geolocation) {``//` `do` `stuff``}` | - -The  _getCurrentPosition_  API is the main method for using geo-location. It retrieves the current geographic location of the user’s device. The location is described as a set of geographic coordinates along with the heading and speed. The location information is returned as a position object. - -The syntax is: - -`getCurrentPosition(showLocation, ErrorHandler, options);` - -* _showLocation:_  This defines the callback method that retrieves location information. - -* _ErrorHandler(Optional):_  This defines the callback method that is invoked when an error occurs in processing the asynchronous call. - -* _options (Optional):_  This defines a set of options for retrieving the location information. - - [![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/Figure-3-2.jpg?resize=350%2C72)][5] - -Figure 3: Graphic elements - - [![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/Figure-4-2.jpg?resize=350%2C144)][6] - -Figure 4: Media elements - -Figure 5 incorporates the set of properties returned by a position object. - -We can present location information to the user in two ways—geodetic and civil: - -1\. The geodetic way of describing a position refers directly to the latitude and longitude. -2\. The civic representation of location data is readable and easily understood by humans. - -As shown in Table 1, each attribute/parameter has both a geodetic representation and a civic representation. - - [![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/table-1.jpg?resize=350%2C132)][7] - -**Web storage** - -In HTML, to store user data on a local machine, we were using JavaScript cookies. To avoid that, HTML5 has introduced Web storage, with which websites themselves store user data on a local machine. - -The advantages of Web storage, as compared to cookies, are: - -* More secure - -* Faster - -* Stores a larger amount of data - -* The stored data is not sent with every server request. It is only included when asked for. This is a big advantage of HTML5 Web storage over cookies. - -There are two types of Web storage objects: - -1) Local – this stores data with no expiration date. -2) Session – this stores data for one session only. - -**How it works:** The  _localStorage_  and  _sessionStorage_  objects create a  _key = value pair._ - -An example is: _ key=“Name”,_   _value=“Palak”_ - -These are stored as strings but can be converted, if required, by using JavaScript functions like  _parseInt()_  and  _parseFloat()_ . - -Given below is the syntax for using Web storage objects: - - `Storing a Value:``• localStorage.setItem(“key1”, “value1”);``• localStorage[“key1”] = “value1”;``Getting a Value:``• alert(localStorage.getItem(“key1”));``• alert(localStorage[“key1”]);``Remove a Value:``• removeItem(“key1”);``Remove All Values:``• localStorage.``clear``();` - - [![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/Figure5-1.jpg?resize=350%2C202)][8] - -Figure 5: Position object properties - -**Application Cache (AppCache)** - -Using HTML5 Apache, we can make a Web application work offline without an Internet connection. All browsers, besides IE, can use  _AppCache_  (at this point in time). - -The advantages of Application Cache are: - -* Enables browsing Web pages offline - -* Pages load faster - -* Results in less load for servers - -The  _cache manifest_  file is a simple text file that lists the resources the browser should cache for offline access. The  _manifest_  attribute can be included on the document’s HTML tag, as follows: - -```...``<``/html``>` - -It should be on all the pages that you want to cache. - -The application pages that are cached will remain unless: - -1\. The user clears them out. -2\. The manifest has been modified. -3\. The cache is updated. - -**Video** - -Until HTML5 was launched, there was no uniform standard for showing video on Web pages. Most of the videos were shown through different plugins like Flash. But HTML5 specifies a standard way to show the video on a Web page by using a video element. - -Currently, it supports three video formats for the video element, as shown in Table 2. - - [![](https://i0.wp.com/opensourceforu.com/wp-content/uploads/2017/05/table-2.jpg?resize=350%2C115)][9] -The example given below shows the use of this video element: - ```````