From ef9788eeebc3161db2244cbc701bf38a5d50d98a Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 26 Feb 2018 12:27:36 +0800 Subject: [PATCH 001/101] PRF:20180102 Best open source tutorials in 2017.md @zjon --- ...0102 Best open source tutorials in 2017.md | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/translated/tech/20180102 Best open source tutorials in 2017.md b/translated/tech/20180102 Best open source tutorials in 2017.md index 892c7d7a8e..9eca82653f 100644 --- a/translated/tech/20180102 Best open source tutorials in 2017.md +++ b/translated/tech/20180102 Best open source tutorials in 2017.md @@ -1,55 +1,57 @@ -Translating zjon -2017最佳开源教程 +Opensource.com 的 2017 年最佳开源教程 ====== + +2017 年,Opensource.com 发布了一系列用于帮助从初学者到专家的教程。让我们看看哪些最好。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-lead-teacher-learner.png?itok=rMJqBN5G) -一个精心编写的教程是任何软件的官方文档的一个很好的补充。 如果官方文件写得不好,不完整或不存在,它也可能是一个有效的选择。 +精心编写的教程对于任何软件的官方文档来说都是一个很好的补充。如果官方文件写得不好,不完整或根本没有,那么这些教程也可以是个有效的替代品。 -2017、Opensource.com 发布一些有关各种主题的优秀教程。这些教程不只是针对专家们的。我们把他们针对各种技能水平和经验的用户。 +2017 年,Opensource.com 发布一些有关各种主题的优秀教程。这些教程不只是针对专家们的,它们是针对各种技能水平和经验的用户的。 -让我们来看看最好的教程。 +让我们来看看其中最好的教程。 ### 关于代码 -对许多人来说,他们对开源的第一次涉足涉及为一个项目或另一个项目提供代码。你在哪里学习编码或编程?以下两篇文章是很好的起点。 +对许多人来说,他们第一次涉足开源是为一个项目或另一个项目贡献代码。你在哪里学习编码或编程的?以下两篇文章是很好的起点。 -严格来说,VM Brasseur 的[如何开始学习编程][1]是为新手程序员的一个很好的起点,而不是一个教程。它不仅指出了一些有助于你开始学习的优秀资源,而且还提供了了解你的学习方式和如何选择语言的重要建议。 +严格来说,VM Brasseur 的[如何开始学习编程][1]是新手程序员的一个很好的起点,而不是一个教程。它不仅指出了一些有助于你开始学习的优秀资源,而且还提供了了解你的学习方式和如何选择语言的重要建议。 -如果您已经在一个 [IDE][2] 或文本编辑器中记录了几个小时,那么您可能需要学习更多关于编码的不同方法。Fraser Tweedale 的[功能编程的简介][3]很好地引入范式可以应用到许多广泛使用的编程语言。 +如果您已经在一个 [IDE][2] 或文本编辑器中敲击了几个小时,那么您可能需要学习更多关于编码的不同方法。Fraser Tweedale 的[函数式编程简介][3]很好地介绍了可以应用到许多广泛使用的编程语言的范式。 -### 流行的 Linux +### 踏足 Linux -Linux 是开源的典范。它运行了大量的网络,为世界顶级超级计算机提供动力。它让任何人都可以在台式机上使用专有的操作系统。 +Linux 是开源的典范。它运行了大量的 Web 站点,为世界顶级的超级计算机提供了动力。它让任何人都可以替代台式机上的专有操作系统。 -如果你有兴趣深入Linux,这里有三个教程供你参考。 +如果你有兴趣深入 Linux,这里有三个教程供你参考。 -Jason Baker 查看[设置 Linux $PATH 变量][4]。他引导你通过这一“任何Linux初学者的重要技巧”,使您能够将系统指向包含程序和脚本的目录。 +Jason Baker 告诉你[设置 Linux $PATH 变量][4]。他引导你掌握这一“任何 Linux 初学者的重要技巧”,使您能够告知系统包含了程序和脚本的目录。 -拥抱你的核心技师 David Both 指南[建立一个 DNS 域名服务器][5]。他详细地记录了如何设置和运行服务器,包括要编辑的配置文件以及如何编辑它们。 +感谢 David Both 的[建立一个 DNS 域名服务器][5]指南。他详细地记录了如何设置和运行服务器,包括要编辑的配置文件以及如何编辑它们。 -想在你的电脑上更复古一点吗?Jim Hall 告诉你如何[在 Linux 下运行 DOS 程序][6]使用 [FreeDOS][7]和 [qemu][8]。Hall 的文章着重于运行 DOS 生产力工具,但并不全是严肃的——他也谈到了运行他最喜欢的 DOS 游戏。 +想在你的电脑上更复古一点吗?Jim Hall 告诉你如何使用 [FreeDOS][7]和 [qemu][8] [在 Linux 下运行 DOS 程序][6]。Hall 的文章着重于运行 DOS 生产力工具,但并不全是严肃的——他也谈到了运行他最喜欢的 DOS 游戏。 -### 3 个 Pi +### 3 片(篇)树莓派 -廉价的单板机使硬件再次变得有趣,这并不是秘密。不仅如此,它们使更多的人更容易接近,无论他们的年龄或技术水平如何。 +廉价的单板计算机使硬件再次变得有趣,这并不是秘密。不仅如此,它们使更多的人更容易接近,无论他们的年龄或技术水平如何。 -其中,[树莓派][9]可能是最广泛使用的单板计算机。Ben Nuttall 带我们通过如何安装和设置 [Postgres 数据库在树莓派上][10]。从那里,你可以在任何你想要的项目中使用它。 +其中,[树莓派][9]可能是最广泛使用的单板计算机。Ben Nuttall 带我们一起[在树莓派上安装和设置 Postgres 数据库][10]。这样,你可以在任何你想要的项目中使用它。 -如果你的品味包括文学和技术,你可能会对 Don Watkins 的[如何将树莓派变成电子书服务器][11]感兴趣。有一点工作和一个 [Calibre 电子书管理软件][12]的副本,你就可以得到你最喜欢的电子书,无论你在哪里。 +如果你的品味包括文学和技术,你可能会对 Don Watkins 的[如何将树莓派变成电子书服务器][11]感兴趣。稍微付出一点努力和一份 [Calibre 电子书管理软件][12]副本,你就可以得到你最喜欢的电子书,无论你在哪里。 -树莓派并不是其中唯一有特点的。还有 [Orange Pi Pc Plus][13],一种开源的单板机。David Egts 看着[开始使用这个可编程迷你电脑][14]。 +树莓派并不是其中唯一有特点的。还有 [Orange Pi Pc Plus][13],这是一种开源的单板机。David Egts 告诉你[如何开始使用这个可编程的迷你电脑][14]。 -### 日常计算学 +### 日常的计算机使用 -开源并不仅针对技术专家,更多的凡人用它来做日常工作,而且更加效率。这里有三篇文章,使我们这些笨手笨脚的人做任何事情变得优雅(或者不是)。 +开源并不仅针对技术专家,更多的普通人用它来做日常工作,而且更加效率。这里有三篇文章,可以使我们这些笨手笨脚的人(你可能不是)做任何事情变得优雅。 -当你想到微博的时候,你可能会想到 Twitter。但是 Twitter 的问题多于它的问题。[Mastodon][15] 是 Twitter 的开放的替代方案,它在 2016 年首次亮相。从此, Mastodon 就获得相当大的用户基数。Seth Kenlon 说明[如何加入和使用 Mastodon][16],甚至告诉你如何在 Mastodon 和 Twitter 间交替使用。 +当你想到微博客的时候,你可能会想到 Twitter。但是 Twitter 的问题很多。[Mastodon][15] 是 Twitter 的开放的替代方案,它在 2016 年首次亮相。从此, Mastodon 就获得相当大的用户基数。Seth Kenlon 说明[如何加入和使用 Mastodon][16],甚至告诉你如何在 Mastodon 和 Twitter 间交替使用。 -你需要一点帮助来维持开支吗?你所需要的只是一个电子表格和正确的模板。我的文章[要控制你的财政状况] [17],向你展示了如何用[LibreOffice Calc][18] (或任何其他电子表格编辑器)创建一个简单而有吸引力的财务跟踪。 +你需要一点帮助来维持开支吗?你所需要的只是一个电子表格和正确的模板。我关于[要控制你的财政状况][17]的文章,向你展示了如何用 [LibreOffice Calc][18] (或任何其他电子表格编辑器)创建一个简单而有吸引力的财务跟踪。 -ImageMagick 是强大的图形处理工具。但是,很多人不经常使用。这意味着他们在最需要它们时忘记了命令。如果是你,Greg Pittman 的 [ImageMagick 入门教程][19]在你需要一些帮助时候能派上用场。 +ImageMagick 是强大的图形处理工具。但是,很多人不经常使用。这意味着他们在最需要它们时忘记了命令。如果你也是这样,Greg Pittman 的 [ImageMagick 入门教程][19]能在你需要一些帮助时候能派上用场。 -你有最喜欢的 2017 Opensource.com 公布的教程吗?请随意留言与社区分享。 +你有最喜欢的 2017 Opensource.com 发布的教程吗?请随意留言与社区分享。 -------------------------------------------------------------------------------- @@ -57,29 +59,29 @@ via: https://opensource.com/article/18/1/best-tutorials 作者:[Scott Nesbitt][a] 译者:[zjon](https://github.com/zjon) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://opensource.com/users/scottnesbitt -[1]:https://opensource.com/article/17/4/how-get-started-learning-program +[1]:https://linux.cn/article-8694-1.html [2]:https://en.wikipedia.org/wiki/Integrated_development_environment -[3]:https://opensource.com/article/17/4/introduction-functional-programming +[3]:https://linux.cn/article-8869-1.html [4]:https://opensource.com/article/17/6/set-path-linux [5]:https://opensource.com/article/17/4/build-your-own-name-server -[6]:https://opensource.com/article/17/10/run-dos-applications-linux +[6]:https://linux.cn/article-9014-1.html [7]:http://www.freedos.org/ [8]:https://www.qemu.org [9]:https://en.wikipedia.org/wiki/Raspberry_Pi -[10]:https://opensource.com/article/17/10/set-postgres-database-your-raspberry-pi -[11]:https://opensource.com/article/17/6/raspberrypi-ebook-server +[10]:https://linux.cn/article-9056-1.html +[11]:https://linux.cn/article-8684-1.html [12]:https://calibre-ebook.com/ [13]:http://www.orangepi.org/ -[14]:https://opensource.com/article/17/1/how-to-orange-pi +[14]:https://linux.cn/article-8308-1.html [15]:https://joinmastodon.org/ [16]:https://opensource.com/article/17/4/guide-to-mastodon -[17]:https://opensource.com/article/17/8/budget-libreoffice-calc +[17]:https://linux.cn/article-8831-1.html [18]:https://www.libreoffice.org/discover/calc/ -[19]:https://opensource.com/article/17/8/imagemagick +[19]:https://linux.cn/article-8851-1.html From 2cba0c8d52ef8e12e102f014ae6da8ffd14ee178 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 26 Feb 2018 12:28:08 +0800 Subject: [PATCH 002/101] PUB:20180102 Best open source tutorials in 2017.md @zjon https://linux.cn/article-9385-1.html --- .../20180102 Best open source tutorials in 2017.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180102 Best open source tutorials in 2017.md (100%) diff --git a/translated/tech/20180102 Best open source tutorials in 2017.md b/published/20180102 Best open source tutorials in 2017.md similarity index 100% rename from translated/tech/20180102 Best open source tutorials in 2017.md rename to published/20180102 Best open source tutorials in 2017.md From d6e5f4bb13d2a2936e5c67a778ac65b8d02e1272 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Mon, 26 Feb 2018 18:38:48 +0800 Subject: [PATCH 003/101] Translated by qhwdw --- ...o Manage PGP and SSH Keys with Seahorse.md | 148 ------------------ ...o Manage PGP and SSH Keys with Seahorse.md | 147 +++++++++++++++++ 2 files changed, 147 insertions(+), 148 deletions(-) delete mode 100644 sources/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md create mode 100644 translated/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md diff --git a/sources/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md b/sources/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md deleted file mode 100644 index 11bcd936d5..0000000000 --- a/sources/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md +++ /dev/null @@ -1,148 +0,0 @@ -Translating by qhwdw -How to Manage PGP and SSH Keys with Seahorse -============================================================ - - -![Seahorse](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fish-1907607_1920.jpg?itok=u07bav4m "Seahorse") -Learn how to manage both PGP and SSH keys with the Seahorse GUI tool.[Creative Commons Zero][6] - -Security is tantamount to peace of mind. After all, security is a big reason why so many users migrated to Linux in the first place. But why stop with merely adopting the platform, when you can also employ several techniques and technologies to help secure your desktop or server systems. - -One such technology involves keys—in the form of PGP and SSH. PGP keys allow you to encrypt and decrypt emails and files, and SSH keys allow you to log into servers with an added layer of security. - -Sure, you can manage these keys via the command-line interface (CLI), but what if you’re working on a desktop with a resplendent GUI? Experienced Linux users may cringe at the idea of shrugging off the command line, but not all users have the same skill set and comfort level there. Thus, the GUI! - -In this article, I will walk you through the process of managing both PGP and SSH keys through the [Seahorse][14] GUI tool. Seahorse has a pretty impressive feature set; it can: - -* Encrypt/decrypt/sign files and text. - -* Manage your keys and keyring. - -* Synchronize your keys and your keyring with remote key servers. - -* Sign and publish keys. - -* Cache your passphrase. - -* Backup both keys and keyring. - -* Add an image in any GDK supported format as a OpenPGP photo ID. - -* Create, configure, and cache SSH keys. - -For those that don’t know, Seahorse is a GNOME application for managing both encryption keys and passwords within the GNOME keyring. But fear not, Seahorse is available for installation on numerous desktops. And since Seahorse is found in the standard repositories, you can open up your desktop’s app store (such as Ubuntu Software or Elementary OS AppCenter) and install. To do this, locate Seahorse in your distribution’s application store and click to install. Once you have Seahorse installed, you’re ready to start making use of a very handy tool. - -Let’s do just that. - -### PGP Keys - -The first thing we’re going to do is create a new PGP key. As I said earlier, PGP keys can be used to encrypt email (with tools like [Thunderbird][15]’s [Enigmail][16] or the built-in encryption function with [Evolution][17]). A PGP key also allows you to encrypt files. Anyone with your public key will be able to decrypt those emails or files. Without a PGP key, no can do. - -Creating a new PGP key pair is incredibly simple with Seahorse. Here’s what you do: - -1. Open the Seahorse app - -2. Click the + button in the upper left corner of the main pane - -3. Select PGP Key (Figure 1) - -4. Click Continue - -5. When prompted, type a full name and email address - -6. Click Create - - -![Seahorse](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_1.jpg?itok=khLOYC61 "Seahorse") -Figure 1: Creating a PGP key with Seahorse.[Used with permission][1] - -While creating your PGP key, you can click to expand the Advanced key options section, where you can configure a comment for the key, encryption type, key strength, and expiration date (Figure 2). - - -![PGP](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_2.jpg?itok=eWiazwrn "PGP") -Figure 2: PGP key advanced options.[Used with permission][2] - -The comment section is very handy to help you remember a key’s purpose (or other informative bits). -With your PGP created, double-click on it from the key listing. In the resulting window, click on the Names and Signatures tab. In this window, you can sign your key (to indicate you trust this key). Click the Sign button and then (in the resulting window) indicate how carefully you’ve checked this key and how others will see the signature (Figure 3). - - -![Key signing](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_3.jpg?itok=7USKG9fI "Key signing") -Figure 3: Signing a key to indicate trust level.[Used with permission][3] - -Signing keys is very important when you’re dealing with other people’s keys, as a signed key will ensure your system (and you) you’ve done the work and can fully trust an imported key. - -Speaking of imported keys, Seahorse allows you to easily import someone’s public key file (the file will end in .asc). Having someone’s public key on your system means you can decrypt emails and files sent to you from them. However, Seahorse has suffered a [known bug][18] for quite some time. The problem is that Seahorse imports using gpg version one, but displays with gpg version two. This means, until this long-standing bug is fixed, importing public keys will always fail. If you want to import a public PGP key into Seahorse, you’re going to have to use the command line. So, if someone has sent you the file olivia.asc, and you want to import it so it can be used with Seahorse, you would issue the command gpg2 --import olivia.asc. That key would then appear in the GnuPG Keys listing. You can open the key, click the I trust signatures button, and then click the Sign this key button to indicate how carefully you’ve checked the key in question. - -### SSH Keys - -Now we get to what I consider to be the most important aspect of Seahorse—SSH keys. Not only does Seahorse make it easy to generate an SSH key, it makes it easy to send that key to a server, so you can take advantage of SSH key authentication. Here’s how you generate a new key and then export it to a remote server. - -1. Open up Seahorse - -2. Click the + button - -3. Select Secure Shell Key - -4. Click Continue - -5. Give the key a description - -6. Click Create and Set Up - -7. Type and verify a passphrase for the key - -8. Click OK - -9. Type the address of the remote server and a remote login name found on the server (Figure 4) - -10. Type the password for the remote user - -11. Click OK - - -![SSH key](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_4.jpg?itok=ZxuxT8ry "SSH key") -Figure 4: Uploading an SSH key to a remote server.[Used with permission][4] - -The new key will be uploaded to the remote server and is ready to use. If your server is set up for SSH key authentication, you’re good to go. - -Do note, during the creation of an SSH key, you can click to expand the Advanced key options and configure Encryption Type and Key Strength (Figure 5). - - -![Advanced options](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_5.jpg?itok=vUT7pi0z "Advanced options") -Figure 5: Advanced SSH key options.[Used with permission][5] - -### A must-use for new Linux users - -Any new-to-Linux user should get familiar with Seahorse. Even with its flaws, Seahorse is still an incredibly handy tool to have at the ready. At some point, you will likely want (or need) to encrypt or decrypt an email/file, or manage secure shell keys for SSH key authentication. If you want to do this, while avoiding the command line, Seahorse is the tool to use. - - _Learn more about Linux through the free ["Introduction to Linux" ][13]course from The Linux Foundation and edX._ - --------------------------------------------------------------------------------- - -via: https://www.linux.com/learn/intro-to-linux/2018/2/how-manage-pgp-and-ssh-keys-seahorse - -作者:[JACK WALLEN ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.linux.com/users/jlwallen -[1]:https://www.linux.com/licenses/category/used-permission -[2]:https://www.linux.com/licenses/category/used-permission -[3]:https://www.linux.com/licenses/category/used-permission -[4]:https://www.linux.com/licenses/category/used-permission -[5]:https://www.linux.com/licenses/category/used-permission -[6]:https://www.linux.com/licenses/category/creative-commons-zero -[7]:https://www.linux.com/files/images/seahorse1jpg -[8]:https://www.linux.com/files/images/seahorse2jpg -[9]:https://www.linux.com/files/images/seahorse3jpg -[10]:https://www.linux.com/files/images/seahorse4jpg -[11]:https://www.linux.com/files/images/seahorse5jpg -[12]:https://www.linux.com/files/images/fish-19076071920jpg -[13]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux -[14]:https://wiki.gnome.org/Apps/Seahorse -[15]:https://www.mozilla.org/en-US/thunderbird/ -[16]:https://enigmail.net/index.php/en/ -[17]:https://wiki.gnome.org/Apps/Evolution -[18]:https://bugs.launchpad.net/ubuntu/+source/seahorse/+bug/1577198 diff --git a/translated/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md b/translated/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md new file mode 100644 index 0000000000..789137066c --- /dev/null +++ b/translated/tech/20180202 How to Manage PGP and SSH Keys with Seahorse.md @@ -0,0 +1,147 @@ +如何使用 Seahorse 管理 PGP 和 SSH 密钥 +============================================================ + + +![Seahorse](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fish-1907607_1920.jpg?itok=u07bav4m "Seahorse") +学习使用 Seahorse GUI 工具去管理 PGP 和 SSH 密钥。[Creative Commons Zero][6] + +安全无异于内心的平静。毕竟,安全是许多用户迁移到 Linux 的最大理由。但是当你可以采用几种方法和技术去确保你的桌面或者服务器系统的安全时,你为什么还要停止使用差不多已经接受的平台呢? + +其中一项技术涉及到密钥 —在 PGP 和 SSH 中,PGP 密钥允许你去加密和解密电子邮件和文件,而 SSH 密钥允许你使用一个额外的安全层去登入服务器。 + +当然,你可以通过命令行接口(CLI)来管理这些密钥,但是,如果你使用一个华丽的 GUI 桌面环境呢?经验丰富的 Linux 用户可能对于摆脱命令行来工作感到很不适应,但是,并不是所有用户都具备与他们相同的技术和水平因此,使用 GUI! + +在本文中,我将带你探索如何使用  [Seahorse][14] GUI 工具来管理 PGP 和 SSH 密钥。Seahorse 有非常强大的功能,它可以: + +* 加密/解密/签名文件和文本。 + +* 管理你的密钥和密钥对。 + +* 同步你的密钥和密钥对到远程密钥服务器。 + +* 签名和发布密钥。 + +* 缓存你的密码。 + +* 备份密钥和密钥对。 + +* 在任何一个 GDK 支持的格式中添加一个图像作为一个 OpenPGP photo ID。 + +* 创建、配置、和缓存 SSH 密钥。 + +对于那些不了解 Seahorse 的人来说,它是一个在 GNOME 密钥对中管理加密密钥和密码的 GNOME 应用程序。不用担心,Seahorse 可以安装在许多的桌面上。并且由于 Seahorse 是在标准仓库中创建的,你可以打开你的桌面应用商店(比如,Ubuntu Software 或者 Elementary OS AppCenter)去安装它。因此,你可以在你的发行版的应用商店中点击去安装它。安装完成后,你就可以去使用这个很方便的工具了。 + +我们开始去使用它吧。 + +### PGP 密钥 + +我们需要做的第一件事情就是生成一个新的 PGP 密钥。正如前面所述,PGP 密钥可以用于加密电子邮件(使用一些工具,像  [Thunderbird][15] 的 [Enigmail][16] 或者使用 [Evolution][17] 内置的加密功能)。一个 PGP 密钥也可以用于加密文件。任何人使用你的公钥都可以解密你的电子邮件和文件。没有 PGP 密钥是做不到的。 + +使用 Seahorse 创建一个新的 PGP 密钥对是非常简单的。以下是操作步骤: + +1. 打开 Seahorse 应用程序 + +2. 在主面板的左上角点击 + 按钮 + +3. 选择 PGP Key(如图 1 ) + +4. 点击 Continue + +5. 当提示时,输入完整的名字和电子邮件地址 + +6. 点击 Create + + +![Seahorse](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_1.jpg?itok=khLOYC61 "Seahorse") +图 1:使用 Seahorse 创建一个 PGP 密钥。[Used with permission][1] + +在创建你的 PGP 密钥期间,你可以点击 Advanced key options 展开选项部分,在那里你可以为密钥添加注释信息、加密类型、密钥长度、以及过期时间(如图 2)。 + + +![PGP](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_2.jpg?itok=eWiazwrn "PGP") +图 2:PGP 密钥高级选项[Used with permission][2] + +增加注释部分可以很方便帮你记住密钥的用途(或者其它的信息)。 +要使用你创建的 PGP,可在密钥列表中双击它。在结果窗口中,点击 Names 和 Signatures 选项卡。在这个窗口中,你可以签名你的密钥(表示你信任这个密钥)。点击 Sign 按钮然后(在结果窗口中)标识 how carefully you’ve checked this key 和 how others will see the signature(如图 3)。 + + +![Key signing](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_3.jpg?itok=7USKG9fI "Key signing") +图 3:签名一个密钥表示信任级别。[Used with permission][3] + +当你处理其它人的密钥时,密钥签名是非常重要的,因为一个签名的密钥将确保你的系统(和你)做了这项工作并且完全信任这个重要的密钥。 + +谈到导入的密钥,Seahorse 可以允许你很容易地去导入其他人的公钥文件(这个文件以 .asc 为后缀)。你的系统上有其他人的公钥,意味着你可以解密从他们那里发送给你的电子邮件和文件。然而,Seahorse 在很长的一段时间内都存在一个 [已知的 bug][18]。这个问题是,Seahorse 导入使用 GPG 版本 1,但是显示的是 GPG 版本 2。这意味着,在这个存在了很长时间的 bug 被修复之前,导入公钥总是失败的。如果你想导入一个公钥文件到 Seahorse 中,你只能去使用命令行。因此,如果有人发送给你一个文件 olivia.asc,你想去导入到 Seahorse 中使用它,你将只能运行命令 gpg2 --import olivia.asc。那个密钥将出现在 GnuPG 密钥列表中。你可以打开密钥,点击 I trust signatures 按钮,然后在问题 how carefully you’ve checked the key 中,点击 Sign this key 按钮去标示。 + +### SSH 密钥 + +现在我们来谈谈我认为 Seahorse 中最重要的一个方面 — SSH 密钥。Seahorse 不仅可以很容易地生成一个 SSH 密钥,而且它也可以很容易地将生成的密钥发送到服务器上,因此,你可以享受到 SSH 密钥验证的好处。下面是如何生成一个新的密钥以及如何导出它到一个远程服务器上。 + +1. 打开 Seahorse 应用程序 + +2. 点击 + 按钮 + +3. 选择 Secure Shell Key + +4. 点击 Continue + +5. 提供一个密钥描述信息 + +6. 点击 Set Up 去创建密钥 + +7. 输入密钥的验证密钥 + +8. 点击 OK + +9. 输入远程服务器地址和服务器上的登陆名(如图 4) + +10. 输入远程用户的密码 + +11. 点击 OK + + +![SSH key](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_4.jpg?itok=ZxuxT8ry "SSH key") +图 4:上传一个 SSH 密钥到远程服务器。[Used with permission][4] + +新密钥将上传到远程服务器上以准备好使用它。如果你的服务器已经设置为使用 SSH 密钥验证,那就一切就绪了。 + +需要注意的是,在创建一个 SSH 密钥期间,你可以点击 Advanced key options 去展开它,配置加密类型和密钥长度(如图 5)。 + + +![Advanced options](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_5.jpg?itok=vUT7pi0z "Advanced options") +图 5:高级 SSH 密钥选项。[Used with permission][5] + +### Linux 新手必备 + +任何 Linux 新手用户都可以很快熟悉使用 Seahorse。即便是它有缺陷,Seahorse 仍然是为你准备的一个极其方便的工具。有时候,你可能希望(或者需要)去加密或者解密一个电子邮件/文件,或者为使用 SSH 验证来管理 SSH 密钥。如果你想去这样做而不希望使用命令行,那么,Seahorse 将是非常适合你的工具。 + + _通过来自 Linux 基金会和 edX 的 ["Linux 入门" ][13] 免费课程学习更多 Linux 的知识。_ + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/2/how-manage-pgp-and-ssh-keys-seahorse + +作者:[JACK WALLEN ][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/jlwallen +[1]:https://www.linux.com/licenses/category/used-permission +[2]:https://www.linux.com/licenses/category/used-permission +[3]:https://www.linux.com/licenses/category/used-permission +[4]:https://www.linux.com/licenses/category/used-permission +[5]:https://www.linux.com/licenses/category/used-permission +[6]:https://www.linux.com/licenses/category/creative-commons-zero +[7]:https://www.linux.com/files/images/seahorse1jpg +[8]:https://www.linux.com/files/images/seahorse2jpg +[9]:https://www.linux.com/files/images/seahorse3jpg +[10]:https://www.linux.com/files/images/seahorse4jpg +[11]:https://www.linux.com/files/images/seahorse5jpg +[12]:https://www.linux.com/files/images/fish-19076071920jpg +[13]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux +[14]:https://wiki.gnome.org/Apps/Seahorse +[15]:https://www.mozilla.org/en-US/thunderbird/ +[16]:https://enigmail.net/index.php/en/ +[17]:https://wiki.gnome.org/Apps/Evolution +[18]:https://bugs.launchpad.net/ubuntu/+source/seahorse/+bug/1577198 From 883fc8d2768c890ebc7eb3be4887b1cfcf61f08f Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 26 Feb 2018 23:31:45 +0800 Subject: [PATCH 004/101] PRF:20180112 Top 5 Firefox extensions to install now.md @ypingcn --- ...Top 5 Firefox extensions to install now.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/translated/tech/20180112 Top 5 Firefox extensions to install now.md b/translated/tech/20180112 Top 5 Firefox extensions to install now.md index 9f4698aea7..bef4ff5eef 100644 --- a/translated/tech/20180112 Top 5 Firefox extensions to install now.md +++ b/translated/tech/20180112 Top 5 Firefox extensions to install now.md @@ -1,17 +1,17 @@ 五个值得现在安装的火狐插件 ====== -合适的插件能大大增强你浏览器的功能,但仔细挑选插件很重要。本文有五个值得一看的插件。 +> 合适的插件能大大增强你浏览器的功能,但仔细挑选插件很重要。本文有五个值得一看的插件。 ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/firefox_blue_lead.jpg) -对于很多用户来说,网页浏览器已经成为电脑使用体验的重要环节。现代浏览器已经发展成强大、可拓展的平台。作为平台的一部分,_插件_能添加或修改浏览器的功能。火狐插件的构建使用了 WebExtensions API ,一个跨浏览器的开发系统。 +对于很多用户来说,网页浏览器已经成为电脑使用体验的重要环节。现代浏览器已经发展成强大、可拓展的平台。作为平台的一部分,_插件_能添加或修改浏览器的功能。火狐插件的构建使用了 WebExtensions API ,这是一个跨浏览器的开发系统。 -你得安装哪一个插件?一般而言,这个问题的答案取决于你如何使用你的浏览器、你对于隐私的看法、你信任插件开发者多少以及其他个人喜好。 +你应该安装哪一个插件?一般而言,这个问题的答案取决于你如何使用你的浏览器、你对于隐私的看法、你信任插件开发者多少以及其他个人喜好。 首先,我想指出浏览器插件通常需要读取和(或者)修改你浏览的网页上的每项内容。你应该_非常_仔细地考虑这件事的后果。如果一个插件有修改所有你访问过的网页的权限,那么它可能记录你的按键、拦截信用卡信息、在线跟踪你、插入广告,以及其他各种各样邪恶的行为。 -并不是每个插件都偷偷摸摸地做这些事,但是在你安装任何插件之前,你要慎重考虑下插件安装来源、涉及的权限、你的风险数据和其他因素。记住,你可以从个人数据的角度来管理一个插件如何影响你的攻击面( LCTT 译者注:攻击面是指入侵者能尝试获取或提取数据的途径总和)——例如使用特定的配置、不使用插件来完成例如网上银行的操作。 +并不是每个插件都偷偷摸摸地做这些事,但是在你安装任何插件之前,你要慎重考虑下插件安装来源、涉及的权限、你的风险数据和其他因素。记住,你可以从个人数据的角度来管理一个插件如何影响你的攻击面( LCTT 译注:攻击面是指入侵者能尝试获取或提取数据的途径总和)——例如使用特定的配置、不使用插件来完成例如网上银行的操作。 考虑到这一点,这里有你或许想要考虑的五个火狐插件 @@ -19,29 +19,29 @@ ![ublock origin ad blocker screenshot][2] -ublock Origin 可以拦截广告和恶意网页,还允许用户定义自己的内容过滤器。 +*ublock Origin 可以拦截广告和恶意网页,还允许用户定义自己的内容过滤器。* -[uBlock Origin][3] 是一款快速、内存占用低、适用范围广的拦截器,它不仅能屏蔽广告,还能让你执行你自己的内容过滤。uBlock Origin 默认使用多份预定义好的过滤名单来拦截广告、跟踪器和恶意网页。它允许你任意地添加列表和规则,或者锁定在一个默认拒绝的模式。除了强大之外,这个插件已被证明是效率高、性能好。 +[uBlock Origin][3] 是一款快速、内存占用低、适用范围广的拦截器,它不仅能屏蔽广告,还能让你执行你自己定制的内容过滤。uBlock Origin 默认使用多份预定义好的过滤名单来拦截广告、跟踪器和恶意网页。它允许你任意地添加列表和规则,或者锁定在一个默认拒绝的模式。除了强大之外,这个插件已被证明是效率高、性能好。 ### Privacy Badger ![privacy badger ad blocker][5] -Privacy Badger 运用了算法来无缝地屏蔽侵犯用户准则的广告和跟踪器。 +*Privacy Badger 运用了算法来无缝地屏蔽侵犯用户准则的广告和跟踪器。* -正如它名字所表明,[Privacy Badger][6] 是一款专注于隐私的插件,它屏蔽广告和第三方跟踪器。EFF (LCTT 译者注:EFF全称是电子前哨基金会(Electronic Frontier Foundation),旨在宣传互联网版权和监督执法机构 )说:“我们想要推荐一款能自动分析并屏蔽任何侵犯用户准则的跟踪器和广告,而 Privacy Badger 诞生于此目的;它不用任何设置、知识或者用户的配置,就能运行得很好;它是由一个明显为用户服务而不是为广告主服务的组织出品;它使用算法来绝定什么正在跟踪,什么没有在跟踪” +正如它名字所表明,[Privacy Badger][6] 是一款专注于隐私的插件,它屏蔽广告和第三方跟踪器。EFF (LCTT 译注:EFF 全称是电子前哨基金会Electronic Frontier Foundation,旨在宣传互联网版权和监督执法机构)说:“我们想要推荐一款能自动分析并屏蔽任何侵犯用户准则的跟踪器和广告,而 Privacy Badger 诞生于此目的;它不用任何设置、知识或者用户的配置,就能运行得很好;它是由一个明显为用户服务而不是为广告主服务的组织出品;它使用算法来确定正在跟踪什么,而没有跟踪什么。” -为什么 Privacy Badger 出现在这列表上的原因跟 uBlock Origin 如此相似?其中一个原因是Privacy Badger 从根本上跟 uBlock Origin 的工作不同。另一个原因是纵深防御的做法是个可以跟随的合理策略。 +为什么 Privacy Badger 出现在这列表上的原因跟 uBlock Origin 如此相似?其中一个原因是 Privacy Badger 从根本上跟 uBlock Origin 的工作不同。另一个原因是纵深防御的做法是个可以遵循的合理策略。 ### LastPass ![lastpass password manager screenshot][8] -LastPass 是一款用户友好的密码管理插件,支持双重授权。 +*LastPass 是一款用户友好的密码管理插件,支持双因子认证。* 这个插件对于很多人来说是个有争议的补充。你是否应该使用密码管理器——如果你用了,你是否应该选择一个浏览器插件——这都是个热议的话题,而答案取决于你的风险资料。我想说大部分不关心的电脑用户应该用一个,因为这比起常见的选择:每一处使用相同的弱密码,都好太多了。 -[LastPass][9] 对于用户很友好,支持双重授权,相当安全。这家公司过去出过点安全事故,但是都处理得当,而且资金充足。记住使用密码管理器不是非此即彼的命题。很多用户选择使用密码管理器管理绝大部分密码,但是保持了一点复杂性,为例如银行这样重要的网页精心设计了密码和使用多重认证。 +[LastPass][9] 对于用户很友好,支持双因子认证,相当安全。这家公司过去出过点安全事故,但是都处理得当,而且资金充足。记住使用密码管理器不是非此即彼的命题。很多用户选择使用密码管理器管理绝大部分密码,但是保持了一点复杂性,为例如银行这样重要的网页采用了精心设计的密码和多因子认证。 ### Xmarks Sync @@ -51,11 +51,11 @@ LastPass 是一款用户友好的密码管理插件,支持双重授权。 [Awesome Screenshot Plus][11] 允许你很容易捕获任意网页的全部或部分区域,也能添加注释、评论、使敏感信息模糊等。你还能用一个可选的在线服务来分享图片。我发现这工具在网页调试时截图、讨论设计和分享信息上很棒。这是一款比你预期中发现自己使用得多的工具。 -我发现这五款插件有用,我把它们推荐给其他人。这就是说,还有很多浏览器插件。我好奇其他的哪一款是 Opensource.com 社区用户正在使用并推荐的。让评论中让我知道。(LCTT 译者注:本文引用自 Opensource.com ,这两句话意在引导用户留言,推荐自己使用的插件) - ![Awesome Screenshot Plus screenshot][13] -Awesome Screenshot Plus 允许你容易地截下任何网页的部分或全部内容。 +*Awesome Screenshot Plus 允许你容易地截下任何网页的部分或全部内容。* + +我发现这五款插件有用,我把它们推荐给其他人。这就是说,还有很多浏览器插件。我很感兴趣社区用户们正在使用哪些插件,请在评论中让我知道。 -------------------------------------------------------------------------------- @@ -63,17 +63,17 @@ via: https://opensource.com/article/18/1/top-5-firefox-extensions 作者:[Jeremy Garcia][a] 译者:[ypingcn](https://github.com/ypingcn) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: https://opensource.com/users/jeremy-garcia -[2]: https://opensource.com/sites/default/files/ublock.png "ublock origin ad blocker screenshot" +[2]: https://opensource.com/sites/default/files/ublock.png [3]: https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/ -[5]: https://opensource.com/sites/default/files/images/life-uploads/privacy_badger_1.0.1.png "privacy badger ad blocker screenshot" +[5]: https://opensource.com/sites/default/files/images/life-uploads/privacy_badger_1.0.1.png [6]: https://www.eff.org/privacybadger -[8]: https://opensource.com/sites/default/files/images/life-uploads/lastpass4.jpg "lastpass password manager screenshot" +[8]: https://opensource.com/sites/default/files/images/life-uploads/lastpass4.jpg [9]: https://addons.mozilla.org/en-US/firefox/addon/lastpass-password-manager/ [10]: https://addons.mozilla.org/en-US/firefox/addon/xmarks-sync/ [11]: https://addons.mozilla.org/en-US/firefox/addon/screenshot-capture-annotate/ -[13]: https://opensource.com/sites/default/files/screenshot_from_2018-01-04_17-11-32.png "Awesome Screenshot Plus screenshot" +[13]: https://opensource.com/sites/default/files/screenshot_from_2018-01-04_17-11-32.png \ No newline at end of file From 5a2379c4b4ea84508eb884947069216920d4af25 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 26 Feb 2018 23:32:10 +0800 Subject: [PATCH 005/101] PUB:20180112 Top 5 Firefox extensions to install now.md @ypingcn https://linux.cn/article-9386-1.html --- .../20180112 Top 5 Firefox extensions to install now.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180112 Top 5 Firefox extensions to install now.md (100%) diff --git a/translated/tech/20180112 Top 5 Firefox extensions to install now.md b/published/20180112 Top 5 Firefox extensions to install now.md similarity index 100% rename from translated/tech/20180112 Top 5 Firefox extensions to install now.md rename to published/20180112 Top 5 Firefox extensions to install now.md From cbfc5deb16627d758d2941750b64f359cf18eed4 Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Mon, 26 Feb 2018 23:38:05 +0800 Subject: [PATCH 006/101] Delete 20180220 How to Get Started Using WSL in Windows 10.md --- ... to Get Started Using WSL in Windows 10.md | 121 ------------------ 1 file changed, 121 deletions(-) delete mode 100644 sources/tech/20180220 How to Get Started Using WSL in Windows 10.md diff --git a/sources/tech/20180220 How to Get Started Using WSL in Windows 10.md b/sources/tech/20180220 How to Get Started Using WSL in Windows 10.md deleted file mode 100644 index 3bee118c23..0000000000 --- a/sources/tech/20180220 How to Get Started Using WSL in Windows 10.md +++ /dev/null @@ -1,121 +0,0 @@ -translated by cyleft - -How to Get Started Using WSL in Windows 10 -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-main.png?itok=wJ5WrU9U) - -In the [previous article][1], we talked about the Windows Subsystem for Linux (WSL) and its target audience. In this article, we will walk through the process of getting started with WSL on your Windows 10 machine. - -### Prepare your system for WSL - -You must be running the latest version of Windows 10 with Fall Creator Update installed. Then, check which version of Windows 10 is installed on your system by searching on “About” in the search box of the Start menu. You should be running version 1709 or the latest to use WSL. - -Here is a screenshot from my system. - -![kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9m][2] - -If an older version is installed, you need to download and install the Windows 10 Fall Creator Update (FCU) from [this][3] page. Once FCU is installed, go to Update Settings (just search for “updates” in the search box of the Start menu) and install any available updates. - -Go to Turn Windows Features On or Off (you know the drill by now) and scroll to the bottom and tick on the box Windows Subsystem for Linux, as shown in the following figure. Click Ok. It will download and install the needed packages. - -![oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7x][4] - -Upon the completion of the installation, the system will offer to restart. Go ahead and reboot your machine. WSL won’t launch without a system reboot, as shown below: - -![GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aN][5] - -Once your system starts, go back to the Turn features on or off setting to confirm that the box next to Windows Subsystem for Linux is selected. - -### Install Linux in Windows - -There are many ways to install Linux on Windows, but we will choose the easiest way. Open the Windows Store and search for Linux. You will see the following option: - -![YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7][6] - -Click on Get the apps, and Windows Store will provide you with three options: Ubuntu, openSUSE Leap 42, and SUSE Linux Enterprise Server. You can install all three distributions side by side and run all three distributions simultaneously. To be able to use SLE, you need a subscription. - -In this case, I am installing openSUSE Leap 42 and Ubuntu. Select your desired distro and click on the Get button to install it. Once installed, you can launch openSUSE in Windows. It can be pinned to the Start menu for quick access. - -![4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OA][7] - -### Using Linux in Windows - -When you launch the distro, it will open the Bash shell and install the distro. Once installed, you can go ahead and start using it. Simple. Just bear in mind that there is no user in openSUSE and it runs as root user, whereas Ubuntu will ask you to create a user. On Ubuntu, you can perform administrative tasks as sudo user. - -You can easily create a user on openSUSE: -``` -# useradd [username] - -# passwd [username] - -``` - -Create a new password for the user and you are all set. For example: -``` -# useradd swapnil - -# passwd swapnil - -``` - -You can switch from root to this use by running the su command: -``` -su swapnil - -``` - -You do need non-root use to perform many tasks, like using commands like rsync to move files on your local machine. - -The first thing you need to do is update the distro. For openSUSE: -``` -zypper up - -``` - -For Ubuntu: -``` -sudo apt-get update - -sudo apt-get dist-upgrade - -``` - -![7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9][8] - -You now have native Linux Bash shell on Windows. Want to ssh into your server from Windows 10? There’s no need to install puTTY or Cygwin. Just open Bash and then ssh into your server. Easy peasy. - -Want to rsync files to your server? Go ahead and use rsync. It really transforms Windows into a usable machine for those Windows users who want to use native Linux command linux tools on their machines without having to deal with VMs. - -### Where is Fedora? - -You may be wondering about Fedora. Unfortunately, Fedora is not yet available through the store. Matthew Miller, the release manager of Fedora said on Twitter, “We're working on resolving some non-technical issues. I'm afraid I don't have any more than that right now.” - -We don’t know yet what these non-technical issues are. When some users asked why the WSL team could not publish Fedora themselves --- after all it’s an open source project -- Rich Turner, a project manager at Microsoft [responded][9], “We have a policy of not publishing others' IP into the store. We believe that the community would MUCH prefer to see a distro published by the distro owner vs. seeing it published by Microsoft or anyone else that isn't the authoritative source.” - -So, Microsoft can’t just go ahead and publish Debian or Arch Linux on Windows Store. The onus is on the official communities to bring their distros to Windows 10 users. - -### What’s next - -In the next article, we will talk about using Windows 10 as a Linux machine and performing most of the tasks that you would perform on your Linux system using the command-line tools. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-10 - -作者:[SWAPNIL BHARTIYA][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.linux.com/users/arnieswap -[1]:https://www.linux.com/blog/learn/2018/2/windows-subsystem-linux-bridge-between-two-platforms -[2]:https://lh6.googleusercontent.com/kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9mr_E255GiiBxf8cRlatrte6z23yvo8lHJG8nQ_WeHhUNYqPp7kHuQTTMueqMshCT71JsbMr2Wih9KFHuHgNg1BclWz-iuBt4O -[3]:https://www.microsoft.com/en-us/software-download/windows10 -[4]:https://lh4.googleusercontent.com/oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7xF9M9_AcHPNSxM18KDWK2ZpVcUOfxVVpNH9LwUJT5EtRE7zUrJC_gWV5f345SZRAgXcJzOE-8rM8-RCPTNtns6vVP37V5Eflp -[5]:https://lh5.googleusercontent.com/GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aNEozAcQA59Z3hDu_SxT6I4K4gwxLPX0YnmUsCKjaQaaG2PoAgUYMcN0Zv0tBFaoUL3sZryddM4mdRj1E2tE-IK_GLK4PDa4zf -[6]:https://lh3.googleusercontent.com/YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7MKEoYxEsX_yLwyMj9N2edt3GJ2JLx6mUsFEZFILCCSBU2sMOqveFVWZTHcCXhFi5P2Xk-9Ikc3NK9seup5CJObIcYJPORdPW -[7]:https://lh6.googleusercontent.com/4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OAOH3Mx7nfOROfyf81k1s4YQyLBcu0qSXOoaqbYkXL5Wpp9gNCdKH_WsEcqWzjG6uXzYvCYQ42psOz6Iz3NF7ElsPrdiFI0cYv -[8]:https://lh6.googleusercontent.com/7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9cU5xiBWz_cpZ1IBidNT0C1wg9zROIncViUzXD0vPoH5cggQtuwkanRfRdDVXOI48AcKFLt-Iq2CBF4mGRwqqWvSOhb0HFpjm -[9]:https://github.com/Microsoft/WSL/issues/2584 From 75285dfd069e9a532b7f53c3531060e90d4d5b8f Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Mon, 26 Feb 2018 23:39:12 +0800 Subject: [PATCH 007/101] translated by cyleft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 20180220 How to Get Started Using WSL in Windows 10.md 其实是一篇过时很久的技术贴。 --- ... to Get Started Using WSL in Windows 10.md | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 translated/tech/20180220 How to Get Started Using WSL in Windows 10.md diff --git a/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md b/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md new file mode 100644 index 0000000000..b4cde0c0d1 --- /dev/null +++ b/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md @@ -0,0 +1,121 @@ +20180220 How to Get Started Using WSL in Windows 10.md + +How to Get Started Using WSL in Windows 10 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-main.png?itok=wJ5WrU9U) + +In the [previous article][1], we talked about the Windows Subsystem for Linux (WSL) and its target audience. In this article, we will walk through the process of getting started with WSL on your Windows 10 machine. + +### Prepare your system for WSL + +You must be running the latest version of Windows 10 with Fall Creator Update installed. Then, check which version of Windows 10 is installed on your system by searching on “About” in the search box of the Start menu. You should be running version 1709 or the latest to use WSL. + +Here is a screenshot from my system. + +![kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9m][2] + +If an older version is installed, you need to download and install the Windows 10 Fall Creator Update (FCU) from [this][3] page. Once FCU is installed, go to Update Settings (just search for “updates” in the search box of the Start menu) and install any available updates. + +Go to Turn Windows Features On or Off (you know the drill by now) and scroll to the bottom and tick on the box Windows Subsystem for Linux, as shown in the following figure. Click Ok. It will download and install the needed packages. + +![oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7x][4] + +Upon the completion of the installation, the system will offer to restart. Go ahead and reboot your machine. WSL won’t launch without a system reboot, as shown below: + +![GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aN][5] + +Once your system starts, go back to the Turn features on or off setting to confirm that the box next to Windows Subsystem for Linux is selected. + +### Install Linux in Windows + +There are many ways to install Linux on Windows, but we will choose the easiest way. Open the Windows Store and search for Linux. You will see the following option: + +![YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7][6] + +Click on Get the apps, and Windows Store will provide you with three options: Ubuntu, openSUSE Leap 42, and SUSE Linux Enterprise Server. You can install all three distributions side by side and run all three distributions simultaneously. To be able to use SLE, you need a subscription. + +In this case, I am installing openSUSE Leap 42 and Ubuntu. Select your desired distro and click on the Get button to install it. Once installed, you can launch openSUSE in Windows. It can be pinned to the Start menu for quick access. + +![4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OA][7] + +### Using Linux in Windows + +When you launch the distro, it will open the Bash shell and install the distro. Once installed, you can go ahead and start using it. Simple. Just bear in mind that there is no user in openSUSE and it runs as root user, whereas Ubuntu will ask you to create a user. On Ubuntu, you can perform administrative tasks as sudo user. + +You can easily create a user on openSUSE: +``` +# useradd [username] + +# passwd [username] + +``` + +Create a new password for the user and you are all set. For example: +``` +# useradd swapnil + +# passwd swapnil + +``` + +You can switch from root to this use by running the su command: +``` +su swapnil + +``` + +You do need non-root use to perform many tasks, like using commands like rsync to move files on your local machine. + +The first thing you need to do is update the distro. For openSUSE: +``` +zypper up + +``` + +For Ubuntu: +``` +sudo apt-get update + +sudo apt-get dist-upgrade + +``` + +![7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9][8] + +You now have native Linux Bash shell on Windows. Want to ssh into your server from Windows 10? There’s no need to install puTTY or Cygwin. Just open Bash and then ssh into your server. Easy peasy. + +Want to rsync files to your server? Go ahead and use rsync. It really transforms Windows into a usable machine for those Windows users who want to use native Linux command linux tools on their machines without having to deal with VMs. + +### Where is Fedora? + +You may be wondering about Fedora. Unfortunately, Fedora is not yet available through the store. Matthew Miller, the release manager of Fedora said on Twitter, “We're working on resolving some non-technical issues. I'm afraid I don't have any more than that right now.” + +We don’t know yet what these non-technical issues are. When some users asked why the WSL team could not publish Fedora themselves --- after all it’s an open source project -- Rich Turner, a project manager at Microsoft [responded][9], “We have a policy of not publishing others' IP into the store. We believe that the community would MUCH prefer to see a distro published by the distro owner vs. seeing it published by Microsoft or anyone else that isn't the authoritative source.” + +So, Microsoft can’t just go ahead and publish Debian or Arch Linux on Windows Store. The onus is on the official communities to bring their distros to Windows 10 users. + +### What’s next + +In the next article, we will talk about using Windows 10 as a Linux machine and performing most of the tasks that you would perform on your Linux system using the command-line tools. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-10 + +作者:[SWAPNIL BHARTIYA][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/arnieswap +[1]:https://www.linux.com/blog/learn/2018/2/windows-subsystem-linux-bridge-between-two-platforms +[2]:https://lh6.googleusercontent.com/kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9mr_E255GiiBxf8cRlatrte6z23yvo8lHJG8nQ_WeHhUNYqPp7kHuQTTMueqMshCT71JsbMr2Wih9KFHuHgNg1BclWz-iuBt4O +[3]:https://www.microsoft.com/en-us/software-download/windows10 +[4]:https://lh4.googleusercontent.com/oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7xF9M9_AcHPNSxM18KDWK2ZpVcUOfxVVpNH9LwUJT5EtRE7zUrJC_gWV5f345SZRAgXcJzOE-8rM8-RCPTNtns6vVP37V5Eflp +[5]:https://lh5.googleusercontent.com/GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aNEozAcQA59Z3hDu_SxT6I4K4gwxLPX0YnmUsCKjaQaaG2PoAgUYMcN0Zv0tBFaoUL3sZryddM4mdRj1E2tE-IK_GLK4PDa4zf +[6]:https://lh3.googleusercontent.com/YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7MKEoYxEsX_yLwyMj9N2edt3GJ2JLx6mUsFEZFILCCSBU2sMOqveFVWZTHcCXhFi5P2Xk-9Ikc3NK9seup5CJObIcYJPORdPW +[7]:https://lh6.googleusercontent.com/4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OAOH3Mx7nfOROfyf81k1s4YQyLBcu0qSXOoaqbYkXL5Wpp9gNCdKH_WsEcqWzjG6uXzYvCYQ42psOz6Iz3NF7ElsPrdiFI0cYv +[8]:https://lh6.googleusercontent.com/7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9cU5xiBWz_cpZ1IBidNT0C1wg9zROIncViUzXD0vPoH5cggQtuwkanRfRdDVXOI48AcKFLt-Iq2CBF4mGRwqqWvSOhb0HFpjm +[9]:https://github.com/Microsoft/WSL/issues/2584 From b2a242cb47ea1485fd79ec5d7aeea855fe1babbc Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Mon, 26 Feb 2018 23:50:29 +0800 Subject: [PATCH 008/101] Update 20180220 How to Get Started Using WSL in Windows 10.md --- ... to Get Started Using WSL in Windows 10.md | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md b/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md index b4cde0c0d1..5816c6fdfd 100644 --- a/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md +++ b/translated/tech/20180220 How to Get Started Using WSL in Windows 10.md @@ -1,49 +1,47 @@ -20180220 How to Get Started Using WSL in Windows 10.md - -How to Get Started Using WSL in Windows 10 +如何在 Windows 10 上开启 WSL(Windows Subsystem for Linux) 之旅 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-main.png?itok=wJ5WrU9U) -In the [previous article][1], we talked about the Windows Subsystem for Linux (WSL) and its target audience. In this article, we will walk through the process of getting started with WSL on your Windows 10 machine. +在 [上一篇文章][1] 中,我们讨论过关于 Windows 的子系统 Linux(WSL)的目标用户。本文,我们将在 Windows 10 的设备上,开启 WSL 的旅程。 -### Prepare your system for WSL +### 为 WSL 做准备 -You must be running the latest version of Windows 10 with Fall Creator Update installed. Then, check which version of Windows 10 is installed on your system by searching on “About” in the search box of the Start menu. You should be running version 1709 or the latest to use WSL. +您必须使用最新版本的 Windows 10 Fall Creator Update。之后,通过在开始菜单栏搜索 “About”,检查 Windows 10 的版本。为了使用 WSL,您的版本应当为 1709 或者最新版。 -Here is a screenshot from my system. +这里有一张关于我的操作系统的截图。 ![kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9m][2] -If an older version is installed, you need to download and install the Windows 10 Fall Creator Update (FCU) from [this][3] page. Once FCU is installed, go to Update Settings (just search for “updates” in the search box of the Start menu) and install any available updates. +如果您安装了之前的版本,您有必要在 [这里][3] 下载并且安装 Windows 10 Fall Creator Update (FCU)。安装完毕后,更新设置(在开始菜单的搜索框中搜索 “updates”)。 -Go to Turn Windows Features On or Off (you know the drill by now) and scroll to the bottom and tick on the box Windows Subsystem for Linux, as shown in the following figure. Click Ok. It will download and install the needed packages. +前往 `启用或关闭 Windows 功能` 页面,然后滚动至底部,如截图所示,勾选 `适用于 Linux 的 Windows 子系统`,点击确定。它将会下载安装需要的包。 ![oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7x][4] -Upon the completion of the installation, the system will offer to restart. Go ahead and reboot your machine. WSL won’t launch without a system reboot, as shown below: +安装完成之后,系统将会询问是否重启。是的,重启设备吧。WSL 在系统重启之前不会启动,如下所示: ![GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aN][5] -Once your system starts, go back to the Turn features on or off setting to confirm that the box next to Windows Subsystem for Linux is selected. +一旦您的系统重启,返回 `启用或关闭 Windows 功能` 页面,确认 `适用于 Linux 的 Windows 子系统` 已经被勾选。 -### Install Linux in Windows +### 在 Windows 中安装 Linux -There are many ways to install Linux on Windows, but we will choose the easiest way. Open the Windows Store and search for Linux. You will see the following option: +在 Windows 中安装 Linux,有很多方式,这里我们选择一种最简单的方式。打开 Microsoft Store,搜索 Linux。您将看到下面的选项: ![YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7][6] -Click on Get the apps, and Windows Store will provide you with three options: Ubuntu, openSUSE Leap 42, and SUSE Linux Enterprise Server. You can install all three distributions side by side and run all three distributions simultaneously. To be able to use SLE, you need a subscription. +点击 `获取`,之后 Windows 商店将会提供三个选项:Ubuntu,openSUSE Leap 42 和 SUSE Linux Enterprise Server。您可以一并安装上述三个发行版,并且它们可以同时运行。为了能使用 SLE,您需要订阅消息。 -In this case, I am installing openSUSE Leap 42 and Ubuntu. Select your desired distro and click on the Get button to install it. Once installed, you can launch openSUSE in Windows. It can be pinned to the Start menu for quick access. +在此,我将安装 openSUSE Leap 42 和 Ubuntu。选中您想要的发行版,点击获得按钮并安装。一旦安装完毕,您就可以在 Windows 中启动 openSUSE。为了方便访问,可以将其固定到开始菜单中。 ![4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OA][7] -### Using Linux in Windows +### 在 Windwods 中使用 Linux -When you launch the distro, it will open the Bash shell and install the distro. Once installed, you can go ahead and start using it. Simple. Just bear in mind that there is no user in openSUSE and it runs as root user, whereas Ubuntu will ask you to create a user. On Ubuntu, you can perform administrative tasks as sudo user. +当您启动发行版,它将会打开一个 Bash Shell 并且安装此发行版。安装完毕之后,您就可以开始使用了。您需要留意,openSUSE 中并没有用户,它直接运行在 root 用户下,但是 Ubuntu 会询问您是否创建用户。在 Ubuntu,您可以执行 sudo 用户管理任务。 -You can easily create a user on openSUSE: +在 openSUSE 上,您可以很轻松的创建一个用户: ``` # useradd [username] @@ -51,7 +49,7 @@ You can easily create a user on openSUSE: ``` -Create a new password for the user and you are all set. For example: +为此用户创建一个新的密码。例如: ``` # useradd swapnil @@ -59,21 +57,21 @@ Create a new password for the user and you are all set. For example: ``` -You can switch from root to this use by running the su command: +您可以通过 su 命令从 root 用户切换过来。 ``` su swapnil ``` -You do need non-root use to perform many tasks, like using commands like rsync to move files on your local machine. +您需要非根用户来执行许多任务,比如使用 rsync 移动文件到本地设备。 -The first thing you need to do is update the distro. For openSUSE: +而首要任务是更新发行版。对于 openSUSE 来说,您应该: ``` zypper up ``` -For Ubuntu: +而对于 Ubuntu: ``` sudo apt-get update @@ -83,28 +81,28 @@ sudo apt-get dist-upgrade ![7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9][8] -You now have native Linux Bash shell on Windows. Want to ssh into your server from Windows 10? There’s no need to install puTTY or Cygwin. Just open Bash and then ssh into your server. Easy peasy. +现在,您就在 Windows 上拥有了原生 Linux Bash shell。想在 Windows 10 上通过 ssh 连接您的服务器?不需要安装 puTTY 或是 Cygwin。打开 Bash 之后,就可以通过 ssh 进入您的服务器。简单之至。 -Want to rsync files to your server? Go ahead and use rsync. It really transforms Windows into a usable machine for those Windows users who want to use native Linux command linux tools on their machines without having to deal with VMs. +想通过 rsync 同步文件到您的服务器?直接使用 rsync。它切实的将我们的 Windows 设备转变得更为实用,帮助那些需要使用原生 Linux 命令和 Linux 工具的用户避开虚拟机,大开方便之门。 -### Where is Fedora? +### 找不到 Fedora? -You may be wondering about Fedora. Unfortunately, Fedora is not yet available through the store. Matthew Miller, the release manager of Fedora said on Twitter, “We're working on resolving some non-technical issues. I'm afraid I don't have any more than that right now.” +您可能想了解 Fedora。可惜,商城里并没有 Fedora。Fedora 项目发布负责人在 Twitter 上表示,“我们正在解决一些非技术性问题。现在可能提供不了更多了。” -We don’t know yet what these non-technical issues are. When some users asked why the WSL team could not publish Fedora themselves --- after all it’s an open source project -- Rich Turner, a project manager at Microsoft [responded][9], “We have a policy of not publishing others' IP into the store. We believe that the community would MUCH prefer to see a distro published by the distro owner vs. seeing it published by Microsoft or anyone else that isn't the authoritative source.” +我们并不确定这些非技术性问题是什么。当一些用户询问 WSL 团队为何不发布 Fedora,毕竟它也是一个开源项目。项目负责人 Rich Turner 在 Microsoft [回应][9],“我们没有发布其他 IP 到应用商店的政策。我们相信,相较于被微软或是其他非权威人士,社区更希望看到发行版由发行版所有者发布。” -So, Microsoft can’t just go ahead and publish Debian or Arch Linux on Windows Store. The onus is on the official communities to bring their distros to Windows 10 users. +因此,微软不方便在 Windows 商店中直接发布 Debian 或是 Arch 系统。这些任务应该落在他们的官方团队中,应该由他们将发行版带给 Windows 10 的用户。 -### What’s next +### 欲知后事,下回分解 -In the next article, we will talk about using Windows 10 as a Linux machine and performing most of the tasks that you would perform on your Linux system using the command-line tools. +下一篇文章,我们会讨论关于将 Windows 10 作为 Linux 设备,并且向您展示,您可能会在 Linux 系统上使用的命令行工具。 -------------------------------------------------------------------------------- via: https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-10 作者:[SWAPNIL BHARTIYA][a] -译者:[译者ID](https://github.com/译者ID) +译者:[CYLeft](https://github.com/CYLeft) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 3d5f11cc3aedcc794a2067e198c165d54aa0e2f7 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 26 Feb 2018 23:53:48 +0800 Subject: [PATCH 009/101] PRF:20180104 Whats behind the Intel design flaw forcing numerous patches.md @qhwdw --- ...el design flaw forcing numerous patches.md | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md b/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md index d0c247d6b3..9c264be0ac 100644 --- a/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md +++ b/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md @@ -1,73 +1,71 @@ Intel 设计缺陷背后的原因是什么? ============================================================ -### 我们知道有问题,但是并不知道问题的详细情况。 - +> 我们知道有问题,但是并不知道问题的详细情况。 ![](https://cdn.arstechnica.net/wp-content/uploads/2015/06/intel-48-core-larrabee-probably-640x427.jpg) +(本文发表于 1 月份)最近 Windows 和 Linux 都发送了重大安全更新,为防范这个尚未完全公开的问题,在最坏的情况下,它可能会导致性能下降多达一半。 -最近 Windows 和 Linux 都发送了重大安全更新,为防范这个尚未完全公开的问题,在最坏的情况下,它可能会导致性能下降多达一半。 +在过去的几周,Linux 内核陆续打了几个补丁。Microsoft [自 11 月份开始也内部测试了 Windows 更新][3],并且它预计在下周二的例行补丁中将这个改进推送到主流 Windows 构建版中。Microsoft 的 Azure 也在下周的维护窗口中做好了安排,而 Amazon 的 AWS 也安排在周五对相关的设施进行维护。 -在过去的几周,Linux 内核陆续打了几个补丁。Microsoft [自 11 月份开始也内部测试了 Windows 更新][3],并且它预计在下周二的例行补丁中将这个改进推送到主流 Windows 构建版中。Microsoft 的 Azure 也在下周的维护窗口中做好了安排,而 Amazon 的 AWS 也安排在周五对相关的设施进行维护。 - -自从 Linux 第一个补丁 [KPTI:内核页表隔离的当前的发展][4] ,明确描绘了出现的错误以后。虽然 Linux 和 Windows 基于不同的考虑,对此持有不同的看法,但是这两个操作系统 — 当然还有其它的 x86 操作系统,比如 FreeBSD 和 [macOS][5] — 对系统内存的处理采用了相同的方式,因为对于操作系统在这一部分特性是与底层的处理器高度耦合的。 +自从 Linux 第一个补丁 (参见 [KPTI:内核页表隔离的当前的发展][4]) 明确描绘了出现的错误以后。虽然 Linux 和 Windows 基于不同的考虑,对此持有不同的看法,但是这两个操作系统 —— 当然还有其它的 x86 操作系统,比如 FreeBSD 和 [macOS][5] — 对系统内存的处理采用了相同的方式,因为对于操作系统在这一部分特性是与底层的处理器高度耦合的。 ### 保持地址跟踪 -在一个系统中的每个内存字节都是隐性编码的,这些数字是每个字节的地址。早期的操作系统使用物理内存地址,但是,物理内存地址由于各种原因,它并不很合适。例如,在地址中经常会有空隙,并且(尤其是 32 位的系统上)物理地址很难操作,需要 36 位的数字,甚至更多。 +在一个系统中的每个内存字节都是隐性编码的,这些编码数字是每个字节的地址。早期的操作系统使用物理内存地址,但是,物理内存地址由于各种原因,它并不很合适。例如,在地址中经常会有空隙,并且(尤其是 32 位的系统上)物理地址很难操作,需要 36 位数字,甚至更多。 -因此,现在操作系统完全依赖一个叫虚拟内存的概念。虚拟内存系统允许程序和内核一起在一个简单、清晰、统一的环境中各自去操作。而不是使用空隙和其它奇怪的东西的物理内存,每个程序和内核自身都使用虚拟地址去访问内存。这些虚拟地址是连续的 — 不用担心有空隙 — 并且合适的大小也更便于操作。32 位的程序仅可以看到 32 位的地址,而不用管物理地址是 36 位还是更多位。 +因此,现在操作系统完全依赖一个叫虚拟内存的概念。虚拟内存系统允许程序和内核一起在一个简单、清晰、统一的环境中各自去操作。而不是使用空隙和其它奇怪的东西的物理内存,每个程序和内核自身都使用虚拟地址去访问内存。这些虚拟地址是连续的 —— 不用担心有空隙 —— 并且合适的大小也更便于操作。32 位的程序仅可以看到 32 位的地址,而不用管物理地址是 36 位还是更多位。 虽然虚拟地址对每个软件几乎是透明的,但是,处理器最终还是需要知道虚拟地址引用的物理地址是哪个。因此,有一个虚拟地址到物理地址的映射,它保存在一个被称为页面表的数据结构中。操作系统构建页面表,使用一个由处理器决定的布局,并且处理器和操作系统在虚拟地址和物理地址之间进行转换时就需要用到页面表。 -这个映射过程是非常重要的,它也是现代操作系统和处理器的重要基础,处理器有专用的缓存 — translation lookaside buffer(简称 TLB)— 它保存了一定数量的虚拟地址到物理地址的映射,这样就不需要每次都使用全部页面。 +这个映射过程是非常重要的,它也是现代操作系统和处理器的重要基础,处理器有专用的缓存 — Translation Lookaside Buffer(简称 TLB)—— 它保存了一定数量的虚拟地址到物理地址的映射,这样就不需要每次都使用全部页面。 虚拟内存的使用为我们提供了很多除了简单寻址之外的有用的特性。其中最主要的是,每个程序都有了自己独立的一组虚拟地址,有了它自己的一组虚拟地址到物理地址的映射。这就是用于提供“内存保护”的关键技术,一个程序不能破坏或者篡改其它程序使用的内存,因为其它程序的内存并不在它的地址映射范围之内。 -由于每个进程使用一个单独的映射,因此每个程序也就有了一个额外的页面表,这就使得 TLB 缓存很拥挤。TLB 并不大 — 一般情况下总共可以容纳几百个映射 — 而系统使用的页面表越多,TLB 能够包含的任何特定的虚拟地址到物理地址的映射就越少。 +由于每个进程使用一个单独的映射,因此每个程序也就有了一个额外的页面表,这就使得 TLB 缓存很拥挤。TLB 并不大 —— 一般情况下总共可以容纳几百个映射 —— 而系统使用的页面表越多,TLB 能够包含的任何特定的虚拟地址到物理地址的映射就越少。 ### 一半一半 -为了更好地使用 TLB,每个主流的操作系统都将虚拟地址范围一分为二。一半用于程序;另一半用于内核。当进程切换时,仅有一半的页面表条目发生变化 — 仅属于程序的那一半。内核的那一半是每个程序公用的(因为只有一个内核)并且因此它可以为每个进程使用相同的页面表映射。这对 TLB 的帮助非常大;虽然它仍然会丢弃属于进程的那一半内存地址映射;但是它还保持着另一半属于内核的映射。 +为了更好地使用 TLB,每个主流的操作系统都将虚拟地址范围一分为二。一半用于程序;另一半用于内核。当进程切换时,仅有一半的页面表条目发生变化 —— 仅属于程序的那一半。内核的那一半是每个程序公用的(因为只有一个内核)并且因此它可以为每个进程使用相同的页面表映射。这对 TLB 的帮助非常大;虽然它仍然会丢弃属于进程的那一半内存地址映射;但是它还保持着另一半属于内核的映射。 这种设计并不是一成不变的。在 Linux 上做了一项工作,使它可以为一个 32 位的进程提供整个地址范围,而不用在内核页面表和每个进程之间共享。虽然这样为程序提供了更多的地址空间,但这是以牺牲性能为代价的,因为每次内核代码需要运行时,TLB 重新加载内核的页面表条目。因此,这种方法并没有广泛应用到 x86 的系统上。 在内核和每个程序之间分割虚拟地址的这种做法的一个负面影响是,内存保护被削弱了。如果内核有它自己的一组页面表和虚拟地址,它将在不同的程序之间提供相同的保护;内核内存将是简单的不可见。但是使用地址分割之后,用户程序和内核使用了相同的地址范围,并且从原理上来说,一个用户程序有可能去读写内核内存。 -为避免这种明显不好的情况,处理器和虚拟地址系统有一个 “Ring" 或者 ”模式“的概念。x86 处理器有许多 rings,但是对于这个问题,仅有两个是相关的:"user" (ring 3)和 "supervisor"(ring 0)。当运行普通的用户程序时,处理器将置为用户模式 (ring 3)。当运行内核代码时,处理器将处于 ring 0 —— supervisor 模式,也称为内核模式。 +为避免这种明显不好的情况,处理器和虚拟地址系统有一个 “Ring” 或者 “模式”的概念。x86 处理器有许多 Ring,但是对于这个问题,仅有两个是相关的:“user” (Ring 3)和 “supervisor”(ring 0)。当运行普通的用户程序时,处理器将置为用户模式 (Ring 3)。当运行内核代码时,处理器将处于 Ring 0 —— supervisor 模式,也称为内核模式。 -这些 rings 也用于从用户程序中保护内核内存。页面表并不仅仅有虚拟地址到物理地址的映射;它也包含关于这些地址的元数据,包含哪个 rings 可能访问哪个地址的信息。内核页面表条目被标记为仅 ring 0 可以访问;程序的条目被标记为任何 ring 都可以访问。如果一个处于 ring 3 中的进程去尝试访问标记为 ring 0 的内存,处理器将阻止这个访问并生成一个意外错误信息。运行在 ring 3 中的用户程序不能得到内核以及运行在 ring 0 内存中的任何东西。 +这些 Ring 也用于从用户程序中保护内核内存。页面表并不仅仅有虚拟地址到物理地址的映射;它也包含关于这些地址的元数据,包含哪个 Ring 可能访问哪个地址的信息。内核页面表条目被标记为仅有 Ring 0 可以访问;程序的条目被标记为任何 Ring 都可以访问。如果一个处于 Ring 3 中的进程去尝试访问标记为 Ring 0 的内存,处理器将阻止这个访问并生成一个意外错误信息。运行在 Ring 3 中的用户程序不能得到内核以及运行在 Ring 0 内存中的任何东西。 至少理论上是这样的。大量的补丁和更新表明,这个地方已经被突破了。这就是最大的谜团所在。 ### Ring 间迁移 -这就是我们所知道的。每个现代处理器都执行一定数量的推测运行。例如,给一些指令,让两个数加起来,然后将结果保存在内存中,在查明内存中的目标是否可访问和可写入之前,一个处理器可能已经推测性地做了加法。在一些常见案例中,在位置是可写入的地方,处理器节省了一些时间,因为它以并行方式计算出内存中的目标是什么。如果它发现目标位置不可写入 — 例如,一个程序尝试去写入到一个没有映射的地址以及压根就不存在的物理位置— 然后它将产生一个意外错误,而推测运行就白做了。 +这就是我们所知道的。每个现代处理器都执行一定数量的推测运行。例如,给一些指令,让两个数加起来,然后将结果保存在内存中,在查明内存中的目标是否可访问和可写入之前,一个处理器可能已经推测性地做了加法。在一些常见案例中,在地址可写入的地方,处理器节省了一些时间,因为它以并行方式计算出内存中的目标是什么。如果它发现目标位置不可写入 —— 例如,一个程序尝试去写入到一个没有映射的地址或压根就不存在的物理位置 —— 然后它将产生一个意外错误,而推测运行就白做了。 -Intel 处理器,尤其是 — [虽然不是 AMD 的][6] — 但允许对 ring 3 代码进行推测运行并写入到 ring 0 内存中的处理器上。处理器并不完全阻止这种写入,但是推测运行轻微扰乱了处理器状态,因为,为了查明目标位置是否可写入,某些数据已经被加载到缓存和 TLB 中。这又意味着一些操作可能快几个周期,或者慢几个周期,这取决于它们所需要的数据是否仍然在缓存中。除此之外,Intel 的处理器还有一些特殊的功能,比如,在 Skylake 处理器上引入的软件保护扩展(SGX)指令,它改变了一点点访问内存的方式。同样的,处理器仍然是保护 ring 0 的内存不被来自 ring 3 的程序所访问,但是同样的,它的缓存和其它内部状态已经发生了变化,产生了可测量的差异。 +Intel 处理器,尤其是([虽然不是 AMD 的][6])允许对 Ring 3 代码进行推测运行并写入到 Ring 0 内存中的处理器上。处理器并不完全阻止这种写入,但是推测运行轻微扰乱了处理器状态,因为,为了查明目标位置是否可写入,某些数据已经被加载到缓存和 TLB 中。这又意味着一些操作可能快几个周期,或者慢几个周期,这取决于它们所需要的数据是否仍然在缓存中。除此之外,Intel 的处理器还有一些特殊的功能,比如,在 Skylake 处理器上引入的软件保护扩展(SGX)指令,它改变了一点点访问内存的方式。同样的,处理器仍然是保护 Ring 0 的内存不被来自 Ring 3 的程序所访问,但是同样的,它的缓存和其它内部状态已经发生了变化,产生了可测量的差异。 -我们至今仍然并不知道具体的情况,到底有多少内核的内存信息泄露给了用户程序,或者信息泄露的情况有多容易发生。以及有哪些 Intel 处理器会受到影响?也或者并不完全清楚,但是,有迹象表明每个 Intel 芯片都使用了推测运行(是自 1995 年 Pentium Pro 以来的,所有主流处理器吗?),它们都可能会因此而泄露信息。 +我们至今仍然并不知道具体的情况,到底有多少内核的内存信息泄露给了用户程序,或者信息泄露的情况有多容易发生。以及有哪些 Intel 处理器会受到影响?也或者并不完全清楚,但是,有迹象表明每个 Intel 芯片都使用了推测运行(是自 1995 年 Pentium Pro 以来的所有主流处理器吗?),它们都可能会因此而泄露信息。 这个问题第一次被披露是由来自 [奥地利的 Graz Technical University][7] 的研究者。他们披露的信息表明这个问题已经足够破坏内核模式地址空间布局随机化(内核 ASLR,或称 KASLR)。ASLR 是防范 [缓冲区溢出][8] 漏洞利用的最后一道防线。启用 ASLR 之后,程序和它们的数据被置于随机的内存地址中,它将使一些安全漏洞利用更加困难。KASLR 将这种随机化应用到内核中,这样就使内核的数据(包括页面表)和代码也随机化分布。 Graz 的研究者开发了 [KAISER][9],一组防范这个问题的 Linux 内核补丁。 -如果这个问题正好使 ASLR 的随机化被破坏了,这或许将成为一个巨大的灾难。ASLR 是一个非常强大的保护措施,但是它并不是完美的,这意味着对于黑客来说将是一个很大的障碍,一个无法逾越的障碍。整个行业对此的反应是 — Windows 和 Linux 都有一个非常重要的变化,秘密开发 — 这表明不仅是 ASLR 被破坏了,而且从内核泄露出信息的更普遍的技术被开发出来了。确实是这样的,研究者已经 [在 tweet 上发布信息][10],他们已经可以随意泄露和读取内核数据了。另一种可能是,漏洞可能被用于从虚拟机中”越狱“,并可能会危及 hypervisor。 +如果这个问题正好使 ASLR 的随机化被破坏了,这或许将成为一个巨大的灾难。ASLR 是一个非常强大的保护措施,但是它并不是完美的,这意味着对于黑客来说将是一个很大的障碍,一个无法逾越的障碍。整个行业对此的反应是 —— Windows 和 Linux 都有一个非常重要的变化,秘密开发 —— 这表明不仅是 ASLR 被破坏了,而且从内核泄露出信息的更普遍的技术被开发出来了。确实是这样的,研究者已经 [在 Twitter 上发布信息][10],他们已经可以随意泄露和读取内核数据了。另一种可能是,漏洞可能被用于从虚拟机中“越狱”,并可能会危及 hypervisor。 Windows 和 Linux 选择的解决方案是非常相似的,将 KAISER 分为两个区域:内核页面表的条目不再是由每个进程共享。在 Linux 中,这被称为内核页面表隔离(KPTI)。 -应用补丁后,内存地址仍然被一分为二:这样使内核的那一半几乎是空的。当然它并不是非常的空,因为一些内核片断需要永久映射,不论进程是运行在 ring 3 还是 ring 0 中,它都几乎是空的。这意味着如果恶意用户程序尝试去探测内核内存以及泄露信息,它将会失败 — 因为那里几乎没有信息。而真正的内核页面中只有当内核自身运行的时刻它才能被用到。 +应用补丁后,内存地址仍然被一分为二:这样使内核的那一半几乎是空的。当然它并不是非常的空,因为一些内核片断需要永久映射,不论进程是运行在 Ring 3 还是 Ring 0 中,它都几乎是空的。这意味着如果恶意用户程序尝试去探测内核内存以及泄露信息,它将会失败 —— 因为那里几乎没有信息。而真正的内核页面中只有当内核自身运行的时刻它才能被用到。 这样做就破坏了最初将地址空间分割的理由。现在,每次切换到用户程序时,TLB 需要实时去清除与内核页面表相关的所有条目,这样就失去了启用分割带来的性能提升。 -影响的具体大小取决于工作负载。每当一个程序被调入到内核 — 从磁盘读入、发送数据到网络、打开一个文件等等 — 这种调用的成本可能会增加一点点,因为它强制 TLB 清除了缓存并实时加载内核页面表。不使用内核的程序可能会观测到 2 - 3 个百分点的性能影响 — 这里仍然有一些开销,因为内核仍然是偶尔会运行去处理一些事情,比如多任务等等。 +影响的具体大小取决于工作负载。每当一个程序被调入到内核 —— 从磁盘读入、发送数据到网络、打开一个文件等等 —— 这种调用的成本可能会增加一点点,因为它强制 TLB 清除了缓存并实时加载内核页面表。不使用内核的程序可能会观测到 2 - 3 个百分点的性能影响 —— 这里仍然有一些开销,因为内核仍然是偶尔会运行去处理一些事情,比如多任务等等。 但是大量调用进入到内核的工作负载将观测到很大的性能损失。在一个基准测试中,一个除了调入到内核之外什么都不做的程序,观察到 [它的性能下降大约为 50%][11];换句话说就是,打补丁后每次对内核的调用的时间要比不打补丁调用内核的时间增加一倍。基准测试使用的 Linux 的网络回环(loopback)也观测到一个很大的影响,比如,在 Postgres 的基准测试中大约是 [17%][12]。真实的数据库负载使用了实时网络可能观测到的影响要低一些,因为使用实时网络时,内核调用的开销基本是使用真实网络的开销。 -虽然对 Intel 系统的影响是众所周知的,但是它们可能并不是唯一受影响的。其它的一些平台,比如 SPARC 和 IBM 的 S390,是不受这个问题影响的,因为它们的处理器的内存管理并不需要分割地址空间和共享内核页面表;在这些平台上的操作系统一直就是将它们的内核页面表从用户模式中隔离出来的。但是其它的,比如 ARM,可能就没有这么幸运了;[适用于 ARM Linux 的类似补丁][13] 正在开发中。 +虽然对 Intel 系统的影响是众所周知的,但是它们可能并不是唯一受影响的。其它的一些平台,比如 SPARC 和 IBM 的 S390,是不受这个问题影响的,因为它们的处理器的内存管理并不需要分割地址空间和共享内核页面表;在这些平台上的操作系统一直就是将它们的内核页面表从用户模式中隔离出来的。但是其它的,比如 ARM,可能就没有这么幸运了;[适用于 ARM Linux 的类似补丁][13] 正在开发中。 - +--- [][15][PETER BRIGHT][14] 是 Ars 的一位技术编辑。他涉及微软、编程及软件开发、Web 技术和浏览器、以及安全方面。它居住在纽约的布鲁克林。 @@ -75,9 +73,9 @@ Windows 和 Linux 选择的解决方案是非常相似的,将 KAISER 分为两 via: https://arstechnica.com/gadgets/2018/01/whats-behind-the-intel-design-flaw-forcing-numerous-patches/ -作者:[ PETER BRIGHT ][a] +作者:[PETER BRIGHT][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 5ebc5f0f509136d6e2047718e924dc85ddba90d9 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 26 Feb 2018 23:54:08 +0800 Subject: [PATCH 010/101] PUB:20180104 Whats behind the Intel design flaw forcing numerous patches.md @qhwdw https://linux.cn/article-9387-1.html --- ...Whats behind the Intel design flaw forcing numerous patches.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180104 Whats behind the Intel design flaw forcing numerous patches.md (100%) diff --git a/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md b/published/20180104 Whats behind the Intel design flaw forcing numerous patches.md similarity index 100% rename from translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md rename to published/20180104 Whats behind the Intel design flaw forcing numerous patches.md From 9d1717cbde11376c5e099054c642bf40345dca71 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 00:09:16 +0800 Subject: [PATCH 011/101] PRF:20171201 Torrents - Everything You Need to Know.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @qhwdw 考虑到翻译的一致性,我将 Torrents 翻译为“种子”了。 --- ... Torrents - Everything You Need to Know.md | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/translated/tech/20171201 Torrents - Everything You Need to Know.md b/translated/tech/20171201 Torrents - Everything You Need to Know.md index 5dde161566..0cf3389e8d 100644 --- a/translated/tech/20171201 Torrents - Everything You Need to Know.md +++ b/translated/tech/20171201 Torrents - Everything You Need to Know.md @@ -1,25 +1,25 @@ -Torrents - 你需要知道的一切事情 +Torrents(种子):你需要知道的一切事情 ====== ![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrenting-how-torrent-works_orig.jpg) -**Torrents** — 每次听到这个词时,在我的脑海里想到的唯一的事情就是免费的电影、游戏、和被破解的软件。但是我们并不知道它们是如何工作的,在 Torrents 中涉及到各种概念。因此,通过这篇文章我们从技术的角度来了解 **torrenting** 是什么。 +**Torrents(种子)** — 每次听到这个词时,在我的脑海里想到的唯一的事情就是免费的电影、游戏、和被破解的软件。但是我们并不知道它们是如何工作的,在“种子”中涉及到各种概念。因此,通过这篇文章我们从技术的角度来了解**种子下载**是什么。 -### Torrents 是什么? +### “种子”是什么? -Torrents 是一个到因特网上文件位置的链接。它们不是一个文件,它们仅仅是动态指向到你想去下载的原始文件上。 +“种子”是一个到因特网上文件位置的链接。它们不是一个文件,它们仅仅是动态指向到你想去下载的原始文件上。 例如:如果你点击 [Google Chrome][1],你可以从谷歌的服务器上下载 Google Chrome 浏览器。 如果你明天、或者下周、或者下个月再去点击那个链接,这个文件仍然可以从谷歌服务器上去下载。 -但是当我们使用 torrents 下载时,它并没有固定的服务器。文件是从以前使用 torrents 下载的其它人的个人电脑上下载的。 +但是当我们使用“种子”下载时,它并没有固定的服务器。文件是从以前使用“种子”下载的其它人的个人电脑上下载的。 ### Torrents 是如何工作的? [![Peer to peer network](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrent_orig.png)][2] -假设 ‘A’ 上有一些视频,它希望以 torrent 方式去下载。因此,他创建了一个 torrent,并将这个链接发送给 ‘B’,这个链接包含了那个视频在因特网上的准确 IP 地址的信息。因此,当 ‘B’ 开始下载那个文件的时候,‘B’ 连接到 ‘A’ 的计算机。在 ‘B’ 下载完成这个视频之后,‘B’ 将开始做为种子,也就是 ‘B’ 将允许其它的 ‘C’ 或者 ‘D’ 从 ‘B’ 的计算机上下载它。 +假设 ‘A’ 上有一些视频,它希望以“种子”方式去下载。因此,他创建了一个“种子”,并将这个链接发送给 ‘B’,这个链接包含了那个视频在因特网上的准确 IP 地址的信息。因此,当 ‘B’ 开始下载那个文件的时候,‘B’ 连接到 ‘A’ 的计算机。在 ‘B’ 下载完成这个视频之后,‘B’ 将开始做为种子,也就是 ‘B’ 将允许其它的 ‘C’ 或者 ‘D’ 从 ‘B’ 的计算机上下载它。 因此每个人先下载文件然后会上传,下载的人越多,下载的速度也越快。并且在任何情况下,如果想停止上传,也没有问题,随时可以。这样做并不会成为什么问题,除非很多的人下载而上传的人很少。 @@ -35,7 +35,7 @@ Torrents 是一个到因特网上文件位置的链接。它们不是一个文 [![qbittorrent software for linux](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/peers_orig.png)][4] -所有的 torrent 文件都独立分割成固定大小的数据包,因此,它们可以非线性顺序和随机顺序下载。每个块都有唯一的标识,因此,一旦所有的块下载完成之后,它们会被拼接出原始文件。 +所有的“种子”文件都独立分割成固定大小的数据包,因此,它们可以非线性顺序和随机顺序下载。每个块都有唯一的标识,因此,一旦所有的块下载完成之后,它们会被拼接出原始文件。 正是因为这种机制,如果你正在从某人处下载一个文件,假如这个时候因某些原因他停止了上传,你可以继续从其它的播种者处继续下载,而不需要从头开始重新下载。 @@ -49,23 +49,23 @@ Torrents 是一个到因特网上文件位置的链接。它们不是一个文 ### 最佳实践 -当你下载一个 torrent 时,总是选择最大的播种者。这就是最佳经验。 +当你下载一个“种子”时,总是选择最大的播种者。这就是最佳经验。 这里并没有最小的标准,但是只要确保你选择的是最大的那一个播种者就可以了。 -### Torrent 相关的法律 +### “种子”相关的法律 [![piracy is illegal](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrent-laws_orig.png)][5] -Torrent 相关的法律和其它的法律并没有什么区别,对受版权保护的其它任何东西一样,侵权行为会受到法律的制裁。大多数的政府都拦截 torrent 站点和协议,但是 torrenting 本身并不是有害的东西。 +“种子”相关的法律和其它的法律并没有什么区别,对受版权保护的其它任何东西一样,侵权行为会受到法律的制裁。大多数的政府都拦截“种子”站点和协议,但是“种子”下载本身并不是有害的东西。 -Torrents 对快速分享文件是非常有用的,并且它们被用来共享开源社区的软件,因为它们能节约大量的服务器资源。但是,许多人却因为盗版而使用它们。 +“种子”对快速分享文件是非常有用的,并且它们被用来共享开源社区的软件,因为它们能节约大量的服务器资源。但是,许多人却因为盗版而使用它们。 ### 结束语 -Torrenting 是降低服务器上负载的一个非常完美的技术。Torrenting 可以使我们将下载速度提升到网卡的极限,这是非常好的。但是,在这种非中心化的服务器上,盗版成为一种必然发生的事。限制我们分享的内容,从不去下载盗版的东西,这是我们的道德责任。 +Torrenting 是降低服务器上负载的一个非常完美的技术。“种子”下载可以使我们将下载速度提升到网卡的极限,这是非常好的。但是,在这种非中心化的服务器上,盗版成为一种必然发生的事。限制我们分享的内容,从不去下载盗版的东西,这是我们的道德责任。 -请在下面的评论中分享你使用 torrents 的心得,分享你喜欢的、法律许可下载的 torrent 网站。 +请在下面的评论中分享你使用“种子”的心得,分享你喜欢的、法律许可下载的“种子”网站。 -------------------------------------------------------------------------------- @@ -73,7 +73,7 @@ via: http://www.linuxandubuntu.com/home/torrents-everything-you-need-to-know 作者:[LINUXANDUBUNTU][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From f15a7c199c350f12b8c5888389139bd5de217e2b Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 00:10:09 +0800 Subject: [PATCH 012/101] PUB:20171201 Torrents - Everything You Need to Know.md @qhwdw --- .../20171201 Torrents - Everything You Need to Know.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171201 Torrents - Everything You Need to Know.md (100%) diff --git a/translated/tech/20171201 Torrents - Everything You Need to Know.md b/published/20171201 Torrents - Everything You Need to Know.md similarity index 100% rename from translated/tech/20171201 Torrents - Everything You Need to Know.md rename to published/20171201 Torrents - Everything You Need to Know.md From bfc599d5fc703436ac705e5b9a1da6f6b15d477e Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 06:47:20 +0800 Subject: [PATCH 013/101] PRF:20171023 Processors-Everything You Need to Know.md @singledo --- ... Processors-Everything You Need to Know.md | 147 ++++++++++-------- 1 file changed, 83 insertions(+), 64 deletions(-) diff --git a/translated/tech/20171023 Processors-Everything You Need to Know.md b/translated/tech/20171023 Processors-Everything You Need to Know.md index b0a7d2dc3c..a7bfa40156 100644 --- a/translated/tech/20171023 Processors-Everything You Need to Know.md +++ b/translated/tech/20171023 Processors-Everything You Need to Know.md @@ -1,73 +1,92 @@ -# 关于处理器你需要知道的每件事 +关于处理器你所需要知道的一切 +============ [![][b]][b] -``` - 我们的手机 ,主机以及笔记本电脑已经成长得如此的成熟 ,以至于它们进化成为我们的一部分 ,而不只是一种设备 。 - 在应用和软件的帮助下 ,处理器执行许多任务 。我们是否曾经想过是什么给了这些软件这样的能力 ?它们是如何执行他们的逻辑的 ?它们的大脑在哪 ? - 我们知道 CPU 或者是处理器是那些需要处理数据和执行逻辑任务设备的大脑 。 -`` + +我们的手机、主机以及笔记本电脑这样的数字设备已经变得如此成熟,以至于它们进化成为我们的一部分,而不只是一种设备。 + +在应用和软件的帮助下,处理器执行许多任务。我们是否曾经想过是什么给了这些软件这样的能力?它们是如何执行它们的逻辑的?它们的大脑在哪? + +我们知道 CPU (或称处理器)是那些需要处理数据和执行逻辑任务的设备的大脑。 + [![cpu image][1]][1] -``` - 在处理器的深处有那些不一样的概念呢 ? 它们是如何进化的 ? 一些处理器是如何做到比其他处理器更快的 ? 我们来看看关于处理器的主要术语并且它们是如何影响处速度的 ? -``` -## 架构 -``` - 处理器有不同的架构 ,你一定偶遇过不同种类的那种你说它们是 64 位或 32 位的程序 ,其中的意思是程序支持特定的处理器架构 。 - 如果一颗处理器是 32 位的架构 ,意味着这颗处理器能够在一个处理周期内处理一个 32 位的数据 。同理可得 ,64 位的处理器能够在一个周期内处理一个 64 位的信息 。 - 你可以使用的 RAM 大小决定于处理器的架构 ,你可以使用的 RAM 总量为处理器架构的幂指数 。 - 16 位架构的处理器 ,仅仅有 64 kb 的 RAM 使用 。32 位架构的处理器 ,最大可使用的 RAM 是 4 GB ,64 位架构的处理器的可用 RAM 是 16 Exa-Byte 。 -``` -## 内核 -``` - 在电脑上 ,核心是基本的处理单元 。核心接收指令并且执行指令 。越多的核心带来越快的速度 。把核心当成工厂里的工人 ,越多的工人使工作能够越快的完成 。另一方面 ,工人越多 ,你所付出的薪水也就越多 ,工厂也会越拥挤 ;相对于核心来说 ,越多的合兴消耗更多的能量 ,比核心少的 CPU 更容易发热 。 -``` -## 时钟速度 + +在处理器的深处有那些不一样的概念呢?它们是如何演化的?一些处理器是如何做到比其它处理器更快的?让我们来看看关于处理器的主要术语,以及它们是如何影响处速度的。 + +### 架构 + +处理器有不同的架构,你一定遇到过不同类型的程序说它们是 64 位或 32 位的,这其中的意思就是程序支持特定的处理器架构。 + +如果一颗处理器是 32 位的架构,这意味着这颗处理器能够在一个处理周期内处理一个 32 位的数据。 + +同理可得,64 位的处理器能够在一个周期内处理一个 64 位的数据。 + +同时,你可以使用的内存大小决定于处理器的架构,你可以使用的内存总量为 2 的处理器架构的幂次方(如:`2^64`)。 + +16 位架构的处理器,仅仅有 64 kb 的内存使用。32 位架构的处理器,最大可使用的 RAM 是 4 GB,64 位架构的处理器的可用内存是 16 EB。 + +### 核心 + +在电脑上,核心是基本的处理单元。核心接收指令并且执行它。越多的核心带来越快的速度。把核心比作工厂里的工人,越多的工人使工作能够越快的完成。另一方面,工人越多,你所付出的薪水也就越多,工厂也会越拥挤;相对于核心来说,越多的核心消耗更多的能量,比核心少的 CPU 更容易发热。 + +### 时钟速度 + [![CPU CLOCK SPEED][2]][2] -``` - GHZ 是 GigaHertz 的简写 ,Giga 意思是 Billon ,Hertz 意思是一秒有几个周期 ,2 GHZ 的处理器意味着处理器一秒能够执行 2 百万个周期 。 - 也被作为 `频率` 或者 `时钟速度` 被熟知 。这项数值越高 ,CPU的性能越好 。 -``` -## CPU 缓存 -``` - CPU 缓存是处理器内部的一块小的存储单元 ,用来存储一些内存 。不管如何 ,我们都需要执行一些任务 ,数据需要从 RAM 传递到 CPU ,CPU 的工作速度远快于 RAM ,CPU 在大多数时间是在等待从 RAM 传递过来的数据 ,而此时 CPU 是处于空闲状态的 。为了解决这个问题 ,RAM 持续的向 CPU 缓存发送数据 。一般的处理器会有 2 ~ 3 M 的 CPU 缓存 。高端的处理器会有 6 M CPU 缓存 ,越大的缓存 ,意味着处理器更好 。 -``` -## 印刷工艺 -``` - 晶体管的大小就是处理器平板印刷的大小 ,尺寸通常是纳米 ,更小的尺寸意味者更好的兼容性 。这允许你更多的核心 ,更小的面积 ,更小的能量消耗 。 - 这最新的 Intel 处理器有 14 nm 的印刷工艺 。 -``` -## 热功耗设计 -``` - 代表这电池的能量 ,单位是瓦特 。在全核心激活以基本频率来处理 Intel 模式 ,高复杂度的负载是一种浪费处理器的行为 。 - 所以 ,越低的热功耗设计 ,对你越好 。一个低的热功耗设计不仅更好的利用电池能量 ,而且产生更少的热量 。 -``` + +GHz 是 GigaHertz 的简写,Giga 意思是 10 亿次,Hertz (赫兹)意思是一秒有几个周期,2 GHz 的处理器意味着处理器一秒能够执行 20 亿个周期 。 + +它也以“频率”或者“时钟速度”而熟知。这项数值越高,CPU 的性能越好。 + +### CPU 缓存 + +CPU 缓存是处理器内部的一块小的存储单元,用来存储一些内存。不管如何,我们需要执行一些任务时,数据需要从内存传递到 CPU,CPU 的工作速度远快于内存,CPU 在大多数时间是在等待从内存传递过来的数据,而此时 CPU 是处于空闲状态的。为了解决这个问题,内存持续的向 CPU 缓存发送数据。 + +一般的处理器会有 2 ~ 3 Mb 的 CPU 缓存。高端的处理器会有 6 Mb 的 CPU 缓存,越大的缓存,意味着处理器更好。 + +### 印刷工艺 + +晶体管的大小就是处理器平板印刷的大小,尺寸通常是纳米,更小的尺寸意味者更紧凑。这可以让你有更多的核心,更小的面积,更小的能量消耗。 + +最新的 Intel 处理器有 14 nm 的印刷工艺。 + +### 热功耗设计(TDP) + +代表着平均功耗,单位是瓦特,是在全核心激活以基础频率来处理 Intel 定义的高复杂度的负载时,处理器所散失的功耗。 + +所以,越低的热功耗设计对你越好。一个低的热功耗设计不仅可以更好的利用能量,而且产生更少的热量。 + [![battery][3]][3] -``` - 桌面版本的处理器通常消耗更多的能量 ,热功耗消耗的能量能够在 40% 以上 ,相对应的移动版本只有不到桌面版本的 1/3 。 -``` -## 内存支持 -``` - 我们已经提到了处理器的架构是如何影响到我们能够使用的内存总量 。这样我们只掌握了正确的理论 。在实际的应用中 ,RAM 的总量对于处理器的规格来说是足够我们使用的 ,由处理器规格详细规定 ,也包含支持的 DDR 版本的内存 。 -``` + +桌面版的处理器通常消耗更多的能量,热功耗消耗的能量能在 40% 以上,相对应的移动版本只有不到桌面版本的 1/3。 + +### 内存支持 + +我们已经提到了处理器的架构是如何影响到我们能够使用的内存总量,但这只是理论上而已。在实际的应用中,我们所能够使用的内存的总量对于处理器的规格来说是足够的,它通常是由处理器规格详细规定的。 + [![RAM][4]][4] -## 超频 -``` - 前面我们讲过时钟频率 ,超频是程序强迫 CPU 执行更多的周期 。游戏玩家经常会使他们的处理器超频 ,以此来获得更好的性能 。这样确实回增加速度 ,但也会增加消耗的能量 ,产生更多的热量 。 - 一些高端的处理器允许超频 ,如果我们想让一个不支持超平的处理器超频 ,我们需要在主板上安装一个新的 BIOS 。 - 这样通常下回成功 ,但这种情况是不安全的 ,也是不被建议的 。 -``` -## 超线程 -``` - 如果对特定的处理需要添加核心是不合适的 ,那么超线程回建立一个虚拟核心 。 - 当我们说双核处理器有超线程 ,这个双核处理器有两个物理核心和两个虚拟核心 ,在技术上讲 ,一个双核处理器拥有四核核心 。 -``` -## 结论 -``` - 一个处理器有许多相关的数据 ,这是对数字设备来说是最重要的部分 。我们在选择设备时 ,我们应该在脑海中仔细的检查处理器在上面提到的数据 。 - 时钟速度 ,核心数 ,CPU 缓存 ,以及架构是比重最大的数据 。印刷尺寸以及热功耗设计比重要小一些 。 - 仍然有疑惑 ? 欢迎评论 ,我会尽快回复的 。 -``` +它也指出了内存所支持的 DDR 的版本号。 + +### 超频 + +前面我们讲过时钟频率,超频是程序强迫 CPU 执行更多的周期。游戏玩家经常会使他们的处理器超频,以此来获得更好的性能。这样确实会增加速度,但也会增加消耗的能量,产生更多的热量。 + +一些高端的处理器允许超频,如果我们想让一个不支持超频的处理器超频,我们需要在主板上安装一个新的 BIOS 。 +这样通常会成功,但这种情况是不安全的,也是不建议的。 + +### 超线程(HT) + +如果不能添加核心以满足特定的处理需要,那么超线程是建立一个虚拟核心的方式。 + +如果一个双核处理器有超线程,那么这个双核处理器就有两个物理核心和两个虚拟核心,在技术上讲,一个双核处理器拥有四个核心。 + +### 结论 + +处理器有许多相关的数据,这些对数字设备来说是最重要的部分。我们在选择设备时,我们应该在脑海中仔细的检查处理器在上面提到的数据。 + +时钟速度、核心数、CPU 缓存,以及架构是最重要的数据。印刷尺寸以及热功耗设计重要性差一些 。 + +仍然有疑惑? 欢迎评论,我会尽快回复的。 -------------------------------------------------------------------------------- @@ -75,7 +94,7 @@ via: http://www.theitstuff.com/processors-everything-need-know 作者:[Rishabh Kandari][a] 译者:[singledo](https://github.com/singledo) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 531e956bf59210ee7b2f6084297904dc0290c013 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 06:47:45 +0800 Subject: [PATCH 014/101] PUB:20171023 Processors-Everything You Need to Know.md @singledo https://linux.cn/article-9389-1.html --- .../20171023 Processors-Everything You Need to Know.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171023 Processors-Everything You Need to Know.md (100%) diff --git a/translated/tech/20171023 Processors-Everything You Need to Know.md b/published/20171023 Processors-Everything You Need to Know.md similarity index 100% rename from translated/tech/20171023 Processors-Everything You Need to Know.md rename to published/20171023 Processors-Everything You Need to Know.md From b0002b5708fd6320155c1e9debdfce8e5cf591aa Mon Sep 17 00:00:00 2001 From: geekpi Date: Tue, 27 Feb 2018 08:55:43 +0800 Subject: [PATCH 015/101] translated --- ...heck if Your Computer Uses UEFI or BIOS.md | 93 ------------------- ...heck if Your Computer Uses UEFI or BIOS.md | 90 ++++++++++++++++++ 2 files changed, 90 insertions(+), 93 deletions(-) delete mode 100644 sources/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md create mode 100644 translated/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md diff --git a/sources/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md b/sources/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md deleted file mode 100644 index c9d1b08794..0000000000 --- a/sources/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md +++ /dev/null @@ -1,93 +0,0 @@ -translating---geekpi - - -How to Check if Your Computer Uses UEFI or BIOS -====== -**Brief: A quick tutorial to tell you if your system uses the modern UEFI or the legacy BIOS. Instructions for both Windows and Linux have been provided.** - -When you are trying to [dual boot Linux with Windows][1], you would want to know if you have UEFI or BIOS boot mode on your system. It helps you decide in partition making for installing Linux. - -I am not going to discuss [what is BIOS][2] here. However, I would like to tell you a few advantages of [UEFI][3] over BIOS. - -UEFI or Unified Extensible Firmware Interface was designed to overcome some of the limitations of BIOS. It added the ability to use larger than 2 TB disks and had a CPU independent architecture and drivers. With a modular design, it supported remote diagnostics and repairing even with no operating system installed and a flexible without-OS environment including networking capability. - -### Advantage of UEFI over BIOS - - * UEFI is faster in initializing your hardware. - * Offer Secure Boot which means everything you load before an OS is loaded has to be signed. This gives your system an added layer of protection from running malware. - * BIOS do not support a partition of over 2TB. - * Most importantly, if you are dual booting it’s always advisable to install both the OS in the same booting mode. - - - -![How to check if system has UEFI or BIOS][4] - -If you are trying to find out whether your system runs UEFI or BIOS, it’s not that difficult. Let me start with Windows first and afterward, we’ll see how to check UEFI or BIOS on Linux systems. - -### Check if you are using UEFI or BIOS on Windows - -On Windows, “System Information” in Start panel and under BIOS Mode, you can find the boot mode. If it says Legacy, your system has BIOS. If it says UEFI, well it’s UEFI. - -![][5] - -**Alternative** : If you using Windows 10, you can check whether you are using UEFI or BIOS by opening File Explorer and navigating to C:\Windows\Panther. Open file setupact.log and search for the below string. -``` -Detected boot environment - -``` - -I would advise opening this file in notepad++, since its a huge text file and notepad may hang (at least it did for me with 6GB RAM). - -You will find a couple of lines which will give you the information. -``` -2017-11-27 09:11:31, Info IBS Callback_BootEnvironmentDetect:FirmwareType 1. -2017-11-27 09:11:31, Info IBS Callback_BootEnvironmentDetect: Detected boot environment: BIOS - -``` - -### Check if you are using UEFI or BIOS on Linux - -The easiest way to find out if you are running UEFI or BIOS is to look for a folder /sys/firmware/efi. The folder will be missing if your system is using BIOS. - -![Find if system uses UEFI or BIOS on Ubuntu Linux][6] - -**Alternative** : The other method is to install a package called efibootmgr. - -On Debian and Ubuntu based distributions, you can install the efibootmgr package using the command below: -``` -sudo apt install efibootmgr - -``` - -Once done, type the below command: -``` -sudo efibootmgr - -``` - -If your system supports UEFI, it will output different variables. If not you will see a message saying EFI variables are not supported. - -![][7] - -### Final Words - -Finding whether your system is using UEFI or BIOS is easy. On one hand, features like faster and secure boot provide an upper hand to UEFI, there is not much that should bother you if you are using BIOS – unless you are planning to use a 2TB hard disk to boot. - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/check-uefi-or-bios/ - -作者:[Ambarish Kumar][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://itsfoss.com/author/ambarish/ -[1]:https://itsfoss.com/guide-install-linux-mint-16-dual-boot-windows/ -[2]:https://www.lifewire.com/bios-basic-input-output-system-2625820 -[3]:https://www.howtogeek.com/56958/htg-explains-how-uefi-will-replace-the-bios/ -[4]:https://itsfoss.com/wp-content/uploads/2018/02/uefi-or-bios-800x450.png -[5]:https://itsfoss.com/wp-content/uploads/2018/01/BIOS-800x491.png -[6]:https://itsfoss.com/wp-content/uploads/2018/02/uefi-bios.png -[7]:https://itsfoss.com/wp-content/uploads/2018/01/bootmanager.jpg diff --git a/translated/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md b/translated/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md new file mode 100644 index 0000000000..692b5598f7 --- /dev/null +++ b/translated/tech/20180204 How to Check if Your Computer Uses UEFI or BIOS.md @@ -0,0 +1,90 @@ +如何检查你的计算机使用的是 UEFI 还是 BIOS +====== +**简介:一个快速的教程,来告诉你的系统使用的是现代 UEFI 或者传统 BIOS。同时提供 Windows 和 Linux 的说明。** + +当你尝试[双启动 Linux 和 Windows ][1]时,你需要知道系统上是否有 UEFI 或 BIOS 启动模式。它可以帮助你决定安装 Linux 的分区。 + +我不打算在这里讨论[什么是 BIOS][2]。不过,我想通过 BIOS 告诉你一些 [UEFI][3] 的优点。 + +UEFI 或者说统一可扩展固件接口旨在克服 BIO S的某些限制。它增加了使用大于 2TB 磁盘的能力,并具有独立于 CPU 的体系结构和驱动程序。采用模块化设计,即使没有安装操作系统,也可以支持远程诊断和修复,以及灵活的无操作系统环境(包括网络功能)。 + +### UEFI 优于 BIOS 的点 + + * UEFI在初始化硬件时速度更快。 + * 提供安全启动,这意味着你在加载操作系统之前加载的所有内容都必须签名。这为你的系统提供了额外的保护层。 + * BIOS 不支持超过 2TB 的分区。 + * 最重要的是,如果你是双引导,那么建议始终在相同的引导模式下安装两个操作系统。 + + + +![How to check if system has UEFI or BIOS][4] + +如果试图查看你的系统运行的是 UEFI 还是 BIOS,这并不难。首先让我从 Windows 开始,然后看看如何在 Linux 系统上查看用的是 UEFI 还是 BIOS。 + +### 在 Windows 中检查使用的是 UEFI 还是 BIOS + +在 Windows 中,在“开始”面板中的“系统信息”中,在 BIOS 模式下,可以找到启动模式。如果它显示的是 Legacy,那么你的系统是 BIOS。如果显示 UEFI,那么它是 UEFI。 + +![][5] + +**另一个方法**:如果你使用 Windows 10,可以打开文件资源管理器并进入到 C:\Windows\Panther 来查看你使用的是 UEFI 还是 BIOS。打开文件 setupact.log 并搜索下面的字符串。 +``` +Detected boot environment + +``` + +我建议在 notepad++ 中打开这个文件,因为这是一个很大的文件和记事本可能挂起(至少它对我来说是 6GB )。 + +你会看到几行有用的信息。 +``` +2017-11-27 09:11:31, Info IBS Callback_BootEnvironmentDetect:FirmwareType 1. +2017-11-27 09:11:31, Info IBS Callback_BootEnvironmentDetect: Detected boot environment: BIOS + +``` + +### 在 Linux 中检查使用的是 UEFI 还是 BIOS + +最简单地找出使用的是 UEFI 还是 BIOS 的方法是查找 /sys/firmware/efi 文件夹。如果使用的 BIOS 那么文件夹不存在。 + +![Find if system uses UEFI or BIOS on Ubuntu Linux][6] + +**另一种方法**:安装名为 efibootmgr 的软件包。 + +在基于 Debian 和 Ubuntu 的发行版中,你可以使用以下命令安装 efibootmgr 包: +``` +sudo apt install efibootmgr + +``` + +完成后,输入以下命令: +``` +sudo efibootmgr + +``` + +如果你的系统支持 UEFI,它会输出不同的变量。如果没有,你将看到一条消息指出 EFI 变量不支持。 + +![][7] + +### 最后的话 + +查看你的系统使用的是 UEFI 还是 BIOS 很容易。一方面,像快速和安全的引导为 UEFI 提供了优势,如果你使用的是 BIOS 也不必担心太多,除非你打算使用 2TB 硬盘。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/check-uefi-or-bios/ + +作者:[Ambarish Kumar][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://itsfoss.com/author/ambarish/ +[1]:https://itsfoss.com/guide-install-linux-mint-16-dual-boot-windows/ +[2]:https://www.lifewire.com/bios-basic-input-output-system-2625820 +[3]:https://www.howtogeek.com/56958/htg-explains-how-uefi-will-replace-the-bios/ +[4]:https://itsfoss.com/wp-content/uploads/2018/02/uefi-or-bios-800x450.png +[5]:https://itsfoss.com/wp-content/uploads/2018/01/BIOS-800x491.png +[6]:https://itsfoss.com/wp-content/uploads/2018/02/uefi-bios.png +[7]:https://itsfoss.com/wp-content/uploads/2018/01/bootmanager.jpg From 5be565aca7703d86ae33a5567f741d99a769af0b Mon Sep 17 00:00:00 2001 From: geekpi Date: Tue, 27 Feb 2018 08:59:53 +0800 Subject: [PATCH 016/101] translating --- sources/tech/20180129 How programmers learn to code.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180129 How programmers learn to code.md b/sources/tech/20180129 How programmers learn to code.md index c741c01161..1253985dba 100644 --- a/sources/tech/20180129 How programmers learn to code.md +++ b/sources/tech/20180129 How programmers learn to code.md @@ -1,3 +1,5 @@ +translating----geekpi + How programmers learn to code ============================================================ From 2f2611dacdbb1977c7423d7be08b211e57a1f579 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Tue, 27 Feb 2018 11:39:06 +0800 Subject: [PATCH 017/101] Translated by qhwdw --- ... build your own RSS notification system.md | 171 ------------------ ... build your own RSS notification system.md | 169 +++++++++++++++++ 2 files changed, 169 insertions(+), 171 deletions(-) delete mode 100644 sources/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md create mode 100644 translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md diff --git a/sources/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md b/sources/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md deleted file mode 100644 index 7f648c5441..0000000000 --- a/sources/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md +++ /dev/null @@ -1,171 +0,0 @@ -Translating by qhwdw -Never miss a Magazine's article, build your own RSS notification system -====== - -![](https://fedoramagazine.org/wp-content/uploads/2018/01/learn-python-rss-notifier.png-945x400.jpg) - -Python is a great programming language to quickly build applications that make our life easier. In this article we will learn how to use Python to build a RSS notification system, the goal being to have fun learning Python using Fedora. If you are looking for a complete RSS notifier application, there are a few already packaged in Fedora. - -### Fedora and Python - getting started - -Python 3.6 is available by default in Fedora, that includes Python's extensive standard library. The standard library provides a collection of modules which make some tasks simpler for us. For example, in our case we will use the [**sqlite3**][1] module to create, add and read data from a database. In the case where a particular problem we are trying to solve is not covered by the standard library, the chance is that someone has already developed a module for everyone to use. The best place to search for such modules is the Python Package Index known as [PyPI][2]. In our example we are going to use the [**feedparser**][3] to parse an RSS feed. - -Since **feedparser** is not in the standard library, we have to install it in our system. Luckily for us there is an rpm package in Fedora, so the installation of **feedparser** is as simple as: -``` -$ sudo dnf install python3-feedparser -``` - -We now have everything we need to start coding our application. - -### Storing the feed data - -We need to store data from the articles that have already been published so that we send a notification only for new articles. The data we want to store will give us a unique way to identify an article. Therefore we will store the **title** and the **publication date** of the article. - -So let's create our database using python **sqlite3** module and a simple SQL query. We are also adding the modules we are going to use later ( **feedparser** , **smtplib** and **email** ). - -#### Creating the Database -``` -#!/usr/bin/python3 -import sqlite3 -import smtplib -from email.mime.text import MIMEText - -import feedparser - -db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite') -db = db_connection.cursor() -db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)') - -``` - -These few lines of code create a new sqlite database stored in a file called 'magazine_rss.sqlite', and then create a new table within the database called 'magazine'. This table has two columns - 'title' and 'date' - that can store data of the type TEXT, which means that the value of each column will be a text string. - -#### Checking the Database for old articles - -Since we only want to add new articles to our database we need a function that will check if the article we get from the RSS feed is already in our database or not. We will use it to decide if we should send an email notification (new article) or not (old article). Ok let's code this function. -``` -def article_is_not_db(article_title, article_date): - """ Check if a given pair of article title and date - is in the database. - Args: - article_title (str): The title of an article - article_date (str): The publication date of an article - Return: - True if the article is not in the database - False if the article is already present in the database - """ - db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date)) - if not db.fetchall(): - return True - else: - return False -``` - -The main part of this function is the SQL query we execute to search through the database. We are using a SELECT instruction to define which column of our magazine table we will run the query on. We are using the 0_sync_master.sh 1_add_new_article_manual.sh 1_add_new_article_newspaper.sh 2_start_translating.sh 3_continue_the_work.sh 4_finish.sh 5_pause.sh base.sh env format.test lctt.cfg parse_url_by_manual.sh parse_url_by_newspaper.py parse_url_by_newspaper.sh README.org reformat.sh symbol to select all columns ( title and date). Then we ask to select only the rows of the table WHERE the article_title and article_date string are equal to the value of the title and date column. - -To finish, we have a simple logic that will return True if the query did not return any results and False if the query found an article in database matching our title, date pair. - -#### Adding a new article to the Database - -Now we can code the function to add a new article to the database. -``` -def add_article_to_db(article_title, article_date): - """ Add a new article title and date to the database - Args: - article_title (str): The title of an article - article_date (str): The publication date of an article - """ - db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date)) - db_connection.commit() -``` - -This function is straight forward, we are using a SQL query to INSERT a new row INTO the magazine table with the VALUES of the article_title and article_date. Then we commit the change to make it persistent. - -That's all we need from the database's point of view, let's look at the notification system and how we can use python to send emails. - -### Sending an email notification - -Let's create a function to send an email using the python standard library module **smtplib.** We are also using the **email** module from the standard library to format our email message. -``` -def send_notification(article_title, article_url): - """ Add a new article title and date to the database - - Args: - article_title (str): The title of an article - article_url (str): The url to access the article - """ - - smtp_server = smtplib.SMTP('smtp.gmail.com', 587) - smtp_server.ehlo() - smtp_server.starttls() - smtp_server.login('your_email@gmail.com', '123your_password') - msg = MIMEText(f'\nHi there is a new Fedora Magazine article : {article_title}. \nYou can read it here {article_url}') - msg['Subject'] = 'New Fedora Magazine Article Available' - msg['From'] = 'your_email@gmail.com' - msg['To'] = 'destination_email@gmail.com' - smtp_server.send_message(msg) - smtp_server.quit() -``` - -In this example I am using the Google mail smtp server to send an email, but this will work with any email services that provides you with a SMTP server. Most of this function is boilerplate needed to configure the access to the smtp server. You will need to update the code with your email address and credentials. - -If you are using 2 Factor Authentication with your gmail account you can setup a password app that will give you a unique password to use for this application. Check out this help [page][4]. - -### Reading Fedora Magazine RSS feed - -We now have functions to store an article in the database and send an email notification, let's create a function that parses the Fedora Magazine RSS feed and extract the articles' data. -``` -def read_article_feed(): - """ Get articles from RSS feed """ - feed = feedparser.parse('https://fedoramagazine.org/feed/') - for article in feed['entries']: - if article_is_not_db(article['title'], article['published']): - send_notification(article['title'], article['link']) - add_article_to_db(article['title'], article['published']) - -if __name__ == '__main__': - read_article_feed() - db_connection.close() -``` - -Here we are making use of the **feedparser.parse** function. The function returns a dictionary representation of the RSS feed, for the full reference of the representation you can consult **feedparser** 's [documentation][5]. - -The RSS feed parser will return the last 10 articles as entries and then we extract the following information: the title, the link and the date the article was published. As a result, we can now use the functions we have previously defined to check if the article is not in the database, then send a notification email and finally, add the article to our database. - -The last if statement is used to execute our read_article_feed function and then close the database connection when we execute our script. - -### Running our script - -Finally, to run our script we need to give the correct permission to the file. Next, we make use of the **cron** utility to automatically execute our script every hour (1 minute past the hour). **cron** is a job scheduler that we can use to run a task at a fixed time. -``` -$ chmod a+x my_rss_notifier.py -$ sudo cp my_rss_notifier.py /etc/cron.hourly -``` - -To keep this tutorial simple, we are using the cron.hourly directory to execute the script every hours, I you wish to learn more about **cron** and how to configure the **crontab,** please read **cron 's** wikipedia [page][6]. - -### Conclusion - -In this tutorial we have learned how to use Python to create a simple sqlite database, parse an RSS feed and send emails. I hope that this showed you how you can easily build your own application using Python and Fedora. - -The script is available on github [here][7]. - - --------------------------------------------------------------------------------- - -via: https://fedoramagazine.org/never-miss-magazines-article-build-rss-notification-system/ - -作者:[Clément Verna][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://fedoramagazine.org -[1]:https://docs.python.org/3/library/sqlite3.html -[2]:https://pypi.python.org/pypi -[3]:https://pypi.python.org/pypi/feedparser/5.2.1 -[4]:https://support.google.com/accounts/answer/185833?hl=en -[5]:https://pythonhosted.org/feedparser/reference.html -[6]:https://en.wikipedia.org/wiki/Cron -[7]:https://github.com/cverna/rss_feed_notifier diff --git a/translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md b/translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md new file mode 100644 index 0000000000..acd94006d8 --- /dev/null +++ b/translated/tech/20180123 Never miss a Magazine-s article, build your own RSS notification system.md @@ -0,0 +1,169 @@ +构建你自己的 RSS 提示系统——让杂志文章一篇也不会错过 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/01/learn-python-rss-notifier.png-945x400.jpg) + +人生苦短,我用 Python,Python 是非常棒的快速构建应用程序的编程语言。在这篇文章中我们将学习如何使用 Python 去构建一个 RSS 提示系统,目标是使用 Fedora 快乐地学习 Python。如果你正在寻找一个完整的 RSS 提示应用程序,在 Fedora 中已经准备好了几个包。 + +### Fedora 和 Python —— 入门知识 + +Python 3.6 在 Fedora 中是默认安装的,它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如,在我们的案例中,我们将使用 [**sqlite3**][1] 模块在数据库中去创建表、添加和读取数据。在这个案例中,我们试图去解决的是在标准库中没有的特定的问题,也有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 [PyPI][2] Python 包索引去搜索一下。在我们的示例中,我们将使用 [**feedparser**][3] 去解析 RSS 源。 + +因为 **feedparser** 并不是标准库,我们需要将它安装到我们的系统上。幸运的是,在 Fedora 中有这个 RPM 包,因此,我们可以运行如下的命令去安装 **feedparser**: +``` +$ sudo dnf install python3-feedparser +``` + +我们现在已经拥有了编写我们的应用程序所需的东西了。 + +### 存储源数据 + +我们需要存储已经发布的文章的数据,这样我们的系统就可以只提示新发布的文章。我们要保存的数据将是用来辨别一篇文章的唯一方法。因此,我们将存储文章的**标题**和**发布日期**。 + +因此,我们来使用 Python **sqlite3** 模块和一个简单的 SQL 语句来创建我们的数据库。同时也添加一些后面将要用到的模块(**feedparse**,**smtplib**,和 **email**)。 + +#### 创建数据库 +``` +#!/usr/bin/python3 +import sqlite3 +import smtplib +from email.mime.text import MIMEText + +import feedparser + +db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite') +db = db_connection.cursor() +db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)') + +``` + +这几行代码创建一个新的保存在一个名为 'magazine_rss.sqlite' 文件中的 sqlite 数据库,然后在数据库创建一个名为 'magazine' 的新表。这个表有两个列 —— 'title' 和 'date' —— 它们能存诸 TEXT 类型的数据,也就是说每个列的值都是文本字符。 + +#### 检查数据库中的旧文章 + +由于我们仅希望增加新的文章到我们的数据库中,因此我们需要一个功能去检查 RSS 源中的文章在数据库中是否存在。我们将根据它来判断是否发送(有新文章的)邮件提示。Ok,现在我们来写这个功能的代码。 +``` +def article_is_not_db(article_title, article_date): + """ Check if a given pair of article title and date + is in the database. + Args: + article_title (str): The title of an article + article_date (str): The publication date of an article + Return: + True if the article is not in the database + False if the article is already present in the database + """ + db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date)) + if not db.fetchall(): + return True + else: + return False +``` + +这个功能的主要部分是一个 SQL 查询,我们运行它去搜索数据库。我们使用一个 SELECT 命令去定义我们将要在哪个列上运行这个查询。我们使用 `*` 符号去选取所有列(title 和 date)。然后,我们使用查询的 WHERE 条件 `article_title` and `article_date` 去匹配标题和日期列中的值,以检索出我们需要的内容。 + +最后,我们使用一个简单的返回 `True` 或者 `False` 的逻辑来表示是否在数据库中找到匹配的文章。 + +#### 在数据库中添加新文章 + +现在我们可以写一些代码去添加新文章到数据库中。 +``` +def add_article_to_db(article_title, article_date): + """ Add a new article title and date to the database + Args: + article_title (str): The title of an article + article_date (str): The publication date of an article + """ + db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date)) + db_connection.commit() +``` + +这个功能很简单,我们使用了一个 SQL 查询去插入一个新行到 'magazine' 表的 article_title 和 article_date 列中。然后提交它到数据库中永久保存。 + +这些就是在数据库中所需要的东西,接下来我们看一下,如何使用 Python 实现提示系统和发送电子邮件。 + +### 发送电子邮件提示 + +我们来使用 Python 标准库模块 **smtplib** 来创建一个发送电子邮件的功能。我们也可以使用标准库中的 **email** 模块去格式化我们的电子邮件信息。 +``` +def send_notification(article_title, article_url): + """ Add a new article title and date to the database + + Args: + article_title (str): The title of an article + article_url (str): The url to access the article + """ + + smtp_server = smtplib.SMTP('smtp.gmail.com', 587) + smtp_server.ehlo() + smtp_server.starttls() + smtp_server.login('your_email@gmail.com', '123your_password') + msg = MIMEText(f'\nHi there is a new Fedora Magazine article : {article_title}. \nYou can read it here {article_url}') + msg['Subject'] = 'New Fedora Magazine Article Available' + msg['From'] = 'your_email@gmail.com' + msg['To'] = 'destination_email@gmail.com' + smtp_server.send_message(msg) + smtp_server.quit() +``` + +在这个示例中,我使用了谷歌邮件系统的 smtp 服务器去发送电子邮件,在你自己的代码中你需要将它更改为你自己的电子邮件服务提供者的 SMTP 服务器。这个功能是个样板,大多数的内容要根据你的 smtp 服务器的参数来配置。代码中的电子邮件地址和凭证也要更改为你自己的。 + +如果在你的 Gmail 帐户中使用了双因子认证,那么你需要配置一个密码应用程序为你的这个应用程序提供一个唯一密码。可以看这个 [帮助页面][4]。 + +### 读取 Fedora Magazine 的 RSS 源 + +我们已经有了在数据库中存储文章和发送提示电子邮件的功能,现在来创建一个解析 Fedora Magazine RSS 源并提取文章数据的功能。 +``` +def read_article_feed(): + """ Get articles from RSS feed """ + feed = feedparser.parse('https://fedoramagazine.org/feed/') + for article in feed['entries']: + if article_is_not_db(article['title'], article['published']): + send_notification(article['title'], article['link']) + add_article_to_db(article['title'], article['published']) + +if __name__ == '__main__': + read_article_feed() + db_connection.close() +``` + +在这里我们将使用 **feedparser.parse** 功能。这个功能返回一个用字典表示的 RSS 源,对于 **feedparser** 的完整描述可以参考它的 [文档][5]。 + +RSS 源解析将返回最后的 10 篇文章作为 `entries`,然后我们提取以下信息:标题、链接、文章发布日期。因此,我们现在可以使用前面定义的检查文章是否在数据库中存在的功能,然后,发送提示电子邮件并将这个文章添加到数据库中。 + +当运行我们的脚本时,最后的 if 语句运行我们的 `read_article_feed` 功能,然后关闭数据库连接。 + +### 运行我们的脚本 + +给脚本文件赋于正确运行权限。接下来,我们使用 **cron** 实用程序去每小时自动运行一次我们的脚本。**cron** 是一个作业计划程序,我们可以使用它在一个固定的时间去运行一个任务。 +``` +$ chmod a+x my_rss_notifier.py +$ sudo cp my_rss_notifier.py /etc/cron.hourly +``` + +**为了使该教程保持简单**,我们使用了 cron.hourly 目录每小时运行一次我们的脚本,如果你想学习关于 **cron** 的更多知识以及如何配置 **crontab**,请阅读 **cron** 的 wikipedia [页面][6]。 + +### 总结 + +在本教程中,我们学习了如何使用 Python 去创建一个简单的 sqlite 数据库、解析一个 RSS 源、以及发送电子邮件。我希望通过这篇文章能够向你展示,**使用 Python 和 Fedora 构建你自己的应用程序是件多么容易的事**。 + +这个脚本在 [GitHub][7] 上可以找到。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/never-miss-magazines-article-build-rss-notification-system/ + +作者:[Clément Verna][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:https://docs.python.org/3/library/sqlite3.html +[2]:https://pypi.python.org/pypi +[3]:https://pypi.python.org/pypi/feedparser/5.2.1 +[4]:https://support.google.com/accounts/answer/185833?hl=en +[5]:https://pythonhosted.org/feedparser/reference.html +[6]:https://en.wikipedia.org/wiki/Cron +[7]:https://github.com/cverna/rss_feed_notifier From de538f939bc380cc88d11dffbf22cae498891753 Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Tue, 27 Feb 2018 11:50:23 +0800 Subject: [PATCH 018/101] Update 20180221 Getting started with SQL.md --- sources/tech/20180221 Getting started with SQL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180221 Getting started with SQL.md b/sources/tech/20180221 Getting started with SQL.md index 469716e478..ee2bcb0f1f 100644 --- a/sources/tech/20180221 Getting started with SQL.md +++ b/sources/tech/20180221 Getting started with SQL.md @@ -1,3 +1,5 @@ +Translating by MjSeven + Getting started with SQL ====== From 979bf2ff6877360a8a832a66871d8ff686556ab4 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Tue, 27 Feb 2018 16:05:29 +0800 Subject: [PATCH 019/101] Translated by qhwdw --- ...0180116 Monitor your Kubernetes Cluster.md | 265 ----------------- ...0180116 Monitor your Kubernetes Cluster.md | 266 ++++++++++++++++++ 2 files changed, 266 insertions(+), 265 deletions(-) delete mode 100644 sources/tech/20180116 Monitor your Kubernetes Cluster.md create mode 100644 translated/tech/20180116 Monitor your Kubernetes Cluster.md diff --git a/sources/tech/20180116 Monitor your Kubernetes Cluster.md b/sources/tech/20180116 Monitor your Kubernetes Cluster.md deleted file mode 100644 index 4ff63402c1..0000000000 --- a/sources/tech/20180116 Monitor your Kubernetes Cluster.md +++ /dev/null @@ -1,265 +0,0 @@ -Translating by qhwdw -Monitor your Kubernetes Cluster -====== -This article originally appeared on [Kevin Monroe's blog][1] - -Keeping an eye on logs and metrics is a necessary evil for cluster admins. The benefits are clear: metrics help you set reasonable performance goals, while log analysis can uncover issues that impact your workloads. The hard part, however, is getting a slew of applications to work together in a useful monitoring solution. - -In this post, I'll cover monitoring a Kubernetes cluster with [Graylog][2] (for logging) and [Prometheus][3] (for metrics). Of course that's not just wiring 3 things together. In fact, it'll end up looking like this: - -![][4] - -As you know, Kubernetes isn't just one thing -- it's a system of masters, workers, networking bits, etc(d). Similarly, Graylog comes with a supporting cast (apache2, mongodb, etc), as does Prometheus (telegraf, grafana, etc). Connecting the dots in a deployment like this may seem daunting, but the right tools can make all the difference. - -I'll walk through this using [conjure-up][5] and the [Canonical Distribution of Kubernetes][6] (CDK). I find the conjure-up interface really helpful for deploying big software, but I know some of you hate GUIs and TUIs and probably other UIs too. For those folks, I'll do the same deployment again from the command line. - -Before we jump in, note that Graylog and Prometheus will be deployed alongside Kubernetes and not in the cluster itself. Things like the Kubernetes Dashboard and Heapster are excellent sources of information from within a running cluster, but my objective is to provide a mechanism for log/metric analysis whether the cluster is running or not. - -### The Walk Through - -First things first, install conjure-up if you don't already have it. On Linux, that's simply: -``` -sudo snap install conjure-up --classic -``` - -There's also a brew package for macOS users: -``` -brew install conjure-up -``` - -You'll need at least version 2.5.2 to take advantage of the recent CDK spell additions, so be sure to `sudo snap refresh conjure-up` or `brew update && brew upgrade conjure-up` if you have an older version installed. - -Once installed, run it: -``` -conjure-up -``` - -![][7] - -You'll be presented with a list of various spells. Select CDK and press `Enter`. - -![][8] - -At this point, you'll see additional components that are available for the CDK spell. We're interested in Graylog and Prometheus, so check both of those and hit `Continue`. - -You'll be guided through various cloud choices to determine where you want your cluster to live. After that, you'll see options for post-deployment steps, followed by a review screen that lets you see what is about to be deployed: - -![][9] - -In addition to the typical K8s-related applications (etcd, flannel, load-balancer, master, and workers), you'll see additional applications related to our logging and metric selections. - -The Graylog stack includes the following: - - * apache2: reverse proxy for the graylog web interface - * elasticsearch: document database for the logs - * filebeat: forwards logs from K8s master/workers to graylog - * graylog: provides an api for log collection and an interface for analysis - * mongodb: database for graylog metadata - - - -The Prometheus stack includes the following: - - * grafana: web interface for metric-related dashboards - * prometheus: metric collector and time series database - * telegraf: sends host metrics to prometheus - - - -You can fine tune the deployment from this review screen, but the defaults will suite our needs. Click `Deploy all Remaining Applications` to get things going. - -The deployment will take a few minutes to settle as machines are brought online and applications are configured in your cloud. Once complete, conjure-up will show a summary screen that includes links to various interesting endpoints for you to browse: - -![][10] - -#### Exploring Logs - -Now that Graylog has been deployed and configured, let's take a look at some of the data we're gathering. By default, the filebeat application will send both syslog and container log events to graylog (that's `/var/log/*.log` and `/var/log/containers/*.log` from the kubernetes master and workers). - -Grab the apache2 address and graylog admin password as follows: -``` -juju status --format yaml apache2/0 | grep public-address - public-address: -juju run-action --wait graylog/0 show-admin-password - admin-password: -``` - -Browse to `http://` and login with admin as the username and as the password. **Note:** if the interface is not immediately available, please wait as the reverse proxy configuration may take up to 5 minutes to complete. - -Once logged in, head to the `Sources` tab to get an overview of the logs collected from our K8s master and workers: - -![][11] - -Drill into those logs by clicking the `System / Inputs` tab and selecting `Show received messages` for the filebeat input: - -![][12] - -From here, you may want to play around with various filters or setup Graylog dashboards to help identify the events that are most important to you. Check out the [Graylog Dashboard][13] docs for details on customizing your view. - -#### Exploring Metrics - -Our deployment exposes two types of metrics through our grafana dashboards: system metrics include things like cpu/memory/disk utilization for the K8s master and worker machines, and cluster metrics include container-level data scraped from the K8s cAdvisor endpoints. - -Grab the grafana address and admin password as follows: -``` -juju status --format yaml grafana/0 | grep public-address - public-address: -juju run-action --wait grafana/0 get-admin-password - password: -``` - -Browse to `http://:3000` and login with admin as the username and as the password. Once logged in, check out the cluster metric dashboard by clicking the `Home` drop-down box and selecting `Kubernetes Metrics (via Prometheus)`: - -![][14] - -We can also check out the system metrics of our K8s host machines by switching the drop-down box to `Node Metrics (via Telegraf) ` - -![][15] - - -### The Other Way - -As alluded to in the intro, I prefer the wizard-y feel of conjure-up to guide me through complex software deployments like Kubernetes. Now that we've seen the conjure-up way, some of you may want to see a command line approach to achieve the same results. Still others may have deployed CDK previously and want to extend it with the Graylog/Prometheus components described above. Regardless of why you've read this far, I've got you covered. - -The tool that underpins conjure-up is [Juju][16]. Everything that the CDK spell did behind the scenes can be done on the command line with Juju. Let's step through how that works. - -**Starting From Scratch** - -If you're on Linux, install Juju like this: -``` -sudo snap install juju --classic -``` - -For macOS, Juju is available from brew: -``` -brew install juju -``` - -Now setup a controller for your preferred cloud. You may be prompted for any required cloud credentials: -``` -juju bootstrap -``` - -We then need to deploy the base CDK bundle: -``` -juju deploy canonical-kubernetes -``` - -**Starting From CDK** - -With our Kubernetes cluster deployed, we need to add all the applications required for Graylog and Prometheus: -``` -## deploy graylog-related applications -juju deploy xenial/apache2 -juju deploy xenial/elasticsearch -juju deploy xenial/filebeat -juju deploy xenial/graylog -juju deploy xenial/mongodb -``` -``` -## deploy prometheus-related applications -juju deploy xenial/grafana -juju deploy xenial/prometheus -juju deploy xenial/telegraf -``` - -Now that the software is deployed, connect them together so they can communicate: -``` -## relate graylog applications -juju relate apache2:reverseproxy graylog:website -juju relate graylog:elasticsearch elasticsearch:client -juju relate graylog:mongodb mongodb:database -juju relate filebeat:beats-host kubernetes-master:juju-info -juju relate filebeat:beats-host kubernetes-worker:jujuu-info -``` -``` -## relate prometheus applications -juju relate prometheus:grafana-source grafana:grafana-source -juju relate telegraf:prometheus-client prometheus:target -juju relate kubernetes-master:juju-info telegraf:juju-info -juju relate kubernetes-worker:juju-info telegraf:juju-info -``` - -At this point, all the applications can communicate with each other, but we have a bit more configuration to do (e.g., setting up the apache2 reverse proxy, telling prometheus how to scrape k8s, importing our grafana dashboards, etc): -``` -## configure graylog applications -juju config apache2 enable_modules="headers proxy_html proxy_http" -juju config apache2 vhost_http_template="$(base64 )" -juju config elasticsearch firewall_enabled="false" -juju config filebeat \ - logpath="/var/log/*.log /var/log/containers/*.log" -juju config filebeat logstash_hosts=":5044" -juju config graylog elasticsearch_cluster_name="" -``` -``` -## configure prometheus applications -juju config prometheus scrape-jobs="" -juju run-action --wait grafana/0 import-dashboard \ - dashboard="$(base64 )" -``` - -Some of the above steps need values specific to your deployment. You can get these in the same way that conjure-up does: - - * : fetch our sample [template][17] from github - * : `juju run --unit graylog/0 'unit-get private-address'` - * : `juju config elasticsearch cluster-name` - * : fetch our sample [scraper][18] from github; [substitute][19]appropriate values for `[K8S_PASSWORD][20]` and `[K8S_API_ENDPOINT][21]` - * : fetch our [host][22] and [k8s][23] dashboards from github - - - -Finally, you'll want to expose the apache2 and grafana applications to make their web interfaces accessible: -``` -## expose relevant endpoints -juju expose apache2 -juju expose grafana -``` - -Now that we have everything deployed, related, configured, and exposed, you can login and poke around using the same steps from the **Exploring Logs** and **Exploring Metrics** sections above. - -### The Wrap Up - -My goal here was to show you how to deploy a Kubernetes cluster with rich monitoring capabilities for logs and metrics. Whether you prefer a guided approach or command line steps, I hope it's clear that monitoring complex deployments doesn't have to be a pipe dream. The trick is to figure out how all the moving parts work, make them work together repeatably, and then break/fix/repeat for a while until everyone can use it. - -This is where tools like conjure-up and Juju really shine. Leveraging the expertise of contributors to this ecosystem makes it easy to manage big software. Start with a solid set of apps, customize as needed, and get back to work! - -Give these bits a try and let me know how it goes. You can find enthusiasts like me on Freenode IRC in **#conjure-up** and **#juju**. Thanks for reading! - -### About the author - -Kevin joined Canonical in 2014 with his focus set on modeling complex software. He found his niche on the Juju Big Software team where his mission is to capture operational knowledge of Big Data and Machine Learning applications into repeatable (and reliable!) solutions. - --------------------------------------------------------------------------------- - -via: https://insights.ubuntu.com/2018/01/16/monitor-your-kubernetes-cluster/ - -作者:[Kevin Monroe][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://insights.ubuntu.com/author/kwmonroe/ -[1]:https://medium.com/@kwmonroe/monitor-your-kubernetes-cluster-a856d2603ec3 -[2]:https://www.graylog.org/ -[3]:https://prometheus.io/ -[4]:https://insights.ubuntu.com/wp-content/uploads/706b/1_TAA57DGVDpe9KHIzOirrBA.png -[5]:https://conjure-up.io/ -[6]:https://jujucharms.com/canonical-kubernetes -[7]:https://insights.ubuntu.com/wp-content/uploads/98fd/1_o0UmYzYkFiHIs2sBgj7G9A.png -[8]:https://insights.ubuntu.com/wp-content/uploads/0351/1_pgVaO_ZlalrjvYd5pOMJMA.png -[9]:https://insights.ubuntu.com/wp-content/uploads/9977/1_WXKxMlml2DWA5Kj6wW9oXQ.png -[10]:https://insights.ubuntu.com/wp-content/uploads/8588/1_NWq7u6g6UAzyFxtbM-ipqg.png -[11]:https://insights.ubuntu.com/wp-content/uploads/a1c3/1_hHK5mSrRJQi6A6u0yPSGOA.png -[12]:https://insights.ubuntu.com/wp-content/uploads/937f/1_cP36lpmSwlsPXJyDUpFluQ.png -[13]:http://docs.graylog.org/en/2.3/pages/dashboards.html -[14]:https://insights.ubuntu.com/wp-content/uploads/9256/1_kskust3AOImIh18QxQPgRw.png -[15]:https://insights.ubuntu.com/wp-content/uploads/2037/1_qJpjPOTGMQbjFY5-cZsYrQ.png -[16]:https://jujucharms.com/ -[17]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/graylog/steps/01_install-graylog/graylog-vhost.tmpl -[18]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/prometheus-scrape-k8s.yaml -[19]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L25 -[20]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L10 -[21]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L11 -[22]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/grafana-telegraf.json -[23]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/grafana-k8s.json diff --git a/translated/tech/20180116 Monitor your Kubernetes Cluster.md b/translated/tech/20180116 Monitor your Kubernetes Cluster.md new file mode 100644 index 0000000000..a8c8db5e5d --- /dev/null +++ b/translated/tech/20180116 Monitor your Kubernetes Cluster.md @@ -0,0 +1,266 @@ +监视 Kubernetes 集群 +====== +这篇文章最初发表在 [Kevin Monroe 的博客][1] 上 + +监视日志和指标状态是集群管理员的重点工作。它的好处很明显:指标能帮你设置一个合理的性能目标,而日志分析可以发现影响你工作负载的问题。然而,困难的是如何找到一个与大量运行的应用程序一起工作的监视解决方案。 + +在本文中,我将使用 [Graylog][2] (用于日志)和 [Prometheus][3] (用于指标)去打造一个Kubernetes 集群的监视解决方案。当然了,这不仅是将三个东西连接起来那么简单,实现上,最终结果看起来应该如下图所示: + +![][4] + +正如你所了解的,Kubernetes 不仅做一件事情 —— 它是 master、workers、networking bit 等等。同样,Graylog 是一个配角(apache2、mongodb、等等),Prometheus 也一样(telegraf、grafana 等等)。在部署中连接这些点看起来似乎有些让人恐惧,但是使用合适的工具将不会那么困难。 + +我将使用 [conjure-up][5] 和 [Canonical Distribution of Kubernetes][6] (CDK) 去探索 Kubernetes。我发现 conjure-up 接口对部署大型软件很有帮助,但是我知道一些人可能不喜欢 GUIs、TUIs 以及其它 UIs。对于这些人,我将用命令行再去部署一遍。 + +在开始之前需要注意的一点是,Graylog 和 Prometheus 是部署在 Kubernetes 侧而不是集群上。像 Kubernetes 仪表盘和 Heapster 是运行的集群中非常好的信息来源,但是我的目标是为日志/指标提供一个分析机制,而不管集群运行与否。 + +### 开始探索 + +如果你的系统上没有 conjure-up,首先要做的第一件事情是,请先安装它,在 Linux 上,这很简单: +``` +sudo snap install conjure-up --classic +``` + +对于 macOS 用户也提供了 brew 包: +``` +brew install conjure-up +``` + +你需要最新的 2.5.2 版,它的好处是添加了 CDK spell,因此,如果你的系统上已经安装了旧的版本,请使用 `sudo snap refresh conjure-up` 或者 `brew update && brew upgrade conjure-up` 去更新它。 + +安装完成后,运行它: +``` +conjure-up +``` + +![][7] + +你将发现有一个 spell 列表。选择 CDK 然后按下 `Enter`。 + +![][8] + +这个时候,你将看到 CDK spell 可用的附加组件。我们感兴趣的是 Graylog 和 Prometheus,因此选择这两个,然后点击 `Continue`。 + +它将引导你选择各种云,以决定你的集群部署的地方。之后,你将看到一些部署的后续步骤,接下来是回顾屏幕,让你再次确认部署内容: + +![][9] + +除了典型的 K8s 相关的应用程序(etcd、flannel、load-balancer、master、以及 workers)之外,你将看到我们选择的日志和指标相关的额外应用程序。 + +Graylog 栈包含如下: + + * apache2:graylog web 接口的反向代理 + * elasticsearch:日志使用的文档数据库 + * filebeat:从 K8s master/workers 转发日志到 graylog + * graylog:为日志收集器提供一个 api,以及提供一个日志分析界面 + * mongodb:保存 graylog 元数据的数据库 + + + +Prometheus 栈包含如下: + + * grafana:指标相关的仪表板的 web 界面 + * prometheus:指标收集器以及时序数据库 + * telegraf:发送主机的指标到 prometheus 中 + + + +你可以在回顾屏幕上微调部署,但是默认组件是必选 的。点击 `Deploy all Remaining Applications` 继续。 + +部署工作将花费一些时间,它将部署你的机器和配置你的云。完成后,conjure-up 将展示一个摘要屏幕,它包含一些链连,你可以用你的终端去浏览各种感兴趣的内容: + +![][10] + +#### 浏览日志 + +现在,Graylog 已经部署和配置完成,我们可以看一下采集到的一些数据。默认情况下,filebeat 应用程序将从 Kubernetes 的 master 和 workers 中转发系统日志( `/var/log/*.log` )和容器日志(`/var/log/containers/*.log`)到 graylog 中。 + +记住如下的 apache2 的地址和 graylog 的 admin 密码: +``` +juju status --format yaml apache2/0 | grep public-address + public-address: +juju run-action --wait graylog/0 show-admin-password + admin-password: +``` + +在浏览器中输入 `http://` ,然后以管理员用户名(admin)和密码()登入。 + +**注意:** 如果这个界面不可用,请等待大约 5 分钟时间,以便于配置的反向代理生效。 + +登入后,顶部的 `Sources` 选项卡可以看到从 K8s 的 master 和 workers 中收集日志的概述: + +![][11] + +通过点击 `System / Inputs` 选项卡深入这些日志,选择 `Show received messages` 查看 filebeat 的输入: + +![][12] + +在这里,你可以应用各种过滤或者设置 Graylog 仪表板去帮助识别大多数比较重要的事件。查看 [Graylog Dashboard][13] 文档,可以了解如何定制你的视图的详细资料。 + +#### 浏览指标 + +我们的部署通过 grafana 仪表板提供了两种类型的指标:系统指标,包括像 K8s master 和 workers 的 cpu/内存/磁盘使用情况,以及集群指标,包括像从 K8s cAdvisor 端点上收集的容器级指标。 + +记住如下的 grafana 的地址和 admin 密码: +``` +juju status --format yaml grafana/0 | grep public-address + public-address: +juju run-action --wait grafana/0 get-admin-password + password: +``` + +在浏览器中输入 `http://:3000`,输入管理员用户(admin)和密码()登入。成功登入后,点击 `Home` 下拉框,选取 `Kubernetes Metrics (via Prometheus)` 去查看集群指标仪表板: + +![][14] + +我们也可以通过下拉框切换到 `Node Metrics (via Telegraf) ` 去查看 K8s 主机的系统指标。 + +![][15] + + +### 另一种方法 + +正如在文章开始的介绍中提到的,我喜欢 conjure-up 的 “魔法之杖” 去指导我完成像 Kubernetes 这种复杂软件的部署。现在,我们来看一下 conjure-up 的另一种方法,你可能希望去看到实现相同结果的一些命令行的方法。还有其它的可能已经部署了前面的 CDK,想去扩展使用上述的 Graylog/Prometheus 组件。不管什么原因你既然看到这了,既来之则安之,继续向下看吧。 + +支持 conjure-up 的工具是 [Juju][16]。CDK spell 所做的一切,都可以使用 juju 命令行来完成。我们来看一下,如何一步步完成这些工作。 + +**从 Scratch 中启动** + +如果你使用的是 Linux,安装 Juju 很简单,命令如下: +``` +sudo snap install juju --classic +``` + +对于 macOS,Juju 也可以从 brew 中安装: +``` +brew install juju +``` + +现在为你选择的云配置一个控制器。你或许会被提示请求一个凭据(用户名密码): +``` +juju bootstrap +``` + +我们接下来需要基于 CDK 捆绑部署: +``` +juju deploy canonical-kubernetes +``` + +**从 CDK 开始** + +使用我们部署的 Kubernetes 集群,我们需要去添加 Graylog 和 Prometheus 所需要的全部应用程序: +``` +## deploy graylog-related applications +juju deploy xenial/apache2 +juju deploy xenial/elasticsearch +juju deploy xenial/filebeat +juju deploy xenial/graylog +juju deploy xenial/mongodb +``` +``` +## deploy prometheus-related applications +juju deploy xenial/grafana +juju deploy xenial/prometheus +juju deploy xenial/telegraf +``` + +现在软件已经部署完毕,将它们连接到一起,以便于它们之间可以相互通讯: +``` +## relate graylog applications +juju relate apache2:reverseproxy graylog:website +juju relate graylog:elasticsearch elasticsearch:client +juju relate graylog:mongodb mongodb:database +juju relate filebeat:beats-host kubernetes-master:juju-info +juju relate filebeat:beats-host kubernetes-worker:jujuu-info +``` +``` +## relate prometheus applications +juju relate prometheus:grafana-source grafana:grafana-source +juju relate telegraf:prometheus-client prometheus:target +juju relate kubernetes-master:juju-info telegraf:juju-info +juju relate kubernetes-worker:juju-info telegraf:juju-info +``` + +这个时候,所有的应用程序已经可以相互之间进行通讯了,但是我们还需要多做一点配置(比如,配置 apache2 反向代理、告诉 prometheus 如何从 K8s 中取数、导入到 grafana 仪表板等等): +``` +## configure graylog applications +juju config apache2 enable_modules="headers proxy_html proxy_http" +juju config apache2 vhost_http_template="$(base64 )" +juju config elasticsearch firewall_enabled="false" +juju config filebeat \ + logpath="/var/log/*.log /var/log/containers/*.log" +juju config filebeat logstash_hosts=":5044" +juju config graylog elasticsearch_cluster_name="" +``` +``` +## configure prometheus applications +juju config prometheus scrape-jobs="" +juju run-action --wait grafana/0 import-dashboard \ + dashboard="$(base64 )" +``` + +以上的步骤需要根据你的部署来指定一些值。你可以用与 conjure-up 相同的方法得到这些: + + * : 从 github 获取我们的示例 [模板][17] + * : `juju run --unit graylog/0 'unit-get private-address'` + * : `juju config elasticsearch cluster-name` + * : 从 github 获取我们的示例 [scraper][18] ;`[K8S_PASSWORD][20]` 和 `[K8S_API_ENDPOINT][21]` [substitute][19] 的正确值 + * : 从 github 获取我们的 [主机][22] 和 [k8s][23] 仪表板 + + + +最后,发布 apache2 和 grafana 应用程序,以便于可以通过它们的 web 界面访问: +``` +## expose relevant endpoints +juju expose apache2 +juju expose grafana +``` + +现在我们已经完成了所有的部署、配置、和发布工作,你可以使用与上面的**浏览日志**和**浏览指标**部分相同的方法去查看它们。 + +### 总结 + +我的目标是向你展示如何去部署一个 Kubernetes 集群,很方便地去监视它的日志和指标。无论你是喜欢向导的方式还是命令行的方式,我希望你清楚地看到部署一个监视系统并不复杂。关键是要搞清楚所有部分是如何工作的,并将它们连接到一起工作,通过断开/修复/重复的方式,直到它们每一个都能正常工作。 + +这里有一些非常好的工具像 conjure-up 和 Juju。充分发挥这个生态系统贡献者的专长让管理大型软件变得更容易。从一套可靠的应用程序开始,按需定制,然后投入到工作中! + +大胆去尝试吧,然后告诉我你用的如何。你可以在 Freenode IRC 的 **#conjure-up** 和 **#juju** 中找到像我这样的爱好者。感谢阅读! + +### 关于作者 + +Kevin 在 2014 年加入 Canonical 公司,他专注于复杂软件建模。他在 Juju 大型软件团队中找到了自己的位置,他的任务是将大数据和机器学习应用程序转化成可重复的(可靠的)解决方案。 + +-------------------------------------------------------------------------------- + +via: https://insights.ubuntu.com/2018/01/16/monitor-your-kubernetes-cluster/ + +作者:[Kevin Monroe][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://insights.ubuntu.com/author/kwmonroe/ +[1]:https://medium.com/@kwmonroe/monitor-your-kubernetes-cluster-a856d2603ec3 +[2]:https://www.graylog.org/ +[3]:https://prometheus.io/ +[4]:https://insights.ubuntu.com/wp-content/uploads/706b/1_TAA57DGVDpe9KHIzOirrBA.png +[5]:https://conjure-up.io/ +[6]:https://jujucharms.com/canonical-kubernetes +[7]:https://insights.ubuntu.com/wp-content/uploads/98fd/1_o0UmYzYkFiHIs2sBgj7G9A.png +[8]:https://insights.ubuntu.com/wp-content/uploads/0351/1_pgVaO_ZlalrjvYd5pOMJMA.png +[9]:https://insights.ubuntu.com/wp-content/uploads/9977/1_WXKxMlml2DWA5Kj6wW9oXQ.png +[10]:https://insights.ubuntu.com/wp-content/uploads/8588/1_NWq7u6g6UAzyFxtbM-ipqg.png +[11]:https://insights.ubuntu.com/wp-content/uploads/a1c3/1_hHK5mSrRJQi6A6u0yPSGOA.png +[12]:https://insights.ubuntu.com/wp-content/uploads/937f/1_cP36lpmSwlsPXJyDUpFluQ.png +[13]:http://docs.graylog.org/en/2.3/pages/dashboards.html +[14]:https://insights.ubuntu.com/wp-content/uploads/9256/1_kskust3AOImIh18QxQPgRw.png +[15]:https://insights.ubuntu.com/wp-content/uploads/2037/1_qJpjPOTGMQbjFY5-cZsYrQ.png +[16]:https://jujucharms.com/ +[17]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/graylog/steps/01_install-graylog/graylog-vhost.tmpl +[18]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/prometheus-scrape-k8s.yaml +[19]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L25 +[20]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L10 +[21]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L11 +[22]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/grafana-telegraf.json +[23]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/grafana-k8s.json From 060fef7eae30a64220ebe046d0163dd6004271b9 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 17:03:38 +0800 Subject: [PATCH 020/101] PRF:20160606 Learn your tools Navigating your Git History.md @qhwdw --- ... your tools Navigating your Git History.md | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/translated/tech/20160606 Learn your tools Navigating your Git History.md b/translated/tech/20160606 Learn your tools Navigating your Git History.md index 1a7d192837..cbf988f14e 100644 --- a/translated/tech/20160606 Learn your tools Navigating your Git History.md +++ b/translated/tech/20160606 Learn your tools Navigating your Git History.md @@ -1,15 +1,15 @@ -学习你的工具:驾驭你的 Git 历史 +学习用工具来驾驭 Git 历史 ============================================================ -在你的日常工作中,不可能每天都从头开始去开发一个新的应用程序。而真实的情况是,在日常工作中,我们大多数时候所面对的都是遗留下来的一个代码库,我们能够去修改一些特性的内容或者现存的一些代码行,是我们在日常工作中很重要的一部分。而这也就是分布式版本控制系统 `git` 的价值所在。现在,我们来深入了解怎么去使用 `git` 的历史以及如何很轻松地去浏览它的历史。 +在你的日常工作中,不可能每天都从头开始去开发一个新的应用程序。而真实的情况是,在日常工作中,我们大多数时候所面对的都是遗留下来的一个代码库,去修改一些特性的内容或者现存的一些代码行,这是我们在日常工作中很重要的一部分。而这也就是分布式版本控制系统 `git` 的价值所在。现在,我们来深入了解怎么去使用 `git` 的历史以及如何很轻松地去浏览它的历史。 ### Git 历史 -首先和最重要的事是,什么是 `git` 历史?正如其名字一样,它是一个 `git` 仓库的提交历史。它包含一堆提交信息,其中有它们的作者的名字、提交的哈希值以及提交日期。查看一个 `git` 仓库历史的方法很简单,就是一个 `git log` 命令。 +首先和最重要的事是,什么是 `git` 历史?正如其名字一样,它是一个 `git` 仓库的提交历史。它包含一堆提交信息,其中有它们的作者的名字、该提交的哈希值以及提交日期。查看一个 `git` 仓库历史的方法很简单,就是一个 `git log` 命令。 -> _*旁注:**为便于本文的演示,我们使用 Ruby 在 Rails 仓库的 `master` 分支。之所以选择它的理由是因为,Rails 有很好的 `git` 历史,有很好的提交信息、引用以及每个变更的解释。如果考虑到代码库的大小、维护者的年龄和数据,Rails 肯定是我见过的最好的仓库。当然了,我并不是说其它 `git` 仓库做的不好,它只是我见过的比较好的一个仓库。_ +> _旁注:为便于本文的演示,我们使用 Ruby on Rails 的仓库的 `master` 分支。之所以选择它的理由是因为,Rails 有良好的 `git` 历史,漂亮的提交信息、引用以及对每个变更的解释。如果考虑到代码库的大小、维护者的年龄和数量,Rails 肯定是我见过的最好的仓库。当然了,我并不是说其它的 `git` 仓库做的不好,它只是我见过的比较好的一个仓库。_ -因此,回到 Rails 仓库。如果你在 Ralis 仓库上运行 `git log`。你将看到如下所示的输出: +那么,回到 Rails 仓库。如果你在 Ralis 仓库上运行 `git log`。你将看到如下所示的输出: ``` commit 66ebbc4952f6cfb37d719f63036441ef98149418 @@ -72,7 +72,7 @@ Date: Thu Jun 2 21:26:53 2016 -0500 [skip ci] Make header bullets consistent in engines.md ``` -正如你所见,`git log` 展示了提交哈希、作者和他的 email 以及提交日期。当然,`git` 输出的可定制性很强大,它允许你去定制 `git log` 命令的输出格式。比如说,我们希望看到提交的信息显示在一行上,我们可以运行 `git log --oneline`,它将输出一个更紧凑的日志: +正如你所见,`git log` 展示了提交的哈希、作者及其 email 以及该提交创建的日期。当然,`git` 输出的可定制性很强大,它允许你去定制 `git log` 命令的输出格式。比如说,我们只想看提交信息的第一行,我们可以运行 `git log --oneline`,它将输出一个更紧凑的日志: ``` 66ebbc4 Dont re-define class SQLite3Adapter on test @@ -89,15 +89,15 @@ e98caf8 [skip ci] Make header bullets consistent in engines.md 如果你想看 `git log` 的全部选项,我建议你去查阅 `git log` 的 man 页面,你可以在一个终端中输入 `man git-log` 或者 `git help log` 来获得。 -> _**小提示:**如果你觉得 `git log` 看起来太恐怖或者过于复杂,或者你觉得看它太无聊了,我建议你去寻找一些 `git` GUI 命令行工具。在以前的文章中,我使用过 [GitX][1] ,我觉得它很不错,但是,由于我看命令行更“亲切”一些,在我尝试了 [tig][2] 之后,就再也没有去用过它。_ +> _小提示:如果你觉得 `git log` 看起来太恐怖或者过于复杂,或者你觉得看它太无聊了,我建议你去寻找一些 `git` 的 GUI 或命令行工具。在之前,我使用过 [GitX][1] ,我觉得它很不错,但是,由于我看命令行更“亲切”一些,在我尝试了 [tig][2] 之后,就再也没有去用过它。_ -### 查找尼莫 +### 寻找尼莫 -现在,我们已经知道了关于 `git log` 命令一些很基础的知识之后,我们来看一下,在我们的日常工作中如何使用它更加高效地浏览历史。 +现在,我们已经知道了关于 `git log` 命令的一些很基础的知识之后,我们来看一下,在我们的日常工作中如何使用它更加高效地浏览历史。 假如,我们怀疑在 `String#classify` 方法中有一个预期之外的行为,我们希望能够找出原因,并且定位出实现它的代码行。 -为达到上述目的,你可以使用的第一个命令是 `git grep`,通过它可以找到这个方法定义在什么地方。简单来说,这个命令输出了给定的某些“样品”的匹配行。现在,我们来找出定义它的方法,它非常简单 —— 我们对  `def classify` 运行 grep,然后看到的输出如下: +为达到上述目的,你可以使用的第一个命令是 `git grep`,通过它可以找到这个方法定义在什么地方。简单来说,这个命令输出了匹配特定模式的那些行。现在,我们来找出定义它的方法,它非常简单 —— 我们对  `def classify` 运行 grep,然后看到的输出如下: ``` ➜ git grep 'def classify' @@ -113,7 +113,7 @@ activesupport/lib/active_support/core_ext/string/inflections.rb: def classifyact activesupport/lib/active_support/core_ext/string/inflections.rb:205: def classifyactivesupport/lib/active_support/inflector/methods.rb:186: def classify(table_name)tools/profile:112: def classify ``` -更好看了,是吧?考虑到上下文,我们可以很轻松地找到,这个方法在`activesupport/lib/active_support/core_ext/string/inflections.rb` 的第 205 行的 `classify` 方法,它看起来像这样,是不是很容易? +更好看了,是吧?考虑到上下文,我们可以很轻松地找到,这个方法在 `activesupport/lib/active_support/core_ext/string/inflections.rb` 的第 205 行的 `classify` 方法,它看起来像这样,是不是很容易? ``` # Creates a class name from a plural table name like Rails does for table names to models. @@ -127,7 +127,7 @@ activesupport/lib/active_support/core_ext/string/inflections.rb:205: def classi end ``` -尽管这个方法我们找到的是在 `String` 上的一个常见的调用,它涉及到`ActiveSupport::Inflector` 上的另一个方法,使用了相同的名字。获得了 `git grep` 的结果,我们可以很轻松地导航到这里,因此,我们看到了结果的第二行, `activesupport/lib/active_support/inflector/methods.rb` 在 186 行上。我们正在寻找的方法是: +尽管我们找到的这个方法是在 `String` 上的一个常见的调用,它调用了 `ActiveSupport::Inflector` 上的另一个同名的方法。根据之前的 `git grep` 的结果,我们可以很轻松地发现结果的第二行, `activesupport/lib/active_support/inflector/methods.rb` 在 186 行上。我们正在寻找的方法是这样的: ``` # Creates a class name from a plural table name like Rails does for table @@ -146,17 +146,17 @@ def classify(table_name) end ``` -酷!考虑到 Rails 仓库的大小,我们借助 `git grep` 找到它,用时没有超越 30 秒。 +酷!考虑到 Rails 仓库的大小,我们借助 `git grep` 找到它,用时都没有超越 30 秒。 ### 那么,最后的变更是什么? -我们已经掌握了有用的方法,现在,我们需要搞清楚这个文件所经历的变更。由于我们已经知道了正确的文件名和行数,我们可以使用 `git blame`。这个命令展示了一个文件中每一行的最后修订者和修订的内容。我们来看一下这个文件最后的修订都做了什么: +现在,我们已经找到了所要找的方法,现在,我们需要搞清楚这个文件所经历的变更。由于我们已经知道了正确的文件名和行数,我们可以使用 `git blame`。这个命令展示了一个文件中每一行的最后修订者和修订的内容。我们来看一下这个文件最后的修订都做了什么: ``` git blame activesupport/lib/active_support/inflector/methods.rb ``` -虽然我们得到了这个文件每一行的最后的变更,但是,我们更感兴趣的是对指定的方法(176 到 189 行)的最后变更。让我们在 `git blame` 命令上增加一个选项,它将只显示那些行。此外,我们将在命令上增加一个 `-s` (阻止) 选项,去跳过那一行变更时的作者名字和修订(提交)的时间戳: +虽然我们得到了这个文件每一行的最后的变更,但是,我们更感兴趣的是对特定方法(176 到 189 行)的最后变更。让我们在 `git blame` 命令上增加一个选项,让它只显示那些行的变化。此外,我们将在命令上增加一个 `-s` (忽略)选项,去跳过那一行变更时的作者名字和修订(提交)的时间戳: ``` git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb @@ -183,13 +183,13 @@ git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb git show 5bb1d4d2 ``` -你亲自做实验了吗?如果没有做,我直接告诉你结果,这个令人惊叹的 [提交][3] 是由 [Schneems][4] 做的,他通过使用 frozen 字符串做了一个非常有趣的性能优化,这在我们当前的上下文中是非常有意义的。但是,由于我们在这个假设的调试会话中,这样做并不能告诉我们当前问题所在。因此,我们怎么样才能够通过研究来发现,我们选定的方法经过了哪些变更? +你亲自做实验了吗?如果没有做,我直接告诉你结果,这个令人惊叹的 [提交][3] 是由 [Schneems][4] 完成的,他通过使用 frozen 字符串做了一个非常有趣的性能优化,这在我们当前的场景中是非常有意义的。但是,由于我们在这个假设的调试会话中,这样做并不能告诉我们当前问题所在。因此,我们怎么样才能够通过研究来发现,我们选定的方法经过了哪些变更? ### 搜索日志 现在,我们回到 `git` 日志,现在的问题是,怎么能够看到 `classify` 方法经历了哪些修订? -`git log` 命令非常强大,因此它提供了非常多的列表选项。我们尝试去看一下保存了这个文件的 `git` 日志内容。使用 `-p` 选项,它的意思是在 `git` 日志中显示这个文件的完整补丁: +`git log` 命令非常强大,因此它提供了非常多的列表选项。我们尝试使用 `-p` 选项去看一下保存了这个文件的 `git` 日志内容,这个选项的意思是在 `git` 日志中显示这个文件的完整补丁: ``` git log -p activesupport/lib/active_support/inflector/methods.rb @@ -201,13 +201,13 @@ git log -p activesupport/lib/active_support/inflector/methods.rb git log -L 176,189:activesupport/lib/active_support/inflector/methods.rb ``` -`git log` 命令接受了 `-L` 选项,它有一个行的范围和文件名做为参数。它的格式可能有点奇怪,格式解释如下: +`git log` 命令接受 `-L` 选项,它用一个行的范围和文件名做为参数。它的格式可能有点奇怪,格式解释如下: ``` git log -L ,: ``` -当我们去运行这个命令之后,我们可以看到对这些行的一个修订列表,它将带我们找到创建这个方法的第一个修订: +当我们运行这个命令之后,我们可以看到对这些行的一个修订列表,它将带我们找到创建这个方法的第一个修订: ``` commit 51xd6bb829c418c5fbf75de1dfbb177233b1b154 @@ -238,11 +238,11 @@ diff--git a/activesupport/lib/active_support/inflector/methods.rb b/activesuppor 现在,我们再来看一下 —— 它是在 2011 年提交的。`git` 可以让我们重回到这个时间。这是一个很好的例子,它充分说明了足够的提交信息对于重新了解当时的上下文环境是多么的重要,因为从这个提交信息中,我们并不能获得足够的信息来重新理解当时的创建这个方法的上下文环境,但是,话说回来,你**不应该**对此感到恼怒,因为,你看到的这些项目,它们的作者都是无偿提供他们的工作时间和精力来做开源工作的。(向开源项目贡献者致敬!) -回到我们的正题,我们并不能确认 `classify` 方法最初实现是怎么回事,考虑到这个第一次的提交只是一个重构。现在,如果你认为,“或许、有可能、这个方法不在 176 行到 189 行的范围之内,那么就你应该在这个文件中扩大搜索范围”,这样想是对的。我们看到在它的修订提交的信息中提到了“重构”这个词,它意味着这个方法可能在那个文件中是真实存在的,只是在重构之后它才存在于那个行的范围内。 +回到我们的正题,我们并不能确认 `classify` 方法最初实现是怎么回事,考虑到这个第一次的提交只是一个重构。现在,如果你认为,“或许、有可能、这个方法不在 176 行到 189 行的范围之内,那么就你应该在这个文件中扩大搜索范围”,这样想是对的。我们看到在它的修订提交的信息中提到了“重构”这个词,它意味着这个方法可能在那个文件中是真实存在的,而且是在重构之后它才存在于那个行的范围内。 但是,我们如何去确认这一点呢?不管你信不信,`git` 可以再次帮助你。`git log` 命令有一个 `-S` 选项,它可以传递一个特定的字符串作为参数,然后去查找代码变更(添加或者删除)。也就是说,如果我们执行 `git log -S classify` 这样的命令,我们可以看到所有包含 `classify` 字符串的变更行的提交。 -如果你在 Ralis 仓库上运行上述命令,首先你会发现这个命令运行有点慢。但是,你应该会发现 `git` 真的解析了在那个仓库中的所有修订来匹配这个字符串,因为仓库非常大,实际上它的运行速度是非常快的。在你的指尖下 `git` 再次展示了它的强大之处。因此,如果去找关于 `classify` 方法的第一个修订,我们可以运行如下的命令: +如果你在 Ralis 仓库上运行上述命令,首先你会发现这个命令运行有点慢。但是,你应该会发现 `git` 实际上解析了在那个仓库中的所有修订来匹配这个字符串,其实它的运行速度是非常快的。在你的指尖下 `git` 再次展示了它的强大之处。因此,如果去找关于 `classify` 方法的第一个修订,我们可以运行如下的命令: ``` git log -S 'def classify' @@ -258,7 +258,7 @@ Date: Wed Nov 24 01:04:44 2004 +0000 git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de ``` -很酷!是吧?它初次被提交到 Rails,是由 DHHD 在一个 `svn` 仓库上做的!这意味着 `classify` 提交到 Rails 仓库的大概时间。现在,我们去看一下这个提交的所有变更信息,我们运行如下的命令: +很酷!是吧?它初次被提交到 Rails,是由 DHH 在一个 `svn` 仓库上做的!这意味着 `classify` 大概在一开始就被提交到了 Rails 仓库。现在,我们去看一下这个提交的所有变更信息,我们运行如下的命令: ``` git show db045dbbf60b53dbe013ef25554fd013baf88134 @@ -268,7 +268,7 @@ git show db045dbbf60b53dbe013ef25554fd013baf88134 ### 下次见 -当然,我们并不会真的去修改任何 bug,因为我们只是去尝试使用一些 `git` 命令,来演示如何查看 `classify` 方法的演变历史。但是不管怎样,`git` 是一个非常强大的工具,我们必须学好它、用好它。我希望这篇文章可以帮助你掌握更多的关于如何使用 `git` 的知识。 +当然,我们并没有真的去修改任何 bug,因为我们只是去尝试使用一些 `git` 命令,来演示如何查看 `classify` 方法的演变历史。但是不管怎样,`git` 是一个非常强大的工具,我们必须学好它、用好它。我希望这篇文章可以帮助你掌握更多的关于如何使用 `git` 的知识。 你喜欢这些内容吗? @@ -284,9 +284,9 @@ git show db045dbbf60b53dbe013ef25554fd013baf88134 via: https://ieftimov.com/learn-your-tools-navigating-git-history -作者:[Ilija Eftimov ][a] +作者:[Ilija Eftimov][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 341a6b158525c76b4a032f18c5eea2153535143c Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 17:04:23 +0800 Subject: [PATCH 021/101] PUB:20160606 Learn your tools Navigating your Git History.md @qhwdw https://linux.cn/article-9390-1.html --- .../20160606 Learn your tools Navigating your Git History.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20160606 Learn your tools Navigating your Git History.md (100%) diff --git a/translated/tech/20160606 Learn your tools Navigating your Git History.md b/published/20160606 Learn your tools Navigating your Git History.md similarity index 100% rename from translated/tech/20160606 Learn your tools Navigating your Git History.md rename to published/20160606 Learn your tools Navigating your Git History.md From 1f602dac14bd5908d2b6b587945bbb135a9c03fc Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Tue, 27 Feb 2018 21:30:41 +0800 Subject: [PATCH 022/101] Delete 20180221 Getting started with SQL.md --- .../tech/20180221 Getting started with SQL.md | 252 ------------------ 1 file changed, 252 deletions(-) delete mode 100644 sources/tech/20180221 Getting started with SQL.md diff --git a/sources/tech/20180221 Getting started with SQL.md b/sources/tech/20180221 Getting started with SQL.md deleted file mode 100644 index ee2bcb0f1f..0000000000 --- a/sources/tech/20180221 Getting started with SQL.md +++ /dev/null @@ -1,252 +0,0 @@ -Translating by MjSeven - -Getting started with SQL -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X) - -Building a database using SQL is simpler than most people think. In fact, you don't even need to be an experienced programmer to use SQL to create a database. In this article, I'll explain how to create a simple relational database management system (RDMS) using MySQL 5.6. Before I get started, I want to quickly thank [SQL Fiddle][1], which I used to run my script. It provides a useful sandbox for testing simple scripts. - - -In this tutorial, I'll build a database that uses the simple schema shown in the entity relationship diagram (ERD) below. The database lists students and the course each is studying. I used two entities (i.e., tables) to keep things simple, with only a single relationship and dependency. The entities are called `dbo_students` and `dbo_courses`. - -![](https://opensource.com/sites/default/files/u128651/erd.png) - -The multiplicity of the database is 1-to-many, as each course can contain many students, but each student can study only one course. - -A quick note on terminology: - - 1. A table is called an entity. - 2. A field is called an attribute. - 3. A record is called a tuple. - 4. The script used to construct the database is called a schema. - - - -### Constructing the schema - -To construct the database, use the `CREATE TABLE ` command, then define each field name and data type. This database uses `VARCHAR(n)` (string) and `INT(n)` (integer), where n refers to the number of values that can be stored. For example `INT(2)` could be 01. - -This is the code used to create the two tables: -``` -CREATE TABLE dbo_students - -( - -  student_id INT(2) AUTO_INCREMENT NOT NULL, - -  student_name VARCHAR(50), - -  course_studied INT(2), - -  PRIMARY KEY (student_id) - -); - - - -CREATE TABLE dbo_courses - -( - -  course_id INT(2) AUTO_INCREMENT NOT NULL, - -  course_name VARCHAR(30), - -  PRIMARY KEY (course_id) - -); - -``` - -`NOT NULL` means that the field cannot be empty, and `AUTO_INCREMENT` means that when a new tuple is added, the ID number will be auto-generated with 1 added to the previously stored ID number in order to enforce referential integrity across entities. `PRIMARY KEY` is the unique identifier attribute for each table. This means each tuple has its own distinct identity. - -### Relationships as a constraint - -As it stands, the two tables exist on their own with no connections or relationships. To connect them, a foreign key must be identified. In `dbo_students`, the foreign key is `course_studied`, the source of which is within `dbo_courses`, meaning that the field is referenced. The specific command within SQL is called a `CONSTRAINT`, and this relationship will be added using another command called `ALTER TABLE`, which allows tables to be edited even after the schema has been constructed. - -The following code adds the relationship to the database construction script: -``` -ALTER TABLE dbo_students - -ADD CONSTRAINT FK_course_studied - -FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); - -``` - -Using the `CONSTRAINT` command is not actually necessary, but it's good practice because it means the constraint can be named and it makes maintenance easier. Now that the database is complete, it's time to add some data. - -### Adding data to the database - -`INSERT INTO
` is the command used to directly choose which attributes (i.e., fields) data is added to. The entity name is defined first, then the attributes. Underneath this command is the data that will be added to that entity, creating a tuple. If `NOT NULL` has been specified, it means that the attribute cannot be left blank. The following code shows how to add records to the table: -``` -INSERT INTO dbo_courses(course_id,course_name) - -VALUES(001,'Software Engineering'); - -INSERT INTO dbo_courses(course_id,course_name) - -VALUES(002,'Computer Science'); - -INSERT INTO dbo_courses(course_id,course_name) - -VALUES(003,'Computing'); - - - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(001,'student1',001); - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(002,'student2',002); - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(003,'student3',002); - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(004,'student4',003); - -``` - -Now that the database schema is complete and data is added, it's time to run queries on the database. - -### Queries - -Queries follow a set structure using these commands: -``` -SELECT - -FROM - -WHERE - -``` - -To display all records within the `dbo_courses` entity and display the course code and course name, use an asterisk. This is a wildcard that eliminates the need to type all attribute names. (Its use is not recommended in production databases.) The code for this query is: -``` -SELECT * - -FROM dbo_courses - -``` - -The output of this query shows all tuples in the table, so all available courses can be displayed: -``` -| course_id |          course_name | - -|-----------|----------------------| - -|         1 | Software Engineering | - -|         2 |     Computer Science | - -|         3 |            Computing | - -``` - -In a future article, I'll explain more complicated queries using one of the three types of joins: Inner, Outer, or Cross. - -Here is the completed script: -``` -CREATE TABLE dbo_students - -( - -  student_id INT(2) AUTO_INCREMENT NOT NULL, - -  student_name VARCHAR(50), - -  course_studied INT(2), - -  PRIMARY KEY (student_id) - -); - - - -CREATE TABLE dbo_courses - -( - -  course_id INT(2) AUTO_INCREMENT NOT NULL, - -  course_name VARCHAR(30), - -  PRIMARY KEY (course_id) - -); - - - -ALTER TABLE dbo_students - -ADD CONSTRAINT FK_course_studied - -FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); - - - -INSERT INTO dbo_courses(course_id,course_name) - -VALUES(001,'Software Engineering'); - -INSERT INTO dbo_courses(course_id,course_name) - -VALUES(002,'Computer Science'); - -INSERT INTO dbo_courses(course_id,course_name) - -VALUES(003,'Computing'); - - - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(001,'student1',001); - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(002,'student2',002); - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(003,'student3',002); - -INSERT INTO dbo_students(student_id,student_name,course_studied) - -VALUES(004,'student4',003); - - - -SELECT * - -FROM dbo_courses - -``` - -### Learning more - -SQL isn't difficult; I think it is simpler than programming, and the language is universal to different database systems. Note that `dbo.` is not a required entity-naming convention; I used it simply because it is the standard in Microsoft SQL Server. - -If you'd like to learn more, the best guide this side of the internet is [W3Schools.com][2]'s comprehensive guide to SQL for all database platforms. - -Please feel free to play around with my database. Also, if you have suggestions or questions, please respond in the comments. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/2/getting-started-sql - -作者:[Aaron Cocker][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/aaroncocker -[1]:http://sqlfiddle.com -[2]:https://www.w3schools.com/sql/default.asp From f55834288191395b5c2643a3cc7b1effb8652afd Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Tue, 27 Feb 2018 21:31:30 +0800 Subject: [PATCH 023/101] Create 20180221 Getting started with SQL.md --- .../tech/20180221 Getting started with SQL.md | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 translated/tech/20180221 Getting started with SQL.md diff --git a/translated/tech/20180221 Getting started with SQL.md b/translated/tech/20180221 Getting started with SQL.md new file mode 100644 index 0000000000..f579c03c76 --- /dev/null +++ b/translated/tech/20180221 Getting started with SQL.md @@ -0,0 +1,239 @@ +开始使用 SQL +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X) + +使用 SQL 构建数据库比大多数人想象得要简单。实际上,你甚至不需要成为一个有经验的程序员来使用 SQL 创建数据库。在本文中,我将解释如何使用 MySQL 5.6 来创建简单的关系型数据库管理系统(RDMS)。在开始之前,我想快速地感谢 [SQL Fiddle][1],这是我用来运行脚本的工具。它提供了一个用于测试简单脚本的有用的沙箱。 + +在本教程中,我将构建一个使用下面实体关系图(ERD)中显示的简单架构的数据库。数据库列出了学生和正在学习的课程。为了保持简单,我使用了两个实体(即表),只有一种关系和依赖关系。这两个实体称为 `dbo_students` 和 `dbo_courses`。 + +![](https://opensource.com/sites/default/files/u128651/erd.png) + +数据库的多样性是一对多的,因为每门课程可以包含很多学生,但每个学生只能学习一门课程。 + +关于术语的快速说明: + + 1. 一张表称为一个实体。 + 2. 一个字段称为一个属性。 + 3. 一条记录称为一个元组。 + 4. 用于构建数据库的脚本称为架构。 + +### 构建架构 + +要构建数据库,使用 `CREATE TABLE <表名>` 命令,然后定义每个字段的名称和数据类型。数据库使用 `VARCHAR(n)` (字符串)和 `INT(n)` (整数),其中 n 表示可以存储的值的长度。例如 `INT(2)` 可能是 01。 + +这是用于创建两个表的代码: +``` +CREATE TABLE dbo_students + +( + +  student_id INT(2) AUTO_INCREMENT NOT NULL, + +  student_name VARCHAR(50), + +  course_studied INT(2), + +  PRIMARY KEY (student_id) + +); + + + +CREATE TABLE dbo_courses + +( + +  course_id INT(2) AUTO_INCREMENT NOT NULL, + +  course_name VARCHAR(30), + +  PRIMARY KEY (course_id) + +); +``` + +`NOT NULL` 意味着字段不能为空,`AUTO_INCREMENT` 意味着当一个新的元组被添加时,ID 号将自动生成,并将 1 添加到先前存储的 ID 号,来强化各实体之间的完整参照性。 `PRIMARY KEY` 是每个表的惟一标识符属性。这意味着每个元组都有自己的不同的标识。 + +### 关系作为一种约束 + +就目前来看,这两张表格是独立存在的,没有任何联系或关系。要连接它们,必须标识一个外键。在 `dbo_students` 中,外键是 `course_studied`,其来源在 `dbo_courses` 中,意味着该字段被引用。SQL 中的特定命令为 `CONSTRAINT`,并且将使用另一个名为 `ALTER TABLE` 的命令添加这种关系,这样即使在架构构建完毕后,也可以编辑表。 + +以下代码将关系添加到数据库构造脚本中: +``` +ALTER TABLE dbo_students + +ADD CONSTRAINT FK_course_studied + +FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); +``` +使用 `CONSTRAINT` 命令实际上并不是必要的,但这是一个好习惯,因为它意味着约束可以被命名并且使维护更容易。现在数据库已经完成了,是时候添加一些数据了。 + +### 将数据添加到数据库 + +`INSERT INTO <表名>`是用于直接选择将数据添加到哪些属性(即字段)的命令。首先声明实体名称,然后声明属性。命令下边是添加到实体的数据,从而创建一个元组。如果指定了 `NOT NULL`,这表示该属性不能留空。以下代码将展示如何向表中添加记录: +``` +INSERT INTO dbo_courses(course_id,course_name) + +VALUES(001,'Software Engineering'); + +INSERT INTO dbo_courses(course_id,course_name) + +VALUES(002,'Computer Science'); + +INSERT INTO dbo_courses(course_id,course_name) + +VALUES(003,'Computing'); + + + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(001,'student1',001); + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(002,'student2',002); + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(003,'student3',002); + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(004,'student4',003); +``` + +现在数据库架构已经完成并添加了数据,现在是时候在数据库上运行查询了。 + +### 查询 + +查询遵循使用以下命令的集合结构: +``` +SELECT + +FROM + +WHERE +``` + +要显示 `dbo_courses` 实体内的所有记录并显示课程代码和课程名称,请使用 * 。 这是一个通配符,它消除了键入所有属性名称的需要。(在生产数据库中不建议使用它。)此处查询的代码是: +``` +SELECT * + +FROM dbo_courses +``` + +此处查询的输出显示表中的所有元组,因此可显示所有可用课程: +``` +| course_id |          course_name | + +|-----------|----------------------| + +|         1 | Software Engineering | + +|         2 |     Computer Science | + +|         3 |            Computing | +``` + +在以后的文章中,我将使用三种类型的连接之一来解释更复杂的查询:Inner,Outer 或 Cross。 + +这是完整的脚本: +``` +CREATE TABLE dbo_students + +( + +  student_id INT(2) AUTO_INCREMENT NOT NULL, + +  student_name VARCHAR(50), + +  course_studied INT(2), + +  PRIMARY KEY (student_id) + +); + + + +CREATE TABLE dbo_courses + +( + +  course_id INT(2) AUTO_INCREMENT NOT NULL, + +  course_name VARCHAR(30), + +  PRIMARY KEY (course_id) + +); + + + +ALTER TABLE dbo_students + +ADD CONSTRAINT FK_course_studied + +FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); + + + +INSERT INTO dbo_courses(course_id,course_name) + +VALUES(001,'Software Engineering'); + +INSERT INTO dbo_courses(course_id,course_name) + +VALUES(002,'Computer Science'); + +INSERT INTO dbo_courses(course_id,course_name) + +VALUES(003,'Computing'); + + + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(001,'student1',001); + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(002,'student2',002); + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(003,'student3',002); + +INSERT INTO dbo_students(student_id,student_name,course_studied) + +VALUES(004,'student4',003); + + + +SELECT * + +FROM dbo_courses +``` + +### 学习更多 + +SQL 并不困难;我认为它比编程简单,并且该语言对于不同的数据库系统是通用的。 请注意,`dbo.<实体>` (译者注:文章中使用的是 `dbo_<实体>`) 不是必需的实体命名约定;我之所以使用,仅仅是因为它是 Microsoft SQL Server 中的标准。 + +如果你想了解更多,在网络上这方面的最佳指南是 [W3Schools.com][2] 中对所有数据库平台的 SQL 综合指南。 + +请随意使用我的数据库。另外,如果你有任何建议或疑问,请在评论中回复。(译注:请点击原文地址进行评论回应) + +-------------------------------------------------------------------------------- + +via: [https://opensource.com/article/18/2/getting-started-sql](https://opensource.com/article/18/2/getting-started-sql) + +作者:[Aaron Cocker][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/aaroncocker +[1]:http://sqlfiddle.com +[2]:https://www.w3schools.com/sql/default.asp From 5ec887b9d5891ee40067d28a0a0b7700cc5725d7 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 21:58:48 +0800 Subject: [PATCH 024/101] =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename translated/tech/{20180209 How to Install Gogs Go Git Service on Ubuntu 16.04 => 20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md} (100%) diff --git a/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04 b/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md similarity index 100% rename from translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04 rename to translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md From 8aac8f3f8de7245b35236eb61f10ee0a312e5e4b Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 22:32:26 +0800 Subject: [PATCH 025/101] PRF:20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md @CYLeft --- ...all Gogs Go Git Service on Ubuntu 16.04.md | 167 ++++++++++-------- 1 file changed, 98 insertions(+), 69 deletions(-) diff --git a/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md b/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md index 6923c0e332..52c5c59dc7 100644 --- a/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md +++ b/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md @@ -1,9 +1,9 @@ -如何在 Ubuntu 16.04 上使用 Gogs 安装 Go 语言编写的 Git 服务器 +如何在 Ubuntu 安装 Go 语言编写的 Git 服务器 Gogs ====== -Gogs 是由 Go 语言编写,提供开源且免费的 Git 服务。Gogs 是一款无痛式自托管的 Git 服务器,能在尽可能小的硬件资源开销上搭建并运行您的私有 Git 服务器。Gogs 的网页界面和 GitHub 十分相近,且提供 MySQL、PostgreSQL 和 SQLite 数据库支持。 +Gogs 是由 Go 语言编写的,自由开源的 Git 服务。Gogs 是一款无痛式自托管的 Git 服务器,能在尽可能小的硬件资源开销上搭建并运行您的私有 Git 服务器。Gogs 的网页界面和 GitHub 十分相近,且提供 MySQL、PostgreSQL 和 SQLite 数据库支持。 -在本教程中,我们将使用 Gogs 在 Ununtu 16.04 上按步骤,指导您安装和配置您的私有 Git 服务器。这篇教程中涵盖了如何在 Ubuntu 上安装 Go 语言、PostgreSQL 和安装并且配置 Nginx 网页服务器作为 Go 应用的反向代理的细节内容。 +在本教程中,我们将使用 Gogs 在 Ununtu 16.04 上按步骤指导您安装和配置您的私有 Git 服务器。这篇教程中涵盖了如何在 Ubuntu 上安装 Go 语言、PostgreSQL 和安装并且配置 Nginx 网页服务器作为 Go 应用的反向代理的细节内容。 ### 搭建环境 @@ -22,9 +22,11 @@ Gogs 是由 Go 语言编写,提供开源且免费的 Git 服务。Gogs 是一 8. 测试 ### 步骤 1 - 更新和升级系统 + 继续之前,更新 Ubuntu 所有的库,升级所有包。 -运行下面的 apt 命令 +运行下面的 `apt` 命令: + ``` sudo apt update sudo apt upgrade @@ -36,12 +38,14 @@ Gogs 提供 MySQL、PostgreSQL、SQLite 和 TiDB 数据库系统支持。 此步骤中,我们将使用 PostgreSQL 作为 Gogs 程序的数据库。 -使用下面的 apt 命令安装 PostgreSQL。 +使用下面的 `apt` 命令安装 PostgreSQL。 + ``` sudo apt install -y postgresql postgresql-client libpq-dev ``` 安装完成之后,启动 PostgreSQL 服务并设置为开机启动。 + ``` systemctl start postgresql systemctl enable postgresql @@ -51,62 +55,71 @@ systemctl enable postgresql 之后,我们需要为 Gogs 创建数据库和用户。 -使用 'postgres' 用户登陆并运行 ‘psql’ 命令获取 PostgreSQL 操作界面. +使用 `postgres` 用户登录并运行 `psql` 命令以访问 PostgreSQL 操作界面。 + ``` su - postgres psql ``` -创建一个名为 ‘git’ 的新用户,给予此用户 ‘CREATEDB’ 权限。 +创建一个名为 `git` 的新用户,给予此用户 `CREATEDB` 权限。 + ``` CREATE USER git CREATEDB; \password git ``` -创建名为 ‘gogs_production’ 的数据库,设置 ‘git’ 用户作为其所有者。 +创建名为 `gogs_production` 的数据库,设置 `git` 用户作为其所有者。 + ``` CREATE DATABASE gogs_production OWNER git; ``` [![创建 Gogs 数据库][1]][2] -作为 Gogs 安装时的 ‘gogs_production’ PostgreSQL 数据库和 ‘git’ 用户已经创建完毕。 +用于 Gogs 的 `gogs_production` PostgreSQL 数据库和 `git` 用户已经创建完毕。 ### 步骤 3 - 安装 Go 和 Git -使用下面的 apt 命令从库中安装 Git。 +使用下面的 `apt` 命令从库中安装 Git。 + ``` sudo apt install git ``` -此时,为系统创建名为 ‘git’ 的新用户。 +此时,为系统创建名为 `git` 的新用户。 + ``` sudo adduser --disabled-login --gecos 'Gogs' git ``` -登陆 ‘git’ 账户并且创建名为 ‘local’ 的目录。 +登录 `git` 账户并且创建名为 `local` 的目录。 + ``` su - git mkdir -p /home/git/local ``` -切换到 ‘local’ 目录,依照下方所展示的内容,使用 wget 命令下载 ‘Go’(最新版)。 +切换到 `local` 目录,依照下方所展示的内容,使用 `wget` 命令下载 Go(最新版)。 + ``` cd ~/local -wget +wget https://dl.google.com/go/go1.9.2.linux-amd64.tar.gz ``` [![安装 Go 和 Git][3]][4] 解压并且删除 go 的压缩文件。 + ``` tar -xf go1.9.2.linux-amd64.tar.gz rm -f go1.9.2.linux-amd64.tar.gz ``` -‘Go’ 二进制文件已经被下载到 ‘~/local/go’ 目录。此时我们需要设置环境变量 - 设置 ‘GOROOT’ 和 ‘GOPATH’ 目录到系统环境,这样,我们就可以在 ‘git’ 用户下执行 ‘go’ 命令。 +Go 二进制文件已经被下载到 `~/local/go` 目录。此时我们需要设置环境变量 - 设置 `GOROOT` 和 `GOPATH` 目录到系统环境,这样,我们就可以在 `git` 用户下执行 `go` 命令。 执行下方的命令。 + ``` cd ~/ echo 'export GOROOT=$HOME/local/go' >> $HOME/.bashrc @@ -114,7 +127,8 @@ echo 'export GOPATH=$HOME/go' >> $HOME/.bashrc echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> $HOME/.bashrc ``` -之后通过运行 'source ~/.bashrc' 重载 Bash,如下: +之后通过运行 `source ~/.bashrc` 重载 Bash,如下: + ``` source ~/.bashrc ``` @@ -123,7 +137,8 @@ source ~/.bashrc [![安装 Go 编程语言][5]][6] -现在运行 'go' 的版本查看命令。 +现在运行 `go` 的版本查看命令。 + ``` go version ``` @@ -132,27 +147,30 @@ go version [![检查 go 版本][7]][8] -现在,Go 已经安装在系统的 ‘git’ 用户下了。 +现在,Go 已经安装在系统的 `git` 用户下了。 ### 步骤 4 - 使用 Gogs 安装 Git 服务 -使用 ‘git’ 用户登陆并且使用 ‘go’ 命令从 GitHub 下载 ‘Gogs’。 +使用 `git` 用户登录并且使用 `go` 命令从 GitHub 下载 Gogs。 + ``` su - git go get -u github.com/gogits/gogs ``` -此命令将在 ‘GOPATH/src’ 目录下载 Gogs 的所有源代码。 +此命令将在 `GOPATH/src` 目录下载 Gogs 的所有源代码。 + +切换至 `$GOPATH/src/github.com/gogits/gogs` 目录,并且使用下列命令搭建 Gogs。 -切换至 '$GOPATH/src/github.com/gogits/gogs' 目录,并且使用下列命令搭建 gogs。 ``` cd $GOPATH/src/github.com/gogits/gogs go build ``` -确保您没有捕获到错误。 +确保您没有遇到错误。 现在使用下面的命令运行 Gogs Go Git 服务器。 + ``` ./gogs web ``` @@ -161,31 +179,34 @@ go build [![安装 Gogs Go Git 服务][9]][10] -打开网页浏览器,键入您的 IP 地址和端口号,我的是 +打开网页浏览器,键入您的 IP 地址和端口号,我的是 http://192.168.33.10:3000/ 。 -您应该会得到于下方一致的反馈。 +您应该会得到与下方一致的反馈。 [![Gogs 网页服务器][11]][12] -Gogs 已经在您的 Ubuntu 系统上安装完毕。现在返回到您的终端,并且键入 'Ctrl + c' 中止服务。 +Gogs 已经在您的 Ubuntu 系统上安装完毕。现在返回到您的终端,并且键入 `Ctrl + C` 中止服务。 ### 步骤 5 - 配置 Gogs Go Git 服务器 本步骤中,我们将为 Gogs 创建惯例配置。 -进入 Gogs 安装目录并新建 ‘custom/conf’ 目录。 +进入 Gogs 安装目录并新建 `custom/conf` 目录。 + ``` cd $GOPATH/src/github.com/gogits/gogs mkdir -p custom/conf/ ``` -复制默认的配置文件到 custom 目录,并使用 [vim][13] 修改。 +复制默认的配置文件到 `custom` 目录,并使用 [vim][13] 修改。 + ``` cp conf/app.ini custom/conf/app.ini vim custom/conf/app.ini ``` -在 ‘ **[server]** ’ 选项中,修改 ‘HOST_ADDR’ 为 ‘127.0.0.1’. +在 `[server]` 小节中,修改 `HOST_ADDR` 为 `127.0.0.1`。 + ``` [server] PROTOCOL = http @@ -193,23 +214,23 @@ vim custom/conf/app.ini ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ HTTP_ADDR = 127.0.0.1 HTTP_PORT = 3000 - ``` -在 ‘ **[database]** ’ 选项中,按照您的数据库信息修改。 +在 `[database]` 选项中,按照您的数据库信息修改。 + ``` [database] DB_TYPE = postgres HOST = 127.0.0.1:5432 NAME = gogs_production USER = git - PASSWD = [email protected]# - + PASSWD = aqwe123@# ``` 保存并退出。 运行下面的命令验证配置项。 + ``` ./gogs web ``` @@ -218,54 +239,57 @@ vim custom/conf/app.ini [![配置服务器][14]][15] -Gogs 现在已经按照自定义配置下运行在 ‘localhost’ 的 3000 端口上了。 +Gogs 现在已经按照自定义配置下运行在 `localhost` 的 3000 端口上了。 ### 步骤 6 - 运行 Gogs 服务器 -这一步,我们将在 Ubuntu 系统上配置 Gogs 服务器。我们会在 ‘/etc/systemd/system’ 目录下创建一个新的服务器配置文件 ‘gogs.service’。 +这一步,我们将在 Ubuntu 系统上配置 Gogs 服务器。我们会在 `/etc/systemd/system` 目录下创建一个新的服务器配置文件 `gogs.service`。 + +切换到 `/etc/systemd/system` 目录,使用 [vim][13] 创建服务器配置文件 `gogs.service`。 -切换到 ‘/etc/systemd/system’ 目录,使用 [vim][13] 创建服务器配置文件 ‘gogs.service’。 ``` cd /etc/systemd/system vim gogs.service ``` -粘贴下面的代码到 gogs 服务器配置文件中。 +粘贴下面的代码到 Gogs 服务器配置文件中。 + ``` [Unit] - Description=Gogs - After=syslog.target - After=network.target - After=mariadb.service mysqld.service postgresql.service memcached.service redis.service +Description=Gogs +After=syslog.target +After=network.target +After=mariadb.service mysqld.service postgresql.service memcached.service redis.service - [Service] - # Modify these two values and uncomment them if you have - # repos with lots of files and get an HTTP error 500 because - # of that - ### - #LimitMEMLOCK=infinity - #LimitNOFILE=65535 - Type=simple - User=git - Group=git - WorkingDirectory=/home/git/go/src/github.com/gogits/gogs - ExecStart=/home/git/go/src/github.com/gogits/gogs/gogs web - Restart=always - Environment=USER=git HOME=/home/git - - [Install] - WantedBy=multi-user.target +[Service] +# Modify these two values and uncomment them if you have +# repos with lots of files and get an HTTP error 500 because +# of that +### +#LimitMEMLOCK=infinity +#LimitNOFILE=65535 +Type=simple +User=git +Group=git +WorkingDirectory=/home/git/go/src/github.com/gogits/gogs +ExecStart=/home/git/go/src/github.com/gogits/gogs/gogs web +Restart=always +Environment=USER=git HOME=/home/git +[Install] +WantedBy=multi-user.target ``` 之后保存并且退出。 现在可以重载系统服务器。 + ``` systemctl daemon-reload ``` -使用下面的命令开启 gogs 服务器并设置为开机启动。 +使用下面的命令开启 Gogs 服务器并设置为开机启动。 + ``` systemctl start gogs systemctl enable gogs @@ -276,6 +300,7 @@ systemctl enable gogs Gogs 服务器现在已经运行在 Ubuntu 系统上了。 使用下面的命令检测: + ``` netstat -plntu systemctl status gogs @@ -290,23 +315,27 @@ systemctl status gogs 在本步中,我们将为 Gogs 安装和配置 Nginx 反向代理。我们会在自己的库中调用 Nginx 包。 使用下面的命令添加 Nginx 库。 + ``` sudo add-apt-repository -y ppa:nginx/stable ``` 此时更新所有的库并且使用下面的命令安装 Nginx。 + ``` sudo apt update sudo apt install nginx -y ``` -之后,进入 ‘/etc/nginx/sites-available’ 目录并且创建虚拟主机文件 ‘gogs’。 +之后,进入 `/etc/nginx/sites-available` 目录并且创建虚拟主机文件 `gogs`。 + ``` cd /etc/nginx/sites-available vim gogs ``` -粘贴下面的代码到配置项。 +粘贴下面的代码到配置文件。 + ``` server {     listen 80; @@ -316,21 +345,21 @@ server {         proxy_pass http://localhost:3000;     } } - ``` 保存退出。 -**注意:** -使用您的域名修改 ‘server_name’ 项。 +**注意:** 请使用您的域名修改 `server_name` 项。 现在激活虚拟主机并且测试 nginx 配置。 + ``` ln -s /etc/nginx/sites-available/gogs /etc/nginx/sites-enabled/ nginx -t ``` -确保没有抛错,重启 Nginx 服务器。 +确保没有遇到错误,重启 Nginx 服务器。 + ``` systemctl restart nginx ``` @@ -339,25 +368,25 @@ systemctl restart nginx ### 步骤 8 - 测试 -打开您的网页浏览器并且输入您的 gogs URL,我的是 +打开您的网页浏览器并且输入您的 Gogs URL,我的是 http://git.hakase-labs.co 现在您将进入安装界面。在页面的顶部,输入您所有的 PostgreSQL 数据库信息。 [![Gogs 安装][22]][23] -之后,滚动到底部,点击 ‘Admin account settings’ 下拉选项。 +之后,滚动到底部,点击 “Admin account settings” 下拉选项。 输入您的管理者用户名和邮箱。 [![键入 gogs 安装设置][24]][25] -之后点击 ‘Install Gogs’ 按钮。 +之后点击 “Install Gogs” 按钮。 然后您将会被重定向到下图显示的 Gogs 用户面板。 [![Gogs 面板][26]][27] -下面是 Gogs ‘Admin Dashboard(管理员面板)’。 +下面是 Gogs 的 “Admin Dashboard(管理员面板)”。 [![浏览 Gogs 面板][28]][29] @@ -369,7 +398,7 @@ via: https://www.howtoforge.com/tutorial/how-to-install-gogs-go-git-service-on-u 作者:[Muhammad Arul][a] 译者:[CYLeft](https://github.com/CYLeft) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ac544d57ba443f7d6f50e8981b7f8ebc21aa6083 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 22:32:55 +0800 Subject: [PATCH 026/101] PUB:20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md @CYLeft https://linux.cn/article-9391-1.html --- ...20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md (100%) diff --git a/translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md b/published/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md similarity index 100% rename from translated/tech/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md rename to published/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md From 373db05c958a6ef949cad0000ff8b0999c294e65 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 23:16:15 +0800 Subject: [PATCH 027/101] PRF:20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md @geekpi --- ...le without restarting vim on Linux-Unix.md | 66 ++++++++----------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/translated/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md b/translated/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md index 44fbad8c5c..0572935c15 100644 --- a/translated/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md +++ b/translated/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md @@ -1,77 +1,67 @@ -如何在 Linux/Unix 中不重启 vim 而重新加载 .vimrc 文件 +如何在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件 ====== -我是一位新的 vim 编辑器用户。我通常加载 ~/.vimrc 用于配置。在编辑 .vimrc 时,我需要不重启 vim 会话而重新加载它。在 Linux 或者类 Unix 系统中,如何在编辑 .vimrc 后,重新加载它而不用重启 vim? +我是一位新的 Vim 编辑器用户。我通常使用 `:vs ~/.vimrc` 来加载 `~/.vimrc` 配置。而当我编辑 `.vimrc` 时,我需要不重启 Vim 会话而重新加载它。在 Linux 或者类 Unix 系统中,如何在编辑 `.vimrc` 后,重新加载它而不用重启 Vim 呢? -vim 是免费开源并且向上兼容 vi 的编辑器。它可以用来编辑各种文本。它在编辑用 C/Perl/Python 编写的程序时特别有用。可以用它来编辑 Linux/Unix 配置文件。~/.vimrc 是你个人的 vim 初始化和自定义文件。 +Vim 是自由开源并且向上兼容 Vi 的编辑器。它可以用来编辑各种文本。它在编辑用 C/Perl/Python 编写的程序时特别有用。可以用它来编辑 Linux/Unix 配置文件。`~/.vimrc` 是你个人的 Vim 初始化和自定义文件。 -### 如何在不重启 vim 会话的情况下重新加载 .vimrc +### 如何在不重启 Vim 会话的情况下重新加载 .vimrc -在 vim 中重新加载 .vimrc 而不重新启动的流程: +在 Vim 中重新加载 `.vimrc` 而不重新启动的流程: - 1. 输入 `vim filename` 启动 vim - 2. 按下 `Esc` 接着输入 `:vs ~/.vimrc` 来加载 vim 配置 - 3. 像这样添加自定义: +1. 输入 `vim filename` 启动 vim +2. 按下 `Esc` 接着输入 `:vs ~/.vimrc` 来加载 vim 配置 +3. 像这样添加自定义配置: - ``` - filetype indent plugin on - set number - syntax on - ``` - - 4. 使用 `:wq` 保存文件,并从 ~/.vimrc 窗口退出 - 5. 输入下面任一命令重载 ~/.vimrc: - - ``` - :so $MYVIMRC - ``` - 或者 - ``` - :source ~/.vimrc - ``` + ``` +filetype indent plugin on +set number +syntax on +``` +4. 使用 `:wq` 保存文件,并从 `~/.vimrc` 窗口退出 +5. 输入下面任一命令重载 `~/.vimrc`:`:so $MYVIMRC` 或者 `:source ~/.vimrc`。 [![How to reload .vimrc file without restarting vim][1]][1] -图1:编辑 ~/.vimrc 并在需要的时候重载而不用退出 vim,这样你就可以继续编辑程序了 -`:so[urce]! {file}` 这个 vim 命令会从给定的文件比如 ~/.vimrc 读取配置。这些命令是在正常模式下执行,就像你输入它们一样。当你在 :global、:argdo、 :windo、:bufdo 之后、循环中或者跟着另一个命令时,显示不会再在执行命令时更新。 +*图1:编辑 ~/.vimrc 并在需要时重载它而不用退出 vim,这样你就可以继续编辑程序了* -### 如何编辑按键来编辑并重载 ~/.vimrc +`:so[urce]! {file}` 这个 vim 命令会从给定的文件比如 `~/.vimrc` 读取配置。就像你输入的一样,这些命令是在普通模式下执行的。当你在 `:global`、:`argdo`、 `:windo`、`:bufdo` 之后、循环中或者跟着另一个命令时,显示不会再在执行命令时更新。 -在你的 ~/.vimrc 后面跟上这些 +### 如何设置按键来编辑并重载 ~/.vimrc + +在你的 `~/.vimrc` 后面跟上这些: ``` " Edit vimr configuration file nnoremap confe :e $MYVIMRC -" - - Reload vims configuration file +" Reload vims configuration file nnoremap confr :source $MYVIMRC ``` -现在只要按下 `Esc` 接着输入 `confe` 开编辑 ~/.vimrc。按下 `Esc` ,接着输入 `confr` 来重新加载。一些喜欢在 .vimrc 中使用 。因此上面的映射变成: +现在只要按下 `Esc` 接着输入 `confe` 就可以编辑 `~/.vimrc`。按下 `Esc` ,接着输入 `confr` 以重新加载。一些人喜欢在 `.vimrc` 中使用 `` 键。因此上面的映射变成: ``` " Edit vimr configuration file nnoremap ve :e $MYVIMRC -" " Reload vimr configuration file nnoremap vr :source $MYVIMRC ``` - 键默认映射成 \\ 键。因此只要输入 \\ 接着 ve 就能编辑文件。按下 \\ 接着 vr 就能重载 ~/vimrc。 - 这就完成了,你可以不用再重启 vim 就能重新加载 .vimrc 了。 +`` 键默认映射成 `\` 键。因此只要输入 `\` 接着 `ve` 就能编辑文件。按下 `\` 接着 `vr` 就能重载 `~/vimrc`。 + +这就完成了,你可以不用再重启 Vim 就能重新加载 `.vimrc` 了。 ### 关于作者 -作者是 nixCraft 的创建者,经验丰富的系统管理员,也是 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][9]、[Facebook][10]、[Google +][11] 上关注他。通过[我的 RSS/XML 订阅][5]获取**最新的系统管理、Linux/Unix 以及开源主题教程**。 +作者是 nixCraft 的创建者,经验丰富的系统管理员,也是 Linux / Unix shell 脚本的培训师。他曾与全球客户以及IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][9]、[Facebook][10]、[Google +][11] 上关注他。通过[RSS/XML 订阅][5]获取最新的系统管理、Linux/Unix 以及开源主题教程。 -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/faq/how-to-reload-vimrc-file-without-restarting-vim-on-linux-unix/ 作者:[Vivek Gite][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From c429cc8bd03d62fc5f86a94492683e5ac850c2a4 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 27 Feb 2018 23:16:41 +0800 Subject: [PATCH 028/101] PUB:20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md @geekpi --- ... to reload .vimrc file without restarting vim on Linux-Unix.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md (100%) diff --git a/translated/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md b/published/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md similarity index 100% rename from translated/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md rename to published/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md From dc868907b901b33acaa6daf202a78e75125515ba Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 28 Feb 2018 00:25:49 +0800 Subject: [PATCH 029/101] PRF:20090203 How the Kernel Manages Your Memory.md @qhwdw --- ...0203 How the Kernel Manages Your Memory.md | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/translated/tech/20090203 How the Kernel Manages Your Memory.md b/translated/tech/20090203 How the Kernel Manages Your Memory.md index ca66bfdf3e..2e72498165 100644 --- a/translated/tech/20090203 How the Kernel Manages Your Memory.md +++ b/translated/tech/20090203 How the Kernel Manages Your Memory.md @@ -1,54 +1,53 @@ 内核如何管理内存 ============================================================ - -在学习了进程的 [虚拟地址布局][1] 之后,我们回到内核,来学习它管理用户内存的机制。这里再次使用 Gonzo: +在学习了进程的 [虚拟地址布局][1] 之后,让我们回到内核,来学习它管理用户内存的机制。这里再次使用 Gonzo: ![Linux kernel mm_struct](http://static.duartes.org/img/blogPosts/mm_struct.png) -Linux 进程在内核中是作为进程描述符 [task_struct][2] (译者注:它是在 Linux 中描述进程完整信息的一种数据结构)的实例来实现的。在 task_struct 中的  [mm][3]  域指向到内存描述符,[mm_struct][4] 是一个程序在内存中的执行摘要。它保存了起始和结束内存段,如下图所示,进程使用的物理内存页面的 [数量][5](RSS 译者注:(Resident Set Size)常驻内存大小 )、虚拟地址空间使用的 [总数量][6]、以及其它片断。 在内存描述中,我们可以获悉它有两种管理内存的方式:虚拟内存区域集和页面表。Gonzo 的内存区域如下所示: +Linux 进程在内核中是作为进程描述符 [task_struct][2] (LCTT 译注:它是在 Linux 中描述进程完整信息的一种数据结构)的实例来实现的。在 task_struct 中的  [mm][3]  域指向到**内存描述符**,[mm_struct][4] 是一个程序在内存中的执行摘要。如上图所示,它保存了起始和结束内存段,进程使用的物理内存页面的 [数量][5](RSS 常驻内存大小Resident Set Size )、虚拟地址空间使用的 [总数量][6]、以及其它片断。 在内存描述符中,我们可以获悉它有两种管理内存的方式:**虚拟内存区域**集和**页面表**。Gonzo 的内存区域如下所示: ![Kernel memory descriptor and memory areas](http://static.duartes.org/img/blogPosts/memoryDescriptorAndMemoryAreas.png) -每个虚拟内存区域(VMA)是一个连续的虚拟地址范围;这些区域绝对不会重叠。一个 [vm_area_struct][7] 的实例完整描述了一个内存区域,包括它的起始和结束地址,[flags][8] 决定了访问权限和行为,并且 [vm_file][9] 域指定了映射到这个区域的文件(如果有的话)。除了内存映射段的例外情况之外,一个 VMA 是不能匿名映射文件的,上面的每个内存段(比如,堆、栈)都对应一个单个的 VMA。虽然它通常都使用在 x86 的机器上,但它并不是必需的。VMAs 也不关心它们在哪个段中。 +每个虚拟内存区域(VMA)是一个连续的虚拟地址范围;这些区域绝对不会重叠。一个 [vm_area_struct][7] 的实例完整地描述了一个内存区域,包括它的起始和结束地址,[flags][8] 决定了访问权限和行为,并且 [vm_file][9] 域指定了映射到这个区域的文件(如果有的话)。(除了内存映射段的例外情况之外,)一个 VMA 是不能**匿名**映射文件的。上面的每个内存段(比如,堆、栈)都对应一个单个的 VMA。虽然它通常都使用在 x86 的机器上,但它并不是必需的。VMA 也不关心它们在哪个段中。 -一个程序的 VMAs 在内存描述符中作为 [mmap][10] 域的一个链接列表保存的,以起始虚拟地址为序进行排列,并且在 [mm_rb][12] 域中作为一个 [红黑树][11] 的根。红黑树允许内核通过给定的虚拟地址去快速搜索内存区域。在你读取文件 `/proc/pid_of_process/maps`时,内核只是简单地读取每个进程的 VMAs 的链接列表并显示它们。 +一个程序的 VMA 在内存描述符中是作为 [mmap][10] 域的一个链接列表保存的,以起始虚拟地址为序进行排列,并且在 [mm_rb][12] 域中作为一个 [红黑树][11] 的根。红黑树允许内核通过给定的虚拟地址去快速搜索内存区域。在你读取文件 `/proc/pid_of_process/maps` 时,内核只是简单地读取每个进程的 VMA 的链接列表并[显示它们][13]。 在 Windows 中,[EPROCESS][14] 块大致类似于一个 task_struct 和 mm_struct 的结合。在 Windows 中模拟一个 VMA 的是虚拟地址描述符,或称为 [VAD][15];它保存在一个 [AVL 树][16] 中。你知道关于 Windows 和 Linux 之间最有趣的事情是什么吗?其实它们只有一点小差别。 -4GB 虚拟地址空间被分为两个页面。在 32 位模式中的 x86 处理器中支持 4KB、2MB、以及 4MB 大小的页面。Linux 和 Windows 都使用大小为 4KB 的页面去映射用户的一部分虚拟地址空间。字节 0-4095 在 page 0 中,字节 4096-8191 在 page 1 中,依次类推。VMA 的大小 _必须是页面大小的倍数_ 。下图是使用 4KB 大小页面的总数量为 3GB 的用户空间: +4GB 虚拟地址空间被分配到**页面**中。在 32 位模式中的 x86 处理器中支持 4KB、2MB、以及 4MB 大小的页面。Linux 和 Windows 都使用大小为 4KB 的页面去映射用户的一部分虚拟地址空间。字节 0-4095 在页面 0 中,字节 4096-8191 在页面 1 中,依次类推。VMA 的大小 _必须是页面大小的倍数_ 。下图是使用 4KB 大小页面的总数量为 3GB 的用户空间: ![4KB Pages Virtual User Space](http://static.duartes.org/img/blogPosts/pagedVirtualSpace.png) -处理器通过查看页面表去转换一个虚拟内存地址到一个真实的物理内存地址。每个进程都有它自己的一组页面表;每当发生进程切换时,用户空间的页面表也同时切换。Linux 在内存描述符的 [pgd][17] 域中保存了一个指向处理器页面表的指针。对于每个虚拟页面,页面表中都有一个相应的页面表条目(PTE),在常规的 x86 页面表中,它是一个简单的如下所示的大小为 4 字节的一条记录: +处理器通过查看**页面表**去转换一个虚拟内存地址到一个真实的物理内存地址。每个进程都有它自己的一组页面表;每当发生进程切换时,用户空间的页面表也同时切换。Linux 在内存描述符的 [pgd][17] 域中保存了一个指向进程的页面表的指针。对于每个虚拟页面,页面表中都有一个相应的**页面表条目**(PTE),在常规的 x86 页面表中,它是一个简单的如下所示的大小为 4 字节的记录: ![x86 Page Table Entry (PTE) for 4KB page](http://static.duartes.org/img/blogPosts/x86PageTableEntry4KB.png) -Linux 通过函数去 [读取][18] 和 [设置][19]  PTE 条目中的每个标志位。标志位 P 告诉处理器这个虚拟页面是否在物理内存中。如果被清除(设置为 0),访问这个页面将触发一个页面故障。请记住,当这个标志位为 0 时,内核可以在剩余的域上做任何想做的事。R/W 标志位是读/写标志;如果被清除,这个页面将变成只读的。U/S 标志位表示用户/超级用户;如果被清除,这个页面将仅被内核访问。这些标志都是用于实现我们在前面看到的只读内存和内核空间保护。 +Linux 通过函数去 [读取][18] 和 [设置][19]  PTE 条目中的每个标志位。标志位 P 告诉处理器这个虚拟页面是否**在**物理内存中。如果该位被清除(设置为 0),访问这个页面将触发一个页面故障。请记住,当这个标志位为 0 时,内核可以在剩余的域上**做任何想做的事**。R/W 标志位是读/写标志;如果被清除,这个页面将变成只读的。U/S 标志位表示用户/超级用户;如果被清除,这个页面将仅被内核访问。这些标志都是用于实现我们在前面看到的只读内存和内核空间保护。 -标志位 D 和 A 用于标识页面是否是“脏的”或者是已被访问过。一个脏页面表示已经被写入,而一个被访问过的页面则表示有一个写入或者读取发生过。这两个标志位都是粘滞位:处理器只能设置它们,而清除则是由内核来完成的。最终,PTE 保存了这个页面相应的起始物理地址,它们按 4KB 进行整齐排列。这个看起来有点小的域是一些痛苦的根源,因为它限制了物理内存最大为 [4 GB][20]。其它的 PTE 域留到下次再讲,因为它是涉及了物理地址扩展的知识。 +标志位 D 和 A 用于标识页面是否是“**脏的**”或者是已**被访问过**。一个脏页面表示已经被写入,而一个被访问过的页面则表示有一个写入或者读取发生过。这两个标志位都是粘滞位:处理器只能设置它们,而清除则是由内核来完成的。最终,PTE 保存了这个页面相应的起始物理地址,它们按 4KB 进行整齐排列。这个看起来不起眼的域是一些痛苦的根源,因为它限制了物理内存最大为 [4 GB][20]。其它的 PTE 域留到下次再讲,因为它是涉及了物理地址扩展的知识。 -由于在一个虚拟页面上的所有字节都共享一个 U/S 和 R/W 标志位,所以内存保护的最小单元是一个虚拟页面。但是,同一个物理内存可能被映射到不同的虚拟页面,这样就有可能会出现相同的物理内存出现不同的保护标志位的情况。请注意,在 PTE 中是看不到运行权限的。这就是为什么经典的 x86 页面上允许代码在栈上被执行的原因,这样会很容易导致挖掘栈缓冲溢出的漏洞(可能会通过使用 [return-to-libc][21] 和其它技术来开发非可执行栈)。由于 PTE 缺少禁止运行标志位说明了一个更广泛的事实:在 VMA 中的权限标志位有可能或者不可能完全转换为硬件保护。内核只能做它能做到的,但是,最终的架构限制了它能做的事情。 +由于在一个虚拟页面上的所有字节都共享一个 U/S 和 R/W 标志位,所以内存保护的最小单元是一个虚拟页面。但是,同一个物理内存可能被映射到不同的虚拟页面,这样就有可能会出现相同的物理内存出现不同的保护标志位的情况。请注意,在 PTE 中是看不到运行权限的。这就是为什么经典的 x86 页面上允许代码在栈上被执行的原因,这样会很容易导致挖掘出栈缓冲溢出漏洞(可能会通过使用 [return-to-libc][21] 和其它技术来找出非可执行栈)。由于 PTE 缺少禁止运行标志位说明了一个更广泛的事实:在 VMA 中的权限标志位有可能或可能不完全转换为硬件保护。内核只能做它能做到的,但是,最终的架构限制了它能做的事情。 -虚拟内存不能保存任何东西,它只是简单地  _映射_  一个程序的地址空间到底层的物理内存上。物理内存被当作一个被称为物理地址空间的巨大块来被处理器访问。虽然内存的操作[涉及到某些][22] 总线,我们在这里先忽略它,并假设物理地址范围从 0 到可用的最大值按字节递增。物理地址空间被内核进一步分解为页面帧。处理器并不会关心帧的具体情况,这一点对内核也是至关重要的,因为,页面帧是物理内存管理的最小单元。Linux 和 Windows 在 32 位模式下都使用 4KB 大小的页面帧;下图是一个有 2 GB 内存的机器的例子: +虚拟内存不保存任何东西,它只是简单地  _映射_  一个程序的地址空间到底层的物理内存上。物理内存被当作一个称之为**物理地址空间**的巨大块而由处理器访问。虽然内存的操作[涉及到某些][22]总线,我们在这里先忽略它,并假设物理地址范围从 0 到可用的最大值按字节递增。物理地址空间被内核进一步分解为**页面帧**。处理器并不会关心帧的具体情况,这一点对内核也是至关重要的,因为,**页面帧是物理内存管理的最小单元**。Linux 和 Windows 在 32 位模式下都使用 4KB 大小的页面帧;下图是一个有 2 GB 内存的机器的例子: ![Physical Address Space](http://static.duartes.org/img/blogPosts/physicalAddressSpace.png) -在 Linux 上每个页面帧是被一个 [描述符][23] 和 [几个标志][24] 来跟踪的。通过这些描述符和标志,实现了对机器上整个物理内存的跟踪;每个页面帧的具体状态是公开的。物理内存是通过使用 [Buddy 内存分配][25] (译者注:一种内存分配算法)技术来管理的,因此,如果可以通过 Buddy 系统分配内存,那么一个页面帧是未分配的(free)。一个被分配的页面帧可以是匿名的、持有程序数据的、或者它可能处于页面缓存中、持有数据保存在一个文件或者块设备中。还有其它的异形页面帧,但是这些异形页面帧现在已经不怎么使用了。Windows 有一个类似的页面帧号(Page Frame Number (PFN))数据库去跟踪物理内存。 +在 Linux 上每个页面帧是被一个 [描述符][23] 和 [几个标志][24] 来跟踪的。通过这些描述符和标志,实现了对机器上整个物理内存的跟踪;每个页面帧的具体状态是公开的。物理内存是通过使用 [Buddy 内存分配][25] (LCTT 译注:一种内存分配算法)技术来管理的,因此,如果一个页面帧可以通过 Buddy 系统分配,那么它是**未分配的**(free)。一个被分配的页面帧可以是**匿名的**、持有程序数据的、或者它可能处于页面缓存中、持有数据保存在一个文件或者块设备中。还有其它的异形页面帧,但是这些异形页面帧现在已经不怎么使用了。Windows 有一个类似的页面帧号(Page Frame Number (PFN))数据库去跟踪物理内存。 -我们把虚拟内存区域(VMA)、页面表条目(PTE)、以及页面帧放在一起来理解它们是如何工作的。下面是一个用户堆的示例: +我们把虚拟内存区域(VMA)、页面表条目(PTE),以及页面帧放在一起来理解它们是如何工作的。下面是一个用户堆的示例: ![Physical Address Space](http://static.duartes.org/img/blogPosts/heapMapped.png) -蓝色的矩形框表示在 VMA 范围内的页面,而箭头表示页面表条目映射页面到页面帧。一些缺少箭头的虚拟页面,表示它们对应的 PTEs 的当前标志位被清除(置为 0)。这可能是因为这个页面从来没有被使用过,或者是它的内容已经被交换出去了(swapped out)。在这两种情况下,即便这些页面在 VMA 中,访问它们也将导致产生一个页面故障。对于这种 VMA 和页面表的不一致的情况,看上去似乎很奇怪,但是这种情况却经常发生。 +蓝色的矩形框表示在 VMA 范围内的页面,而箭头表示页面表条目映射页面到页面帧。一些缺少箭头的虚拟页面,表示它们对应的 PTE 的当前标志位被清除(置为 0)。这可能是因为这个页面从来没有被使用过,或者是它的内容已经被交换出去了。在这两种情况下,即便这些页面在 VMA 中,访问它们也将导致产生一个页面故障。对于这种 VMA 和页面表的不一致的情况,看上去似乎很奇怪,但是这种情况却经常发生。 -一个 VMA 像一个在你的程序和内核之间的合约。你请求它做一些事情(分配内存、文件映射、等等),内核会回应“收到”,然后去创建或者更新相应的 VMA。 但是,它 _并不立刻_ 去“兑现”对你的承诺,而是它会等待到发生一个页面故障时才去 _真正_ 做这个工作。内核是个“懒惰的家伙”、“不诚实的人渣”;这就是虚拟内存的基本原理。它适用于大多数的、一些类似的和意外的情况,但是,它是规则是,VMAs 记录 _约定的_ 内容,而 PTEs 才反映这个“懒惰的内核”  _真正做了什么_。通过这两种数据结构共同来管理程序的内存;它们共同来完成解决页面故障、释放内存、从内存中交换出数据、等等。下图是内存分配的一个简单案例: +一个 VMA 像一个在你的程序和内核之间的合约。你请求它做一些事情(分配内存、文件映射、等等),内核会回应“收到”,然后去创建或者更新相应的 VMA。 但是,它 _并不立刻_ 去“兑现”对你的承诺,而是它会等待到发生一个页面故障时才去 _真正_ 做这个工作。内核是个“懒惰的家伙”、“不诚实的人渣”;这就是虚拟内存的基本原理。它适用于大多数的情况,有一些类似情况和有一些意外的情况,但是,它是规则是,VMA 记录 _约定的_ 内容,而 PTE 才反映这个“懒惰的内核”  _真正做了什么_。通过这两种数据结构共同来管理程序的内存;它们共同来完成解决页面故障、释放内存、从内存中交换出数据、等等。下图是内存分配的一个简单案例: ![Example of demand paging and memory allocation](http://static.duartes.org/img/blogPosts/heapAllocation.png) -当程序通过 [brk()][26] 系统调用来请求一些内存时,内核只是简单地 [更新][27] 堆的 VMA 并给程序回复“已搞定”。而在这个时候并没有真正地分配页面帧并且新的页面也没有映射到物理内存上。一旦程序尝试去访问这个页面时,将发生页面故障,然后处理器调用 [do_page_fault()][28]。这个函数将使用 [find_vma()][30] 去  [搜索][29] 发生页面故障的 VMA。如果找到了,然后在 VMA 上进行权限检查以防范恶意访问(读取或者写入)。如果没有合适的 VMA,也没有尝试访问的内存的“合约”,将会给进程返回段故障。 +当程序通过 [brk()][26] 系统调用来请求一些内存时,内核只是简单地 [更新][27] 堆的 VMA 并给程序回复“已搞定”。而在这个时候并没有真正地分配页面帧,并且新的页面也没有映射到物理内存上。一旦程序尝试去访问这个页面时,处理器将发生页面故障,然后调用 [do_page_fault()][28]。这个函数将使用 [find_vma()][30] 去  [搜索][29] 发生页面故障的 VMA。如果找到了,然后在 VMA 上进行权限检查以防范恶意访问(读取或者写入)。如果没有合适的 VMA,也没有所尝试访问的内存的“合约”,将会给进程返回段故障。 -当找到了一个合适的 VMA,内核必须通过查找 PTE 的内容和 VMA 的类型去处理故障。在我们的案例中,PTE 显示这个页面是 [不存在的][33]。事实上,我们的 PTE 是全部空白的(全部都是 0),在 Linux 中这表示虚拟内存还没有被映射。由于这是匿名 VMA,我们有一个完全的 RAM 事务,它必须被 [do_anonymous_page()][34] 来处理,它分配页面帧,并且用一个 PTE 去映射故障虚拟页面到一个新分配的帧。 +当[找到][31]了一个合适的 VMA,内核必须通过查找 PTE 的内容和 VMA 的类型去[处理][32]故障。在我们的案例中,PTE 显示这个页面是 [不存在的][33]。事实上,我们的 PTE 是全部空白的(全部都是 0),在 Linux 中这表示虚拟内存还没有被映射。由于这是匿名 VMA,我们有一个完全的 RAM 事务,它必须被 [do_anonymous_page()][34] 来处理,它分配页面帧,并且用一个 PTE 去映射故障虚拟页面到一个新分配的帧。 有时候,事情可能会有所不同。例如,对于被交换出内存的页面的 PTE,在当前(Present)标志位上是 0,但它并不是空白的。而是在交换位置仍有页面内容,它必须从磁盘上读取并且通过 [do_swap_page()][35] 来加载到一个被称为 [major fault][36] 的页面帧上。 @@ -60,12 +59,12 @@ via: http://duartes.org/gustavo/blog/post/how-the-kernel-manages-your-memory/ 作者:[Gustavo Duarte][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:http://duartes.org/gustavo/blog/about/ -[1]:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory +[1]:https://linux.cn/article-9255-1.html [2]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/sched.h#L1075 [3]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/sched.h#L1129 [4]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L173 From 9de120e63e03bfa371651741d8aafb5f3481e68e Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 28 Feb 2018 00:26:04 +0800 Subject: [PATCH 030/101] PUB:20090203 How the Kernel Manages Your Memory.md @qhwdw --- .../20090203 How the Kernel Manages Your Memory.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20090203 How the Kernel Manages Your Memory.md (100%) diff --git a/translated/tech/20090203 How the Kernel Manages Your Memory.md b/published/20090203 How the Kernel Manages Your Memory.md similarity index 100% rename from translated/tech/20090203 How the Kernel Manages Your Memory.md rename to published/20090203 How the Kernel Manages Your Memory.md From 950b546a8cfc5af23c3d85a5cb0d316df51139d1 Mon Sep 17 00:00:00 2001 From: geekpi Date: Wed, 28 Feb 2018 08:47:35 +0800 Subject: [PATCH 031/101] translated --- ...tware for Partition Imaging and Cloning.md | 99 ------------------- ...tware for Partition Imaging and Cloning.md | 97 ++++++++++++++++++ 2 files changed, 97 insertions(+), 99 deletions(-) delete mode 100644 sources/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md create mode 100644 translated/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md diff --git a/sources/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md b/sources/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md deleted file mode 100644 index 592bce9548..0000000000 --- a/sources/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md +++ /dev/null @@ -1,99 +0,0 @@ -translating---geekpi - -Partclone – A Versatile Free Software for Partition Imaging and Cloning -====== - -![](https://www.fossmint.com/wp-content/uploads/2018/01/Partclone-Backup-Tool-For-Linux.png) - -**[Partclone][1]** is a free and open-source tool for creating and cloning partition images brought to you by the developers of **Clonezilla**. In fact, **Partclone** is one of the tools that **Clonezilla** is based on. - -It provides users with the tools required to backup and restores used partition blocks along with high compatibility with several file systems thanks to its ability to use existing libraries like **e2fslibs** to read and write partitions e.g. **ext2**. - -Its best stronghold is the variety of formats it supports including ext2, ext3, ext4, hfs+, reiserfs, reiser4, btrfs, vmfs3, vmfs5, xfs, jfs, ufs, ntfs, fat(12/16/32), exfat, f2fs, and nilfs. - -It also has a plethora of available programs including **partclone.ext2** (ext3 & ext4), partclone.ntfs, partclone.exfat, partclone.hfsp, and partclone.vmfs (v3 and v5), among others. - -### Features in Partclone - - * **Freeware:** **Partclone** is free for everyone to download and use. - * **Open Source:** **Partclone** is released under the GNU GPL license and is open to contribution on [GitHub][2]. - * **Cross-Platform** : Available on Linux, Windows, MAC, ESX file system backup/restore, and FreeBSD. - * An online [Documentation page][3] from where you can view help docs and track its GitHub issues. - * An online [user manual][4] for beginners and pros alike. - * Rescue support. - * Clone partitions to image files. - * Restore image files to partitions. - * Duplicate partitions quickly. - * Support for raw clone. - * Displays transfer rate and elapsed time. - * Supports piping. - * Support for crc32. - * Supports vmfs for ESX vmware server and ufs for FreeBSD file system. - - - -There are a lot more features bundled in **Partclone** and you can see the rest of them [here][5]. - -[__Download Partclone for Linux][6] - -### How to Install and Use Partclone - -To install Partclone on Linux. -``` -$ sudo apt install partclone [On Debian/Ubuntu] -$ sudo yum install partclone [On CentOS/RHEL/Fedora] - -``` - -Clone partition to image. -``` -# partclone.ext4 -d -c -s /dev/sda1 -o sda1.img - -``` - -Restore image to partition. -``` -# partclone.ext4 -d -r -s sda1.img -o /dev/sda1 - -``` - -Partition to partition clone. -``` -# partclone.ext4 -d -b -s /dev/sda1 -o /dev/sdb1 - -``` - -Display image information. -``` -# partclone.info -s sda1.img - -``` - -Check image. -``` -# partclone.chkimg -s sda1.img - -``` - -Are you a **Partclone** user? I wrote on [**Deepin Clone**][7] just recently and apparently, there are certain tasks Partclone is better at handling. What has been your experience with other backup and restore utility tools? - -Do share your thoughts and suggestions with us in the comments section below. - --------------------------------------------------------------------------------- - -via: https://www.fossmint.com/partclone-linux-backup-clone-tool/ - -作者:[Martins D. Okoi;View All Posts;Peter Beck;Martins Divine Okoi][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: -[1]:https://partclone.org/ -[2]:https://github.com/Thomas-Tsai/partclone -[3]:https://partclone.org/help/ -[4]:https://partclone.org/usage/ -[5]:https://partclone.org/features/ -[6]:https://partclone.org/download/ -[7]:https://www.fossmint.com/deepin-clone-system-backup-restore-for-deepin-users/ diff --git a/translated/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md b/translated/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md new file mode 100644 index 0000000000..3df91e5d87 --- /dev/null +++ b/translated/tech/20180116 A Versatile Free Software for Partition Imaging and Cloning.md @@ -0,0 +1,97 @@ +Partclone - 多功能的分区和克隆免费软件 +====== + +![](https://www.fossmint.com/wp-content/uploads/2018/01/Partclone-Backup-Tool-For-Linux.png) + +**[Partclone][1]** 是由 **Clonezilla** 开发者开发的免费开源的用于创建和克隆分区镜像的软件。实际上,**Partclone** 是基于 **Clonezilla** 的工具之一。 + +它为用户提供了备份与恢复占用的分区块工具,并与多个文件系统的高度兼容,这要归功于它能够使用像 **e2fslibs** 这样的现有库来读取和写入分区,例如 **ext2**。 + +它最大的优点是支持各种格式,包括 ext2、ext3、ext4、hfs +、reiserfs、reiser4、btrfs、vmfs3、vmfs5、xfs、jfs、ufs、ntfs、fat(12/16/32)、exfat、f2fs 和 nilfs。 + +它还有许多的程序,包括 **partclone.ext2**ext3&ext4)、partclone.ntfs、partclone.exfat、partclone.hfsp 和 partclone.vmfs(v3和v5) 等等。 + +### Partclone中的功能 + + * **免费软件:** **Partclone**免费供所有人下载和使用。 +  * **开源:** **Partclone**是在 GNU GPL 许可下发布的,并在 [GitHub][2] 上公开。 +  * **跨平台**:适用于 Linux、Windows、MAC、ESX 文件系统备份/恢复和 FreeBSD。 +  * 一个在线的[文档页面][3],你可以从中查看帮助文档并跟踪其 GitHub 问题。 +  * 为初学者和专业人士提供的在线[用户手册][4]。 +  * 支持救援。 +  * 克隆分区成镜像文件。 +  * 将镜像文件恢复到分区。 +  * 快速复制分区。 +  * 支持 raw 克隆。 +  * 显示传输速率和持续时间。 +  * 支持管道。 +  * 支持 crc32。 +  * 支持 ESX vmware server 的 vmfs 和 FreeBSD 的文件系统 ufs。 + + + +**Partclone** 中还捆绑了更多功能,你可以在[这里][5]查看其余的功能。 + +[下载 Linux 中的 Partclone][6] + +### 如何安装和使用 Partclone + +在 Linux 上安装 Partclone。 +``` +$ sudo apt install partclone [On Debian/Ubuntu] +$ sudo yum install partclone [On CentOS/RHEL/Fedora] + +``` + +克隆分区为镜像。 +``` +# partclone.ext4 -d -c -s /dev/sda1 -o sda1.img + +``` + +将镜像恢复到分区。 +``` +# partclone.ext4 -d -r -s sda1.img -o /dev/sda1 + +``` + +分区到分区克隆。 +``` +# partclone.ext4 -d -b -s /dev/sda1 -o /dev/sdb1 + +``` + +显示镜像信息。 +``` +# partclone.info -s sda1.img + +``` + +检查镜像。 +``` +# partclone.chkimg -s sda1.img + +``` + +你是 **Partclone** 的用户吗?我最近在 [**Deepin Clone**][7] 上写了一篇文章,显然,Partclone 有擅长处理的任务。你使用其他备份和恢复工具的经验是什么? + +请在下面的评论区与我们分享你的想法和建议。 + +-------------------------------------------------------------------------------- + +via: https://www.fossmint.com/partclone-linux-backup-clone-tool/ + +作者:[Martins D. Okoi;View All Posts;Peter Beck;Martins Divine Okoi][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: +[1]:https://partclone.org/ +[2]:https://github.com/Thomas-Tsai/partclone +[3]:https://partclone.org/help/ +[4]:https://partclone.org/usage/ +[5]:https://partclone.org/features/ +[6]:https://partclone.org/download/ +[7]:https://www.fossmint.com/deepin-clone-system-backup-restore-for-deepin-users/ From 5bf5c79616d918a2acfac595e1fc31869402a478 Mon Sep 17 00:00:00 2001 From: geekpi Date: Wed, 28 Feb 2018 08:52:02 +0800 Subject: [PATCH 032/101] translating --- .../20171116 Record and Share Terminal Session with Showterm.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20171116 Record and Share Terminal Session with Showterm.md b/sources/tech/20171116 Record and Share Terminal Session with Showterm.md index ff86cf743d..8d3ce451b5 100644 --- a/sources/tech/20171116 Record and Share Terminal Session with Showterm.md +++ b/sources/tech/20171116 Record and Share Terminal Session with Showterm.md @@ -1,3 +1,5 @@ +translating---geekpi + Record and Share Terminal Session with Showterm ====== From 93c5e60176661119df2bc6f611d7c815bd9e1037 Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Wed, 28 Feb 2018 10:34:03 +0800 Subject: [PATCH 033/101] translating by heart4lor --- .../tech/20180217 The List Of Useful Bash Keyboard Shortcuts.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180217 The List Of Useful Bash Keyboard Shortcuts.md b/sources/tech/20180217 The List Of Useful Bash Keyboard Shortcuts.md index beba179fee..be44c1b034 100644 --- a/sources/tech/20180217 The List Of Useful Bash Keyboard Shortcuts.md +++ b/sources/tech/20180217 The List Of Useful Bash Keyboard Shortcuts.md @@ -1,5 +1,7 @@ The List Of Useful Bash Keyboard Shortcuts ====== +translating by heart4lor + ![](https://www.ostechnix.com/wp-content/uploads/2018/02/Bash-720x340.jpg) Nowadays, I spend more time in Terminal, trying to accomplish more in CLI than GUI. I learned many BASH tricks over time. And, here is the list of useful of BASH shortcuts that every Linux users should know to get things done faster in their BASH shell. I won’t claim that this list is a complete list of BASH shortcuts, but just enough to move around your BASH shell faster than before. Learning how to navigate faster in BASH Shell not only saves some time, but also makes you proud of yourself for learning something worth. Well, let’s get started. From a08fd950e97ee9db2805c222ac9a344a6ea85cbc Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 28 Feb 2018 12:52:49 +0800 Subject: [PATCH 034/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Protecting=20Code?= =?UTF-8?q?=20Integrity=20with=20PGP=20=E2=80=94=20Part=201:=20Basic=20Con?= =?UTF-8?q?cepts=20and=20Tools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... PGP - Part 1- Basic Concepts and Tools.md | 268 ++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md diff --git a/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md b/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md new file mode 100644 index 0000000000..19581aaabb --- /dev/null +++ b/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md @@ -0,0 +1,268 @@ +Protecting Code Integrity with PGP — Part 1: Basic Concepts and Tools +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/pgp-security.jpg?itok=lulwyzYc) + +In this article series, we take an in-depth look at using PGP to ensure the integrity of software. These articles will provide practical guidelines aimed at developers working on free software projects and will cover the following topics: + + 1. PGP basics and best practices + + 2. How to use PGP with Git + + 3. How to protect your developer accounts + + + + +We use the term "Free" as in "Freedom," but the guidelines set out in this series can also be used for any other kind of software that relies on contributions from a distributed team of developers. If you write code that goes into public source repositories, you can benefit from getting acquainted with and following this guide. + +### Structure + +Each section is split into two areas: + + * The checklist that can be adapted to your project's needs + + * Free-form list of considerations that explain what dictated these decisions, together with configuration instructions + + + + +#### Checklist priority levels + +The items in each checklist include the priority level, which we hope will help guide your decision: + + * (ESSENTIAL) items should definitely be high on the consideration list. If not implemented, they will introduce high risks to the code that gets committed to the open-source project. + + * (NICE) to have items will improve the overall security, but will affect how you interact with your work environment, and probably require learning new habits or unlearning old ones. + + + + +Remember, these are only guidelines. If you feel these priority levels do not reflect your project's commitment to security, you should adjust them as you see fit. + +## Basic PGP concepts and tools + +### Checklist + + 1. Understand the role of PGP in Free Software Development (ESSENTIAL) + + 2. Understand the basics of Public Key Cryptography (ESSENTIAL) + + 3. Understand PGP Encryption vs. Signatures (ESSENTIAL) + + 4. Understand PGP key identities (ESSENTIAL) + + 5. Understand PGP key validity (ESSENTIAL) + + 6. Install GnuPG utilities (version 2.x) (ESSENTIAL) + + + + +### Considerations + +The Free Software community has long relied on PGP for assuring the authenticity and integrity of software products it produced. You may not be aware of it, but whether you are a Linux, Mac or Windows user, you have previously relied on PGP to ensure the integrity of your computing environment: + + * Linux distributions rely on PGP to ensure that binary or source packages have not been altered between when they have been produced and when they are installed by the end-user. + + * Free Software projects usually provide detached PGP signatures to accompany released software archives, so that downstream projects can verify the integrity of downloaded releases before integrating them into their own distributed downloads. + + * Free Software projects routinely rely on PGP signatures within the code itself in order to track provenance and verify integrity of code committed by project developers. + + + + +This is very similar to developer certificates/code signing mechanisms used by programmers working on proprietary platforms. In fact, the core concepts behind these two technologies are very much the same -- they differ mostly in the technical aspects of the implementation and the way they delegate trust. PGP does not rely on centralized Certification Authorities, but instead lets each user assign their own trust to each certificate. + +Our goal is to get your project on board using PGP for code provenance and integrity tracking, following best practices and observing basic security precautions. + +### Extremely Basic Overview of PGP operations + +You do not need to know the exact details of how PGP works -- understanding the core concepts is enough to be able to use it successfully for our purposes. PGP relies on Public Key Cryptography to convert plain text into encrypted text. This process requires two distinct keys: + + * A public key that is known to everyone + + * A private key that is only known to the owner + + + + +#### Encryption + +For encryption, PGP uses the public key of the owner to create a message that is only decryptable using the owner's private key: + + 1. The sender generates a random encryption key ("session key") + + 2. The sender encrypts the contents using that session key (using a symmetric cipher) + + 3. The sender encrypts the session key using the recipient's public PGP key + + 4. The sender sends both the encrypted contents and the encrypted session key to the recipient + + + + +To decrypt: + + 1. The recipient decrypts the session key using their private PGP key + + 2. The recipient uses the session key to decrypt the contents of the message + + + + +#### Signatures + +For creating signatures, the private/public PGP keys are used the opposite way: + + 1. The signer generates the checksum hash of the contents + + 2. The signer uses their own private PGP key to encrypt that checksum + + 3. The signer provides the encrypted checksum alongside the contents + + + + +To verify the signature: + + 1. The verifier generates their own checksum hash of the contents + + 2. The verifier uses the signer's public PGP key to decrypt the provided checksum + + 3. If the checksums match, the integrity of the contents is verified + + + + +#### Combined usage + +Frequently, encrypted messages are also signed with the sender's own PGP key. This should be the default whenever using encrypted messaging, as encryption without authentication is not very meaningful (unless you are a whistleblower or a secret agent and need plausible deniability). + +### Understanding Key Identities + +Each PGP key must have one or multiple Identities associated with it. Usually, an "Identity" is the person's full name and email address in the following format: +``` +Alice Engineer + +``` + +Sometimes it will also contain a comment in brackets, to tell the end-user more about that particular key: +``` +Bob Designer (obsolete 1024-bit key) + +``` + +Since people can be associated with multiple professional and personal entities, they can have multiple identities on the same key: +``` +Alice Engineer +Alice Engineer +Alice Engineer + +``` + +When multiple identities are used, one of them would be marked as the "primary identity" to make searching easier. + +### Understanding Key Validity + +To be able to use someone else's public key for encryption or verification, you need to be sure that it actually belongs to the right person (Alice) and not to an impostor (Eve). In PGP, this certainty is called "key validity:" + + * Validity: full -- means we are pretty sure this key belongs to Alice + + * Validity: marginal -- means we are somewhat sure this key belongs to Alice + + * Validity: unknown -- means there is no assurance at all that this key belongs to Alice + + + + +#### Web of Trust (WOT) vs. Trust on First Use (TOFU) + +PGP incorporates a trust delegation mechanism known as the "Web of Trust." At its core, this is an attempt to replace the need for centralized Certification Authorities of the HTTPS/TLS world. Instead of various software makers dictating who should be your trusted certifying entity, PGP leaves this responsibility to each user. + +Unfortunately, very few people understand how the Web of Trust works, and even fewer bother to keep it going. It remains an important aspect of the OpenPGP specification, but recent versions of GnuPG (2.2 and above) have implemented an alternative mechanism called "Trust on First Use" (TOFU). + +You can think of TOFU as "the SSH-like approach to trust." With SSH, the first time you connect to a remote system, its key fingerprint is recorded and remembered. If the key changes in the future, the SSH client will alert you and refuse to connect, forcing you to make a decision on whether you choose to trust the changed key or not. + +Similarly, the first time you import someone's PGP key, it is assumed to be trusted. If at any point in the future GnuPG comes across another key with the same identity, both the previously imported key and the new key will be marked as invalid and you will need to manually figure out which one to keep. + +In this guide, we will be using the TOFU trust model. + +### Installing OpenPGP software + +First, it is important to understand the distinction between PGP, OpenPGP, GnuPG and gpg: + + * PGP ("Pretty Good Privacy") is the name of the original commercial software + + * OpenPGP is the IETF standard compatible with the original PGP tool + + * GnuPG ("Gnu Privacy Guard") is free software that implements the OpenPGP standard + + * The command-line tool for GnuPG is called "gpg" + + + + +Today, the term "PGP" is almost universally used to mean "the OpenPGP standard," not the original commercial software, and therefore "PGP" and "OpenPGP" are interchangeable. The terms "GnuPG" and "gpg" should only be used when referring to the tools, not to the output they produce or OpenPGP features they implement. For example: + + * PGP (not GnuPG or GPG) key + + * PGP (not GnuPG or GPG) signature + + * PGP (not GnuPG or GPG) keyserver + + + + +Understanding this should protect you from an inevitable pedantic "actually" from other PGP users you come across. + +#### Installing GnuPG + +If you are using Linux, you should already have GnuPG installed. On a Mac, you should install [GPG-Suite][1] or you can use brew install gnupg2. On a Windows PC, you should install [GPG4Win][2], and you will probably need to adjust some of the commands in the guide to work for you, unless you have a unix-like environment set up. For all other platforms, you'll need to do your own research to find the correct places to download and install GnuPG. + +#### GnuPG 1 vs. 2 + +Both GnuPG v.1 and GnuPG v.2 implement the same standard, but they provide incompatible libraries and command-line tools, so many distributions ship both the legacy version 1 and the latest version 2. You need to make sure you are always using GnuPG v.2. + +First, run: +``` +$ gpg --version | head -n1 + +``` + +If you see gpg (GnuPG) 1.4.x, then you are using GnuPG v.1. Try the gpg2 command: +``` +$ gpg2 --version | head -n1 + +``` + +If you see gpg (GnuPG) 2.x.x, then you are good to go. This guide will assume you have the version 2.2 of GnuPG (or later). If you are using version 2.0 of GnuPG, some of the commands in this guide will not work, and you should consider installing the latest 2.2 version of GnuPG. + +#### Making sure you always use GnuPG v.2 + +If you have both gpg and gpg2 commands, you should make sure you are always using GnuPG v2, not the legacy version. You can make sure of this by setting the alias: +``` +$ alias gpg=gpg2 + +``` + +You can put that in your .bashrc to make sure it's always loaded whenever you use the gpg commands. + +In part 2 of this series, we will explain the basic steps for generating and protecting your master PGP key. + +Learn more about Linux through the free ["Introduction to Linux" ][3]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools + +作者:[Konstantin Ryabitsev][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/mricon +[1]:https://gpgtools.org/ +[2]:https://www.gpg4win.org/ +[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From 4393415fee9fdea12fdce92829092cb4f8a6ae34 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 28 Feb 2018 12:55:29 +0800 Subject: [PATCH 035/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Protecting=20Code?= =?UTF-8?q?=20Integrity=20with=20PGP=20=E2=80=94=20Part=202:=20Generating?= =?UTF-8?q?=20Your=20Master=20Key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...GP - Part 2- Generating Your Master Key.md | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md diff --git a/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md b/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md new file mode 100644 index 0000000000..282e35b60e --- /dev/null +++ b/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md @@ -0,0 +1,176 @@ +Protecting Code Integrity with PGP — Part 2: Generating Your Master Key +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/binary-1538717_1920.png?itok=kv_sxSnf) + +In this article series, we're taking an in-depth look at using PGP and provide practical guidelines for developers working on free software projects. In the previous article, we provided an introduction to [basic tools and concepts][1]. In this installment, we show how to generate and protect your master PGP key. + +### Checklist + + 1. Generate a 4096-bit RSA master key (ESSENTIAL) + + 2. Back up the master key using paperkey (ESSENTIAL) + + 3. Add all relevant identities (ESSENTIAL) + + + + +### Considerations + +#### Understanding the "Master" (Certify) key + +In this and next section we'll talk about the "master key" and "subkeys." It is important to understand the following: + + 1. There are no technical differences between the "master key" and "subkeys." + + 2. At creation time, we assign functional limitations to each key by giving it specific capabilities. + + 3. A PGP key can have four capabilities. + + * [S] key can be used for signing + + * [E] key can be used for encryption + + * [A] key can be used for authentication + + * [C] key can be used for certifying other keys + + 4. A single key may have multiple capabilities. + + + + +The key carrying the [C] (certify) capability is considered the "master" key because it is the only key that can be used to indicate relationship with other keys. Only the [C] key can be used to: + + * Add or revoke other keys (subkeys) with S/E/A capabilities + + * Add, change or revoke identities (uids) associated with the key + + * Add or change the expiration date on itself or any subkey + + * Sign other people's keys for the web of trust purposes + + + + +In the Free Software world, the [C] key is your digital identity. Once you create that key, you should take extra care to protect it and prevent it from falling into malicious hands. + +#### Before you create the master key + +Before you create your master key you need to pick your primary identity and your master passphrase. + +##### Primary identity + +Identities are strings using the same format as the "From" field in emails: +``` +Alice Engineer + +``` + +You can create new identities, revoke old ones, and change which identity is your "primary" one at any time. Since the primary identity is shown in all GnuPG operations, you should pick a name and address that are both professional and the most likely ones to be used for PGP-protected communication, such as your work address or the address you use for signing off on project commits. + +##### Passphrase + +The passphrase is used exclusively for encrypting the private key with a symmetric algorithm while it is stored on disk. If the contents of your .gnupg directory ever get leaked, a good passphrase is the last line of defense between the thief and them being able to impersonate you online, which is why it is important to set up a good passphrase. + +A good guideline for a strong passphrase is 3-4 words from a rich or mixed dictionary that are not quotes from popular sources (songs, books, slogans). You'll be using this passphrase fairly frequently, so it should be both easy to type and easy to remember. + +##### Algorithm and key strength + +Even though GnuPG has had support for Elliptic Curve crypto for a while now, we'll be sticking to RSA keys, at least for a little while longer. While it is possible to start using ED25519 keys right now, it is likely that you will come across tools and hardware devices that will not be able to handle them correctly. + +You may also wonder why the master key is 4096-bit, if later in the guide we state that 2048-bit keys should be good enough for the lifetime of RSA public key cryptography. The reasons are mostly social and not technical: master keys happen to be the most visible ones on the keychain, and some of the developers you interact with will inevitably judge you negatively if your master key has fewer bits than theirs. + +#### Generate the master key + +To generate your new master key, issue the following command, putting in the right values instead of "Alice Engineer:" +``` +$ gpg --quick-generate-key 'Alice Engineer ' rsa4096 cert + +``` + +A dialog will pop up asking to enter the passphrase. Then, you may need to move your mouse around or type on some keys to generate enough entropy until the command completes. + +Review the output of the command, it will be something like this: +``` +pub rsa4096 2017-12-06 [C] [expires: 2019-12-06] + 111122223333444455556666AAAABBBBCCCCDDDD +uid Alice Engineer + +``` + +Note the long string on the second line -- that is the full fingerprint of your newly generated key. Key IDs can be represented in three different forms: + + * Fingerprint, a full 40-character key identifier + + * Long, last 16-characters of the fingerprint (AAAABBBBCCCCDDDD) + + * Short, last 8 characters of the fingerprint (CCCCDDDD) + + + + +You should avoid using 8-character "short key IDs" as they are not sufficiently unique. + +At this point, I suggest you open a text editor, copy the fingerprint of your new key and paste it there. You'll need to use it for the next few steps, so having it close by will be handy. + +#### Back up your master key + +For disaster recovery purposes -- and especially if you intend to use the Web of Trust and collect key signatures from other project developers -- you should create a hardcopy backup of your private key. This is supposed to be the "last resort" measure in case all other backup mechanisms have failed. + +The best way to create a printable hardcopy of your private key is using the paperkey software written for this very purpose. Paperkey is available on all Linux distros, as well as installable via brew install paperkey on Macs. + +Run the following command, replacing [fpr] with the full fingerprint of your key: +``` +$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt + +``` + +The output will be in a format that is easy to OCR or input by hand, should you ever need to recover it. Print out that file, then take a pen and write the key passphrase on the margin of the paper. This is a required step because the key printout is still encrypted with the passphrase, and if you ever change the passphrase on your key, you will not remember what it used to be when you had first created it -- guaranteed. + +Put the resulting printout and the hand-written passphrase into an envelope and store in a secure and well-protected place, preferably away from your home, such as your bank vault. + +**Note on printers:** Long gone are days when printers were dumb devices connected to your computer's parallel port. These days they have full operating systems, hard drives, and cloud integration. Since the key content we send to the printer will be encrypted with the passphrase, this is a fairly safe operation, but use your best paranoid judgement. + +#### Add relevant identities + +If you have multiple relevant email addresses (personal, work, open-source project, etc), you should add them to your master key. You don't need to do this for any addresses that you don't expect to use with PGP (e.g., probably not your school alumni address). + +The command is (put the full key fingerprint instead of [fpr]): +``` +$ gpg --quick-add-uid [fpr] 'Alice Engineer ' + +``` + +You can review the UIDs you've already added using: +``` +$ gpg --list-key [fpr] | grep ^uid + +``` + +##### Pick the primary UID + +GnuPG will make the latest UID you add as your primary UID, so if that is different from what you want, you should fix it back: +``` +$ gpg --quick-set-primary-uid [fpr] 'Alice Engineer ' + +``` + +Next time, we'll look at generating PGP subkeys, which are the keys you'll actually be using for day-to-day work. + +Learn more about Linux through the free ["Introduction to Linux" ][2]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/PGP/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key + +作者:[KONSTANTIN RYABITSEV][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/mricon +[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools +[2]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From 627cea351f30fee6a43605bbbe49ee12c6f1ad11 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Wed, 28 Feb 2018 14:39:36 +0800 Subject: [PATCH 036/101] Translated by qhwdw --- ...214 6 open source home automation tools.md | 119 ------------------ ...214 6 open source home automation tools.md | 113 +++++++++++++++++ 2 files changed, 113 insertions(+), 119 deletions(-) delete mode 100644 sources/tech/20171214 6 open source home automation tools.md create mode 100644 translated/tech/20171214 6 open source home automation tools.md diff --git a/sources/tech/20171214 6 open source home automation tools.md b/sources/tech/20171214 6 open source home automation tools.md deleted file mode 100644 index 07ab7776ac..0000000000 --- a/sources/tech/20171214 6 open source home automation tools.md +++ /dev/null @@ -1,119 +0,0 @@ -Translating by qhwdw -6 open source home automation tools -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520x292_openlightbulbs.png?itok=nrv9hgnH) - -The [Internet of Things][13] isn't just a buzzword, it's a reality that's expanded rapidly since we last published a review article on home automation tools in 2016\. In 2017, [26.5% of U.S. households][14] already had some type of smart home technology in use; within five years that percentage is expected to double. - -With an ever-expanding number of devices available to help you automate, protect, and monitor your home, it has never been easier nor more tempting to try your hand at home automation. Whether you're looking to control your HVAC system remotely, integrate a home theater, protect your home from theft, fire, or other threats, reduce your energy usage, or just control a few lights, there are countless devices available at your disposal. - -But at the same time, many users worry about the security and privacy implications of bringing new devices into their homes—a very real and [serious consideration][15]. They want to control who has access to the vital systems that control their appliances and record every moment of their everyday lives. And understandably so: In an era when even your refrigerator may now be a smart device, don't you want to know if your fridge is phoning home? Wouldn't you want some basic assurance that, even if you give a device permission to communicate externally, it is only accessible to those who are explicitly authorized? - -[Security concerns][16] are among the many reasons why open source will be critical to our future with connected devices. Being able to fully understand the programs that control your home means you can view, and if necessary modify, the source code running on the devices themselves. - -While connected devices often contain proprietary components, a good first step in bringing open source into your home automation system is to ensure that the device that ties your devices together—and presents you with an interface to them (the "hub")—is open source. Fortunately, there are many choices out there, with options to run on everything from your always-on personal computer to a Raspberry Pi. - -Here are just a few of our favorites. - -### Calaos - -[Calaos][17] is designed as a full-stack home automation platform, including a server application, touchscreen interface, web application, native mobile applications for iOS and Android, and a preconfigured Linux operating system to run underneath. The Calaos project emerged from a French company, so its support forums are primarily in French, although most of the instructional material and documentation have been translated into English. - -Calaos is licensed under version 3 of the [GPL][18] and you can view its source on [GitHub][19]. - -### Domoticz - -[Domoticz][20] is a home automation system with a pretty wide library of supported devices, ranging from weather stations to smoke detectors to remote controls, and a large number of additional third-party [integrations][21] are documented on the project's website. It is designed with an HTML5 frontend, making it accessible from desktop browsers and most modern smartphones, and is lightweight, running on many low-power devices like the Raspberry Pi. - -Domoticz is written primarily in C/C++ under the [GPLv3][22], and its [source code][23] can be browsed on GitHub. - -### Home Assistant - -[Home Assistant][24] is an open source home automation platform designed to be easily deployed on almost any machine that can run Python 3, from a Raspberry Pi to a network-attached storage (NAS) device, and it even ships with a Docker container to make deploying on other systems a breeze. It integrates with a large number of open source as well as commercial offerings, allowing you to link, for example, IFTTT, weather information, or your Amazon Echo device, to control hardware from locks to lights. - -Home Assistant is released under an [MIT license][25], and its source can be downloaded from [GitHub][26]. - -### MisterHouse - -[MisterHouse][27] has gained a lot of ground since 2016, when we mentioned it as "another option to consider" on this list. It uses Perl scripts to monitor anything that can be queried by a computer or control anything capable of being remote controlled. It responds to voice commands, time of day, weather, location, and other events to turn on the lights, wake you up, record your favorite TV show, announce phone callers, warn that your front door is open, report how long your son has been online, tell you if your daughter's car is speeding, and much more. It runs on Linux, macOS, and Windows computers and can read/write from a wide variety of devices including security systems, weather stations, caller ID, routers, vehicle location systems, and more - -MisterHouse is licensed under the [GPLv2][28] and you can view its source code on [GitHub][29]. - -### OpenHAB - -[OpenHAB][30] (short for Open Home Automation Bus) is one of the best-known home automation tools among open source enthusiasts, with a large user community and quite a number of supported devices and integrations. Written in Java, openHAB is portable across most major operating systems and even runs nicely on the Raspberry Pi. Supporting hundreds of devices, openHAB is designed to be device-agnostic while making it easier for developers to add their own devices or plugins to the system. OpenHAB also ships iOS and Android apps for device control, as well as design tools so you can create your own UI for your home system. - -You can find openHAB's [source code][31] on GitHub licensed under the [Eclipse Public License][32]. - -### OpenMotics - -[OpenMotics][33] is a home automation system with both hardware and software under open source licenses. It's designed to provide a comprehensive system for controlling devices, rather than stitching together many devices from different providers. Unlike many of the other systems designed primarily for easy retrofitting, OpenMotics focuses on a hardwired solution. For more, see our [full article][34] from OpenMotics backend developer Frederick Ryckbosch. - -The source code for OpenMotics is licensed under the [GPLv2][35] and is available for download on [GitHub][36]. - -These aren't the only options available, of course. Many home automation enthusiasts go with a different solution, or even decide to roll their own. Other users choose to use individual smart home devices without integrating them into a single comprehensive system. - -If the solutions above don't meet your needs, here are some potential alternatives to consider: - -* [EventGhost][1] is an open source ([GPL v2][2]) home theater automation tool that operates only on Microsoft Windows PCs. It allows users to control media PCs and attached hardware by using plugins that trigger macros or by writing custom Python scripts. - -* [ioBroker][3] is a JavaScript-based IoT platform that can control lights, locks, thermostats, media, webcams, and more. It will run on any hardware that runs Node.js, including Windows, Linux, and macOS, and is open sourced under the [MIT license][4]. - -* [Jeedom][5] is a home automation platform comprised of open source software ([GPL v2][6]) to control lights, locks, media, and more. It includes a mobile app (Android and iOS) and operates on Linux PCs; the company also sells hubs that it says provide a ready-to-use solution for setting up home automation. - -* [LinuxMCE][7] bills itself as the "'digital glue' between your media and all of your electrical appliances." It runs on Linux (including Raspberry Pi), is released under the Pluto open source [license][8], and can be used for home security, telecom (VoIP and voice mail), A/V equipment, home automation, and—uniquely—to play video games. - -* [OpenNetHome][9], like the other solutions in this category, is open source software for controlling lights, alarms, appliances, etc. It's based on Java and Apache Maven, operates on Windows, macOS, and Linux—including Raspberry Pi, and is released under [GPLv3][10]. - -* [Smarthomatic][11] is an open source home automation framework that concentrates on hardware devices and software, rather than user interfaces. Licensed under [GPLv3][12], it's used for things such as controlling lights, appliances, and air humidity, measuring ambient temperature, and remembering to water your plants. - -Now it's your turn: Do you already have an open source home automation system in place? Or perhaps you're researching the options to create one. What advice would you have to a newcomer to home automation, and what system or systems would you recommend? - --------------------------------------------------------------------------------- - -via: https://opensource.com/life/17/12/home-automation-tools - -作者:[Jason Baker][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/jason-baker -[1]:http://www.eventghost.net/ -[2]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.html -[3]:http://iobroker.net/ -[4]:https://github.com/ioBroker/ioBroker#license -[5]:https://www.jeedom.com/site/en/index.html -[6]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.html -[7]:http://www.linuxmce.com/ -[8]:http://wiki.linuxmce.org/index.php/License -[9]:http://opennethome.org/ -[10]:https://github.com/NetHome/NetHomeServer/blob/master/LICENSE -[11]:https://www.smarthomatic.org/ -[12]:https://github.com/breaker27/smarthomatic/blob/develop/GPL3.txt -[13]:https://opensource.com/resources/internet-of-things -[14]:https://www.statista.com/outlook/279/109/smart-home/united-states -[15]:http://www.crn.com/slide-shows/internet-of-things/300089496/black-hat-2017-9-iot-security-threats-to-watch.htm -[16]:https://opensource.com/business/15/5/why-open-source-means-stronger-security -[17]:https://calaos.fr/en/ -[18]:https://github.com/calaos/calaos-os/blob/master/LICENSE -[19]:https://github.com/calaos -[20]:https://domoticz.com/ -[21]:https://www.domoticz.com/wiki/Integrations_and_Protocols -[22]:https://github.com/domoticz/domoticz/blob/master/License.txt -[23]:https://github.com/domoticz/domoticz -[24]:https://home-assistant.io/ -[25]:https://github.com/home-assistant/home-assistant/blob/dev/LICENSE.md -[26]:https://github.com/balloob/home-assistant -[27]:http://misterhouse.sourceforge.net/ -[28]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html -[29]:https://github.com/hollie/misterhouse -[30]:http://www.openhab.org/ -[31]:https://github.com/openhab/openhab -[32]:https://github.com/openhab/openhab/blob/master/LICENSE.TXT -[33]:https://www.openmotics.com/ -[34]:https://opensource.com/life/14/12/open-source-home-automation-system-opemmotics -[35]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html -[36]:https://github.com/openmotics diff --git a/translated/tech/20171214 6 open source home automation tools.md b/translated/tech/20171214 6 open source home automation tools.md new file mode 100644 index 0000000000..742ab453fe --- /dev/null +++ b/translated/tech/20171214 6 open source home automation tools.md @@ -0,0 +1,113 @@ +6 个开源的家庭自动化工具 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520x292_openlightbulbs.png?itok=nrv9hgnH) + +[物联网][13] 不仅是一个时髦词,在现实中,自 2016 年我们发布了一篇关于家庭自动化工具的评论文章以来,它也在迅速占领着我们的生活。在 2017,[26.5% 的美国家庭][14] 已经使用了一些智能家居技术;预计五年内,这一数字还将翻倍。 + +使用数量持续增加的各种设备,可以帮助你实现对家庭的自动化管理、安保、和监视,在家庭自动化方面,从来没有像现在这样容易和更加吸引人过。不论你是要远程控制你的 HVAC 系统,集成一个家庭影院,保护你的家免受盗窃、火灾、或是其它威胁,还是节省能源或只是控制几盏灯,现在都有无数的设备可以帮到你。 + +但同时,还有许多用户担心安装在他们家庭中的新设备带来的安全和隐私问题 —— 一个很现实也很 [严肃的问题][15]。他们想要去控制有谁可以接触到这个重要的系统,这个系统管理着他们的应用程序,记录了他们生活中的点点滴滴。这种想法是可以理解的:毕竟在一个连你的冰箱都是智能设备的今天,你不想要一个基本的保证吗?甚至是如果你授权了设备可以与外界通讯,它是否是仅被授权的人能够访问它呢? + +[对安全的担心][16] 是为什么开源对我们将来使用的互联设备至关重要的众多理由之一。由于源代码运行在他们自己的设备上,完全可以去搞明白控制你的家庭的程序,也就是说你可以查看它的代码,如果必要的话甚至可以去修改它。 + +虽然联网设备通常都包含他们专有的组件,但是将开源引入家庭自动化的第一步是确保你的设备和这些设备可以共同工作 —— 它们为你提供一个接口—— 并且是开源的。幸运的是,现在有许多解决方案可供选择,从 PC 到树莓派,你可以在它们上做任何事情。 + +这里有几个我比较喜欢的。 + +### Calaos + +[Calaos][17] 是一个设计为全栈家庭自动化的平台,包含一个服务器应用程序、触摸屏接口、Web 应用程序、支持 iOS 和 Android 的原生移动应用、以及一个运行在底层的预配置好的 Linux 操作系统。Calaos 项目出自一个法国公司,因此它的支持论坛以法语为主,不过大量的介绍资料和文档都已经翻译为英语了。 + +Calaos 使用的是 [GPL][18] v3 的许可证,你可以在 [GitHub][19] 上查看它的源代码。 + +### Domoticz + +[Domoticz][20] 是一个有大量设备库支持的家庭自动化系统,在它的项目网站上有大量的文档,从气象站到远程控制的烟雾探测器,以及大量的第三方 [集成][21] 。它使用一个 HTML5 前端,可以从桌面浏览器或者大多数现代的智能手机上访问它,它是一个轻量级的应用,可以运行在像树莓派这样的低功耗设备上。 + +Domoticz 是用 C++ 写的,使用 [GPLv3][22] 许可证。它的 [源代码][23] 在 GitHub 上。 + +### Home Assistant + +[Home Assistant][24] 是一个开源的家庭自动化平台,它可以轻松部署在任何能运行 Python 3 的机器上,从树莓派到网络附加存储(NAS),甚至可以使用 Docker 容器轻松地部署到其它系统上。它集成了大量的开源的和商业的产品,允许你去连接它们,比如,IFTTT、天气信息、或者你的 Amazon Echo 设备,去控制从锁到灯的各种硬件。 + +Home Assistant 以 [MIT 许可证][25] 发布,它的源代码可以从 [GitHub][26] 上下载。 + +### MisterHouse + +从 2016 年起,[MisterHouse][27] 取得了很多的进展,我们把它作为一个“可以考虑的另外选择”列在这个清单上。它使用 Perl 脚本去监视任何东西,它可以通过一台计算机来查询或者控制任何可以远程控制的东西。它可以响应语音命令,查询当前时间、天气、位置、以及其它事件,比如去打开灯、唤醒你、记下你喜欢的电视节目、通报呼入的来电、开门报警、记录你儿子上了多长时间的网、如果你女儿汽车超速它也可以告诉你等等。它可以运行在 Linux、macOS、以及 Windows 计算机上,它可以读/写很多的设备,包括安全系统、气象站、来电显示、路由器、机动车位置系统等等。 + +MisterHouse 使用 [GPLv2][28] 许可证,你可以在 [GitHub][29] 上查看它的源代码。 + +### OpenHAB + +[OpenHAB][30](开放家庭自动化总线的简称)是在开源爱好者中大家熟知的家庭自动化工具,它拥有大量用户的社区以及支持和集成了大量的设备。它是用 Java 写的,OpenHAB 非常轻便,可以跨大多数主流操作系统使用,它甚至在树莓派上也运行的很好。支持成百上千的设备,OpenHAB 被设计为与设备无关的,这使开发者在系统中添加他们的设备或者插件很容易。OpenHAB 也支持通过 iOS 和 Android 应用来控制设备以及设计工具,因此,你可以为你的家庭系统创建你自己的 UI。 + +你可以在 GitHub 上找到 OpenHAB 的 [源代码][31],它使用 [Eclipse 公共许可证][32]。 + +### OpenMotics + +[OpenMotics][33] 是一个开源的硬件和软件家庭自动化系统。它的设计目标是为控制设备提供一个综合的系统,而不是从不同的供应商处将各种设备拼接在一起。不像其它的系统主要是为了方便的改装而设计的,OpenMotics 专注于硬件解决方案。更多资料请查阅来自 OpenMotics 的后端开发者 Frederick Ryckbosch的 [完整文章][34] 。 + +OpenMotics 使用 [GPLv2][35] 许可证,它的源代码可以从 [GitHub][36] 上下载。 + +当然了,我们的选择不仅有这些。许多家庭自动化爱好者使用不同的解决方案,甚至是它们自己动手做。其它用户选择使用单独的智能家庭设备而无需集成它们到一个单一的综合系统中。 + +如果上面的解决方案并不能满足你的需求,下面还有一些潜在的替代者可以去考虑: + +* [EventGhost][1] 是一个开源的([GPL v2][2])家庭影院自动化工具,它只能运行在 Microsoft Windows PC 上。它允许用户去控制多媒体电脑和连接的硬件,它通过触发宏指令的插件或者定制的 Python 脚本来使用。 +* [ioBroker][3] 是一个基于 JavaScript 的物联网平台,它能够控制灯、锁、空调、多媒体、网络摄像头等等。它可以运行在任何可以运行 Node.js 的硬件上,包括 Windows、Linux、以及 macOS,它使用 [MIT 许可证][4]。 +* [Jeedom][5] 是一个由开源软件([GPL v2][6])构成的家庭自动化平台,它可以控制灯、锁、多媒体等等。它包含一个移动应用程序(Android 和 iOS),并且可以运行在 Linux PC 上;该公司也销售 hubs,它为配置家庭自动化提供一个现成的解决方案。 +* [LinuxMCE][7] 标称它是你的多媒体与电子设备之间的“数字粘合剂”。它运行在 Linux(包括树莓派)上,它基于 Pluto 开源 [许可证][8] 发布,它可以用于家庭安全、电话(VoIP 和语音信箱)、A/V 设备、家庭自动化、以及玩视频游戏。 +* [OpenNetHome][9],和这一类中的其它解决方案一样,是一个控制灯、报警、应用程序等等的一个开源软件。它基于 Java 和 Apache Maven,可以运行在 Windows、macOS、以及 Linux —— 包括树莓派,它以 [GPLv3][10] 许可证发布。 +* [Smarthomatic][11] 是一个专注于硬件设备和软件的开源家庭自动化框架,而不仅是用户接口。它基于 [GPLv3][12] 许可证,它可用于控制灯、电器、以及空调、检测温度、提醒给植物浇水。 + +现在该轮到你了:你已经准备好家庭自动化系统了吗?或者正在研究去设计一个。你对家庭自动化的新手有什么建议,你会推荐什么样的系统? + +-------------------------------------------------------------------------------- + +via: https://opensource.com/life/17/12/home-automation-tools + +作者:[Jason Baker][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jason-baker +[1]:http://www.eventghost.net/ +[2]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +[3]:http://iobroker.net/ +[4]:https://github.com/ioBroker/ioBroker#license +[5]:https://www.jeedom.com/site/en/index.html +[6]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +[7]:http://www.linuxmce.com/ +[8]:http://wiki.linuxmce.org/index.php/License +[9]:http://opennethome.org/ +[10]:https://github.com/NetHome/NetHomeServer/blob/master/LICENSE +[11]:https://www.smarthomatic.org/ +[12]:https://github.com/breaker27/smarthomatic/blob/develop/GPL3.txt +[13]:https://opensource.com/resources/internet-of-things +[14]:https://www.statista.com/outlook/279/109/smart-home/united-states +[15]:http://www.crn.com/slide-shows/internet-of-things/300089496/black-hat-2017-9-iot-security-threats-to-watch.htm +[16]:https://opensource.com/business/15/5/why-open-source-means-stronger-security +[17]:https://calaos.fr/en/ +[18]:https://github.com/calaos/calaos-os/blob/master/LICENSE +[19]:https://github.com/calaos +[20]:https://domoticz.com/ +[21]:https://www.domoticz.com/wiki/Integrations_and_Protocols +[22]:https://github.com/domoticz/domoticz/blob/master/License.txt +[23]:https://github.com/domoticz/domoticz +[24]:https://home-assistant.io/ +[25]:https://github.com/home-assistant/home-assistant/blob/dev/LICENSE.md +[26]:https://github.com/balloob/home-assistant +[27]:http://misterhouse.sourceforge.net/ +[28]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +[29]:https://github.com/hollie/misterhouse +[30]:http://www.openhab.org/ +[31]:https://github.com/openhab/openhab +[32]:https://github.com/openhab/openhab/blob/master/LICENSE.TXT +[33]:https://www.openmotics.com/ +[34]:https://opensource.com/life/14/12/open-source-home-automation-system-opemmotics +[35]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +[36]:https://github.com/openmotics From 8b96d71224b337cd633dbf9d9ec6c82e00645f4d Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 28 Feb 2018 15:47:27 +0800 Subject: [PATCH 037/101] PRF:20090724 Top 20 OpenSSH Server Best Security Practices.md @shipsw --- ... OpenSSH Server Best Security Practices.md | 369 +++++++++++------- 1 file changed, 225 insertions(+), 144 deletions(-) diff --git a/translated/tech/20090724 Top 20 OpenSSH Server Best Security Practices.md b/translated/tech/20090724 Top 20 OpenSSH Server Best Security Practices.md index b0fb1bcccf..53be8e2057 100644 --- a/translated/tech/20090724 Top 20 OpenSSH Server Best Security Practices.md +++ b/translated/tech/20090724 Top 20 OpenSSH Server Best Security Practices.md @@ -1,223 +1,272 @@ -Translated by shipsw +20 个 OpenSSH 最佳安全实践 +====== -20 个 OpenSSH 安全实践 -====== ![OpenSSH 安全提示][1] -OpenSSH 是 SSH 协议的一个实现。一般被 scp 或 sftp 用在远程登录、备份、远程文件传输等功能上。SSH能够完美保障两个网络或系统间数据传输的保密性和完整性。尽管如此,他主要用在使用公匙加密的服务器验证上。不时出现关于 OpenSSH 零日漏洞的[谣言][2]。本文描述**如何设置你的 Linux 或类 Unix 系统以提高 sshd 的安全性**。 +OpenSSH 是 SSH 协议的一个实现。一般通过 `scp` 或 `sftp` 用于远程登录、备份、远程文件传输等功能。SSH能够完美保障两个网络或系统间数据传输的保密性和完整性。尽管如此,它最大的优势是使用公匙加密来进行服务器验证。时不时会出现关于 OpenSSH 零日漏洞的[传言][2]。本文将描述如何设置你的 Linux 或类 Unix 系统以提高 sshd 的安全性。 -#### OpenSSH 默认设置 +### OpenSSH 默认设置 - * TCP 端口 - 22 - * OpenSSH 服务配置文件 - sshd_config (位于 /etc/ssh/) +* TCP 端口 - 22 +* OpenSSH 服务配置文件 - `sshd_config` (位于 `/etc/ssh/`) +### 1、 基于公匙的登录 +OpenSSH 服务支持各种验证方式。推荐使用公匙加密验证。首先,使用以下 `ssh-keygen` 命令在本地电脑上创建密匙对: -#### 1. 基于公匙的登录 - -OpenSSH 服务支持各种验证方式。推荐使用公匙加密验证。首先,使用以下 ssh-keygen 命令在本地电脑上创建密匙对: - -低于 1024 位的 DSA 和 RSA 加密是很弱的,请不要使用。RSA 密匙主要是在考虑 ssh 客户端兼容性的时候代替 ECDSA 密匙使用的。 +> 1024 位或低于它的 DSA 和 RSA 加密是很弱的,请不要使用。当考虑 ssh 客户端向后兼容性的时候,请使用 RSA密匙代替 ECDSA 密匙。所有的 ssh 密钥要么使用 ED25519 ,要么使用 RSA,不要使用其它类型。 ``` $ ssh-keygen -t key_type -b bits -C "comment" +``` + +示例: + +``` $ ssh-keygen -t ed25519 -C "Login to production cluster at xyz corp" +或 $ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_aws_$(date +%Y-%m-%d) -C "AWS key for abc corp clients" ``` -下一步,使用 ssh-copy-id 命令安装公匙: + +下一步,使用 `ssh-copy-id` 命令安装公匙: + ``` $ ssh-copy-id -i /path/to/public-key-file user@host +或 $ ssh-copy-id user@remote-server-ip-or-dns-name +``` + +示例: + +``` $ ssh-copy-id vivek@rhel7-aws-server ``` -提示输入用户名和密码的时候,使用你自己的 ssh 公匙: -`$ ssh vivek@rhel7-aws-server` -[![OpenSSH 服务安全最佳实践][3]][3] + +提示输入用户名和密码的时候,确认基于 ssh 公匙的登录是否工作: + +``` +$ ssh vivek@rhel7-aws-server +``` + +[![OpenSSH 服务安全最佳实践][3]][3] + 更多有关 ssh 公匙的信息,参照以下文章: -* [为备份脚本设置无密码安全登录][48] - -* [sshpass: 使用脚本密码登录SSH服务器][49] - -* [如何为一个 Linux/类Unix 系统设置 SSH 登录密匙][50] - -* [如何使用 Ansible 工具上传 ssh 登录授权公匙][51] +* [为备份脚本设置无密码安全登录][48] +* [sshpass:使用脚本密码登录 SSH 服务器][49] +* [如何为一个 Linux/类 Unix 系统设置 SSH 登录密匙][50] +* [如何使用 Ansible 工具上传 ssh 登录授权公匙][51] -#### 2. 禁用 root 用户登录 +### 2、 禁用 root 用户登录 -禁用 root 用户登录前,确认普通用户可以以 root 身份登录。例如,允许用户 vivek 使用 sudo 命令以 root 身份登录。 +禁用 root 用户登录前,确认普通用户可以以 root 身份登录。例如,允许用户 vivek 使用 `sudo` 命令以 root 身份登录。 -##### 在 Debian/Ubuntu 系统中如何将用户 vivek 添加到 sudo 组中 +#### 在 Debian/Ubuntu 系统中如何将用户 vivek 添加到 sudo 组中 -允许 sudo 组中的用户执行任何命令。 [将用户 vivek 添加到 sudo 组中][4]: -`$ sudo adduser vivek sudo` -使用 [id 命令][5] 验证用户组。 -`$ id vivek` +允许 sudo 组中的用户执行任何命令。 [将用户 vivek 添加到 sudo 组中][4]: -##### 在 CentOS/RHEL 系统中如何将用户 vivek 添加到 sudo 组中 +``` +$ sudo adduser vivek sudo +``` + +使用 [id 命令][5] 验证用户组。 + +``` +$ id vivek +``` + +#### 在 CentOS/RHEL 系统中如何将用户 vivek 添加到 sudo 组中 + +在 CentOS/RHEL 和 Fedora 系统中允许 wheel 组中的用户执行所有的命令。使用 `usermod` 命令将用户 vivek 添加到 wheel 组中: -在 CentOS/RHEL 和 Fedora 系统中允许 wheel 组中的用户执行所有的命令。使用 uermod 命令将用户 vivek 添加到 wheel 组中: ``` $ sudo usermod -aG wheel vivek $ id vivek ``` -##### 测试 sudo 权限并禁用 ssh root 登录 +#### 测试 sudo 权限并禁用 ssh root 登录 测试并确保用户 vivek 可以以 root 身份登录执行以下命令: + ``` $ sudo -i $ sudo /etc/init.d/sshd status $ sudo systemctl status httpd ``` -添加以下内容到 sshd_config 文件中来禁用 root 登录。 + +添加以下内容到 `sshd_config` 文件中来禁用 root 登录: + ``` PermitRootLogin no ChallengeResponseAuthentication no PasswordAuthentication no UsePAM no ``` + 更多信息参见“[如何通过禁用 Linux 的 ssh 密码登录来增强系统安全][6]” 。 -#### 3. 禁用密码登录 +### 3、 禁用密码登录 + +所有的密码登录都应该禁用,仅留下公匙登录。添加以下内容到 `sshd_config` 文件中: -所有的密码登录都应该禁用,仅留下公匙登录。添加以下内容到 sshd_config 文件中: ``` AuthenticationMethods publickey PubkeyAuthentication yes ``` -CentOS 6.x/RHEL 6.x 系统中老版本的 SSHD 用户可以使用以下设置: + +CentOS 6.x/RHEL 6.x 系统中老版本的 sshd 用户可以使用以下设置: + ``` PubkeyAuthentication yes ``` -#### 4. 限制用户的 ssh 权限 +### 4、 限制用户的 ssh 访问 + +默认状态下,所有的系统用户都可以使用密码或公匙登录。但是有些时候需要为 FTP 或者 email 服务创建 UNIX/Linux 用户。然而,这些用户也可以使用 ssh 登录系统。他们将获得访问系统工具的完整权限,包括编译器和诸如 Perl、Python(可以打开网络端口干很多疯狂的事情)等的脚本语言。通过添加以下内容到 `sshd_config` 文件中来仅允许用户 root、vivek 和 jerry 通过 SSH 登录系统: + +``` +AllowUsers vivek jerry +``` + +当然,你也可以添加以下内容到 `sshd_config` 文件中来达到仅拒绝一部分用户通过 SSH 登录系统的效果。 + +``` +DenyUsers root saroj anjali foo +``` -默认状态下,所有的系统用户都可以使用密码或公匙登录。但是有些时候需要为 FTP 或者 email 服务创建 UNIX/Linux 用户。所以,这些用户也可以使用 ssh 登录系统。他们将获得访问系统工具的完整权限,包括编译器和诸如 Perl、Python(可以打开网络端口干很多疯狂的事情) 等的脚本语言。通过添加以下内容到 sshd_config 文件中来仅允许用户 root、vivek 和 jerry 通过 SSH 登录系统: -`AllowUsers vivek jerry` -当然,你也可以添加以下内容到 sshd_config 文件中来达到仅拒绝一部分用户通过 SSH 登录系统的效果。 -`DenyUsers root saroj anjali foo` 你也可以通过[配置 Linux PAM][7] 来禁用或允许用户通过 sshd 登录。也可以允许或禁止一个[用户组列表][8]通过 ssh 登录系统。 -#### 5. 禁用空密码 +### 5、 禁用空密码 -你需要明确禁止空密码账户远程登录系统,更新 sshd_config 文件的以下内容: -`PermitEmptyPasswords no` +你需要明确禁止空密码账户远程登录系统,更新 `sshd_config` 文件的以下内容: -#### 6. 为 ssh 用户或者密匙使用强密码 +``` +PermitEmptyPasswords no +``` + +### 6、 为 ssh 用户或者密匙使用强密码 + +为密匙使用强密码和短语的重要性再怎么强调都不过分。暴力破解可以起作用就是因为用户使用了基于字典的密码。你可以强制用户避开[字典密码][9]并使用[约翰的开膛手工具][10]来检测弱密码。以下是一个随机密码生成器(放到你的 `~/.bashrc` 下): -为密匙使用强密码和短语的重要性再怎么强调都不过分。暴力破解可以起作用就是因为用户使用了基于字典的密码。你可以强制用户避开字典密码并使用[约翰的开膛手工具][10]来检测弱密码。以下是一个随机密码生成器(放到你的 ~/.bashrc 下): ``` genpasswd() { local l=$1 - [ "$l" == "" ] && l=20 - tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs + [ "$l" == "" ] && l=20 + tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs } ``` -运行: -`genpasswd 16` -输出: +运行: + +``` +genpasswd 16 +``` + +输出: + ``` uw8CnDVMwC6vOKgW ``` -* [使用 mkpasswd / makepasswd / pwgen 生成随机密码][52] -* [Linux / UNIX: 生成密码][53] +* [使用 mkpasswd / makepasswd / pwgen 生成随机密码][52] +* [Linux / UNIX: 生成密码][53] +* [Linux 随机密码生成命令][54] -* [Linux 随机密码生成命令][54] +### 7、 为 SSH 的 22端口配置防火墙 --------------------------------------------------------------------------------- +你需要更新 `iptables`/`ufw`/`firewall-cmd` 或 pf 防火墙配置来为 ssh 的 TCP 端口 22 配置防火墙。一般来说,OpenSSH 服务应该仅允许本地或者其他的远端地址访问。 -#### 7. 为 SSH 端口 # 22 配置防火墙 +#### Netfilter(Iptables) 配置 -你需要更新 iptables/ufw/firewall-cmd 或 pf firewall 来为 ssh TCP 端口 # 22 配置防火墙。一般来说,OpenSSH 服务应该仅允许本地或者其他的远端地址访问。 +更新 [/etc/sysconfig/iptables (Redhat 和其派生系统特有文件) ][11] 实现仅接受来自于 192.168.1.0/24 和 202.54.1.5/29 的连接,输入: -##### Netfilter (Iptables) 配置 - -更新 [/etc/sysconfig/iptables (Redhat和其派生系统特有文件) ][11] 实现仅接受来自于 192.168.1.0/24 和 202.54.1.5/29 的连接, 输入: ``` -A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT -A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT ``` -如果同时使用 IPv6 的话,可以编辑/etc/sysconfig/ip6tables(Redhat 和其派生系统特有文件),输入: +如果同时使用 IPv6 的话,可以编辑 `/etc/sysconfig/ip6tables` (Redhat 和其派生系统特有文件),输入: + ``` -A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT - ``` -将 ipv6network::/ipv6mask 替换为实际的 IPv6 网段。 +将 `ipv6network::/ipv6mask` 替换为实际的 IPv6 网段。 -##### Debian/Ubuntu Linux 下的 UFW +#### Debian/Ubuntu Linux 下的 UFW -[UFW 是 uncomplicated firewall 的首字母缩写,主要用来管理 Linux 防火墙][12],目的是提供一种用户友好的界面。输入[以下命令使得系统进允许网段 202.54.1.5/29 接入端口 22][13]: -`$ sudo ufw allow from 202.54.1.5/29 to any port 22` -更多信息请参见 "[Linux: 菜鸟管理员的 25 个 Iptables Netfilter 命令][14]"。 +[UFW 是 Uncomplicated FireWall 的首字母缩写,主要用来管理 Linux 防火墙][12],目的是提供一种用户友好的界面。输入[以下命令使得系统仅允许网段 202.54.1.5/29 接入端口 22][13]: -##### *BSD PF 防火墙配置 +``` +$ sudo ufw allow from 202.54.1.5/29 to any port 22 +``` + +更多信息请参见 “[Linux:菜鸟管理员的 25 个 Iptables Netfilter 命令][14]”。 + +#### *BSD PF 防火墙配置 如果使用 PF 防火墙 [/etc/pf.conf][15] 配置如下: + ``` pass in on $ext_if inet proto tcp from {192.168.1.0/24, 202.54.1.5/29} to $ssh_server_ip port ssh flags S/SA synproxy state ``` -#### 8. 修改 SSH 端口和绑定 IP +### 8、 修改 SSH 端口和绑定 IP + +ssh 默认监听系统中所有可用的网卡。修改并绑定 ssh 端口有助于避免暴力脚本的连接(许多暴力脚本只尝试端口 22)。更新文件 `sshd_config` 的以下内容来绑定端口 300 到 IP 192.168.1.5 和 202.54.1.5: -SSH 默认监听系统中所有可用的网卡。修改并绑定 ssh 端口有助于避免暴力脚本的连接(许多暴力脚本只尝试端口 22)。更新文件 sshd_config 的以下内容来绑定端口 300 到 IP 192.168.1.5 和 202.54.1.5: ``` Port 300 ListenAddress 192.168.1.5 ListenAddress 202.54.1.5 ``` -端口 300 监听地址 192.168.1.5 监听地址 202.54.1.5 - 当需要接受动态广域网地址的连接时,使用主动脚本是个不错的选择,比如 fail2ban 或 denyhosts。 -#### 9. 使用 TCP wrappers (可选的) +### 9、 使用 TCP wrappers (可选的) + +TCP wrapper 是一个基于主机的访问控制系统,用来过滤来自互联网的网络访问。OpenSSH 支持 TCP wrappers。只需要更新文件 `/etc/hosts.allow` 中的以下内容就可以使得 SSH 只接受来自于 192.168.1.2 和 172.16.23.12 的连接: -TCP wrapper 是一个基于主机的访问控制系统,用来过滤来自互联网的网络访问。OpenSSH 支持 TCP wrappers。只需要更新文件 /etc/hosts.allow 中的以下内容就可以使得 SSH 只接受来自于 192.168.1.2 和 172.16.23.12 的连接: ``` sshd : 192.168.1.2 172.16.23.12 ``` 在 Linux/Mac OS X 和类 UNIX 系统中参见 [TCP wrappers 设置和使用的常见问题][16]。 -#### 10. 阻止 SSH 破解或暴力攻击 +### 10、 阻止 SSH 破解或暴力攻击 -暴力破解是一种在单一或者分布式网络中使用大量组合(用户名和密码的组合)来尝试连接一个加密系统的方法。可以使用以下软件来应对暴力攻击: +暴力破解是一种在单一或者分布式网络中使用大量(用户名和密码的)组合来尝试连接一个加密系统的方法。可以使用以下软件来应对暴力攻击: - * [DenyHosts][17] 是一个基于 Python SSH 安全工具。该工具通过监控授权日志中的非法登录日志并封禁原始IP的方式来应对暴力攻击。 - * RHEL / Fedora 和 CentOS Linux 下如何设置 [DenyHosts][18]。 - * [Fail2ban][19] 是另一个类似的用来预防针对 SSH 攻击的工具。 - * [sshguard][20] 是一个使用 pf 来预防针对 SSH 和其他服务攻击的工具。 - * [security/sshblock][21] 阻止滥用 SSH 尝试登录。 - * [IPQ BDB filter][22] 可以看做是 fail2ban 的一个简化版。 +* [DenyHosts][17] 是一个基于 Python SSH 安全工具。该工具通过监控授权日志中的非法登录日志并封禁原始 IP 的方式来应对暴力攻击。 + * RHEL / Fedora 和 CentOS Linux 下如何设置 [DenyHosts][18]。 +* [Fail2ban][19] 是另一个类似的用来预防针对 SSH 攻击的工具。 +* [sshguard][20] 是一个使用 pf 来预防针对 SSH 和其他服务攻击的工具。 +* [security/sshblock][21] 阻止滥用 SSH 尝试登录。 +* [IPQ BDB filter][22] 可以看做是 fail2ban 的一个简化版。 +### 11、 限制 TCP 端口 22 的传入速率(可选的) +netfilter 和 pf 都提供速率限制选项可以对端口 22 的传入速率进行简单的限制。 -#### 11. 限制 TCP 端口 # 22 的传入速率 (可选的) - -netfilter 和 pf 都提供速率限制选项可以对端口 # 22 的传入速率进行简单的限制。 - -##### Iptables 示例 +#### Iptables 示例 以下脚本将会阻止 60 秒内尝试登录 5 次以上的客户端的连入。 + ``` #!/bin/bash inet_if=eth1 ssh_port=22 -$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --set -$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --update --seconds 60 --hitcount 5 +$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --set +$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --update --seconds 60 --hitcount 5 ``` 在你的 iptables 脚本中调用以上脚本。其他配置选项: + ``` -$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT -$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT +$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT +$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT $IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT # another one line example # $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT @@ -225,9 +274,10 @@ $IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLI 其他细节参见 iptables 用户手册。 -##### *BSD PF 示例 +#### *BSD PF 示例 + +以下脚本将限制每个客户端的连入数量为 20,并且 5 秒内的连接不超过 15 个。如果客户端触发此规则,则将其加入 abusive_ips 表并限制该客户端连入。最后 flush 关键词杀死所有触发规则的客户端的连接。 -以下脚本将限制每个客户端的连入数量为 20,并且 5 秒范围的连接不超过 15 个。如果客户端触发此规则则将其加入 abusive_ips 表并限制该客户端连入。最后 flush 关键词杀死所有触发规则的客户端的状态。 ``` sshd_server_ip = "202.54.1.5" table persist @@ -235,9 +285,10 @@ block in quick from pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate 15/5, overload flush) ``` -#### 12. 使用端口敲门 (可选的) +### 12、 使用端口敲门(可选的) + +[端口敲门][23]是通过在一组预先指定的封闭端口上生成连接尝试,以便从外部打开防火墙上的端口的方法。一旦指定的端口连接顺序被触发,防火墙规则就被动态修改以允许发送连接的主机连入指定的端口。以下是一个使用 iptables 实现的端口敲门的示例: -[端口敲门][23]是通过在一组预先指定的封闭端口上生成连接尝试来从外部打开防火墙上的端口的方法。一旦指定的端口连接顺序被触发,防火墙规则就被动态修改以允许发送连接的主机连入指定的端口。以下是一个使用 iptables 实现的端口敲门的示例: ``` $IPT -N stage1 $IPT -A stage1 -m recent --remove --name knock @@ -257,24 +308,31 @@ $IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j $IPT -A INPUT -p tcp --syn -j door ``` +更多信息请参见: -更多信息请参见: [Debian / Ubuntu: 使用 Knockd and Iptables 设置端口敲门][55] -#### 13. 配置空闲超时注销时长 +### 13、 配置空闲超时注销时长 + +用户可以通过 ssh 连入服务器,可以配置一个超时时间间隔来避免无人值守的 ssh 会话。 打开 `sshd_config` 并确保配置以下值: -用户可以通过 ssh 连入服务器,可以配置一个超时时间间隔来避免无人值守的 ssh 会话。 打开 sshd_config 并确保配置以下值: ``` ClientAliveInterval 300 ClientAliveCountMax 0 ``` -以秒为单位设置一个空闲超时时间(300秒 = 5分钟)。一旦空闲时间超过这个值,空闲用户就会被踢出会话。更多细节参见[如何自动注销空闲超时的 BASH / TCSH / SSH 用户][24]。 -#### 14. 为 ssh 用户启用警示标语 +以秒为单位设置一个空闲超时时间(300秒 = 5分钟)。一旦空闲时间超过这个值,空闲用户就会被踢出会话。更多细节参见[如何自动注销空闲超时的 BASH / TCSH / SSH 用户][24]。 + +### 14、 为 ssh 用户启用警示标语 + +更新 `sshd_config` 文件如下行来设置用户的警示标语: + +``` +Banner /etc/issue +``` + +`/etc/issue 示例文件: -更新 sshd_config 文件如下来设置用户的警示标语 -`Banner /etc/issue` -/etc/issue 示例文件: ``` ---------------------------------------------------------------------------------------------- You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only. @@ -297,45 +355,61 @@ or monitoring of the content of privileged communications, or work product, rela or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details. ---------------------------------------------------------------------------------------------- - ``` 以上是一个标准的示例,更多的用户协议和法律细节请咨询你的律师团队。 -#### 15. 禁用 .rhosts 文件 (核实) +### 15、 禁用 .rhosts 文件(需核实) + +禁止读取用户的 `~/.rhosts` 和 `~/.shosts` 文件。更新 `sshd_config` 文件中的以下内容: + +``` +IgnoreRhosts yes +``` -禁止读取用户的 ~/.rhosts 和 ~/.shosts 文件。更新 sshd_config 文件中的以下内容: -`IgnoreRhosts yes` SSH 可以模拟过时的 rsh 命令,所以应该禁用不安全的 RSH 连接。 -#### 16. 禁用 host-based 授权 (核实) +### 16、 禁用基于主机的授权(需核实) -禁用 host-based 授权,更新 sshd_config 文件的以下选项: -`HostbasedAuthentication no` +禁用基于主机的授权,更新 `sshd_config` 文件的以下选项: -#### 17. 为 OpenSSH 和 操作系统打补丁 +``` +HostbasedAuthentication no +``` + +### 17、 为 OpenSSH 和操作系统打补丁 推荐你使用类似 [yum][25]、[apt-get][26] 和 [freebsd-update][27] 等工具保持系统安装了最新的安全补丁。 -#### 18. Chroot OpenSSH (将用户锁定在主目录) +### 18、 Chroot OpenSSH (将用户锁定在主目录) -默认设置下用户可以浏览诸如 /etc/、/bin 等目录。可以使用 chroot 或者其他专有工具如 [rssh][28] 来保护ssh连接。从版本 4.8p1 或 4.9p1 起,OpenSSH 不再需要依赖诸如 rssh 或复杂的 chroot(1) 等第三方工具来将用户锁定在主目录中。可以使用新的 ChrootDirectory 指令将用户锁定在其主目录,参见[这篇博文][29]。 +默认设置下用户可以浏览诸如 `/etc`、`/bin` 等目录。可以使用 chroot 或者其他专有工具如 [rssh][28] 来保护 ssh 连接。从版本 4.8p1 或 4.9p1 起,OpenSSH 不再需要依赖诸如 rssh 或复杂的 chroot(1) 等第三方工具来将用户锁定在主目录中。可以使用新的 `ChrootDirectory` 指令将用户锁定在其主目录,参见[这篇博文][29]。 -#### 19. 禁用客户端的 OpenSSH 服务 +### 19. 禁用客户端的 OpenSSH 服务 + +工作站和笔记本不需要 OpenSSH 服务。如果不需要提供 ssh 远程登录和文件传输功能的话,可以禁用 sshd 服务。CentOS / RHEL 用户可以使用 [yum 命令][30] 禁用或删除 openssh-server: + +``` +$ sudo yum erase openssh-server +``` + +Debian / Ubuntu 用户可以使用 [apt 命令][31]/[apt-get 命令][32] 删除 openssh-server: + +``` +$ sudo apt-get remove openssh-server +``` + +有可能需要更新 iptables 脚本来移除 ssh 的例外规则。CentOS / RHEL / Fedora 系统可以编辑文件 `/etc/sysconfig/iptables` 和 `/etc/sysconfig/ip6tables`。最后[重启 iptables][33] 服务: -工作站和笔记本不需要 OpenSSH 服务。如果不需要提供 SSH 远程登录和文件传输功能的话,可以禁用 SSHD 服务。CentOS / RHEL 用户可以使用 [yum 命令][30] 禁用或删除openssh-server: -`$ sudo yum erase openssh-server` -Debian / Ubuntu 用户可以使用 [apt 命令][31]/[apt-get 命令][32] 删除 openssh-server: -`$ sudo apt-get remove openssh-server` -有可能需要更新 iptables 脚本来移除 ssh 例外规则。CentOS / RHEL / Fedora 系统可以编辑文件 /etc/sysconfig/iptables 和 /etc/sysconfig/ip6tables。最后[重启 iptables][33] 服务: ``` # service iptables restart # service ip6tables restart ``` -#### 20. 来自 Mozilla 的额外提示 +### 20. 来自 Mozilla 的额外提示 + +如果使用 6.7+ 版本的 OpenSSH,可以尝试下[以下设置][34]: -如果使用 6.7+ 版本的 OpenSSH,可以尝试下以下设置: ``` #################[ WARNING ]######################## # Do not use any setting blindly. Read sshd_config # @@ -361,10 +435,11 @@ MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@op LogLevel VERBOSE # Log sftp level file access (read/write/etc.) that would not be easily logged otherwise. -Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO +Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO ``` 使用以下命令获取 OpenSSH 支持的加密方法: + ``` $ ssh -Q cipher $ ssh -Q cipher-auth @@ -372,15 +447,25 @@ $ ssh -Q mac $ ssh -Q kex $ ssh -Q key ``` -[![OpenSSH安全教程查询密码和算法选择][35]][35] -#### 如何测试 sshd_config 文件并重启/重新加载 SSH 服务? +[![OpenSSH安全教程查询密码和算法选择][35]][35] + +### 如何测试 sshd_config 文件并重启/重新加载 SSH 服务? + +在重启 sshd 前检查配置文件的有效性和密匙的完整性,运行: + +``` +$ sudo sshd -t +``` + +扩展测试模式: + +``` +$ sudo sshd -T +``` -在重启 sshd 前检查配置文件的有效性和密匙的完整性,运行: -`$ sudo sshd -t` -扩展测试模式: -`$ sudo sshd -T` 最后,根据系统的的版本[重启 Linux 或类 Unix 系统中的 sshd 服务][37]: + ``` $ [sudo systemctl start ssh][38] ## Debian/Ubunt Linux## $ [sudo systemctl restart sshd.service][39] ## CentOS/RHEL/Fedora Linux## @@ -388,25 +473,21 @@ $ doas /etc/rc.d/sshd restart ## OpenBSD## $ sudo service sshd restart ## FreeBSD## ``` -#### 其他建议 +### 其他建议 - 1. [使用 2FA 加强 SSH 的安全性][40] - 可以使用[OATH Toolkit][41] 或 [DuoSecurity][42] 启用多重身份验证。 - 2. [基于密匙链的身份验证][43] - 密匙链是一个 bash 脚本,可以使得基于密匙的验证非常的灵活方便。相对于无密码密匙,它提供更好的安全性。 +1. [使用 2FA 加强 SSH 的安全性][40] - 可以使用 [OATH Toolkit][41] 或 [DuoSecurity][42] 启用多重身份验证。 +2. [基于密匙链的身份验证][43] - 密匙链是一个 bash 脚本,可以使得基于密匙的验证非常的灵活方便。相对于无密码密匙,它提供更好的安全性。 +### 更多信息: +* [OpenSSH 官方][44] 项目。 +* 用户手册: sshd(8)、ssh(1)、ssh-add(1)、ssh-agent(1)。 -#### 更多信息: +如果知道这里没用提及的方便的软件或者技术,请在下面的评论中分享,以帮助读者保持 OpenSSH 的安全。 - * [OpenSSH 官方][44] 项目. - * 用户手册: sshd(8),ssh(1),ssh-add(1),ssh-agent(1) +### 关于作者 - - -如果你发现一个方便的软件或者技术,请在下面的评论中分享,以帮助读者保持 OpenSSH 的安全。 - -#### 关于作者 - -作者是 nixCraft 的创始人,一个经验丰富的系统管理员和 Linux/Unix 脚本培训师。他曾与全球客户合作,领域涉及IT,教育,国防和空间研究以及非营利部门等多个行业。请在 [Twitter][45]、[Facebook][46]、[Google+][47] 上关注他。 +作者是 nixCraft 的创始人,一个经验丰富的系统管理员和 Linux/Unix 脚本培训师。他曾与全球客户合作,领域涉及 IT,教育,国防和空间研究以及非营利部门等多个行业。请在 [Twitter][45]、[Facebook][46]、[Google+][47] 上关注他。 -------------------------------------------------------------------------------- @@ -414,7 +495,7 @@ via: https://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices 作者:[Vivek Gite][a] 译者:[shipsw](https://github.com/shipsw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -467,7 +548,7 @@ via: https://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices [46]:https://facebook.com/nixcraft [47]:https://plus.google.com/+CybercitiBiz [48]:https://www.cyberciti.biz/faq/ssh-passwordless-login-with-keychain-for-scripts/ -[49]:https://www.cyberciti.biz/faq/noninteractive-shell-script-ssh-password-provider/ +[49]:https://linux.cn/article-8086-1.html [50]:https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/ [51]:https://www.cyberciti.biz/faq/how-to-upload-ssh-public-key-to-as-authorized_key-using-ansible/ [52]:https://www.cyberciti.biz/faq/generating-random-password/ From 16164a26aa6cb2a5885f520a21806d238a71435a Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 28 Feb 2018 15:47:46 +0800 Subject: [PATCH 038/101] PUB:20090724 Top 20 OpenSSH Server Best Security Practices.md @shipsw https://linux.cn/article-9394-1.html --- .../20090724 Top 20 OpenSSH Server Best Security Practices.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20090724 Top 20 OpenSSH Server Best Security Practices.md (100%) diff --git a/translated/tech/20090724 Top 20 OpenSSH Server Best Security Practices.md b/published/20090724 Top 20 OpenSSH Server Best Security Practices.md similarity index 100% rename from translated/tech/20090724 Top 20 OpenSSH Server Best Security Practices.md rename to published/20090724 Top 20 OpenSSH Server Best Security Practices.md From 423374bb87e327685d1e28d857f28e642d0951ae Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Wed, 28 Feb 2018 17:04:52 +0800 Subject: [PATCH 039/101] apply for translation --- sources/tech/20180123 Migrating to Linux- The Command Line.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180123 Migrating to Linux- The Command Line.md b/sources/tech/20180123 Migrating to Linux- The Command Line.md index 602c23bbf2..b5bc658131 100644 --- a/sources/tech/20180123 Migrating to Linux- The Command Line.md +++ b/sources/tech/20180123 Migrating to Linux- The Command Line.md @@ -1,3 +1,5 @@ +translated by cyleft + Migrating to Linux: The Command Line ====== From 01fe1e394117f079ffbe5fbb62ad5e78331a7210 Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Wed, 28 Feb 2018 17:19:33 +0800 Subject: [PATCH 040/101] Update 20171017 What Are the Hidden Files in my Linux Home Directory For.md --- ... What Are the Hidden Files in my Linux Home Directory For.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md b/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md index fa8613f03d..9021bd1183 100644 --- a/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md +++ b/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md @@ -1,3 +1,5 @@ +Translating by MjSeven + What Are the Hidden Files in my Linux Home Directory For? ====== From 002cf295154595fa6781419987fcd899d26b3ef6 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Wed, 28 Feb 2018 17:35:43 +0800 Subject: [PATCH 041/101] Translated by qhwdw --- ...inated bottlenecks for Ranger community.md | 72 ------------------- ...inated bottlenecks for Ranger community.md | 72 +++++++++++++++++++ 2 files changed, 72 insertions(+), 72 deletions(-) delete mode 100644 sources/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md create mode 100644 translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md diff --git a/sources/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md b/sources/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md deleted file mode 100644 index 5f0b2ef111..0000000000 --- a/sources/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md +++ /dev/null @@ -1,72 +0,0 @@ -Translating by qhwdw -How DevOps eliminated bottlenecks for Ranger community -====== -![配图](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/traffic-light-go.png?itok=nC_851ys) -The Visual Studio Application Lifecycle Management (ALM) [Ranger][1] program is a community of volunteers that gives professional guidance, practical experience, and gap-filling solutions to the developer community. It was created in 2006 as an internal Microsoft community to "connect the product group with the field and remove adoption blockers." By 2009, the community had more than 200 members, which led to collaboration and planning challenges, bottlenecks due to dependencies and manual processes, and increasing delays and dissatisfaction within the developer community. In 2010, the program evolved to include Microsoft Most Valued Professionals (MVPs), expanding into a geographically distributed community that spans the globe. - -The community is divided into roughly a dozen active teams. Each team is committed to design, build, and support one guidance or tooling project through its lifetime. In the past, teams typically bottlenecked at the team management level due to a rigid, waterfall-style process and high dependency on one or more program managers. The program managers intervened in decision making, releases, and driving the "why, what, and how" for projects. Also, a lack of real-time metrics prevented teams from effectively monitoring their solutions, and alerts about bugs and issues typically came from the community. - -It was time to find a better way of doing things and delivering value to the developer community. - -### DevOps to the rescue - -> "DevOps is the union of people, process, and products to enable continuous delivery of value to our end users." --[Donovan Brown][2] - -To address these challenges, the community stopped all new projects for a couple of sprints to explore Agile practices and new products. The aim was to re-energize the community, to find ways to promote autonomy, mastery, and purpose, as outlined in the book [Drive][3], by Daniel H. Pink, and to overhaul the rigid processes and products. - -> Mature self-organizing, self-managed, and cross-functional teams thrive on autonomy, mastery, and purpose." --Drive, Daniel H. Pink. - -Getting the culture--the people--right was the first step to embrace DevOps. The community implemented the [Scrum][4] framework, used [kanban][5] to improve the engineering process, and adopted visualization to improve transparency, awareness, and most important, trust. With self-organization of teams, the traditional hierarchy and chain-of-command disappeared. Self-management encouraged teams to actively monitor and evolve their own process. - -In April 2010, the community took another pivotal step by switching and committing its culture, process, and products to the cloud. While the core focus of the free "by-the-community-for-the-community" [solutions][6] remains on guidance and filling gaps, there's a growing investment in open source solutions (OSS) to research and share outcomes from the DevOps transformations. - -Continuous integration (CI) and continuous delivery (CD) replaced rigid manual processes with automated pipelines. This empowered teams to deploy solutions to canary and early-adopter users without intervention from program management. Adding telemetry enabled teams to watch their solutions and often detect and address unknown issues before users noticed them. - -The DevOps transformation is an ongoing evolution, using experiments to explore and validate people, process, and product innovations. Recent experiments introduced pipeline innovations that are continuously improving the value flow. Scanning components automatically, continuously, and silently checks security, licensing, and quality of open source components. Deployment rings and feature flags enable teams to have fine-grained control of features for all or specific users. - -In October 2017, the community moved most of its private version control repositories to [GitHub][7]. Transferring ownership and administration responsibilities for all repositories to the ALM DevOps Rangers community gives the teams autonomy and an opportunity to energize the broader community to contribute to the open source solutions. Teams are empowered to deliver quality and value to their end users. - -### Benefits and accomplishments - -Embracing DevOps enabled the Ranger community to become nimble, realize faster-to-market and quicker-to-learn-and-react processes, reduce investment of precious time, and proclaim autonomy. - -Here's a list of our observations from the transition, listed in no specific order: - - * Autonomy, mastery, and purpose are core. - * Start with something tangible and iterate--avoid the big bang. - * Tangible and actionable metrics are important--ensure it does not turn into noise. - * The most challenging parts of transformation are the people (culture). - * There's no blueprint; every organization and every team is unique. - * Transformation is continuous. - * Transparency and visibility are key. - * Use the engineering process to reinforce desired behavior. - - - -Table of transformation changes: - -PAST CURRENT ENVISIONED Branching Servicing and release isolation Feature Master Build Manual and error prone Automated and consistent Issue detection Call from user Proactive telemetry Issue resolution Days to weeks Minutes to days Minutes Planning Detailed design Prototyping and storyboards Program management 2 program managers (PM) 0.25 PM 0.125 PM Release cadence 6 to 12 months 3 to 5 sprints Every sprint Release Manual and error prone Automated and consistent Sprints 1 month 3 weeks Team size 10 to 15 2 to 5 Time to build Hours Seconds Time to release Days Minutes - -But, we're not done! Instead, we're part of an exciting, continuous, and likely never-ending transformation. - -If you'd like to learn more about our transformation, positive experiences, and known challenges that need to be addressed, see "[Our journey of transforming to a DevOps culture][8]." - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/17/11/devops-rangers-transformation - -作者:[Willy Schaub][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/wpschaub -[1]:https://aka.ms/vsaraboutus -[2]:http://donovanbrown.com/post/what-is-devops -[3]:http://www.danpink.com/books/drive/ -[4]:http://www.scrumguides.org/scrum-guide.html -[5]:https://leankit.com/learn/kanban/what-is-kanban/ -[6]:https://aka.ms/vsarsolutions -[7]:https://github.com/ALM-Rangers -[8]:https://github.com/ALM-Rangers/Guidance/blob/master/src/Stories/our-journey-of-transforming-to-a-devops-culture.md diff --git a/translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md b/translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md new file mode 100644 index 0000000000..a231fcefce --- /dev/null +++ b/translated/tech/20171122 How DevOps eliminated bottlenecks for Ranger community.md @@ -0,0 +1,72 @@ +DevOps 如何消除掉 Ranger 社区的瓶颈 +====== +![配图](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/traffic-light-go.png?itok=nC_851ys) + +Visual Studio Application Lifecycle Management(ALM)项目 —— [Ranger][1] 是一个志愿者社区,它提供专业的指导、实践经验、以及开发者社区的漏洞修补解决方案。它创建于 2006 年,作为微软内部社区去 "connect the product group with the field and remove adoption blockers"。 在 2009 时,社区已经有超过 200 位成员,这导致了协作和计划面临很大的挑战,在依赖和手工流程上产生了瓶颈,并导致了开发者社区不断增加的延迟和各种报怨。在 2010 时,计划进一步去扩充包括微软最有价值专家(MVP)在内的分布在全球的社区。 + +这个社区被分割成十几个活跃的团队。每个团队都致力于通过它的生命周期去设计、构建和支持一个指导或处理项目。在以前,团队的瓶颈在团队管理级别上,原因是严格的、瀑布式的流程和高度依赖一个或多个项目经理。在制作、发布和“为什么、做什么、和怎么做”驱动的决定上,项目经理都要介入其中。另外,缺乏一个实时的指标阻止了团队对他们的解决方案效率的监控,以及对来自社区的关于 bug 和常见问题的关注。 + +是时候去寻找一些做好这些事情的方法了,更好地实现开发者社区的价值。 + +### DevOps 去“灭火” + +> "DevOps 是人员、流程、和产品的结合,使我们的最终用户能够持续传递价值。" --[Donovan Brown][2] + +为解决这些挑战,社区停止了所有对新项目的冲刺,去探索敏捷实践和新产品。致力于使社区重新活跃起来,为找到促进自治、掌控、和目标的方法,正如在 Daniel H. Pink 的书 —— [Drive][3] 中所说的那样,对僵化的流程和产品进行彻底的改革。 + +> “成熟的自组织、自管理、和跨职能团队,在自治、掌控、和目标上茁壮成长。" --Drive, Daniel H. Pink. + +从文化开始 —— 人 —— 第一步是去拥抱 DevOps。社区实现了 [Scrum][4] 框架,使用 [kanban][5] 去提升工程化流程,并且通过可视化去提升透明度、意识和最重要的东西 —— 信任。使用自组织团队后,传统的等级制度和指挥系统消失了。自管理促使团队去积极监视和设计它们自己的流程。 + +在 2010 年 4 月份,社区再次实施了另外的关键一步,切换并提交它们的文化、流程、以及产品到云上。虽然开放的”为社区而社区“的核心 [解决方案][6] 仍然是指导和补充,但是在开源解决方案(OSS)上大量增加投资去研究和共享 DevOps 转换的成就。 + +持续集成(CI)和持续交付(CD)使用自动化流水线代替了死板的人工流程。这使得团队在不受来自项目经理的干预的情况下为早期问题和早期应用者部署解决方案。增加遥测技术可以使团队关注他们的解决方案,以及在用户注意到它们之前,检测和处理未知的问题。 + +DevOps 转变是一个持续进化的过程,通过实验去探索和验证人、流程、和产品的改革。最新的试验引入了流水线革新,它可以持续提升价值流。自动扫描组件、持续地、以及静默地检查安全、协议、和开源组件的品质。部署环和特性标志允许团队对所有或者特定用户进行更细粒度的控制。 + +在 2017 年 10 月,社区将大部分的私有版本控制仓库转移到 [GitHub][7] 上。对所有仓库转移所有者和管理职责到 ALM DevOps Rangers 社区,给团队提供自治和机会,去激励更多的社区对开源解决方案作贡献。团队被授权向他们的最终用户交付质量和价值。 + +### 好处和成就 + +拥抱 DevOps 使 Ranger 社区变得更加敏捷,实现了对市场的快速反应和快速学习和反应的流程,减少了宝贵的时间投入,并宣布自治。 + +下面是从这个转变中观察到的一个列表,排列没有特定的顺序: + + * 自治、掌控、和目标是核心。 + * 从可触摸的和可迭代的东西开始 —— 避免摊子铺的过大。 + * 可触摸的和可操作的指标很重要 —— 确保不要掺杂其它东西。 + * 人(文化)的转变是最具挑战的部分。 + * 没有蓝图;任何一个组织和任何一个团队都是独一无二的。 + * 转变是一个持续的过程。 + * 透明和可视非常关键。 + * 使用工程化流程去强化预期行为。 + + + +转换变化表:~~(致核对:以下是表格,格式转换造成错乱了。)~~ + +PAST CURRENT ENVISIONED Branching Servicing and release isolation Feature Master Build Manual and error prone Automated and consistent Issue detection Call from user Proactive telemetry Issue resolution Days to weeks Minutes to days Minutes Planning Detailed design Prototyping and storyboards Program management 2 program managers (PM) 0.25 PM 0.125 PM Release cadence 6 to 12 months 3 to 5 sprints Every sprint Release Manual and error prone Automated and consistent Sprints 1 month 3 weeks Team size 10 to 15 2 to 5 Time to build Hours Seconds Time to release Days Minutes + +但是,我们还没有做完,相反,我们就是一个令人兴奋的、持续不断的、几乎从不结束的转变的一部分。 + +如果你想去学习更多的关于我们的转变、有益的经验、以及想知道我们所经历的挑战,请查看 [转变到 DevOps 文化的记录][8]。" + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/11/devops-rangers-transformation + +作者:[Willy Schaub][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/wpschaub +[1]:https://aka.ms/vsaraboutus +[2]:http://donovanbrown.com/post/what-is-devops +[3]:http://www.danpink.com/books/drive/ +[4]:http://www.scrumguides.org/scrum-guide.html +[5]:https://leankit.com/learn/kanban/what-is-kanban/ +[6]:https://aka.ms/vsarsolutions +[7]:https://github.com/ALM-Rangers +[8]:https://github.com/ALM-Rangers/Guidance/blob/master/src/Stories/our-journey-of-transforming-to-a-devops-culture.md From bcb3092c6d3032f3c7e9ae1bc3b3e697fc5b2825 Mon Sep 17 00:00:00 2001 From: Auk7F7 <34982730+Auk7F7@users.noreply.github.com> Date: Wed, 28 Feb 2018 21:58:33 +0800 Subject: [PATCH 042/101] Update 20180221 Create a wiki on your Linux desktop with Zim.md translating by Auk7F7 --- .../20180221 Create a wiki on your Linux desktop with Zim.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md b/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md index 9929e45536..4b01a80721 100644 --- a/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md +++ b/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md @@ -1,3 +1,5 @@ +translating by Auk7F7 + Create a wiki on your Linux desktop with Zim ====== From 78da6153db83077b2e58d19f41c669f6aa396a40 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 28 Feb 2018 23:17:05 +0800 Subject: [PATCH 043/101] PRF:20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md @MjSeven --- ...Bing Desktop Wallpaper Changer On Linux.md | 138 +++++++++--------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/translated/tech/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md b/translated/tech/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md index d4a0b0e3ba..243b622b3e 100644 --- a/translated/tech/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md +++ b/translated/tech/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md @@ -1,9 +1,9 @@ -两种简单的方式在 Linux 安装必应桌面墙纸更换器 +在 Linux 上安装必应桌面墙纸更换器 ====== 你是否厌倦了 Linux 桌面背景,想要设置好看的壁纸,但是不知道在哪里可以找到?别担心,我们在这里会帮助你。 -我们都知道必应搜索引擎但是由于一些原因很少有人使用它,每个人都喜欢必应网站的背景壁纸,它是非常漂亮和惊人的高分辨率图像。 +我们都知道必应搜索引擎,但是由于一些原因很少有人使用它,每个人都喜欢必应网站的背景壁纸,它是非常漂亮和惊人的高分辨率图像。 如果你想使用这些图片作为你的桌面壁纸,你可以手动下载它,但是很难去每天下载一个新的图片,然后把它设置为壁纸。这就是自动壁纸改变的地方。 @@ -11,106 +11,104 @@ ### 方法 1: 使用 Utkarsh Gupta Shell 脚本 -这个小型 python 脚本会自动下载并将桌面壁纸更改为当天的必应照片。该脚本在机器时自动运行,并在 GNU/Linux 上使用 Gnome 或 Cinnamon 工作。它不需要手动工作,安装程序会为你做所有事情。 +这个小型 Python 脚本会自动下载并将桌面壁纸更改为当天的必应照片。该脚本在机器启动时自动运行,并工作于 GNU/Linux 上的 Gnome 或 Cinnamon 环境。它不需要手动工作,安装程序会为你做所有事情。 -从 2.0+ 版本开始,安装程序就像普通的 Linux 二进制命令一样工作,它会为某些任务请求 sudo 权限。 +从 2.0+ 版本开始,该脚本的安装程序就可以像普通的 Linux 二进制命令一样工作,它会为某些任务请求 sudo 权限。 只需克隆仓库并切换到项目目录,然后运行 shell 脚本即可安装必应桌面墙纸更换器。 - $ https://github.com/UtkarshGpta/bing-desktop-wallpaper-changer/archive/master.zip - $ unzip master - $ cd bing-desktop-wallpaper-changer-master +``` +$ https://github.com/UtkarshGpta/bing-desktop-wallpaper-changer/archive/master.zip +$ unzip master +$ cd bing-desktop-wallpaper-changer-master +``` 运行 `installer.sh` 使用 `--install` 选项来安装必应桌面墙纸更换器。它会下载并设置必应照片为你的 Linux 桌面。 - $ ./installer.sh --install +``` +$ ./installer.sh --install - Bing-Desktop-Wallpaper-Changer - BDWC Installer v3_beta2 - - GitHub: - Contributors: - . - . - [sudo] password for daygeek: ** - - ****** - - ** - . - Where do you want to install Bing-Desktop-Wallpaper-Changer? - Entering 'opt' or leaving input blank will install in /opt/bing-desktop-wallpaper-changer - Entering 'home' will install in /home/daygeek/bing-desktop-wallpaper-changer - Install Bing-Desktop-Wallpaper-Changer in (opt/home)? : ** - - Press Enter - - ** - - Should we create bing-desktop-wallpaper-changer symlink to /usr/bin/bingwallpaper so you could easily execute it? - Create symlink for easy execution, e.g. in Terminal (y/n)? : ** - - y - - ** - - Should bing-desktop-wallpaper-changer needs to autostart when you log in? (Add in Startup Application) - Add in Startup Application (y/n)? : ** - - y - - ** - . - . - Executing bing-desktop-wallpaper-changer... - - - Finished!! +Bing-Desktop-Wallpaper-Changer +BDWC Installer v3_beta2 -[![][2]![][2]][3] +GitHub: +Contributors: +. +. +[sudo] password for daygeek: ****** +. +Where do you want to install Bing-Desktop-Wallpaper-Changer? + Entering 'opt' or leaving input blank will install in /opt/bing-desktop-wallpaper-changer + Entering 'home' will install in /home/daygeek/bing-desktop-wallpaper-changer + Install Bing-Desktop-Wallpaper-Changer in (opt/home)? :Press Enter -卸载脚本 +Should we create bing-desktop-wallpaper-changer symlink to /usr/bin/bingwallpaper so you could easily execute it? + Create symlink for easy execution, e.g. in Terminal (y/n)? : y - $ ./installer.sh --uninstall +Should bing-desktop-wallpaper-changer needs to autostart when you log in? (Add in Startup Application) + Add in Startup Application (y/n)? : y +. +. +Executing bing-desktop-wallpaper-changer... + + +Finished!! +``` + +![][3] + +要卸载该脚本: + +``` +$ ./installer.sh --uninstall +``` 使用帮助页面了解更多关于此脚本的选项。 - $ ./installer.sh --help +``` +$ ./installer.sh --help +``` ### 方法 2: 使用 GNOME Shell 扩展 -轻量级[GNOME shell 扩展][4],可将你的壁纸每天更改为微软必应的壁纸。它还会显示一个包含图像标题和解释的通知。 +这个轻量级 [GNOME shell 扩展][4],可将你的壁纸每天更改为微软必应的壁纸。它还会显示一个包含图像标题和解释的通知。 -该扩展广泛地基于 Elinvention 的 NASA APOD 扩展,受到了 Utkarsh Gupta 的 Bing Desktop WallpaperChanger 启发。 +该扩展大部分基于 Elinvention 的 NASA APOD 扩展,受到了 Utkarsh Gupta 的 Bing Desktop WallpaperChanger 启发。 -### 特点 +#### 特点 -- 获取当天的必应壁纸并设置为锁屏和桌面墙纸(这两者都是用户可选的) -- 可强制选择某个特定区域(即地区) -- 在多个监视器设置中自动选择最高分辨率(和最合适的墙纸) -- 可以选择在1到7天之后清理墙纸目录(删除最旧的) -- 只有当他们被更新时,才会尝试下载壁纸 -- 不会持续进行更新 - 每天只进行一次,启动时也要进行一次(更新是在必应更新时进行的) +- 获取当天的必应壁纸并设置为锁屏和桌面墙纸(这两者都是用户可选的) +- 可强制选择某个特定区域(即地区) +- 为多个显示器自动选择最高分辨率(和最合适的墙纸) +- 可以选择在 1 到 7 天之后清理墙纸目录(删除最旧的) +- 只有当它们被更新时,才会尝试下载壁纸 +- 不会持续进行更新 - 每天只进行一次,启动时也要进行一次(更新是在必应更新时进行的) -### 如何安装 +#### 如何安装 -访问 [extenisons.gnome.org][5]网站并将切换按钮拖到 `ON`,然后点击 `Install` 按钮安装必应壁纸 GNOME 扩展。(译者注:页面上并没有发现 ON 按钮,但是有 Download 按钮) -[![][2]![][2]][6] +访问 [extenisons.gnome.org][5] 网站并将切换按钮拖到 “ON”,然后点击 “Install” 按钮安装必应壁纸 GNOME 扩展。(LCTT 译注:页面上并没有发现 ON 按钮,但是有 Download 按钮) + +![][6] 安装必应壁纸 GNOME 扩展后,它会自动下载并为你的 Linux 桌面设置当天的必应照片,并显示关于壁纸的通知。 -[![][2]![][2]][7] + +![][7] 托盘指示器将帮助你执行少量操作,也可以打开设置。 -[![][2]![][2]][8] + +![][8] 根据你的要求自定义设置。 -[![][2]![][2]][9] + +![][9] -------------------------------------------------------------------------------- -via: [https://www.2daygeek.com/bing-desktop-wallpaper-changer-linux-bing-photo-of-the-day/](https://www.2daygeek.com/bing-desktop-wallpaper-changer-linux-bing-photo-of-the-day/) +via: https://www.2daygeek.com/bing-desktop-wallpaper-changer-linux-bing-photo-of-the-day/ -作者:[2daygeek](https://www.2daygeek.com/author/2daygeek/) 译者:[MjSeven](https://github.com/MjSeven) 校对:[校对者 ID](a) +作者:[2daygeek][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 418ccdbdc56e72a3d3191d691763c8e61b6d0e04 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 28 Feb 2018 23:19:09 +0800 Subject: [PATCH 044/101] PUB: 20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md @MjSeven https://linux.cn/article-9395-1.html --- ...asy Ways To Install Bing Desktop Wallpaper Changer On Linux.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md (100%) diff --git a/translated/tech/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md b/published/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md similarity index 100% rename from translated/tech/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md rename to published/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md From 845af437c3d32a2cb2127c71105b87a7f1b385d3 Mon Sep 17 00:00:00 2001 From: geekpi Date: Thu, 1 Mar 2018 08:37:22 +0800 Subject: [PATCH 045/101] translated --- ...C for Meltdown or Spectre Vulnerability.md | 64 ------------------- ...C for Meltdown or Spectre Vulnerability.md | 62 ++++++++++++++++++ 2 files changed, 62 insertions(+), 64 deletions(-) delete mode 100644 sources/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md create mode 100644 translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md diff --git a/sources/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md b/sources/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md deleted file mode 100644 index 1828625b63..0000000000 --- a/sources/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md +++ /dev/null @@ -1,64 +0,0 @@ -translating---geekpi - -How to Check Your Linux PC for Meltdown or Spectre Vulnerability -====== - -![](https://www.maketecheasier.com/assets/uploads/2018/01/lmc-feat.jpg) - -One of the scariest realities of the Meltdown and Spectre vulnerabilities is just how widespread they are. Virtually every modern computer is affected in some way. The real question is how exactly are _you_ affected? Every system is at a different state of vulnerability depending on which software has and hasn’t been patched. - -Since Meltdown and Spectre are both fairly new and things are moving quickly, it’s not all that easy to tell what you need to look out for or what’s been fixed on your system. There are a couple of tools available that can help. They’re not perfect, but they can help you figure out what you need to know. - -### Simple Test - -One of the top Linux kernel developers provided a simple way of checking the status of your system in regards to the Meltdown and Spectre vulnerabilities. This one is the easiest, and is most concise, but it doesn’t work on every system. Some distributions decided not to include support for this report. Even still, it’s worth a shot to check. -``` -grep . /sys/devices/system/cpu/vulnerabilities/* - -``` - -![Kernel Vulnerability Check][1] - -You should see output similar to the image above. Chances are, you’ll see that at least one of the vulnerabilities remains unchecked on your system. This is especially true since Linux hasn’t made any progress in mitigating Spectre v1 yet. - -### The Script - -If the above method didn’t work for you, or you want a more detailed report of your system, a developer has created a shell script that will check your system to see what exactly it is susceptible to and what has been done to mitigate Meltdown and Spectre. - -In order to get the script, make sure you have Git installed on your system, and then clone the script’s repository into a directory that you don’t mind running it out of. -``` -cd ~/Downloads -git clone https://github.com/speed47/spectre-meltdown-checker.git - -``` - -It’s not a large repository, so it should only take a few seconds to clone. When it’s done, enter the newly created directory and run the provided script. -``` -cd spectre-meltdown-checker -./spectre-meltdown-checker.sh - -``` - -You’ll see a bunch of junk spit out into the terminal. Don’t worry, its not too hard to follow. First, the script checks your hardware, and then it runs through the three vulnerabilities: Spectre v1, Spectre v2, and Meltdown. Each gets its own section. In between, the script tells you plainly whether you are vulnerable to each of the three. - -![Meltdown Spectre Check Script Ubuntu][2] - -Each section provides you with a breakdown of potential mitigation and whether or not they have been applied. Here’s where you need to exercise a bit of common sense. The determinations that it gives might seem like they’re in conflict. Do a bit of digging to see if the fixes that it says are applied actually do fully mitigate the problem or not. - -### What This Means - -So, what’s the takeaway? Most Linux systems have been patched against Meltdown. If you haven’t updated yet for that, you should. Spectre v1 is still a big problem, and not a lot of progress has been made there as of yet. Spectre v2 will depend a lot on your distribution and what patches it’s chosen to apply. Regardless of what either tool says, nothing is perfect. Do your research and stay on the lookout for information coming straight from the kernel and distribution developers. - --------------------------------------------------------------------------------- - -via: https://www.maketecheasier.com/check-linux-meltdown-spectre-vulnerability/ - -作者:[Nick Congleton][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.maketecheasier.com/author/nickcongleton/ -[1]:https://www.maketecheasier.com/assets/uploads/2018/01/lmc-kernel-check.jpg (Kernel Vulnerability Check) -[2]:https://www.maketecheasier.com/assets/uploads/2018/01/lmc-script.jpg (Meltdown Spectre Check Script Ubuntu) diff --git a/translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md b/translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md new file mode 100644 index 0000000000..069058b917 --- /dev/null +++ b/translated/tech/20180201 How to Check Your Linux PC for Meltdown or Spectre Vulnerability.md @@ -0,0 +1,62 @@ +如何检查你的 Linux PC 是否存在 Meltdown 或者 Spectre 漏洞 +====== + +![](https://www.maketecheasier.com/assets/uploads/2018/01/lmc-feat.jpg) + +Meltdown 和 Specter 漏洞的最恐怖的现实之一是它们涉及非常广泛。几乎每台现代计算机都会受到一些影响。真正的问题是_你_是否受到了影响?每个系统都处于不同的脆弱状态,具体取决于已经或者还没有打补丁的软件。 + +由于 Meltdown 和 Spectre 都是相当新的,并且事情正在迅速发展,所以告诉你需要注意什么或在系统上修复了什么并非易事。有一些工具可以提供帮助。它们并不完美,但它们可以帮助你找出你需要知道的东西。 + +### 简单测试 + +顶级的 Linux 内核开发人员之一提供了一种简单的方式来检查系统在 Meltdown 和 Specter 漏洞方面的状态。它是简单的,也是最简洁的,但它不适用于每个系统。有些发行版不支持它。即使如此,也值得一试。 +``` +grep . /sys/devices/system/cpu/vulnerabilities/* + +``` + +![Kernel Vulnerability Check][1] + +你应该看到与上面截图类似的输出。很有可能你会发现系统中至少有一个漏洞还存在。这的确是真的,因为 Linux 在减轻 Specter v1 影响方面还没有取得任何进展。 + +### 脚本 + +如果上面的方法不适合你,或者你希望看到更详细的系统报告,一位开发人员已创建了一个 shell 脚本,它将检查你的系统来查看系统收到什么漏洞影响,还有做了什么来减轻 Meltdown 和 Spectre 的影响。 + +要得到脚本,请确保你的系统上安装了 Git,然后将脚本仓库克隆到一个你不介意运行它的目录中。 +``` +cd ~/Downloads +git clone https://github.com/speed47/spectre-meltdown-checker.git + +``` + +这不是一个大型仓库,所以它应该只需要几秒钟就克隆完成。完成后,输入新创建的目录并运行提供的脚本。 +``` +cd spectre-meltdown-checker +./spectre-meltdown-checker.sh + +``` + +你会在中断看到很多输出。别担心,它不是太难查看。首先,脚本检查你的硬件,然后运行三个漏洞:Specter v1、Spectre v2 和 Meltdown。每个漏洞都有自己的部分。在这之间,脚本明确地告诉你是否受到这三个漏洞的影响。 + +![Meltdown Spectre Check Script Ubuntu][2] + +每个部分为你提供潜在的可用的缓解方案,以及它们是否已被应用。这里需要你的一点常识。它给出的决定可能看起来有冲突。研究一下,看看它所说的修复是否实际上完全缓解了这个问题。 + +### 这意味着什么 + +所以,要点是什么?大多数 Linux 系统已经针对 Meltdown 进行了修补。如果你还没有更新,你应该更新一下。 Specter v1 仍然是一个大问题,到目前为止还没有取得很大进展。Spectre v2 将取决于你的发行版以及它选择应用的补丁。无论哪种工具都说,没有什么是完美的。做好研究并留意直接来自内核和发行版开发者的信息。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/check-linux-meltdown-spectre-vulnerability/ + +作者:[Nick Congleton][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.maketecheasier.com/author/nickcongleton/ +[1]:https://www.maketecheasier.com/assets/uploads/2018/01/lmc-kernel-check.jpg (Kernel Vulnerability Check) +[2]:https://www.maketecheasier.com/assets/uploads/2018/01/lmc-script.jpg (Meltdown Spectre Check Script Ubuntu) From 21253ea5f38c50a7695cebd434f7b7bfaf6e3b6f Mon Sep 17 00:00:00 2001 From: geekpi Date: Thu, 1 Mar 2018 08:40:43 +0800 Subject: [PATCH 046/101] translating --- ...e login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md b/sources/tech/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md index 485be46ab7..4909271a4f 100644 --- a/sources/tech/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md +++ b/sources/tech/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md @@ -1,3 +1,5 @@ +translating---geekpi + How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora) ====== Learn how to create login banners in Linux to display different warning or information messages to user who is about to log in or after he logs in. From 5682afbdad76edf8a70587dc1fdc90c26903ce69 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 11:16:09 +0800 Subject: [PATCH 047/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Why=20Python=20de?= =?UTF-8?q?vs=20should=20use=20Pipenv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...80228 Why Python devs should use Pipenv.md | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 sources/tech/20180228 Why Python devs should use Pipenv.md diff --git a/sources/tech/20180228 Why Python devs should use Pipenv.md b/sources/tech/20180228 Why Python devs should use Pipenv.md new file mode 100644 index 0000000000..0928aba316 --- /dev/null +++ b/sources/tech/20180228 Why Python devs should use Pipenv.md @@ -0,0 +1,133 @@ +Why Python devs should use Pipenv +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd) + +This article was co-written with [Jeff Triplett][1]. + +Pipenv, the "Python Development Workflow for Humans" created by Kenneth Reitz a little more than a year ago, has become the [official Python-recommended resource][2] for managing package dependencies. But there is still confusion about what problems it solves and how it's more useful than the standard workflow using `pip` and a `requirements.txt` file. In this month's Python column, we'll fill in the gaps. + +### A brief history of Python package installation + +To understand the problems that Pipenv solves, it's useful to show how Python package management has evolved. + +Take yourself back to the first Python iteration. We had Python, but there was no clean way to install packages. + +Then came [Easy Install][3], a package that installs other Python packages with relative ease. But it came with a catch: it wasn't easy to uninstall packages that were no longer needed. + +Enter [pip][4], which most Python users are familiar with. `pip` lets us install and uninstall packages. We could specify versions, run `pip freeze > requirements.txt` to output a list of installed packages to a text file, and use that same text file to install everything an app needed with `pip install -r requirements.txt`. + +But `pip` didn't include a way to isolate packages from each other. We might work on apps that use different versions of the same libraries, so we needed a way to enable that. Along came [virtual environments][5], which enabled us to create small, isolated environments for each app we worked on. We've seen many tools for managing virtual environments: [virtualenv][6], [venv][7], [virtualenvwrapper][8], [pyenv][9], [pyenv-virtualenv][10], [pyenv-virtualenvwrapper][11], and even more. They all play well with `pip` and `requirements.txt` files. + +### The new kid: Pipenv + +Pipenv aims to solve several problems. + +`pip` library for package installation, plus a library for creating a virtual environment, plus a library for managing virtual environments, plus all the commands associated with those libraries. That's a lot to manage. Pipenv ships with package management and virtual environment support, so you can use one tool to install, uninstall, track, and document your dependencies and to create, use, and organize your virtual environments. When you start a project with it, Pipenv will automatically create a virtual environment for that project if you aren't already using one. + +First, the problem of needing thelibrary for package installation, plus a library for creating a virtual environment, plus a library for managing virtual environments, plus all the commands associated with those libraries. That's a lot to manage. Pipenv ships with package management and virtual environment support, so you can use one tool to install, uninstall, track, and document your dependencies and to create, use, and organize your virtual environments. When you start a project with it, Pipenv will automatically create a virtual environment for that project if you aren't already using one. + +Pipenv accomplishes this dependency management by abandoning the `requirements.txt` norm and trading it for a new document called a [Pipfile][12]. When you install a library with Pipenv, a `Pipfile` for your project is automatically updated with the details of that installation, including version information and possibly the Git repository location, file path, and other information. + +Second, Pipenv wants to make it easier to manage complex interdependencies. Your app might depend on a specific version of a library, and that library might depend on a specific version of another library, and it's just dependencies and turtles all the way down. When two libraries your app uses have conflicting dependencies, your life can become hard. Pipenv wants to ease that pain by keeping track of a tree of your app's interdependencies in a file called `Pipfile.lock`. `Pipfile.lock` also verifies that the right versions of dependencies are used in production. + +Also, Pipenv is handy when multiple developers are working on a project. With a `pip` workflow, Casey might install a library and spend two days implementing a new feature using that library. When Casey commits the changes, they might forget to run `pip freeze` to update the requirements file. The next day, Jamie pulls down Casey's changes, and suddenly tests are failing. It takes time to realize that the problem is libraries missing from the requirements file that Jamie doesn't have installed in the virtual environment. + +Because Pipenv auto-documents dependencies as you install them, if Jamie and Casey had been using Pipenv, the `Pipfile` would have been automatically updated and included in Casey's commit. Jamie and Casey would have saved time and shipped their product faster. + +Finally, using Pipenv signals to other people who work on your project that it ships with a standardized way to install project dependencies and development and testing requirements. Using a workflow with `pip` and requirements files means that you may have one single `requirements.txt` file, or several requirements files for different environments. It might not be clear to your colleagues whether they should run `dev.txt` or `local.txt` when they're running the project on their laptops, for example. It can also create confusion when two similar requirements files get wildly out of sync with each other: Is `local.txt` out of date, or is it really supposed to be that different from `dev.txt`? Multiple requirements files require more context and documentation to enable others to install the dependencies properly and as expected. This workflow has the potential to confuse colleagues and increase your maintenance burden. + +Using Pipenv, which gives you `Pipfile`, lets you avoid these problems by managing dependencies for different environments for you. This command will install the main project dependencies: +``` +pipenv install + +``` + +Adding the `--dev` tag will install the dev/testing requirements: +``` +pipenv install --dev + +``` + +There are other benefits to using Pipenv: It has better security features, graphs your dependencies in an easier-to-understand format, seamlessly handles `.env` files, and can automatically handle differing dependencies for development versus production environments in one file. You can read more in the [documentation][13]. + +### Pipenv in action + +The basics of using Pipenv are detailed in the [Managing Application Dependencies][14] section of the official Python packaging tutorial. To install Pipenv, use `pip`: +``` +pip install pipenv + +``` + +To install packages to use in your project, change into the directory for your project. Then to install a package (we'll use Django as an example), run: +``` +pipenv install django + +``` + +You will see some output that indicates that Pipenv is creating a `Pipfile` for your project. + +If you aren't already using a virtual environment, you will also see some output from Pipenv saying it is creating a virtual environment for you. + +Then, you will see the output you are used to seeing when you install packages. + +To generate a `Pipfile.lock` file, run: +``` +pipenv lock + +``` + +You can also run Python scripts with Pipenv. To run a top-level Python script called `hello.py`, run: +``` +pipenv run python hello.py + +``` + +And you will see your expected result in the console. + +To start a shell, run: +``` +pipenv shell + +``` + +If you would like to convert a project that currently uses a `requirements.txt` file to use Pipenv, install Pipenv and run: +``` +pipenv install requirements.txt + +``` + +This will create a Pipfile and install the specified requirements. Consider your project upgraded! + +### Learn more + +Check out the Pipenv documentation, particularly [Basic Usage of Pipenv][15], to take you further. Pipenv creator Kenneth Reitz gave a talk on Pipenv, "[The Future of Python Dependency Management][16]," at a recent PyTennessee event. The talk wasn't recorded, but his [slides][17] are helpful in understanding what Pipenv does and the problems it solves. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/why-python-devs-should-use-pipenv + +作者:[Lacey Williams Henschel][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/laceynwilliams +[1]:https://opensource.com/users/jefftriplett +[2]:https://packaging.python.org/tutorials/managing-dependencies/#managing-dependencies +[3]:http://peak.telecommunity.com/DevCenter/EasyInstall +[4]:https://packaging.python.org/tutorials/installing-packages/#use-pip-for-installing +[5]:https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments +[6]:https://virtualenv.pypa.io/en/stable/ +[7]:https://docs.python.org/3/library/venv.html +[8]:https://virtualenvwrapper.readthedocs.io/en/latest/ +[9]:https://github.com/pyenv/pyenv +[10]:https://github.com/pyenv/pyenv-virtualenv +[11]:https://github.com/pyenv/pyenv-virtualenvwrapper +[12]:https://github.com/pypa/pipfile +[13]:https://docs.pipenv.org/ +[14]:https://packaging.python.org/tutorials/managing-dependencies/ +[15]:https://docs.pipenv.org/basics/ +[16]:https://www.pytennessee.org/schedule/presentation/158/ +[17]:https://speakerdeck.com/kennethreitz/the-future-of-python-dependency-management From 52007a9d543fdce00c419a0d5d54e1f8be96a60f Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 11:18:28 +0800 Subject: [PATCH 048/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20block?= =?UTF-8?q?=20local=20spoofed=20addresses=20using=20the=20Linux=20firewall?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ofed addresses using the Linux firewall.md | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 sources/tech/20180227 How to block local spoofed addresses using the Linux firewall.md diff --git a/sources/tech/20180227 How to block local spoofed addresses using the Linux firewall.md b/sources/tech/20180227 How to block local spoofed addresses using the Linux firewall.md new file mode 100644 index 0000000000..dcacec8e89 --- /dev/null +++ b/sources/tech/20180227 How to block local spoofed addresses using the Linux firewall.md @@ -0,0 +1,79 @@ +How to block local spoofed addresses using the Linux firewall +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_UnspokenBlockers_1110_A.png?itok=x8A9mqVA) + +Attackers are finding sophisticated ways to penetrate even remote networks that are protected by intrusion detection and prevention systems. No IDS/IPS can halt or minimize attacks by hackers who are determined to take over your network. Improper configuration allows attackers to bypass all implemented network security measures. + +In this article, I will explain how security engineers or system administrators can prevent these attacks. + +Almost all Linux distributions come with a built-in firewall to secure processes and applications running on the Linux host. Most firewalls are designed as IDS/IPS solutions, whose primary purpose is to detect and prevent malicious packets from gaining access to a network. + +A Linux firewall usually comes with two interfaces: iptables and ipchains. Most people refer to these interfaces as the "iptables firewall" or the "ipchains firewall." Both interfaces are designed as packet filters. Iptables acts as a stateful firewall, making decisions based on previous packets. Ipchains does not make decisions based on previous packets; hence, it is designed as a stateless firewall. + +In this article, we will focus on the iptables firewall, which comes with kernel version 2.4 and beyond. + +With the iptables firewall, you can create policies, or ordered sets of rules, which communicate to the kernel how it should treat specific classes of packets. Inside the kernel is the Netfilter framework. Netfilter is both a framework and the project name for the iptables firewall. As a framework, Netfilter allows iptables to hook functions designed to perform operations on packets. In a nutshell, iptables relies on the Netfilter framework to build firewall functionality such as filtering packet data. + +Each iptables rule is applied to a chain within a table. An iptables chain is a collection of rules that are compared against packets with similar characteristics, while a table (such as nat or mangle) describes diverse categories of functionality. For instance, a mangle table alters packet data. Thus, specialized rules that alter packet data are applied to it, and filtering rules are applied to the filter table because the filter table filters packet data. + +Iptables rules have a set of matches, along with a target, such as `Drop` or `Deny`, that instructs iptables what to do with a packet that conforms to the rule. Thus, without a target and a set of matches, iptables can’t effectively process packets. A target simply refers to a specific action to be taken if a packet matches a rule. Matches, on the other hand, must be met by every packet in order for iptables to process them. + +Now that we understand how the iptables firewall operates, let's look at how to use iptables firewall to detect and reject or drop spoofed addresses. + +### Turning on source address verification + +The first step I, as a security engineer, take when I deal with spoofed addresses from remote hosts is to turn on source address verification in the kernel. + +Source address verification is a kernel-level feature that drops packets pretending to come from your network. It uses the reverse path filter method to check whether the source of the received packet is reachable through the interface it came in. + +To turn source address verification, utilize the simple shell script below instead of doing it manually: +``` +#!/bin/sh + +#author’s name: Michael K Aboagye + +#purpose of program: to enable reverse path filtering + +#date: 7/02/18 + +#displays “enabling source address verification” on the screen + +echo -n "Enabling source address verification…" + +#Overwrites the value 0 to 1 to enable source address verification + +echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter + +echo "completed" + +``` + +The preceding script, when executed, displays the message `Enabling source address verification` without appending a new line. The default value of the reverse path filter is 0.0, which means no source validation. Thus, the second line simply overwrites the default value 0 to 1. 1 means that the kernel will validate the source by confirming the reverse path. + +Finally, you can use the following command to drop or reject spoofed addresses from remote hosts by choosing either one of these targets: `DROP` or `REJECT`. However, I recommend using `DROP` for security reasons. + +Replace the “IP-address” placeholder with your own IP address, as shown below. Also, you must choose to use either `REJECT` or `DROP`; the two targets don’t work together. +``` +   iptables -A INPUT -i internal_interface -s IP_address -j REJECT / DROP   + + + +    iptables -A INPUT -i internal_interface -s 192.168.0.0/16  -j REJECT/ DROP + +``` + +This article provides only the basics of how to prevent spoofing attacks from remote hosts using the iptables firewall. + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/block-local-spoofed-addresses-using-linux-firewall + +作者:[Michael Kwaku Aboagye][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/revoks From 298cb9f260f8bf459601038678d34115465c5246 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 11:38:21 +0800 Subject: [PATCH 049/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Emacs=20#1:=20Dit?= =?UTF-8?q?ching=20a=20bunch=20of=20stuff=20and=20moving=20to=20Emacs=20an?= =?UTF-8?q?d=20org-mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... stuff and moving to Emacs and org-mode.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 sources/talk/20180227 Emacs -1- Ditching a bunch of stuff and moving to Emacs and org-mode.md diff --git a/sources/talk/20180227 Emacs -1- Ditching a bunch of stuff and moving to Emacs and org-mode.md b/sources/talk/20180227 Emacs -1- Ditching a bunch of stuff and moving to Emacs and org-mode.md new file mode 100644 index 0000000000..501ba538b6 --- /dev/null +++ b/sources/talk/20180227 Emacs -1- Ditching a bunch of stuff and moving to Emacs and org-mode.md @@ -0,0 +1,73 @@ +Emacs #1: Ditching a bunch of stuff and moving to Emacs and org-mode +====== +I’ll admit it. After over a decade of vim, I’m hooked on [Emacs][1]. + +I’ve long had this frustration over how to organize things. I’ve followed approaches like [GTD][2] and [ZTD][3], but things like email or large files are really hard to organize. + +I had been using Asana for tasks, Evernote for notes, Thunderbird for email, a combination of ikiwiki and some other items for a personal knowledge base, and various files in an archive directory on my PC. When my new job added Slack to the mix, that was finally the last straw. + +A lot of todo-management tools integrate with email — poorly. When you want to do something like “remind me to reply to this in a week”, a lot of times that’s impossible because the tool doesn’t store the email in a fashion you can easily reply to. And that problem is even worse with Slack. + +It was right around then that I stumbled onto [Carsten Dominik’s Google Talk on org-mode][4]. Carsten was the author of org-mode, and although the talk is 10 years old, it is still highly relevant. + +I’d stumbled across [org-mode][5] before, but each time I didn’t really dig in because I had the reaction of “an outliner? But I need a todo list.” Turns out I was missing out. org-mode is all that. + +### Just what IS Emacs? And org-mode? + +Emacs grew up as a text editor. It still is, and that heritage is definitely present throughout. But to say Emacs is an editor would be rather unfair. + +Emacs is something more like a platform or a toolkit. Not only do you have source code to it, but the very configuration is a program, and there are hooks all over the place. It’s as if it was super easy to write a Firefox plugin. A couple lines, and boom, behavior changed. + +org-mode is very similar. Yes, it’s an outliner, but that’s not really what it is. It’s an information organization platform. Its website says “Your life in plain text: Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system.” + +### Capturing + +If you’ve ever read productivity guides based on GTD, one of the things they stress is effortless capture of items. The idea is that when something pops into your head, get it down into a trusted system quickly so you can get on with what you were doing. org-mode has a capture system for just this. I can press `C-c c` from anywhere in Emacs, and up pops a spot to type my note. But, critically, automatically embedded in that note is a link back to what I was doing when I pressed `C-c c`. If I was editing a file, it’ll have a link back to that file and the line I was on. If I was viewing an email, it’ll link back to that email (by Message-Id, no less, so it finds it in any folder). Same for participating in a chat, or even viewing another org-mode entry. + +So I can make a note that will remind me in a week to reply to a certain email, and when I click the link in that note, it’ll bring up the email in my mail reader — even if I subsequently archived it out of my inbox. + +YES, this is what I was looking for! + +### The tool suite + +Once you’re using org-mode, pretty soon you want to integrate everything with it. There are browser plugins for capturing things from the web. Multiple Emacs mail or news readers integrate with it. ERC (IRC client) does as well. So I found myself switching from Thunderbird and mairix+mutt (for the mail archives) to mu4e, and from xchat+slack to ERC. + +And wouldn’t you know it, I liked each of those Emacs-based tools **better** than the standalone they replaced. + +A small side tidbit: I’m using OfflineIMAP again! I even used it with GNUS way back when. + +### One Emacs process to rule them + +I used to use Emacs extensively, way back. Back then, Emacs was a “large” program. (Now my battery status applet literally uses more RAM than Emacs). There was this problem of startup time back then, so there was a way to connect to a running Emacs process. + +I like to spawn programs with Mod-p (an xmonad shortcut to a dzen menubar, but Alt-F2 in more traditional DEs would do the trick). It’s convenient to not run several emacsen with this setup, so you don’t run into issues with trying to capture to a file that’s open in another one. The solution is very simple: I created a script, named it `em`, and put it on my path. All it does is this: + +`#!/bin/bash exec emacsclient -c -a "" "$@"` + +It creates a new emacs process if one doesn’t already exist; otherwise, it uses what you’ve got. A bonus here: parameters such as `-nw` work just fine, so it really acts just as if you’d typed `emacs` at the shell prompt. It’s a suitable setting for `EDITOR`. + +### Up next… + +I’ll be talking about my use of, and showing off configurations for: + + * org-mode, including syncing between computers, capturing, agenda and todos, files, linking, keywords and tags, various exporting (slideshows), etc. + * mu4e for email, including multiple accounts, bbdb integration + * ERC for IRC and IM + + +-------------------------------------------------------------------------------- + +via: http://changelog.complete.org/archives/9861-emacs-1-ditching-a-bunch-of-stuff-and-moving-to-emacs-and-org-mode + +作者:[John Goerzen][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://changelog.complete.org/archives/author/jgoerzen +[1]:https://www.gnu.org/software/emacs/ +[2]:https://gettingthingsdone.com/ +[3]:https://zenhabits.net/zen-to-done-the-simple-productivity-e-book/ +[4]:https://www.youtube.com/watch?v=oJTwQvgfgMM +[5]:https://orgmode.org/ From 852194cbfe72fa6cb1404f75afbbf3746b321b17 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 11:46:19 +0800 Subject: [PATCH 050/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20'Getting=20to=20D?= =?UTF-8?q?one'=20on=20the=20Linux=20command=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ting to Done- on the Linux command line.md | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 sources/tech/20180226 -Getting to Done- on the Linux command line.md diff --git a/sources/tech/20180226 -Getting to Done- on the Linux command line.md b/sources/tech/20180226 -Getting to Done- on the Linux command line.md new file mode 100644 index 0000000000..c325a0d884 --- /dev/null +++ b/sources/tech/20180226 -Getting to Done- on the Linux command line.md @@ -0,0 +1,126 @@ +'Getting to Done' on the Linux command line +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_terminals.png?itok=CfBqYBah) +There is a lot of talk about getting things done at the command line. How many articles are there about using obscure flags with `ls`, nifty regular expressions with Sed and Awk, and how to parse out lots of text with Perl? That isn't what this is about. + +This is about [Getting _to_ Done][1], making sure that the stuff we have to do actually gets tracked and done using tools that don't require a graphical desktop, a web browser, or an internet connection. To do this, we'll look at four ways of tracking your to-do list: plaintext files, Todo.txt, TaskWarrior, and Org-mode. + +### Plain (and simple) text + + +![plaintext][3] + +I like to use Vim, but you can use Nano too. + +The most straightforward way to manage your to-do list is using a plaintext file in your editor of choice. Just open an empty file and add tasks, one per line. When you are done, delete the line. Simple, effective, and it doesn't matter what you use to do it. There are a couple of drawbacks to this method, though. Once you delete a line and save the file, it is gone forever. That can be a problem if you have to report on what you have done this week or last week. And while using a simple file is flexible, it can also get cluttered really easily. + +### Todo.txt: Plaintext leveled up + + +![todo.txt screen][5] + +Neat, organized, and easy to use + +That leads us to the [Todo.txt][6] file format and application. Installation is simple—[download][7] the latest release from GitHub and run `sudo make install` from the unpacked archive. + + +![Installing todo.txt][9] + +It works from a Git clone as well. + +Todo.txt makes it very easy to add tasks, list tasks, and mark them as done: + +| `todo.sh add "Some Task"` | add "Some Task" to my todo list | +| `todo.sh ls` | list all my tasks | +| `todo.sh ls due:2018-02-15` | list all tasks due on February 15, 2018 | +| `todo.sh do 3` | mark task number 3 as "done" | + +The actual list is still in plaintext, and you can edit it with your favorite text editor as long as you follow the [correct format][10]. + +There is also a very robust help built into the application. + + +![Syntax highlighting in todo.txt][12] + +You can even get syntax highlighting. + +There is also a large selection of add-ons, as well as specifications for writing your own. There are even browser extensions, mobile apps, and desktop apps that support the Todo.txt format. + + +![GNOME extensions in todo.txt][14] + +Even GNOME extensions. + +The biggest drawback to Todo.txt is the lack of an automatic or built-in synchronization mechanism. Most (if not all) of the browser extensions and mobile apps require Dropbox to perform synchronization between the app and the copy on your desktop. If you would like something with sync built-in, we have... + +### Taskwarrior: Now we're cooking with Python + +[Taskwarrior][15] is a Python application with many of the same features as Todo.txt. However, it stores the data in a database and has built-in synchronization capabilities. It also keeps track of what is next, notes how old tasks are, and will warn you if you have something more important to do than what you just did. + +[Installation][16] of Taskwarrior can be done either with your distribution's package manager, through Python's `pip` utility, or built from source. Using it is also pretty straightforward, with commands similar to Todo.txt: + +| `task add "Some Task"` | Add "Some Task" to the list | +| `task list` | List all tasks | +| `task list due ``:today` | List all tasks due on today's date | +| `task do 3` | Complete task number 3 | + +Taskwarrior also has some pretty nice text user interfaces. + +![Taskwarrior in Vit][18] + +I like Vit, which was inspired by Vim. + +Unlike Todo.txt, Taskwarrior can synchronize with a local or remote server. A very basic synchronization server called `taskd` is available if you wish to run your own, and there are several services available if you do not. + +Taskwarrior also has a thriving and extensive ecosystem of add-ons and extensions, as well as mobile and desktop apps. + +![Taskwarrior on GNOME][20] + +Taskwarrior looks really nice on GNOME. + +The only disadvantage to Taskwarrior is that, unlike the other programs listed here, you cannot directly modify the to-do list itself. You can export the task list to various formats, modify the export, and then re-import the files, but it is a lot clunkier than just opening the file directly in a text editor. + +Which brings us to the most powerful of them all... + +### Emacs Org-mode: Hulk smash tasks + +![Org-mode][22] + +Emacs has everything. + +Emacs [Org-mode][23] is by far the most powerful, most flexible open source to-do list manager out there. It supports multiple files, uses plaintext, is almost infinitely customizable, and understands calendars, due dates, and schedules. It is also significantly more complicated to set up than the other applications listed here. But once it is set up, it does everything the other applications do and more. If you are familiar with or a fan of [Bullet Journals][24], Org-mode is possibly the closest you can get on a computer. + +Org-mode will run anywhere Emacs runs, and there are a few mobile applications that can interact with it as well. Unfortunately, there are no desktop apps or browser extensions that support Org. Despite all that, Org-mode is still one of the best applications for tracking your to-do list, since it is so very powerful. + +### Choose your tool + +In the end, the goal of all these programs is to help you track what you need to do and make sure you don't forget to do something. While they all have the same basic functions, choosing which one is right for you depends on a lot of factors. Do you want synchronization built-in or not? Do you need a mobile app? Do any of the add-ons include a "must have" feature? Whatever your choice, remember that the program alone cannot make you more organized, but it can help. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/getting-to-done-agile-linux-command-line + +作者:[Kevin Sonney][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: +[1]:https://www.scruminc.com/getting-done/ +[3]:https://opensource.com/sites/default/files/u128651/plain-text.png (plaintext) +[5]:https://opensource.com/sites/default/files/u128651/todo-txt.png (todo.txt screen) +[6]:http://todotxt.org/ +[7]:https://github.com/todotxt/todo.txt-cli/releases +[9]:https://opensource.com/sites/default/files/u128651/todo-txt-install.png (Installing todo.txt) +[10]:https://github.com/todotxt/todo.txt +[12]:https://opensource.com/sites/default/files/u128651/todo-txt-vim.png (Syntax highlighting in todo.txt) +[14]:https://opensource.com/sites/default/files/u128651/tod-txt-gnome.png (GNOME extensions in todo.txt) +[15]:https://taskwarrior.org/ +[16]:https://taskwarrior.org/download/ +[18]:https://opensource.com/sites/default/files/u128651/taskwarrior-vit.png (Taskwarrior in Vit) +[20]:https://opensource.com/sites/default/files/u128651/taskwarrior-gnome.png (Taskwarrior on GNOME) +[22]:https://opensource.com/sites/default/files/u128651/emacs-org-mode.png (Org-mode) +[23]:https://orgmode.org/ +[24]:http://bulletjournal.com/ From e8df4da706db54b406d0844b001e080c77e06513 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 12:42:14 +0800 Subject: [PATCH 051/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=205=20keys=20to=20b?= =?UTF-8?q?uilding=20open=20hardware?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...180226 5 keys to building open hardware.md | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 sources/talk/20180226 5 keys to building open hardware.md diff --git a/sources/talk/20180226 5 keys to building open hardware.md b/sources/talk/20180226 5 keys to building open hardware.md new file mode 100644 index 0000000000..7819149996 --- /dev/null +++ b/sources/talk/20180226 5 keys to building open hardware.md @@ -0,0 +1,85 @@ +5 keys to building open hardware +====== +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openhardwaretools.png?itok=DC1RC_1f) + +The science community is increasingly embracing free and open source hardware ([FOSH][1]). Researchers have been busy [hacking their own equipment][2] and creating hundreds of devices based on the distributed digital manufacturing model to advance their scientific experiments. + +A major reason for all this interest in distributed digital manufacturing of scientific FOSH is money: Research indicates that FOSH [slashes costs by 90% to 99%][3] compared to proprietary tools. Commercializing scientific FOSH with [open hardware business models][4] has supported the rapid growth of an engineering subfield to develop FOSH for science, which comes together annually at the [Gathering for Open Science Hardware][5]. + +Remarkably, not one, but [two new academic journals][6] are devoted to the topic: the [Journal of Open Hardware][7] (from Ubiquity Press, a new open access publisher that also publishes the [Journal of Open Research Software][8] ) and [HardwareX][9] (an [open access journal][10] from Elsevier, one of the world's largest academic publishers). + +Because of the academic community's support, scientific FOSH developers can get academic credit while having fun designing open hardware and pushing science forward faster. + +### 5 steps for scientific FOSH + +Shane Oberloier and I co-authored a new [article][11] published in Designs, an open access engineering design journal, about the principles of designing FOSH scientific equipment. We used the example of a slide dryer, fabricated for under $20, which costs up to 300 times less than proprietary equivalents. [Scientific][1] and [medical][12] equipment tends to be complex with huge payoffs for developing FOSH alternatives. + +I've summarized the five steps (including six design principles) that Shane and I detail in our Designs article. These design principles can be generalized to non-scientific devices, although the more complex the design or equipment, the larger the potential savings. + +If you are interested in designing open hardware for scientific projects, these steps will maximize your project's impact. + + 1. Evaluate similar existing tools for their functions but base your FOSH design on replicating their physical effects, not pre-existing designs. If necessary, evaluate a proof of concept. + + + 2. Use the following design principles: + + + * Use only free and open source software toolchains (e.g., open source CAD packages such as [OpenSCAD][13], [FreeCAD][14], or [Blender][15]) and open hardware for device fabrication. + * Attempt to minimize the number and type of parts and the complexity of the tools. + * Minimize the amount of material and the cost of production. + * Maximize the use of components that can be distributed or digitally manufactured by using widespread and accessible tools such as the open source [RepRap 3D printer][16]. + * Create [parametric designs][17] with predesigned components, which enable others to customize your design. By making parametric designs rather than solving a specific case, all future cases can also be solved while enabling future users to alter the core variables to make the device useful for them. + * All components that are not easily and economically fabricated with existing open hardware equipment in a distributed fashion should be chosen from off-the-shelf parts that are readily available throughout the world. + + + 3. Validate the design for the targeted function(s). + + + 4. Meticulously document the design, manufacture, assembly, calibration, and operation of the device. This should include the raw source of the design, not just the files used for production. The Open Source Hardware Association has extensive [guidelines][18] for properly documenting and releasing open source designs, which can be summarized as follows: + + + * Share design files in a universal type. + * Include a fully detailed bill of materials, including prices and sourcing information. + * If software is involved, make sure the code is clear and understandable to the general public. + * Include many photos so that nothing is obscured, and they can be used as a reference while manufacturing. + * In the methods section, the entire manufacturing process must be detailed to act as instructions for users to replicate the design. + * Share online and specify a license. This gives users information on what constitutes fair use of the design. + + + 5. Share aggressively! For FOSH to proliferate, designs must be shared widely, frequently, and noticeably to raise awareness of their existence. All documentation should be published in the open access literature and shared with appropriate communities. One nice universal repository to consider is the [Open Science Framework][19], hosted by the Center for Open Science, which is set up to take any type of file and handle large datasets. + + + +This article was supported by [Fulbright Finland][20], which is sponsoring Joshua Pearce's research in open source scientific hardware in Finland as the Fulbright-Aalto University Distinguished Chair. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/5-steps-creating-successful-open-hardware + +作者:[Joshua Pearce][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jmpearce +[1]:https://opensource.com/business/16/4/how-calculate-open-source-hardware-return-investment +[2]:https://opensource.com/node/16840 +[3]:http://www.appropedia.org/Open-source_Lab +[4]:https://www.academia.edu/32004903/Emerging_Business_Models_for_Open_Source_Hardware +[5]:http://openhardware.science/ +[6]:https://opensource.com/life/16/7/hardwarex-open-access-journal +[7]:https://openhardware.metajnl.com/ +[8]:https://openresearchsoftware.metajnl.com/ +[9]:https://www.journals.elsevier.com/hardwarex +[10]:https://opensource.com/node/30041 +[11]:https://www.academia.edu/35603319/General_Design_Procedure_for_Free_and_Open-Source_Hardware_for_Scientific_Equipment +[12]:https://www.academia.edu/35382852/Maximizing_Returns_for_Public_Funding_of_Medical_Research_with_Open_source_Hardware +[13]:http://www.openscad.org/ +[14]:https://www.freecadweb.org/ +[15]:https://www.blender.org/ +[16]:http://reprap.org/ +[17]:https://en.wikipedia.org/wiki/Parametric_design +[18]:https://www.oshwa.org/sharing-best-practices/ +[19]:https://osf.io/ +[20]:http://www.fulbright.fi/en From d9ebfdaa6ef0d6349f89672698abb6066d2eead0 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Thu, 1 Mar 2018 12:42:53 +0800 Subject: [PATCH 052/101] Translated by qhwdw --- ...hat-s next in DevOps- 5 trends to watch.md | 89 ------------------- ...hat-s next in DevOps- 5 trends to watch.md | 88 ++++++++++++++++++ 2 files changed, 88 insertions(+), 89 deletions(-) delete mode 100644 sources/tech/20171009 What-s next in DevOps- 5 trends to watch.md create mode 100644 translated/tech/20171009 What-s next in DevOps- 5 trends to watch.md diff --git a/sources/tech/20171009 What-s next in DevOps- 5 trends to watch.md b/sources/tech/20171009 What-s next in DevOps- 5 trends to watch.md deleted file mode 100644 index be07522161..0000000000 --- a/sources/tech/20171009 What-s next in DevOps- 5 trends to watch.md +++ /dev/null @@ -1,89 +0,0 @@ -Translating by qhwdw -What’s next in DevOps: 5 trends to watch -====== - -![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/CIO%20Magnifying%20Glass%20Code.png?itok=IqZsJCEH) - -The term "DevOps" is typically credited [to this 2008 presentation][1] on agile infrastructure and operations. Now ubiquitous in IT vocabulary, the mashup word is less than 10 years old: We're still figuring out this modern way of working in IT. - -Sure, people who have been "doing DevOps" for years have accrued plenty of wisdom along the way. But most DevOps environments - and the mix of people and [culture][2], process and methodology, and tools and technology - are far from mature. - -More change is coming. That's kind of the whole point. "DevOps is a process, an algorithm," says Robert Reeves, CTO at [Datical][3]. "Its entire purpose is to change and evolve over time." - -What should we expect next? Here are some key trends to watch, according to DevOps experts. - -### 1. Expect increasing interdependence between DevOps, containers, and microservices - -The forces driving the proliferation of DevOps culture themselves may evolve. Sure, DevOps will still fundamentally knock down traditional IT silos and bottlenecks, but the reasons for doing so may become more urgent. Exhibits A & B: Growing interest in and [adoption of containers and microservices][4]. The technologies pack a powerful, scalable one-two punch, best paired with planned, [ongoing management][5]. - -"One of the major factors impacting DevOps is the shift towards microservices," says Arvind Soni, VP of product at [Netsil][6], adding that containers and orchestration are enabling developers to package and deliver services at an ever-increasing pace. DevOps teams will likely be tasked with helping to fuel that pace and to manage the ongoing complexity of a scalable microservices architecture. - -### 2. Expect fewer safety nets - -DevOps enables teams to build software with greater speed and agility, deploying faster and more frequently, while improving quality and stability. But good IT leaders don't typically ignore risk management, so plenty of early DevOps iterations began with safeguards and fallback positions in place. To get to the next level of speed and agility, more teams will take off their training wheels. - -"As teams mature, they may decide that some of the guard rails that were added early on may not be required anymore," says Nic Grange, CTO of [Retriever Communications][7]. Grange gives the example of a staging server: As DevOps teams mature, they may decide it's no longer necessary, especially if they're rarely catching issues in that pre-production environment. (Grange points out that this move isn't advisable for inexperienced teams.) - -"The team may be at a point where it is confident enough with its monitoring and ability to identify and resolve issues in production," Grange says. "The process of deploying and testing in staging may just be slowing them down without any demonstrable value." - -### 3. Expect DevOps to spread elsewhere - -DevOps brings two traditional IT groups, development and operations, into much closer alignment. As more companies see the benefits in the trenches, the culture is likely to spread. It's already happening in some organizations, evident in the increasing appearance of the term "DevSecOps," which reflects the intentional and much earlier inclusion of security in the software development lifecycle. - -"DevSecOps is not only tools, it is integrating a security mindset into development practices early on," says Derek Weeks, VP and DevOps advocate at [Sonatype][8]. - -Doing that isn't a technology challenge, it's a cultural challenge, says [Red Hat][9] security strategist Kirsten Newcomer. - -"Security teams have historically been isolated from development teams - and each team has developed deep expertise in different areas of IT," Newcomer says. "It doesn't need to be this way. Enterprises that care deeply about security and also care deeply about their ability to quickly deliver business value through software are finding ways to move security left in their application development lifecycles. They're adopting DevSecOps by integrating security practices, tooling, and automation throughout the CI/CD pipeline. To do this well, they're integrating their teams - security professionals are embedded with application development teams from inception (design) through to production deployment. Both sides are seeing the value - each team expands their skill sets and knowledge base, making them more valuable technologists. DevOps done right - or DevSecOps - improves IT security." - -Beyond security, look for DevOps expansion into areas such as database teams, QA, and even potentially outside of IT altogether. - -"This is a very DevOps thing to do: Identify areas of friction and resolve them," Datical's Reeves says. "Security and databases are currently the big bottlenecks for companies that have previously adopted DevOps." - -### 4. Expect ROI to increase - -As companies get deeper into their DevOps work, IT teams will be able to show greater return on investment in methodologies, processes, containers, and microservices, says Eric Schabell, global technology evangelist director, Red Hat. "The Holy Grail was to be moving faster, accomplishing more and becoming flexible. As these components find broader adoption and organizations become more vested in their application the results shall appear," Schabell says. - -"Everything has a learning curve with a peak of excitement as the emerging technologies gain our attention, but also go through a trough of disillusionment when the realization hits that applying it all is hard. Finally, we'll start to see a climb out of the trough and reap the benefits that we've been chasing with DevOps, containers, and microservices." - -### 5. Expect success metrics to keep evolving - -"I believe that two of the core tenets of the DevOps culture, automation and measurement, are never 'done,'" says Mike Kail, CTO at [CYBRIC][10] and former CIO at Yahoo. "There will always be opportunities to automate a task or improve upon an already automated solution, and what is important to measure will likely change and expand over time. This maturation process is a continuous journey, not a destination or completed task." - -In the spirit of DevOps, that maturation and learning will also depend on collaboration and sharing. Kail thinks it's still very much early days for Agile methodologies and DevOps culture, and that means plenty of room for growth. - -"As more mature organizations continue to measure actionable metrics, I believe - [I] hope - that those learnings will be broadly shared so we can all learn and improve from them," Kail says. - -As Red Hat technology evangelist [Gordon Haff][11] recently noted, organizations working hard to improve their DevOps metrics are using factors tied to business outcomes. "You probably don't really care about how many lines of code your developers write, whether a server had a hardware failure overnight, or how comprehensive your test coverage is," [writes Haff][12]. "In fact, you may not even directly care about the responsiveness of your website or the rapidity of your updates. But you do care to the degree such metrics can be correlated with customers abandoning shopping carts or leaving for a competitor." - -Some examples of DevOps metrics tied to business outcomes include customer ticket volume (as an indicator of overall customer satisfaction) and Net Promoter Score (the willingness of customers to recommend a company's products or services). For more on this topic, see his full article, [DevOps metrics: Are you measuring what matters? ][12] - -### No rest for the speedy - -By the way, if you were hoping things would get a little more leisurely anytime soon, you're out of luck. - -"If you think releases are fast today, you ain't seen nothing yet," Reeves says. "That's why bringing all stakeholders, including security and database teams, into the DevOps tent is so crucial. The friction caused by these two groups today will only grow as releases increase exponentially." - --------------------------------------------------------------------------------- - -via: https://enterprisersproject.com/article/2017/10/what-s-next-devops-5-trends-watch - -作者:[Kevin Casey][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://enterprisersproject.com/user/kevin-casey -[1]:http://www.jedi.be/presentations/agile-infrastructure-agile-2008.pdf -[2]:https://enterprisersproject.com/article/2017/9/5-ways-nurture-devops-culture -[3]:https://www.datical.com/ -[4]:https://enterprisersproject.com/article/2017/9/microservices-and-containers-6-things-know-start-time -[5]:https://enterprisersproject.com/article/2017/10/microservices-and-containers-6-management-tips-long-haul -[6]:https://netsil.com/ -[7]:http://retrievercommunications.com/ -[8]:https://www.sonatype.com/ -[9]:https://www.redhat.com/en/ -[10]:https://www.cybric.io/ -[11]:https://enterprisersproject.com/user/gordon-haff -[12]:https://enterprisersproject.com/article/2017/7/devops-metrics-are-you-measuring-what-matters diff --git a/translated/tech/20171009 What-s next in DevOps- 5 trends to watch.md b/translated/tech/20171009 What-s next in DevOps- 5 trends to watch.md new file mode 100644 index 0000000000..d6d7ecce7f --- /dev/null +++ b/translated/tech/20171009 What-s next in DevOps- 5 trends to watch.md @@ -0,0 +1,88 @@ +DevOps 接下来会发生什么:观察到的 5 个趋势 +====== + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/CIO%20Magnifying%20Glass%20Code.png?itok=IqZsJCEH) + +"DevOps" 一词通常认为是来源于 [2008 年关于敏捷基础设施和运营的介绍][1]。现在的 IT 词汇中,它无处不在,这个“混搭”的词汇出现还不到 10 年:我们还在研究它在 IT 中更现代化的工作方法。 + +当然,多年来一直在 “从事 DevOps" 的人积累了丰富的知识。但是大多数的 DevOps 环境 —— 人与 [文化][2] 、流程与方法、工具与技术的融合 —— 还远远没有成熟。 + +更多的变化即将到来。Robert Reeves 说 ”DevOps 是一个过程,一种算法“,他是 [Datical][3] 的 CTO, "它的绝对目标就是随着时间进行改变和演进”,这就是重点。 + +那我们预计接下来会发生什么呢?这里有一些专家们观察到的重要趋势。 + +### 1. 预计 DevOps、容器、以及微服务之间的相互依赖会增强 + +驱动 DevOps 发展的文化本身可能会演进。当然,DevOps 仍然将在根本上摧毁传统的 IT 站点和瓶颈,但这样做的理由可能会变得更加急迫。展示(证据) A & B: [对容器和微服务的兴趣][4] 与日俱增。这个技术组合很强大、可连续扩展、与规划和 [持续进行的管理][5]配合最佳。 + +Arvind Soni 说 "影响 DevOps 的其中一个主要因素是向微服务转变“,它是 [Netsil][6] 的产品副总裁,添加容器和业务流程,使开发者打包和交付的速度越来越快。DevOps 团队的任务可能是帮助去加速打包并管理越来越复杂的微服务弹性架构。 + +### 2. 预计 ”安全网“ 更少 + +DevOps 使团队可以更快更敏捷地去构建软件,部署速度也更快更频繁、同时还能提升软件质量和稳定性。但是好的 IT 领导通常都不会忽视管理风险,因此,早期大量的 DevOps 迭代都是使用了安全防护 —— 从后备的不重要业务开始的。为了实现更快的速度和敏捷性,越来越多的团队将抛弃他们的 ”辅助轮“(译者注:意思说减少了安全防护措施)。 + +Nic Grange 说 "随着团队的成熟,他们决定不再需要一些早期增加的安全 ”防护栏“ 了”,他是 [Retriever Communications][7] 的 CTO。Grange 给出了一个展示服务器的示例:随着 DevOps 团队的成熟,他们决定不再需要了,尤其是他们很少在试生产环境中发现问题。(Grange 指出,这一举措对于缺乏 DevOps 经验的团队来说,不可轻易效仿) + +Grange 说 "这个团队可能在监视和发现并解决生产系统中出现的问题的能力上有足够的信心“,"部署过程和测试阶段,如果没有任何证据证明它的价值,那么它可能会把整个进度拖慢”。 + +### 3. 预计 DevOps 将在其它领域大面积展开 + +DevOps 将两个传统的 IT 组(开发和运营)结合的更紧密。越来越多的公司看到了这种结合的好处,这种文化可能会传播开来。这种情况在一些组织中已经出现,在 “DevSecOps” 一词越来越多出现的情况下,它反映出了在软件开发周期中有意地、越来越早地包含了安全性。 + +Derek Weeks 说 "DevSecOps 不仅是一个工具,它是将安全思维更早地集成到开发实践中“,它是 [Sonatype][8] 的副总裁和 DevOps 拥挤者。 + + [Red Hat][9] 的安全策略师 Kirsten Newcomer 说,这种做法并不是一个技术挑战,而是一个文化挑战。 + +Newcomer 说 "从历史来看,安全团队都是从开发团队中分离出来的 —— 每个团队在它们不同的 IT 领域中形成了各自的专长” ,"它并不需要这种方法。每个关心安全性的企业也关心他们通过软件快速交付业务价值的能力,这些企业正在寻找方法,将安全放进应用程序的开发周期中。它们采用 DevSecOps 通过 CI/CD 流水线去集成安全实践、工具、和自动化。为了做的更好,他们整合他们的团队 —— 将安全专家整合到应用程序开发团队中,参与到从设计到产品部署的全过程中。这种做法使双方都看到了价值 —— 每个团队都扩充了它们的技能和知识,使他们成为更有价值的技术专家。DevOps 做对了—— 或者说是 DevSecOps —— 提升了 IT 安全性。“ + +除了安全以外,让 DevOps 扩展到其它领域,比如数据库团队、QA、甚至是 IT 以外的潜在领域。 + +Datical 的 Reeves 说 "这是一件非常 DevOps 化的事情:发现相互掣肘的地方并解决它们”,"对于以前采用 DevOps 的企业来说,安全和数据库是他们面临的最大瓶颈。“ + +### 4. 预计 ROI 将会增加 + +Eric Schabell 说,”由于公司深入推进他们的 DevOps 工作,IT 团队在方法、流程、容器、和微服务方面的投资将得到更多的回报。“ 他是 Red Hat 的全球技术传播总监,Schabell 说 "Holy Grail 将移动的更快、完成的更多、并且变得更灵活。由于这些组件找到了更宽阔的天地,组织在应用程序中更有归属感时,结果就会出现。” + +"每当新兴技术获得我们的关注时,任何事都有一个令人兴奋的学习曲线,但当认识到它应用很困难的时候,同时也会经历一个从兴奋到幻灭的低谷。最终,我们将开始看到从低谷中爬出来,并收获到应用 DevOps、容器、和微服务的好处。“ + +### 5. 预计成功的指标将持续演进 + +Mike Kail 说 "我相信 DevOps 文化的两个核心原则 —— 自动化和可衡量是从来不会变的”,它是 [CYBRIC][10] 的 CTO,也是 Yahoo 前 CIO。“总是有办法去自动化一个任务,或者提升一个已经自动化的解决方案,而随着时间的推移,重要的事情是测量可能的变化和扩展。这个成熟的过程是一个永不停步的旅行,而不是一个目的地或者已完成的任务。” + +在 DevOps 的精神中,成熟和学习也与协作者和分享精神有关。Kail 认为,对于敏捷方法和 DevOps 文化来说,它仍然为时尚早,这意味着它们还有足够的增长空间。 + +Kail 说 "随着越来越多的成熟组织持续去测量可控指标,我相信(希望) —— 这些经验应该被广泛的分享,以便我们去学习并改善它们。“ + +作为 Red Hat 技术传播专家 [Gordon Haff][11] 最近注意到,组织使用业务成果相关的因素去改善他们的 DevOps 指标的工作越来越困难。 [Haff 写道][12] "你或许并不真正关心你的开发者写了多少行代码、服务器是否在一夜之间出现了硬件故障、或者你的测试覆盖面是否全面”。事实上,你可能并不直接关心你的网站的响应速度和更新快慢。但是你要注意的是,这些指标可能与消费者放弃购物车或者转到你的竞争对手那里有关。“ + +与业务成果相关的一些 DevOps 指标的例子包括,消费者交易金额(作为消费者花销统计的指标)和净推荐值(消费者推荐公司产品和服务的意愿)。关于这个主题更多的内容,请查看这篇完整的文章—— [DevOps 指标:你是否测量了重要的东西 ][12]。 + +### 唯一不变的就是改变 + +顺利说一句,如果你希望这件事一蹴而就,那你就要倒霉了。 + +Reeves 说 "如果你认为今天发布非常快,那你就什么也没有看到”,“这就是为什么要让相关者包括数据库团队进入到 DevOps 中的重要原因。因为今天这两组人员的冲突会随着发布速度的提升而呈指数级增长。” + +-------------------------------------------------------------------------------- + +via: https://enterprisersproject.com/article/2017/10/what-s-next-devops-5-trends-watch + +作者:[Kevin Casey][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://enterprisersproject.com/user/kevin-casey +[1]:http://www.jedi.be/presentations/agile-infrastructure-agile-2008.pdf +[2]:https://enterprisersproject.com/article/2017/9/5-ways-nurture-devops-culture +[3]:https://www.datical.com/ +[4]:https://enterprisersproject.com/article/2017/9/microservices-and-containers-6-things-know-start-time +[5]:https://enterprisersproject.com/article/2017/10/microservices-and-containers-6-management-tips-long-haul +[6]:https://netsil.com/ +[7]:http://retrievercommunications.com/ +[8]:https://www.sonatype.com/ +[9]:https://www.redhat.com/en/ +[10]:https://www.cybric.io/ +[11]:https://enterprisersproject.com/user/gordon-haff +[12]:https://enterprisersproject.com/article/2017/7/devops-metrics-are-you-measuring-what-matters From 5fb5658d238b52b43c4831732e3388b4b484c2e6 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 12:57:32 +0800 Subject: [PATCH 053/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Linux=20Virtual?= =?UTF-8?q?=20Machines=20vs=20Linux=20Live=20Images?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...x Virtual Machines vs Linux Live Images.md | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md diff --git a/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md b/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md new file mode 100644 index 0000000000..f846e9486d --- /dev/null +++ b/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md @@ -0,0 +1,58 @@ +Linux Virtual Machines vs Linux Live Images +====== +I'll be the first to admit that I tend to try out new [Linux distros][1] on a far too frequent basis. Yet the method I use to test them, does vary depending on my goals for each instance. In this article, we're going to look at both running Linux virtual machines and running Linux live images. There are advantages to each method, but there are some hurdles with each method as well. + +### Testing out a new Linux distro for the first time + +When I test out a brand new Linux distro for the first time, the method I use depends heavily on the resources of the PC I'm currently on. If I have access to my desktop PC, I'm going to run the distro to be tested in a virtual machine. The reason for this approach is that I can download and test the distro in not only a live environment, but also as an installed product with persistent storage abilities. + +On the other hand, if I am working with much less robust hardware on a PC, then testing out a distro with a virtual machine installation of Linux is counter-productive. I'd be pushing that PC to its limits and honestly would be better off using a live Linux image instead running from a flash drive. + +### Touring software on a new Linux distro + +If you're interested in checking out a distro's desktop environment or the available software, you can't go wrong with a live image of the distro. A live environment provides you with a birds eye view of what to expect in terms of overall layout, applications provided and how the user experience flows overall. + +To be fair, you could do the same thing with a virtual machine installation, but it may be a bit overkill if you would rather avoid filling up hard drive space with yet more data. After all, this is a simple tour of the distro. Remember what I said in the first section – I like to run Linux in a virtual machine to test it. This means I'm going to see how it installs, what the partition options look like and other elements you wouldn't see from using a live image of any given distro. + +Touring usually indicates that you're only looking to take a quick look at a distro, so in this case the method that can be done with the least amount of resistance and time investment is a good course of action. + +### Taking a Linux distro with you + +While it's not as common as it was a few years ago, the ability to take a Linux distro with you may be a consideration for some users. Obviously, virtual machine installations don't necessarily lend themselves favorably to portability. However a live image of a Linux distro is actually quite portable. A live image can be written to a DVD or copied onto a flash drive for easy traveling. + +Expanding on this concept of Linux portability, it's also beneficial to have a live image on a flash drive when showing off how Linux works on a friend's computer. This empowers you to demonstrate how Linux can enrich their life while not relying on running a virtual machine on their PC. It's a bit of a win-win in favor of using a live image. + +### Alternative to dual-booting Linux + +This next item is a huge one. Consider this – perhaps you're a Windows user. You like playing with Linux, but would rather not take the plunge. Dual-booting is out of the question in case something goes wrong or perhaps you're not comfortable identifying individual partitions. Whatever the case may be, both using Linux in a virtual machine or from a live image might be a great option for you. + +Now I'm going to take a rather odd stance on something. I think you'll get far more value in the long term running Linux on a flash drive using a live image than with a virtual machine. There are two reasons for this. First of all, you'll get used to truly running Linux vs running it inside of a virtual machine on top of Windows. Second, you can setup your flash drive to contain user data with persistent storage. + +I'll grant you the same could be said with a virtual machine running Linux, however you will never have an update break anything using the live image approach. Why? Because you're not updating a host OS or the guest OS. Remember there are entire distros that are designed to be nothing more than persistent storage Linux distros. Puppy Linux is one great example. Not only can it run on PCs that would otherwise be recycled or thrown away, it allows you to never be bothered again with tedious system updates thanks to the way the distro handles security. It's not a normal Linux distro and it's walled off in such a way that the persistent live image is free from anything scary. + +### When a Linux virtual machine is absolutely the best option + +As I bring this article to a close, let me leave you with this. There is one instance where using a virtual machine such as Virtual Box is absolutely better than using a live image – recording the desktop environment of any Linux distro. + +For example, I make videos that provide a tour and review of a variety of Linux distros. Doing this with live images would require me to capture the screen with a hardware device or install a software capture device from the live image's repositories. Clearly, a virtual machine is better suited for this job than a live image of a Linux distro. + +Once you toss audio capture into the mix, there is no question that if you're going to use software to capture your review, you really want to have a host OS that has all the basic needs covered for a reasonably decent capture environment. Again, you could do all of this with a hardware device...but that might be cost prohibitive if you're only do video/audio capturing as a part time endeavor. + +### A Linux virtual machine vs a Linux live image + +What is your preferred method of trying out new distros? Perhaps you're someone who is fine with formatting their hard drive and throwing caution to the wind, thus, making the idea of any of this unneeded? + +Most people I've interacted with online tend to follow much of the methodology I've touched on above, but I'd love to hear what approach works best for you. Hit the comments, let me know which method you prefer when checking out the greatest and latest from the Linux distro world. + +-------------------------------------------------------------------------------- + +via: https://www.datamation.com/open-source/linux-virtual-machines-vs-linux-live-images.html + +作者:[Matt Hartley][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.datamation.com/author/Matt-Hartley-3080.html +[1]:https://www.datamation.com/open-source/best-linux-distro.html From 39d3a6881582bb8c5e93758cc1ab09ebb8183bf3 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 14:47:24 +0800 Subject: [PATCH 054/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Why=20culture=20i?= =?UTF-8?q?s=20the=20most=20important=20issue=20in=20a=20DevOps=20transfor?= =?UTF-8?q?mation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ortant issue in a DevOps transformation.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 sources/talk/20180223 Why culture is the most important issue in a DevOps transformation.md diff --git a/sources/talk/20180223 Why culture is the most important issue in a DevOps transformation.md b/sources/talk/20180223 Why culture is the most important issue in a DevOps transformation.md new file mode 100644 index 0000000000..8fe1b6f273 --- /dev/null +++ b/sources/talk/20180223 Why culture is the most important issue in a DevOps transformation.md @@ -0,0 +1,91 @@ +Why culture is the most important issue in a DevOps transformation +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_community2.png?itok=1blC7-NY) + +You've been appointed the DevOps champion in your organisation: congratulations. So, what's the most important issue that you need to address? + +It's the technology—tools and the toolchain—right? Everybody knows that unless you get the right tools for the job, you're never going to make things work. You need integration with your existing stack (though whether you go with tight or loose integration will be an interesting question), a support plan (vendor, third party, or internal), and a bug-tracking system to go with your source code management system. And that's just the start. + +No! Don't be ridiculous: It's clearly the process that's most important. If the team doesn't agree on how stand-ups are run, who participates, the frequency and length of the meetings, and how many people are required for a quorum, then you'll never be able to institute a consistent, repeatable working pattern. + +In fact, although both the technology and the process are important, there's a third component that is equally important, but typically even harder to get right: culture. Yup, it's that touch-feely thing we techies tend to struggle with.1 + +### Culture + +I was visiting a midsized government institution a few months ago (not in the UK, as it happens), and we arrived a little early to meet the CEO and CTO. We were ushered into the CEO's office and waited for a while as the two of them finished participating in the daily stand-up. They apologised for being a minute or two late, but far from being offended, I was impressed. Here was an organisation where the culture of participation was clearly infused all the way up to the top. + +Not that culture can be imposed from the top—nor can you rely on it percolating up from the bottom3—but these two C-level execs were not only modelling the behaviour they expected from the rest of their team, but also seemed, from the brief discussion we had about the process afterwards, to be truly invested in it. If you can get management to buy into the process—and be seen buying in—you are at least likely to have problems with other groups finding plausible excuses to keep their distance and get away with it. + +So let's assume management believes you should give DevOps a go. Where do you start? + +Developers may well be your easiest target group. They are often keen to try new things and find ways to move things along faster, so they are often the group that can be expected to adopt new technologies and methodologies. DevOps arguably has been driven mainly by the development community. + +But you shouldn't assume all developers will be keen to embrace this change. For some, the way things have always been done—your Rick Parfitts of dev, if you will7—is fine. Finding ways to help them work efficiently in the new world is part of your job, not just theirs. If you have superstar developers who aren't happy with change, you risk alienating and losing them if you try to force them into your brave new world. What's worse, if they dig their heels in, you risk the adoption of your DevSecOps vision being compromised when they explain to their managers that things aren't going to change if it makes their lives more difficult and reduces their productivity. + +Maybe you're not going to be able to move all the systems and people to DevOps immediately. Maybe you're going to need to choose which apps start with and who will be your first DevOps champions. Maybe it's time to move slowly. + +### Not maybe: definitely + +No—I lied. You're definitely going to need to move slowly. Trying to change everything at once is a recipe for disaster. + +This goes for all elements of the change—which people to choose, which technologies to choose, which applications to choose, which user base to choose, which use cases to choose—bar one. For those elements, if you try to move everything in one go, you will fail. You'll fail for a number of reasons. You'll fail for reasons I can't imagine and, more importantly, for reasons you can't imagine. But some of the reasons will include: + + * People—most people—don't like change. + * Technologies don't like change (you can't just switch and expect everything to still work). + * Applications don't like change (things worked before, or at least failed in known ways). You want to change everything in one go? Well, they'll all fail in new and exciting9 ways. + * Users don't like change. + * Use cases don't like change. + + + +### The one exception + +You noticed I wrote "bar one" when discussing which elements you shouldn't choose to change all in one go? Well done. + +What's that exception? It's the initial team. When you choose your initial application to change and you're thinking about choosing the team to make that change, select the members carefully and select a complete set. This is important. If you choose just developers, just test folks, just security folks, just ops folks, or just management—if you leave out one functional group from your list—you won't have proved anything at all. Well, you might have proved to a small section of your community that it kind of works, but you'll have missed out on a trick. And that trick is: If you choose keen people from across your functional groups, it's much harder to fail. + +Say your first attempt goes brilliantly. How are you going to convince other people to replicate your success and adopt DevOps? Well, the company newsletter, of course. And that will convince how many people, exactly? Yes, that number.12 If, on the other hand, you have team members from across the functional parts or the organisation, when you succeed, they'll tell their colleagues and you'll get more buy-in next time. + +If it fails, if you've chosen your team wisely—if they're all enthusiastic and know that "fail often, fail fast" is good—they'll be ready to go again. + +Therefore, you need to choose enthusiasts from across your functional groups. They can work on the technologies and the process, and once that's working, it's the people who will create that cultural change. You can just sit back and enjoy. Until the next crisis, of course. + +1\. OK, you're right. It should be "with which we techies tend to struggle."2 + +2\. You thought I was going to qualify that bit about techies struggling with touchy-feely stuff, didn't you? Read it again: I put "tend to." That's the best you're getting. + +3\. Is percolating a bottom-up process? I don't drink coffee,4 so I wouldn't know. + +4\. Do people even use percolators to make coffee anymore? Feel free to let me know in the comments. I may pretend interest if you're lucky. + +5\. For U.S. readers (and some other countries, maybe?), please substitute "check" for "tick" here.6 + +6\. For U.S. techie readers, feel free to perform `s/tick/check/;`. + +7\. This is a Status Quo8 reference for which I'm extremely sorry. + +8\. For millennial readers, please consult your favourite online reference engine or just roll your eyes and move on. + +9\. For people who say, "but I love excitement," try being on call at 2 a.m. on a Sunday at the end of the quarter when your chief financial officer calls you up to ask why all of last month's sales figures have been corrupted with the letters "DEADBEEF."10 + +10\. For people not in the know, this is a string often used by techies as test data because a) it's non-numerical; b) it's numerical (in hexadecimal); c) it's easy to search for in debug files; and d) it's funny.11 + +11\. Though see.9 + +12\. It's a low number, is all I'm saying. + +This article originally appeared on [Alice, Eve, and Bob – a security blog][1] and is republished with permission. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/most-important-issue-devops-transformation + +作者:[Mike Bursell][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mikecamel +[1]:https://aliceevebob.com/2018/02/06/moving-to-devops-whats-most-important/ From 2bf23b63bc3a034a549b1337fdbbd854227cab47 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 14:55:35 +0800 Subject: [PATCH 055/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Plasma=20Mobile?= =?UTF-8?q?=20Could=20Give=20Life=20to=20a=20Mobile=20Linux=20Experience?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Give Life to a Mobile Linux Experience.md | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md diff --git a/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md b/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md new file mode 100644 index 0000000000..583714836e --- /dev/null +++ b/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md @@ -0,0 +1,123 @@ +Plasma Mobile Could Give Life to a Mobile Linux Experience +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/plasma-mobile_0.png?itok=uUIQFRcm) + +In the past few years, it’s become clear that, outside of powering Android, Linux on mobile devices has been a resounding failure. Canonical came close, even releasing devices running Ubuntu Touch. Unfortunately, the idea of [Scopes][1]was doomed before it touched down on its first piece of hardware and subsequently died a silent death. + +The next best hope for mobile Linux comes in the form of the [Samsung DeX][2] program. With DeX, users will be able to install an app (Linux On Galaxy—not available yet) on their Samsung devices, which would in turn allow them to run a full-blown Linux distribution. The caveat here is that you’ll be running both Android and Linux at the same time—which is not exactly an efficient use of resources. On top of that, most Linux distributions aren’t designed to run on such small form factors. The good news for DeX is that, when you run Linux on Galaxy and dock your Samsung device to DeX, that Linux OS will be running on your connected monitor—so form factor issues need not apply. + +Outside of those two options, a pure Linux on mobile experience doesn’t exist. Or does it? + +You may have heard of the [Purism Librem 5][3]. It’s a crowdfunded device that promises to finally bring a pure Linux experience to the mobile landscape. This device will be powered by a i.MX8 SoC chip, so it should run most any Linux operating system. + +Out of the box, the device will run an encrypted version of [PureOS][4]. However, last year Purism and KDE joined together to create a mobile version of the KDE desktop that could run on the Librem 5. Recently [ISOs were made available for a beta version of Plasma Mobile][5] and, judging from first glance, they’re onto something that makes perfect sense for a mobile Linux platform. I’ve booted up a live instance of Plasma Mobile to kick the tires a bit. + +What I saw seriously impressed me. Let’s take a look. + +### Testing platform + +Before you download the ISO and attempt to fire it up as a VirtualBox VM, you should know that it won’t work well. Because Plasma Mobile uses Wayland (and VirtualBox has yet to play well with that particular X replacement), you’ll find VirtualBox VM a less-than-ideal platform for the beta release. Also know that the Calamares installer doesn’t function well either. In fact, I have yet to get the OS installed on a non-mobile device. And since I don’t own a supported mobile device, I’ve had to run it as a live session on either a laptop or an [Antsle][6] antlet VM every time. + +### What makes Plasma Mobile special? + +This could be easily summed up by saying, Plasma Mobile got it all right. Instead of Canonical re-inventing a perfectly functioning wheel, the developers of KDE simply re-tooled the interface such that a full-functioning Linux distribution (complete with all the apps you’ve grown to love and depend upon) could work on a smaller platform. And they did a spectacular job. Even better, they’ve created an interface that any user of a mobile device could instantly feel familiar with. + +What you have with the Plasma Mobile interface (Figure 1) are the elements common to most Android home screens: + + * Quick Launchers + + * Notification Shade + + * App Drawer + + * Overview button (so you can go back to a previously used app, still running in memory) + + * Home button + + + + +![KDE mobile][8] + +Figure 1: The Plasma Mobile desktop interface. + +[Used with permission][9] + +Because KDE went this route with the UX, it means there’s zero learning curve. And because this is an actual Linux platform, it takes that user-friendly mobile interface and overlays it onto a system that allows for easy installation and usage of apps like: + + * GIMP + + * LibreOffice + + * Audacity + + * Clementine + + * Dropbox + + * And so much more + + + + +Unfortunately, without being able to install Plasma Mobile, you cannot really kick the tires too much, as the live user doesn’t have permission to install applications. However, once Plasma Mobile is fully installed, the Discover software center will allow you to install a host of applications (Figure 2). + + +![Discover center][11] + +Figure 2: The Discover software center on Plasma Mobile. + +[Used with permission][9] + +Swipe up (or scroll down—depending on what hardware you’re using) to reveal the app drawer, where you can launch all of your installed applications (Figure 3). + +![KDE mobile][13] + +Figure 3: The Plasma Mobile app drawer ready to launch applications. + +[Used with permission][9] + +Open up a terminal window and you can take care of standard Linux admin tasks, such as using SSH to log into a remote server. Using apt, you can install all of the developer tools you need to make Plasma Mobile a powerful development platform. + +We’re talking serious mobile power—either from a phone or a tablet. + +### A ways to go + +Clearly Plasma Mobile is still way too early in development for it to be of any use to the average user. And because most virtual machine technology doesn’t play well with Wayland, you’re likely to get too frustrated with the current ISO image to thoroughly try it out. However, even without being able to fully install the platform (or get full usage out of it), it’s obvious KDE and Purism are going to have the ideal platform that will put Linux into the hands of mobile users. + +If you want to test the waters of Plasma Mobile on an actual mobile device, a handy list of supported hardware can be found [here][14] (for PostmarketOS) or [here][15] (for Halium). If you happen to be lucky enough to have a device that also includes Wi-Fi support, you’ll find you get more out of testing the environment. + +If you do have a supported device, you’ll need to use either [PostmarketOS][16] (a touch-optimized, pre-configured Alpine Linux that can be installed on smartphones and other mobile devices) or [Halium][15] (an application that creates an minimal Android layer which allows a new interface to interact with the Android kernel). Using Halium further limits the number of supported devices, as it has only been built for select hardware. However, if you’re willing, you can build your own Halium images (documentation for this process is found [here][17]). If you want to give PostmarketOS a go, [here are the necessary build instructions][18]. + +Suffice it to say, Plasma Mobile isn’t nearly ready for mass market. If you’re a Linux enthusiast and want to give it a go, let either PostmarketOS or Halium help you get the operating system up and running on your device. Otherwise, your best bet is to wait it out and hope Purism and KDE succeed in bringing this oustanding mobile take on Linux to the masses. + +Learn more about Linux through the free ["Introduction to Linux" ][19]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/2/plasma-mobile-could-give-life-mobile-linux-experience + +作者:[JACK WALLEN][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/jlwallen +[1]:https://launchpad.net/unity-scopes +[2]:http://www.samsung.com/global/galaxy/apps/samsung-dex/ +[3]:https://puri.sm/shop/librem-5/ +[4]:https://www.pureos.net/ +[5]:http://blog.bshah.in/2018/01/26/trying-out-plasma-mobile/ +[6]:https://antsle.com/ +[8]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/kdemobile_1.jpg?itok=EK3_vFVP (KDE mobile) +[9]:https://www.linux.com/licenses/category/used-permission +[11]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/kdemobile_2.jpg?itok=CiUQ-MnB (Discover center) +[13]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/kdemobile_3.jpg?itok=i6V8fgK8 (KDE mobile) +[14]:http://blog.bshah.in/2018/02/02/trying-out-plasma-mobile-part-two/ +[15]:https://github.com/halium/projectmanagement/issues?q=is%3Aissue+is%3Aopen+label%3APorts +[16]:https://postmarketos.org/ +[17]:http://docs.halium.org/en/latest/ +[18]:https://wiki.postmarketos.org/wiki/Installation_guide +[19]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From 9aeb98c9e3a2de5fd4da3d056eebb72625201b63 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 15:28:24 +0800 Subject: [PATCH 056/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20To=20Run=20?= =?UTF-8?q?A=20Command=20For=20A=20Specific=20Time=20In=20Linux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... A Command For A Specific Time In Linux.md | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md diff --git a/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md b/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md new file mode 100644 index 0000000000..7556da2062 --- /dev/null +++ b/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md @@ -0,0 +1,107 @@ +How To Run A Command For A Specific Time In Linux +====== +![](https://www.ostechnix.com/wp-content/uploads/2018/02/Run-A-Command-For-A-Specific-Time-In-Linux-1-720x340.png) + +The other day I was transferring a large file using rsync to another system on my local area network. Since it is very big file, It took around 20 minutes to complete. I don’t want to wait that longer, and I don’t want to terminate the process by pressing CTRL+C either. I was just wondering if there could be any easy ways to run a command for a specific time and kill it automatically once the time is out in Unix-like operating systems – hence this post. Read on. + +### Run A Command For A Specific Time In Linux + +We can do this in two methods. + +#### Method 1 – Using “timeout” command + +The most common method is using **timeout** command. For those who don’t know, the timeout command will effectively limit the absolute execution time of a process. The timeout command is part of the GNU coreutils package, so it comes pre-installed in all GNU/Linux systems. + +Let us say, you want to run a command for only 5 seconds, and then kill it. To do so, we use: +``` +$ timeout + +``` + +For example, the following command will terminate after 10 seconds. +``` +$ timeout 10s tail -f /var/log/pacman.log + +``` + +![][2] + +You also don’t have to specify the suffix “s” for seconds. The following command is same as above. +``` +$ timeout 10 tail -f /var/log/pacman.log + +``` + +The other available suffixes are: + + * ‘m’ for minutes, + * ‘h’ for hours + * ‘d’ for days. + + + +If you run this **tail -f /var/log/pacman.log** command, it will keep running until you manually end it by pressing CTRL+C. However, if you run it along with **timeout** command, it will be killed automatically after the given time interval. If the command is till running after the time out, you can send a **kill** signal like below. +``` +$ timeout -k 20 10 tail -f /var/log/pacman.log + +``` + +In this case, if you the tail command still running after 10 seconds, the timeout command will send it a kill signal after 20 seconds and end it. + +For more details, check the man pages. +``` +$ man timeout + +``` + +Sometimes, a particular program might take long time to complete and end up freezing your system. In such cases, you can use this trick to end the process automatically after a particular time. + +Also, consider using **Cpulimit** , a simple application to limit the CPU usage of a process. For more details, check the following link. + +#### Method 2 – Using “Timelimit” program + +The Timelimit utility executes a given command with the supplied arguments and terminates the spawned process after a given time with a given signal. First, it will pass the warning signal and then after timeout, it will send the **kill** signal. + +Unlike the timeout utility, the Timelimit has more options. You can pass number of arguments such as killsig, warnsig, killtime, warntime etc. It is available in the default repositories of Debian-based systems. So, you can install it using command: +``` +$ sudo apt-get install timelimit + +``` + +For Arch-based systems, it is available in the AUR. So, you can install it using any AUR helper programs such as [**Pacaur**][3], [**Packer**][4], [**Yay**][5], [**Yaourt**][6] etc. + +For other distributions, download the source [**from here**][7] and manually install it. After installing Timelimit program, run the following command for a specific time, for example 10 seconds: +``` +$ timelimit -t10 tail -f /var/log/pacman.log + +``` + +If you run timelimit without any arguments, it will use the default values: warntime=3600 seconds, warnsig=15, killtime=120, killsig=9. For more details, refer the man pages and the project’s website given at the end of this guide. +``` +$ man timelimit + +``` + +And, that’s all for today. I hope this was useful. More good stuffs to come. Stay tuned! + +Cheers! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/run-command-specific-time-linux/ + +作者:[SK][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[2]:http://www.ostechnix.com/wp-content/uploads/2018/02/Timeout.gif +[3]:https://www.ostechnix.com/install-pacaur-arch-linux/ +[4]:https://www.ostechnix.com/install-packer-arch-linux-2/ +[5]:https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/ +[6]:https://www.ostechnix.com/install-yaourt-arch-linux/ +[7]:http://devel.ringlet.net/sysutils/timelimit/#download From 06a86fa7a5ec074f888dbaa7296d2bf40c6b4115 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Thu, 1 Mar 2018 17:20:19 +0800 Subject: [PATCH 057/101] Translated by qhwdw --- ...h kSar To Identifying Linux Bottlenecks.md | 341 ----------------- ...h kSar To Identifying Linux Bottlenecks.md | 350 ++++++++++++++++++ 2 files changed, 350 insertions(+), 341 deletions(-) delete mode 100644 sources/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md create mode 100644 translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md diff --git a/sources/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md b/sources/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md deleted file mode 100644 index e386b29fd5..0000000000 --- a/sources/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md +++ /dev/null @@ -1,341 +0,0 @@ -Translating by qhwdw -How To Create sar Graphs With kSar To Identifying Linux Bottlenecks -====== -The sar command collects, report, or save UNIX / Linux system activity information. It will save selected counters in the operating system to the /var/log/sa/sadd file. From the collected data, you get lots of information about your server: - - 1. CPU utilization - 2. Memory paging and its utilization - 3. Network I/O, and transfer statistics - 4. Process creation activity - 5. All block devices activity - 6. Interrupts/sec etc. - - - -The sar command output can be used for identifying server bottlenecks. However, analyzing information provided by sar can be difficult, so use kSar tool. kSar takes sar command output and plots a nice easy to understand graph over a period of time. - - -## sysstat Package - -The sar, sa1, and sa2 commands are part of sysstat package. Collection of performance monitoring tools for Linux includes - - 1. sar : Displays the data. - 2. sa1 and sa2: Collect and store the data for later analysis. The sa2 shell script write a daily report in the /var/log/sa directory. The sa1 shell script collect and store binary data in the system activity daily data file. - 3. sadc - System activity data collector. You can configure various options by modifying sa1 and sa2 scripts. They are located at the following location: - * /usr/lib64/sa/sa1 (64bit) or /usr/lib/sa/sa1 (32bit) - This calls sadc to log reports to/var/log/sa/sadX format. - * /usr/lib64/sa/sa2 (64bit) or /usr/lib/sa/sa2 (32bit) - This calls sar to log reports to /var/log/sa/sarX format. - - - -### How do I install sar on my system? - -Type the following [yum command][1] to install sysstat on a CentOS/RHEL based system: -`# yum install sysstat` -Sample outputs: -``` -Loaded plugins: downloadonly, fastestmirror, priorities, - : protectbase, security -Loading mirror speeds from cached hostfile - * addons: mirror.cs.vt.edu - * base: mirror.ash.fastserv.com - * epel: serverbeach1.fedoraproject.org - * extras: mirror.cogentco.com - * updates: centos.mirror.nac.net -0 packages excluded due to repository protections -Setting up Install Process -Resolving Dependencies ---> Running transaction check ----> Package sysstat.x86_64 0:7.0.2-3.el5 set to be updated ---> Finished Dependency Resolution - -Dependencies Resolved - -==================================================================== - Package Arch Version Repository Size -==================================================================== -Installing: - sysstat x86_64 7.0.2-3.el5 base 173 k - -Transaction Summary -==================================================================== -Install 1 Package(s) -Update 0 Package(s) -Remove 0 Package(s) - -Total download size: 173 k -Is this ok [y/N]: y -Downloading Packages: -sysstat-7.0.2-3.el5.x86_64.rpm | 173 kB 00:00 -Running rpm_check_debug -Running Transaction Test -Finished Transaction Test -Transaction Test Succeeded -Running Transaction - Installing : sysstat 1/1 - -Installed: - sysstat.x86_64 0:7.0.2-3.el5 - -Complete! -``` - - -### Configuration files for sysstat - -Edit /etc/sysconfig/sysstat file specify how long to keep log files in days, maximum is a month: -`# vi /etc/sysconfig/sysstat` -Sample outputs: -``` -# keep log for 28 days -# the default is 7 -HISTORY=28 -``` - -Save and close the file. - -### Find the default cron job for sar - -[The default cron job is located][2] at /etc/cron.d/sysstat: -`# cat /etc/cron.d/sysstat` -Sample outputs: -``` -# run system activity accounting tool every 10 minutes -*/10 * * * * root /usr/lib64/sa/sa1 1 1 -# generate a daily summary of process accounting at 23:53 -53 23 * * * root /usr/lib64/sa/sa2 -A -``` - -### Tell sadc to report statistics for disks - -Edit the /etc/cron.d/sysstat file using a text editor such as NA command or vim command, enter: -`# vi /etc/cron.d/sysstat` -Update it as follows to log all disk stats (the -d option force to log stats for each block device and the -I option force report statistics for all system interrupts): -``` -# run system activity accounting tool every 10 minutes -*/10 * * * * root /usr/lib64/sa/sa1 -I -d 1 1 -# generate a daily summary of process accounting at 23:53 -53 23 * * * root /usr/lib64/sa/sa2 -A -``` - -On a CentOS/RHEL 7.x you need to pass the -S DISK option to collect data for block devices. Pass the -S XALL to collect data about: - - 1. Disk - 2. Partition - 3. System interrupts - 4. SNMP - 5. IPv6 - - -``` -# Run system activity accounting tool every 10 minutes -*/10 * * * * root /usr/lib64/sa/sa1 -S DISK 1 1 -# 0 * * * * root /usr/lib64/sa/sa1 600 6 & -# Generate a daily summary of process accounting at 23:53 -53 23 * * * root /usr/lib64/sa/sa2 -A -# Run system activity accounting tool every 10 minutes -``` - -Save and close the file. Turn on the service for a CentOS/RHEL version 5.x/6.x, enter: -`# chkconfig sysstat on -# service sysstat start` -Sample outputs: -``` -Calling the system activity data collector (sadc): -``` - -For a CentOS/RHEL 7.x, run the following commands: -``` -# systemctl enable sysstat -# systemctl start sysstat.service -# systemctl status sysstat.service -``` -Sample outputs: -``` -● sysstat.service - Resets System Activity Logs - Loaded: loaded (/usr/lib/systemd/system/sysstat.service; enabled; vendor preset: enabled) - Active: active (exited) since Sat 2018-01-06 16:33:19 IST; 3s ago - Process: 28297 ExecStart=/usr/lib64/sa/sa1 --boot (code=exited, status=0/SUCCESS) - Main PID: 28297 (code=exited, status=0/SUCCESS) - -Jan 06 16:33:19 centos7-box systemd[1]: Starting Resets System Activity Logs... -Jan 06 16:33:19 centos7-box systemd[1]: Started Resets System Activity Logs. -``` - -## How Do I Use sar? How do I View Stats? - -Use the sar command to display output the contents of selected cumulative activity counters in the operating system. In this example, sar is run to get real-time reporting from the command line about CPU utilization: -`# sar -u 3 10` -Sample outputs: -``` -Linux 2.6.18-164.2.1.el5 (www-03.nixcraft.in) 12/14/2009 - -09:49:47 PM CPU %user %nice %system %iowait %steal %idle -09:49:50 PM all 5.66 0.00 1.22 0.04 0.00 93.08 -09:49:53 PM all 12.29 0.00 1.93 0.04 0.00 85.74 -09:49:56 PM all 9.30 0.00 1.61 0.00 0.00 89.10 -09:49:59 PM all 10.86 0.00 1.51 0.04 0.00 87.58 -09:50:02 PM all 14.21 0.00 3.27 0.04 0.00 82.47 -09:50:05 PM all 13.98 0.00 4.04 0.04 0.00 81.93 -09:50:08 PM all 6.60 6.89 1.26 0.00 0.00 85.25 -09:50:11 PM all 7.25 0.00 1.55 0.04 0.00 91.15 -09:50:14 PM all 6.61 0.00 1.09 0.00 0.00 92.31 -09:50:17 PM all 5.71 0.00 0.96 0.00 0.00 93.33 -Average: all 9.24 0.69 1.84 0.03 0.00 88.20 -``` - -Where, - - * 3 = interval - * 10 = count - - - -To view process creation statistics, enter: -`# sar -c 3 10` -To view I/O and transfer rate statistics, enter: -`# sar -b 3 10` -To view paging statistics, enter: -`# sar -B 3 10` -To view block device statistics, enter: -`# sar -d 3 10` -To view statistics for all interrupt statistics, enter: -`# sar -I XALL 3 10` -To view device specific network statistics, enter: -``` -# sar -n DEV 3 10 -# sar -n EDEV 3 10 -``` -To view CPU specific statistics, enter: -``` -# sar -P ALL -# Only 1st CPU stats -# sar -P 1 3 10 -``` -To view queue length and load averages statistics, enter: -`# sar -q 3 10` -To view memory and swap space utilization statistics, enter: -``` -# sar -r 3 10 -# sar -R 3 10 -``` -To view status of inode, file and other kernel tables statistics, enter: -`# sar -v 3 10` -To view system switching activity statistics, enter: -`# sar -w 3 10` -To view swapping statistics, enter: -`# sar -W 3 10` -To view statistics for a given process called Apache with PID # 3256, enter: -`# sar -x 3256 3 10` - -## Say Hello To kSar - -sar and sadf provides CLI based output. The output may confuse all new users / sys admin. So you need to use kSar which is a java application that graph your sar data. It also permit to export data to PDF/JPG/PNG/CSV. You can load data from three method : local file, local command execution, and remote command execution via SSH. kSar supports the sar output of the following OS: - - 1. Solaris 8, 9 and 10 - 2. Mac OS/X 10.4+ - 3. Linux (Systat Version >= 5.0.5) - 4. AIX (4.3 & 5.3) - 5. HPUX 11.00+ - - - -### Download And Install kSar - -Visit the [official][3] website and grab the latest source code. Use [wget to][4] download the source code, enter: -`$ wget https://github.com/vlsi/ksar/releases/download/v5.2.4-snapshot-652bf16/ksar-5.2.4-SNAPSHOT-all.jar` - -#### How Do I Run kSar? - -Make sure [JAVA jdk][5] is installed and working correctly. Type the following command to start kSar, run: -`$ java -jar ksar-5.2.4-SNAPSHOT-all.jar` - -![Fig.01: kSar welcome screen][6] -Next you will see main kSar window, and menus with two panels. -![Fig.02: kSar - the main window][7] -The left one will have a list of graphs available depending on the data kSar has parsed. The right window will show you the graph you have selected. - -## How Do I Generate sar Graphs Using kSar? - -First, you need to grab sar command statistics from the server named server1. Type the following command to get stats, run: -`[ **server1** ]# LC_ALL=C sar -A > /tmp/sar.data.txt` -Next copy file to local desktop from a remote box using the scp command: -`[ **desktop** ]$ scp user@server1.nixcraft.com:/tmp/sar.data.txt /tmp/` -Switch to kSar Windows. Click on **Data** > **Load data from text file** > Select sar.data.txt from /tmp/ > Click the **Open** button. -Now, the graph type tree is deployed in left pane and a graph has been selected: -![Fig.03: Processes for server1][8] - -![Fig.03: Disk stats \(blok device\) stats for server1][9]![Fig.05: Memory stats for server1][10] - -#### Zoom in and out - -Using the move, you can interactively zoom onto up a part of a graph. To select a zone to zoom, click on the upper left conner and while still holding the mouse but on move to the lower-right of the zone you want to zoom. To come back to unzoomed view click and drag the mouse to any corner location except a lower-right one. You can also right click and select zoom options - -#### Understanding kSar Graphs And sar Data - -I strongly recommend reading sar and sadf command man page: -`$ man sar -$ man sadf` - -## Case Study: Identifying Linux Server CPU Bottlenecks - -With sar command and kSar tool, one can get the detailed snapshot of memory, CPU, and other subsystems. For example, if CPU utilization is more than 80% for a long period, a CPU bottleneck is most likely occurring. Using **sar -x ALL** you can find out CPU eating process. The output of [mpstat command][11] (part of sysstat package itself) will also help you understand the cpu utilization. You can easily analyze this information with kSar. - -### I Found CPU Bottlenecks… - -Performance tuning options for the CPU are as follows: - - 1. Make sure that no unnecessary programs are running in the background. Turn off [all unnecessary services on Linux][12]. - 2. Use [cron to schedule][13] jobs (e.g., backup) to run at off-peak hours. - 3. Use [top and ps command][14] to find out all non-critical background jobs / services. Make sure you lower their priority using [renice command][15]. - 4. Use [taskset command to set a processes's][16] CPU affinity (offload cpu) i.e. bind processes to different CPUs. For example, run MySQL database on cpu #2 and Apache on cpu # 3. - 5. Make sure you are using latest drivers and firmware for your server. - 6. If possible add additional CPUs to the system. - 7. Use faster CPUs for a single-threaded application (e.g. Lighttpd web server app). - 8. Use more CPUs for a multi-threaded application (e.g. MySQL database server app). - 9. Use more computer nodes and set up a [load balancer][17] for a web app. - - - -## isag - Interactive System Activity Grapher (alternate tool) - -The isag command graphically displays the system activity data stored in a binary data file by a previous sar run. The isag command invokes sar to extract the data to be plotted. isag has limited set of options as compare to kSar. - -![Fig.06: isag CPU utilization graphs][18] - - -### about the author - -The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][19], [Facebook][20], [Google+][21]. - --------------------------------------------------------------------------------- - -via: https://www.cyberciti.biz/tips/identifying-linux-bottlenecks-sar-graphs-with-ksar.html - -作者:[Vivek Gite][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.cyberciti.biz -[1]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info) -[2]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ -[3]:https://github.com/vlsi/ksar -[4]:https://www.cyberciti.biz/tips/linux-wget-your-ultimate-command-line-downloader.html -[5]:https://www.cyberciti.biz/faq/howto-ubuntu-linux-install-configure-jdk-jre/ -[6]:https://www.cyberciti.biz/media/new/tips/2009/12/sar-welcome.png (kSar welcome screen) -[7]:https://www.cyberciti.biz/media/new/tips/2009/12/screenshot-kSar-a-sar-grapher-01.png (kSar - the main window) -[8]:https://www.cyberciti.biz/media/new/tips/2009/12/cpu-ksar.png (Linux kSar Processes for server1 ) -[9]:https://www.cyberciti.biz/media/new/tips/2009/12/disk-stats-ksar.png (Linux Disk I/O Stats Using kSar) -[10]:https://www.cyberciti.biz/media/new/tips/2009/12/memory-ksar.png (Linux Memory paging and its utilization stats) -[11]:https://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html -[12]:https://www.cyberciti.biz/faq/check-running-services-in-rhel-redhat-fedora-centoslinux/ -[13]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ -[14]:https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/ -[15]:https://www.cyberciti.biz/faq/howto-change-unix-linux-process-priority/ -[16]:https://www.cyberciti.biz/faq/taskset-cpu-affinity-command/ -[17]:https://www.cyberciti.biz/tips/load-balancer-open-source-software.html -[18]:https://www.cyberciti.biz/media/new/tips/2009/12/isag.cpu_.png (Fig.06: isag CPU utilization graphs) -[19]:https://twitter.com/nixcraft -[20]:https://facebook.com/nixcraft -[21]:https://plus.google.com/+CybercitiBiz diff --git a/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md b/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md new file mode 100644 index 0000000000..4d67c5173b --- /dev/null +++ b/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md @@ -0,0 +1,350 @@ +如何使用 kSar 去创建 sar 图表来发现 Linux 瓶颈 +====== +sar 命令收集、报告、或者保存 UNIX / Linux 系统的活动信息。它保存选择的计数器到操作系统的 `/var/log/sa/sadd` 文件中。从收集的数据中,你可以得到许多关于你的服务器的信息: + + 1. CPU 使用率 + 2. 内存页面和使用率 + 3. 网络 I/O 和传输统计 + 4. 进程创建活动 + 5. 所有的块设备活动 + 6. 每秒中断数等等 + + + +sar 命令的输出能够用于识别服务器瓶颈。但是,分析 sar 命令提供的信息可能比较困难,所以要使用 kSar 工具。kSar 工具将 sar 命令的输出绘制成基于时间周期的、易于理解的图表。 + + +## sysstat 包 + +sar、sa1、和 sa2 命令都是 sysstat 包的一部分。它是 Linux 包含的性能监视工具集合。 + + 1. sar:显示数据 + 2. sa1 和 sa2:为以后分析去收集和保存数据。sa2 shell 脚本在 `/var/log/sa` 目录中每日写入一个报告。sa1 shell 脚本将每日的系统活动信息以二进制数据的形式写入到文件中。 + 3. sadc —— 系统活动数据收集器。你可以通过修改 sa1 和 sa2 脚本去配置各种选项。它们位于以下的目录: + * /usr/lib64/sa/sa1 (64bit) 或者 /usr/lib/sa/sa1 (32bit) —— 它调用 sadc 去记录报告到 /var/log/sa/sadX 格式。 + * /usr/lib64/sa/sa2 (64bit) 或者 /usr/lib/sa/sa2 (32bit) —— 它调用 sar 去记录报告到 /var/log/sa/sarX 格式。 + + + +### 如何在我的系统上安装 sar? + +在一个基于 CentOS/RHEL 的系统上,输入如下的 [yum 命令][1] 去安装 sysstat: +`# yum install sysstat` +示例输出如下: +``` +Loaded plugins: downloadonly, fastestmirror, priorities, + : protectbase, security +Loading mirror speeds from cached hostfile + * addons: mirror.cs.vt.edu + * base: mirror.ash.fastserv.com + * epel: serverbeach1.fedoraproject.org + * extras: mirror.cogentco.com + * updates: centos.mirror.nac.net +0 packages excluded due to repository protections +Setting up Install Process +Resolving Dependencies +--> Running transaction check +---> Package sysstat.x86_64 0:7.0.2-3.el5 set to be updated +--> Finished Dependency Resolution + +Dependencies Resolved + +==================================================================== + Package Arch Version Repository Size +==================================================================== +Installing: + sysstat x86_64 7.0.2-3.el5 base 173 k + +Transaction Summary +==================================================================== +Install 1 Package(s) +Update 0 Package(s) +Remove 0 Package(s) + +Total download size: 173 k +Is this ok [y/N]: y +Downloading Packages: +sysstat-7.0.2-3.el5.x86_64.rpm | 173 kB 00:00 +Running rpm_check_debug +Running Transaction Test +Finished Transaction Test +Transaction Test Succeeded +Running Transaction + Installing : sysstat 1/1 + +Installed: + sysstat.x86_64 0:7.0.2-3.el5 + +Complete! +``` + + +### 为 sysstat 配置文件 + +编辑 /etc/sysconfig/sysstat 文件去指定日志文件保存多少天(最长为一个月): +`# vi /etc/sysconfig/sysstat` +示例输出如下 : +``` +# keep log for 28 days +# the default is 7 +HISTORY=28 +``` + +保存并关闭这个文件。 + +### 找到 sar 默认的 cron 作业 + +[默认的 cron 作业位于][2] `/etc/cron.d/sysstat`: +`# cat /etc/cron.d/sysstat` +示例输出如下: +``` +# run system activity accounting tool every 10 minutes +*/10 * * * * root /usr/lib64/sa/sa1 1 1 +# generate a daily summary of process accounting at 23:53 +53 23 * * * root /usr/lib64/sa/sa2 -A +``` + +### 告诉 sadc 去报告磁盘的统计数据 + +使用一个文本编辑器去编辑 `/etc/cron.d/sysstat` 文件,比如使用 NA 命令或者 vim 命令,输入如下: +`# vi /etc/cron.d/sysstat` +像下面的示例那样更新这个文件,以记录所有的硬盘统计数据(`-d` 选项强制记录每个块设备的统计数据,而 `-I` 选项强制记录所有系统中断的统计数据): +``` +# run system activity accounting tool every 10 minutes +*/10 * * * * root /usr/lib64/sa/sa1 -I -d 1 1 +# generate a daily summary of process accounting at 23:53 +53 23 * * * root /usr/lib64/sa/sa2 -A +``` + +在一个 CentOS/RHEL 7.x 系统上你需要传递 `-S DISK` 选项去收集块设备的数据。传递`-S XALL` 选项去采集如下所列的数据: + + 1. 磁盘 + 2. 分区 + 3. 系统中断 + 4. SNMP + 5. IPv6 + + +``` +# Run system activity accounting tool every 10 minutes +*/10 * * * * root /usr/lib64/sa/sa1 -S DISK 1 1 +# 0 * * * * root /usr/lib64/sa/sa1 600 6 & +# Generate a daily summary of process accounting at 23:53 +53 23 * * * root /usr/lib64/sa/sa2 -A +# Run system activity accounting tool every 10 minutes +``` + +保存并关闭这个文件。 + +###打开 CentOS/RHEL 版本 5.x/6.x 的服务 + +输入如下命令: + +``` +chkconfig sysstat on +service sysstat start +``` + +示例输出如下: +``` +Calling the system activity data collector (sadc): +``` + +对于 CentOS/RHEL 7.x,运行如下的命令: +``` +# systemctl enable sysstat +# systemctl start sysstat.service +# systemctl status sysstat.service +``` +示例输出: +``` +● sysstat.service - Resets System Activity Logs + Loaded: loaded (/usr/lib/systemd/system/sysstat.service; enabled; vendor preset: enabled) + Active: active (exited) since Sat 2018-01-06 16:33:19 IST; 3s ago + Process: 28297 ExecStart=/usr/lib64/sa/sa1 --boot (code=exited, status=0/SUCCESS) + Main PID: 28297 (code=exited, status=0/SUCCESS) + +Jan 06 16:33:19 centos7-box systemd[1]: Starting Resets System Activity Logs... +Jan 06 16:33:19 centos7-box systemd[1]: Started Resets System Activity Logs. +``` + +## 如何使用 sar?如何查看统计数据? + +使用 sar 命令去显示操作系统中选定的累积活动计数器输出。在这个示例中,运行 sar 命令行,去实时获得 CPU 使用率的报告: +`# sar -u 3 10` +示例输出: +``` +Linux 2.6.18-164.2.1.el5 (www-03.nixcraft.in) 12/14/2009 + +09:49:47 PM CPU %user %nice %system %iowait %steal %idle +09:49:50 PM all 5.66 0.00 1.22 0.04 0.00 93.08 +09:49:53 PM all 12.29 0.00 1.93 0.04 0.00 85.74 +09:49:56 PM all 9.30 0.00 1.61 0.00 0.00 89.10 +09:49:59 PM all 10.86 0.00 1.51 0.04 0.00 87.58 +09:50:02 PM all 14.21 0.00 3.27 0.04 0.00 82.47 +09:50:05 PM all 13.98 0.00 4.04 0.04 0.00 81.93 +09:50:08 PM all 6.60 6.89 1.26 0.00 0.00 85.25 +09:50:11 PM all 7.25 0.00 1.55 0.04 0.00 91.15 +09:50:14 PM all 6.61 0.00 1.09 0.00 0.00 92.31 +09:50:17 PM all 5.71 0.00 0.96 0.00 0.00 93.33 +Average: all 9.24 0.69 1.84 0.03 0.00 88.20 +``` + +其中: + + * 3 = 间隔时间 + * 10 = 次数 + + + +查看进程创建的统计数据,输入: +`# sar -c 3 10` +查看 I/O 和传输率统计数据,输入: +`# sar -b 3 10` +查看内存页面统计数据,输入: +`# sar -B 3 10` +查看块设备统计数据,输入: +`# sar -d 3 10` +查看所有中断的统计数据,输入: +`# sar -I XALL 3 10` +查看网络设备特定的统计数据,输入: +``` +# sar -n DEV 3 10 +# sar -n EDEV 3 10 +``` +查看 CPU 特定的统计数据,输入: +``` +# sar -P ALL +# Only 1st CPU stats +# sar -P 1 3 10 +``` +查看队列长度和平均负载的统计数据,输入: +`# sar -q 3 10` +查看内存和 swap 空间的使用统计数据,输入: +``` +# sar -r 3 10 +# sar -R 3 10 +``` +查看 inode、文件、和其它内核表统计数据状态,输入: +`# sar -v 3 10` +查看系统切换活动统计数据,输入: +`# sar -w 3 10` +查看 swapping 统计数据,输入: +`# sar -W 3 10` +查看一个 PID 为 3256 的 Apache 进程,输入: +`# sar -x 3256 3 10` + +## kSar 介绍 + +sar 和 sadf 提供了基于命令行界面的输出。这种输出可能会使新手用户/系统管理员感到无从下手。因此,你需要使用 kSar,它是一个图形化显示你的 sar 数据的 Java 应用程序。它也允许你以 PDF/JPG/PNG/CSV 格式导出数据。你可以用三种方式去加载数据:本地文件、运行本地命令、以及通过 SSH 远程运行的命令。kSar 可以处理下列操作系统的 sar 输出: + + 1. Solaris 8, 9 和 10 + 2. Mac OS/X 10.4+ + 3. Linux (Systat Version >= 5.0.5) + 4. AIX (4.3 & 5.3) + 5. HPUX 11.00+ + + + +### 下载和安装 kSar + +访问 [官方][3] 网站去获得最新版本的源代码。使用 [wget][4] 去下载源代码,输入: +`$ wget https://github.com/vlsi/ksar/releases/download/v5.2.4-snapshot-652bf16/ksar-5.2.4-SNAPSHOT-all.jar` + +#### 如何运行 kSar? + +首先要确保你的机器上 [JAVA jdk][5] 已安装并能够正常工作。输入下列命令去启动 kSar: +`$ java -jar ksar-5.2.4-SNAPSHOT-all.jar` + +![Fig.01: kSar welcome screen][6] +接下来你将看到 kSar 的主窗口,和有两个菜单的面板。 +![Fig.02: kSar - the main window][7] +左侧有一个列表,是 kSar 根据数据已经解析出的可用图表的列表。右侧窗口将展示你选定的图表。 + +## 如何使用 kSar 去生成 sar 图表? + +首先,你需要从命名为 server1 的服务器上采集 sar 命令的统计数据。输入如下的命令: +`[ **server1** ]# LC_ALL=C sar -A > /tmp/sar.data.txt` +接下来,使用 scp 命令从本地桌面拷贝到远程电脑上: +`[ **desktop** ]$ scp user@server1.nixcraft.com:/tmp/sar.data.txt /tmp/` +切换到 kSar 窗口,点击 **Data** > **Load data from text file** > 从 /tmp/ 中选择 sar.data.txt > 点击 **Open** 按扭。 +现在,图表类型树已经出现在左侧面板中并选定了一个图形: +![Fig.03: Processes for server1][8] + +![Fig.03: Disk stats \(blok device\) stats for server1][9]![Fig.05: Memory stats for server1][10] + +#### 放大和缩小 + +通过移动你可以交互式缩放图像的一部分。在要缩放的图像的左上角点击并按下鼠标,移动到要缩放区域的右下角,可以选定要缩放的区域。返回到未缩放状态,点击并拖动鼠标到除了右下角外的任意位置,你也可以点击并选择 zoom 选项。 + +#### 了解 kSar 图像和 sar 数据 + +我强烈建议你去阅读 sar 和 sadf 命令的 man 页面: +``` +$ man sar +$ man sadf +``` + +## 案例学习:识别 Linux 服务器的 CPU 瓶颈 + +使用 sar 命令和 kSar 工具,可以得到内存、CPU、以及其它子系统的详细快照。例如,如果 CPU 使用率在一个很长的时间内持续高于 80%,有可能就是出现了一个 CPU 瓶颈。使用 **sar -x ALL** 你可以找到大量消耗 CPU 的进程。[mpstat 命令][11] 的输出(sysstat 包的一部分)也会帮你去了解 CPU 的使用率。你可以使用 kSar 很容易地去分析这些信息。 + +### 找出 CPU 瓶颈 … + +然后对 CPU 选择执行如下的调整: + + 1. 确保没有不需要的进程在后台运行。关闭 [Linux 上所有不需要的服务][12]。 + 2. 使用 [cron 去计划作业][13] (比如,备份)运行在一个非高峰时刻。 + 3. 使用 [top 和 ps 命令][14] 去找出所有非关键的后台作业/服务。使用 [renice 命令][15] 去调整低优先级作业。 + 4. 使用 [taskset 命令去设置进程使用的 CPU ][16] (卸载 CPU),即,绑定进程到不同的 CPU 上。例如,在 2# CPU 上运行 MySQL 数据库,而在 3# CPU 上运行 Apache。 + 5. 确保你的系统使用了最新的驱动程序和固件。 + 6. 如有可能在系统上增加额外的 CPU。 + 7. 为单线程应用程序使用更快的 CPU(比如,Lighttpd web 服务器应用程序)。 + 8. 为多线程应用程序使用多个 CPU(比如,MySQL 数据库服务器应用程序)。 + 9. 为一个 web 应用程序使用多个计算节点并设置一个 [负载均衡器][17]。 + + + +## isag —— 交互式系统活动记录器(替代工具) + +isag 命令图形化显示了以前运行 sar 命令时存储在二进制文件中的系统活动数据。isag 命令引用 sar 并提取出它的数据来绘制图形。与 kSar 相比,isag 的选项比较少。 + +![Fig.06: isag CPU utilization graphs][18] + + +### 关于作者 + +本文作者是 nixCraft 的创始人和一位经验丰富的 Linux 操作系统/Unix shell 脚本培训师。他与包括 IT、教育、国防和空间研究、以及非营利组织等全球各行业客户一起合作。可以在 [Twitter][19]、[Facebook][20]、[Google+][21] 上关注他。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/identifying-linux-bottlenecks-sar-graphs-with-ksar.html + +作者:[Vivek Gite][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info" +[2]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ +[3]:https://github.com/vlsi/ksar +[4]:https://www.cyberciti.biz/tips/linux-wget-your-ultimate-command-line-downloader.html +[5]:https://www.cyberciti.biz/faq/howto-ubuntu-linux-install-configure-jdk-jre/ +[6]:https://www.cyberciti.biz/media/new/tips/2009/12/sar-welcome.png "kSar welcome screen" +[7]:https://www.cyberciti.biz/media/new/tips/2009/12/screenshot-kSar-a-sar-grapher-01.png "kSar - the main window" +[8]:https://www.cyberciti.biz/media/new/tips/2009/12/cpu-ksar.png "Linux kSar Processes for server1 " +[9]:https://www.cyberciti.biz/media/new/tips/2009/12/disk-stats-ksar.png "Linux Disk I/O Stats Using kSar" +[10]:https://www.cyberciti.biz/media/new/tips/2009/12/memory-ksar.png "Linux Memory paging and its utilization stats" +[11]:https://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html +[12]:https://www.cyberciti.biz/faq/check-running-services-in-rhel-redhat-fedora-centoslinux/ +[13]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ +[14]:https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/ +[15]:https://www.cyberciti.biz/faq/howto-change-unix-linux-process-priority/ +[16]:https://www.cyberciti.biz/faq/taskset-cpu-affinity-command/ +[17]:https://www.cyberciti.biz/tips/load-balancer-open-source-software.html +[18]:https://www.cyberciti.biz/media/new/tips/2009/12/isag.cpu_.png "Fig.06: isag CPU utilization graphs" +[19]:https://twitter.com/nixcraft +[20]:https://facebook.com/nixcraft +[21]:https://plus.google.com/+CybercitiBiz From 1e1e8aa9f5e2eaf5e908bd4d8f9a3d8f9c0fe110 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Mar 2018 17:21:42 +0800 Subject: [PATCH 058/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Evolutional=20Ste?= =?UTF-8?q?ps=20of=20Computer=20Systems?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0 Evolutional Steps of Computer Systems.md | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 sources/talk/20170210 Evolutional Steps of Computer Systems.md diff --git a/sources/talk/20170210 Evolutional Steps of Computer Systems.md b/sources/talk/20170210 Evolutional Steps of Computer Systems.md new file mode 100644 index 0000000000..16c3f0480a --- /dev/null +++ b/sources/talk/20170210 Evolutional Steps of Computer Systems.md @@ -0,0 +1,112 @@ +Evolutional Steps of Computer Systems +====== +Throughout the history of the modern computer, there were several evolutional steps related to the way we interact with the system. I tend to categorize those steps as following: + + 1. Numeric Systems + 2. Application-Specific Systems + 3. Application-Centric Systems + 4. Information-Centric Systems + 5. Application-Less Systems + + + +Following sections describe how I see those categories. + +### Numeric Systems + +[Early computers][1] were designed with numbers in mind. They could add, subtract, multiply, divide. Some of them were able to perform more complex mathematical operations such as differentiate or integrate. + +If you map characters to numbers, they were able to «compute» [strings][2] as well but this is somewhat «creative use of numbers» instead of meaningful processing arbitrary information. + +### Application-Specific Systems + +For higher-level problems, pure numeric systems are not sufficient. Application-specific systems were developed to do one single task. They were very similar to numeric systems. However, with sufficiently complex number calculations, systems were able to accomplish very well-defined higher level tasks such as calculations related to scheduling problems or other optimization problems. + +Systems of this category were built for one single purpose, one distinct problem they solved. + +### Application-Centric Systems + +Systems that are application-centric are the first real general purpose systems. Their main usage style is still mostly application-specific but with multiple applications working either time-sliced (one app after another) or in multi-tasking mode (multiple apps at the same time). + +Early personal computers [from the 70s][3] of the previous century were the first application-centric systems that became popular for a wide group of people. + +Yet modern operating systems - Windows, macOS, most GNU/Linux desktop environments - still follow the same principles. + +Of course, there are sub-categories as well: + + 1. Strict Application-Centric Systems + 2. Loose Application-Centric Systems + + + +Strict application-centric systems such as [Windows 3.1][4] (Program Manager and File Manager) or even the initial version of [Windows 95][5] had no pre-defined folder hierarchy. The user did start text processing software like [WinWord][6] and saved the files in the program folder of WinWord. When working with a spreadsheet program, its files were saved in the application folder of the spreadsheet tool. And so on. Users did not create their own hierarchy of folders mostly because of convenience, laziness, or because they did not saw any necessity. The number of files per user were sill within dozens up to a few hundreds. + +For accessing information, the user typically opened an application and within the application, the files containing the generated data were retrieved using file/open. + +It was [Windows 95][5] SP2 that introduced «[My Documents][7]» for the Windows platform. With this file hierarchy template, application designers began switching to «My Documents» as a default file save/open location instead of using the software product installation path. This made the users embrace this pattern and start to maintain folder hierarchies on their own. + +This resulted in loose application-centric systems: typical file retrieval is done via a file manager. When a file is opened, the associated application is started by the operating system. It is a small or subtle but very important usage shift. Application-centric systems are still the dominant usage pattern for personal computers. + +Nevertheless, this pattern comes with many disadvantages. For example in order to prevent data retrieval problems, there is the need to maintain a strict hierarchy of folders that contain all related files of a given project. Unfortunately, nature does not fit well in strict hierarchy of folders. Further more, [this does not scale well][8]. Desktop search engines and advanced data organizing tools like [tagstore][9] are able to smooth the edged a bit. As studies show, only a minority of users are using such advanced retrieval tools. Most users still navigate through the file system without using any alternative or supplemental retrieval techniques. + +### Information-Centric Systems + +One possible way of dealing with the issue that a certain topic needs to have a folder that holds all related files is to switch from an application-centric system to an information-centric systems. + +Instead of opening a spreadsheet application to work with the project budget, opening a word processor application to write the project report, and opening another tool to work with image files, an information-centric system combines all the information on the project in one place, in one application. + +The calculations for the previous month is right beneath notes from a client meeting which is right beneath a photography of the whiteboard notes which is right beneath some todo tasks. Without any application or file border in between. + +Early attempts to create such an environment were IBM [OS/2][10], Microsoft [OLE][11] or [NeXT][12]. None of them were a major success for a variety of reasons. A very interesting information-centric environment is [Acme][13] from [Plan 9][14]. It combines [a wide variety of applications][15] within one application but it never reached a notable distribution even with its ports to Windows or GNU/Linux. + +Modern approaches for an information-centric system are advanced [personal wikis][16] like [TheBrain][17] or [Microsoft OneNote][18]. + +My personal tool of choice is the [GNU/Emacs][19] platform with its [Org-mode][19] extension. I hardly leave Org-mode when I work with my computer. For accessing external data sources, I created [Memacs][20] which brings me a broad variety of data into Org-mode. I love to do spreadsheet calculations right beneath scheduled tasks, in-line images, internal and external links, and so forth. It is truly an information-centric system where the user doesn't have to deal with application borders or strictly hierarchical file-system folders. Multi-classifications is possible using simple or advanced tagging. All kinds of views can be derived with a single command. One of those views is my calendar, the agenda. Another derived view is the list of borrowed things. And so on. There are no limits for Org-mode users. If you can think of it, it is most likely possible within Org-mode. + +Is this the end of the evolution? Certainly not. + +### Application-Less Systems + +I can think of a class of systems which I refer to as application-less systems. As the next logical step, there is no need to have single-domain applications even when they are as capable as Org-mode. The computer offers a nice to use interface to information and features, not files and applications. Even a classical operating system is not accessible. + +Application-less systems might as well be combined with [artificial intelligence][21]. Think of it as some kind of [HAL 9000][22] from [A Space Odyssey][23]. Or [LCARS][24] from Star Trek. + +It is hard to believe that there is a transition between our application-based, vendor-based software culture and application-less systems. Maybe the open source movement with its slow but constant development will be able to form a truly application-less environment where all kinds of organizations and people are contributing to. + +Information and features to retrieve and manipulate information, this is all it takes. This is all we need. Everything else is just limiting distraction. + +-------------------------------------------------------------------------------- + +via: http://karl-voit.at/2017/02/10/evolution-of-systems/ + +作者:[Karl Voit][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://karl-voit.at +[1]:https://en.wikipedia.org/wiki/History_of_computing_hardware +[2]:https://en.wikipedia.org/wiki/String_%2528computer_science%2529 +[3]:https://en.wikipedia.org/wiki/Xerox_Alto +[4]:https://en.wikipedia.org/wiki/Windows_3.1x +[5]:https://en.wikipedia.org/wiki/Windows_95 +[6]:https://en.wikipedia.org/wiki/Microsoft_Word +[7]:https://en.wikipedia.org/wiki/My_Documents +[8]:http://karl-voit.at/tagstore/downloads/Voit2012b.pdf +[9]:http://karl-voit.at/tagstore/ +[10]:https://en.wikipedia.org/wiki/OS/2 +[11]:https://en.wikipedia.org/wiki/Object_Linking_and_Embedding +[12]:https://en.wikipedia.org/wiki/NeXT +[13]:https://en.wikipedia.org/wiki/Acme_%2528text_editor%2529 +[14]:https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs +[15]:https://en.wikipedia.org/wiki/List_of_Plan_9_applications +[16]:https://en.wikipedia.org/wiki/Personal_wiki +[17]:https://en.wikipedia.org/wiki/TheBrain +[18]:https://en.wikipedia.org/wiki/Microsoft_OneNote +[19]:../../../../tags/emacs +[20]:https://github.com/novoid/Memacs +[21]:https://en.wikipedia.org/wiki/Artificial_intelligence +[22]:https://en.wikipedia.org/wiki/HAL_9000 +[23]:https://en.wikipedia.org/wiki/2001:_A_Space_Odyssey +[24]:https://en.wikipedia.org/wiki/LCARS From 40b19f517e8952d466cde70ac1c81cd63547287d Mon Sep 17 00:00:00 2001 From: Auk7F7 <34982730+Auk7F7@users.noreply.github.com> Date: Thu, 1 Mar 2018 20:47:47 +0800 Subject: [PATCH 059/101] Delete 20180221 Create a wiki on your Linux desktop with Zim.md --- ...e a wiki on your Linux desktop with Zim.md | 117 ------------------ 1 file changed, 117 deletions(-) delete mode 100644 sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md diff --git a/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md b/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md deleted file mode 100644 index 4b01a80721..0000000000 --- a/sources/tech/20180221 Create a wiki on your Linux desktop with Zim.md +++ /dev/null @@ -1,117 +0,0 @@ -translating by Auk7F7 - -Create a wiki on your Linux desktop with Zim -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_bees_network.png?itok=NFNRQpJi) - -There's no denying the usefulness of a wiki, even to a non-geek. You can do so much with one—write notes and drafts, collaborate on projects, build complete websites. And so much more. - -I've used more than a few wikis over the years, either for my own work or at various contract and full-time gigs I've held. While traditional wikis are fine, I really like the idea of [desktop wikis][1] . They're small, easy to install and maintain, and even easier to use. And, as you've probably guessed, there are a number a desktop wikis available for Linux. - -Let's take a look at one of the better desktop wikis: [Zim][2]. - -### Getting going - -You can either [download][3] and install Zim from the software's website, or do it the easy way and install it through your distro's package manager. - -Once Zim's installed, start it up. - -A key concept in Zim is notebooks. They're like a collection of wiki pages on a single subject. When you first start Zim, it asks you to specify a folder for your notebooks and the name of a notebook. Zim suggests "Notes" for the name, and `~/Notebooks/` for the folder. Change that if you want. I did. - -![](https://opensource.com/sites/default/files/u128651/zim1.png) - -After you set the name and the folder for your notebook, click **OK**. You get what's essentially a container for your wiki pages. - -![](https://opensource.com/sites/default/files/u128651/zim2.png) - -### Adding pages to a notebook - -So you have a container. Now what? You start adding pages to it, of course. To do that, select **File > New Page**. - -![](https://opensource.com/sites/default/files/u128651/zim3.png) - -Enter a name for the page, then click **OK**. From there, you can start typing to add information to that page. - -![](https://opensource.com/sites/default/files/u128651/zim4.png) - -That page can be whatever you want it to be: notes for a course you're taking, the outline for a book or article or essay, or an inventory of your books. It's up to you. - -Zim has a number of formatting options, including: - - * Headings - * Character formatting - * Bullet and numbered lists - * Checklists - - - -You can also add images and attach files to your wiki pages, and even pull in text from a text file. - -### Zim's wiki syntax - -You can add formatting to a page using the toolbar, but that's not the only way to do the deed. If, like me, you're kind of old school, you can use wiki markup for formatting. - -[Zim's markup][4] is based on the markup that's used with [DokuWiki][5]. It's essentially [WikiText][6] with a few minor variations. To create a bullet list, for example, type an asterisk. Surround a word or a phrase with two asterisks to make it bold. - -### Adding links - -If you have a number of pages in a notebook, it's easy to link them. There are two ways to do that. - -The first way is to use [CamelCase][7] to name the pages. Let's say I have a notebook called "Course Notes." I can rename the notebook for the data analysis course I'm taking by typing "AnalysisCourse." When I want to link to it from another page in the notebook, I just type "AnalysisCourse" and press the space bar. Instant hyperlink. - -The second way is to click the **Insert link** button on the toolbar. Type the name of the page you want to link to in the **Link to** field, select it from the displayed list of options, then click **Link**. - -![](https://opensource.com/sites/default/files/u128651/zim5.png) - -I've only been able to link between pages in the same notebook. Whenever I've tried to link to a page in another notebook, the file (which has the extension .txt) always opens in a text editor. - -### Exporting your wiki pages - -There might come a time when you want to use the information in a notebook elsewhere—say, in a document or on a web page. Instead of copying and pasting (and losing formatting), you can export your notebook pages to any of the following formats: - - * HTML - * LaTeX - * Markdown - * ReStructuredText - - - -To do that, click on the wiki page you want to export. Then, select **File > Export**. Decide whether to export the whole notebook or just a single page, then click **Forward**. - -![](https://opensource.com/sites/default/files/u128651/zim6.png) - -Select the file format you want to use to save the page or notebook. With HTML and LaTeX, you can choose a template. Play around to see what works best for you. For example, if you want to turn your wiki pages into HTML presentation slides, you can choose "SlideShow_s5" from the **Template** list. If you're wondering, that produces slides driven by the [S5 slide framework][8]. - -![](https://opensource.com/sites/default/files/u128651/zim7.png) - -Click **Forward**. If you're exporting a notebook, you can choose to export the pages as individual files or as one file. You can also point to the folder where you want to save the exported file. - -![](https://opensource.com/sites/default/files/u128651/zim8.png) - -### Is that all Zim can do? - -Not even close. Zim also has a number of [plugins][9] that expand its capabilities. It even packs a built-in web server that lets you view your notebooks as static HTML files. This is useful for sharing your pages and notebooks on an internal network. - -All in all, Zim is a powerful, yet compact tool for managing your information. It's easily the best desktop wiki I've used, and it's one that I keep going back to. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/2/create-wiki-your-linux-desktop-zim - -作者:[Scott Nesbitt][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/scottnesbitt -[1]:https://opensource.com/article/17/2/3-desktop-wikis -[2]:http://zim-wiki.org/ -[3]:http://zim-wiki.org/downloads.html -[4]:http://zim-wiki.org/manual/Help/Wiki_Syntax.html -[5]:https://www.dokuwiki.org/wiki:syntax -[6]:http://en.wikipedia.org/wiki/Wikilink -[7]:https://en.wikipedia.org/wiki/Camel_case -[8]:https://meyerweb.com/eric/tools/s5/ -[9]:http://zim-wiki.org/manual/Plugins.html From 08bfb3ca17c3a07b5e49d0a99f408b65b2250fe0 Mon Sep 17 00:00:00 2001 From: Auk7F7 <34982730+Auk7F7@users.noreply.github.com> Date: Thu, 1 Mar 2018 20:48:55 +0800 Subject: [PATCH 060/101] Create 20180221 Create a wiki on your Linux desktop with Zim.md translated by Auk7F7 --- ...e a wiki on your Linux desktop with Zim.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 translated/tech/20180221 Create a wiki on your Linux desktop with Zim.md diff --git a/translated/tech/20180221 Create a wiki on your Linux desktop with Zim.md b/translated/tech/20180221 Create a wiki on your Linux desktop with Zim.md new file mode 100644 index 0000000000..b979630754 --- /dev/null +++ b/translated/tech/20180221 Create a wiki on your Linux desktop with Zim.md @@ -0,0 +1,116 @@ + +使用 Zim 在你的 Linux 桌面上创建一个 wiki +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_bees_network.png?itok=NFNRQpJi) + +不可否认 wiki 的用处,即使对于一个极客来说也是如此。你可以用它做很多事——写笔记和手稿,协作项目,建立完整的网站。还有更多的事。 + +这些年来,我已经使用了超过几条维基百科,要么是为了我自己的工作,要么就是为了我所持有的各种合约和全职工作。虽然传统的维基很好,但我真的喜欢[桌面版 wiki][1] 这个想法。它们体积小,易于安装和维护,甚至更容易使用。而且,正如你可能猜到的那样,Linux 中有许多可用的桌面版 wiki。 + +让我们来看看更好的桌面版的 wiki 之一: [Zim][2]。 + +### 开始吧 + +你可以从 Zim 的官网[下载][3]并安装 Zim,或者通过发行版的软件包管理器轻松地安装。 + +一旦安装了 Zim,就启动它。 + +在 Zim 中的一个关键概念是笔记本,它们就像一个主题上的 wiki 页面的集合。当你第一次启动 Zim 时,它要求你为你的笔记本指定一个文件夹和笔记本的名称。Zim 建议用 "Notes" 来表示文件夹的名称和指定文件夹为`~/Notebooks/`。如果你愿意,你可以改变它。我是这么做的。 + +![](https://opensource.com/sites/default/files/u128651/zim1.png) + +在为笔记本设置好名称和指定好文件夹后,单击 **OK** 。你得到的本质上是你的 wiki 页面的容器。 + +![](https://opensource.com/sites/default/files/u128651/zim2.png) + +### 将页面添加到笔记本 + +所以你有了一个容器。那现在怎么办?你应该开始往里面添加页面。当然,为此,选择 **File > New Page**。 + +![](https://opensource.com/sites/default/files/u128651/zim3.png) + +输入该页面的名称,然后单击 **OK**。从那里开始,你可以开始输入信息以向该页面添加信息。 + +![](https://opensource.com/sites/default/files/u128651/zim4.png) + +这一页可以是你想要的任何内容:你正在选修的课程的笔记,一本书或者一片文章或论文的大纲,或者是你的书的清单。这取决于你。 + +Zim 有一些格式化的选项,其中包括: + + * 标题 + * 字符格式 + * 子弹和编号清单 + * 核对清单 + + + +你可以添加图片和附加文件到你的 wiki 页面,甚至可以从文本文件中提取文本。 + +### Zim 的 wiki 语法 + +你可以使用工具栏向一个页面添加格式。但这不是唯一的方法。如果你像我一样是个老派人士,你可以使用 wiki 标记来进行格式化。 + +[Zim 的标记][4] 是基于在 [DokuWiki][5] 中使用的标记。它本质上是有一些小变化的 [WikiText][6] 。例如,要创建一个子弹列表,输入一个星号(*)。用两个星号包围一个单词或短语来使它加黑。 + +### 添加链接 + +如果你在笔记本上有一些页面,很容易将它们联系起来。有两种方法可以做到这一点。 + +第一种方法是使用 [CamelCase][7] 来命名这些页面。假设我有个叫做 "Course Notes." 的笔记本。我可以通过输入 "AnalysisCourse." 来重命名我正在学习的数据分析课程。 当我想从笔记本的另一个页面链接到它时,我只需要输入 "AnalysisCourse" 然后按下空格键。即时超链接。 + +第二种方法是点击工具栏上的 **Insert link** 按钮。 在 **Link to** 中输入你想要链接到的页面的名称,从显示的列表中选择它,然后点击 **Link**。 + +![](https://opensource.com/sites/default/files/u128651/zim5.png) + +我只能在同一个笔记本中的页面之间进行链接。每当我试图连接到另一个笔记本中的一个页面时,这个文件(有 .txt 的后缀名)总是在文本编辑器中被打开。 + +### 输出你的 wiki 页面 + +也许有一天你会想在别的地方使用笔记本上的信息ーー比如, 在一份文件或网页上。你可以将笔记本页面导出到以下格式中的任何一种, 而不是复制和粘贴(和丢失格式) : + + * HTML + * LaTeX + * Markdown + * ReStructuredText + + + +为此,点击你想要导出的 wiki 页面。然后,选择 **File > Export**。决定是要导出整个笔记本还是一个页面,然后点击 **Forward**。 + +![](https://opensource.com/sites/default/files/u128651/zim6.png) + +选择要用来保存页面或笔记本的文件格式。 使用 HTML 和 LaTeX,你可以选择一个模板。 随便看看什么最适合你。 例如, 如果你想把你的 wiki 页面变成 HTML 演示幻灯片, 你可以在 **Template** 中选择 "SlideShow s5"。 如果你想知道, 这会产生由 [S5 幻灯片框架][8]驱动的幻灯片。 + +![](https://opensource.com/sites/default/files/u128651/zim7.png) + +点击 **Forward**,如果你在导出一个笔记本, 你可以选择将页面作为单个文件或一个文件导出。 你还可以指向要保存导出文件的文件夹。 + +![](https://opensource.com/sites/default/files/u128651/zim8.png) + +### Zim 能做的就这些吗? + +远远不止这些,还有一些 [插件][9] 可以扩展它的功能。它甚至包含一个内置的 Web 服务器,可以让你将你的笔记本作为静态的 HTML 文件。这对于在内部网络上分享你的页面和笔记本是非常有用的。 + +总的来说,Zim 是一个用来管理你的信息的强大而又紧凑的工具。这是我使用过的最好的桌面版 wik ,而且我一直在使用它。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/create-wiki-your-linux-desktop-zim + +作者:[Scott Nesbitt][a] +译者:[Auk7F7](https://github.com/Auk7F7) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/scottnesbitt +[1]:https://opensource.com/article/17/2/3-desktop-wikis +[2]:http://zim-wiki.org/ +[3]:http://zim-wiki.org/downloads.html +[4]:http://zim-wiki.org/manual/Help/Wiki_Syntax.html +[5]:https://www.dokuwiki.org/wiki:syntax +[6]:http://en.wikipedia.org/wiki/Wikilink +[7]:https://en.wikipedia.org/wiki/Camel_case +[8]:https://meyerweb.com/eric/tools/s5/ +[9]:http://zim-wiki.org/manual/Plugins.html From cbdaffcf4d17c302bf5dc61f2f7a3cf559f1975b Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Mar 2018 22:11:07 +0800 Subject: [PATCH 061/101] PRF:20170921 How to answer questions in a helpful way.md @HardworkFish --- ...ow to answer questions in a helpful way.md | 109 ++++++------------ 1 file changed, 38 insertions(+), 71 deletions(-) diff --git a/translated/tech/20170921 How to answer questions in a helpful way.md b/translated/tech/20170921 How to answer questions in a helpful way.md index acc67fd10c..41436b0a90 100644 --- a/translated/tech/20170921 How to answer questions in a helpful way.md +++ b/translated/tech/20170921 How to answer questions in a helpful way.md @@ -1,28 +1,21 @@ - 如何提供有帮助的回答 ============================= -如果你的同事问你一个不太清晰的问题,你会怎么回答?我认为提问题是一种技巧(可以看 [如何提出有意义的问题][1]) 同时,合理地回答问题也是一种技巧。他们都是非常实用的。 +如果你的同事问你一个不太清晰的问题,你会怎么回答?我认为提问题是一种技巧(可以看 [如何提出有意义的问题][1]) 同时,合理地回答问题也是一种技巧,它们都是非常实用的。 -一开始 - 有时向你提问的人不尊重你的时间,这很糟糕。 - -理想情况下,我们假设问你问题的人是一个理性的人并且正在尽力解决问题而你想帮助他们。和我一起工作的人是这样,我所生活的世界也是这样。当然,现实生活并不是这样。 +一开始 —— 有时向你提问的人不尊重你的时间,这很糟糕。理想情况下,我们假设问你问题的人是一个理性的人并且正在尽力解决问题,而你想帮助他们。和我一起工作的人是这样,我所生活的世界也是这样。当然,现实生活并不是这样。 下面是有助于回答问题的一些方法! - -### 如果他们提问不清楚,帮他们澄清 +### 如果他们的提问不清楚,帮他们澄清 通常初学者不会提出很清晰的问题,或者问一些对回答问题没有必要信息的问题。你可以尝试以下方法 澄清问题: -* ** 重述为一个更明确的问题 ** 来回复他们(”你是想问 X 吗?“) - -* ** 向他们了解更具体的他们并没有提供的信息 ** (”你使用 IPv6 ?”) - -* ** 问是什么导致了他们的问题 ** 例如,有时有些人会进入我的团队频道,询问我们的服务发现(service discovery )如何工作的。这通常是因为他们试图设置/重新配置服务。在这种情况下,如果问“你正在使用哪种服务?可以给我看看你正在处理的 pull requests 吗?”是有帮助的。 - -这些方法很多来自 [如何提出有意义的问题][2]中的要点。(尽管我永远不会对某人说“噢,你得先看完 “如何提出有意义的问题”这篇文章后再来像我提问) +* **重述为一个更明确的问题**来回复他们(“你是想问 X 吗?”) +* **向他们了解更具体的他们并没有提供的信息** (“你使用 IPv6 ?”) +* **问是什么导致了他们的问题**。例如,有时有些人会进入我的团队频道,询问我们的服务发现service discovery如何工作的。这通常是因为他们试图设置/重新配置服务。在这种情况下,如果问“你正在使用哪种服务?可以给我看看你正在处理的‘拉取请求’吗?”是有帮助的。 +这些方法很多来自[如何提出有意义的问题][2]中的要点。(尽管我永远不会对某人说“噢,你得先看完《如何提出有意义的问题》这篇文章后再来向我提问) ### 弄清楚他们已经知道了什么 @@ -30,66 +23,54 @@ Harold Treen 给了我一个很好的例子: -> 前几天,有人请我解释“ Redux-Sagas ”。与其深入解释不如说“ 他们就像 worker threads 监听行为(actions),让你更新 Redux store 。 +> 前几天,有人请我解释 “Redux-Sagas”。与其深入解释,不如说 “它们就像监听 action 的工人线程,并可以让你更新 Redux store。 -> 我开始搞清楚他们对 Redux 、行为(actions)、store 以及其他基本概念了解多少。将这些概念都联系在一起再来解释会容易得多。 +> 我开始搞清楚他们对 Redux、action、store 以及其他基本概念了解多少。将这些概念都联系在一起再来解释会容易得多。 -弄清楚问你问题的人已经知道什么是非常重要的。因为有时他们可能会对基础概念感到疑惑(“ Redux 是什么?“),或者他们可能是专家但是恰巧遇到了微妙的极端情况(corner case)。如果答案建立在他们不知道的概念上会令他们困惑,但如果重述他们已经知道的的又会是乏味的。 +弄清楚问你问题的人已经知道什么是非常重要的。因为有时他们可能会对基础概念感到疑惑(“Redux 是什么?”),或者他们可能是专家,但是恰巧遇到了微妙的极端情况corner case。如果答案建立在他们不知道的概念上会令他们困惑,但如果重述他们已经知道的的又会是乏味的。 这里有一个很实用的技巧来了解他们已经知道什么 - 比如可以尝试用“你对 X 了解多少?”而不是问“你知道 X 吗?”。 - ### 给他们一个文档 -“RTFM” (“去读那些他妈的手册”(Read The Fucking Manual))是一个典型的无用的回答,但事实上如果向他们指明一个特定的文档会是非常有用的!当我提问题的时候,我当然很乐意翻看那些能实际解决我的问题的文档,因为它也可能解决其他我想问的问题。 +“RTFM” (“去读那些他妈的手册”Read The Fucking Manual)是一个典型的无用的回答,但事实上如果向他们指明一个特定的文档会是非常有用的!当我提问题的时候,我当然很乐意翻看那些能实际解决我的问题的文档,因为它也可能解决其他我想问的问题。 我认为明确你所给的文档的确能够解决问题是非常重要的,或者至少经过查阅后确认它对解决问题有帮助。否则,你可能将以下面这种情形结束对话(非常常见): * Ali:我应该如何处理 X ? +* Jada:\<文档链接> +* Ali: 这个没有实际解释如何处理 X ,它仅仅解释了如何处理 Y ! -* Jada:<文档链接> - -* Ali: 这个并有实际解释如何处理 X ,它仅仅解释了如何处理 Y ! - -如果我所给的文档特别长,我会指明文档中那个我将会谈及的特定部分。[bash 手册][3] 有44000个字(真的!),所以如果只说“它在 bash 手册中有说明”是没有帮助的:) - +如果我所给的文档特别长,我会指明文档中那个我将会谈及的特定部分。[bash 手册][3] 有 44000 个字(真的!),所以如果只说“它在 bash 手册中有说明”是没有帮助的 :) ### 告诉他们一个有用的搜索 -在工作中,我经常发现我可以利用我所知道的关键字进行搜索找到能够解决我的问题的答案。对于初学者来说,这些关键字往往不是那么明显。所以说“这是我用来寻找这个答案的搜索”可能有用些。再次说明,回答时请经检查后以确保搜索能够得到他们所需要的答案:) - +在工作中,我经常发现我可以利用我所知道的关键字进行搜索来找到能够解决我的问题的答案。对于初学者来说,这些关键字往往不是那么明显。所以说“这是我用来寻找这个答案的搜索”可能有用些。再次说明,回答时请经检查后以确保搜索能够得到他们所需要的答案 :) ### 写新文档 -人们经常一次又一次地问我的团队同样的问题。很显然这并不是他们的错(他们怎么能够知道在他们之前已经有10个人问了这个问题,且知道答案是什么呢?)因此,我们会尝试写新文档,而不是直接回答回答问题。 +人们经常一次又一次地问我的团队同样的问题。很显然这并不是他们的错(他们怎么能够知道在他们之前已经有 10 个人问了这个问题,且知道答案是什么呢?)因此,我们会尝试写新文档,而不是直接回答回答问题。 1. 马上写新文档 - 2. 给他们我们刚刚写好的新文档 - 3. 公示 写文档有时往往比回答问题需要花很多时间,但这是值得的。写文档尤其重要,如果: a. 这个问题被问了一遍又一遍 - b. 随着时间的推移,这个答案不会变化太大(如果这个答案每一个星期或者一个月就会变化,文档就会过时并且令人受挫) - ### 解释你做了什么 对于一个话题,作为初学者来说,这样的交流会真让人沮丧: * 新人:“嗨!你如何处理 X ?” - * 有经验的人:“我已经处理过了,而且它已经完美解决了” - * 新人:”...... 但是你做了什么?!“ 如果问你问题的人想知道事情是如何进行的,这样是有帮助的: * 让他们去完成任务而不是自己做 - * 告诉他们你是如何得到你给他们的答案的。 这可能比你自己做的时间还要长,但对于被问的人来说这是一个学习机会,因为那样做使得他们将来能够更好地解决问题。 @@ -97,88 +78,74 @@ b. 随着时间的推移,这个答案不会变化太大(如果这个答案 这样,你可以进行更好的交流,像这: * 新人:“这个网站出现了错误,发生了什么?” - -* 有经验的人:(2分钟后)”oh 这是因为发生了数据库故障转移“ - -* 新人: ”你是怎么知道的??!?!?“ - -* 有经验的人:“以下是我所做的!“: - +* 有经验的人:(2分钟后)“oh 这是因为发生了数据库故障转移” +* 新人: “你是怎么知道的??!?!?” +* 有经验的人:“以下是我所做的!”: 1. 通常这些错误是因为服务器 Y 被关闭了。我查看了一下 `$PLACE` 但它表明服务器 Y 开着。所以,并不是这个原因导致的。 - 2. 然后我查看 X 的仪表盘 ,仪表盘的这个部分显示这里发生了数据库故障转移。 - 3. 然后我在日志中找到了相应服务器,并且它显示连接数据库错误,看起来错误就是这里。 如果你正在解释你是如何调试一个问题,解释你是如何发现问题,以及如何找出问题的。尽管看起来你好像已经得到正确答案,但感觉更好的是能够帮助他们提高学习和诊断能力,并了解可用的资源。 - ### 解决根本问题 -这一点有点棘手。有时候人们认为他们依旧找到了解决问题的正确途径,且他们只再多一点信息就可以解决问题。但他们可能并不是走在正确的道路上!比如: +这一点有点棘手。有时候人们认为他们依旧找到了解决问题的正确途径,且他们只要再多一点信息就可以解决问题。但他们可能并不是走在正确的道路上!比如: -* George:”我在处理 X 的时候遇到了错误,我该如何修复它?“ - -* Jasminda:”你是正在尝试解决 Y 吗?如果是这样,你不应该处理 X ,反而你应该处理 Z 。“ - -* George:“噢,你是对的!!!谢谢你!我回反过来处理 Z 的。“ +* George:“我在处理 X 的时候遇到了错误,我该如何修复它?” +* Jasminda:“你是正在尝试解决 Y 吗?如果是这样,你不应该处理 X ,反而你应该处理 Z 。” +* George:“噢,你是对的!!!谢谢你!我回反过来处理 Z 的。” Jasminda 一点都没有回答 George 的问题!反而,她猜测 George 并不想处理 X ,并且她是猜对了。这是非常有用的! 如果你这样做可能会产生高高在上的感觉: -* George:”我在处理 X 的时候遇到了错误,我该如何修复它?“ +* George:“我在处理 X 的时候遇到了错误,我该如何修复它?” +* Jasminda:“不要这样做,如果你想处理 Y ,你应该反过来完成 Z 。” +* George:“好吧,我并不是想处理 Y 。实际上我想处理 X 因为某些原因(REASONS)。所以我该如何处理 X 。” -* Jasminda:不要这样做,如果你想处理 Y ,你应该反过来完成 Z 。 - -* George:“好吧,我并不是想处理 Y 。实际上我想处理 X 因为某些原因(REASONS)。所以我该如何处理 X 。 - -所以不要高高在上,且要记住有时有些提问者可能已经偏离根本问题很远了。同时回答提问者提出的问题以及他们本该提出的问题都是合理的:“嗯,如果你想处理 X ,那么你可能需要这么做,但如果你想用这个解决 Y 问题,可能通过处理其他事情你可以更好地解决这个问题,这就是为什么可以做得更好的原因。 +所以不要高高在上,且要记住有时有些提问者可能已经偏离根本问题很远了。同时回答提问者提出的问题以及他们本该提出的问题都是合理的:“嗯,如果你想处理 X ,那么你可能需要这么做,但如果你想用这个解决 Y 问题,可能通过处理其他事情你可以更好地解决这个问题,这就是为什么可以做得更好的原因。” -### 询问”那个回答可以解决您的问题吗?” +### 询问“那个回答可以解决您的问题吗?” -我总是喜欢在我回答了问题之后核实是否真的已经解决了问题:”这个回答解决了您的问题吗?您还有其他问题吗?“在问完这个之后最好等待一会,因为人们通常需要一两分钟来知道他们是否已经找到了答案。 +我总是喜欢在我回答了问题之后核实是否真的已经解决了问题:“这个回答解决了您的问题吗?您还有其他问题吗?”在问完这个之后最好等待一会,因为人们通常需要一两分钟来知道他们是否已经找到了答案。 我发现尤其是问“这个回答解决了您的问题吗”这个额外的步骤在写完文档后是非常有用的。通常,在写关于我熟悉的东西的文档时,我会忽略掉重要的东西而不会意识到它。 - ### 结对编程和面对面交谈 我是远程工作的,所以我的很多对话都是基于文本的。我认为这是沟通的默认方式。 今天,我们生活在一个方便进行小视频会议和屏幕共享的世界!在工作时候,在任何时间我都可以点击一个按钮并快速加入与他人的视频对话或者屏幕共享的对话中! -例如,最近有人问如何自动调节他们的服务容量规划。我告诉他们我们有几样东西需要清理,但我还不太确定他们要清理的是什么。然后我们进行了一个简短的视屏会话并在5分钟后,我们解决了他们问题。 +例如,最近有人问如何自动调节他们的服务容量规划。我告诉他们我们有几样东西需要清理,但我还不太确定他们要清理的是什么。然后我们进行了一个简短的视频会话并在 5 分钟后,我们解决了他们问题。 我认为,特别是如果有人真的被困在该如何开始一项任务时,开启视频进行结对编程几分钟真的比电子邮件或者一些即时通信更有效。 - ### 不要表现得过于惊讶 这是源自 Recurse Center 的一则法则:[不要故作惊讶][4]。这里有一个常见的情景: -* 某人1:“什么是 Linux 内核” +* 某甲:“什么是 Linux 内核” +* 某乙:“你竟然不知道什么是 Linux 内核?!!!!?!!!????” -* 某人2:“你竟然不知道什么是 Linux 内核(LINUX KERNEL)?!!!!?!!!????” +某乙的表现(无论他们是否真的如此惊讶)是没有帮助的。这大部分只会让某甲不好受,因为他们确实不知道什么是 Linux 内核。 -某人2表现(无论他们是否真的如此惊讶)是没有帮助的。这大部分只会让某人1不好受,因为他们确实不知道什么是 Linux 内核。 +我一直在假装不惊讶,即使我事实上确实有点惊讶那个人不知道这种东西。 -我一直在假装不惊讶即使我事实上确实有点惊讶那个人不知道这种东西但它是令人敬畏的。 - -### 回答问题是令人敬畏的 +### 回答问题真的很棒 显然并不是所有方法都是合适的,但希望你能够发现这里有些是有帮助的!我发现花时间去回答问题并教导人们是其实是很有收获的。 -特别感谢 Josh Triplett 的一些建议并做了很多有益的补充,以及感谢 Harold Treen、Vaibhav Sagar、Peter Bhat Hatkins、Wesley Aptekar Cassels 和 Paul Gowder的阅读或评论。 +特别感谢 Josh Triplett 的一些建议并做了很多有益的补充,以及感谢 Harold Treen、Vaibhav Sagar、Peter Bhat Hatkins、Wesley Aptekar Cassels 和 Paul Gowder 的阅读或评论。 -------------------------------------------------------------------------------- via: https://jvns.ca/blog/answer-questions-well/ -作者:[ Julia Evans][a] +作者:[Julia Evans][a] 译者:[HardworkFish](https://github.com/HardworkFish) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 1f01d6963b98bc00d12267fcf4c9ee714a3f2320 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Mar 2018 22:11:34 +0800 Subject: [PATCH 062/101] PUB:20170921 How to answer questions in a helpful way.md @HardworkFish https://linux.cn/article-9396-1.html --- .../20170921 How to answer questions in a helpful way.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170921 How to answer questions in a helpful way.md (100%) diff --git a/translated/tech/20170921 How to answer questions in a helpful way.md b/published/20170921 How to answer questions in a helpful way.md similarity index 100% rename from translated/tech/20170921 How to answer questions in a helpful way.md rename to published/20170921 How to answer questions in a helpful way.md From 29704d6db89bbe8e5b9b53e04a0d81f3920f800c Mon Sep 17 00:00:00 2001 From: kimii <2545489745@qq.com> Date: Thu, 1 Mar 2018 14:27:28 +0000 Subject: [PATCH 063/101] Update 20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md --- ...Code Integrity with PGP - Part 1- Basic Concepts and Tools.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md b/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md index 19581aaabb..71a46b6854 100644 --- a/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md +++ b/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md @@ -1,3 +1,4 @@ +translating by kimii Protecting Code Integrity with PGP — Part 1: Basic Concepts and Tools ====== From 6dd82da85593ce50ac3d7984270262582921ccdc Mon Sep 17 00:00:00 2001 From: erialin Date: Thu, 1 Mar 2018 23:46:38 +0800 Subject: [PATCH 064/101] erialin translating --- ...l Terminal Multiplexer For Heavy Command-Line Linux User.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/tech/20180130 tmux - A Powerful Terminal Multiplexer For Heavy Command-Line Linux User.md b/sources/tech/20180130 tmux - A Powerful Terminal Multiplexer For Heavy Command-Line Linux User.md index 4adaa7a2bc..83a5704d3c 100644 --- a/sources/tech/20180130 tmux - A Powerful Terminal Multiplexer For Heavy Command-Line Linux User.md +++ b/sources/tech/20180130 tmux - A Powerful Terminal Multiplexer For Heavy Command-Line Linux User.md @@ -1,3 +1,6 @@ +erialin translating + + tmux – A Powerful Terminal Multiplexer For Heavy Command-Line Linux User ====== tmux stands for terminal multiplexer, it allows users to create/enable multiple terminals (vertical & horizontal) in single window, this can be accessed and controlled easily from single window when you are working with different issues. From bb6ccda6482190b0b57d6518f793ab5e854c5a44 Mon Sep 17 00:00:00 2001 From: loujiaye <956939307@qq.com> Date: Thu, 1 Mar 2018 15:56:57 +0000 Subject: [PATCH 065/101] loujiaye translating --- ...80224 How To Run A Command For A Specific Time In Linux.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md b/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md index 7556da2062..e3e30a4daa 100644 --- a/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md +++ b/sources/tech/20180224 How To Run A Command For A Specific Time In Linux.md @@ -1,3 +1,7 @@ +loujiaye Translating + + + How To Run A Command For A Specific Time In Linux ====== ![](https://www.ostechnix.com/wp-content/uploads/2018/02/Run-A-Command-For-A-Specific-Time-In-Linux-1-720x340.png) From faae8a75b7b92dfff0c0993884749e19ae24ea7a Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 01:21:32 +0800 Subject: [PATCH 066/101] PRF:20171109 Concurrent Servers- Part 4 - libuv.md @qhwdw --- ...1109 Concurrent Servers- Part 4 - libuv.md | 90 +++++++++---------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md b/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md index e819027b7d..2e714c630f 100644 --- a/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md +++ b/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md @@ -12,17 +12,17 @@ ### 使用 libuv 抽象出事件驱动循环 -在 [第三节][11] 中,我们看到了基于 `select` 和 `epoll` 的服务器的相似之处,并且,我说过,在它们之间抽象出细微的差别是件很有吸引力的事。许多库已经做到了这些,所以在这一部分中我将去选一个并使用它。我选的这个库是 [libuv][12],它最初设计用于 Node.js 底层的可移植平台层,并且,后来发现在其它的项目中已有使用。libuv 是用 C 写的,因此,它具有很高的可移植性,非常适用嵌入到像 JavaScript 和 Python 这样的高级语言中。 +在 [第三节][11] 中,我们看到了基于 `select` 和 `epoll` 的服务器的相似之处,并且,我说过,在它们之间抽象出细微的差别是件很有吸引力的事。许多库已经做到了这些,所以在这一部分中我将去选一个并使用它。我选的这个库是 [libuv][12],它最初设计用于 Node.js 底层的可移植平台层,并且,后来发现在其它的项目中也有使用。libuv 是用 C 写的,因此,它具有很高的可移植性,非常适用嵌入到像 JavaScript 和 Python 这样的高级语言中。 -虽然 libuv 为抽象出底层平台细节已经变成了一个相当大的框架,但它仍然是以 _事件循环_ 思想为中心的。在我们第三部分的事件驱动服务器中,事件循环在 `main` 函数中是很明确的;当使用 libuv 时,该循环通常隐藏在库自身中,而用户代码仅需要注册事件句柄(作为一个回调函数)和运行这个循环。此外,libuv 会在给定的平台上使用更快的事件循环实现,对于 Linux 它是 epoll,等等。 +虽然 libuv 为了抽象出底层平台细节已经变成了一个相当大的框架,但它仍然是以 _事件循环_ 思想为中心的。在我们第三部分的事件驱动服务器中,事件循环是显式定义在 `main` 函数中的;当使用 libuv 时,该循环通常隐藏在库自身中,而用户代码仅需要注册事件句柄(作为一个回调函数)和运行这个循环。此外,libuv 会在给定的平台上使用更快的事件循环实现,对于 Linux 它是 `epoll`,等等。 ![libuv loop](https://eli.thegreenplace.net/images/2017/libuvloop.png) -libuv 支持多路事件循环,并且,因此事件循环在库中是非常重要的;它有一个句柄 —— `uv_loop_t`,和创建/杀死/启动/停止循环的函数。也就是说,在这篇文章中,我将仅需要使用 “默认的” 循环,libuv 可通过 `uv_default_loop()` 提供它;多路循环大多用于多线程事件驱动的服务器,这是一个更高级别的话题,我将留在这一系列文章的以后部分。 +libuv 支持多路事件循环,因此事件循环在库中是非常重要的;它有一个句柄 —— `uv_loop_t`,以及创建/杀死/启动/停止循环的函数。也就是说,在这篇文章中,我将仅需要使用 “默认的” 循环,libuv 可通过 `uv_default_loop()` 提供它;多路循环大多用于多线程事件驱动的服务器,这是一个更高级别的话题,我将留在这一系列文章的以后部分。 ### 使用 libuv 的并发服务器 -为了对 libuv 有一个更深的印象,让我们跳转到我们的可靠协议的服务器,它通过我们的这个系列已经有了一个强大的重新实现。这个服务器的结构与第三部分中的基于 select 和 epoll 的服务器有一些相似之处,因为,它也依赖回调。完整的 [示例代码在这里][13];我们开始设置这个服务器的套接字绑定到一个本地端口: +为了对 libuv 有一个更深的印象,让我们跳转到我们的可靠协议的服务器,它通过我们的这个系列已经有了一个强大的重新实现。这个服务器的结构与第三部分中的基于 `select` 和 `epoll` 的服务器有一些相似之处,因为,它也依赖回调。完整的 [示例代码在这里][13];我们开始设置这个服务器的套接字绑定到一个本地端口: ``` int portnum = 9090; @@ -47,9 +47,9 @@ if ((rc = uv_tcp_bind(&server_stream, (const struct sockaddr*)&server_address, 0 } ``` -除了它被封装进 libuv API 中之外,你看到的是一个相当标准的套接字。在它的返回中,我们取得一个可工作于任何 libuv 支持的平台上的可移植接口。 +除了它被封装进 libuv API 中之外,你看到的是一个相当标准的套接字。在它的返回中,我们取得了一个可工作于任何 libuv 支持的平台上的可移植接口。 -这些代码也展示了很认真负责的错误处理;多数的 libuv 函数返回一个整数状态,返回一个负数意味着出现了一个错误。在我们的服务器中,我们把这些错误看做致命问题进行处理,但也可以设想为一个更优雅的错误恢复。 +这些代码也展示了很认真负责的错误处理;多数的 libuv 函数返回一个整数状态,返回一个负数意味着出现了一个错误。在我们的服务器中,我们把这些错误看做致命问题进行处理,但也可以设想一个更优雅的错误恢复。 现在,那个套接字已经绑定,是时候去监听它了。这里我们运行首个回调注册: @@ -73,7 +73,7 @@ uv_run(uv_default_loop(), UV_RUN_DEFAULT); return uv_loop_close(uv_default_loop()); ``` -注意,在运行事件循环之前,只有一个回调是通过 main 注册的;我们稍后将看到怎么去添加更多的回调。在事件循环的整个运行过程中,添加和删除回调并不是一个问题 —— 事实上,大多数服务器就是这么写的。 +注意,在运行事件循环之前,只有一个回调是通过 `main` 注册的;我们稍后将看到怎么去添加更多的回调。在事件循环的整个运行过程中,添加和删除回调并不是一个问题 —— 事实上,大多数服务器就是这么写的。 这是一个 `on_peer_connected`,它处理到服务器的新的客户端连接: @@ -132,8 +132,8 @@ void on_peer_connected(uv_stream_t* server_stream, int status) { 这些代码都有很好的注释,但是,这里有一些重要的 libuv 语法我想去强调一下: -* 传入自定义数据到回调中:因为 C 还没有闭包,这可能是个挑战,libuv 在它的所有的处理类型中有一个 `void* data` 字段;这些字段可以被用于传递用户数据。例如,注意 `client->data` 是如何指向到一个 `peer_state_t` 结构上,以便于 `uv_write` 和 `uv_read_start` 注册的回调可以知道它们正在处理的是哪个客户端的数据。 -* 内存管理:在带有垃圾回收的语言中进行事件驱动编程是非常容易的,因为,回调通常运行在一个它们注册的完全不同的栈帧中,使得基于栈的内存管理很困难。它总是需要传递堆分配的数据到 libuv 回调中(当所有回调运行时,除了 main,其它的都运行在栈上),并且,为了避免泄漏,许多情况下都要求这些数据去安全释放。这些都是些需要实践的内容 [[1]][6]。 +* 传入自定义数据到回调中:因为 C 语言还没有闭包,这可能是个挑战,libuv 在它的所有的处理类型中有一个 `void* data` 字段;这些字段可以被用于传递用户数据。例如,注意 `client->data` 是如何指向到一个 `peer_state_t` 结构上,以便于 `uv_write` 和 `uv_read_start` 注册的回调可以知道它们正在处理的是哪个客户端的数据。 +* 内存管理:在带有垃圾回收的语言中进行事件驱动编程是非常容易的,因为,回调通常运行在一个与它们注册的地方完全不同的栈帧中,使得基于栈的内存管理很困难。它总是需要传递堆分配的数据到 libuv 回调中(当所有回调运行时,除了 `main`,其它的都运行在栈上),并且,为了避免泄漏,许多情况下都要求这些数据去安全释放(`free()`)。这些都是些需要实践的内容 ^注1 。 这个服务器上对端的状态如下: @@ -146,7 +146,7 @@ typedef struct { } peer_state_t; ``` -它与第三部分中的状态非常类似;我们不再需要 sendptr,因为,在调用 "done writing" 回调之前,`uv_write` 将确保去发送它提供的整个缓冲。我们也为其它的回调使用保持了一个到客户端的指针。这里是 `on_wrote_init_ack`: +它与第三部分中的状态非常类似;我们不再需要 `sendptr`,因为,在调用 “done writing” 回调之前,`uv_write` 将确保发送它提供的整个缓冲。我们也为其它的回调使用保持了一个到客户端的指针。这里是 `on_wrote_init_ack`: ``` void on_wrote_init_ack(uv_write_t* req, int status) { @@ -171,7 +171,7 @@ void on_wrote_init_ack(uv_write_t* req, int status) { } ``` -然后,我们确信知道了这个初始的 '*' 已经被发送到对端,我们通过调用 `uv_read_start` 去监听从这个对端来的入站数据,它注册一个回调(`on_peer_read`)去被调用,不论什么时候,事件循环都在套接字上接收来自客户端的调用: +然后,我们确信知道了这个初始的 `'*'` 已经被发送到对端,我们通过调用 `uv_read_start` 去监听从这个对端来的入站数据,它注册一个将被事件循环调用的回调(`on_peer_read`),不论什么时候,事件循环都在套接字上接收来自客户端的调用: ``` void on_peer_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) { @@ -236,11 +236,11 @@ void on_peer_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) { } ``` -这个服务器的运行时行为非常类似于第三部分的事件驱动服务器:所有的客户端都在一个单个的线程中并发处理。并且一些行为被维护在服务器代码中:服务器的逻辑实现为一个集成的回调,并且长周期运行是禁止的,因为它会阻塞事件循环。这一点也很类似。让我们进一步探索这个问题。 +这个服务器的运行时行为非常类似于第三部分的事件驱动服务器:所有的客户端都在一个单个的线程中并发处理。并且类似的,一些特定的行为必须在服务器代码中维护:服务器的逻辑实现为一个集成的回调,并且长周期运行是禁止的,因为它会阻塞事件循环。这一点也很类似。让我们进一步探索这个问题。 ### 在事件驱动循环中的长周期运行的操作 -单线程的事件驱动代码使它先天地对一些常见问题非常敏感:整个循环中的长周期运行的代码块。参见如下的程序: +单线程的事件驱动代码使它先天就容易受到一些常见问题的影响:长周期运行的代码会阻塞整个循环。参见如下的程序: ``` void on_timer(uv_timer_t* timer) { @@ -280,23 +280,21 @@ on_timer [18850 ms] ... ``` -`on_timer` 忠实地每秒执行一次,直到随机出现的睡眠为止。在那个时间点,`on_timer` 不再被调用,直到睡眠时间结束;事实上,_没有其它的回调_  在这个时间帧中被调用。这个睡眠调用阻塞当前线程,它正是被调用的线程,并且也是事件循环使用的线程。当这个线程被阻塞后,事件循环也被阻塞。 +`on_timer` 忠实地每秒执行一次,直到随机出现的睡眠为止。在那个时间点,`on_timer` 不再被调用,直到睡眠时间结束;事实上,_没有其它的回调_  会在这个时间帧中被调用。这个睡眠调用阻塞了当前线程,它正是被调用的线程,并且也是事件循环使用的线程。当这个线程被阻塞后,事件循环也被阻塞。 这个示例演示了在事件驱动的调用中为什么回调不能被阻塞是多少的重要。并且,同样适用于 Node.js 服务器、客户端侧的 Javascript、大多数的 GUI 编程框架、以及许多其它的异步编程模型。 -但是,有时候运行耗时的任务是不可避免的。并不是所有任务都有一个异步 APIs;例如,我们可能使用一些仅有同步 API 的库去处理,或者,正在执行一个可能的长周期计算。我们如何用事件驱动编程去结合这些代码?线程可以帮到你! +但是,有时候运行耗时的任务是不可避免的。并不是所有任务都有一个异步 API;例如,我们可能使用一些仅有同步 API 的库去处理,或者,正在执行一个可能的长周期计算。我们如何用事件驱动编程去结合这些代码?线程可以帮到你! -### “转换” 阻塞调用到异步调用的线程 +### “转换” 阻塞调用为异步调用的线程 -一个线程池可以被用于去转换阻塞调用到异步调用,通过与事件循环并行运行,并且当任务完成时去由它去公布事件。一个给定的阻塞函数 `do_work()`,这里介绍了它是怎么运行的: +一个线程池可以用于转换阻塞调用为异步调用,通过与事件循环并行运行,并且当任务完成时去由它去公布事件。以阻塞函数 `do_work()` 为例,这里介绍了它是怎么运行的: -1. 在一个回调中,用 `do_work()` 代表直接调用,我们将它打包进一个 “任务”,并且请求线程池去运行这个任务。当任务完成时,我们也为循环去调用它注册一个回调;我们称它为 `on_work_done()`。 +1. 不在一个回调中直接调用 `do_work()` ,而是将它打包进一个 “任务”,让线程池去运行这个任务。当任务完成时,我们也为循环去调用它注册一个回调;我们称它为 `on_work_done()`。 +2. 在这个时间点,我们的回调就可以返回了,而事件循环保持运行;在同一时间点,线程池中的有一个线程运行这个任务。 +3. 一旦任务运行完成,通知主线程(指正在运行事件循环的线程),并且事件循环调用 `on_work_done()`。 -2. 在这个时间点,我们的回调可以返回并且事件循环保持运行;在同一时间点,线程池中的一个线程运行这个任务。 - -3. 一旦任务运行完成,通知主线程(指正在运行事件循环的线程),并且,通过事件循环调用 `on_work_done()`。 - -让我们看一下,使用 libuv 的工作调度 API,是怎么去解决我们前面的 timer/sleep 示例中展示的问题的: +让我们看一下,使用 libuv 的工作调度 API,是怎么去解决我们前面的计时器/睡眠示例中展示的问题的: ``` void on_after_work(uv_work_t* req, int status) { @@ -327,7 +325,7 @@ int main(int argc, const char** argv) { } ``` -通过一个 work_req [[2]][14] 类型的句柄,我们进入一个任务队列,代替在 `on_timer` 上直接调用 sleep,这个函数在任务中(`on_work`)运行,并且,一旦任务完成(`on_after_work`),这个函数被调用一次。`on_work` 在这里是指发生的 “work”(阻塞中的/耗时的操作)。在这两个回调传递到 `uv_queue_work` 时,注意一个关键的区别:`on_work` 运行在线程池中,而 `on_after_work` 运行在事件循环中的主线程上 - 就好像是其它的回调一样。 +通过一个 `work_req` ^注2 类型的句柄,我们进入一个任务队列,代替在 `on_timer` 上直接调用 sleep,这个函数在任务中(`on_work`)运行,并且,一旦任务完成(`on_after_work`),这个函数被调用一次。`on_work` 是指 “work”(阻塞中的/耗时的操作)进行的地方。注意在这两个回调传递到 `uv_queue_work` 时的一个关键区别:`on_work` 运行在线程池中,而 `on_after_work` 运行在事件循环中的主线程上 —— 就好像是其它的回调一样。 让我们看一下这种方式的运行: @@ -347,25 +345,25 @@ on_timer [97578 ms] ... ``` -即便在 sleep 函数被调用时,定时器也每秒钟滴答一下,睡眠(sleeping)现在运行在一个单独的线程中,并且不会阻塞事件循环。 +即便在 sleep 函数被调用时,定时器也每秒钟滴答一下,睡眠现在运行在一个单独的线程中,并且不会阻塞事件循环。 ### 一个用于练习的素数测试服务器 -因为通过睡眼去模拟工作并不是件让人兴奋的事,我有一个事先准备好的更综合的一个示例 - 一个基于套接字接受来自客户端的数字的服务器,检查这个数字是否是素数,然后去返回一个 “prime" 或者 “composite”。完整的 [服务器代码在这里][15] - 我不在这里粘贴了,因为它太长了,更希望读者在一些自己的练习中去体会它。 +因为通过睡眠去模拟工作并不是件让人兴奋的事,我有一个事先准备好的更综合的一个示例 —— 一个基于套接字接受来自客户端的数字的服务器,检查这个数字是否是素数,然后去返回一个 “prime" 或者 “composite”。完整的 [服务器代码在这里][15] —— 我不在这里粘贴了,因为它太长了,更希望读者在一些自己的练习中去体会它。 这个服务器使用了一个原生的素数测试算法,因此,对于大的素数可能花很长时间才返回一个回答。在我的机器中,对于 2305843009213693951,它花了 ~5 秒钟去计算,但是,你的方法可能不同。 -练习 1:服务器有一个设置(通过一个名为 MODE 的环境变量)要么去在套接字回调(意味着在主线程上)中运行素数测试,要么在 libuv 工作队列中。当多个客户端同时连接时,使用这个设置来观察服务器的行为。当它计算一个大的任务时,在阻塞模式中,服务器将不回复其它客户端,而在非阻塞模式中,它会回复。 +练习 1:服务器有一个设置(通过一个名为 `MODE` 的环境变量)要么在套接字回调(意味着在主线程上)中运行素数测试,要么在 libuv 工作队列中。当多个客户端同时连接时,使用这个设置来观察服务器的行为。当它计算一个大的任务时,在阻塞模式中,服务器将不回复其它客户端,而在非阻塞模式中,它会回复。 -练习 2;libuv 有一个缺省大小的线程池,并且线程池的大小可以通过环境变量配置。你可以通过使用多个客户端去实验找出它的缺省值是多少?找到线程池缺省值后,使用不同的设置去看一下,在重负载下怎么去影响服务器的响应能力。 +练习 2:libuv 有一个缺省大小的线程池,并且线程池的大小可以通过环境变量配置。你可以通过使用多个客户端去实验找出它的缺省值是多少?找到线程池缺省值后,使用不同的设置去看一下,在重负载下怎么去影响服务器的响应能力。 ### 在非阻塞文件系统中使用工作队列 -对于仅傻傻的演示和 CPU 密集型的计算来说,将可能的阻塞操作委托给一个线程池并不是明智的;libuv 在它的文件系统 APIs 中本身就大量使用了这种性能。通过这种方式,libuv 使用一个异步 API,在一个轻便的方式中,显示出它强大的文件系统的处理能力。 +对于只是呆板的演示和 CPU 密集型的计算来说,将可能的阻塞操作委托给一个线程池并不是明智的;libuv 在它的文件系统 API 中本身就大量使用了这种能力。通过这种方式,libuv 使用一个异步 API,以一个轻便的方式显示出它强大的文件系统的处理能力。 -让我们使用 `uv_fs_read()`,例如,这个函数从一个文件中(以一个 `uv_fs_t` 句柄为代表)读取一个文件到一个缓冲中 [[3]][16],并且当读取完成后调用一个回调。换句话说,`uv_fs_read()` 总是立即返回,甚至如果文件在一个类似 NFS 的系统上,并且,数据到达缓冲区可能需要一些时间。换句话说,这个 API 与这种方式中其它的 libuv APIs 是异步的。这是怎么工作的呢? +让我们使用 `uv_fs_read()`,例如,这个函数从一个文件中(表示为一个 `uv_fs_t` 句柄)读取一个文件到一个缓冲中 ^注3,并且当读取完成后调用一个回调。换句话说,`uv_fs_read()` 总是立即返回,即使是文件在一个类似 NFS 的系统上,而数据到达缓冲区可能需要一些时间。换句话说,这个 API 与这种方式中其它的 libuv API 是异步的。这是怎么工作的呢? -在这一点上,我们看一下 libuv 的底层;内部实际上非常简单,并且它是一个很好的练习。作为一个便携的库,libuv 对于 Windows 和 Unix 系统在它的许多函数上有不同的实现。我们去看一下在 libuv 源树中的 src/unix/fs.c。 +在这一点上,我们看一下 libuv 的底层;内部实际上非常简单,并且它是一个很好的练习。作为一个可移植的库,libuv 对于 Windows 和 Unix 系统在它的许多函数上有不同的实现。我们去看一下在 libuv 源树中的 `src/unix/fs.c`。 这是 `uv_fs_read` 的代码: @@ -400,9 +398,9 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, } ``` -第一次看可能觉得很困难,因为它延缓真实的工作到 INIT 和 POST 宏中,在 POST 中与一些本地变量一起设置。这样做可以避免了文件中的许多重复代码。 +第一次看可能觉得很困难,因为它延缓真实的工作到 `INIT` 和 `POST` 宏中,以及为 `POST` 设置了一些本地变量。这样做可以避免了文件中的许多重复代码。 -这是 INIT 宏: +这是 `INIT` 宏: ``` #define INIT(subtype) \ @@ -421,9 +419,9 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, while (0) ``` -它设置了请求,并且更重要的是,设置 `req->fs_type` 域为真实的 FS 请求类型。因为 `uv_fs_read` 调用 invokes INIT(READ),它意味着 `req->fs_type` 被分配一个常数 `UV_FS_READ`。 +它设置了请求,并且更重要的是,设置 `req->fs_type` 域为真实的 FS 请求类型。因为 `uv_fs_read` 调用 `INIT(READ)`,它意味着 `req->fs_type` 被分配一个常数 `UV_FS_READ`。 -这是 POST 宏: +这是 `POST` 宏: ``` #define POST \ @@ -440,31 +438,25 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, while (0) ``` -它做什么取决于回调是否为 NULL。在 libuv 文件系统 APIs 中,一个 NULL 回调意味着我们真实地希望去执行一个 _同步_ 操作。在这种情况下,POST 直接调用 `uv__fs_work`(我们需要了解一下这个函数的功能),而对于一个 non-NULL 回调,它提交 `uv__fs_work` 作为一个工作事项到工作队列(指的是线程池),然后,注册 `uv__fs_done` 作为回调;该函数执行一些登记并调用用户提供的回调。 +它做什么取决于回调是否为 `NULL`。在 libuv 文件系统 API 中,一个 `NULL` 回调意味着我们真实地希望去执行一个 _同步_ 操作。在这种情况下,`POST` 直接调用 `uv__fs_work`(我们需要了解一下这个函数的功能),而对于一个非 `NULL` 回调,它把 `uv__fs_work` 作为一个工作项提交到工作队列(指的是线程池),然后,注册 `uv__fs_done` 作为回调;该函数执行一些登记并调用用户提供的回调。 -如果我们去看 `uv__fs_work` 的代码,我们将看到它使用很多宏去按需路由工作到真实的文件系统调用。在我们的案例中,对于 `UV_FS_READ` 这个调用将被 `uv__fs_read` 生成,它(最终)使用普通的 POSIX APIs 去读取。这个函数可以在一个 _阻塞_ 方式中很安全地实现。因为,它通过异步 API 调用时被置于一个线程池中。 +如果我们去看 `uv__fs_work` 的代码,我们将看到它使用很多宏按照需求将工作分发到实际的文件系统调用。在我们的案例中,对于 `UV_FS_READ` 这个调用将被 `uv__fs_read` 生成,它(最终)使用普通的 POSIX API 去读取。这个函数可以在一个 _阻塞_ 方式中很安全地实现。因为,它通过异步 API 调用时被置于一个线程池中。 -在 Node.js 中,fs.readFile 函数是映射到 `uv_fs_read` 上。因此,可以在一个非阻塞模式中读取文件,甚至是当底层文件系统 API 是阻塞方式时。 +在 Node.js 中,`fs.readFile` 函数是映射到 `uv_fs_read` 上。因此,可以在一个非阻塞模式中读取文件,甚至是当底层文件系统 API 是阻塞方式时。 * * * - -[[1]][1] 为确保服务器不泄露内存,我在一个启用泄露检查的 Valgrind 中运行它。因为服务器经常是被设计为永久运行,这是一个挑战;为克服这个问题,我在服务器上添加了一个 “kill 开关” - 一个从客户端接收的特定序列,以使它可以停止事件循环并退出。这个代码在 `theon_wrote_buf` 句柄中。 - - -[[2]][2] 在这里我们不过多地使用 `work_req`;讨论的素数测试服务器接下来将展示怎么被用于去传递上下文信息到回调中。 - - -[[3]][3] `uv_fs_read()` 提供了一个类似于 preadv Linux 系统调用的通用 API:它使用多缓冲区用于排序,并且支持一个到文件中的偏移。基于我们讨论的目的可以忽略这些特性。 - +- 注1: 为确保服务器不泄露内存,我在一个启用泄露检查的 Valgrind 中运行它。因为服务器经常是被设计为永久运行,这是一个挑战;为克服这个问题,我在服务器上添加了一个 “kill 开关” —— 一个从客户端接收的特定序列,以使它可以停止事件循环并退出。这个代码在 `theon_wrote_buf` 句柄中。 +- 注2: 在这里我们不过多地使用 `work_req`;讨论的素数测试服务器接下来将展示怎么被用于去传递上下文信息到回调中。 +- 注3: `uv_fs_read()` 提供了一个类似于 `preadv` Linux 系统调用的通用 API:它使用多缓冲区用于排序,并且支持一个到文件中的偏移。基于我们讨论的目的可以忽略这些特性。 -------------------------------------------------------------------------------- via: https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/ -作者:[Eli Bendersky ][a] +作者:[Eli Bendersky][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From a49c11f420739fc6b7b355beba4d344efe8fd2a7 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 01:22:07 +0800 Subject: [PATCH 067/101] PUB:20171109 Concurrent Servers- Part 4 - libuv.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @qhwdw 这个系列的第五篇出来了,回头选题后,你可以再看看。 --- .../20171109 Concurrent Servers- Part 4 - libuv.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171109 Concurrent Servers- Part 4 - libuv.md (100%) diff --git a/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md b/published/20171109 Concurrent Servers- Part 4 - libuv.md similarity index 100% rename from translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md rename to published/20171109 Concurrent Servers- Part 4 - libuv.md From 3bf6ad29fee8840a6f86bce0207223a2239e9dc6 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 2 Mar 2018 09:04:05 +0800 Subject: [PATCH 068/101] translated --- ... Ways to Extend the Power of Kubernetes.md | 41 ------------------- ... Ways to Extend the Power of Kubernetes.md | 39 ++++++++++++++++++ 2 files changed, 39 insertions(+), 41 deletions(-) delete mode 100644 sources/tech/20180203 3 Ways to Extend the Power of Kubernetes.md create mode 100644 translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md diff --git a/sources/tech/20180203 3 Ways to Extend the Power of Kubernetes.md b/sources/tech/20180203 3 Ways to Extend the Power of Kubernetes.md deleted file mode 100644 index 9e2c0368f8..0000000000 --- a/sources/tech/20180203 3 Ways to Extend the Power of Kubernetes.md +++ /dev/null @@ -1,41 +0,0 @@ -translating---geekpi - -3 Ways to Extend the Power of Kubernetes -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/chen-goldberg-kubecon.png?itok=WR_4i31u) - -The ability to extend Kubernetes is its secret superpower, said Chen Goldberg, Director of Engineering at Google, speaking at the recent [KubeCon + CloudNativeCon][1] in Austin. - -In the race to build tools that help engineers become more productive, Goldberg talked about how she once led a team that developed a platform that did just that. Despite the fact the platform initially worked, it was not extensible, and it was also difficult to modify. - -Fortunately, said Goldberg, Kubernetes suffers from neither of these problems. To begin with, Kubernetes is self-healing system, as it uses controllers that implement what is called a " _Reconciliation Loop._ " In a reconciliation loop, a controller observes the current state of the system and compares it to its desired state. Once it has established the difference between each of these two states, it works towards achieving the desired state. This makes Kubernetes well-adapted to dynamic environments. - -### 3 Ways to Extend Kubernetes - -Goldberg then explained that to build the controllers, you need resources, that is, you need to extend Kubernetes. There are three ways to do that and, from the most flexible (but also more difficult) to the easiest they are: using a Kube aggregator, using an API server builder, or creating a Custom Resource Definition (or CRD). - -The latter allows to extend Kubernetes' functionality even with minimal coding. To demonstrate how it is done, Goggle Software Engineer Anthony Yeh came on stage and showcased adding a stateful set to Kubernetes. (Stateful sets objects used to manage stateful applications, that is applications that need to store the state of the application, keeping track of, for example, a user's identity and their personal settings.) Using _catset_ , a CRD implemented in 100 lines of JavaScript in one single file, Yeh showed how you can add a stateful set to a Kubernetes deployment. A prior extension that was not a CRD, required 24 files and over 3,000 lines of code. - -Addressing the issue of reliability of CRDs, Goldberg said Kubernetes had started a certification program that allows companies to register and certify their extensions for the Kubernetes community. In one month over 30 companies had signed up for the program. - -Goldberg went on to explain how the extensibility of Kubernetes was a hot topic in this year's KubeCon, and how Google and IBM were building a platform to manage and secure microservices using CRDs. Or how some developers were bringing machine-learning to Kubernetes, and others were demonstrating open service broker and the consumption of services on hybrid settings. - -In conclusion, Goldberg said, extensibility is about empowerment. And, the extensibility of Kubernetes makes it a general purpose and easy to use platform for developers, which allows them to run any application. - -You can watch the entire video below: - -https://www.youtube.com/embed/1kjgwXP_N7A?enablejsapi=1 - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/event/kubecon/2018/2/3-ways-extend-power-kubernetes - -作者:[PAUL BROWN][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.linux.com/users/bro66 -[1]:http://events17.linuxfoundation.org/events/kubecon-and-cloudnativecon-north-america diff --git a/translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md b/translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md new file mode 100644 index 0000000000..ceee299984 --- /dev/null +++ b/translated/tech/20180203 3 Ways to Extend the Power of Kubernetes.md @@ -0,0 +1,39 @@ +3种扩展 Kubernetes 能力的方式 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/chen-goldberg-kubecon.png?itok=WR_4i31u) + +Google 的工程总监 Chen Goldberg 在奥斯汀最近的[KubeCon 和 CloudNativeCon][1]上说,Kubernetes 的扩展能力是它的秘密武器。 + +在建立帮助工程师提高工作效率的工具的竞赛中,Goldberg 谈到他曾经领导过一个开发这样一个平台的团队。尽管平台最初有用,但它无法扩展,并且修改也很困难。 + +幸运的是,Goldberg 说,Kubernetes 没有这些问题。首先,Kubernetes 是一个自我修复系统,因为它使用的控制器实现了“_协调环_”(Reconciliation Loop)。在协调环中,控制器观察系统的当前状态并将其与所需状态进行比较。一旦它确定了这两个状态之间的差异,它就会努力实现所需的状态。这使得 Kubernetes 非常适合动态环境。 + +### 3种扩展 Kubernetes 的方式 + +Goldberg 然后解释说,要建立控制器,你需要资源,也就是说,你需要扩展 Kubernetes。有三种方法可以做到这一点,从最灵活(但也更困难)到最简单的是:使用 Kube 聚合器,使用 API​​ 服务器构建器或创建自定义资源定义(或 CRD)。 + +后者允许即使使用最少的编码来扩展 Kubernetes 的功能。为了演示它是如何完成的,Goggle 软件工程师 Anthony Yeh 出席并展示了为 Kubernetes 添加一个状态集。 (状态集对象用于管理有状态应用,即需要存储应用状态的程序,跟踪例如用户身份及其个人设置。)使用 _catset_,在一个 100 行 JavaScript 的文件中实现的 CRD,Yeh 展示了如何将状态集添加到 Kubernetes 部署中。之前的扩展不是 CRD,需要 24 个文件和 3000 多行代码。 + +为解决 CRD 可靠性问题,Goldberg 表示,Kubernetes 已经启动了一项认证计划,允许公司在 Kubernetes 社区注册和认证其扩展。在一个月内,已有 30 多家公司报名参加该计划。 + +Goldberg 继续解释 Kubernetes 的可扩展性如何成为今年 KubeCon 的热门话题,以及 Google 和 IBM 如何构建一个使用 CRD 管理和保护微服务的平台。或者一些开发人员如何将机器学习带入 Kubernetes,另外展示开放服务代理以及在混合设置上的服务消费。 + +Goldberg 总结说,可扩展性是种增能。而且,Kubernetes 的可扩展性使其成为开发者的通用平台,并且易于使用,这使得他们可以运行任何应用程序。 + +你可以在下面观看整个视频: + +https://www.youtube.com/embed/1kjgwXP_N7A?enablejsapi=1 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/event/kubecon/2018/2/3-ways-extend-power-kubernetes + +作者:[PAUL BROWN][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/bro66 +[1]:http://events17.linuxfoundation.org/events/kubecon-and-cloudnativecon-north-america From d2ce9ebfd9e10ae14a1976dfe802e49b055c3da0 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 2 Mar 2018 09:07:50 +0800 Subject: [PATCH 069/101] translating --- .../20180131 How to access-view Python help when using vim.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180131 How to access-view Python help when using vim.md b/sources/tech/20180131 How to access-view Python help when using vim.md index c91e16d81d..f37a56908b 100644 --- a/sources/tech/20180131 How to access-view Python help when using vim.md +++ b/sources/tech/20180131 How to access-view Python help when using vim.md @@ -1,3 +1,5 @@ +translating---geekpi + How to access/view Python help when using vim ====== From 25057651426960cf4deb947de7c9b886c66659a6 Mon Sep 17 00:00:00 2001 From: shipsw Date: Fri, 2 Mar 2018 09:10:58 +0800 Subject: [PATCH 070/101] Update 20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md translating by shipsw --- ...to use yum-cron to automatically update RHEL-CentOS Linux.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md b/sources/tech/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md index b0ca149c3e..4f96731332 100644 --- a/sources/tech/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md +++ b/sources/tech/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md @@ -1,3 +1,5 @@ +translating by shipsw + How to use yum-cron to automatically update RHEL/CentOS Linux ====== The yum command line tool is used to install and update software packages under RHEL / CentOS Linux server. I know how to apply updates using [yum update command line][1], but I would like to use cron to update packages where appropriate manually. How do I configure yum to install software patches/updates [automatically with cron][2]? From 33df2b4dace5e125d58cc6e60401cbf46e0daa55 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Mar 2018 11:13:50 +0800 Subject: [PATCH 071/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Top=2010=20open?= =?UTF-8?q?=20source=20legal=20stories=20that=20shook=202017?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...en source legal stories that shook 2017.md | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 sources/talk/20180227 Top 10 open source legal stories that shook 2017.md diff --git a/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md b/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md new file mode 100644 index 0000000000..7ac21bdb5b --- /dev/null +++ b/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md @@ -0,0 +1,190 @@ +Top 10 open source legal stories that shook 2017 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/law_legal_gavel_court.jpg?itok=tc27pzjI) + +Like every year, legal issues were a hot topic in the open source world in 2017. While we're deep into the first quarter of the year, it's still worthwhile to look back at the top legal news in open source last year. + +### 1. GitHub revises ToS + +In February 2017, GitHub [announced][1] it was revising its terms of service and invited comments on the changes, several of which concerned rights in the user-uploaded content. The [earlier GitHub terms][2] included an agreement by the user to allow others to "view and fork" public repositories, as well as an indemnification provision protecting GitHub against third-party claims. The new terms added a license from the user to GitHub to allow it to store and serve content, a default ["inbound=outbound"][3] contributor license, and an agreement by the user to comply with third-party licenses covering uploaded content. While keeping the "view and fork" language, the new terms state that further rights can be granted by adopting an open source license. The terms also add a waiver of [moral rights][4] with a two-level fallback license, the second license granting GitHub permission to use content without attribution and to make reasonable adaptations "as necessary to render the website and provide the service." + +In March, after the new terms became effective, concerns were raised by several developers, notably [Thorsten Glaser][5] and [Joey][6] [Hess][7], who said they would be removing their repositories from GitHub. As Glaser and Hess read the new terms, they seemed to require users to grant rights to GitHub and other users that were broader than third-party licenses would permit, particularly copyleft licenses like the GPL and licenses requiring attribution. Moreover, the license to GitHub could be read as giving it a more favorable license in users' own content than ordinary users would receive under the nominal license. Donald Robertson of the Free Software Foundation (FSF) [wrote][8] that, while GitHub's terms were confusing, they were not in conflict with copyleft: "Because it's highly unlikely that GitHub intended to destroy their business model and user base, we don't read the ambiguity in the terms as granting or requiring overly broad permissions outside those already granted by the GPL." + +GitHub eventually added a sentence addressing the issue; it can be seen in the [current version][9] of the terms: "If you upload Content that already comes with a license granting GitHub the permissions we need to run our Service, no additional license is required." + +### 2. Kernel enforcement statement + +[Section 4][10] of GPLv2 speaks of automatic termination of rights for those who violate the terms of the license. By [2006][11] the FSF had come to see this provision as unduly harsh in the case of inadvertent violations. GPLv3 modifies the GPLv2 approach to termination by providing a 30-day cure opportunity for first-time violators as well as a 60-day period of repose. Many GPL projects like the Linux kernel continue to be licensed under GPLv2. + +As I [wrote][12] last year, 2016 saw public condemnation of the GPL enforcement tactics of former Netfilter contributor Patrick McHardy. In a further reaction to McHardy's conduct, the Linux Foundation [Technical Advisory Board][13] (TAB), elected by the individual kernel developers, drafted a Linux Kernel Enforcement Statement, which was [announced by Greg Kroah-Hartman][14] on the Linux kernel mailing list (LKML) on October 16, 2017. The [statement][15], now part of the kernel's Documentation directory, incorporates the GPLv3 cure and repose language verbatim as a "commitment to users of the Linux kernel on behalf of ourselves and any successors to our copyright interests." The commitment, described as a grant of additional permission under GPLv2, applies to non-defensive assertions of GPLv2 rights. The kernel statement in effect adopts a recommendation in the [Principles of Community-Oriented GPL Enforcement][16]. To date, the statement has been signed by over 100 kernel developers. Kroah-Hartman published an [FAQ][17] on the statement and a detailed [explanation][18] authored by several TAB members. + +### 3. Red Hat, Facebook, Google, and IBM announce GPLv2/LGPLv2.x cure commitment + +A month after the announcement of the kernel enforcement statement on LKML, a coalition of companies led by Red Hat and including Facebook, Google, and IBM [announced][19] their own commitment to [extend the GPLv3 cure][20] and repose opportunities to all code covered by their copyrights and licensed under GPLv2, LGPLv2, and LGPLv2.1. (The termination provision in LGPLv2.x is essentially identical to that in GPLv2.) As with the kernel statement, the commitment does not apply to defensive proceedings or claims brought in response to some prior proceeding or claim (for example, a GPL violation counterclaim in a patent infringement lawsuit, as occurred in [Twin Peaks Software v. Red Hat][21]). + +### 4. EPL 2.0 released + +The [Eclipse Public License version 1.0][22], a weak copyleft license that descends from the [Common Public License][23] and indirectly the [IBM Public License][24], has been the primary license of Eclipse Foundation projects. It sees significant use outside of Eclipse as well; for example, EPL is the license of the [Clojure][25] language implementation and the preferred open source license of the Clojure community, and it is the main license of [OpenDaylight][26]. + +Following a quiet two-year community review process, in August 2017 the Eclipse Foundation [announced][27] that a new version 2 of the EPL had been approved by the Eclipse Foundation board and by the OSI. The Eclipse Foundation intends EPL 2.0 to be the default license for Eclipse community projects. + +EPL 2.0 is a fairly conservative license revision. Perhaps the most notable change concerns GPL compatibility. EPL 1.0 is regarded as GPL-incompatible by both the [FSF][28] and the [Eclipse Foundation][29]. The FSF has suggested that this is at least because of the conflicting copyleft requirements in the two licenses, and (rather more dubiously) the choice of law clause in EPL 1.0, which has been removed in EPL 2.0. As a weak copyleft license, EPL normally requires at least some subset of derivative works to be licensed under EPL if distributed in source code form. [FSF][30] and [Eclipse][31] published opinions about the use of GPL for Eclipse IDE plugins several years ago. Apart from the issue of license compatibility, the Eclipse Foundation generally prohibits projects from distributing third-party code under GPL and LGPL. + +While EPL 2.0 remains GPL-incompatible by default, it enables the initial "Contributor" to authorize the licensing of EPL-covered source code under a "Secondary License"—GPLv2, GPLv3, or a later version of the GPL, which may include identified GPL exceptions or additional permissions like the [Classpath Exception][32]—if the EPL-covered code is combined with GPL-licensed code contained in a separate file. Some Eclipse projects have already relicensed to EPL 2.0 and are making use of this "Secondary License" feature, including [OMR][33] and [OpenJ9][34]. As the FSF [observes][35], invocation of the Secondary License feature is roughly equivalent to dual-licensing the code under EPL / GPL. + +### 5. Java EE migration to Eclipse + +The [Java Community Process][36] (JCP) facilitates development of Java technology specifications (Java Specification Requests, aka JSRs), including those defining the [Java Enterprise Edition][37] platform (Java EE). The JCP rests on a complex legal architecture centered around the Java Specification Participation Agreement (JSPA). While JCP governance is shared among multiple organizational and individual participants, the JCP is in no way vendor-neutral. Oracle owns the Java trademark and has special controls over the JCP. Some JCP [reforms][38] were adopted several years ago, including measures to mandate open source licensing and open source project development practices for JSR reference implementations (RIs), but efforts to modernize the JSPA stalled during the pendency of the Oracle v. Google litigation. + +In August 2017, Oracle announced it would explore [moving Java EE][39] to an open source foundation. Following consultation with IBM and Red Hat, the two other major contributors to Java EE, Oracle announced in September that it had [selected the Eclipse Foundation][40] to house the successor to Java EE. + +The migration to Eclipse has been underway since then. The Eclipse board approved a new top-level Eclipse project, [EE4J][41] (Eclipse Enterprise for Java), to serve as the umbrella project for development of RIs and technology compatibility kits (TCKs) for the successor platform. The [GlassFish][42] project, consisting of source code of the RIs for the majority of Java EE JSRs for which Oracle has served as specification lead, has mostly been under a dual license of CDDL and GPLv2 plus the Classpath Exception. Oracle is in the process of [relicensing this code][43] to EPL 2.0 with GPLv2 plus the Classpath Exception as the Secondary License (see EPL 2.0 topic). In addition, Oracle is expected to relicense proprietary Java EE TCKs so they can be developed as Eclipse open source projects. Still to be determined are the name of an Eclipse-owned certification mark to succeed Java EE and the development of a new specification process in place of the one defined in the JSPA. + +### 6. React licensing controversy + +Open source licenses that specifically address patent licensing often couple the patent license grant with a "patent defense" clause, terminating the patent license upon certain acts of litigation brought by the licensee, an approach borrowed from standards agreements. The early period of corporate experimentation with open source licensing was characterized by enthusiasm for patent defense clauses that were broad (in the sense that a relatively wide range of conduct would trigger termination). The arrival of the Apache License 2.0 and Eclipse Public License 1.0 in 2004 marked an end to that era; their patent termination criteria are basically limited to patent lawsuits in which the user accuses the licensed software itself of infringement. + +In May 2013 Facebook released the [React][44] JavaScript library under the Apache License 2.0, but the 0.12.0 release (October 2014) switched to the 3-clause BSD license along with a patent license grant in a separate `PATENTS` file. The idea of using a simple, standard permissive open source license with a bespoke patent license in a separate file has some precedent in projects maintained by [Google][45] and [Microsoft][46]. However, the patent defense clauses in those cases take the narrow Apache/EPL approach. The React `PATENTS` language terminated the patent license in cases where the licensee brought a patent infringement action against Facebook, or against any party "arising from" any Facebook product, even where the claim was unrelated to React, as well as where the licensee alleged that a Facebook patent was invalid or unenforceable. In response to criticism from the community, Facebook [revised][47] the patent license language in April 2015, but the revised version continued to include as termination criteria patent litigation against Facebook and patent litigation "arising from" Facebook products. + +Facebook came to apply the React license to many of its community projects. In April 2017 an [issue][48] was opened in the Apache Software Foundation (ASF) "Legal Discuss" issue tracker concerning whether Apache Cassandra could use [RocksDB][49], another Facebook project using the React license, as a dependency. In addition to the several other ASF projects that were apparently already using RocksDB, a large number of ASF projects used React itself. In June, Chris Mattmann, VP of legal affairs for the ASF, [ruled][50] that the React license was relegated to the forbidden Category X (see my discussion of the [JSON license][12] last year)—despite the fact that the ASF has long placed open source licenses with similarly broad patent defense clauses (MPL 1.1, IBM-PL, CPL) in its semi-favored Category B. In response, Facebook relicensed RocksDB under [GPLv2][51] and the [Apache License][52] 2.0, and a few months later announced it was [relicensing React][53] and three other identically licensed projects under the MIT license. More recent Facebook project license changes from the React approach to conventional open source licenses include [osquery][54] (GPLv2 / Apache License 2.0) and [React Native][55] (MIT). + +Much of the community criticism of the React license was rather misinformed and often seemed to be little more than ad hominem attack against Facebook. One of the few examples of sober, well-reasoned analysis of the topic is [Heather Meeker's article][56] on Opensource.com. Whatever actual merits the React license may have, Facebook's decision to use it without making it licensor-neutral and without seeking OSI approval were tactical mistakes, as [Simon Phipps points out][57]. + +### 7. OpenSSL relicensing effort + +The [license][58] covering most of OpenSSL is a conjunction of two 1990s-vintage BSD-derivative licenses. The first closely resembles an early license of the Apache web server. The second is the bespoke license of OpenSSL's predecessor project SSLeay. Both licenses contain an advertising clause like that in the 4-clause BSD license. The closing sentence of the SSLeay license, a gratuitous snipe at the GPL, supports an interpretation, endorsed by the FSF but no doubt unintended, that the license is copyleft. If only because of the advertising clauses, the OpenSSL license has long been understood to be GPL-incompatible, as Mark McLoughlin explained in a now-classic [essay][59]. + +In 2015, a year after the disclosure of the Heartbleed vulnerability and the Linux Foundation's subsequent formation of the [Core Infrastructure Initiative][60], Rich Salz said in a [blog post][61] that OpenSSL planned to relicense to the Apache License 2.0. The OpenSSL team followed up in March 2017 with a [press release][62] announcing the relicensing initiative and set up a website to collect agreements to the license change from the project's several hundred past contributors. + +A form email sent to identified individual contributors, asking for permission to relicense, soon drew criticism, mainly because of its closing sentence: "If we do not hear from you, we will assume that you have no objection." Some raised policy and legal concerns over what Theo de Raadt called a "[manufacturing consent in volume][63]" approach. De Raadt mocked the effort by [posting][64] a facetious attempt to relicense GCC to the [ISC license][65]. + +Salz posted an [update][66] on the relicensing effort in June. At that point, 40% of contacted contributors had responded, with the vast majority in favor of the license change and fewer than a dozen objections, amounting to 86 commits, with half of them surviving in the master branch. Salz described in detail the reasonable steps the project had taken to review those objections, resulting in a determination that at most 10 commits required removal and rewriting. + +### 8. Open Source Security v. Perens + +Open Source Security, Inc. (OSS) is the commercial vehicle through which Brad Spengler maintains the out-of-tree [grsecurity][67] patchset to the Linux kernel. In 2015, citing concerns about GPL noncompliance by users and misuse of the grsecurity trademark, OSS began [limiting access][68] to the stable patchset to paying customers. In 2017 OSS [ceased][69] releasing any public branches of grsecurity. The [Grsecurity Stable Patch Access Agreement][70] affirms that grsecurity is licensed under GPLv2 and that the user has all GPLv2 "rights and obligations," but states a policy of terminating access to future updates if a user redistributes patchsets or changelogs "outside of the explicit obligations under the GPL to User's customers." + +In June 2017, Bruce Perens published a [blog post][71] contending that the grsecurity agreement violated the GPL. OSS sued Perens in the Northern District of California, with claims for defamation, false light, and tortious interference with prospective advantage. In December the court [granted][72] Perens' motion to dismiss, denied without prejudice Perens' motion to strike under the California [anti-SLAPP][73] statute, and denied OSS's motion for partial summary judgment. In essence, the court said that as statements of opinion by a non-lawyer, Perens' blog posts were not defamatory. OSS has said it intends to appeal. + +### 9. Artifex Software v. Hancom + +Artifex Software licenses [Ghostscript][74] gratis under the [GPL][75] (more recently AGPL) and for revenue under proprietary licenses. In December 2016 Artifex sued Hancom, a South Korean vendor of office suite software, in the Northern District of California. Artifex alleged that Hancom had incorporated Ghostscript into its Hangul word processing program and Hancom Office product without obtaining a proprietary license or complying with the GPL. The [complaint][76] includes claims for breach of contract as well as copyright infringement. In addition to monetary damages, Artifex requested injunctive relief, including an order compelling Hancom to distribute the source code of Hangul and Hancom Office to Hancom's customers. + +In April 2017 the court [denied][77] Hancom's motion to dismiss. One of Hancom's arguments was that Artifex did not plead the existence of a contract because there was no demonstration of mutual assent. The court disagreed, stating that the allegations of Hancom's use of Ghostscript, failure to obtain a proprietary license, and public representation that its use of Ghostscript was licensed under the GPL were sufficient to plead the existence of a contract. In addition, Artifex's allegations regarding its dual-licensing scheme were deemed sufficient to plead damages for breach of contract. The denial of the motion to dismiss was widely misreported and sensationalized as a ruling that the GPL itself was "an enforceable contract." + +In September the court [denied][78] Hancom's motion for summary judgment on the breach of contract claim. Hancom first argued that as a matter of law Artifex was not entitled to money damages, essentially because GPL compliance required no payment to Artifex. The court rejected this argument, as the value of a royalty-bearing license and an unjust enrichment theory could serve as the measure of Artifex's damages. Second, Hancom argued in essence that any damages for contract breach could not be based on continuing GPL-noncompliant activity after Hancom first began shipping Ghostscript in violation of the GPL, because at that moment Hancom's GPL license was automatically terminated. In rejecting this argument, the court noted that GPLv3's language suggested Hancom's GPL obligations persisted beyond the termination of its GPL rights. The parties reached a settlement in December. + +Special thanks to Chris Gillespie for his research and analysis of the Artifex case. + +### 10. SFLC/Conservancy trademark dispute + +In 2006 the Software Freedom Law Center formed a [separate nonprofit organization][79], which it named the Software Freedom Conservancy. By July 2011, the two organizations no longer had any board members, officers, or employees in common, and SFLC ceased providing legal services to Conservancy. SFLC obtained a registration from the USPTO for the service mark SOFTWARE FREEDOM LAW CENTER in early 2011. In November 2011 Conservancy applied to register the mark SOFTWARE FREEDOM CONSERVANCY; the registration issued in September 2012. SFLC continues to be run by its founder Eben Moglen, while Conservancy is managed by former SFLC employees Karen Sandler and Bradley Kuhn. The two organizations are known to have opposing positions on a number of significant legal and policy matters (see, for example, my discussion of the [ZFS-on-Linux][12] issue last year). + +In September 2017, SFLC filed a [petition][80] with the [Trademark Trial and Appeal Board][81] to cancel Conservancy's trademark registration under Section 14 of the Lanham Trademark Act of 1946, [15 U.S.C.][82][§][82][1064][82], claiming that Conservancy's mark is confusingly similar to SFLC's. In November, Conservancy submitted its [answer][83] listing its affirmative defenses, and in December Conservancy filed a [summary judgment motion][84] on those defenses. The TTAB in effect [denied the summary judgment motion][85] on the basis that the affirmative defenses in Conservancy's answer were insufficiently pleaded. + +Moglen publicly [proposed a mutual release][86] of all claims "in return for an iron-clad agreement for mutual non-disparagement," including "a perpetual, royalty-free trademark license for Conservancy to keep and use its current name." [Conservancy responded][87] in a blog post that it could not "accept any settlement offer that includes a trademark license we don't need. Furthermore, any trademark license necessarily gives SFLC perpetual control over how we pursue our charitable mission." + +SFLC [moved][88] for leave to amend its petition to add a second ground for cancellation, that Conservancy's trademark registration was obtained by fraud. Conservancy's [response][89] argues that the proposed amendment does not state a claim for fraud. Meanwhile, Conservancy has submitted [applications for trademarks][90] for "THE SOFTWARE CONSERVANCY." + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/top-10-open-source-legal-stories-shook-2017 + +作者:[Richard Fontana][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/fontana +[1]:https://github.com/blog/2314-new-github-terms-of-service +[2]:https://web.archive.org/web/20170131092801/https:/help.github.com/articles/github-terms-of-service/ +[3]:https://opensource.com/law/11/7/trouble-harmony-part-1 +[4]:https://en.wikipedia.org/wiki/Moral_rights +[5]:https://www.mirbsd.org/permalinks/wlog-10_e20170301-tg.htm#e20170301-tg_wlog-10 +[6]:https://joeyh.name/blog/entry/removing_everything_from_github/ +[7]:https://joeyh.name/blog/entry/what_I_would_ask_my_lawyers_about_the_new_Github_TOS/ +[8]:https://www.fsf.org/blogs/licensing/do-githubs-updated-terms-of-service-conflict-with-copyleft +[9]:https://help.github.com/articles/github-terms-of-service/ +[10]:https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html#section4 +[11]:http://gplv3.fsf.org/gpl-rationale-2006-01-16.html#SECTION00390000000000000000 +[12]:https://opensource.com/article/17/1/yearbook-7-notable-legal-developments-2016 +[13]:https://www.linuxfoundation.org/about/technical-advisory-board/ +[14]:https://lkml.org/lkml/2017/10/16/122 +[15]:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/kernel-enforcement-statement.rst?h=v4.15 +[16]:https://sfconservancy.org/copyleft-compliance/principles.html +[17]:http://kroah.com/log/blog/2017/10/16/linux-kernel-community-enforcement-statement-faq/ +[18]:http://kroah.com/log/blog/2017/10/16/linux-kernel-community-enforcement-statement/ +[19]:https://www.redhat.com/en/about/press-releases/technology-industry-leaders-join-forces-increase-predictability-open-source-licensing +[20]:https://www.redhat.com/en/about/gplv3-enforcement-statement +[21]:https://lwn.net/Articles/516735/ +[22]:https://www.eclipse.org/legal/epl-v10.html +[23]:https://opensource.org/licenses/cpl1.0.php +[24]:https://opensource.org/licenses/IPL-1.0 +[25]:https://clojure.org/ +[26]:https://www.opendaylight.org/ +[27]:https://www.eclipse.org/org/press-release/20170829eplv2.php +[28]:https://www.gnu.org/licenses/license-list.en.html#EPL +[29]:http://www.eclipse.org/legal/eplfaq.php#GPLCOMPATIBLE +[30]:https://www.fsf.org/blogs/licensing/using-the-gpl-for-eclipse-plug-ins +[31]:https://mmilinkov.wordpress.com/2010/04/06/epl-gpl-commentary/ +[32]:https://www.gnu.org/software/classpath/license.html +[33]:https://github.com/eclipse/omr/blob/master/LICENSE +[34]:https://github.com/eclipse/openj9/blob/master/LICENSE +[35]:https://www.gnu.org/licenses/license-list.en.html#EPL2 +[36]:https://jcp.org/en/home/index +[37]:http://www.oracle.com/technetwork/java/javaee/overview/index.html +[38]:https://jcp.org/en/jsr/detail?id=348 +[39]:https://blogs.oracle.com/theaquarium/opening-up-java-ee +[40]:https://blogs.oracle.com/theaquarium/opening-up-ee-update +[41]:https://projects.eclipse.org/projects/ee4j/charter +[42]:https://javaee.github.io/glassfish/ +[43]:https://mmilinkov.wordpress.com/2018/01/23/ee4j-current-status-and-whats-next/ +[44]:https://reactjs.org/ +[45]:https://www.webmproject.org/license/additional/ +[46]:https://github.com/dotnet/coreclr/blob/master/PATENTS.TXT +[47]:https://github.com/facebook/react/blob/v0.13.3/PATENTS +[48]:https://issues.apache.org/jira/browse/LEGAL-303 +[49]:http://rocksdb.org/ +[50]:https://issues.apache.org/jira/browse/LEGAL-303?focusedCommentId=16052957&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-16052957 +[51]:https://github.com/facebook/rocksdb/pull/2226 +[52]:https://github.com/facebook/rocksdb/pull/2589 +[53]:https://code.facebook.com/posts/300798627056246/relicensing-react-jest-flow-and-immutable-js/ +[54]:https://github.com/facebook/osquery/pull/4007 +[55]:https://github.com/facebook/react-native/commit/26684cf3adf4094eb6c405d345a75bf8c7c0bf88 +[56]:https://opensource.com/article/17/9/facebook-patents-license +[57]:https://opensource.com/article/17/9/5-reasons-facebooks-react-license-was-mistake +[58]:https://www.openssl.org/source/license.html +[59]:https://people.gnome.org/~markmc/openssl-and-the-gpl.html +[60]:https://www.coreinfrastructure.org/ +[61]:https://www.openssl.org/blog/blog/2015/08/01/cla/ +[62]:https://www.coreinfrastructure.org/news/announcements/2017/03/openssl-re-licensing-apache-license-v-20-encourage-broader-use-other-foss +[63]:https://marc.info/?l=openbsd-tech&m=149028829020600&w=2 +[64]:https://marc.info/?l=openbsd-tech&m=149032069130072&w=2 +[65]:https://opensource.org/licenses/ISC +[66]:https://www.openssl.org/blog/blog/2017/06/17/code-removal/ +[67]:https://grsecurity.net/ +[68]:https://grsecurity.net/announce.php +[69]:https://grsecurity.net/passing_the_baton.php +[70]:https://web.archive.org/web/20170805231029/https:/grsecurity.net/agree/agreement.php +[71]:https://perens.com/2017/06/28/warning-grsecurity-potential-contributory-infringement-risk-for-customers/ +[72]:https://www.courtlistener.com/docket/6132658/53/open-source-security-inc-v-perens/ +[73]:https://en.wikipedia.org/wiki/Strategic_lawsuit_against_public_participation +[74]:https://www.ghostscript.com/ +[75]:https://www.gnu.org/licenses/licenses.en.html +[76]:https://www.courtlistener.com/recap/gov.uscourts.cand.305835.1.0.pdf +[77]:https://ia801909.us.archive.org/13/items/gov.uscourts.cand.305835/gov.uscourts.cand.305835.32.0.pdf +[78]:https://ia801909.us.archive.org/13/items/gov.uscourts.cand.305835/gov.uscourts.cand.305835.54.0.pdf +[79]:https://www.softwarefreedom.org/news/2006/apr/03/conservancy-launch/ +[80]:http://ttabvue.uspto.gov/ttabvue/v?pno=92066968&pty=CAN&eno=1 +[81]:https://www.uspto.gov/trademarks-application-process/trademark-trial-and-appeal-board +[82]:https://www.law.cornell.edu/uscode/text/15/1064 +[83]:http://ttabvue.uspto.gov/ttabvue/v?pno=92066968&pty=CAN&eno=5 +[84]:http://ttabvue.uspto.gov/ttabvue/v?pno=92066968&pty=CAN&eno=6 +[85]:http://ttabvue.uspto.gov/ttabvue/v?pno=92066968&pty=CAN&eno=8 +[86]:https://www.softwarefreedom.org/blog/2017/dec/22/conservancy/ +[87]:https://sfconservancy.org/blog/2017/dec/22/sflc-escalation/ +[88]:http://ttabvue.uspto.gov/ttabvue/v?pno=92066968&pty=CAN&eno=7 +[89]:http://ttabvue.uspto.gov/ttabvue/v?pno=92066968&pty=CAN&eno=9 +[90]:http://tsdr.uspto.gov/documentviewer?caseId=sn87670034&docId=FTK20171106083425#docIndex=0&page=1 From fd757cb1c7293aa4849f2155ac12d590804d9996 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Mar 2018 11:23:01 +0800 Subject: [PATCH 072/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Concurrent=20Serv?= =?UTF-8?q?ers:=20Part=205=20-=20Redis=20case=20study?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rent Servers- Part 5 - Redis case study.md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md diff --git a/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md b/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md new file mode 100644 index 0000000000..823db314c5 --- /dev/null +++ b/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md @@ -0,0 +1,119 @@ +Concurrent Servers: Part 5 - Redis case study +====== +This is part 5 in a series of posts on writing concurrent network servers. After discussing techniques for constructing concurrent servers in parts 1-4, this time we're going to do a case study of an existing production-quality server - [Redis][10]. + +![Redis logo](https://eli.thegreenplace.net/images/2017/redis_logo.png) + +Redis is a fascinating project and I've been following it with interest for a while now. One of the things I admire most about Redis is the clarity of its C source code. It also happens to be a great example of a high-performance concurrent in-memory database server, so the opportunity to use it as a case study for this series was too good to ignore. + +Let's see how the ideas discussed in parts 1-4 apply to a real-world application. + +All posts in the series: + +* [Part 1 - Introduction][3] + +* [Part 2 - Threads][4] + +* [Part 3 - Event-driven][5] + +* [Part 4 - libuv][6] + +* [Part 5 - Redis case study][7] + +### Event-handling library + +One of Redis's main claims to fame around the time of its original release in 2009 was its speed - the sheer number of concurrent client connections the server could handle. It was especially notable that Redis did this all in a single thread, without any complex locking and synchronization schemes on the data stored in memory. + +This feat was achieved by Redis's own implementation of an event-driven library which is wrapping the fastest event loop available on a system (epoll for Linux, kqueue for BSD and so on). This library is called [ae][11]. ae makes it possible to write a fast server as long as none of the internals are blocking, which Redis goes to great lengths to guarantee [[1]][12]. + +What mainly interests us here is ae's support of file events - registering callbacks to be invoked when file descriptors (like network sockets) have something interesting pending. Like libuv, ae supports multiple event loops and - having read parts 3 and 4 in this series - the signature of aeCreateFileEvent shouldn't be surprising: + +``` +int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, + aeFileProc *proc, void *clientData); +``` + +It registers a callback (proc) for new file events on fd, with the given event loop. When using epoll, it will call epoll_ctl to add an event on the file descriptor (either EPOLLIN, EPOLLOUT or both, depending on the mask parameter). ae's aeProcessEvents is the "run the event loop and dispatch callbacks" function, and it calls epoll_wait under the hood. + +### Handling client requests + +Let's trace through the Redis server code to see how ae is used to register callbacks for client events. initServer starts it by registering a callback for read events on the socket(s) being listened to, by calling aeCreateFileEvent with the callback acceptTcpHandler. This callback is invoked when new client connections are available. It calls accept [[2]][13] and then acceptCommonHandler, which in turn calls createClient to initialize the data structures required to track a new client connection. + +createClient's job is to start listening for data coming in from the client. It sets the socket to non-blocking mode (a key ingredient in an asynchronous event loop) and registers another file event callback with aeCreateFileEvent - for read events - readQueryFromClient. This function will be invoked by the event loop every time the client sends some data. + +readQueryFromClient does just what we'd expect - parses the client's command and acts on it by querying and/or manipulating data and sending a reply back. Since the client socket is non-blocking, this function has to be able to handle EAGAIN, as well as partial data; data read from the client is accumulated in a client-specific buffer, and the full query may be split across multiple invocations of the callback. + +### Sending data back to clients + +In the previous paragraph I said that readQueryFromClient ends up sending replies back to clients. This is logically true, because readQueryFromClient prepares the reply to be sent, but it doesn't actually do the physical sending - since there's no guarantee the client socket is ready for writing/sending data. We have to use the event loop machinery for that. + +The way Redis does this is by registering a beforeSleep function to be called every time the event loop is about to go sleeping waiting for sockets to become available for reading/writing. One of the things beforeSleep does is call handleClientsWithPendingWrites. This function tries to send all available replies immediately by calling writeToClient; if some of the sockets are unavailable, it registers an event-loop callback to invoke sendReplyToClient when the socket is ready. This can be seen as a kind of optimization - if the socket is immediately ready for sending (which often is the case for TCP sockets), there's no need to register the event - just send the data. Since sockets are non-blocking, this never actually blocks the loop. + +### Why does Redis roll its own event library? + +In [part 4][14] we've discussed building asynchronous concurrent servers using libuv. It's interesting to ponder the fact that Redis doesn't use libuv, or any similar event library, and instead implements its own - ae, including wrappers for epoll, kqueue and select. In fact, antirez (Redis's creator) answered precisely this question [in a blog post in 2011][15]. The gist of his answer: ae is ~770 lines of code he intimately understands; libuv is huge, without providing additional functionality Redis needs. + +Today, ae has grown to ~1300 lines, which is still trivial compared to libuv's 26K (this is without Windows, test, samples, docs). libuv is a far more general library, which makes it more complex and more difficult to adapt to the particular needs of another project; ae, on the other hand, was designed for Redis, co-evolved with Redis and contains only what Redis needs. + +This is another great example of the dependencies in software projects formula I mentioned [in a post earlier this year][16]: + +> The benefit of dependencies is inversely proportional to the amount of effort spent on a software project. + +antirez referred to this, to some extent, in his post. He mentioned that dependencies that provide a lot of added value ("foundational" dependencies in my post) make more sense (jemalloc and Lua are his examples) than dependencies like libuv, whose functionality is fairly easy to implement for the particular needs of Redis. + +### Multi-threading in Redis + +[For the vast majority of its history][17], Redis has been a purely single-threaded affair. Some people find this surprising, but it makes total sense with a bit of thought. Redis is inherently network-bound - as long as the database size is reasonable, for any given client request, much more time is spent waiting on the network than inside Redis's data structures. + +These days, however, things are not quite that simple. There are several new capabilities in Redis that use threads: + +1. "Lazy" [freeing of memory][8]. + +2. Writing a [persistence journal][9] with fsync calls in a background thread. + +3. Running user-defined modules that need to perform a long-running operation. + +For the first two features, Redis uses its own simple bio library (the acronym stands for "Background I/O"). The library is hard-coded for Redis's needs and can't be used outside it - it runs a pre-set number of threads, one per background job type Redis needs. + +For the third feature, [Redis modules][18] could define new Redis commands, and thus are held to the same standards as regular Redis commands, including not blocking the main thread. If a custom Redis command defined in a module wants to perform a long-running operation, it has to spin up a thread to run it in the background. src/modules/helloblock.c in the Redis tree provides an example. + +With these features, Redis combines an event loop with threading to get both speed in the common case and flexibility in the general case, similarly to the work queue discussion in [part 4][19] of this series. + + +| [[1]][1] | A core aspect of Redis is its being an _in-memory_ database; therefore, queries should never take too long to execute. There are all kinds of complications, however. In case of partitioning, a server may end up routing the request to another instance; in this case async I/O is used to avoid blocking other clients. | + + +| [[2]][2] | Through anetAccept; anet is Redis's wrapper for TCP socket code. | + + + +-------------------------------------------------------------------------------- + +via: https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/ + +作者:[Eli Bendersky][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://eli.thegreenplace.net/pages/about +[1]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id1 +[2]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id2 +[3]:http://eli.thegreenplace.net/2017/concurrent-servers-part-1-introduction/ +[4]:http://eli.thegreenplace.net/2017/concurrent-servers-part-2-threads/ +[5]:http://eli.thegreenplace.net/2017/concurrent-servers-part-3-event-driven/ +[6]:http://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/ +[7]:http://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/ +[8]:http://antirez.com/news/93 +[9]:https://redis.io/topics/persistence +[10]:https://redis.io/ +[11]:https://redis.io/topics/internals-rediseventlib +[12]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id4 +[13]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id5 +[14]:http://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/ +[15]:http://oldblog.antirez.com/post/redis-win32-msft-patch.html +[16]:http://eli.thegreenplace.net/2017/benefits-of-dependencies-in-software-projects-as-a-function-of-effort/ +[17]:http://antirez.com/news/93 +[18]:https://redis.io/topics/modules-intro +[19]:http://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/ From 7b0f0b2f56871423b8e044767b5e35fdcdc16c71 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Mar 2018 14:28:41 +0800 Subject: [PATCH 073/101] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Managing=20Digita?= =?UTF-8?q?l=20Files=20(e.g.,=20Photographs)=20in=20Files=20and=20Folders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...e.g., Photographs) in Files and Folders.md | 610 ++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 sources/tech/20140510 Managing Digital Files (e.g., Photographs) in Files and Folders.md diff --git a/sources/tech/20140510 Managing Digital Files (e.g., Photographs) in Files and Folders.md b/sources/tech/20140510 Managing Digital Files (e.g., Photographs) in Files and Folders.md new file mode 100644 index 0000000000..d1fd01ef0c --- /dev/null +++ b/sources/tech/20140510 Managing Digital Files (e.g., Photographs) in Files and Folders.md @@ -0,0 +1,610 @@ +Managing Digital Files (e.g., Photographs) in Files and Folders +====== +Update 2014-05-14: added real world example + +Update 2015-03-16: filtering photographs according to their GPS coordinates + +Update 2016-08-29: replaced outdated `show-sel.sh` method with new `filetags --filter` method + +Update 2017-08-28: Email comment on geeqie video thumbnails + +I am a passionate photographer when being on vacation or whenever I see something beautiful. This way, I collected many [JPEG][1] files over the past years. Here, I describe how I manage my digital photographs while avoiding any [vendor lock-in][2] which binds me to a temporary solution and leads to loss of data. Instead, I prefer solutions where I am able to **invest my time and effort for a long-term relationship**. + +This (very long) entry is **not about image files only** : I am going to explain further things like my folder hierarchy, file name convention, and so forth. Therefore, this information applies to all kind of files I process. + +Before I start explaining my method, we should come to an agreement whether or not we do have the same set of requirements I am trying to match with my method. If you are into [raw image formats][3], storing your photographs somewhere in the cloud or anything else very special to you (and not to me), you might not get satisfied with the things described here. Decide yourself. + +### My requirements + +For **getting the photographs (and movies) from my digital camera to my computer** , I just want to put the SD card into my computer and invoke the fetch-workflow. This thing also has to **pre-process the files** to meet my file name convention (described further down) and to rotate images that are in portrait orientation (and not in landscape). + +Those files are written to my photography inbox folder `$HOME/tmp/digicam/`. In this folder, I want to **look through my image files and play movies** to **sort out/delete, rename, add/remove tags, and put sets of related files into separate destination folders**. + +After that, I want to **navigate through my set of folders** containing the sets of image/movie files. In rare occasions, I want to **open an image file in an independent image processing tool** like [the GIMP][4]. Just for **rotating JPEG files** , I want to have a quick method which does not require an image processing tool and which is rotating JPEG images [in a loss-less way][5]. + +My digital camera has now support for tagging images with [GPS][6] coordinates. Therefore, I need a method to **visualize GPS coordinates for single files as well as for a set of files** showing the path I was walking. + +There is another nice feature I want to use: imagine a beautiful vacation in Venice where you took hundreds of photographs. Each of them is so beautiful so that you do not want to delete some of them. On the other side, you might want to get a smaller set of photographs for presenting to your friends at home. And they are only expecting maybe two dozens of files before being too jealous. Therefore, I want to be able to **define and show a certain sub-set of photos**. + +In terms of being independent and **avoid lock-in effects** , I do not want to use a tool I am not able to use when a company discontinues a product or service. For the very same reason and because I am a privacy-aware person, **I do not want to use any cloud-based service**. In order to keep myself open for new possibilities, I do not want to invest any effort in something which is only available on one specific operating system platform. **Basic stuff has to be available on any platform** (viewing, navigation, ...). But the **full set of requirements have to work on GNU/Linux** , in my case Debian GNU/Linux. + +Before I describe my current solutions to this fairly large set of requirements mentioned above, I have to explain my general folder structure and file naming convention I also use for digital photographs. But first, there is an important fact you have to consider: + +#### iPhoto, Picasa, and such considered harmful + +Software tools which manage collections of photographs do provide pretty cool features. They offer a nice user interface and try to give you cozy work-flows for all kinds of requirements. + +The big issue I do have got with them is numerous. They mostly use proprietary storage formats for almost everything: image files, meta-data, and so forth. This is a huge issue, when you are going to change to a different software in a couple of years. Trust me: **you are going to switch** , some day, in any case, for multiple reasons. + +If you are in the position where you need to switch your tool, you are going to realize that iPhoto or Picasa do store original image files and everything you did to them separately. Rotation of images, adding description to image files, tags, cropping, and so forth: **everything will be lost forever** if you are not able to export it and re-import it to the new tool. Chances are very high that you are not going to do this without loss of information or data. + +I do not want to invest any effort in a tool which locks away my work. **I refuse to lock-in myself to any proprietary tool.** Been there, done that. Learned my lessons. + +This is the reason why I keep time-stamps, image descriptions, or tags in the file name itself. File names are permanent unless I manually change them. They do not get lost when I backup my photographs or when I copy them to USB memory sticks or other operating systems. Everybody is able to read them. Any future system is able to process them. + +### My file name convention + +All my files which do have a relation to a specific day or a time I start with a **date-stamp** or a **time-stamp** according to an adopted [ISO 8601][7]. + +Example file name with a date-stamp and two tags: `2014-05-09 Budget export for project 42 -- finance company.csv` + +Example file name with a time-stamp (even including optional seconds) and two tags: `2014-05-09T22.19.58 Susan presenting her new shoes -- family clothing.jpg` + +I have to use adopted ISO time-stamps because colons are not suitable for the Windows [file system NTFS][8]. Therefore, I replaced colons with dots for separating hours from minutes from the optional seconds. + +In case of **time or date duration** , I separate the two date- or time-stamps with two minus signs: "`2014-05-09--2014-05-13 Jazz festival Graz -- folder tourism music.pdf`". + +Time/date-stamps in file names have the advantage that they remain unchanged until I manually change them. Meta-data which is included in the file content itself (like [Exif][9]) tends to get lost when files are processed via tools that do not take care of those meta-data. Additionally, starting a file name with such a date/time-stamp ensures that files are displayed in a temporal order instead of alphabetic order. The alphabet is a [totally artificial sort order][10] and it is typically less practical for locating files by the user. + +When I want to associate **tags** to a file name, I place them between the original file name and the [file name extension][11] separated by a space, two minus signs and an additional space: "`--`". My tags are lower case English words which do not contain spaces or special characters. Sometimes, I might use concatenated words like `quantifiedself` or `usergenerated`. I [tend to prefer general categories][12] instead of more (too) more specific describing tags. I re-use my tags on Twitter [hashtags][13], file names, folder names, bookmarks, blog entries like this one, and so forth. + +Tags as part of the file name have several advantages. You are able to locate files with the help of tags by using your usual desktop search engine. Tags in file-names can not be lost because of copying on different storage media. This usually happens, whenever a system uses a different storage place than the file name: meta-data data-base, [dot-files][14], [alternate data streams][15], and so forth. + +Of course, please do **avoid special characters** , umlauts, colons, and so forth in file and folder names in general. Especially when you synchronize files between different operating system platforms. + +My **file name convention for folders** is the same as for files. + +Note: Because of the clever [filenametimestamps][16]-module of [Memacs][17], all files and folders with a date/time-stamp appear on the very same time/day on my Org-mode calendar (agenda). This way, I get a very cool overview on what happened when on which day including all photographs I took. + +### My general folder structure + +In this section, I will describe my most important folders within my home folder. NOTE: this might get moved to an independent page somewhere in the future. Or not. Time will tell. :-) + +Lots of stuff is only of interest for a certain period of time. These are things like downloads to quickly skim through its content, unpack ZIP files to examine the files contained, minor interesting stuff, and so forth. For **temporary stuff** I do have the `$HOME/tmp/` sub-hierarchy. New photographs are placed in `$HOME/tmp/digicam/`. Stuff I temporary copy from a CD, DVD, or USB memory stick are put in `$HOME/tmp/fromcd/`. Whenever a software tool needs temporary data within my user folder hierarchy, I use `$HOME/tmp/Tools/` as an starting point. A very frequent folder for me is `$HOME/tmp/2del/`: "2del" means "ready for being deleted any time". All my browser are using this folder as the default download folder for example. In case I need to free space on a machine, I firstly look at this `2del`-folder for stuff to delete. + +In contrast to the temporary stuff described above, I certainly want to keep files **for a longer period of time** as well. Those files gets moved to my `$HOME/archive/` sub-hierarchy. Its got several sub-folders for backups, web/download-stuff I want to keep, binary files I want to archive, index files of removable media (CD, DVD, memory sticks, external hard drives), and a folder where I place stuff I want to archive (and look for a decent destination folder) in the near future. Sometimes, I am too busy or impatient for the moment to file things properly. Yes, that's me I even have a "do not bug me now"-folder. Is this weird to you? :-) + +The most important sub-hierarchy within my archive is `$HOME/archive/events_memories/` and its sub/folders `2014/`, `2013/`, `2012/`, and so forth. As you might have guessed already, there is one **sub-folder per year**. Within each of them, there are single files and folders. The files are named according to my file name convention described in the previous section. Folder names start with an [ISO 8601][7] datestamp in the form "YYYY-MM-DD" followed by a hopefully descriptive name like `$HOME/archive/events_memories/2014/2014-05-08 Business marathon with colleagues/`. Within those date-related folders I keep all kinds of files which are related to a certain event: photographs, (scanned) PDF-files, text files, and so forth. + +For **sharing data** , I maintain a `$HOME/share/` sub-hierarchy. There is my Dropbox folder, folders for important people I share data using all kinds of methods (like [unison][18]). I also share data among my set of devices: Mac Mini at home, GNU/Linux notebook at home, Android phone, root-server (my personal cloud), Windows-notebook at work. I don't want to elaborate on my synchronization set-up here. There might be another blog entry for this if you ask nicely. :-) + +Within my `$HOME/templates_labels/` sub-hierarchy, I keep all kinds of **template files** ([LaTeX][19], scripts, ...), cliparts and **logos** , and so forth. + +My **Org-mode** files, I mostly keep within `$HOME/org/`. I practice retentiveness and do not explain how much I love [Emacs/Org-mode][20] and how much I get out of it this time. You probably have read or heard me elaborating the awesome things I do with it. Just look out for [my `emacs` tag][21] on my blog and its [hashtag `#orgmode`][22] on twitter. + +So far about my most important folder sub-hierarchies. + +### My workflows + +Tataaaa, after you learned about my folder structure and file name convention, here are my current workflows and tools I use for the requirements I described further up. + +Please note that **you have to know, what you are doing**. My examples here contain folder paths and more that **only works on my machine or my set-up**. **You have to adopt stuff** like paths, file names, and so forth to meet your requirements! + +#### Workflow: Moving files from my SD card to the laptop, rotating portrait images, and renaming files + +When I want to move data from my digital camera to my GNU/Linux notebook, I take out its Mini-SD storage card and put it in my notebook. Then it gets mounted on `/media/digicam` automatically. + +Then, I invoke [getdigicamdata.sh][23] which does several things: it moves the files from the SD card to a temporary folder for processing. The original file names are being converted to lower-case characters. All portrait photographs are rotated using [jhead][24]. Also with jhead, I generate file-name time-stamps from the Exif header time-stamps. Using [date2name][25] I add time-stamps also to the movie files. After processing all those files, they get moved to the destination folder for new digicam files: $HOME/tmp/digicam/tmp/~. + +#### Workflow: Folder navigation, viewing, renaming, deleting image files + +For skimming through my image and movie files, I prefer to use [geeqie][26] on GNU/Linux. It is a fairly lightweight image browser which has one big advantage other file browsers are missing: I can add external scripts/tools that can be invoked by a keyboard shortcut. This way, I am able to extend the feature-set of the image browser by arbitrary external commands. + +Basic image management functionality is built-in to geeqie: navigating my folder hierarchy, viewing image files in window-mode and in full-screen more (shortcut `f`), renaming file names, deleting files, showing Exif meta-data (shortcut `Ctrl-e`). + +On OS X, I use [Xee][27]. Unlike geeqie, it is not extendable by external commands. However, the basic navigation, viewing, and renaming functions are available as well. + +#### Workflow: Adding and removing tags + +I created a Python script called [filetags][28] which I use for adding and removing tags to single files as well as a set of files. + +For digital photographs, I use tags like, e.g., `specialL` for landscape images that I consider suitable for desktop backgrounds and so forth, `specialP` for portrait photographs I would like to show to others, `sel` for a selection, and many more. + +##### Initial set-up of filetags with geeqie + +Adding filetags to geeqie is a manual step: `Edit > Preferences > Configure Editors ...`. Then create an additional entry with `New`. There, you can define a new desktop-file which looks like this: + +add-tags.desktop +``` +[Desktop Entry] +Name=filetags +GenericName=filetags +Comment= +Exec=/home/vk/src/misc/vk-filetags-interactive-adding-wrapper-with-gnome-terminal.sh %F +Icon= +Terminal=true +Type=Application +Categories=Application;Graphics; +hidden=false +MimeType=image/*;video/*;image/mpo;image/thm +Categories=X-Geeqie; + +``` + +The wrapper-script `vk-filetags-interactive-adding-wrapper-with-gnome-terminal.sh` is necessary because I want a new terminal window to pop-up in order to add tags to my files: + +vk-filetags-interactive-adding-wrapper-with-gnome-terminal.sh +``` +#!/bin/sh + +/usr/bin/gnome-terminal \ + --geometry=85x15+330+5 \ + --tab-with-profile=big \ + --hide-menubar \ + -x /home/vk/src/filetags/filetags.py --interactive "${@}" + +#end + +``` + +In geeqie, you can add a keyboard shortcut in `Edit > Preferences > Preferences ... > Keyboard`. I associated `t` with the `filetags` command. + +The filetags script is also able to remove tags from a single file or a set of files. It basically uses the same method as described above. The only difference is the additional `--remove` parameter for the filetags script: + +remove-tags.desktop +``` +[Desktop Entry] +Name=filetags-remove +GenericName=filetags-remove +Comment= +Exec=/home/vk/src/misc/vk-filetags-interactive-removing-wrapper-with-gnome-terminal.sh %F +Icon= +Terminal=true +Type=Application +Categories=Application;Graphics; +hidden=false +MimeType=image/*;video/*;image/mpo;image/thm +Categories=X-Geeqie; + +``` + +vk-filetags-interactive-removing-wrapper-with-gnome-terminal.sh +``` +#!/bin/sh + +/usr/bin/gnome-terminal \ + --geometry=85x15+330+5 \ + --tab-with-profile=big \ + --hide-menubar \ + -x /home/vk/src/filetags/filetags.py --interactive --remove "${@}" + +#end + +``` + +For removing tags, I created a keyboard shortcut for `T`. + +##### Using filetags within geeqie + +When I skim though image files in the geeqie file browser, I select files I want to tag (one to many) and press `t`. Then, a small window pops up and asks me for one or more tags. After confirming with `Return`, these tags gets added to the file names. + +The same goes for removing tags: selecting multiple files, pressing `T`, entering tags to be removed, and confirming with `Return`. That's it. There is [almost no simpler way to add or remove tags to files][29]. + +#### Workflow: Advanced file renaming with appendfilename + +##### Without appendfilename + +Renaming a large set of files can be a tedious process. With original file names like `2014-04-20T17.09.11_p1100386.jpg`, the process to add a description to its file name is quite annoying. You are going to press `Ctrl-r` (rename) in geeqie which opens the file rename dialog. The base-name (file-name without the file extension) is marked by default. So if you do not want to delete/overwrite the file name (but append to it), you have to press the cursor key for ``. Then, the cursor is placed between the base name and the extension. Type in your description (don't forget the initial space character) and confirm with `Return`. + +##### Using appendfilename with geeqie + +With [appendfilename][30], my process is simplified to gain maximum user experience for appending text to file names: When I press `a` (append) in geeqie, a dialog window pops up, asking for a text. After confirming with `Return`, the entered text gets placed between the time-stamp and the optional tags. + +For example when I press `a` on `2014-04-20T17.09.11_p1100386.jpg` and I type `Pick-nick in Graz`, the file name gets changed to `2014-04-20T17.09.11_p1100386 Pick-nick in Graz.jpg`. When I press `a` once again and enter `with Susan`, the file name gets changed to `2014-04-20T17.09.11_p1100386 Pick-nick in Graz with Susan.jpg`. When the file name got tags as well, the appended text gets appended before the tag-separator. + +This way, I do not have to be afraid to overwrite time-stamps or tags. The process for renaming gets much more enjoyable for me! + +And the best part: when I want to add the same text to multiple selected files, this also works with appendfilename. + +##### Initial set-up of appendfilename with geeqie + +Add an additional editor to geeqie: `Edit > Preferences > Configure Editors ... > New`. Then enter the desktop file definition: + +appendfilename.desktop +``` +[Desktop Entry] +Name=appendfilename +GenericName=appendfilename +Comment= +Exec=/home/vk/src/misc/vk-appendfilename-interactive-wrapper-with-gnome-terminal.sh %F +Icon= +Terminal=true +Type=Application +Categories=Application;Graphics; +hidden=false +MimeType=image/*;video/*;image/mpo;image/thm +Categories=X-Geeqie; + +``` + +Once again, I do use a wrapper-script that provides me the terminal window: + +vk-appendfilename-interactive-wrapper-with-gnome-terminal.sh +``` +#!/bin/sh + +/usr/bin/gnome-terminal \ + --geometry=90x5+330+5 \ + --tab-with-profile=big \ + --hide-menubar \ + -x /home/vk/src/appendfilename/appendfilename.py "${@}" + +#end + +``` + +#### Workflow: Play movie files + +On GNU/Linux, I use [mplayer][31] to play-back video files. Since geeqie does not play movie files on itself, I have to create a set-up where I can open a movie file in mplayer. + +##### Initial set-up of mplayer with geeqie + +I did already associate movie file extensions to mplayer using [xdg-open][32]. Therefore, I only had to create a general "open" command to geeqie which uses xdg-open to open any file with its associated application. + +Once again, visit `Edit > Preferences > Configure Editors ...` in geeqie and add an entry for `open`: + +open.desktop +``` +[Desktop Entry] +Name=open +GenericName=open +Comment= +Exec=/usr/bin/xdg-open %F +Icon= +Terminal=true +Type=Application +hidden=false +NOMimeType=*; +MimeType=image/*;video/* +Categories=X-Geeqie; + +``` + +When you also associate the shortcut `o` (see above) to geeqie, you are able to open video files (and other files) with their associated application. + +##### Opening movie files (and others) with xdg-open + +After the set-up process from above, you just have to press `o` when your geeqie cursor is above the file. That's it. + +#### Workflow: Open in an external image editor + +I rarely want to be able to quickly edit image files in the GIMP. Therefore, I added a shortcut `g` and associated it with the external editor "GNU Image Manipulation Program" (GIMP) which was already created by default by geeqie. + +This way, only pressing `g` opens the current image file in the GIMP. + +#### Workflow: Move to archive folder + +Now that I have added comments to my file names, I want to move single files to `$HOME/archive/events_memories/2014/` or set of files to new folders within this folder like `$HOME/archive/events_memories/2014/2014-05-08 Business-Marathon After-Show-Party`. + +The usual way is to select one or multiple files and move them to a folder with the shortcut `Ctrl-m`. + +So booooring. + +Therefore, I (again) wrote a Python script which does this job for me: [move2archive][33] (in short: `m2a`) expects one or more files as command line parameters. Then, a dialog appears where I am able to enter an optional folder name. When I do not enter anything at all but press `Return`, the files gets moved to the folder of the corresponding year. When I enter a folder name like `Business-Marathon After-Show-Party`, the date-stamp of the first image file is appended to the folder (`$HOME/archive/events_memories/2014/2014-05-08 Business-Marathon After-Show-Party`), the resulting folder gets created, and the files gets moved. + +Once again: I am in geeqie, select one or more files, press `m` (move) and either press only `Return` (no special sub-folder) or enter a descriptive text which is the name of the sub-folder to be created (optionally without date-stamp). + +**No image managing tool is as quick and as fun to use as my geeqie with appendfilename and move2archive via shotcuts.** + +##### Initial set-up of m2a with geeqie + +Once again, adding `m2a` to geeqie is a manual step: `Edit > Preferences > Configure Editors ...`. Then create an additional entry with `New`. There, you can define a new desktop-file which looks like this: + +m2a.desktop +``` +[Desktop Entry] +Name=move2archive +GenericName=move2archive +Comment=Moving one or more files to my archive folder +Exec=/home/vk/src/misc/vk-m2a-interactive-wrapper-with-gnome-terminal.sh %F +Icon= +Terminal=true +Type=Application +Categories=Application;Graphics; +hidden=false +MimeType=image/*;video/*;image/mpo;image/thm +Categories=X-Geeqie; + +``` + +The wrapper-script `vk-m2a-interactive-wrapper-with-gnome-terminal.sh` is necessary because I want a new terminal window to pop-up in order to enter my desired destination folder for my files: + +vk-m2a-interactive-wrapper-with-gnome-terminal.sh +``` +#!/bin/sh + +/usr/bin/gnome-terminal \ + --geometry=157x56+330+5 \ + --tab-with-profile=big \ + --hide-menubar \ + -x /home/vk/src/m2a/m2a.py --pauseonexit "${@}" + +#end + +``` + +In geeqie, you can add a keyboard shortcut in `Edit > Preferences > Preferences ... > Keyboard`. I associated `m` with the `m2a` command. + +#### Workflow: Rotate images (loss-less) + +Usually, portrait photographs are being marked automatically as portrait photographs by my digital camera. However, there are certain situations (like taking a photograph from above the motif) where my camera gets it wrong. In those **rare cases** , I have to manually fix the orientation. + +You have to know that the JPEG file format is a lossy format which should be used only for photographs and not for computer-generated stuff like screen-shots or diagrams. Rotating a JPEG image file in the dumb way usually results in decompressing/visualizing the image file, rotating the resulting image, and re-encoding the result once again. This causes a resulting image with [much worse image quality than the original image][5]. + +Therefore, you should use a lossless method to rotate you JPEG image files. + +Once again, I add an "external editor" to geeqie: `Edit > Preferences > Configure Editors ... > New`. There, I add two entries: one for rotating 270 degrees (which is 90 degrees counter-clock-wise) and one for rotating 90 degrees (clock-wise) using [exiftran][34]: + +rotate-270.desktop +``` +[Desktop Entry] +Version=1.0 +Type=Application +Name=Losslessly rotate JPEG image counterclockwise + +# call the helper script +TryExec=exiftran +Exec=exiftran -p -2 -i -g %f + +# Desktop files that are usable only in Geeqie should be marked like this: +Categories=X-Geeqie; +OnlyShowIn=X-Geeqie; + +# Show in menu "Edit/Orientation" +X-Geeqie-Menu-Path=EditMenu/OrientationMenu + +MimeType=image/jpeg; + +``` + +rotate-90.desktop +``` +[Desktop Entry] +Version=1.0 +Type=Application +Name=Losslessly rotate JPEG image clockwise + +# call the helper script +TryExec=exiftran +Exec=exiftran -p -9 -i -g %f + +# Desktop files that are usable only in Geeqie should be marked like this: +Categories=X-Geeqie; +OnlyShowIn=X-Geeqie; + +# Show in menu "Edit/Orientation" +X-Geeqie-Menu-Path=EditMenu/OrientationMenu + +# It can be made verbose +# X-Geeqie-Verbose=true + +MimeType=image/jpeg; + +``` + +I created geeqie keyboard shortcuts for `[` (counter-clock-wise) and `]` (clock-wise). + +#### Workflow: Visualizing GPS coordinates + +My digital camera has a GPS sensor which stores the current geographic location within the Exif meta-data of the JPEG files. The location data gets stored in [WGS 84][35] format like "47, 58, 26.73; 16, 23, 55.51" (latitude; longitude). This is not human-readable in the sense I would expect: either a map or a location name. Therefore, I added functionality to geeqie so, that I am able to see the location of a single image file on [OpenStreetMap][36]: `Edit > Preferences > Configure Editors ... > New` + +photolocation.desktop +``` +[Desktop Entry] +Name=vkphotolocation +GenericName=vkphotolocation +Comment= +Exec=/home/vk/src/misc/vkphotolocation.sh %F +Icon= +Terminal=true +Type=Application +Categories=Application;Graphics; +hidden=false +MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-gray;image/x-icb;image/x-ico;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/x-pcx;image/svg+xml;image/svg+xml-compressed;image/vnd.wap.wbmp; + +``` + +This calls my wrapper-script named `vkphotolocation.sh` which uses [ExifTool][37] to extract the coordinates in a suitable format that [Marble][38] is able to read and visualize: + +vkphotolocation.sh +``` +#!/bin/sh + +IMAGEFILE="${1}" +IMAGEFILEBASENAME=`basename ${IMAGEFILE}` + +COORDINATES=`exiftool -c %.6f "${IMAGEFILE}" | awk '/GPS Position/ { print $4 " " $6 }'` + +if [ "x${COORDINATES}" = "x" ]; then + zenity --info --title="${IMAGEFILEBASENAME}" --text="No GPS-location found in the image file." +else + /usr/bin/marble --latlon "${COORDINATES}" --distance 0.5 +fi + +#end + +``` + +Mapped to the keyboard shortcut `G`, I can quickly get to the **map position of its location of a single image file**. + +When I want to visualize the **positions of multiple JPEG image files as a path** , I am using [GpsPrune][39]. I was not able to derive a method where GpsPrune takes a set of files as command line parameters. And because of this, I have to manually start GpsPrune, select a set of files or a folder with `File > Add photos`. + +This way, I get a dot for each JPEG location on a map of OpenStreetMap (if configured so). By clicking on such a dot, I get details of the corresponding image. + +If you happen to be abroad while taking photographs, visualizing the GPS positions is a **great help for adding descriptions** to the file name! + +#### Workflow: Filtering photographs according to their GPS coordinates + +This is no workflow of mine. For the sake of completeness, I list features of tools that make this workflow possible. What I would like to do is looking for only those photographs out of a big pile of images, that are within a certain area (rectangle or point + distance). + +So far, I found only [DigiKam][40] which is able to [filter according to a rectangle][41]. If you know another tool, please add it to the comments below or write an email. + +#### Workflow: Showing a sub-set of a given set + +As described in the requirements above, I want to be able to define a sub-set of files within a folder in order to present this small collection to other people. + +The work-flow is pretty simple: I add a tag (via `t`/filetags) to the files of the selection. For this, I use the tag `sel` which is short for "selection". After I tagged the set of files, I can press `s` which I associated with a script that shows only the files tagged with `sel`. + +Of course, this also works with any tag or tag combination. Therefore, with the same method, you are able to get a decent overview on all photos of your wedding that are tagged with "church" and "rings". + +Nifty feature, isn't it? :-) + +##### Initial set-up of filetags for filtering according to tags + geeqie + +You have to define an additional "external editor": `Edit > Preferences > Configure Editors ... > New`: + +filter-tags.desktop +``` +[Desktop Entry] +Name=filetag-filter +GenericName=filetag-filter +Comment= +Exec=/home/vk/src/misc/vk-filetag-filter-wrapper-with-gnome-terminal.sh +Icon= +Terminal=true +Type=Application +Categories=Application;Graphics; +hidden=false +MimeType=image/*;video/*;image/mpo;image/thm +Categories=X-Geeqie; + +``` + +This once again calls a wrapper-script I wrote: + +vk-filetag-filter-wrapper-with-gnome-terminal.sh +``` +#!/bin/sh + +/usr/bin/gnome-terminal \ + --geometry=85x15+330+5 \ + --hide-menubar \ + -x /home/vk/src/filetags/filetags.py --filter + +#end + +``` + +What `filetags` with parameter `--filter` does is basically the following: the user gets asked to enter one or more tags. Then, all matching files of the current folder are linked to `$HOME/.filetags_tagfilter/` using [symbolic links][42]. Then, a new geeqie instance is started which shows the linked files. + +After quitting this new geeqie instance, you see the old geeqie instance, from where you invoked the selection process. + +#### Summary with a real world example + +Wow, this was a very long blog entry. No wonder that you might have lost the overview here and there. To sum up the things I am able to do within geeqie (that extends the standard feature set), I have this cool table below: + +shortcut function `m` m2a `o` open (for non-images) `a` add text to file name `t` filetags (add) `T` filetags (remove) `s` filetags (filter) `g` gimp `G` show GPS position `[` lossless rotate counterclockwise `]` lossless rotate clockwise `Ctrl-e` EXIF `f` full-screen + +Parts of a file name (including its path) and tools I use to manipulate the components accordingly: +``` + /this/is/a/folder/2014-04-20T17.09 Pick-nick in Graz -- food graz.jpg + [ m2a ] [ date2name ] [ appendfilename ] [filetags] + +``` + +In practice, I do the following steps to get my photographs from the camera to my archive: I put the SD memory card into my SD card reader of my computer. Then I start [getdigicamdata.sh][23]. After it is finished, I open `$HOME/tmp/digicam/tmp/` within geeqie. I skim through the photographs and delete the ones that did not work out. If there is an image with the wrong orientation, I correct it by `[` or `]`. + +In a second run, I add descriptions to files I consider worth commenting on (`a`). Whenever I want to add tags I do so as well: I quickly mark all files that should share a tag (`Ctrl` \+ mouse-click) and tag them using [filetags][28] (`t`). + +To combine files from a given event, I select corresponding files and move them to their "event-folder" within the yearly archive folder by typing the event description in [move2archive][33] (`m`). The rest (no special event folder) is moved to the yearly archive directly by move2archive (`m`) without stating a event description. + +To finish my work-flow, I delete all files on my SD card, dismount it from the operating system, and put it back into my digital camera. + +That's it. + +Because this work-flow requires almost no overhead at all, commenting, tagging, and filing photographs is not a tedious job any more. + +### Finally + +So, this is a detailed description of my work-flows related to photographs and movies I make. You probably have found additional stuff I might be interested in. So please do not hesitate and leave a comment or email by using the links below. + +I also would like to get feed-back if my work-flow works for you as well. And: if you have published your work-flows or find descriptions of other peoples work-flows, please do leave a comment as well! + +Have fun and don't waste your time with the wrong tools or inefficient methods! + +### Other Tools + +Read about [gThumb in this article][43]. + +Please do suggest your tools of choice when you've got the feeling that they fit my requirements mentioned above. + +### Email Comments + +> Date: Sat, 26 Aug 2017 22:05:09 +0200 +> Hello Karl, +> I like your articles and work with memacs and of course orgmode but I am not very familiar with python by the way... in your blog post of "managing-digital-photographs" you write about to open videos with [Geeqie][26]. +> It works, but I cant see any video thumbnails in the browser of Geeqie. Do you have any suggestions to get this to work? +> Thank you, Thomas + +Hi Thomas, + +Thanks for your kind words. I always feel great when somebody finds my work useful in his/her life. Unfortunately most of the time, I never hear of them. + +Yes, I sometimes use Geeqie to visualize folders that not only contain image files but movie files as well. In those cases, I don't see any thumbnail image of the video. You're absolutely right, there are many file browsers out there which are able to display some kind of preview image of a video. + +Quite frankly, I never thought of video thumbnails and I don't miss them. A quick research in the preferences and with my search engine did not suggest that there is a possible way to enable video previews in Geeqie. So no luck here. + +-------------------------------------------------------------------------------- + +via: http://karl-voit.at/managing-digital-photographs/ + +作者:[Karl Voit][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://karl-voit.at +[1]:https://en.wikipedia.org/wiki/Jpeg +[2]:http://en.wikipedia.org/wiki/Vendor_lock-in +[3]:https://en.wikipedia.org/wiki/Raw_image_format +[4]:http://www.gimp.org/ +[5]:http://petapixel.com/2012/08/14/why-you-should-always-rotate-original-jpeg-photos-losslessly/ +[6]:https://en.wikipedia.org/wiki/Gps +[7]:https://en.wikipedia.org/wiki/Iso_date +[8]:https://en.wikipedia.org/wiki/Ntfs +[9]:https://en.wikipedia.org/wiki/Exif +[10]:http://www.isisinform.com/reinventing-knowledge-the-medieval-controversy-of-alphabetical-order/ +[11]:https://en.wikipedia.org/wiki/File_name_extension +[12]:http://karl-voit.at/tagstore/en/papers.shtml +[13]:https://en.wikipedia.org/wiki/Hashtag +[14]:https://en.wikipedia.org/wiki/Dot-file +[15]:https://en.wikipedia.org/wiki/NTFS#Alternate_data_streams_.28ADS.29 +[16]:https://github.com/novoid/Memacs/blob/master/docs/memacs_filenametimestamps.org +[17]:https://github.com/novoid/Memacs +[18]:http://www.cis.upenn.edu/~bcpierce/unison/ +[19]:https://github.com/novoid/LaTeX-KOMA-template +[20]:http://orgmode.org/ +[21]:http://karl-voit.at/tags/emacs +[22]:https://twitter.com/search?q%3D%2523orgmode&src%3Dtypd +[23]:https://github.com/novoid/getdigicamdata.sh +[24]:http://www.sentex.net/%3Ccode%3Emwandel/jhead/ +[25]:https://github.com/novoid/date2name +[26]:http://geeqie.sourceforge.net/ +[27]:http://xee.c3.cx/ +[28]:https://github.com/novoid/filetag +[29]:http://karl-voit.at/tagstore/ +[30]:https://github.com/novoid/appendfilename +[31]:http://www.mplayerhq.hu +[32]:https://wiki.archlinux.org/index.php/xdg-open +[33]:https://github.com/novoid/move2archive +[34]:http://manpages.ubuntu.com/manpages/raring/man1/exiftran.1.html +[35]:https://en.wikipedia.org/wiki/WGS84#A_new_World_Geodetic_System:_WGS_84 +[36]:http://www.openstreetmap.org/ +[37]:http://www.sno.phy.queensu.ca/~phil/exiftool/ +[38]:http://userbase.kde.org/Marble/Tracking +[39]:http://activityworkshop.net/software/gpsprune/ +[40]:https://en.wikipedia.org/wiki/DigiKam +[41]:https://docs.kde.org/development/en/extragear-graphics/digikam/using-kapp.html#idp7659904 +[42]:https://en.wikipedia.org/wiki/Symbolic_link +[43]:http://karl-voit.at/2017/02/19/gthumb From 938613297545d0ab06767f880f54172134163ff8 Mon Sep 17 00:00:00 2001 From: LightonXue <30288036+LightonXue@users.noreply.github.com> Date: Fri, 2 Mar 2018 17:17:27 +0800 Subject: [PATCH 074/101] Update 20180227 Top 10 open source legal stories that shook 2017.md --- ...20180227 Top 10 open source legal stories that shook 2017.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md b/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md index 7ac21bdb5b..53052c7526 100644 --- a/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md +++ b/sources/talk/20180227 Top 10 open source legal stories that shook 2017.md @@ -1,3 +1,5 @@ +LightonXue翻译中 + Top 10 open source legal stories that shook 2017 ====== From 0b397d427a5cfbe285a984592e2184f188991e3d Mon Sep 17 00:00:00 2001 From: qhwdw Date: Fri, 2 Mar 2018 20:19:24 +0800 Subject: [PATCH 075/101] Translating by qhwdw --- .../20171207 Concurrent Servers- Part 5 - Redis case study.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md b/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md index 823db314c5..1205fa643d 100644 --- a/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md +++ b/sources/tech/20171207 Concurrent Servers- Part 5 - Redis case study.md @@ -1,3 +1,4 @@ +Translating by qhwdw Concurrent Servers: Part 5 - Redis case study ====== This is part 5 in a series of posts on writing concurrent network servers. After discussing techniques for constructing concurrent servers in parts 1-4, this time we're going to do a case study of an existing production-quality server - [Redis][10]. From 4c129222a7bf946d6c3d1f490d14eda7732e65f3 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 20:28:52 +0800 Subject: [PATCH 076/101] PRF:20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md @qhwdw --- ...h kSar To Identifying Linux Bottlenecks.md | 275 ++++++++++++------ 1 file changed, 180 insertions(+), 95 deletions(-) diff --git a/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md b/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md index 4d67c5173b..fe53159cec 100644 --- a/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md +++ b/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md @@ -1,36 +1,37 @@ -如何使用 kSar 去创建 sar 图表来发现 Linux 瓶颈 +使用 sar 和 kSar 来发现 Linux 性能瓶颈 ====== -sar 命令收集、报告、或者保存 UNIX / Linux 系统的活动信息。它保存选择的计数器到操作系统的 `/var/log/sa/sadd` 文件中。从收集的数据中,你可以得到许多关于你的服务器的信息: - 1. CPU 使用率 - 2. 内存页面和使用率 - 3. 网络 I/O 和传输统计 - 4. 进程创建活动 - 5. 所有的块设备活动 - 6. 每秒中断数等等 +`sar` 命令用用收集、报告、或者保存 UNIX / Linux 系统的活动信息。它保存选择的计数器到操作系统的 `/var/log/sa/sadd` 文件中。从收集的数据中,你可以得到许多关于你的服务器的信息: +1. CPU 使用率 +2. 内存页面和使用率 +3. 网络 I/O 和传输统计 +4. 进程创建活动 +5. 所有的块设备活动 +6. 每秒中断数等等 +`sar` 命令的输出能够用于识别服务器瓶颈。但是,分析 `sar` 命令提供的信息可能比较困难,所以要使用 kSar 工具。kSar 工具可以将 `sar` 命令的输出绘制成基于时间周期的、易于理解的图表。 -sar 命令的输出能够用于识别服务器瓶颈。但是,分析 sar 命令提供的信息可能比较困难,所以要使用 kSar 工具。kSar 工具将 sar 命令的输出绘制成基于时间周期的、易于理解的图表。 +### sysstat 包 +`sar`、`sa1`、和 `sa2` 命令都是 sysstat 包的一部分。它是 Linux 包含的性能监视工具集合。 -## sysstat 包 +1. `sar`:显示数据 +2. `sa1` 和 `sa2`:收集和保存数据用于以后分析。`sa2` shell 脚本在 `/var/log/sa` 目录中每日写入一个报告。`sa1` shell 脚本将每日的系统活动信息以二进制数据的形式写入到文件中。 +3. sadc —— 系统活动数据收集器。你可以通过修改 `sa1` 和 `sa2` 脚本去配置各种选项。它们位于以下的目录: + * `/usr/lib64/sa/sa1` (64 位)或者 `/usr/lib/sa/sa1` (32 位) —— 它调用 `sadc` 去记录报告到 `/var/log/sa/sadX` 格式。 + * `/usr/lib64/sa/sa2` (64 位)或者 `/usr/lib/sa/sa2` (32 位) —— 它调用 `sar` 去记录报告到 `/var/log/sa/sarX` 格式。 -sar、sa1、和 sa2 命令都是 sysstat 包的一部分。它是 Linux 包含的性能监视工具集合。 - - 1. sar:显示数据 - 2. sa1 和 sa2:为以后分析去收集和保存数据。sa2 shell 脚本在 `/var/log/sa` 目录中每日写入一个报告。sa1 shell 脚本将每日的系统活动信息以二进制数据的形式写入到文件中。 - 3. sadc —— 系统活动数据收集器。你可以通过修改 sa1 和 sa2 脚本去配置各种选项。它们位于以下的目录: - * /usr/lib64/sa/sa1 (64bit) 或者 /usr/lib/sa/sa1 (32bit) —— 它调用 sadc 去记录报告到 /var/log/sa/sadX 格式。 - * /usr/lib64/sa/sa2 (64bit) 或者 /usr/lib/sa/sa2 (32bit) —— 它调用 sar 去记录报告到 /var/log/sa/sarX 格式。 - - - -### 如何在我的系统上安装 sar? +#### 如何在我的系统上安装 sar? 在一个基于 CentOS/RHEL 的系统上,输入如下的 [yum 命令][1] 去安装 sysstat: -`# yum install sysstat` + +``` +# yum install sysstat +``` + 示例输出如下: + ``` Loaded plugins: downloadonly, fastestmirror, priorities, : protectbase, security @@ -78,12 +79,16 @@ Installed: Complete! ``` +#### 为 sysstat 配置文件 -### 为 sysstat 配置文件 +编辑 `/etc/sysconfig/sysstat` 文件去指定日志文件保存多少天(最长为一个月): + +``` +# vi /etc/sysconfig/sysstat +``` -编辑 /etc/sysconfig/sysstat 文件去指定日志文件保存多少天(最长为一个月): -`# vi /etc/sysconfig/sysstat` 示例输出如下 : + ``` # keep log for 28 days # the default is 7 @@ -95,8 +100,13 @@ HISTORY=28 ### 找到 sar 默认的 cron 作业 [默认的 cron 作业位于][2] `/etc/cron.d/sysstat`: -`# cat /etc/cron.d/sysstat` + +``` +# cat /etc/cron.d/sysstat +``` + 示例输出如下: + ``` # run system activity accounting tool every 10 minutes */10 * * * * root /usr/lib64/sa/sa1 1 1 @@ -104,11 +114,16 @@ HISTORY=28 53 23 * * * root /usr/lib64/sa/sa2 -A ``` -### 告诉 sadc 去报告磁盘的统计数据 +#### 告诉 sadc 去报告磁盘的统计数据 + +使用一个文本编辑器去编辑 `/etc/cron.d/sysstat` 文件,比如使用 `vim` 命令,输入如下: + +``` +# vi /etc/cron.d/sysstat +``` -使用一个文本编辑器去编辑 `/etc/cron.d/sysstat` 文件,比如使用 NA 命令或者 vim 命令,输入如下: -`# vi /etc/cron.d/sysstat` 像下面的示例那样更新这个文件,以记录所有的硬盘统计数据(`-d` 选项强制记录每个块设备的统计数据,而 `-I` 选项强制记录所有系统中断的统计数据): + ``` # run system activity accounting tool every 10 minutes */10 * * * * root /usr/lib64/sa/sa1 -I -d 1 1 @@ -116,14 +131,13 @@ HISTORY=28 53 23 * * * root /usr/lib64/sa/sa2 -A ``` -在一个 CentOS/RHEL 7.x 系统上你需要传递 `-S DISK` 选项去收集块设备的数据。传递`-S XALL` 选项去采集如下所列的数据: - - 1. 磁盘 - 2. 分区 - 3. 系统中断 - 4. SNMP - 5. IPv6 +在 CentOS/RHEL 7.x 系统上你需要传递 `-S DISK` 选项去收集块设备的数据。传递 `-S XALL` 选项去采集如下所列的数据: +1. 磁盘 +2. 分区 +3. 系统中断 +4. SNMP +5. IPv6 ``` # Run system activity accounting tool every 10 minutes @@ -136,7 +150,7 @@ HISTORY=28 保存并关闭这个文件。 -###打开 CentOS/RHEL 版本 5.x/6.x 的服务 +#### 打开 CentOS/RHEL 版本 5.x/6.x 的服务 输入如下命令: @@ -146,17 +160,21 @@ service sysstat start ``` 示例输出如下: + ``` Calling the system activity data collector (sadc): ``` 对于 CentOS/RHEL 7.x,运行如下的命令: + ``` # systemctl enable sysstat # systemctl start sysstat.service # systemctl status sysstat.service ``` + 示例输出: + ``` ● sysstat.service - Resets System Activity Logs Loaded: loaded (/usr/lib/systemd/system/sysstat.service; enabled; vendor preset: enabled) @@ -168,11 +186,16 @@ Jan 06 16:33:19 centos7-box systemd[1]: Starting Resets System Activity Logs... Jan 06 16:33:19 centos7-box systemd[1]: Started Resets System Activity Logs. ``` -## 如何使用 sar?如何查看统计数据? +### 如何使用 sar?如何查看统计数据? + +使用 `sar` 命令去显示操作系统中选定的累积活动计数器输出。在这个示例中,运行 `sar` 命令行,去实时获得 CPU 使用率的报告: + +``` +# sar -u 3 10 +``` -使用 sar 命令去显示操作系统中选定的累积活动计数器输出。在这个示例中,运行 sar 命令行,去实时获得 CPU 使用率的报告: -`# sar -u 3 10` 示例输出: + ``` Linux 2.6.18-164.2.1.el5 (www-03.nixcraft.in) 12/14/2009 @@ -192,126 +215,188 @@ Average: all 9.24 0.69 1.84 0.03 0.00 88.20 其中: - * 3 = 间隔时间 - * 10 = 次数 - - + * 3 表示间隔时间 + * 10 表示次数 查看进程创建的统计数据,输入: -`# sar -c 3 10` + +``` +# sar -c 3 10 +``` + 查看 I/O 和传输率统计数据,输入: -`# sar -b 3 10` + +``` +# sar -b 3 10 +``` + 查看内存页面统计数据,输入: -`# sar -B 3 10` + +``` +# sar -B 3 10 +``` + 查看块设备统计数据,输入: -`# sar -d 3 10` + +``` +# sar -d 3 10 +``` + 查看所有中断的统计数据,输入: -`# sar -I XALL 3 10` + +``` +# sar -I XALL 3 10 +``` + 查看网络设备特定的统计数据,输入: + ``` # sar -n DEV 3 10 # sar -n EDEV 3 10 ``` + 查看 CPU 特定的统计数据,输入: + ``` # sar -P ALL # Only 1st CPU stats # sar -P 1 3 10 ``` + 查看队列长度和平均负载的统计数据,输入: -`# sar -q 3 10` -查看内存和 swap 空间的使用统计数据,输入: + +``` +# sar -q 3 10 +``` + +查看内存和交换空间的使用统计数据,输入: + ``` # sar -r 3 10 # sar -R 3 10 ``` + 查看 inode、文件、和其它内核表统计数据状态,输入: -`# sar -v 3 10` + +``` +# sar -v 3 10 +``` + 查看系统切换活动统计数据,输入: -`# sar -w 3 10` -查看 swapping 统计数据,输入: -`# sar -W 3 10` + +``` +# sar -w 3 10 +``` + +查看交换统计数据,输入: + +``` +# sar -W 3 10 +``` + 查看一个 PID 为 3256 的 Apache 进程,输入: -`# sar -x 3256 3 10` -## kSar 介绍 +``` +# sar -x 3256 3 10 +``` -sar 和 sadf 提供了基于命令行界面的输出。这种输出可能会使新手用户/系统管理员感到无从下手。因此,你需要使用 kSar,它是一个图形化显示你的 sar 数据的 Java 应用程序。它也允许你以 PDF/JPG/PNG/CSV 格式导出数据。你可以用三种方式去加载数据:本地文件、运行本地命令、以及通过 SSH 远程运行的命令。kSar 可以处理下列操作系统的 sar 输出: +### kSar 介绍 - 1. Solaris 8, 9 和 10 - 2. Mac OS/X 10.4+ - 3. Linux (Systat Version >= 5.0.5) - 4. AIX (4.3 & 5.3) - 5. HPUX 11.00+ +`sar` 和 `sadf` 提供了基于命令行界面的输出。这种输出可能会使新手用户/系统管理员感到无从下手。因此,你需要使用 kSar,它是一个图形化显示你的 `sar` 数据的 Java 应用程序。它也允许你以 PDF/JPG/PNG/CSV 格式导出数据。你可以用三种方式去加载数据:本地文件、运行本地命令、以及通过 SSH 远程运行的命令。kSar 可以处理下列操作系统的 `sar` 输出: +1. Solaris 8, 9 和 10 +2. Mac OS/X 10.4+ +3. Linux (Systat Version >= 5.0.5) +4. AIX (4.3 & 5.3) +5. HPUX 11.00+ - -### 下载和安装 kSar +#### 下载和安装 kSar 访问 [官方][3] 网站去获得最新版本的源代码。使用 [wget][4] 去下载源代码,输入: -`$ wget https://github.com/vlsi/ksar/releases/download/v5.2.4-snapshot-652bf16/ksar-5.2.4-SNAPSHOT-all.jar` + +``` +$ wget https://github.com/vlsi/ksar/releases/download/v5.2.4-snapshot-652bf16/ksar-5.2.4-SNAPSHOT-all.jar +``` #### 如何运行 kSar? 首先要确保你的机器上 [JAVA jdk][5] 已安装并能够正常工作。输入下列命令去启动 kSar: -`$ java -jar ksar-5.2.4-SNAPSHOT-all.jar` + +``` +$ java -jar ksar-5.2.4-SNAPSHOT-all.jar +``` ![Fig.01: kSar welcome screen][6] + 接下来你将看到 kSar 的主窗口,和有两个菜单的面板。 + ![Fig.02: kSar - the main window][7] + 左侧有一个列表,是 kSar 根据数据已经解析出的可用图表的列表。右侧窗口将展示你选定的图表。 -## 如何使用 kSar 去生成 sar 图表? +#### 如何使用 kSar 去生成 sar 图表? + +首先,你需要从命名为 server1 的服务器上采集 `sar` 命令的统计数据。输入如下的命令: + +``` +[ server1 ]# LC_ALL=C sar -A > /tmp/sar.data.txt +``` + +接下来,使用 `scp` 命令从本地桌面拷贝到远程电脑上: + +``` +[ desktop ]$ scp user@server1.nixcraft.com:/tmp/sar.data.txt /tmp/ +``` + +切换到 kSar 窗口,点击 “Data” > “Load data from text file” > 从 `/tmp/` 中选择 `sar.data.txt` > 点击 “Open” 按钮。 -首先,你需要从命名为 server1 的服务器上采集 sar 命令的统计数据。输入如下的命令: -`[ **server1** ]# LC_ALL=C sar -A > /tmp/sar.data.txt` -接下来,使用 scp 命令从本地桌面拷贝到远程电脑上: -`[ **desktop** ]$ scp user@server1.nixcraft.com:/tmp/sar.data.txt /tmp/` -切换到 kSar 窗口,点击 **Data** > **Load data from text file** > 从 /tmp/ 中选择 sar.data.txt > 点击 **Open** 按扭。 现在,图表类型树已经出现在左侧面板中并选定了一个图形: + ![Fig.03: Processes for server1][8] -![Fig.03: Disk stats \(blok device\) stats for server1][9]![Fig.05: Memory stats for server1][10] +![Fig.03: Disk stats (blok device) stats for server1][9] -#### 放大和缩小 +![Fig.05: Memory stats for server1][10] + +##### 放大和缩小 通过移动你可以交互式缩放图像的一部分。在要缩放的图像的左上角点击并按下鼠标,移动到要缩放区域的右下角,可以选定要缩放的区域。返回到未缩放状态,点击并拖动鼠标到除了右下角外的任意位置,你也可以点击并选择 zoom 选项。 -#### 了解 kSar 图像和 sar 数据 +##### 了解 kSar 图像和 sar 数据 + +我强烈建议你去阅读 `sar` 和 `sadf` 命令的 man 页面: -我强烈建议你去阅读 sar 和 sadf 命令的 man 页面: ``` $ man sar $ man sadf ``` -## 案例学习:识别 Linux 服务器的 CPU 瓶颈 +### 案例学习:识别 Linux 服务器的 CPU 瓶颈 -使用 sar 命令和 kSar 工具,可以得到内存、CPU、以及其它子系统的详细快照。例如,如果 CPU 使用率在一个很长的时间内持续高于 80%,有可能就是出现了一个 CPU 瓶颈。使用 **sar -x ALL** 你可以找到大量消耗 CPU 的进程。[mpstat 命令][11] 的输出(sysstat 包的一部分)也会帮你去了解 CPU 的使用率。你可以使用 kSar 很容易地去分析这些信息。 +使用 `sar` 命令和 kSar 工具,可以得到内存、CPU、以及其它子系统的详细快照。例如,如果 CPU 使用率在一个很长的时间内持续高于 80%,有可能就是出现了一个 CPU 瓶颈。使用 `sar -x ALL` 你可以找到大量消耗 CPU 的进程。 -### 找出 CPU 瓶颈 … +[mpstat 命令][11] 的输出(sysstat 包的一部分)也会帮你去了解 CPU 的使用率。但你可以使用 kSar 很容易地去分析这些信息。 -然后对 CPU 选择执行如下的调整: +#### 找出 CPU 瓶颈后 … - 1. 确保没有不需要的进程在后台运行。关闭 [Linux 上所有不需要的服务][12]。 - 2. 使用 [cron 去计划作业][13] (比如,备份)运行在一个非高峰时刻。 - 3. 使用 [top 和 ps 命令][14] 去找出所有非关键的后台作业/服务。使用 [renice 命令][15] 去调整低优先级作业。 - 4. 使用 [taskset 命令去设置进程使用的 CPU ][16] (卸载 CPU),即,绑定进程到不同的 CPU 上。例如,在 2# CPU 上运行 MySQL 数据库,而在 3# CPU 上运行 Apache。 - 5. 确保你的系统使用了最新的驱动程序和固件。 - 6. 如有可能在系统上增加额外的 CPU。 - 7. 为单线程应用程序使用更快的 CPU(比如,Lighttpd web 服务器应用程序)。 - 8. 为多线程应用程序使用多个 CPU(比如,MySQL 数据库服务器应用程序)。 - 9. 为一个 web 应用程序使用多个计算节点并设置一个 [负载均衡器][17]。 +对 CPU 执行如下的调整: +1. 确保没有不需要的进程在后台运行。关闭 [Linux 上所有不需要的服务][12]。 +2. 使用 [cron][13] 在一个非高峰时刻运行任务(比如,备份)。 +3. 使用 [top 和 ps 命令][14] 去找出所有非关键的后台作业/服务。使用 [renice 命令][15] 去调整低优先级作业。 +4. 使用 [taskset 命令去设置进程使用的 CPU ][16] (卸载所使用的 CPU),即,绑定进程到不同的 CPU 上。例如,在 2# CPU 上运行 MySQL 数据库,而在 3# CPU 上运行 Apache。 +5. 确保你的系统使用了最新的驱动程序和固件。 +6. 如有可能在系统上增加额外的 CPU。 +7. 为单线程应用程序使用更快的 CPU(比如,Lighttpd web 服务器应用程序)。 +8. 为多线程应用程序使用多个 CPU(比如,MySQL 数据库服务器应用程序)。 +9. 为一个 web 应用程序使用多个计算节点并设置一个 [负载均衡器][17]。 +### isag —— 交互式系统活动记录器(替代工具) -## isag —— 交互式系统活动记录器(替代工具) - -isag 命令图形化显示了以前运行 sar 命令时存储在二进制文件中的系统活动数据。isag 命令引用 sar 并提取出它的数据来绘制图形。与 kSar 相比,isag 的选项比较少。 +`isag` 命令图形化显示了以前运行 `sar` 命令时存储在二进制文件中的系统活动数据。`isag` 命令引用 `sar` 并提取出它的数据来绘制图形。与 kSar 相比,`isag` 的选项比较少。 ![Fig.06: isag CPU utilization graphs][18] - ### 关于作者 本文作者是 nixCraft 的创始人和一位经验丰富的 Linux 操作系统/Unix shell 脚本培训师。他与包括 IT、教育、国防和空间研究、以及非营利组织等全球各行业客户一起合作。可以在 [Twitter][19]、[Facebook][20]、[Google+][21] 上关注他。 @@ -322,7 +407,7 @@ via: https://www.cyberciti.biz/tips/identifying-linux-bottlenecks-sar-graphs-wit 作者:[Vivek Gite][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 7d099701ab9dadca3797843452aa5a78de84e71d Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 20:30:02 +0800 Subject: [PATCH 077/101] PUB:20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md @qhwdw https://linux.cn/article-9398-1.html --- ...reate sar Graphs With kSar To Identifying Linux Bottlenecks.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md (100%) diff --git a/translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md b/published/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md similarity index 100% rename from translated/tech/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md rename to published/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md From 22383e30b9b91135888c3f10048bcebee011654e Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 21:52:05 +0800 Subject: [PATCH 078/101] PRF:20150615 Let-s Build A Simple Interpreter. Part 1..md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @BriFuture 翻译的很好,不过我看这个系列好长…… --- ...t-s Build A Simple Interpreter. Part 1..md | 108 +++++++++--------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md b/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md index 3a62934f42..ed2e0f0a0e 100644 --- a/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md +++ b/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md @@ -1,26 +1,27 @@ -让我们做个简单的解释器(1) +让我们做个简单的解释器(一) ====== +> “如果你不知道编译器是怎么工作的,那你就不知道电脑是怎么工作的。如果你不能百分百确定,那就是不知道它们是如何工作的。” --Steve Yegge -> **" If you don't know how compilers work, then you don't know how computers work. If you're not 100% sure whether you know how compilers work, then you don't know how they work."** -- Steve Yegge -> **“如果你不知道编译器是怎么工作的,那你就不知道电脑是怎么工作的。如果你不能百分百确定,那就是不知道他们是如何工作的。”** --Steve Yegge +就是这样。想一想。你是萌新还是一个资深的软件开发者实际上都无关紧要:如果你不知道编译器compiler解释器interpreter是怎么工作的,那么你就不知道电脑是怎么工作的。就这么简单。 -就是这样。想一想。你是萌新还是一个资深的软件开发者实际上都无关紧要:如果你不知道编译器和解释器是怎么工作的,那么你就不知道电脑是怎么工作的。就这么简单。 +所以,你知道编译器和解释器是怎么工作的吗?我是说,你百分百确定自己知道他们怎么工作吗?如果不知道。 -所以,你知道编译器和解释器是怎么工作的吗?我是说,你百分百确定自己知道他们怎么工作吗?如果不知道。![][1] +![][1] -或者如果你不知道但你非常想要了解它。 ![][2] +或者如果你不知道但你非常想要了解它。 -不用担心。如果你能坚持跟着这个系列做下去,和我一起构建一个解释器和编译器,最后你将会知道他们是怎么工作的。并且你会变成一个自信满满的快乐的人。至少我希望如此。![][3]。 +![][2] + +不用担心。如果你能坚持跟着这个系列做下去,和我一起构建一个解释器和编译器,最后你将会知道他们是怎么工作的。并且你会变成一个自信满满的快乐的人。至少我希望如此。 + +![][3] 为什么要学习编译器和解释器?有三点理由。 - 1. 要写出一个解释器或编译器,你需要有很多的专业知识,并能融会贯通。写一个解释器或编译器能帮你加强这些能力,成为一个更厉害的软件开发者。而且,你要学的技能对写软件非常有用,而不是仅仅局限于解释器或编译器。 - 2. 你确实想要了解电脑是怎么工作的。一般解释器和编译器看上去很魔幻。你或许不习惯这种魔力。你会想去揭开构建解释器和编译器那层神秘的面纱,了解他们的原理,把事情做好。 - 3. 你想要创建自己的编程语言或者特定领域的语言。如果你创建了一个,你还要为它创建一个解释器或者编译器。最近,兴起了对新的编程语言的兴趣。你能看到几乎每天都有一门新的编程语言横空出世:Elixir,Go,Rust,还有很多。 - - - +1. 要写出一个解释器或编译器,你需要有很多的专业知识,并能融会贯通。写一个解释器或编译器能帮你加强这些能力,成为一个更厉害的软件开发者。而且,你要学的技能对编写软件非常有用,而不是仅仅局限于解释器或编译器。 +2. 你确实想要了解电脑是怎么工作的。通常解释器和编译器看上去很魔幻。你或许不习惯这种魔力。你会想去揭开构建解释器和编译器那层神秘的面纱,了解它们的原理,把事情做好。 +3. 你想要创建自己的编程语言或者特定领域的语言。如果你创建了一个,你还要为它创建一个解释器或者编译器。最近,兴起了对新的编程语言的兴趣。你能看到几乎每天都有一门新的编程语言横空出世:Elixir,Go,Rust,还有很多。 好,但什么是解释器和编译器? @@ -32,11 +33,12 @@ 我希望你现在确信你很想学习构建一个编译器和解释器。你期望在这个教程里学习解释器的哪些知识呢? -你看这样如何。你和我一起做一个简单的解释器当作 [Pascal][5] 语言的子集。在这个系列结束的时候你能做出一个可以运行的 Pascal 解释器和一个像 Python 的 [pdb][6] 那样的源代码级别的调试器。 +你看这样如何。你和我一起为 [Pascal][5] 语言的一个大子集做一个简单的解释器。在这个系列结束的时候你能做出一个可以运行的 Pascal 解释器和一个像 Python 的 [pdb][6] 那样的源代码级别的调试器。 -你或许会问,为什么是 Pascal?有一点,它不是我为了这个系列而提出的一个虚构的语言:它是真实存在的一门编程语言,有很多重要的语言结构。有些陈旧但有用的计算机书籍使用 Pascal 编程语言作为示例(我知道对于选择一门语言来构建解释器,这个理由并不令人信服,但我认为学一门非主流的语言也不错:)。 +你或许会问,为什么是 Pascal?一方面,它不是我为了这个系列而提出的一个虚构的语言:它是真实存在的一门编程语言,有很多重要的语言结构。有些陈旧但有用的计算机书籍使用 Pascal 编程语言作为示例(我知道对于选择一门语言来构建解释器,这个理由并不令人信服,但我认为学一门非主流的语言也不错 :))。 + +这有个 Pascal 中的阶乘函数示例,你将能用自己的解释器解释代码,还能够用可交互的源码级调试器进行调试,你可以这样创造: -这有个 Pascal 中的阶乘函数示例,你能用自己的解释器解释代码,还能够用可交互的源码级调试器进行调试,你可以这样创造: ``` program factorial; @@ -57,15 +59,14 @@ begin end. ``` -这个 Pascal 解释器的实现语言会用 Python,但你也可以用其他任何语言,因为这里展示的思想不依赖任何特殊的实现语言。好,让我们开始干活。准备好了,出发! - -你会从编写一个简单的算术表达式解析器,也就是常说的计算器,开始学习解释器和编译器。今天的目标非常简单:让你的计算器能处理两个个位数相加,比如 **3+5**。这是你的计算器的源代码,不好意思,是解释器: +这个 Pascal 解释器的实现语言会使用 Python,但你也可以用其他任何语言,因为这里展示的思想不依赖任何特殊的实现语言。好,让我们开始干活。准备好了,出发! +你会从编写一个简单的算术表达式解析器,也就是常说的计算器,开始学习解释器和编译器。今天的目标非常简单:让你的计算器能处理两个个位数相加,比如 `3+5`。下面是你的计算器的源代码——不好意思,是解释器: ``` # 标记类型 # -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, EOF = 'INTEGER', 'PLUS', 'EOF' @@ -73,7 +74,7 @@ class Token(object): def __init__(self, type, value): # token 类型: INTEGER, PLUS, MINUS, or EOF self.type = type - # token 值: 0, 1, 2. 3, 4, 5, 6, 7, 8, 9, '+', 或 None + # token 值: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '+', 或 None self.value = value def __str__(self): @@ -187,7 +188,8 @@ if __name__ == '__main__': ``` -把上面的代码保存到 calc1.py 文件,或者直接从 [GitHub][7] 上下载。在你深入研究代码前,在命令行里面运行它看看效果。试一试!这是我笔记本上的示例会话(如果你想在 Python3 下运行,你要把 raw_input 换成 input): +把上面的代码保存到 `calc1.py` 文件,或者直接从 [GitHub][7] 上下载。在你深入研究代码前,在命令行里面运行它看看效果。试一试!这是我笔记本上的示例会话(如果你想在 Python3 下运行,你要把 `raw_input` 换成 `input`): + ``` $ python calc1.py calc> 3+4 @@ -205,31 +207,32 @@ calc> * 此时支持的唯一一个运算符是加法 * 输入中不允许有任何的空格符号 - - 要让计算器变得简单,这些限制非常必要。不用担心,你很快就会让它变得很复杂。 好,现在让我们深入它,看看解释器是怎么工作,它是怎么评估出算术表达式的。 -当你在命令行中输入一个表达式 3+5,解释器就获得了字符串 “3+5”。为了让解释器能够真正理解要用这个字符串做什么,它首先要把输入 “3+5” 分到叫做 **token(标记)** 的容器里。**标记** 是一个拥有类型和值的对象。比如说,对字符 “3” 而言,标记的类型是 INTEGER 整数,对应的值是 3。 +当你在命令行中输入一个表达式 `3+5`,解释器就获得了字符串 “3+5”。为了让解释器能够真正理解要用这个字符串做什么,它首先要把输入 “3+5” 分到叫做 `token`(标记)的容器里。标记token 是一个拥有类型和值的对象。比如说,对字符 “3” 而言,标记的类型是 INTEGER 整数,对应的值是 3。 -把输入字符串分成标记的过程叫 **词法分析**。因此解释器的需要做的第一步是读取输入字符,并将其转换成标记流。解释器中的这一部分叫做 **词法分析器**,或者简短点叫 **lexer**。你也可以给它起别的名字,诸如 **扫描器** 或者 **标记器**。他们指的都是同一个东西:解释器或编译器中将输入字符转换成标记流的那部分。 +把输入字符串分成标记的过程叫词法分析lexical analysis。因此解释器的需要做的第一步是读取输入字符,并将其转换成标记流。解释器中的这一部分叫做词法分析器lexical analyzer,或者简短点叫 **lexer**。你也可以给它起别的名字,诸如扫描器scanner或者标记器tokenizer。它们指的都是同一个东西:解释器或编译器中将输入字符转换成标记流的那部分。 -Interpreter 类中的 get_next_token 方法就是词法分析器。每次调用它的时候,你都能从传入解释器的输入字符中获得创建的下一个标记。仔细看看这个方法,看看它是如何完成把字符转换成标记的任务的。输入被存在可变文本中,它保存了输入的字符串和关于该字符串的索引(把字符串想象成字符数组)。pos 开始时设为 0,指向 ‘3’.这个方法一开始检查字符是不是数字,如果是,就将 pos 加 1,并返回一个 INTEGER 类型的标记实例,并把字符 ‘3’ 的值设为整数,也就是整数 3: +`Interpreter` 类中的 `get_next_token` 方法就是词法分析器。每次调用它的时候,你都能从传入解释器的输入字符中获得创建的下一个标记。仔细看看这个方法,看看它是如何完成把字符转换成标记的任务的。输入被存在可变文本中,它保存了输入的字符串和关于该字符串的索引(把字符串想象成字符数组)。`pos` 开始时设为 0,指向字符 ‘3’。这个方法一开始检查字符是不是数字,如果是,就将 `pos` 加 1,并返回一个 INTEGER 类型的标记实例,并把字符 ‘3’ 的值设为整数,也就是整数 3: ![][8] -现在 pos 指向文本中的 ‘+’ 号。下次调用这个方法的时候,它会测试 pos 位置的字符是不是个数字,然后检测下一个字符是不是个加号,就是这样。结果这个方法把 pos 加一,返回一个新创建的标记,类型是 PLUS,值为 ‘+’。 +现在 `pos` 指向文本中的 ‘+’ 号。下次调用这个方法的时候,它会测试 `pos` 位置的字符是不是个数字,然后检测下一个字符是不是个加号,就是这样。结果这个方法把 `pos` 加 1,返回一个新创建的标记,类型是 PLUS,值为 ‘+’。 ![][9] -pos 现在指向字符 ‘5’。当你再调用 get_next_token 方法时,该方法会检查这是不是个数字,就是这样,然后它把 pos 加一,返回一个新的 INTEGER 标记,该标记的值被设为 5: +`pos` 现在指向字符 ‘5’。当你再调用 `get_next_token` 方法时,该方法会检查这是不是个数字,就是这样,然后它把 `pos` 加 1,返回一个新的 INTEGER 标记,该标记的值被设为整数 5: + ![][10] -因为 pos 索引现在到了字符串 “3+5” 的末尾,你每次调用 get_next_token 方法时,它将会返回 EOF 标记: +因为 `pos` 索引现在到了字符串 “3+5” 的末尾,你每次调用 `get_next_token` 方法时,它将会返回 EOF 标记: + ![][11] 自己试一试,看看计算器里的词法分析器的运行: + ``` >>> from calc1 import Interpreter >>> @@ -248,17 +251,16 @@ Token(EOF, None) >>> ``` -既然你的解释器能够从输入字符中获取标记流,解释器需要做点什么:它需要在词法分析器 get_next_token 中获取的标记流中找出相应的结构。你的解释器应该能够找到流中的结构:INTEGER -> PLUS -> INTEGER。就是这样,它尝试找出标记的序列:整数后面要跟着加号,加号后面要跟着整数。 +既然你的解释器能够从输入字符中获取标记流,解释器需要对它做点什么:它需要在词法分析器 `get_next_token` 中获取的标记流中找出相应的结构。你的解释器应该能够找到流中的结构:INTEGER -> PLUS -> INTEGER。就是这样,它尝试找出标记的序列:整数后面要跟着加号,加号后面要跟着整数。 -负责找出并解释结构的方法就是 expr。该方法检验标记序列确实与期望的标记序列是对应的,比如 INTEGER -> PLUS -> INTEGER。成功确认了这个结构后,就会生成加号左右两边的标记的值相加的结果,这样就成功解释你输入到解释器中的算术表达式了。 +负责找出并解释结构的方法就是 `expr`。该方法检验标记序列确实与期望的标记序列是对应的,比如 INTEGER -> PLUS -> INTEGER。成功确认了这个结构后,就会生成加号左右两边的标记的值相加的结果,这样就成功解释你输入到解释器中的算术表达式了。 -expr 方法用了一个助手方法 eat 来检验传入的标记类型是否与当前的标记类型相匹配。在匹配到传入的标记类型后,eat 方法获取下一个标记,并将其赋给 current_token 变量,然后高效地 “吃掉” 当前匹配的标记,并将标记流的虚拟指针向后移动。如果标记流的结构与期望的 INTEGER PLUS INTEGER 标记序列不对应,eat 方法就抛出一个异常。 +`expr` 方法用了一个助手方法 `eat` 来检验传入的标记类型是否与当前的标记类型相匹配。在匹配到传入的标记类型后,`eat` 方法会获取下一个标记,并将其赋给 `current_token` 变量,然后高效地 “吃掉” 当前匹配的标记,并将标记流的虚拟指针向后移动。如果标记流的结构与期望的 INTEGER -> PLUS -> INTEGER 标记序列不对应,`eat` 方法就抛出一个异常。 让我们回顾下解释器做了什么来对算术表达式进行评估的: - * 解释器接受输入字符串,就把它当作 “3+5” - * 解释器调用 expr 方法,在词法分析器 get_next_token 返回的标记流中找出结构。这个结构就是 INTEGER PLUS INTEGER 这样的格式。在确认了格式后,它就通过把两个整型标记相加解释输入,因为此时对于解释器来说很清楚,他要做的就是把两个整数 3 和 5 进行相加。 - +* 解释器接受输入字符串,比如说 “3+5” +* 解释器调用 `expr` 方法,在词法分析器 `get_next_token` 返回的标记流中找出结构。这个结构就是 INTEGER -> PLUS -> INTEGER 这样的格式。在确认了格式后,它就通过把两个整型标记相加来解释输入,因为此时对于解释器来说很清楚,它要做的就是把两个整数 3 和 5 进行相加。 恭喜。你刚刚学习了怎么构建自己的第一个解释器! @@ -268,42 +270,38 @@ expr 方法用了一个助手方法 eat 来检验传入的标记类型是否与 看了这篇文章,你肯定觉得不够,是吗?好,准备好做这些练习: - 1. 修改代码,允许输入多位数,比如 “12+3” - 2. 添加一个方法忽略空格符,让你的计算器能够处理带有空白的输入,比如“12 + 3” - 3. 修改代码,用 ‘-’ 号而非 ‘+’ 号去执行减法比如 “7-5” - +1. 修改代码,允许输入多位数,比如 “12+3” +2. 添加一个方法忽略空格符,让你的计算器能够处理带有空白的输入,比如 “12 + 3” +3. 修改代码,用 ‘-’ 号而非 ‘+’ 号去执行减法比如 “7-5” **检验你的理解** - 1. 什么是解释器? - 2. 什么是编译器 - 3. 解释器和编译器有什么差别? - 4. 什么是标记? - 5. 将输入分隔成若干个标记的过程叫什么? - 6. 解释器中进行词法分析的部分叫什么? - 7. 解释器或编译器中进行词法分析的部分有哪些其他的常见名字? - - +1. 什么是解释器? +2. 什么是编译器 +3. 解释器和编译器有什么差别? +4. 什么是标记? +5. 将输入分隔成若干个标记的过程叫什么? +6. 解释器中进行词法分析的部分叫什么? +7. 解释器或编译器中进行词法分析的部分有哪些其他的常见名字? 在结束本文前,我衷心希望你能留下学习解释器和编译器的承诺。并且现在就开始做。不要把它留到以后。不要拖延。如果你已经看完了本文,就开始吧。如果已经仔细看完了但是还没做什么练习 —— 现在就开始做吧。如果已经开始做练习了,那就把剩下的做完。你懂得。而且你知道吗?签下承诺书,今天就开始学习解释器和编译器! +> 本人, ______,身体健全,思想正常,在此承诺从今天开始学习解释器和编译器,直到我百分百了解它们是怎么工作的! -_本人, ______,身体健全,思想正常,在此承诺从今天开始学习解释器和编译器,直到我百分百了解它们是怎么工作的!_ +> -签字人: +> 签字人: -日期: +> 日期: ![][13] 签字,写上日期,把它放在你每天都能看到的地方,确保你能坚守承诺。谨记你的承诺: -> "Commitment is doing the thing you said you were going to do long after the mood you said it in has left you." -- Darren Hardy > “承诺就是,你说自己会去做的事,在你说完就一直陪着你的东西。” —— Darren Hardy 好,今天的就结束了。这个系列的下一篇文章里,你将会扩展自己的计算器,让它能够处理更复杂的算术表达式。敬请期待。 - -------------------------------------------------------------------------------- via: https://ruslanspivak.com/lsbasi-part1/ @@ -311,7 +309,7 @@ via: https://ruslanspivak.com/lsbasi-part1/ 作者:[Ruslan Spivak][a] 译者:[BriFuture](https://github.com/BriFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From fc6166dd996c2c68b9dd7c1b74ab173bd2dcc495 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 21:53:05 +0800 Subject: [PATCH 079/101] PUB:20150615 Let-s Build A Simple Interpreter. Part 1..md @BriFuture --- .../20150615 Let-s Build A Simple Interpreter. Part 1..md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20150615 Let-s Build A Simple Interpreter. Part 1..md (100%) diff --git a/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md b/published/20150615 Let-s Build A Simple Interpreter. Part 1..md similarity index 100% rename from translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md rename to published/20150615 Let-s Build A Simple Interpreter. Part 1..md From e777ab79344a68b5db35cf0323e02030e5c21650 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 22:04:56 +0800 Subject: [PATCH 080/101] =?UTF-8?q?=E5=BD=92=E6=A1=A3201802?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...430 Linux Find Out Last System Reboot Time and Date Command.md | 0 ...o Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md | 0 ...070129 How To Debug a Bash Shell Script Under Linux or UNIX.md | 0 ...e lftp to accelerate ftp-https download speed on Linux-UNIX.md | 0 ...0071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md | 0 ...30 Linux System Monitoring Tools Every SysAdmin Should Know.md | 0 .../20090724 Top 20 OpenSSH Server Best Security Practices.md | 0 ...20110917 Have I been hacked by root-notty- - Sysadmin World.md | 0 ...Best Open Source Alternatives to Microsoft Office for Linux.md | 0 .../20130319 Linux - Unix Bash Shell List All Builtin Commands.md | 0 published/{ => 201802}/20141029 What does an idle CPU do.md | 0 ...Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md | 0 .../20160606 Learn your tools Navigating your Git History.md | 0 .../20170216 25 Free Books To Learn Linux For Free.md | 0 .../20170429 Monitoring network bandwidth with iftop command.md | 0 .../{ => 201802}/20170511 Working with VI editor - The Basics.md | 0 ...0170707 Lessons from my first year of live coding on Twitch.md | 0 ...w to automate your system administration tasks with Ansible.md | 0 .../{ => 201802}/20170915 How To Install And Setup Vagrant.md | 0 ...asy Ways To Install Bing Desktop Wallpaper Changer On Linux.md | 0 .../20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md | 0 published/{ => 201802}/20171005 Reasons Kubernetes is cool.md | 0 .../20171016 Using the Linux find command with caution.md | 0 .../20171019 More ways to examine network connections on Linux.md | 0 .../20171023 Processors-Everything You Need to Know.md | 0 ...0171027 Easy guide to secure VNC server with TLS encryption.md | 0 ...030 How to bind ntpd to specific IP addresses on Linux-Unix.md | 0 ...ow To Fully Update And Upgrade Offline Debian-based Systems.md | 0 ...08 How To Setup Japanese Language Environment In Arch Linux.md | 0 ...Step guide for creating Master Slave replication in MariaDB.md | 0 .../20171117 How to Install and Use Docker on Linux.md | 0 ...use special permissions- the setuid, setgid and sticky bits.md | 0 ...ng Your Website From Application Layer DOS Attacks With mod.md | 0 ...ython and Pygame are a great pair for beginning programmers.md | 0 .../20171202 MariaDB administration commands for beginners.md | 0 ...203 Increase Torrent Speed - Here Is Why It Will Never Work.md | 0 ...20171204 Tutorial on how to write basic udev rules in Linux.md | 0 .../20171208 Sessions And Cookies - How Does User-Login Work.md | 0 ...ux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md | 0 published/{ => 201802}/20171211 A tour of containerd 1.0.md | 0 ... Count The Number Of Files And Folders-Directories In Linux.md | 0 .../20171214 How to install and use encryptpad on ubuntu 16.04.md | 0 published/{ => 201802}/20171215 Linux Vs Unix.md | 0 published/{ => 201802}/20171218 Internet Chemotherapy.md | 0 ...171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md | 0 ...0171226 Dockerizing Compiled Software - Tianon-s Ramblings .md | 0 .../{ => 201802}/20171228 Dual Boot Ubuntu And Arch Linux.md | 0 ...71228 Linux wc Command Explained for Beginners (6 Examples).md | 0 .../20171230 What Is A Web Crawler- How Web Crawlers work.md | 0 ...71231 Making Vim Even More Awesome With These Cool Features.md | 0 .../{ => 201802}/20171231 Why You Should Still Love Telnet.md | 0 .../{ => 201802}/20180102 Best open source tutorials in 2017.md | 0 ... Linux uptime Command Explained for Beginners with Examples.md | 0 ...wget- Their Differences, Usage and Which One You Should Use.md | 0 .../20180102 xfs file system commands with examples.md | 0 .../20180103 Creating an Offline YUM repository for LAN.md | 0 ...20180103 How to preconfigure LXD containers with cloud-init.md | 0 .../20180104 How to Change Your Linux Console Fonts.md | 0 ...Whats behind the Intel design flaw forcing numerous patches.md | 0 ...How To Display Asterisks When You Type Password In terminal.md | 0 .../20180106 Meltdown and Spectre Linux Kernel Status.md | 0 .../20180111 Multimedia Apps for the Linux Console.md | 0 .../20180112 Top 5 Firefox extensions to install now.md | 0 .../{ => 201802}/20180115 How To Boot Into Linux Command Line.md | 0 published/{ => 201802}/20180118 Getting Started with ncurses.md | 0 published/{ => 201802}/20180120 The World Map In Your Terminal.md | 0 published/{ => 201802}/20180121 Shell Scripting a Bunco Game.md | 0 published/{ => 201802}/20180122 How to price cryptocurrencies.md | 0 ...80122 Linux rm Command Explained for Beginners (8 Examples).md | 0 ...Linux mkdir Command Explained for Beginners (with examples).md | 0 .../20180124 8 ways to generate random password in Linux.md | 0 published/{ => 201802}/20180125 A step-by-step guide to Git.md | 0 ... Linux whereis Command Explained for Beginners (5 Examples).md | 0 ...126 Creating an Adventure Game in the Terminal with ncurses.md | 0 .../20180130 Linux Kernel 4.15 An Unusual Release Cycle.md | 0 .../20180131 Fastest way to unzip a zip file in Python.md | 0 .../20180131 Why you should use named pipes on Linux.md | 0 .../{ => 201802}/20180201 Custom Embedded Linux Distributions.md | 0 ... to reload .vimrc file without restarting vim on Linux-Unix.md | 0 published/{ => 201802}/20180202 Tuning MySQL 3 Simple Tweaks.md | 0 .../{ => 201802}/20180202 Which Linux Kernel Version Is Stable.md | 0 .../20180203 Open source software 20 years and counting.md | 0 .../20180206 Save Some Battery On Our Linux Machines With TLP.md | 0 published/{ => 201802}/20180206 Simple TensorFlow Examples.md | 0 .../20180206 What Is Kali Linux, and Do You Need It.md | 0 ...20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md | 0 .../20180209 Linux rmdir Command for Beginners (with Examples).md | 0 .../20180210 How to create AWS ec2 key using Ansible.md | 0 ...20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md | 0 89 files changed, 0 insertions(+), 0 deletions(-) rename published/{ => 201802}/20060430 Linux Find Out Last System Reboot Time and Date Command.md (100%) rename published/{ => 201802}/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md (100%) rename published/{ => 201802}/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md (100%) rename published/{ => 201802}/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md (100%) rename published/{ => 201802}/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md (100%) rename published/{ => 201802}/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md (100%) rename published/{ => 201802}/20090724 Top 20 OpenSSH Server Best Security Practices.md (100%) rename published/{ => 201802}/20110917 Have I been hacked by root-notty- - Sysadmin World.md (100%) rename published/{ => 201802}/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md (100%) rename published/{ => 201802}/20130319 Linux - Unix Bash Shell List All Builtin Commands.md (100%) rename published/{ => 201802}/20141029 What does an idle CPU do.md (100%) rename published/{ => 201802}/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md (100%) rename published/{ => 201802}/20160606 Learn your tools Navigating your Git History.md (100%) rename published/{ => 201802}/20170216 25 Free Books To Learn Linux For Free.md (100%) rename published/{ => 201802}/20170429 Monitoring network bandwidth with iftop command.md (100%) rename published/{ => 201802}/20170511 Working with VI editor - The Basics.md (100%) rename published/{ => 201802}/20170707 Lessons from my first year of live coding on Twitch.md (100%) rename published/{ => 201802}/20170724 How to automate your system administration tasks with Ansible.md (100%) rename published/{ => 201802}/20170915 How To Install And Setup Vagrant.md (100%) rename published/{ => 201802}/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md (100%) rename published/{ => 201802}/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md (100%) rename published/{ => 201802}/20171005 Reasons Kubernetes is cool.md (100%) rename published/{ => 201802}/20171016 Using the Linux find command with caution.md (100%) rename published/{ => 201802}/20171019 More ways to examine network connections on Linux.md (100%) rename published/{ => 201802}/20171023 Processors-Everything You Need to Know.md (100%) rename published/{ => 201802}/20171027 Easy guide to secure VNC server with TLS encryption.md (100%) rename published/{ => 201802}/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md (100%) rename published/{ => 201802}/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md (100%) rename published/{ => 201802}/20171108 How To Setup Japanese Language Environment In Arch Linux.md (100%) rename published/{ => 201802}/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md (100%) rename published/{ => 201802}/20171117 How to Install and Use Docker on Linux.md (100%) rename published/{ => 201802}/20171120 How to use special permissions- the setuid, setgid and sticky bits.md (100%) rename published/{ => 201802}/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md (100%) rename published/{ => 201802}/20171128 Why Python and Pygame are a great pair for beginning programmers.md (100%) rename published/{ => 201802}/20171202 MariaDB administration commands for beginners.md (100%) rename published/{ => 201802}/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md (100%) rename published/{ => 201802}/20171204 Tutorial on how to write basic udev rules in Linux.md (100%) rename published/{ => 201802}/20171208 Sessions And Cookies - How Does User-Login Work.md (100%) rename published/{ => 201802}/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md (100%) rename published/{ => 201802}/20171211 A tour of containerd 1.0.md (100%) rename published/{ => 201802}/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md (100%) rename published/{ => 201802}/20171214 How to install and use encryptpad on ubuntu 16.04.md (100%) rename published/{ => 201802}/20171215 Linux Vs Unix.md (100%) rename published/{ => 201802}/20171218 Internet Chemotherapy.md (100%) rename published/{ => 201802}/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md (100%) rename published/{ => 201802}/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md (100%) rename published/{ => 201802}/20171228 Dual Boot Ubuntu And Arch Linux.md (100%) rename published/{ => 201802}/20171228 Linux wc Command Explained for Beginners (6 Examples).md (100%) rename published/{ => 201802}/20171230 What Is A Web Crawler- How Web Crawlers work.md (100%) rename published/{ => 201802}/20171231 Making Vim Even More Awesome With These Cool Features.md (100%) rename published/{ => 201802}/20171231 Why You Should Still Love Telnet.md (100%) rename published/{ => 201802}/20180102 Best open source tutorials in 2017.md (100%) rename published/{ => 201802}/20180102 Linux uptime Command Explained for Beginners with Examples.md (100%) rename published/{ => 201802}/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md (100%) rename published/{ => 201802}/20180102 xfs file system commands with examples.md (100%) rename published/{ => 201802}/20180103 Creating an Offline YUM repository for LAN.md (100%) rename published/{ => 201802}/20180103 How to preconfigure LXD containers with cloud-init.md (100%) rename published/{ => 201802}/20180104 How to Change Your Linux Console Fonts.md (100%) rename published/{ => 201802}/20180104 Whats behind the Intel design flaw forcing numerous patches.md (100%) rename published/{ => 201802}/20180105 How To Display Asterisks When You Type Password In terminal.md (100%) rename published/{ => 201802}/20180106 Meltdown and Spectre Linux Kernel Status.md (100%) rename published/{ => 201802}/20180111 Multimedia Apps for the Linux Console.md (100%) rename published/{ => 201802}/20180112 Top 5 Firefox extensions to install now.md (100%) rename published/{ => 201802}/20180115 How To Boot Into Linux Command Line.md (100%) rename published/{ => 201802}/20180118 Getting Started with ncurses.md (100%) rename published/{ => 201802}/20180120 The World Map In Your Terminal.md (100%) rename published/{ => 201802}/20180121 Shell Scripting a Bunco Game.md (100%) rename published/{ => 201802}/20180122 How to price cryptocurrencies.md (100%) rename published/{ => 201802}/20180122 Linux rm Command Explained for Beginners (8 Examples).md (100%) rename published/{ => 201802}/20180123 Linux mkdir Command Explained for Beginners (with examples).md (100%) rename published/{ => 201802}/20180124 8 ways to generate random password in Linux.md (100%) rename published/{ => 201802}/20180125 A step-by-step guide to Git.md (100%) rename published/{ => 201802}/20180125 Linux whereis Command Explained for Beginners (5 Examples).md (100%) rename published/{ => 201802}/20180126 Creating an Adventure Game in the Terminal with ncurses.md (100%) rename published/{ => 201802}/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md (100%) rename published/{ => 201802}/20180131 Fastest way to unzip a zip file in Python.md (100%) rename published/{ => 201802}/20180131 Why you should use named pipes on Linux.md (100%) rename published/{ => 201802}/20180201 Custom Embedded Linux Distributions.md (100%) rename published/{ => 201802}/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md (100%) rename published/{ => 201802}/20180202 Tuning MySQL 3 Simple Tweaks.md (100%) rename published/{ => 201802}/20180202 Which Linux Kernel Version Is Stable.md (100%) rename published/{ => 201802}/20180203 Open source software 20 years and counting.md (100%) rename published/{ => 201802}/20180206 Save Some Battery On Our Linux Machines With TLP.md (100%) rename published/{ => 201802}/20180206 Simple TensorFlow Examples.md (100%) rename published/{ => 201802}/20180206 What Is Kali Linux, and Do You Need It.md (100%) rename published/{ => 201802}/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md (100%) rename published/{ => 201802}/20180209 Linux rmdir Command for Beginners (with Examples).md (100%) rename published/{ => 201802}/20180210 How to create AWS ec2 key using Ansible.md (100%) rename published/{ => 201802}/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md (100%) diff --git a/published/20060430 Linux Find Out Last System Reboot Time and Date Command.md b/published/201802/20060430 Linux Find Out Last System Reboot Time and Date Command.md similarity index 100% rename from published/20060430 Linux Find Out Last System Reboot Time and Date Command.md rename to published/201802/20060430 Linux Find Out Last System Reboot Time and Date Command.md diff --git a/published/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md b/published/201802/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md similarity index 100% rename from published/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md rename to published/201802/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md diff --git a/published/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md b/published/201802/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md similarity index 100% rename from published/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md rename to published/201802/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md diff --git a/published/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md b/published/201802/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md similarity index 100% rename from published/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md rename to published/201802/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md diff --git a/published/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md b/published/201802/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md similarity index 100% rename from published/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md rename to published/201802/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md diff --git a/published/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md b/published/201802/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md similarity index 100% rename from published/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md rename to published/201802/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md diff --git a/published/20090724 Top 20 OpenSSH Server Best Security Practices.md b/published/201802/20090724 Top 20 OpenSSH Server Best Security Practices.md similarity index 100% rename from published/20090724 Top 20 OpenSSH Server Best Security Practices.md rename to published/201802/20090724 Top 20 OpenSSH Server Best Security Practices.md diff --git a/published/20110917 Have I been hacked by root-notty- - Sysadmin World.md b/published/201802/20110917 Have I been hacked by root-notty- - Sysadmin World.md similarity index 100% rename from published/20110917 Have I been hacked by root-notty- - Sysadmin World.md rename to published/201802/20110917 Have I been hacked by root-notty- - Sysadmin World.md diff --git a/published/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md b/published/201802/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md similarity index 100% rename from published/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md rename to published/201802/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md diff --git a/published/20130319 Linux - Unix Bash Shell List All Builtin Commands.md b/published/201802/20130319 Linux - Unix Bash Shell List All Builtin Commands.md similarity index 100% rename from published/20130319 Linux - Unix Bash Shell List All Builtin Commands.md rename to published/201802/20130319 Linux - Unix Bash Shell List All Builtin Commands.md diff --git a/published/20141029 What does an idle CPU do.md b/published/201802/20141029 What does an idle CPU do.md similarity index 100% rename from published/20141029 What does an idle CPU do.md rename to published/201802/20141029 What does an idle CPU do.md diff --git a/published/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md b/published/201802/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md similarity index 100% rename from published/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md rename to published/201802/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md diff --git a/published/20160606 Learn your tools Navigating your Git History.md b/published/201802/20160606 Learn your tools Navigating your Git History.md similarity index 100% rename from published/20160606 Learn your tools Navigating your Git History.md rename to published/201802/20160606 Learn your tools Navigating your Git History.md diff --git a/published/20170216 25 Free Books To Learn Linux For Free.md b/published/201802/20170216 25 Free Books To Learn Linux For Free.md similarity index 100% rename from published/20170216 25 Free Books To Learn Linux For Free.md rename to published/201802/20170216 25 Free Books To Learn Linux For Free.md diff --git a/published/20170429 Monitoring network bandwidth with iftop command.md b/published/201802/20170429 Monitoring network bandwidth with iftop command.md similarity index 100% rename from published/20170429 Monitoring network bandwidth with iftop command.md rename to published/201802/20170429 Monitoring network bandwidth with iftop command.md diff --git a/published/20170511 Working with VI editor - The Basics.md b/published/201802/20170511 Working with VI editor - The Basics.md similarity index 100% rename from published/20170511 Working with VI editor - The Basics.md rename to published/201802/20170511 Working with VI editor - The Basics.md diff --git a/published/20170707 Lessons from my first year of live coding on Twitch.md b/published/201802/20170707 Lessons from my first year of live coding on Twitch.md similarity index 100% rename from published/20170707 Lessons from my first year of live coding on Twitch.md rename to published/201802/20170707 Lessons from my first year of live coding on Twitch.md diff --git a/published/20170724 How to automate your system administration tasks with Ansible.md b/published/201802/20170724 How to automate your system administration tasks with Ansible.md similarity index 100% rename from published/20170724 How to automate your system administration tasks with Ansible.md rename to published/201802/20170724 How to automate your system administration tasks with Ansible.md diff --git a/published/20170915 How To Install And Setup Vagrant.md b/published/201802/20170915 How To Install And Setup Vagrant.md similarity index 100% rename from published/20170915 How To Install And Setup Vagrant.md rename to published/201802/20170915 How To Install And Setup Vagrant.md diff --git a/published/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md b/published/201802/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md similarity index 100% rename from published/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md rename to published/201802/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md diff --git a/published/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md b/published/201802/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md similarity index 100% rename from published/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md rename to published/201802/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md diff --git a/published/20171005 Reasons Kubernetes is cool.md b/published/201802/20171005 Reasons Kubernetes is cool.md similarity index 100% rename from published/20171005 Reasons Kubernetes is cool.md rename to published/201802/20171005 Reasons Kubernetes is cool.md diff --git a/published/20171016 Using the Linux find command with caution.md b/published/201802/20171016 Using the Linux find command with caution.md similarity index 100% rename from published/20171016 Using the Linux find command with caution.md rename to published/201802/20171016 Using the Linux find command with caution.md diff --git a/published/20171019 More ways to examine network connections on Linux.md b/published/201802/20171019 More ways to examine network connections on Linux.md similarity index 100% rename from published/20171019 More ways to examine network connections on Linux.md rename to published/201802/20171019 More ways to examine network connections on Linux.md diff --git a/published/20171023 Processors-Everything You Need to Know.md b/published/201802/20171023 Processors-Everything You Need to Know.md similarity index 100% rename from published/20171023 Processors-Everything You Need to Know.md rename to published/201802/20171023 Processors-Everything You Need to Know.md diff --git a/published/20171027 Easy guide to secure VNC server with TLS encryption.md b/published/201802/20171027 Easy guide to secure VNC server with TLS encryption.md similarity index 100% rename from published/20171027 Easy guide to secure VNC server with TLS encryption.md rename to published/201802/20171027 Easy guide to secure VNC server with TLS encryption.md diff --git a/published/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md b/published/201802/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md similarity index 100% rename from published/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md rename to published/201802/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md diff --git a/published/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md b/published/201802/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md similarity index 100% rename from published/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md rename to published/201802/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md diff --git a/published/20171108 How To Setup Japanese Language Environment In Arch Linux.md b/published/201802/20171108 How To Setup Japanese Language Environment In Arch Linux.md similarity index 100% rename from published/20171108 How To Setup Japanese Language Environment In Arch Linux.md rename to published/201802/20171108 How To Setup Japanese Language Environment In Arch Linux.md diff --git a/published/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md b/published/201802/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md similarity index 100% rename from published/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md rename to published/201802/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md diff --git a/published/20171117 How to Install and Use Docker on Linux.md b/published/201802/20171117 How to Install and Use Docker on Linux.md similarity index 100% rename from published/20171117 How to Install and Use Docker on Linux.md rename to published/201802/20171117 How to Install and Use Docker on Linux.md diff --git a/published/20171120 How to use special permissions- the setuid, setgid and sticky bits.md b/published/201802/20171120 How to use special permissions- the setuid, setgid and sticky bits.md similarity index 100% rename from published/20171120 How to use special permissions- the setuid, setgid and sticky bits.md rename to published/201802/20171120 How to use special permissions- the setuid, setgid and sticky bits.md diff --git a/published/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md b/published/201802/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md similarity index 100% rename from published/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md rename to published/201802/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md diff --git a/published/20171128 Why Python and Pygame are a great pair for beginning programmers.md b/published/201802/20171128 Why Python and Pygame are a great pair for beginning programmers.md similarity index 100% rename from published/20171128 Why Python and Pygame are a great pair for beginning programmers.md rename to published/201802/20171128 Why Python and Pygame are a great pair for beginning programmers.md diff --git a/published/20171202 MariaDB administration commands for beginners.md b/published/201802/20171202 MariaDB administration commands for beginners.md similarity index 100% rename from published/20171202 MariaDB administration commands for beginners.md rename to published/201802/20171202 MariaDB administration commands for beginners.md diff --git a/published/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md b/published/201802/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md similarity index 100% rename from published/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md rename to published/201802/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md diff --git a/published/20171204 Tutorial on how to write basic udev rules in Linux.md b/published/201802/20171204 Tutorial on how to write basic udev rules in Linux.md similarity index 100% rename from published/20171204 Tutorial on how to write basic udev rules in Linux.md rename to published/201802/20171204 Tutorial on how to write basic udev rules in Linux.md diff --git a/published/20171208 Sessions And Cookies - How Does User-Login Work.md b/published/201802/20171208 Sessions And Cookies - How Does User-Login Work.md similarity index 100% rename from published/20171208 Sessions And Cookies - How Does User-Login Work.md rename to published/201802/20171208 Sessions And Cookies - How Does User-Login Work.md diff --git a/published/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md b/published/201802/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md similarity index 100% rename from published/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md rename to published/201802/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md diff --git a/published/20171211 A tour of containerd 1.0.md b/published/201802/20171211 A tour of containerd 1.0.md similarity index 100% rename from published/20171211 A tour of containerd 1.0.md rename to published/201802/20171211 A tour of containerd 1.0.md diff --git a/published/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md b/published/201802/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md similarity index 100% rename from published/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md rename to published/201802/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md diff --git a/published/20171214 How to install and use encryptpad on ubuntu 16.04.md b/published/201802/20171214 How to install and use encryptpad on ubuntu 16.04.md similarity index 100% rename from published/20171214 How to install and use encryptpad on ubuntu 16.04.md rename to published/201802/20171214 How to install and use encryptpad on ubuntu 16.04.md diff --git a/published/20171215 Linux Vs Unix.md b/published/201802/20171215 Linux Vs Unix.md similarity index 100% rename from published/20171215 Linux Vs Unix.md rename to published/201802/20171215 Linux Vs Unix.md diff --git a/published/20171218 Internet Chemotherapy.md b/published/201802/20171218 Internet Chemotherapy.md similarity index 100% rename from published/20171218 Internet Chemotherapy.md rename to published/201802/20171218 Internet Chemotherapy.md diff --git a/published/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md b/published/201802/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md similarity index 100% rename from published/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md rename to published/201802/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md diff --git a/published/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md b/published/201802/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md similarity index 100% rename from published/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md rename to published/201802/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md diff --git a/published/20171228 Dual Boot Ubuntu And Arch Linux.md b/published/201802/20171228 Dual Boot Ubuntu And Arch Linux.md similarity index 100% rename from published/20171228 Dual Boot Ubuntu And Arch Linux.md rename to published/201802/20171228 Dual Boot Ubuntu And Arch Linux.md diff --git a/published/20171228 Linux wc Command Explained for Beginners (6 Examples).md b/published/201802/20171228 Linux wc Command Explained for Beginners (6 Examples).md similarity index 100% rename from published/20171228 Linux wc Command Explained for Beginners (6 Examples).md rename to published/201802/20171228 Linux wc Command Explained for Beginners (6 Examples).md diff --git a/published/20171230 What Is A Web Crawler- How Web Crawlers work.md b/published/201802/20171230 What Is A Web Crawler- How Web Crawlers work.md similarity index 100% rename from published/20171230 What Is A Web Crawler- How Web Crawlers work.md rename to published/201802/20171230 What Is A Web Crawler- How Web Crawlers work.md diff --git a/published/20171231 Making Vim Even More Awesome With These Cool Features.md b/published/201802/20171231 Making Vim Even More Awesome With These Cool Features.md similarity index 100% rename from published/20171231 Making Vim Even More Awesome With These Cool Features.md rename to published/201802/20171231 Making Vim Even More Awesome With These Cool Features.md diff --git a/published/20171231 Why You Should Still Love Telnet.md b/published/201802/20171231 Why You Should Still Love Telnet.md similarity index 100% rename from published/20171231 Why You Should Still Love Telnet.md rename to published/201802/20171231 Why You Should Still Love Telnet.md diff --git a/published/20180102 Best open source tutorials in 2017.md b/published/201802/20180102 Best open source tutorials in 2017.md similarity index 100% rename from published/20180102 Best open source tutorials in 2017.md rename to published/201802/20180102 Best open source tutorials in 2017.md diff --git a/published/20180102 Linux uptime Command Explained for Beginners with Examples.md b/published/201802/20180102 Linux uptime Command Explained for Beginners with Examples.md similarity index 100% rename from published/20180102 Linux uptime Command Explained for Beginners with Examples.md rename to published/201802/20180102 Linux uptime Command Explained for Beginners with Examples.md diff --git a/published/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md b/published/201802/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md similarity index 100% rename from published/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md rename to published/201802/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md diff --git a/published/20180102 xfs file system commands with examples.md b/published/201802/20180102 xfs file system commands with examples.md similarity index 100% rename from published/20180102 xfs file system commands with examples.md rename to published/201802/20180102 xfs file system commands with examples.md diff --git a/published/20180103 Creating an Offline YUM repository for LAN.md b/published/201802/20180103 Creating an Offline YUM repository for LAN.md similarity index 100% rename from published/20180103 Creating an Offline YUM repository for LAN.md rename to published/201802/20180103 Creating an Offline YUM repository for LAN.md diff --git a/published/20180103 How to preconfigure LXD containers with cloud-init.md b/published/201802/20180103 How to preconfigure LXD containers with cloud-init.md similarity index 100% rename from published/20180103 How to preconfigure LXD containers with cloud-init.md rename to published/201802/20180103 How to preconfigure LXD containers with cloud-init.md diff --git a/published/20180104 How to Change Your Linux Console Fonts.md b/published/201802/20180104 How to Change Your Linux Console Fonts.md similarity index 100% rename from published/20180104 How to Change Your Linux Console Fonts.md rename to published/201802/20180104 How to Change Your Linux Console Fonts.md diff --git a/published/20180104 Whats behind the Intel design flaw forcing numerous patches.md b/published/201802/20180104 Whats behind the Intel design flaw forcing numerous patches.md similarity index 100% rename from published/20180104 Whats behind the Intel design flaw forcing numerous patches.md rename to published/201802/20180104 Whats behind the Intel design flaw forcing numerous patches.md diff --git a/published/20180105 How To Display Asterisks When You Type Password In terminal.md b/published/201802/20180105 How To Display Asterisks When You Type Password In terminal.md similarity index 100% rename from published/20180105 How To Display Asterisks When You Type Password In terminal.md rename to published/201802/20180105 How To Display Asterisks When You Type Password In terminal.md diff --git a/published/20180106 Meltdown and Spectre Linux Kernel Status.md b/published/201802/20180106 Meltdown and Spectre Linux Kernel Status.md similarity index 100% rename from published/20180106 Meltdown and Spectre Linux Kernel Status.md rename to published/201802/20180106 Meltdown and Spectre Linux Kernel Status.md diff --git a/published/20180111 Multimedia Apps for the Linux Console.md b/published/201802/20180111 Multimedia Apps for the Linux Console.md similarity index 100% rename from published/20180111 Multimedia Apps for the Linux Console.md rename to published/201802/20180111 Multimedia Apps for the Linux Console.md diff --git a/published/20180112 Top 5 Firefox extensions to install now.md b/published/201802/20180112 Top 5 Firefox extensions to install now.md similarity index 100% rename from published/20180112 Top 5 Firefox extensions to install now.md rename to published/201802/20180112 Top 5 Firefox extensions to install now.md diff --git a/published/20180115 How To Boot Into Linux Command Line.md b/published/201802/20180115 How To Boot Into Linux Command Line.md similarity index 100% rename from published/20180115 How To Boot Into Linux Command Line.md rename to published/201802/20180115 How To Boot Into Linux Command Line.md diff --git a/published/20180118 Getting Started with ncurses.md b/published/201802/20180118 Getting Started with ncurses.md similarity index 100% rename from published/20180118 Getting Started with ncurses.md rename to published/201802/20180118 Getting Started with ncurses.md diff --git a/published/20180120 The World Map In Your Terminal.md b/published/201802/20180120 The World Map In Your Terminal.md similarity index 100% rename from published/20180120 The World Map In Your Terminal.md rename to published/201802/20180120 The World Map In Your Terminal.md diff --git a/published/20180121 Shell Scripting a Bunco Game.md b/published/201802/20180121 Shell Scripting a Bunco Game.md similarity index 100% rename from published/20180121 Shell Scripting a Bunco Game.md rename to published/201802/20180121 Shell Scripting a Bunco Game.md diff --git a/published/20180122 How to price cryptocurrencies.md b/published/201802/20180122 How to price cryptocurrencies.md similarity index 100% rename from published/20180122 How to price cryptocurrencies.md rename to published/201802/20180122 How to price cryptocurrencies.md diff --git a/published/20180122 Linux rm Command Explained for Beginners (8 Examples).md b/published/201802/20180122 Linux rm Command Explained for Beginners (8 Examples).md similarity index 100% rename from published/20180122 Linux rm Command Explained for Beginners (8 Examples).md rename to published/201802/20180122 Linux rm Command Explained for Beginners (8 Examples).md diff --git a/published/20180123 Linux mkdir Command Explained for Beginners (with examples).md b/published/201802/20180123 Linux mkdir Command Explained for Beginners (with examples).md similarity index 100% rename from published/20180123 Linux mkdir Command Explained for Beginners (with examples).md rename to published/201802/20180123 Linux mkdir Command Explained for Beginners (with examples).md diff --git a/published/20180124 8 ways to generate random password in Linux.md b/published/201802/20180124 8 ways to generate random password in Linux.md similarity index 100% rename from published/20180124 8 ways to generate random password in Linux.md rename to published/201802/20180124 8 ways to generate random password in Linux.md diff --git a/published/20180125 A step-by-step guide to Git.md b/published/201802/20180125 A step-by-step guide to Git.md similarity index 100% rename from published/20180125 A step-by-step guide to Git.md rename to published/201802/20180125 A step-by-step guide to Git.md diff --git a/published/20180125 Linux whereis Command Explained for Beginners (5 Examples).md b/published/201802/20180125 Linux whereis Command Explained for Beginners (5 Examples).md similarity index 100% rename from published/20180125 Linux whereis Command Explained for Beginners (5 Examples).md rename to published/201802/20180125 Linux whereis Command Explained for Beginners (5 Examples).md diff --git a/published/20180126 Creating an Adventure Game in the Terminal with ncurses.md b/published/201802/20180126 Creating an Adventure Game in the Terminal with ncurses.md similarity index 100% rename from published/20180126 Creating an Adventure Game in the Terminal with ncurses.md rename to published/201802/20180126 Creating an Adventure Game in the Terminal with ncurses.md diff --git a/published/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md b/published/201802/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md similarity index 100% rename from published/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md rename to published/201802/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md diff --git a/published/20180131 Fastest way to unzip a zip file in Python.md b/published/201802/20180131 Fastest way to unzip a zip file in Python.md similarity index 100% rename from published/20180131 Fastest way to unzip a zip file in Python.md rename to published/201802/20180131 Fastest way to unzip a zip file in Python.md diff --git a/published/20180131 Why you should use named pipes on Linux.md b/published/201802/20180131 Why you should use named pipes on Linux.md similarity index 100% rename from published/20180131 Why you should use named pipes on Linux.md rename to published/201802/20180131 Why you should use named pipes on Linux.md diff --git a/published/20180201 Custom Embedded Linux Distributions.md b/published/201802/20180201 Custom Embedded Linux Distributions.md similarity index 100% rename from published/20180201 Custom Embedded Linux Distributions.md rename to published/201802/20180201 Custom Embedded Linux Distributions.md diff --git a/published/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md b/published/201802/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md similarity index 100% rename from published/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md rename to published/201802/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md diff --git a/published/20180202 Tuning MySQL 3 Simple Tweaks.md b/published/201802/20180202 Tuning MySQL 3 Simple Tweaks.md similarity index 100% rename from published/20180202 Tuning MySQL 3 Simple Tweaks.md rename to published/201802/20180202 Tuning MySQL 3 Simple Tweaks.md diff --git a/published/20180202 Which Linux Kernel Version Is Stable.md b/published/201802/20180202 Which Linux Kernel Version Is Stable.md similarity index 100% rename from published/20180202 Which Linux Kernel Version Is Stable.md rename to published/201802/20180202 Which Linux Kernel Version Is Stable.md diff --git a/published/20180203 Open source software 20 years and counting.md b/published/201802/20180203 Open source software 20 years and counting.md similarity index 100% rename from published/20180203 Open source software 20 years and counting.md rename to published/201802/20180203 Open source software 20 years and counting.md diff --git a/published/20180206 Save Some Battery On Our Linux Machines With TLP.md b/published/201802/20180206 Save Some Battery On Our Linux Machines With TLP.md similarity index 100% rename from published/20180206 Save Some Battery On Our Linux Machines With TLP.md rename to published/201802/20180206 Save Some Battery On Our Linux Machines With TLP.md diff --git a/published/20180206 Simple TensorFlow Examples.md b/published/201802/20180206 Simple TensorFlow Examples.md similarity index 100% rename from published/20180206 Simple TensorFlow Examples.md rename to published/201802/20180206 Simple TensorFlow Examples.md diff --git a/published/20180206 What Is Kali Linux, and Do You Need It.md b/published/201802/20180206 What Is Kali Linux, and Do You Need It.md similarity index 100% rename from published/20180206 What Is Kali Linux, and Do You Need It.md rename to published/201802/20180206 What Is Kali Linux, and Do You Need It.md diff --git a/published/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md b/published/201802/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md similarity index 100% rename from published/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md rename to published/201802/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md diff --git a/published/20180209 Linux rmdir Command for Beginners (with Examples).md b/published/201802/20180209 Linux rmdir Command for Beginners (with Examples).md similarity index 100% rename from published/20180209 Linux rmdir Command for Beginners (with Examples).md rename to published/201802/20180209 Linux rmdir Command for Beginners (with Examples).md diff --git a/published/20180210 How to create AWS ec2 key using Ansible.md b/published/201802/20180210 How to create AWS ec2 key using Ansible.md similarity index 100% rename from published/20180210 How to create AWS ec2 key using Ansible.md rename to published/201802/20180210 How to create AWS ec2 key using Ansible.md diff --git a/published/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md b/published/201802/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md similarity index 100% rename from published/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md rename to published/201802/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md From b6045de9a7706ff8b14578a814242a334c3daf35 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 22:47:46 +0800 Subject: [PATCH 081/101] PRF:20171002 Bash Bypass Alias Linux-Unix Command.md @geekpi --- ...02 Bash Bypass Alias Linux-Unix Command.md | 116 +++++++++++++----- 1 file changed, 82 insertions(+), 34 deletions(-) diff --git a/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md b/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md index e4dec43782..e055c1f519 100644 --- a/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md +++ b/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md @@ -1,23 +1,34 @@ -绕过 Linux/Unix 命令别名 +4 种绕过 Linux/Unix 命令别名的方法 ====== + 我在我的 Linux 系统上定义了如下 mount 别名: + ``` alias mount='mount | column -t' ``` -但是我需要在挂载文件系统和其他用途时绕过 bash 别名。我如何在 Linux、\*BSD、macOS 或者类 Unix 系统上临时禁用或者绕过 bash shell 呢? +但是我需要在挂载文件系统和其他用途时绕过这个 bash 别名。我如何在 Linux、*BSD、macOS 或者类 Unix 系统上临时禁用或者绕过 bash shell 呢? + +你可以使用 `alias` 命令定义或显示 bash shell 别名。一旦创建了 bash shell 别名,它们将优先于外部或内部命令。本文将展示如何暂时绕过 bash 别名,以便你可以运行实际的内部或外部命令。 -你可以使用 alias 命令定义或显示 bash shell 别名。一旦创建了 bash shell 别名,它们将优先于外部或内部命令。本文将展示如何暂时绕过 bash 别名,以便你可以运行实际的内部或外部命令。 [![Bash Bypass Alias Linux BSD macOS Unix Command][1]][1] -## 4 种绕过 bash 别名的方法 - +### 4 种绕过 bash 别名的方法 尝试以下任意一种方法来运行被 bash shell 别名绕过的命令。让我们[如下定义一个别名][2]: -`alias mount='mount | column -t'` + +``` +alias mount='mount | column -t' +``` + 运行如下: -`mount ` + +``` +mount +``` + 示例输出: + ``` sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) @@ -30,45 +41,83 @@ binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_m lxcfs on /var/lib/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) ``` -### 方法1 - 使用 \command +#### 方法 1 - 使用 `\command` -输入以下命令暂时绕过名为 mount 的 bash 别名: -`\mount` +输入以下命令暂时绕过名为 `mount` 的 bash 别名: -### 方法2 - 使用 "command" 或 'command' +``` +\mount +``` + +#### 方法 2 - 使用 `"command"` 或 `'command'` + +如下引用 `mount` 命令调用实际的 `/bin/mount`: + +``` +"mount" +``` -如下引用 mount 命令调用实际的 /bin/mount: -`"mount"` 或者 -`'mount'` -### Method 3 - Use full command path +``` +'mount' +``` -Use full binary path such as /bin/mount: -`/bin/mount -/bin/mount /dev/sda1 /mnt/sda` +#### 方法 3 - 使用命令的完全路径 -### 方法3 - 使用完整的命令路径 +使用完整的二进制路径,如 `/bin/mount`: + +``` +/bin/mount +/bin/mount /dev/sda1 /mnt/sda +``` + +#### 方法 4 - 使用内部命令 `command` 语法是: -`command cmd -command cmd arg1 arg2` -要覆盖 .bash_aliases 中设置的别名,例如 mount: -`command mount -command mount /dev/sdc /mnt/pendrive/` -[”command“ 运行命令或显示][3]关于命令的信息。它带参数运行命令会抑制 shell 函数查询或者别名,或者显示有关给定命令的信息。 -## 关于 unalias 命令的说明 +``` +command cmd +command cmd arg1 arg2 +``` + +要覆盖 `.bash_aliases` 中设置的别名,例如 `mount`: + +``` +command mount +command mount /dev/sdc /mnt/pendrive/ +``` + +[“command” 直接运行命令或显示][3]关于命令的信息。它带参数运行命令会抑制 shell 函数查询或者别名,或者显示有关给定命令的信息。 + +### 关于 unalias 命令的说明 + +要从当前会话的已定义别名列表中移除别名,请使用 `unalias` 命令: + +``` +unalias mount +``` -要从当前会话的已定义别名列表中移除别名,请使用 unalias 命令: -`unalias mount` 要从当前 bash 会话中删除所有别名定义: -`unalias -a` -确保你更新你的 ~/.bashrc 或 $HOME/.bash_aliases。如果要永久删除定义的别名,则必须删除定义的别名: -`vi ~/.bashrc` + +``` +unalias -a +``` + +确保你更新你的 `~/.bashrc` 或 `$HOME/.bash_aliases`。如果要永久删除定义的别名,则必须删除定义的别名: + +``` +vi ~/.bashrc +``` + 或者 -`joe $HOME/.bash_aliases` + +``` +joe $HOME/.bash_aliases +``` + 想了解更多信息,参考[这里][4]的在线手册,或者输入下面的命令查看: + ``` man bash help command @@ -76,14 +125,13 @@ help unalias help alias ``` - -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/faq/bash-bypass-alias-command-on-linux-macos-unix/ 作者:[Vivek Gite][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 4acadb7a3b95f5ec1863e226c9f5f73ebef9a85d Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 2 Mar 2018 22:48:03 +0800 Subject: [PATCH 082/101] PUB:20171002 Bash Bypass Alias Linux-Unix Command.md @geekpi --- .../20171002 Bash Bypass Alias Linux-Unix Command.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171002 Bash Bypass Alias Linux-Unix Command.md (100%) diff --git a/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md b/published/20171002 Bash Bypass Alias Linux-Unix Command.md similarity index 100% rename from translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md rename to published/20171002 Bash Bypass Alias Linux-Unix Command.md From a073357f3d9383260c6d12d5347b8845c6c12765 Mon Sep 17 00:00:00 2001 From: kimii <2545489745@qq.com> Date: Fri, 2 Mar 2018 15:31:52 +0000 Subject: [PATCH 083/101] Update 20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md --- ...de Integrity with PGP - Part 2- Generating Your Master Key.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md b/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md index 282e35b60e..d78f1daafd 100644 --- a/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md +++ b/sources/tech/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md @@ -1,3 +1,4 @@ +translating by kimii Protecting Code Integrity with PGP — Part 2: Generating Your Master Key ====== From ca71c46bff950f1ea9b283590fd2e0636af281ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=91=E9=AD=85=E9=AD=8D=E9=AD=89?= <625310581@qq.com> Date: Sat, 3 Mar 2018 00:05:57 +0800 Subject: [PATCH 084/101] translating by HardworkFish --- sources/tech/20180228 Why Python devs should use Pipenv.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/tech/20180228 Why Python devs should use Pipenv.md b/sources/tech/20180228 Why Python devs should use Pipenv.md index 0928aba316..274ef29353 100644 --- a/sources/tech/20180228 Why Python devs should use Pipenv.md +++ b/sources/tech/20180228 Why Python devs should use Pipenv.md @@ -1,3 +1,6 @@ + +translating by HardworkFish + Why Python devs should use Pipenv ====== From 98613cac70815fe64eefe1f27112805e992b6e27 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Sat, 3 Mar 2018 14:09:12 +0800 Subject: [PATCH 085/101] Translated by qhwdw --- ...ience Courses You Can Start in February.md | 1407 ----------------- ...ience Courses You Can Start in February.md | 1147 ++++++++++++++ 2 files changed, 1147 insertions(+), 1407 deletions(-) delete mode 100644 sources/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md create mode 100644 translated/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md diff --git a/sources/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md b/sources/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md deleted file mode 100644 index e6f04ebca8..0000000000 --- a/sources/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md +++ /dev/null @@ -1,1407 +0,0 @@ -Translating by qhwdw -440+ Free Online Programming & Computer Science Courses You Can Start in February -============================================================ - -![](https://cdn-images-1.medium.com/max/1250/1*c28Ze3oxasgGMGaV7-qoFw.png) - -Six years ago, universities like MIT and Stanford first opened up free online courses to the public. Today, more than 800 schools around the world have created thousands of free online courses. - -I’ve compiled this list of over 440 such free online courses that you can start this month. For this, I leveraged [Class Central][450]’s database of over 9,000 courses. I’ve also included each course’s average rating. - - -![](https://cdn-images-1.medium.com/max/1250/1*qc6pW2c3mjTHVo45iCJaaQ.png) -[Class Central][1]’s home page. - -I’ve sorted these courses into the following categories based on their difficulty level: - -* Beginner - -* Intermediate - -* Advanced - -Courses that are being offered for the first time are marked as [NEW]. - -Many of these courses are completely self-paced. The rest will start at various times later in February. You can find complete lists of the technology-related courses starting later in 2018 on Class Central’s [Computer Science][451], [Data Science][452], and [Programming][453] subject pages. - -I understand this a long list and might be daunting for learners new to programming. In that case, you might find [David Venturi][454]’s recommendations for the best [Data Science online courses][455] useful — even if you’re not looking to learn Data Science. I hope to create more of these guides in the future. - -And finally if you have trouble figuring out how to signup for Coursera courses for free, don’t worry — I’ve [written an article on how to do that, too][456]. - -### BEGINNER(112) - -* [An Introduction to Interactive Programming in Python (Part 1)][2] from  _Rice University_  ★★★★★(3018) - -* [Introduction to Computer Science and Programming Using Python][3] from  _Massachusetts Institute of Technology_  ★★★★★(115) - -* [Learn to Program: The Fundamentals][4] from  _University of Toronto_ ★★★★★(100) - -* [Intro to Computer Science][5] from  _University of Virginia_  ★★★★☆(68) - -* [CS50’s Introduction to Computer Science][6] from  _Harvard University_ ★★★★★(65) - -* [An Introduction to Interactive Programming in Python (Part 2)][7] from  _Rice University_  ★★★★★(52) - -* [How to Use Git and GitHub][8] - -* [Introduction to Linux][9] from  _Linux Foundation_  ★★★★☆(37) - -* [Internet History, Technology, and Security][10] from  _University of Michigan_ ★★★★★(36) - -* [Intro to HTML and CSS][11] - -* [Introduction to VBA/Excel Programming][12] from  _Cal Poly Pomona_ ★★★★☆(26) - -* [[New] CS50’s Understanding Technology][13] from  _Harvard University_ - -* [[New] CS50’s Computer Science for Business Professionals][14] from  _Harvard University_ - -* [[New] Introducción a la programación en Java: cómo comenzar a programar][15] from  _Universidad Carlos iii de Madrid_ - -* [[New] Introduction to the Internet of Things (IoT)][16] from  _Curtin University_ - -* [[New] Version Control with Git][17] from  _Atlassian_ - -* [JavaScript Basics][18] - -* [CS101: Computer Science 101][19] from  _Stanford University_  ★★★★☆(15) - -* [Programming Basics][20] from  _Indian Institute of Technology Bombay_ ★★☆☆☆(13) - -* [Web Security Fundamentals][21] from  _KU Leuven University_  ★★★★☆(12) - -* [Programming Foundations with Python][22] - -* [Networking: Introduction to Computer Networking][23] from  _Stanford University_  ★★★★★(11) - -* [DB: Introduction to Databases][24] from  _Stanford University_  ★★★★★(11) - -* [Creative Programming for Digital Media & Mobile Apps][25] from  _University of London International Programmes_  ★★★★☆(10) - -* [Programming Foundations with JavaScript, HTML and CSS][26] from  _Duke University_  ★★★★☆(9) - -* [Usable Security][27] from  _University of Maryland, College Park_  ★★★☆☆(9) - -* [Introduction to Bootstrap — A Tutorial][28] from  _Microsoft_  ★★★☆☆(9) - -* [HTML5 Coding Essentials and Best Practices][29] from  _World Wide Web Consortium (W3C)_  ★★★★☆(9) - -* [Python for Everybody — Exploring Information][30] - -* [Learn to Program: Crafting Quality Code][31] from  _University of Toronto_ ★★★★☆(7) - -* [Introduction to Programming for the Visual Arts with p5.js][32] from  _University of California, Los Angeles_  ★★★★★(7) - -* [Intro to Relational Databases][33] - -* [Introduction to jQuery][34] from  _Microsoft_  ★★★★☆(5) - -* [HTML5 and CSS Fundamentals][35] from  _World Wide Web Consortium (W3C)_ ★★★★☆(5) - -* [Java Programming Basics][36] - -* [Linux Command Line Basics][37] - -* [Introduction to Java Programming — Part 1][38] from  _The Hong Kong University of Science and Technology_  ★★★★☆(4) - -* [Introduction to Java Programming: Starting to code in Java][39] from  _Universidad Carlos iii de Madrid_  ★★★★☆(4) - -* [Paradigms of Computer Programming — Abstraction and Concurrency][40]from  _Université catholique de Louvain_  ★★★★☆(4) - -* [Paradigms of Computer Programming — Fundamentals][41] from  _Université catholique de Louvain_  ★★★★★(4) - -* [Programming in Scratch][42] from  _Harvey Mudd College_  ★★★★★(4) - -* [Programming for the Web with JavaScript][43] from  _University of Pennsylvania_ ★★★★★(2) - -* [The Beauty and Joy of Computing — AP® CS Principles Part 1][44] from  _University of California, Berkeley_  ★★★★★(2) - -* [Introduction to Computing using Python][45] from  _Georgia Institute of Technology_  ★★★★★(2) - -* [Object-Oriented Programming][46] from  _Indian Institute of Technology Bombay_ ★★★★☆(2) - -* [Think. Create. Code][47] from  _University of Adelaide_  ★★★★★(2) - -* [The Computing Technology Inside Your Smartphone][48] from  _Cornell University_  ★★★★★(2) - -* [Android Basics: Make Your First App][49] from  _Google_  ★★★★☆(2) - -* [Learn to Program Using Python][50] from  _University of Texas Arlington_ ★★★★★(2) - -* [Introduction to HTML and JavaScript][51] from  _Microsoft_  ★★★★★(2) - -* [CS For All: Introduction to Computer Science and Python Programming][52]from  _Harvey Mudd College_  ★★★★★(2) - -* [Intro to JavaScript][53] - -* [Android for Beginners][54] - -* [Networks: Friends, Money, and Bytes][55] from  _Princeton University_ ★★★☆☆(1) - -* [How to Code: Simple Data][56] from  _The University of British Columbia_ ★★★★★(1) - -* [Web Development and Design using Wordpress][57] from  _California Institute of the Arts_  ★★★★☆(1) - -* [Android App Development for Beginners][58] from  _Galileo University_ ★☆☆☆☆(1) - -* [Android App Development for Beginners][59] from  _Galileo University_ ★☆☆☆☆(1) - -* [Web Coding Fundamentals for Artists][60] from  _National University of Singapore_  ★★★★☆(1) - -* [Introduction to ReactJS][61] from  _Microsoft_  ★★☆☆☆(1) - -* [Introduction to Node.js][62] from  _Microsoft_  ★★★★★(1) - -* [Learn to Program in Java][63] from  _Microsoft_  ★★★★★(1) - -* [Computing: Art, Magic, Science][64] from  _ETH Zurich_  ★★★★☆(1) - -* [Cyber Security: Safety at Home, Online, in Life][65] from  _Newcastle University_ ★★★☆☆(1) - -* [Software Engineering Essentials][66] from  _Technische Universität München (Technical University of Munich)_  ★★★★★(1) - -* [MyCS: Computer Science for Beginners][67] from  _Harvey Mudd College_ ★★★☆☆(1) - -* [Version Control with Git][68] - -* [Web Applications for Everybody][69] - -* [CS50’s AP® Computer Science Principles][70] from  _Harvard University_ - -* [Programming Fundamentals][71] from  _Duke University_ - -* [Introduction to Cybersecurity][72] from  _University of Washington_ - -* [Python Data Representations][73] from  _Rice University_ - -* [Python Programming Essentials][74] from  _Rice University_ - -* [Software Engineering: Introduction][75] from  _The University of British Columbia_ - -* [Introduction to Web Development][76] from  _University of California, Davis_ - -* [Introduction to Java Programming — Part 2][77] from  _The Hong Kong University of Science and Technology_ - -* [Excel/VBA for Creative Problem Solving, Part 2][78] from  _University of Colorado Boulder_ - -* [Excel/VBA for Creative Problem Solving, Part 2][79] from  _University of Colorado Boulder_ - -* [AP Computer Science A: Java Programming Polymorphism and Advanced Data Structures][80] from  _Purdue University_ - -* [AP Computer Science A: Java Programming Loops and Data Structures][81]from  _Purdue University_ - -* [AP Computer Science A: Java Programming Classes and Objects][82] from  _Purdue University_ - -* [Java Fundamentals for Android Development][83] from  _Galileo University_ - -* [Monetize Android Apps with Business Models][84] from  _Galileo University_ - -* [Monetize Android Apps with Business Models][85] from  _Galileo University_ - -* [Java Fundamentals for Android Development][86] from  _Galileo University_ - -* [Introduction to Java Programming: Writing Good Code][87] from  _Universidad Carlos iii de Madrid_ - -* [Cyber Security Basics: A Hands-on Approach][88] from  _Universidad Carlos iii de Madrid_ - -* [Deep Learning for Business][89] from  _Yonsei University_ - -* [Introduction to TCP/IP][90] from  _Yonsei University_ - -* [Video Game Design and Balance][91] from  _Rochester Institute of Technology_ - -* [Web Accessibility][92] from  _Google_ - -* [Mobile Web Development][93] from  _Google_ - -* [Introduction to Programming Using Python][94] from  _University of Texas Arlington_ - -* [Introduction to Python: Absolute Beginner][95] from  _Microsoft_ - -* [Introduction to Python: Fundamentals][96] from  _Microsoft_ - -* [Introduction to Design Thinking][97] from  _Microsoft_ - -* [Logic and Computational Thinking][98] from  _Microsoft_ - -* [Writing Professional Code][99] from  _Microsoft_ - -* [Object Oriented Programming in Java][100] from  _Microsoft_ - -* [CSS Basics][101] from  _Microsoft_ - -* [Computing: Art, Magic, Science — Part II][102] from  _ETH Zurich_ - -* [JavaScript Introduction][103] from  _World Wide Web Consortium (W3C)_ - -* [Object-oriented Programming in Python: Create Your Own Adventure Game][104] from  _Raspberry Pi Foundation_ - -* [Learn Swift Programming Syntax][105] - -* [JavaScript and the DOM][106] - -* [Blockchain in the Energy Sector][107] from  _InnoEnergy_ - -* [Introduction to Virtual Reality][108] - -* [ES6 — JavaScript Improved][109] - -* [Introduction to Python][110] - -* [HTTP & Web Servers][111] - -* [GitHub & Collaboration][112] - -* [Swift for Beginners][113] - -### INTERMEDIATE(259) - -* [Machine Learning][114] from  _Stanford University_  ★★★★★(325) - -* [Algorithms, Part I][115] from  _Princeton University_  ★★★★★(58) - -* [Machine Learning for Musicians and Artists][116] from  _Goldsmiths, University of London_  ★★★★★(57) - -* [Cryptography I][117] from  _Stanford University_  ★★★★★(49) - -* [CS188.1x: Artificial Intelligence][118] from  _University of California, Berkeley_ ★★★★★(30) - -* [Principles of Computing (Part 1)][119] from  _Rice University_  ★★★★★(29) - -* [[New] Algorithmic Design and Techniques][120] from  _University of California, San Diego_ - -* [Software Security ][121]from  _University of Maryland, College Park_ ★★★★☆(25) - -* [[New] Introduction to Soft Computing][122] from  _Indian Institute of Technology, Kharagpur_ - -* [[New] Cloud Computing][123] from  _Indian Institute of Technology, Kharagpur_ - -* [[New] Database Management System][124] from  _Indian Institute of Technology, Kharagpur_ - -* [[New] Introduction To Haskell Programming][125] from  _Chennai Mathematical Institute_ - -* [Algorithms, Part II][126] from  _Princeton University_  ★★★★★(21) - -* [Professional Web Accessibility Auditing Made Easy][127] from  _Chang School of Continuing Education_  ★★★★★(21) - -* [Agile Development Using Ruby on Rails — The Basics][128] from  _University of California, Berkeley_  ★★★★★(19) - -* [Automata Theory][129] from  _Stanford University_  ★★★★☆(18) - -* [Intro to Machine Learning][130] from  _Stanford University_  ★★★★☆(18) - -* [Web Development][131] - -* [Principles of Computing (Part 2)][132] from  _Rice University_  ★★★★☆(16) - -* [Android Development for Beginners][133] from  _Google_  ★★★★☆(16) - -* [C++ For C Programmers, Part A][134] from  _University of California, Santa Cruz_ ★★★☆☆(16) - -* [The Nature of Code][135] from  _Processing Foundation_  ★★★★★(16) - -* [Concepts in Game Development][136] from  _Swinburne University of Technology_ ★★★★☆(15) - -* [Algorithmic Thinking (Part 1)][137] from  _Rice University_  ★★★★☆(14) - -* [Design of Computer Programs][138] from  _Stanford University_  ★★★★☆(13) - -* [Java Programming: Solving Problems with Software][139] from  _Duke University_ ★★★☆☆(13) - -* [Responsive Web Design][140] from  _University of London International Programmes_  ★★★★☆(12) - -* [Discrete Optimization][141] from  _University of Melbourne_  ★★★★☆(12) - -* [Introduction to Game Development][142] from  _Michigan State University_ ★★★★★(12) - -* [Introduction to Functional Programming][143] from  _Delft University of Technology_  ★★★★☆(11) - -* [Developing Android Apps][144] from  _Google_  ★★★☆☆(11) - -* [Object-Oriented JavaScript][145] from  _Hack Reactor_  ★★★★★(11) - -* [Programming Languages][146] from  _University of Virginia_  ★★★☆☆(10) - -* [Algorithmic Thinking (Part 2)][147] from  _Rice University_  ★★★★☆(9) - -* [Responsive Web Design Fundamentals][148] from  _Google_  ★★★★★(9) - -* [Image and Video Processing: From Mars to Hollywood with a Stop at the Hospital][149] from  _Duke University_  ★★★★☆(8) - -* [Cryptography][150] from  _University of Maryland, College Park_  ★★★★☆(8) - -* [Cryptography][151] from  _University of Maryland, College Park_  ★★★★☆(8) - -* [Learning from Data (Introductory Machine Learning course)][152] from  _California Institute of Technology_  ★★★★★(8) - -* [Julia Scientific Programming][153] from  _University of Cape Town_  ★★★★★(8) - -* [Cloud Computing Applications, Part 1: Cloud Systems and Infrastructure][154]from  _University of Illinois at Urbana-Champaign_  ★★★☆☆(7) - -* [Introduction To Swift Programming][155] from  _University of Toronto_ ★☆☆☆☆(7) - -* [Software Testing][156] from  _University of Utah_  ★★★★☆(7) - -* [Data Wrangling with MongoDB][157] from  _MongoDB University_  ★★★★☆(7) - -* [Intro to AJAX][158] - -* [Computer Architecture][159] from  _Princeton University_  ★★★★☆(6) - -* [Internet of Things: How did we get here?][160] from  _University of California, San Diego _ ★★☆☆☆(6) - -* [Introduction to Meteor.js Development ][161]from  _University of London International Programmes_  ★★★★☆(6) - -* [How to Code: Systematic Program Design — Part 1][162] from  _The University of British Columbia_  ★★★★☆(6) - -* [Intro to DevOps][163] from  _Nutanix_  ★★★☆☆(6) - -* [Full Stack Foundations][164] - -* [Intro to Algorithms][165] - -* [Software Construction in Java][166] from  _Massachusetts Institute of Technology_ ★★★★★(5) - -* [Agile Development Using Ruby on Rails — Advanced][167] from  _University of California, Berkeley_  ★★★★★(5) - -* [Computer Graphics][168] from  _University of California, Berkeley_  ★★★★☆(5) - -* [Software Development Process][169] from  _Georgia Institute of Technology_ ★★★★☆(5) - -* [Computer Networking][170] from  _Georgia Institute of Technology_  ★★★★☆(5) - -* [Java Programming: Arrays, Lists, and Structured Data][171] from  _Duke University_  ★★★★★(5) - -* [Cloud Computing Concepts: Part 2][172] from  _University of Illinois at Urbana-Champaign_  ★★★★★(5) - -* [HTML5 Game Development][173] from  _Google_  ★★★☆☆(5) - -* [Introduction to C++][174] from  _Microsoft_  ★★★★☆(5) - -* [Software Debugging][175] from  _Saarland University_  ★★★★★(5) - -* [Parallel Programming Concepts][176] - -* [Intro to iOS App Development with Swift][177] - -* [Internet of Things: Setting Up Your DragonBoard™ Development Platform][178]from  _University of California, San Diego _ ★★★☆☆(4) - -* [Internet of Things & Augmented Reality Emerging Technologies][179] from  _Yonsei University_  ★★★☆☆(4) - -* [Database Management Essentials][180] from  _University of Colorado System_ ★★★★☆(4) - -* [Website Performance Optimization][181] from  _Google_  ★★★★☆(4) - -* [UX Design for Mobile Developers][182] from  _Google_  ★★★★★(4) - -* [Querying Data with Transact-SQL][183] from  _Microsoft_  ★★★★☆(4) - -* [Interactive Computer Graphics][184] from  _The University of Tokyo_  ★★☆☆☆(4) - -* [Intro to jQuery][185] - -* [Using Python for Research][186] from  _Harvard University_  ★★★☆☆(3) - -* [Networks Illustrated: Principles without Calculus][187] from  _Princeton University_ ★★★★☆(3) - -* [VLSI CAD Part I: Logic][188] from  _University of Illinois at Urbana-Champaign_ ★★★★★(3) - -* [Internet of Things: Communication Technologies][189] from  _University of California, San Diego _ ★★★☆☆(3) - -* [MATLAB and Octave for Beginners][190] from  _École Polytechnique Fédérale de Lausanne_  ★★★☆☆(3) - -* [Wireless Communication Emerging Technologies][191] from  _Yonsei University_ ★★★★☆(3) - -* [JavaScript Promises][192] from  _Google_  ★★★★★(3) - -* [Android Basics: Multiscreen Apps][193] from  _Google_  ★★★★☆(3) - -* [Android Basics: User Input][194] from  _Google_  ★★★★☆(3) - -* [DevOps for Developers: How to Get Started][195] from  _Microsoft_  ★★★★☆(3) - -* [Autonomous Mobile Robots][196] from  _ETH Zurich_  ★★★☆☆(3) - -* [Agile Software Development][197] from  _ETH Zurich_  ★★★★☆(3) - -* [JavaScript Testing][198] - -* [Configuring Linux Web Servers][199] - -* [JavaScript Design Patterns][200] - -* [Compilers][201] from  _Stanford University_  ★★★★☆(2) - -* [LPL: Language, Proof and Logic][202] from  _Stanford University_  ★★★★★(2) - -* [Mobile Application Experiences Part 1: From a Domain to an App Idea][203]from  _Massachusetts Institute of Technology_  ★★★★★(2) - -* [Machine Learning: Unsupervised Learning][204] from  _Brown University_ ★★★★★(2) - -* [Programming Languages, Part B][205] from  _University of Washington_ ★★★★★(2) - -* [Responsive Website Tutorial and Examples][206] from  _University of London International Programmes_  ★★★★★(2) - -* [iOS App Development Basics][207] from  _University of Toronto_  ★★★★☆(2) - -* [Programming, Data Structures and Algorithms][208] from  _Indian Institute of Technology Madras_  ★★☆☆☆(2) - -* [Android App Components — Services, Local IPC, and Content Providers][209]from  _Vanderbilt University_  ★★★☆☆(2) - -* [Android App Components — Intents, Activities, and Broadcast Receivers][210]from  _Vanderbilt University_  ★★★☆☆(2) - -* [Introduction to Mobile Application Development using Android][211] from  _The Hong Kong University of Science and Technology_  ★★★★☆(2) - -* [Internet Emerging Technologies][212] from  _Yonsei University_  ★★★☆☆(2) - -* [Object-Oriented Design][213] from  _University of Alberta_  ★★★☆☆(2) - -* [Android Basics: Networking][214] from  _Google_  ★★★★☆(2) - -* [Browser Rendering Optimization][215] from  _Google_  ★★★★☆(2) - -* [Google Cloud Platform Fundamentals: Core Infrastructure][216] from  _Google_ ★★★★☆(2) - -* [Client-Server Communication][217] from  _Google_  ★★★★★(2) - -* [Developing International Software, Part 1][218] from  _Microsoft_  ★★★★☆(2) - -* [Analyzing and Visualizing Data with Power BI][219] from  _Microsoft_ ★★★★★(2) - -* [Networking for Web Developers][220] - -* [Computation Structures 2: Computer Architecture][221] from  _Massachusetts Institute of Technology_  ★★★★☆(1) - -* [Software Development Fundamentals][222] from  _University of Pennsylvania_ ★★★☆☆(1) - -* [Software Architecture & Design][223] from  _Georgia Institute of Technology_ ★★★★★(1) - -* [Database Systems Concepts & Design][224] from  _Georgia Institute of Technology_ ★★★★☆(1) - -* [Programming Languages, Part C][225] from  _University of Washington_ ★★★★★(1) - -* [How to Code: Complex Data][226] from  _The University of British Columbia_ ★★★★★(1) - -* [Running Product Design Sprints][227] from  _University of Virginia_  ★★★☆☆(1) - -* [Java for Android][228] from  _Vanderbilt University_  ★☆☆☆☆(1) - -* [Server-side Development with NodeJS, Express and MongoDB][229] from  _The Hong Kong University of Science and Technology_  ★★★★★(1) - -* [Cyber Security Economics][230] from  _Delft University of Technology_ ★★☆☆☆(1) - -* [Web Application Development: Basic Concepts][231] from  _University of New Mexico_  ★★★★☆(1) - -* [Algorithms][232] from  _Indian Institute of Technology Bombay_  ★★★★★(1) - -* [Android: Introducción a la Programación][233] from  _Universitat Politècnica de València_  ★★★★☆(1) - -* [Service-Oriented Architecture][234] from  _University of Alberta_  ★★★★★(1) - -* [Design Patterns][235] from  _University of Alberta_  ★☆☆☆☆(1) - -* [Cybersecurity and Mobility][236] from  _University System of Georgia_ ★☆☆☆☆(1) - -* [Google Cloud Platform Fundamentals for AWS Professionals][237] from  _Google Cloud_  ★★☆☆☆(1) - -* [Android Basics: User Interface][238] from  _Google_  ★★☆☆☆(1) - -* [Scalable Microservices with Kubernetes][239] from  _Google_  ★★★★☆(1) - -* [Developing Scalable Apps in Java][240] from  _Google_  ★★★★☆(1) - -* [Android Performance][241] from  _Google_  ★★★★★(1) - -* [Android Basics: Button Clicks][242] from  _Google_  ★★★☆☆(1) - -* [Gradle for Android and Java][243] from  _Google_  ★★★★★(1) - -* [VR Software Development][244] from  _Google_  ★★★★☆(1) - -* [Developing Scalable Apps in Python][245] from  _Google_  ★★★★☆(1) - -* [Material Design for Android Developers][246] from  _Google_  ★★★★★(1) - -* [Intermediate C++][247] from  _Microsoft_  ★★★★☆(1) - -* [Introduction to C#][248] from  _Microsoft_  ★★☆☆☆(1) - -* [AngularJS: Advanced Framework Techniques][249] from  _Microsoft_ ★★★★☆(1) - -* [Principles of Machine Learning][250] from  _Microsoft_  ★★★★★(1) - -* [Asynchronous Programming with Javascript][251] from  _Microsoft_ ★★★★★(1) - -* [Build a Modern Computer from First Principles: Nand to Tetris Part II (project-centered course)][252] from  _Hebrew University of Jerusalem_ ★★★★★(1) - -* [A developer’s guide to the Internet of Things (IoT)][253] from  _IBM_ ★★★★☆(1) - -* [Introduction to Cloud Infrastructure Technologies][254] from  _Linux Foundation_ ★★★★☆(1) - -* [2D Game Development with libGDX][255] from  _Amazon_  ★★★★★(1) - -* [Introduction to Real-Time Systems][256] from  _IEEE_  ★★★★☆(1) - -* [Design and Analysis of Algorithms][257] from  _Chennai Mathematical Institute_ ★★★☆☆(1) - -* [How to Win Coding Competitions: Secrets of Champions][258] from  _ITMO University_  ★★★☆☆(1) - -* [HTML5 Apps and Games][259] from  _World Wide Web Consortium (W3C)_ ★★★☆☆(1) - -* [Technical Interview][260] from  _Pramp_  ★★★★★(1) - -* [Android Basics: Data Storage][261] - -* [Intro to Theoretical Computer Science][262] - -* [Algorithms: Design and Analysis][263] from  _Stanford University_ - -* [Shortest Paths Revisited, NP-Complete Problems and What To Do About Them][264] from  _Stanford University_ - -* [Mobile Application Experiences][265] from  _Massachusetts Institute of Technology_ - -* [Advanced Software Construction in Java][266] from  _Massachusetts Institute of Technology_ - -* [Mobile Application Experiences Part 3: Building Mobile Apps][267] from  _Massachusetts Institute of Technology_ - -* [Algorithm Design and Analysis][268] from  _University of Pennsylvania_ - -* [Data Structures and Software Design][269] from  _University of Pennsylvania_ - -* [Introduction to Neurohacking In R][270] from  _Johns Hopkins University_ - -* [Database Systems Concepts and Design][271] from  _Georgia Institute of Technology_ - -* [Software Analysis & Testing][272] from  _Georgia Institute of Technology_ - -* [Writing, Running, and Fixing Code in C][273] from  _Duke University_ - -* [Animation and CGI Motion][274] from  _Columbia University_ - -* [Minecraft, Coding and Teaching][275] from  _University of California, San Diego_ - -* [Internet of Things: Sensing and Actuation From Devices][276] from  _University of California, San Diego_ - -* [How Virtual Reality (VR) Works][277] from  _University of California, San Diego_ - -* [Creating Virtual Reality (VR) Apps][278] from  _University of California, San Diego_ - -* [Building a Cybersecurity Toolkit][279] from  _University of Washington_ - -* [Cybersecurity: The CISO’s View][280] from  _University of Washington_ - -* [Build Your Own iOS App][281] from  _University of Toronto_ - -* [算法设计与分析 Design and Analysis of Algorithms][282] from  _Peking University_ - -* [面向对象技术高级课程(The Advanced Object-Oriented Technology)][283]from  _Peking University_ - -* [How to Code: Systematic Program Design — Part 3][284] from  _The University of British Columbia_ - -* [How to Code: Systematic Program Design — Part 2][285] from  _The University of British Columbia_ - -* [Software Construction: Data Abstraction][286] from  _The University of British Columbia_ - -* [Software Construction: Object-Oriented Design][287] from  _The University of British Columbia_ - -* [Testing with Agile][288] from  _University of Virginia_ - -* [SQL for Data Science][289] from  _University of California, Davis_ - -* [LAFF — On Programming for Correctness][290] from  _The University of Texas at Austin_ - -* [Multiplatform Mobile App Development with NativeScript][291] from  _The Hong Kong University of Science and Technology_ - -* [Front-End JavaScript Frameworks: Angular][292] from  _The Hong Kong University of Science and Technology_ - -* [Multiplatform Mobile App Development with Web Technologies: Ionic and Cordova][293] from  _The Hong Kong University of Science and Technology_ - -* [Developing Android Apps with App Inventor][294] from  _The Hong Kong University of Science and Technology_ - -* [Front-End Web UI Frameworks and Tools: Bootstrap 4][295] from  _The Hong Kong University of Science and Technology_ - -* [Globally Distributed Software Engineering][296] from  _Delft University of Technology_ - -* [Основы разработки на C++: жёлтый пояс][297] from  _Moscow Institute of Physics and Technology_ - -* [Building Arduino robots and devices][298] from  _Moscow Institute of Physics and Technology_ - -* [Implementation of Data Structures][299] from  _Indian Institute of Technology Bombay_ - -* [Foundations of Data Structures][300] from  _Indian Institute of Technology Bombay_ - -* [Professional Android App Development][301] from  _Galileo University_ - -* [Professional Android App Development][302] from  _Galileo University_ - -* [The Software Architect Code: Building the Digital World][303] from  _Universidad Carlos iii de Madrid_ - -* [Introduction to Java Programming: Fundamental Data Structures and Algorithms][304] from  _Universidad Carlos iii de Madrid_ - -* [Enterprise Software Lifecycle Management][305] from  _National Research Nuclear University MEPhI_ - -* [Использование механизмов операционных систем в разработке программного обеспечения][306] from  _National Research Nuclear University MEPhI_ - -* [Requirements Elicitation: Artifact and Stakeholder Analysis][307] from  _University of Colorado System_ - -* [Linux Server Management and Security][308] from  _University of Colorado System_ - -* [Requirements Specifications: Goals and Conflict Analysis][309] from  _University of Colorado System_ - -* [Software Requirements Prioritization: Risk Analysis][310] from  _University of Colorado System_ - -* [Homeland Security & Cybersecurity Connection — It’s Not About the Terrorists][311] from  _University of Colorado System_ - -* [SRS Documents: Requirements and Diagrammatic Notations][312] from  _University of Colorado System_ - -* [Requirements Gathering for Secure Software Development][313] from  _University of Colorado System_ - -* [Software Testing Management][314] from  _University System of Maryland_ - -* [Cloud Computing for Enterprises][315] from  _University System of Maryland_ - -* [Cloud Computing Infrastructure][316] from  _University System of Maryland_ - -* [Formal Software Verification][317] from  _University System of Maryland_ - -* [Software Testing Fundamentals][318] from  _University System of Maryland_ - -* [Cloud Computing Management][319] from  _University System of Maryland_ - -* [Introduction to Data Structures][320] from  _University of Adelaide_ - -* [Gameplay Programming for Video Game Designers][321] from  _Rochester Institute of Technology_ - -* [Teamwork & Collaboration][322] from  _Rochester Institute of Technology_ - -* [Web Connectivity and Security in Embedded Systems][323] from  _EIT Digital_ - -* [Architecting Smart IoT Devices][324] from  _EIT Digital_ - -* [Introduction to Architecting Smart IoT Devices][325] from  _EIT Digital_ - -* [Cybersecurity and the X-Factor][326] from  _University System of Georgia_ - -* [Intro to Progressive Web Apps][327] from  _Google_ - -* [Advanced Android App Development][328] from  _Google_ - -* [Google Maps APIs][329] from  _Google_ - -* [Offline Web Applications][330] from  _Google_ - -* [Firebase Essentials For Android][331] from  _Google_ - -* [Developing Intelligent Apps and Bots][332] from  _Microsoft_ - -* [Developing SQL Databases][333] from  _Microsoft_ - -* [Building Functional Prototypes using Node.js][334] from  _Microsoft_ - -* [Building Interactive Prototypes using JavaScript][335] from  _Microsoft_ - -* [Algorithms and Data Structures][336] from  _Microsoft_ - -* [Algorithms and Data Structures in C#][337] from  _Microsoft_ - -* [Creating Programmatic SQL Database Objects][338] from  _Microsoft_ - -* [AngularJS: Framework Fundamentals][339] from  _Microsoft_ - -* [Introduction to TypeScript 2][340] from  _Microsoft_ - -* [Advanced CSS Concepts][341] from  _Microsoft_ - -* [Implementing In-Memory SQL Database Objects][342] from  _Microsoft_ - -* [Optimizing Performance for SQL Based Applications][343] from  _Microsoft_ - -* [Programmation Concurrente (avec Java)][344] from  _Sorbonne Universités_ - -* [C++ For C Programmers, Part B][345] from  _University of California, Santa Cruz_ - -* [Introduction to Kubernetes][346] from  _Linux Foundation_ - -* [Introduction to DevOps: Transforming and Improving Operations][347] from  _Linux Foundation_ - -* [Introduction to DevOps: Transforming and Improving Operations][348] from  _Linux Foundation_ - -* [UML Class Diagrams for Software Engineering][349] from  _KU Leuven University_ - -* [Mobile Usability and Design for Android][350] from  _Facebook_ - -* [Mobile Usability and Design for IOS][351] from  _Facebook_ - -* [Concurrency][352] from  _AdaCore University_ - -* [Fundamentals of Red Hat Enterprise Linux][353] from  _Red Hat_ - -* [Fundamentals of Containers, Kubernetes, and Red Hat OpenShift][354] from  _Red Hat_ - -* [C++ For Programmers][355] - -* [Learn Backbone.js][356] - -* [How to create in Android][357] - -* [How to Make an iOS App][358] - -* [iOS Persistence and Core Data][359] - -* [UIKit Fundamentals][360] - -* [iOS Networking with Swift][361] - -* [Designing RESTful APIs][362] - -* [VR Platforms & Applications][363] - -* [Swift for Developers][364] - -* [The MVC Pattern in Ruby][365] - -* [Deploying Applications with Heroku][366] - -* [Dynamic Web Applications with Sinatra][367] - -* [Building iOS Interfaces][368] - -* [VR Design][369] - -* [New Android Fundamentals][370] - -* [iOS Design Patterns][371] - -* [VR Scenes and Objects][372] - -### ADVANCED(78) - -* [Creative Applications of Deep Learning with TensorFlow][373] - -* [[New] An Introduction to Probability in Computing][374] from  _Indian Institute of Technology Madras_ - -* [[New] Information security — IV][375] from  _Indian Institute of Technology Madras_ - -* [[New] Matlab Programming For Numerical Computation][376] from  _Indian Institute of Technology Madras_ - -* [[New] Digital Switching — I][377] from  _Indian Institute of Technology Kanpur_ - -* [[New] Advanced Graph Theory][378] from  _Indian Institute of Technology Kanpur_ - -* [[New] Deep Learning in Computer Vision][379] from  _Higher School of Economics_ - -* [[New] Natural Language Processing][380] from  _Higher School of Economics_ - -* [[New] Practical Reinforcement Learning][381] from  _Higher School of Economics_ - -* [[New] Real Time Operating System][382] from  _Indian Institute of Technology, Kharagpur_ - -* [[New] Traditional and Non-Traditional Optimization Tools][383] from  _Indian Institute of Technology, Kharagpur_ - -* [[New] Basics of software-defined radios and practical applications][384] from  _Indian Institute of Technology Roorkee_ - -* [[New] Sparse Representations in Image Processing: From Theory to Practice][385] from  _Technion — Israel Institute of Technology_ - -* [Introduction to Artificial Intelligence][386] from  _Stanford University_ ★★★★☆(24) - -* [Neural Networks for Machine Learning][387] from  _University of Toronto_ ★★★★☆(22) - -* [Machine Learning for Data Science and Analytics][388] from  _Columbia University_ ★★★☆☆(15) - -* [Machine Learning for Trading][389] from  _Georgia Institute of Technology_ ★★★☆☆(13) - -* [Neural Networks and Deep Learning][390] from  _deeplearning.ai_  ★★★★★(9) - -* [Artificial Intelligence (AI)][391] from  _Columbia University_  ★★★★☆(9) - -* [Computational Neuroscience][392] from  _University of Washington_  ★★★★☆(8) - -* [Introduction to Computer Vision][393] from  _Georgia Institute of Technology_ ★★★★★(6) - -* [Reinforcement Learning][394] from  _Brown University_  ★★☆☆☆(6) - -* [Intro to Parallel Programming][395] from  _Nvidia_  ★★★★☆(6) - -* [Interactive 3D Graphics][396] from  _Autodesk_  ★★★★☆(6) - -* [Machine Learning][397] from  _Georgia Institute of Technology_  ★★★★★(5) - -* [Enabling Technologies for Data Science and Analytics: The Internet of Things][398] from  _Columbia University_  ★☆☆☆☆(5) - -* [Applied Cryptography][399] from  _University of Virginia_  ★★★★☆(5) - -* [Practical Deep Learning For Coders, Part 1][400] from  _fast.ai_  ★★★★☆(5) - -* [Advanced Operating Systems][401] from  _Georgia Institute of Technology_ ★★★★★(4) - -* [Machine Learning][402] from  _Columbia University_  ★★★★★(4) - -* [Introduction to Computer Architecture][403] from  _Carnegie Mellon University_ ★★★★★(4) - -* [Probabilistic Graphical Models 2: Inference][404] from  _Stanford University_ ★★★★☆(3) - -* [Applied Machine Learning in Python][405] from  _University of Michigan_ ★★★★☆(3) - -* [Quantitative Formal Modeling and Worst-Case Performance Analysis][406] from  _EIT Digital _ ★★★☆☆(3) - -* [6.S191: Introduction to Deep Learning][407] from  _Massachusetts Institute of Technology_  ★★★★☆(2) - -* [Introduction to Operating Systems][408] from  _Georgia Institute of Technology_ ★★★★★(2) - -* [Nearest Neighbor Collaborative Filtering][409] from  _University of Minnesota_ ★★☆☆☆(2) - -* [6.S094: Deep Learning for Self-Driving Cars][410] from  _Massachusetts Institute of Technology_  ★★★★☆(1) - -* [High Performance Computer Architecture][411] from  _Georgia Institute of Technology_  ★★★★★(1) - -* [Computability, Complexity & Algorithms][412] from  _Georgia Institute of Technology_  ★★★★★(1) - -* [Computational Photography][413] from  _Georgia Institute of Technology_ ★★★★☆(1) - -* [Intro to Information Security][414] from  _Georgia Institute of Technology_ ★☆☆☆☆(1) - -* [Knowledge-Based AI: Cognitive Systems][415] from  _Georgia Institute of Technology_  ★★★☆☆(1) - -* [Embedded Hardware and Operating Systems][416] from  _EIT Digital _ ★☆☆☆☆(1) - -* [Learn TensorFlow and deep learning, without a Ph.D.][417] from  _Google_ ★★★★☆(1) - -* [DevOps Practices and Principles][418] from  _Microsoft_  ★★☆☆☆(1) - -* [Sparse Representations in Signal and Image Processing: Fundamentals][419]from  _Technion — Israel Institute of Technology_  ★★★★★(1) - -* [Introduction to Cloud Foundry and Cloud Native Software Architecture][420]from  _Linux Foundation_  ★★★★★(1) - -* [Blockchain for Business — An Introduction to Hyperledger Technologies][421]from  _Linux Foundation_  ★★★★☆(1) - -* [Computation Structures 3: Computer Organization][422] from  _Massachusetts Institute of Technology_ - -* [GT — Refresher — Advanced OS][423] from  _Georgia Institute of Technology_ - -* [High Performance Computing][424] from  _Georgia Institute of Technology_ - -* [Compilers: Theory and Practice][425] from  _Georgia Institute of Technology_ - -* [Cyber-Physical Systems Security][426] from  _Georgia Institute of Technology_ - -* [Network Security][427] from  _Georgia Institute of Technology_ - -* [Artificial Intelligence][428] from  _Georgia Institute of Technology_ - -* [Information Security: Context and Introduction][429] from  _University of London International Programmes_ - -* [Advanced Modeling for Discrete Optimization][430] from  _University of Melbourne_ - -* [Basic Modeling for Discrete Optimization][431] from  _University of Melbourne_ - -* [Nature, in Code: Biology in JavaScript][432] from  _École Polytechnique Fédérale de Lausanne_ - -* [Matrix Factorization and Advanced Techniques][433] from  _University of Minnesota_ - -* [System Validation: Automata and behavioural equivalences][434] from  _EIT Digital_ - -* [System Validation (2): Model process behaviour][435] from  _EIT Digital_ - -* [System Validation (4): Modelling Software, Protocols, and other behaviour][436] from  _EIT Digital_ - -* [DevOps Testing][437] from  _Microsoft_ - -* [Deep Learning Explained][438] from  _Microsoft_ - -* [Introduction to Artificial Intelligence (AI)][439] from  _Microsoft_ - -* [DevOps for Databases][440] from  _Microsoft_ - -* [Infrastructure as Code][441] from  _Microsoft_ - -* [Deep Learning for Natural Language Processing][442] from  _University of Oxford_ - -* [Statistical Machine Learning][443] from  _Carnegie Mellon University_ - -* [Cyber-Physical Systems: Modeling and Simulation][444] from  _University of California, Santa Cruz_ - -* [Introduction to OpenStack][445] from  _Linux Foundation_ - -* [Computer System Design: Advanced Concepts of Modern Microprocessors][446]from  _Chalmers University of Technology_ - -* [Reliable Distributed Algorithms, Part 2][447] from  _KTH Royal Institute of Technology_ - -* [Deep Learning Summer School][448] - -* [Continuous Integration and Deployment][449] - --------------------------------------------------------------------------------- - -作者简介: - -Founder of www.class-central.com — The most popular online course search engine - - ----- - - -via: https://medium.freecodecamp.org/440-free-online-programming-computer-science-courses-you-can-start-in-february-e075f920cb5b - -作者:[Dhawal Shah ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://medium.freecodecamp.org/@dhawalhs -[1]:https://www.class-central.com/ -[2]:https://www.class-central.com/mooc/408/coursera-an-introduction-to-interactive-programming-in-python-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[3]:https://www.class-central.com/mooc/1341/edx-introduction-to-computer-science-and-programming-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[4]:https://www.class-central.com/mooc/385/coursera-learn-to-program-the-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[5]:https://www.class-central.com/mooc/320/udacity-intro-to-computer-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[6]:https://www.class-central.com/mooc/442/edx-cs50-s-introduction-to-computer-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[7]:https://www.class-central.com/mooc/3196/coursera-an-introduction-to-interactive-programming-in-python-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[8]:https://www.class-central.com/mooc/2661/udacity-how-to-use-git-and-github?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[9]:https://www.class-central.com/mooc/1857/edx-introduction-to-linux?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[10]:https://www.class-central.com/mooc/335/coursera-internet-history-technology-and-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[11]:https://www.class-central.com/mooc/2659/udacity-intro-to-html-and-css?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[12]:https://www.class-central.com/mooc/1797/open-education-by-blackboard-introduction-to-vba-excel-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[13]:https://www.class-central.com/mooc/10142/edx-cs50-s-understanding-technology?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[14]:https://www.class-central.com/mooc/10143/edx-cs50-s-computer-science-for-business-professionals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[15]:https://www.class-central.com/mooc/10316/edx-introduccion-a-la-programacion-en-java-como-comenzar-a-programar?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[16]:https://www.class-central.com/mooc/9750/edx-introduction-to-the-internet-of-things-iot?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[17]:https://www.class-central.com/mooc/10166/coursera-version-control-with-git?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[18]:https://www.class-central.com/mooc/2660/udacity-javascript-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[19]:https://www.class-central.com/mooc/2175/stanford-openedx-cs101-computer-science-101?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[20]:https://www.class-central.com/mooc/1650/edx-programming-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[21]:https://www.class-central.com/mooc/8726/edx-web-security-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[22]:https://www.class-central.com/mooc/2013/udacity-programming-foundations-with-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[23]:https://www.class-central.com/mooc/1578/stanford-openedx-networking-introduction-to-computer-networking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[24]:https://www.class-central.com/mooc/1580/stanford-openedx-db-introduction-to-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[25]:https://www.class-central.com/mooc/529/coursera-creative-programming-for-digital-media-mobile-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[26]:https://www.class-central.com/mooc/4256/coursera-programming-foundations-with-javascript-html-and-css?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[27]:https://www.class-central.com/mooc/1727/coursera-usable-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[28]:https://www.class-central.com/mooc/3338/edx-introduction-to-bootstrap-a-tutorial?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[29]:https://www.class-central.com/mooc/3444/edx-html5-coding-essentials-and-best-practices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[30]:https://www.class-central.com/mooc/7363/python-for-everybody-exploring-information?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[31]:https://www.class-central.com/mooc/390/coursera-learn-to-program-crafting-quality-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[32]:https://www.class-central.com/mooc/3770/kadenze-introduction-to-programming-for-the-visual-arts-with-p5-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[33]:https://www.class-central.com/mooc/3253/udacity-intro-to-relational-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[34]:https://www.class-central.com/mooc/4062/edx-introduction-to-jquery?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[35]:https://www.class-central.com/mooc/5764/edx-html5-and-css-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[36]:https://www.class-central.com/mooc/6686/udacity-java-programming-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[37]:https://www.class-central.com/mooc/4049/udacity-linux-command-line-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[38]:https://www.class-central.com/mooc/1983/edx-introduction-to-java-programming-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[39]:https://www.class-central.com/mooc/2813/edx-introduction-to-java-programming-starting-to-code-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[40]:https://www.class-central.com/mooc/2630/edx-paradigms-of-computer-programming-abstraction-and-concurrency?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[41]:https://www.class-central.com/mooc/2298/edx-paradigms-of-computer-programming-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[42]:https://www.class-central.com/mooc/2954/edx-programming-in-scratch?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[43]:https://www.class-central.com/mooc/8518/edx-programming-for-the-web-with-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[44]:https://www.class-central.com/mooc/2525/edx-the-beauty-and-joy-of-computing-ap-cs-principles-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[45]:https://www.class-central.com/mooc/7622/edx-introduction-to-computing-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[46]:https://www.class-central.com/mooc/1651/edx-object-oriented-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[47]:https://www.class-central.com/mooc/3231/edx-think-create-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[48]:https://www.class-central.com/mooc/2809/edx-the-computing-technology-inside-your-smartphone?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[49]:https://www.class-central.com/mooc/7278/udacity-android-basics-make-your-first-app?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[50]:https://www.class-central.com/mooc/3695/edx-learn-to-program-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[51]:https://www.class-central.com/mooc/5923/edx-introduction-to-html-and-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[52]:https://www.class-central.com/mooc/3483/edx-cs-for-all-introduction-to-computer-science-and-python-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[53]:https://www.class-central.com/mooc/8059/udacity-intro-to-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[54]:https://www.class-central.com/mooc/7623/udacity-android-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[55]:https://www.class-central.com/mooc/359/coursera-networks-friends-money-and-bytes?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[56]:https://www.class-central.com/mooc/8202/edx-how-to-code-simple-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[57]:https://www.class-central.com/mooc/6408/kadenze-web-development-and-design-using-wordpress?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[58]:https://www.class-central.com/mooc/7315/edx-android-app-development-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[59]:https://www.class-central.com/mooc/7315/edx-android-app-development-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[60]:https://www.class-central.com/mooc/3781/kadenze-web-coding-fundamentals-for-artists?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[61]:https://www.class-central.com/mooc/8770/edx-introduction-to-reactjs?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[62]:https://www.class-central.com/mooc/9597/edx-introduction-to-node-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[63]:https://www.class-central.com/mooc/8718/edx-learn-to-program-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[64]:https://www.class-central.com/mooc/2195/edx-computing-art-magic-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[65]:https://www.class-central.com/mooc/6265/futurelearn-cyber-security-safety-at-home-online-in-life?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[66]:https://www.class-central.com/mooc/8527/edx-software-engineering-essentials?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[67]:https://www.class-central.com/mooc/2957/edx-mycs-computer-science-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[68]:https://www.class-central.com/mooc/8430/udacity-version-control-with-git?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[69]:https://www.class-central.com/mooc/7362/web-applications-for-everybody?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[70]:https://www.class-central.com/mooc/7017/edx-cs50-s-ap-computer-science-principles?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[71]:https://www.class-central.com/mooc/9574/coursera-programming-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[72]:https://www.class-central.com/mooc/8651/edx-introduction-to-cybersecurity?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[73]:https://www.class-central.com/mooc/9550/coursera-python-data-representations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[74]:https://www.class-central.com/mooc/9549/coursera-python-programming-essentials?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[75]:https://www.class-central.com/mooc/8205/edx-software-engineering-introduction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[76]:https://www.class-central.com/mooc/7027/coursera-introduction-to-web-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[77]:https://www.class-central.com/mooc/3486/edx-introduction-to-java-programming-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[78]:https://www.class-central.com/mooc/9943/coursera-excel-vba-for-creative-problem-solving-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[79]:https://www.class-central.com/mooc/9943/coursera-excel-vba-for-creative-problem-solving-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[80]:https://www.class-central.com/mooc/7219/edx-ap-computer-science-a-java-programming-polymorphism-and-advanced-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[81]:https://www.class-central.com/mooc/7212/edx-ap-computer-science-a-java-programming-loops-and-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[82]:https://www.class-central.com/mooc/7211/edx-ap-computer-science-a-java-programming-classes-and-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[83]:https://www.class-central.com/mooc/7313/edx-java-fundamentals-for-android-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[84]:https://www.class-central.com/mooc/7345/edx-monetize-android-apps-with-business-models?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[85]:https://www.class-central.com/mooc/7345/edx-monetize-android-apps-with-business-models?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[86]:https://www.class-central.com/mooc/7313/edx-java-fundamentals-for-android-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[87]:https://www.class-central.com/mooc/5735/edx-introduction-to-java-programming-writing-good-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[88]:https://www.class-central.com/mooc/7849/edx-cyber-security-basics-a-hands-on-approach?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[89]:https://www.class-central.com/mooc/9431/coursera-deep-learning-for-business?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[90]:https://www.class-central.com/mooc/9143/coursera-introduction-to-tcp-ip?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[91]:https://www.class-central.com/mooc/6660/edx-video-game-design-and-balance?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[92]:https://www.class-central.com/mooc/6531/udacity-web-accessibility?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[93]:https://www.class-central.com/mooc/1046/udacity-mobile-web-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[94]:https://www.class-central.com/mooc/10134/edx-introduction-to-programming-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[95]:https://www.class-central.com/mooc/8671/edx-introduction-to-python-absolute-beginner?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[96]:https://www.class-central.com/mooc/8650/edx-introduction-to-python-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[97]:https://www.class-central.com/mooc/8845/edx-introduction-to-design-thinking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[98]:https://www.class-central.com/mooc/8725/edx-logic-and-computational-thinking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[99]:https://www.class-central.com/mooc/8808/edx-writing-professional-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[100]:https://www.class-central.com/mooc/8723/edx-object-oriented-programming-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[101]:https://www.class-central.com/mooc/7199/edx-css-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[102]:https://www.class-central.com/mooc/4084/edx-computing-art-magic-science-part-ii?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[103]:https://www.class-central.com/mooc/8496/edx-javascript-introduction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[104]:https://www.class-central.com/mooc/8884/futurelearn-object-oriented-programming-in-python-create-your-own-adventure-game?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[105]:https://www.class-central.com/mooc/3925/udacity-learn-swift-programming-syntax?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[106]:https://www.class-central.com/mooc/9990/udacity-javascript-and-the-dom?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[107]:https://www.class-central.com/mooc/9526/futurelearn-blockchain-in-the-energy-sector?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[108]:https://www.class-central.com/mooc/7379/udacity-introduction-to-virtual-reality?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[109]:https://www.class-central.com/mooc/8543/udacity-es6-javascript-improved?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[110]:https://www.class-central.com/mooc/8577/udacity-introduction-to-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[111]:https://www.class-central.com/mooc/8374/udacity-http-web-servers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[112]:https://www.class-central.com/mooc/8542/udacity-github-collaboration?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[113]:https://www.class-central.com/mooc/7494/udacity-swift-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[114]:https://www.class-central.com/mooc/835/coursera-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[115]:https://www.class-central.com/mooc/339/coursera-algorithms-part-i?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[116]:https://www.class-central.com/mooc/3768/kadenze-machine-learning-for-musicians-and-artists?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[117]:https://www.class-central.com/mooc/616/coursera-cryptography-i?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[118]:https://www.class-central.com/mooc/445/edx-cs188-1x-artificial-intelligence?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[119]:https://www.class-central.com/mooc/1724/coursera-principles-of-computing-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[120]:https://www.class-central.com/mooc/10241/edx-algorithmic-design-and-techniques?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[121]:https://www.class-central.com/mooc/1728/coursera-software-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[122]:https://www.class-central.com/mooc/10053/nptel-introduction-to-soft-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[123]:https://www.class-central.com/mooc/10027/nptel-cloud-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[124]:https://www.class-central.com/mooc/9914/nptel-database-management-system?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[125]:https://www.class-central.com/mooc/10044/nptel-introduction-to-haskell-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[126]:https://www.class-central.com/mooc/340/coursera-algorithms-part-ii?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[127]:https://www.class-central.com/mooc/5174/canvas-network-professional-web-accessibility-auditing-made-easy?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[128]:https://www.class-central.com/mooc/443/edx-agile-development-using-ruby-on-rails-the-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[129]:https://www.class-central.com/mooc/376/stanford-openedx-automata-theory?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[130]:https://www.class-central.com/mooc/2996/udacity-intro-to-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[131]:https://www.class-central.com/mooc/324/udacity-web-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[132]:https://www.class-central.com/mooc/3198/coursera-principles-of-computing-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[133]:https://www.class-central.com/mooc/3579/udacity-android-development-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[134]:https://www.class-central.com/mooc/671/coursera-c-for-c-programmers-part-a?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[135]:https://www.class-central.com/mooc/3777/kadenze-the-nature-of-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[136]:https://www.class-central.com/mooc/1176/open2study-concepts-in-game-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[137]:https://www.class-central.com/mooc/1725/coursera-algorithmic-thinking-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[138]:https://www.class-central.com/mooc/323/udacity-design-of-computer-programs?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[139]:https://www.class-central.com/mooc/4305/coursera-java-programming-solving-problems-with-software?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[140]:https://www.class-central.com/mooc/4200/coursera-responsive-web-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[141]:https://www.class-central.com/mooc/487/coursera-discrete-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[142]:https://www.class-central.com/mooc/4275/coursera-introduction-to-game-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[143]:https://www.class-central.com/mooc/2147/edx-introduction-to-functional-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[144]:https://www.class-central.com/mooc/2211/udacity-developing-android-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[145]:https://www.class-central.com/mooc/2658/udacity-object-oriented-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[146]:https://www.class-central.com/mooc/325/udacity-programming-languages?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[147]:https://www.class-central.com/mooc/3200/coursera-algorithmic-thinking-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[148]:https://www.class-central.com/mooc/3255/udacity-responsive-web-design-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[149]:https://www.class-central.com/mooc/462/coursera-image-and-video-processing-from-mars-to-hollywood-with-a-stop-at-the-hospital?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[150]:https://www.class-central.com/mooc/1730/coursera-cryptography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[151]:https://www.class-central.com/mooc/1730/coursera-cryptography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[152]:https://www.class-central.com/mooc/366/learning-from-data-introductory-machine-learning-course?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[153]:https://www.class-central.com/mooc/7092/coursera-julia-scientific-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[154]:https://www.class-central.com/mooc/2738/coursera-cloud-computing-applications-part-1-cloud-systems-and-infrastructure?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[155]:https://www.class-central.com/mooc/4248/coursera-introduction-to-swift-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[156]:https://www.class-central.com/mooc/365/udacity-software-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[157]:https://www.class-central.com/mooc/1479/udacity-data-wrangling-with-mongodb?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[158]:https://www.class-central.com/mooc/2997/udacity-intro-to-ajax?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[159]:https://www.class-central.com/mooc/342/coursera-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[160]:https://www.class-central.com/mooc/4276/coursera-internet-of-things-how-did-we-get-here?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[161]:https://www.class-central.com/mooc/4328/coursera-introduction-to-meteor-js-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[162]:https://www.class-central.com/mooc/3465/edx-how-to-code-systematic-program-design-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[163]:https://www.class-central.com/mooc/4013/udacity-intro-to-devops?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[164]:https://www.class-central.com/mooc/3254/udacity-full-stack-foundations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[165]:https://www.class-central.com/mooc/364/udacity-intro-to-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[166]:https://www.class-central.com/mooc/6469/edx-software-construction-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[167]:https://www.class-central.com/mooc/558/edx-agile-development-using-ruby-on-rails-advanced?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[168]:https://www.class-central.com/mooc/548/edx-computer-graphics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[169]:https://www.class-central.com/mooc/2335/udacity-software-development-process?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[170]:https://www.class-central.com/mooc/2336/udacity-computer-networking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[171]:https://www.class-central.com/mooc/4362/coursera-java-programming-arrays-lists-and-structured-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[172]:https://www.class-central.com/mooc/2942/coursera-cloud-computing-concepts-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[173]:https://www.class-central.com/mooc/551/udacity-html5-game-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[174]:https://www.class-central.com/mooc/4758/edx-introduction-to-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[175]:https://www.class-central.com/mooc/457/udacity-software-debugging?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[176]:https://www.class-central.com/mooc/1701/openhpi-parallel-programming-concepts?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[177]:https://www.class-central.com/mooc/2861/udacity-intro-to-ios-app-development-with-swift?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[178]:https://www.class-central.com/mooc/4260/coursera-internet-of-things-setting-up-your-dragonboard-development-platform?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[179]:https://www.class-central.com/mooc/3934/coursera-internet-of-things-augmented-reality-emerging-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[180]:https://www.class-central.com/mooc/4337/coursera-database-management-essentials?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[181]:https://www.class-central.com/mooc/2189/udacity-website-performance-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[182]:https://www.class-central.com/mooc/2212/udacity-ux-design-for-mobile-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[183]:https://www.class-central.com/mooc/3341/edx-querying-data-with-transact-sql?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[184]:https://www.class-central.com/mooc/2067/coursera-interactive-computer-graphics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[185]:https://www.class-central.com/mooc/2998/udacity-intro-to-jquery?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[186]:https://www.class-central.com/mooc/7204/edx-using-python-for-research?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[187]:https://www.class-central.com/mooc/891/coursera-networks-illustrated-principles-without-calculus?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[188]:https://www.class-central.com/mooc/428/coursera-vlsi-cad-part-i-logic?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[189]:https://www.class-central.com/mooc/4173/coursera-internet-of-things-communication-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[190]:https://www.class-central.com/mooc/7376/edx-matlab-and-octave-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[191]:https://www.class-central.com/mooc/3936/coursera-wireless-communication-emerging-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[192]:https://www.class-central.com/mooc/5680/udacity-javascript-promises?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[193]:https://www.class-central.com/mooc/6549/udacity-android-basics-multiscreen-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[194]:https://www.class-central.com/mooc/7343/udacity-android-basics-user-input?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[195]:https://www.class-central.com/mooc/6333/edx-devops-for-developers-how-to-get-started?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[196]:https://www.class-central.com/mooc/1564/edx-autonomous-mobile-robots?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[197]:https://www.class-central.com/mooc/6878/edx-agile-software-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[198]:https://www.class-central.com/mooc/3351/udacity-javascript-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[199]:https://www.class-central.com/mooc/4050/udacity-configuring-linux-web-servers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[200]:https://www.class-central.com/mooc/3082/udacity-javascript-design-patterns?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[201]:https://www.class-central.com/mooc/2716/stanford-openedx-compilers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[202]:https://www.class-central.com/mooc/2340/stanford-openedx-lpl-language-proof-and-logic?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[203]:https://www.class-central.com/mooc/1523/edx-mobile-application-experiences-part-1-from-a-domain-to-an-app-idea?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[204]:https://www.class-central.com/mooc/1848/udacity-machine-learning-unsupervised-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[205]:https://www.class-central.com/mooc/6920/coursera-programming-languages-part-b?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[206]:https://www.class-central.com/mooc/4356/coursera-responsive-website-tutorial-and-examples?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[207]:https://www.class-central.com/mooc/4348/coursera-ios-app-development-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[208]:https://www.class-central.com/mooc/2778/nptel-programming-data-structures-and-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[209]:https://www.class-central.com/mooc/7763/coursera-android-app-components-services-local-ipc-and-content-providers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[210]:https://www.class-central.com/mooc/5500/coursera-android-app-components-intents-activities-and-broadcast-receivers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[211]:https://www.class-central.com/mooc/3758/edx-introduction-to-mobile-application-development-using-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[212]:https://www.class-central.com/mooc/3933/coursera-internet-emerging-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[213]:https://www.class-central.com/mooc/9216/coursera-object-oriented-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[214]:https://www.class-central.com/mooc/6728/udacity-android-basics-networking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[215]:https://www.class-central.com/mooc/3524/udacity-browser-rendering-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[216]:https://www.class-central.com/mooc/7784/coursera-google-cloud-platform-fundamentals-core-infrastructure?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[217]:https://www.class-central.com/mooc/6527/udacity-client-server-communication?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[218]:https://www.class-central.com/mooc/3996/edx-developing-international-software-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[219]:https://www.class-central.com/mooc/5156/edx-analyzing-and-visualizing-data-with-power-bi?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[220]:https://www.class-central.com/mooc/5965/udacity-networking-for-web-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[221]:https://www.class-central.com/mooc/4810/edx-computation-structures-2-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[222]:https://www.class-central.com/mooc/8516/edx-software-development-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[223]:https://www.class-central.com/mooc/3418/udacity-software-architecture-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[224]:https://www.class-central.com/mooc/8573/udacity-database-systems-concepts-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[225]:https://www.class-central.com/mooc/7187/coursera-programming-languages-part-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[226]:https://www.class-central.com/mooc/8199/edx-how-to-code-complex-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[227]:https://www.class-central.com/mooc/5592/coursera-running-product-design-sprints?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[228]:https://www.class-central.com/mooc/5446/coursera-java-for-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[229]:https://www.class-central.com/mooc/8888/coursera-server-side-development-with-nodejs-express-and-mongodb?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[230]:https://www.class-central.com/mooc/6991/edx-cyber-security-economics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[231]:https://www.class-central.com/mooc/5497/coursera-web-application-development-basic-concepts?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[232]:https://www.class-central.com/mooc/5752/edx-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[233]:https://www.class-central.com/mooc/2964/edx-android-introduccion-a-la-programacion?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[234]:https://www.class-central.com/mooc/9219/coursera-service-oriented-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[235]:https://www.class-central.com/mooc/9215/coursera-design-patterns?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[236]:https://www.class-central.com/mooc/6584/coursera-cybersecurity-and-mobility?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[237]:https://www.class-central.com/mooc/8614/coursera-google-cloud-platform-fundamentals-for-aws-professionals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[238]:https://www.class-central.com/mooc/7342/udacity-android-basics-user-interface?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[239]:https://www.class-central.com/mooc/6275/udacity-scalable-microservices-with-kubernetes?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[240]:https://www.class-central.com/mooc/2215/udacity-developing-scalable-apps-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[241]:https://www.class-central.com/mooc/3455/udacity-android-performance?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[242]:https://www.class-central.com/mooc/7279/udacity-android-basics-button-clicks?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[243]:https://www.class-central.com/mooc/3584/udacity-gradle-for-android-and-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[244]:https://www.class-central.com/mooc/7463/udacity-vr-software-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[245]:https://www.class-central.com/mooc/3525/udacity-developing-scalable-apps-in-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[246]:https://www.class-central.com/mooc/3581/udacity-material-design-for-android-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[247]:https://www.class-central.com/mooc/7590/edx-intermediate-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[248]:https://www.class-central.com/mooc/8823/edx-introduction-to-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[249]:https://www.class-central.com/mooc/7384/edx-angularjs-advanced-framework-techniques?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[250]:https://www.class-central.com/mooc/6511/edx-principles-of-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[251]:https://www.class-central.com/mooc/8002/edx-asynchronous-programming-with-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[252]:https://www.class-central.com/mooc/8025/coursera-build-a-modern-computer-from-first-principles-nand-to-tetris-part-ii-project-centered-course?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[253]:https://www.class-central.com/mooc/6040/coursera-a-developer-s-guide-to-the-internet-of-things-iot?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[254]:https://www.class-central.com/mooc/6000/edx-introduction-to-cloud-infrastructure-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[255]:https://www.class-central.com/mooc/4856/udacity-2d-game-development-with-libgdx?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[256]:https://www.class-central.com/mooc/4990/edx-introduction-to-real-time-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[257]:https://www.class-central.com/mooc/3984/nptel-design-and-analysis-of-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[258]:https://www.class-central.com/mooc/6300/edx-how-to-win-coding-competitions-secrets-of-champions?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[259]:https://www.class-central.com/mooc/4671/edx-html5-apps-and-games?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[260]:https://www.class-central.com/mooc/6143/udacity-technical-interview?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[261]:https://www.class-central.com/mooc/6956/udacity-android-basics-data-storage?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[262]:https://www.class-central.com/mooc/455/udacity-intro-to-theoretical-computer-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[263]:https://www.class-central.com/mooc/8984/stanford-openedx-algorithms-design-and-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[264]:https://www.class-central.com/mooc/7351/coursera-shortest-paths-revisited-np-complete-problems-and-what-to-do-about-them?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[265]:https://www.class-central.com/mooc/7840/edx-mobile-application-experiences?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[266]:https://www.class-central.com/mooc/6475/edx-advanced-software-construction-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[267]:https://www.class-central.com/mooc/5633/edx-mobile-application-experiences-part-3-building-mobile-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[268]:https://www.class-central.com/mooc/8520/edx-algorithm-design-and-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[269]:https://www.class-central.com/mooc/8517/edx-data-structures-and-software-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[270]:https://www.class-central.com/mooc/6420/coursera-introduction-to-neurohacking-in-r?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[271]:https://www.class-central.com/mooc/8994/edx-database-systems-concepts-and-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[272]:https://www.class-central.com/mooc/8568/udacity-software-analysis-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[273]:https://www.class-central.com/mooc/9797/coursera-writing-running-and-fixing-code-in-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[274]:https://www.class-central.com/mooc/7242/edx-animation-and-cgi-motion?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[275]:https://www.class-central.com/mooc/7480/edx-minecraft-coding-and-teaching?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[276]:https://www.class-central.com/mooc/4182/coursera-internet-of-things-sensing-and-actuation-from-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[277]:https://www.class-central.com/mooc/8514/edx-how-virtual-reality-vr-works?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[278]:https://www.class-central.com/mooc/8515/edx-creating-virtual-reality-vr-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[279]:https://www.class-central.com/mooc/8653/edx-building-a-cybersecurity-toolkit?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[280]:https://www.class-central.com/mooc/8652/edx-cybersecurity-the-ciso-s-view?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[281]:https://www.class-central.com/mooc/6235/coursera-build-your-own-ios-app?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[282]:https://www.class-central.com/mooc/3230/coursera--design-and-analysis-of-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[283]:https://www.class-central.com/mooc/1737/coursera--the-advanced-object-oriented-technology?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[284]:https://www.class-central.com/mooc/3464/edx-how-to-code-systematic-program-design-part-3?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[285]:https://www.class-central.com/mooc/3466/edx-how-to-code-systematic-program-design-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[286]:https://www.class-central.com/mooc/8200/edx-software-construction-data-abstraction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[287]:https://www.class-central.com/mooc/8201/edx-software-construction-object-oriented-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[288]:https://www.class-central.com/mooc/6523/coursera-testing-with-agile?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[289]:https://www.class-central.com/mooc/9725/coursera-sql-for-data-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[290]:https://www.class-central.com/mooc/7852/edx-laff-on-programming-for-correctness?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[291]:https://www.class-central.com/mooc/8684/coursera-multiplatform-mobile-app-development-with-nativescript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[292]:https://www.class-central.com/mooc/8681/coursera-front-end-javascript-frameworks-angular?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[293]:https://www.class-central.com/mooc/8683/coursera-multiplatform-mobile-app-development-with-web-technologies-ionic-and-cordova?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[294]:https://www.class-central.com/mooc/8687/coursera-developing-android-apps-with-app-inventor?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[295]:https://www.class-central.com/mooc/8682/coursera-front-end-web-ui-frameworks-and-tools-bootstrap-4?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[296]:https://www.class-central.com/mooc/9119/edx-globally-distributed-software-engineering?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[297]:https://www.class-central.com/mooc/10071/coursera----c--?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[298]:https://www.class-central.com/mooc/7785/coursera-building-arduino-robots-and-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[299]:https://www.class-central.com/mooc/5753/edx-implementation-of-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[300]:https://www.class-central.com/mooc/5755/edx-foundations-of-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[301]:https://www.class-central.com/mooc/7346/edx-professional-android-app-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[302]:https://www.class-central.com/mooc/7346/edx-professional-android-app-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[303]:https://www.class-central.com/mooc/4812/edx-the-software-architect-code-building-the-digital-world?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[304]:https://www.class-central.com/mooc/7454/edx-introduction-to-java-programming-fundamental-data-structures-and-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[305]:https://www.class-central.com/mooc/6304/edx-enterprise-software-lifecycle-management?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[306]:https://www.class-central.com/mooc/10036/coursera--------?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[307]:https://www.class-central.com/mooc/9811/coursera-requirements-elicitation-artifact-and-stakeholder-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[308]:https://www.class-central.com/mooc/9319/coursera-linux-server-management-and-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[309]:https://www.class-central.com/mooc/9807/coursera-requirements-specifications-goals-and-conflict-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[310]:https://www.class-central.com/mooc/9810/coursera-software-requirements-prioritization-risk-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[311]:https://www.class-central.com/mooc/8820/coursera-homeland-security-cybersecurity-connection-it-s-not-about-the-terrorists?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[312]:https://www.class-central.com/mooc/9808/coursera-srs-documents-requirements-and-diagrammatic-notations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[313]:https://www.class-central.com/mooc/9809/coursera-requirements-gathering-for-secure-software-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[314]:https://www.class-central.com/mooc/8171/edx-software-testing-management?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[315]:https://www.class-central.com/mooc/8168/edx-cloud-computing-for-enterprises?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[316]:https://www.class-central.com/mooc/8181/edx-cloud-computing-infrastructure?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[317]:https://www.class-central.com/mooc/8180/edx-formal-software-verification?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[318]:https://www.class-central.com/mooc/8179/edx-software-testing-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[319]:https://www.class-central.com/mooc/8172/edx-cloud-computing-management?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[320]:https://www.class-central.com/mooc/7391/edx-introduction-to-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[321]:https://www.class-central.com/mooc/6657/edx-gameplay-programming-for-video-game-designers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[322]:https://www.class-central.com/mooc/6658/edx-teamwork-collaboration?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[323]:https://www.class-central.com/mooc/7415/coursera-web-connectivity-and-security-in-embedded-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[324]:https://www.class-central.com/mooc/6839/coursera-architecting-smart-iot-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[325]:https://www.class-central.com/mooc/6748/coursera-introduction-to-architecting-smart-iot-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[326]:https://www.class-central.com/mooc/6585/coursera-cybersecurity-and-the-x-factor?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[327]:https://www.class-central.com/mooc/6548/udacity-intro-to-progressive-web-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[328]:https://www.class-central.com/mooc/3580/udacity-advanced-android-app-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[329]:https://www.class-central.com/mooc/6477/udacity-google-maps-apis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[330]:https://www.class-central.com/mooc/5679/udacity-offline-web-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[331]:https://www.class-central.com/mooc/5055/udacity-firebase-essentials-for-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[332]:https://www.class-central.com/mooc/6357/edx-developing-intelligent-apps-and-bots?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[333]:https://www.class-central.com/mooc/7405/edx-developing-sql-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[334]:https://www.class-central.com/mooc/8722/edx-building-functional-prototypes-using-node-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[335]:https://www.class-central.com/mooc/8719/edx-building-interactive-prototypes-using-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[336]:https://www.class-central.com/mooc/8937/edx-algorithms-and-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[337]:https://www.class-central.com/mooc/9483/edx-algorithms-and-data-structures-in-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[338]:https://www.class-central.com/mooc/7401/edx-creating-programmatic-sql-database-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[339]:https://www.class-central.com/mooc/7377/edx-angularjs-framework-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[340]:https://www.class-central.com/mooc/8633/edx-introduction-to-typescript-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[341]:https://www.class-central.com/mooc/7208/edx-advanced-css-concepts?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[342]:https://www.class-central.com/mooc/7399/edx-implementing-in-memory-sql-database-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[343]:https://www.class-central.com/mooc/7398/edx-optimizing-performance-for-sql-based-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[344]:https://www.class-central.com/mooc/8369/edx-programmation-concurrente-avec-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[345]:https://www.class-central.com/mooc/6931/coursera-c-for-c-programmers-part-b?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[346]:https://www.class-central.com/mooc/8764/edx-introduction-to-kubernetes?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[347]:https://www.class-central.com/mooc/7506/edx-introduction-to-devops-transforming-and-improving-operations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[348]:https://www.class-central.com/mooc/7506/edx-introduction-to-devops-transforming-and-improving-operations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[349]:https://www.class-central.com/mooc/7837/edx-uml-class-diagrams-for-software-engineering?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[350]:https://www.class-central.com/mooc/9701/udacity-mobile-usability-and-design-for-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[351]:https://www.class-central.com/mooc/9700/udacity-mobile-usability-and-design-for-ios?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[352]:https://www.class-central.com/mooc/6493/concurrency?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[353]:https://www.class-central.com/mooc/8670/edx-fundamentals-of-red-hat-enterprise-linux?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[354]:https://www.class-central.com/mooc/9105/edx-fundamentals-of-containers-kubernetes-and-red-hat-openshift?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[355]:https://www.class-central.com/mooc/8839/udacity-c-for-programmers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[356]:https://www.class-central.com/mooc/4071/udacity-learn-backbone-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[357]:https://www.class-central.com/mooc/4419/udacity-how-to-create-anything-in-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[358]:https://www.class-central.com/mooc/3527/udacity-how-to-make-an-ios-app?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[359]:https://www.class-central.com/mooc/3526/udacity-ios-persistence-and-core-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[360]:https://www.class-central.com/mooc/3350/udacity-uikit-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[361]:https://www.class-central.com/mooc/3393/udacity-ios-networking-with-swift?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[362]:https://www.class-central.com/mooc/4887/udacity-designing-restful-apis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[363]:https://www.class-central.com/mooc/8422/udacity-vr-platforms-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[364]:https://www.class-central.com/mooc/7495/udacity-swift-for-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[365]:https://www.class-central.com/mooc/6797/udacity-the-mvc-pattern-in-ruby?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[366]:https://www.class-central.com/mooc/6798/udacity-deploying-applications-with-heroku?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[367]:https://www.class-central.com/mooc/6796/udacity-dynamic-web-applications-with-sinatra?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[368]:https://www.class-central.com/mooc/7753/udacity-building-ios-interfaces?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[369]:https://www.class-central.com/mooc/8394/udacity-vr-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[370]:https://www.class-central.com/mooc/7755/udacity-new-android-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[371]:https://www.class-central.com/mooc/7754/udacity-ios-design-patterns?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[372]:https://www.class-central.com/mooc/7380/udacity-vr-scenes-and-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[373]:https://www.class-central.com/mooc/6679/kadenze-creative-applications-of-deep-learning-with-tensorflow?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[374]:https://www.class-central.com/mooc/10029/nptel-an-introduction-to-probability-in-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[375]:https://www.class-central.com/mooc/9913/nptel-information-security-iv?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[376]:https://www.class-central.com/mooc/10094/nptel-matlab-programming-for-numerical-computation?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[377]:https://www.class-central.com/mooc/10051/nptel-digital-switching-i?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[378]:https://www.class-central.com/mooc/9817/nptel-advanced-graph-theory?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[379]:https://www.class-central.com/mooc/9608/coursera-deep-learning-in-computer-vision?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[380]:https://www.class-central.com/mooc/9603/coursera-natural-language-processing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[381]:https://www.class-central.com/mooc/9924/coursera-practical-reinforcement-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[382]:https://www.class-central.com/mooc/9848/nptel-real-time-operating-system?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[383]:https://www.class-central.com/mooc/10066/nptel-traditional-and-non-traditional-optimization-tools?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[384]:https://www.class-central.com/mooc/10088/nptel-basics-of-software-defined-radios-and-practical-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[385]:https://www.class-central.com/mooc/9135/edx-sparse-representations-in-image-processing-from-theory-to-practice?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[386]:https://www.class-central.com/mooc/301/udacity-introduction-to-artificial-intelligence?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[387]:https://www.class-central.com/mooc/398/coursera-neural-networks-for-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[388]:https://www.class-central.com/mooc/4912/edx-machine-learning-for-data-science-and-analytics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[389]:https://www.class-central.com/mooc/1026/udacity-machine-learning-for-trading?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[390]:https://www.class-central.com/mooc/9058/coursera-neural-networks-and-deep-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[391]:https://www.class-central.com/mooc/7230/edx-artificial-intelligence-ai?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[392]:https://www.class-central.com/mooc/449/coursera-computational-neuroscience?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[393]:https://www.class-central.com/mooc/1022/udacity-introduction-to-computer-vision?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[394]:https://www.class-central.com/mooc/1849/udacity-reinforcement-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[395]:https://www.class-central.com/mooc/549/udacity-intro-to-parallel-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[396]:https://www.class-central.com/mooc/552/udacity-interactive-3d-graphics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[397]:https://www.class-central.com/mooc/1020/udacity-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[398]:https://www.class-central.com/mooc/4911/edx-enabling-technologies-for-data-science-and-analytics-the-internet-of-things?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[399]:https://www.class-central.com/mooc/326/udacity-applied-cryptography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[400]:https://www.class-central.com/mooc/7887/practical-deep-learning-for-coders-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[401]:https://www.class-central.com/mooc/1016/udacity-advanced-operating-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[402]:https://www.class-central.com/mooc/7231/edx-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[403]:https://www.class-central.com/mooc/642/introduction-to-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[404]:https://www.class-central.com/mooc/7292/coursera-probabilistic-graphical-models-2-inference?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[405]:https://www.class-central.com/mooc/6673/coursera-applied-machine-learning-in-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[406]:https://www.class-central.com/mooc/4864/coursera-quantitative-formal-modeling-and-worst-case-performance-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[407]:https://www.class-central.com/mooc/8083/6-s191-introduction-to-deep-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[408]:https://www.class-central.com/mooc/3419/udacity-introduction-to-operating-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[409]:https://www.class-central.com/mooc/6927/coursera-nearest-neighbor-collaborative-filtering?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[410]:https://www.class-central.com/mooc/8132/6-s094-deep-learning-for-self-driving-cars?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[411]:https://www.class-central.com/mooc/1018/udacity-high-performance-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[412]:https://www.class-central.com/mooc/1024/udacity-computability-complexity-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[413]:https://www.class-central.com/mooc/1023/udacity-computational-photography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[414]:https://www.class-central.com/mooc/3420/udacity-intro-to-information-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[415]:https://www.class-central.com/mooc/1025/udacity-knowledge-based-ai-cognitive-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[416]:https://www.class-central.com/mooc/6826/coursera-embedded-hardware-and-operating-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[417]:https://www.class-central.com/mooc/8480/learn-tensorflow-and-deep-learning-without-a-ph-d?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[418]:https://www.class-central.com/mooc/9475/edx-devops-practices-and-principles?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[419]:https://www.class-central.com/mooc/9133/edx-sparse-representations-in-signal-and-image-processing-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[420]:https://www.class-central.com/mooc/8387/edx-introduction-to-cloud-foundry-and-cloud-native-software-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[421]:https://www.class-central.com/mooc/9484/edx-blockchain-for-business-an-introduction-to-hyperledger-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[422]:https://www.class-central.com/mooc/6245/edx-computation-structures-3-computer-organization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[423]:https://www.class-central.com/mooc/4734/udacity-gt-refresher-advanced-os?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[424]:https://www.class-central.com/mooc/1028/udacity-high-performance-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[425]:https://www.class-central.com/mooc/8572/udacity-compilers-theory-and-practice?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[426]:https://www.class-central.com/mooc/8569/udacity-cyber-physical-systems-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[427]:https://www.class-central.com/mooc/8570/udacity-network-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[428]:https://www.class-central.com/mooc/8565/udacity-artificial-intelligence?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[429]:https://www.class-central.com/mooc/8123/coursera-information-security-context-and-introduction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[430]:https://www.class-central.com/mooc/7757/coursera-advanced-modeling-for-discrete-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[431]:https://www.class-central.com/mooc/7759/coursera-basic-modeling-for-discrete-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[432]:https://www.class-central.com/mooc/6881/edx-nature-in-code-biology-in-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[433]:https://www.class-central.com/mooc/6933/coursera-matrix-factorization-and-advanced-techniques?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[434]:https://www.class-central.com/mooc/6825/coursera-system-validation-automata-and-behavioural-equivalences?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[435]:https://www.class-central.com/mooc/7420/coursera-system-validation-2-model-process-behaviour?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[436]:https://www.class-central.com/mooc/7803/coursera-system-validation-4-modelling-software-protocols-and-other-behaviour?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[437]:https://www.class-central.com/mooc/9479/edx-devops-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[438]:https://www.class-central.com/mooc/8746/edx-deep-learning-explained?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[439]:https://www.class-central.com/mooc/9164/edx-introduction-to-artificial-intelligence-ai?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[440]:https://www.class-central.com/mooc/9480/edx-devops-for-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[441]:https://www.class-central.com/mooc/9476/edx-infrastructure-as-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[442]:https://www.class-central.com/mooc/8097/deep-learning-for-natural-language-processing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[443]:https://www.class-central.com/mooc/8509/statistical-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[444]:https://www.class-central.com/mooc/9791/coursera-cyber-physical-systems-modeling-and-simulation?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[445]:https://www.class-central.com/mooc/7202/edx-introduction-to-openstack?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[446]:https://www.class-central.com/mooc/7046/edx-computer-system-design-advanced-concepts-of-modern-microprocessors?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[447]:https://www.class-central.com/mooc/6603/edx-reliable-distributed-algorithms-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[448]:https://www.class-central.com/mooc/8481/deep-learning-summer-school?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[449]:https://www.class-central.com/mooc/8021/udacity-continuous-integration-and-deployment?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 -[450]:https://www.class-central.com/ -[451]:https://www.class-central.com/subject/cs -[452]:https://www.class-central.com/subject/data-science -[453]:https://www.class-central.com/subject/programming-and-software-development -[454]:https://medium.com/@davidventuri -[455]:https://medium.freecodecamp.com/the-best-data-science-courses-on-the-internet-ranked-by-your-reviews-6dc5b910ea40 -[456]:https://medium.freecodecamp.org/how-to-sign-up-for-coursera-courses-for-free-98266efaa531 diff --git a/translated/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md b/translated/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md new file mode 100644 index 0000000000..653ee599e4 --- /dev/null +++ b/translated/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md @@ -0,0 +1,1147 @@ +2 月份开始你可以去学习的 440 多个免费的编程&计算机科学的在线课程 +============================================================ + +![](https://cdn-images-1.medium.com/max/1250/1*c28Ze3oxasgGMGaV7-qoFw.png) + +六年前,一些大学如 MIT 和斯坦福首次向公共免费开放了他们的在线课程。现在,全世界超过 800 所学校已经创建了成千上万的免费课程。 + +我编制了一个有 440 多个免费在线课程的清单,你可以从这个月开始去学习它了。为了这个清单,我利用了一个超过 9000 课程的 [班级中心][450] 的数据库。也包括了每个课程的平均评分。 + + +![](https://cdn-images-1.medium.com/max/1250/1*qc6pW2c3mjTHVo45iCJaaQ.png) +[班级中心][1] 的主页 + +按它们不同的级别,我将这些课程分成以下三类: + +* 初级 + +* 中级 + +* 高级 + +对于首次出现的课程,我标记为 [NEW]。 + +这些课程中的大多数都是可以自学的。其余的将在二月份的某个时间为你奉上。2018 年,在班级中心的[计算机科学][451]、[数据科学][452]、和 [编程][453] 主题的页面上,你可以找到与这个技术相关的完整的清单。 + +我也知道,这个长长的清单,可能会让学习编程的新手望而却步。在这些课程中,你可以找到 [David Venturi][454] 推荐的非常有用的最佳 [数据科学在线课程][455]  —  即使你不想学习数据科学。以后,我想去创建更多的这种指南。 + +最后,如果你不知道如何去注册这些免费课程,没关系 —— 我也写了一篇 [如何去注册][456] 的文章。 + +### 初级(112) + +* [Python 交互式编程入门(第 1 部分)][2] 来自 _Rice University_  ★★★★★(3018) + +* [计算机科学入门和使用 Python 编程][3] 来自  _Massachusetts Institute of Technology_  ★★★★★(115) + +* [学习编程:基本原理][4] 来自  _University of Toronto_ ★★★★★(100) + +* [计算机科学入门][5] 来自  _University of Virginia_  ★★★★☆(68) + +* [CS50 的计算机科学入门][6] 来自  _Harvard University_ ★★★★★(65) + +* [Python 交互式编程入门(第 2 部分)][7] 来自  _Rice University_  ★★★★★(52) + +* [如何使用 Git 和 GitHub][8] + +* [Linux 入门][9] 来自  _Linux Foundation_  ★★★★☆(37) + +* [因特网历史、技术、和安全][10] 来自  _University of Michigan_ ★★★★★(36) + +* [HTML 和 CSS 入门][11] + +* [VBA/Excel 编程入门][12] 来自  _Cal Poly Pomona_ ★★★★☆(26) + +* [[New] CS50 的理解技术][13] 来自  _Harvard University_ + +* [[New] CS50 的为商务人士的计算机科学][14] 来自  _Harvard University_ + +* [[New] Introducción a la programación en Java: cómo comenzar a programar][15] 来自  _Universidad Carlos iii de Madrid_ + +* [[New] 物联网 (IoT) 入门][16] 来自  _Curtin University_ + +* [[New] 使用 Git 管理版本][17] 来自  _Atlassian_ + +* [JavaScript 基础][18] + +* [CS101: 计算机科学 101][19] 来自  _Stanford University_  ★★★★☆(15) + +* [编程基础][20] 来自  _Indian Institute of Technology Bombay_ ★★☆☆☆(13) + +* [Web 安全基本原理][21] 来自  _KU Leuven University_  ★★★★☆(12) + +* [Python 编程基础][22] + +* [网络:计算机网络入门][23] 来自  _Stanford University_  ★★★★★(11) + +* [DB:数据库入门][24] 来自  _Stanford University_  ★★★★★(11) + +* [数字多媒体&移动应用创意编程][25] 来自  _University of London International Programmes_  ★★★★☆(10) + +* [使用 JavaScript、HTML 和 CSS 基础][26] 来自  _Duke University_  ★★★★☆(9) + +* [实用安全][27] 来自  _University of Maryland, College Park_  ★★★☆☆(9) + +* [Bootstrap 入门 — 一个教程][28] 来自  _Microsoft_  ★★★☆☆(9) + +* [HTML5 编码基础和最佳实践][29] 来自  _World Wide Web Consortium (W3C)_  ★★★★☆(9) + +* [大家都来学 Python  —  浏览信息][30] + +* [学习编程:编写高品质代码][31] 来自  _University of Toronto_ ★★★★☆(7) + +* [使用 p5.js 为视觉艺术编程入门][32] 来自  _University of California, Los Angeles_  ★★★★★(7) + +* [关系型数据库入门][33] + +* [jQuery 入门][34] 来自  _Microsoft_  ★★★★☆(5) + +* [HTML5 和 CSS 基础][35] 来自  _World Wide Web Consortium (W3C)_ ★★★★☆(5) + +* [Java 编程基础][36] + +* [Linux 命令行基础][37] + +* [Java 编程入门 — 第 1 部分][38] 来自  _The Hong Kong University of Science and Technology_  ★★★★☆(4) + +* [Java 编程入门:在 Java 中写代码][39] 来自  _Universidad Carlos iii de Madrid_  ★★★★☆(4) + +* [计算机编程范例 — 抽象和并发][40]来自  _Université catholique de Louvain_  ★★★★☆(4) + +* [计算机编程范例 — 基本原理][41] 来自  _Université catholique de Louvain_  ★★★★★(4) + +* [在 Scratch 中编程][42] 来自  _Harvey Mudd College_  ★★★★★(4) + +* [使用 JavaScript 的 Web 编程][43] 来自  _University of Pennsylvania_ ★★★★★(2) + +* [计算的美与乐 — AP® CS 原理 第 1 部分][44] 来自  _University of California, Berkeley_  ★★★★★(2) + +* [Python 计算入门][45] 来自  _Georgia Institute of Technology_  ★★★★★(2) + +* [面向对象的编程][46] 来自  _Indian Institute of Technology Bombay_ ★★★★☆(2) + +* [思维. 创新. 代码][47] 来自  _University of Adelaide_  ★★★★★(2) + +* [智能手机中的计算技术][48] 来自  _Cornell University_  ★★★★★(2) + +* [Android 基础:编写你的第一个 App][49] 来自  _Google_  ★★★★☆(2) + +* [学习 Python 编程][50] 来自  _University of Texas Arlington_ ★★★★★(2) + +* [HTML 和 JavaScript 入门][51] 来自  _Microsoft_  ★★★★★(2) + +* [大众计算机科学:计算机科学和 Python 编程入门][52]来自  _Harvey Mudd College_  ★★★★★(2) + +* [JavaScript 入门][53] + +* [Android 新手入门][54] + +* [网络:友好,金钱,和字节][55] 来自  _Princeton University_ ★★★☆☆(1) + +* [如何编码:数据基础][56] 来自  _The University of British Columbia_ ★★★★★(1) + +* [使用 Wordpress 开发和设计 Web][57] 来自  _California Institute of the Arts_  ★★★★☆(1) + +* [Android App 新手开发指南][58] 来自  _Galileo University_ ★☆☆☆☆(1) + +* [Android App 新手开发指南][59] 来自  _Galileo University_ ★☆☆☆☆(1) + +* [艺术家的 Web 编码基础][60] 来自  _National University of Singapore_  ★★★★☆(1) + +* [ReactJS 入门][61] 来自  _Microsoft_  ★★☆☆☆(1) + +* [Node.js 入门][62] 来自  _Microsoft_  ★★★★★(1) + +* [学习 Java 编程][63] 来自  _Microsoft_  ★★★★★(1) + +* [计算:艺术、魔术、科学][64] 来自  _ETH Zurich_  ★★★★☆(1) + +* [Cyber 安全:居家安全、在线、生活][65] 来自  _Newcastle University_ ★★★☆☆(1) + +* [软件工程师基础][66] 来自  _Technische Universität München (Technical University of Munich)_  ★★★★★(1) + +* [我的计算机科学: 计算机科学新手指南][67] 来自  _Harvey Mudd College_ ★★★☆☆(1) + +* [使用 Git 管理版本][68] + +* [大众 Web 应用][69] + +* [CS50’s AP® 计算机科学原理][70] 来自  _Harvard University_ + +* [编程基础][71] 来自  _Duke University_ + +* [Cyber 安全入门][72] 来自  _University of Washington_ + +* [Python 表示数据][73] 来自  _Rice University_ + +* [Python 编程基础][74] 来自  _Rice University_ + +* [软件工程师:入门][75] 来自  _The University of British Columbia_ + +* [Web 开发入门][76] 来自  _University of California, Davis_ + +* [Java 编程入门 — 第 2 部分][77] 来自  _The Hong Kong University of Science and Technology_ + +* [Excel/VBA 解决创意问题, 第 2 部分][78] 来自  _University of Colorado Boulder_ + +* [Excel/VBA 解决创意问题,第 2 部分][79] 来自  _University of Colorado Boulder_ + +* [AP 计算机科学 A:Java 编程的多态和高级数据结构][80] 来自  _Purdue University_ + +* [AP 计算机科学 A:Java 编程的循环和数据结构][81]来自  _Purdue University_ + +* [AP 计算机科学 A:Java 编程的类和对象][82] 来自  _Purdue University_ + +* [Android 开发的 Java 基础][83] 来自  _Galileo University_ + +* [很赚钱的 Android Apps 所使用的商业模式][84] 来自  _Galileo University_ + +* [很赚钱的 Android Apps 所使用的商业模式][85] 来自  _Galileo University_ + +* [Android 开发的 Java 基础][86] 来自  _Galileo University_ + +* [Java 编程入门:写出好代码][87] 来自  _Universidad Carlos iii de Madrid_ + +* [Cyber 安全基础:动手实践][88] 来自  _Universidad Carlos iii de Madrid_ + +* [业务深度学习][89] 来自  _Yonsei University_ + +* [TCP/IP 入门][90] 来自  _Yonsei University_ + +* [视频游戏设计和平衡][91] 来自  _Rochester Institute of Technology_ + +* [Web 易用性][92] 来自  _Google_ + +* [移动 Web 开发][93] 来自  _Google_ + +* [Python 编程入门][94] 来自  _University of Texas Arlington_ + +* [Python 入门:从零开始][95] 来自  _Microsoft_ + +* [Python:基础][96] 来自  _Microsoft_ + +* [设计思想入门][97] 来自  _Microsoft_ + +* [逻辑和计算思维][98] 来自  _Microsoft_ + +* [像专家一样写代码][99] 来自  _Microsoft_ + +* [Java 中的面向对象编程][100] 来自  _Microsoft_ + +* [CSS 基础 来自  _Microsoft_ + +* [计算:艺术、魔术、科学 — 第 2 部分][102] 来自  _ETH Zurich_ + +* [JavaScript 入门][103] 来自  _World Wide Web Consortium (W3C)_ + +* [Python 的面向对象编程:创建你自己的冒险游戏][104] 来自  _Raspberry Pi Foundation_ + +* [学习 Swift 编程语法][105] + +* [JavaScript 和 DOM][106] + +* [能源行业中的区块链][107] 来自  _InnoEnergy_ + +* [虚拟现实入门][108] + +* [ES6 — 改善后的 JavaScript][109] + +* [Python 入门][110] + +* [HTTP & Web 服务器][111] + +* [GitHub & 合作][112] + +* [Swift 新手指南][113] + +### 中级(259) + +* [机器学习][114] 来自  _Stanford University_  ★★★★★(325) +* [算法,第 1 部分][115] 来自  _Princeton University_  ★★★★★(58) +* [为音乐家和艺术家的机器学习][116] 来自  _Goldsmiths, University of London_  ★★★★★(57) +* [密码学 I][117] 来自  _Stanford University_  ★★★★★(49) +* [CS188.1x:人工智能][118] 来自  _University of California, Berkeley_ ★★★★★(30) +* [计算的原理(第 1 部分)][119] 来自  _Rice University_  ★★★★★(29) +* [[New] 算法设计和技术][120] 来自  _University of California, San Diego_ +* [软件安全][121]来自  _University of Maryland, College Park_ ★★★★☆(25) +* [[New] 柔性计算入门][122] 来自  _Indian Institute of Technology, Kharagpur_ +* [[New] 云计算][123] 来自  _Indian Institute of Technology, Kharagpur_ +* [[New] 数据库管理系统][124] 来自  _Indian Institute of Technology, Kharagpur_ +* [[New] Haskell 编程入门][125] 来自  _Chennai Mathematical Institute_ +* [算法,第 II 部分][126] 来自  _Princeton University_  ★★★★★(21) +* [越来越容易的专业 Web 易访问性审计][127] 来自  _Chang School of Continuing Education_  ★★★★★(21) +* [在 Rails 上使用 Ruby 进行敏捷开发 — 基础篇][128] 来自  _University of California, Berkeley_  ★★★★★(19) +* [自动化理论][129] 来自  _Stanford University_  ★★★★☆(18) +* [机器学习入门][130] 来自  _Stanford University_  ★★★★☆(18) +* [Web 开发][131] +* [计算原理(第 2 部分)][132] 来自  _Rice University_  ★★★★☆(16) +* [Android 开发新手指南][133] 来自  _Google_  ★★★★☆(16) +* [C 程序员学习 C++,Part A][134] 来自  _University of California, Santa Cruz_ ★★★☆☆(16) +* [代码的本质][135] 来自  _Processing Foundation_  ★★★★★(16) +* [游戏开发的概念][136] 来自  _Swinburne University of Technology_ ★★★★☆(15) +* [算法的思想(第 1 部分)][137] 来自  _Rice University_  ★★★★☆(14) +* [计算机程序的设计][138] 来自  _Stanford University_  ★★★★☆(13) +* [Java 编程:用软件解决问题][139] 来自  _Duke University_ ★★★☆☆(13) +* [Web 响应设计][140] 来自  _University of London International Programmes_  ★★★★☆(12) +* [离散优化][141] 来自  _University of Melbourne_  ★★★★☆(12) +* [游戏开发入门][142] 来自  _Michigan State University_ ★★★★★(12) +* [函数式编程入门][143] 来自  _Delft University of Technology_  ★★★★☆(11) +* [开发 Android Apps][144] 来自  _Google_  ★★★☆☆(11) +* [面向对象的 JavaScript][145] 来自  _Hack Reactor_  ★★★★★(11) +* [编程语言][146] 来自  _University of Virginia_  ★★★☆☆(10) +* [算法的思想(第 2 部分)][147] 来自  _Rice University_  ★★★★☆(9) +* [Web 响应设计基础][148] 来自  _Google_  ★★★★★(9) +* [图像和视频处理:从火星到好莱坞而止于医院][149] 来自  _Duke University_  ★★★★☆(8) +* [密码学][150] 来自  _University of Maryland, College Park_  ★★★★☆(8) +* [密码学][151] 来自  _University of Maryland, College Park_  ★★★★☆(8) +* [学习数据(机器学习入门)][152] 来自  _California Institute of Technology_  ★★★★★(8) +* [Julia 科学编程][153] 来自  _University of Cape Town_  ★★★★★(8) +* [云计算应用程序,第 1 部分:云系统和基础设施][154]来自  _University of Illinois at Urbana-Champaign_  ★★★☆☆(7) +* [Swift 编程入门][155] 来自  _University of Toronto_ ★☆☆☆☆(7) +* [Software 测试][156] 来自  _University of Utah_  ★★★★☆(7) +* [使用 MongoDB 管理数据][157] 来自  _MongoDB University_  ★★★★☆(7) +* [AJAX 入门][158] +* [计算机架构][159] 来自  _Princeton University_  ★★★★☆(6) +* [物联网:我们如何用它?][160] 来自  _University of California, San Diego _ ★★☆☆☆(6) +* [Meteor.js 开发入门][161]来自  _University of London International Programmes_  ★★★★☆(6) +* [如何编码:系统化程序设计 — 第 1 部分][162] 来自  _The University of British Columbia_  ★★★★☆(6) +* [DevOps 入门][163] 来自  _Nutanix_  ★★★☆☆(6) +* [全栈基础][164] +* [算法入门][165] +* [Java 中的软件架构][166] 来自  _Massachusetts Institute of Technology_ ★★★★★(5) +* [在 Rails 上使用 Ruby 进行敏捷开发  —  高级篇][167] 来自  _University of California, Berkeley_  ★★★★★(5) +* [计算机图形][168] 来自  _University of California, Berkeley_  ★★★★☆(5) +* [软件开发过程][169] 来自  _Georgia Institute of Technology_ ★★★★☆(5) +* [计算机网络][170] 来自  _Georgia Institute of Technology_  ★★★★☆(5) +* [Java 编程:数组、列表、和数据结构][171] 来自  _Duke University_  ★★★★★(5) +* [云计算概念:第 2 部分][172] 来自  _University of Illinois at Urbana-Champaign_  ★★★★★(5) +* [HTML5 游戏开发][173] 来自  _Google_  ★★★☆☆(5) +* [C++ 入门][174] 来自  _Microsoft_  ★★★★☆(5) +* [软件调试][175] 来自  _Saarland University_  ★★★★★(5) +* [并行编程概念][176] +* [使用 Swift 开发 iOS App 入门][177] +* [物联网:配置你的 DragonBoard™ 开发平台][178]来自  _University of California, San Diego _ ★★★☆☆(4) +* [物联网 & 增强现实新技术][179] 来自  _Yonsei University_  ★★★☆☆(4) +* [Database 管理基础][180] 来自  _University of Colorado System_ ★★★★☆(4) +* [Web 网络性能优化][181] 来自  _Google_  ★★★★☆(4) +* [移动开发者的 UX 设计][182] 来自  _Google_  ★★★★★(4) +* [使用 Transact-SQL 查询数据][183] 来自  _Microsoft_  ★★★★☆(4) +* [计算机图形交互][184] 来自  _The University of Tokyo_  ★★☆☆☆(4) +* [jQuery 入门][185] +* [将 Python 用于研究][186] 来自  _Harvard University_  ★★★☆☆(3) +* [图解网络:无需微积分][187] 来自  _Princeton University_ ★★★★☆(3) +* [VLSI CAD 第 I 部分:逻辑][188] 来自  _University of Illinois at Urbana-Champaign_ ★★★★★(3) +* [物联网:通讯技术][189] 来自  _University of California, San Diego _ ★★★☆☆(3) +* [MATLAB 和 Octave 的新手指南][190] 来自  _École Polytechnique Fédérale de Lausanne_  ★★★☆☆(3) +* [无线通讯新技术][191] 来自  _Yonsei University_ ★★★★☆(3) +* [JavaScript Promises][192] 来自  _Google_  ★★★★★(3) +* [Android 基础:多屏 Apps][193] 来自  _Google_  ★★★★☆(3) +* [Android 基础:用户输入][194] 来自  _Google_  ★★★★☆(3) +* [DevOps:开发者如何入门][195] 来自  _Microsoft_  ★★★★☆(3) +* [自主移动机器人][196] 来自  _ETH Zurich_  ★★★☆☆(3) +* [敏捷软件开发][197] 来自  _ETH Zurich_  ★★★★☆(3) +* [JavaScript 调试][198] +* [配置 Linux Web 服务器][199] +* [JavaScript 设计模式][200] +* [编译器][201] 来自  _Stanford University_  ★★★★☆(2) +* [LPL: 语言,验证和逻辑][202] 来自  _Stanford University_  ★★★★★(2) +* [移动应用程序体验(第 1 部分):从一个领域到一个应用程序创意][203]来自  _Massachusetts Institute of Technology_  ★★★★★(2) +* [机器学习:自主学习][204] 来自  _Brown University_ ★★★★★(2) +* [编程语言,Part B][205] 来自  _University of Washington_ ★★★★★(2) +* [响应式 Web 网站教程和示例][206] 来自  _University of London International Programmes_  ★★★★★(2) +* [iOS App 开发基础][207] 来自  _University of Toronto_  ★★★★☆(2) +* [编程、数据结构和算法][208] 来自  _Indian Institute of Technology Madras_  ★★☆☆☆(2) +* [Android App 组件 — 服务、本地 IPC、以及内容提供者][209]来自  _Vanderbilt University_  ★★★☆☆(2) +* [Android App 组件 — Intents、Activities、和广播接收器][210]来自  _Vanderbilt University_  ★★★☆☆(2) +* [Android 移动应用程序开发入门][211] 来自  _The Hong Kong University of Science and Technology_  ★★★★☆(2) +* [因特网新兴技术][212] 来自  _Yonsei University_  ★★★☆☆(2) +* [面向对象的设计][213] 来自  _University of Alberta_  ★★★☆☆(2) +* [Android 基础:网络][214] 来自  _Google_  ★★★★☆(2) +* [浏览器底层优化][215] 来自  _Google_  ★★★★☆(2) +* [Google 云平台基础:核心基础设施][216] 来自  _Google_ ★★★★☆(2) +* [客户端-服务器通讯][217] 来自  _Google_  ★★★★★(2) +* [开发国际化软件,第 1 部分][218] 来自  _Microsoft_  ★★★★☆(2) +* [使用 Power BI 分析和可视化数据][219] 来自  _Microsoft_ ★★★★★(2) +* [Web 开发者之网络][220] +* [计算结构2:计算机架构][221] 来自  _Massachusetts Institute of Technology_  ★★★★☆(1) +* [软件开发基础][222] 来自  _University of Pennsylvania_ ★★★☆☆(1) +* [软件架构与设计][223] 来自  _Georgia Institute of Technology_ ★★★★★(1) +* [数据库系统概念与设计][224] 来自  _Georgia Institute of Technology_ ★★★★☆(1) +* [编程语言,Part C][225] 来自  _University of Washington_ ★★★★★(1) +* [如何编码:复杂数据][226] 来自  _The University of British Columbia_ ★★★★★(1) +* [产品设计冲刺][227] 来自  _University of Virginia_  ★★★☆☆(1) +* [Android 之 Java][228] 来自  _Vanderbilt University_  ★☆☆☆☆(1) +* [使用 NodeJS、Express 和 MongoDB 进行服务器侧开发][229] 来自  _The Hong Kong University of Science and Technology_  ★★★★★(1) +* [Cyber 安全经济][230] 来自  _Delft University of Technology_ ★★☆☆☆(1) +* [Web 应用程序开发:基本概念][231] 来自  _University of New Mexico_  ★★★★☆(1) +* [算法][232] 来自  _Indian Institute of Technology Bombay_  ★★★★★(1) +* [Android:Introducción a la Programación][233] 来自  _Universitat Politècnica de València_  ★★★★☆(1) +* [面向服务的架构][234] 来自  _University of Alberta_  ★★★★★(1) +* 设计模式][235] 来自  _University of Alberta_  ★☆☆☆☆(1) +* [Cybersecurity 和便捷性][236] 来自  _University System of Georgia_ ★☆☆☆☆(1) +* [Google 云平台基础之 AWS 安全专家篇][237] 来自  _Google Cloud_  ★★☆☆☆(1) +* [Android 基础:用户界面][238] 来自  _Google_  ★★☆☆☆(1) +* [使用 Kubernetes 的弹性微服务][239] 来自  _Google_  ★★★★☆(1) +* [用 Java 开发弹性应用程序][240] 来自  _Google_  ★★★★☆(1) +* [Android 性能][241] 来自  _Google_  ★★★★★(1) +* [Android 基础:点击按钮][242] 来自  _Google_  ★★★☆☆(1) +* [Android 和 Java 的 Gradle][243] 来自  _Google_  ★★★★★(1) +* [VR 软件开发][244] 来自  _Google_  ★★★★☆(1) +* [用 Python 开发弹性应用程序][245] 来自  _Google_  ★★★★☆(1) +* [Android 开发者的内容设计][246] 来自  _Google_  ★★★★★(1) +* [中级 C++][247] 来自  _Microsoft_  ★★★★☆(1) +* [C# 入门][248] 来自  _Microsoft_  ★★☆☆☆(1) +* [AngularJS:高级框架技术][249] 来自  _Microsoft_ ★★★★☆(1) +* [机器学习原理][250] 来自  _Microsoft_  ★★★★★(1) +* [Javascript 异步编程][251] 来自  _Microsoft_ ★★★★★(1) +* [从第一原则构建现代化计算机:Nand 到 Tetris 第 II 部分(以项目为中心的课程)][252] 来自  _Hebrew University of Jerusalem_ ★★★★★(1) +* [物联网开发者指南][253] 来自  _IBM_ ★★★★☆(1) +* [云基础设施技术入门][254] 来自  _Linux Foundation_ ★★★★☆(1) +* [使用 libGDX 开发 2D 游戏][255] 来自  _Amazon_  ★★★★★(1) +* [实时系统入门][256] 来自  _IEEE_  ★★★★☆(1) +* [算法设计与分析][257] 来自  _Chennai Mathematical Institute_ ★★★☆☆(1) +* [如何赢得编码比赛:冠军的秘密][258] 来自  _ITMO University_  ★★★☆☆(1) +* [HTML5 应用程序和游戏][259] 来自  _World Wide Web Consortium (W3C)_ ★★★☆☆(1) +* [面试技术][260] 来自  _Pramp_  ★★★★★(1) +* [Android 基础:数据存储][261] +* [计算机科学理论入门][262] +* [算法:设计与分析][263] 来自  _Stanford University_ +* [最短路径回访、完整 NP 问题以及如何实现][264] 来自  _Stanford University_ +* [移动应用程序体验][265] 来自  _Massachusetts Institute of Technology_ +* [Java 中的高级软件结构][266] 来自  _Massachusetts Institute of Technology_ +* [移动应用程序体验 第 3 部分:构建移动应用程序][267] 来自  _Massachusetts Institute of Technology_ +* [算法设计与分析][268] 来自  _University of Pennsylvania_ +* [数据结构与软件设计][269] 来自  _University of Pennsylvania_ +* [R 中的 Neurohacking 入门][270] 来自  _Johns Hopkins University_ +* [数据库系统概念与设计][271] 来自  _Georgia Institute of Technology_ +* [软件分析与测试][272] 来自  _Georgia Institute of Technology_ +* [在 C 中编写、运行和修复代码][273] 来自  _Duke University_ +* [动画和 CGI 手势][274] 来自  _Columbia University_ +* [Minecraft、编码和测试][275] 来自  _University of California, San Diego_ +* [物联网:来自设备的传感和驱动][276] 来自  _University of California, San Diego_ +* [虚拟现实如何工作][277] 来自  _University of California, San Diego_ +* [创建虚拟现实应用程序][278] 来自  _University of California, San Diego_ +* [构建一个Cybersecurity 工具箱][279] 来自  _University of Washington_ +* [Cybersecurity: The CISO’s View][280] 来自  _University of Washington_ +* [构建你自己的 iOS App][281] 来自  _University of Toronto_ +* [算法设计与分析][282] 来自  _Peking University_ +* [面向对象技术高级课程][283]来自  _Peking University_ +* [如何编码:系统化程序设计 — Part 3][284] 来自  _The University of British Columbia_ +* [如何编码:系统化程序设计 — Part 2][285] 来自  _The University of British Columbia_ +* [软件结构:数据抽象][286] 来自  _The University of British Columbia_ +* [软件结构:面向对象的设计][287] 来自  _The University of British Columbia_ +* [敏捷测试][288] 来自  _University of Virginia_ +* [数据科学中的 SQL][289] 来自  _University of California, Davis_ +* [LAFF — 正确编程][290] 来自  _The University of Texas at Austin_ +* [使用 NativeScript 进行跨平台移动 App 开发][291] 来自  _The Hong Kong University of Science and Technology_ +* [前后端 JavaScript 框架:Angular][292] 来自  _The Hong Kong University of Science and Technology_ +* [使用 Web 技术开发跨平台移动 App:Ionic 和 Cordova][293] 来自  _The Hong Kong University of Science and Technology_ +* [使用 App Inventor 开发 Android Apps][294] 来自  _The Hong Kong University of Science and Technology_ +* [前后端 Web UI 框架和工具:Bootstrap 4][295] 来自  _The Hong Kong University of Science and Technology_ +* [全球软件发布引擎][296] 来自  _Delft University of Technology_ +* [Основы разработки на C++: жёлтый пояс][297] 来自  _Moscow Institute of Physics and Technology_ +* [构建机器人和设备][298] 来自  _Moscow Institute of Physics and Technology_ +* [数据结构实现][299] 来自  _Indian Institute of Technology Bombay_ +* [数据结构基础][300] 来自  _Indian Institute of Technology Bombay_ +* [专业 Android App 开发][301] 来自  _Galileo University_ +* [专业 Android App 开发][302] 来自  _Galileo University_ +* [软件架构师代码:构建数字世界][303] 来自  _Universidad Carlos iii de Madrid_ +* [Java 编程入门:数据结构和算法基础][304] 来自  _Universidad Carlos iii de Madrid_ +* [企业软件生命周期管理][305] 来自  _National Research Nuclear University MEPhI_ +* [Использование механизмов операционных систем в разработке программного обеспечения][306] 来自  _National Research Nuclear University MEPhI_ +* [需求获取:加工和利益相关者分析][307] 来自  _University of Colorado System_ +* [Linux 服务器管理与安全性][308] 来自  _University of Colorado System_ +* [特殊需求:目标和冲突分析][309] 来自  _University of Colorado System_ +* [软件需求优先级:风险分析][310] 来自  _University of Colorado System_ +* [国家安全与 Cybersecurity 的联系 — 它是恐怖主义者的公证人][311] 来自  _University of Colorado System_ +* [SRS 文档:需求与图解][312] 来自  _University of Colorado System_ +* [安全软件开发的需求收集][313] 来自  _University of Colorado System_ +* [软件测试管理][314] 来自  _University System of Maryland_ +* [企业云计算][315] 来自  _University System of Maryland_ +* [云计算基础设施][316] 来自  _University System of Maryland_ +* [软件验证形式][317] 来自  _University System of Maryland_ +* [软件测试基础][318] 来自  _University System of Maryland_ +* [云计算管理][319] 来自  _University System of Maryland_ +* [数据结构入门][320] 来自  _University of Adelaide_ +* [视频游戏设计者的 Gameplay 编程][321] 来自  _Rochester Institute of Technology_ +* [团队工作与协作][322] 来自  _Rochester Institute of Technology_ +* [嵌入式系统的 Web 连接与安全][323] 来自  _EIT Digital_ +* [物联网设备的智能架构][324] 来自  _EIT Digital_ +* [物联网智能架构入门][325] 来自  _EIT Digital_ +* [Cybersecurity 和 X-Factor][326] 来自  _University System of Georgia_ +* [循序渐进介绍 Web 应用程序][327] 来自  _Google_ +* [高级 Android 应用程序开发][328] 来自  _Google_ +* [Google 地图 APIs][329] 来自  _Google_ +* [离线 Web 应用程序][330] 来自  _Google_ +* [Android 的 Firebase 基础][331] 来自  _Google_ +* [开发聪明的 Apps 和机器人][332] 来自  _Microsoft_ +* [开发 SQL 数据库][333] 来自  _Microsoft_ +* [使用 Node.js 构建功能原型][334] 来自  _Microsoft_ +* [使用 JavaScript 构建交互原型][335] 来自  _Microsoft_ +* [算法和数据结构][336] 来自  _Microsoft_ +* [在 C# 中的算法和数据结构][337] 来自  _Microsoft_ +* [创建系统化的 SQL 数据库对象][338] 来自  _Microsoft_ +* [AngularJS:框架基础][339] 来自  _Microsoft_ +* [TypeScript 2 入门][340] 来自  _Microsoft_ +* [高级 CSS 概念][341] 来自  _Microsoft_ +* [实现 In-Memory SQL 数据库对象][342] 来自  _Microsoft_ +* [优化基于 SQL 的应用程序][343] 来自  _Microsoft_ +* [并发编程 (avec Java)][344] 来自  _Sorbonne Universités_ +* [C 程序员学习 C++,Part B][345] 来自  _University of California, Santa Cruz_ +* [Kubernetes 入门][346] 来自  _Linux Foundation_ +* [DevOps 入门:转变和改善运营][347] 来自  _Linux Foundation_ +* [DevOps 入门:转变和改善运营][348] 来自  _Linux Foundation_ +* [软件工程师的 UML 类示意图][349] 来自  _KU Leuven University_ +* [Android 的移动适用性与设计][350] 来自  _Facebook_ +* [IOS 的移动适用性与设计][351] 来自  _Facebook_ +* [并发][352] 来自  _AdaCore University_ +* [Red Hat 企业 Linux 基础][353] 来自  _Red Hat_ +* [Containers 基础、Kubernetes、和 Red Hat OpenShift][354] 来自  _Red Hat_ +* [程序员的 C++][355] +* [学习 Backbone.js][356] +* [如何在 Android 中创建][357] +* [如何制作一个 iOS App][358] +* [iOS 持久化与核心数据][359] +* [UIKit 基础][360] +* [使用 Swift 实现 iOS 网络][361] +* [设计 RESTful APIs][362] +* [VR 平台与应用程序][363] +* [为开发者的 Swift 语言][364] +* [Ruby 中的 MVC 模式][365] +* [使用 Heroku 部署应用程序][366] +* [使用 Sinatra 开发动态 Web 应用程序][367] +* [构建 iOS 界面][368] +* [VR 设计][369] +* [[New] Android 基础][370] +* [iOS 设计模式][371] +* [VR 场景与对象][372] + +### 高级(78) + +* [使用 TensorFlow 深度学习创新应用程序][373] + +* [[New] 计算中的概率入门][374] 来自  _Indian Institute of Technology Madras_ + +* [[New] 信息安全 — IV][375] 来自  _Indian Institute of Technology Madras_ + +* [[New] 数学计算的 Matlab 编程][376] 来自  _Indian Institute of Technology Madras_ + +* [[New] 数字开头 — I][377] 来自  _Indian Institute of Technology Kanpur_ + +* [[New] 高级图形理论][378] 来自  _Indian Institute of Technology Kanpur_ + +* [[New] 计算机视觉中的深度学习][379] 来自  _Higher School of Economics_ + +* [[New] 自然语言处理][380] 来自  _Higher School of Economics_ + +* [[New] 实践强化学习][381] 来自  _Higher School of Economics_ + +* [[New] 实时操作系统][382] 来自  _Indian Institute of Technology, Kharagpur_ + +* [[New] 传统的和非传统的优化工具][383] 来自  _Indian Institute of Technology, Kharagpur_ + +* [[New] 软件定义无线与实际应用程序][384] 来自  _Indian Institute of Technology Roorkee_ + +* [[New] 图像处理中的稀疏表示:从理论到实践][385] 来自  _Technion — Israel Institute of Technology_ + +* [人工智能入门][386] 来自  _Stanford University_ ★★★★☆(24) + +* [机器学习之神经网络][387] 来自  _University of Toronto_ ★★★★☆(22) + +* [机器学习之数据科学与分析][388] 来自  _Columbia University_ ★★★☆☆(15) + +* [机器学习之交易][389] 来自  _Georgia Institute of Technology_ ★★★☆☆(13) + +* [神经网络与深度学习][390] 来自  _deeplearning.ai_  ★★★★★(9) + +* [人工智能(AI)][391] 来自  _Columbia University_  ★★★★☆(9) + +* [计算神经科学][392] 来自  _University of Washington_  ★★★★☆(8) + +* [计算机视觉入门][393] 来自  _Georgia Institute of Technology_ ★★★★★(6) + +* [强化学习][394] 来自  _Brown University_  ★★☆☆☆(6) + +* [并行编程入门][395] 来自  _Nvidia_  ★★★★☆(6) + +* [互动 3D 图形][396] 来自  _Autodesk_  ★★★★☆(6) + +* 机器学习][397] 来自  _Georgia Institute of Technology_  ★★★★★(5) + +* [数据科学与分析的可用技术:物联网][398] 来自  _Columbia University_  ★☆☆☆☆(5) + +* [应用密码学][399] 来自  _University of Virginia_  ★★★★☆(5) + +* [开发者的深度学习实践:第 1 部分][400] 来自  _fast.ai_  ★★★★☆(5) + +* [高级操作系统][401] 来自  _Georgia Institute of Technology_ ★★★★★(4) + +* [机器学习][402] 来自  _Columbia University_  ★★★★★(4) + +* [计算机架构入门][403] 来自  _Carnegie Mellon University_ ★★★★★(4) + +* [概率图形模型 2:推测][404] 来自  _Stanford University_ ★★★★☆(3) + +* [Python 中应用机器学习][405] 来自  _University of Michigan_ ★★★★☆(3) + +* [定量形式模型与最坏性能分析][406] 来自  _EIT Digital _ ★★★☆☆(3) + +* [6.S191:深度学习入门][407] 来自  _Massachusetts Institute of Technology_  ★★★★☆(2) + +* [操作系统入门][408] 来自  _Georgia Institute of Technology_ ★★★★★(2) + +* [近场合作过滤器][409] 来自  _University of Minnesota_ ★★☆☆☆(2) + +* [6.S094:汽车自动驾驶之深度学习][410] 来自  _Massachusetts Institute of Technology_  ★★★★☆(1) + +* [高性能计算架构][411] 来自  _Georgia Institute of Technology_  ★★★★★(1) + +* [可计算性、复杂性和算法][412] 来自  _Georgia Institute of Technology_  ★★★★★(1) + +* [计算摄影学][413] 来自  _Georgia Institute of Technology_ ★★★★☆(1) + +* [信息安全入门][414] 来自  _Georgia Institute of Technology_ ★☆☆☆☆(1) + +* [AI 知识库:认知系统][415] 来自  _Georgia Institute of Technology_  ★★★☆☆(1) + +* [嵌入式硬件和操作系统][416] 来自  _EIT Digital _ ★☆☆☆☆(1) + +* [学习 TensorFlow 与深度学习][417] 来自  _Google_ ★★★★☆(1) + +* [DevOps 实践和原则][418] 来自  _Microsoft_  ★★☆☆☆(1) + +* [信号与图像处理中的稀疏表示:基础][419]来自  _Technion — Israel Institute of Technology_  ★★★★★(1) + +* [云计算和云原生软件架构入门][420]来自  _Linux Foundation_  ★★★★★(1) + +* [商业应用区块链 — Hyperledger 技术][421]来自  _Linux Foundation_  ★★★★☆(1) + +* [计算结构 3:计算机组织][422] 来自  _Massachusetts Institute of Technology_ + +* [GT — Refresher — Advanced OS][423] 来自  _Georgia Institute of Technology_ + +* [高性能计算][424] 来自  _Georgia Institute of Technology_ + +* [编译器:理论与实践][425] 来自  _Georgia Institute of Technology_ + +* [Cyber-物理系统安全][426] 来自  _Georgia Institute of Technology_ + +* [网络安全][427] 来自  _Georgia Institute of Technology_ + +* [人工智能][428] 来自  _Georgia Institute of Technology_ + +* [信息安全:环境与入门][429] 来自  _University of London International Programmes_ + +* [离散优化之高级模型][430] 来自  _University of Melbourne_ + +* [离散优化之基本模型][431] 来自  _University of Melbourne_ + +* [代码的本质:JavaScript 中的生物学][432] 来自  _École Polytechnique Fédérale de Lausanne_ + +* [模型因子与高级技术][433] 来自  _University of Minnesota_ + +* [系统验证:自动化与等价行为][434] 来自  _EIT Digital_ + +* [系统验证(2):建模过程行为][435] 来自  _EIT Digital_ + +* [系统验证(4):软件模型、协议和其它行为][436] 来自  _EIT Digital_ + +* [DevOps 测试][437] 来自  _Microsoft_ + +* [深度学习说明][438] 来自  _Microsoft_ + +* [人工智能入门][439] 来自  _Microsoft_ + +* [DevOps 之数据库][440] 来自  _Microsoft_ + +* [基础设施代码化][441] 来自  _Microsoft_ + +* [深度学习之自然语言处理][442] 来自  _University of Oxford_ + +* [机器学习之统计学][443] 来自  _Carnegie Mellon University_ + +* [信息物理系统:建模与仿真][444] 来自  _University of California, Santa Cruz_ + +* [OpenStack 入门][445] 来自  _Linux Foundation_ + +* [计算机系统设计:现代微处理器的高级概念][446]来自  _Chalmers University of Technology_ + +* [可靠的分布式算法,第 2 部分][447] 来自  _KTH Royal Institute of Technology_ + +* [深度学习暑期课程][448] + +* [持续集成与部署][449] + +-------------------------------------------------------------------------------- + +作者简介: + +www.class-central.com  — 最流行的在线课程搜索引擎的创始人 + +---- + + +via: https://medium.freecodecamp.org/440-free-online-programming-computer-science-courses-you-can-start-in-february-e075f920cb5b + +作者:[Dhawal Shah ][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://medium.freecodecamp.org/@dhawalhs +[1]:https://www.class-central.com/ +[2]:https://www.class-central.com/mooc/408/coursera-an-introduction-to-interactive-programming-in-python-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[3]:https://www.class-central.com/mooc/1341/edx-introduction-to-computer-science-and-programming-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[4]:https://www.class-central.com/mooc/385/coursera-learn-to-program-the-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[5]:https://www.class-central.com/mooc/320/udacity-intro-to-computer-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[6]:https://www.class-central.com/mooc/442/edx-cs50-s-introduction-to-computer-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[7]:https://www.class-central.com/mooc/3196/coursera-an-introduction-to-interactive-programming-in-python-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[8]:https://www.class-central.com/mooc/2661/udacity-how-to-use-git-and-github?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[9]:https://www.class-central.com/mooc/1857/edx-introduction-to-linux?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[10]:https://www.class-central.com/mooc/335/coursera-internet-history-technology-and-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[11]:https://www.class-central.com/mooc/2659/udacity-intro-to-html-and-css?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[12]:https://www.class-central.com/mooc/1797/open-education-by-blackboard-introduction-to-vba-excel-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[13]:https://www.class-central.com/mooc/10142/edx-cs50-s-understanding-technology?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[14]:https://www.class-central.com/mooc/10143/edx-cs50-s-computer-science-for-business-professionals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[15]:https://www.class-central.com/mooc/10316/edx-introduccion-a-la-programacion-en-java-como-comenzar-a-programar?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[16]:https://www.class-central.com/mooc/9750/edx-introduction-to-the-internet-of-things-iot?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[17]:https://www.class-central.com/mooc/10166/coursera-version-control-with-git?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[18]:https://www.class-central.com/mooc/2660/udacity-javascript-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[19]:https://www.class-central.com/mooc/2175/stanford-openedx-cs101-computer-science-101?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[20]:https://www.class-central.com/mooc/1650/edx-programming-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[21]:https://www.class-central.com/mooc/8726/edx-web-security-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[22]:https://www.class-central.com/mooc/2013/udacity-programming-foundations-with-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[23]:https://www.class-central.com/mooc/1578/stanford-openedx-networking-introduction-to-computer-networking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[24]:https://www.class-central.com/mooc/1580/stanford-openedx-db-introduction-to-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[25]:https://www.class-central.com/mooc/529/coursera-creative-programming-for-digital-media-mobile-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[26]:https://www.class-central.com/mooc/4256/coursera-programming-foundations-with-javascript-html-and-css?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[27]:https://www.class-central.com/mooc/1727/coursera-usable-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[28]:https://www.class-central.com/mooc/3338/edx-introduction-to-bootstrap-a-tutorial?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[29]:https://www.class-central.com/mooc/3444/edx-html5-coding-essentials-and-best-practices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[30]:https://www.class-central.com/mooc/7363/python-for-everybody-exploring-information?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[31]:https://www.class-central.com/mooc/390/coursera-learn-to-program-crafting-quality-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[32]:https://www.class-central.com/mooc/3770/kadenze-introduction-to-programming-for-the-visual-arts-with-p5-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[33]:https://www.class-central.com/mooc/3253/udacity-intro-to-relational-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[34]:https://www.class-central.com/mooc/4062/edx-introduction-to-jquery?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[35]:https://www.class-central.com/mooc/5764/edx-html5-and-css-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[36]:https://www.class-central.com/mooc/6686/udacity-java-programming-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[37]:https://www.class-central.com/mooc/4049/udacity-linux-command-line-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[38]:https://www.class-central.com/mooc/1983/edx-introduction-to-java-programming-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[39]:https://www.class-central.com/mooc/2813/edx-introduction-to-java-programming-starting-to-code-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[40]:https://www.class-central.com/mooc/2630/edx-paradigms-of-computer-programming-abstraction-and-concurrency?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[41]:https://www.class-central.com/mooc/2298/edx-paradigms-of-computer-programming-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[42]:https://www.class-central.com/mooc/2954/edx-programming-in-scratch?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[43]:https://www.class-central.com/mooc/8518/edx-programming-for-the-web-with-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[44]:https://www.class-central.com/mooc/2525/edx-the-beauty-and-joy-of-computing-ap-cs-principles-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[45]:https://www.class-central.com/mooc/7622/edx-introduction-to-computing-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[46]:https://www.class-central.com/mooc/1651/edx-object-oriented-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[47]:https://www.class-central.com/mooc/3231/edx-think-create-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[48]:https://www.class-central.com/mooc/2809/edx-the-computing-technology-inside-your-smartphone?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[49]:https://www.class-central.com/mooc/7278/udacity-android-basics-make-your-first-app?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[50]:https://www.class-central.com/mooc/3695/edx-learn-to-program-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[51]:https://www.class-central.com/mooc/5923/edx-introduction-to-html-and-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[52]:https://www.class-central.com/mooc/3483/edx-cs-for-all-introduction-to-computer-science-and-python-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[53]:https://www.class-central.com/mooc/8059/udacity-intro-to-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[54]:https://www.class-central.com/mooc/7623/udacity-android-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[55]:https://www.class-central.com/mooc/359/coursera-networks-friends-money-and-bytes?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[56]:https://www.class-central.com/mooc/8202/edx-how-to-code-simple-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[57]:https://www.class-central.com/mooc/6408/kadenze-web-development-and-design-using-wordpress?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[58]:https://www.class-central.com/mooc/7315/edx-android-app-development-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[59]:https://www.class-central.com/mooc/7315/edx-android-app-development-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[60]:https://www.class-central.com/mooc/3781/kadenze-web-coding-fundamentals-for-artists?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[61]:https://www.class-central.com/mooc/8770/edx-introduction-to-reactjs?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[62]:https://www.class-central.com/mooc/9597/edx-introduction-to-node-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[63]:https://www.class-central.com/mooc/8718/edx-learn-to-program-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[64]:https://www.class-central.com/mooc/2195/edx-computing-art-magic-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[65]:https://www.class-central.com/mooc/6265/futurelearn-cyber-security-safety-at-home-online-in-life?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[66]:https://www.class-central.com/mooc/8527/edx-software-engineering-essentials?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[67]:https://www.class-central.com/mooc/2957/edx-mycs-computer-science-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[68]:https://www.class-central.com/mooc/8430/udacity-version-control-with-git?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[69]:https://www.class-central.com/mooc/7362/web-applications-for-everybody?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[70]:https://www.class-central.com/mooc/7017/edx-cs50-s-ap-computer-science-principles?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[71]:https://www.class-central.com/mooc/9574/coursera-programming-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[72]:https://www.class-central.com/mooc/8651/edx-introduction-to-cybersecurity?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[73]:https://www.class-central.com/mooc/9550/coursera-python-data-representations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[74]:https://www.class-central.com/mooc/9549/coursera-python-programming-essentials?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[75]:https://www.class-central.com/mooc/8205/edx-software-engineering-introduction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[76]:https://www.class-central.com/mooc/7027/coursera-introduction-to-web-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[77]:https://www.class-central.com/mooc/3486/edx-introduction-to-java-programming-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[78]:https://www.class-central.com/mooc/9943/coursera-excel-vba-for-creative-problem-solving-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[79]:https://www.class-central.com/mooc/9943/coursera-excel-vba-for-creative-problem-solving-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[80]:https://www.class-central.com/mooc/7219/edx-ap-computer-science-a-java-programming-polymorphism-and-advanced-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[81]:https://www.class-central.com/mooc/7212/edx-ap-computer-science-a-java-programming-loops-and-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[82]:https://www.class-central.com/mooc/7211/edx-ap-computer-science-a-java-programming-classes-and-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[83]:https://www.class-central.com/mooc/7313/edx-java-fundamentals-for-android-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[84]:https://www.class-central.com/mooc/7345/edx-monetize-android-apps-with-business-models?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[85]:https://www.class-central.com/mooc/7345/edx-monetize-android-apps-with-business-models?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[86]:https://www.class-central.com/mooc/7313/edx-java-fundamentals-for-android-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[87]:https://www.class-central.com/mooc/5735/edx-introduction-to-java-programming-writing-good-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[88]:https://www.class-central.com/mooc/7849/edx-cyber-security-basics-a-hands-on-approach?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[89]:https://www.class-central.com/mooc/9431/coursera-deep-learning-for-business?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[90]:https://www.class-central.com/mooc/9143/coursera-introduction-to-tcp-ip?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[91]:https://www.class-central.com/mooc/6660/edx-video-game-design-and-balance?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[92]:https://www.class-central.com/mooc/6531/udacity-web-accessibility?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[93]:https://www.class-central.com/mooc/1046/udacity-mobile-web-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[94]:https://www.class-central.com/mooc/10134/edx-introduction-to-programming-using-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[95]:https://www.class-central.com/mooc/8671/edx-introduction-to-python-absolute-beginner?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[96]:https://www.class-central.com/mooc/8650/edx-introduction-to-python-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[97]:https://www.class-central.com/mooc/8845/edx-introduction-to-design-thinking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[98]:https://www.class-central.com/mooc/8725/edx-logic-and-computational-thinking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[99]:https://www.class-central.com/mooc/8808/edx-writing-professional-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[100]:https://www.class-central.com/mooc/8723/edx-object-oriented-programming-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[101]:https://www.class-central.com/mooc/7199/edx-css-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[102]:https://www.class-central.com/mooc/4084/edx-computing-art-magic-science-part-ii?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[103]:https://www.class-central.com/mooc/8496/edx-javascript-introduction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[104]:https://www.class-central.com/mooc/8884/futurelearn-object-oriented-programming-in-python-create-your-own-adventure-game?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[105]:https://www.class-central.com/mooc/3925/udacity-learn-swift-programming-syntax?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[106]:https://www.class-central.com/mooc/9990/udacity-javascript-and-the-dom?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[107]:https://www.class-central.com/mooc/9526/futurelearn-blockchain-in-the-energy-sector?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[108]:https://www.class-central.com/mooc/7379/udacity-introduction-to-virtual-reality?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[109]:https://www.class-central.com/mooc/8543/udacity-es6-javascript-improved?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[110]:https://www.class-central.com/mooc/8577/udacity-introduction-to-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[111]:https://www.class-central.com/mooc/8374/udacity-http-web-servers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[112]:https://www.class-central.com/mooc/8542/udacity-github-collaboration?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[113]:https://www.class-central.com/mooc/7494/udacity-swift-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[114]:https://www.class-central.com/mooc/835/coursera-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[115]:https://www.class-central.com/mooc/339/coursera-algorithms-part-i?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[116]:https://www.class-central.com/mooc/3768/kadenze-machine-learning-for-musicians-and-artists?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[117]:https://www.class-central.com/mooc/616/coursera-cryptography-i?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[118]:https://www.class-central.com/mooc/445/edx-cs188-1x-artificial-intelligence?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[119]:https://www.class-central.com/mooc/1724/coursera-principles-of-computing-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[120]:https://www.class-central.com/mooc/10241/edx-algorithmic-design-and-techniques?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[121]:https://www.class-central.com/mooc/1728/coursera-software-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[122]:https://www.class-central.com/mooc/10053/nptel-introduction-to-soft-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[123]:https://www.class-central.com/mooc/10027/nptel-cloud-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[124]:https://www.class-central.com/mooc/9914/nptel-database-management-system?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[125]:https://www.class-central.com/mooc/10044/nptel-introduction-to-haskell-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[126]:https://www.class-central.com/mooc/340/coursera-algorithms-part-ii?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[127]:https://www.class-central.com/mooc/5174/canvas-network-professional-web-accessibility-auditing-made-easy?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[128]:https://www.class-central.com/mooc/443/edx-agile-development-using-ruby-on-rails-the-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[129]:https://www.class-central.com/mooc/376/stanford-openedx-automata-theory?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[130]:https://www.class-central.com/mooc/2996/udacity-intro-to-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[131]:https://www.class-central.com/mooc/324/udacity-web-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[132]:https://www.class-central.com/mooc/3198/coursera-principles-of-computing-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[133]:https://www.class-central.com/mooc/3579/udacity-android-development-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[134]:https://www.class-central.com/mooc/671/coursera-c-for-c-programmers-part-a?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[135]:https://www.class-central.com/mooc/3777/kadenze-the-nature-of-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[136]:https://www.class-central.com/mooc/1176/open2study-concepts-in-game-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[137]:https://www.class-central.com/mooc/1725/coursera-algorithmic-thinking-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[138]:https://www.class-central.com/mooc/323/udacity-design-of-computer-programs?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[139]:https://www.class-central.com/mooc/4305/coursera-java-programming-solving-problems-with-software?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[140]:https://www.class-central.com/mooc/4200/coursera-responsive-web-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[141]:https://www.class-central.com/mooc/487/coursera-discrete-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[142]:https://www.class-central.com/mooc/4275/coursera-introduction-to-game-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[143]:https://www.class-central.com/mooc/2147/edx-introduction-to-functional-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[144]:https://www.class-central.com/mooc/2211/udacity-developing-android-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[145]:https://www.class-central.com/mooc/2658/udacity-object-oriented-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[146]:https://www.class-central.com/mooc/325/udacity-programming-languages?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[147]:https://www.class-central.com/mooc/3200/coursera-algorithmic-thinking-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[148]:https://www.class-central.com/mooc/3255/udacity-responsive-web-design-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[149]:https://www.class-central.com/mooc/462/coursera-image-and-video-processing-from-mars-to-hollywood-with-a-stop-at-the-hospital?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[150]:https://www.class-central.com/mooc/1730/coursera-cryptography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[151]:https://www.class-central.com/mooc/1730/coursera-cryptography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[152]:https://www.class-central.com/mooc/366/learning-from-data-introductory-machine-learning-course?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[153]:https://www.class-central.com/mooc/7092/coursera-julia-scientific-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[154]:https://www.class-central.com/mooc/2738/coursera-cloud-computing-applications-part-1-cloud-systems-and-infrastructure?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[155]:https://www.class-central.com/mooc/4248/coursera-introduction-to-swift-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[156]:https://www.class-central.com/mooc/365/udacity-software-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[157]:https://www.class-central.com/mooc/1479/udacity-data-wrangling-with-mongodb?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[158]:https://www.class-central.com/mooc/2997/udacity-intro-to-ajax?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[159]:https://www.class-central.com/mooc/342/coursera-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[160]:https://www.class-central.com/mooc/4276/coursera-internet-of-things-how-did-we-get-here?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[161]:https://www.class-central.com/mooc/4328/coursera-introduction-to-meteor-js-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[162]:https://www.class-central.com/mooc/3465/edx-how-to-code-systematic-program-design-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[163]:https://www.class-central.com/mooc/4013/udacity-intro-to-devops?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[164]:https://www.class-central.com/mooc/3254/udacity-full-stack-foundations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[165]:https://www.class-central.com/mooc/364/udacity-intro-to-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[166]:https://www.class-central.com/mooc/6469/edx-software-construction-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[167]:https://www.class-central.com/mooc/558/edx-agile-development-using-ruby-on-rails-advanced?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[168]:https://www.class-central.com/mooc/548/edx-computer-graphics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[169]:https://www.class-central.com/mooc/2335/udacity-software-development-process?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[170]:https://www.class-central.com/mooc/2336/udacity-computer-networking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[171]:https://www.class-central.com/mooc/4362/coursera-java-programming-arrays-lists-and-structured-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[172]:https://www.class-central.com/mooc/2942/coursera-cloud-computing-concepts-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[173]:https://www.class-central.com/mooc/551/udacity-html5-game-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[174]:https://www.class-central.com/mooc/4758/edx-introduction-to-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[175]:https://www.class-central.com/mooc/457/udacity-software-debugging?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[176]:https://www.class-central.com/mooc/1701/openhpi-parallel-programming-concepts?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[177]:https://www.class-central.com/mooc/2861/udacity-intro-to-ios-app-development-with-swift?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[178]:https://www.class-central.com/mooc/4260/coursera-internet-of-things-setting-up-your-dragonboard-development-platform?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[179]:https://www.class-central.com/mooc/3934/coursera-internet-of-things-augmented-reality-emerging-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[180]:https://www.class-central.com/mooc/4337/coursera-database-management-essentials?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[181]:https://www.class-central.com/mooc/2189/udacity-website-performance-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[182]:https://www.class-central.com/mooc/2212/udacity-ux-design-for-mobile-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[183]:https://www.class-central.com/mooc/3341/edx-querying-data-with-transact-sql?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[184]:https://www.class-central.com/mooc/2067/coursera-interactive-computer-graphics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[185]:https://www.class-central.com/mooc/2998/udacity-intro-to-jquery?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[186]:https://www.class-central.com/mooc/7204/edx-using-python-for-research?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[187]:https://www.class-central.com/mooc/891/coursera-networks-illustrated-principles-without-calculus?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[188]:https://www.class-central.com/mooc/428/coursera-vlsi-cad-part-i-logic?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[189]:https://www.class-central.com/mooc/4173/coursera-internet-of-things-communication-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[190]:https://www.class-central.com/mooc/7376/edx-matlab-and-octave-for-beginners?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[191]:https://www.class-central.com/mooc/3936/coursera-wireless-communication-emerging-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[192]:https://www.class-central.com/mooc/5680/udacity-javascript-promises?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[193]:https://www.class-central.com/mooc/6549/udacity-android-basics-multiscreen-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[194]:https://www.class-central.com/mooc/7343/udacity-android-basics-user-input?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[195]:https://www.class-central.com/mooc/6333/edx-devops-for-developers-how-to-get-started?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[196]:https://www.class-central.com/mooc/1564/edx-autonomous-mobile-robots?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[197]:https://www.class-central.com/mooc/6878/edx-agile-software-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[198]:https://www.class-central.com/mooc/3351/udacity-javascript-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[199]:https://www.class-central.com/mooc/4050/udacity-configuring-linux-web-servers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[200]:https://www.class-central.com/mooc/3082/udacity-javascript-design-patterns?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[201]:https://www.class-central.com/mooc/2716/stanford-openedx-compilers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[202]:https://www.class-central.com/mooc/2340/stanford-openedx-lpl-language-proof-and-logic?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[203]:https://www.class-central.com/mooc/1523/edx-mobile-application-experiences-part-1-from-a-domain-to-an-app-idea?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[204]:https://www.class-central.com/mooc/1848/udacity-machine-learning-unsupervised-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[205]:https://www.class-central.com/mooc/6920/coursera-programming-languages-part-b?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[206]:https://www.class-central.com/mooc/4356/coursera-responsive-website-tutorial-and-examples?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[207]:https://www.class-central.com/mooc/4348/coursera-ios-app-development-basics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[208]:https://www.class-central.com/mooc/2778/nptel-programming-data-structures-and-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[209]:https://www.class-central.com/mooc/7763/coursera-android-app-components-services-local-ipc-and-content-providers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[210]:https://www.class-central.com/mooc/5500/coursera-android-app-components-intents-activities-and-broadcast-receivers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[211]:https://www.class-central.com/mooc/3758/edx-introduction-to-mobile-application-development-using-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[212]:https://www.class-central.com/mooc/3933/coursera-internet-emerging-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[213]:https://www.class-central.com/mooc/9216/coursera-object-oriented-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[214]:https://www.class-central.com/mooc/6728/udacity-android-basics-networking?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[215]:https://www.class-central.com/mooc/3524/udacity-browser-rendering-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[216]:https://www.class-central.com/mooc/7784/coursera-google-cloud-platform-fundamentals-core-infrastructure?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[217]:https://www.class-central.com/mooc/6527/udacity-client-server-communication?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[218]:https://www.class-central.com/mooc/3996/edx-developing-international-software-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[219]:https://www.class-central.com/mooc/5156/edx-analyzing-and-visualizing-data-with-power-bi?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[220]:https://www.class-central.com/mooc/5965/udacity-networking-for-web-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[221]:https://www.class-central.com/mooc/4810/edx-computation-structures-2-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[222]:https://www.class-central.com/mooc/8516/edx-software-development-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[223]:https://www.class-central.com/mooc/3418/udacity-software-architecture-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[224]:https://www.class-central.com/mooc/8573/udacity-database-systems-concepts-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[225]:https://www.class-central.com/mooc/7187/coursera-programming-languages-part-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[226]:https://www.class-central.com/mooc/8199/edx-how-to-code-complex-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[227]:https://www.class-central.com/mooc/5592/coursera-running-product-design-sprints?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[228]:https://www.class-central.com/mooc/5446/coursera-java-for-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[229]:https://www.class-central.com/mooc/8888/coursera-server-side-development-with-nodejs-express-and-mongodb?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[230]:https://www.class-central.com/mooc/6991/edx-cyber-security-economics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[231]:https://www.class-central.com/mooc/5497/coursera-web-application-development-basic-concepts?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[232]:https://www.class-central.com/mooc/5752/edx-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[233]:https://www.class-central.com/mooc/2964/edx-android-introduccion-a-la-programacion?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[234]:https://www.class-central.com/mooc/9219/coursera-service-oriented-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[235]:https://www.class-central.com/mooc/9215/coursera-design-patterns?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[236]:https://www.class-central.com/mooc/6584/coursera-cybersecurity-and-mobility?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[237]:https://www.class-central.com/mooc/8614/coursera-google-cloud-platform-fundamentals-for-aws-professionals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[238]:https://www.class-central.com/mooc/7342/udacity-android-basics-user-interface?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[239]:https://www.class-central.com/mooc/6275/udacity-scalable-microservices-with-kubernetes?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[240]:https://www.class-central.com/mooc/2215/udacity-developing-scalable-apps-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[241]:https://www.class-central.com/mooc/3455/udacity-android-performance?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[242]:https://www.class-central.com/mooc/7279/udacity-android-basics-button-clicks?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[243]:https://www.class-central.com/mooc/3584/udacity-gradle-for-android-and-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[244]:https://www.class-central.com/mooc/7463/udacity-vr-software-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[245]:https://www.class-central.com/mooc/3525/udacity-developing-scalable-apps-in-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[246]:https://www.class-central.com/mooc/3581/udacity-material-design-for-android-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[247]:https://www.class-central.com/mooc/7590/edx-intermediate-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[248]:https://www.class-central.com/mooc/8823/edx-introduction-to-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[249]:https://www.class-central.com/mooc/7384/edx-angularjs-advanced-framework-techniques?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[250]:https://www.class-central.com/mooc/6511/edx-principles-of-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[251]:https://www.class-central.com/mooc/8002/edx-asynchronous-programming-with-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[252]:https://www.class-central.com/mooc/8025/coursera-build-a-modern-computer-from-first-principles-nand-to-tetris-part-ii-project-centered-course?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[253]:https://www.class-central.com/mooc/6040/coursera-a-developer-s-guide-to-the-internet-of-things-iot?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[254]:https://www.class-central.com/mooc/6000/edx-introduction-to-cloud-infrastructure-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[255]:https://www.class-central.com/mooc/4856/udacity-2d-game-development-with-libgdx?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[256]:https://www.class-central.com/mooc/4990/edx-introduction-to-real-time-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[257]:https://www.class-central.com/mooc/3984/nptel-design-and-analysis-of-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[258]:https://www.class-central.com/mooc/6300/edx-how-to-win-coding-competitions-secrets-of-champions?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[259]:https://www.class-central.com/mooc/4671/edx-html5-apps-and-games?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[260]:https://www.class-central.com/mooc/6143/udacity-technical-interview?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[261]:https://www.class-central.com/mooc/6956/udacity-android-basics-data-storage?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[262]:https://www.class-central.com/mooc/455/udacity-intro-to-theoretical-computer-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[263]:https://www.class-central.com/mooc/8984/stanford-openedx-algorithms-design-and-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[264]:https://www.class-central.com/mooc/7351/coursera-shortest-paths-revisited-np-complete-problems-and-what-to-do-about-them?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[265]:https://www.class-central.com/mooc/7840/edx-mobile-application-experiences?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[266]:https://www.class-central.com/mooc/6475/edx-advanced-software-construction-in-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[267]:https://www.class-central.com/mooc/5633/edx-mobile-application-experiences-part-3-building-mobile-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[268]:https://www.class-central.com/mooc/8520/edx-algorithm-design-and-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[269]:https://www.class-central.com/mooc/8517/edx-data-structures-and-software-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[270]:https://www.class-central.com/mooc/6420/coursera-introduction-to-neurohacking-in-r?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[271]:https://www.class-central.com/mooc/8994/edx-database-systems-concepts-and-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[272]:https://www.class-central.com/mooc/8568/udacity-software-analysis-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[273]:https://www.class-central.com/mooc/9797/coursera-writing-running-and-fixing-code-in-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[274]:https://www.class-central.com/mooc/7242/edx-animation-and-cgi-motion?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[275]:https://www.class-central.com/mooc/7480/edx-minecraft-coding-and-teaching?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[276]:https://www.class-central.com/mooc/4182/coursera-internet-of-things-sensing-and-actuation-from-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[277]:https://www.class-central.com/mooc/8514/edx-how-virtual-reality-vr-works?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[278]:https://www.class-central.com/mooc/8515/edx-creating-virtual-reality-vr-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[279]:https://www.class-central.com/mooc/8653/edx-building-a-cybersecurity-toolkit?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[280]:https://www.class-central.com/mooc/8652/edx-cybersecurity-the-ciso-s-view?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[281]:https://www.class-central.com/mooc/6235/coursera-build-your-own-ios-app?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[282]:https://www.class-central.com/mooc/3230/coursera--design-and-analysis-of-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[283]:https://www.class-central.com/mooc/1737/coursera--the-advanced-object-oriented-technology?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[284]:https://www.class-central.com/mooc/3464/edx-how-to-code-systematic-program-design-part-3?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[285]:https://www.class-central.com/mooc/3466/edx-how-to-code-systematic-program-design-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[286]:https://www.class-central.com/mooc/8200/edx-software-construction-data-abstraction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[287]:https://www.class-central.com/mooc/8201/edx-software-construction-object-oriented-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[288]:https://www.class-central.com/mooc/6523/coursera-testing-with-agile?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[289]:https://www.class-central.com/mooc/9725/coursera-sql-for-data-science?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[290]:https://www.class-central.com/mooc/7852/edx-laff-on-programming-for-correctness?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[291]:https://www.class-central.com/mooc/8684/coursera-multiplatform-mobile-app-development-with-nativescript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[292]:https://www.class-central.com/mooc/8681/coursera-front-end-javascript-frameworks-angular?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[293]:https://www.class-central.com/mooc/8683/coursera-multiplatform-mobile-app-development-with-web-technologies-ionic-and-cordova?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[294]:https://www.class-central.com/mooc/8687/coursera-developing-android-apps-with-app-inventor?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[295]:https://www.class-central.com/mooc/8682/coursera-front-end-web-ui-frameworks-and-tools-bootstrap-4?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[296]:https://www.class-central.com/mooc/9119/edx-globally-distributed-software-engineering?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[297]:https://www.class-central.com/mooc/10071/coursera----c--?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[298]:https://www.class-central.com/mooc/7785/coursera-building-arduino-robots-and-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[299]:https://www.class-central.com/mooc/5753/edx-implementation-of-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[300]:https://www.class-central.com/mooc/5755/edx-foundations-of-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[301]:https://www.class-central.com/mooc/7346/edx-professional-android-app-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[302]:https://www.class-central.com/mooc/7346/edx-professional-android-app-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[303]:https://www.class-central.com/mooc/4812/edx-the-software-architect-code-building-the-digital-world?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[304]:https://www.class-central.com/mooc/7454/edx-introduction-to-java-programming-fundamental-data-structures-and-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[305]:https://www.class-central.com/mooc/6304/edx-enterprise-software-lifecycle-management?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[306]:https://www.class-central.com/mooc/10036/coursera--------?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[307]:https://www.class-central.com/mooc/9811/coursera-requirements-elicitation-artifact-and-stakeholder-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[308]:https://www.class-central.com/mooc/9319/coursera-linux-server-management-and-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[309]:https://www.class-central.com/mooc/9807/coursera-requirements-specifications-goals-and-conflict-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[310]:https://www.class-central.com/mooc/9810/coursera-software-requirements-prioritization-risk-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[311]:https://www.class-central.com/mooc/8820/coursera-homeland-security-cybersecurity-connection-it-s-not-about-the-terrorists?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[312]:https://www.class-central.com/mooc/9808/coursera-srs-documents-requirements-and-diagrammatic-notations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[313]:https://www.class-central.com/mooc/9809/coursera-requirements-gathering-for-secure-software-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[314]:https://www.class-central.com/mooc/8171/edx-software-testing-management?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[315]:https://www.class-central.com/mooc/8168/edx-cloud-computing-for-enterprises?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[316]:https://www.class-central.com/mooc/8181/edx-cloud-computing-infrastructure?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[317]:https://www.class-central.com/mooc/8180/edx-formal-software-verification?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[318]:https://www.class-central.com/mooc/8179/edx-software-testing-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[319]:https://www.class-central.com/mooc/8172/edx-cloud-computing-management?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[320]:https://www.class-central.com/mooc/7391/edx-introduction-to-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[321]:https://www.class-central.com/mooc/6657/edx-gameplay-programming-for-video-game-designers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[322]:https://www.class-central.com/mooc/6658/edx-teamwork-collaboration?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[323]:https://www.class-central.com/mooc/7415/coursera-web-connectivity-and-security-in-embedded-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[324]:https://www.class-central.com/mooc/6839/coursera-architecting-smart-iot-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[325]:https://www.class-central.com/mooc/6748/coursera-introduction-to-architecting-smart-iot-devices?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[326]:https://www.class-central.com/mooc/6585/coursera-cybersecurity-and-the-x-factor?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[327]:https://www.class-central.com/mooc/6548/udacity-intro-to-progressive-web-apps?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[328]:https://www.class-central.com/mooc/3580/udacity-advanced-android-app-development?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[329]:https://www.class-central.com/mooc/6477/udacity-google-maps-apis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[330]:https://www.class-central.com/mooc/5679/udacity-offline-web-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[331]:https://www.class-central.com/mooc/5055/udacity-firebase-essentials-for-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[332]:https://www.class-central.com/mooc/6357/edx-developing-intelligent-apps-and-bots?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[333]:https://www.class-central.com/mooc/7405/edx-developing-sql-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[334]:https://www.class-central.com/mooc/8722/edx-building-functional-prototypes-using-node-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[335]:https://www.class-central.com/mooc/8719/edx-building-interactive-prototypes-using-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[336]:https://www.class-central.com/mooc/8937/edx-algorithms-and-data-structures?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[337]:https://www.class-central.com/mooc/9483/edx-algorithms-and-data-structures-in-c?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[338]:https://www.class-central.com/mooc/7401/edx-creating-programmatic-sql-database-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[339]:https://www.class-central.com/mooc/7377/edx-angularjs-framework-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[340]:https://www.class-central.com/mooc/8633/edx-introduction-to-typescript-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[341]:https://www.class-central.com/mooc/7208/edx-advanced-css-concepts?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[342]:https://www.class-central.com/mooc/7399/edx-implementing-in-memory-sql-database-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[343]:https://www.class-central.com/mooc/7398/edx-optimizing-performance-for-sql-based-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[344]:https://www.class-central.com/mooc/8369/edx-programmation-concurrente-avec-java?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[345]:https://www.class-central.com/mooc/6931/coursera-c-for-c-programmers-part-b?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[346]:https://www.class-central.com/mooc/8764/edx-introduction-to-kubernetes?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[347]:https://www.class-central.com/mooc/7506/edx-introduction-to-devops-transforming-and-improving-operations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[348]:https://www.class-central.com/mooc/7506/edx-introduction-to-devops-transforming-and-improving-operations?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[349]:https://www.class-central.com/mooc/7837/edx-uml-class-diagrams-for-software-engineering?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[350]:https://www.class-central.com/mooc/9701/udacity-mobile-usability-and-design-for-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[351]:https://www.class-central.com/mooc/9700/udacity-mobile-usability-and-design-for-ios?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[352]:https://www.class-central.com/mooc/6493/concurrency?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[353]:https://www.class-central.com/mooc/8670/edx-fundamentals-of-red-hat-enterprise-linux?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[354]:https://www.class-central.com/mooc/9105/edx-fundamentals-of-containers-kubernetes-and-red-hat-openshift?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[355]:https://www.class-central.com/mooc/8839/udacity-c-for-programmers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[356]:https://www.class-central.com/mooc/4071/udacity-learn-backbone-js?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[357]:https://www.class-central.com/mooc/4419/udacity-how-to-create-anything-in-android?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[358]:https://www.class-central.com/mooc/3527/udacity-how-to-make-an-ios-app?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[359]:https://www.class-central.com/mooc/3526/udacity-ios-persistence-and-core-data?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[360]:https://www.class-central.com/mooc/3350/udacity-uikit-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[361]:https://www.class-central.com/mooc/3393/udacity-ios-networking-with-swift?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[362]:https://www.class-central.com/mooc/4887/udacity-designing-restful-apis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[363]:https://www.class-central.com/mooc/8422/udacity-vr-platforms-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[364]:https://www.class-central.com/mooc/7495/udacity-swift-for-developers?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[365]:https://www.class-central.com/mooc/6797/udacity-the-mvc-pattern-in-ruby?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[366]:https://www.class-central.com/mooc/6798/udacity-deploying-applications-with-heroku?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[367]:https://www.class-central.com/mooc/6796/udacity-dynamic-web-applications-with-sinatra?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[368]:https://www.class-central.com/mooc/7753/udacity-building-ios-interfaces?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[369]:https://www.class-central.com/mooc/8394/udacity-vr-design?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[370]:https://www.class-central.com/mooc/7755/udacity-new-android-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[371]:https://www.class-central.com/mooc/7754/udacity-ios-design-patterns?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[372]:https://www.class-central.com/mooc/7380/udacity-vr-scenes-and-objects?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[373]:https://www.class-central.com/mooc/6679/kadenze-creative-applications-of-deep-learning-with-tensorflow?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[374]:https://www.class-central.com/mooc/10029/nptel-an-introduction-to-probability-in-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[375]:https://www.class-central.com/mooc/9913/nptel-information-security-iv?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[376]:https://www.class-central.com/mooc/10094/nptel-matlab-programming-for-numerical-computation?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[377]:https://www.class-central.com/mooc/10051/nptel-digital-switching-i?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[378]:https://www.class-central.com/mooc/9817/nptel-advanced-graph-theory?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[379]:https://www.class-central.com/mooc/9608/coursera-deep-learning-in-computer-vision?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[380]:https://www.class-central.com/mooc/9603/coursera-natural-language-processing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[381]:https://www.class-central.com/mooc/9924/coursera-practical-reinforcement-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[382]:https://www.class-central.com/mooc/9848/nptel-real-time-operating-system?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[383]:https://www.class-central.com/mooc/10066/nptel-traditional-and-non-traditional-optimization-tools?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[384]:https://www.class-central.com/mooc/10088/nptel-basics-of-software-defined-radios-and-practical-applications?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[385]:https://www.class-central.com/mooc/9135/edx-sparse-representations-in-image-processing-from-theory-to-practice?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[386]:https://www.class-central.com/mooc/301/udacity-introduction-to-artificial-intelligence?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[387]:https://www.class-central.com/mooc/398/coursera-neural-networks-for-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[388]:https://www.class-central.com/mooc/4912/edx-machine-learning-for-data-science-and-analytics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[389]:https://www.class-central.com/mooc/1026/udacity-machine-learning-for-trading?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[390]:https://www.class-central.com/mooc/9058/coursera-neural-networks-and-deep-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[391]:https://www.class-central.com/mooc/7230/edx-artificial-intelligence-ai?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[392]:https://www.class-central.com/mooc/449/coursera-computational-neuroscience?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[393]:https://www.class-central.com/mooc/1022/udacity-introduction-to-computer-vision?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[394]:https://www.class-central.com/mooc/1849/udacity-reinforcement-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[395]:https://www.class-central.com/mooc/549/udacity-intro-to-parallel-programming?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[396]:https://www.class-central.com/mooc/552/udacity-interactive-3d-graphics?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[397]:https://www.class-central.com/mooc/1020/udacity-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[398]:https://www.class-central.com/mooc/4911/edx-enabling-technologies-for-data-science-and-analytics-the-internet-of-things?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[399]:https://www.class-central.com/mooc/326/udacity-applied-cryptography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[400]:https://www.class-central.com/mooc/7887/practical-deep-learning-for-coders-part-1?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[401]:https://www.class-central.com/mooc/1016/udacity-advanced-operating-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[402]:https://www.class-central.com/mooc/7231/edx-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[403]:https://www.class-central.com/mooc/642/introduction-to-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[404]:https://www.class-central.com/mooc/7292/coursera-probabilistic-graphical-models-2-inference?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[405]:https://www.class-central.com/mooc/6673/coursera-applied-machine-learning-in-python?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[406]:https://www.class-central.com/mooc/4864/coursera-quantitative-formal-modeling-and-worst-case-performance-analysis?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[407]:https://www.class-central.com/mooc/8083/6-s191-introduction-to-deep-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[408]:https://www.class-central.com/mooc/3419/udacity-introduction-to-operating-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[409]:https://www.class-central.com/mooc/6927/coursera-nearest-neighbor-collaborative-filtering?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[410]:https://www.class-central.com/mooc/8132/6-s094-deep-learning-for-self-driving-cars?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[411]:https://www.class-central.com/mooc/1018/udacity-high-performance-computer-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[412]:https://www.class-central.com/mooc/1024/udacity-computability-complexity-algorithms?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[413]:https://www.class-central.com/mooc/1023/udacity-computational-photography?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[414]:https://www.class-central.com/mooc/3420/udacity-intro-to-information-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[415]:https://www.class-central.com/mooc/1025/udacity-knowledge-based-ai-cognitive-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[416]:https://www.class-central.com/mooc/6826/coursera-embedded-hardware-and-operating-systems?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[417]:https://www.class-central.com/mooc/8480/learn-tensorflow-and-deep-learning-without-a-ph-d?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[418]:https://www.class-central.com/mooc/9475/edx-devops-practices-and-principles?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[419]:https://www.class-central.com/mooc/9133/edx-sparse-representations-in-signal-and-image-processing-fundamentals?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[420]:https://www.class-central.com/mooc/8387/edx-introduction-to-cloud-foundry-and-cloud-native-software-architecture?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[421]:https://www.class-central.com/mooc/9484/edx-blockchain-for-business-an-introduction-to-hyperledger-technologies?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[422]:https://www.class-central.com/mooc/6245/edx-computation-structures-3-computer-organization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[423]:https://www.class-central.com/mooc/4734/udacity-gt-refresher-advanced-os?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[424]:https://www.class-central.com/mooc/1028/udacity-high-performance-computing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[425]:https://www.class-central.com/mooc/8572/udacity-compilers-theory-and-practice?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[426]:https://www.class-central.com/mooc/8569/udacity-cyber-physical-systems-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[427]:https://www.class-central.com/mooc/8570/udacity-network-security?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[428]:https://www.class-central.com/mooc/8565/udacity-artificial-intelligence?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[429]:https://www.class-central.com/mooc/8123/coursera-information-security-context-and-introduction?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[430]:https://www.class-central.com/mooc/7757/coursera-advanced-modeling-for-discrete-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[431]:https://www.class-central.com/mooc/7759/coursera-basic-modeling-for-discrete-optimization?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[432]:https://www.class-central.com/mooc/6881/edx-nature-in-code-biology-in-javascript?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[433]:https://www.class-central.com/mooc/6933/coursera-matrix-factorization-and-advanced-techniques?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[434]:https://www.class-central.com/mooc/6825/coursera-system-validation-automata-and-behavioural-equivalences?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[435]:https://www.class-central.com/mooc/7420/coursera-system-validation-2-model-process-behaviour?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[436]:https://www.class-central.com/mooc/7803/coursera-system-validation-4-modelling-software-protocols-and-other-behaviour?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[437]:https://www.class-central.com/mooc/9479/edx-devops-testing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[438]:https://www.class-central.com/mooc/8746/edx-deep-learning-explained?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[439]:https://www.class-central.com/mooc/9164/edx-introduction-to-artificial-intelligence-ai?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[440]:https://www.class-central.com/mooc/9480/edx-devops-for-databases?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[441]:https://www.class-central.com/mooc/9476/edx-infrastructure-as-code?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[442]:https://www.class-central.com/mooc/8097/deep-learning-for-natural-language-processing?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[443]:https://www.class-central.com/mooc/8509/statistical-machine-learning?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[444]:https://www.class-central.com/mooc/9791/coursera-cyber-physical-systems-modeling-and-simulation?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[445]:https://www.class-central.com/mooc/7202/edx-introduction-to-openstack?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[446]:https://www.class-central.com/mooc/7046/edx-computer-system-design-advanced-concepts-of-modern-microprocessors?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[447]:https://www.class-central.com/mooc/6603/edx-reliable-distributed-algorithms-part-2?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[448]:https://www.class-central.com/mooc/8481/deep-learning-summer-school?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[449]:https://www.class-central.com/mooc/8021/udacity-continuous-integration-and-deployment?utm_source=fcc_medium&utm_medium=web&utm_campaign=mooc_report_programming_feb_2018 +[450]:https://www.class-central.com/ +[451]:https://www.class-central.com/subject/cs +[452]:https://www.class-central.com/subject/data-science +[453]:https://www.class-central.com/subject/programming-and-software-development +[454]:https://medium.com/@davidventuri +[455]:https://medium.freecodecamp.com/the-best-data-science-courses-on-the-internet-ranked-by-your-reviews-6dc5b910ea40 +[456]:https://medium.freecodecamp.org/how-to-sign-up-for-coursera-courses-for-free-98266efaa531 From a9400f5fa83a09e1a346de1a84fd80020b1f4467 Mon Sep 17 00:00:00 2001 From: runningwater Date: Sat, 3 Mar 2018 18:40:05 +0800 Subject: [PATCH 086/101] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E7=94=B3=E9=A2=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20170926 Managing users on Linux systems.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/tech/20170926 Managing users on Linux systems.md b/sources/tech/20170926 Managing users on Linux systems.md index 9842eab1d5..999110166d 100644 --- a/sources/tech/20170926 Managing users on Linux systems.md +++ b/sources/tech/20170926 Managing users on Linux systems.md @@ -1,3 +1,4 @@ +(Translating by runningwater) Managing users on Linux systems ====== Your Linux users may not be raging bulls, but keeping them happy is always a challenge as it involves managing their accounts, monitoring their access rights, tracking down the solutions to problems they run into, and keeping them informed about important changes on the systems they use. Here are some of the tasks and tools that make the job a little easier. @@ -215,7 +216,7 @@ Managing user accounts on a busy server depends in part on starting out with wel via: https://www.networkworld.com/article/3225109/linux/managing-users-on-linux-systems.html 作者:[Sandra Henry-Stocker][a] -译者:[译者ID](https://github.com/译者ID) +译者:[runningwater](https://github.com/runningwater) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From d827579bdf7211a2cd2a9043ac21ed0d4442976e Mon Sep 17 00:00:00 2001 From: cmn <2545489745@qq.com> Date: Sat, 3 Mar 2018 20:41:45 +0800 Subject: [PATCH 087/101] translated --- ... PGP - Part 1- Basic Concepts and Tools.md | 269 ----------------- ... PGP - Part 1- Basic Concepts and Tools.md | 271 ++++++++++++++++++ 2 files changed, 271 insertions(+), 269 deletions(-) delete mode 100644 sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md create mode 100644 translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md diff --git a/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md b/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md deleted file mode 100644 index 71a46b6854..0000000000 --- a/sources/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md +++ /dev/null @@ -1,269 +0,0 @@ -translating by kimii -Protecting Code Integrity with PGP — Part 1: Basic Concepts and Tools -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/pgp-security.jpg?itok=lulwyzYc) - -In this article series, we take an in-depth look at using PGP to ensure the integrity of software. These articles will provide practical guidelines aimed at developers working on free software projects and will cover the following topics: - - 1. PGP basics and best practices - - 2. How to use PGP with Git - - 3. How to protect your developer accounts - - - - -We use the term "Free" as in "Freedom," but the guidelines set out in this series can also be used for any other kind of software that relies on contributions from a distributed team of developers. If you write code that goes into public source repositories, you can benefit from getting acquainted with and following this guide. - -### Structure - -Each section is split into two areas: - - * The checklist that can be adapted to your project's needs - - * Free-form list of considerations that explain what dictated these decisions, together with configuration instructions - - - - -#### Checklist priority levels - -The items in each checklist include the priority level, which we hope will help guide your decision: - - * (ESSENTIAL) items should definitely be high on the consideration list. If not implemented, they will introduce high risks to the code that gets committed to the open-source project. - - * (NICE) to have items will improve the overall security, but will affect how you interact with your work environment, and probably require learning new habits or unlearning old ones. - - - - -Remember, these are only guidelines. If you feel these priority levels do not reflect your project's commitment to security, you should adjust them as you see fit. - -## Basic PGP concepts and tools - -### Checklist - - 1. Understand the role of PGP in Free Software Development (ESSENTIAL) - - 2. Understand the basics of Public Key Cryptography (ESSENTIAL) - - 3. Understand PGP Encryption vs. Signatures (ESSENTIAL) - - 4. Understand PGP key identities (ESSENTIAL) - - 5. Understand PGP key validity (ESSENTIAL) - - 6. Install GnuPG utilities (version 2.x) (ESSENTIAL) - - - - -### Considerations - -The Free Software community has long relied on PGP for assuring the authenticity and integrity of software products it produced. You may not be aware of it, but whether you are a Linux, Mac or Windows user, you have previously relied on PGP to ensure the integrity of your computing environment: - - * Linux distributions rely on PGP to ensure that binary or source packages have not been altered between when they have been produced and when they are installed by the end-user. - - * Free Software projects usually provide detached PGP signatures to accompany released software archives, so that downstream projects can verify the integrity of downloaded releases before integrating them into their own distributed downloads. - - * Free Software projects routinely rely on PGP signatures within the code itself in order to track provenance and verify integrity of code committed by project developers. - - - - -This is very similar to developer certificates/code signing mechanisms used by programmers working on proprietary platforms. In fact, the core concepts behind these two technologies are very much the same -- they differ mostly in the technical aspects of the implementation and the way they delegate trust. PGP does not rely on centralized Certification Authorities, but instead lets each user assign their own trust to each certificate. - -Our goal is to get your project on board using PGP for code provenance and integrity tracking, following best practices and observing basic security precautions. - -### Extremely Basic Overview of PGP operations - -You do not need to know the exact details of how PGP works -- understanding the core concepts is enough to be able to use it successfully for our purposes. PGP relies on Public Key Cryptography to convert plain text into encrypted text. This process requires two distinct keys: - - * A public key that is known to everyone - - * A private key that is only known to the owner - - - - -#### Encryption - -For encryption, PGP uses the public key of the owner to create a message that is only decryptable using the owner's private key: - - 1. The sender generates a random encryption key ("session key") - - 2. The sender encrypts the contents using that session key (using a symmetric cipher) - - 3. The sender encrypts the session key using the recipient's public PGP key - - 4. The sender sends both the encrypted contents and the encrypted session key to the recipient - - - - -To decrypt: - - 1. The recipient decrypts the session key using their private PGP key - - 2. The recipient uses the session key to decrypt the contents of the message - - - - -#### Signatures - -For creating signatures, the private/public PGP keys are used the opposite way: - - 1. The signer generates the checksum hash of the contents - - 2. The signer uses their own private PGP key to encrypt that checksum - - 3. The signer provides the encrypted checksum alongside the contents - - - - -To verify the signature: - - 1. The verifier generates their own checksum hash of the contents - - 2. The verifier uses the signer's public PGP key to decrypt the provided checksum - - 3. If the checksums match, the integrity of the contents is verified - - - - -#### Combined usage - -Frequently, encrypted messages are also signed with the sender's own PGP key. This should be the default whenever using encrypted messaging, as encryption without authentication is not very meaningful (unless you are a whistleblower or a secret agent and need plausible deniability). - -### Understanding Key Identities - -Each PGP key must have one or multiple Identities associated with it. Usually, an "Identity" is the person's full name and email address in the following format: -``` -Alice Engineer - -``` - -Sometimes it will also contain a comment in brackets, to tell the end-user more about that particular key: -``` -Bob Designer (obsolete 1024-bit key) - -``` - -Since people can be associated with multiple professional and personal entities, they can have multiple identities on the same key: -``` -Alice Engineer -Alice Engineer -Alice Engineer - -``` - -When multiple identities are used, one of them would be marked as the "primary identity" to make searching easier. - -### Understanding Key Validity - -To be able to use someone else's public key for encryption or verification, you need to be sure that it actually belongs to the right person (Alice) and not to an impostor (Eve). In PGP, this certainty is called "key validity:" - - * Validity: full -- means we are pretty sure this key belongs to Alice - - * Validity: marginal -- means we are somewhat sure this key belongs to Alice - - * Validity: unknown -- means there is no assurance at all that this key belongs to Alice - - - - -#### Web of Trust (WOT) vs. Trust on First Use (TOFU) - -PGP incorporates a trust delegation mechanism known as the "Web of Trust." At its core, this is an attempt to replace the need for centralized Certification Authorities of the HTTPS/TLS world. Instead of various software makers dictating who should be your trusted certifying entity, PGP leaves this responsibility to each user. - -Unfortunately, very few people understand how the Web of Trust works, and even fewer bother to keep it going. It remains an important aspect of the OpenPGP specification, but recent versions of GnuPG (2.2 and above) have implemented an alternative mechanism called "Trust on First Use" (TOFU). - -You can think of TOFU as "the SSH-like approach to trust." With SSH, the first time you connect to a remote system, its key fingerprint is recorded and remembered. If the key changes in the future, the SSH client will alert you and refuse to connect, forcing you to make a decision on whether you choose to trust the changed key or not. - -Similarly, the first time you import someone's PGP key, it is assumed to be trusted. If at any point in the future GnuPG comes across another key with the same identity, both the previously imported key and the new key will be marked as invalid and you will need to manually figure out which one to keep. - -In this guide, we will be using the TOFU trust model. - -### Installing OpenPGP software - -First, it is important to understand the distinction between PGP, OpenPGP, GnuPG and gpg: - - * PGP ("Pretty Good Privacy") is the name of the original commercial software - - * OpenPGP is the IETF standard compatible with the original PGP tool - - * GnuPG ("Gnu Privacy Guard") is free software that implements the OpenPGP standard - - * The command-line tool for GnuPG is called "gpg" - - - - -Today, the term "PGP" is almost universally used to mean "the OpenPGP standard," not the original commercial software, and therefore "PGP" and "OpenPGP" are interchangeable. The terms "GnuPG" and "gpg" should only be used when referring to the tools, not to the output they produce or OpenPGP features they implement. For example: - - * PGP (not GnuPG or GPG) key - - * PGP (not GnuPG or GPG) signature - - * PGP (not GnuPG or GPG) keyserver - - - - -Understanding this should protect you from an inevitable pedantic "actually" from other PGP users you come across. - -#### Installing GnuPG - -If you are using Linux, you should already have GnuPG installed. On a Mac, you should install [GPG-Suite][1] or you can use brew install gnupg2. On a Windows PC, you should install [GPG4Win][2], and you will probably need to adjust some of the commands in the guide to work for you, unless you have a unix-like environment set up. For all other platforms, you'll need to do your own research to find the correct places to download and install GnuPG. - -#### GnuPG 1 vs. 2 - -Both GnuPG v.1 and GnuPG v.2 implement the same standard, but they provide incompatible libraries and command-line tools, so many distributions ship both the legacy version 1 and the latest version 2. You need to make sure you are always using GnuPG v.2. - -First, run: -``` -$ gpg --version | head -n1 - -``` - -If you see gpg (GnuPG) 1.4.x, then you are using GnuPG v.1. Try the gpg2 command: -``` -$ gpg2 --version | head -n1 - -``` - -If you see gpg (GnuPG) 2.x.x, then you are good to go. This guide will assume you have the version 2.2 of GnuPG (or later). If you are using version 2.0 of GnuPG, some of the commands in this guide will not work, and you should consider installing the latest 2.2 version of GnuPG. - -#### Making sure you always use GnuPG v.2 - -If you have both gpg and gpg2 commands, you should make sure you are always using GnuPG v2, not the legacy version. You can make sure of this by setting the alias: -``` -$ alias gpg=gpg2 - -``` - -You can put that in your .bashrc to make sure it's always loaded whenever you use the gpg commands. - -In part 2 of this series, we will explain the basic steps for generating and protecting your master PGP key. - -Learn more about Linux through the free ["Introduction to Linux" ][3]course from The Linux Foundation and edX. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools - -作者:[Konstantin Ryabitsev][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.linux.com/users/mricon -[1]:https://gpgtools.org/ -[2]:https://www.gpg4win.org/ -[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md b/translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md new file mode 100644 index 0000000000..87cd2d7e1f --- /dev/null +++ b/translated/tech/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md @@ -0,0 +1,271 @@ +用 PGP 保护代码完整性 - 第一部分: 基本概念和工具 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/pgp-security.jpg?itok=lulwyzYc) + +在本系列文章中,我们将深度探讨如何使用 PGP 确保软件完整性。这些文章将为工作于自由软件项目的开发者提供实用指南,并且将包含以下主题: + + + 1. PGP 基础和最佳实践 + + 2. 如何用 Git 使用 PGP + + 3. 如何保护你的开发者账户 + + +我们使用与“Freedom”含义相同的词项“Free”,但这个系列中列出的指南也可以被任何其它类型的依赖于分布式团队开发者贡献的软件中。如果你编写进入公共源仓库的代码,你可以从了解和遵循这篇指南中受益。 + +### 结构 + +每节分为两个部分: + + * 适用于你项目需求的清单 + + * 自由形式的考虑事项的列表,解释这些决定取决于什么,并伴随着配置指令 + + + + +#### 清单优先级 + +每个清单中各项包含着优先级,用来帮助指导你的决定: + + * (ESSENTIAL) 该项一定要排在考虑事项列表的前面。如果没有这样做,它们将给提交到开源项目中的代码带来高风险。 + + * (NICE) 包含该项将提升整体安全性,但会影响你与工作环境的交互方式,并且可能需要学习新的习惯或者放弃旧的习惯。 + + + + +记住,这些只是指导。如果你感到这些优先级不能反映你项目提交的安全,你应该根据自己的需要调整它们。 + +## PGP 基本概念和工具 + +### 清单 + + 1. 理解 PGP 在自由软件开发中的作用 (ESSENTIAL) + + 2. 理解公钥密码学(Public Key Cryptography)的基础知识 (ESSENTIAL) + + 3. 理解 PGP 加密和签名的不同 (ESSENTIAL) + + 4. 理解 PGP 密钥身份(key identities) (ESSENTIAL) + + 5. 理解 PGP 密钥有效性(key validity) (ESSENTIAL) + + 6. 安装 GnuPG 工具(版本 2.x) (ESSENTIAL) + + + + +### 考虑事项 + +自由软件社区长期依赖于 PGP 确保它生产的软件产品的真实性和完整性。你可能没有注意到,但无论你是一个 linux,Mac 和 Windowas 用户,你都曾依赖 PGP 来确保你电脑环境的完整性: + + * Linux 发行版依赖 PGP 来确保当二进制或者原代码包从被生产出来到被终端用户安装之间没被更改过 + + * 自由软件项目通常会提供分离的 PGP 签名以伴随发行软件存档,使得下游的项目可以把下载的版本集成到自己的分布式下载之前,验证下载版本的完整性。 + + * 自由软件项目通常依赖代码本身的 PGP 签名来跟踪起源,并验证项目开发者提交的代码的完整性 + + + + + +这与工作于专有平台的程序员使用的开发者证书或代码签名机制非常相似。实际上,这两种技术背后的核心概念非常相似 -- 尽管它们在实现的技术层面和它们委托信任方式的大多不同。PGP 不依赖于集中式认证机构,而是让每个用户为每个证书分配自己的信任。 + +我们的目标是使你的项目通过使用 PGP 来进行代码起源和完整性追踪,遵循最佳实践并遵守基本的安全预防措施。 + +### 极其基本的 PGP 操作概括 + +你不需要知道 PGP 如何工作的具体细节 -- 理解核心概念足以成功地达到我们的目的。PGP 依赖于公钥密码学来将明文转换为密文。这个过程需要两种不同的密钥: + + * 公钥,被所有人知道 + + * 私钥,只被拥有者知道 + + + + +#### 加密 + +对加密来说,PGP 使用拥有者的公钥创造一条只能通过拥有者私钥解密的消息: + + 1. 发送者生成一条随机的加密密钥(“会话密钥”) + + 2. 发送者使用该会话密钥(使用对称密码)加密内容 + + 3. 发送者使用接收者的 PGP 公钥加密会话密钥 + + 4. 发送者向接收者发送加密后的内容和加密后的会话密钥 + + + + +对于解密: + + 1. 接受者使用他们的 PGP 私钥解密会话密钥 + + 2. 接受者使用会话密钥解密消息的内容 + + + + +#### 签名 +为了创建签名,PGP 私钥或公钥会以相反的方式使用: + + 1. 签名者生成内容的校检和哈希 + 2. 签名者使用自己的 PGP 私钥来加密该校检和 + 3. 签名者伴随内容提供加密后的校检和 + + + + +为了验证签名: + + 1. 验证者生成自己的内容校检和哈希 + + 2. 验证者使用签名者的 PGP 公钥来解密提供的校检和 + + 3. 如果校检和匹配,就验证了内容的完整性 + + + + + + +通常,加密消息也被发送者自己的 PGP 密钥签名。无论何时使用加密消息,这应当是默认的,因为没有认证的加密没有很大意义(除非你是一个告密者或秘密代理并且需要可行的可否认性) + +``` +Bob Designer (obsolete 1024-bit key) + +``` +### 理解密钥身份 + +每个 PGP 密钥必须有一个或多个与之关联的身份。通常,一个“身份”指的是以下格式中的人物全名和邮件地址: +``` +Alice Engineer + +``` + +有时也会在括号中包含说明,来告诉终端用户关于该特定密钥的更多信息: +``` +Bob Designer (obsolete 1024-bit key) + +``` + + + +由于人们可以和多个职业和个人实体相关联,因此在同一密钥上可以有多个身份: +``` +Alice Engineer +Alice Engineer +Alice Engineer + +``` + +当使用多个身份时,其中之一将被标记为“primary identity”(主要身份)来让检索更简单。 + +### 理解密钥有效性 + +为了能使用其他人的公钥来加密或验证,你需要确保它确实属于正确的人(Alice)而不属于冒牌的(Eve)。在 PGP 中,这被称为密钥有效性: + + * Validity: full -- 意味着非常确认该密钥属于 Alice + * Validity: marginal -- 意味着大致确认该密钥属于 Alice + * Validity: unknown -- 意味着不确认该密钥是否属于 Alice + + + +#### Web of Trust (WOT) vs. Trust on First Use (TOFU) + +PGP 使用了一种信任委托机制叫“Web of Trust”。它的核心是尝试替代 HTTPS/TLS 世界中对集中式认证机构的需求。PGP 把这个责任交给了每个用户,而非各种软件制作商来决定谁应该是你的可信认证实体。 + +不幸的是,很少有人理解 Web of Trust 的是如何工作的,能让继续工作的人更少。它仍然是 OpenPGP 规范的一个重要方面,但 GnuPG 的近期版本(2.2 及以上)已经实现了一种替代机制叫“Trust on First Use”(TOFU)。 + +你可以把 TOFU 当作类似 SSH 的信任方式。使用 SSH,当你第一次连接到远程系统,它的密钥指纹会被记录和保存。如果将来密钥改变,SSH 客户端将会提醒你并拒绝连接,迫使你决定是否信任已改变的的密钥。 + +同样,当你第一次导入某人的 PGP 密钥,它被假定可信。如果在将来的任何时候,GnuPG 碰巧发现另一同样身份的密钥,过去导入的密钥和新密钥都将被标记为无效,并且你需要手动指出保留哪个。 + + +### 安装 OpenPGP 软件 + +首先,理解 PGP, OpenPGP, GnuPG 和 gpg 之间的不同很重要: + + * PGP ("Pretty Good Privacy") 是原始商业软件的名字 + + * OpenPGP 是与原始 PGP 工具兼容的 IETF 标准 + + * GnuPG ("Gnu Privacy Guard")是实现了 OpenPGP 标准的自由软件 + + * GnuPG 的命令行工具称为 “gpg” + + + + + +今天,“PGP”这个词几乎被普遍用来表示开放的 OpenPGP 标准,而不是原始的商业软件,因此“PGP”和“OpenPGP”是可以互换的。“GnuPG”和“pgp”这两个词应该仅在提及工具时使用,而不用于它们产生的输出或它们实现的 OpenPGP 功能。举例: + + * PGP(而非 GnuPG 或 GPG)密钥 + + * PGP(而非 GnuPG 或 GPG)签名 + + * PGP(而非 GnuPG 或 GPG)密钥服务器 + + + + +理解这一点应该可以保护你免受来自你遇到的其他 PGP 用户“实际上”不可避免的迂腐。 + +#### 安装 GnuPG + +如果你正在使用 Linux,你应该已经安装过了 GnuPG。在 Mac 上,你应该安装[GPG-Suite][1],或者使用 brew 安装 gnupg2。在 windows 上,你应该安装[GPG4Win][2],并且为了奏效你可能需要调整指南中的部分命令,除非你设置了类似 unix 的环境。对其他平台来说,你需要自行查找正确的地址来下载和安装 GnuPG。 + +#### GnuPG 1 vs. 2 + +GnuPG v.1 和 GnuPG v.2 都实现了同样的标准,但它们提供不兼容的库和命令行工具,所以许多发行版都发布了旧版本 1 和最新版本 2。你需要确保你总是使用 GnuPG v.2。 + +首先,运行: +``` +$ gpg --version | head -n1 + +``` + +如果你看到 gpg (GnuPG) 1.4.x,说明你正使用 GnuPG v.1。尝试 gpg2 命令: +``` +$ gpg2 --version | head -n1 + +``` + +如果你看到 gpg (GnuPG) 2.x.x,说明你可以继续了。这篇指南将假设你使用 GnuPG 2.2 版本(或更晚)。如果你正使用 GnuPG 的 2.0 版本,本指南中某些命令可能无效,你应该考虑安装 GnuPG 最新的 2.2 版本 + +#### 确保你总是使用 GnuPG v.2 + +如果你 gpg 和 gpg2 命令都有,你应该确保总是使用 GnuPG v.2,而不是旧的版本。你可以通过设置别名来确保这一点: +``` +$ alias gpg=gpg2 + +``` + +你可以把它放在你的 .bashrc 中,以确保它在你使用 gpg 命令时总是被加载。 + +在本系列的第 2 部分中,我们将介绍生成和保护你的 PGP 主密钥的基本步骤。 + +通过 Linux 基金会和 edX 的免费[“Introduction to Linux” ][3]课程了解关于 Linux 的更多信息。 + + + + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools + +作者:[Konstantin Ryabitsev][a] +译者:[kimii](https://github.com/kimii) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/mricon +[1]:https://gpgtools.org/ +[2]:https://www.gpg4win.org/ +[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From 287deb07789586cb3829b6bfb1a3c7a3e13a3a66 Mon Sep 17 00:00:00 2001 From: DarkSun Date: Sun, 4 Mar 2018 16:38:21 +0800 Subject: [PATCH 088/101] Revert "remove jvns.ca" --- sources/tech/20160810 How does gdb work.md | 220 +++++++++++++++ ...20171010 Operating a Kubernetes network.md | 217 +++++++++++++++ ...1121 Finding Files with mlocate- Part 3.md | 142 ++++++++++ .../20171124 How do groups work on Linux.md | 143 ++++++++++ sources/tech/20171224 My first Rust macro.md | 145 ++++++++++ .../20180104 How does gdb call functions.md | 254 ++++++++++++++++++ ...ures resolving symbol addresses is hard.md | 163 +++++++++++ 7 files changed, 1284 insertions(+) create mode 100644 sources/tech/20160810 How does gdb work.md create mode 100644 sources/tech/20171010 Operating a Kubernetes network.md create mode 100644 sources/tech/20171121 Finding Files with mlocate- Part 3.md create mode 100644 sources/tech/20171124 How do groups work on Linux.md create mode 100644 sources/tech/20171224 My first Rust macro.md create mode 100644 sources/tech/20180104 How does gdb call functions.md create mode 100644 sources/tech/20180109 Profiler adventures resolving symbol addresses is hard.md diff --git a/sources/tech/20160810 How does gdb work.md b/sources/tech/20160810 How does gdb work.md new file mode 100644 index 0000000000..56b0cfe7bf --- /dev/null +++ b/sources/tech/20160810 How does gdb work.md @@ -0,0 +1,220 @@ +translating by ucasFL + +How does gdb work? +============================================================ + +Hello! Today I was working a bit on my [ruby stacktrace project][1] and I realized that now I know a couple of things about how gdb works internally. + +Lately I’ve been using gdb to look at Ruby programs, so we’re going to be running gdb on a Ruby program. This really means the Ruby interpreter. First, we’re going to print out the address of a global variable: `ruby_current_thread`: + +### getting a global variable + +Here’s how to get the address of the global `ruby_current_thread`: + +``` +$ sudo gdb -p 2983 +(gdb) p & ruby_current_thread +$2 = (rb_thread_t **) 0x5598a9a8f7f0 + +``` + +There are a few places a variable can live: on the heap, the stack, or in your program’s text. Global variables are part of your program! You can think of them as being allocated at compile time, kind of. It turns out we can figure out the address of a global variable pretty easily! Let’s see how `gdb` came up with `0x5598a9a8f7f0`. + +We can find the approximate region this variable lives in by looking at a cool file in `/proc` called `/proc/$pid/maps`. + +``` +$ sudo cat /proc/2983/maps | grep bin/ruby +5598a9605000-5598a9886000 r-xp 00000000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +5598a9a86000-5598a9a8b000 r--p 00281000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +5598a9a8b000-5598a9a8d000 rw-p 00286000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby + +``` + +So! There’s this starting address `5598a9605000` That’s  _like_  `0x5598a9a8f7f0`, but different. How different? Well, here’s what I get when I subtract them: + +``` +(gdb) p/x 0x5598a9a8f7f0 - 0x5598a9605000 +$4 = 0x48a7f0 + +``` + +“What’s that number?”, you might ask? WELL. Let’s look at the **symbol table**for our program with `nm`. + +``` +sudo nm /proc/2983/exe | grep ruby_current_thread +000000000048a7f0 b ruby_current_thread + +``` + +What’s that we see? Could it be `0x48a7f0`? Yes it is! So!! If we want to find the address of a global variable in our program, all we need to do is look up the name of the variable in the symbol table, and then add that to the start of the range in `/proc/whatever/maps`, and we’re done! + +So now we know how gdb does that. But gdb does so much more!! Let’s skip ahead to… + +### dereferencing pointers + +``` +(gdb) p ruby_current_thread +$1 = (rb_thread_t *) 0x5598ab3235b0 + +``` + +The next thing we’re going to do is **dereference** that `ruby_current_thread`pointer. We want to see what’s in that address! To do that, gdb will run a bunch of system calls like this: + +``` +ptrace(PTRACE_PEEKTEXT, 2983, 0x5598a9a8f7f0, [0x5598ab3235b0]) = 0 + +``` + +You remember this address `0x5598a9a8f7f0`? gdb is asking “hey, what’s in that address exactly”? `2983` is the PID of the process we’re running gdb on. It’s using the `ptrace` system call which is how gdb does everything. + +Awesome! So we can dereference memory and figure out what bytes are at what memory addresses. Some useful gdb commands to know here are `x/40w variable` and `x/40b variable` which will display 40 words / bytes at a given address, respectively. + +### describing structs + +The memory at an address looks like this. A bunch of bytes! + +``` +(gdb) x/40b ruby_current_thread +0x5598ab3235b0: 16 -90 55 -85 -104 85 0 0 +0x5598ab3235b8: 32 47 50 -85 -104 85 0 0 +0x5598ab3235c0: 16 -64 -55 115 -97 127 0 0 +0x5598ab3235c8: 0 0 2 0 0 0 0 0 +0x5598ab3235d0: -96 -83 -39 115 -97 127 0 0 + +``` + +That’s useful, but not that useful! If you are a human like me and want to know what it MEANS, you need more. Like this: + +``` +(gdb) p *(ruby_current_thread) +$8 = {self = 94114195940880, vm = 0x5598ab322f20, stack = 0x7f9f73c9c010, + stack_size = 131072, cfp = 0x7f9f73d9ada0, safe_level = 0, raised_flag = 0, + last_status = 8, state = 0, waiting_fd = -1, passed_block = 0x0, + passed_bmethod_me = 0x0, passed_ci = 0x0, top_self = 94114195612680, + top_wrapper = 0, base_block = 0x0, root_lep = 0x0, root_svar = 8, thread_id = + 140322820187904, + +``` + +GOODNESS. That is a lot more useful. How does gdb know that there are all these cool fields like `stack_size`? Enter DWARF. DWARF is a way to store extra debugging data about your program, so that debuggers like gdb can do their job better! It’s generally stored as part of a binary. If I run `dwarfdump` on my Ruby binary, I get some output like this: + +(I’ve redacted it heavily to make it easier to understand) + +``` +DW_AT_name "rb_thread_struct" +DW_AT_byte_size 0x000003e8 +DW_TAG_member + DW_AT_name "self" + DW_AT_type <0x00000579> + DW_AT_data_member_location DW_OP_plus_uconst 0 +DW_TAG_member + DW_AT_name "vm" + DW_AT_type <0x0000270c> + DW_AT_data_member_location DW_OP_plus_uconst 8 +DW_TAG_member + DW_AT_name "stack" + DW_AT_type <0x000006b3> + DW_AT_data_member_location DW_OP_plus_uconst 16 +DW_TAG_member + DW_AT_name "stack_size" + DW_AT_type <0x00000031> + DW_AT_data_member_location DW_OP_plus_uconst 24 +DW_TAG_member + DW_AT_name "cfp" + DW_AT_type <0x00002712> + DW_AT_data_member_location DW_OP_plus_uconst 32 +DW_TAG_member + DW_AT_name "safe_level" + DW_AT_type <0x00000066> + +``` + +So. The name of the type of `ruby_current_thread` is `rb_thread_struct`. It has size `0x3e8` (or 1000 bytes), and it has a bunch of member items. `stack_size` is one of them, at an offset of 24, and it has type 31\. What’s 31? No worries! We can look that up in the DWARF info too! + +``` +< 1><0x00000031> DW_TAG_typedef + DW_AT_name "size_t" + DW_AT_type <0x0000003c> +< 1><0x0000003c> DW_TAG_base_type + DW_AT_byte_size 0x00000008 + DW_AT_encoding DW_ATE_unsigned + DW_AT_name "long unsigned int" + +``` + +So! `stack_size` has type `size_t`, which means `long unsigned int`, and is 8 bytes. That means that we can read the stack size! + +How that would break down, once we have the DWARF debugging data, is: + +1. Read the region of memory that `ruby_current_thread` is pointing to + +2. Add 24 bytes to get to `stack_size` + +3. Read 8 bytes (in little-endian format, since we’re on x86) + +4. Get the answer! + +Which in this case is 131072 or 128 kb. + +To me, this makes it a lot more obvious what debugging info is **for** – if we didn’t have all this extra metadata about what all these variables meant, we would have no idea what the bytes at address `0x5598ab3235b0` meant. + +This is also why you can install debug info for a program separately from your program – gdb doesn’t care where it gets the extra debug info from. + +### DWARF is confusing + +I’ve been reading a bunch of DWARF info recently. Right now I’m using libdwarf which hasn’t been the best experience – the API is confusing, you initialize everything in a weird way, and it’s really slow (it takes 0.3 seconds to read all the debugging data out of my Ruby program which seems ridiculous). I’ve been told that libdw from elfutils is better. + +Also, I casually remarked that you can look at `DW_AT_data_member_location` to get the offset of a struct member! But I looked up on Stack Overflow how to actually do that and I got [this answer][2]. Basically you start with a check like: + +``` +dwarf_whatform(attrs[i], &form, &error); + if (form == DW_FORM_data1 || form == DW_FORM_data2 + form == DW_FORM_data2 || form == DW_FORM_data4 + form == DW_FORM_data8 || form == DW_FORM_udata) { + +``` + +and then it keeps GOING. Why are there 8 million different `DW_FORM_data` things I need to check for? What is happening? I have no idea. + +Anyway my impression is that DWARF is a large and complicated standard (and possibly the libraries people use to generate DWARF are subtly incompatible?), but it’s what we have, so that’s what we work with! + +I think it’s really cool that I can write code that reads DWARF and my code actually mostly works. Except when it crashes. I’m working on that. + +### unwinding stacktraces + +In an earlier version of this post, I said that gdb unwinds stacktraces using libunwind. It turns out that this isn’t true at all! + +Someone who’s worked on gdb a lot emailed me to say that they actually spent a ton of time figuring out how to unwind stacktraces so that they can do a better job than libunwind does. This means that if you get stopped in the middle of a weird program with less debug info than you might hope for that’s done something strange with its stack, gdb will try to figure out where you are anyway. Thanks <3 + +### other things gdb does + +The few things I’ve described here (reading memory, understanding DWARF to show you structs) aren’t everything gdb does – just looking through Brendan Gregg’s [gdb example from yesterday][3], we see that gdb also knows how to + +* disassemble assembly + +* show you the contents of your registers + +and in terms of manipulating your program, it can + +* set breakpoints and step through a program + +* modify memory (!! danger !!) + +Knowing more about how gdb works makes me feel a lot more confident when using it! I used to get really confused because gdb kind of acts like a C REPL sometimes – you type `ruby_current_thread->cfp->iseq`, and it feels like writing C code! But you’re not really writing C at all, and it was easy for me to run into limitations in gdb and not understand why. + +Knowing that it’s using DWARF to figure out the contents of the structs gives me a better mental model and have more correct expectations! Awesome. + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2016/08/10/how-does-gdb-work/ + +作者:[ Julia Evans][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca/ +[1]:http://jvns.ca/blog/2016/06/12/a-weird-system-call-process-vm-readv/ +[2]:https://stackoverflow.com/questions/25047329/how-to-get-struct-member-offset-from-dwarf-info +[3]:http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html diff --git a/sources/tech/20171010 Operating a Kubernetes network.md b/sources/tech/20171010 Operating a Kubernetes network.md new file mode 100644 index 0000000000..abac12f718 --- /dev/null +++ b/sources/tech/20171010 Operating a Kubernetes network.md @@ -0,0 +1,217 @@ +**translating by [erlinux](https://github.com/erlinux)** +Operating a Kubernetes network +============================================================ + +I’ve been working on Kubernetes networking a lot recently. One thing I’ve noticed is, while there’s a reasonable amount written about how to **set up** your Kubernetes network, I haven’t seen much about how to **operate** your network and be confident that it won’t create a lot of production incidents for you down the line. + +In this post I’m going to try to convince you of three things: (all I think pretty reasonable :)) + +* Avoiding networking outages in production is important + +* Operating networking software is hard + +* It’s worth thinking critically about major changes to your networking infrastructure and the impact that will have on your reliability, even if very fancy Googlers say “this is what we do at Google”. (google engineers are doing great work on Kubernetes!! But I think it’s important to still look at the architecture and make sure it makes sense for your organization.) + +I’m definitely not a Kubernetes networking expert by any means, but I have run into a few issues while setting things up and definitely know a LOT more about Kubernetes networking than I used to. + +### Operating networking software is hard + +Here I’m not talking about operating physical networks (I don’t know anything about that), but instead about keeping software like DNS servers & load balancers & proxies working correctly. + +I have been working on a team that’s responsible for a lot of networking infrastructure for a year, and I have learned a few things about operating networking infrastructure! (though I still have a lot to learn obviously). 3 overall thoughts before we start: + +* Networking software often relies very heavily on the Linux kernel. So in addition to configuring the software correctly you also need to make sure that a bunch of different sysctls are set correctly, and a misconfigured sysctl can easily be the difference between “everything is 100% fine” and “everything is on fire”. + +* Networking requirements change over time (for example maybe you’re doing 5x more DNS lookups than you were last year! Maybe your DNS server suddenly started returning TCP DNS responses instead of UDP which is a totally different kernel workload!). This means software that was working fine before can suddenly start having issues. + +* To fix a production networking issues you often need a lot of expertise. (for example see this [great post by Sophie Haskins on debugging a kube-dns issue][1]) I’m a lot better at debugging networking issues than I was, but that’s only after spending a huge amount of time investing in my knowledge of Linux networking. + +I am still far from an expert at networking operations but I think it seems important to: + +1. Very rarely make major changes to the production networking infrastructure (because it’s super disruptive) + +2. When you  _are_  making major changes, think really carefully about what the failure modes are for the new network architecture are + +3. Have multiple people who are able to understand your networking setup + +Switching to Kubernetes is obviously a pretty major networking change! So let’s talk about what some of the things that can go wrong are! + +### Kubernetes networking components + +The Kubernetes networking components we’re going to talk about in this post are: + +* Your overlay network backend (like flannel/calico/weave net/romana) + +* `kube-dns` + +* `kube-proxy` + +* Ingress controllers / load balancers + +* The `kubelet` + +If you’re going to set up HTTP services you probably need all of these. I’m not using most of these components yet but I’m trying to understand them, so that’s what this post is about. + +### The simplest way: Use host networking for all your containers + +Let’s start with the simplest possible thing you can do. This won’t let you run HTTP services in Kubernetes. I think it’s pretty safe because there are less moving parts. + +If you use host networking for all your containers I think all you need to do is: + +1. Configure the kubelet to configure DNS correctly inside your containers + +2. That’s it + +If you use host networking for literally every pod you don’t need kube-dns or kube-proxy. You don’t even need a working overlay network. + +In this setup your pods can connect to the outside world (the same way any process on your hosts would talk to the outside world) but the outside world can’t connect to your pods. + +This isn’t super important (I think most people want to run HTTP services inside Kubernetes and actually communicate with those services) but I do think it’s interesting to realize that at some level all of this networking complexity isn’t strictly required and sometimes you can get away without using it. Avoiding networking complexity seems like a good idea to me if you can. + +### Operating an overlay network + +The first networking component we’re going to talk about is your overlay network. Kubernetes assumes that every pod has an IP address and that you can communicate with services inside that pod by using that IP address. When I say “overlay network” this is what I mean (“the system that lets you refer to a pod by its IP address”). + +All other Kubernetes networking stuff relies on the overlay networking working correctly. You can read more about the [kubernetes networking model here][10]. + +The way Kelsey Hightower describes in [kubernetes the hard way][11] seems pretty good but it’s not really viable on AWS for clusters more than 50 nodes or so, so I’m not going to talk about that. + +There are a lot of overlay network backends (calico, flannel, weaveworks, romana) and the landscape is pretty confusing. But as far as I’m concerned an overlay network has 2 responsibilities: + +1. Make sure your pods can send network requests outside your cluster + +2. Keep a stable mapping of nodes to subnets and keep every node in your cluster updated with that mapping. Do the right thing when nodes are added & removed. + +Okay! So! What can go wrong with your overlay network? + +* The overlay network is responsible for setting up iptables rules (basically `iptables -A -t nat POSTROUTING -s $SUBNET -j MASQUERADE`) to ensure that containers can make network requests outside Kubernetes. If something goes wrong with this rule then your containers can’t connect to the external network. This isn’t that hard (it’s just a few iptables rules) but it is important. I made a [pull request][2] because I wanted to make sure this was resilient + +* Something can go wrong with adding or deleting nodes. We’re using the flannel hostgw backend and at the time we started using it, node deletion [did not work][3]. + +* Your overlay network is probably dependent on a distributed database (etcd). If that database has an incident, this can cause issues. For example [https://github.com/coreos/flannel/issues/610][4] says that if you have data loss in your flannel etcd cluster it can result in containers losing network connectivity. (this has now been fixed) + +* You upgrade Docker and everything breaks + +* Probably more things! + +I’m mostly talking about past issues in Flannel here but I promise I’m not picking on Flannel – I actually really **like** Flannel because I feel like it’s relatively simple (for instance the [vxlan backend part of it][12] is like 500 lines of code) and I feel like it’s possible for me to reason through any issues with it. And it’s obviously continuously improving. They’ve been great about reviewing pull requests. + +My approach to operating an overlay network so far has been: + +* Learn how it works in detail and how to debug it (for example the hostgw network backend for Flannel works by creating routes, so you mostly just need to do `sudo ip route list` to see whether it’s doing the correct thing) + +* Maintain an internal build so it’s easy to patch it if needed + +* When there are issues, contribute patches upstream + +I think it’s actually really useful to go through the list of merged PRs and see bugs that have been fixed in the past – it’s a bit time consuming but is a great way to get a concrete list of kinds of issues other people have run into. + +It’s possible that for other people their overlay networks just work but that hasn’t been my experience and I’ve heard other folks report similar issues. If you have an overlay network setup that is a) on AWS and b) works on a cluster more than 50-100 nodes where you feel more confident about operating it I would like to know. + +### Operating kube-proxy and kube-dns? + +Now that we have some thoughts about operating overlay networks, let’s talk about + +There’s a question mark next to this one because I haven’t done this. Here I have more questions than answers. + +Here’s how Kubernetes services work! A service is a collection of pods, which each have their own IP address (like 10.1.0.3, 10.2.3.5, 10.3.5.6) + +1. Every Kubernetes service gets an IP address (like 10.23.1.2) + +2. `kube-dns` resolves Kubernetes service DNS names to IP addresses (so my-svc.my-namespace.svc.cluster.local might map to 10.23.1.2) + +3. `kube-proxy` sets up iptables rules in order to do random load balancing between them. Kube-proxy also has a userspace round-robin load balancer but my impression is that they don’t recommend using it. + +So when you make a request to `my-svc.my-namespace.svc.cluster.local`, it resolves to 10.23.1.2, and then iptables rules on your local host (generated by kube-proxy) redirect it to one of 10.1.0.3 or 10.2.3.5 or 10.3.5.6 at random. + +Some things that I can imagine going wrong with this: + +* `kube-dns` is misconfigured + +* `kube-proxy` dies and your iptables rules don’t get updated + +* Some issue related to maintaining a large number of iptables rules + +Let’s talk about the iptables rules a bit, since doing load balancing by creating a bajillion iptables rules is something I had never heard of before! + +kube-proxy creates one iptables rule per target host like this: (these rules are from [this github issue][13]) + +``` +-A KUBE-SVC-LI77LBOOMGYET5US -m comment --comment "default/showreadiness:showreadiness" -m statistic --mode random --probability 0.20000000019 -j KUBE-SEP-E4QKA7SLJRFZZ2DD[b][c] +-A KUBE-SVC-LI77LBOOMGYET5US -m comment --comment "default/showreadiness:showreadiness" -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-LZ7EGMG4DRXMY26H +-A KUBE-SVC-LI77LBOOMGYET5US -m comment --comment "default/showreadiness:showreadiness" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-RKIFTWKKG3OHTTMI +-A KUBE-SVC-LI77LBOOMGYET5US -m comment --comment "default/showreadiness:showreadiness" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-CGDKBCNM24SZWCMS +-A KUBE-SVC-LI77LBOOMGYET5US -m comment --comment "default/showreadiness:showreadiness" -j KUBE-SEP-RI4SRNQQXWSTGE2Y + +``` + +So kube-proxy creates a **lot** of iptables rules. What does that mean? What are the implications of that in for my network? There’s a great talk from Huawei called [Scale Kubernetes to Support 50,000 services][14] that says if you have 5,000 services in your kubernetes cluster, it takes **11 minutes** to add a new rule. If that happened to your real cluster I think it would be very bad. + +I definitely don’t have 5,000 services in my cluster, but 5,000 isn’t SUCH a bit number. The proposal they give to solve this problem is to replace this iptables backend for kube-proxy with IPVS which is a load balancer that lives in the Linux kernel. + +It seems like kube-proxy is going in the direction of various Linux kernel based load balancers. I think this is partly because they support UDP load balancing, and other load balancers (like HAProxy) don’t support UDP load balancing. + +But I feel comfortable with HAProxy! Is it possible to replace kube-proxy with HAProxy! I googled this and I found this [thread on kubernetes-sig-network][15] saying: + +> kube-proxy is so awesome, we have used in production for almost a year, it works well most of time, but as we have more and more services in our cluster, we found it was getting hard to debug and maintain. There is no iptables expert in our team, we do have HAProxy&LVS experts, as we have used these for several years, so we decided to replace this distributed proxy with a centralized HAProxy. I think this maybe useful for some other people who are considering using HAProxy with kubernetes, so we just update this project and make it open source: [https://github.com/AdoHe/kube2haproxy][5]. If you found it’s useful , please take a look and give a try. + +So that’s an interesting option! I definitely don’t have answers here, but, some thoughts: + +* Load balancers are complicated + +* DNS is also complicated + +* If you already have a lot of experience operating one kind of load balancer (like HAProxy), it might make sense to do some extra work to use that instead of starting to use an entirely new kind of load balancer (like kube-proxy) + +* I’ve been thinking about where we want to be using kube-proxy or kube-dns at all – I think instead it might be better to just invest in Envoy and rely entirely on Envoy for all load balancing & service discovery. So then you just need to be good at operating Envoy. + +As you can see my thoughts on how to operate your Kubernetes internal proxies are still pretty confused and I’m still not super experienced with them. It’s totally possible that kube-proxy and kube-dns are fine and that they will just work fine but I still find it helpful to think through what some of the implications of using them are (for example “you can’t have 5,000 Kubernetes services”). + +### Ingress + +If you’re running a Kubernetes cluster, it’s pretty likely that you actually need HTTP requests to get into your cluster so far. This blog post is already too long and I don’t know much about ingress yet so we’re not going to talk about that. + +### Useful links + +A couple of useful links, to summarize: + +* [The Kubernetes networking model][6] + +* How GKE networking works: [https://www.youtube.com/watch?v=y2bhV81MfKQ][7] + +* The aforementioned talk on `kube-proxy` performance: [https://www.youtube.com/watch?v=4-pawkiazEg][8] + +### I think networking operations is important + +My sense of all this Kubernetes networking software is that it’s all still quite new and I’m not sure we (as a community) really know how to operate all of it well. This makes me worried as an operator because I really want my network to keep working! :) Also I feel like as an organization running your own Kubernetes cluster you need to make a pretty large investment into making sure you understand all the pieces so that you can fix things when they break. Which isn’t a bad thing, it’s just a thing. + +My plan right now is just to keep learning about how things work and reduce the number of moving parts I need to worry about as much as possible. + +As usual I hope this was helpful and I would very much like to know what I got wrong in this post! + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2017/10/10/operating-a-kubernetes-network/ + +作者:[Julia Evans ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca/about +[1]:http://blog.sophaskins.net/blog/misadventures-with-kube-dns/ +[2]:https://github.com/coreos/flannel/pull/808 +[3]:https://github.com/coreos/flannel/pull/803 +[4]:https://github.com/coreos/flannel/issues/610 +[5]:https://github.com/AdoHe/kube2haproxy +[6]:https://kubernetes.io/docs/concepts/cluster-administration/networking/#kubernetes-model +[7]:https://www.youtube.com/watch?v=y2bhV81MfKQ +[8]:https://www.youtube.com/watch?v=4-pawkiazEg +[9]:https://jvns.ca/categories/kubernetes +[10]:https://kubernetes.io/docs/concepts/cluster-administration/networking/#kubernetes-model +[11]:https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/11-pod-network-routes.md +[12]:https://github.com/coreos/flannel/tree/master/backend/vxlan +[13]:https://github.com/kubernetes/kubernetes/issues/37932 +[14]:https://www.youtube.com/watch?v=4-pawkiazEg +[15]:https://groups.google.com/forum/#!topic/kubernetes-sig-network/3NlBVbTUUU0 diff --git a/sources/tech/20171121 Finding Files with mlocate- Part 3.md b/sources/tech/20171121 Finding Files with mlocate- Part 3.md new file mode 100644 index 0000000000..c9eccb2fc7 --- /dev/null +++ b/sources/tech/20171121 Finding Files with mlocate- Part 3.md @@ -0,0 +1,142 @@ +Finding Files with mlocate: Part 3 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/question-mark-2492009_1920.jpg?itok=stJ3GxL2) +In the previous articles in this short series, we [introduced the mlocate][1] (or just locate) command, and then discussed some ways [the updatedb tool][2] can be used to help you find that one particular file in a thousand. + +You are probably also aware of xargs as well as the find command. Our trusty friend locate can also play nicely with the --null option of xargs by outputting all of the results onto one line (without spaces which isn't great if you want to read it yourself) by using the -0 switch like this: +``` +# locate -0 .bash +``` + +An option I like to use (if I remember to use it -- because the locate command rarely needs to be queried twice thanks to its simple syntax) is the -e option. +``` +# locate -e .bash +``` + +For the curious, that -e switch means "existing." And, in this case, you can use -e to ensure that any files returned by the locate command do actually exist at the time of the query on your filesystems. + +It's almost magical, that even on a slow machine, the mastery of the modern locate command allows us to query its file database and then check against the actual existence of many files in seemingly no time whatsoever. Let's try a quick test with a file search that's going to return a zillion results and use the time command to see how long it takes both with and without the -e option being enabled. + +I'll choose files with the compressed .gz extension. Starting with a count, you can see there's not quite a zillion but a fair number of files ending in .gz on my machine, note the -c for "count": +``` +# locate -c .gz +7539 +``` + +This time, we'll output the list but time it and see the abbreviated results as follows: +``` +# time locate .gz +real 0m0.091s +user 0m0.025s +sys 0m0.012s +``` + +That's pretty swift, but it's only reading from the overnight-run database. Let's get it to do a check against those 7,539 files, too, to see if they truly exist and haven't been deleted or renamed since last night: +``` +# time locate -e .gz +real 0m0.096s +user 0m0.028s +sys 0m0.055s +``` + +The speed difference is nominal as you can see. There's no point in talking about lightning or blink-and-you-miss-it, because those aren't suitable yardsticks. Relative to the other indexing service I mentioned previously, let's just say that's pretty darned fast. + +If you need to move the efficient database file used by the locate command (in my version it lives here: /var/lib/mlocate/mlocate.db) then that's also easy to do. You may wish to do this, for example, because you've generated a massive database file (it's only 1.1MB in my case so it's really tiny in reality), which needs to be put onto a faster filesystem. + +Incidentally, even the mlocate utility appears to have created an slocate group of users on my machine, so don't be too alarmed if you see something similar, as shown here from a standard file listing: +``` +-rw-r-----. 1 root slocate 1.1M Jan 11 11:11 /var/lib/mlocate/mlocate.db +``` + +Back to the matter in hand. If you want to move away from /var/lib/mlocate as your directory being used by the database then you can use this command syntax (and you'll have to become the "root" user with sudo -i or su - for at least the first command to work correctly): +``` +# updatedb -o /home/chrisbinnie/my_new.db +# locate -d /home/chrisbinnie/my_new.db SEARCH_TERM +``` + +Obviously, replace your database name and path. The SEARCH_TERM element is the fragment of the filename that you're looking for (wildcards and all). + +If you remember I mentioned that you need to run updatedb command as the superuser to reach all the areas of your filesystems. + +This next example should cover two useful scenarios in one. According to the manual, you can also create a "private" database for standard users as follows: +``` +# updatedb -l 0 -o DATABASE -U source_directory +``` + +Here the previously seen -o option means that we output our database to a file (obviously called DATABASE). The -l 0 addition apparently means that the "visibility" of the database file is affected. It means (if I'm reading the docs correctly) that my user can read it but, otherwise, without that option, only the locate command can. + +The second useful scenario for this example is that we can create a little database file specifying exactly which path its top-level should be. Have a look at the database-root or -U source_directory option in our example. If you don't specify a new root file path, then the whole filesystem(s) is scanned instead. + +If you want to get clever and chuck a couple of top-level source directories into one command, then you can manage that having created two separate databases. Very useful for scripting methinks. + +You can achieve that with this command: +``` +# locate -d /home/chrisbinnie/database_one -d /home/chrisbinnie/database_two SEARCH_TERM +``` + +The manual dutifully warns however that ALL users that can read the DATABASE file can also get the complete list of files in the subdirectories of the chosen source_directory. So use these commands with some care. + +### Priced To Sell + +Back to the mind-blowing simplicity of the locate command in use on a day-to-day basis. There are many times when newbies may confused with case-sensitivity on Unix-type systems. Simply use the conventional -i option to ignore case entirely when using the flexible locate command: +``` +# locate -i ChrisBinnie.pdf +``` + +If you have a file structure that has a number of symlinks holding it together, then there might be occasion when you want to remove broken symlinks from the search results. You can do that with this command: +``` +# locate -Le chrisbinnie_111111.xml +``` + +If you needed to limit the search results then you could use this functionality, also in a script for example (similar to the -c option for counting), as so: +``` +# locate -l25 *.gz +``` + +This command simply stops after outputting the first 25 files that were found. When piped through the grep command, it's very useful on a super busy system. + +### Popular Area + +We briefly touched upon performance earlier, and I happened to see this [nicely written blog entry][3], where the author discusses thoughts on the trade-offs between the database size becoming unwieldy and the speed at which results are delivered. + +What piqued my interest are the comments on how the original locate command was written and what limiting factors were considered during its creation. Namely how disk space isn't quite so precious any longer and nor is the delivery of results even when 700,000 files are involved. + +I'm certain that the author(s) of mlocate and its forebears would have something to say in response to that blog post. I suspect that holding onto the file permissions to give us the "secure" and "slocate" functionality in the database might be a fairly big hit in terms of overhead. And, as much as I enjoyed the post, I won't be writing a Bash script to replace mlocate any time soon. I'm more than happy with the locate command and extol its qualities at every opportunity. + +### Sold + +I hope you've acquired enough insight into the superb locate command to prune, tweak, adjust, and tune it to your unique set of requirements. As we've seen, it's fast, convenient, powerful, and efficient. Additionally, you can ignore the "root" user demands and use it within scripts for very specific tasks. + +My favorite aspect, however, is when I'm awakened in the middle of the night because of an emergency. It's not a good look, having to remember the complex find command and typing it slowly with bleary eyes (and managing to add lots of typos): +``` +# find . -type f -name "*.gz" +``` + +Instead of that, I can just use the simple locate command: +``` +# locate *.gz +``` + +As has been said, any fool can create something bigger, bolder, and tougher, but it takes a bit of genius to create something simpler. And, in terms of introducing more people to the venerable Unix-type command line, there's little argument that the locate command welcomes them with open arms. + +Learn more about essential sysadmin skills: Download the [Future Proof Your SysAdmin Career][4] ebook now. + +Chris Binnie's latest book, Linux Server Security: Hack and Defend, shows how hackers launch sophisticated attacks to compromise servers, steal data, and crack complex passwords, so you can learn how to defend against these attacks. In the book, he also talks you through making your servers invisible, performing penetration testing, and mitigating unwelcome attacks. You can find out more about DevSecOps and Linux security via his website ([http://www.devsecops.cc][5]). + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2017/11/finding-files-mlocate-part-3 + +作者:[Chris Binnie][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/chrisbinnie +[1]:https://www.linux.com/blog/learn/intro-to-linux/2017/11/finding-files-mlocate +[2]:https://www.linux.com/blog/learn/intro-to-linux/finding-files-mlocate-part-2 +[3]:http://jvns.ca/blog/2015/03/05/how-the-locate-command-works-and-lets-rewrite-it-in-one-minute/ +[4]:https://go.pardot.com/l/6342/2017-07-17/3vwshv?utm_source=linco&utm_medium=blog&utm_campaign=sysadmin&utm_content=promo +[5]:http://www.devsecops.cc/ diff --git a/sources/tech/20171124 How do groups work on Linux.md b/sources/tech/20171124 How do groups work on Linux.md new file mode 100644 index 0000000000..3e9c386e01 --- /dev/null +++ b/sources/tech/20171124 How do groups work on Linux.md @@ -0,0 +1,143 @@ +HankChow Translating + +How do groups work on Linux? +============================================================ + +Hello! Last week, I thought I knew how users and groups worked on Linux. Here is what I thought: + +1. Every process belongs to a user (like `julia`) + +2. When a process tries to read a file owned by a group, Linux a) checks if the user `julia` can access the file, and b) checks which groups `julia` belongs to, and whether any of those groups owns & can access that file + +3. If either of those is true (or if the ‘any’ bits are set right) then the process can access the file + +So, for example, if a process is owned by the `julia` user and `julia` is in the `awesome` group, then the process would be allowed to read this file. + +``` +r--r--r-- 1 root awesome 6872 Sep 24 11:09 file.txt + +``` + +I had not thought carefully about this, but if pressed I would have said that it probably checks the `/etc/group` file at runtime to see what groups you’re in. + +### that is not how groups work + +I found out at work last week that, no, what I describe above is not how groups work. In particular Linux does **not** check which groups a process’s user belongs to every time that process tries to access a file. + +Here is how groups actually work! I learned this by reading Chapter 9 (“Process Credentials”) of [The Linux Programming Interface][1] which is an incredible book. As soon as I realized that I did not understand how users and groups worked, I opened up the table of contents with absolute confidence that it would tell me what’s up, and I was right. + +### how users and groups checks are done + +They key new insight for me was pretty simple! The chapter starts out by saying that user and group IDs are **attributes of the process**: + +* real user ID and group ID; + +* effective user ID and group ID; + +* saved set-user-ID and saved set-group-ID; + +* file-system user ID and group ID (Linux-specific); and + +* supplementary group IDs. + +This means that the way Linux **actually** does group checks to see a process can read a file is: + +* look at the process’s group IDs & supplementary group IDs (from the attributes on the process, **not** by looking them up in `/etc/group`) + +* look at the group on the file + +* see if they match + +Generally when doing access control checks it uses the **effective** user/group ID, not the real user/group ID. Technically when accessing a file it actually uses the **file-system** ids but those are usually the same as the effective uid/gid. + +### Adding a user to a group doesn’t put existing processes in that group + +Here’s another fun example that follows from this: if I create a new `panda` group and add myself (bork) to it, then run `groups` to check my group memberships – I’m not in the panda group! + +``` +bork@kiwi~> sudo addgroup panda +Adding group `panda' (GID 1001) ... +Done. +bork@kiwi~> sudo adduser bork panda +Adding user `bork' to group `panda' ... +Adding user bork to group panda +Done. +bork@kiwi~> groups +bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd + +``` + +no `panda` in that list! To double check, let’s try making a file owned by the `panda`group and see if I can access it: + +``` +$ touch panda-file.txt +$ sudo chown root:panda panda-file.txt +$ sudo chmod 660 panda-file.txt +$ cat panda-file.txt +cat: panda-file.txt: Permission denied + +``` + +Sure enough, I can’t access `panda-file.txt`. No big surprise there. My shell didn’t have the `panda` group as a supplementary GID before, and running `adduser bork panda` didn’t do anything to change that. + +### how do you get your groups in the first place? + +So this raises kind of a confusing question, right – if processes have groups baked into them, how do you get assigned your groups in the first place? Obviously you can’t assign yourself more groups (that would defeat the purpose of access control). + +It’s relatively clear how processes I **execute** from my shell (bash/fish) get their groups – my shell runs as me, and it has a bunch of group IDs on it. Processes I execute from my shell are forked from the shell so they get the same groups as the shell had. + +So there needs to be some “first” process that has your groups set on it, and all the other processes you set inherit their groups from that. That process is called your **login shell** and it’s run by the `login` program (`/bin/login`) on my laptop. `login` runs as root and calls a C function called `initgroups` to set up your groups (by reading `/etc/group`). It’s allowed to set up your groups because it runs as root. + +### let’s try logging in again! + +So! Let’s say I am running in a shell, and I want to refresh my groups! From what we’ve learned about how groups are initialized, I should be able to run `login` to refresh my groups and start a new login shell! + +Let’s try it: + +``` +$ sudo login bork +$ groups +bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd panda +$ cat panda-file.txt # it works! I can access the file owned by `panda` now! + +``` + +Sure enough, it works! Now the new shell that `login` spawned is part of the `panda` group! Awesome! This won’t affect any other shells I already have running. If I really want the new `panda` group everywhere, I need to restart my login session completely, which means quitting my window manager and logging in again. + +### newgrp + +Somebody on Twitter told me that if you want to start a new shell with a new group that you’ve been added to, you can use `newgrp`. Like this: + +``` +sudo addgroup panda +sudo adduser bork panda +newgrp panda # starts a new shell, and you don't have to be root to run it! + +``` + +You can accomplish the same(ish) thing with `sg panda bash` which will start a `bash` shell that runs with the `panda` group. + +### setuid sets the effective user ID + +I’ve also always been a little vague about what it means for a process to run as “setuid root”. It turns out that setuid sets the effective user ID! So if I (`julia`) run a setuid root process (like `passwd`), then the **real** user ID will be set to `julia`, and the **effective** user ID will be set to `root`. + +`passwd` needs to run as root, but it can look at its real user ID to see that `julia`started the process, and prevent `julia` from editing any passwords except for `julia`’s password. + +### that’s all! + +There are a bunch more details about all the edge cases and exactly how everything works in The Linux Programming Interface so I will not get into all the details here. That book is amazing. Everything I talked about in this post is from Chapter 9, which is a 17-page chapter inside a 1300-page book. + +The thing I love most about that book is that reading 17 pages about how users and groups work is really approachable, self-contained, super useful, and I don’t have to tackle all 1300 pages of it at once to learn helpful things :) + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2017/11/20/groups/ + +作者:[Julia Evans ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca/ +[1]:http://man7.org/tlpi/ diff --git a/sources/tech/20171224 My first Rust macro.md b/sources/tech/20171224 My first Rust macro.md new file mode 100644 index 0000000000..a8002e050b --- /dev/null +++ b/sources/tech/20171224 My first Rust macro.md @@ -0,0 +1,145 @@ +My first Rust macro +============================================================ + +Last night I wrote a Rust macro for the first time!! The most striking thing to me about this was how **easy** it was – I kind of expected it to be a weird hard finicky thing, and instead I found that I could go from “I don’t know how macros work but I think I could do this with a macro” to “wow I’m done” in less than an hour. + +I used [these examples][2] to figure out how to write my macro. + +### what’s a macro? + +There’s more than one kind of macro in Rust – + +* macros defined using `macro_rules` (they have an exclamation mark and you call them like functions – `my_macro!()`) + +* “syntax extensions” / “procedural macros” like `#[derive(Debug)]` (you put these like annotations on your functions) + +* built-in macros like `println!` + +[Macros in Rust][3] and [Macros in Rust part II][4] seems like a nice overview of the different kinds with examples + +I’m not actually going to try to explain what a macro **is**, instead I will just show you what I used a macro for yesterday and hopefully that will be interesting. I’m going to be talking about `macro_rules!`, I don’t understand syntax extension/procedural macros yet. + +### compiling the `get_stack_trace` function for 30 different Ruby versions + +I’d written some functions that got the stack trace out of a running Ruby program (`get_stack_trace`). But the function I wrote only worked for Ruby 2.2.0 – here’s what it looked like. Basically it imported some structs from `bindings::ruby_2_2_0` and then used them. + +``` +use bindings::ruby_2_2_0::{rb_control_frame_struct, rb_thread_t, RString}; +fn get_stack_trace(pid: pid_t) -> Vec { + // some code using rb_control_frame_struct, rb_thread_t, RString +} + +``` + +Let’s say I wanted to instead have a version of `get_stack_trace` that worked for Ruby 2.1.6. `bindings::ruby_2_2_0` and `bindings::ruby_2_1_6` had basically all the same structs in them. But `bindings::ruby_2_1_6::rb_thread_t` wasn’t the **same** as `bindings::ruby_2_2_0::rb_thread_t`, it just had the same name and most of the same struct members. + +So I could implement a working function for Ruby 2.1.6 really easily! I just need to basically replace `2_2_0` for `2_1_6`, and then the compiler would generate different code (because `rb_thread_t` is different). Here’s a sketch of what the Ruby 2.1.6 version would look like: + +``` +use bindings::ruby_2_1_6::{rb_control_frame_struct, rb_thread_t, RString}; +fn get_stack_trace(pid: pid_t) -> Vec { + // some code using rb_control_frame_struct, rb_thread_t, RString +} + +``` + +### what I wanted to do + +I basically wanted to write code like this, to generate a `get_stack_trace` function for every Ruby version. The code inside `get_stack_trace` would be the same in every case, it’s just the `use bindings::ruby_2_1_3` that needed to be different + +``` +pub mod ruby_2_1_3 { + use bindings::ruby_2_1_3::{rb_control_frame_struct, rb_thread_t, RString}; + fn get_stack_trace(pid: pid_t) -> Vec { + // insert code here + } +} +pub mod ruby_2_1_4 { + use bindings::ruby_2_1_4::{rb_control_frame_struct, rb_thread_t, RString}; + fn get_stack_trace(pid: pid_t) -> Vec { + // same code + } +} +pub mod ruby_2_1_5 { + use bindings::ruby_2_1_5::{rb_control_frame_struct, rb_thread_t, RString}; + fn get_stack_trace(pid: pid_t) -> Vec { + // same code + } +} +pub mod ruby_2_1_6 { + use bindings::ruby_2_1_6::{rb_control_frame_struct, rb_thread_t, RString}; + fn get_stack_trace(pid: pid_t) -> Vec { + // same code + } +} + +``` + +### macros to the rescue! + +This really repetitive thing was I wanted to do was a GREAT fit for macros. Here’s what using `macro_rules!` to do this looked like! + +``` +macro_rules! ruby_bindings( + ($ruby_version:ident) => ( + pub mod $ruby_version { + use bindings::$ruby_version::{rb_control_frame_struct, rb_thread_t, RString}; + fn get_stack_trace(pid: pid_t) -> Vec { + // insert code here + } + } +)); + +``` + +I basically just needed to put my code in and insert `$ruby_version` in the places I wanted it to go in. So simple! I literally just looked at an example, tried the first thing I thought would work, and it worked pretty much right away. + +(the [actual code][5] is more lines and messier but the usage of macros is exactly as simple in this example) + +I was SO HAPPY about this because I’d been worried getting this to work would be hard but instead it was so easy!! + +### dispatching to the right code + +Then I wrote some super simple dispatch code to call the right code depending on which Ruby version was running! + +``` + let version = get_api_version(pid); + let stack_trace_function = match version.as_ref() { + "2.1.1" => stack_trace::ruby_2_1_1::get_stack_trace, + "2.1.2" => stack_trace::ruby_2_1_2::get_stack_trace, + "2.1.3" => stack_trace::ruby_2_1_3::get_stack_trace, + "2.1.4" => stack_trace::ruby_2_1_4::get_stack_trace, + "2.1.5" => stack_trace::ruby_2_1_5::get_stack_trace, + "2.1.6" => stack_trace::ruby_2_1_6::get_stack_trace, + "2.1.7" => stack_trace::ruby_2_1_7::get_stack_trace, + "2.1.8" => stack_trace::ruby_2_1_8::get_stack_trace, + // and like 20 more versions + _ => panic!("OH NO OH NO OH NO"), + }; + +``` + +### it works! + +I tried out my prototype, and it totally worked! The same program could get stack traces out the running Ruby program for all of the ~10 different Ruby versions I tried – it figured which Ruby version was running, called the right code, and got me stack traces!! + +Previously I’d compile a version for Ruby 2.2.0 but then if I tried to use it for any other Ruby version it would crash, so this was a huge improvement. + +There are still more issues with this approach that I need to sort out. The two main ones right now are: firstly the ruby binary that ships with Debian doesn’t have symbols and I need the address of the current thread, and secondly it’s still possible that `#ifdefs` will ruin my day. + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2017/12/24/my-first-rust-macro/ + +作者:[Julia Evans ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca +[1]:https://jvns.ca/categories/ruby-profiler +[2]:https://gist.github.com/jfager/5936197 +[3]:https://www.ncameron.org/blog/macros-in-rust-pt1/ +[4]:https://www.ncameron.org/blog/macros-in-rust-pt2/ +[5]:https://github.com/jvns/ruby-stacktrace/blob/b0b92863564e54da59ea7f066aff5bb0d92a4968/src/lib.rs#L249-L393 diff --git a/sources/tech/20180104 How does gdb call functions.md b/sources/tech/20180104 How does gdb call functions.md new file mode 100644 index 0000000000..c88fae999e --- /dev/null +++ b/sources/tech/20180104 How does gdb call functions.md @@ -0,0 +1,254 @@ +translating by ucasFL + +How does gdb call functions? +============================================================ + +(previous gdb posts: [how does gdb work? (2016)][4] and [three things you can do with gdb (2014)][5]) + +I discovered this week that you can call C functions from gdb! I thought this was cool because I’d previously thought of gdb as mostly a read-only debugging tool. + +I was really surprised by that (how does that WORK??). As I often do, I asked [on Twitter][6] how that even works, and I got a lot of really useful answers! My favorite answer was [Evan Klitzke’s example C code][7] showing a way to do it. Code that  _works_  is very exciting! + +I believe (through some stracing & experiments) that that example C code is different from how gdb actually calls functions, so I’ll talk about what I’ve figured out about what gdb does in this post and how I’ve figured it out. + +There is a lot I still don’t know about how gdb calls functions, and very likely some things in here are wrong. + +### What does it mean to call a C function from gdb? + +Before I get into how this works, let’s talk quickly about why I found it surprising / nonobvious. + +So, you have a running C program (the “target program”). You want to run a function from it. To do that, you need to basically: + +* pause the program (because it is already running code!) + +* find the address of the function you want to call (using the symbol table) + +* convince the program (the “target program”) to jump to that address + +* when the function returns, restore the instruction pointer and registers to what they were before + +Using the symbol table to figure out the address of the function you want to call is pretty straightforward – here’s some sketchy (but working!) Rust code that I’ve been using on Linux to do that. This code uses the [elf crate][8]. If I wanted to find the address of the `foo` function in PID 2345, I’d run `elf_symbol_value("/proc/2345/exe", "foo")`. + +``` +fn elf_symbol_value(file_name: &str, symbol_name: &str) -> Result> { + // open the ELF file + let file = elf::File::open_path(file_name).ok().ok_or("parse error")?; + // loop over all the sections & symbols until you find the right one! + let sections = &file.sections; + for s in sections { + for sym in file.get_symbols(&s).ok().ok_or("parse error")? { + if sym.name == symbol_name { + return Ok(sym.value); + } + } + } + None.ok_or("No symbol found")? +} + +``` + +This won’t totally work on its own, you also need to look at the memory maps of the file and add the symbol offset to the start of the place that file is mapped. But finding the memory maps isn’t so hard, they’re in `/proc/PID/maps`. + +Anyway, this is all to say that finding the address of the function to call seemed straightforward to me but that the rest of it (change the instruction pointer? restore the registers? what else?) didn’t seem so obvious! + +### You can’t just jump + +I kind of said this already but – you can’t just find the address of the function you want to run and then jump to that address. I tried that in gdb (`jump foo`) and the program segfaulted. Makes sense! + +### How you can call C functions from gdb + +First, let’s see that this is possible. I wrote a tiny C program that sleeps for 1000 seconds and called it `test.c`: + +``` +#include + +int foo() { + return 3; +} +int main() { + sleep(1000); +} + +``` + +Next, compile and run it: + +``` +$ gcc -o test test.c +$ ./test + +``` + +Finally, let’s attach to the `test` program with gdb: + +``` +$ sudo gdb -p $(pgrep -f test) +(gdb) p foo() +$1 = 3 +(gdb) quit + +``` + +So I ran `p foo()` and it ran the function! That’s fun. + +### Why is this useful? + +a few possible uses for this: + +* it lets you treat gdb a little bit like a C REPL, which is fun and I imagine could be useful for development + +* utility functions to display / navigate complex data structures quickly while debugging in gdb (thanks [@invalidop][1]) + +* [set an arbitrary process’s namespace while it’s running][2] (featuring a not-so-surprising appearance from my colleague [nelhage][3]!) + +* probably more that I don’t know about + +### How it works + +I got a variety of useful answers on Twitter when I asked how calling functions from gdb works! A lot of them were like “well you get the address of the function from the symbol table” but that is not the whole story!! + +One person pointed me to this nice 2 part series on how gdb works that they’d written: [Debugging with the natives, part 1][9] and [Debugging with the natives, part 2][10]. Part 1 explains approximately how calling functions works (or could work – figuring out what gdb **actually** does isn’t trivial, but I’ll try my best!). + +The steps outlined there are: + +1. Stop the process + +2. Create a new stack frame (far away from the actual stack) + +3. Save all the registers + +4. Set the registers to the arguments you want to call your function with + +5. Set the stack pointer to the new stack frame + +6. Put a trap instruction somewhere in memory + +7. Set the return address to that trap instruction + +8. Set the instruction pointer register to the address of the function you want to call + +9. Start the process again! + +I’m not going to go through how gdb does all of these (I don’t know!) but here are a few things I’ve learned about the various pieces this evening. + +**Create a stack frame** + +If you’re going to run a C function, most likely it needs a stack to store variables on! You definitely don’t want it to clobber your current stack. Concretely – before gdb calls your function (by setting the instruction pointer to it and letting it go), it needs to set the **stack pointer** to… something. + +There was some speculation on Twitter about how this works: + +> i think it constructs a new stack frame for the call right on top of the stack where you’re sitting! + +and: + +> Are you certain it does that? It could allocate a pseudo stack, then temporarily change sp value to that location. You could try, put a breakpoint there and look at the sp register address, see if it’s contiguous to your current program register? + +I did an experiment where (inside gdb) I ran:` + +``` +(gdb) p $rsp +$7 = (void *) 0x7ffea3d0bca8 +(gdb) break foo +Breakpoint 1 at 0x40052a +(gdb) p foo() +Breakpoint 1, 0x000000000040052a in foo () +(gdb) p $rsp +$8 = (void *) 0x7ffea3d0bc00 + +``` + +This seems in line with the “gdb constructs a new stack frame for the call right on top of the stack where you’re sitting” theory, since the stack pointer (`$rsp`) goes from being `...bca8` to `..bc00` – stack pointers grow downward, so a `bc00`stack pointer is **after** a `bca8` pointer. Interesting! + +So it seems like gdb just creates the new stack frames right where you are. That’s a bit surprising to me! + +**change the instruction pointer** + +Let’s see whether gdb changes the instruction pointer! + +``` +(gdb) p $rip +$1 = (void (*)()) 0x7fae7d29a2f0 <__nanosleep_nocancel+7> +(gdb) b foo +Breakpoint 1 at 0x40052a +(gdb) p foo() +Breakpoint 1, 0x000000000040052a in foo () +(gdb) p $rip +$3 = (void (*)()) 0x40052a + +``` + +It does! The instruction pointer changes from `0x7fae7d29a2f0` to `0x40052a` (the address of the `foo` function). + +I stared at the strace output and I still don’t understand **how** it changes, but that’s okay. + +**aside: how breakpoints are set!!** + +Above I wrote `break foo`. I straced gdb while running all of this and understood almost nothing but I found ONE THING that makes sense to me!! + +Here are some of the system calls that gdb uses to set a breakpoint. It’s really simple! It replaces one instruction with `cc` (which [https://defuse.ca/online-x86-assembler.htm][11] tells me means `int3` which means `send SIGTRAP`), and then once the program is interrupted, it puts the instruction back the way it was. + +I was putting a breakpoint on a function `foo` with the address `0x400528`. + +This `PTRACE_POKEDATA` is how gdb changes the code of running programs. + +``` +// change the 0x400528 instructions +25622 ptrace(PTRACE_PEEKTEXT, 25618, 0x400528, [0x5d00000003b8e589]) = 0 +25622 ptrace(PTRACE_POKEDATA, 25618, 0x400528, 0x5d00000003cce589) = 0 +// start the program running +25622 ptrace(PTRACE_CONT, 25618, 0x1, SIG_0) = 0 +// get a signal when it hits the breakpoint +25622 ptrace(PTRACE_GETSIGINFO, 25618, NULL, {si_signo=SIGTRAP, si_code=SI_KERNEL, si_value={int=-1447215360, ptr=0x7ffda9bd3f00}}) = 0 +// change the 0x400528 instructions back to what they were before +25622 ptrace(PTRACE_PEEKTEXT, 25618, 0x400528, [0x5d00000003cce589]) = 0 +25622 ptrace(PTRACE_POKEDATA, 25618, 0x400528, 0x5d00000003b8e589) = 0 + +``` + +**put a trap instruction somewhere** + +When gdb runs a function, it **also** puts trap instructions in a bunch of places! Here’s one of them (per strace). It’s basically replacing one instruction with `cc` (`int3`). + +``` +5908 ptrace(PTRACE_PEEKTEXT, 5810, 0x7f6fa7c0b260, [0x48f389fd89485355]) = 0 +5908 ptrace(PTRACE_PEEKTEXT, 5810, 0x7f6fa7c0b260, [0x48f389fd89485355]) = 0 +5908 ptrace(PTRACE_POKEDATA, 5810, 0x7f6fa7c0b260, 0x48f389fd894853cc) = 0 + +``` + +What’s `0x7f6fa7c0b260`? Well, I looked in the process’s memory maps, and it turns it’s somewhere in `/lib/x86_64-linux-gnu/libc-2.23.so`. That’s weird! Why is gdb putting trap instructions in libc? + +Well, let’s see what function that’s in. It turns out it’s `__libc_siglongjmp`. The other functions gdb is putting traps in are `__longjmp`, `____longjmp_chk`, `dl_main`, and `_dl_close_worker`. + +Why? I don’t know! Maybe for some reason when our function `foo()` returns, it’s calling `longjmp`, and that is how gdb gets control back? I’m not sure. + +### how gdb calls functions is complicated! + +I’m going to stop there (it’s 1am!), but now I know a little more! + +It seems like the answer to “how does gdb call a function?” is definitely not that simple. I found it interesting to try to figure a little bit of it out and hopefully you have too! + +I still have a lot of unanswered questions about how exactly gdb does all of these things, but that’s okay. I don’t really need to know the details of how this works and I’m happy to have a slightly improved understanding. + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/ + +作者:[Julia Evans ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca/ +[1]:https://twitter.com/invalidop/status/949161146526781440 +[2]:https://github.com/baloo/setns/blob/master/setns.c +[3]:https://github.com/nelhage +[4]:https://jvns.ca/blog/2016/08/10/how-does-gdb-work/ +[5]:https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/ +[6]:https://twitter.com/b0rk/status/948060808243765248 +[7]:https://github.com/eklitzke/ptrace-call-userspace/blob/master/call_fprintf.c +[8]:https://cole14.github.io/rust-elf +[9]:https://www.cl.cam.ac.uk/~srk31/blog/2016/02/25/#native-debugging-part-1 +[10]:https://www.cl.cam.ac.uk/~srk31/blog/2017/01/30/#native-debugging-part-2 +[11]:https://defuse.ca/online-x86-assembler.htm diff --git a/sources/tech/20180109 Profiler adventures resolving symbol addresses is hard.md b/sources/tech/20180109 Profiler adventures resolving symbol addresses is hard.md new file mode 100644 index 0000000000..971f575f5f --- /dev/null +++ b/sources/tech/20180109 Profiler adventures resolving symbol addresses is hard.md @@ -0,0 +1,163 @@ +Profiler adventures: resolving symbol addresses is hard! +============================================================ + +The other day I posted [How does gdb call functions?][1]. In that post I said: + +> Using the symbol table to figure out the address of the function you want to call is pretty straightforward + +Unsurprisingly, it turns out that figuring out the address in memory corresponding to a given symbol is actually not really that straightforward. This is actually something I’ve been doing in my profiler, and I think it’s interesting, so I thought I’d write about it! + +Basically the problem I’ve been trying to solve is – I have a symbol (like `ruby_api_version`), and I want to figure out which address that symbol is mapped to in my target process’s memory (so that I can get the data in it, like the Ruby process’s Ruby version). So far I’ve run into (and fixed!) 3 issues when trying to do this: + +1. When binaries are loaded into memory, they’re loaded at a random address (so I can’t just read the symbol table) + +2. The symbol I want isn’t necessary in the “main” binary (`/proc/PID/exe`, sometimes it’s in some other dynamically linked library) + +3. I need to look at the ELF program header to adjust which address I look at for the symbol + +I’ll start with some background, and then explain these 3 things! (I actually don’t know what gdb does) + +### what’s a symbol? + +Most binaries have functions and variables in them. For instance, Perl has a global variable called `PL_bincompat_options` and a function called `Perl_sv_catpv_mg`. + +Sometimes binaries need to look up functions from another binary (for example, if the binary is a dynamically linked library, you need to look up its functions by name). Also sometimes you’re debugging your code and you want to know what function an address corresponds to. + +Symbols are how you look up functions / variables in a binary. They’re in a section called the “symbol table”. The symbol table is basically an index for your binary! Sometimes they’re missing (“stripped”). There are a lot of binary formats, but this post is just about the usual binary format on Linux: ELF. + +### how do you get the symbol table of a binary? + +A thing that I learned today (or at least learned and then forgot) is that there are 2 possible sections symbols can live in: `.symtab` and `.dynsym`. `.dynsym` is the “dynamic symbol table”. According to [this page][2], the dynsym is a smaller version of the symtab that only contains global symbols. + +There are at least 3 ways to read the symbol table of a binary on Linux: you can use nm, objdump, or readelf. + +* **read the .symtab**: `nm $FILE`, `objdump --syms $FILE`, `readelf -a $FILE` + +* **read the .dynsym**: `nm -D $FILE`, `objdump --dynamic-syms $FILE`, `readelf -a $FILE` + +`readelf -a` is the same in both cases because `readelf -a` just shows you everything in an ELF file. It’s my favorite because I don’t need to guess where the information I want is, I can just print out everything and then use grep. + +Here’s an example of some of the symbols in `/usr/bin/perl`. You can see that each symbol has a **name**, a **value**, and a **type**. The value is basically the offset of the code/data corresponding to that symbol in the binary. (except some symbols have value 0\. I think that has something to do with dynamic linking but I don’t understand it so we’re not going to get into it) + +``` +$ readelf -a /usr/bin/perl +... + Num: Value Size Type Ndx Name + 523: 00000000004d6590 49 FUNC 14 Perl_sv_catpv_mg + 524: 0000000000543410 7 FUNC 14 Perl_sv_copypv + 525: 00000000005a43e0 202 OBJECT 16 PL_bincompat_options + 526: 00000000004e6d20 2427 FUNC 14 Perl_pp_ucfirst + 527: 000000000044a8c0 1561 FUNC 14 Perl_Gv_AMupdate +... + +``` + +### the question we want to answer: what address is a symbol mapped to? + +That’s enough background! + +Now – suppose I’m a debugger, and I want to know what address the `ruby_api_version` symbol is mapped to. Let’s use readelf to look at the relevant Ruby binary! + +``` +readelf -a ~/.rbenv/versions/2.1.6/bin/ruby | grep ruby_api_version + 365: 00000000001f9180 12 OBJECT GLOBAL DEFAULT 15 ruby_api_version + +``` + +Neat! The offset of `ruby_api_version` is `0x1f9180`. We’re done, right? Of course not! :) + +### Problem 1: ASLR (Address space layout randomization) + +Here’s the first issue: when Linux loads a binary into memory (like `~/.rbenv/versions/2.1.6/bin/ruby`), it doesn’t just load it at the `0` address. Instead, it usually adds a random offset. Wikipedia’s article on ASLR explains why: + +> Address space layout randomization (ASLR) is a memory-protection process for operating systems (OSes) that guards against buffer-overflow attacks by randomizing the location where system executables are loaded into memory. + +We can see this happening in practice: I started `/home/bork/.rbenv/versions/2.1.6/bin/ruby` 3 times and every time the process gets mapped to a different place in memory. (`0x56121c86f000`, `0x55f440b43000`, `0x56163334a000`) + +Here we’re meeting our good friend `/proc/$PID/maps` – this file contains a list of memory maps for a process. The memory maps tell us every address range in the process’s virtual memory (it turns out virtual memory isn’t contiguous! Instead process get a bunch of possibly-disjoint memory maps!). This file is so useful! You can find the address of the stack, the heap, every dynamically loaded library, anonymous memory maps, and probably more. + +``` +$ cat /proc/(pgrep -f 2.1.6)/maps | grep 'bin/ruby' +56121c86f000-56121caf0000 r-xp 00000000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +56121ccf0000-56121ccf5000 r--p 00281000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +56121ccf5000-56121ccf7000 rw-p 00286000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +$ cat /proc/(pgrep -f 2.1.6)/maps | grep 'bin/ruby' +55f440b43000-55f440dc4000 r-xp 00000000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +55f440fc4000-55f440fc9000 r--p 00281000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +55f440fc9000-55f440fcb000 rw-p 00286000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +$ cat /proc/(pgrep -f 2.1.6)/maps | grep 'bin/ruby' +56163334a000-5616335cb000 r-xp 00000000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +5616337cb000-5616337d0000 r--p 00281000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby +5616337d0000-5616337d2000 rw-p 00286000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby + +``` + +Okay, so in the last example we see that our binary is mapped at `0x56163334a000`. If we combine this with the knowledge that `ruby_api_version` is at `0x1f9180`, then that means that we just need to look that the address `0x1f9180 + 0x56163334a000` to find our variable, right? + +Yes! In this case, that works. But in other cases it won’t! So that brings us to problem 2. + +### Problem 2: dynamically loaded libraries + +Next up, I tried running system Ruby: `/usr/bin/ruby`. This binary has basically no symbols at all! Disaster! In particular it does not have a `ruby_api_version`symbol. + +But when I tried to print the `ruby_api_version` variable with gdb, it worked!!! Where was gdb finding my symbol? I found the answer with the help of our good friend: `/proc/PID/maps` + +It turns out that `/usr/bin/ruby` dynamically loads a library called `libruby-2.3`. You can see it in the memory maps here: + +``` +$ cat /proc/(pgrep -f /usr/bin/ruby)/maps | grep libruby +7f2c5d789000-7f2c5d9f1000 r-xp 00000000 00:14 /usr/lib/x86_64-linux-gnu/libruby-2.3.so.2.3.0 +7f2c5d9f1000-7f2c5dbf0000 ---p 00268000 00:14 /usr/lib/x86_64-linux-gnu/libruby-2.3.so.2.3.0 +7f2c5dbf0000-7f2c5dbf6000 r--p 00267000 00:14 /usr/lib/x86_64-linux-gnu/libruby-2.3.so.2.3.0 +7f2c5dbf6000-7f2c5dbf7000 rw-p 0026d000 00:14 /usr/lib/x86_64-linux-gnu/libruby-2.3.so.2.3.0 + +``` + +And if we read it with `readelf`, we find the address of that symbol! + +``` +readelf -a /usr/lib/x86_64-linux-gnu/libruby-2.3.so.2.3.0 | grep ruby_api_version + 374: 00000000001c72f0 12 OBJECT GLOBAL DEFAULT 13 ruby_api_version + +``` + +So in this case the address of the symbol we want is `0x7f2c5d789000` (the start of the libruby-2.3 memory map) plus `0x1c72f0`. Nice! But we’re still not done. There is (at least) one more mystery! + +### Problem 3: the `vaddr` offset in the ELF program header + +This one I just figured out today so it’s the one I have the shakiest understanding of. Here’s what happened. + +I was running system ruby on Ubuntu 14.04: Ruby 1.9.3\. And my usual code (find the libruby map, get its address, get the symbol offset, add them up) wasn’t working!!! I was confused. + +But I’d asked Julian if he knew of any weird stuff I need to worry about a while back and he said “well, you should read the code for `dlsym`, you’re trying to do basically the same thing”. So I decided to, instead of randomly guessing, go read the code for `dlsym`. + +The man page for `dlsym` says “dlsym, dlvsym - obtain address of a symbol in a shared object or executable”. Perfect!! + +[Here’s the dlsym code from musl I read][3]. (musl is like glibc, but, different. Maybe easier to read? I don’t understand it that well.) + +The dlsym code says (on line 1468) `return def.dso->base + def.sym->st_value;` That sounds like what I’m doing!! But what’s `dso->base`? It looks like `base = map - addr_min;`, and `addr_min = ph->p_vaddr;`. (there’s also some stuff that makes sure `addr_min` is aligned with the page size which I should maybe pay attention to.) + +So the code I want is something like `map_base - ph->p_vaddr + sym->st_value`. + +I looked up this `vaddr` thing in the ELF program header, subtracted it from my calculation, and voilà! It worked!!! + +### there are probably more problems! + +I imagine I will discover even more ways that I am calculating the symbol address wrong. It’s interesting that such a seemingly simple thing (“what’s the address of this symbol?”) is so complicated! + +It would be nice to be able to just call `dlsym` and have it do all the right calculations for me, but I think I can’t because the symbol is in a different process. Maybe I’m wrong about that though! I would like to be wrong about that. If you know an easier way to do all this I would very much like to know! + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2018/01/09/resolving-symbol-addresses/ + +作者:[Julia Evans ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca +[1]:https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/ +[2]:https://blogs.oracle.com/ali/inside-elf-symbol-tables +[3]:https://github.com/esmil/musl/blob/194f9cf93da8ae62491b7386edf481ea8565ae4e/src/ldso/dynlink.c#L1451 From 9bc0397637ab2bb6dab29813ea5b6efc261fb5f3 Mon Sep 17 00:00:00 2001 From: sugarfillet <1911093465@qq.com> Date: Sun, 4 Mar 2018 22:23:19 +0800 Subject: [PATCH 089/101] translating by sugarfillet --- ...Plasma Mobile Could Give Life to a Mobile Linux Experience.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md b/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md index 583714836e..caceb0db7a 100644 --- a/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md +++ b/sources/tech/20180223 Plasma Mobile Could Give Life to a Mobile Linux Experience.md @@ -1,3 +1,4 @@ +translating by sugarfillet Plasma Mobile Could Give Life to a Mobile Linux Experience ====== From 82c83722850126bd231a01042eae8b45a21d1adb Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 4 Mar 2018 23:20:27 +0800 Subject: [PATCH 090/101] PRF:20180102 HTTP errors in WordPress.md @wenwensnow --- .../tech/20180102 HTTP errors in WordPress.md | 155 ++++++++---------- 1 file changed, 71 insertions(+), 84 deletions(-) diff --git a/translated/tech/20180102 HTTP errors in WordPress.md b/translated/tech/20180102 HTTP errors in WordPress.md index 5acb3613be..ee2c5c7390 100644 --- a/translated/tech/20180102 HTTP errors in WordPress.md +++ b/translated/tech/20180102 HTTP errors in WordPress.md @@ -1,32 +1,29 @@ -WordPress 中的HTTP错误 +如何修复 WordPress 中的 HTTP 错误 ====== + ![http error wordpress][1] -我们会向你介绍,如何修复WordPress中的HTTP错误(在Linux VPS上)。 下面列出了WordPress用户遇到的最常见的HTTP错误,我们的建议侧重于如何发现错误原因以及解决方法。 +我们会向你介绍,如何在 Linux VPS 上修复 WordPress 中的 HTTP 错误。 下面列出了 WordPress 用户遇到的最常见的 HTTP 错误,我们的建议侧重于如何发现错误原因以及解决方法。 +### 1、 修复在上传图像时出现的 HTTP 错误 +如果你在基于 WordPress 的网页中上传图像时出现错误,这也许是因为服务器上 PHP 的配置,例如存储空间不足或者其他配置问题造成的。 -### 1\. 修复在上传图像时出现的HTTP错误 - -如果你在基于WordPress的网页中上传图像时出现错误,这也许是因为服务器上PHP配置,例如存储空间不足或者其他配置问题造成的。 - - -用如下命令查找php配置文件: - +用如下命令查找 php 配置文件: ``` -#php -i | grep php.ini +php -i | grep php.ini Configuration File (php.ini) Path => /etc Loaded Configuration File => /etc/php.ini ``` -根据输出结果,php配置文件位于 '/etc'文件夹下。编辑 '/etc/php.ini'文件,找出下列行,并按照下面的例子修改其中相对应的值: - +根据输出结果,php 配置文件位于 `/etc` 文件夹下。编辑 `/etc/php.ini` 文件,找出下列行,并按照下面的例子修改其中相对应的值: ``` vi /etc/php.ini ``` + ``` upload_max_filesize = 64M post_max_size = 32M @@ -35,18 +32,17 @@ max_input_time 300 memory_limit = 128M ``` -当然,如果你不习惯使用vi文本编辑器,你可以选用自己喜欢的。 - +当然,如果你不习惯使用 vi 文本编辑器,你可以选用自己喜欢的。 不要忘记重启你的网页服务器来让改动生效。 - -如果你安装的网页服务器是Apache,你需要使用 .htaccess文件。首先,找到 .htaccess 文件。它位于WordPress安装路径的根文件夹下。如果没有找到 .htaccess文件,需要自己手动创建一个,然后加入如下内容: +如果你安装的网页服务器是 Apache,你也可以使用 `.htaccess` 文件。首先,找到 `.htaccess` 文件。它位于 WordPress 安装路径的根文件夹下。如果没有找到 `.htaccess` 文件,需要自己手动创建一个,然后加入如下内容: ``` vi /www/html/path_to_wordpress/.htaccess ``` + ``` php_value upload_max_filesize 64M php_value post_max_size 32M @@ -55,132 +51,123 @@ php_value max_input_time 180 # BEGIN WordPress -RewriteEngine On -RewriteBase / -RewriteRule ^index\.php$ - [L] -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule . /index.php [L] + RewriteEngine On + RewriteBase / + RewriteRule ^index\.php$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.php [L] # END WordPress ``` -如果你使用的网页服务器是nginx,在WordPress实例中具体配置nginx服务器的设置。详细配置和下面的例子相似: + +如果你使用的网页服务器是 nginx,在 nginx 的 `server` 配置块中配置你的 WordPress 实例。详细配置和下面的例子相似: ``` server { -listen 80; -client_max_body_size 128m; -client_body_timeout 300; + listen 80; + client_max_body_size 128m; + client_body_timeout 300; -server_name your-domain.com www.your-domain.com; + server_name your-domain.com www.your-domain.com; -root /var/www/html/wordpress; -index index.php; + root /var/www/html/wordpress; + index index.php; -location = /favicon.ico { -log_not_found off; -access_log off; -} + location = /favicon.ico { + log_not_found off; + access_log off; + } -location = /robots.txt { -allow all; -log_not_found off; -access_log off; -} + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } -location / { -try_files $uri $uri/ /index.php?$args; -} + location / { + try_files $uri $uri/ /index.php?$args; + } -location ~ \.php$ { -include fastcgi_params; -fastcgi_pass 127.0.0.1:9000; -fastcgi_index index.php; -fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; -} + location ~ \.php$ { + include fastcgi_params; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } -location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { -expires max; -log_not_found off; -} + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + expires max; + log_not_found off; + } } ``` -根据自己的PHP配置,你需要将 'fastcgi_pass 127.0.0.1:9000;' 用类似于 'fastcgi_pass unix:/var/run/php7-fpm.sock;' 替换掉(依照实际连接方式) +根据自己的 PHP 配置,你需要将 `fastcgi_pass 127.0.0.1:9000;` 用类似于 `fastcgi_pass unix:/var/run/php7-fpm.sock;` 替换掉(依照实际连接方式) +重启 nginx 服务来使改动生效。 -重启nginx服务来使改动生效。 +### 2、 修复因为不恰当的文件权限而产生的 HTTP 错误 - - -### 2\. 修复因为不恰当的文件权限而产生的HTTP错误 - -如果你在WordPress中出现一个意外错误,也许是因为不恰当的文件权限导致的,所以需要给WordPress文件和文件夹设置一个正确的权限: +如果你在 WordPress 中出现一个意外错误,也许是因为不恰当的文件权限导致的,所以需要给 WordPress 文件和文件夹设置一个正确的权限: ``` chown www-data:www-data -R /var/www/html/path_to_wordpress/ ``` -将 'www-data' 替换成实际的网页服务器用户,将 '/var/www/html/path_to_wordpress' 换成WordPress的实际安装路径。 +将 `www-data` 替换成实际的网页服务器用户,将 `/var/www/html/path_to_wordpress` 换成 WordPress 的实际安装路径。 +### 3、 修复因为内存不足而产生的 HTTP 错误 -### 3\. 修复因为内存不足而产生的HTTP错误 - -你可以通过在wp-config.php中添加如下内容来设置PHP的最大内存限制: +你可以通过在 `wp-config.php` 中添加如下内容来设置 PHP 的最大内存限制: ``` - define('WP_MEMORY_LIMIT', '128MB'); +define('WP_MEMORY_LIMIT', '128MB'); ``` -### 4\. 修复因为PHP.INI文件错误配置而产生的HTTP错误 +### 4、 修复因为 php.ini 文件错误配置而产生的 HTTP 错误 -编辑PHP配置主文件,然后找到 'cgi.fix_pathinfo' 这一行。 这一行内容默认情况下是被注释掉的,默认值为1。取消这一行的注释(删掉这一行最前面的分号),然后将1改为0.同时需要修改 'date.timezone' 这一PHP设置,再次编辑 PHP 配置文件并将这一选项改成 'date.timezone = US/Central' (或者将等号后内容改为你所在的时区) +编辑 PHP 配置主文件,然后找到 `cgi.fix_pathinfo` 这一行。 这一行内容默认情况下是被注释掉的,默认值为 `1`。取消这一行的注释(删掉这一行最前面的分号),然后将 `1` 改为 `0` 。同时需要修改 `date.timezone` 这一 PHP 设置,再次编辑 PHP 配置文件并将这一选项改成 `date.timezone = Asia/Shanghai` (或者将等号后内容改为你所在的时区)。 ``` - vi /etc/php.ini +vi /etc/php.ini ``` ``` - cgi.fix_pathinfo=0 - date.timezone = America/New_York +cgi.fix_pathinfo=0 +date.timezone = Asia/Shanghai ``` -### 5. 修复因为Apache mod_security模块而产生的HTTP错误 +### 5、 修复因为 Apache mod_security 模块而产生的 HTTP 错误 -如果你在使用 Apache mod_security 模块,这可能也会引起问题。试着禁用这一模块,确认是否因为在 .htaccess 文件中加入如下内容而引起了问题: +如果你在使用 Apache mod_security 模块,这可能也会引起问题。试着禁用这一模块,确认是否因为在 `.htaccess` 文件中加入如下内容而引起了问题: ``` -SecFilterEngine Off -SecFilterScanPOST Off + SecFilterEngine Off + SecFilterScanPOST Off ``` -### 6. 修复因为有问题的插件/主题而产生的HTTP错误 - -一些插件或主题也会导致HTTP错误以及其他问题。你可以首先禁用有问题的插件/主题,或暂时禁用所有WordPress插件。如果你有phpMyAdmin,使用它来禁用所有插件:在其中找到 wp_options这一表格,在 option_name 这一列中找到 'active_plugins' 这一行,然后将 option_value 改为 :a:0:{} +### 6、 修复因为有问题的插件/主题而产生的 HTTP 错误 +一些插件或主题也会导致 HTTP 错误以及其他问题。你可以首先禁用有问题的插件/主题,或暂时禁用所有 WordPress 插件。如果你有 phpMyAdmin,使用它来禁用所有插件:在其中找到 `wp_options` 数据表,在 `option_name` 这一列中找到 `active_plugins` 这一记录,然后将 `option_value` 改为 :`a:0:{}`。 或者用以下命令通过SSH重命名插件所在文件夹: ``` - mv /www/html/path_to_wordpress/wp-content/plugins /www/html/path_to_wordpress/wp-content/plugins.old +mv /www/html/path_to_wordpress/wp-content/plugins /www/html/path_to_wordpress/wp-content/plugins.old ``` -通常情况下,HTTP错误会被记录在网页服务器的日志文件中,所以寻找错误时一个很好的切入点就是查看服务器日志。 - - -如果你在使用WordPress VPS主机服务的话,你不需要自己去修复WordPress中出现的HTTP错误。你只要让你的Linux管理员来处理它们,他们24小时在线并且会立刻开始着手解决你的问题。 - - +通常情况下,HTTP 错误会被记录在网页服务器的日志文件中,所以寻找错误时一个很好的切入点就是查看服务器日志。 -------------------------------------------------------------------------------- via: https://www.rosehosting.com/blog/http-error-wordpress/ 作者:[rosehosting][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[wenwensnow](https://github.com/wenwensnow) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From a922a0633829cf77f5e4c4fd6be0febf7904f236 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 4 Mar 2018 23:21:51 +0800 Subject: [PATCH 091/101] PUB:20180102 HTTP errors in WordPress.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @wenwensnow https://linux.cn/article-9404-1.html 下回记得写译者哦~ --- .../tech => published}/20180102 HTTP errors in WordPress.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180102 HTTP errors in WordPress.md (100%) diff --git a/translated/tech/20180102 HTTP errors in WordPress.md b/published/20180102 HTTP errors in WordPress.md similarity index 100% rename from translated/tech/20180102 HTTP errors in WordPress.md rename to published/20180102 HTTP errors in WordPress.md From 290648f081942de1c3f4dc0b8c6cd9171ceb0249 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 4 Mar 2018 23:36:26 +0800 Subject: [PATCH 092/101] PRF:20180111 The Fold Command Tutorial With Examples For Beginners.md @Flowsnow --- ...nd Tutorial With Examples For Beginners.md | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/translated/tech/20180111 The Fold Command Tutorial With Examples For Beginners.md b/translated/tech/20180111 The Fold Command Tutorial With Examples For Beginners.md index 9cc63eb46a..c5ebfdc98f 100644 --- a/translated/tech/20180111 The Fold Command Tutorial With Examples For Beginners.md +++ b/translated/tech/20180111 The Fold Command Tutorial With Examples For Beginners.md @@ -1,24 +1,24 @@ -Fold命令入门级示例教程 +fold 命令入门示例教程 ====== ![](https://www.ostechnix.com/wp-content/uploads/2018/01/Fold-Command-2-720x340.png) -你有没有发现自己在某种情况下想要折叠或打破命令的输出用于适应特定的宽度? 在运行虚拟机的时候,我遇到了几次这种的情况,特别是没有GUI的服务器。 以防万一,如果你想限制一个命令的输出为一个特定的宽度,现在看看这里! **fold**命令在这里就能派的上用场了! fold命令以适合指定的宽度调整输入文件中的每一行并将其打印到标准输出。 +你有没有发现自己在某种情况下想要折叠或中断命令的输出,以适应特定的宽度?在运行虚拟机的时候,我遇到了几次这种的情况,特别是没有 GUI 的服务器。 以防万一,如果你想限制一个命令的输出为一个特定的宽度,现在看看这里! `fold` 命令在这里就能派的上用场了! `fold` 命令会以适合指定的宽度调整输入文件中的每一行,并将其打印到标准输出。 -在这个简短的教程中,我们将看到fold命令的用法,带有实例哦。 +在这个简短的教程中,我们将看到 `fold` 命令的用法,带有实例。 -### fold命令示例教程 +### fold 命令示例教程 -fold命令是GNU coreutils包的一部分,所以我们不用为安装的事情烦恼。 +`fold` 命令是 GNU coreutils 包的一部分,所以我们不用为安装的事情烦恼。 + +`fold` 命令的典型语法: -fold命令的典型语法: ``` fold [OPTION]... [FILE]... ``` -请允许我向您展示一些示例,以便您更好地了解fold命令。 我有一个名为linux.txt文件,内容是随机的。 +请允许我向您展示一些示例,以便您更好地了解 `fold` 命令。 我有一个名为 `linux.txt` 文件,内容是随机的。 -Allow me to show you some examples, so you can get a better idea about fold command. I have a file named **linux.txt** with some random lines. ![][2] @@ -28,19 +28,19 @@ Allow me to show you some examples, so you can get a better idea about fold comm fold linux.txt ``` -每行**80**列是默认的宽度。 这里是上述命令的输出: +每行 80 列是默认的宽度。 这里是上述命令的输出: ![][3] -正如你在上面的输出中看到的,fold命令已经将输出限制为80个字符的宽度。 +正如你在上面的输出中看到的,`fold` 命令已经将输出限制为 80 个字符的宽度。 -当然,我们可以指定您的首选宽度,例如50,如下所示: +当然,我们可以指定您的首选宽度,例如 50,如下所示: ``` fold -w50 linux.txt ``` -Sample output would be: +示例输出: ![][4] @@ -50,7 +50,7 @@ Sample output would be: fold -w50 linux.txt > linux1.txt ``` -以上命令将把**linux.txt**的行宽度改为50个字符,并将输出写入到名为**linux1.txt**的新文件中。 +以上命令将把 `linux.txt` 的行宽度改为 50 个字符,并将输出写入到名为 `linux1.txt` 的新文件中。 让我们检查一下新文件的内容: @@ -60,9 +60,9 @@ cat linux1.txt ![][5] -你有没有注意到前面的命令的输出? 有些词在行之间被打破。 为了解决这个问题,我们可以使用-s标志来在空格处换行。 +你有没有注意到前面的命令的输出? 有些词在行之间被中断。 为了解决这个问题,我们可以使用 `-s` 标志来在空格处换行。 -以下命令将给定文件中的每行调整为宽度“50”,并在空格处换到新行: +以下命令将给定文件中的每行调整为宽度 50,并在空格处换到新行: ``` fold -w50 -s linux.txt @@ -72,28 +72,29 @@ fold -w50 -s linux.txt ![][6] -看清楚了吗? 现在,输出很清楚。 换到新行中的单词都是用空格隔开的,所在行单词的长度大于50的时候就会被调整到下一行。 +看清楚了吗? 现在,输出很清楚。 换到新行中的单词都是用空格隔开的,所在行单词的长度大于 50 的时候就会被调整到下一行。 -在所有上面的例子中,我们用列来限制输出宽度。 但是,我们可以使用**-b**选项将输出的宽度强制为指定的字节数。 以下命令以20个字节中断输出。 +在所有上面的例子中,我们用列来限制输出宽度。 但是,我们可以使用 `-b` 选项将输出的宽度强制为指定的字节数。 以下命令以 20 个字节中断输出。 ``` fold -b20 linux.txt ``` -Sample output: +示例输出: ![][7] -**另请阅读:** +另请阅读: -+ [Unix命令入门级示例教程][8] +- [Uniq 命令入门级示例教程][8] + +有关更多详细信息,请参阅 man 手册页。 -有关更多详细信息,请参阅man手册页。 ``` man fold ``` -而且,这些就是所有的内容了。 您现在知道如何使用fold命令以适应特定的宽度来限制命令的输出。 我希望这是有用的。 我们将每天发布更多有用的指南。 敬请关注! +这些就是所有的内容了。 您现在知道如何使用 `fold` 命令以适应特定的宽度来限制命令的输出。 我希望这是有用的。 我们将每天发布更多有用的指南。 敬请关注! 干杯! @@ -103,7 +104,7 @@ via: https://www.ostechnix.com/fold-command-tutorial-examples-beginners/ 作者:[SK][a] 译者:[Flowsnow](https://github.com/Flowsnow) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From a3c0df93ab62f93bc2d3c2672c7da7b45ccf8a8c Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 4 Mar 2018 23:36:56 +0800 Subject: [PATCH 093/101] PUB:20180111 The Fold Command Tutorial With Examples For Beginners.md @Flowsnow https://linux.cn/article-9405-1.html --- ...80111 The Fold Command Tutorial With Examples For Beginners.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180111 The Fold Command Tutorial With Examples For Beginners.md (100%) diff --git a/translated/tech/20180111 The Fold Command Tutorial With Examples For Beginners.md b/published/20180111 The Fold Command Tutorial With Examples For Beginners.md similarity index 100% rename from translated/tech/20180111 The Fold Command Tutorial With Examples For Beginners.md rename to published/20180111 The Fold Command Tutorial With Examples For Beginners.md From f5051559037959916c6683823b781b641290b07a Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 5 Mar 2018 00:29:07 +0800 Subject: [PATCH 094/101] PRF:20171218 Whats CGManager.md @geekpi --- translated/tech/20171218 Whats CGManager.md | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/translated/tech/20171218 Whats CGManager.md b/translated/tech/20171218 Whats CGManager.md index a21776eea7..41c9fd71be 100644 --- a/translated/tech/20171218 Whats CGManager.md +++ b/translated/tech/20171218 Whats CGManager.md @@ -1,47 +1,47 @@ -什么是 CGManager?[][1] +什么是 CGManager? ============================================================ CGManager 是一个核心的特权守护进程,通过一个简单的 D-Bus API 管理你所有的 cgroup。它被设计用来处理嵌套的 LXC 容器以及接受无特权的请求,包括解析用户名称空间的 UID/GID。 -# 组件[][2] +### 组件 -### cgmanager[][3] +#### cgmanager -这个守护进程在主机上运行,​​将 cgroupfs 挂载到一个独立的挂载名称空间(所以它不能从主机上看到),绑定 /sys/fs/cgroup/cgmanager/sock 用于传入的 D-Bus 查询,并通常处理主机上直接运行的所有客户端。 +这个守护进程在宿主机上运行,​​将 cgroupfs 挂载到一个独立的挂载名称空间(所以它不能从宿主机上看到),绑定 `/sys/fs/cgroup/cgmanager/sock` 用于传入的 D-Bus 查询,并通常处理宿主机上直接运行的所有客户端。 -cgmanager 同时接受使用 D-Bus + SCM 凭证的身份验证请求,用于在命名空间之间转换 uid、gid 和 pid,或者使用简单的 “unauthenticated”(只是初始的 ucred)D-Bus 来查询来自主机级别的查询。 +cgmanager 既接受使用 D-Bus + SCM 凭证的身份验证请求,用于在命名空间之间转换 uid、gid 和 pid,也可以使用简单的 “unauthenticated”(只是初始的 ucred)D-Bus 来查询来自宿主机级别的查询。 -### cgproxy[][4] +#### cgproxy -你可能会在两种情况下看到这个守护进程运行。在主机上,如果你的内核小于 3.8(没有 pidns 连接支持)或在容器中(只有 cgproxy 运行)。 +你可能会在两种情况下看到这个守护进程运行。在宿主机上,如果你的内核老于 3.8(没有 pidns 连接支持)或处于容器中(只有 cgproxy 运行)。 cgproxy 本身并不做任何 cgroup 配置更改,而是如其名称所示,代理请求给主 cgmanager 进程。 -这是必要的,所以一个进程可以直接使用 D-Bus(例如使用 dbus-send)与 /sys/fs/cgroup/cgmanager/sock 进行通信。 +这是必要的,所以一个进程可以直接使用 D-Bus(例如使用 dbus-send)与 `/sys/fs/cgroup/cgmanager/sock` 进行通信。 -之后 cgproxy 将从该查询中得到 ucred,并对真正的 cgmanager 套接字进行经过身份验证的 SCM 查询,并通过 ucred 结构体传递参数,使它们能够正确地转换为 cgmanager 可以理解的主机命名空间 。 +之后 cgproxy 将从该查询中得到 ucred,并对真正的 cgmanager 套接字进行身份验证的 SCM 查询,并通过 ucred 结构体传递参数,使它们能够正确地转换为 cgmanager 可以理解的宿主机命名空间 。 -### cgm[][5] +#### cgm 一个简单的命令行工具,与 D-Bus 服务通信,并允许你从命令行执行所有常见的 cgroup 操作。 -# 通信协议[][6] +### 通信协议 如上所述,cgmanager 和 cgproxy 使用 D-Bus。建议外部客户端(所以不要是 cgproxy)使用标准的 D-Bus API,不要试图实现 SCM creds 协议,因为它是不必要的,并且容易出错。 -相反,只要简单假设与 /sys/fs/cgroup/cgmanager/sock 的通信总是正确的。 +相反,只要简单假设与 `/sys/fs/cgroup/cgmanager/sock` 的通信总是正确的。 cgmanager API 仅在独立的 D-Bus 套接字上可用,cgmanager 本身不连接到系统总线,所以 cgmanager/cgproxy 不要求有运行中的 dbus 守护进程。 你可以在[这里][7]阅读更多关于 D-Bus API。 -# Licensing[][8] +### 许可证 CGManager 是免费软件,大部分代码是根据 GNU LGPLv2.1+ 许可条款发布的,一些二进制文件是在 GNU GPLv2 许可下发布的。 该项目的默认许可证是 GNU LGPLv2.1+ -# Support[][9] +### 支持 CGManager 的稳定版本支持依赖于 Linux 发行版以及它们自己承诺推出稳定修复和安全更新。 @@ -51,9 +51,9 @@ CGManager 的稳定版本支持依赖于 Linux 发行版以及它们自己承诺 via: https://linuxcontainers.org/cgmanager/introduction/ -作者:[Canonical Ltd. ][a] +作者:[Canonical Ltd.][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 389fac14e8321b2e64a2966aed68f268d0a52d38 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 5 Mar 2018 00:29:31 +0800 Subject: [PATCH 095/101] PUB:20171218 Whats CGManager.md @geekpi --- {translated/tech => published}/20171218 Whats CGManager.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171218 Whats CGManager.md (100%) diff --git a/translated/tech/20171218 Whats CGManager.md b/published/20171218 Whats CGManager.md similarity index 100% rename from translated/tech/20171218 Whats CGManager.md rename to published/20171218 Whats CGManager.md From 532909a7ff2034f93eac969acba8a4e32ef5870c Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 5 Mar 2018 00:59:35 +0800 Subject: [PATCH 096/101] PUB:20171121 How to organize your passwords using pass password manager.md @lujun9972 @locez https://linux.cn/article-9407-1.html --- ...r passwords using pass password manager.md | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) rename {translated/tech => published}/20171121 How to organize your passwords using pass password manager.md (52%) diff --git a/translated/tech/20171121 How to organize your passwords using pass password manager.md b/published/20171121 How to organize your passwords using pass password manager.md similarity index 52% rename from translated/tech/20171121 How to organize your passwords using pass password manager.md rename to published/20171121 How to organize your passwords using pass password manager.md index be460cc720..8f8f183a02 100644 --- a/translated/tech/20171121 How to organize your passwords using pass password manager.md +++ b/published/20171121 How to organize your passwords using pass password manager.md @@ -3,11 +3,11 @@ ### 目标 -学习在 Linux 上使用 "pass" 密码管理器来管理你的密码 +学习在 Linux 上使用 pass 密码管理器来管理你的密码 ### 条件 - * 需要 root 权限来安装需要的包 + * 需要 root 权限来安装需要的包 ### 难度 @@ -15,75 +15,81 @@ ### 约定 - * **#** - 执行指定命令需要 root 权限,可以是直接使用 root 用户来执行或者使用 `sudo` 命令来执行 - * **$** - 使用普通的非特权用户执行指定命令 + * `#` - 执行指定命令需要 root 权限,可以是直接使用 root 用户来执行或者使用 `sudo` 命令来执行 + * `$` - 使用普通的非特权用户执行指定命令 ### 介绍 -如果你有根据不同的意图设置不同密码的好习惯,你可能已经感受到需要一个密码管理器的必要性了。在 Linux 上有很多选择,可以是专利软件(如果你敢的话)也可以是开源软件。如果你跟我一样喜欢简洁的话,你可能会对 `pass` 感兴趣。 +如果你有根据不同的意图设置不同密码的好习惯,你可能已经感受到需要一个密码管理器的必要性了。在 Linux 上有很多选择,可以是专有软件(如果你敢用的话)也可以是开源软件。如果你跟我一样喜欢简洁的话,你可能会对 `pass` 感兴趣。 -### First steps +### 第一步 -Pass 作为一个密码管理器,其实际上是一些你可能早已每天使用的、可信赖且实用的工具的一种封装,比如 `gpg` 和 `git` 。虽然它也有图形界面,但它专门设计能成在命令行下工作的:因此它也可以在 headless machines 上工作 (LCTT 注:根据 wikipedia 的说法,所谓 headless machines 是指没有显示器、键盘和鼠标的机器,一般通过网络链接来控制)。 +pass 作为一个密码管理器,其实际上是一些你可能早已每天使用的、可信赖且实用的工具的一种封装,比如 `gpg` 和 `git` 。虽然它也有图形界面,但它专门设计能成在命令行下工作的:因此它也可以在 headless 机器上工作(LCTT 译注:根据 wikipedia 的说法,所谓 headless 是指没有显示器、键盘和鼠标的机器,一般通过网络链接来控制)。 -### 步骤 1 - 安装 +### 安装 -Pass 在主流的 linux 发行版中都是可用的,你可以通过包管理器安装: +pass 在主流的 Linux 发行版中都是可用的,你可以通过包管理器安装: #### Fedora + ``` # dnf install pass ``` -#### RHEL and CentOS +#### RHEL 和 CentOS + +pass 不在官方仓库中,但你可以从 `epel` 中获取道它。要在 CentOS7 上启用后面这个源,只需要执行: -Pass 不在官方仓库中,但你可以从 `epel` 中获取道它。要在 CentOS7 上启用后面这个源,只需要执行: ``` # yum install epel-release ``` -然而在 Red Hat 企业版的 Linux 上,这个额外的源是不可用的;你需要从 EPEL 官方网站上下载它。 +然而在 Red Hat 企业版的 Linux 上,这个额外的源是不可用的;你需要从 EPEL 官方网站上下载它。 + +#### Debian 和 Ubuntu -#### Debian and Ubuntu ``` # apt-get install pass ``` #### Arch Linux + ``` # pacman -S pass ``` ### 初始化密码仓库 -安装好 `pass` 后,就可以开始使用和配置它了。首先,由于 pass 依赖 `gpg` 来对我们的密码进行加密并以安全的方式进行存储,我们必须准备好一个 `gpg 密钥对`。 +安装好 `pass` 后,就可以开始使用和配置它了。首先,由于 `pass` 依赖于 `gpg` 来对我们的密码进行加密并以安全的方式进行存储,我们必须准备好一个 gpg 密钥对。 + +首先我们要初始化密码仓库:这就是一个用来存放 gpg 加密后的密码的目录。默认情况下它会在你的 `$HOME` 创建一个隐藏目录,不过你也可以通过使用 `PASSWORD_STORE_DIR` 这一环境变量来指定另一个路径。让我们运行: -首先我们要初始化 `密码仓库`:这就是一个用来存放 gpg 加密后的密码的目录。默认情况下它会在你的 `$HOME` 创建一个隐藏目录,不过你也可以通过使用 `PASSWORD_STORE_DIR` 这一环境变量来指定另一个路径。让我们运行: ``` $ pass init ``` -然后`密码仓库`目录就创建好了。现在,让我们来存储我们第一个密码: +然后 `password-store` 目录就创建好了。现在,让我们来存储我们第一个密码: + ``` $ pass edit mysite ``` 这会打开默认文本编辑器,我么只需要输入密码就可以了。输入的内容会用 gpg 加密并存储为密码仓库目录中的 `mysite.gpg` 文件。 -Pass 以目录树的形式存储加密后的文件,也就是说我们可以在逻辑上将多个文件放在子目录中以实现更好的组织形式,我们只需要在创建文件时指定存在哪个目录下就行了,像这样: +`pass` 以目录树的形式存储加密后的文件,也就是说我们可以在逻辑上将多个文件放在子目录中以实现更好的组织形式,我们只需要在创建文件时指定存在哪个目录下就行了,像这样: + ``` $ pass edit foo/bar ``` 跟上面的命令一样,它也会让你输入密码,但是创建的文件是放在密码仓库目录下的 `foo` 子目录中的。要查看文件组织结构,只需要不带任何参数运行 `pass` 命令即可: -``` +``` $ pass Password Store ├── foo │   └── bar └── mysite - ``` 若想修改密码,只需要重复创建密码的操作就行了。 @@ -91,11 +97,13 @@ Password Store ### 获取密码 有两种方法可以获取密码:第一种会显示密码到终端上,方法是运行: + ``` pass mysite ``` -然而更好的方法是使用 `-c` 选项让 pass 将密码直接拷贝到剪切板上: +然而更好的方法是使用 `-c` 选项让 `pass` 将密码直接拷贝到剪切板上: + ``` pass -c mysite ``` @@ -104,29 +112,32 @@ pass -c mysite ### 生成密码 -Pass 也可以为我们自动生成(并自动存储)安全密码。假设我们想要生成一个由 15 个字符组成的密码:包含字母,数字和特殊符号,其命令如下: +`pass` 也可以为我们自动生成(并自动存储)安全密码。假设我们想要生成一个由 15 个字符组成的密码:包含字母,数字和特殊符号,其命令如下: + ``` pass generate mysite 15 ``` -若希望密码只包含字母和数字则可以是使用 `--no-symbols` 选项。生成的密码会显示在屏幕上。也可以通过 `--clip` 或 `-c` 选项让 pass 把密码直接拷贝到剪切板中。通过使用 `-q` 或 `--qrcode` 选项来生成二维码: +若希望密码只包含字母和数字则可以是使用 `--no-symbols` 选项。生成的密码会显示在屏幕上。也可以通过 `--clip` 或 `-c` 选项让 `pass` 把密码直接拷贝到剪切板中。通过使用 `-q` 或 `--qrcode` 选项来生成二维码: ![qrcode][1] -从上面的截屏中尅看出,生成了一个二维码,不过由于 `mysite` 的密码已经存在了,pass 会提示我们确认是否要覆盖原密码。 +从上面的截屏中可看出,生成了一个二维码,不过由于运行该命令时 `mysite` 的密码已经存在了,`pass` 会提示我们确认是否要覆盖原密码。 -Pass 使用 `/dev/urandom` 设备作为(伪)随机数据生成器来生成密码,同时它使用 `xclip` 工具来将密码拷贝到粘帖板中,同时使用 `qrencode` 来将密码以二维码的形式显示出来。在我看来,这种模块化的设计正是它最大的优势:它并不重复造轮子,而只是将常用的工具包装起来完成任务。 +`pass` 使用 `/dev/urandom` 设备作为(伪)随机数据生成器来生成密码,同时它使用 `xclip` 工具来将密码拷贝到粘帖板中,而使用 `qrencode` 来将密码以二维码的形式显示出来。在我看来,这种模块化的设计正是它最大的优势:它并不重复造轮子,而只是将常用的工具包装起来完成任务。 -你也可以使用 `pass mv`,`pass cp`,和 `pass rm` 来重命名,拷贝和删除密码仓库中的文件。 +你也可以使用 `pass mv`、`pass cp` 和 `pass rm` 来重命名、拷贝和删除密码仓库中的文件。 ### 将密码仓库变成 git 仓库 `pass` 另一个很棒的功能就是可以将密码仓库当成 git 仓库来用:通过版本管理系统能让我们管理密码更方便。 + ``` pass git init ``` 这会创建 git 仓库,并自动提交所有已存在的文件。下一步就是指定跟踪的远程仓库了: + ``` pass git remote add ``` @@ -135,7 +146,6 @@ pass git remote add `pass` 有一个叫做 `qtpass` 的图形界面,而且也支持 Windows 和 MacOs。通过使用 `PassFF` 插件,它还能获取 firefox 中存储的密码。在它的项目网站上可以查看更多详细信息。试一下 `pass` 吧,你不会失望的! - -------------------------------------------------------------------------------- via: https://linuxconfig.org/how-to-organize-your-passwords-using-pass-password-manager @@ -147,4 +157,4 @@ via: https://linuxconfig.org/how-to-organize-your-passwords-using-pass-password- 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://linuxconfig.org -[1]:/https://linuxconfig.org/images/pass-manager-qrcode.png +[1]:https://linuxconfig.org/images/pass-manager-qrcode.png From de5d2c90e50ccc1d748562e5882ce9779f861eed Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 5 Mar 2018 08:49:29 +0800 Subject: [PATCH 097/101] translated --- .../20180129 How programmers learn to code.md | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) rename {sources => translated}/tech/20180129 How programmers learn to code.md (51%) diff --git a/sources/tech/20180129 How programmers learn to code.md b/translated/tech/20180129 How programmers learn to code.md similarity index 51% rename from sources/tech/20180129 How programmers learn to code.md rename to translated/tech/20180129 How programmers learn to code.md index 1253985dba..a9fa843d5b 100644 --- a/sources/tech/20180129 How programmers learn to code.md +++ b/translated/tech/20180129 How programmers learn to code.md @@ -1,44 +1,42 @@ -translating----geekpi - -How programmers learn to code +程序员如何学习编码 ============================================================ [![How programmers learn to code](https://mybroadband.co.za/news/wp-content/uploads/2016/01/Programmer-working-computer-code.jpg)][8] -HackerRank recently published the results of its 2018 Developer Skills Report, in which it asked programmers when they started coding. +HackerRank 最近公布了 2018 年开发者技能报告的结果,其中向程序员询问了他们何时开始编码。 -39,441 professional and student developers completed the online survey from 16 October to 1 November 2016, with over 25% of the developers surveyed writing their first piece of code before they were 16 years old. +39,441 名专业和学生开发者于 2016 年 10 月 16 日至 11 月 1 日完成了在线调查,超过 25% 的被调查的开发者在 16 岁前编写了他们的第一段代码。 -### How programmers learn +### 程序员是如何学习的 -In terms of how programmers learnt to code, self-teaching is the norm for developers of all ages, stated the report. +报告称,就程序员如何学习编码而言,自学是所有年龄段开发者的常态。 -“Even though 67% of developers have computer science degrees, roughly 74% said they were at least partially self-taught.” +“尽管 67% 的开发者拥有计算机科学学位,但大约 74% 的人表示他们至少一部分是自学的。” -On average, developers know four languages, but they want to learn four more. +开发者平均了解四种语言,但他们想学习更多语言。 -The thirst for learning varies by generations – developers between 18 and 24 plan to learn six languages, whereas developers older than 35 only plan to learn three. +对学习的渴望因人而异 - 18 至 24 岁的开发者计划学习 6 种语言,而 35 岁以上的开发者只计划学习 3 种语言。 [![HackerRank 2018 how did you learn to code](https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-did-you-learn-to-code.jpg)][5] -### What programmers want +### 程序员想要什么 -HackerRank also looked at what developers want most from an employer. +HackerRank 还研究了开发者最想从雇主那里得到什么。 -On average, a good work-life balance, closely followed by professional growth and learning, was the most desired requirement. +平均而言,良好的工作与生活平衡,紧随其后的是专业成长与学习,是最理想的要求。 -Segmenting the data by region revealed that Americans crave work-life balance more than developers Asia and Europe. +按地区划分的数据显示,美国人比亚洲和欧洲的开发者更渴望工作与生活的平衡。 -Students tend to rank growth and learning over work-life balance, while professionals rate compensation more highly than students do. +学生倾向于将成长和学习列在工作与生活的平衡之上,而专业人员对薪酬的排名比学生高得多。 -People who work in smaller companies tended to rank work-life balance lower, but it was still in their top three. +在小公司工作的人倾向于降低工作与生活的平衡,但仍处于前三名。 -Age also made a difference, with developers 25 and older rating work-life balance as most important, while those between 18 and 24 rate it as less important. +年龄也制造了不同,25 岁以上的开发者将工作与生活的平衡评为最重要的,而 18 岁至 24 岁的人们则认为其重要性较低。 -“In some ways, we’ve discovered a slight contradiction here. Developers want work-life balance, but they also have an insatiable thirst and need for learning,” said HackerRank. +HackerRank 说:“在某些方面,我们发现了一个小矛盾。开发人员需要工作与生活的平衡,但他们也渴望学习“。 -It advised that focusing on doing what you enjoy, as opposed to trying to learning everything, can help strike a better work-life balance. +它建议,专注于做你喜欢的事情,而不是试图学习一切,这可以帮助实现更好的工作与生活的平衡。 [![HackerRank 2018 what do developers want most](https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-what-do-developers-want-most-640x342.jpg)][6] @@ -49,7 +47,7 @@ It advised that focusing on doing what you enjoy, as opposed to trying to learni via: https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html 作者:[Staff Writer ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[geekpi](https://github.com/geekpi) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 49811e19df5781a664effd7e5148e8b22ac355fe Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 5 Mar 2018 08:53:16 +0800 Subject: [PATCH 098/101] translating --- ...5 of the Best Linux Dark Themes that Are Easy on the Eyes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md b/sources/tech/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md index db70cd8732..16918d59dd 100644 --- a/sources/tech/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md +++ b/sources/tech/20180119 5 of the Best Linux Dark Themes that Are Easy on the Eyes.md @@ -1,3 +1,5 @@ +translatng---geekpi + 5 of the Best Linux Dark Themes that Are Easy on the Eyes ====== From 965e219987e1c97b5f9d3143f571b4a9b2e53aab Mon Sep 17 00:00:00 2001 From: imquanquan Date: Mon, 5 Mar 2018 10:37:52 +0800 Subject: [PATCH 099/101] applying to translating --- ... 9 Lightweight Linux Applications to Speed Up Your System.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20170310 9 Lightweight Linux Applications to Speed Up Your System.md b/sources/tech/20170310 9 Lightweight Linux Applications to Speed Up Your System.md index 5d5696cf6c..1a273a60a2 100644 --- a/sources/tech/20170310 9 Lightweight Linux Applications to Speed Up Your System.md +++ b/sources/tech/20170310 9 Lightweight Linux Applications to Speed Up Your System.md @@ -1,3 +1,5 @@ +translating by imquanquan + 9 Lightweight Linux Applications to Speed Up Your System ====== **Brief:** One of the many ways to [speed up Ubuntu][1] system is to use lightweight alternatives of the popular applications. We have already seen [must have Linux application][2] earlier. we'll see the lightweight alternative applications for Ubuntu and other Linux distributions. From a87f041cd61d6971dfd364bc8a6ad46d03b82300 Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Mon, 5 Mar 2018 11:02:09 +0800 Subject: [PATCH 100/101] Delete 20171017 What Are the Hidden Files in my Linux Home Directory For.md --- ...en Files in my Linux Home Directory For.md | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md diff --git a/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md b/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md deleted file mode 100644 index 9021bd1183..0000000000 --- a/sources/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md +++ /dev/null @@ -1,63 +0,0 @@ -Translating by MjSeven - -What Are the Hidden Files in my Linux Home Directory For? -====== - -![](https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-linux-hero.png) - -In your Linux system you probably store a lot of files and folders in your Home directory. But beneath those files, do you know that your Home directory also comes with a lot of hidden files and folders? If you run `ls -a` on your home directory, you'll discover a pile of hidden files and directories with dot prefixes. What do these hidden files do anyway? - -### What are hidden files in the home directory for? - -![hidden-files-liunux-2][1] - -Most commonly, hidden files and directories in the home directory contain settings or data that's accessed by that user's programs. They're not intended to be edited by the user, only the application. That's why they're hidden from the user's normal view. - -In general files from your own home directory can be removed and changed without damaging the operating system. The applications that rely on those hidden files, however, might not be as flexible. When you remove a hidden file from the home directory, you'll typically lose the settings for the application associated with it. - -The program that relied on that hidden file will typically recreate it. However, you'll be starting from the "out-of-the-box" settings, like a brand new user. If you're having trouble with an application, that can actually be a huge help. It lets you remove customizations that might be causing trouble. But if you're not, it just means you'll need to set everything back the way you like it. - - -### What are some specific uses of hidden files in the home directory? -![hidden-files-linux-3][2] - -Everyone will have different hidden files in their home directory. There are some that everyone has. However, the files serve a similar purpose, regardless of the parent application. - -### System Settings - -System settings include the configuration for your desktop environment and your shell. - - * **Configuration files** for your shell and command line utilities: Depending on the specific shell and command-like utilities you use, the specific file name will change. You 'll see files like ".bashrc," ".vimrc" and ".zshrc." These files contain any settings you've changed about your shell's operating environment or tweaks you've made to the settings of command-line utilities like `vim`. Removing these files will return the associated application to its default state. Considering many Linux users build up an array of subtle tweaks and settings over the years, removing this file could be a huge headache. - * **User profiles:** Like the configuration files above, these files (typically ".profile" or ".bash_profile") save user settings for the shell. This file often contains your PATH. It also contains [aliases][3] you've set. Users can also put aliases in `.bashrc` or other locations. The PATH governs where the shell looks for executable commands. By appending or modifying your PATH, you can change where your shell looks for commands. Aliases change the names of commands. One alias might set `ll` to call `ls -l`, for example. This provides text-based shortcuts to often-used commands. If you delete `.profile`, you can often find the default version in the "/etc/skel" directory. - * **Desktop environment settings:** This saves any customization of your desktop environment. That includes the desktop background, screensavers, shortcut keys, menu bar and taskbar icons, and anything else that the user has set about their desktop environment. When you remove this file, the user's environment reverts to the new user environment at the next login. - - - -### Application configuration files - -You'll find these in the ".config" folder in Ubuntu. These are settings for your specific applications. They'll include things like the preference lists and settings. - - * **Configuration files for applications** : This includes settings from the application preferences menu, workspace configurations and more. Exactly what you'll find here depends on the parent application. - * **Web browser data:** This may include things like bookmarks and browsing history. The majority of files make up the cache. This is where the web browser stores temporarily download files, like images. Removing this might slow down some media-heavy websites the first time you visit them. - * **Caches** : If a user application caches data that's only relevant to that user (like the [Spotify app storing cache of your playlist][4]), the home directory is a natural place to store it. These caches might contain masses of data or just a few lines of code: it depends on what the parent application needs. If you remove these files, the application recreates them as necessary. - * **Logs:** Some user applications might store logs here as well. Depending on how developers set up the application, you might find log files stored in your home directory. This isn't a common choice, however. - - -### Conclusion -In most cases the hidden files in your Linux home directory as used to store user settings. This includes settings for command-line utilities as well as GUI-based applications. Removing them will remove user settings. Typically, it won't cause a program to break. - --------------------------------------------------------------------------------- - -via: https://www.maketecheasier.com/hidden-files-linux-home-directory/ - -作者:[Alexander Fox][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.maketecheasier.com/author/alexfox/ -[1]:https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-liunux-2.png (hidden-files-liunux-2) -[2]:https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-linux-3.png (hidden-files-linux-3) -[3]:https://www.maketecheasier.com/making-the-linux-command-line-a-little-friendlier/#aliases -[4]:https://www.maketecheasier.com/clear-spotify-cache/ From 104668113e796e5207f09fa24f7ce0cdc6198894 Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Mon, 5 Mar 2018 11:03:28 +0800 Subject: [PATCH 101/101] Create 20171017 What Are the Hidden Files in my Linux Home Directory For.md --- ...en Files in my Linux Home Directory For.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 translated/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md diff --git a/translated/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md b/translated/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md new file mode 100644 index 0000000000..681dfe94a8 --- /dev/null +++ b/translated/tech/20171017 What Are the Hidden Files in my Linux Home Directory For.md @@ -0,0 +1,64 @@ +我的 Linux 主目录中的隐藏文件是干什么用的? +====== + +![](https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-linux-hero.png) + +在你的 Linux 系统中,你可能会在主目录中存储大量文件和文件夹。但在这些文件下面,你知道你的主目录还附带了很多隐藏的文件和文件夹吗?如果你在主目录中运行 `ls -a`,你会发现一堆带有点前缀的隐藏文件和目录。这些隐藏的文件到底做了什么? + +### 在主目录中隐藏的文件是干什么用的? + +![hidden-files-liunux-2][1] + +通常,主目录中的隐藏文件和目录包含该用户程序访问的设置或数据。它们不打算由用户编辑,只需要应用程序进行编辑。这就是为什么它们被隐藏在用户的正常视图中。 + +通常,可以在不损坏操作系统的情况下删除和修改自己主目录中的文件。然而,依赖这些隐藏文件的应用程序可能不那么灵活。从主目录中删除隐藏文件时,通常会丢失与其关联的应用程序的设置。 + +依赖该隐藏文件的程序通常会重新创建它。 但是,你将从“开箱即用”设置开始,如全新用户。如果你在使用应用程序时遇到问题,那实际上可能是一个巨大的帮助。它可以让你删除可能造成麻烦的自定义设置。但如果你不这样做,这意味着你需要把所有的东西都设置成原来的样子。 + +### 主目录中某些隐藏文件的特定用途是什么? + +![hidden-files-linux-3][2] + +每个人在他们的主目录中都会有不同的隐藏文件。每个人都有一些。但是,无论父应用程序如何,这些文件都有类似的用途。 + +### 系统设置 + +系统设置包括桌面环境和 shell 的配置。 + +* 你的 shell 和命令行程序的**配置文件:**根据你使用的特定 shell 和类似命令的应用程序,特定的文件名称会变化。你会看到 ".bashrc"、".vimrc" 和 ".zshrc"。这些文件包含你已经更改的有关 shell 的操作环境的任何设置,或者对 `vim` 等命令行实用工具的设置进行了调整。删除这些文件将使关联的应用程序返回到其默认状态。考虑到许多 Linux 用户多年来建立了一系列微妙的调整和设置,删除这个文件可能是一个非常头疼的问题。 + +* **用户配置文件:**像上面的配置文件一样,这些文件(通常是 ".profile" 或 ".bash_profile")保存 shell 的用户设置。该文件通常包含你的 PATH。(译注: PATH 是环境变量)它还包含你设置的[别名][3]。用户也可以在 `.bashrc` 或其他位置放置别名。PATH 控制着 shell 寻找可执行命令的位置。通过添加或修改 PATH,可以更改 shell 的命令查找位置。别名更改了原有命令的名称。例如:一个别名可能将 `ls -l` 设置为 `ll`。这为经常使用的命令提供基于文本的快捷方式。如果删除 `.profile` 文件,通常可以在 "/etc/skel" 目录中找到默认版本。 + +* **桌面环境设置:**这里保存你的桌面环境的任何定制。其中包括桌面背景,屏幕保护程序,快捷键,菜单栏和任务栏图标以及用户针对其桌面环境设置的其他任何内容。当你删除这个文件时,用户的环境会在下一次登录时恢复到新的用户环境。 + +### 应用配置文件 + +你会在 Ubuntu 的 ".config" 文件夹中找到它们。 这些是针对特定应用程序的设置。 它们将包含喜好列表和设置等内容。 + +* **应用程序的配置文件:**这包括应用程序首选项菜单中的设置,工作区配置等。 你在这里找到的具体取决于父应用程序。 + +* **Web浏览器数据:**这可能包括书签和浏览历史记录等内容。大部分文件构成缓存。这是 Web 浏览器临时存储下载文件(如图片)的地方。删除这些内容可能会降低你首次访问某些媒体网站的速度。 + +* **缓存:**如果用户应用程序缓存仅与该用户相关的数据(如 [Spotify 应用程序存储播放列表的缓存][4]),则主目录是存储该目录的默认地点。 这些缓存可能包含大量数据或仅包含几行代码:这取决于父应用程序需要什么。 如果你删除这些文件,则应用程序会根据需要重新创建它们。 + +* **日志:**一些用户应用程序也可能在这里存储日志。根据开发人员设置应用程序的方式,你可能会发现存储在你的主目录中的日志文件。然而,这不是一个常见的选择。 + +### 结论 + +在大多数情况下,你的 Linux 主目录中的隐藏文件用于存储用户设置。 这包括命令行程序以及基于 GUI 的应用程序的设置。删除它们将删除用户设置。 通常情况下,它不会导致程序中断。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/hidden-files-linux-home-directory/ + +作者:[Alexander Fox][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.maketecheasier.com/author/alexfox/ +[1]:https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-liunux-2.png (hidden-files-liunux-2) +[2]:https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-linux-3.png (hidden-files-linux-3) +[3]:https://www.maketecheasier.com/making-the-linux-command-line-a-little-friendlier/#aliases +[4]:https://www.maketecheasier.com/clear-spotify-cache/