安卓编年史（25）：Android 4.4，奇巧——更完美，更少的内存占用（2）

Summary: 奇巧的主屏幕配置界面漂亮地对蜂巢进行了复古。

奇巧的主屏幕配置界面漂亮地对蜂巢进行了复古。

![](/data/attachment/album/201706/24/162030ibzruefjuf4bouzo.jpg)

![](/data/attachment/album/201706/24/162105cll3hih12igzqh3q.jpg)

*新的“添加到主屏幕”界面无疑受到了蜂巢的启发。 [Ron Amadeo 供图]*

奇巧的主屏幕配置界面漂亮地对蜂巢进行了复古。在有巨大的 10 英寸屏幕的蜂巢平板上（上方右侧图片），长按主屏背景会向你展现一个所有主屏幕的缩放视图。可以从下面的小部件抽屉里将它们拖放到任意主屏上——这很方便。在将蜂巢的界面带到手机上时，从安卓 4.0 直到 4.3，谷歌都跳过了这个设计，把它留给了大屏幕设备，在手机上长按后只显示一个选项列表（中间的图片）。

但在奇巧上，谷歌最终给出了解决方案。在长按后，4.4 呈现一个略微缩放的视图——你可以看到当前主屏以及它左右侧的屏幕。点击“小部件”按钮会打开一个小部件略缩图的完整列表，但是长按一个小部件后，你会回到缩放视图，并且你可以在主屏页面之间滚动，将图标放在你想要的位置。将图标或者小部件拖动过最右侧的主屏页面，你可以创建一个新的主屏页面。

![](/data/attachment/album/201706/24/162143obfx9a9195lauuul.jpg)

*联系人和去掉所有蓝色痕迹的键盘。 [Ron Amadeo 供图]*

奇巧是电子风格设计的完结。在系统的大多数地方，剩下的蓝色高亮都被换成了灰色。在联系人应用中，头部和联系人列表字母分割线的蓝色都移除掉了。图片的位置换了一侧，底栏变成了浅灰色以和顶部相称。几乎将蓝色渗透进每个应用的键盘，现在是灰底、灰色、灰高亮。这可不是件坏事。应用应该允许有它们自己的配色方案——在键盘上强迫存在潜在的颜色冲突可不是个好设计。

![](/data/attachment/album/201706/24/162220tqhqsgw167st7wdb.jpg)

*前三张是奇巧的拨号盘，最后一张是 4.3 的。 [Ron Amadeo 供图]*

谷歌完全重制了奇巧中的拨号，创造了一个疯狂的设计，改变了用户对手机的思考方式。实际上新版拨号中的数字都被尽可能地隐藏了——在首屏上甚至没有拨号盘。打电话的主要界面现在是个搜索栏！如果你想给你的联系人打电话，只要在搜索栏输入他的名字；如果你想给一个公司打电话，只要输入公司的名字，拨号会通过谷歌地图庞大的数据库找到号码。它工作得令人难以置信的好，这是只有谷歌才能完成的事情。

如果搜索不是你的菜的话，应用还会智能地显示通话记录列表，最常联系人，还有指向所有联系人的链接。底部的链接指向你的通话记录，传统的拨号盘，以及常规的更多操作按钮，包含一个设置页面。

![](/data/attachment/album/201706/24/162307jmxtgtz1u1mg7u3g.jpg)

*Office 相关：新的内置应用 Google Drive，以及打印支持。 [Ron Amadeo 供图]*

在奇巧中 Google Drive 终于作为内置应用包含了进来，令人惊奇的是这居然等了这么长时间。Drive 允许用户创建和编辑 Google Docs 表格和文档，用相机扫描文档并作为 PDF 上传，或者查看（不能编辑）演示文稿。Drive 的设计十分现代，侧面拥有滑出式导航抽屉，并且是 Google Now 风格卡片式设计。

为了有更多的移动办公乐趣，奇巧包含了系统级打印框架。在设置的底部有“打印”设置界面，任何打印机 OEM 厂商都可以为它写个插件。谷歌云打印自然是首批支持者之一。只要你的打印机和云打印相连接，无论是本地或通过一台装有 Chrome 浏览器的电脑，你都可以借助网络进行打印。应用同样也需要支持打印框架。点击 Google Drive 里的“i”按钮会显示文档信息，并且给你打印的选项。就像桌面系统那样，会弹出一个设置对话框，有打印份数，纸张尺寸，以及页面选择等选项。

![](/data/attachment/album/201706/24/162349wq17ds15gjddezqg.jpg)

*Google+ 应用的“相片”部分，它取代了相册。 [Ron Amadeo 供图]*

Google+ 相片和相册最初都在 Nexus 5 上随附，但在 Google Play 设备稍晚版本的奇巧上，相册被砍掉了，Google+ 完全接手了相片管理。新应用的主题从深色变成了浅色，Google+ 相片还带来了现代的导航抽屉设计。

安卓一直以来都有即时上传功能，它会自动备份所有图片到谷歌的云存储，开始是 Picasa 后来是 Google+。G+ 相片相比相册最大的好处是它可以管理那些云端存储的图片。图片右下角的云图标指示备份状态，它会从右到左地填满来指示上传状态。G+ 相片带来了它自己的照片编辑器，还有许多其它的 Google+ 图片功能，比如高亮，自动美化，当然，还有分享到 Google+。

![](/data/attachment/album/201706/24/162421b863utokez6iptmv.jpg)

*时钟应用的调整，添加了一个闹钟页面并修改了时间输入框。 [Ron Amadeo 供图]*

谷歌将 4.2 引入的优秀时间选择器换成了一个奇怪的时钟界面，操作起来比旧界面更慢了也更不精确了。首先是个可以选择小时的单指针时钟，然后显示的是另一个选择分钟的单指针时钟。选择的时候要转动分针或点击数字，这让用用户很难选择不是整五分钟的时间增量。不像之前的时间选择器需要选择一个时间段，这里默认时间段是 AM（重复一下，这样设置的时候容易不小心偏差 12 小时）。

---

![](/data/attachment/album/201706/24/162535j8ke2nu4ccvw44g9.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron 是 Ars Technica 的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。[@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/26/>

译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


使用 Go 一年的体验

从C++转做Go快两年了，感觉还可以，起码不用像C++一样担心内存泄漏（一般情况不会泄漏，也不排除特殊）。从C++转go比较方便，上手快，相当于由俭入奢；如果由python转go就比较麻烦（身边很多原python程序员成天抱怨。。。），会感觉没有python方便，相当于由奢入俭。各有利弊，各取所长吧。

用了Golang一段时间了，目前有几个难以接受的问题：

1.没有成熟的异常处理机制，通过错误返回值来判断是否异常过于原始，很多时候需要完整的异常堆栈信息。

2.没有泛型机制，无法很好的复用代码。静态强类型语言不支持泛型让我直接感觉回到了Java1.5之前，很难想象这是一门2009年发布的语言。

Golang语言特性很少，加上由gofmt这样的工具统一团队代码风格，可以说是工程性很优秀的语言，但一些关键特性的缺失还是令很多人望而却步(说得好听叫简洁，说得难听叫简陋)。

![](/data/attachment/album/201706/24/215524k9caxmcp8c3ppa39.jpg)

我们公司 [Mobile Jazz](http://mobilejazz.com/) 从一个内部试验性项目开始使用 [Go](https://golang.org/)。如公司名暗示的那样，我们是开发移动应用的。

在发布一个应用给公众后，我们很快意识到我们缺失一个工具来检查用户实际发生的情况以及他们是如何与应用交互的 - 如果有任何问题或者 bug 的报告，这将会相当方便。

现在有几款工具声称能在这个方面帮助开发者，但是没有一个能完全满足要求，因此我们决定自己构建一个。我们开始创建一组基础的脚本，如今它很快进化成了完整的工具，称为 [Bugfender](https://www.bugfender.com/)！

由于这最初是一个实验，我们决定使用一种新的趋势技术。对学习以及持续教育的热爱是 Mobile Jazz 的核心价值的之一，因此我们决定使用 Go 构建。这是一个由 Google 开发的相对较新的编程语言。它是编程世界的的新玩家，已经有许多受尊敬的开发者对它赞不绝口。

一年后，这个实验变成了一个初创项目，我们拥有了一个已经帮助了来自全世界的数以千计的开发者的令人难以置信的工具。我们的服务器每天处理来自 700 万台设备的超过 200GB 的数据。

在使用 Go 一年之后，我们想要分享我们将一个小小的实验变成处理百万日志的生产服务器的一些想法和经验。

### Go 生态系统

公司中没有人有使用 Go 的经验。Bugfender 是我们第一次深入这个语言。

学习基本上相当直接的。我们之前在 C/C++/Java/Objective-C/PHP 的经验让我们学习 Go 相当快，并且在几天内就开始开发了。当然会有一些新的和不常见的东西需要学习，包括 GOPATH 还有如何处理包，但这在我们的预期之内。

几天之内，我们意识到即使是一个以简化为设计目的的语言，Go 也是非常强大的。它能够做任何现代编程语言应该能做的事：能够处理 JSON、服务器之间通讯甚至访问数据库也没问题（并且只需要几行代码）。

在构建一个服务器时，你应该首先决定是否使用任何第三方库或者框架。对于 Bugfender，我们决定使用：

#### Martini

[Martini](https://github.com/go-martini/martini) 是一个强大的 Go 的 web 框架。我们开始这个实验时，它是一个很棒的解决方案，至今也是，我们还没遇到任何问题。然而如果我们今天再次开始这个实验的话，我们会选择一个不同的框架，因为 Martini 不在维护了。

我们还试验了 [Iris](https://github.com/kataras/iris)（我们目前的最爱）还有 [Gin](https://github.com/gin-gonic/gin)。Gin 是 Martini 继任者，并且迁移到这上能让我们重用已有的代码。

在过去的一年中，我们意识到 Go 的标准库是非常强大的，你不必依靠一个臃肿的 web 框架来构建一个服务器。最好在特定任务上使用专门的高性能库。

~~Iris 是我们目前最喜欢的，并且将来我们将使用它重写服务来替代 Martini/Gin，但这目前并不是优先的。~~

**修改：** 在讨论了 Iris 的各个方面之后，我们意识到 Iris 或许不是最好的选择。如果我们决定重写我们的 web 组件，我们或许会研究其他的选择，我们欢迎你的建议。

#### Gorm

有些人喜欢 ORM，而有些人则不喜欢。我们决定使用 ORM，更确切地说是 [GORM](https://github.com/jinzhu/gorm)。我们的实现只针对 web 前端，对于日志提取 API 仍然继续使用手工优化的 SQL。在一开始，我们确实很喜欢它，但是随着时间的推移，我们开始发现问题，并且我们很快将它从代码中完全移除，并且使用 [sqlx](https://github.com/jmoiron/sqlx) 这个标准 SQL 库。

GORM 的一个主要问题是 Go 的生态系统。作为一个新语言，自我们开始开发产品以来 Go 已经有很多新版本。在这些新版本中的一些改变并不向后兼容，因此要使用最新的库版本，我们要经常重写已有代码并检查我们为解决版本问题所做的 hack。

上述这两个库是大多数 web 服务的主要组件，因此做一个好的选择很重要，因为将来更改会很困难，并且会影响你服务器的性能。

### 第三方服务

在创建一个实际使用的产品的另外一个重要方面是考虑库、第三方服务和工具的可用性。在这方面，Go 还缺乏成熟度，大多数公司还没有提供 Go 库，因此你或许需要依赖其他人写的不能一直保证质量的库。

比如，对于使用 [Redis](https://github.com/go-redis/redis) 和 [ElasticSearch](https://github.com/olivere/elastic) 有很好的库，但是对于其他服务比如 Mixpanel 或者 Stripe 还没有好的。

我们建议在使用 Go 之前事先检查对于你需要的产品是否有好的库可用。

我们在 Go 的包管理系统上也遇到了很多问题。它处理版本的方式远没有达到最好，并且在过去的一年中，我们在不同的团队成员之间使用同一个库的不同版本上遇到了很多问题。然而，最近要归功于 Go 新支持的 vendor 包特性，除了 [gopkg.in](http://labix.org/gopkg.in) 服务外，这个问题基本被解决了。

### 开发者工具

![](/data/attachment/album/201706/24/215525vf6x2ifni4i2jwwf.jpg)

由于 Go 是一门相对新的语言，你或许发现相比其他成熟的语言像 Java，它可用的开发工具并不很好。当我们开始 Bugfender 时，使用任何 IDE 都很困难，似乎没有 IDE 支持 Go。但是在过去的一年中，随着 [IntelliJ](https://plugins.jetbrains.com/plugin/5047-go) 和 [Visual Studio Code Go](https://github.com/Microsoft/vscode-go) 插件的引入，这一切改善了很多。

最后看下其他的 Go 工具，调试器并不很好，而分析器甚至更糟，因此有时调试你的代码或者尝试优化它会很困难。

### 前往生产

这确实是 Go 最好的东西之一，如果你想要部署一些东西到生产环境中，你只需要构建你的二进制并发送到服务器中，没有依赖，不需要安装额外的软件，你只需要能在服务器中运行二进制文件就行。

如果你习惯于处理那些需要包管理器或者需要小心你使用的语言解释器的语言，用 Go 工作会感到很高兴。

我们对 Go 的稳定性也很满意，因为服务器似乎从没有崩溃过。我们在发送大量数据给 Go Routines 时遇到过一个问题，但是我们几乎没见到任何崩溃。注意：如果你需要发送大量数据给 Go Routine，你需要小心堆溢出。

如果你对性能感兴趣，我们没法与其他语言相比较，因为我们从零开始使用 Go，但是对于我们处理的数据量，我们感觉性能是非常好的，我们绝对不能如此轻松地使用 PHP 处理同等数量的请求。

### 总结

在过去的一年中，我们对 Go 的感觉起起伏伏。最初我们是兴奋的，但是在实验变成真实的产品后我们开始发现问题。我们几次考虑过用 Java 完全重写，但是目前为止，仍旧使用的是 Go，并且过去的一年中， Go 生态已经有了很大的提升，这简化了我们的工作。

如果你想要使用 Go 构建你的产品，你可以保证它可以工作，但是你确实需要小心一件事：可以雇佣的开发者。硅谷中只有很少的高级 Go 开发者，并且在其他地方寻找也是一件非常困难的任务。

---

via: <https://bugfender.com/one-year-using-go>

作者：[ALEIX VENTAYOL](https://bugfender.com/author/aleixventayol) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


开源硬件起步的 8 个步骤

闲得蛋疼。一个优秀的开源软件拥抱者应该更认真地对待驱动开源软件的硬件。而不是想当然地利用工具在面包板上实现自己头脑风暴中的那些蹩脚想法。你更应该把硬件设计当成一件艺术品来看待。

>
> 制造自己的硬件比以往任何时候都更容易，更便宜。以下是你设计、构建和测试你的第一块板子所需的事情。
>
>
>

![8 ways to get started with open source hardware](/data/attachment/album/201706/25/122938ot2vtlpq6altkexp.jpg "8 ways to get started with open source hardware")

著名的计算机科学家<ruby> 阿伦凯 <rp>  （ </rp> <rt>  Alan Kay </rt> <rp>  ） </rp></ruby>曾经说过：“认真对待软件的人应该制造他们自己的硬件。” 我认为如今就如 同 1982 年他所说的一样。然而，现在和那时之间的不同是硬件变得越来越快、越来越小，最重要的是：更便宜。 现在可以用 5 美元购买一台完整的电脑。

随着大公司降低自己产品的价格，能够生产生产级硬件的制造业生态系统得以增长，这些硬件的成本足够便宜，并且达到了普通人都可以接受的程度。这种可用性以及可负担性正在帮助推动诸如众筹和创客运动之类的事情，但同时它们也让更多的个人能够通过开源硬件参与到开源当中。

>
> 探索开源硬件
>
>
> * [什么是开源硬件？](https://opensource.com/resources/what-open-hardware?src=open_hardware_resources_menu)
> * [什么是树莓派？](https://opensource.com/resources/what-raspberry-pi?src=open_hardware_resources_menu)
> * [什么是 Arduino？](https://opensource.com/resources/what-arduino?src=open_hardware_resources_menu)
>
>
>

开源硬件和非开源硬件有很多区别，但是开源硬件联盟（OSHWA）定义了一个大多数人同意的定义，如果你熟悉开源软件，这不会听上去太奇怪：

>
> “开源硬件（OSHW）是一个指有形的造物：机器、设备或者其它物理东西的术语——其设计向公众发布，任何人可以制造、修改、分发并使用那些造物。”
>
>
>

我们身边已经有很多开源硬件了。你可能没有注意到你在使用的主板实际上可能是开源硬件。从低调而多能的 [Arduino](https://opensource.com/node/20751)，一直到像 [BeagleBone](https://opensource.com/node/35211) 系列和 [C.H.I.P.](https://opensource.com/node/24891) 计算机这样的完整功能的电脑，有很多开源硬件的例子，还有更多的在设计中。

硬件可能很复杂，对初学者而言有时候不太理解为什么设计需要某些东西。但开源硬件使你不仅可以看到工作示例，还可以更改这些设计，或者在你自己的设计中剔除或复制所需的部分，就如复制和粘贴一样简单。

### 我该如何开始？

我们先要指出硬件很“硬”，它很复杂甚至很深奥，你可能用到的工具并不总是最人性化的。任何一个玩微处理器的时间足够长的人都可以向你证实：你会烧坏一些东西，看到神奇的烟雾在某个时刻冒出来。没关系，我们都遇到过，有些人还会反复遭遇，因为我们在做一件事情的前 100 次时都不会得到教训，但不要让这些阻碍你：当做错事情时，你会学到教训，而且你将来还可以将有趣的故事告诉别人。

#### 建模

首先要做的是使用现有的电路板、跳线、面包板以及你要连接的任何设备来建模你想要做的事情。在许多情况下，最简单的事情就是在板上添加更多的 LED，并以新颖的方式让它们闪烁起来。这是一个很好的做出原型的方式，也是一个常见的做法。它看上去并不漂亮，你可能会发现你的线接错了，但这些都是原型 - 你只是想证明硬件可以工作。当硬件不工作时，一定要仔细检查一切，不要害怕寻求帮助 - 有时第二双眼睛会发现你奇怪的接地短路。

#### 设计

当你弄清楚你想要构建的硬件，现在是时候把你的想法从跳线和面包板变成实际的设计了。这时事情会变得让人气馁，但是从小处开始，事情上，可以从熟悉加工和处理这样非常小的地方开始，所以为什么不从制作一块带有 LED 和电池的印刷电路板开始？认真地说，这可能听起来过于简单，但在这里有很多新的基础要了解。

1. **找到一个电子设计自动化（EDA）工具来使用。** 有很多好的开源软件可以选择，但是它们并不总是用户友好的。[Fritzing](http://fritzing.org/home/)、[gEDA](http://www.geda-project.org/) 还有 [KiCad](http://kicad-pcb.org/) 都是开源的，并且其可用性一个比一个好。如果你想要尝试更多的商业软件，那么还有一些其他的选择。Eagle 有个受限的免费版本可供使用，有许多的开源硬件是用它设计的。
2. **在 EDA 工具中设计你的电路板。** 依据你选择的工具，这可能会非常快，或者可能是学习如何设计的很好的练习。这是我建议从小的硬件开始的原因之一。一个带 LED 的电路可以如一块电池、一个电阻、一个 LED 一样简单。电路图非常简单，并且板子也会非常小、非常简单。
3. **为打样而导出设计。** 这与列表中的下一件事情紧密相连，但如果你以前没有这样做过，这也可能是一个令人困惑的过程。当你在导出时，你会有很多细节需要调整，并且需要以某种方式导出以便电路板工厂能确切知道你要做的。
4. **找到一个电路板工厂。** 有许多电路板工厂可以制作你的设计，并且一些比其他更加友好及有帮助。一个特别棒的地方是 [OSH Park](https://oshpark.com/)，这些人非常友好并支持开源硬件。他们也有一个非常扎实的流程来确认你发送给它的就是会被制造的，所以他们值得一试。还有很多其他选择；看看 [PCB Shopper](http://pcbshopper.com/)，它可以让你比较不同实体 PCB 商家的价格、周转时间等等。
5. **等待。** 这或许是在制造你自己的电路板中最难的一部分了，因为它会花费时间将数字部分变成物理产品。计划好两周时间来拿到你的电路板。这是你继续下个项目的绝好时间，买到或确保你当前制造的所有部分都有了，或者随便试试而不要担心。你的第一块电路板是艰难的 - 你现在非常想要，但是保持耐心。
6. **修补并提升。** 一旦拿到你的板子，是时候上电测试了。如果你是以 LED 电路开始，那么它很容易调试，并且你会得到一些可以工作起来的东西。如果你有更复杂的电路，那么需要有条理并且有耐心。有时候电路不工作，并且你需要用你的调试技能来追踪问题。
7. **最后，如果你做的是开源硬件，那就发布它。**\* 我们谈论的是开源硬件，因此确保它包含了一个许可，发布它、共享它，把它放在人们可以看见你所做的地方。你或许会想写一篇博客并提交到如 Hackaday 上面。
8. **最重要的是，玩得开心。** 坦白说，如果你在做一些事但是你不开心，你应该停止这样做。开源硬件可以很有趣，虽然有时是困难而且复杂的。但是不是一切都工作：见鬼，我已经设计了一半的电路不工作；或者我（意外地）在电源和接地之间造成了 12 次短路；这些电路板是双层板：是的。我在这个过程中学到了一些东西：非常多，并且我不会再犯同样的错误。我会做出新的板子，但不是这些。（我会支持并盯着这些板子和它们的错误，悲伤的是，它们不会在我盯着它们时感到良心会痛）。

现在有许多的开源硬件，有许多好的例子从中可以查看、复制、衍生，并且有很多信息使制造硬件变得简单。这就是开源硬件：一个人们制造它们、共享它们的社区，每个人可以制作他们自己的东西并构建他们想要的硬件——而不是他们可以得到的硬件。

（题图：Thomas Hawk on [Flickr](https://www.flickr.com/photos/thomashawk/3048157616/in/photolist-5DmB4E-BzrZ4-5aUXCN-nvBWYa-qbkwAq-fEFeDm-fuZxgC-dufA8D-oi8Npd-b6FiBp-7ChGA3-aSn7xK-7NXMyh-a9bQQr-5NG9W7-agCY7E-4QD9zm-7HLTtj-4uCiHy-bYUUtG). [CC BY-NC 2.0](https://creativecommons.org/licenses/by-nc/2.0/) 。由 Opensource.com 修改）

---

作者简介：

John 'Warthog9' Hawley - John 在 VMWare 的开源项目办公室为上游开源项目工作。在以前的生活中，他曾在 MinnowBoard 开源硬件项目上工作，领导了 kernel.org 的系统管理团队，并在桌面集群变得很酷之前构建了它们。为了乐趣，他构建了多个明星项目，比如一个受欢迎的英国电视节目 K-9 的复制品，在无人机的飞行计算机视觉处理中完成，设计并制作了一堆自己的硬件。

---

via: <https://opensource.com/article/17/5/8-ways-get-started-open-source-hardware>

作者：[John 'Warthog9' Hawley](https://opensource.com/article/17/5/8-ways-get-started-open-source-hardware) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


蚁族：我们用“人”来构建软件

这。。。。。

囧~

快快快，蚁A，拿 Human 来重构代码。

![Coding From Anthill](/data/attachment/album/201706/25/184147ofjkpitwpokx7wpa.png)

用过 Java 的同学大多都用过或听说过 Ant，它是用来构建 Java 项目的一个工具。

那么，在蚁族的世界中，他们（它们？）是不是用“Human（人）”来构建项目呢？

顺便说一句，有四只手（足）真好~

---

via: <http://turnoff.us/geek/ant/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者：[wxy](https://github.com/wxy)

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


Linus Torvalds 说 Linux 仍然惊讶和激励着他

English Skills

![](/data/attachment/album/201706/26/094309dq1alanvvyan7zqp.jpg)

>
> Linus Torvalds 和 VMware 开源负责人 Dirk Hohndel 上周在中国 LinuxCon 上进行了一次“炉边聊天”。
>
>
>

周一，Linus Torvalds 首次来到中国参加[在北京召开的 LinuxCon + ContainerCon + CloudOpen](https://www.lfasiallc.com/linuxcon-containercon-cloudopen-china)。在近 2000 名观众面前，Linus Torvalds 和 VMware 开源负责人 Dirk Hohndel 进行了进行了一次“炉边聊天”，谈及是什么在惊讶和激励着他，以及有志的开源开发者们该如何上手。下面是他们谈话中的一些亮点。

### Linux 开发中有什么令人惊讶的事情?

>
> “我觉得有趣的是我认为已经稳定的代码仍然在不断的得到改进，有些东西我们已经很多年没有碰了，然后有人来改进了它们，或者在我以为根本就不会有人用的东西上提交了 Bug 报告。我们有了新的硬件，开发了新的功能，但是 25 年后，我们仍然有老的、非常基础的东西，并且人们依然在关心和改善着它们。”
>
>
>

### 什么在激励着他

>
> “我真的很喜欢我正在做的事情。我喜欢醒来时有一个在技术上有趣而富有挑战性并且不太紧张的工作，因此我可以长时间的为此工作；或者做一些我感觉我正在做一个真正有影响的事情，做一些不仅仅是对我来说有意义的事情。
>
>
> “我偶尔在工作中休息一下，例如我在 Git 上工作两到三周的时候就开始休息了。但是每次休息的时间比较长我都会感到无聊厌倦。当我出去潜水一周，就想着要回来，我从没有感觉我需要一个更长的假期。”
>
>
>

（LCTT 译注：此处“在 Git 上工作” 是指 Linus 在 Git 版本仓库里面开发 Linux 内核，而非开发 Git 软件——事实上，Linus 在早期开发完 Git 的原型之后，主要的 Git 开发已经有别人接手了，虽然他被称之为 Git 之父。而“潜水”是真的指潜水运动，Linus 喜好玩潜水运动。）

### Linux 的未来领导力

>
> “我们的工作进程不会只是 25 年，我们仍然有非常强大的维护团队。我们常常抱怨我们没有足够的维护者 - 这是真的，我们只有数十名顶级维护者做日常合并的工作，这对于一个开源项目来说是一个非常强大的团队。而且随着这些顶级维护者慢慢变老变胖，我们不断有新人进来。一个新人成长为一个顶级维护者需要几年的时间，因此我不觉得我们应该为 Linux 的下一个 20 年担心。”
>
>
>

### Linux 会被替代吗？

>
> “或许会有一些新的项目将来会并且表明他们比我们做的更好，但是我不担心这个。有很多非常成功的 Linux 的分支（fork），人们不会把它们看作是分支是因为他们很和谐。如果有人想要改变一切并且让内核变得更好，我的感觉是，干吧，证明你自己。我可能觉得那是一个坏主意，但是你可以证明我是错的。”
>
>
>

（LCTT 译注：此处所说的分支，应该是指类似 Android、AGL 等 Linux 分支并没有分裂 Linux 生态，而是彼此补充。）

### 对 Git 的想法

>
> “我对 Git 的广泛传播感到非常的惊讶。显然我非常高兴，它验证了我对分布式开发的看法。然而那时，已经有如此之多的源码版本控制工具，很难再去推出一个新的版本控制系统。我预计它主要限于内核开发 - 因为它是针对我们所做的。”
>
>
> “在刚开始的三到四年里，关于 Git 的抱怨是它如此的与众不同，难以使用。大约五年前，事情发生了改变。有足够多的项目和开发者开始使用 Git ，它变得不再与众不同；人们习惯于使用 Git 。他们开始利用这种开发模式，使用 Git 的安全感，意味着任何东西都不会损坏或者丢失。”
>
>
> “在某些方面，Git 比 Linux 更为人所知。Linux 常常被隐藏起来，例如安卓手机就运行在 Linux 之上，但是你并不知道。但是使用 Git 时，你确切地知道你在使用 Git 。”
>
>
>

### 分支 Linux

>
> “当我坐下来开始写 Git ，一个首要的原则就是你应该能 fork 并且在此基础上做你自己的事情。如果你有友好的 fork（能证明我错了，并且能够改进内核），在这种情况下，人们可以回来说我们实际上改进了内核，这没有什么不好的感觉。我会采纳你的改进并且将其合并进来。这就是为什么你应该鼓励 fork 。你也想让良好的回馈变得很简单。”
>
>
>

### 开源开发者应该如何开始

>
> “于我而言，我总是自我激励，知道自己想要做什么，我从来没有被告知要去做什么。我不确定我的例子是否适合人们效仿。如果你是一个新手程序员，你可以从成千上万的开源项目中找到你所感兴趣的，你可以长期关注这个项目，去了解它的代码，以至于你可以在某个部分的代码上可以成为专家，不需要是整个项目。没有人是整个内核的专家，但是你可以很好地了解其中的一个领域。”
>
>
> “如果你能成为社区的一份子，能提交补丁，那将不仅仅是编程，而是有开源社会方面的意义。你作为一个程序员提升了你自己并且和外界联系了起来。你基本上可以向外展示 - 我做了这些改进，我有能力在我的社区或者工作上走得更远。你不得不花费一定的时间来学习一个项目，但是你将有一个巨大的上升空间 - 不仅仅是从职业方面，而且在你的生活中有一个惊人的项目。”
>
>
>

---

via: <https://www.linux.com/blog/event/lc3-china/20176/6/linus-torvalds-explains-how-linux-still-surprises-and-motivates-him>

作者：[Linux 基金会](https://www.linux.com/users/lfadmin) 译者：[rieonke](https://github.com/rieonke) 校对：[wxy](https://github.com/wxy)

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


ps_mem：一个用于精确报告 Linux 核心内存用量的简单 Python 脚本

Summary: ps_mem 是一个可以帮助我们精确获取 Linux 中各个程序核心内存使用情况的简单 python 脚本。这个工具和其它的区别在于其精确显示核心内存使用情况。

有点意思。

![](/data/attachment/album/201706/26/165617wobmm87558zh2obd.jpg)

[ps\_mem](https://github.com/pixelb/ps_mem) 是一个可以帮助我们精确获取 Linux 中各个程序核心内存使用情况的简单 python 脚本。虽然在 Linux 上有很多可用于查看内存使用情况的工具，比如 `free`、`vmstat`、`smem`、`top` 等，但这个工具和其它的区别在于其精确显示核心内存使用情况。

它会分别计算一个程序私有内存总量和共享内存总量，并以更准确的方式给出了总的内存使用量。很明显的，它将帮助大家知道系统中哪个程序正在占用更多的内存。

你可以通过包管理器、`pip` 、或直接运行 `ps_mem.py` 脚本等多种方式来安装 `ps_mem` 工具。需要注意的是：需要有 root 权限。

另外，推荐阅读以下内存工具：

* [free – 一个在 Linux 上查看内存用量统计（可用和已用）的标准工具](http://www.2daygeek.com/free-command-to-check-memory-usage-statistics-in-linux/)
* [smem – Linux 内存报告/统计工具](http://www.2daygeek.com/smem-linux-memory-usage-statistics-reporting-tool/)
* [vmstat – 一个好用的用于虚拟内存统计的标准工具](http://www.2daygeek.com/linux-vmstat-command-examples-tool-report-virtual-memory-statistics/)

### 通过包管理器安装 ps\_mem

基于 RHEL 的系统默认仓库就包含 ps\_mem 工具，所以我们可以简单地通过包管理器进行安装。

对于 RHEL/CentOS ，使用 [yum 包管理器](http://www.2daygeek.com/yum-command-examples/) 安装 `ps_mem` 包：

```
$ sudo yum install ps_mem

```

对于Fedora ，使用 [dnf 包管理器](http://www.2daygeek.com/dnf-command-examples/) 安装 ps\_mem 包：

```
$ sudo dnf install ps_mem

```

对于 Arch Linux ，使用 [pacman 包管理器](http://www.2daygeek.com/pacman-command-examples/) 安装 ps\_mem 包：

```
$ sudo pacman -S ps_mem

```

### 通过 pip 安装 ps\_mem

`pip` 是在 Linux 上推荐使用的一种安装 Python 包的工具。可以使用 `pip` 命令而不是包管理器去获取最新的版本。使用 `pip` 包前，请确保你的系统上已安装过 `pip` 包。否则，先使用发行版本的包管理器安装 `python-pip` 包。

对于基于 Debian 的系统：

```
$ sudo apt-get install python-pip

```

对于基于 RHEL/CentOS 的系统：

```
$ sudo yum install python-pip

```

对于 Fedora

```
$ sudo dnf install python-pip

```

对于 openSUSE

```
$ sudo zypper install python-pip

```

对于基于 Arch Linux 的系统：

```
$ sudo pacman -S python-pip

```

最后，在 Linux 上运行 `pip` 工具安装 `ps_mem` ：

```
$ sudo pip install ps_mem

```

### 直接运行 ps\_mem.py 脚本

我们也可以从开发者 github 页面下载文件，并直接运行 `ps_mem.py` 脚本。

```
$ git clone https://github.com/pixelb/ps_mem.git && cd ps_mem
$ sudo python ps_mem.py

```

### ps\_mem 使用方法

不带任何参数直接运行 `ps_mem` 以精确获取每个程序的的核心内存使用情况。

```
$ sudo ps_mem
 Private  +   Shared  =  RAM used   Program

  1.6 MiB + 438.5 KiB =   2.1 MiB   packagekitd
  1.7 MiB + 498.0 KiB =   2.1 MiB   indicator-application-service
912.0 KiB +   1.3 MiB =   2.2 MiB   window-stack-bridge
  2.0 MiB + 350.5 KiB =   2.3 MiB   gnome-keyring-daemon
  1.8 MiB + 575.0 KiB =   2.3 MiB   whoopsie
  2.4 MiB + 304.5 KiB =   2.7 MiB   systemd-journald
  2.7 MiB + 157.5 KiB =   2.8 MiB   ibus-engine-simple
  2.7 MiB + 182.0 KiB =   2.9 MiB   ibus-dconf
  2.7 MiB + 332.5 KiB =   3.0 MiB   NetworkManager
  3.1 MiB + 169.5 KiB =   3.2 MiB   polkitd
  1.9 MiB +   1.7 MiB =   3.6 MiB   systemd (2)
  3.4 MiB + 172.5 KiB =   3.6 MiB   deja-dup-monitor
  2.9 MiB + 685.0 KiB =   3.6 MiB   zeitgeist-datahub
  2.9 MiB + 848.0 KiB =   3.7 MiB   python2.7
. . . . . .
222.1 MiB +   9.4 MiB = 231.5 MiB   compiz
286.2 MiB +  11.8 MiB = 298.0 MiB   firefox
---------------------------------
                          1.3 GiB
=================================

```

输出中打印出全路径：

```
$ sudo ps_mem -s
 Private  +   Shared  =  RAM used   Program

  3.2 MiB + 951.0 KiB =   4.1 MiB   /usr/lib/evolution/evolution-addressbook-factory
  3.7 MiB + 826.5 KiB =   4.5 MiB   /usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1
  3.7 MiB + 853.0 KiB =   4.6 MiB   /usr/lib/unity-settings-daemon/unity-fallback-mount-helper
. . .  . . .
131.9 MiB + 168.0 KiB = 132.1 MiB   /usr/sbin/mysqld
222.1 MiB +   9.4 MiB = 231.5 MiB   /usr/bin/compiz
286.2 MiB +  11.8 MiB = 298.1 MiB   /usr/lib/firefox/firefox
---------------------------------
                          1.3 GiB
=================================

```

只显示特定的 PID 列表的内存使用情况：

```
$ sudo ps_mem -p 2886,4386
 Private  +   Shared  =  RAM used   Program

 13.5 MiB +   2.9 MiB =  16.4 MiB   gnome-terminal-server
286.2 MiB +  11.8 MiB = 298.0 MiB   firefox
---------------------------------
                        314.4 MiB
=================================

```

每 N 秒打印进程内存。以下命令每 2 秒报告一次内存使用情况：

```
$ sudo ps_mem w 2

```

只显示内存总量：

```
$ sudo ps_mem -t
1329884160

```

---

via: <http://www.2daygeek.com/ps_mem-report-core-memory-usage-accurately-in-linux/>

作者：[2DAYGEEK](http://www.2daygeek.com/author/2daygeek/) 译者：[xllc](https://github.com/xllc) 校对：[wxy](https://github.com/wxy)

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


如何以 LaTeX 创建文档

Summary: LaTeX（读作 lay-tech ）是使用纯文本创建文档的方法，使用与 HTML/CSS 或 Markdown 类似的标记标签进行风格化。 LaTeX 最常用于为学术界（如学术期刊）创建文档。

最大的缺点是不直观，精确与方便不可兼得

Latex的强大之处在于公式编辑，但语法略显晦涩。<br />
对于大部分普通写作需求，Markdown足以应对，而且更加简单易学。

不是 LaTex，是 LaTeX!

谢谢！

>
> 学习以 LaTeX 文本标记语言排版文档
>
>
>

![A introduction to creating documents in LaTeX](/data/attachment/album/201706/26/182603moiwjj5fqxiw7lo9.png "A introduction to creating documents in LaTeX")

LaTeX（读作 `lay-tech` ）是使用纯文本创建文档的方法，使用与 HTML/CSS 或 Markdown 类似的标记标签进行风格化。 LaTeX 最常用于为学术界（如学术期刊）创建文档。 在 LaTeX 中，作者不必直接对文档进行风格化，就像在 Microsoft Word，LibreOffice Writer 或 Apple Pages 等文字处理程序中一样； 而是用纯文本编写代码，这些代码必须经过编译才能生成 PDF 文档。

### 起步

要想使用 LaTeX 来书写文档，首先你必须要安装一个 LaTeX 编辑器。我用的是一款自由开源软件（FOSS），其在学术界也是大受欢迎，叫做 [TexStudio](http://www.texstudio.org/)，它可以运行在 Windows、Unix/Linux、BSD 和 Mac OS X 上。同时你还需要安装一个 **Tex** 排版系统的分发版。因为我都是在 MacOS 上书写文档，所以我使用的分发版是 [MacTex 或 BasicTex](https://www.tug.org/mactex/morepackages.html)。对于 Windows 用户你可以使用 [MiKTex](https://miktex.org/download)，而且 Linux 用户也可以在软件库中找到它。

当你完成了 TexStudio 和某个 LaTeX 的分发版的下载，你就可以开始对你的文档进行排版了。

### 创建你的第一个文档

在这个简短的教程里，我们会创建一个简单的文章，包括一个大标题、一个子标题和两个段落。

在启动 TexStudio 后，保存一份新的文档。 （我将其保存为 `helloworld.tex` ，因为我正在编写本教程的 Hello，World！文档。这是编程的一个传统。）接下来，你需要在你的 `.tex` 文件顶部添加一些样板代码用于指定文档的类型和大小。 这与 HTML5 文件中使用的样板代码类似。

我的代码（如下方）将会把页面大小设置为 A4，文本大小设置为 12pt 。 你可以直接把这些代码放入 TexStudio，并指定你自己的页面大小、字体大小、名称、标题和其他详细信息进行编辑：

```
\documentclass[a4paper,12pt]{article}
\begin{document}
\title{Hello World! My first LaTeX document}
\author{Aaron Cocker}
\date{\today}
\maketitle

content will go here

\end{document}

```

接下来，点击那个大的绿色箭头来编译该文档。就是下方截图中的中间的那个按钮。

![compile button in TexStudio](/data/attachment/album/201706/26/182604f86z83w5ylz5d8d3.png "compile button in TexStudio")

如果这期间发生了什么错误，它将显示在底部的对话框里。

在你编译了这个文档之后，你可以看到它就像一个 PDF 一样显示在程序的 WYSIWYG （所见即所得）预览区域中。记住一旦你修改了代码就必须重新编译，就像我们在 C++ 中编程一样。

通过点击 **Tools > Commands > View PDF** 可以来预览你的文档，如下截图所示。

![Menu to view a PDF](/data/attachment/album/201706/26/182604uv6vtn6a6y76e0lp.png "Menu to view a PDF")

PDF 的输出将会显示在右侧，就像这样：

![Viewing the LaTeX code as PDF](/data/attachment/album/201706/26/182605eo44htqno043uudp.png "Viewing the LaTeX code as PDF")

现在你可以添加一个段落。首先先通过 `\section{}` 命令来写一个子标题。在命令的大括号中输入你的子标题；我写的是 `Introduction`。

```
\section{Introduction}

```

现在你已经给你的段落标记了一个子标题，是时候来写一个段落了。在这个例子中，我使用了 Lipsum 的 [lorem ipsum 生成器](http://www.lipsum.com/feed/html)。要创建一个段落，要使用 `\paragraph{}` 命令， 将你的文本插入到 `\maketitle` 和 `\end{document}` 之间的 `\paragraph{}` 大括号下方，而不是中间。

以下就是我创建的段落的代码：

```
\section{Introduction}

\paragraph{}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras lorem nisi, tincidunt tempus sem nec, elementum feugiat ipsum. Nulla in diam libero. Nunc tristique ex a nibh egestas sollicitudin.

\paragraph{}
Mauris efficitur vitae ex id egestas. Vestibulum ligula felis, pulvinar a posuere id, luctus vitae leo. Sed ac imperdiet orci, non elementum leo. Nullam molestie congue placerat. Phasellus tempor et libero maximus commodo.

```

现在你的文档就已经完成了，你可以将其通过 **Save As** 选项导出并保存为一个 PDF 文档（和大多数程序一样）。

这是一个我已经完成的文档及其相应的代码：

![The finished document with code and the PDF output side-by-side](/data/attachment/album/201706/26/182605dm66cb68a66fvfvz.png "The finished document with code and the PDF output side-by-side")

本教程所有的代码如下所示：

```
\documentclass[a4paper,12pt]{article}
\begin{document}
\title{Hello World! My first LaTeX document}
\author{Aaron Cocker}
\date{\today}
\maketitle

\section{Introduction}

\paragraph{}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras lorem nisi, tincidunt tempus sem nec, elementum feugiat ipsum. Nulla in diam libero. Nunc tristique ex a nibh egestas sollicitudin.

\paragraph{}
Mauris efficitur vitae ex id egestas. Vestibulum ligula felis, pulvinar a posuere id, luctus vitae leo. Sed ac imperdiet orci, non elementum leo. Nullam molestie congue placerat. Phasellus tempor et libero maximus commodo.

\end{document}

```

### 更多

在 LaTeX 撰写的数以千计的优秀资源中，大多数大学制作的指南是可索引的，同时也可以在 Google 搜索中找到。 [普林斯顿大学](https://www.cs.princeton.edu/courses/archive/spr10/cos433/Latex/latex-guide.pdf) 提供了一个很好的扩展教程，为了更深入的了解，普林斯顿大学的导师 Donald Knuth 提供了 [The TexBook](http://www.ctex.org/documents/shredder/src/texbook.pdf)，这是关于 LaTeX 的最好的教程。

（题图 : opensource.com）

---

作者简介：

Aaron Cocker - 一名在英国上大学的计算机学士。我是一个有抱负的数据科学家。我最喜欢的语言是 Python。 你可以随时通过邮箱联系我 : [aaron@aaroncocker.org.uk](mailto:aaron@aaroncocker.org.uk) 或者访问我的个人网站 : <https://aaroncocker.org.uk>

---

via: <https://opensource.com/article/17/6/introduction-latex>

作者：[Aaron Cocker](https://opensource.com/users/aaroncocker) 译者：[chenxinlong](https://github.com/chenxinlong) 校对：[wxy](https://github.com/wxy)

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


使用 Ubuntu Cleaner 为 Ubuntu/LinuxMint 释放空间

![](/data/attachment/album/201706/27/003731rmtkxi66yinoxyy4.jpg)

我们中的大部分人都会经常忘记清理 Linux 系统中的垃圾文件，这会导致我们的系统空间不足。

一般情况下我们不得不按标准的程序来释放 Linux 发行版中的空间（删除发行版缓存、系统日志、应用程序缓存和垃圾邮件），但如果我们每次以手动方式执行相同的过程，那么会花费大量的时间和困难。

在 Linux 的应用程序中，可以使这个任务更容易。今天我们将教你如何使用 Ubuntu Cleaner，它衍生自 Ubuntu Tweak 中的 Janitor 模块。

[Ubuntu Cleaner](http://ubuntu-cleaner.blogspot.in/) 是一个可以简化你清理 Ubuntu 系统的工具。如我们所知道，Ubuntu Tweak 是帮助我们调整 Ubuntu 及其衍生发行版的最佳实用程序之一。但由于它的主要开发人员没有时间维护它，因此已被弃用。

建议阅读：

* [Stacer - Linux 系统优化和监控工具](http://www.2daygeek.com/stacer-linux-system-optimizer-and-monitoring-tool/)
* [BleachBit - 在 Linux 中清理系统的快速而最佳方法](http://www.2daygeek.com/bleachbit-system-cleaner-on-ubuntu-debian-fedora-opensuse-arch-linux-mint/)

因为许多用户在最新版本中仍使用 Ubuntu Tweak 这个工具（因为他们不想离开这个工具），所以 Ubuntu Cleaner 的开发人员从 Ubuntu Tweak 工具中复刻了 janitor 模块，并将这个有用的功能带回 Ubuntu 社区，并命名为 Ubuntu Cleaner。它也成为了 Ubuntu 多年来最受欢迎的实用程序之一。

建议阅读：

* [uCareSystem - 用于 Ubuntu / LinuxMint 的一体化系统更新和维护工具](http://www.2daygeek.com/ucaresystem-system-update-and-maintenance-tool-for-ubuntu-linuxmint/)

我猜所有那些怀念 Ubuntu Tweak 的人都会因为有 Ubuntu Cleaner 而感到高兴，因为它是从 janitor 模块衍生出来的。

Ubuntu Cleaner 将删除 Ubuntu 及其衍生发行版中的以下垃圾文件：

* 应用缓存 (浏览器缓存)
* 缩略图缓存
* Apt 缓存
* 旧的内核
* 包的配置文件
* 不需要的包

### 如何安装 Ubuntu Cleaner

因为开发者提供官方 PPA ，我们可以通过 PPA 轻松地将 Ubuntu Cleaner 安装到 Ubuntu 及其衍生发行版。 Ubuntu Cleaner 目前支持 Ubuntu 14.04 LTS 和 Ubuntu 16.04 LTS。

```
$ sudo add-apt-repository ppa:gerardpuig/ppa
$ sudo apt update
$ sudo apt install ubuntu-cleaner

```

### 如何使用 Ubuntu Cleaner

从主菜单启动 Ubuntu Cleaner ，你可以看到得以下默认界面。

![](/data/attachment/album/201706/27/003743w1f1dd1muibidrlb.png)

勾选你要清理的文件前面的 “复选框”。 最后点击 “清理” 按钮从系统中删除垃圾文件。

![](/data/attachment/album/201706/27/003745ow6szjh333plx6yb.png)

现在我们已经成功清除了系统中的垃圾。

![](/data/attachment/album/201706/27/003747yawztgm97zgla7cc.png)

---

via: <http://www.2daygeek.com/ubuntu-cleaner-system-cleaner-ubuntu-tweak-alternative-janitor/#>

作者：[2DAYGEEK](http://www.2daygeek.com/author/2daygeek/) 译者：[chenxinlong](https://github.com/chenxinlong) 校对：[wxy](https://github.com/wxy)

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


极客漫画：Linus Torvalds 的家

Summary: 只能通过 22 端口（SSH）进入，没窗户，没天窗，没排风扇……

这个笑话很冷

二楼阳台的作用是？

国外的房子（house），很多有个这种阁楼。

No Windows~

只能通过 22 端口（SSH）进入，没窗户，没天窗，没排风扇……

![Linus Torvald's House](/data/attachment/album/201706/27/005330hd8qcgeezn0g1mqq.png)

只能通过 22 端口（SSH）进入，没窗户，没天窗，没排风扇……

---

via: <http://turnoff.us/geek/linus-torvalds-house/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者：[wxy](https://github.com/wxy)

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


极客漫画：Web 服务器中的生活

Summary: Web 服务器总是忙忙碌碌的，从不下班，这似乎比运维工程师还要辛苦。

tes

很有趣

有趣

厉害了

nice

Web 服务器总是忙忙碌碌的，从不下班，这似乎比运维工程师还要辛苦。

![Life in a Web Server](/data/attachment/album/201706/27/015752ynml3afmo52v0wwd.png)

Web 服务器总是忙忙碌碌的，从不下班，这似乎比运维工程师还要辛苦。

每一个线程都在忙着，然而也有不太一样的，比如那个被数据库操作拖在那里的，就只能发呆；而那个被糟糕的代码搞得堆栈溢出的，看起来已经要崩溃了。

处理完请求之后，Web 服务器会给出生成的页面和 Cookie（饼干），如果下次带着这些饼干的编号来，那就可以很快地找到你要的饼干——这就是用饼干保存的会话。

这就是 Tomcat Web 服务器里面的生活。

---

via: <http://turnoff.us/geek/life-in-a-web-server/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者：[wxy](https://github.com/wxy)

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


开发一个 Linux 调试器（二）：断点

![](/data/attachment/album/201706/27/085227v29kih3cftuftnk5.jpg)

在该系列的第一部分，我们写了一个小的进程启动器，作为我们调试器的基础。在这篇博客中，我们会学习在 x86 Linux 上断点是如何工作的，以及如何给我们工具添加设置断点的能力。

### 系列文章索引

随着后面文章的发布，这些链接会逐渐生效。

1. [准备环境](/article-8626-1.html)
2. [断点](https://github.com/TartanLlama/minidbg/tree/tut_break)
3. 寄存器和内存
4. Elves 和 dwarves
5. 源码和信号
6. 源码层逐步执行
7. 源码层断点
8. 调用栈
9. 读取变量 10.之后步骤

### 断点是如何形成的？

有两种类型的断点：硬件和软件。硬件断点通常涉及到设置与体系结构相关的寄存器来为你产生断点，而软件断点则涉及到修改正在执行的代码。在这篇文章中我们只会关注软件断点，因为它们比较简单，而且可以设置任意多断点。在 x86 机器上任一时刻你最多只能有 4 个硬件断点，但是它们能让你在读取或者写入给定地址时触发，而不是只有当代码执行到那里的时候。

我前面说软件断点是通过修改正在执行的代码实现的，那么问题就来了：

* 我们如何修改代码？
* 为了设置断点我们要做什么修改？
* 如何告知调试器？

第一个问题的答案显然是 `ptrace`。我们之前已经用它为我们的程序设置跟踪并继续程序的执行，但我们也可以用它来读或者写内存。

当执行到断点时，我们的更改要让处理器暂停并给程序发送信号。在 x86 机器上这是通过 `int 3` 重写该地址上的指令实现的。x86 机器有个<ruby> 中断向量表 <rp>  （ </rp> <rt>  interrupt vector table </rt> <rp>  ） </rp></ruby>，操作系统能用它来为多种事件注册处理程序，例如页故障、保护故障和无效操作码。它就像是注册错误处理回调函数，但是是在硬件层面的。当处理器执行 `int 3` 指令时，控制权就被传递给断点中断处理器，对于 Linux 来说，就是给进程发送 `SIGTRAP` 信号。你可以在下图中看到这个进程，我们用 `0xcc` 覆盖了 `mov` 指令的第一个字节，它是 `init 3` 的指令代码。

![断点](/data/attachment/album/201706/27/085310slyjyd6m1l01lv25.png)

谜题的最后一个部分是调试器如何被告知中断的。如果你回顾前面的文章，我们可以用 `waitpid` 来监听被发送给被调试的程序的信号。这里我们也可以这样做：设置断点、继续执行程序、调用 `waitpid` 并等待直到发生 `SIGTRAP`。然后就可以通过打印已运行到的源码位置、或改变有图形用户界面的调试器中关注的代码行，将这个断点传达给用户。

### 实现软件断点

我们会实现一个 `breakpoint` 类来表示某个位置的断点，我们可以根据需要启用或者停用该断点。

```
class breakpoint {
public:
    breakpoint(pid_t pid, std::intptr_t addr)
        : m_pid{pid}, m_addr{addr}, m_enabled{false}, m_saved_data{}
    {}

    void enable();
    void disable();

    auto is_enabled() const -> bool { return m_enabled; }
    auto get_address() const -> std::intptr_t { return m_addr; }

private:
    pid_t m_pid;
    std::intptr_t m_addr;
    bool m_enabled;
    uint64_t m_saved_data; //data which used to be at the breakpoint address
};

```

这里的大部分代码都是跟踪状态；真正神奇的地方是 `enable` 和 `disable` 函数。

正如我们上面学到的，我们要用 `int 3` 指令 - 编码为 `0xcc` - 替换当前指定地址的指令。我们还要保存该地址之前的值，以便后面恢复该代码；我们不想忘了执行用户（原来）的代码。

```
void breakpoint::enable() {
    m_saved_data = ptrace(PTRACE_PEEKDATA, m_pid, m_addr, nullptr);
    uint64_t int3 = 0xcc;
    uint64_t data_with_int3 = ((m_saved_data & ~0xff) | int3); //set bottom byte to 0xcc
    ptrace(PTRACE_POKEDATA, m_pid, m_addr, data_with_int3);

    m_enabled = true;
}

```

`PTRACE_PEEKDATA` 请求告知 `ptrace` 如何读取被跟踪进程的内存。我们给它一个进程 ID 和一个地址，然后它返回给我们该地址当前的 64 位内容。 `(m_saved_data & ~0xff)` 把这个数据的低位字节置零，然后我们用它和我们的 `int 3` 指令按位或（`OR`）来设置断点。最后我们通过 `PTRACE_POKEDATA` 用我们的新数据覆盖那部分内存来设置断点。

`disable` 的实现比较简单，我们只需要恢复用 `0xcc` 所覆盖的原始数据。

```
void breakpoint::disable() {
    ptrace(PTRACE_POKEDATA, m_pid, m_addr, m_saved_data);
    m_enabled = false;
}

```

### 在调试器中增加断点

为了支持通过用户界面设置断点，我们要在 debugger 类修改三个地方：

1. 给 `debugger` 添加断点存储数据结构
2. 添加 `set_breakpoint_at_address` 函数
3. 给我们的 `handle_command` 函数添加 `break` 命令

我会将我的断点保存到 `std::unordered_map<std::intptr_t, breakpoint>` 结构，以便能简单快速地判断一个给定的地址是否有断点，如果有的话，取回该 breakpoint 对象。

```
class debugger {
    //...
    void set_breakpoint_at_address(std::intptr_t addr);
    //...
private:
    //...
    std::unordered_map<std::intptr_t,breakpoint> m_breakpoints;
}

```

在 `set_breakpoint_at_address` 函数中我们会新建一个 breakpoint 对象，启用它，把它添加到数据结构里，并给用户打印一条信息。如果你喜欢的话，你可以重构所有的输出信息，从而你可以将调试器作为库或者命令行工具使用，为了简便，我把它们都整合到了一起。

```
void debugger::set_breakpoint_at_address(std::intptr_t addr) {
    std::cout << "Set breakpoint at address 0x" << std::hex << addr << std::endl;
    breakpoint bp {m_pid, addr};
    bp.enable();
    m_breakpoints[addr] = bp;
}

```

现在我们会在我们的命令处理程序中增加对我们新函数的调用。

```
void debugger::handle_command(const std::string& line) {
    auto args = split(line,' ');
    auto command = args[0];

    if (is_prefix(command, "cont")) {
        continue_execution();
    }
    else if(is_prefix(command, "break")) {
        std::string addr {args[1], 2}; //naively assume that the user has written 0xADDRESS
        set_breakpoint_at_address(std::stol(addr, 0, 16));
    }
    else {
        std::cerr << "Unknown command\n";
    }
}

```

我删除了字符串中的前两个字符并对结果调用 `std::stol`，你也可以让该解析更健壮一些。`std::stol` 可以将字符串按照所给基数转化为整数。

### 从断点继续执行

如果你尝试这样做，你可能会发现，如果你从断点处继续执行，不会发生任何事情。这是因为断点仍然在内存中，因此一直被重复命中。简单的解决办法就是停用这个断点、运行到下一步、再次启用这个断点、然后继续执行。不过我们还需要更改程序计数器，指回到断点前面，这部分内容会留到下一篇关于操作寄存器的文章中介绍。

### 测试它

当然，如果你不知道要在哪个地址设置，那么在某些地址设置断点并非很有用。后面我们会学习如何在函数名或者代码行设置断点，但现在我们可以通过手动实现。

测试你调试器的简单方法是写一个 hello world 程序，这个程序输出到 `std::err`（为了避免缓存），并在调用输出操作符的地方设置断点。如果你继续执行被调试的程序，执行很可能会停止而不会输出任何东西。然后你可以重启调试器并在调用之后设置一个断点，现在你应该看到成功地输出了消息。

查找地址的一个方法是使用 `objdump`。如果你打开一个终端并执行 `objdump -d <your program>`，然后你应该看到你的程序的反汇编代码。你就可以找到 `main` 函数并定位到你想设置断点的 `call` 指令。例如，我编译了一个 hello world 程序，反汇编它，然后得到了如下的 `main` 的反汇编代码：

```
0000000000400936 <main>:
  400936:   55                      push   %rbp
  400937:   48 89 e5                mov    %rsp,%rbp
  40093a:   be 35 0a 40 00          mov    $0x400a35,%esi
  40093f:   bf 60 10 60 00          mov    $0x601060,%edi
  400944:   e8 d7 fe ff ff          callq  400820 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400949:   b8 00 00 00 00          mov    $0x0,%eax
  40094e:   5d                      pop    %rbp
  40094f:   c3                      retq

```

正如你看到的，要没有输出，我们要在 `0x400944` 设置断点，要看到输出，要在 `0x400949` 设置断点。

### 总结

现在你应该有了一个可以启动程序、允许在内存地址上设置断点的调试器。后面我们会添加读写内存和寄存器的功能。再次说明，如果你有任何问题请在评论框中告诉我。

你可以在[这里](https://github.com/TartanLlama/minidbg/tree/tut_break) 找到该项目的代码。

---

via: <http://blog.tartanllama.xyz/c++/2017/03/24/writing-a-linux-debugger-breakpoints/>

作者：[Simon Brand](http://blog.tartanllama.xyz/) 译者：[ictlyh](https://github.com/ictlyh) 校对：[jasminepeng](https://github.com/jasminepeng)

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


六大标志性的开源形象概览

“Firefox 中的 "fox" 实际上是一只红色的熊猫”Firefox 指的是小熊猫，不是大熊猫。

这是依据原文中 "red panda" 一词， 摘抄于必应词典的解释 “小熊猫（Red Panda），又名红熊猫，也常被称作火狐，也就是很多人喜欢用的浏览器Firefox。Mozilla为用户提供了与小熊猫互动的方法…<br />
”

谢谢！！

![六大标志性的开源形象概览](/data/attachment/album/201706/28/013211usxqlgncmzjl3mpg.png "A look at 6 iconic open source brands")

品牌是营销的重要组成部分。完成了品牌的塑造并形成一定的影响力之后，一个简单的 Logo （比如说耐克旋风一样） 就会成为这个品牌的强大广告。如果你常常在美国各州之间穿梭，你将会看各种描述品牌的标志符号，如麦当劳的<ruby> 金色拱门 <rp>  （ </rp> <rt>  golden arches </rt> <rp>  ） </rp></ruby>。即便是没有任何文字或图像的简单色彩组合也是可以用来作为一个品牌的，比如美国弗吉尼亚理工大学的栗色和橙色，这种独特的色彩结合是很难被认错的。

所以，现在的问题是：品牌对于开源社区是否真的那么重要呢？

对于我和其他很多的人来说，是的，非常重要。开源软件要与付费软件进行竞争，那么它必须要将自己定义为切实可行的替代品。并且，它也必须要让人容易记住以及形成一定程度的影响力。如果某个开源软件项目以一种设计难看的 Logo、糟糕的口号、前后矛盾的信息来表现自己的话，那它就很难引起大众的注意、难以记住和得到广泛使用。

现有很多项目这方面做得很好，我们可以从中寻找灵感和指导方法。以下是我最喜欢的六个开源品牌。

### 六大开源品牌

#### Linux

![Linux's Tux 吉祥物](/data/attachment/album/201706/28/013213rxkm6px1ydzy0a40.png "Linux&#039;s Tux mascot")

这个可爱的 Linux 企鹅叫做 Tux，人们通常将其称为吉祥物，而非 Logo。

Tux 是 Larry Ewing 在 1996 年使用 GIMP 0.54 创建出来的。按 Jeff Ayers 讲述的[故事](https://en.wikipedia.org/wiki/Tux)：自从 Linus Torvalds 1993 年在澳大利亚的某个动物园被一只企鹅咬了一口之后，他就特别的钟爱它们。Torvalds 当时正在为 Linux 寻找一个有趣的形象，他觉得一个饱食后正在休息的胖企鹅是一个不错的选择。Tux 同时也出现在视频游戏和麦片广告中，它甚至还有一个叫做 Gown 的异性同伴。正如 Mac 用户熟知那个被咬了一口的苹果、Windows 用户熟知那个飘动的窗口那样，作为 Linux 用户，你肯定也非常熟悉 Tux。

#### Mozilla

![Mozilla 2017 的新 Logo ](/data/attachment/album/201706/28/013215i1ifxgti1kimx8g8.png "Mozilla new logo 2017")

[Mozilla](https://www.mozilla.org/en-US/) 基金会是一个非营利组织和 [自由软件社区](https://en.wikipedia.org/wiki/Mozilla)。

近期，它完成了[品牌重建行动](https://blog.mozilla.org/opendesign/arrival/)，其创意团队负责人 Tim Murray 这样写道：“该项目的核心就是应让人们更好地理解 Mozilla 自身的目的和商标的需求而生。我们的品牌标识，包括 Logo、口号及其设计，是我们用以传递我们自身的信仰和所做的工作的重要信号。”

以真正的开源方式，Mozilla 邀请所有的人来为项目贡献自己的力量。“数千个电子邮件、数百场会议、几十种理念，以及之后的三轮讨究，我们把自己的想法都分享了出来。”但是，他们仍然遵循指导方针进行，还需要你参与到贡献中来。

#### Firefox

![Firefox logo](/data/attachment/album/201706/28/013217py9dy56llm905lmi.png "Firefox logo")

[Firefox](https://en.wikipedia.org/wiki/Firefox) 是 Mozilla 开发的一款旗舰级软件产品，是一个非常受欢迎的 [web 浏览器](https://en.wikipedia.org/wiki/Web_browser)。

Firefox 中的 "fox" 实际上是一只小熊猫（亦称“<ruby> 红熊猫 <rp>  （ </rp> <rt>  Red Panda </rt> <rp>  ） </rp></ruby>”、“火狐”），这是一种中国本土的像猫一样的真实动物。故事是这样的：Firefox 原本有个 "Phoenix" 的别称，表明它是由 Netscape 浏览器发展而来的。但在经历了 Phoenix 科技的商标起诉之后，它更名为 Mozilla Firebird。然后，Firebird RDMS 项目说它给其自己项目带来了歧义，其名称最终在 2004 年 02 月变更为 Mozilla Firefox。

平面设计师 Steve Garrity 对 Firefox 和 Phoenix 早期的 Logo 作出了批评，在“[品牌化 Mozilla：走向 Mozilla 2.0](http://actsofvolition.com/steven/mozillabranding/)”一文中详细阐述了各种缺陷。所以，Mozilla 邀请 Garrity 来领导更好的品牌化工作。新的形象是由 silverorange 开发出来的，但最终的渲染却是 Jon Hicks 完成的，他同时也为 Camino、MailChimp 和 Opera 进行过品牌化工作。

早在 2013 年，[Jeopardy!](http://www.complex.com/pop-culture/2013/09/firefox-jeopardy-answer) 上边关于询问 Firefox 使用哪个动物做 Logo 的帖子则成了最后的线索。三位回答者都不知道答案就是一个小熊猫，而是回答了 “su”、 “raccoon” 和 “Excel”。

#### GIMP

![Wilber the Gimp logo](/data/attachment/album/201706/28/013219hm8iiebtgrnmimcm.png "Wilber the Gimp logo")

GIMP 的 Logo 是由 Tuomas Kuosmanen 在 1997 年 09 月 25 日创建的 [Wilber the GIMP](https://www.gimp.org/about/ancient_history.html)。

GIMP 是<ruby> GNU 图像处理程序 <rp>  （ </rp> <rt>  GNU Image Manipulation Program </rt> <rp>  ） </rp></ruby>的缩写，主要用于相片修整和图像处理。Wilber 现在已经有了一些配饰，比如 Simon Budig 设计的一顶安全帽、Raphaël Quintet 设计的巫师帽。根据 GIMP 的“[链接到我们](https://www.gimp.org/about/linking.html)” 页面，它高度鼓励人们使用 Wilber，你甚至可以在源代码中的 `/docs/Wilber_Construction_Kit.xcf.gz` 获得 Wilber 的构建素材。

那么，Wilber 到底是那一种生物呢？很显然，这是一个值得热烈讨论的问题。在 [gimper.net](https://gimper.net/threads/what-is-wilber.793/) 上的一个论坛众说纷纭：一种产于北美大草原的<ruby> 小狼 <rp>  （ </rp> <rt>  coyote </rt> <rp>  ） </rp></ruby>、熊猫、狗，或者<ruby> “高飞” <rp>  （ </rp> <rt>  Goofy </rt> <rp>  ） </rp></ruby>的一种衍生形象，仅举几例。而 [GimpChat.com](http://gimpchat.com/viewtopic.php?f=4&t=10265) 上一位叫做 TheWarrior 的用户直接发邮件给 Wilber 的创造者 Kuosmanen，被告知说 “Wilber 是一种独立物种的动物 —— 就叫 ‘GIMP’。什么是 GIMP，这是个玩笑，因为人们一直在问，说它是一只狗、狐狸或者其他什么的就太没意思了。我设计的这一个形象的时候，在我脑袋中并没有特定哪种动物原型。”

#### PostgreSQL

![PostgreSQL logo](/data/attachment/album/201706/28/013221g1ivitsg2jtr0r2h.png "PostgreSQL logo")

正如你所见和熟悉的一样，使用动物头像来做 Logo 非常普遍。

一只名为 [Slonik](http://www.vertabelo.com/blog/notes-from-the-lab/the-history-of-slonik-the-postgresql-elephant-logo) 的大象就是 [PostgreSQL](https://wiki.postgresql.org/wiki/Logo) 的 Logo 的一部分，这是一个开源的关系型数据库管理系统 （RDMS）。Patrycja Dybka 在 Vertabelo 上写过博文，解释了这一名称是由俄语单词的大象（slony）演化而来的。Oleg Bartunov 也说过，这个 Logo 是在一个[邮件讨论](http://www.pgsql.ru/db/mw/msg.html?mid=1238939)中初步形成的。在讨论里，在费城圣约瑟夫大学的 David Yang 建议使用大象：“……但如果你想要一个动物头像的 Logo，那么使用某种大象如何？ 毕竟就像阿加莎·克里斯蒂（侦探小说家 Agatha Christie）说的那样，*大象让人印象深刻*。”

#### VLC 媒体播放器

![VLC logo](/data/attachment/album/201706/28/013223pg2lhhrnvvzrnb8b.png "VLC logo")

该 Logo 不再是动物主题了，而是交通锥筒。

VLC 是一款无处不在的媒体播放器，它神奇地出现在很多人的桌面电脑上，让很多人体验到了开源，即使不知道它是开源的。VLC 是由总部在法国的 VideoLAN 组织所支持的 VideoLAN 项目的一款产品。VideoLAN 源自 1996 年在法国中央理工大学的一个学生项目。根据维基百科的描述，这个交通锥标图标参考了由法国中央理工大学的网络学生协会收集自巴黎街道上的交通锥筒。最初的手绘 Logo 在 2006 年由 Richard Oistad 重新进行了渲染。

一些有趣的花絮：

* Seamus Islwyn 的帖子 “[VLC 中的交通锥表达了哪些含义？](http://www.ehow.com/info_10029162_traffic-cone-mean-vlc.html)” 告诉我们：在十二月的时候，VLC 锥筒会戴着一顶圣诞帽，但在 12 月 31 日它就会消失不见，恢复原样的锥筒。
* 有人说，VLC 的意思是 “<ruby> 非常大的锥筒 <rp>  （ </rp> <rt>  Very Large Cone </rt> <rp>  ） </rp></ruby>” 或者选用它仅仅是为了和法国那些交通锥筒相关联而已。
* “官方” 的故事背景是否准确？在 VLC 的 jean-baptiste Kempf 和用户在 [VideoLAN 论坛](https://forum.videolan.org/viewtopic.php?f=5&t=92513) 上的交流似乎表明，交通锥筒收集说法以及漏斗、建筑区、扩音器和其他一些说法，可能是不正确的。

我们是否完全解答了 VLC 的交通锥筒起源的问题了呢？我个人觉得：那就是 “星期六夜现场” 的尖头外星人。他们就是来自法国的，记得吗？确切地说是来自 Remulak 星球。

**我很期待看到你关于自己喜欢、讨厌以及为它所代表的品牌而倍感激动的那些开源 Logo 的评论。**

（题图：opensource.com）

---

作者简介：

Jeff Macharyas - 他有多年的出版和印刷工作经验，他曾担任过快速印刷、美国观察家、USO 巡逻、今天校园和其他出版物的艺术总监以及项目经理、编辑和发行经理。杰夫持有佛罗里达州立大学的通信信息、罗格斯大学的社会媒体营销研究生证书以及 Utica 学院的网络安全与计算机取证硕士学位。

---

译者简介：

[GHLandy](http://ghlandy.com) —— 另一种生活中，有属于你也适合你的舞台。或许有你狠心放弃的专业，或者不必上妆，不用摆出另外一副面孔。—— 摘自林特特《以自己喜欢的方式过一生》

---

via: <https://opensource.com/article/17/2/six-open-source-brands>

作者：[Jeff Macharyas](https://opensource.com/users/jeffmacharyas) 译者：[GHLandy](https://github.com/GHLandy) 校对：[wxy](https://github.com/wxy)

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


AWS 技术文章特辑

![](/data/attachment/album/201706/28/214618tsjmjpts2s699p2s.jpg)

AWS 作为全球首屈一指的云服务商，无论是在服务上，还是在技术上，均引领了云技术方面的发展。在 AWS 上，有很多前沿技术的应用，我们特地收集整理了一些 AWS 技术方面的精华文章，分享给您。

### 数据库

1. [数据库迁移服务 DMS——手把手教你玩转 MongoDB 到 DynamoDB 之间数据库迁移](https://mp.weixin.qq.com/s/1SLc-7h99OrDjVVmwaAP_w)
2. [让你的数据库流动起来 – 利用 MySQL Binlog 实现流式实时分析架构](https://mp.weixin.qq.com/s/5aiw4phGKwHZkI7eRifs9A)
3. [破解谷堆悖论：轻松搞定 RDS MySQL 到 Redshift 的数据同步](https://mp.weixin.qq.com/s/UY4PLdFRI508RFnEIBjCFQ)
4. [使用 Oracle Data Pump 将数据库迁移到 AWS 的 RDS Oracle 数据库](https://mp.weixin.qq.com/s/x4mP8ssOJ3K5OIvnFK10LA)
5. [使用 DMS 迁移 Oracle 数据库](https://mp.weixin.qq.com/s/76o-JaN3Gg0gT9lG_rZ1MQ)
6. [将 Oracle 数据库迁移到 AWS 云的方法](https://mp.weixin.qq.com/s/obS73TK_g-oKoNs-Yo-iZg)
7. [使用 DMT 工具迁移北京区域的数据库](https://mp.weixin.qq.com/s/hlp1QLGHlJ8KJ3-u7yeseA)
8. [手把手教你调校 AWS PB 级数据仓库](https://mp.weixin.qq.com/s/8CYv_7CtXqAHaeVlrihSmQ)
9. [Amazon DynamoDB 让海量数据管理变为可能](https://mp.weixin.qq.com/s/pk6s8VE_VEjj4wCmkZExcQ)
10. [Mycat：轻松实现百亿级大表分布式存储与秒级并行查询](https://mp.weixin.qq.com/s/Ote_ydlezvRtrEK8HOYMSQ)

### 存储

1. [EBS 新功能：块存储调整超 Easy，24×7不停机！](https://mp.weixin.qq.com/s/MKdUoedQO33nYRgSMYMK1Q)
2. [AWS 文件存储网关初体验](https://mp.weixin.qq.com/s/XVNwckefDlgFu0R_cAQMPg)
3. [利用 S3fs 在 Amazon EC2 Linux 实例上挂载 S3 存储桶](https://mp.weixin.qq.com/s/tgm938pPkkR78Ov1p3dJ-A)
4. [客户端直连 S3 实现分片续传的思路与实践](https://mp.weixin.qq.com/s/yNEr1hiJI2e5TlyMUgLuRA)
5. [如何使用 AWS 命令行分段上传大文件](https://mp.weixin.qq.com/s/fCCWpH9OmGxYD5lNLspk1Q)
6. [乐高君倾情出演：三分钟教会你如何使用 Snowmobile](https://mp.weixin.qq.com/s/7MpoKPPEefT-xcd3JG2w8A)

### 无服务器

1. [深入 Serverless—让Lambda 和 API Gateway支持二进制数据](https://mp.weixin.qq.com/s/oMG-cW-2J0VuLNUBMM3J7Q)
2. [带您玩转 Lambda，轻松构建 Serverless 后台！](https://mp.weixin.qq.com/s/bpajapZkroyrbYjyv6YuCQ)
3. [在 AWS 上构建无服务器的分析系统](https://mp.weixin.qq.com/s/gp5Ngb33MRTtyOr5iP9GMQ)
4. [如何在 1 个小时之内轻松构建一个 Serverless 实时数据分析平台](https://mp.weixin.qq.com/s/0OQ8vfq29awCDcIrL_9qLQ)

### 软件开发

1. [云端开发工具 AWS CodeStar 快速入门](https://mp.weixin.qq.com/s/FqUJJ-hyZr-IU8ao2zEVjw)
2. [分分钟启动 AWS 应用程序开发 | AWS CodeStar 介绍](https://mp.weixin.qq.com/s/pYHuBPvQT64d8hXATBUxuw)
3. [新上线！AWS CodeDeploy 自动部署初相识](https://mp.weixin.qq.com/s/qpVWkD6LcdSv82vAhBTuwg)
4. [AWS Kinesis 的 Javascript 交互方法](https://mp.weixin.qq.com/s/6dPskvAbcX14WwaQnzvkuA)（[上](https://mp.weixin.qq.com/s/6dPskvAbcX14WwaQnzvkuA)，[下](https://mp.weixin.qq.com/s/nTzX8sgHxc43aqnbRQwiPQ)）

### 网络服务

1. [在 VPC 中自建基于 BIND 的 DNS 服务器](https://mp.weixin.qq.com/s/Fvj6tMT8unjRhAKTDe3ANw)
2. [AWS 上 NAT 的那点事](https://mp.weixin.qq.com/s/g0dzyf6lZIDmbNsOLSmZig)
3. [基于 AWS 平台跳板机配置](https://mp.weixin.qq.com/s/sh9brYoQUdkC0YCSbTTyUQ)
4. [使用 Docker 封装 IPSec 网关并实现与 AWS VPC 的动态 VPN 连接](https://mp.weixin.qq.com/s/ZkdgGf4WmN9eHFtyvtFCfw)
5. [大家热聊的 VPC，大咖给你讲清楚](https://mp.weixin.qq.com/s/mQB10w_7z6-gmFgWwrtErQ)
6. [防盗图利器：AWS WAF – Web 应用程序防火墙初体验](http://mp.weixin.qq.com/s/CGe4km_z5E3NIljtJcPWZw)
7. [想了解 Amazon ECS？这篇文章就够了！](https://mp.weixin.qq.com/s/3AaGBHn8OfdKYWA9hLaU9w)
8. [使用 AWS ALB 实现基于主机名的路由分发](https://mp.weixin.qq.com/s/xtGFubplvmzLLFJpMxwsWg)

### 大数据与人工智能

1. [利用 Amazon Redshift 构建新一代数据分析 BI 系统](https://mp.weixin.qq.com/s/_VqGAEerFPL3YvUSBjrmvA)
2. [Redshift 又添新功能：让用户直接查询 S3 中的海量数据而无需复制到本地](https://mp.weixin.qq.com/s/Dm7Gbak3VW9taZOzRkGrRw)
3. [如何使用 Apache Mahout 在 Amazon Elastic MapReduce 上构建推荐系统](http://mp.weixin.qq.com/s/DW9OVoaGNxKP6hOTTNxnaw)
4. [手把手教你使用 Amazon EMR 进行交互式数据查询](https://mp.weixin.qq.com/s/Lb_oMOrlKNTiWg-zG-VB_g)
5. [巧用 Amazon EMR 节省数据分析成本](https://mp.weixin.qq.com/s/eNhNqmB6--t9rmySr97ZbA)
6. [用 50 行代码和人工智能增强 MacOS 功能！](https://mp.weixin.qq.com/s/NuaPzzIYt2VpqNbG_woPyg)
7. [如何在 AWS 上安装使用分布式 TensorFlow](https://mp.weixin.qq.com/s/EzuNVJNPv0VQP91XPIsWrw)
8. [分布式神经网络框架 CaffeOnSpark 在 AWS 上的部署过程](https://mp.weixin.qq.com/s/iqJalr5v0CrKH-IGa_tnGA)
9. [程序员的深度学习入门指南](https://mp.weixin.qq.com/s/MC94MX7kQgR-0RLGMRB2wg)

### 其它

1. [通过 AWS Config 管理 AWS 服务配置](http://mp.weixin.qq.com/s/hod_3dVBsyn5Caa9ZdXObw)
2. [云迁移的 21 个最佳实践](http://mp.weixin.qq.com/s/uTKmjfoReiHwfyZSGhbUAg)
3. [使用 AWS Lambda 和 Amazon DynamoDB 实现 CloudFormation 模板的动态管理](https://mp.weixin.qq.com/s/U-B6OV-kXZVG4vOjr3JEPw)
4. [DAX - DynamoDB 集成全托管的内存缓存，轻松搞定读取负载！](https://mp.weixin.qq.com/s/uRc07jw3t2qUxiy1tLY3bw)
5. [CrowdTangle 经验谈：如何立足 AWS 构建 SaaS 解决方案](https://mp.weixin.qq.com/s/dIzXMid-pMVX2KZRjTMuqA)
6. [如何灵活地调整 Amazon EC2 的 IAM 角色?](https://mp.weixin.qq.com/s/xposBR7maivgC_Ct-nMCoQ)
7. [使用 Amazon CloudFront 签名 URL+S3 实现私有内容发布](https://mp.weixin.qq.com/s/9_o7vSwDP95d8-dGn6xqqQ)（[1](https://mp.weixin.qq.com/s/9_o7vSwDP95d8-dGn6xqqQ)，[2](https://mp.weixin.qq.com/s/fAjYQcO0qKp3eBsJ8ZXDIw)）
8. [管理者如何授权？通过 AWS 目录服务管理 AWS 资源](https://mp.weixin.qq.com/s/KhtAk1SJdzdcbjbktJ3uKw)
9. [AWS Limit Monitoring：书到用时方恨少，资源提限需趁早！](https://mp.weixin.qq.com/s/cXDjyxF69JlKxyQPoYR-hw)
10. [Elastic GPU：更灵活高效的选择](https://mp.weixin.qq.com/s/MB2ugSZXDUiZfDgkKeh5wQ)
11. [全球首创！Amazon EC2 F1 实例权威解读](https://mp.weixin.qq.com/s/Eyql9BTkkP7YWGUnwzzb6Q)
12. [Amazon Polly：你打字，我说话！](https://mp.weixin.qq.com/s/XU8T4iUnATrXIkMlwzrjUg)
13. [Amazon Lex 快速上手](https://mp.weixin.qq.com/s/Tew_jd9FY3r0IBD3jvjR-A)
14. [Amazon Rekognition 快速入门](https://mp.weixin.qq.com/s/-qo4WnlKLJIGPd4NONjOBg)
15. [利用 CloudWatch 搭建无人值守的监控预警平台](https://mp.weixin.qq.com/s/cYcFxEgyoBBkd_zkend3BQ)
16. [一键搞定云端网络环境，让您轻松迁移至 AWS！](https://mp.weixin.qq.com/s/iqOqnEEhilquBA_Ug6eqIA)
17. [CloudFront 常见错误配置及解决方法](https://mp.weixin.qq.com/s/LgYdF3_mTapkE8dBlu5z-g)
18. [CloudWatch Events 监控您应用的安全](https://mp.weixin.qq.com/s/FpEsYTQzuMhD65nCrjr0Jw)
19. [专线直连 AWS 建立混合 IT 环境实务指南](https://mp.weixin.qq.com/s/kbQwcWSk5Lshh7kpc0NaRw)
20. [将 VMware 中的 Ubuntu 12.04 映像导入成 Amazon EC2 AMI](https://mp.weixin.qq.com/s/uH-rX729Fad7K3u-s1ta5Q)
21. [手把手教你在 FPGA 实例上运行“Hello World”](https://mp.weixin.qq.com/s/NkSrIc-90kdULeMvKT0zpA)

---

还想看到更多技术分享，深入了解 AWS 最前沿的技术发展？

现在有机会了！

![](/data/attachment/album/201706/28/213949dbkvbmtyssbaaake.jpg)

![](/data/attachment/album/201706/28/214009ynrds94ffnvdaraq.jpg)

**不要犹豫了，马上[点此免费报名参加](https://www.awssummit.cn/Login/?trackingCode=linux&invitationCode=channel)！**

**7 月 26 日，不要错过。**


pass：一款简单的基于 Linux 命令行的密码管理工具

Summary: pass 是 Linux 上的一个简单的命令行密码管理器，它将密码存储在一个 gpg 加密后的文件里。这些加密后的文件很好地组织按目录结构存放。

![](/data/attachment/album/201706/29/105744x67odqqehemidl14.jpg)

现如今要记住类似 email、银行、社交媒体、在线支付、ftp 等等这么多的密码相信对每一个人来说都是一个巨大的挑战。

由于需求和使用，密码管理器现如今变得非常的流行。在 Linux 中我们可以有很多选择，包括基于 GUI 和基于 CLI 两种。今天我们要讲的是一款基于 CLI 的密码管理器叫做 pass 。

[pass](https://www.passwordstore.org/) 是 Linux 上的一个简单的命令行密码管理器，它将密码存储在一个 `gpg` 加密后的文件里。这些加密后的文件很好地组织按目录结构存放。

所有密码都存在于 `~/.password-store` 中，它提供了添加、编辑、生成和检索密码等简单命令。

* 建议阅读：[KeePass - 存储/安全密码的最佳密码管理工具](http://www.2daygeek.com/keepass-best-linux-password-manager-arch-linux-mint-ubuntu-debian-fedora-opensuse/)

它是一个非常简短和简单的 shell 脚本。 它能够临时将密码放在剪贴板上，并使用 `git` 跟踪密码的修改。

这是一个很小的 shell 脚本，它还使用了少量的默认工具比如 `gnupg`、`tree` 和 `git`，同时还有活跃的社区为它提供 GUI 和扩展。

### 如何在 Linux 中安装 Pass

Pass 可从大多数 Linux 的主要发行版的仓库中获得。 所以，你可以使用你的分布式包管理器来安装它。

对于基于 Debian 的系统，你可以使用 [apt-get](http://www.2daygeek.com/apt-get-apt-cache-command-examples/) 或 [apt](http://www.2daygeek.com/apt-command-examples/) 包管理器命令来安装 pass。

```
$ sudo apt-get install pass

```

对于基于 RHEL/CentOS 的操作系统, 使用 [yum](http://www.2daygeek.com/yum-command-examples/) 包管理器命令来安装它。

```
$ sudo yum install pass

```

Fedora 系统可用 [dnf](http://www.2daygeek.com/dnf-command-examples/) 包管理器命令来安装。

```
$ sudo dnf install pass

```

openSUSE 系统可以用 [zypper](http://www.2daygeek.com/zypper-command-examples/) 包管理器命令来安装。

```
$ sudo zypper in password-store

```

对于基于 Arch Linux 的操作系统用 [pacman](http://www.2daygeek.com/pacman-command-examples/) 包管理器来安装它。

```
$ pacman -S pass

```

### 如何生成 GPG 密钥对

确保你拥有你个人的 GPG 密钥对。如果没有的话，你可以通过在终端中输入以下的命令并安装指导来创建你的 GPG 密钥对。

```
$ gpg --gen-key

```

运行以上的命令以生成 GPG 密钥对时会有一系列的问题询问，谨慎输入问题的答案，其中有一些只要使用默认值即可。

### 初始化密码存储

如果你已经有了 GPG 密钥对，请通过运行以下命令初始化本地密码存储，你可以使用 email-id 或 gpg-id 初始化。

```
$ pass init 2daygeek@gmail.com
mkdir: created directory '/home/magi/.password-store/'
Password store initialized for 2daygeek@gmail.com

```

上述命令将在 `~/.password-store` 目录下创建一个密码存储区。

`pass` 命令提供了简单的语法来管理密码。 我们一个个来看，如何添加、编辑、生成和检索密码。

通过下面的命令检查目录结构树。

```
$ pass
or
$ pass ls
or
$ pass show
Password Store

```

我没有看到任何树型结构，所以我们将根据我们的需求来创建一个。

### 插入一个新的密码信息

我们将通过运行以下命令来保存 gmail 的 id 及其密码。

```
$ pass insert eMail/2daygeek@gmail.com
mkdir: created directory '/home/magi/.password-store/eMail'
Enter password for eMail/2daygeek@gmail.com:
Retype password for eMail/2daygeek@gmail.com:

```

执行重复操作，直到所有的密码插入完成。 比如保存 Facebook 密码。

```
$ pass insert Social/Facebook_2daygeek
mkdir: created directory '/home/magi/.password-store/Social'
Enter password for Social/Facebook_2daygeek:
Retype password for Social/Facebook_2daygeek:

```

我们可以列出存储中的所有现有的密码。

```
$ pass show
Password Store
├── 2g
├── Bank
├── eMail
│   ├── 2daygeek@gmail.com
│   └── magesh.maruthamuthu@gmail.com
├── eMail
├── Social
│   ├── Facebook_2daygeek
│   └── Gplus_2daygeek
├── Social
└── Sudha
    └── sudha21.magesh@gmail.com

```

### 显示已有密码

运行以下命令从密码存储中检索密码信息，它会询问你输入密码以解锁。

![](/data/attachment/album/201706/29/105810iuyorruhv8duthtz.png)

```
$ pass eMail/2daygeek@gmail.com
*******

```

### 在剪贴板中复制密码

要直接将密码直接复制到剪贴板上，而不是在终端上输入，请使用以下更安全的命令，它会在 45 秒后自动清除密码。

```
$ pass -c eMail/magesh.maruthamuthu@gmail.com
Copied eMail/magesh.maruthamuthu@gmail.com to clipboard. Will clear in 45 seconds.

```

### 生成一个新密码

如果你想生成一些比较难以猜测的密码用于代替原有的奇怪密码，可以通过其内部的 `pwgen` 功能来实现。

```
$ pass generate eMail/2daygeek@gmail.com 15
An entry already exists for eMail/2daygeek@gmail.com. Overwrite it? [y/N] y
The generated password for eMail/2daygeek@gmail.com is:
y!NZ<%T)5Iwym_S

```

生成没有符号的密码。

```
$ pass generate eMail/2daygeek@gmail.com 15 -n
An entry already exists for eMail/2daygeek@gmail.com. Overwrite it? [y/N] y
The generated password for eMail/2daygeek@gmail.com is:
TP9ACLyzUZUwBwO

```

### 编辑现有的密码

使用编辑器插入新密码或编辑现有密码。 当你运行下面的命令时，将会在包含密码的文本编辑器中打开文件 `/dev/shm/pass.wUyGth1Hv0rnh/6kOBG-eMail-2daygeek@gmail.com.txt`。 只需在其中添加新密码，然后保存并退出即可。

```
$ pass edit eMail/2daygeek@gmail.com

File: /dev/shm/pass.wUyGth1Hv0rnh/6kOBG-eMail-2daygeek@gmail.com.txt
TP9ACLyzUZUwBwO

```

### 移除密码

删除现有密码。 它将从 `~/.password-store` 中删除包含 `.gpg` 的条目。

```
$ pass rm eMail/2daygeek@gmail.com
Are you sure you would like to delete eMail/2daygeek@gmail.com? [y/N] y
removed '/home/magi/.password-store/eMail/2daygeek@gmail.com.gpg'

```

### 多选项功能

要保存详细信息，如 URL、用户名、密码、引脚等信息，可以使用以下格式。 首先确保你要将第一项设置为密码，因为它用于在使用剪贴板选项时将第一行复制为密码，以及后续行中的附加信息。

```
$ pass insert eMail/2daygeek@gmail.com -m
Enter contents of eMail/2daygeek@gmail.com and press Ctrl+D when finished:

H3$%hbhYT
URL : http://www.2daygeek.com
Info : Linux Tips & Tricks
Ftp User : 2g

```

 （题图：Pixabay， CC0）

---

via: <http://www.2daygeek.com/pass-command-line-password-manager-linux/>

作者：[2DAYGEEK](http://www.2daygeek.com/author/2daygeek/) 译者：[chenxinlong](https://github.com/chenxinlong) 校对：[wxy](https://github.com/wxy)

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


Powerline：Vim 和 Bash 中的一个强大状态栏插件

Summary: Powerline 是 vim、zsh、bash、tmux、IPython、Awesome、bar、fish、lemonbar、pdb、rc、shell、tcsh、wm、i3 和 Qtil 中的一个状态栏插件。它给程序提供了状态栏，并使程序更好看。它用 Python 写成。

在vim那几张图暴露了，powline在不同字体下很不稳定，很多字体都有对不齐的问题，会上下错位几个像素

嗯，powerline 的字体问题是它最麻烦的地方，其实这篇写的过于简陋了，可以本篇相关的几篇，powerline 的字体安装和配置是个大问题。当然，配置好了就很爽了。

![](/data/attachment/album/201706/29/113131dqpqahdfjm9o8hq8.png)

[Powerline](https://github.com/powerline/powerline) 是 vim、zsh、bash、tmux、IPython、Awesome、bar、fish、lemonbar、pdb、rc、shell、tcsh、wm、i3 和 Qtil 中的一个状态栏插件。它给程序提供了状态栏，并使程序更好看。它用 Python 写成。

它是可扩展的并且功能丰富，它用 Python 写成，非常轻便不需要任何第三方的依赖，只需要一个 Python 解释器。

它的稳定以及可测试的代码库经过完整的测试，并且在 Python 2.6+ 和 Python 3 中工作良好。

最初该状态栏只在 vim 中可用，随后项目进化为许多 Linux 程序如 zsh、bash、tmux、IPython、Awesome、i3 和 Qtil 提供状态栏。

其配置以及配色方案用 JSON 写成。它是一种标准简易的文件格式，可以让用户配置 Powerline 支持的程序。

快速并且轻量级，支持守护进程可以提供更好的性能。

### 安装预先要求

确保你的系统有下面预先要求的包。如果没有，在安装 powerline 之前先安装它们。

对于 Debian 用户，使用 [APT 包管理器](http://www.2daygeek.com/apt-command-examples/)或者[Apt-Get 包管理器](http://www.2daygeek.com/apt-get-apt-cache-command-examples/)安装需要的包。

```
$ sudo apt-get install python-pip git

```

对于 openSUSE 用户，使用 [Zypper 包管理器](http://www.2daygeek.com/zypper-command-examples/)安装需要的包。

```
$ sudo zypper install python-pip git

```

对于 Fedora 用户，使用 [dnf 包管理器](http://www.2daygeek.com/dnf-command-examples/)安装需要的包。

```
$ sudo dnf install python-pip git

```

对于 Arch Linux 用户，使用 [pacman 包管理器](http://www.2daygeek.com/pacman-command-examples/)安装需要的包。

```
$ sudo pacman -S python-pip git

```

对于 CentOS/RHEL 用户，使用 [yum 包管理器](http://www.2daygeek.com/yum-command-examples/)安装需要的包。

```
$ sudo yum install python-pip git

```

### 如何在 Linux 中安装 Powerline

在本篇中，我们将向你展示如何安装 Powerline。以及如何在基于 Debian 以及 RHEL 的系统中在 Bash、tumx 和 Vim 中使用。

```
$ sudo pip install git+git://github.com/Lokaltog/powerline

```

找出 powerline 安装位置以便配置程序。

```
$ pip show powerline-status
Name: powerline-status
Version: 2.6.dev9999+git.517f38c566456d65a2170f9bc310e6b4f8112282
Summary: The ultimate statusline/prompt utility.
Home-page: https://github.com/powerline/powerline
Author: Kim Silkebaekken
Author-email: kim.silkebaekken+vim@gmail.com
License: MIT
Location: /usr/lib/python2.7/site-packages
Requires:

```

### 在 Bash Shell 中添加/启用 Powerline

添加下面的行到 `.bashrc` 中，它会默认在基础 shell 中启用 powerline。

```
if [ -f `which powerline-daemon` ]; then
  powerline-daemon -q
  POWERLINE_BASH_CONTINUATION=1
  POWERLINE_BASH_SELECT=1
  . /usr/local/lib/python2.7/site-packages/powerline/bindings/bash/powerline.sh
fi

```

重新加载 `.bashrc` 文件使得 powerline 在当前窗口中立即生效。

```
$ source ~/.bashrc

```

![](/data/attachment/album/201706/29/113139gwj5jastckk65emo.png)

### 在 tmux 中添加/启用 Powerline

tmux 是最好的终端仿真程序之一，它提供多窗口以及状态栏，但是相比 powerline 的状态栏看上去不那么好。添加下面的的行到 `.tmux.conf` 中，它会默认在 tmux 中启用 powerline。如果你没有找到 `.tmux.conf` 文件，那么创建一个新的。

```
# vi ~/.tmuc.conf

source "/usr/local/lib/python2.7/site-packages/powerline/bindings/tmux/powerline.conf"

```

![](/data/attachment/album/201706/29/113141ionppiipino8pjsi.png)

### 在 Vim 中添加/启用 Powerline

vim 是管理员最爱的文本编辑器之一。添加下面的行到 `.vimrc` 中，启用 powerline 使 vim 更加强大。注意，在 vim 7.x 中，你可能不会在系统中发现 .vimrc 文件，因此不必担心，创建一个新的文件，并添加下面行。

```
# vi ~/.vimrc

set  rtp+=/usr/local/lib/python2.7/site-packages/powerline/bindings/vim/
set laststatus=2
set t_Co=256

```

![](/data/attachment/album/201706/29/113142uurqtxxwtgax2ci8.png)

![](/data/attachment/album/201706/29/113144hl7qy5jsqnv7y9yl.png)

---

via: <http://www.2daygeek.com/powerline-adds-powerful-statusline-to-vim-bash-tumx-in-ubuntu-fedora-debian-arch-linux-mint/>

作者：[2DAYGEEK](http://www.2daygeek.com/author/2daygeek/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


在 Linux 中使用 shell 脚本自动创建/移除并挂载交换文件

Summary: 今天我发现了一个 Gary Stafford 写的 shell 小脚本（两个 shell 脚本，一个用于创建交换文件，另外一个用于移除交换文件），它可以帮助我们在 Linux 中创建/移除并且自动挂载交换文件。

![](/data/attachment/album/201706/30/061909cfq48cj311388u3f.jpg)

几天前我们写了一篇关于在 Linux 中 3 种创建交换文件的方法，它们是常见的方法，但是需要人工操作。

今天我发现了一个 [Gary Stafford](https://programmaticponderings.com/2013/12/19/scripting-linux-swap-space/) 写的 shell 小脚本（两个 shell 脚本，一个用于创建交换文件，另外一个用于移除交换文件），它可以帮助我们在 Linux 中创建/移除并且自动挂载交换文件。

默认这个脚本创建并挂载 512MB 的交换文件。如果你想要更多的交换空间和不同的文件名，你需要相应地修改脚本。修改脚本不是一件困难的事，因为这是一个容易上手而且很小的脚本。

**推荐阅读：** [Linux 中 3 种简易创建或扩展交换空间的方法](http://www.2daygeek.com/add-extend-increase-swap-space-memory-file-partition-linux/)

### 如何检查当前交换文件大小

使用 [free](http://www.2daygeek.com/free-command-to-check-memory-usage-statistics-in-linux/) 和 `swapon` 命令检查已经存在交换空间。

```
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           2.0G        1.3G        139M         45M        483M        426M
Swap:          2.0G        655M        1.4G

$ swapon --show
NAME      TYPE      SIZE   USED PRIO
/dev/sda5 partition   2G 655.2M   -1

```

上面的输出显示我当前的交换空间是 `2GB`。

### 创建交换文件

创建 `create_swap.sh` 文件并添加下面的内容来自动化交换空间的创建和挂载。

```
$ nano create_swap.sh
#!/bin/sh

# size of swapfile in megabytes
swapsize=1024

# does the swap file already exist?
grep -q "swapfile" /etc/fstab

# if not then create it
if [ $? -ne 0 ]; then
    echo 'swapfile not found. Adding swapfile.'
    fallocate -l ${swapsize}M /swapfile
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile
    echo '/swapfile none swap defaults 0 0' >> /etc/fstab
else
    echo 'swapfile found. No changes made.'
fi

echo '--------------------------------------------'
echo 'Check whether the swap space created or not?'
echo '--------------------------------------------'
swapon --show

```

给文件添加执行权限。

```
$ sudo +x create_swap.sh

```

运行文件来创建和挂载交换文件。

```
$ sudo ./create_swap.sh

swapfile not found. Adding swapfile.
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=d9004261-396a-4321-a45f-9923e3e1328c
--------------------------------------------
Check whether the swap space created or not?
--------------------------------------------
NAME      TYPE       SIZE   USED PRIO
/dev/sda5 partition    2G 954.1M   -1
/swapfile file      1024M     0B   -2

```

你可以看到新的 1024M 的 `swapfile`。重启系统以使用新的交换文件。

### 移除交换文件

如果不再需要交换文件，接着创建 `remove_swap.sh` 文件并添加下面的内容来移除交换文件以及它的 `/etc/fstab` 挂载点。

```
$ nano remove_swap.sh
#!/bin/sh

# does the swap file exist?
grep -q "swapfile" /etc/fstab

# if it does then remove it
if [ $? -eq 0 ]; then
    echo 'swapfile found. Removing swapfile.'
    sed -i '/swapfile/d' /etc/fstab
    echo "3" > /proc/sys/vm/drop_caches
    swapoff -a
    rm -f /swapfile
else
    echo 'No swapfile found. No changes made.'
fi

echo '--------------------------------------------'
echo 'Check whether the swap space removed or not?'
echo '--------------------------------------------'
swapon --show

```

并给文件添加可执行权限。

```
$ sudo +x remove_swap.sh

```

运行脚本来移除并卸载交换文件。

```
$ sudo ./remove_swap.sh

swapfile found. Removing swapfile.
swapoff: /dev/sda5: swapoff failed: Cannot allocate memory
--------------------------------------------
Check whether the swap space removed or not?
--------------------------------------------
NAME      TYPE      SIZE   USED PRIO
/dev/sda5 partition   2G 951.8M   -1

```

---

via: <http://www.2daygeek.com/shell-script-create-add-extend-swap-space-linux/>

作者：[2DAYGEEK](http://www.2daygeek.com/author/2daygeek/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


用 NMAP 探测操作系统

![](/data/attachment/album/201707/01/170757zv6rrxfb2bipcbon.jpg)

有时，能够知道一个网络里的机器的操作系统（OS）是有一定好处的。当你知道一台机器的操作系统后，因为你可以在网上搜索专门针对该系统的安全漏洞，所以入侵系统也会更加容易。当然，安全漏洞通常都会很快被修补，但安全漏洞存在时你需要知道。

对你自己的网络进行扫描以便发现操作系统类型可以帮助你了解黑客将如何侵入你的网络。

### 操作系统探测数据库

NAMP 带有一个数据库，它在你安装 NAMP 的时候就会被安装。这个数据库用于操作系统的探测，但是它不会自动更新。

这个数据库位于 `/usr/share/nmap/nmap-os-db`。进行更新的最简单方式是首先找到数据库的版本号，用文本编辑器打开这个文件，版本号通常位于第二行。我的数据库的第二行是 `# $Id: nmap-os-db 35407 2015-11-10 04:26:26Z dmiller $`，即这个文件的数据库版本是 35407。

要在网上查找一个可更新版本，可以浏览 <https://svn.nmap.org/nmap> ，如图 1 所示：

![Figure 01.jpg](/data/attachment/album/201707/01/170811qqzba28gcabpt8et.jpg)

*图 1*

你可以从图中看到版本号为 36736，与我的系统上的版本号相比，这个版本号似乎是一个更新的版本。为了对更新的操作系统进行准确的操作系统探测，当然需要对这个数据库进行更新。

保留较旧的数据库版本也是一个不错的主意。我当前和版本是 35407，我将在终端执行下面的命令：

```
sudo mv /usr/share/nmap/nmap-os-db /usr/share/nmap/nmap-os-db-35407

```

这个数据库被以包含版本号的方式重命名了，下一步就是从网站上下载新版本的数据库，在终端执行下面命令：

```
cd /usr/share/nmap
sudo su
wget https://svn.nmap.org/nmap/nmap-os-db

```

新的数据库即将开始被下载，但是你应该加上版本号，就像你在图 1 中看到的版本号 36736。使用文本编辑器打开这个数据库，然后在第二行加上版本号。当版本号变化后，你可以更新你的数据库，然后在其中加入版本号，以便在再次检查更新时做好准备。

### 系统探测过程

在我们开始使用实际的命令并执行系统探测之前，我们应该详细介绍扫描过程中将会发生的事情。

会执行五种不同的测试，每种测试由一个或者多个数据包组成，目标系统对每个数据包作出的响应有助于确定操作系统的类型。

五种不同的测试是：

1. <ruby> 序列生成 <rp>  （ </rp> <rt>  Sequence Generation </rt> <rp>  ） </rp></ruby>
2. ICMP 回显
3. TCP <ruby> 显式拥塞通知 <rp>  （ </rp> <rt>  Explicit Congestion Notification </rt> <rp>  ） </rp></ruby>
4. TCP
5. UDP

现在让我们分别看看他们各自在做什么。

**序列生成**

序列生成测试由六个数据包组成，这六个包是每隔 100 毫秒分开发送的，且都是 TCP SYN 包。

每个 TCP SYN 包的结果将有助于 NMAP 确定操作系统的类型。

**ICMP 回显**

两个有着不同设置的 ICMP 请求包被送到目标系统，由此产生的反应将有助于实现验证操作系统类型。

**TCP <ruby> 显式拥塞通知 <rp>  （ </rp> <rt>  Explicit Congestion Notification </rt> <rp>  ） </rp></ruby>**

当生成许多包通过路由器时会导致其负载变大，这称之为拥塞。其结果就是系统会变慢以降低拥堵，以便路由器不会发生丢包。

这个包仅为了得到目标系统的响应而发送。因为不同的操作系统以不同的方式处理这个包，所以返回的特定值可以用来判断操作系统。

**TCP**

在这个测试中会发送六个数据包。

一些带有特定的包设置的包被发送用来到打开的或关闭的端口。结果也将会因为操作系统的不同而不同。

所有 TCP 包都是以如下不同的标志被发送：

1. 无标志
2. SYN、FIN、URG 和 PSH
3. ACK
4. SYN
5. ACK
6. FIN、PSH 和 URG

**UDP**

这个测试由一个被发送给一个关闭的端口的数据包组成。

如果目标系统上的这个端口是关闭的，而且返回一条 ICMP 端口不可达的信息，那么就说明没有防火墙。

### NMAP 操作系统检测命令

现在我们开始实际动手进行系统探测。如果你已经读过一些我写的关于 NMAP 的文章，那么最好不要执行 PING 操作。为了跳过 PING，我们使用参数 `Pn`。为了看到详细的信息，你应该使用 `-v` 参数用于动态显示。为了获取系统的信息，需要使用 `-O` 参数。

为了使命令顺利运行和执行 TCP SYN 扫描，你需要以管理员的身份来执行这个命令。在我的例子中，我将只在一个系统上而不是整个网络上进行扫描，使用的命令是：

```
sudo nmap -v -Pn -O 192.168.0.63

```

扫描的结果如图2所示，扫描显示七个开放的端口。

![Figure 02.jpg](/data/attachment/album/201707/01/170819l0w1qvyuwybxdthk.jpg)

*图 2*

开放的端口是：

1. 21/tcp ftp
2. 22/tcp ssh
3. 111/tcp rpcbind
4. 139/tcp netbios-ssn
5. 445/tcp microsoft-ds
6. 2049/tcp nfs
7. 54045/tcp unknown

系统的 MAC 地址为为：`00:1E:4F:9F:DF:7F`。

后面部分显示系统类型为：

```
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.6
Uptime guess: 0.324 days (since Sun Apr 23 08:43:32 2017)

```

系统当前运行的是 Ubuntu Server 16.04，Linux 内核为 4.8，运行时间猜的较准确。

我在另一个系统了又进行了一次测试，结果如图3所示：

![Figure 03.jpg](/data/attachment/album/201707/01/170827str4db1r7a14laa1.jpg)

*图 3*

这次扫描中开放的端口与上次不同。所猜的系统为 ‘Microsoft Windows 2000|XP’，实际上是 Windows XP sp3。

### 端口嗅探结果

让我们来看看图 2 所示的第一次扫描中在后台发生了什么。

首先 NMAP 执行一次 TCP 隐秘扫描，在本次系统探测实例中以一个如图 4 所示的数据包 2032 开始。

![Figure 04.jpg](/data/attachment/album/201707/01/170840mxlkkzxlo9itp2t0.jpg)

*图 4*

<ruby> 序列生成 <rp>  （ </rp> <rt>  Sequence Generation </rt> <rp>  ） </rp></ruby>开始于数据包 2032/2033，第六个数据包是 2047/2048。注意每个都被发送两次，且每隔 100ms 发送下一个数据包。

发送的 ICMP 数据包是 2050 - 2053，2 个数据包重复一遍，实际上是 4 个数据包。

2056-2057 是 TCP 显式拥塞通知数据包。

对 TCP 的 6 个测试是 2059、2060、2061、2063、2065、2067。

最后的 UDP 测试是 2073。

这些就是用于确定目标系统上操作系统的类型的测试。

我希望这将有助于你理解如何更新 NMAP 系统探测数据库和执行对系统的扫描。请注意，你可以和你不在同一个网络中的系统进行扫描，所以可以对互联网上的任何系统进行扫描。

---

via: <https://www.linux.org/threads/nmap-os-detection.4564/>

作者：[Jarret B](https://www.linux.org/members/jarret-b.29858/) 译者：[zhousiyu325](https://github.com/zhousiyu325) 校对：[wxy](https://github.com/wxy)

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


uCareSystem：Ubuntu/Linux Mint 的一体化系统更新和维护工具

Summary: uCareSystem Core 是一种能够自动执行基本的系统维护活动的轻型实用程序，另一方面它可以通过多种方式减少系统管理员的任务，节省大量时间。它没有任何 GUI，并提供纯粹的命令行界面来执行活动。

![](/data/attachment/album/201707/01/172353kby5o5rmj6nobjyg.jpg)

[uCareSystem Core](https://github.com/cerebrux/uCareSystem) 是一种能够自动执行基本的系统维护活动的轻型实用程序，另一方面它可以通过多种方式减少系统管理员的任务，节省大量时间。它没有任何 GUI，并提供纯粹的命令行界面来执行活动。

Ubuntu 中有几种实用程序来执行系统维护活动。每种工具有它们相应的独特功能和设计。你可以添加一个 cron 任务来自动化这些任务。

uCareSystem Core 会自动刷新发行版仓库、更新可用包列表、卸载包（过期包、孤儿包和旧的 Linux 内核）以及清理取回的包来节省系统磁盘空间。

* 建议阅读：[Stacer - Linux 系统优化器及监控工具](http://www.2daygeek.com/stacer-linux-system-optimizer-and-monitoring-tool/)
* 建议阅读：[BleachBit – 快速及最佳的方式清理你的 Linux 系统](http://www.2daygeek.com/bleachbit-system-cleaner-on-ubuntu-debian-fedora-opensuse-arch-linux-mint/)
* 建议阅读：[用 Ubuntu Cleaner 在 Ubuntu/LinuxMint 中释放一些空间](/article-8642-1.html)

### uCareSystem Core 功能

* 更新包列表（它将刷新包索引）
* 下载及安装更新
* 更新包及系统库到最新版本
* 移除不需要的、过期的和孤儿包。
* 移除旧内核（它为了安全保留当前和之前一个内核）
* 移除不需要的配置文件
* 清理已下载的临时包

### 在 Ubuntu/LinuxMint 中安装 uCareSystem Core

因为开发者提供了自己的 PPA，因此我们可以轻易地通过 PPA 在 Ubuntu/LinuxMint 中安装 uCareSystem Core。

```
$ sudo add-apt-repository ppa:utappia/stable
$ sudo apt update
$ sudo apt install ucaresystem-core

```

我们已经成功安装了 `uCareSystem Core` 包，并且在执行 CareSystem Core 命令之前要了解它是否会节省磁盘空间，使用 `df -h` 命令检查当前磁盘利用率。

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            979M     0  979M   0% /dev
tmpfs           200M  6.4M  194M   4% /run
/dev/sda1        38G   19G   17G  54% /
tmpfs           999M  216K  999M   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           999M     0  999M   0% /sys/fs/cgroup
tmpfs           200M  112K  200M   1% /run/user/1000

```

只需在终端中运行 `ucaresystem-core` 命令，在结束之前它会自动执行而不需要人类交互。

```
$ sudo ucaresystem-core

_______________________________________________________

            uCareSystem Core v3.0
                 ~  ''  ~

 Welcome to all-in-one System Update and maintenance
 assistant app.

 This simple script will automatically
 refresh your packagelist, download and
 install updates (if there are any), remove any old
 kernels, obsolete packages and configuration files
 to free up disk space, without any need of user
 interference.
_______________________________________________________

 uCareSystem Core will start in 5 seconds...
#########################
          Started
#########################

Ign:1 https://wire-app.wire.com/linux/debian stable InRelease
Hit:2 https://wire-app.wire.com/linux/debian stable Release
Hit:4 https://deb.nodesource.com/node_6.x yakkety InRelease
Hit:5 https://repo.skype.com/deb stable InRelease
Hit:6 http://in.archive.ubuntu.com/ubuntu yakkety InRelease
Hit:7 http://archive.canonical.com/ubuntu yakkety InRelease
.
.
.
Removing linux-image-extra-4.8.0-34-generic (4.8.0-34.36) ...
Purging configuration files for linux-image-extra-4.8.0-34-generic (4.8.0-34.36) ...
Removing linux-image-extra-4.8.0-32-generic (4.8.0-32.34) ...
Purging configuration files for linux-image-extra-4.8.0-32-generic (4.8.0-32.34) ...

#####################################
Finished removing unused config files
#####################################

Reading package lists... Done
Building dependency tree
Reading state information... Done
Del tilix 1.5.6-1~webupd8~yakkety1 [449 kB]
Del tilix-common 1.5.6-1~webupd8~yakkety1 [174 kB]
Del libfreetype6 2.6.3-3ubuntu1.2 [336 kB]
Del terminix 1.5.6-1~webupd8~yakkety1 [13.7 kB]

######################################
 Cleaned downloaded temporary packages
######################################

#########################
          Done
#########################

```

我可以看见它如预期那样工作。同样也可以发现大概在`/` 分区节省了 `2GB`。

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            979M     0  979M   0% /dev
tmpfs           200M  6.4M  194M   4% /run
/dev/sda1        38G   18G   19G  49% /
tmpfs           999M  216K  999M   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           999M     0  999M   0% /sys/fs/cgroup
tmpfs           200M  112K  200M   1% /run/user/1000

```

---

via: <http://www.2daygeek.com/ucaresystem-system-update-and-maintenance-tool-for-ubuntu-linuxmint/>

作者：[2DAYGEEK](http://www.2daygeek.com/author/2daygeek/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


Boot Repair Tool： 可以修复与启动相关的大部分问题

Summary: 我们都碰到过启动相关的问题，并且大部分时候都是简单的 GRUB 上的问题。 有时候很多人会觉得、输入一段很长的命令或在论坛中搜索来找到解决方法太麻烦了。今天我要告诉你如何使用一个简单而轻巧的软件来解决大部分的启动相关的问题。这个工具就是著名的 Boot Repair Tool 。

![boot repair tool repair the most boot related problems ](/data/attachment/album/201707/01/193901jmjekuzxwwj6wm4m.jpg)

我们都碰到过启动相关的问题，并且大部分时候都是简单的 **GRUB** 上的问题。 有时候很多人会觉得、输入一段很长的命令或在论坛中搜索来找到解决方法太麻烦了。今天我要告诉你如何使用一个简单而轻巧的软件来解决大部分的启动相关的问题。这个工具就是著名的 **Boot Repair Tool** 。好了，话不多说，让我们开始吧。

### 如何在 Linux 中安装和使用启动修复工具

你需要一个你所安装的操作系统的现场版的 USB 棒或 DVD，这是安装这个应用并使用它的前提条件。 引导到操作系统[17](http://www.linuxandubuntu.com/home/category/distros) 并打开终端并输入以下命令

```
sudo add-apt-repository -y ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair && boot-repair

```

![install boot repair tool in linux](/data/attachment/album/201707/01/193902fouju6xov064pj03.jpg)

在安装结束以后，你可以从应用菜单或或其它你在系统上启动应用的地方启动你的修复工具。

![run boot-repair from apps menu](/data/attachment/album/201707/01/193903zaexszmm7env7ex3.jpg)

你可以在菜单栏中看到 Boot Repair。

![Picture](/data/attachment/album/201707/01/193905iozgxqvxozlqdeeg.jpg)

启动它，它就会开始进行一些扫描操作，我们只要等它自己结束就好了。

![boot repair app menu to repair system](/data/attachment/album/201707/01/193906xyqpvuyj054y3345.jpg)

现在你会看到这个界面，这是基于之前扫描的建议修复。 在底部还可以有一个高级选项，你可以在高级选项里进行各方面的设置。 我建议没有经验的用户使用推荐维修，因为它很简单，在大多数情况下我们都可以这样做。

![apply recommended fixes to fix grub issues](/data/attachment/album/201707/01/193907x4njrshpi2iss0hf.jpg)

选择推荐的更新后，它将开始修复。 等待进一步的处理。

![fix the grub menu using boot repair](/data/attachment/album/201707/01/193907ylxphlspybsywyzr.jpg)

你现在会看到一个指令界面。 现在是轮到我们操作的时候了。打开终端，逐个复制并粘贴其中高亮的命令到终端中。

![download and install grub using the given commands](/data/attachment/album/201707/01/193908kxrxpkwytpp3rtc3.jpg)

命令完成后，你会看到一个上面提及的要求确认的界面。 使用箭头键或 Tab 键选择“Yes”，然后按回车键。 现在在 **启动修复工具** 界面中点击 “forward”。

![install grub menu and kernel to fix boot menu](/data/attachment/album/201707/01/193909vl2tklt75wmnbu5k.jpg)

现在你会看到这个界面。 复制在那里提到的命令，并将其粘贴到终端中，然后按回车并让其执行此操作。 需要一段时间所以请耐心等待，它将下载GRUB、内核或任何修复您的引导所需的内容。

![install grub](/data/attachment/album/201707/01/193910eh39thflmmnkmhcc.jpg)

现在你可能会看到一些选项用于配置安装 GRUB 的位置。 选择“yes”，然后按回车，你会看到上面的界面。使用空格键选择选项和按 TAB 以浏览选项。 选择并安装 GRUB 后，可以关闭终端。 现在在启动修复工具屏幕中选择 “forward” 选项。

![scan for the boot issues](/data/attachment/album/201707/01/193911t783ddwpddjdl7j2.jpg)

现在它会做一些扫描操作，并且会询问你一些需要确认的一些选项。 每个选项都选择是即可。

![fixed boot issues with boot rescue](/data/attachment/album/201707/01/193912uzg99ji9zy997wov.jpg)

它会显示一个成功的确认消息。 如果没有，并且显示失败的消息，则将生成链接。 转到该链接获取更多帮助。

成功后，重启你的电脑。 当你重新启动时，你会看到 GRUB。 现在已成功维修您的电脑。 一切顺利。

### 引导修复的高级技巧

当我的电脑出现双引导启动画面时，我发现在修复时，它无法识别 [安装在另一个分区上的 Windows 7](http://www.linuxandubuntu.com/home/how-to-dual-boot-windows-7-and-ubuntu)。 这里有一个简单的提示来帮你解决这个问题。

打开终端并安装 os-prober。 它很简单，可以在软件中心或通过终端找到。

os-prober 可以帮助您识别安装在 PC 上的其他操作系统。

![install os-prober](/data/attachment/album/201707/01/193913y5p0hs0o5t5tw0lp.jpg)

os-prober 安装完成后，通过输入 `os-prober` 在终端运行它。 如果失败了那么试着用 root 账号运行它。 之后运行`update-grub` 命令。 这就是你可以用于从 GRUB 中启动 Windows 的所需要做的全部。

![upgrade-grub in linux](/data/attachment/album/201707/01/193914q1zmsjlq7t43y34q.jpg)

### 总结

以上就是全部的内容。现在你已经成功地修复了你的 PC。

---

via: <http://www.linuxandubuntu.com/home/boot-repair-tool-repair-the-most-boot-related-problems>

作者：[linuxandubuntu](http://www.linuxandubuntu.com/home/boot-repair-tool-repair-the-most-boot-related-problems) 译者：[chenxinlong](https://github.com/chenxinlong) 校对：[wxy](https://github.com/wxy)

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


安卓编年史（26）：Android Wear

Summary: 2014 年 6 月安卓装备上了新元素：智能手表。谷歌在 2014 的 Google I/O 上发布了“Android Wear”，意图在你的手腕上装备一台小电脑。

![](/data/attachment/album/201707/02/113335x4sc6r24s2c6zooc.jpg)

### Android Wear

![The LG G Watch. One of the first Android Wear devices.](/data/attachment/album/201707/02/113515nxlu6nfplc6pq5e6.png)

2014 年 6 月安卓装备上了新元素：智能手表。谷歌在 2014 的 Google I/O 上发布了“[Android Wear](http://arstechnica.com/gadgets/2014/06/android-wear-review/)”，意图在你的手腕上装备一台小电脑。为[一块 1.6 英寸的屏幕](http://arstechnica.com/gadgets/2014/06/reviewing-android-wears-first-watches-sometimes-promising-often-frustrating/)进行设计意味着需要从头构思整个界面，所以谷歌精简了安卓 4.4 KitKat，并创建出了一个小巧的智能手表操作系统。Android Wear 设备不是独立的计算机。它们依赖于运行着配套 Android Wear 应用的安卓智能手机进行连接，认证，以及应用数据获取。

![ The typical Android Wear home screen.](/data/attachment/album/201707/02/113516ke0zeeqsxeswe3zm.png)

Android Wear 智能手表主要是一个通知机器。有了安卓 4.3 及以上版本内建的新 API，任何手机收到的通知都能同时显示在手表上——无需任何应用支持。通知操作按钮也带到了手表上，让用户可以从手表上与通知进行交互。在手表上清除一条通知会同时在手机上将其清除，用户无需拿出另一台设备就可以管理通知消息。每个手表还带有一个语音命令系统和一个麦克风，让用户可以抬腕唤醒手表，说“OK Google”，并发出一条命令。你还可以通过语音回复信息。手表上甚至还有一个装有原生手表应用的应用抽屉。

![Three Android Wear screens, showing music on the home screen, the voice command system, and a Google Now traffic card.](/data/attachment/album/201707/02/113517wvzdzfs8pphppp8d.png)

主屏幕上显示的自然是时间了，它还允许用户切换无数不同的表盘风格。通知界面采用了卡片风格设计。一个垂直滚动的通知列表会在手表上堆积，包括一些显示天气或交通信息的 Google Now 卡片。向左滑动能够清除一条通知，向右滑动会一次打开一个操作按钮。在主屏幕点击会打开语音命令系统，在哪里你可以激活设置或应用抽屉。除了这些以外最初的 Android Wear 的主屏幕没有多少内容。

![The layout of the OS.](/data/attachment/album/201707/02/113518gitcigqat7itxaaw.png)

2014 年 Android Wear 设备仅仅发售了 720000 部，从那之后我们就没有从软件或硬件上看到多少发展。时至今日，智能手表的销售[一年不如一年](http://www.businesswire.com/news/home/20161024005145/en/Smartwatch-Market-Declines-51.6-Quarter-Platforms-Vendors)，甚至在 [Apple Watch](http://arstechnica.com/apple/2015/05/review-the-absolutely-optional-apple-watch-and-watch-os-1-0/) 发布后，没人能够真正确定他们想要让小腕上计算机做什么。明显这种情况会持续到 2017 年 Android Wear 2.0 发布。从 Moto 360 给市场带来圆形设备以来，我们还没从硬件厂商那边看到一些新玩意。

---

![](/data/attachment/album/201706/24/162535j8ke2nu4ccvw44g9.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron 是 Ars Technica 的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。[@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/27/>

作者：[RON AMADEO](http://arstechnica.com/author/ronamadeo) 译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


安卓编年史（27）：Android 5.0 Lollipop——有史以来最重要的安卓版本

Summary: 2014 年 11 月，谷歌发布了 安卓 5.0 棒棒糖。很多系统更新都被称作“有史以来最大的”，但那些陈词滥调在安卓 5.0 棒棒糖的身上成真了。

![](/data/attachment/album/201707/02/113725eo4u5xrggrxgu45x.jpg)

### Android 5.0 Lollipop——有史以来最重要的安卓版本

![](/data/attachment/album/201707/02/113914nr0m4nw107otaao3.jpg)

2014 年 11 月，谷歌发布了 [安卓 5.0 棒棒糖](http://arstechnica.com/gadgets/2014/11/android-5-0-lollipop-thoroughly-reviewed/)。很多系统更新都被称作“有史以来最大的”，但那些陈词滥调在安卓 5.0 棒棒糖的身上成真了。首先，它改变了安卓发布的方式。谷歌与这个版本的安卓一同开始了“开发者预览”计划，可以以 beta 的形式提前几个月看到新版本。由于版本代号和版本号现在被用作市场营销工具，最终的名称在 beta 期间始终保密，仅以字母指代。在 2014 年的 Google I/O 大会，谷歌宣布了“Android L 开发者预览”。

给开发者（以及全世界）四个月的时间接触学习这个版本肯定是有必要的。安卓 L 包含了大范围的变动，它们在系统中都是首次亮相，直到今天还能感受到这些变动。棒棒糖引入了 Material Design 设计理念，作为修改安卓每个界面的指南。一个新的运行时环境“ART”，它代表着驱动安卓应用引擎的完全革新。谷歌的“OK Google”语音命令系统升级到能在任意界面生效，在一些设备上它甚至可以在设备锁定的时候工作。多用户系统从平板来到了手机上。棒棒糖还铺设了 Android for Work 的基础，这是一个关注企业与个人双重应用的特性。

#### Material Design 给了安卓（以及谷歌的所有产品）一个统一形象

当 Matias Duarte 踏上 I/O 大会的舞台并宣布 Material Design 时，它公布的不仅仅是一个安卓的统一设计蓝图，还是谷歌的所有产品以及第三方应用生态的统一设计蓝图。这个想法是安卓、iOS、Chrome OS，以及 Web 版的谷歌产品，都应该有一致的界面风格、字体，以及行为。它们在不需要在不同尺寸的屏幕上有相同的布局，Material Design 提供了有一致行为的构建元素，它们能够基于屏幕尺寸自适应布局。

Duarte 和他的团队在蜂巢中尝试了“电子”风格审美，以及在果冻豆中的“卡片”主题风格，但 Material Design 最终成了被选中的设计系统，应用到谷歌的所有产品线。Material Design 已经超出了一个用户界面设计指南的概念，成为了谷歌作为一个公司的一致性代表。

Material Design 主要的比喻是“纸和墨”。所有的用户界面是“纸”的片层，漂浮于最底端平面之上。阴影用来提供界面的层次结构——用户界面的每个层在 Z 轴上拥有一个位置，并在其之下的元素上投射一个阴影。这是在安卓 4.1 的 Google Now 中使用的“卡片”风格更清晰的进化版本。“墨”是用来指代谷歌推荐开发者在界面的重要项目上使用的泼色。这个概念也引用了真实世界的物体概念，与 Windows 8 和 iOS 7 带来的反拟物化“不惜一切代价扁平化”的趋势相违。

动画也是一个重点，思想是任何东西都不应该“弹出”到屏幕上。组件应该滑进，缩小，或放大。“纸”表面和真实世界中的纸还有点不同，它们可以缩小，扩展，合并以及增大。为了让动画系统协同图像资源工作，阴影不像之前版本中那样整合进用户界面组件——实际上谷歌创造了一个实时的 3D 阴影系统，这样阴影就能够在这些动画和转换中正确渲染。

![棒棒糖的层状界面和阴影的夸张侧视图。](/data/attachment/album/201707/02/113914weq0qndawnur6nyy.jpg)

为了将 Material Design 带到谷歌的其它地方以及应用生态系统，谷歌创建并持续维护着[一个统一的设计指南](https://design.google.com/resources/)，描述了一切设计的规范。那里有应该与不应该做的，基线、基线网格、色板、堆叠图解、字体、库、布局建议以及更多内容。谷歌甚至开始定期举办[针对设计的会议](https://design.google.com/events/)，来听取设计者的声音以及给他们教学，还成立了 [Material Design 奖项](https://design.google.com/articles/material-design-awards/)。在发布 Material Design 后不久，Duarte 离开了安卓团队并成为了谷歌的 Material Design 总监，创建了一个完全专注于设计的部门。

---

![](/data/attachment/album/201706/24/162535j8ke2nu4ccvw44g9.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron 是 Ars Technica 的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。[@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/27/>

作者：[RON AMADEO](http://arstechnica.com/author/ronamadeo) 译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


为树莓派 3 构建 64 位内核

Summary: 因为树莓派基金会还没有为官方的树莓派系统 Raspbian 提供 64 位版本。然而你可以构建一个，多亏了 Electron752 提供的许多补丁。

我的派装的CentOS,不过也是32位的。

>
> 编辑：在写完这个这篇文章之后，我在树莓派 3 上基于 Debian 开始打造 64 位的系统。你可以[在这里找到](https://github.com/bamarni/pi64)。
>
>
>

**![](/data/attachment/album/201707/02/225856ciizhnzt6l42hhok.jpg)**

**树莓派 3** 配有 Broadcom BCM2837 64 位 ARMv8 四核 Cortex A53 处理器，它是一个 **64 位 CPU**。如果你有一块，运行以下命令可能会让你感到惊讶：

```
uname -a
Linux raspberrypi 4.4.34-v7+ #930 SMP Wed Nov 23 15:20:41 GMT 2016 armv7l GNU/Linux

```

是的，这是一个 **32 位内核**。这是因为树莓派基金会还没有为官方的树莓派系统 Raspbian 提供 64 位版本。然而你可以构建一个，多亏了 [Electron752](https://github.com/Electron752) 提供的许多补丁。

### 构建内核

树莓派基金会维护着[它们自己的 Linux 内核分支](https://github.com/raspberrypi/linux)，它为它们的设备特别裁剪过，同时定期地从上游合并。

我们将会遵照[这个页面](https://www.raspberrypi.org/documentation/linux/kernel/building.md)的指导来**构建一个 64 位内核**。

我们不能使用“本地构建”的方法，因为它需要一块 64 位的树莓派，这个我们明显还没有。因此我们需要**交叉编译**它，**Ubuntu** 是推荐的系统。我个人没有 Ubuntu，因此我在一个有 2 个 CPU 的 Ubuntu 16.04 Digital Ocean 实例上构建，这应该花费我 $0.03。如果你也想这么做，你可以通过[这个链接](https://m.do.co/c/8ef9c5832a9c)得到 $10 的免费额度。或者你可以通过使用 Virtualbox 中的 Ubuntu VM 作为实例。

首先，我们需要一些**构建工具**以及\*\* aarch64 交叉编译器\*\*：

```
apt-get update
apt-get install -y bc build-essential gcc-aarch64-linux-gnu git unzip

```

接着我们可以下载 **Linux 内核源码**：

```
git clone –depth=1 -b rpi-4.8.y https://github.com/raspberrypi/linux.git

```

进入到创建的 git 目录。另外你可以为你的内核添加额外的版本标签，可以通过编辑 `Makefile` 的开始几行完成：

```
VERSION = 4
PATCHLEVEL = 8
SUBLEVEL = 13
EXTRAVERSION = +bilal

```

为了**构建它**，运行下面的命令：

```
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
make -j 3 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

```

第一个应该很快。第二个则会完全不同，我没有精确计时，但是对我来说大概要半个小时。根据你的 CPU 数（nproc \* 1.5）调整 `-j` 标志。

### 选择一个 Linux 发行版

在内核编译的时候，我们可以开始准备它的 Linux 发行版了。在本教程中为了简单我使用 **Raspbian**，即使这是一个只有 32 位的发行版。

>
> 如果你想要一直用 64 位系统，你应该选一个有 aarch64 支持的发行版，Debian 有一个健壮的 [ARM64 移植版](https://wiki.debian.org/Arm64Port)。得到它基本有三种方式：
>
>
> * 下载一个预构建的根文件系统，这很可能会如页面中提到的那样给你一个过期的版本。
> * 如果你熟悉 debootstrap，用它构建你自己的（这回比较棘手，因为它需要一些手工调整，它最初的目的是在已经运行的主机上进行 chroot，而不是为其他机器构建根文件系统）
> * 我建议使用 multistrap，这里有一个很好的教程：<http://free-electrons.com/blog/embdebian-with-multistrap/>
>
>
>

回到 Raspbian，我们现在可以下载官方系统，并开始准备了。

打开一个新的 shell 会话并运行下面的命令：

```
wget -O raspbian.zip https://downloads.raspberrypi.org/raspbian_lite_latest
unzip raspbian.zip

```

我们用下面的命令审查：

```
fdisk -l 2016-11-25-raspbian-jessie-lite.img
Disk 2016-11-25-raspbian-jessie-lite.img: 1.3 GiB, 1390411776 bytes, 2715648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x244b8248

Device Boot Start End Sectors Size Id Type
2016-11-25-raspbian-jessie-lite.img1 8192 137215 129024 63M c W95 FAT32 (LBA)
2016-11-25-raspbian-jessie-lite.img2 137216 2715647 2578432 1.2G 83 Linux

```

我们可以看到它有**两个分区**。第一个是**启动分区**，它主要包含了 bootloader、Linux 内核以及少量配置文件。第二个是**根分区**。

我们可以在我们的文件系统上**挂载这些分区**，从**根分区**开始：

```
mount -o loop,offset=70254592 2016-11-25-raspbian-jessie-lite.img /mnt

```

`offset` 取决于扇区大小（512）：70254592 = 512 \* 137216

接着是**启动分区**：

```
mount -o loop,offset=4194304,sizelimit=66060288 2016-11-25-raspbian-jessie-lite.img /mnt/boot

```

`offset` ：4194304 = 512 \* 8192，`sizelimit`：66060288 = 512 \* 129024 。

树莓派系统现在应该可以在 `/mnt` 中看到了。我们基本要完成了。

### 打包内核

内核编译完成后，最后一步包括**复制 Linux 内核**以及**设备树**到启动分区中：

```
cp arch/arm64/boot/Image /mnt/boot/kernel8.img
cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /mnt/boot/

```

调整 `config.txt` :

```
echo “kernel=kernel8.img” >> /mnt/boot/config.txt

```

安装**内核模块** :

```
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu INSTALL_MOD_PATH=/mnt modules_install
umount /mnt/boot
umount /mnt

```

就是这样了，用于树莓派 3 的\*\* ARM64 Linux 内核\*\*诞生了！

现在你可以压缩镜像，通过 scp 下载下来，并按照标准的步骤放到你的 SD 卡中。

最后你会得到：

```
uname -a
Linux raspberrypi 4.8.13+bilal-v8+ #1 SMP Wed Dec 14 14:09:38 UTC 2016 aarch64 GNU/Linux

```

---

via: <https://devsidestory.com/build-a-64-bit-kernel-for-your-raspberry-pi-3/>

作者：[Bilal Amarni](http://devsidestory.com/about-me) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


开发一个 Linux 调试器（三）：寄存器和内存

![](/data/attachment/album/201707/03/231153g7abc3nedej477u8.jpg)

上一篇博文中我们给调试器添加了一个简单的地址断点。这次，我们将添加读写寄存器和内存的功能，这将使我们能够使用我们的程序计数器、观察状态和改变程序的行为。

### 系列文章索引

随着后面文章的发布，这些链接会逐渐生效。

1. [准备环境](/article-8626-1.html)
2. [断点](/article-8645-1.html)
3. [寄存器和内存](https://blog.tartanllama.xyz/c++/2017/03/31/writing-a-linux-debugger-registers/)
4. [Elves 和 dwarves](https://blog.tartanllama.xyz/c++/2017/04/05/writing-a-linux-debugger-elf-dwarf/)
5. [源码和信号](https://blog.tartanllama.xyz/c++/2017/04/24/writing-a-linux-debugger-source-signal/)
6. [源码级逐步执行](https://blog.tartanllama.xyz/c++/2017/05/06/writing-a-linux-debugger-dwarf-step/)
7. 源码级断点
8. 调用栈展开
9. 读取变量
10. 下一步

### 注册我们的寄存器

在我们真正读取任何寄存器之前，我们需要告诉调试器一些关于我们的目标平台的信息，这里是 x86*64 平台。除了多组通用和专用目的寄存器，x86*64 还提供浮点和向量寄存器。为了简化，我将跳过后两种寄存器，但是你如果喜欢的话也可以选择支持它们。x86\_64 也允许你像访问 32、16 或者 8 位寄存器那样访问一些 64 位寄存器，但我只会介绍 64 位寄存器。由于这些简化，对于每个寄存器我们只需要它的名称、它的 DWARF 寄存器编号以及 `ptrace` 返回结构体中的存储地址。我使用范围枚举引用这些寄存器，然后我列出了一个全局寄存器描述符数组，其中元素顺序和 `ptrace` 中寄存器结构体相同。

```
enum class reg {
    rax, rbx, rcx, rdx,
    rdi, rsi, rbp, rsp,
    r8,  r9,  r10, r11,
    r12, r13, r14, r15,
    rip, rflags,    cs,
    orig_rax, fs_base,
    gs_base,
    fs, gs, ss, ds, es
};

constexpr std::size_t n_registers = 27;

struct reg_descriptor {
    reg r;
    int dwarf_r;
    std::string name;
};

const std::array<reg_descriptor, n_registers> g_register_descriptors {{
    { reg::r15, 15, "r15" },
    { reg::r14, 14, "r14" },
    { reg::r13, 13, "r13" },
    { reg::r12, 12, "r12" },
    { reg::rbp, 6, "rbp" },
    { reg::rbx, 3, "rbx" },
    { reg::r11, 11, "r11" },
    { reg::r10, 10, "r10" },
    { reg::r9, 9, "r9" },
    { reg::r8, 8, "r8" },
    { reg::rax, 0, "rax" },
    { reg::rcx, 2, "rcx" },
    { reg::rdx, 1, "rdx" },
    { reg::rsi, 4, "rsi" },
    { reg::rdi, 5, "rdi" },
    { reg::orig_rax, -1, "orig_rax" },
    { reg::rip, -1, "rip" },
    { reg::cs, 51, "cs" },
    { reg::rflags, 49, "eflags" },
    { reg::rsp, 7, "rsp" },
    { reg::ss, 52, "ss" },
    { reg::fs_base, 58, "fs_base" },
    { reg::gs_base, 59, "gs_base" },
    { reg::ds, 53, "ds" },
    { reg::es, 50, "es" },
    { reg::fs, 54, "fs" },
    { reg::gs, 55, "gs" },
}};

```

如果你想自己看看的话，你通常可以在 `/usr/include/sys/user.h` 找到寄存器数据结构，另外 DWARF 寄存器编号取自 [System V x86\_64 ABI](https://www.uclibc.org/docs/psABI-x86_64.pdf)。

现在我们可以编写一堆函数来和寄存器交互。我们希望可以读取寄存器、写入数据、根据 DWARF 寄存器编号获取值，以及通过名称查找寄存器，反之类似。让我们先从实现 `get_register_value` 开始：

```
uint64_t get_register_value(pid_t pid, reg r) {
    user_regs_struct regs;
    ptrace(PTRACE_GETREGS, pid, nullptr, &regs);
    //...
}

```

`ptrace` 使得我们可以轻易获得我们想要的数据。我们只需要构造一个 `user_regs_struct` 实例并把它和 `PTRACE_GETREGS` 请求传递给 `ptrace`。

现在根据要请求的寄存器，我们要读取 `regs`。我们可以写一个很大的 switch 语句，但由于我们 `g_register_descriptors` 表的布局顺序和 `user_regs_struct` 相同，我们只需要搜索寄存器描述符的索引，然后作为 `uint64_t` 数组访问 `user_regs_struct` 就行。（你也可以重新排序 `reg` 枚举变量，然后使用索引把它们转换为底层类型，但第一次我就使用这种方式编写，它能正常工作，我也就懒得改它了。）

```
        auto it = std::find_if(begin(g_register_descriptors), end(g_register_descriptors),
                               [r](auto&& rd) { return rd.r == r; });

        return *(reinterpret_cast<uint64_t*>(&regs) + (it - begin(g_register_descriptors)));

```

到 `uint64_t` 的转换是安全的，因为 `user_regs_struct` 是一个标准布局类型，但我认为指针算术技术上是<ruby> 未定义的行为 <rt>  undefined behavior </rt></ruby>。当前没有编译器会对此产生警告，我也懒得修改，但是如果你想保持最严格的正确性，那就写一个大的 switch 语句。

`set_register_value` 非常类似，我们只是写入该位置并在最后写回寄存器：

```
void set_register_value(pid_t pid, reg r, uint64_t value) {
    user_regs_struct regs;
    ptrace(PTRACE_GETREGS, pid, nullptr, &regs);
    auto it = std::find_if(begin(g_register_descriptors), end(g_register_descriptors),
                           [r](auto&& rd) { return rd.r == r; });

    *(reinterpret_cast<uint64_t*>(&regs) + (it - begin(g_register_descriptors))) = value;
    ptrace(PTRACE_SETREGS, pid, nullptr, &regs);
}

```

下一步是通过 DWARF 寄存器编号查找。这次我会真正检查一个错误条件以防我们得到一些奇怪的 DWARF 信息。

```
uint64_t get_register_value_from_dwarf_register (pid_t pid, unsigned regnum) {
    auto it = std::find_if(begin(g_register_descriptors), end(g_register_descriptors),
                           [regnum](auto&& rd) { return rd.dwarf_r == regnum; });
    if (it == end(g_register_descriptors)) {
        throw std::out_of_range{"Unknown dwarf register"};
    }

    return get_register_value(pid, it->r);
}

```

就快完成啦，现在我们已经有了寄存器名称查找：

```
std::string get_register_name(reg r) {
    auto it = std::find_if(begin(g_register_descriptors), end(g_register_descriptors),
                           [r](auto&& rd) { return rd.r == r; });
    return it->name;
}

reg get_register_from_name(const std::string& name) {
    auto it = std::find_if(begin(g_register_descriptors), end(g_register_descriptors),
                           [name](auto&& rd) { return rd.name == name; });
    return it->r;
}

```

最后我们会添加一个简单的帮助函数用于导出所有寄存器的内容：

```
void debugger::dump_registers() {
    for (const auto& rd : g_register_descriptors) {
        std::cout << rd.name << " 0x"
                  << std::setfill('0') << std::setw(16) << std::hex << get_register_value(m_pid, rd.r) << std::endl;
    }
}

```

正如你看到的，iostreams 有非常精确的接口用于美观地输出十六进制数据（啊哈哈哈哈哈哈）。如果你喜欢你也可以通过 I/O 操纵器来摆脱这种混乱。

这些已经足够支持我们在调试器接下来的部分轻松地处理寄存器，所以我们现在可以把这些添加到我们的用户界面。

### 显示我们的寄存器

这里我们要做的就是给 `handle_command` 函数添加一个命令。通过下面的代码，用户可以输入 `register read rax`、 `register write rax 0x42` 以及类似的语句。

```
    else if (is_prefix(command, "register")) {
        if (is_prefix(args[1], "dump")) {
            dump_registers();
        }
        else if (is_prefix(args[1], "read")) {
            std::cout << get_register_value(m_pid, get_register_from_name(args[2])) << std::endl;
        }
        else if (is_prefix(args[1], "write")) {
            std::string val {args[3], 2}; //assume 0xVAL
            set_register_value(m_pid, get_register_from_name(args[2]), std::stol(val, 0, 16));
        }
    }

```

### 接下来做什么？

设置断点的时候我们已经读取和写入内存，因此我们只需要添加一些函数用于隐藏 `ptrace` 调用。

```
uint64_t debugger::read_memory(uint64_t address) {
    return ptrace(PTRACE_PEEKDATA, m_pid, address, nullptr);
}

void debugger::write_memory(uint64_t address, uint64_t value) {
    ptrace(PTRACE_POKEDATA, m_pid, address, value);
}

```

你可能想要添加支持一次读取或者写入多个字节，你可以在每次希望读取另一个字节时通过递增地址来实现。如果你需要的话，你也可以使用 [`process_vm_readv` 和 `process_vm_writev`](http://man7.org/linux/man-pages/man2/process_vm_readv.2.html) 或 `/proc/<pid>/mem` 代替 `ptrace`。

现在我们会给我们的用户界面添加命令：

```
    else if(is_prefix(command, "memory")) {
        std::string addr {args[2], 2}; //assume 0xADDRESS

        if (is_prefix(args[1], "read")) {
            std::cout << std::hex << read_memory(std::stol(addr, 0, 16)) << std::endl;
        }
        if (is_prefix(args[1], "write")) {
            std::string val {args[3], 2}; //assume 0xVAL
            write_memory(std::stol(addr, 0, 16), std::stol(val, 0, 16));
        }
    }

```

### 给 `continue_execution` 打补丁

在我们测试我们的更改之前，我们现在可以实现一个更健全的 `continue_execution` 版本。由于我们可以获取程序计数器，我们可以检查我们的断点映射来判断我们是否处于一个断点。如果是的话，我们可以停用断点并在继续之前跳过它。

为了清晰和简洁起见，首先我们要添加一些帮助函数：

```
uint64_t debugger::get_pc() {
    return get_register_value(m_pid, reg::rip);
}

void debugger::set_pc(uint64_t pc) {
    set_register_value(m_pid, reg::rip, pc);
}

```

然后我们可以编写函数来跳过断点：

```
void debugger::step_over_breakpoint() {
    // - 1 because execution will go past the breakpoint
    auto possible_breakpoint_location = get_pc() - 1;

    if (m_breakpoints.count(possible_breakpoint_location)) {
        auto& bp = m_breakpoints[possible_breakpoint_location];

        if (bp.is_enabled()) {
            auto previous_instruction_address = possible_breakpoint_location;
            set_pc(previous_instruction_address);

            bp.disable();
            ptrace(PTRACE_SINGLESTEP, m_pid, nullptr, nullptr);
            wait_for_signal();
            bp.enable();
        }
    }
}

```

首先我们检查当前程序计算器的值是否设置了一个断点。如果有，首先我们把执行返回到断点之前，停用它，跳过原来的指令，再重新启用断点。

`wait_for_signal` 封装了我们常用的 `waitpid` 模式：

```
void debugger::wait_for_signal() {
    int wait_status;
    auto options = 0;
    waitpid(m_pid, &wait_status, options);
}

```

最后我们像下面这样重写 `continue_execution`：

```
void debugger::continue_execution() {
    step_over_breakpoint();
    ptrace(PTRACE_CONT, m_pid, nullptr, nullptr);
    wait_for_signal();
}

```

### 测试效果

现在我们可以读取和修改寄存器了，我们可以对我们的 hello world 程序做一些有意思的更改。类似第一次测试，再次尝试在 `call` 指令处设置断点然后从那里继续执行。你可以看到输出了 `Hello world`。现在是有趣的部分，在输出调用后设一个断点、继续、将 `call` 参数设置代码的地址写入程序计数器（`rip`）并继续。由于程序计数器操纵，你应该再次看到输出了 `Hello world`。为了以防你不确定在哪里设置断点，下面是我上一篇博文中的 `objdump` 输出：

```
0000000000400936 <main>:
  400936:   55                      push   rbp
  400937:   48 89 e5                mov    rbp,rsp
  40093a:   be 35 0a 40 00          mov    esi,0x400a35
  40093f:   bf 60 10 60 00          mov    edi,0x601060
  400944:   e8 d7 fe ff ff          call   400820 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400949:   b8 00 00 00 00          mov    eax,0x0
  40094e:   5d                      pop    rbp
  40094f:   c3                      ret

```

你要将程序计数器移回 `0x40093a` 以便正确设置 `esi` 和 `edi` 寄存器。

在下一篇博客中，我们会第一次接触到 DWARF 信息并给我们的调试器添加一系列逐步调试的功能。之后，我们会有一个功能工具，它能逐步执行代码、在想要的地方设置断点、修改数据以及其它。一如以往，如果你有任何问题请留下你的评论！

你可以在[这里](https://github.com/TartanLlama/minidbg/tree/tut_registers)找到这篇博文的代码。

---

via: <https://blog.tartanllama.xyz/c++/2017/03/31/writing-a-linux-debugger-registers/>

作者：[TartanLlama](https://www.twitter.com/TartanLlama) 译者：[ictlyh](https://github.com/ictlyh) 校对：[jasminepeng](https://github.com/jasminepeng)

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


arm64 服务器中的 Debian armhf 虚拟机

Summary: 在 Collabora 公司，我们所做的许多工作之一就是为客户构建包括 32 位和 64 位 ARM 系统在内的各种架构的 Debian 衍生版。就像 Debian 做的那样，我们的 OBS 系统建立在原生系统而不是仿真器上。

看到这种深度文章没有人瞎逼逼我就放心了。

主要是看不懂，没空瞎逼逼

来自117.136.79.240的 Android Browser|Android 7.0 用户

![](/data/attachment/album/201707/03/234237ijzz96p617j6buff.jpg)

在 Collabora 公司，我们所做的许多工作之一就是为客户构建包括 32 位和 64 位 ARM 系统在内的各种架构的 [Debian](https://debian.org/) 衍生版。就像 Debian 做的那样，我们的 [OBS](http://openbuildservice.org/) 系统建立在原生系统而不是仿真器上。

幸运的是随着几年前 ARM 服务器系统的出现，为这些系统原生构建不再像以前那么痛苦了。对于 32 位的 ARM，我们一直依赖 [Calxeda](https://en.wikipedia.org/wiki/Calxeda) 刀片服务器，然而不幸的是 Calxeda 在不久前淘汰，硬件开始显露其年龄（尽管幸运的是 Debian Stretch 还支持它，因此至少软件还是新的）。

在 64 位 ARM 方面，我们运行在基于 Gigabyte MP30-AR1 的服务器上，该服务器可以运行 32 位的 ARM 代码（与之相反，比如基于 ThunderX 的服务器只能运行 64 位代码）。像这样在它们之上运行 armhf 虚拟机作为<ruby> 从构建服务器 <rp>  （ </rp> <rt>  build slaves </rt> <rp>  ） </rp></ruby>似乎是一个很好的选择，但是设置起来可能会需要更多东西的介入。

第一个陷阱是 Debian 中没有标准的 bootloader 或者 boot 固件来启动 qemu 仿真的 “virt” 设备（我不想使用真实机器的仿真）。这也意味着在启动时客户机内没有任何东西会加载内核，也不会从客户机网络引导，这意味着需要直接的内核引导。

第二个陷阱是当前的 Debian Stretch 的 armhf 内核并不支持 qemu 虚拟机所提供的通用 PCI 主机控制器，这意味着客户机中不会出现存储器和网络。希望这会被尽快解决（[Debian bug 864726](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=864726)），并出现在 Stretch 更新中，那在之前需要使用 bug 报告中附带的补丁的自定义内核，但在这篇文章中我不想进一步说。

高兴的假设我们有一个可用的内核，剩下的挑战是很好地管理直接内核加载。或者更具体地说，如何确保主机启动客户机通过标准 apt 工具安装的内核，而不必在客户机/主机之间复制内核，这本质上归结于客户机将 `/boot` 暴露给主机。我们选择的方案是使用 qemu 的 9pfs 支持来从主机共享一个文件夹，并将其用作客户机的 `/boot`。对于 9p 文件夹，似乎需要 “mapped” 安全模式，因为 “none” 模式对 dpkg 有问题（[Debian bug 864718](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=864718)）。

由于我们使用 libvirt 作为我们的虚拟机管理器，剩下的事情就是如何将它们组合到一起。

第一步是安装系统，基本和平常一样。可以直接引导进入由普通的 Stretch armhf netboot 安装程序提供的 `vmlinuz` 和 `initrd.gz`（下载到如 `/tmp` 中）。 设置整体来说很直接，会有一些小的调整：

* `/srv/armhf-vm-boot` 设置为 9p 共享文件夹（这个应该存在，并且由 libvirt-qemu 拥有），这之后会被用于共享 `/boot`。
* 内核参数中在 `root=` 后面加上 VM 中的 root 分区，根据你的情况调整。
* 镜像文件使用 virtio 总线，这似乎不是默认的。

除了这些调整，最后的示例命令与 virt-install 手册页中的相似。

```
virt-install --name armhf-vm --arch armv7l --memory 512 \
  --disk /srv/armhf-vm.img,bus=virtio
  --filesystem /srv/armhf-vm-boot,virtio-boot,mode=mapped \
  --boot=kernel=/tmp/vmlinuz,initrd=/tmp/initrd.gz,kernel_args="console=ttyAMA0,root=/dev/vda1"

```

按照通常的方式运行安装。到最后安装程序可能会提示它不知道如何安装引导程序，这个没什么问题。只要在结束安装和重启之前，切换到 shell 并以某种方式将目标系统中的 `/boot/vmlinuz` 和 `/boot/initrd.img` 复制到主机中（比如 chroot 进入 `/target` 并在已安装的系统中使用 scp）。 这是必需的，因为安装程序不支持 9p，但是要启动系统，需要 initramfs 以及能够挂载根文件系统的模块，这由已安装的 initramfs 提供。这些完成后，安装就可以完成了。

接下来，引导已安装的系统。调整 libvirt 配置（比如使用 virsh 编辑并调整 xml）来使用从安装程序复制过来的内核以及 initramfs，而不只是使用它提供的。再次启动虚拟机，它应该就能愉快地进入安装的 Debian 系统中了。

要在客户机这一侧完成，`/boot` 应该移动到共享的 9pfs 中，`/boot` 的新 fstab 条目看上去应该这样：

```
virtio-boot /boot  9p trans=virtio,version=9p2000.L,x-systemd.automount 0 0

```

有了这一步，这只是将 `/boot` 中的文件混到新的文件系统里面，并且客户机完事了（确保 `vmlinuz`/`initrd.img` 保持符号链接）。内核可以如常升级，并对主机可见。

这时对于主机端，有另外一个问题需要跨过，由于客户机使用 9p 映射安全模式，客户机的符号链接对主机而言将是普通的包含链接目标的文件。为了解决这个问题，我们在客户机启动前使用 libvirt qemu 的 hook 支持来设置合适的符号链接。作为一个例子，下面是我们最终使用的脚本（`/etc/libvirt/hooks/qemu`）：

```
vm=$1
action=$2
bootdir=/srv/${vm}-boot

if [ ${action} != "prepare" ] ; then
  exit 0
fi

if [ ! -d ${bootdir} ] ; then
  exit 0
fi

ln -sf $(basename $(cat ${bootdir}/vmlinuz))  ${bootdir}/virtio-vmlinuz
ln -sf $(basename $(cat ${bootdir}/initrd.img))  ${bootdir}/virtio-initrd.img

```

有了这个，我们可以简单地定义 libvirt 使用 `/srv/${vm}-boot/virtio-{vmlinuz,initrd.img}` 作为机器的内核 / `initramfs`，并且当 VM 启动时，它会自动获取客户机安装的最新内核 / `initramfs`。

只有最后一个边缘情况了，当从 VM libvirt 重启会让 qemu 处理它而不是重启 qemu。如果这不幸发生的话，意味着重启不会加载新内核。所以现在我们通过配置 libvirt 来解决这个问题，从而在重启时停止虚拟机。由于我们通常只在升级内核（安装）时重启 VM，虽然这有点乏味，但这避免了重启加载的是旧内核 / `initramfs` 而不是预期的。

---

via: <https://www.collabora.com/news-and-blog/blog/2017/06/20/debian-armhf-vm-on-arm64-server/>

作者：[Sjoerd Simons](https://www.collabora.com/news-and-blog/blog/2017/06/20/debian-armhf-vm-on-arm64-server/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


极客漫画： 一场 Java 惊魂之旅

Summary: 周末带着儿子去了一个不一样的迪尼斯乐园——Java 大世界。

好冷

害怕.jpg

周末带着儿子去了一个不一样的迪尼斯乐园——Java 大世界。

![A Java Nightmare](/data/attachment/album/201707/04/010057ba4doaazae468aim.png)

周末带着儿子去了一个不一样的迪尼斯乐园——Java 大世界。

公园的门口，有两个 Java 吉祥物 Duke，只是左边那个好像是戴着发带的女 Duke。看见没有，公园大门最顶部的标志是著名的咖啡杯——基本上是公众所熟知的 Java 语言的形象了，相对来说，Duke 的知名度不如咖啡杯。公园门口的标语上写着“堆”满了乐趣（“堆”，即 heap，是一种 Java 等语言用于操作数据的内存结构）。

驶过道路上的标牌，上面分别写着：

* “麦格王国”，麦格——mageek，可能影射的是 [Majava.A 安全漏洞](https://www.f-secure.com/v-descs/exploit_java_majava_a.shtml)，这是一个攻击 JRE 漏洞的恶意文件，此处嘲讽 Java 的安全缺陷。
* “热点中心”，热点——Hotspot，是 Java 一个较新的虚拟机。
* “极演播室”，极——JEE，即 Java EE，是 J2EE 的一个新名称，面向企业的一种应用框架/标准。

进入公园看到的大型广告牌上写着：只需要写出来——即可运行。这里隐喻 Java 的跨平台特性。

远处的街道上，有大大的 Duke 充气人偶，而孩子手中的气球上画着咖啡杯，这真是一个 Java 的世界啊。

根据指示牌，有通往：

* 小小新世界，“hello world” 是各种编程语言教学中通常学生们接触到的第一个程序例子。
* 拼图馆，拼图——Jigsaw，是 OpenJDK 项目下的一个子项目，旨在为 Java SE 平台设计实现一个标准的模块系统，并应用到该平台和 JDK 中。
* 汤姆猫小岛，汤姆猫——Tomcat，Tomcat 服务器是一个自由开源的 Web 应用服务器，用于 JSP 程序。

孩子兴奋极了，要去那个“神秘阀门”去玩。我觉得也可以去汤姆猫小岛看看，此处用 servlets 指代了服务项目。而 servlet 是一种 Java 应用。

正在这时，广播发出警告，“异常抛出”——Exception Thrown 是 Java 等语言用于处理异常情况的机制。得赶紧疏散，而可怜的娃还不明白发生了什么。跑吧！

结果爸爸被触手怪抓去了——触手怪的下面写着“内存溢出”，一定是因为这个才导致触手怪出现的！

眼看电锯就要切到脑袋上了——啊，吓死我了，原来是又一个 Java 的噩梦啊！

---

via: <http://turnoff.us/geek/a-java-nightmare/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者：[wxy](https://github.com/wxy)

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


极客漫画：Bash on Windows

微软那个子系统很锤子，用了一次就放弃了，个人还是喜欢在Gnu/Linux上用BASH

来自陕西西安的 Chrome Mobile 59.0|Android 7.0 用户

暂时不用，看后续发展吧

改变大家的习惯，这个不容易的。

这就跟windows下开个linux虚拟机差不多，唯一好的就是直接在cmd运行bash，很快进入环境，验证一些想法，比如shell或者命令测试还是可以的。

已经能把lnmp环境跑起来了，虽然还有一些问题，但开发时不用再搭建wnmp环境或者虚拟机跑lnmp环境，更加接近生产环境，应该是一件好事。

强烈要求加入Mac OS。

我还是非常喜欢这个子系统，虽然在一些微妙的地方有点小问题但还不太碍事，从这个东西刚出到现在我也一直在感受这个子系统的完善，不管用git ssh还是scp都特别方便，何况又可以操纵Windows的文件还能用apt安装包，就从方便的角度实在不错，起码我忽然有个想法想验证的时候不用cygwin 不用虚拟机 更不用Xshell 直接打开Bash on Ubuntu on Windows就好了。

前些天装了一台Window10，可以试试这个Bash

windows收集用户信息这个梗一直都在。

感觉并不好用

如果有QQ和微信的Linux 版，我真的就不用windows了。在 windows 下面折腾 docker 很心累最后放弃的路过……

win10下docker很累？hyper-v装上，没法再容易了。windows都不会玩，你确定linux你就玩的很好了？

和开虚拟机不一样的谢谢 bash on Windows里面那个Linux子系统基本上相当于直接搭建在了api上层

来自223.104.176.212的 Chrome Mobile 40.0|Android 6.0 用户

据我所知 QQ 和 微信都有网页版

而且 QQ 也可在 CrossOver 上用..

微信也有人做了 linux 版

https://github.com/geeeeeeeeek/electronic-wechat

以前日子被Windows10折腾得不要不要的，一怒一下换了Linux，结果更加折腾了。。。

折腾过后,<br />
你就会轻松了..

有啊，

![Bash on Windows](/data/attachment/album/201707/04/095610ahb9dz0t65g3b50d.png)

微软发布了 Bash on Windows，旨在吸引开发者使用 Windows 平台。其高级程序经理 Rich Turner [呼吁](/article-7998-1.html) Linux 开发人员放弃 Linux ，转到 Windows 10 上来：“Windows 中的 Linux 子系统将给开发者们提供所有他们在 Linux 开发中必要的工具，而不用丧失 Windows 10 的优势。”

这是诱惑么？这是诱惑么？这是诱惑么？

---

via: <http://turnoff.us/geek/bash-on-windows/>

作者：[Daniel Stori](http://turnoff.us/about/) 译者：[wxy](https://github.com/wxy)

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


Linux 上如何安装并切换最新版本的 Python 3.6

Summary: 如果你安装了 Linux 系统，正在学习 Python 并想要使用最新的版本的话，那么这篇文章就是为你而写的。

为什么不是conda，为什么不是virtualenv呢

一般都选择编译安装！

![](/data/attachment/album/201707/05/130559ns7er7rr7apswawc.jpg)

**Python** 是 Linux 中一种最流行的编程语言。它被写成了各种工具和库。除此之外，Python 在开发者之间很流行因为它非常简单，并且实际很容易掌握。如果你安装了 Linux 系统，正在学习 **Python** 并想要使用最新的版本的话，那么这篇文章就是为你而写的。现在我已经安装好了 Linux Mint 18。默认安装的版本是 2.7 和 3.5。你可以用这个命令检查：

```
$ python -V
$ python2 -V
$ python3 -V

```

安装最新的 Python 3.6 到 Linux 中：

```
$ sudo add-apt-repository ppa:jonathonf/python-3.6
$ sudo apt update
$ sudo apt install python3.6

```

检查已安装的 Python 3.6 版本

```
$ python3.6 -V

```

**请注意**旧版本仍然还在，它仍然可以通过 `python3` 可用，新的版本可以通过命令 `python3.6`。如果你想要默认使用这个版本而不是 3.5 运行所有的程序，这有个工具叫 `update-alternatives`。但是如果你尝试获取可能的列表，我们会得到错误：

![Python 3.6  - install latest version into Linux Mint](/data/attachment/album/201707/05/130610e7hzm8nrlmr9qn77.png)

这是正常的，你首先需要为那个问题设置文件，因为维护者没有设置这个：

```
$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2

```

现在再次查看：

```
$ update-alternatives --list python3

```

![Python 3.6  - install latest version into Linux Mint](/data/attachment/album/201707/05/130611govi7v0ogq0gvu8q.png)

现在我们选择需要的版本并按需切换。对于设置使用配置命令：

```
$ sudo update-alternatives --config python3

```

![Python 3.6  - install latest version into Linux Mint](/data/attachment/album/201707/05/130611zkh4cxco2x0135lh.png)

在提示符中，你需要指定默认使用的编号。

>
> 选择版本时要小心，不要去动 python（python2），只使用我说的 python3，Python 2.7 编写了各种系统工具，如果你尝试用错误的解释器版本运行它们，可能就不会工作。
>
>
>

愿原力与你同在，好运！！！

---

via: <https://mintguide.org/other/794-python-3-6-install-latest-version-into-linux-mint.html>

作者： [Shekin](https://mintguide.org/user/Shekin/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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